summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGraeme Gregory <dp@xora.org.uk>2008-12-15 14:27:45 +0000
committerGraeme Gregory <dp@xora.org.uk>2008-12-15 14:27:45 +0000
commitddb4e5d5dbf924d484ec088dc6f49d28496463b1 (patch)
tree24f68d917b46181515e52d0f07fd6d4644dc3081
parentaf62e575c1cb33ffa666c4d4a205a53e21b0c009 (diff)
src/glamo* : drag in the kdrive EXA sources, initial commit will need heavy
editing.
-rw-r--r--src/glamo-cmdq.c496
-rw-r--r--src/glamo-cmdq.h160
-rw-r--r--src/glamo-draw.c925
-rw-r--r--src/glamo-draw.h59
-rw-r--r--src/glamo-funcs.c601
-rw-r--r--src/glamo-funcs.h87
-rw-r--r--src/glamo-log.h80
-rw-r--r--src/glamo-regs.h783
-rw-r--r--src/glamo-stub.c88
-rw-r--r--src/glamo-video.c910
10 files changed, 4189 insertions, 0 deletions
diff --git a/src/glamo-cmdq.c b/src/glamo-cmdq.c
new file mode 100644
index 0000000..a576cd9
--- /dev/null
+++ b/src/glamo-cmdq.c
@@ -0,0 +1,496 @@
+/*
+ * Copyright © 2007 OpenMoko, Inc.
+ *
+ * This driver is based on Xati,
+ * Copyright © 2004 Eric Anholt
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <sys/time.h>
+
+#include "glamo-log.h"
+#include "glamo.h"
+#include "glamo-regs.h"
+#include "glamo-cmdq.h"
+#include "glamo-draw.h"
+
+static void GLAMOCMDQResetCP(ScreenPtr pScreen);
+#ifndef NDEBUG
+static void
+GLAMODebugFifo(GLAMOScreenInfo *glamos)
+{
+ GLAMOCardInfo *glamoc = glamos->glamoc;
+ char *mmio = glamoc->reg_base;
+ CARD32 offset;
+
+ ErrorF("GLAMO_REG_CMDQ_STATUS: 0x%04x\n",
+ MMIO_IN16(mmio, GLAMO_REG_CMDQ_STATUS));
+
+ offset = MMIO_IN16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRL);
+ offset |= (MMIO_IN16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRH) << 16) & 0x7;
+ ErrorF("GLAMO_REG_CMDQ_WRITE_ADDR: 0x%08x\n", (unsigned int) offset);
+
+ offset = MMIO_IN16(mmio, GLAMO_REG_CMDQ_READ_ADDRL);
+ offset |= (MMIO_IN16(mmio, GLAMO_REG_CMDQ_READ_ADDRH) << 16) & 0x7;
+ ErrorF("GLAMO_REG_CMDQ_READ_ADDR: 0x%08x\n", (unsigned int) offset);
+}
+#endif
+
+void
+GLAMOEngineReset(ScreenPtr pScreen, enum GLAMOEngine engine)
+{
+ KdScreenPriv(pScreen);
+ GLAMOCardInfo(pScreenPriv);
+ CARD32 reg;
+ CARD16 mask;
+ char *mmio = glamoc->reg_base;
+
+ if (!mmio)
+ return;
+
+ switch (engine) {
+ case GLAMO_ENGINE_CMDQ:
+ reg = GLAMO_REG_CLOCK_2D;
+ mask = GLAMO_CLOCK_2D_CMDQ_RESET;
+ break;
+ case GLAMO_ENGINE_ISP:
+ reg = GLAMO_REG_CLOCK_ISP;
+ mask = GLAMO_CLOCK_ISP2_RESET;
+ break;
+ case GLAMO_ENGINE_2D:
+ reg = GLAMO_REG_CLOCK_2D;
+ mask = GLAMO_CLOCK_2D_RESET;
+ break;
+ default:
+ return;
+ break;
+ }
+ MMIOSetBitMask(mmio, reg, mask, 0xffff);
+ usleep(5);
+ MMIOSetBitMask(mmio, reg, mask, 0);
+ usleep(5);
+
+}
+
+void
+GLAMOEngineDisable(ScreenPtr pScreen, enum GLAMOEngine engine)
+{
+ KdScreenPriv(pScreen);
+ GLAMOCardInfo(pScreenPriv);
+ char *mmio = glamoc->reg_base;
+
+ if (!mmio)
+ return;
+ switch (engine) {
+ case GLAMO_ENGINE_CMDQ:
+ MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_2D,
+ GLAMO_CLOCK_2D_EN_M6CLK,
+ 0);
+ MMIOSetBitMask(mmio, GLAMO_REG_HOSTBUS(2),
+ GLAMO_HOSTBUS2_MMIO_EN_CMDQ,
+ 0);
+ MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_GEN5_1,
+ GLAMO_CLOCK_GEN51_EN_DIV_MCLK,
+ 0);
+ break;
+ case GLAMO_ENGINE_ISP:
+ MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_ISP,
+ GLAMO_CLOCK_ISP_EN_M2CLK |
+ GLAMO_CLOCK_ISP_EN_I1CLK,
+ 0);
+ MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_GEN5_2,
+ GLAMO_CLOCK_GEN52_EN_DIV_ICLK,
+ 0);
+ MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_GEN5_1,
+ GLAMO_CLOCK_GEN51_EN_DIV_JCLK,
+ 0);
+ MMIOSetBitMask(mmio, GLAMO_REG_HOSTBUS(2),
+ GLAMO_HOSTBUS2_MMIO_EN_ISP,
+ 0);
+ break;
+ case GLAMO_ENGINE_2D:
+ MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_2D,
+ GLAMO_CLOCK_2D_EN_M7CLK |
+ GLAMO_CLOCK_2D_EN_GCLK |
+ GLAMO_CLOCK_2D_DG_M7CLK |
+ GLAMO_CLOCK_2D_DG_GCLK,
+ 0);
+ MMIOSetBitMask(mmio, GLAMO_REG_HOSTBUS(2),
+ GLAMO_HOSTBUS2_MMIO_EN_2D,
+ 0);
+ MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_GEN5_1,
+ GLAMO_CLOCK_GEN51_EN_DIV_GCLK,
+ 0);
+ break;
+ default:
+ break;
+ }
+ return;
+}
+
+void
+GLAMOEngineEnable(ScreenPtr pScreen, enum GLAMOEngine engine)
+{
+ KdScreenPriv(pScreen);
+ GLAMOCardInfo(pScreenPriv);
+ char *mmio = glamoc->reg_base;
+
+ if (!mmio)
+ return;
+
+ switch (engine) {
+ case GLAMO_ENGINE_CMDQ:
+ MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_2D,
+ GLAMO_CLOCK_2D_EN_M6CLK,
+ 0xffff);
+ MMIOSetBitMask(mmio, GLAMO_REG_HOSTBUS(2),
+ GLAMO_HOSTBUS2_MMIO_EN_CMDQ,
+ 0xffff);
+ MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_GEN5_1,
+ GLAMO_CLOCK_GEN51_EN_DIV_MCLK,
+ 0xffff);
+ break;
+ case GLAMO_ENGINE_ISP:
+ MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_ISP,
+ GLAMO_CLOCK_ISP_EN_M2CLK |
+ GLAMO_CLOCK_ISP_EN_I1CLK,
+ 0xffff);
+ MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_GEN5_2,
+ GLAMO_CLOCK_GEN52_EN_DIV_ICLK,
+ 0xffff);
+ MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_GEN5_1,
+ GLAMO_CLOCK_GEN51_EN_DIV_JCLK,
+ 0xffff);
+ MMIOSetBitMask(mmio, GLAMO_REG_HOSTBUS(2),
+ GLAMO_HOSTBUS2_MMIO_EN_ISP,
+ 0xffff);
+ break;
+ case GLAMO_ENGINE_2D:
+ MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_2D,
+ GLAMO_CLOCK_2D_EN_M7CLK |
+ GLAMO_CLOCK_2D_EN_GCLK |
+ GLAMO_CLOCK_2D_DG_M7CLK |
+ GLAMO_CLOCK_2D_DG_GCLK,
+ 0xffff);
+ MMIOSetBitMask(mmio, GLAMO_REG_HOSTBUS(2),
+ GLAMO_HOSTBUS2_MMIO_EN_2D,
+ 0xffff);
+ MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_GEN5_1,
+ GLAMO_CLOCK_GEN51_EN_DIV_GCLK,
+ 0xffff);
+ break;
+ default:
+ break;
+ }
+}
+
+int
+GLAMOEngineBusy(ScreenPtr pScreen, enum GLAMOEngine engine)
+{
+ KdScreenPriv(pScreen);
+ GLAMOCardInfo(pScreenPriv);
+ GLAMOScreenInfo(pScreenPriv);
+ char *mmio = glamoc->reg_base;
+ CARD16 status, mask, val;
+
+ if (!mmio)
+ return FALSE;
+
+ if (glamos->cmd_queue_cache != NULL)
+ GLAMOFlushCMDQCache(glamos, 0);
+
+ switch (engine)
+ {
+ case GLAMO_ENGINE_CMDQ:
+ mask = 0x3;
+ val = mask;
+ break;
+ case GLAMO_ENGINE_ISP:
+ mask = 0x3 | (1 << 8);
+ val = 0x3;
+ break;
+ case GLAMO_ENGINE_2D:
+ mask = 0x3 | (1 << 4);
+ val = 0x3;
+ break;
+ case GLAMO_ENGINE_ALL:
+ default:
+ mask = 1 << 2;
+ val = mask;
+ break;
+ }
+
+ status = MMIO_IN16(mmio, GLAMO_REG_CMDQ_STATUS);
+
+ return !((status & mask) == val);
+}
+
+static void
+GLAMOEngineWaitReal(ScreenPtr pScreen,
+ enum GLAMOEngine engine,
+ Bool do_flush)
+{
+ KdScreenPriv(pScreen);
+ GLAMOCardInfo(pScreenPriv);
+ GLAMOScreenInfo(pScreenPriv);
+ char *mmio = glamoc->reg_base;
+ CARD16 status, mask, val;
+ TIMEOUT_LOCALS;
+
+ if (!mmio)
+ return;
+
+ if (glamos->cmd_queue_cache != NULL && do_flush)
+ GLAMOFlushCMDQCache(glamos, 0);
+
+ switch (engine)
+ {
+ case GLAMO_ENGINE_CMDQ:
+ mask = 0x3;
+ val = mask;
+ break;
+ case GLAMO_ENGINE_ISP:
+ mask = 0x3 | (1 << 8);
+ val = 0x3;
+ break;
+ case GLAMO_ENGINE_2D:
+ mask = 0x3 | (1 << 4);
+ val = 0x3;
+ break;
+ case GLAMO_ENGINE_ALL:
+ default:
+ mask = 1 << 2;
+ val = mask;
+ break;
+ }
+
+ WHILE_NOT_TIMEOUT(5) {
+ status = MMIO_IN16(mmio, GLAMO_REG_CMDQ_STATUS);
+ if ((status & mask) == val)
+ break;
+ }
+ if (TIMEDOUT()) {
+ GLAMO_LOG_ERROR("Timeout idling accelerator "
+ "(0x%x), resetting...\n",
+ status);
+ GLAMODumpRegs(glamos, 0x1600, 0x1612);
+ GLAMOEngineReset(glamos->screen->pScreen, GLAMO_ENGINE_CMDQ);
+ GLAMODrawSetup(glamos->screen->pScreen);
+ }
+}
+
+void
+GLAMOEngineWait(ScreenPtr pScreen,
+ enum GLAMOEngine engine)
+{
+ GLAMOEngineWaitReal(pScreen, engine, TRUE);
+}
+
+MemBuf *
+GLAMOCreateCMDQCache(GLAMOScreenInfo *glamos)
+{
+ MemBuf *buf;
+
+ buf = (MemBuf *)xcalloc(1, sizeof(MemBuf));
+ if (buf == NULL)
+ return NULL;
+
+ /*buf->size = glamos->ring_len / 2;*/
+ buf->size = glamos->ring_len;
+ buf->address = xcalloc(1, buf->size);
+ if (buf->address == NULL) {
+ xfree(buf);
+ return NULL;
+ }
+ buf->used = 0;
+
+ return buf;
+}
+
+static void
+GLAMODispatchCMDQCache(GLAMOScreenInfo *glamos)
+{
+ GLAMOCardInfo *glamoc = glamos->glamoc;
+ MemBuf *buf = glamos->cmd_queue_cache;
+ char *mmio = glamoc->reg_base;
+ CARD16 *addr;
+ int count, ring_count;
+ TIMEOUT_LOCALS;
+
+ addr = (CARD16 *)((char *)buf->address + glamos->cmd_queue_cache_start);
+ count = (buf->used - glamos->cmd_queue_cache_start) / 2;
+ ring_count = glamos->ring_len / 2;
+ if (count + glamos->ring_write >= ring_count) {
+ GLAMOCMDQResetCP(glamos->screen->pScreen);
+ glamos->ring_write = 0;
+ }
+
+ WHILE_NOT_TIMEOUT(.5) {
+ if (count <= 0)
+ break;
+
+ glamos->ring_addr[glamos->ring_write] = *addr;
+ glamos->ring_write++; addr++;
+ if (glamos->ring_write >= ring_count) {
+ GLAMO_LOG_ERROR("wrapped over ring_write\n");
+ GLAMODumpRegs(glamos, 0x1600, 0x1612);
+ glamos->ring_write = 0;
+ }
+ count--;
+ }
+ if (TIMEDOUT()) {
+ GLAMO_LOG_ERROR("Timeout submitting packets, "
+ "resetting...\n");
+ GLAMODumpRegs(glamos, 0x1600, 0x1612);
+ GLAMOEngineReset(glamos->screen->pScreen, GLAMO_ENGINE_CMDQ);
+ GLAMODrawSetup(glamos->screen->pScreen);
+ }
+
+ MMIO_OUT16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRH,
+ (glamos->ring_write >> 15) & 0x7);
+ MMIO_OUT16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRL,
+ (glamos->ring_write << 1) & 0xffff);
+ GLAMOEngineWaitReal(glamos->screen->pScreen,
+ GLAMO_ENGINE_CMDQ, FALSE);
+}
+
+void
+GLAMOFlushCMDQCache(GLAMOScreenInfo *glamos, Bool discard)
+{
+ MemBuf *buf = glamos->cmd_queue_cache;
+
+ if ((glamos->cmd_queue_cache_start == buf->used) && !discard)
+ return;
+ GLAMODispatchCMDQCache(glamos);
+
+ buf->used = 0;
+ glamos->cmd_queue_cache_start = 0;
+}
+
+#define CQ_LEN 255
+static void
+GLAMOCMDQResetCP(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ GLAMOCardInfo(pScreenPriv);
+ char *mmio = glamoc->reg_base;
+ int cq_len = CQ_LEN;
+ CARD32 queue_offset = 0;
+
+ /* make the decoder happy? */
+ memset((char*)glamos->ring_addr, 0, glamos->ring_len+2);
+
+ GLAMOEngineReset(glamos->screen->pScreen, GLAMO_ENGINE_CMDQ);
+
+ if (glamos->use_exa) {
+ queue_offset = glamos->exa_cmd_queue->offset;
+ } else {
+ queue_offset = glamos->cmd_queue->offset;
+ }
+ MMIO_OUT16(mmio, GLAMO_REG_CMDQ_BASE_ADDRL,
+ queue_offset & 0xffff);
+ MMIO_OUT16(mmio, GLAMO_REG_CMDQ_BASE_ADDRH,
+ (queue_offset >> 16) & 0x7f);
+ MMIO_OUT16(mmio, GLAMO_REG_CMDQ_LEN, cq_len);
+
+ MMIO_OUT16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRH, 0);
+ MMIO_OUT16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRL, 0);
+ MMIO_OUT16(mmio, GLAMO_REG_CMDQ_READ_ADDRH, 0);
+ MMIO_OUT16(mmio, GLAMO_REG_CMDQ_READ_ADDRL, 0);
+ MMIO_OUT16(mmio, GLAMO_REG_CMDQ_CONTROL,
+ 1 << 12 |
+ 5 << 8 |
+ 8 << 4);
+ GLAMOEngineWaitReal(pScreen, GLAMO_ENGINE_ALL, FALSE);
+}
+
+static Bool
+GLAMOCMDQInit(ScreenPtr pScreen,
+ Bool force)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ GLAMOCardInfo(pScreenPriv);
+ char *mmio = glamoc->reg_base;
+ int cq_len = CQ_LEN;
+
+ if (!force && glamos->use_exa && glamos->exa_cmd_queue)
+ return TRUE;
+ if (!force && !glamos->use_exa && glamos->cmd_queue)
+ return TRUE;
+
+ glamos->ring_len = (cq_len + 1) * 1024;
+
+ if (glamos->use_exa) {
+ glamos->exa_cmd_queue =
+ exaOffscreenAlloc(pScreen, glamos->ring_len + 4,
+ glamos->exa.pixmapOffsetAlign,
+ TRUE, NULL, NULL);
+ if (!glamos->exa_cmd_queue)
+ return FALSE;
+ glamos->ring_addr =
+ (CARD16 *) (pScreenPriv->screen->memory_base +
+ glamos->exa_cmd_queue->offset);
+ } else {
+ glamos->cmd_queue =
+ KdOffscreenAlloc(pScreen, glamos->ring_len + 4,
+ glamos->kaa.offsetAlign,
+ TRUE, NULL, NULL);
+ if (!glamos->cmd_queue)
+ return FALSE;
+ glamos->ring_addr =
+ (CARD16 *) (pScreenPriv->screen->memory_base +
+ glamos->cmd_queue->offset);
+ }
+
+ GLAMOEngineEnable(glamos->screen->pScreen, GLAMO_ENGINE_CMDQ);
+ GLAMOCMDQResetCP(glamos->screen->pScreen);
+ return TRUE;
+}
+
+void
+GLAMOCMDQCacheSetup(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+
+ GLAMOCMDQInit(pScreen, TRUE);
+
+ if (glamos->cmd_queue_cache)
+ return;
+
+ glamos->cmd_queue_cache = GLAMOCreateCMDQCache(glamos);
+ if (glamos->cmd_queue_cache == FALSE)
+ FatalError("Failed to allocate cmd queue cache buffer.\n");
+}
+
+void
+GLAMOCMQCacheTeardown(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+
+ GLAMOEngineWait(pScreen, GLAMO_ENGINE_ALL);
+
+ xfree(glamos->cmd_queue_cache->address);
+ xfree(glamos->cmd_queue_cache);
+ glamos->cmd_queue_cache = NULL;
+}
diff --git a/src/glamo-cmdq.h b/src/glamo-cmdq.h
new file mode 100644
index 0000000..e64aaca
--- /dev/null
+++ b/src/glamo-cmdq.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright © 2007 OpenMoko, Inc.
+ *
+ * This driver is based on Xati,
+ * Copyright © 2004 Eric Anholt
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _GLAMO_DMA_H_
+#define _GLAMO_DMA_H_
+
+#define CCE_DEBUG 1
+
+#if !CCE_DEBUG
+
+#define RING_LOCALS CARD16 *__head; int __count
+#define BEGIN_CMDQ(n) \
+do { \
+ if ((glamos->cmd_queue_cache->used + 2 * (n)) > \
+ glamos->cmd_queue_cache->size) { \
+ GLAMOFlushCMDQCache(glamos, 1); \
+ } \
+ __head = (CARD16 *)((char *)glamos->cmd_queue_cache->address + \
+ glamos->cmd_queue_cache->used); \
+ __count = 0; \
+} while (0)
+#define END_CMDQ() do { \
+ glamos->cmd_queue_cache->used += __count * 2; \
+} while (0)
+
+#else
+
+#define RING_LOCALS \
+ CARD16 *__head; int __count, __total, __reg, __packet0count
+#define BEGIN_CMDQ(n) \
+do { \
+ if ((glamos->cmd_queue_cache->used + 2 * (n)) > \
+ glamos->cmd_queue_cache->size) { \
+ GLAMOFlushCMDQCache(glamos, 1); \
+ } \
+ __head = (CARD16 *)((char *)glamos->cmd_queue_cache->address + \
+ glamos->cmd_queue_cache->used); \
+ __count = 0; \
+ __total = n; \
+ __reg = 0; \
+ __packet0count = 0; \
+} while (0)
+#define END_CMDQ() do { \
+ if (__count != __total) \
+ FatalError("count != total (%d vs %d) at %s:%d\n", \
+ __count, __total, __FILE__, __LINE__); \
+ glamos->cmd_queue_cache->used += __count * 2; \
+} while (0)
+
+#endif
+
+#define OUT_PAIR(v1, v2) \
+do { \
+ __head[__count++] = (v1); \
+ __head[__count++] = (v2); \
+} while (0)
+
+#define OUT_BURST_REG(reg, val) do { \
+ if (__reg != reg) \
+ FatalError("unexpected reg (0x%x vs 0x%x) at %s:%d\n", \
+ reg, __reg, __FILE__, __LINE__); \
+ if (__packet0count-- <= 0) \
+ FatalError("overrun of packet0 at %s:%d\n", \
+ __FILE__, __LINE__); \
+ __head[__count++] = (val); \
+ __reg += 2; \
+} while (0)
+
+#define OUT_REG(reg, val) \
+ OUT_PAIR(reg, val)
+
+#define OUT_BURST(reg, n) \
+do { \
+ OUT_PAIR((1 << 15) | reg, n); \
+ __reg = reg; \
+ __packet0count = n; \
+} while (0)
+
+
+#define TIMEOUT_LOCALS struct timeval _target, _curtime
+
+static inline Bool
+tv_le(struct timeval *tv1, struct timeval *tv2)
+{
+ if (tv1->tv_sec < tv2->tv_sec ||
+ (tv1->tv_sec == tv2->tv_sec && tv1->tv_usec < tv2->tv_usec))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+#define WHILE_NOT_TIMEOUT(_timeout) \
+ gettimeofday(&_target, NULL); \
+ _target.tv_usec += ((_timeout) * 1000000); \
+ _target.tv_sec += _target.tv_usec / 1000000; \
+ _target.tv_usec = _target.tv_usec % 1000000; \
+ while (gettimeofday(&_curtime, NULL), tv_le(&_curtime, &_target))
+
+#define TIMEDOUT() (!tv_le(&_curtime, &_target))
+
+MemBuf *
+GLAMOCreateCMDQCache(GLAMOScreenInfo *glamos);
+
+void
+GLAMOFlushCMDQCache(GLAMOScreenInfo *glamos, Bool discard);
+
+void
+GLAMOCMDQCacheSetup(ScreenPtr pScreen);
+
+void
+GLAMOCMQCacheTeardown(ScreenPtr pScreen);
+
+enum GLAMOEngine {
+ GLAMO_ENGINE_CMDQ,
+ GLAMO_ENGINE_ISP,
+ GLAMO_ENGINE_2D,
+ GLAMO_ENGINE_MPEG,
+ GLAMO_ENGINE_ALL,
+ NB_GLAMO_ENGINES /*should be the last entry*/
+};
+
+void
+GLAMOEngineEnable(ScreenPtr pScreen, enum GLAMOEngine engine);
+
+void
+GLAMOEngineDisable(ScreenPtr pScreen, enum GLAMOEngine engine);
+
+void
+GLAMOEngineReset(ScreenPtr pScreen, enum GLAMOEngine engine);
+
+int
+GLAMOEngineBusy(ScreenPtr pScreen, enum GLAMOEngine engine);
+
+void
+GLAMOEngineWait(ScreenPtr pScreen, enum GLAMOEngine engine);
+
+#endif /* _GLAMO_DMA_H_ */
+
diff --git a/src/glamo-draw.c b/src/glamo-draw.c
new file mode 100644
index 0000000..e1b6805
--- /dev/null
+++ b/src/glamo-draw.c
@@ -0,0 +1,925 @@
+/*
+ * Copyright © 2007 OpenMoko, Inc.
+ *
+ * This driver is based on Xati,
+ * Copyright © 2003 Eric Anholt
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "glamo-log.h"
+#include "glamo.h"
+#include "glamo-regs.h"
+#include "glamo-cmdq.h"
+#include "glamo-draw.h"
+#include "kaa.h"
+
+static const CARD8 GLAMOSolidRop[16] = {
+ /* GXclear */ 0x00, /* 0 */
+ /* GXand */ 0xa0, /* src AND dst */
+ /* GXandReverse */ 0x50, /* src AND NOT dst */
+ /* GXcopy */ 0xf0, /* src */
+ /* GXandInverted*/ 0x0a, /* NOT src AND dst */
+ /* GXnoop */ 0xaa, /* dst */
+ /* GXxor */ 0x5a, /* src XOR dst */
+ /* GXor */ 0xfa, /* src OR dst */
+ /* GXnor */ 0x05, /* NOT src AND NOT dst */
+ /* GXequiv */ 0xa5, /* NOT src XOR dst */
+ /* GXinvert */ 0x55, /* NOT dst */
+ /* GXorReverse */ 0xf5, /* src OR NOT dst */
+ /* GXcopyInverted*/ 0x0f, /* NOT src */
+ /* GXorInverted */ 0xaf, /* NOT src OR dst */
+ /* GXnand */ 0x5f, /* NOT src OR NOT dst */
+ /* GXset */ 0xff, /* 1 */
+};
+
+static const CARD8 GLAMOBltRop[16] = {
+ /* GXclear */ 0x00, /* 0 */
+ /* GXand */ 0x88, /* src AND dst */
+ /* GXandReverse */ 0x44, /* src AND NOT dst */
+ /* GXcopy */ 0xcc, /* src */
+ /* GXandInverted*/ 0x22, /* NOT src AND dst */
+ /* GXnoop */ 0xaa, /* dst */
+ /* GXxor */ 0x66, /* src XOR dst */
+ /* GXor */ 0xee, /* src OR dst */
+ /* GXnor */ 0x11, /* NOT src AND NOT dst */
+ /* GXequiv */ 0x99, /* NOT src XOR dst */
+ /* GXinvert */ 0x55, /* NOT dst */
+ /* GXorReverse */ 0xdd, /* src OR NOT dst */
+ /* GXcopyInverted*/ 0x33, /* NOT src */
+ /* GXorInverted */ 0xbb, /* NOT src OR dst */
+ /* GXnand */ 0x77, /* NOT src OR NOT dst */
+ /* GXset */ 0xff, /* 1 */
+};
+
+static GLAMOScreenInfo *accel_glamos;
+static CARD32 settings, color, src_pitch_offset, dst_pitch_offset;
+
+int sample_count;
+float sample_offsets_x[255];
+float sample_offsets_y[255];
+
+/********************************
+ * exa entry points declarations
+ ********************************/
+
+Bool
+GLAMOExaPrepareSolid(PixmapPtr pPixmap,
+ int alu,
+ Pixel planemask,
+ Pixel fg);
+
+void
+GLAMOExaSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2);
+
+void
+GLAMOExaDoneSolid(PixmapPtr pPixmap);
+
+void
+GLAMOExaCopy(PixmapPtr pDstPixmap,
+ int srcX,
+ int srcY,
+ int dstX,
+ int dstY,
+ int width,
+ int height);
+
+void
+GLAMOExaDoneCopy(PixmapPtr pDstPixmap);
+
+Bool
+GLAMOExaCheckComposite(int op,
+ PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture,
+ PicturePtr pDstPicture);
+
+
+Bool
+GLAMOExaPrepareComposite(int op,
+ PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture,
+ PicturePtr pDstPicture,
+ PixmapPtr pSrc,
+ PixmapPtr pMask,
+ PixmapPtr pDst);
+
+void
+GLAMOExaComposite(PixmapPtr pDst,
+ int srcX,
+ int srcY,
+ int maskX,
+ int maskY,
+ int dstX,
+ int dstY,
+ int width,
+ int height);
+
+Bool
+GLAMOExaPrepareCopy(PixmapPtr pSrcPixmap,
+ PixmapPtr pDstPixmap,
+ int dx,
+ int dy,
+ int alu,
+ Pixel planemask);
+
+void
+GLAMOExaDoneComposite(PixmapPtr pDst);
+
+
+Bool
+GLAMOExaUploadToScreen(PixmapPtr pDst,
+ int x,
+ int y,
+ int w,
+ int h,
+ char *src,
+ int src_pitch);
+Bool
+GLAMOExaDownloadFromScreen(PixmapPtr pSrc,
+ int x, int y,
+ int w, int h,
+ char *dst,
+ int dst_pitch);
+
+void
+GLAMOExaWaitMarker (ScreenPtr pScreen, int marker);
+
+static void
+MarkForWait(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ if (glamos->use_exa) {
+ exaMarkSync(pScreen);
+ } else {
+ kaaMarkSync(pScreen);
+ }
+}
+
+static void
+WaitSync(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ if (glamos->use_exa) {
+ exaWaitSync(pScreen);
+ } else {
+ kaaWaitSync(pScreen);
+ }
+}
+
+void
+GLAMODrawSetup(ScreenPtr pScreen)
+{
+ GLAMOEngineEnable(pScreen, GLAMO_ENGINE_2D);
+ GLAMOEngineReset(pScreen, GLAMO_ENGINE_2D);
+}
+
+static void
+GLAMOWaitMarker(ScreenPtr pScreen, int marker)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+
+ GLAMO_LOG("enter\n");
+ GLAMOEngineWait(pScreen, GLAMO_ENGINE_ALL);
+ GLAMO_LOG("leave\n");
+}
+
+static Bool
+GLAMOPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
+{
+ KdScreenPriv(pPix->drawable.pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ CARD32 offset, pitch;
+ FbBits mask;
+ RING_LOCALS;
+
+ if (pPix->drawable.bitsPerPixel != 16) {
+ GLAMO_LOG("pPix->drawable.bitsPerPixel:%d\n",
+ pPix->drawable.bitsPerPixel);
+ GLAMO_FALLBACK(("Only 16bpp is supported\n"));
+ }
+
+ mask = FbFullMask(16);
+ if ((pm & mask) != mask)
+ GLAMO_FALLBACK(("Can't do planemask 0x%08x\n", (unsigned int) pm));
+
+ accel_glamos = glamos;
+
+ glamos->settings = GLAMOSolidRop[alu] << 8;
+ glamos->src_offset = ((CARD8 *) pPix->devPrivate.ptr -
+ pScreenPriv->screen->memory_base);
+ glamos->src_pitch = pPix->devKind;
+ glamos->srcPixmap = pPix;
+ glamos->foreground = fg;
+
+ GLAMO_LOG("enter:, src_offset:%#x, src_pitch:%d, fg%#x\n",
+ glamos->foreground,glamos->src_pitch, glamos->src_offset);
+
+ /*
+ BEGIN_CMDQ(12);
+ OUT_REG(GLAMO_REG_2D_DST_ADDRL, offset & 0xffff);
+ OUT_REG(GLAMO_REG_2D_DST_ADDRH, (offset >> 16) & 0x7f);
+ OUT_REG(GLAMO_REG_2D_DST_PITCH, pitch);
+ OUT_REG(GLAMO_REG_2D_DST_HEIGHT, pPix->drawable.height);
+ OUT_REG(GLAMO_REG_2D_PAT_FG, fg);
+ OUT_REG(GLAMO_REG_2D_COMMAND2, settings);
+ END_CMDQ();
+ */
+
+ kaaMarkSync(glamos->screen->pScreen);
+ GLAMO_LOG("leave\n");
+
+ return TRUE;
+}
+
+static void
+GLAMOSolid(int x1, int y1, int x2, int y2)
+{
+ GLAMO_LOG("enter: (x1,y1,x2,y2):(%d,%d,%d,%d)\n",
+ x1, y1, x2, y2);
+ GLAMOScreenInfo *glamos = accel_glamos;
+ RING_LOCALS;
+
+ BEGIN_CMDQ(26);
+ OUT_REG(GLAMO_REG_2D_DST_ADDRL, glamos->src_offset & 0xffff);
+ OUT_REG(GLAMO_REG_2D_DST_ADDRH, (glamos->src_offset >> 16) & 0x7f);
+ OUT_REG(GLAMO_REG_2D_DST_PITCH, glamos->src_pitch);
+ OUT_REG(GLAMO_REG_2D_DST_HEIGHT, glamos->srcPixmap->drawable.height);
+ OUT_REG(GLAMO_REG_2D_PAT_FG, glamos->foreground);
+ OUT_REG(GLAMO_REG_2D_COMMAND2, glamos->settings);
+ OUT_REG(GLAMO_REG_2D_DST_X, x1);
+ OUT_REG(GLAMO_REG_2D_DST_Y, y1);
+ OUT_REG(GLAMO_REG_2D_RECT_WIDTH, x2 - x1);
+ OUT_REG(GLAMO_REG_2D_RECT_HEIGHT, y2 - y1);
+ OUT_REG(GLAMO_REG_2D_COMMAND3, 0);
+ OUT_REG(GLAMO_REG_2D_ID1, 0);
+ OUT_REG(GLAMO_REG_2D_ID2, 0);
+ END_CMDQ();
+ GLAMO_LOG("leave\n");
+}
+
+static void
+GLAMODoneSolid(void)
+{
+ GLAMOScreenInfo *glamos = accel_glamos;
+ kaaWaitSync(glamos->screen->pScreen);
+ if (glamos->cmd_queue_cache)
+ GLAMOFlushCMDQCache(glamos, 1);
+}
+
+static Bool
+GLAMOPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst,
+ int dx, int dy, int alu, Pixel pm)
+{
+ KdScreenPriv(pDst->drawable.pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ CARD32 src_offset, src_pitch;
+ CARD32 dst_offset, dst_pitch;
+ FbBits mask;
+ RING_LOCALS;
+
+ GLAMO_LOG("enter\n");
+
+ if (pSrc->drawable.bitsPerPixel != 16 ||
+ pDst->drawable.bitsPerPixel != 16) {
+ GLAMO_LOG("pSrc->drawable.bitsPerPixel:%d\n"
+ "pDst->drawable.bitsPerPixel:%d\n",
+ pSrc->drawable.bitsPerPixel,
+ pDst->drawable.bitsPerPixel);
+ GLAMO_FALLBACK(("Only 16bpp is supported"));
+ }
+
+ mask = FbFullMask(16);
+ if ((pm & mask) != mask)
+ GLAMO_FALLBACK(("Can't do planemask 0x%08x", (unsigned int) pm));
+
+ accel_glamos = glamos;
+ glamos->src_offset = ((CARD8 *) pSrc->devPrivate.ptr -
+ pScreenPriv->screen->memory_base);
+ glamos->src_pitch = pSrc->devKind;
+ glamos->dst_offset = ((CARD8 *) pDst->devPrivate.ptr -
+ pScreenPriv->screen->memory_base);
+ glamos->dst_pitch = pDst->devKind;
+ glamos->settings = GLAMOBltRop[alu] << 8;
+ glamos->srcPixmap = pSrc;
+ glamos->dstPixmap = pDst;
+
+ kaaMarkSync(pDst->drawable.pScreen);
+ GLAMO_LOG("leave\n");
+
+ return TRUE;
+}
+
+static void
+GLAMOCopy(int srcX, int srcY, int dstX, int dstY, int w, int h)
+{
+ GLAMOScreenInfo *glamos = accel_glamos;
+ RING_LOCALS;
+
+ GLAMO_LOG("enter: src(%d,%d), dst(%d,%d), wxh(%dx%d)\n",
+ srcX, srcY, dstX, dstY, w, h);
+ GLAMO_LOG("src_offset:%#x, dst_offset:%#x\n",
+ glamos->src_offset, glamos->dst_offset);
+
+ BEGIN_CMDQ(34);
+
+ OUT_REG(GLAMO_REG_2D_SRC_ADDRL, glamos->src_offset & 0xffff);
+ OUT_REG(GLAMO_REG_2D_SRC_ADDRH, (glamos->src_offset >> 16) & 0x7f);
+ OUT_REG(GLAMO_REG_2D_SRC_PITCH, glamos->src_pitch & 0x7ff);
+ OUT_REG(GLAMO_REG_2D_SRC_X, srcX & 0x7ff);
+ OUT_REG(GLAMO_REG_2D_SRC_Y, srcY & 0x7ff);
+ OUT_REG(GLAMO_REG_2D_DST_X, dstX & 0x7ff);
+ OUT_REG(GLAMO_REG_2D_DST_Y, dstY & 0x7ff);
+ OUT_REG(GLAMO_REG_2D_DST_ADDRL, glamos->dst_offset & 0xffff);
+ OUT_REG(GLAMO_REG_2D_DST_ADDRH, (glamos->dst_offset >> 16) & 0x7f);
+ OUT_REG(GLAMO_REG_2D_DST_PITCH, glamos->dst_pitch & 0x7ff);
+ OUT_REG(GLAMO_REG_2D_DST_HEIGHT,
+ glamos->dstPixmap->drawable.height & 0x3ff);
+ OUT_REG(GLAMO_REG_2D_RECT_WIDTH, w & 0x3ff);
+ OUT_REG(GLAMO_REG_2D_RECT_HEIGHT, h & 0x3ff);
+
+ OUT_REG(GLAMO_REG_2D_COMMAND2, glamos->settings & 0xffff);
+
+ OUT_REG(GLAMO_REG_2D_COMMAND3, 0);
+ OUT_REG(GLAMO_REG_2D_ID1, 0);
+ OUT_REG(GLAMO_REG_2D_ID2, 0);
+ END_CMDQ();
+
+ GLAMO_LOG("leave\n");
+}
+
+static void
+GLAMODoneCopy(void)
+{
+ GLAMOScreenInfo *glamos = accel_glamos;
+ GLAMO_LOG("enter\n");
+ kaaWaitSync(glamos->screen->pScreen);
+ kaaMarkSync(glamos->screen->pScreen);
+ if (glamos->cmd_queue_cache)
+ GLAMOFlushCMDQCache(glamos, 1);
+ kaaWaitSync(glamos->screen->pScreen);
+ GLAMO_LOG("leave\n");
+}
+
+static Bool
+GLAMOUploadToScreen(PixmapPtr pDst, char *src, int src_pitch)
+{
+ int width, height, bpp, i;
+ CARD8 *dst_offset;
+ int dst_pitch;
+
+ GLAMO_LOG("enter\n");
+ dst_offset = (CARD8 *)pDst->devPrivate.ptr;
+ dst_pitch = pDst->devKind;
+ width = pDst->drawable.width;
+ height = pDst->drawable.height;
+ bpp = pDst->drawable.bitsPerPixel;
+ bpp /= 8;
+
+ GLAMO_LOG("wxh(%dx%d), bpp:%d, dst_pitch:%d, src_pitch:%d\n",
+ width, height, bpp, dst_pitch, src_pitch);
+
+ for (i = 0; i < height; i++)
+ {
+ memcpy(dst_offset, src, width * bpp);
+
+ dst_offset += dst_pitch;
+ src += src_pitch;
+ }
+
+ return TRUE;
+}
+
+static void
+GLAMOBlockHandler(pointer blockData, OSTimePtr timeout, pointer readmask)
+{
+ ScreenPtr pScreen = (ScreenPtr) blockData;
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+
+ /* When the server is going to sleep,
+ * make sure that the cmd queue cache
+ * has been flushed.
+ */
+ if (glamos->use_exa)
+ exaWaitSync(pScreen);
+ else
+ kaaWaitSync(pScreen);
+ if (glamos->cmd_queue_cache)
+ GLAMOFlushCMDQCache(glamos, 1);
+}
+
+static void
+GLAMOWakeupHandler(pointer blockData, int result, pointer readmask)
+{
+}
+
+Bool
+GLAMODrawKaaInit(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ int offscreen_memory_size = 0;
+
+ offscreen_memory_size =
+ screen->memory_size - screen->off_screen_base;
+
+ LogMessage(X_INFO,
+ "vram size:%d, "
+ "onscreen vram size:%d, "
+ "offscreen vram size:%d\n",
+ screen->memory_size,
+ screen->off_screen_base,
+ offscreen_memory_size);
+
+ GLAMO_LOG("enter\n");
+
+ RegisterBlockAndWakeupHandlers(GLAMOBlockHandler, GLAMOWakeupHandler,
+ pScreen);
+
+ memset(&glamos->kaa, 0, sizeof(KaaScreenInfoRec));
+ glamos->kaa.waitMarker = GLAMOWaitMarker;
+ glamos->kaa.PrepareSolid = GLAMOPrepareSolid;
+ glamos->kaa.Solid = GLAMOSolid;
+ glamos->kaa.DoneSolid = GLAMODoneSolid;
+ glamos->kaa.PrepareCopy = GLAMOPrepareCopy;
+ glamos->kaa.Copy = GLAMOCopy;
+ glamos->kaa.DoneCopy = GLAMODoneCopy;
+ glamos->kaa.UploadToScreen = GLAMOUploadToScreen;
+
+ if (offscreen_memory_size > 0) {
+ glamos->kaa.flags = KAA_OFFSCREEN_PIXMAPS;
+ }
+ glamos->kaa.offsetAlign = 16;
+ glamos->kaa.pitchAlign = 16;
+
+ if (!kaaDrawInit(pScreen, &glamos->kaa)) {
+ GLAMO_LOG_ERROR("failed to init kaa\n");
+ return FALSE;
+ }
+
+ GLAMO_LOG("leave\n");
+ return TRUE;
+}
+
+/**
+ * exaDDXDriverInit is required by the top-level EXA module, and is used by
+ * the xorg DDX to hook in its EnableDisableFB wrapper. We don't need it, since
+ * we won't be enabling/disabling the FB.
+ */
+#ifndef GetGLAMOExaPriv
+#define GetGLAMOExaPriv(pScreen) \
+(GLAMOScreenInfo*)pScreen->devPrivates[glamoExaScreenPrivateIndex].ptr
+#endif
+void
+exaDDXDriverInit(ScreenPtr pScreen)
+{
+}
+
+static int glamoExaScreenPrivateIndex;
+
+Bool
+GLAMODrawExaInit(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ int offscreen_memory_size = 0;
+ char *use_exa = NULL;
+ Bool success = FALSE;
+
+ GLAMO_LOG("enter\n");
+
+ memset(&glamos->exa, 0, sizeof(ExaDriverRec));
+ glamos->exa.memoryBase = screen->memory_base;
+ glamos->exa.memorySize = screen->memory_size;
+ glamos->exa.offScreenBase = screen->off_screen_base;
+
+ glamos->exa.exa_major = 2;
+ glamos->exa.exa_minor = 0;
+
+ glamos->exa.PrepareSolid = GLAMOExaPrepareSolid;
+ glamos->exa.Solid = GLAMOExaSolid;
+ glamos->exa.DoneSolid = GLAMOExaDoneSolid;
+
+ glamos->exa.PrepareCopy = GLAMOExaPrepareCopy;
+ glamos->exa.Copy = GLAMOExaCopy;
+ glamos->exa.DoneCopy = GLAMOExaDoneCopy;
+
+ glamos->exa.CheckComposite = GLAMOExaCheckComposite;
+ glamos->exa.PrepareComposite = GLAMOExaPrepareComposite;
+ glamos->exa.Composite = GLAMOExaComposite;
+ glamos->exa.DoneComposite = GLAMOExaDoneComposite;
+
+
+ glamos->exa.DownloadFromScreen = GLAMOExaDownloadFromScreen;
+ glamos->exa.UploadToScreen = GLAMOExaUploadToScreen;
+
+ /*glamos->exa.MarkSync = GLAMOExaMarkSync;*/
+ glamos->exa.WaitMarker = GLAMOExaWaitMarker;
+
+ glamos->exa.pixmapOffsetAlign = 1;
+ glamos->exa.pixmapPitchAlign = 1;
+
+ glamos->exa.maxX = 640;
+ glamos->exa.maxY = 640;
+
+ glamos->exa.flags = EXA_OFFSCREEN_PIXMAPS;
+
+ RegisterBlockAndWakeupHandlers(GLAMOBlockHandler,
+ GLAMOWakeupHandler,
+ pScreen);
+
+ glamoExaScreenPrivateIndex = AllocateScreenPrivateIndex() ;
+ pScreen->devPrivates[glamoExaScreenPrivateIndex].ptr = glamos;
+ success = exaDriverInit(pScreen, &glamos->exa);
+ if (success) {
+ ErrorF("Initialized EXA acceleration\n");
+ } else {
+ ErrorF("Failed to initialize EXA acceleration\n");
+ }
+ GLAMO_LOG("leave\n");
+
+ return success;
+}
+
+Bool
+GLAMODrawInit(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ int offscreen_memory_size = 0;
+ char *use_exa = NULL;
+
+ LogMessage(X_INFO, "Screen: %d/%d depth/bpp\n",
+ pScreenPriv->screen->fb[0].depth,
+ pScreenPriv->screen->fb[0].bitsPerPixel);
+
+ use_exa = getenv("USE_EXA");
+ if (use_exa && !strcmp(use_exa, "yes")) {
+ glamos->use_exa = TRUE;
+ return GLAMODrawExaInit(pScreen);
+ } else {
+ glamos->use_exa = FALSE;
+ return GLAMODrawKaaInit(pScreen);
+ }
+}
+
+#if 0
+static void
+GLAMOScratchSave(ScreenPtr pScreen, KdOffscreenArea *area)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+
+ glamos->scratch_area = NULL;
+}
+#endif
+
+void
+GLAMODrawEnable(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+
+ GLAMO_LOG("enter\n");
+ GLAMOCMDQCacheSetup(pScreen);
+ GLAMODrawSetup(pScreen);
+ GLAMOEngineWait(pScreen, GLAMO_ENGINE_ALL);
+ GLAMO_LOG("leave\n");
+
+
+}
+
+
+void
+GLAMODrawDisable(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ if (!glamos->use_exa) {
+ kaaWaitSync(pScreen);
+ }
+ GLAMOCMQCacheTeardown(pScreen);
+}
+
+void
+GLAMODrawFini(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ RemoveBlockAndWakeupHandlers(GLAMOBlockHandler, GLAMOWakeupHandler,
+ pScreen);
+
+ if (!glamos->use_exa) {
+ kaaDrawFini(pScreen);
+ }
+}
+
+/***************************************
+ * <glamo exa entry point definitions>
+ ***************************************/
+Bool
+GLAMOExaPrepareSolid(PixmapPtr pPix,
+ int alu,
+ Pixel pm,
+ Pixel fg)
+{
+ KdScreenPriv(pPix->drawable.pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ CARD32 offset, pitch;
+ FbBits mask;
+ RING_LOCALS;
+
+ if (pPix->drawable.bitsPerPixel != 16)
+ GLAMO_FALLBACK(("Only 16bpp is supported\n"));
+
+ mask = FbFullMask(16);
+ if ((pm & mask) != mask)
+ GLAMO_FALLBACK(("Can't do planemask 0x%08x\n",
+ (unsigned int) pm));
+
+ settings = GLAMOSolidRop[alu] << 8;
+ offset = exaGetPixmapOffset(pPix);
+ pitch = pPix->devKind;
+
+ GLAMO_LOG("enter.pitch:%d\n", pitch);
+
+ BEGIN_CMDQ(12);
+ OUT_REG(GLAMO_REG_2D_DST_ADDRL, offset & 0xffff);
+ OUT_REG(GLAMO_REG_2D_DST_ADDRH, (offset >> 16) & 0x7f);
+ OUT_REG(GLAMO_REG_2D_DST_PITCH, pitch);
+ OUT_REG(GLAMO_REG_2D_DST_HEIGHT, pPix->drawable.height);
+ OUT_REG(GLAMO_REG_2D_PAT_FG, fg);
+ OUT_REG(GLAMO_REG_2D_COMMAND2, settings);
+ END_CMDQ();
+ GLAMO_LOG("leave\n");
+
+ return TRUE;
+}
+
+void
+GLAMOExaSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
+{
+ GLAMO_LOG("enter\n");
+ GLAMOScreenInfo *glamos = GetGLAMOExaPriv(pPix->drawable.pScreen);
+ RING_LOCALS;
+
+ BEGIN_CMDQ(14);
+ OUT_REG(GLAMO_REG_2D_DST_X, x1);
+ OUT_REG(GLAMO_REG_2D_DST_Y, y1);
+ OUT_REG(GLAMO_REG_2D_RECT_WIDTH, x2 - x1);
+ OUT_REG(GLAMO_REG_2D_RECT_HEIGHT, y2 - y1);
+ OUT_REG(GLAMO_REG_2D_COMMAND3, 0);
+ OUT_REG(GLAMO_REG_2D_ID1, 0);
+ OUT_REG(GLAMO_REG_2D_ID2, 0);
+ END_CMDQ();
+ GLAMO_LOG("leave\n");
+}
+
+void
+GLAMOExaDoneSolid(PixmapPtr pPix)
+{
+ GLAMOScreenInfo *glamos = GetGLAMOExaPriv(pPix->drawable.pScreen);
+ exaWaitSync(glamos->screen->pScreen);
+ if (glamos->cmd_queue_cache)
+ GLAMOFlushCMDQCache(glamos, 1);
+}
+
+Bool
+GLAMOExaPrepareCopy(PixmapPtr pSrc,
+ PixmapPtr pDst,
+ int dx,
+ int dy,
+ int alu,
+ Pixel pm)
+{
+ KdScreenPriv(pDst->drawable.pScreen);
+ GLAMOScreenInfo *glamos = GetGLAMOExaPriv(pDst->drawable.pScreen);
+ CARD32 src_offset, src_pitch;
+ CARD32 dst_offset, dst_pitch;
+ FbBits mask;
+ RING_LOCALS;
+
+ GLAMO_LOG("enter\n");
+
+ if (pSrc->drawable.bitsPerPixel != 16 ||
+ pDst->drawable.bitsPerPixel != 16)
+ GLAMO_FALLBACK(("Only 16bpp is supported"));
+
+ mask = FbFullMask(16);
+ if ((pm & mask) != mask) {
+ GLAMO_FALLBACK(("Can't do planemask 0x%08x",
+ (unsigned int) pm));
+ }
+
+ glamos->src_offset = exaGetPixmapOffset(pSrc);
+ glamos->src_pitch = pSrc->devKind;
+
+ glamos->dst_offset = exaGetPixmapOffset(pDst);
+ glamos->dst_pitch = pDst->devKind;
+ GLAMO_LOG("src_offset:%d, src_pitch:%d, "
+ "dst_offset:%d, dst_pitch:%d, mem_base:%#x\n",
+ glamos->src_offset,
+ glamos->src_pitch,
+ glamos->dst_offset,
+ glamos->dst_pitch,
+ pScreenPriv->screen->memory_base);
+
+ glamos->settings = GLAMOBltRop[alu] << 8;
+ exaMarkSync(pDst->drawable.pScreen);
+ GLAMO_LOG("leave\n");
+ return TRUE;
+}
+
+void
+GLAMOExaCopy(PixmapPtr pDst,
+ int srcX,
+ int srcY,
+ int dstX,
+ int dstY,
+ int width,
+ int height)
+{
+ GLAMOScreenInfo *glamos = GetGLAMOExaPriv(pDst->drawable.pScreen);
+ RING_LOCALS;
+
+ GLAMO_LOG("enter (%d,%d,%d,%d),(%dx%d)\n",
+ srcX, srcY, dstX, dstY,
+ width, height);
+
+ BEGIN_CMDQ(34);
+
+ OUT_REG(GLAMO_REG_2D_SRC_ADDRL, glamos->src_offset & 0xffff);
+ OUT_REG(GLAMO_REG_2D_SRC_ADDRH, (glamos->src_offset >> 16) & 0x7f);
+ OUT_REG(GLAMO_REG_2D_SRC_PITCH, glamos->src_pitch);
+
+ OUT_REG(GLAMO_REG_2D_DST_ADDRL, glamos->dst_offset & 0xffff);
+ OUT_REG(GLAMO_REG_2D_DST_ADDRH, (glamos->dst_offset >> 16) & 0x7f);
+ OUT_REG(GLAMO_REG_2D_DST_PITCH, glamos->dst_pitch);
+ OUT_REG(GLAMO_REG_2D_DST_HEIGHT, pDst->drawable.height);
+
+ OUT_REG(GLAMO_REG_2D_COMMAND2, glamos->settings);
+
+ OUT_REG(GLAMO_REG_2D_SRC_X, srcX);
+ OUT_REG(GLAMO_REG_2D_SRC_Y, srcY);
+ OUT_REG(GLAMO_REG_2D_DST_X, dstX);
+ OUT_REG(GLAMO_REG_2D_DST_Y, dstY);
+ OUT_REG(GLAMO_REG_2D_RECT_WIDTH, width);
+ OUT_REG(GLAMO_REG_2D_RECT_HEIGHT, height);
+ OUT_REG(GLAMO_REG_2D_COMMAND3, 0);
+ OUT_REG(GLAMO_REG_2D_ID1, 0);
+ OUT_REG(GLAMO_REG_2D_ID2, 0);
+ END_CMDQ();
+ GLAMO_LOG("leave\n");
+}
+
+void
+GLAMOExaDoneCopy(PixmapPtr pDst)
+{
+ GLAMOScreenInfo *glamos = GetGLAMOExaPriv(pDst->drawable.pScreen);
+ GLAMO_LOG("enter\n");
+ exaWaitSync(glamos->screen->pScreen);
+ if (glamos->cmd_queue_cache)
+ GLAMOFlushCMDQCache(glamos, 1);
+ GLAMO_LOG("leave\n");
+}
+
+Bool
+GLAMOExaCheckComposite(int op,
+ PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture,
+ PicturePtr pDstPicture)
+{
+ return FALSE;
+}
+
+Bool
+GLAMOExaPrepareComposite(int op,
+ PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture,
+ PicturePtr pDstPicture,
+ PixmapPtr pSrc,
+ PixmapPtr pMask,
+ PixmapPtr pDst)
+{
+ return FALSE;
+}
+
+void
+GLAMOExaComposite(PixmapPtr pDst,
+ int srcX,
+ int srcY,
+ int maskX,
+ int maskY,
+ int dstX,
+ int dstY,
+ int width,
+ int height)
+{
+}
+
+void
+GLAMOExaDoneComposite(PixmapPtr pDst)
+{
+}
+
+Bool
+GLAMOExaUploadToScreen(PixmapPtr pDst,
+ int x,
+ int y,
+ int w,
+ int h,
+ char *src,
+ int src_pitch)
+{
+ int bpp, i;
+ CARD8 *dst_offset;
+ int dst_pitch;
+ KdScreenPriv(pDst->drawable.pScreen);
+ GLAMOScreenInfo *glamos = GetGLAMOExaPriv(pDst->drawable.pScreen);
+
+ GLAMO_LOG("enter\n");
+ bpp = pDst->drawable.bitsPerPixel / 8;
+ dst_pitch = pDst->devKind;
+ dst_offset = glamos->exa.memoryBase + exaGetPixmapOffset(pDst)
+ + x*bpp + y*dst_pitch;
+
+ GLAMO_LOG("dst_pitch:%d, src_pitch\n", dst_pitch, src_pitch);
+ for (i = 0; i < h; i++) {
+ memcpy(dst_offset, src, w*bpp);
+ dst_offset += dst_pitch;
+ src += src_pitch;
+ }
+
+ return TRUE;
+}
+
+Bool
+GLAMOExaDownloadFromScreen(PixmapPtr pSrc,
+ int x, int y,
+ int w, int h,
+ char *dst,
+ int dst_pitch)
+{
+ int bpp, i;
+ CARD8 *dst_offset, *src;
+ int src_pitch;
+ KdScreenPriv(pSrc->drawable.pScreen);
+ GLAMOScreenInfo *glamos = GetGLAMOExaPriv(pSrc->drawable.pScreen);
+
+ GLAMO_LOG("enter\n");
+ bpp = pSrc->drawable.bitsPerPixel;
+ bpp /= 8;
+ src_pitch = pSrc->devKind;
+ src = glamos->exa.memoryBase + exaGetPixmapOffset(pSrc) +
+ x*bpp + y*src_pitch;
+ dst_offset = dst ;
+
+ GLAMO_LOG("dst_pitch:%d, src_pitch\n", dst_pitch, src_pitch);
+ for (i = 0; i < h; i++) {
+ memcpy(dst_offset, src, w*bpp);
+ dst_offset += dst_pitch;
+ src += src_pitch;
+ }
+
+ return TRUE;
+}
+
+void
+GLAMOExaWaitMarker (ScreenPtr pScreen, int marker)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo *glamos = GetGLAMOExaPriv(pScreen);
+
+ GLAMO_LOG("enter\n");
+ GLAMOEngineWait(pScreen, GLAMO_ENGINE_ALL);
+ GLAMO_LOG("leave\n");
+}
+
+/**********************
+ * </glamo exa functions>
+ **********************/
diff --git a/src/glamo-draw.h b/src/glamo-draw.h
new file mode 100644
index 0000000..f93ae82
--- /dev/null
+++ b/src/glamo-draw.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2007 OpenMoko, Inc.
+ *
+ * This driver is based on Xati,
+ * Copyright © 2004 Eric Anholt
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _GLAMO_DRAW_H_
+#define _GLAMO_DRAW_H_
+
+void GLAMOWaitIdle(GLAMOScreenInfo *glamos);
+
+#define GLAMO_TRACE_FALL 1
+#define GLAMO_TRACE_DRAW 1
+
+#if GLAMO_TRACE_FALL
+#define GLAMO_FALLBACK(x) \
+do { \
+ ErrorF("%s: ", __FUNCTION__); \
+ ErrorF x; \
+ return FALSE; \
+} while (0)
+#else
+#define GLAMO_FALLBACK(x) return FALSE
+#endif
+
+#if GLAMO_TRACE_DRAW
+#define ENTER_DRAW(pix) GLAMOEnterDraw(pix, __FUNCTION__)
+#define LEAVE_DRAW(pix) GLAMOLeaveDraw(pix, __FUNCTION__)
+
+void
+GLAMOEnterDraw (PixmapPtr pPixmap, const char *function);
+
+void
+GLAMOLeaveDraw (PixmapPtr pPixmap, const char *function);
+#else /* GLAMO_TRACE */
+#define ENTER_DRAW(pix)
+#define LEAVE_DRAW(pix)
+#endif /* !GLAMO_TRACE */
+
+#endif /* _GLAMO_DRAW_H_ */
diff --git a/src/glamo-funcs.c b/src/glamo-funcs.c
new file mode 100644
index 0000000..5114202
--- /dev/null
+++ b/src/glamo-funcs.c
@@ -0,0 +1,601 @@
+/*
+ * Copyright © 2007 OpenMoko, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * Author:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+
+#include "glamo-log.h"
+#include "glamo.h"
+#include "glamo-funcs.h"
+#include "glamo-regs.h"
+#include "glamo-cmdq.h"
+
+#define GLAMO_OUT_REG(glamo_mmio, reg, val) \
+ (*((volatile unsigned short *) ((glamo_mmio) + (reg))) = (val))
+
+#define GLAMO_IN_REG(glamo_mmio, reg) \
+ (*((volatile unsigned short *) ((glamo_mmio) + (reg))))
+
+void
+GLAMOOutReg(ScreenPtr pScreen, unsigned short reg, unsigned short val)
+{
+ KdScreenPriv(pScreen);
+ GLAMOCardInfo(pScreenPriv);
+ GLAMO_LOG("mark: pScreen:%#x, reg:%#x, val:%#x, reg_base:%#x\n",
+ pScreen, reg, val, glamoc->reg_base);
+ if (!glamoc->reg_base) {
+ GLAMO_LOG_ERROR("got null glamoc->reg_base\n");
+ return;
+ }
+ GLAMO_OUT_REG(glamoc->reg_base, reg, val);
+}
+
+unsigned short
+GLAMOInReg(ScreenPtr pScreen, unsigned short reg)
+{
+ KdScreenPriv(pScreen);
+ GLAMOCardInfo(pScreenPriv);
+ GLAMO_LOG("mark: pScreen:%#x, reg:%#x, reg_base:%#x\n",
+ pScreen, reg, glamoc->reg_base);
+ if (!glamoc->reg_base) {
+ GLAMO_LOG_ERROR("got null glamoc->reg_base\n");
+ return 0;
+ }
+ return GLAMO_IN_REG(glamoc->reg_base, reg);
+}
+
+void
+GLAMOSetBitMask(ScreenPtr pScreen, int reg, int mask, int val)
+{
+ int old;
+ old = GLAMOInReg(pScreen, reg);
+ old &= ~mask;
+ old |= val & mask;
+ GLAMO_LOG("mark\n");
+ GLAMOOutReg(pScreen, reg, old);
+}
+
+void
+setCmdMode (ScreenPtr pScreen, Bool on)
+{
+ if (on) {
+ GLAMO_LOG("mark\n");
+ /*TODO: busy waiting is bad*/
+ while (!GLAMOInReg(pScreen, GLAMO_REG_LCD_STATUS1)
+ & (1 << 15)) {
+ GLAMO_LOG("mark\n");
+ usleep(1 * 1000);
+ }
+ GLAMO_LOG("mark\n");
+ GLAMOOutReg(pScreen,
+ GLAMO_REG_LCD_COMMAND1,
+ GLAMO_LCD_CMD_TYPE_DISP |
+ GLAMO_LCD_CMD_DATA_FIRE_VSYNC);
+ GLAMO_LOG("mark\n");
+ while (!GLAMOInReg(pScreen, GLAMO_REG_LCD_STATUS2)
+ & (1 << 12)) {
+ GLAMO_LOG("mark\n");
+ usleep(1 * 1000);
+ }
+ /* wait */
+ GLAMO_LOG("mark\n");
+ usleep(100 * 1000);
+ } else {
+ GLAMO_LOG("mark\n");
+ GLAMOOutReg(pScreen,
+ GLAMO_REG_LCD_COMMAND1,
+ GLAMO_LCD_CMD_TYPE_DISP |
+ GLAMO_LCD_CMD_DATA_DISP_SYNC);
+ GLAMO_LOG("mark\n");
+ GLAMOOutReg(pScreen,
+ GLAMO_REG_LCD_COMMAND1,
+ GLAMO_LCD_CMD_TYPE_DISP |
+ GLAMO_LCD_CMD_DATA_DISP_FIRE);
+ }
+}
+
+#define STATUS_ENABLED 0x1
+static int engine_status[NB_GLAMO_ENGINES];
+
+void
+GLAMOResetEngine(ScreenPtr pScreen, enum GLAMOEngine engine)
+{
+ int reg, mask;
+
+ GLAMO_LOG("enter\n");
+
+ if (!(engine_status[engine] & STATUS_ENABLED))
+ return;
+
+ switch (engine) {
+ case GLAMO_ENGINE_MPEG:
+ reg = GLAMO_REG_CLOCK_MPEG;
+ mask = GLAMO_CLOCK_MPEG_DEC_RESET;
+ break;
+ case GLAMO_ENGINE_ISP:
+ reg = GLAMO_REG_CLOCK_ISP;
+ mask = GLAMO_CLOCK_ISP2_RESET;
+ break;
+ case GLAMO_ENGINE_CMDQ:
+ reg = GLAMO_REG_CLOCK_2D;
+ mask = GLAMO_CLOCK_2D_CMDQ_RESET;
+ break;
+ case GLAMO_ENGINE_2D:
+ reg = GLAMO_REG_CLOCK_2D;
+ mask = GLAMO_CLOCK_2D_RESET;
+ break;
+ }
+
+ GLAMOSetBitMask(pScreen, reg, mask, 0xffff);
+ usleep(1000);
+ GLAMOSetBitMask(pScreen, reg, mask, 0);
+ usleep(1000);
+
+ GLAMO_LOG("leave\n");
+}
+
+void
+GLAMOEnableEngine(ScreenPtr pScreen, enum GLAMOEngine engine)
+{
+ GLAMO_LOG("enter\n");
+ if (engine_status[engine] & STATUS_ENABLED)
+ return;
+
+ GLAMOSetBitMask(pScreen,
+ GLAMO_REG_CLOCK_GEN5_1,
+ GLAMO_CLOCK_GEN51_EN_DIV_MCLK,
+ 0xffff);
+
+ switch (engine) {
+ case GLAMO_ENGINE_MPEG:
+ GLAMOSetBitMask(pScreen,
+ GLAMO_REG_CLOCK_MPEG,
+ GLAMO_CLOCK_MPEG_EN_X6CLK |
+ GLAMO_CLOCK_MPEG_DG_X6CLK |
+ GLAMO_CLOCK_MPEG_EN_X4CLK |
+ GLAMO_CLOCK_MPEG_DG_X4CLK |
+ GLAMO_CLOCK_MPEG_EN_X2CLK |
+ GLAMO_CLOCK_MPEG_DG_X2CLK |
+ GLAMO_CLOCK_MPEG_EN_X0CLK |
+ GLAMO_CLOCK_MPEG_DG_X0CLK,
+ 0xffff & ~GLAMO_CLOCK_MPEG_DG_X0CLK);
+ GLAMOSetBitMask(pScreen,
+ GLAMO_REG_CLOCK_MPROC,
+ GLAMO_CLOCK_MPROC_EN_M4CLK,
+ 0xffff);
+ GLAMOSetBitMask(pScreen,
+ GLAMO_REG_CLOCK_GEN5_1,
+ GLAMO_CLOCK_GEN51_EN_DIV_JCLK,
+ 0xffff);
+ GLAMOSetBitMask(pScreen,
+ GLAMO_REG_HOSTBUS(2),
+ GLAMO_HOSTBUS2_MMIO_EN_MPEG |
+ GLAMO_HOSTBUS2_MMIO_EN_MICROP1,
+ 0xffff);
+ GLAMOSetBitMask(pScreen,
+ GLAMO_REG_CLOCK_MPROC,
+ GLAMO_CLOCK_MPROC_EN_KCLK,
+ 0xffff);
+ break;
+ case GLAMO_ENGINE_ISP:
+ GLAMOSetBitMask(pScreen,
+ GLAMO_REG_CLOCK_ISP,
+ GLAMO_CLOCK_ISP_EN_M2CLK |
+ GLAMO_CLOCK_ISP_EN_I1CLK,
+ 0xffff);
+ GLAMOSetBitMask(pScreen,
+ GLAMO_REG_CLOCK_GEN5_2,
+ GLAMO_CLOCK_GEN52_EN_DIV_ICLK,
+ 0xffff);
+ GLAMOSetBitMask(pScreen,
+ GLAMO_REG_CLOCK_GEN5_1,
+ GLAMO_CLOCK_GEN51_EN_DIV_JCLK,
+ 0xffff);
+ GLAMOSetBitMask(pScreen,
+ GLAMO_REG_HOSTBUS(2),
+ GLAMO_HOSTBUS2_MMIO_EN_ISP,
+ 0xffff);
+ break;
+ case GLAMO_ENGINE_CMDQ:
+ GLAMOSetBitMask(pScreen,
+ GLAMO_REG_CLOCK_2D,
+ GLAMO_CLOCK_2D_EN_M6CLK,
+ 0xffff);
+ GLAMOSetBitMask(pScreen,
+ GLAMO_REG_HOSTBUS(2),
+ GLAMO_HOSTBUS2_MMIO_EN_CMDQ,
+ 0xffff);
+ break;
+ case GLAMO_ENGINE_2D:
+ GLAMOSetBitMask(pScreen,
+ GLAMO_REG_CLOCK_2D,
+ GLAMO_CLOCK_2D_EN_M7CLK |
+ GLAMO_CLOCK_2D_EN_GCLK |
+ GLAMO_CLOCK_2D_DG_M7CLK |
+ GLAMO_CLOCK_2D_DG_GCLK,
+ 0xffff);
+ GLAMOSetBitMask(pScreen,
+ GLAMO_REG_HOSTBUS(2),
+ GLAMO_HOSTBUS2_MMIO_EN_2D,
+ 0xffff);
+ GLAMOSetBitMask(pScreen,
+ GLAMO_REG_CLOCK_GEN5_1,
+ GLAMO_CLOCK_GEN51_EN_DIV_GCLK,
+ 0xffff);
+ break;
+ }
+ usleep(1000);
+ engine_status[engine] |= STATUS_ENABLED;
+ GLAMO_LOG("leave\n");
+}
+
+
+#ifdef XV
+void
+GLAMOISPWaitEngineIdle (ScreenPtr pScreen)
+{
+ GLAMO_LOG("enter\n");
+ while (1) {
+ int val = GLAMOInReg(pScreen, GLAMO_REG_ISP_STATUS);
+ if (val & 0x1) {
+ usleep(1 * 1000);
+ GLAMO_LOG("isp busy\n");
+ continue;
+ }
+ break;
+ }
+ GLAMO_LOG("leave\n");
+}
+
+static void
+SetOnFlyLUTRegs(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ struct {
+ int src_block_x;
+ int src_block_y;
+ int src_block_w;
+ int src_block_h;
+ int jpeg_out_y;
+ int jpeg_out_x;
+ int fifo_full_cnt;
+ int in_length;
+ int fifo_data_cnt;
+ int in_height;
+ } onfly;
+ RING_LOCALS;
+
+ GLAMO_LOG("enter\n");
+
+ onfly.src_block_y = 32;
+ onfly.src_block_x = 32;
+ onfly.src_block_w = 36;
+ onfly.src_block_h = 35;
+ onfly.jpeg_out_y = 32;
+ onfly.jpeg_out_x = 32;
+ onfly.fifo_full_cnt = onfly.src_block_w * 2 + 2;
+ onfly.in_length = onfly.jpeg_out_x + 3;
+ onfly.fifo_data_cnt = onfly.src_block_w * onfly.src_block_h / 2;
+ onfly.in_height = onfly.jpeg_out_y + 2;
+
+ BEGIN_CMDQ(10);
+ OUT_REG(GLAMO_REG_ISP_ONFLY_MODE1,
+ onfly.src_block_y << 10 | onfly.src_block_x << 2);
+ OUT_REG(GLAMO_REG_ISP_ONFLY_MODE2,
+ onfly.src_block_h << 8 | onfly.src_block_w);
+ OUT_REG(GLAMO_REG_ISP_ONFLY_MODE3,
+ onfly.jpeg_out_y << 8 | onfly.jpeg_out_x);
+ OUT_REG(GLAMO_REG_ISP_ONFLY_MODE4,
+ onfly.fifo_full_cnt << 8 | onfly.in_length);
+ OUT_REG(GLAMO_REG_ISP_ONFLY_MODE5,
+ onfly.fifo_data_cnt << 6 | onfly.in_height);
+ END_CMDQ();
+ GLAMO_LOG("leave\n");
+}
+
+static void
+SetScalingWeightMatrixRegs(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ int left = 1 << 14;
+ RING_LOCALS;
+
+ GLAMO_LOG("enter\n");
+
+ /* nearest */
+
+ BEGIN_CMDQ(12);
+ OUT_BURST(GLAMO_REG_ISP_DEC_SCALEH_MATRIX, 10);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX + 0, left);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX + 2, 0);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX + 4, left);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX + 6, 0);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX + 8, left);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX + 10, 0);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX + 12, left);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX + 14, 0);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX + 16, left);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX + 18, 0);
+ END_CMDQ();
+
+ BEGIN_CMDQ(12);
+ OUT_BURST(GLAMO_REG_ISP_DEC_SCALEV_MATRIX, 10);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX + 0, left);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX + 2, 0);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX + 4, left);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX + 6, 0);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX + 8, left);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX + 10, 0);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX + 12, left);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX + 14, 0);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX + 16, left);
+ OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX + 18, 0);
+ END_CMDQ();
+ GLAMO_LOG("leave\n");
+}
+
+static void
+GLAMOISPYuvRgbPipelineInit(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ unsigned short en3;
+ RING_LOCALS;
+
+ GLAMO_LOG("enter.glamos:%#x\n", glamos);
+
+ BEGIN_CMDQ(18);
+
+ /*
+ * set the ISP into YUV 4:2:0 planar mode,
+ * enable scaling.
+ */
+ en3 = GLAMO_ISP_EN3_PLANE_MODE |
+ GLAMO_ISP_EN3_YUV_INPUT |
+ GLAMO_ISP_EN3_YUV420 |
+ GLAMO_ISP_EN3_SCALE_IMPROVE;
+
+ OUT_REG(GLAMO_REG_ISP_EN3, en3);
+
+ /*
+ * In 8.8 fixed point,
+ *
+ * R = Y + 1.402 (Cr-128)
+ * = Y + 0x0167 Cr - 0xb3
+ *
+ * G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128)
+ * = Y - 0x0058 Cb - 0x00b6 Cr + 0x89
+ *
+ * B = Y + 1.772 (Cb-128)
+ * = Y + 0x01c5 Cb - 0xe2
+ */
+
+ OUT_REG(GLAMO_REG_ISP_YUV2RGB_11, 0x0167);
+ OUT_REG(GLAMO_REG_ISP_YUV2RGB_21, 0x01c5);
+ OUT_REG(GLAMO_REG_ISP_YUV2RGB_32, 0x00b6);
+ OUT_REG(GLAMO_REG_ISP_YUV2RGB_33, 0x0058);
+ OUT_REG(GLAMO_REG_ISP_YUV2RGB_RG, 0xb3 << 8 | 0x89);
+ OUT_REG(GLAMO_REG_ISP_YUV2RGB_B, 0xe2);
+
+ OUT_REG(GLAMO_REG_ISP_PORT1_DEC_EN, GLAMO_ISP_PORT1_EN_OUTPUT);
+ OUT_REG(GLAMO_REG_ISP_PORT2_EN, GLAMO_ISP_PORT2_EN_DECODE);
+
+ END_CMDQ();
+
+ SetOnFlyLUTRegs(pScreen);
+ SetScalingWeightMatrixRegs(pScreen);
+
+ GLAMO_LOG("leave\n");
+}
+
+static void
+GLAMOISPColorKeyOverlayInit(ScreenPtr pScreen)
+{
+ GLAMO_RETURN_IF_FAIL (pScreen);
+
+ /*GLAMOSetBitMask(pScreen,
+ GLAMO_REG_ISP_EN2,
+ GLAMO_ISP_EN2_OVERLAY,
+ 0x0001);*/
+ GLAMOSetBitMask(pScreen,
+ GLAMO_REG_ISP_EN4,
+ GLAMO_ISP_EN4_OVERLAY|GLAMO_ISP_EN4_LCD_OVERLAY,
+ 0x0003);
+}
+
+void
+GLAMOISPSetColorKeyOverlay(ScreenPtr pScreen,
+ CARD32 start_addr/*addr on 23bits*/,
+ CARD16 x /*12bits*/,
+ CARD16 y /*12bits*/,
+ CARD16 width /*12bits*/,
+ CARD16 height /*12bits*/,
+ CARD16 pitch /*12bits*/,
+ CARD8 red_key /*5bits*/,
+ CARD8 green_key /*6bits*/,
+ CARD8 blue_key /*5bits*/)
+{
+ unsigned short green_red_keys = 0;
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ RING_LOCALS;
+
+ GLAMO_LOG("enter. start_addr:%#x, (x,y):(%hd,%hd), "
+ "width,height:(%dx%d), pitch:%d\n"
+ "red, green, blue:(%d, %d, %d)\n",
+ start_addr, x, y, width, height, pitch,
+ red_key, green_key, blue_key);
+
+ green_red_keys = (green_key << 8+2) & 0xff00;
+ green_red_keys |= (red_key << 3) & 0x00ff;
+
+ BEGIN_CMDQ(18);
+
+ OUT_REG(GLAMO_REG_ISP_OVERLAY_GR_KEY, green_red_keys);
+ OUT_REG(GLAMO_REG_ISP_OVERLAY_B_KEY, (blue_key << 3) && 0x00ff);
+ OUT_REG(GLAMO_REG_ISP_OVERLAY_ADDRL, start_addr & 0x00ff);
+ OUT_REG(GLAMO_REG_ISP_OVERLAY_ADDRH, start_addr & 0x7f00);
+ OUT_REG(GLAMO_REG_ISP_OVERLAY_X, x & 0x0fff);
+ OUT_REG(GLAMO_REG_ISP_OVERLAY_Y, y & 0x0fff);
+ OUT_REG(GLAMO_REG_ISP_OVERLAY_WIDTH, width & 0x0fff);
+ OUT_REG(GLAMO_REG_ISP_OVERLAY_HEIGHT, width & 0x0fff);
+ OUT_REG(GLAMO_REG_ISP_OVERLAY_PITCH, pitch & 0x0fff);
+ /*TODO: no idea what this one is*/
+ /*OUT_REG(GLAMO_REG_ISP_OVERLAY_BLOCK_XY, 0);*/
+
+ END_CMDQ();
+
+ GLAMO_LOG("leave\n");
+}
+
+void
+GLAMOISPSetColorKeyOverlay2(ScreenPtr pScreen,
+ CARD32 start_addr/*addr on 23bits*/,
+ CARD16 x /*12bits*/,
+ CARD16 y /*12bits*/,
+ CARD16 width /*12bits*/,
+ CARD16 height /*12bits*/,
+ CARD16 pitch /*12bits*/,
+ CARD16 color_key /*16bits*/)
+{
+ CARD8 red, green, blue;
+
+ /*assume color key has rgb 565 format*/
+ red = (color_key >> 11);
+ green = (color_key >> 5) & 0x003f;
+ blue = (color_key) & 0x001f;
+ GLAMOISPSetColorKeyOverlay(pScreen, start_addr, x, y,
+ width, height, pitch,
+ red, green, blue);
+}
+
+void
+GLAMOISPEngineInit (ScreenPtr pScreen)
+{
+ static Bool isp_enabled, isp_reset;
+
+ GLAMO_LOG("enter\n");
+ if (!isp_enabled) {
+ GLAMOEnableEngine(pScreen, GLAMO_ENGINE_ISP);
+ isp_enabled = TRUE;
+ GLAMO_LOG("enabled ISP\n");
+ }
+ if (!isp_reset) {
+ GLAMOResetEngine(pScreen, GLAMO_ENGINE_ISP);
+ GLAMO_LOG("reset ISP\n");
+ }
+ GLAMOISPYuvRgbPipelineInit(pScreen);
+ /*GLAMOISPColorKeyOverlayInit(pScreen);*/
+ GLAMO_LOG("leave\n");
+}
+
+void
+GLAMOISPDisplayYUVPlanarFrame (ScreenPtr pScreen,
+ unsigned int y_addr,
+ unsigned int u_addr,
+ unsigned int v_addr,
+ short y_pitch,
+ short uv_pitch,
+ short src_crop_rect_width,
+ short src_crop_rect_height,
+ unsigned int dst_addr,
+ short dst_pitch,
+ short dst_rect_width,
+ short dst_rect_height,
+ short scale_w,
+ short scale_h)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ int en3;
+ RING_LOCALS;
+
+
+ GLAMO_LOG("enter: y_addr:%#x, u_addr:%#x, v_addr:%#x\n"
+ "y_pitch:%hd, uv_pitch:%hd\n"
+ "src_crop_rect(%hdx%hd)\n"
+ "dst_addr:%#x, dst_pitch:%hd\n"
+ "dst_rect(%hdx%hd), dst_scale(%hdx%hd)\n",
+ y_addr, u_addr, v_addr,
+ y_pitch, uv_pitch,
+ src_crop_rect_width, src_crop_rect_height,
+ dst_addr, dst_pitch,
+ dst_rect_width, dst_rect_height,
+ scale_w, scale_h);
+
+
+ /*scale_w <<= 11;*/
+ /*scale_h <<= 11;*/
+
+
+ BEGIN_CMDQ(38);
+
+ /*
+ * set Y, U, V pitches.
+ */
+ OUT_REG(GLAMO_REG_ISP_DEC_PITCH_Y, y_pitch & 0x1fff);
+ OUT_REG(GLAMO_REG_ISP_DEC_PITCH_UV, uv_pitch & 0x1fff);
+ OUT_REG(GLAMO_REG_ISP_PORT1_DEC_PITCH, dst_pitch & 0x1fff);
+
+ /*
+ * set yuv starting addresses, pitches and crop rect size
+ */
+ OUT_REG(GLAMO_REG_ISP_DEC_Y_ADDRL, y_addr & 0xffff);
+ OUT_REG(GLAMO_REG_ISP_DEC_Y_ADDRH, (y_addr >> 16) & 0x7f);
+
+ OUT_REG(GLAMO_REG_ISP_DEC_U_ADDRL, u_addr & 0xffff);
+ OUT_REG(GLAMO_REG_ISP_DEC_U_ADDRH, (u_addr >> 16) & 0x7f);
+
+ OUT_REG(GLAMO_REG_ISP_DEC_V_ADDRL, v_addr & 0xffff);
+ OUT_REG(GLAMO_REG_ISP_DEC_V_ADDRH, (v_addr >> 16) & 0x7f);
+
+ OUT_REG(GLAMO_REG_ISP_DEC_HEIGHT, src_crop_rect_height & 0x1fff);
+ OUT_REG(GLAMO_REG_ISP_DEC_WIDTH, src_crop_rect_width & 0x1fff);
+
+ /*
+ * set output coordinates/sizes and scaling
+ */
+ OUT_REG(GLAMO_REG_ISP_PORT1_DEC_0_ADDRL, dst_addr & 0xffff);
+ OUT_REG(GLAMO_REG_ISP_PORT1_DEC_0_ADDRH, (dst_addr >> 16) & 0x7f);
+
+ OUT_REG(GLAMO_REG_ISP_PORT1_DEC_WIDTH, dst_rect_width & 0x1fff);
+ OUT_REG(GLAMO_REG_ISP_PORT1_DEC_HEIGHT, dst_rect_height & 0x1fff);
+
+ OUT_REG(GLAMO_REG_ISP_DEC_SCALEH, scale_w);
+ OUT_REG(GLAMO_REG_ISP_DEC_SCALEV, scale_h);
+
+ OUT_REG(GLAMO_REG_ISP_EN1, GLAMO_ISP_EN1_FIRE_ISP);
+ OUT_REG(GLAMO_REG_ISP_EN1, 0);
+
+ END_CMDQ();
+
+ GLAMOEngineWait(pScreen, GLAMO_ENGINE_ALL);
+
+
+ GLAMO_LOG("leave\n");
+
+}
+
+#endif /*XV*/
+
diff --git a/src/glamo-funcs.h b/src/glamo-funcs.h
new file mode 100644
index 0000000..f4c9a6e
--- /dev/null
+++ b/src/glamo-funcs.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2007 OpenMoko, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * Author:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+#ifndef _GLAMO_FUNCS_H_
+#define _GLAMO_FUNCS_H_
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include <assert.h>
+#include "os.h"
+#include "kdrive.h"
+
+void glamoOutReg(ScreenPtr pScreen, unsigned short reg, unsigned short val);
+
+unsigned short glamoInReg(ScreenPtr pScreen, unsigned short reg);
+
+void glamoSetBitMask(ScreenPtr pScreen, int reg, int mask, int val);
+
+void setCmdMode (ScreenPtr pScreen, Bool on);
+
+Bool glamoRotateLCD (ScreenPtr pScreen, Rotation rotation);
+
+#ifdef XV
+
+void GLAMOISPWaitEngineIdle (ScreenPtr pScreen);
+void GLAMOISPEngineInit (ScreenPtr pScreen);
+void GLAMOISPDisplayYUVPlanarFrame (ScreenPtr pScreen,
+ unsigned int y_addr,
+ unsigned int u_addr,
+ unsigned int v_addr,
+ short y_pitch,
+ short uv_pitch,
+ short src_crop_rect_width,
+ short src_crop_rect_height,
+ unsigned int dst_addr,
+ short dst_pitch,
+ short dst_rect_width,
+ short dst_rect_height,
+ short scale_w,
+ short scale_h);
+
+void GLAMOISPSetColorKeyOverlay(ScreenPtr pScreen,
+ CARD32 start_addr/*addr on 23bits*/,
+ CARD16 x /*12bits*/,
+ CARD16 y /*12bits*/,
+ CARD16 width /*12bits*/,
+ CARD16 height /*12bits*/,
+ CARD16 pitch /*12bits*/,
+ CARD8 red_key /*5bits*/,
+ CARD8 green_key /*6bits*/,
+ CARD8 blue_key /*5bits*/);
+
+void GLAMOISPSetColorKeyOverlay2(ScreenPtr pScreen,
+ CARD32 start_addr/*addr on 23bits*/,
+ CARD16 x /*12bits*/,
+ CARD16 y /*12bits*/,
+ CARD16 width /*12bits*/,
+ CARD16 height /*12bits*/,
+ CARD16 pitch /*12bits*/,
+ CARD16 color_key /*16bits*/);
+#endif /*XV*/
+
+#endif /*_GLAMO_FUNCS_H_*/
+
diff --git a/src/glamo-log.h b/src/glamo-log.h
new file mode 100644
index 0000000..abd284b
--- /dev/null
+++ b/src/glamo-log.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright © 2007 OpenMoko, Inc.
+ *
+ * This driver is based on Xati,
+ * Copyright © 2004 Eric Anholt
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * Author: Dodji Seketeli <dodji@openedhand.com>
+ */
+#ifndef _GLAMO_LOG_H_
+#define _GLAMO_LOG_H_
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include <assert.h>
+#include "os.h"
+
+#ifdef NDEBUG
+/*we are not in debug mode*/
+#define GLAMO_LOG
+#define GLAMO_LOG_ERROR
+
+#else /*NDEBUG*/
+#define ERROR_LOG_LEVEL 3
+#define INFO_LOG_LEVEL 4
+
+#ifndef GLAMO_LOG
+#define GLAMO_LOG(...) \
+LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, "in %s:%d:%s: ",\
+ __FILE__, __LINE__, __func__) ; \
+LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, __VA_ARGS__)
+#endif /*GLAMO_LOG*/
+
+#ifndef GLAMO_LOG_ERROR
+#define GLAMO_LOG_ERROR(...) \
+LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, "Error:in %s:%d:%s: ",\
+ __FILE__, __LINE__, __func__) ; \
+LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, __VA_ARGS__)
+#endif /*GLAMO_LOG_ERROR*/
+
+
+#endif /*NDEBUG*/
+
+#ifndef GLAMO_RETURN_IF_FAIL
+#define GLAMO_RETURN_IF_FAIL(cond) \
+if (!(cond)) {\
+ GLAMO_LOG_ERROR("contion failed:%s\n",#cond);\
+ return; \
+}
+#endif /*GLAMO_RETURN_IF_FAIL*/
+
+#ifndef GLAMO_RETURN_VAL_IF_FAIL
+#define GLAMO_RETURN_VAL_IF_FAIL(cond, val) \
+if (!(cond)) {\
+ GLAMO_LOG_ERROR("contion failed:%s\n",#cond);\
+ return val; \
+}
+#endif /*GLAMO_RETURN_VAL_IF_FAIL*/
+
+#endif /*_GLAMO_LOG_H_*/
+
diff --git a/src/glamo-regs.h b/src/glamo-regs.h
new file mode 100644
index 0000000..18a84d7
--- /dev/null
+++ b/src/glamo-regs.h
@@ -0,0 +1,783 @@
+#ifndef _GLAMO_REGS_H
+#define _GLAMO_REGS_H
+
+/* Smedia Glamo 336x/337x driver
+ *
+ * (C) 2007 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+enum glamo_regster_offsets {
+ GLAMO_REGOFS_GENERIC = 0x0000,
+ GLAMO_REGOFS_HOSTBUS = 0x0200,
+ GLAMO_REGOFS_MEMORY = 0x0300,
+ GLAMO_REGOFS_VIDCAP = 0x0400,
+ GLAMO_REGOFS_ISP = 0x0500,
+ GLAMO_REGOFS_JPEG = 0x0800,
+ GLAMO_REGOFS_MPEG = 0x0c00,
+ GLAMO_REGOFS_LCD = 0x1100,
+ GLAMO_REGOFS_MMC = 0x1400,
+ GLAMO_REGOFS_MPROC0 = 0x1500,
+ GLAMO_REGOFS_MPROC1 = 0x1580,
+ GLAMO_REGOFS_CMDQUEUE = 0x1600,
+ GLAMO_REGOFS_RISC = 0x1680,
+ GLAMO_REGOFS_2D = 0x1700,
+ GLAMO_REGOFS_3D = 0x1b00,
+};
+
+
+enum glamo_register_generic {
+ GLAMO_REG_GCONF1 = 0x0000,
+ GLAMO_REG_GCONF2 = 0x0002,
+#define GLAMO_REG_DEVICE_ID GLAMO_REG_GCONF2
+ GLAMO_REG_GCONF3 = 0x0004,
+#define GLAMO_REG_REVISION_ID GLAMO_REG_GCONF3
+ GLAMO_REG_IRQ_GEN1 = 0x0006,
+#define GLAMO_REG_IRQ_ENABLE GLAMO_REG_IRQ_GEN1
+ GLAMO_REG_IRQ_GEN2 = 0x0008,
+#define GLAMO_REG_IRQ_SET GLAMO_REG_IRQ_GEN2
+ GLAMO_REG_IRQ_GEN3 = 0x000a,
+#define GLAMO_REG_IRQ_CLEAR GLAMO_REG_IRQ_GEN3
+ GLAMO_REG_IRQ_GEN4 = 0x000c,
+#define GLAMO_REG_IRQ_STATUS GLAMO_REG_IRQ_GEN4
+ GLAMO_REG_CLOCK_HOST = 0x0010,
+ GLAMO_REG_CLOCK_MEMORY = 0x0012,
+ GLAMO_REG_CLOCK_LCD = 0x0014,
+ GLAMO_REG_CLOCK_MMC = 0x0016,
+ GLAMO_REG_CLOCK_ISP = 0x0018,
+ GLAMO_REG_CLOCK_JPEG = 0x001a,
+ GLAMO_REG_CLOCK_3D = 0x001c,
+ GLAMO_REG_CLOCK_2D = 0x001e,
+ GLAMO_REG_CLOCK_RISC1 = 0x0020, /* 3365 only? */
+ GLAMO_REG_CLOCK_RISC2 = 0x0022, /* 3365 only? */
+ GLAMO_REG_CLOCK_MPEG = 0x0024,
+ GLAMO_REG_CLOCK_MPROC = 0x0026,
+
+ GLAMO_REG_CLOCK_GEN5_1 = 0x0030,
+ GLAMO_REG_CLOCK_GEN5_2 = 0x0032,
+ GLAMO_REG_CLOCK_GEN6 = 0x0034,
+ GLAMO_REG_CLOCK_GEN7 = 0x0036,
+ GLAMO_REG_CLOCK_GEN8 = 0x0038,
+ GLAMO_REG_CLOCK_GEN9 = 0x003a,
+ GLAMO_REG_CLOCK_GEN10 = 0x003c,
+ GLAMO_REG_CLOCK_GEN11 = 0x003e,
+ GLAMO_REG_PLL_GEN1 = 0x0040,
+ GLAMO_REG_PLL_GEN2 = 0x0042,
+ GLAMO_REG_PLL_GEN3 = 0x0044,
+ GLAMO_REG_PLL_GEN4 = 0x0046,
+ GLAMO_REG_PLL_GEN5 = 0x0048,
+ GLAMO_REG_GPIO_GEN1 = 0x0050,
+ GLAMO_REG_GPIO_GEN2 = 0x0052,
+ GLAMO_REG_GPIO_GEN3 = 0x0054,
+ GLAMO_REG_GPIO_GEN4 = 0x0056,
+ GLAMO_REG_GPIO_GEN5 = 0x0058,
+ GLAMO_REG_GPIO_GEN6 = 0x005a,
+ GLAMO_REG_GPIO_GEN7 = 0x005c,
+ GLAMO_REG_GPIO_GEN8 = 0x005e,
+ GLAMO_REG_GPIO_GEN9 = 0x0060,
+ GLAMO_REG_GPIO_GEN10 = 0x0062,
+ GLAMO_REG_DFT_GEN1 = 0x0070,
+ GLAMO_REG_DFT_GEN2 = 0x0072,
+ GLAMO_REG_DFT_GEN3 = 0x0074,
+ GLAMO_REG_DFT_GEN4 = 0x0076,
+
+ GLAMO_REG_DFT_GEN5 = 0x01e0,
+ GLAMO_REG_DFT_GEN6 = 0x01f0,
+};
+
+#define GLAMO_REG_HOSTBUS(x) (GLAMO_REGOFS_HOSTBUS-2+(x*2))
+
+#define REG_MEM(x) (GLAMO_REGOFS_MEMORY+(x))
+#define GLAMO_REG_MEM_TIMING(x) (GLAMO_REG_MEM_TIMING1-2+(x*2))
+
+enum glamo_register_mem {
+ GLAMO_REG_MEM_TYPE = REG_MEM(0x00),
+ GLAMO_REG_MEM_GEN = REG_MEM(0x02),
+ GLAMO_REG_MEM_TIMING1 = REG_MEM(0x04),
+ GLAMO_REG_MEM_TIMING2 = REG_MEM(0x06),
+ GLAMO_REG_MEM_TIMING3 = REG_MEM(0x08),
+ GLAMO_REG_MEM_TIMING4 = REG_MEM(0x0a),
+ GLAMO_REG_MEM_TIMING5 = REG_MEM(0x0c),
+ GLAMO_REG_MEM_TIMING6 = REG_MEM(0x0e),
+ GLAMO_REG_MEM_TIMING7 = REG_MEM(0x10),
+ GLAMO_REG_MEM_TIMING8 = REG_MEM(0x12),
+ GLAMO_REG_MEM_TIMING9 = REG_MEM(0x14),
+ GLAMO_REG_MEM_TIMING10 = REG_MEM(0x16),
+ GLAMO_REG_MEM_TIMING11 = REG_MEM(0x18),
+ GLAMO_REG_MEM_POWER1 = REG_MEM(0x1a),
+ GLAMO_REG_MEM_POWER2 = REG_MEM(0x1c),
+ GLAMO_REG_MEM_LCD_BUF1 = REG_MEM(0x1e),
+ GLAMO_REG_MEM_LCD_BUF2 = REG_MEM(0x20),
+ GLAMO_REG_MEM_LCD_BUF3 = REG_MEM(0x22),
+ GLAMO_REG_MEM_LCD_BUF4 = REG_MEM(0x24),
+ GLAMO_REG_MEM_BIST1 = REG_MEM(0x26),
+ GLAMO_REG_MEM_BIST2 = REG_MEM(0x28),
+ GLAMO_REG_MEM_BIST3 = REG_MEM(0x2a),
+ GLAMO_REG_MEM_BIST4 = REG_MEM(0x2c),
+ GLAMO_REG_MEM_BIST5 = REG_MEM(0x2e),
+ GLAMO_REG_MEM_MAH1 = REG_MEM(0x30),
+ GLAMO_REG_MEM_MAH2 = REG_MEM(0x32),
+ GLAMO_REG_MEM_DRAM1 = REG_MEM(0x34),
+ GLAMO_REG_MEM_DRAM2 = REG_MEM(0x36),
+ GLAMO_REG_MEM_CRC = REG_MEM(0x38),
+};
+
+#define GLAMO_MEM_TYPE_MASK 0x03
+
+enum glamo_reg_mem_dram1 {
+ GLAMO_MEM_DRAM1_EN_SDRAM_CLK = (1 << 11),
+ GLAMO_MEM_DRAM1_SELF_REFRESH = (1 << 12),
+};
+
+enum glamo_reg_mem_dram2 {
+ GLAMO_MEM_DRAM2_DEEP_PWRDOWN = (1 << 12),
+};
+
+enum glamo_irq {
+ GLAMO_IRQ_HOSTBUS = 0x0001,
+ GLAMO_IRQ_JPEG = 0x0002,
+ GLAMO_IRQ_MPEG = 0x0004,
+ GLAMO_IRQ_MPROC1 = 0x0008,
+ GLAMO_IRQ_MPROC0 = 0x0010,
+ GLAMO_IRQ_CMDQUEUE = 0x0020,
+ GLAMO_IRQ_2D = 0x0040,
+ GLAMO_IRQ_MMC = 0x0080,
+ GLAMO_IRQ_RISC = 0x0100,
+};
+
+enum glamo_reg_clock_host {
+ GLAMO_CLOCK_HOST_DG_BCLK = 0x0001,
+ GLAMO_CLOCK_HOST_DG_M0CLK = 0x0004,
+ GLAMO_CLOCK_HOST_RESET = 0x1000,
+};
+
+enum glamo_reg_clock_mem {
+ GLAMO_CLOCK_MEM_DG_M1CLK = 0x0001,
+ GLAMO_CLOCK_MEM_EN_M1CLK = 0x0002,
+ GLAMO_CLOCK_MEM_DG_MOCACLK = 0x0004,
+ GLAMO_CLOCK_MEM_EN_MOCACLK = 0x0008,
+ GLAMO_CLOCK_MEM_RESET = 0x1000,
+ GLAMO_CLOCK_MOCA_RESET = 0x2000,
+};
+
+enum glamo_reg_clock_lcd {
+ GLAMO_CLOCK_LCD_DG_DCLK = 0x0001,
+ GLAMO_CLOCK_LCD_EN_DCLK = 0x0002,
+ GLAMO_CLOCK_LCD_DG_DMCLK = 0x0004,
+ GLAMO_CLOCK_LCD_EN_DMCLK = 0x0008,
+ //
+ GLAMO_CLOCK_LCD_EN_DHCLK = 0x0020,
+ GLAMO_CLOCK_LCD_DG_M5CLK = 0x0040,
+ GLAMO_CLOCK_LCD_EN_M5CLK = 0x0080,
+ GLAMO_CLOCK_LCD_RESET = 0x1000,
+};
+
+enum glamo_reg_clock_mmc {
+ GLAMO_CLOCK_MMC_DG_TCLK = 0x0001,
+ GLAMO_CLOCK_MMC_EN_TCLK = 0x0002,
+ GLAMO_CLOCK_MMC_DG_M9CLK = 0x0004,
+ GLAMO_CLOCK_MMC_EN_M9CLK = 0x0008,
+ GLAMO_CLOCK_MMC_RESET = 0x1000,
+};
+
+enum glamo_reg_clock_isp {
+ GLAMO_CLOCK_ISP_DG_I1CLK = 0x0001,
+ GLAMO_CLOCK_ISP_EN_I1CLK = 0x0002,
+ GLAMO_CLOCK_ISP_DG_CCLK = 0x0004,
+ GLAMO_CLOCK_ISP_EN_CCLK = 0x0008,
+ //
+ GLAMO_CLOCK_ISP_EN_SCLK = 0x0020,
+ GLAMO_CLOCK_ISP_DG_M2CLK = 0x0040,
+ GLAMO_CLOCK_ISP_EN_M2CLK = 0x0080,
+ GLAMO_CLOCK_ISP_DG_M15CLK = 0x0100,
+ GLAMO_CLOCK_ISP_EN_M15CLK = 0x0200,
+ GLAMO_CLOCK_ISP1_RESET = 0x1000,
+ GLAMO_CLOCK_ISP2_RESET = 0x2000,
+};
+
+enum glamo_reg_clock_jpeg {
+ GLAMO_CLOCK_JPEG_DG_JCLK = 0x0001,
+ GLAMO_CLOCK_JPEG_EN_JCLK = 0x0002,
+ GLAMO_CLOCK_JPEG_DG_M3CLK = 0x0004,
+ GLAMO_CLOCK_JPEG_EN_M3CLK = 0x0008,
+ GLAMO_CLOCK_JPEG_RESET = 0x1000,
+};
+
+enum glamo_reg_clock_2d {
+ GLAMO_CLOCK_2D_DG_GCLK = 0x0001,
+ GLAMO_CLOCK_2D_EN_GCLK = 0x0002,
+ GLAMO_CLOCK_2D_DG_M7CLK = 0x0004,
+ GLAMO_CLOCK_2D_EN_M7CLK = 0x0008,
+ GLAMO_CLOCK_2D_DG_M6CLK = 0x0010,
+ GLAMO_CLOCK_2D_EN_M6CLK = 0x0020,
+ GLAMO_CLOCK_2D_RESET = 0x1000,
+ GLAMO_CLOCK_2D_CMDQ_RESET = 0x2000,
+};
+
+enum glamo_reg_clock_3d {
+ GLAMO_CLOCK_3D_DG_ECLK = 0x0001,
+ GLAMO_CLOCK_3D_EN_ECLK = 0x0002,
+ GLAMO_CLOCK_3D_DG_RCLK = 0x0004,
+ GLAMO_CLOCK_3D_EN_RCLK = 0x0008,
+ GLAMO_CLOCK_3D_DG_M8CLK = 0x0010,
+ GLAMO_CLOCK_3D_EN_M8CLK = 0x0020,
+ GLAMO_CLOCK_3D_BACK_RESET = 0x1000,
+ GLAMO_CLOCK_3D_FRONT_RESET = 0x2000,
+};
+
+enum glamo_reg_clock_mpeg {
+ GLAMO_CLOCK_MPEG_DG_X0CLK = 0x0001,
+ GLAMO_CLOCK_MPEG_EN_X0CLK = 0x0002,
+ GLAMO_CLOCK_MPEG_DG_X1CLK = 0x0004,
+ GLAMO_CLOCK_MPEG_EN_X1CLK = 0x0008,
+ GLAMO_CLOCK_MPEG_DG_X2CLK = 0x0010,
+ GLAMO_CLOCK_MPEG_EN_X2CLK = 0x0020,
+ GLAMO_CLOCK_MPEG_DG_X3CLK = 0x0040,
+ GLAMO_CLOCK_MPEG_EN_X3CLK = 0x0080,
+ GLAMO_CLOCK_MPEG_DG_X4CLK = 0x0100,
+ GLAMO_CLOCK_MPEG_EN_X4CLK = 0x0200,
+ GLAMO_CLOCK_MPEG_DG_X6CLK = 0x0400,
+ GLAMO_CLOCK_MPEG_EN_X6CLK = 0x0800,
+ GLAMO_CLOCK_MPEG_ENC_RESET = 0x1000,
+ GLAMO_CLOCK_MPEG_DEC_RESET = 0x2000,
+};
+
+enum glamo_reg_clock_mproc {
+ GLAMO_CLOCK_MPROC_DG_I0CLK = 0x0001,
+ GLAMO_CLOCK_MPROC_EN_I0CLK = 0x0002,
+ GLAMO_CLOCK_MPROC_DG_X5CLK = 0x0004,
+ GLAMO_CLOCK_MPROC_EN_X5CLK = 0x0008,
+ GLAMO_CLOCK_MPROC_EN_KCLK = 0x0020,
+ GLAMO_CLOCK_MPROC_DG_M4CLK = 0x0040,
+ GLAMO_CLOCK_MPROC_EN_M4CLK = 0x0080,
+ GLAMO_CLOCK_MPROC_DG_M10CLK = 0x0100,
+ GLAMO_CLOCK_MPROC_EN_M10CLK = 0x0200,
+ GLAMO_CLOCK_MPROC_RESET = 0x1000,
+};
+
+enum glamo_reg_clock51 {
+ GLAMO_CLOCK_GEN51_EN_DIV_MCLK = 0x0001,
+ GLAMO_CLOCK_GEN51_EN_DIV_SCLK = 0x0002,
+ GLAMO_CLOCK_GEN51_EN_DIV_JCLK = 0x0004,
+ GLAMO_CLOCK_GEN51_EN_DIV_DCLK = 0x0008,
+ GLAMO_CLOCK_GEN51_EN_DIV_DMCLK = 0x0010,
+ GLAMO_CLOCK_GEN51_EN_DIV_DHCLK = 0x0020,
+ GLAMO_CLOCK_GEN51_EN_DIV_GCLK = 0x0040,
+ GLAMO_CLOCK_GEN51_EN_DIV_TCLK = 0x0080,
+ /* FIXME: higher bits */
+};
+
+enum glamo_reg_clock52 {
+ GLAMO_CLOCK_GEN52_EN_DIV_ACLK = 0x0001,
+ GLAMO_CLOCK_GEN52_EN_DIV_AMCLK = 0x0002,
+ GLAMO_CLOCK_GEN52_EN_DIV_OCLK = 0x0004,
+ GLAMO_CLOCK_GEN52_EN_DIV_ZCLK = 0x0008,
+ GLAMO_CLOCK_GEN52_EN_DIV_ICLK = 0x0010,
+ /* FIXME: higher bits */
+};
+
+enum glamo_reg_hostbus2 {
+ GLAMO_HOSTBUS2_MMIO_EN_ISP = 0x0001,
+ GLAMO_HOSTBUS2_MMIO_EN_JPEG = 0x0002,
+ GLAMO_HOSTBUS2_MMIO_EN_MPEG = 0x0004,
+ GLAMO_HOSTBUS2_MMIO_EN_LCD = 0x0008,
+ GLAMO_HOSTBUS2_MMIO_EN_MMC = 0x0010,
+ GLAMO_HOSTBUS2_MMIO_EN_MICROP0 = 0x0020,
+ GLAMO_HOSTBUS2_MMIO_EN_MICROP1 = 0x0040,
+ GLAMO_HOSTBUS2_MMIO_EN_CMDQ = 0x0080,
+ GLAMO_HOSTBUS2_MMIO_EN_RISC = 0x0100,
+ GLAMO_HOSTBUS2_MMIO_EN_2D = 0x0200,
+ GLAMO_HOSTBUS2_MMIO_EN_3D = 0x0400,
+};
+
+/* LCD Controller */
+
+#define REG_LCD(x) (GLAMO_REGOFS_LCD + (x))
+enum glamo_reg_lcd {
+ GLAMO_REG_LCD_MODE1 = REG_LCD(0x00),
+ GLAMO_REG_LCD_MODE2 = REG_LCD(0x02),
+ GLAMO_REG_LCD_MODE3 = REG_LCD(0x04),
+ GLAMO_REG_LCD_WIDTH = REG_LCD(0x06),
+ GLAMO_REG_LCD_HEIGHT = REG_LCD(0x08),
+ GLAMO_REG_LCD_POLARITY = REG_LCD(0x0a),
+ GLAMO_REG_LCD_A_BASE1 = REG_LCD(0x0c),
+ GLAMO_REG_LCD_A_BASE2 = REG_LCD(0x0e),
+ GLAMO_REG_LCD_B_BASE1 = REG_LCD(0x10),
+ GLAMO_REG_LCD_B_BASE2 = REG_LCD(0x12),
+ GLAMO_REG_LCD_C_BASE1 = REG_LCD(0x14),
+ GLAMO_REG_LCD_C_BASE2 = REG_LCD(0x16),
+ GLAMO_REG_LCD_PITCH = REG_LCD(0x18),
+ /* RES */
+ GLAMO_REG_LCD_HORIZ_TOTAL = REG_LCD(0x1c),
+ /* RES */
+ GLAMO_REG_LCD_HORIZ_RETR_START = REG_LCD(0x20),
+ /* RES */
+ GLAMO_REG_LCD_HORIZ_RETR_END = REG_LCD(0x24),
+ /* RES */
+ GLAMO_REG_LCD_HORIZ_DISP_START = REG_LCD(0x28),
+ /* RES */
+ GLAMO_REG_LCD_HORIZ_DISP_END = REG_LCD(0x2c),
+ /* RES */
+ GLAMO_REG_LCD_VERT_TOTAL = REG_LCD(0x30),
+ /* RES */
+ GLAMO_REG_LCD_VERT_RETR_START = REG_LCD(0x34),
+ /* RES */
+ GLAMO_REG_LCD_VERT_RETR_END = REG_LCD(0x38),
+ /* RES */
+ GLAMO_REG_LCD_VERT_DISP_START = REG_LCD(0x3c),
+ /* RES */
+ GLAMO_REG_LCD_VERT_DISP_END = REG_LCD(0x40),
+ /* RES */
+ GLAMO_REG_LCD_POL = REG_LCD(0x44),
+ GLAMO_REG_LCD_DATA_START = REG_LCD(0x46),
+ GLAMO_REG_LCD_FRATE_CONTRO = REG_LCD(0x48),
+ GLAMO_REG_LCD_DATA_CMD_HDR = REG_LCD(0x4a),
+ GLAMO_REG_LCD_SP_START = REG_LCD(0x4c),
+ GLAMO_REG_LCD_SP_END = REG_LCD(0x4e),
+ GLAMO_REG_LCD_CURSOR_BASE1 = REG_LCD(0x50),
+ GLAMO_REG_LCD_CURSOR_BASE2 = REG_LCD(0x52),
+ GLAMO_REG_LCD_CURSOR_PITCH = REG_LCD(0x54),
+ GLAMO_REG_LCD_CURSOR_X_SIZE = REG_LCD(0x56),
+ GLAMO_REG_LCD_CURSOR_Y_SIZE = REG_LCD(0x58),
+ GLAMO_REG_LCD_CURSOR_X_POS = REG_LCD(0x5a),
+ GLAMO_REG_LCD_CURSOR_Y_POS = REG_LCD(0x5c),
+ GLAMO_REG_LCD_CURSOR_PRESET = REG_LCD(0x5e),
+ GLAMO_REG_LCD_CURSOR_FG_COLOR = REG_LCD(0x60),
+ /* RES */
+ GLAMO_REG_LCD_CURSOR_BG_COLOR = REG_LCD(0x64),
+ /* RES */
+ GLAMO_REG_LCD_CURSOR_DST_COLOR = REG_LCD(0x68),
+ /* RES */
+ GLAMO_REG_LCD_STATUS1 = REG_LCD(0x80),
+ GLAMO_REG_LCD_STATUS2 = REG_LCD(0x82),
+ GLAMO_REG_LCD_STATUS3 = REG_LCD(0x84),
+ GLAMO_REG_LCD_STATUS4 = REG_LCD(0x86),
+ /* RES */
+ GLAMO_REG_LCD_COMMAND1 = REG_LCD(0xa0),
+ GLAMO_REG_LCD_COMMAND2 = REG_LCD(0xa2),
+ /* RES */
+ GLAMO_REG_LCD_WFORM_DELAY1 = REG_LCD(0xb0),
+ GLAMO_REG_LCD_WFORM_DELAY2 = REG_LCD(0xb2),
+ /* RES */
+ GLAMO_REG_LCD_GAMMA_CORR = REG_LCD(0x100),
+ /* RES */
+ GLAMO_REG_LCD_GAMMA_R_ENTRY01 = REG_LCD(0x110),
+ GLAMO_REG_LCD_GAMMA_R_ENTRY23 = REG_LCD(0x112),
+ GLAMO_REG_LCD_GAMMA_R_ENTRY45 = REG_LCD(0x114),
+ GLAMO_REG_LCD_GAMMA_R_ENTRY67 = REG_LCD(0x116),
+ GLAMO_REG_LCD_GAMMA_R_ENTRY8 = REG_LCD(0x118),
+ /* RES */
+ GLAMO_REG_LCD_GAMMA_G_ENTRY01 = REG_LCD(0x130),
+ GLAMO_REG_LCD_GAMMA_G_ENTRY23 = REG_LCD(0x132),
+ GLAMO_REG_LCD_GAMMA_G_ENTRY45 = REG_LCD(0x134),
+ GLAMO_REG_LCD_GAMMA_G_ENTRY67 = REG_LCD(0x136),
+ GLAMO_REG_LCD_GAMMA_G_ENTRY8 = REG_LCD(0x138),
+ /* RES */
+ GLAMO_REG_LCD_GAMMA_B_ENTRY01 = REG_LCD(0x150),
+ GLAMO_REG_LCD_GAMMA_B_ENTRY23 = REG_LCD(0x152),
+ GLAMO_REG_LCD_GAMMA_B_ENTRY45 = REG_LCD(0x154),
+ GLAMO_REG_LCD_GAMMA_B_ENTRY67 = REG_LCD(0x156),
+ GLAMO_REG_LCD_GAMMA_B_ENTRY8 = REG_LCD(0x158),
+ /* RES */
+ GLAMO_REG_LCD_SRAM_DRIVING1 = REG_LCD(0x160),
+ GLAMO_REG_LCD_SRAM_DRIVING2 = REG_LCD(0x162),
+ GLAMO_REG_LCD_SRAM_DRIVING3 = REG_LCD(0x164),
+};
+
+enum glamo_reg_lcd_mode1 {
+ GLAMO_LCD_MODE1_PWRSAVE = 0x0001,
+ GLAMO_LCD_MODE1_PARTIAL_PRT = 0x0002,
+ GLAMO_LCD_MODE1_HWFLIP = 0x0004,
+ GLAMO_LCD_MODE1_LCD2 = 0x0008,
+ /* RES */
+ GLAMO_LCD_MODE1_PARTIAL_MODE = 0x0020,
+ GLAMO_LCD_MODE1_CURSOR_DSTCOLOR = 0x0040,
+ GLAMO_LCD_MODE1_PARTIAL_ENABLE = 0x0080,
+ GLAMO_LCD_MODE1_TVCLK_IN_ENABLE = 0x0100,
+ GLAMO_LCD_MODE1_HSYNC_HIGH_ACT = 0x0200,
+ GLAMO_LCD_MODE1_VSYNC_HIGH_ACT = 0x0400,
+ GLAMO_LCD_MODE1_HSYNC_FLIP = 0x0800,
+ GLAMO_LCD_MODE1_GAMMA_COR_EN = 0x1000,
+ GLAMO_LCD_MODE1_DITHER_EN = 0x2000,
+ GLAMO_LCD_MODE1_CURSOR_EN = 0x4000,
+ GLAMO_LCD_MODE1_ROTATE_EN = 0x8000,
+};
+
+enum glamo_reg_lcd_mode2 {
+ GLAMO_LCD_MODE2_CRC_CHECK_EN = 0x0001,
+ GLAMO_LCD_MODE2_DCMD_PER_LINE = 0x0002,
+ GLAMO_LCD_MODE2_NOUSE_BDEF = 0x0004,
+ GLAMO_LCD_MODE2_OUT_POS_MODE = 0x0008,
+ GLAMO_LCD_MODE2_FRATE_CTRL_EN = 0x0010,
+ GLAMO_LCD_MODE2_SINGLE_BUFFER = 0x0020,
+ GLAMO_LCD_MODE2_SER_LSB_TO_MSB = 0x0040,
+ /* FIXME */
+};
+
+enum glamo_reg_lcd_mode3 {
+ /* LCD color source data format */
+ GLAMO_LCD_SRC_RGB565 = 0x0000,
+ GLAMO_LCD_SRC_ARGB1555 = 0x4000,
+ GLAMO_LCD_SRC_ARGB4444 = 0x8000,
+ /* interface type */
+ GLAMO_LCD_MODE3_LCD = 0x1000,
+ GLAMO_LCD_MODE3_RGB = 0x0800,
+ GLAMO_LCD_MODE3_CPU = 0x0000,
+ /* mode */
+ GLAMO_LCD_MODE3_RGB332 = 0x0000,
+ GLAMO_LCD_MODE3_RGB444 = 0x0100,
+ GLAMO_LCD_MODE3_RGB565 = 0x0200,
+ GLAMO_LCD_MODE3_RGB666 = 0x0300,
+ /* depth */
+ GLAMO_LCD_MODE3_6BITS = 0x0000,
+ GLAMO_LCD_MODE3_8BITS = 0x0010,
+ GLAMO_LCD_MODE3_9BITS = 0x0020,
+ GLAMO_LCD_MODE3_16BITS = 0x0030,
+ GLAMO_LCD_MODE3_18BITS = 0x0040,
+};
+
+enum glamo_lcd_rot_mode {
+ GLAMO_LCD_ROT_MODE_0 = 0x0000,
+ GLAMO_LCD_ROT_MODE_180 = 0x2000,
+ GLAMO_LCD_ROT_MODE_MIRROR = 0x4000,
+ GLAMO_LCD_ROT_MODE_FLIP = 0x6000,
+ GLAMO_LCD_ROT_MODE_90 = 0x8000,
+ GLAMO_LCD_ROT_MODE_270 = 0xa000,
+};
+#define GLAMO_LCD_ROT_MODE_MASK 0xe000
+
+enum glamo_lcd_cmd_type {
+ GLAMO_LCD_CMD_TYPE_DISP = 0x0000,
+ GLAMO_LCD_CMD_TYPE_PARALLEL = 0x4000,
+ GLAMO_LCD_CMD_TYPE_SERIAL = 0x8000,
+ GLAMO_LCD_CMD_TYPE_SERIAL_DIRECT= 0xc000,
+};
+#define GLAMO_LCD_CMD_TYPE_MASK 0xc000
+
+enum glamo_lcd_cmds {
+ GLAMO_LCD_CMD_DATA_DISP_FIRE = 0x00,
+ GLAMO_LCD_CMD_DATA_DISP_SYNC = 0x01, /* RGB only */
+ /* switch to command mode, no display */
+ GLAMO_LCD_CMD_DATA_FIRE_NO_DISP = 0x02,
+ /* display until VSYNC, switch to command */
+ GLAMO_LCD_CMD_DATA_FIRE_VSYNC = 0x11,
+ /* display until HSYNC, switch to command */
+ GLAMO_LCD_CMD_DATA_FIRE_HSYNC = 0x12,
+ /* display until VSYNC, 1 black frame, VSYNC, switch to command */
+ GLAMO_LCD_CMD_DATA_FIRE_VSYNC_B = 0x13,
+ /* don't care about display and switch to command */
+ GLAMO_LCD_CMD_DATA_FIRE_FREE = 0x14, /* RGB only */
+ /* don't care about display, keep data display but disable data,
+ * and switch to command */
+ GLAMO_LCD_CMD_DATA_FIRE_FREE_D = 0x15, /* RGB only */
+};
+
+enum glamo_core_revisions {
+ GLAMO_CORE_REV_A0 = 0x0000,
+ GLAMO_CORE_REV_A1 = 0x0001,
+ GLAMO_CORE_REV_A2 = 0x0002,
+ GLAMO_CORE_REV_A3 = 0x0003,
+};
+
+#define REG_ISP(x) (GLAMO_REGOFS_ISP+(x))
+
+enum glamo_register_isp {
+ GLAMO_REG_ISP_EN1 = REG_ISP(0x00),
+ GLAMO_REG_ISP_EN2 = REG_ISP(0x02),
+ GLAMO_REG_ISP_EN3 = REG_ISP(0x04),
+ GLAMO_REG_ISP_EN4 = REG_ISP(0x06),
+ GLAMO_REG_ISP_CAP_0_ADDRL = REG_ISP(0x08),
+ GLAMO_REG_ISP_CAP_0_ADDRH = REG_ISP(0x0a),
+ GLAMO_REG_ISP_CAP_1_ADDRL = REG_ISP(0x0c),
+ GLAMO_REG_ISP_CAP_1_ADDRH = REG_ISP(0x0e),
+ GLAMO_REG_ISP_DEC_Y_ADDRL = REG_ISP(0x10),
+ GLAMO_REG_ISP_DEC_Y_ADDRH = REG_ISP(0x12),
+ GLAMO_REG_ISP_DEC_U_ADDRL = REG_ISP(0x14),
+ GLAMO_REG_ISP_DEC_U_ADDRH = REG_ISP(0x16),
+ GLAMO_REG_ISP_DEC_V_ADDRL = REG_ISP(0x18),
+ GLAMO_REG_ISP_DEC_V_ADDRH = REG_ISP(0x1a),
+ GLAMO_REG_ISP_CAP_SEG_HEIGHT = REG_ISP(0x1c),
+ GLAMO_REG_ISP_CAP_PITCH = REG_ISP(0x1e),
+ GLAMO_REG_ISP_CAP_HEIGHT = REG_ISP(0x20),
+ GLAMO_REG_ISP_CAP_WIDTH = REG_ISP(0x22),
+ GLAMO_REG_ISP_DEC_PITCH_Y = REG_ISP(0x24),
+ GLAMO_REG_ISP_DEC_PITCH_UV = REG_ISP(0x26),
+ GLAMO_REG_ISP_DEC_HEIGHT = REG_ISP(0x28),
+ GLAMO_REG_ISP_DEC_WIDTH = REG_ISP(0x2a),
+ GLAMO_REG_ISP_ONFLY_MODE1 = REG_ISP(0x2c),
+ GLAMO_REG_ISP_ONFLY_MODE2 = REG_ISP(0x2e),
+ GLAMO_REG_ISP_ONFLY_MODE3 = REG_ISP(0x30),
+ GLAMO_REG_ISP_ONFLY_MODE4 = REG_ISP(0x32),
+ GLAMO_REG_ISP_ONFLY_MODE5 = REG_ISP(0x34),
+ //
+ GLAMO_REG_ISP_YUV2RGB_11 = REG_ISP(0x50),
+ GLAMO_REG_ISP_YUV2RGB_21 = REG_ISP(0x52),
+ GLAMO_REG_ISP_YUV2RGB_32 = REG_ISP(0x54),
+ GLAMO_REG_ISP_YUV2RGB_33 = REG_ISP(0x56),
+ GLAMO_REG_ISP_YUV2RGB_RG = REG_ISP(0x58),
+ GLAMO_REG_ISP_YUV2RGB_B = REG_ISP(0x5a),
+ //
+ GLAMO_REG_ISP_PORT1_SCALEH = REG_ISP(0x76),
+ GLAMO_REG_ISP_PORT1_SCALEV = REG_ISP(0x78),
+ GLAMO_REG_ISP_PORT2_SCALEH = REG_ISP(0x7a),
+ GLAMO_REG_ISP_PORT2_SCALEV = REG_ISP(0x7c),
+ GLAMO_REG_ISP_DEC_SCALEH = REG_ISP(0x7e),
+ GLAMO_REG_ISP_DEC_SCALEV = REG_ISP(0x80),
+ GLAMO_REG_ISP_TURBO = REG_ISP(0x82),
+ GLAMO_REG_ISP_PORT1_CAP_EN = REG_ISP(0x84),
+ GLAMO_REG_ISP_PORT1_CAP_0_ADDRL = REG_ISP(0x86),
+ GLAMO_REG_ISP_PORT1_CAP_0_ADDRH = REG_ISP(0x88),
+ GLAMO_REG_ISP_PORT1_CAP_1_ADDRL = REG_ISP(0x8a),
+ GLAMO_REG_ISP_PORT1_CAP_1_ADDRH = REG_ISP(0x8c),
+ GLAMO_REG_ISP_PORT1_CAP_WIDTH = REG_ISP(0x8e),
+ GLAMO_REG_ISP_PORT1_CAP_HEIGHT = REG_ISP(0x90),
+ GLAMO_REG_ISP_PORT1_CAP_PITCH = REG_ISP(0x92),
+ GLAMO_REG_ISP_PORT1_CAP_CLIP_L = REG_ISP(0x94),
+ GLAMO_REG_ISP_PORT1_CAP_CLIP_R = REG_ISP(0x96),
+ GLAMO_REG_ISP_PORT1_CAP_CLIP_T = REG_ISP(0x98),
+ GLAMO_REG_ISP_PORT1_CAP_CLIP_B = REG_ISP(0x9a),
+ GLAMO_REG_ISP_PORT1_DEC_EN = REG_ISP(0x9c),
+ GLAMO_REG_ISP_PORT1_DEC_0_ADDRL = REG_ISP(0x9e),
+ GLAMO_REG_ISP_PORT1_DEC_0_ADDRH = REG_ISP(0xa0),
+ GLAMO_REG_ISP_PORT1_DEC_1_ADDRL = REG_ISP(0xa2),
+ GLAMO_REG_ISP_PORT1_DEC_1_ADDRH = REG_ISP(0xa4),
+ GLAMO_REG_ISP_PORT1_DEC_WIDTH = REG_ISP(0xa6),
+ GLAMO_REG_ISP_PORT1_DEC_HEIGHT = REG_ISP(0xa8),
+ GLAMO_REG_ISP_PORT1_DEC_PITCH = REG_ISP(0xaa),
+ GLAMO_REG_ISP_PORT1_DEC_CLIP_L = REG_ISP(0xac),
+ GLAMO_REG_ISP_PORT1_DEC_CLIP_R = REG_ISP(0xae),
+ GLAMO_REG_ISP_PORT1_DEC_CLIP_T = REG_ISP(0xb0),
+ GLAMO_REG_ISP_PORT1_DEC_CLIP_B = REG_ISP(0xb2),
+ GLAMO_REG_ISP_PORT2_EN = REG_ISP(0xb4),
+ GLAMO_REG_ISP_PORT2_0_Y_ADDRL = REG_ISP(0xb6),
+ GLAMO_REG_ISP_PORT2_0_Y_ADDRH = REG_ISP(0xb8),
+ GLAMO_REG_ISP_PORT2_0_U_ADDRL = REG_ISP(0xba),
+ GLAMO_REG_ISP_PORT2_0_U_ADDRH = REG_ISP(0xbc),
+ GLAMO_REG_ISP_PORT2_0_V_ADDRL = REG_ISP(0xbe),
+ GLAMO_REG_ISP_PORT2_0_V_ADDRH = REG_ISP(0xc0),
+ GLAMO_REG_ISP_PORT2_1_Y_ADDRL = REG_ISP(0xc2),
+ GLAMO_REG_ISP_PORT2_1_Y_ADDRH = REG_ISP(0xc4),
+ GLAMO_REG_ISP_PORT2_1_U_ADDRL = REG_ISP(0xc6),
+ GLAMO_REG_ISP_PORT2_1_U_ADDRH = REG_ISP(0xc8),
+ GLAMO_REG_ISP_PORT2_1_V_ADDRL = REG_ISP(0xca),
+ GLAMO_REG_ISP_PORT2_1_V_ADDRH = REG_ISP(0xcc),
+ GLAMO_REG_ISP_PORT2_2_Y_ADDRL = REG_ISP(0xce),
+ GLAMO_REG_ISP_PORT2_2_Y_ADDRH = REG_ISP(0xd0),
+ GLAMO_REG_ISP_PORT2_2_U_ADDRL = REG_ISP(0xd2),
+ GLAMO_REG_ISP_PORT2_2_U_ADDRH = REG_ISP(0xd4),
+ GLAMO_REG_ISP_PORT2_2_V_ADDRL = REG_ISP(0xd6),
+ GLAMO_REG_ISP_PORT2_2_V_ADDRH = REG_ISP(0xd8),
+ GLAMO_REG_ISP_PORT2_WIDTH = REG_ISP(0xda),
+ GLAMO_REG_ISP_PORT2_HEIGHT = REG_ISP(0xdc),
+ GLAMO_REG_ISP_PORT2_Y_PITCH = REG_ISP(0xde),
+ GLAMO_REG_ISP_PORT2_UV_PITCH = REG_ISP(0xe0),
+ //
+ GLAMO_REG_ISP_OVERLAY_GR_KEY = REG_ISP(0xe2),
+ GLAMO_REG_ISP_OVERLAY_B_KEY = REG_ISP(0xe4),
+ GLAMO_REG_ISP_OVERLAY_ADDRL = REG_ISP(0xe6),
+ GLAMO_REG_ISP_OVERLAY_ADDRH = REG_ISP(0xe8),
+ GLAMO_REG_ISP_OVERLAY_X = REG_ISP(0xea),
+ GLAMO_REG_ISP_OVERLAY_Y = REG_ISP(0xec),
+ GLAMO_REG_ISP_OVERLAY_WIDTH = REG_ISP(0xee),
+ GLAMO_REG_ISP_OVERLAY_HEIGHT = REG_ISP(0xf0),
+ GLAMO_REG_ISP_OVERLAY_PITCH = REG_ISP(0xf2),
+ GLAMO_REG_ISP_OVERLAY_BLOCK_XY = REG_ISP(0xf4),
+ //
+ GLAMO_REG_ISP_RGB2YUV_11_12 = REG_ISP(0xf6),
+ GLAMO_REG_ISP_RGB2YUV_13_21 = REG_ISP(0xf8),
+ GLAMO_REG_ISP_RGB2YUV_22_23 = REG_ISP(0xfa),
+ GLAMO_REG_ISP_RGB2YUV_31_32 = REG_ISP(0xfc),
+ GLAMO_REG_ISP_RGB2YUV_33 = REG_ISP(0xfe),
+ //
+ GLAMO_REG_ISP_PORT1_SCALEH_MATRIX = REG_ISP(0x10c),
+ //
+ GLAMO_REG_ISP_PORT1_SCALEV_MATRIX = REG_ISP(0x120),
+ //
+ GLAMO_REG_ISP_PORT2_SCALEH_MATRIX = REG_ISP(0x134),
+ //
+ GLAMO_REG_ISP_PORT2_SCALEV_MATRIX = REG_ISP(0x148),
+ //
+ GLAMO_REG_ISP_DEC_SCALEH_MATRIX = REG_ISP(0x15c),
+ //
+ GLAMO_REG_ISP_DEC_SCALEV_MATRIX = REG_ISP(0x170),
+ //
+ GLAMO_REG_ISP_STATUS = REG_ISP(0x184),
+};
+
+enum glamo_isp_rot_mode {
+ GLAMO_ISP_ROT_MODE_0 = 0x0000,
+ GLAMO_ISP_ROT_MODE_90 = 0x0400,
+ GLAMO_ISP_ROT_MODE_270 = 0x0800,
+ GLAMO_ISP_ROT_MODE_180 = 0x0c00,
+ GLAMO_ISP_ROT_MODE_MIRROR = 0x1000,
+ GLAMO_ISP_ROT_MODE_FLIP = 0x1400,
+};
+#define GLAMO_ISP_ROT_MODE_MASK 0x1c00
+
+enum glamo_reg_isp_en1 {
+ GLAMO_ISP_EN1_FIRE_ISP = 0x0001,
+ GLAMO_ISP_EN1_FIRE_CAP = 0x0002,
+ GLAMO_ISP_EN1_VIDEO_CONF = 0x0004,
+ GLAMO_ISP_EN1_BAYER_SRC = 0x0008,
+ //
+ GLAMO_ISP_EN1_YUV_PACK = 0x0040,
+ GLAMO_ISP_EN1_PLANE_MODE = 0x0080,
+ GLAMO_ISP_EN1_YUV_INPUT = 0x0100,
+ GLAMO_ISP_EN1_YUV420 = 0x0200,
+ //
+};
+
+enum glamo_reg_isp_en2 {
+ GLAMO_ISP_EN2_OVERLAY = 0x0001,
+ GLAMO_ISP_EN2_LCD_OVERLAY = 0x0002,
+};
+
+enum glamo_reg_isp_en3 {
+ //
+ GLAMO_ISP_EN3_SCALE_IMPROVE = 0x0040,
+ GLAMO_ISP_EN3_PLANE_MODE = 0x0080,
+ GLAMO_ISP_EN3_YUV_INPUT = 0x0100,
+ GLAMO_ISP_EN3_YUV420 = 0x0200,
+ //
+};
+
+enum glamo_reg_isp_en4 {
+ GLAMO_ISP_EN4_OVERLAY = 0x0001,
+ GLAMO_ISP_EN4_LCD_OVERLAY = 0x0002,
+};
+
+enum glamo_reg_isp_port1_en {
+ GLAMO_ISP_PORT1_EN_OUTPUT = 0x0001,
+// GLAMO_ISP_PORT1_EN_SCALE = 0x0002,
+ GLAMO_ISP_PORT1_EN_CLIP = 0x0004,
+ GLAMO_ISP_PORT1_EN_CLIP_OUT = 0x0008,
+ GLAMO_ISP_PORT1_EN_DUAL_BUF = 0x0010,
+};
+
+enum glamo_reg_isp_port2_en {
+ GLAMO_ISP_PORT2_EN_OUTPUT = 0x0001,
+ GLAMO_ISP_PORT2_EN_SCALE = 0x0002,
+ GLAMO_ISP_PORT2_EN_JPEG = 0x0010,
+ GLAMO_ISP_PORT2_EN_MPEG = 0x0020,
+ GLAMO_ISP_PORT2_EN_ENCODE = 0x0040,
+ GLAMO_ISP_PORT2_EN_DECODE = 0x0080,
+};
+
+#define REG_MPEG(x) (GLAMO_REGOFS_MPEG+(x))
+
+enum glamo_register_mpeg {
+ //
+ GLAMO_REG_MPEG_DC_ADDRL = REG_MPEG(0x3c),
+ GLAMO_REG_MPEG_DC_ADDRH = REG_MPEG(0x3e),
+ GLAMO_REG_MPEG_AC_ADDRL = REG_MPEG(0x40),
+ GLAMO_REG_MPEG_AC_ADDRH = REG_MPEG(0x42),
+ //
+ GLAMO_REG_MPEG_SAFE_1 = REG_MPEG(0x60),
+ GLAMO_REG_MPEG_SAFE_2 = REG_MPEG(0x62),
+ GLAMO_REG_MPEG_SAFE_3 = REG_MPEG(0x64),
+ //
+ GLAMO_REG_MPEG_DEC_OUT0_Y_ADDRL = REG_MPEG(0x6e),
+ GLAMO_REG_MPEG_DEC_OUT0_Y_ADDRH = REG_MPEG(0x70),
+ GLAMO_REG_MPEG_DEC_OUT0_U_ADDRL = REG_MPEG(0x72),
+ GLAMO_REG_MPEG_DEC_OUT0_U_ADDRH = REG_MPEG(0x74),
+ GLAMO_REG_MPEG_DEC_OUT0_V_ADDRL = REG_MPEG(0x76),
+ GLAMO_REG_MPEG_DEC_OUT0_V_ADDRH = REG_MPEG(0x78),
+ GLAMO_REG_MPEG_DEC_OUT1_Y_ADDRL = REG_MPEG(0x7a),
+ GLAMO_REG_MPEG_DEC_OUT1_Y_ADDRH = REG_MPEG(0x7c),
+ GLAMO_REG_MPEG_DEC_OUT1_U_ADDRL = REG_MPEG(0x7e),
+ GLAMO_REG_MPEG_DEC_OUT1_U_ADDRH = REG_MPEG(0x80),
+ GLAMO_REG_MPEG_DEC_OUT1_V_ADDRL = REG_MPEG(0x82),
+ GLAMO_REG_MPEG_DEC_OUT1_V_ADDRH = REG_MPEG(0x84),
+ GLAMO_REG_MPEG_DEC_OUT2_Y_ADDRL = REG_MPEG(0x86),
+ GLAMO_REG_MPEG_DEC_OUT2_Y_ADDRH = REG_MPEG(0x88),
+ GLAMO_REG_MPEG_DEC_OUT2_U_ADDRL = REG_MPEG(0x8a),
+ GLAMO_REG_MPEG_DEC_OUT2_U_ADDRH = REG_MPEG(0x8c),
+ GLAMO_REG_MPEG_DEC_OUT2_V_ADDRL = REG_MPEG(0x8e),
+ GLAMO_REG_MPEG_DEC_OUT2_V_ADDRH = REG_MPEG(0x90),
+ GLAMO_REG_MPEG_DEC_WIDTH = REG_MPEG(0x92),
+ GLAMO_REG_MPEG_DEC_HEIGHT = REG_MPEG(0x94),
+ GLAMO_REG_MPEG_SPECIAL = REG_MPEG(0x96),
+ GLAMO_REG_MPEG_DEC_IN_ADDRL = REG_MPEG(0x98),
+ GLAMO_REG_MPEG_DEC_IN_ADDRH = REG_MPEG(0x9a),
+ //
+ GLAMO_REG_MPEG_DEBLK_THRESHOLD = REG_MPEG(0xc0),
+ //
+ GLAMO_REG_MPEG_DEC_STATUS = REG_MPEG(0xc8),
+ GLAMO_REG_MPEG_DEC_RB0 = REG_MPEG(0xca),
+ GLAMO_REG_MPEG_DEC_RB1 = REG_MPEG(0xcc),
+};
+
+#define REG_CMDQ(x) (GLAMO_REGOFS_CMDQUEUE+(x))
+
+enum glamo_register_cq {
+ GLAMO_REG_CMDQ_BASE_ADDRL = REG_CMDQ(0x00),
+ GLAMO_REG_CMDQ_BASE_ADDRH = REG_CMDQ(0x02),
+ GLAMO_REG_CMDQ_LEN = REG_CMDQ(0x04),
+ GLAMO_REG_CMDQ_WRITE_ADDRL = REG_CMDQ(0x06),
+ GLAMO_REG_CMDQ_WRITE_ADDRH = REG_CMDQ(0x08),
+ GLAMO_REG_CMDQ_FLIP = REG_CMDQ(0x0a),
+ GLAMO_REG_CMDQ_CONTROL = REG_CMDQ(0x0c),
+ GLAMO_REG_CMDQ_READ_ADDRL = REG_CMDQ(0x0e),
+ GLAMO_REG_CMDQ_READ_ADDRH = REG_CMDQ(0x10),
+ GLAMO_REG_CMDQ_STATUS = REG_CMDQ(0x12),
+};
+
+#define REG_2D(x) (GLAMO_REGOFS_2D+(x))
+
+enum glamo_register_2d {
+ GLAMO_REG_2D_SRC_ADDRL = REG_2D(0x00),
+ GLAMO_REG_2D_SRC_ADDRH = REG_2D(0x02),
+ GLAMO_REG_2D_SRC_PITCH = REG_2D(0x04),
+ GLAMO_REG_2D_SRC_X = REG_2D(0x06),
+ GLAMO_REG_2D_SRC_Y = REG_2D(0x08),
+ GLAMO_REG_2D_DST_X = REG_2D(0x0a),
+ GLAMO_REG_2D_DST_Y = REG_2D(0x0c),
+ GLAMO_REG_2D_DST_ADDRL = REG_2D(0x0e),
+ GLAMO_REG_2D_DST_ADDRH = REG_2D(0x10),
+ GLAMO_REG_2D_DST_PITCH = REG_2D(0x12),
+ GLAMO_REG_2D_DST_HEIGHT = REG_2D(0x14),
+ GLAMO_REG_2D_RECT_WIDTH = REG_2D(0x16),
+ GLAMO_REG_2D_RECT_HEIGHT = REG_2D(0x18),
+ GLAMO_REG_2D_PAT_ADDRL = REG_2D(0x1a),
+ GLAMO_REG_2D_PAT_ADDRH = REG_2D(0x1c),
+ GLAMO_REG_2D_PAT_FG = REG_2D(0x1e),
+ GLAMO_REG_2D_PAT_BG = REG_2D(0x20),
+ GLAMO_REG_2D_SRC_FG = REG_2D(0x22),
+ GLAMO_REG_2D_SRC_BG = REG_2D(0x24),
+ GLAMO_REG_2D_MASK1 = REG_2D(0x26),
+ GLAMO_REG_2D_MASK2 = REG_2D(0x28),
+ GLAMO_REG_2D_MASK3 = REG_2D(0x2a),
+ GLAMO_REG_2D_MASK4 = REG_2D(0x2c),
+ GLAMO_REG_2D_ROT_X = REG_2D(0x2e),
+ GLAMO_REG_2D_ROT_Y = REG_2D(0x30),
+ GLAMO_REG_2D_LEFT_CLIP = REG_2D(0x32),
+ GLAMO_REG_2D_TOP_CLIP = REG_2D(0x34),
+ GLAMO_REG_2D_RIGHT_CLIP = REG_2D(0x36),
+ GLAMO_REG_2D_BOTTOM_CLIP = REG_2D(0x38),
+ GLAMO_REG_2D_COMMAND1 = REG_2D(0x3A),
+ GLAMO_REG_2D_COMMAND2 = REG_2D(0x3C),
+ GLAMO_REG_2D_COMMAND3 = REG_2D(0x3E),
+ GLAMO_REG_2D_SAFE = REG_2D(0x40),
+ GLAMO_REG_2D_STATUS = REG_2D(0x42),
+ GLAMO_REG_2D_ID1 = REG_2D(0x44),
+ GLAMO_REG_2D_ID2 = REG_2D(0x46),
+ GLAMO_REG_2D_ID3 = REG_2D(0x48),
+};
+
+#endif /* _GLAMO_REGS_H */
diff --git a/src/glamo-stub.c b/src/glamo-stub.c
new file mode 100644
index 0000000..96c712d
--- /dev/null
+++ b/src/glamo-stub.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright © 2007 OpenMoko, Inc.
+ *
+ * This driver is based on Xati,
+ * Copyright © 2003 Eric Anholt
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "glamo.h"
+#include "klinux.h"
+
+
+extern int use_evdev;
+
+void
+InitCard(char *name)
+{
+ KdCardAttr attr;
+
+ attr.io = 0;
+ attr.address[0] = 0x8000000;
+ attr.naddr = 1;
+ KdCardInfoAdd(&GLAMOFuncs, &attr, 0);
+}
+
+void
+InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ char *verbosity_str=NULL;
+ int verbosity=0;
+ verbosity_str = getenv("VERBOSITY");
+ if (!verbosity_str) {
+ verbosity = 5;
+ } else {
+ verbosity = atoi(verbosity_str);
+ }
+ LogSetParameter(XLOG_VERBOSITY, verbosity) ;
+ LogMessage(X_INFO, "verbosity set to %d\n", verbosity);
+ KdInitOutput(pScreenInfo, argc, argv);
+}
+
+void
+InitInput(int argc, char **argv)
+{
+ if (use_evdev)
+ KdInitInput (&LinuxEvdevMouseFuncs, &LinuxEvdevKeyboardFuncs);
+ else
+ KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
+#ifdef TOUCHSCREEN
+ KdAddMouseDriver (&TsFuncs);
+#endif
+}
+
+void
+ddxUseMsg (void)
+{
+ KdUseMsg();
+}
+
+int
+ddxProcessArgument(int argc, char **argv, int i)
+{
+ int ret;
+
+ ret = KdProcessArgument(argc, argv, i);
+
+ return ret;
+}
diff --git a/src/glamo-video.c b/src/glamo-video.c
new file mode 100644
index 0000000..c2f7cd2
--- /dev/null
+++ b/src/glamo-video.c
@@ -0,0 +1,910 @@
+/*
+ * Copyright © 2007 OpenMoko, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * authors:
+ * Dodji SEKETELI <dodji@openedhand.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+
+#ifdef XV
+
+#include "glamo.h"
+#include "glamo-cmdq.h"
+#include "glamo-draw.h"
+#include "glamo-regs.h"
+#include "glamo-log.h"
+#include "kaa.h"
+
+#include <X11/extensions/Xv.h>
+#include "fourcc.h"
+
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+#define SYS_PITCH_ALIGN(w) (((w) + 3) & ~3)
+#define VID_PITCH_ALIGN(w) (((w) + 1) & ~1)
+
+#define IMAGE_MAX_WIDTH 640
+#define IMAGE_MAX_HEIGHT 640
+
+static void
+GLAMOStopVideo(KdScreenInfo *screen, pointer data, Bool exit)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ GLAMOPortPrivPtr pPortPriv = (GLAMOPortPrivPtr)data;
+
+
+ GLAMO_LOG("enter\n");
+
+
+ /*
+ for (i = 0; i < GLAMO_VIDEO_NUM_BUFS; i++)
+ if (pPortPriv->off_screen[i]) {
+ KdOffscreenFree (pScreen, pPortPriv->off_screen[i]);
+ pPortPriv->off_screen[i] = 0;
+ }
+ */
+
+
+ GLAMO_LOG("leave\n");
+
+}
+
+static int
+GLAMOSetPortAttribute(KdScreenInfo *screen, Atom attribute, int value,
+ pointer data)
+{
+ return BadMatch;
+}
+
+static int
+GLAMOGetPortAttribute(KdScreenInfo *screen, Atom attribute, int *value,
+ pointer data)
+{
+ return BadMatch;
+}
+
+static void
+GLAMOQueryBestSize(KdScreenInfo *screen,
+ Bool motion,
+ short vid_w,
+ short vid_h,
+ short drw_w,
+ short drw_h,
+ unsigned int *p_w,
+ unsigned int *p_h,
+ pointer data)
+{
+ *p_w = drw_w;
+ *p_h = drw_h;
+}
+
+static void
+GLAMOVideoSave(ScreenPtr pScreen, KdOffscreenArea *area)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ GLAMOPortPrivPtr pPortPriv = glamos->pAdaptor->pPortPrivates[0].ptr;
+ int i;
+
+ GLAMO_LOG("mark\n");
+}
+
+static Bool
+GetYUVFrameByteSize (int fourcc_code,
+ unsigned short width,
+ unsigned short height,
+ unsigned int *size)
+{
+ if (!size)
+ return FALSE;
+ switch (fourcc_code) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ *size = width*height * 3 / 2 ;
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+
+}
+
+static Bool
+GetYUVFrameAddresses (unsigned int frame_addr,
+ int fourcc_code,
+ unsigned short frame_width,
+ unsigned short frame_height,
+ unsigned short x,
+ unsigned short y,
+ unsigned int *y_addr,
+ unsigned int *u_addr,
+ unsigned int *v_addr)
+{
+ Bool is_ok = FALSE;
+
+ if (!u_addr || !v_addr) {
+ GLAMO_LOG_ERROR("failed sanity check\n");
+ goto out;
+ }
+
+
+ GLAMO_LOG("enter: frame(%dx%d), frame_addr:%#x\n"
+ "position:(%d,%d)\n",
+ frame_width, frame_height,
+ frame_addr, x, y);
+
+
+ switch (fourcc_code) {
+ case FOURCC_YV12:
+ *y_addr = frame_addr + x + y * frame_width;
+ *v_addr = frame_addr + frame_width*frame_height+
+ x/2 + (y/2) *(frame_width/2);
+ *u_addr = frame_addr + frame_width*frame_height +
+ frame_width*frame_height/4 +
+ x/2 + (y/2)*(frame_width/2);
+ is_ok = TRUE;
+ break;
+ case FOURCC_I420:
+ *y_addr = frame_addr + x + y*frame_width;
+ *u_addr = frame_addr + frame_width*frame_height+
+ x/2 + (y/2)*frame_width/2;
+ *v_addr = frame_addr + frame_width*frame_height +
+ frame_width*frame_height/4 +
+ x/2 + (y/2)*frame_height/2;
+ is_ok = TRUE;
+ break;
+ default:
+ is_ok = FALSE;
+ break;
+ }
+
+ GLAMO_LOG("y_addr:%#x, u_addr:%#x, v_addr:%#x\n",
+ *y_addr, *u_addr, *v_addr);
+
+out:
+
+ GLAMO_LOG("leave. is_ok:%d\n",
+ is_ok);
+
+ return is_ok;
+}
+
+/**
+ * copy a portion of the YUV frame "src_frame" to a destination in memory.
+ * The portion to copy is a rectangle located at (src_x,src_y),
+ * of size (rect_width,rect_height).
+ *
+ * @src_frame pointer to the start of the YUV frame to consider
+ * @frame_width width of the YUV frame
+ * @frame_height height of the YUV frame
+ * @src_x
+ * @src_y
+ * @rect_width
+ * @rect_height
+ */
+static Bool
+CopyYUVPlanarFrameRect (const char *src_frame,
+ int fourcc_code,
+ unsigned short frame_width,
+ unsigned short frame_height,
+ unsigned short src_x,
+ unsigned short src_y,
+ unsigned short rect_width,
+ unsigned short rect_height,
+ char *destination)
+{
+ char *y_copy_src, *u_copy_src, *v_copy_src,
+ *y_copy_dst, *u_copy_dst, *v_copy_dst;
+ unsigned line;
+ Bool is_ok = FALSE;
+
+
+ GLAMO_LOG("enter. src_frame:%#x, code:%#x\n"
+ "frame(%d,%d)-(%dx%d), crop(%dx%d)\n"
+ "dest:%#x",
+ (unsigned)src_frame, (unsigned)fourcc_code,
+ src_x, src_y, frame_width, frame_height,
+ rect_width, rect_height, (unsigned)destination);
+
+
+ switch (fourcc_code) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ /*planar yuv formats of the 4:2:0 family*/
+ y_copy_src = (char*) src_frame + src_x +
+ frame_width*src_y;
+ u_copy_src = (char*) src_frame +
+ frame_width*frame_height +
+ src_x/2 + (frame_width/2)*(src_y/2);
+ v_copy_src = (char*) src_frame +
+ frame_width*frame_height*5/4 + src_x/2 +
+ (frame_width/2)*src_y/2;
+ y_copy_dst = destination;
+ u_copy_dst = destination + rect_width*rect_height;
+ v_copy_dst = destination + rect_width*rect_height*5/4;
+
+ GLAMO_LOG("y_copy_src:%#x, "
+ "u_copy_src:%#x, "
+ "v_copy_src:%#x\n"
+ "y_copy_dst:%#x, "
+ "u_copy_dst:%#x, "
+ "v_copy_dst:%#x\n",
+ (unsigned)y_copy_src,
+ (unsigned)u_copy_src,
+ (unsigned)v_copy_src,
+ (unsigned)y_copy_dst,
+ (unsigned)u_copy_dst,
+ (unsigned)v_copy_dst);
+
+ for (line = 0; line < rect_height; line++) {
+
+ GLAMO_LOG("============\n"
+ "line:%d\n"
+ "============\n",
+ line);
+ GLAMO_LOG("y_copy_src:%#x, "
+ "y_copy_dst:%#x, \n",
+ (unsigned)y_copy_src,
+ (unsigned)y_copy_dst);
+
+
+ memcpy(y_copy_dst,
+ y_copy_src,
+ rect_width);
+ y_copy_src += frame_width;
+ y_copy_dst += rect_width;
+
+ /*
+ * one line out of two has chrominance (u,v)
+ * sampling.
+ */
+ if (!(line&1)) {
+
+ GLAMO_LOG("u_copy_src:%#x, "
+ "u_copy_dst:%#x\n",
+ (unsigned)u_copy_src,
+ (unsigned)u_copy_dst);
+
+ memcpy(u_copy_dst,
+ u_copy_src,
+ rect_width/2);
+
+ GLAMO_LOG("v_copy_src:%#x, "
+ "v_copy_dst:%#x\n",
+ (unsigned)v_copy_src,
+ (unsigned)v_copy_dst);
+
+ memcpy(v_copy_dst,
+ v_copy_src,
+ rect_width/2);
+ u_copy_src += frame_width/2;
+ u_copy_dst += rect_width/2;
+ v_copy_src += frame_width/2;
+ v_copy_dst += rect_width/2;
+ }
+ }
+ break;
+ default:
+ /*
+ * glamo 3362 only supports YUV 4:2:0 planar formats.
+ */
+ is_ok = FALSE;
+ goto out;
+ }
+ is_ok = TRUE;
+out:
+
+ GLAMO_LOG("leave.is_ok:%d\n", is_ok);
+
+ return is_ok;
+}
+
+static Bool
+GLAMOVideoUploadFrameToOffscreen (KdScreenInfo *screen,
+ unsigned char *yuv_frame,
+ int fourcc_code,
+ unsigned yuv_frame_width,
+ unsigned yuv_frame_height,
+ short src_x, short src_y,
+ short src_w, short src_h,
+ GLAMOPortPrivPtr portPriv,
+ unsigned int *out_offscreen_frame)
+{
+ int idx = 0;
+ unsigned size = 0;
+ Bool is_ok = FALSE;
+ ScreenPtr pScreen = screen->pScreen;
+ char *offscreen_frame = NULL;
+
+
+ GLAMO_LOG("enter. frame(%dx%d), crop(%dx%d)\n",
+ yuv_frame_width, yuv_frame_height,
+ src_w, src_h);
+
+
+ if (!GetYUVFrameByteSize (fourcc_code, src_w, src_h, &size)) {
+ GLAMO_LOG_ERROR("failed to get frame size\n");
+ goto out;
+ }
+
+ if (!portPriv->off_screen_yuv_buf
+ || size < portPriv->off_screen_yuv_buf->size) {
+ if (portPriv->off_screen_yuv_buf) {
+ KdOffscreenFree(pScreen,
+ portPriv->off_screen_yuv_buf);
+ }
+ portPriv->off_screen_yuv_buf =
+ KdOffscreenAlloc(pScreen, size, VID_PITCH_ALIGN(2),
+ TRUE, GLAMOVideoSave, portPriv);
+ if (!portPriv->off_screen_yuv_buf) {
+ GLAMO_LOG_ERROR("failed to allocate "
+ "offscreen memory\n");
+ goto out;
+ }
+
+ GLAMO_LOG("allocated %d bytes of offscreen memory\n", size);
+
+ }
+ offscreen_frame = screen->memory_base +
+ portPriv->off_screen_yuv_buf->offset;
+
+ if (out_offscreen_frame)
+ *out_offscreen_frame = portPriv->off_screen_yuv_buf->offset;
+
+ if (!CopyYUVPlanarFrameRect (yuv_frame, fourcc_code,
+ yuv_frame_width, yuv_frame_height,
+ src_x, src_y, src_w, src_h,
+ offscreen_frame)) {
+ GLAMO_LOG_ERROR("failed to copy yuv "
+ "frame to offscreen memory\n");
+ goto out;
+ }
+
+ is_ok = TRUE;
+out:
+
+
+ GLAMO_LOG("leave:%d\n", is_ok);
+
+ return is_ok;
+
+}
+
+static void
+GLAMODisplayYUVPlanarFrameRegion (ScreenPtr pScreen,
+ unsigned int yuv_frame_addr,
+ int fourcc_code,
+ short frame_width,
+ short frame_height,
+ unsigned int dst_addr,
+ short dst_pitch,
+ unsigned short scale_w,
+ unsigned short scale_h,
+ RegionPtr clipping_region,
+ BoxPtr dst_box)
+{
+ BoxPtr rect = NULL;
+ int num_rects = 0;
+ int i =0;
+ int dst_width = 0, dst_height = 0;
+ unsigned int y_addr = 0, u_addr = 0, v_addr = 0,
+ src_x, src_y, src_w, src_h, dest_addr;
+
+ GLAMO_RETURN_IF_FAIL(clipping_region && dst_box);
+
+
+ GLAMO_LOG("enter: frame addr:%#x, fourcc:%#x, \n"
+ "frame:(%dx%d), dst_addr:%#x, dst_pitch:%hd\n"
+ "scale:(%hd,%hd), dst_box(%d,%d)\n",
+ yuv_frame_addr, fourcc_code, frame_width, frame_height,
+ dst_addr, dst_pitch, scale_w, scale_h,
+ dst_box->x1, dst_box->y1);
+
+
+ GLAMO_RETURN_IF_FAIL(clipping_region);
+ rect = REGION_RECTS(clipping_region);
+ num_rects = REGION_NUM_RECTS(clipping_region);
+
+ GLAMO_LOG("num_rects to display:%d\n", num_rects);
+
+ for (i = 0; i < num_rects; i++, rect++) {
+
+ GLAMO_LOG("rect num:%d, (%d,%d,%d,%d)\n",
+ i,
+ rect->x1, rect->y1,
+ rect->x2, rect->y2);
+
+ dst_width = abs(rect->x2 - rect->x1);
+ dst_height = abs(rect->y2 - rect->y1);
+ dest_addr = dst_addr + rect->x1*2 + rect->y1*dst_pitch;
+ src_w = (dst_width * scale_w) >> 11;
+ src_h = (dst_height * scale_h) >> 11;
+ src_x = ((abs(rect->x1 - dst_box->x1) * scale_w) >> 11);
+ src_y = ((abs(rect->y1 - dst_box->y1) * scale_h) >> 11);
+
+ GLAMO_LOG("matching src rect:(%d,%d)-(%dx%d)\n",
+
+ src_x,src_y, src_w, src_h);
+
+ if (!GetYUVFrameAddresses (yuv_frame_addr,
+ fourcc_code,
+ frame_width,
+ frame_height,
+ src_x,
+ src_y,
+ &y_addr,
+ &u_addr,
+ &v_addr)) {
+ GLAMO_LOG_ERROR("failed to get yuv frame @\n");
+ continue;
+ }
+ GLAMOISPDisplayYUVPlanarFrame(pScreen,
+ y_addr,
+ u_addr,
+ v_addr,
+ frame_width,
+ frame_width/2,
+ src_w, src_h,
+ dest_addr,
+ dst_pitch,
+ dst_width, dst_height,
+ scale_w, scale_h);
+ }
+
+ GLAMO_LOG("leave\n");
+
+}
+
+static void
+GLAMODisplayFrame (KdScreenInfo *screen,
+ GLAMOPortPrivPtr portPriv)
+{
+ GLAMOVideoFrameDisplayInfo *info;
+ BoxRec dst_box;
+ unsigned int dest_w, dest_h, dest_frame_addr;
+ unsigned short scale_w, scale_h;
+ PixmapPtr dest_pixmap;
+ ScreenPtr pScreen;
+
+
+ GLAMO_LOG("enter\n");
+
+
+ GLAMO_RETURN_IF_FAIL (screen
+ && screen->pScreen
+ && portPriv);
+
+ info = &portPriv->frame_display_info;
+
+ GLAMO_RETURN_IF_FAIL (info
+ && info->dest_drawable);
+
+ if (info->dest_drawable->type == DRAWABLE_WINDOW) {
+ dest_pixmap =
+ (*screen->pScreen->GetWindowPixmap)
+ ((WindowPtr)info->dest_drawable);
+ } else {
+ dest_pixmap = (PixmapPtr)info->dest_drawable;
+ }
+ dest_frame_addr =
+ (CARD8*)dest_pixmap->devPrivate.ptr - screen->memory_base;
+
+ dest_w = abs(info->dest_box.x2 - info->dest_box.x1);
+ dest_h = abs(info->dest_box.y2 - info->dest_box.y1);
+ scale_w = (info->src_w << 11)/dest_w;
+ scale_h = (info->src_h << 11)/dest_h;
+
+ GLAMODisplayYUVPlanarFrameRegion(screen->pScreen,
+ info->offscreen_frame_addr,
+ info->id,
+ info->src_w, info->src_h,
+ dest_frame_addr,
+ dest_pixmap->devKind,
+ scale_w, scale_h,
+ &info->clipped_dest_region,
+ &info->dest_box);
+
+ GLAMO_LOG("leave\n");
+
+}
+
+static int
+GLAMOPutImage(KdScreenInfo *screen, DrawablePtr dst_drawable,
+ short src_x, short src_y,
+ short drw_x, short drw_y,
+ short src_w, short src_h,
+ short drw_w, short drw_h,
+ int id,
+ unsigned char *buf,
+ short width,
+ short height,
+ Bool sync,
+ RegionPtr clipBoxes,
+ pointer data)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ GLAMOCardInfo(pScreenPriv);
+ GLAMOPortPrivPtr portPriv = (GLAMOPortPrivPtr)data;
+ GLAMOVideoFrameDisplayInfo *info = NULL;
+ unsigned short scale_w, scale_h;
+ unsigned int offscreen_frame_addr = 0, dst_addr = 0;
+ PixmapPtr dst_pixmap;
+ RegionRec dst_reg;
+
+
+ GLAMO_LOG("enter. id:%#x, frame:(%dx%d) srccrop:(%d,%d)-(%dx%d)\n"
+ "dst geo:(%d,%d)-(%dx%d)\n",
+ id, width, height, src_x, src_y, src_w, src_h,
+ drw_x, drw_y, drw_w, drw_h);
+
+ /*
+ * upload the YUV frame to offscreen vram so that GLAMO can
+ * later have access to it and blit it from offscreen vram to
+ * onscreen vram.
+ */
+ if (!GLAMOVideoUploadFrameToOffscreen(screen, buf, id,
+ width, height,
+ src_x, src_y, src_w, src_h,
+ portPriv,
+ &offscreen_frame_addr)) {
+ GLAMO_LOG("failed to upload frame to offscreen\n");
+ return BadAlloc;
+ }
+
+ GLAMO_LOG("copied video frame to vram offset:%#x\n",
+ offscreen_frame_addr);
+ GLAMO_LOG("y_pitch:%hd, crop(%hdx%hd)\n", src_w, src_w, src_h);
+
+
+ /*
+ * Save the information necessary to display the video frame
+ * - that has been uploaded to offscreen vram - in portPriv.
+ * That way, we can later display that very same frame from
+ * within other driver calls like ReputImage.
+ */
+ info = &portPriv->frame_display_info;
+ memset(&dst_reg, 0, sizeof(dst_reg));
+
+ info->offscreen_frame_addr = offscreen_frame_addr;
+ info->id = id;
+ info->src_w = src_w;
+ info->src_h = src_h;
+ info->dest_drawable = dst_drawable;
+ info->drw_w = drw_w;
+ info->drw_h = drw_h;
+ info->dest_box.x1 = drw_x;
+ info->dest_box.y1 = drw_y;
+ info->dest_box.x2 = drw_x + drw_w;
+ info->dest_box.y2 = drw_y + drw_h;
+ REGION_INIT(pScreen, &dst_reg, &info->dest_box, 0);
+ REGION_INTERSECT(pScreen, &info->clipped_dest_region,
+ &dst_reg, clipBoxes);
+ REGION_UNINIT(pScreen, &dst_reg);
+ GLAMO_RETURN_VAL_IF_FAIL(REGION_NOTEMPTY(pScreen,
+ &info->clipped_dest_region),
+ BadImplementation);
+
+ /*
+ * Okay now that we did save all the information necessary to
+ * display the video frame in portPriv, let's display the frame.
+ */
+ GLAMODisplayFrame(screen, portPriv);
+
+
+ GLAMO_LOG("leave\n");
+
+ return Success;
+}
+
+static int
+GLAMOReputImage(KdScreenInfo *screen,
+ DrawablePtr dest_drawable,
+ short drw_x, short drw_y,
+ RegionPtr clipBoxes,
+ pointer data)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ GLAMOPortPrivPtr portPriv = (GLAMOPortPrivPtr)data;
+ RegionRec dst_reg;
+
+
+ GLAMO_LOG("enter\n");
+
+
+ GLAMO_RETURN_VAL_IF_FAIL(portPriv
+ && screen
+ && dest_drawable
+ && clipBoxes,
+ BadImplementation);
+ GLAMOVideoFrameDisplayInfo *info = &portPriv->frame_display_info;
+ memset(&dst_reg, 0, sizeof(dst_reg));
+
+ info->dest_box.x1 = drw_x;
+ info->dest_box.y1 = drw_y;
+ info->dest_box.x2 = drw_x + info->drw_w;
+ info->dest_box.y2 = drw_y + info->drw_h;
+ REGION_INIT(pScreen, &dst_reg, &info->dest_box, 0);
+ REGION_INTERSECT(pScreen, &info->clipped_dest_region,
+ &dst_reg, clipBoxes);
+ REGION_UNINIT(pScreen, &dst_reg);
+ GLAMO_RETURN_VAL_IF_FAIL(REGION_NOTEMPTY(pScreen,
+ &info->clipped_dest_region),
+ BadImplementation);
+ GLAMODisplayFrame(screen, portPriv);
+
+ GLAMO_LOG("leave\n");
+
+ return Success;
+}
+
+static int
+GLAMOQueryImageAttributes(KdScreenInfo *screen, int id, unsigned short *w,
+ unsigned short *h, int *pitches, int *offsets)
+{
+ int size, tmp;
+
+ if (*w > IMAGE_MAX_WIDTH)
+ *w = IMAGE_MAX_WIDTH;
+ if (*h > IMAGE_MAX_HEIGHT)
+ *h = IMAGE_MAX_HEIGHT;
+
+ *w = (*w + 1) & ~1;
+ if (offsets)
+ offsets[0] = 0;
+
+ switch (id)
+ {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ *h = (*h + 1) & ~1;
+
+ tmp = SYS_PITCH_ALIGN(*w);
+ size = tmp * *h;
+
+ if (pitches)
+ pitches[0] = tmp;
+ if (offsets)
+ offsets[1] = size;
+
+ tmp = SYS_PITCH_ALIGN(*w / 2);
+ size += tmp * *h / 2;
+ if (pitches)
+ pitches[1] = pitches[2] = tmp;
+ if (offsets)
+ offsets[2] = size;
+
+ size += tmp * *h / 2;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ size = *w << 1;
+ if (pitches)
+ pitches[0] = size;
+ size *= *h;
+ break;
+ }
+
+ return size;
+}
+
+
+/* client libraries expect an encoding */
+static KdVideoEncodingRec DummyEncoding[1] =
+{
+ {
+ 0,
+ "XV_IMAGE",
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ {1, 1}
+ }
+};
+
+#define NUM_FORMATS 1
+
+static KdVideoFormatRec Formats[NUM_FORMATS] =
+{
+ {16, TrueColor}
+};
+
+#define NUM_ATTRIBUTES 0
+static KdAttributeRec Attributes[NUM_ATTRIBUTES] =
+{
+};
+
+static KdImageRec Images[] =
+{
+ XVIMAGE_YV12,
+ XVIMAGE_I420,
+};
+#define NUM_IMAGES (sizeof(Images)/sizeof(Images[0]))
+
+static KdVideoAdaptorPtr
+GLAMOSetupImageVideo(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ KdVideoAdaptorPtr adapt;
+ GLAMOPortPrivPtr portPriv;
+ int i;
+
+ GLAMO_LOG("enter\n");
+ glamos->num_texture_ports = 1;
+
+ adapt = xcalloc(1, sizeof(KdVideoAdaptorRec) +
+ glamos->num_texture_ports *
+ (sizeof(GLAMOPortPrivRec) + sizeof(DevUnion)));
+ if (adapt == NULL)
+ return NULL;
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = VIDEO_CLIP_TO_VIEWPORT;
+ adapt->name = "GLAMO Texture Video";
+ adapt->nEncodings = 1;
+ adapt->pEncodings = DummyEncoding;
+ adapt->nFormats = NUM_FORMATS;
+ adapt->pFormats = Formats;
+ adapt->nPorts = glamos->num_texture_ports;
+ adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
+
+ portPriv = (GLAMOPortPrivPtr)
+ (&adapt->pPortPrivates[glamos->num_texture_ports]);
+
+ for (i = 0; i < glamos->num_texture_ports; i++)
+ adapt->pPortPrivates[i].ptr = &portPriv[i];
+
+ adapt->nAttributes = NUM_ATTRIBUTES;
+ adapt->pAttributes = Attributes;
+ adapt->pImages = Images;
+ adapt->nImages = NUM_IMAGES;
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = GLAMOStopVideo;
+ adapt->SetPortAttribute = GLAMOSetPortAttribute;
+ adapt->GetPortAttribute = GLAMOGetPortAttribute;
+ adapt->QueryBestSize = GLAMOQueryBestSize;
+ adapt->PutImage = GLAMOPutImage;
+ adapt->ReputImage = GLAMOReputImage;
+ adapt->QueryImageAttributes = GLAMOQueryImageAttributes;
+
+ for (i = 0; i < glamos->num_texture_ports; i++) {
+ REGION_INIT(pScreen, &portPriv[i].clip, NullBox, 0);
+ portPriv[i].color_key = 0xffff;
+ }
+
+ glamos->pAdaptor = adapt;
+
+ GLAMO_LOG("leave. adaptor:%#x\n", (unsigned)adapt);
+
+ return adapt;
+}
+
+Bool
+GLAMOInitVideo(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ GLAMOCardInfo(pScreenPriv);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ KdVideoAdaptorPtr *oldAdaptors = NULL, *newAdaptors = NULL;
+ KdVideoAdaptorPtr newAdaptor = NULL;
+ int num_adaptors;
+ Bool is_ok = FALSE;
+
+ GLAMO_LOG("enter\n");
+
+ glamos->pAdaptor = NULL;
+
+ if (glamoc->reg_base == NULL) {
+ GLAMO_LOG("glamoc->reg_base is null\n");
+ goto out;
+ }
+
+ num_adaptors = KdXVListGenericAdaptors(screen, &oldAdaptors);
+
+ newAdaptor = GLAMOSetupImageVideo(pScreen);
+
+ if (newAdaptor) {
+ if (!num_adaptors) {
+ num_adaptors = 1;
+ newAdaptors = &newAdaptor;
+ } else {
+ newAdaptors = xalloc((num_adaptors + 1) *
+ sizeof(KdVideoAdaptorPtr *));
+ if (!newAdaptors)
+ goto out;
+
+ memcpy(newAdaptors,
+ oldAdaptors,
+ num_adaptors * sizeof(KdVideoAdaptorPtr));
+ newAdaptors[num_adaptors] = newAdaptor;
+ num_adaptors++;
+ }
+ }
+
+ GLAMOCMDQCacheSetup(pScreen);
+ GLAMOISPEngineInit(pScreen);
+
+ if (num_adaptors)
+ KdXVScreenInit(pScreen, newAdaptors, num_adaptors);
+
+ is_ok = TRUE;
+out:
+ GLAMO_LOG("leave. is_ok:%d, adaptors:%d\n",
+ is_ok, num_adaptors);
+ /*
+ if (newAdaptors) {
+ xfree(newAdaptors);
+ }
+ */
+ return is_ok;
+}
+
+void
+GLAMOFiniVideo(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ GLAMOScreenInfo(pScreenPriv);
+ KdVideoAdaptorPtr adapt = glamos->pAdaptor;
+ GLAMOPortPrivPtr portPriv;
+ int i;
+
+ GLAMO_LOG ("enter\n");
+
+ if (!adapt)
+ return;
+
+ for (i = 0; i < glamos->num_texture_ports; i++) {
+ portPriv = (GLAMOPortPrivPtr)(adapt->pPortPrivates[i].ptr);
+ GLAMO_LOG("freeing clipping region...\n");
+ REGION_UNINIT(pScreen, &portPriv->clip);
+ GLAMO_LOG("freed clipping region\n");
+ if (portPriv->off_screen_yuv_buf) {
+ GLAMO_LOG("freeing offscreen yuv buf...\n");
+ KdOffscreenFree(pScreen,
+ portPriv->off_screen_yuv_buf);
+ portPriv->off_screen_yuv_buf = NULL;
+ GLAMO_LOG("freeed offscreen yuv buf\n");
+ }
+ REGION_UNINIT
+ (pScreen,
+ &portPriv->frame_display_info.clipped_dest_region);
+ }
+ xfree(adapt);
+ glamos->pAdaptor = NULL;
+ GLAMO_LOG ("leave\n");
+}
+
+void
+GLAMOVideoTeardown(ScreenPtr pScreen)
+{
+ GLAMOEngineReset(pScreen, GLAMO_ENGINE_ISP);
+ GLAMOEngineDisable(pScreen, GLAMO_ENGINE_ISP);
+}
+
+#endif /*XV*/