diff options
Diffstat (limited to 'xorg-server/hw/kdrive/epson/epson13806draw.c')
-rw-r--r-- | xorg-server/hw/kdrive/epson/epson13806draw.c | 649 |
1 files changed, 649 insertions, 0 deletions
diff --git a/xorg-server/hw/kdrive/epson/epson13806draw.c b/xorg-server/hw/kdrive/epson/epson13806draw.c new file mode 100644 index 000000000..3222353a3 --- /dev/null +++ b/xorg-server/hw/kdrive/epson/epson13806draw.c @@ -0,0 +1,649 @@ +/* + * Copyright 2004 by Costas Stylianou <costas.stylianou@psion.com> +44(0)7850 394095 + * + * 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 Costas Sylianou not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Costas Stylianou makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * COSTAS STYLIANOU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL COSTAS STYLIANOU 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. + */ +/* + * epson13806draw.c - Implementation of hardware accelerated functions for epson S1D13806 + * Graphic controller. + * + * History: + * 28-Jan-04 C.Stylianou PRJ NBL: Created from chipsdraw.c + * + */ + +#include "epson13806.h" +#include "epson13806draw.h" +#include "epson13806reg.h" + +#include "kaa.h" + +#include "gcstruct.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "mistruct.h" +#include "dixfontstr.h" +#include "fb.h" +#include "migc.h" +#include "miline.h" + + +// Functionality of BitBLT ROP register for Epson S1D13806 Graphics controller +CARD8 epson13806Rop[16] = { + /* GXclear */ 0x00, /* 0 */ + /* GXand */ 0x08, /* src AND dst */ + /* GXandReverse */ 0x04, /* src AND NOT dst */ + /* GXcopy */ 0x0C, /* src */ + /* GXandInverted*/ 0x02, /* NOT src AND dst */ + /* GXnoop */ 0x0A, /* dst */ + /* GXxor */ 0x06, /* src XOR dst */ + /* GXor */ 0x0E, /* src OR dst */ + /* GXnor */ 0x01, /* NOT src AND NOT dst */ + /* GXequiv */ 0x09, /* NOT src XOR dst */ + /* GXinvert */ 0x05, /* NOT dst */ + /* GXorReverse */ 0x0D, /* src OR NOT dst */ + /* GXcopyInverted*/ 0x03, /* NOT src */ + /* GXorInverted */ 0x0B, /* NOT src OR dst */ + /* GXnand */ 0x07, /* NOT src OR NOT dst */ + /* GXset */ 0x0F, /* 1 */ +}; + + + +#undef __DEBUG_EPSON__ +#undef __DEBUG_EPSON_FBSET__ +#undef __DEBUG_EPSON_SOLID__ +#undef __DEBUG_EPSON_COPY__ + + +#ifdef __DEBUG_EPSON__ + #define EPSON_DEBUG(a) a +#else + #define EPSON_DEBUG(a) +#endif + +#ifdef __DEBUG_EPSON_FBSET__ + #define EPSON_DEBUG_FBSET(a) a +#else + #define EPSON_DEBUG_FBSET(a) +#endif + +#ifdef __DEBUG_EPSON_SOLID__ + #define EPSON_DEBUG_SOLID(a) a +#else + #define EPSON_DEBUG_SOLID(a) +#endif + +#ifdef __DEBUG_EPSON_COPY__ + #define EPSON_DEBUG_COPY(a) a +#else + #define EPSON_DEBUG_COPY(a) +#endif + + +static unsigned int byteStride; // Distance between lines in the frame buffer (in bytes) +static unsigned int bytesPerPixel; +static unsigned int pixelStride; + +static unsigned char *regbase; + +/* + * epsonSet + * + * Description: Sets Epson variables + * + * History: + * 11-Feb-04 C.Stylianou NBL: Created. + * + */ + +static void +epsonSet (ScreenPtr pScreen) +{ + EPSON_DEBUG_FBSET (fprintf(stderr,"+epsonSet\n")); + + KdScreenPriv(pScreen); + + byteStride = pScreenPriv->screen->fb[0].byteStride; + bytesPerPixel = pScreenPriv->screen->fb[0].bitsPerPixel >> 3; + pixelStride = pScreenPriv->screen->fb[0].pixelStride; + + EPSON_DEBUG_FBSET (fprintf(stderr,"byteStride: [%x]\n", pScreenPriv->screen->fb[0].byteStride)); + EPSON_DEBUG_FBSET (fprintf(stderr,"bytesPerPixel: [%x]\n", pScreenPriv->screen->fb[0].bitsPerPixel >> 3)); + EPSON_DEBUG_FBSET (fprintf(stderr,"pixelStride: [%x]\n", pScreenPriv->screen->fb[0].pixelStride)); + + EPSON_DEBUG_FBSET (fprintf(stderr,"-epsonSet\n")); +} + + +/* + * epsonBg + * + * Description: Sets background colour + * + * History: + * 11-Feb-04 C.Stylianou NBL: Created. + * + */ + +static void +epsonBg (Pixel bg) +{ + EPSON13806_REG16(EPSON13806_BLTBGCOLOR) = bg; +} + + +/* + * epsonFg + * + * Description: Sets foreground colour + * + * History: + * 11-Feb-04 C.Stylianou NBL: Created. + * + */ + +static void +epsonFg (Pixel fg) +{ + EPSON13806_REG16(EPSON13806_BLTFGCOLOR) = fg; +} + + +/* + * epsonWaitForHwBltDone + * + * Description: Wait for previous blt to be done before programming any blt registers + * + * History: + * 11-Feb-04 C.Stylianou NBL: Created. + * + */ + +static void +epsonWaitForHwBltDone (void) +{ + while (EPSON13806_REG (EPSON13806_BLTCTRL0) & EPSON13806_BLTCTRL0_ACTIVE) {} +} + + +/* + * epsonDrawSync + * + * Description: Sync hardware acceleration + * + * History: + * 11-Feb-04 C.Stylianou NBL: Created. + * + */ + +static void +epsonWaitMarker (ScreenPtr pScreen, int marker) +{ + EPSON_DEBUG (fprintf(stderr,"+epsonDrawSync\n")); + + epsonWaitForHwBltDone (); + + EPSON_DEBUG (fprintf(stderr,"-epsonDrawSync\n")); +} + + +/* + * epsonPrepareSolid + * + * Description: Prepare Solid Fill i.e, can it be accelerated + * + * History: + * 11-Feb-04 C.Stylianou NBL: Created. + * + */ + +static Bool +epsonPrepareSolid (PixmapPtr pPixmap, + int alu, + Pixel pm, + Pixel fg) +{ + EPSON_DEBUG_SOLID (fprintf(stderr,"+epsonPrepareSolid\n")); + + FbBits depthMask; + + depthMask = FbFullMask(pPixmap->drawable.depth); + if ((pm & depthMask) != depthMask) + return FALSE; + + epsonSet (pPixmap->drawable.pScreen); + fg &= 0xffff; + epsonFg (fg); + epsonBg (fg); + + epsonWaitForHwBltDone (); + + EPSON_DEBUG_SOLID (fprintf(stderr,"Solid.alu [0x%x], [%d]\n", alu ,epson13806Rop[alu])); + EPSON13806_REG(EPSON13806_BLTROP) = epson13806Rop[alu]; + + if (epson13806Rop[alu] == GXnoop) + { + EPSON13806_REG(EPSON13806_BLTOPERATION) = EPSON13806_BLTOPERATION_PATFILLROP; + } + else + { + EPSON13806_REG(EPSON13806_BLTOPERATION) = EPSON13806_BLTOPERATION_SOLIDFILL; + } + + + EPSON_DEBUG_SOLID (fprintf(stderr,"-epsonPrepareSolid\n")); + return TRUE; + +} + + +/* + * epsonSolid + * + * Description: Executes Solid Fill + * + * History: + * 11-Feb-04 C.Stylianou NBL: Created. + * + */ + +static void +epsonSolid (int x1, int y1, int x2, int y2) +{ + + EPSON_DEBUG_SOLID (fprintf(stderr,"+epsonSolid\n")); + + CARD32 dst_addr; + int width, height; + + EPSON_DEBUG_SOLID (fprintf(stderr,"Solid X1 [%d] Y1 [%d] X2 [%d] Y2 [%d]\n", x1, y1, x2, y2)); + + dst_addr = y1 * byteStride + x1 * bytesPerPixel; + width = ((x2 - x1)-1); + height = ((y2 - y1)-1); + + // program dst address + EPSON13806_REG16(EPSON13806_BLTDSTSTART01) = dst_addr; + EPSON13806_REG(EPSON13806_BLTDSTSTART2) = dst_addr >> 16; + + // program width and height of blit + EPSON13806_REG16(EPSON13806_BLTWIDTH) = width; + EPSON13806_REG16(EPSON13806_BLTHEIGHT) = height; + + EPSON13806_REG(EPSON13806_BLTCTRL0) = EPSON13806_BLTCTRL0_ACTIVE; + + // Wait for operation to complete + while (EPSON13806_REG(EPSON13806_BLTCTRL0) & EPSON13806_BLTCTRL0_ACTIVE) {} + + EPSON_DEBUG_SOLID (fprintf(stderr,"-epsonSolid\n")); +} + + +/* + * epsonDoneSolid + * + * Description: Done Solid + * + * History: + * 11-Feb-04 C.Stylianou NBL: Created. + * + */ + +static void +epsonDoneSolid (void) +{ + EPSON_DEBUG_SOLID (fprintf(stderr,"+epsonDoneSolid\n")); + + // Read from BitBLT data offset 0 to shut it down + //(void)EPSON13806_REG(EPSON13806_BITBLTDATA); + + EPSON_DEBUG_SOLID (fprintf(stderr,"-epsonDoneSolid\n")); + +} + + +/* + * epsonPrepareCopy + * + * Description: Prepares BitBLT, i.e, can it be accelerated + * + * History: + * 11-Feb-04 C.Stylianou NBL: Created. + * + */ + +static Bool +epsonPrepareCopy (PixmapPtr pSrcPixmap, + PixmapPtr pDstPixmap, + int dx, + int dy, + int alu, + Pixel pm) +{ + EPSON_DEBUG_COPY (fprintf(stderr,"+epsonPrepareCopy dx [0x%x] dy [0x%x]\n", dx, dy)); + + FbBits depthMask; + + depthMask = FbFullMask(pDstPixmap->drawable.depth); + + if ((pm & depthMask) != depthMask) + return FALSE; + + epsonSet (pDstPixmap->drawable.pScreen); + epsonWaitForHwBltDone (); + EPSON13806_REG(EPSON13806_BLTROP) = epson13806Rop[alu]; + + EPSON_DEBUG_COPY (fprintf(stderr,"-epsonPrepareCopy\n")); + + return TRUE; +} + + +/* + * epsonCopy + * + * Description: Executes BitBLT + * + * History: + * 11-Feb-04 C.Stylianou NBL: Created. + * + */ + +static void +epsonCopy (int srcX, + int srcY, + int dstX, + int dstY, + int width, + int height) +{ + EPSON_DEBUG_COPY (fprintf(stderr,"+epsonCopy\n")); + int src_addr, dst_addr; + int neg_dir = FALSE; + + if (!width || !height) + return; + + src_addr = srcX * bytesPerPixel + srcY * byteStride; + dst_addr = dstX * bytesPerPixel + dstY * byteStride; + + /* + * See if regions overlap and dest region is beyond source region. + * If so, we need to do a move BLT in negative direction. Only applies + * if the BLT is not transparent. + */ + + if ((srcX + width > dstX) && (srcX < dstX + width) && + (srcY + height > dstY) && (srcY < dstY + height) && + (dst_addr > src_addr)) + { + neg_dir = TRUE; + + // negative direction : get the coords of lower right corner + src_addr += byteStride * (height-1) + bytesPerPixel * (width-1); + dst_addr += byteStride * (height-1) + bytesPerPixel * (width-1); + } + + // program BLIT memory offset + EPSON13806_REG16(EPSON13806_BLTSTRIDE) = byteStride/2; + + // program src and dst addresses + EPSON13806_REG16(EPSON13806_BLTSRCSTART01) = src_addr; + EPSON13806_REG(EPSON13806_BLTSRCSTART2) = src_addr >> 16; + EPSON13806_REG16(EPSON13806_BLTDSTSTART01) = dst_addr; + EPSON13806_REG(EPSON13806_BLTDSTSTART2) = dst_addr >> 16; + + // program width and height of blit + EPSON13806_REG16(EPSON13806_BLTWIDTH) = width-1; + EPSON13806_REG16(EPSON13806_BLTHEIGHT) = height-1; + + // select pos/neg move BLIT + EPSON13806_REG(EPSON13806_BLTOPERATION) = neg_dir ? + EPSON13806_BLTOPERATION_MOVENEGROP : EPSON13806_BLTOPERATION_MOVEPOSROP; + + EPSON13806_REG(EPSON13806_BLTCTRL0) = EPSON13806_BLTCTRL0_ACTIVE; + + // Wait for operation to complete + while (EPSON13806_REG(EPSON13806_BLTCTRL0) & EPSON13806_BLTCTRL0_ACTIVE) {} + + EPSON_DEBUG_COPY (fprintf(stderr,"-epsonCopy\n")); +} + + +/* + * epsonDoneCopy + * + * Description: Done Copy + * + * History: + * 11-Feb-04 C.Stylianou NBL: Created. + * + */ + +static void +epsonDoneCopy (void) +{ + EPSON_DEBUG_COPY (fprintf(stderr,"+epsonDoneCopy\n")); + + // Read from BitBLT data offset 0 to shut it down + //(void)EPSON13806_REG(EPSON13806_BITBLTDATA); + + EPSON_DEBUG_COPY (fprintf(stderr,"-epsonDoneCopy\n")); +} + + +/* + * epsonDrawInit + * + * Description: Configure the Epson S1D13806 for a 800x600 TFT colour display + * + * History: + * 11-Feb-04 C.Stylianou NBL: Created. + * + */ + +Bool +epsonDrawInit (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + EpsonScrPriv *epsons = screen->driver; + + EPSON_DEBUG (fprintf(stderr,"+epsonDrawInit\n")); + + epsonSet(pScreen); + +#if 0 + EPSON13806_REG(EPSON13806_MISC) = 0x00; + EPSON13806_REG(EPSON13806_DISPMODE) = 0x00; + EPSON13806_REG16(EPSON13806_GPIOCFG) = 0xffff; + EPSON13806_REG16(EPSON13806_GPIOCTRL) = 0x0001; + + EPSON13806_REG(EPSON13806_MEMCLKCFG) = 0x01; + EPSON13806_REG(EPSON13806_LCDPCLKCFG) = 0x00; + EPSON13806_REG(EPSON13806_CRTPCLKCFG) = 0x02; + EPSON13806_REG(EPSON13806_MPCLKCFG) = 0x02; + EPSON13806_REG(EPSON13806_CPUMEMWAITSEL) = 0x01; + EPSON13806_REG(EPSON13806_MEMCFG) = 0x80; + EPSON13806_REG(EPSON13806_DRAMREFRESH) = 0x03; + EPSON13806_REG16(EPSON13806_DRAMTIMINGCTRL) = 0x0100; + + // 5ms delay for internal LCD SDRAM to initialize + usleep(5000); + + EPSON13806_REG(EPSON13806_PANELTYPE) = 0x25; + EPSON13806_REG(EPSON13806_MODRATE) = 0x00; + EPSON13806_REG(EPSON13806_LCDHDP) = 0x63; + EPSON13806_REG(EPSON13806_LCDHNDP) = 0x1f; + EPSON13806_REG(EPSON13806_TFTFPLINESTART) = 0x01; + EPSON13806_REG(EPSON13806_TFTFPLINEPULSE) = 0x0b; + EPSON13806_REG16(EPSON13806_LCDVDP0) = 0x0257; + EPSON13806_REG(EPSON13806_LCDVNDP) = 0x1b; + EPSON13806_REG(EPSON13806_TFTFPFRAMESTART) = 0x0a; + EPSON13806_REG(EPSON13806_TFTFPFRAMEPULSE) = 0x01; + EPSON13806_REG(EPSON13806_LCDDISPMODE) = 0x85; + EPSON13806_REG(EPSON13806_LCDMISC) = 0x00; + EPSON13806_REG16(EPSON13806_LCDSTART01) = 0x0000; + EPSON13806_REG(EPSON13806_LCDSTART2) = 0x00; + EPSON13806_REG16(EPSON13806_LCDSTRIDE) = byteStride>>1; + EPSON13806_REG(EPSON13806_LCDPIXELPAN) = 0x00; + EPSON13806_REG(EPSON13806_LCDFIFOHIGH) = 0x00; + EPSON13806_REG(EPSON13806_LCDFIFOLOW) = 0x00; +#endif + + + EPSON13806_REG(EPSON13806_BLTCTRL0) = 0x00; + EPSON13806_REG(EPSON13806_BLTCTRL1) = 0x01; // We're using 16 bpp + EPSON13806_REG16(EPSON13806_BLTSTRIDE) = byteStride>>1; // program BLIT memory offset + +#if 0 + EPSON13806_REG(EPSON13806_LUTMODE) = 0x00; + EPSON13806_REG(EPSON13806_LUTADDR) = 0x00; + EPSON13806_REG(EPSON13806_PWRSAVECFG) = 0x10; + EPSON13806_REG(EPSON13806_PWRSAVESTATUS) = 0x00; + EPSON13806_REG(EPSON13806_CPUMEMWATCHDOG) = 0x00; + EPSON13806_REG(EPSON13806_DISPMODE) = 0x01; + + // Enable backlight voltage + EPSON13806_REG16(EPSON13806_GPIOCTRL) |= 1<<1; + // 10ms delay after turning on LCD. + usleep(10000); +#endif + + // Instruct the BitBLT unit to fill the screen with black, i.e clear fb. + static int addr = 0x00000000; + EPSON13806_REG16(EPSON13806_BLTDSTSTART01) = addr; + EPSON13806_REG(EPSON13806_BLTDSTSTART2) = addr >> 16; + EPSON13806_REG16(EPSON13806_BLTFGCOLOR) = 0x0000; + EPSON13806_REG(EPSON13806_BLTOPERATION) = EPSON13806_BLTOPERATION_SOLIDFILL; // solid fill blt + EPSON13806_REG16(EPSON13806_BLTWIDTH) = (0x0320-1); + EPSON13806_REG16(EPSON13806_BLTHEIGHT) = (0x0258-1); + EPSON13806_REG(EPSON13806_BLTCTRL0) = EPSON13806_BLTCTRL0_ACTIVE; + +#if 0 + // Enable LCD data + EPSON13806_REG(EPSON13806_LCDDISPMODE) &= ~(1<<7); + + // Turn on backlight full + EPSON13806_REG16(EPSON13806_GPIOCTRL) |= 0x00fc; +#endif + + memset(&epsons->kaa, 0, sizeof(KaaScreenInfoRec)); + epsons->kaa.waitMarker = epsonWaitMarker; + epsons->kaa.PrepareSolid = epsonPrepareSolid; + epsons->kaa.Solid = epsonSolid; + epsons->kaa.DoneSolid = epsonDoneSolid; + epsons->kaa.PrepareCopy = epsonPrepareCopy; + epsons->kaa.Copy = epsonCopy; + epsons->kaa.DoneCopy = epsonDoneCopy; + epsons->kaa.flags = KAA_OFFSCREEN_PIXMAPS; + + if (!kaaDrawInit (pScreen, &epsons->kaa)) + return FALSE; + + EPSON_DEBUG (fprintf(stderr,"-epsonDrawInit\n")); + return TRUE; +} + + +/* + * epsonDrawEnable + * + * Description: Enables hardware acceleration + * + * History: + * 11-Feb-04 C.Stylianou NBL: Created. + * + */ + +void +epsonDrawEnable (ScreenPtr pScreen) +{ + EPSON_DEBUG (fprintf(stderr,"+epsonDrawEnable\n")); + epsonWaitForHwBltDone (); + kaaMarkSync (pScreen); + EPSON_DEBUG (fprintf(stderr,"-epsonDrawEnable\n")); +} + + +/* + * epsonDrawDisable + * + * Description: Disables hardware acceleration + * + * History: + * 11-Feb-04 C.Stylianou NBL: Created. + * + */ + +void +epsonDrawDisable (ScreenPtr pScreen) +{ + EPSON_DEBUG (fprintf(stderr,"+epsonDrawDisable\n")); +} + + +/* + * epsonDrawFini + * + * Description: Finish hardware acceleration + * + * History: + * 11-Feb-04 C.Stylianou NBL: Created. + * + */ + +void +epsonDrawFini (ScreenPtr pScreen) +{ + EPSON_DEBUG (fprintf(stderr,"+epsonDrawFini\n")); +} + + +/* + * initEpson13806 + * + * Description: Maps Epson S1D13806 registers + * + * History: + * 11-Feb-04 C.Stylianou NBL: Created. + * + */ + +void +initEpson13806(void) +{ + EPSON_DEBUG (fprintf(stderr,"+initEpson\n")); + + // Map Epson S1D13806 registers + regbase = KdMapDevice (EPSON13806_PHYSICAL_REG_ADDR, EPSON13806_GPIO_REGSIZE); + if (!regbase) + perror("ERROR: regbase\n"); // Sets up register mappings in header files. + +#if 0 + CARD8 rev_code; + rev_code = EPSON13806_REG (EPSON13806_REVCODE); + if ((rev_code >> 2) != 0x07) + perror("ERROR: EPSON13806 Display Controller NOT FOUND!\n"); +#endif + + EPSON_DEBUG (fprintf(stderr,"-initEpson\n")); +} |