From ddb4e5d5dbf924d484ec088dc6f49d28496463b1 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 15 Dec 2008 14:27:45 +0000 Subject: src/glamo* : drag in the kdrive EXA sources, initial commit will need heavy editing. --- src/glamo-cmdq.c | 496 +++++++++++++++++++++++++++++ src/glamo-cmdq.h | 160 ++++++++++ src/glamo-draw.c | 925 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/glamo-draw.h | 59 ++++ src/glamo-funcs.c | 601 +++++++++++++++++++++++++++++++++++ src/glamo-funcs.h | 87 +++++ src/glamo-log.h | 80 +++++ src/glamo-regs.h | 783 +++++++++++++++++++++++++++++++++++++++++++++ src/glamo-stub.c | 88 ++++++ src/glamo-video.c | 910 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 4189 insertions(+) create mode 100644 src/glamo-cmdq.c create mode 100644 src/glamo-cmdq.h create mode 100644 src/glamo-draw.c create mode 100644 src/glamo-draw.h create mode 100644 src/glamo-funcs.c create mode 100644 src/glamo-funcs.h create mode 100644 src/glamo-log.h create mode 100644 src/glamo-regs.h create mode 100644 src/glamo-stub.c create mode 100644 src/glamo-video.c (limited to 'src') 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 + +#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 +#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); + } +} + +/*************************************** + * + ***************************************/ +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"); +} + +/********************** + * + **********************/ 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 + */ + +#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 + */ +#ifndef _GLAMO_FUNCS_H_ +#define _GLAMO_FUNCS_H_ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#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 + */ +#ifndef _GLAMO_LOG_H_ +#define _GLAMO_LOG_H_ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#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 + * 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 +#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 + */ + +#ifdef HAVE_CONFIG_H +#include +#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 +#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*/ -- cgit v1.2.3