(Add Teddy Wang from Silicon Motion to the CC: list) On Wed, 2009-12-23 at 11:51 -0800, Greg Kroah-Hartman wrote: > From: Wu Zhangjin <wuzhangjin@xxxxxxxxx> > > Yeeloong netbook has a sm712 video card, need this driver, but it is not > ready to upstream yet, so, go to drivers/staing at first. > > This source code is originally from Silicon Motion Technology Corp, and > maintained at http://dev.lemote.com/code/linux_loongson for YeeLoong > netbook. I have done a lot of cleanups for it and merged it into my git > repository at http://dev.lemote.com/code/rt4ls. > > Thanks to Simon for testing it on a little-endian x86 platform. > > Thanks to Olivier Croset <olivier.croset@xxxxxxxxxxxxxxxxxx> for > reporting the problem about __BIG_ENDIAN compiling problem and send a > relative patch. > > The suspend/resume and blank support are contributed by Jason from > Silicon Motion Technology. > > Tested-by: Simon Braunschmidt <sbraun@xxxxxxxxx> > Signed-off-by: Wu Zhangjin <wuzhangjin@xxxxxxxxx> > Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx> > --- > drivers/staging/Kconfig | 2 + > drivers/staging/Makefile | 1 + > drivers/staging/sm7xx/Kconfig | 15 + > drivers/staging/sm7xx/Makefile | 3 + > drivers/staging/sm7xx/TODO | 10 + > drivers/staging/sm7xx/smtc2d.c | 979 +++++++++++++++++++++++++++++++ > drivers/staging/sm7xx/smtc2d.h | 530 +++++++++++++++++ > drivers/staging/sm7xx/smtcfb.c | 1253 ++++++++++++++++++++++++++++++++++++++++ > drivers/staging/sm7xx/smtcfb.h | 793 +++++++++++++++++++++++++ > 9 files changed, 3586 insertions(+), 0 deletions(-) > create mode 100644 drivers/staging/sm7xx/Kconfig > create mode 100644 drivers/staging/sm7xx/Makefile > create mode 100644 drivers/staging/sm7xx/TODO > create mode 100644 drivers/staging/sm7xx/smtc2d.c > create mode 100644 drivers/staging/sm7xx/smtc2d.h > create mode 100644 drivers/staging/sm7xx/smtcfb.c > create mode 100644 drivers/staging/sm7xx/smtcfb.h > > diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig > index 093f57a..db0de94 100644 > --- a/drivers/staging/Kconfig > +++ b/drivers/staging/Kconfig > @@ -145,5 +145,7 @@ source "drivers/staging/wavelan/Kconfig" > > source "drivers/staging/netwave/Kconfig" > > +source "drivers/staging/sm7xx/Kconfig" > + > endif # !STAGING_EXCLUDE_BUILD > endif # STAGING > diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile > index 069864f..73c6a71 100644 > --- a/drivers/staging/Makefile > +++ b/drivers/staging/Makefile > @@ -53,3 +53,4 @@ obj-$(CONFIG_ARLAN) += arlan/ > obj-$(CONFIG_WAVELAN) += wavelan/ > obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/ > obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/ > +obj-$(CONFIG_FB_SM7XX) += sm7xx/ > diff --git a/drivers/staging/sm7xx/Kconfig b/drivers/staging/sm7xx/Kconfig > new file mode 100644 > index 0000000..204dbfc > --- /dev/null > +++ b/drivers/staging/sm7xx/Kconfig > @@ -0,0 +1,15 @@ > +config FB_SM7XX > + tristate "Silicon Motion SM7XX Frame Buffer Support" > + depends on FB > + select FB_CFB_FILLRECT > + select FB_CFB_COPYAREA > + select FB_CFB_IMAGEBLIT > + help > + Frame Buffer driver for the Silicon Motion SM7XX serial graphic card. > + > +config FB_SM7XX_ACCEL > + bool "Siliconmotion Acceleration functions (EXPERIMENTAL)" > + depends on FB_SM7XX && EXPERIMENTAL > + help > + This will compile the Trident frame buffer device with > + acceleration functions. > diff --git a/drivers/staging/sm7xx/Makefile b/drivers/staging/sm7xx/Makefile > new file mode 100644 > index 0000000..f43cb91 > --- /dev/null > +++ b/drivers/staging/sm7xx/Makefile > @@ -0,0 +1,3 @@ > +obj-$(CONFIG_FB_SM7XX) += sm7xx.o > + > +sm7xx-y := smtcfb.o > diff --git a/drivers/staging/sm7xx/TODO b/drivers/staging/sm7xx/TODO > new file mode 100644 > index 0000000..1f61f5e > --- /dev/null > +++ b/drivers/staging/sm7xx/TODO > @@ -0,0 +1,10 @@ > +TODO: > +- Dual head support > +- use kernel coding style > +- checkpatch.pl clean > +- refine the code and remove unused code > +- use kernel framebuffer mode setting instead of hard code > +- move it to drivers/video/sm7xx/ or make it be drivers/video/sm7xxfb.c > + > +Please send any patches to Greg Kroah-Hartman <greg@xxxxxxxxx> and > +Teddy Wang <teddy.wang@xxxxxxxxxxxxxxxxxxxx>. > diff --git a/drivers/staging/sm7xx/smtc2d.c b/drivers/staging/sm7xx/smtc2d.c > new file mode 100644 > index 0000000..133b86c > --- /dev/null > +++ b/drivers/staging/sm7xx/smtc2d.c > @@ -0,0 +1,979 @@ > +/* > + * Silicon Motion SM7XX 2D drawing engine functions. > + * > + * Copyright (C) 2006 Silicon Motion Technology Corp. > + * Author: Boyod boyod.yang@xxxxxxxxxxxxxxxxxxxx > + * > + * Copyright (C) 2009 Lemote, Inc. > + * Author: Wu Zhangjin, wuzj@xxxxxxxxxx > + * > + * This file is subject to the terms and conditions of the GNU General Public > + * License. See the file COPYING in the main directory of this archive for > + * more details. > + * > + * Version 0.10.26192.21.01 > + * - Add PowerPC support > + * - Add 2D support for Lynx - > + * Verified on 2.6.19.2 > + * Boyod.yang <boyod.yang@xxxxxxxxxxxxxxxxxxxx> > + */ > + > +unsigned char smtc_de_busy; > + > +void SMTC_write2Dreg(unsigned long nOffset, unsigned long nData) > +{ > + writel(nData, smtc_2DBaseAddress + nOffset); > +} > + > +unsigned long SMTC_read2Dreg(unsigned long nOffset) > +{ > + return readl(smtc_2DBaseAddress + nOffset); > +} > + > +void SMTC_write2Ddataport(unsigned long nOffset, unsigned long nData) > +{ > + writel(nData, smtc_2Ddataport + nOffset); > +} > + > +/********************************************************************** > + * > + * deInit > + * > + * Purpose > + * Drawing engine initialization. > + * > + **********************************************************************/ > + > +void deInit(unsigned int nModeWidth, unsigned int nModeHeight, > + unsigned int bpp) > +{ > + /* Get current power configuration. */ > + unsigned char clock; > + clock = smtc_seqr(0x21); > + > + /* initialize global 'mutex lock' variable */ > + smtc_de_busy = 0; > + > + /* Enable 2D Drawing Engine */ > + smtc_seqw(0x21, clock & 0xF8); > + > + SMTC_write2Dreg(DE_CLIP_TL, > + FIELD_VALUE(0, DE_CLIP_TL, TOP, 0) | > + FIELD_SET(0, DE_CLIP_TL, STATUS, DISABLE) | > + FIELD_SET(0, DE_CLIP_TL, INHIBIT, OUTSIDE) | > + FIELD_VALUE(0, DE_CLIP_TL, LEFT, 0)); > + > + if (bpp >= 24) { > + SMTC_write2Dreg(DE_PITCH, > + FIELD_VALUE(0, DE_PITCH, DESTINATION, > + nModeWidth * 3) | FIELD_VALUE(0, > + DE_PITCH, > + SOURCE, > + nModeWidth > + * 3)); > + } else { > + SMTC_write2Dreg(DE_PITCH, > + FIELD_VALUE(0, DE_PITCH, DESTINATION, > + nModeWidth) | FIELD_VALUE(0, > + DE_PITCH, > + SOURCE, > + nModeWidth)); > + } > + > + SMTC_write2Dreg(DE_WINDOW_WIDTH, > + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, > + nModeWidth) | FIELD_VALUE(0, > + DE_WINDOW_WIDTH, > + SOURCE, > + nModeWidth)); > + > + switch (bpp) { > + case 8: > + SMTC_write2Dreg(DE_STRETCH_FORMAT, > + FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, > + NORMAL) | FIELD_VALUE(0, > + DE_STRETCH_FORMAT, > + PATTERN_Y, > + 0) | > + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, > + 0) | FIELD_SET(0, DE_STRETCH_FORMAT, > + PIXEL_FORMAT, > + 8) | FIELD_SET(0, > + DE_STRETCH_FORMAT, > + ADDRESSING, > + XY) | > + FIELD_VALUE(0, DE_STRETCH_FORMAT, > + SOURCE_HEIGHT, 3)); > + break; > + case 24: > + SMTC_write2Dreg(DE_STRETCH_FORMAT, > + FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, > + NORMAL) | FIELD_VALUE(0, > + DE_STRETCH_FORMAT, > + PATTERN_Y, > + 0) | > + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, > + 0) | FIELD_SET(0, DE_STRETCH_FORMAT, > + PIXEL_FORMAT, > + 24) | FIELD_SET(0, > + DE_STRETCH_FORMAT, > + ADDRESSING, > + XY) | > + FIELD_VALUE(0, DE_STRETCH_FORMAT, > + SOURCE_HEIGHT, 3)); > + break; > + case 16: > + default: > + SMTC_write2Dreg(DE_STRETCH_FORMAT, > + FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, > + NORMAL) | FIELD_VALUE(0, > + DE_STRETCH_FORMAT, > + PATTERN_Y, > + 0) | > + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, > + 0) | FIELD_SET(0, DE_STRETCH_FORMAT, > + PIXEL_FORMAT, > + 16) | FIELD_SET(0, > + DE_STRETCH_FORMAT, > + ADDRESSING, > + XY) | > + FIELD_VALUE(0, DE_STRETCH_FORMAT, > + SOURCE_HEIGHT, 3)); > + break; > + } > + > + SMTC_write2Dreg(DE_MASKS, > + FIELD_VALUE(0, DE_MASKS, BYTE_MASK, 0xFFFF) | > + FIELD_VALUE(0, DE_MASKS, BIT_MASK, 0xFFFF)); > + SMTC_write2Dreg(DE_COLOR_COMPARE_MASK, > + FIELD_VALUE(0, DE_COLOR_COMPARE_MASK, MASKS, \ > + 0xFFFFFF)); > + SMTC_write2Dreg(DE_COLOR_COMPARE, > + FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, 0xFFFFFF)); > +} > + > +void deVerticalLine(unsigned long dst_base, > + unsigned long dst_pitch, > + unsigned long nX, > + unsigned long nY, > + unsigned long dst_height, unsigned long nColor) > +{ > + deWaitForNotBusy(); > + > + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, > + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, > + dst_base)); > + > + SMTC_write2Dreg(DE_PITCH, > + FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | > + FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); > + > + SMTC_write2Dreg(DE_WINDOW_WIDTH, > + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, > + dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH, > + SOURCE, > + dst_pitch)); > + > + SMTC_write2Dreg(DE_FOREGROUND, > + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); > + > + SMTC_write2Dreg(DE_DESTINATION, > + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | > + FIELD_VALUE(0, DE_DESTINATION, X, nX) | > + FIELD_VALUE(0, DE_DESTINATION, Y, nY)); > + > + SMTC_write2Dreg(DE_DIMENSION, > + FIELD_VALUE(0, DE_DIMENSION, X, 1) | > + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); > + > + SMTC_write2Dreg(DE_CONTROL, > + FIELD_SET(0, DE_CONTROL, STATUS, START) | > + FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | > + FIELD_SET(0, DE_CONTROL, MAJOR, Y) | > + FIELD_SET(0, DE_CONTROL, STEP_X, NEGATIVE) | > + FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) | > + FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) | > + FIELD_SET(0, DE_CONTROL, COMMAND, SHORT_STROKE) | > + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | > + FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C)); > + > + smtc_de_busy = 1; > +} > + > +void deHorizontalLine(unsigned long dst_base, > + unsigned long dst_pitch, > + unsigned long nX, > + unsigned long nY, > + unsigned long dst_width, unsigned long nColor) > +{ > + deWaitForNotBusy(); > + > + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, > + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, > + dst_base)); > + > + SMTC_write2Dreg(DE_PITCH, > + FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | > + FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); > + > + SMTC_write2Dreg(DE_WINDOW_WIDTH, > + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, > + dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH, > + SOURCE, > + dst_pitch)); > + SMTC_write2Dreg(DE_FOREGROUND, > + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); > + SMTC_write2Dreg(DE_DESTINATION, > + FIELD_SET(0, DE_DESTINATION, WRAP, > + DISABLE) | FIELD_VALUE(0, DE_DESTINATION, X, > + nX) | FIELD_VALUE(0, > + DE_DESTINATION, > + Y, > + nY)); > + SMTC_write2Dreg(DE_DIMENSION, > + FIELD_VALUE(0, DE_DIMENSION, X, > + dst_width) | FIELD_VALUE(0, DE_DIMENSION, > + Y_ET, 1)); > + SMTC_write2Dreg(DE_CONTROL, > + FIELD_SET(0, DE_CONTROL, STATUS, START) | FIELD_SET(0, > + DE_CONTROL, > + DIRECTION, > + RIGHT_TO_LEFT) > + | FIELD_SET(0, DE_CONTROL, MAJOR, X) | FIELD_SET(0, > + DE_CONTROL, > + STEP_X, > + POSITIVE) > + | FIELD_SET(0, DE_CONTROL, STEP_Y, > + NEGATIVE) | FIELD_SET(0, DE_CONTROL, > + LAST_PIXEL, > + OFF) | FIELD_SET(0, > + DE_CONTROL, > + COMMAND, > + SHORT_STROKE) > + | FIELD_SET(0, DE_CONTROL, ROP_SELECT, > + ROP2) | FIELD_VALUE(0, DE_CONTROL, ROP, > + 0x0C)); > + > + smtc_de_busy = 1; > +} > + > +void deLine(unsigned long dst_base, > + unsigned long dst_pitch, > + unsigned long nX1, > + unsigned long nY1, > + unsigned long nX2, unsigned long nY2, unsigned long nColor) > +{ > + unsigned long nCommand = > + FIELD_SET(0, DE_CONTROL, STATUS, START) | > + FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | > + FIELD_SET(0, DE_CONTROL, MAJOR, X) | > + FIELD_SET(0, DE_CONTROL, STEP_X, POSITIVE) | > + FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) | > + FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) | > + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | > + FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C); > + unsigned long DeltaX; > + unsigned long DeltaY; > + > + /* Calculate delta X */ > + if (nX1 <= nX2) > + DeltaX = nX2 - nX1; > + else { > + DeltaX = nX1 - nX2; > + nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_X, NEGATIVE); > + } > + > + /* Calculate delta Y */ > + if (nY1 <= nY2) > + DeltaY = nY2 - nY1; > + else { > + DeltaY = nY1 - nY2; > + nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_Y, NEGATIVE); > + } > + > + /* Determine the major axis */ > + if (DeltaX < DeltaY) > + nCommand = FIELD_SET(nCommand, DE_CONTROL, MAJOR, Y); > + > + /* Vertical line? */ > + if (nX1 == nX2) > + deVerticalLine(dst_base, dst_pitch, nX1, nY1, DeltaY, nColor); > + > + /* Horizontal line? */ > + else if (nY1 == nY2) > + deHorizontalLine(dst_base, dst_pitch, nX1, nY1, \ > + DeltaX, nColor); > + > + /* Diagonal line? */ > + else if (DeltaX == DeltaY) { > + deWaitForNotBusy(); > + > + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, > + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, > + ADDRESS, dst_base)); > + > + SMTC_write2Dreg(DE_PITCH, > + FIELD_VALUE(0, DE_PITCH, DESTINATION, > + dst_pitch) | FIELD_VALUE(0, > + DE_PITCH, > + SOURCE, > + dst_pitch)); > + > + SMTC_write2Dreg(DE_WINDOW_WIDTH, > + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, > + dst_pitch) | FIELD_VALUE(0, > + DE_WINDOW_WIDTH, > + SOURCE, > + dst_pitch)); > + > + SMTC_write2Dreg(DE_FOREGROUND, > + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); > + > + SMTC_write2Dreg(DE_DESTINATION, > + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | > + FIELD_VALUE(0, DE_DESTINATION, X, 1) | > + FIELD_VALUE(0, DE_DESTINATION, Y, nY1)); > + > + SMTC_write2Dreg(DE_DIMENSION, > + FIELD_VALUE(0, DE_DIMENSION, X, 1) | > + FIELD_VALUE(0, DE_DIMENSION, Y_ET, DeltaX)); > + > + SMTC_write2Dreg(DE_CONTROL, > + FIELD_SET(nCommand, DE_CONTROL, COMMAND, > + SHORT_STROKE)); > + } > + > + /* Generic line */ > + else { > + unsigned int k1, k2, et, w; > + if (DeltaX < DeltaY) { > + k1 = 2 * DeltaX; > + et = k1 - DeltaY; > + k2 = et - DeltaY; > + w = DeltaY + 1; > + } else { > + k1 = 2 * DeltaY; > + et = k1 - DeltaX; > + k2 = et - DeltaX; > + w = DeltaX + 1; > + } > + > + deWaitForNotBusy(); > + > + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, > + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, > + ADDRESS, dst_base)); > + > + SMTC_write2Dreg(DE_PITCH, > + FIELD_VALUE(0, DE_PITCH, DESTINATION, > + dst_pitch) | FIELD_VALUE(0, > + DE_PITCH, > + SOURCE, > + dst_pitch)); > + > + SMTC_write2Dreg(DE_WINDOW_WIDTH, > + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, > + dst_pitch) | FIELD_VALUE(0, > + DE_WINDOW_WIDTH, > + SOURCE, > + dst_pitch)); > + > + SMTC_write2Dreg(DE_FOREGROUND, > + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); > + > + SMTC_write2Dreg(DE_SOURCE, > + FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | > + FIELD_VALUE(0, DE_SOURCE, X_K1, k1) | > + FIELD_VALUE(0, DE_SOURCE, Y_K2, k2)); > + > + SMTC_write2Dreg(DE_DESTINATION, > + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | > + FIELD_VALUE(0, DE_DESTINATION, X, nX1) | > + FIELD_VALUE(0, DE_DESTINATION, Y, nY1)); > + > + SMTC_write2Dreg(DE_DIMENSION, > + FIELD_VALUE(0, DE_DIMENSION, X, w) | > + FIELD_VALUE(0, DE_DIMENSION, Y_ET, et)); > + > + SMTC_write2Dreg(DE_CONTROL, > + FIELD_SET(nCommand, DE_CONTROL, COMMAND, > + LINE_DRAW)); > + } > + > + smtc_de_busy = 1; > +} > + > +void deFillRect(unsigned long dst_base, > + unsigned long dst_pitch, > + unsigned long dst_X, > + unsigned long dst_Y, > + unsigned long dst_width, > + unsigned long dst_height, unsigned long nColor) > +{ > + deWaitForNotBusy(); > + > + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, > + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, > + dst_base)); > + > + if (dst_pitch) { > + SMTC_write2Dreg(DE_PITCH, > + FIELD_VALUE(0, DE_PITCH, DESTINATION, > + dst_pitch) | FIELD_VALUE(0, > + DE_PITCH, > + SOURCE, > + dst_pitch)); > + > + SMTC_write2Dreg(DE_WINDOW_WIDTH, > + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, > + dst_pitch) | FIELD_VALUE(0, > + DE_WINDOW_WIDTH, > + SOURCE, > + dst_pitch)); > + } > + > + SMTC_write2Dreg(DE_FOREGROUND, > + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); > + > + SMTC_write2Dreg(DE_DESTINATION, > + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | > + FIELD_VALUE(0, DE_DESTINATION, X, dst_X) | > + FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y)); > + > + SMTC_write2Dreg(DE_DIMENSION, > + FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | > + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); > + > + SMTC_write2Dreg(DE_CONTROL, > + FIELD_SET(0, DE_CONTROL, STATUS, START) | > + FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | > + FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) | > + FIELD_SET(0, DE_CONTROL, COMMAND, RECTANGLE_FILL) | > + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | > + FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C)); > + > + smtc_de_busy = 1; > +} > + > +/********************************************************************** > + * > + * deRotatePattern > + * > + * Purpose > + * Rotate the given pattern if necessary > + * > + * Parameters > + * [in] > + * pPattern - Pointer to DE_SURFACE structure containing > + * pattern attributes > + * patternX - X position (0-7) of pattern origin > + * patternY - Y position (0-7) of pattern origin > + * > + * [out] > + * pattern_dstaddr - Pointer to pre-allocated buffer containing > + * rotated pattern > + * > + **********************************************************************/ > +void deRotatePattern(unsigned char *pattern_dstaddr, > + unsigned long pattern_src_addr, > + unsigned long pattern_BPP, > + unsigned long pattern_stride, int patternX, int patternY) > +{ > + unsigned int i; > + unsigned long pattern[PATTERN_WIDTH * PATTERN_HEIGHT]; > + unsigned int x, y; > + unsigned char *pjPatByte; > + > + if (pattern_dstaddr != NULL) { > + deWaitForNotBusy(); > + > + if (patternX || patternY) { > + /* Rotate pattern */ > + pjPatByte = (unsigned char *)pattern; > + > + switch (pattern_BPP) { > + case 8: > + { > + for (y = 0; y < 8; y++) { > + unsigned char *pjBuffer = > + pattern_dstaddr + > + ((patternY + y) & 7) * 8; > + for (x = 0; x < 8; x++) { > + pjBuffer[(patternX + > + x) & 7] = > + pjPatByte[x]; > + } > + pjPatByte += pattern_stride; > + } > + break; > + } > + > + case 16: > + { > + for (y = 0; y < 8; y++) { > + unsigned short *pjBuffer = > + (unsigned short *) > + pattern_dstaddr + > + ((patternY + y) & 7) * 8; > + for (x = 0; x < 8; x++) { > + pjBuffer[(patternX + > + x) & 7] = > + ((unsigned short *) > + pjPatByte)[x]; > + } > + pjPatByte += pattern_stride; > + } > + break; > + } > + > + case 32: > + { > + for (y = 0; y < 8; y++) { > + unsigned long *pjBuffer = > + (unsigned long *) > + pattern_dstaddr + > + ((patternY + y) & 7) * 8; > + for (x = 0; x < 8; x++) { > + pjBuffer[(patternX + > + x) & 7] = > + ((unsigned long *) > + pjPatByte)[x]; > + } > + pjPatByte += pattern_stride; > + } > + break; > + } > + } > + } else { > + /*Don't rotate,just copy pattern into pattern_dstaddr*/ > + for (i = 0; i < (pattern_BPP * 2); i++) { > + ((unsigned long *)pattern_dstaddr)[i] = > + pattern[i]; > + } > + } > + > + } > +} > + > +/********************************************************************** > + * > + * deCopy > + * > + * Purpose > + * Copy a rectangular area of the source surface to a destination surface > + * > + * Remarks > + * Source bitmap must have the same color depth (BPP) as the destination > + * bitmap. > + * > +**********************************************************************/ > +void deCopy(unsigned long dst_base, > + unsigned long dst_pitch, > + unsigned long dst_BPP, > + unsigned long dst_X, > + unsigned long dst_Y, > + unsigned long dst_width, > + unsigned long dst_height, > + unsigned long src_base, > + unsigned long src_pitch, > + unsigned long src_X, > + unsigned long src_Y, pTransparent pTransp, unsigned char nROP2) > +{ > + unsigned long nDirection = 0; > + unsigned long nTransparent = 0; > + /* Direction of ROP2 operation: > + * 1 = Left to Right, > + * (-1) = Right to Left > + */ > + unsigned long opSign = 1; > + /* xWidth is in pixels */ > + unsigned long xWidth = 192 / (dst_BPP / 8); > + unsigned long de_ctrl = 0; > + > + deWaitForNotBusy(); > + > + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, > + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, > + dst_base)); > + > + SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, > + FIELD_VALUE(0, DE_WINDOW_SOURCE_BASE, ADDRESS, > + src_base)); > + > + if (dst_pitch && src_pitch) { > + SMTC_write2Dreg(DE_PITCH, > + FIELD_VALUE(0, DE_PITCH, DESTINATION, > + dst_pitch) | FIELD_VALUE(0, > + DE_PITCH, > + SOURCE, > + src_pitch)); > + > + SMTC_write2Dreg(DE_WINDOW_WIDTH, > + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, > + dst_pitch) | FIELD_VALUE(0, > + DE_WINDOW_WIDTH, > + SOURCE, > + src_pitch)); > + } > + > + /* Set transparent bits if necessary */ > + if (pTransp != NULL) { > + nTransparent = > + pTransp->match | pTransp->select | pTransp->control; > + > + /* Set color compare register */ > + SMTC_write2Dreg(DE_COLOR_COMPARE, > + FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, > + pTransp->color)); > + } > + > + /* Determine direction of operation */ > + if (src_Y < dst_Y) { > + /* +----------+ > + |S | > + | +----------+ > + | | | | > + | | | | > + +---|------+ | > + | D | > + +----------+ */ > + > + nDirection = BOTTOM_TO_TOP; > + } else if (src_Y > dst_Y) { > + /* +----------+ > + |D | > + | +----------+ > + | | | | > + | | | | > + +---|------+ | > + | S | > + +----------+ */ > + > + nDirection = TOP_TO_BOTTOM; > + } else { > + /* src_Y == dst_Y */ > + > + if (src_X <= dst_X) { > + /* +------+---+------+ > + |S | | D| > + | | | | > + | | | | > + | | | | > + +------+---+------+ */ > + > + nDirection = RIGHT_TO_LEFT; > + } else { > + /* src_X > dst_X */ > + > + /* +------+---+------+ > + |D | | S| > + | | | | > + | | | | > + | | | | > + +------+---+------+ */ > + > + nDirection = LEFT_TO_RIGHT; > + } > + } > + > + if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) { > + src_X += dst_width - 1; > + src_Y += dst_height - 1; > + dst_X += dst_width - 1; > + dst_Y += dst_height - 1; > + opSign = (-1); > + } > + > + if (dst_BPP >= 24) { > + src_X *= 3; > + src_Y *= 3; > + dst_X *= 3; > + dst_Y *= 3; > + dst_width *= 3; > + if ((nDirection == BOTTOM_TO_TOP) > + || (nDirection == RIGHT_TO_LEFT)) { > + src_X += 2; > + dst_X += 2; > + } > + } > + > + /* Workaround for 192 byte hw bug */ > + if ((nROP2 != 0x0C) && ((dst_width * (dst_BPP / 8)) >= 192)) { > + /* > + * Perform the ROP2 operation in chunks of (xWidth * > + * dst_height) > + */ > + while (1) { > + deWaitForNotBusy(); > + > + SMTC_write2Dreg(DE_SOURCE, > + FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | > + FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) | > + FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y)); > + > + SMTC_write2Dreg(DE_DESTINATION, > + FIELD_SET(0, DE_DESTINATION, WRAP, > + DISABLE) | FIELD_VALUE(0, > + DE_DESTINATION, > + X, > + dst_X) > + | FIELD_VALUE(0, DE_DESTINATION, Y, > + dst_Y)); > + > + SMTC_write2Dreg(DE_DIMENSION, > + FIELD_VALUE(0, DE_DIMENSION, X, > + xWidth) | FIELD_VALUE(0, > + DE_DIMENSION, > + Y_ET, > + dst_height)); > + > + de_ctrl = > + FIELD_VALUE(0, DE_CONTROL, ROP, > + nROP2) | nTransparent | FIELD_SET(0, > + DE_CONTROL, > + ROP_SELECT, > + ROP2) > + | FIELD_SET(0, DE_CONTROL, COMMAND, > + BITBLT) | ((nDirection == > + 1) ? FIELD_SET(0, > + DE_CONTROL, > + DIRECTION, > + RIGHT_TO_LEFT) > + : FIELD_SET(0, DE_CONTROL, > + DIRECTION, > + LEFT_TO_RIGHT)) | > + FIELD_SET(0, DE_CONTROL, STATUS, START); > + > + SMTC_write2Dreg(DE_CONTROL, de_ctrl); > + > + src_X += (opSign * xWidth); > + dst_X += (opSign * xWidth); > + dst_width -= xWidth; > + > + if (dst_width <= 0) { > + /* ROP2 operation is complete */ > + break; > + } > + > + if (xWidth > dst_width) > + xWidth = dst_width; > + } > + } else { > + deWaitForNotBusy(); > + SMTC_write2Dreg(DE_SOURCE, > + FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | > + FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) | > + FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y)); > + > + SMTC_write2Dreg(DE_DESTINATION, > + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | > + FIELD_VALUE(0, DE_DESTINATION, X, dst_X) | > + FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y)); > + > + SMTC_write2Dreg(DE_DIMENSION, > + FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | > + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); > + > + de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, nROP2) | > + nTransparent | > + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | > + FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) | > + ((nDirection == 1) ? FIELD_SET(0, DE_CONTROL, DIRECTION, > + RIGHT_TO_LEFT) > + : FIELD_SET(0, DE_CONTROL, DIRECTION, > + LEFT_TO_RIGHT)) | FIELD_SET(0, DE_CONTROL, > + STATUS, START); > + SMTC_write2Dreg(DE_CONTROL, de_ctrl); > + } > + > + smtc_de_busy = 1; > +} > + > +/* > + * This function sets the pixel format that will apply to the 2D Engine. > + */ > +void deSetPixelFormat(unsigned long bpp) > +{ > + unsigned long de_format; > + > + de_format = SMTC_read2Dreg(DE_STRETCH_FORMAT); > + > + switch (bpp) { > + case 8: > + de_format = > + FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 8); > + break; > + default: > + case 16: > + de_format = > + FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 16); > + break; > + case 32: > + de_format = > + FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 32); > + break; > + } > + > + SMTC_write2Dreg(DE_STRETCH_FORMAT, de_format); > +} > + > +/* > + * System memory to Video memory monochrome expansion. > + * > + * Source is monochrome image in system memory. This function expands the > + * monochrome data to color image in video memory. > + */ > + > +long deSystemMem2VideoMemMonoBlt(const char *pSrcbuf, > + long srcDelta, > + unsigned long startBit, > + unsigned long dBase, > + unsigned long dPitch, > + unsigned long bpp, > + unsigned long dx, unsigned long dy, > + unsigned long width, unsigned long height, > + unsigned long fColor, > + unsigned long bColor, > + unsigned long rop2) { > + unsigned long bytePerPixel; > + unsigned long ulBytesPerScan; > + unsigned long ul4BytesPerScan; > + unsigned long ulBytesRemain; > + unsigned long de_ctrl = 0; > + unsigned char ajRemain[4]; > + long i, j; > + > + bytePerPixel = bpp / 8; > + > + /* Just make sure the start bit is within legal range */ > + startBit &= 7; > + > + ulBytesPerScan = (width + startBit + 7) / 8; > + ul4BytesPerScan = ulBytesPerScan & ~3; > + ulBytesRemain = ulBytesPerScan & 3; > + > + if (smtc_de_busy) > + deWaitForNotBusy(); > + > + /* > + * 2D Source Base. Use 0 for HOST Blt. > + */ > + > + SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, 0); > + > + /* > + * 2D Destination Base. > + * > + * It is an address offset (128 bit aligned) from the beginning of > + * frame buffer. > + */ > + > + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, dBase); > + > + if (dPitch) { > + > + /* > + * Program pitch (distance between the 1st points of two > + * adjacent lines). > + * > + * Note that input pitch is BYTE value, but the 2D Pitch > + * register uses pixel values. Need Byte to pixel convertion. > + */ > + > + SMTC_write2Dreg(DE_PITCH, > + FIELD_VALUE(0, DE_PITCH, DESTINATION, > + dPitch / > + bytePerPixel) | FIELD_VALUE(0, > + DE_PITCH, > + SOURCE, > + dPitch / > + bytePerPixel)); > + > + /* Screen Window width in Pixels. > + * > + * 2D engine uses this value to calculate the linear address in > + * frame buffer for a given point. > + */ > + > + SMTC_write2Dreg(DE_WINDOW_WIDTH, > + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, > + (dPitch / > + bytePerPixel)) | FIELD_VALUE(0, > + DE_WINDOW_WIDTH, > + SOURCE, > + (dPitch > + / > + bytePerPixel))); > + } > + /* Note: For 2D Source in Host Write, only X_K1 field is needed, and > + * Y_K2 field is not used. For mono bitmap, use startBit for X_K1. > + */ > + > + SMTC_write2Dreg(DE_SOURCE, > + FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | > + FIELD_VALUE(0, DE_SOURCE, X_K1, startBit) | > + FIELD_VALUE(0, DE_SOURCE, Y_K2, 0)); > + > + SMTC_write2Dreg(DE_DESTINATION, > + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | > + FIELD_VALUE(0, DE_DESTINATION, X, dx) | > + FIELD_VALUE(0, DE_DESTINATION, Y, dy)); > + > + SMTC_write2Dreg(DE_DIMENSION, > + FIELD_VALUE(0, DE_DIMENSION, X, width) | > + FIELD_VALUE(0, DE_DIMENSION, Y_ET, height)); > + > + SMTC_write2Dreg(DE_FOREGROUND, fColor); > + SMTC_write2Dreg(DE_BACKGROUND, bColor); > + > + if (bpp) > + deSetPixelFormat(bpp); > + /* Set the pixel format of the destination */ > + > + de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, rop2) | > + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | > + FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) | > + FIELD_SET(0, DE_CONTROL, HOST, MONO) | > + FIELD_SET(0, DE_CONTROL, STATUS, START); > + > + SMTC_write2Dreg(DE_CONTROL, de_ctrl | deGetTransparency()); > + > + /* Write MONO data (line by line) to 2D Engine data port */ > + for (i = 0; i < height; i++) { > + /* For each line, send the data in chunks of 4 bytes */ > + for (j = 0; j < (ul4BytesPerScan / 4); j++) > + SMTC_write2Ddataport(0, > + *(unsigned long *)(pSrcbuf + > + (j * 4))); > + > + if (ulBytesRemain) { > + memcpy(ajRemain, pSrcbuf + ul4BytesPerScan, > + ulBytesRemain); > + SMTC_write2Ddataport(0, *(unsigned long *)ajRemain); > + } > + > + pSrcbuf += srcDelta; > + } > + smtc_de_busy = 1; > + > + return 0; > +} > + > +/* > + * This function gets the transparency status from DE_CONTROL register. > + * It returns a double word with the transparent fields properly set, > + * while other fields are 0. > + */ > +unsigned long deGetTransparency(void) > +{ > + unsigned long de_ctrl; > + > + de_ctrl = SMTC_read2Dreg(DE_CONTROL); > + > + de_ctrl &= > + FIELD_MASK(DE_CONTROL_TRANSPARENCY_MATCH) | > + FIELD_MASK(DE_CONTROL_TRANSPARENCY_SELECT) | > + FIELD_MASK(DE_CONTROL_TRANSPARENCY); > + > + return de_ctrl; > +} > diff --git a/drivers/staging/sm7xx/smtc2d.h b/drivers/staging/sm7xx/smtc2d.h > new file mode 100644 > index 0000000..38d0c33 > --- /dev/null > +++ b/drivers/staging/sm7xx/smtc2d.h > @@ -0,0 +1,530 @@ > +/* > + * Silicon Motion SM712 2D drawing engine functions. > + * > + * Copyright (C) 2006 Silicon Motion Technology Corp. > + * Author: Ge Wang, gewang@xxxxxxxxxxxxxxxxx > + * > + * Copyright (C) 2009 Lemote, Inc. > + * Author: Wu Zhangjin, wuzj@xxxxxxxxxx > + * > + * This file is subject to the terms and conditions of the GNU General Public > + * License. See the file COPYING in the main directory of this archive for > + * more details. > + */ > + > +#ifndef NULL > +#define NULL 0 > +#endif > + > +/* Internal macros */ > + > +#define _F_START(f) (0 ? f) > +#define _F_END(f) (1 ? f) > +#define _F_SIZE(f) (1 + _F_END(f) - _F_START(f)) > +#define _F_MASK(f) (((1ULL << _F_SIZE(f)) - 1) << _F_START(f)) > +#define _F_NORMALIZE(v, f) (((v) & _F_MASK(f)) >> _F_START(f)) > +#define _F_DENORMALIZE(v, f) (((v) << _F_START(f)) & _F_MASK(f)) > + > +/* Global macros */ > + > +#define FIELD_GET(x, reg, field) \ > +( \ > + _F_NORMALIZE((x), reg ## _ ## field) \ > +) > + > +#define FIELD_SET(x, reg, field, value) \ > +( \ > + (x & ~_F_MASK(reg ## _ ## field)) \ > + | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \ > +) > + > +#define FIELD_VALUE(x, reg, field, value) \ > +( \ > + (x & ~_F_MASK(reg ## _ ## field)) \ > + | _F_DENORMALIZE(value, reg ## _ ## field) \ > +) > + > +#define FIELD_CLEAR(reg, field) \ > +( \ > + ~_F_MASK(reg ## _ ## field) \ > +) > + > +/* Field Macros */ > + > +#define FIELD_START(field) (0 ? field) > +#define FIELD_END(field) (1 ? field) > +#define FIELD_SIZE(field) \ > + (1 + FIELD_END(field) - FIELD_START(field)) > + > +#define FIELD_MASK(field) \ > + (((1 << (FIELD_SIZE(field)-1)) \ > + | ((1 << (FIELD_SIZE(field)-1)) - 1)) \ > + << FIELD_START(field)) > + > +#define FIELD_NORMALIZE(reg, field) \ > + (((reg) & FIELD_MASK(field)) >> FIELD_START(field)) > + > +#define FIELD_DENORMALIZE(field, value) \ > + (((value) << FIELD_START(field)) & FIELD_MASK(field)) > + > +#define FIELD_INIT(reg, field, value) \ > + FIELD_DENORMALIZE(reg ## _ ## field, \ > + reg ## _ ## field ## _ ## value) > + > +#define FIELD_INIT_VAL(reg, field, value) \ > + (FIELD_DENORMALIZE(reg ## _ ## field, value)) > + > +#define FIELD_VAL_SET(x, r, f, v) ({ \ > + x = (x & ~FIELD_MASK(r ## _ ## f)) \ > + | FIELD_DENORMALIZE(r ## _ ## f, r ## _ ## f ## _ ## v) \ > +}) > + > +#define RGB(r, g, b) ((unsigned long)(((r) << 16) | ((g) << 8) | (b))) > + > +/* Transparent info definition */ > +typedef struct { > + unsigned long match; /* Matching pixel is OPAQUE/TRANSPARENT */ > + unsigned long select; /* Transparency controlled by SRC/DST */ > + unsigned long control; /* ENABLE/DISABLE transparency */ > + unsigned long color; /* Transparent color */ > +} Transparent, *pTransparent; > + > +#define PIXEL_DEPTH_1_BP 0 /* 1 bit per pixel */ > +#define PIXEL_DEPTH_8_BPP 1 /* 8 bits per pixel */ > +#define PIXEL_DEPTH_16_BPP 2 /* 16 bits per pixel */ > +#define PIXEL_DEPTH_32_BPP 3 /* 32 bits per pixel */ > +#define PIXEL_DEPTH_YUV422 8 /* 16 bits per pixel YUV422 */ > +#define PIXEL_DEPTH_YUV420 9 /* 16 bits per pixel YUV420 */ > + > +#define PATTERN_WIDTH 8 > +#define PATTERN_HEIGHT 8 > + > +#define TOP_TO_BOTTOM 0 > +#define BOTTOM_TO_TOP 1 > +#define RIGHT_TO_LEFT BOTTOM_TO_TOP > +#define LEFT_TO_RIGHT TOP_TO_BOTTOM > + > +/* Constants used in Transparent structure */ > +#define MATCH_OPAQUE 0x00000000 > +#define MATCH_TRANSPARENT 0x00000400 > +#define SOURCE 0x00000000 > +#define DESTINATION 0x00000200 > + > +/* 2D registers. */ > + > +#define DE_SOURCE 0x000000 > +#define DE_SOURCE_WRAP 31 : 31 > +#define DE_SOURCE_WRAP_DISABLE 0 > +#define DE_SOURCE_WRAP_ENABLE 1 > +#define DE_SOURCE_X_K1 29 : 16 > +#define DE_SOURCE_Y_K2 15 : 0 > + > +#define DE_DESTINATION 0x000004 > +#define DE_DESTINATION_WRAP 31 : 31 > +#define DE_DESTINATION_WRAP_DISABLE 0 > +#define DE_DESTINATION_WRAP_ENABLE 1 > +#define DE_DESTINATION_X 28 : 16 > +#define DE_DESTINATION_Y 15 : 0 > + > +#define DE_DIMENSION 0x000008 > +#define DE_DIMENSION_X 28 : 16 > +#define DE_DIMENSION_Y_ET 15 : 0 > + > +#define DE_CONTROL 0x00000C > +#define DE_CONTROL_STATUS 31 : 31 > +#define DE_CONTROL_STATUS_STOP 0 > +#define DE_CONTROL_STATUS_START 1 > +#define DE_CONTROL_PATTERN 30 : 30 > +#define DE_CONTROL_PATTERN_MONO 0 > +#define DE_CONTROL_PATTERN_COLOR 1 > +#define DE_CONTROL_UPDATE_DESTINATION_X 29 : 29 > +#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE 0 > +#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE 1 > +#define DE_CONTROL_QUICK_START 28 : 28 > +#define DE_CONTROL_QUICK_START_DISABLE 0 > +#define DE_CONTROL_QUICK_START_ENABLE 1 > +#define DE_CONTROL_DIRECTION 27 : 27 > +#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT 0 > +#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT 1 > +#define DE_CONTROL_MAJOR 26 : 26 > +#define DE_CONTROL_MAJOR_X 0 > +#define DE_CONTROL_MAJOR_Y 1 > +#define DE_CONTROL_STEP_X 25 : 25 > +#define DE_CONTROL_STEP_X_POSITIVE 1 > +#define DE_CONTROL_STEP_X_NEGATIVE 0 > +#define DE_CONTROL_STEP_Y 24 : 24 > +#define DE_CONTROL_STEP_Y_POSITIVE 1 > +#define DE_CONTROL_STEP_Y_NEGATIVE 0 > +#define DE_CONTROL_STRETCH 23 : 23 > +#define DE_CONTROL_STRETCH_DISABLE 0 > +#define DE_CONTROL_STRETCH_ENABLE 1 > +#define DE_CONTROL_HOST 22 : 22 > +#define DE_CONTROL_HOST_COLOR 0 > +#define DE_CONTROL_HOST_MONO 1 > +#define DE_CONTROL_LAST_PIXEL 21 : 21 > +#define DE_CONTROL_LAST_PIXEL_OFF 0 > +#define DE_CONTROL_LAST_PIXEL_ON 1 > +#define DE_CONTROL_COMMAND 20 : 16 > +#define DE_CONTROL_COMMAND_BITBLT 0 > +#define DE_CONTROL_COMMAND_RECTANGLE_FILL 1 > +#define DE_CONTROL_COMMAND_DE_TILE 2 > +#define DE_CONTROL_COMMAND_TRAPEZOID_FILL 3 > +#define DE_CONTROL_COMMAND_ALPHA_BLEND 4 > +#define DE_CONTROL_COMMAND_RLE_STRIP 5 > +#define DE_CONTROL_COMMAND_SHORT_STROKE 6 > +#define DE_CONTROL_COMMAND_LINE_DRAW 7 > +#define DE_CONTROL_COMMAND_HOST_WRITE 8 > +#define DE_CONTROL_COMMAND_HOST_READ 9 > +#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP 10 > +#define DE_CONTROL_COMMAND_ROTATE 11 > +#define DE_CONTROL_COMMAND_FONT 12 > +#define DE_CONTROL_COMMAND_TEXTURE_LOAD 15 > +#define DE_CONTROL_ROP_SELECT 15 : 15 > +#define DE_CONTROL_ROP_SELECT_ROP3 0 > +#define DE_CONTROL_ROP_SELECT_ROP2 1 > +#define DE_CONTROL_ROP2_SOURCE 14 : 14 > +#define DE_CONTROL_ROP2_SOURCE_BITMAP 0 > +#define DE_CONTROL_ROP2_SOURCE_PATTERN 1 > +#define DE_CONTROL_MONO_DATA 13 : 12 > +#define DE_CONTROL_MONO_DATA_NOT_PACKED 0 > +#define DE_CONTROL_MONO_DATA_8_PACKED 1 > +#define DE_CONTROL_MONO_DATA_16_PACKED 2 > +#define DE_CONTROL_MONO_DATA_32_PACKED 3 > +#define DE_CONTROL_REPEAT_ROTATE 11 : 11 > +#define DE_CONTROL_REPEAT_ROTATE_DISABLE 0 > +#define DE_CONTROL_REPEAT_ROTATE_ENABLE 1 > +#define DE_CONTROL_TRANSPARENCY_MATCH 10 : 10 > +#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE 0 > +#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT 1 > +#define DE_CONTROL_TRANSPARENCY_SELECT 9 : 9 > +#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE 0 > +#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION 1 > +#define DE_CONTROL_TRANSPARENCY 8 : 8 > +#define DE_CONTROL_TRANSPARENCY_DISABLE 0 > +#define DE_CONTROL_TRANSPARENCY_ENABLE 1 > +#define DE_CONTROL_ROP 7 : 0 > + > +/* Pseudo fields. */ > + > +#define DE_CONTROL_SHORT_STROKE_DIR 27 : 24 > +#define DE_CONTROL_SHORT_STROKE_DIR_225 0 > +#define DE_CONTROL_SHORT_STROKE_DIR_135 1 > +#define DE_CONTROL_SHORT_STROKE_DIR_315 2 > +#define DE_CONTROL_SHORT_STROKE_DIR_45 3 > +#define DE_CONTROL_SHORT_STROKE_DIR_270 4 > +#define DE_CONTROL_SHORT_STROKE_DIR_90 5 > +#define DE_CONTROL_SHORT_STROKE_DIR_180 8 > +#define DE_CONTROL_SHORT_STROKE_DIR_0 10 > +#define DE_CONTROL_ROTATION 25 : 24 > +#define DE_CONTROL_ROTATION_0 0 > +#define DE_CONTROL_ROTATION_270 1 > +#define DE_CONTROL_ROTATION_90 2 > +#define DE_CONTROL_ROTATION_180 3 > + > +#define DE_PITCH 0x000010 > +#define DE_PITCH_DESTINATION 28 : 16 > +#define DE_PITCH_SOURCE 12 : 0 > + > +#define DE_FOREGROUND 0x000014 > +#define DE_FOREGROUND_COLOR 31 : 0 > + > +#define DE_BACKGROUND 0x000018 > +#define DE_BACKGROUND_COLOR 31 : 0 > + > +#define DE_STRETCH_FORMAT 0x00001C > +#define DE_STRETCH_FORMAT_PATTERN_XY 30 : 30 > +#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL 0 > +#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE 1 > +#define DE_STRETCH_FORMAT_PATTERN_Y 29 : 27 > +#define DE_STRETCH_FORMAT_PATTERN_X 25 : 23 > +#define DE_STRETCH_FORMAT_PIXEL_FORMAT 21 : 20 > +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8 0 > +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16 1 > +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_24 3 > +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32 2 > +#define DE_STRETCH_FORMAT_ADDRESSING 19 : 16 > +#define DE_STRETCH_FORMAT_ADDRESSING_XY 0 > +#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR 15 > +#define DE_STRETCH_FORMAT_SOURCE_HEIGHT 11 : 0 > + > +#define DE_COLOR_COMPARE 0x000020 > +#define DE_COLOR_COMPARE_COLOR 23 : 0 > + > +#define DE_COLOR_COMPARE_MASK 0x000024 > +#define DE_COLOR_COMPARE_MASK_MASKS 23 : 0 > + > +#define DE_MASKS 0x000028 > +#define DE_MASKS_BYTE_MASK 31 : 16 > +#define DE_MASKS_BIT_MASK 15 : 0 > + > +#define DE_CLIP_TL 0x00002C > +#define DE_CLIP_TL_TOP 31 : 16 > +#define DE_CLIP_TL_STATUS 13 : 13 > +#define DE_CLIP_TL_STATUS_DISABLE 0 > +#define DE_CLIP_TL_STATUS_ENABLE 1 > +#define DE_CLIP_TL_INHIBIT 12 : 12 > +#define DE_CLIP_TL_INHIBIT_OUTSIDE 0 > +#define DE_CLIP_TL_INHIBIT_INSIDE 1 > +#define DE_CLIP_TL_LEFT 11 : 0 > + > +#define DE_CLIP_BR 0x000030 > +#define DE_CLIP_BR_BOTTOM 31 : 16 > +#define DE_CLIP_BR_RIGHT 12 : 0 > + > +#define DE_MONO_PATTERN_LOW 0x000034 > +#define DE_MONO_PATTERN_LOW_PATTERN 31 : 0 > + > +#define DE_MONO_PATTERN_HIGH 0x000038 > +#define DE_MONO_PATTERN_HIGH_PATTERN 31 : 0 > + > +#define DE_WINDOW_WIDTH 0x00003C > +#define DE_WINDOW_WIDTH_DESTINATION 28 : 16 > +#define DE_WINDOW_WIDTH_SOURCE 12 : 0 > + > +#define DE_WINDOW_SOURCE_BASE 0x000040 > +#define DE_WINDOW_SOURCE_BASE_EXT 27 : 27 > +#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL 0 > +#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL 1 > +#define DE_WINDOW_SOURCE_BASE_CS 26 : 26 > +#define DE_WINDOW_SOURCE_BASE_CS_0 0 > +#define DE_WINDOW_SOURCE_BASE_CS_1 1 > +#define DE_WINDOW_SOURCE_BASE_ADDRESS 25 : 0 > + > +#define DE_WINDOW_DESTINATION_BASE 0x000044 > +#define DE_WINDOW_DESTINATION_BASE_EXT 27 : 27 > +#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL 0 > +#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL 1 > +#define DE_WINDOW_DESTINATION_BASE_CS 26 : 26 > +#define DE_WINDOW_DESTINATION_BASE_CS_0 0 > +#define DE_WINDOW_DESTINATION_BASE_CS_1 1 > +#define DE_WINDOW_DESTINATION_BASE_ADDRESS 25 : 0 > + > +#define DE_ALPHA 0x000048 > +#define DE_ALPHA_VALUE 7 : 0 > + > +#define DE_WRAP 0x00004C > +#define DE_WRAP_X 31 : 16 > +#define DE_WRAP_Y 15 : 0 > + > +#define DE_STATUS 0x000050 > +#define DE_STATUS_CSC 1 : 1 > +#define DE_STATUS_CSC_CLEAR 0 > +#define DE_STATUS_CSC_NOT_ACTIVE 0 > +#define DE_STATUS_CSC_ACTIVE 1 > +#define DE_STATUS_2D 0 : 0 > +#define DE_STATUS_2D_CLEAR 0 > +#define DE_STATUS_2D_NOT_ACTIVE 0 > +#define DE_STATUS_2D_ACTIVE 1 > + > +/* Color Space Conversion registers. */ > + > +#define CSC_Y_SOURCE_BASE 0x0000C8 > +#define CSC_Y_SOURCE_BASE_EXT 27 : 27 > +#define CSC_Y_SOURCE_BASE_EXT_LOCAL 0 > +#define CSC_Y_SOURCE_BASE_EXT_EXTERNAL 1 > +#define CSC_Y_SOURCE_BASE_CS 26 : 26 > +#define CSC_Y_SOURCE_BASE_CS_0 0 > +#define CSC_Y_SOURCE_BASE_CS_1 1 > +#define CSC_Y_SOURCE_BASE_ADDRESS 25 : 0 > + > +#define CSC_CONSTANTS 0x0000CC > +#define CSC_CONSTANTS_Y 31 : 24 > +#define CSC_CONSTANTS_R 23 : 16 > +#define CSC_CONSTANTS_G 15 : 8 > +#define CSC_CONSTANTS_B 7 : 0 > + > +#define CSC_Y_SOURCE_X 0x0000D0 > +#define CSC_Y_SOURCE_X_INTEGER 26 : 16 > +#define CSC_Y_SOURCE_X_FRACTION 15 : 3 > + > +#define CSC_Y_SOURCE_Y 0x0000D4 > +#define CSC_Y_SOURCE_Y_INTEGER 27 : 16 > +#define CSC_Y_SOURCE_Y_FRACTION 15 : 3 > + > +#define CSC_U_SOURCE_BASE 0x0000D8 > +#define CSC_U_SOURCE_BASE_EXT 27 : 27 > +#define CSC_U_SOURCE_BASE_EXT_LOCAL 0 > +#define CSC_U_SOURCE_BASE_EXT_EXTERNAL 1 > +#define CSC_U_SOURCE_BASE_CS 26 : 26 > +#define CSC_U_SOURCE_BASE_CS_0 0 > +#define CSC_U_SOURCE_BASE_CS_1 1 > +#define CSC_U_SOURCE_BASE_ADDRESS 25 : 0 > + > +#define CSC_V_SOURCE_BASE 0x0000DC > +#define CSC_V_SOURCE_BASE_EXT 27 : 27 > +#define CSC_V_SOURCE_BASE_EXT_LOCAL 0 > +#define CSC_V_SOURCE_BASE_EXT_EXTERNAL 1 > +#define CSC_V_SOURCE_BASE_CS 26 : 26 > +#define CSC_V_SOURCE_BASE_CS_0 0 > +#define CSC_V_SOURCE_BASE_CS_1 1 > +#define CSC_V_SOURCE_BASE_ADDRESS 25 : 0 > + > +#define CSC_SOURCE_DIMENSION 0x0000E0 > +#define CSC_SOURCE_DIMENSION_X 31 : 16 > +#define CSC_SOURCE_DIMENSION_Y 15 : 0 > + > +#define CSC_SOURCE_PITCH 0x0000E4 > +#define CSC_SOURCE_PITCH_Y 31 : 16 > +#define CSC_SOURCE_PITCH_UV 15 : 0 > + > +#define CSC_DESTINATION 0x0000E8 > +#define CSC_DESTINATION_WRAP 31 : 31 > +#define CSC_DESTINATION_WRAP_DISABLE 0 > +#define CSC_DESTINATION_WRAP_ENABLE 1 > +#define CSC_DESTINATION_X 27 : 16 > +#define CSC_DESTINATION_Y 11 : 0 > + > +#define CSC_DESTINATION_DIMENSION 0x0000EC > +#define CSC_DESTINATION_DIMENSION_X 31 : 16 > +#define CSC_DESTINATION_DIMENSION_Y 15 : 0 > + > +#define CSC_DESTINATION_PITCH 0x0000F0 > +#define CSC_DESTINATION_PITCH_X 31 : 16 > +#define CSC_DESTINATION_PITCH_Y 15 : 0 > + > +#define CSC_SCALE_FACTOR 0x0000F4 > +#define CSC_SCALE_FACTOR_HORIZONTAL 31 : 16 > +#define CSC_SCALE_FACTOR_VERTICAL 15 : 0 > + > +#define CSC_DESTINATION_BASE 0x0000F8 > +#define CSC_DESTINATION_BASE_EXT 27 : 27 > +#define CSC_DESTINATION_BASE_EXT_LOCAL 0 > +#define CSC_DESTINATION_BASE_EXT_EXTERNAL 1 > +#define CSC_DESTINATION_BASE_CS 26 : 26 > +#define CSC_DESTINATION_BASE_CS_0 0 > +#define CSC_DESTINATION_BASE_CS_1 1 > +#define CSC_DESTINATION_BASE_ADDRESS 25 : 0 > + > +#define CSC_CONTROL 0x0000FC > +#define CSC_CONTROL_STATUS 31 : 31 > +#define CSC_CONTROL_STATUS_STOP 0 > +#define CSC_CONTROL_STATUS_START 1 > +#define CSC_CONTROL_SOURCE_FORMAT 30 : 28 > +#define CSC_CONTROL_SOURCE_FORMAT_YUV422 0 > +#define CSC_CONTROL_SOURCE_FORMAT_YUV420I 1 > +#define CSC_CONTROL_SOURCE_FORMAT_YUV420 2 > +#define CSC_CONTROL_SOURCE_FORMAT_YVU9 3 > +#define CSC_CONTROL_SOURCE_FORMAT_IYU1 4 > +#define CSC_CONTROL_SOURCE_FORMAT_IYU2 5 > +#define CSC_CONTROL_SOURCE_FORMAT_RGB565 6 > +#define CSC_CONTROL_SOURCE_FORMAT_RGB8888 7 > +#define CSC_CONTROL_DESTINATION_FORMAT 27 : 26 > +#define CSC_CONTROL_DESTINATION_FORMAT_RGB565 0 > +#define CSC_CONTROL_DESTINATION_FORMAT_RGB8888 1 > +#define CSC_CONTROL_HORIZONTAL_FILTER 25 : 25 > +#define CSC_CONTROL_HORIZONTAL_FILTER_DISABLE 0 > +#define CSC_CONTROL_HORIZONTAL_FILTER_ENABLE 1 > +#define CSC_CONTROL_VERTICAL_FILTER 24 : 24 > +#define CSC_CONTROL_VERTICAL_FILTER_DISABLE 0 > +#define CSC_CONTROL_VERTICAL_FILTER_ENABLE 1 > +#define CSC_CONTROL_BYTE_ORDER 23 : 23 > +#define CSC_CONTROL_BYTE_ORDER_YUYV 0 > +#define CSC_CONTROL_BYTE_ORDER_UYVY 1 > + > +#define DE_DATA_PORT_501 0x110000 > +#define DE_DATA_PORT_712 0x400000 > +#define DE_DATA_PORT_722 0x6000 > + > +/* point to virtual Memory Map IO starting address */ > +extern char *smtc_RegBaseAddress; > +/* point to virtual video memory starting address */ > +extern char *smtc_VRAMBaseAddress; > +extern unsigned char smtc_de_busy; > + > +extern unsigned long memRead32(unsigned long nOffset); > +extern void memWrite32(unsigned long nOffset, unsigned long nData); > +extern unsigned long SMTC_read2Dreg(unsigned long nOffset); > + > +/* 2D functions */ > +extern void deInit(unsigned int nModeWidth, unsigned int nModeHeight, > + unsigned int bpp); > + > +extern void deWaitForNotBusy(void); > + > +extern void deVerticalLine(unsigned long dst_base, > + unsigned long dst_pitch, > + unsigned long nX, > + unsigned long nY, > + unsigned long dst_height, > + unsigned long nColor); > + > +extern void deHorizontalLine(unsigned long dst_base, > + unsigned long dst_pitch, > + unsigned long nX, > + unsigned long nY, > + unsigned long dst_width, > + unsigned long nColor); > + > +extern void deLine(unsigned long dst_base, > + unsigned long dst_pitch, > + unsigned long nX1, > + unsigned long nY1, > + unsigned long nX2, > + unsigned long nY2, > + unsigned long nColor); > + > +extern void deFillRect(unsigned long dst_base, > + unsigned long dst_pitch, > + unsigned long dst_X, > + unsigned long dst_Y, > + unsigned long dst_width, > + unsigned long dst_height, > + unsigned long nColor); > + > +extern void deRotatePattern(unsigned char *pattern_dstaddr, > + unsigned long pattern_src_addr, > + unsigned long pattern_BPP, > + unsigned long pattern_stride, > + int patternX, > + int patternY); > + > +extern void deCopy(unsigned long dst_base, > + unsigned long dst_pitch, > + unsigned long dst_BPP, > + unsigned long dst_X, > + unsigned long dst_Y, > + unsigned long dst_width, > + unsigned long dst_height, > + unsigned long src_base, > + unsigned long src_pitch, > + unsigned long src_X, > + unsigned long src_Y, > + pTransparent pTransp, > + unsigned char nROP2); > + > +/* > + * System memory to Video memory monochrome expansion. > + * > + * Source is monochrome image in system memory. This function expands the > + * monochrome data to color image in video memory. > + * > + * @pSrcbuf: pointer to start of source buffer in system memory > + * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top > + * down and -ive mean button up > + * @startBit: Mono data can start at any bit in a byte, this value should > + * be 0 to 7 > + * @dBase: Address of destination : offset in frame buffer > + * @dPitch: Pitch value of destination surface in BYTE > + * @bpp: Color depth of destination surface > + * @dx, dy: Starting coordinate of destination surface > + * @width, height: width and height of rectange in pixel value > + * @fColor,bColor: Foreground, Background color (corresponding to a 1, 0 in > + * the monochrome data) > + * @rop2: ROP value > + */ > + > +extern long deSystemMem2VideoMemMonoBlt( > + const char *pSrcbuf, > + long srcDelta, > + unsigned long startBit, > + unsigned long dBase, > + unsigned long dPitch, > + unsigned long bpp, > + unsigned long dx, unsigned long dy, > + unsigned long width, unsigned long height, > + unsigned long fColor, > + unsigned long bColor, > + unsigned long rop2); > + > +extern unsigned long deGetTransparency(void); > +extern void deSetPixelFormat(unsigned long bpp); > diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c > new file mode 100644 > index 0000000..161dbc9 > --- /dev/null > +++ b/drivers/staging/sm7xx/smtcfb.c > @@ -0,0 +1,1253 @@ > +/* > + * Silicon Motion SM7XX frame buffer device > + * > + * Copyright (C) 2006 Silicon Motion Technology Corp. > + * Authors: Ge Wang, gewang@xxxxxxxxxxxxxxxxx > + * Boyod boyod.yang@xxxxxxxxxxxxxxxxxxxx > + * > + * Copyright (C) 2009 Lemote, Inc. > + * Author: Wu Zhangjin, wuzj@xxxxxxxxxx > + * > + * This file is subject to the terms and conditions of the GNU General Public > + * License. See the file COPYING in the main directory of this archive for > + * more details. > + * > + * Version 0.10.26192.21.01 > + * - Add PowerPC/Big endian support > + * - Add 2D support for Lynx > + * - Verified on2.6.19.2 Boyod.yang <boyod.yang@xxxxxxxxxxxxxxxxxxxx> > + * > + * Version 0.09.2621.00.01 > + * - Only support Linux Kernel's version 2.6.21. > + * Boyod.yang <boyod.yang@xxxxxxxxxxxxxxxxxxxx> > + * > + * Version 0.09 > + * - Only support Linux Kernel's version 2.6.12. > + * Boyod.yang <boyod.yang@xxxxxxxxxxxxxxxxxxxx> > + */ > + > +#ifndef __KERNEL__ > +#define __KERNEL__ > +#endif > + > +#include <linux/io.h> > +#include <linux/fb.h> > +#include <linux/pci.h> > +#include <linux/init.h> > +#include <linux/uaccess.h> > +#include <linux/console.h> > +#include <linux/screen_info.h> > + > +#ifdef CONFIG_PM > +#include <linux/pm.h> > +#endif > + > +struct screen_info smtc_screen_info; > + > +#include "smtcfb.h" > +#include "smtc2d.h" > + > +#ifdef DEBUG > +#define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg) > +#else > +#define smdbg(format, arg...) > +#endif > + > +/* > +* Private structure > +*/ > +struct smtcfb_info { > + /* > + * The following is a pointer to be passed into the > + * functions below. The modules outside the main > + * voyager.c driver have no knowledge as to what > + * is within this structure. > + */ > + struct fb_info fb; > + struct display_switch *dispsw; > + struct pci_dev *dev; > + signed int currcon; > + > + struct { > + u8 red, green, blue; > + } palette[NR_RGB]; > + > + u_int palette_size; > +}; > + > +struct par_info { > + /* > + * Hardware > + */ > + u16 chipID; > + unsigned char __iomem *m_pMMIO; > + char __iomem *m_pLFB; > + char *m_pDPR; > + char *m_pVPR; > + char *m_pCPR; > + > + u_int width; > + u_int height; > + u_int hz; > + u_long BaseAddressInVRAM; > + u8 chipRevID; > +}; > + > +struct vesa_mode_table { > + char mode_index[6]; > + u16 lfb_width; > + u16 lfb_height; > + u16 lfb_depth; > +}; > + > +static struct vesa_mode_table vesa_mode[] = { > + {"0x301", 640, 480, 8}, > + {"0x303", 800, 600, 8}, > + {"0x305", 1024, 768, 8}, > + {"0x307", 1280, 1024, 8}, > + > + {"0x311", 640, 480, 16}, > + {"0x314", 800, 600, 16}, > + {"0x317", 1024, 768, 16}, > + {"0x31A", 1280, 1024, 16}, > + > + {"0x312", 640, 480, 24}, > + {"0x315", 800, 600, 24}, > + {"0x318", 1024, 768, 24}, > + {"0x31B", 1280, 1024, 24}, > +}; > + > +char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */ > +char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */ > + > +char *smtc_2DBaseAddress; /* 2D engine starting address */ > +char *smtc_2Ddataport; /* 2D data port offset */ > +short smtc_2Dacceleration; > + > +static u32 colreg[17]; > +static struct par_info hw; /* hardware information */ > + > +u16 smtc_ChipIDs[] = { > + 0x710, > + 0x712, > + 0x720 > +}; > + > +#define numSMTCchipIDs (sizeof(smtc_ChipIDs) / sizeof(u16)) > + > +void deWaitForNotBusy(void) > +{ > + unsigned long i = 0x1000000; > + while (i--) { > + if ((smtc_seqr(0x16) & 0x18) == 0x10) > + break; > + } > + smtc_de_busy = 0; > +} > + > +static void sm712_set_timing(struct smtcfb_info *sfb, > + struct par_info *ppar_info) > +{ > + int i = 0, j = 0; > + u32 m_nScreenStride; > + > + smdbg("\nppar_info->width = %d ppar_info->height = %d" > + "sfb->fb.var.bits_per_pixel = %d ppar_info->hz = %d\n", > + ppar_info->width, ppar_info->height, > + sfb->fb.var.bits_per_pixel, ppar_info->hz); > + > + for (j = 0; j < numVGAModes; j++) { > + if (VGAMode[j].mmSizeX == ppar_info->width && > + VGAMode[j].mmSizeY == ppar_info->height && > + VGAMode[j].bpp == sfb->fb.var.bits_per_pixel && > + VGAMode[j].hz == ppar_info->hz) { > + > + smdbg("\nVGAMode[j].mmSizeX = %d VGAMode[j].mmSizeY =" > + "%d VGAMode[j].bpp = %d" > + "VGAMode[j].hz=%d\n", > + VGAMode[j].mmSizeX, VGAMode[j].mmSizeY, > + VGAMode[j].bpp, VGAMode[j].hz); > + > + smdbg("VGAMode index=%d\n", j); > + > + smtc_mmiowb(0x0, 0x3c6); > + > + smtc_seqw(0, 0x1); > + > + smtc_mmiowb(VGAMode[j].Init_MISC, 0x3c2); > + > + /* init SEQ register SR00 - SR04 */ > + for (i = 0; i < SIZE_SR00_SR04; i++) > + smtc_seqw(i, VGAMode[j].Init_SR00_SR04[i]); > + > + /* init SEQ register SR10 - SR24 */ > + for (i = 0; i < SIZE_SR10_SR24; i++) > + smtc_seqw(i + 0x10, > + VGAMode[j].Init_SR10_SR24[i]); > + > + /* init SEQ register SR30 - SR75 */ > + for (i = 0; i < SIZE_SR30_SR75; i++) > + if (((i + 0x30) != 0x62) \ > + && ((i + 0x30) != 0x6a) \ > + && ((i + 0x30) != 0x6b)) > + smtc_seqw(i + 0x30, > + VGAMode[j].Init_SR30_SR75[i]); > + > + /* init SEQ register SR80 - SR93 */ > + for (i = 0; i < SIZE_SR80_SR93; i++) > + smtc_seqw(i + 0x80, > + VGAMode[j].Init_SR80_SR93[i]); > + > + /* init SEQ register SRA0 - SRAF */ > + for (i = 0; i < SIZE_SRA0_SRAF; i++) > + smtc_seqw(i + 0xa0, > + VGAMode[j].Init_SRA0_SRAF[i]); > + > + /* init Graphic register GR00 - GR08 */ > + for (i = 0; i < SIZE_GR00_GR08; i++) > + smtc_grphw(i, VGAMode[j].Init_GR00_GR08[i]); > + > + /* init Attribute register AR00 - AR14 */ > + for (i = 0; i < SIZE_AR00_AR14; i++) > + smtc_attrw(i, VGAMode[j].Init_AR00_AR14[i]); > + > + /* init CRTC register CR00 - CR18 */ > + for (i = 0; i < SIZE_CR00_CR18; i++) > + smtc_crtcw(i, VGAMode[j].Init_CR00_CR18[i]); > + > + /* init CRTC register CR30 - CR4D */ > + for (i = 0; i < SIZE_CR30_CR4D; i++) > + smtc_crtcw(i + 0x30, > + VGAMode[j].Init_CR30_CR4D[i]); > + > + /* init CRTC register CR90 - CRA7 */ > + for (i = 0; i < SIZE_CR90_CRA7; i++) > + smtc_crtcw(i + 0x90, > + VGAMode[j].Init_CR90_CRA7[i]); > + } > + } > + smtc_mmiowb(0x67, 0x3c2); > + > + /* set VPR registers */ > + writel(0x0, ppar_info->m_pVPR + 0x0C); > + writel(0x0, ppar_info->m_pVPR + 0x40); > + > + /* set data width */ > + m_nScreenStride = > + (ppar_info->width * sfb->fb.var.bits_per_pixel) / 64; > + switch (sfb->fb.var.bits_per_pixel) { > + case 8: > + writel(0x0, ppar_info->m_pVPR + 0x0); > + break; > + case 16: > + writel(0x00020000, ppar_info->m_pVPR + 0x0); > + break; > + case 24: > + writel(0x00040000, ppar_info->m_pVPR + 0x0); > + break; > + case 32: > + writel(0x00030000, ppar_info->m_pVPR + 0x0); > + break; > + } > + writel((u32) (((m_nScreenStride + 2) << 16) | m_nScreenStride), > + ppar_info->m_pVPR + 0x10); > + > +} > + > +static void sm712_setpalette(int regno, unsigned red, unsigned green, > + unsigned blue, struct fb_info *info) > +{ > + struct par_info *cur_par = (struct par_info *)info->par; > + > + if (cur_par->BaseAddressInVRAM) > + /* > + * second display palette for dual head. Enable CRT RAM, 6-bit > + * RAM > + */ > + smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x20); > + else > + /* primary display palette. Enable LCD RAM only, 6-bit RAM */ > + smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x10); > + smtc_mmiowb(regno, dac_reg); > + smtc_mmiowb(red >> 10, dac_val); > + smtc_mmiowb(green >> 10, dac_val); > + smtc_mmiowb(blue >> 10, dac_val); > +} > + > +static void smtc_set_timing(struct smtcfb_info *sfb, struct par_info > + *ppar_info) > +{ > + switch (ppar_info->chipID) { > + case 0x710: > + case 0x712: > + case 0x720: > + sm712_set_timing(sfb, ppar_info); > + break; > + } > +} > + > +static struct fb_var_screeninfo smtcfb_var = { > + .xres = 1024, > + .yres = 600, > + .xres_virtual = 1024, > + .yres_virtual = 600, > + .bits_per_pixel = 16, > + .red = {16, 8, 0}, > + .green = {8, 8, 0}, > + .blue = {0, 8, 0}, > + .activate = FB_ACTIVATE_NOW, > + .height = -1, > + .width = -1, > + .vmode = FB_VMODE_NONINTERLACED, > +}; > + > +static struct fb_fix_screeninfo smtcfb_fix = { > + .id = "sm712fb", > + .type = FB_TYPE_PACKED_PIXELS, > + .visual = FB_VISUAL_TRUECOLOR, > + .line_length = 800 * 3, > + .accel = FB_ACCEL_SMI_LYNX, > +}; > + > +/* chan_to_field > + * > + * convert a colour value into a field position > + * > + * from pxafb.c > + */ > + > +static inline unsigned int chan_to_field(unsigned int chan, > + struct fb_bitfield *bf) > +{ > + chan &= 0xffff; > + chan >>= 16 - bf->length; > + return chan << bf->offset; > +} > + > +static int smtcfb_blank(int blank_mode, struct fb_info *info) > +{ > + /* clear DPMS setting */ > + switch (blank_mode) { > + case FB_BLANK_UNBLANK: > + /* Screen On: HSync: On, VSync : On */ > + smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20))); > + smtc_seqw(0x6a, 0x16); > + smtc_seqw(0x6b, 0x02); > + smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77)); > + smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30))); > + smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0))); > + smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01)); > + smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03)); > + break; > + case FB_BLANK_NORMAL: > + /* Screen Off: HSync: On, VSync : On Soft blank */ > + smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20))); > + smtc_seqw(0x6a, 0x16); > + smtc_seqw(0x6b, 0x02); > + smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30))); > + smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0))); > + smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01)); > + smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); > + break; > + case FB_BLANK_VSYNC_SUSPEND: > + /* Screen On: HSync: On, VSync : Off */ > + smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); > + smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); > + smtc_seqw(0x6a, 0x0c); > + smtc_seqw(0x6b, 0x02); > + smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); > + smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20)); > + smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20)); > + smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); > + smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); > + smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); > + break; > + case FB_BLANK_HSYNC_SUSPEND: > + /* Screen On: HSync: Off, VSync : On */ > + smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); > + smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); > + smtc_seqw(0x6a, 0x0c); > + smtc_seqw(0x6b, 0x02); > + smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); > + smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10)); > + smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8)); > + smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); > + smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); > + smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); > + break; > + case FB_BLANK_POWERDOWN: > + /* Screen On: HSync: Off, VSync : Off */ > + smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); > + smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); > + smtc_seqw(0x6a, 0x0c); > + smtc_seqw(0x6b, 0x02); > + smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); > + smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30)); > + smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8)); > + smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); > + smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); > + smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); > + break; > + default: > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green, > + unsigned blue, unsigned trans, struct fb_info *info) > +{ > + struct smtcfb_info *sfb = (struct smtcfb_info *)info; > + u32 val; > + > + if (regno > 255) > + return 1; > + > + switch (sfb->fb.fix.visual) { > + case FB_VISUAL_DIRECTCOLOR: > + case FB_VISUAL_TRUECOLOR: > + /* > + * 16/32 bit true-colour, use pseuo-palette for 16 base color > + */ > + if (regno < 16) { > + if (sfb->fb.var.bits_per_pixel == 16) { > + u32 *pal = sfb->fb.pseudo_palette; > + val = chan_to_field(red, &sfb->fb.var.red); > + val |= chan_to_field(green, \ > + &sfb->fb.var.green); > + val |= chan_to_field(blue, &sfb->fb.var.blue); > +#ifdef __BIG_ENDIAN > + pal[regno] = > + ((red & 0xf800) >> 8) | > + ((green & 0xe000) >> 13) | > + ((green & 0x1c00) << 3) | > + ((blue & 0xf800) >> 3); > +#else > + pal[regno] = val; > +#endif > + } else { > + u32 *pal = sfb->fb.pseudo_palette; > + val = chan_to_field(red, &sfb->fb.var.red); > + val |= chan_to_field(green, \ > + &sfb->fb.var.green); > + val |= chan_to_field(blue, &sfb->fb.var.blue); > +#ifdef __BIG_ENDIAN > + val = > + (val & 0xff00ff00 >> 8) | > + (val & 0x00ff00ff << 8); > +#endif > + pal[regno] = val; > + } > + } > + break; > + > + case FB_VISUAL_PSEUDOCOLOR: > + /* color depth 8 bit */ > + sm712_setpalette(regno, red, green, blue, info); > + break; > + > + default: > + return 1; /* unknown type */ > + } > + > + return 0; > + > +} > + > +#ifdef __BIG_ENDIAN > +static ssize_t smtcfb_read(struct fb_info *info, char __user * buf, size_t > + count, loff_t *ppos) > +{ > + unsigned long p = *ppos; > + > + u32 *buffer, *dst; > + u32 __iomem *src; > + int c, i, cnt = 0, err = 0; > + unsigned long total_size; > + > + if (!info || !info->screen_base) > + return -ENODEV; > + > + if (info->state != FBINFO_STATE_RUNNING) > + return -EPERM; > + > + total_size = info->screen_size; > + > + if (total_size == 0) > + total_size = info->fix.smem_len; > + > + if (p >= total_size) > + return 0; > + > + if (count >= total_size) > + count = total_size; > + > + if (count + p > total_size) > + count = total_size - p; > + > + buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); > + if (!buffer) > + return -ENOMEM; > + > + src = (u32 __iomem *) (info->screen_base + p); > + > + if (info->fbops->fb_sync) > + info->fbops->fb_sync(info); > + > + while (count) { > + c = (count > PAGE_SIZE) ? PAGE_SIZE : count; > + dst = buffer; > + for (i = c >> 2; i--;) { > + *dst = fb_readl(src++); > + *dst = > + (*dst & 0xff00ff00 >> 8) | > + (*dst & 0x00ff00ff << 8); > + dst++; > + } > + if (c & 3) { > + u8 *dst8 = (u8 *) dst; > + u8 __iomem *src8 = (u8 __iomem *) src; > + > + for (i = c & 3; i--;) { > + if (i & 1) { > + *dst8++ = fb_readb(++src8); > + } else { > + *dst8++ = fb_readb(--src8); > + src8 += 2; > + } > + } > + src = (u32 __iomem *) src8; > + } > + > + if (copy_to_user(buf, buffer, c)) { > + err = -EFAULT; > + break; > + } > + *ppos += c; > + buf += c; > + cnt += c; > + count -= c; > + } > + > + kfree(buffer); > + > + return (err) ? err : cnt; > +} > + > +static ssize_t > +smtcfb_write(struct fb_info *info, const char __user *buf, size_t count, > + loff_t *ppos) > +{ > + unsigned long p = *ppos; > + > + u32 *buffer, *src; > + u32 __iomem *dst; > + int c, i, cnt = 0, err = 0; > + unsigned long total_size; > + > + if (!info || !info->screen_base) > + return -ENODEV; > + > + if (info->state != FBINFO_STATE_RUNNING) > + return -EPERM; > + > + total_size = info->screen_size; > + > + if (total_size == 0) > + total_size = info->fix.smem_len; > + > + if (p > total_size) > + return -EFBIG; > + > + if (count > total_size) { > + err = -EFBIG; > + count = total_size; > + } > + > + if (count + p > total_size) { > + if (!err) > + err = -ENOSPC; > + > + count = total_size - p; > + } > + > + buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); > + if (!buffer) > + return -ENOMEM; > + > + dst = (u32 __iomem *) (info->screen_base + p); > + > + if (info->fbops->fb_sync) > + info->fbops->fb_sync(info); > + > + while (count) { > + c = (count > PAGE_SIZE) ? PAGE_SIZE : count; > + src = buffer; > + > + if (copy_from_user(src, buf, c)) { > + err = -EFAULT; > + break; > + } > + > + for (i = c >> 2; i--;) { > + fb_writel((*src & 0xff00ff00 >> 8) | > + (*src & 0x00ff00ff << 8), dst++); > + src++; > + } > + if (c & 3) { > + u8 *src8 = (u8 *) src; > + u8 __iomem *dst8 = (u8 __iomem *) dst; > + > + for (i = c & 3; i--;) { > + if (i & 1) { > + fb_writeb(*src8++, ++dst8); > + } else { > + fb_writeb(*src8++, --dst8); > + dst8 += 2; > + } > + } > + dst = (u32 __iomem *) dst8; > + } > + > + *ppos += c; > + buf += c; > + cnt += c; > + count -= c; > + } > + > + kfree(buffer); > + > + return (cnt) ? cnt : err; > +} > +#endif /* ! __BIG_ENDIAN */ > + > +#include "smtc2d.c" > + > +void smtcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) > +{ > + struct par_info *p = (struct par_info *)info->par; > + > + if (smtc_2Dacceleration) { > + if (!area->width || !area->height) > + return; > + > + deCopy(p->BaseAddressInVRAM, 0, info->var.bits_per_pixel, > + area->dx, area->dy, area->width, area->height, > + p->BaseAddressInVRAM, 0, area->sx, area->sy, 0, 0xC); > + > + } else > + cfb_copyarea(info, area); > +} > + > +void smtcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) > +{ > + struct par_info *p = (struct par_info *)info->par; > + > + if (smtc_2Dacceleration) { > + if (!rect->width || !rect->height) > + return; > + if (info->var.bits_per_pixel >= 24) > + deFillRect(p->BaseAddressInVRAM, 0, rect->dx * 3, > + rect->dy * 3, rect->width * 3, rect->height, > + rect->color); > + else > + deFillRect(p->BaseAddressInVRAM, 0, rect->dx, rect->dy, > + rect->width, rect->height, rect->color); > + } else > + cfb_fillrect(info, rect); > +} > + > +void smtcfb_imageblit(struct fb_info *info, const struct fb_image *image) > +{ > + struct par_info *p = (struct par_info *)info->par; > + u32 bg_col = 0, fg_col = 0; > + > + if ((smtc_2Dacceleration) && (image->depth == 1)) { > + if (smtc_de_busy) > + deWaitForNotBusy(); > + > + switch (info->var.bits_per_pixel) { > + case 8: > + bg_col = image->bg_color; > + fg_col = image->fg_color; > + break; > + case 16: > + bg_col = > + ((u32 *) (info->pseudo_palette))[image->bg_color]; > + fg_col = > + ((u32 *) (info->pseudo_palette))[image->fg_color]; > + break; > + case 32: > + bg_col = > + ((u32 *) (info->pseudo_palette))[image->bg_color]; > + fg_col = > + ((u32 *) (info->pseudo_palette))[image->fg_color]; > + break; > + } > + > + deSystemMem2VideoMemMonoBlt( > + image->data, > + image->width / 8, > + 0, > + p->BaseAddressInVRAM, > + 0, > + 0, > + image->dx, image->dy, > + image->width, image->height, > + fg_col, bg_col, > + 0x0C); > + > + } else > + cfb_imageblit(info, image); > +} > + > +static struct fb_ops smtcfb_ops = { > + .owner = THIS_MODULE, > + .fb_setcolreg = smtc_setcolreg, > + .fb_blank = smtcfb_blank, > + .fb_fillrect = smtcfb_fillrect, > + .fb_imageblit = smtcfb_imageblit, > + .fb_copyarea = smtcfb_copyarea, > +#ifdef __BIG_ENDIAN > + .fb_read = smtcfb_read, > + .fb_write = smtcfb_write, > +#endif > + > +}; > + > +void smtcfb_setmode(struct smtcfb_info *sfb) > +{ > + switch (sfb->fb.var.bits_per_pixel) { > + case 32: > + sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; > + sfb->fb.fix.line_length = sfb->fb.var.xres * 4; > + sfb->fb.var.red.length = 8; > + sfb->fb.var.green.length = 8; > + sfb->fb.var.blue.length = 8; > + sfb->fb.var.red.offset = 16; > + sfb->fb.var.green.offset = 8; > + sfb->fb.var.blue.offset = 0; > + > + break; > + case 8: > + sfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; > + sfb->fb.fix.line_length = sfb->fb.var.xres; > + sfb->fb.var.red.offset = 5; > + sfb->fb.var.red.length = 3; > + sfb->fb.var.green.offset = 2; > + sfb->fb.var.green.length = 3; > + sfb->fb.var.blue.offset = 0; > + sfb->fb.var.blue.length = 2; > + break; > + case 24: > + sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; > + sfb->fb.fix.line_length = sfb->fb.var.xres * 3; > + sfb->fb.var.red.length = 8; > + sfb->fb.var.green.length = 8; > + sfb->fb.var.blue.length = 8; > + > + sfb->fb.var.red.offset = 16; > + sfb->fb.var.green.offset = 8; > + sfb->fb.var.blue.offset = 0; > + > + break; > + case 16: > + default: > + sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; > + sfb->fb.fix.line_length = sfb->fb.var.xres * 2; > + > + sfb->fb.var.red.length = 5; > + sfb->fb.var.green.length = 6; > + sfb->fb.var.blue.length = 5; > + > + sfb->fb.var.red.offset = 11; > + sfb->fb.var.green.offset = 5; > + sfb->fb.var.blue.offset = 0; > + > + break; > + } > + > + hw.width = sfb->fb.var.xres; > + hw.height = sfb->fb.var.yres; > + hw.hz = 60; > + smtc_set_timing(sfb, &hw); > + if (smtc_2Dacceleration) { > + printk("2D acceleration enabled!\n"); > + /* Init smtc drawing engine */ > + deInit(sfb->fb.var.xres, sfb->fb.var.yres, > + sfb->fb.var.bits_per_pixel); > + } > +} > + > +/* > + * Alloc struct smtcfb_info and assign the default value > + */ > +static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *dev, > + char *name) > +{ > + struct smtcfb_info *sfb; > + > + sfb = kmalloc(sizeof(struct smtcfb_info), GFP_KERNEL); > + > + if (!sfb) > + return NULL; > + > + memset(sfb, 0, sizeof(struct smtcfb_info)); > + > + sfb->currcon = -1; > + sfb->dev = dev; > + > + /*** Init sfb->fb with default value ***/ > + sfb->fb.flags = FBINFO_FLAG_DEFAULT; > + sfb->fb.fbops = &smtcfb_ops; > + sfb->fb.var = smtcfb_var; > + sfb->fb.fix = smtcfb_fix; > + > + strcpy(sfb->fb.fix.id, name); > + > + sfb->fb.fix.type = FB_TYPE_PACKED_PIXELS; > + sfb->fb.fix.type_aux = 0; > + sfb->fb.fix.xpanstep = 0; > + sfb->fb.fix.ypanstep = 0; > + sfb->fb.fix.ywrapstep = 0; > + sfb->fb.fix.accel = FB_ACCEL_SMI_LYNX; > + > + sfb->fb.var.nonstd = 0; > + sfb->fb.var.activate = FB_ACTIVATE_NOW; > + sfb->fb.var.height = -1; > + sfb->fb.var.width = -1; > + /* text mode acceleration */ > + sfb->fb.var.accel_flags = FB_ACCELF_TEXT; > + sfb->fb.var.vmode = FB_VMODE_NONINTERLACED; > + sfb->fb.par = &hw; > + sfb->fb.pseudo_palette = colreg; > + > + return sfb; > +} > + > +/* > + * Unmap in the memory mapped IO registers > + */ > + > +static void smtc_unmap_mmio(struct smtcfb_info *sfb) > +{ > + if (sfb && smtc_RegBaseAddress) > + smtc_RegBaseAddress = NULL; > +} > + > +/* > + * Map in the screen memory > + */ > + > +static int smtc_map_smem(struct smtcfb_info *sfb, > + struct pci_dev *dev, u_long smem_len) > +{ > + if (sfb->fb.var.bits_per_pixel == 32) { > +#ifdef __BIG_ENDIAN > + sfb->fb.fix.smem_start = pci_resource_start(dev, 0) > + + 0x800000; > +#else > + sfb->fb.fix.smem_start = pci_resource_start(dev, 0); > +#endif > + } else { > + sfb->fb.fix.smem_start = pci_resource_start(dev, 0); > + } > + > + sfb->fb.fix.smem_len = smem_len; > + > + sfb->fb.screen_base = smtc_VRAMBaseAddress; > + > + if (!sfb->fb.screen_base) { > + printk(KERN_INFO "%s: unable to map screen memory\n", > + sfb->fb.fix.id); > + return -ENOMEM; > + } > + > + return 0; > +} > + > +/* > + * Unmap in the screen memory > + * > + */ > +static void smtc_unmap_smem(struct smtcfb_info *sfb) > +{ > + if (sfb && sfb->fb.screen_base) { > + iounmap(sfb->fb.screen_base); > + sfb->fb.screen_base = NULL; > + } > +} > + > +/* > + * We need to wake up the LynxEM+, and make sure its in linear memory mode. > + */ > +static inline void sm7xx_init_hw(void) > +{ > + outb_p(0x18, 0x3c4); > + outb_p(0x11, 0x3c5); > +} > + > +static void smtc_free_fb_info(struct smtcfb_info *sfb) > +{ > + if (sfb) { > + fb_alloc_cmap(&sfb->fb.cmap, 0, 0); > + kfree(sfb); > + } > +} > + > +/* > + * sm712vga_setup - process command line options, get vga parameter > + * @options: string of options > + * Returns zero. > + * > + */ > +static int __init __maybe_unused sm712vga_setup(char *options) > +{ > + int index; > + > + if (!options || !*options) { > + smdbg("\n No vga parameter\n"); > + return -EINVAL; > + } > + > + smtc_screen_info.lfb_width = 0; > + smtc_screen_info.lfb_height = 0; > + smtc_screen_info.lfb_depth = 0; > + > + smdbg("\nsm712vga_setup = %s\n", options); > + > + for (index = 0; > + index < (sizeof(vesa_mode) / sizeof(struct vesa_mode_table)); > + index++) { > + if (strstr(options, vesa_mode[index].mode_index)) { > + smtc_screen_info.lfb_width = vesa_mode[index].lfb_width; > + smtc_screen_info.lfb_height = > + vesa_mode[index].lfb_height; > + smtc_screen_info.lfb_depth = vesa_mode[index].lfb_depth; > + return 0; > + } > + } > + > + return -1; > +} > +__setup("vga=", sm712vga_setup); > + > +/* Jason (08/13/2009) > + * Original init function changed to probe method to be used by pci_drv > + * process used to detect chips replaced with kernel process in pci_drv > + */ > +static int __init smtcfb_pci_probe(struct pci_dev *pdev, > + const struct pci_device_id *ent) > +{ > + struct smtcfb_info *sfb; > + u_long smem_size = 0x00800000; /* default 8MB */ > + char name[16]; > + int err; > + unsigned long pFramebufferPhysical; > + > + printk(KERN_INFO > + "Silicon Motion display driver " SMTC_LINUX_FB_VERSION "\n"); > + > + err = pci_enable_device(pdev); /* enable SMTC chip */ > + > + if (err) > + return err; > + err = -ENOMEM; > + > + hw.chipID = ent->device; > + sprintf(name, "sm%Xfb", hw.chipID); > + > + sfb = smtc_alloc_fb_info(pdev, name); > + > + if (!sfb) > + goto failed; > + /* Jason (08/13/2009) > + * Store fb_info to be further used when suspending and resuming > + */ > + pci_set_drvdata(pdev, sfb); > + > + sm7xx_init_hw(); > + > + /*get mode parameter from smtc_screen_info */ > + if (smtc_screen_info.lfb_width != 0) { > + sfb->fb.var.xres = smtc_screen_info.lfb_width; > + sfb->fb.var.yres = smtc_screen_info.lfb_height; > + sfb->fb.var.bits_per_pixel = smtc_screen_info.lfb_depth; > + } else { > + /* default resolution 1024x600 16bit mode */ > + sfb->fb.var.xres = SCREEN_X_RES; > + sfb->fb.var.yres = SCREEN_Y_RES; > + sfb->fb.var.bits_per_pixel = SCREEN_BPP; > + } > + > +#ifdef __BIG_ENDIAN > + if (sfb->fb.var.bits_per_pixel == 24) > + sfb->fb.var.bits_per_pixel = (smtc_screen_info.lfb_depth = 32); > +#endif > + /* Map address and memory detection */ > + pFramebufferPhysical = pci_resource_start(pdev, 0); > + pci_read_config_byte(pdev, PCI_REVISION_ID, &hw.chipRevID); > + > + switch (hw.chipID) { > + case 0x710: > + case 0x712: > + sfb->fb.fix.mmio_start = pFramebufferPhysical + 0x00400000; > + sfb->fb.fix.mmio_len = 0x00400000; > + smem_size = SM712_VIDEOMEMORYSIZE; > +#ifdef __BIG_ENDIAN > + hw.m_pLFB = (smtc_VRAMBaseAddress = > + ioremap(pFramebufferPhysical, 0x00c00000)); > +#else > + hw.m_pLFB = (smtc_VRAMBaseAddress = > + ioremap(pFramebufferPhysical, 0x00800000)); > +#endif > + hw.m_pMMIO = (smtc_RegBaseAddress = > + smtc_VRAMBaseAddress + 0x00700000); > + smtc_2DBaseAddress = (hw.m_pDPR = > + smtc_VRAMBaseAddress + 0x00408000); > + smtc_2Ddataport = smtc_VRAMBaseAddress + DE_DATA_PORT_712; > + hw.m_pVPR = hw.m_pLFB + 0x0040c000; > +#ifdef __BIG_ENDIAN > + if (sfb->fb.var.bits_per_pixel == 32) { > + smtc_VRAMBaseAddress += 0x800000; > + hw.m_pLFB += 0x800000; > + printk(KERN_INFO > + "\nsmtc_VRAMBaseAddress=%p hw.m_pLFB=%p\n", > + smtc_VRAMBaseAddress, hw.m_pLFB); > + } > +#endif > + if (!smtc_RegBaseAddress) { > + printk(KERN_INFO > + "%s: unable to map memory mapped IO\n", > + sfb->fb.fix.id); > + return -ENOMEM; > + } > + > + /* set MCLK = 14.31818 * (0x16 / 0x2) */ > + smtc_seqw(0x6a, 0x16); > + smtc_seqw(0x6b, 0x02); > + smtc_seqw(0x62, 0x3e); > + /* enable PCI burst */ > + smtc_seqw(0x17, 0x20); > + /* enable word swap */ > +#ifdef __BIG_ENDIAN > + if (sfb->fb.var.bits_per_pixel == 32) > + smtc_seqw(0x17, 0x30); > +#endif > +#ifdef CONFIG_FB_SM7XX_ACCEL > + smtc_2Dacceleration = 1; > +#endif > + break; > + case 0x720: > + sfb->fb.fix.mmio_start = pFramebufferPhysical; > + sfb->fb.fix.mmio_len = 0x00200000; > + smem_size = SM722_VIDEOMEMORYSIZE; > + smtc_2DBaseAddress = (hw.m_pDPR = > + ioremap(pFramebufferPhysical, 0x00a00000)); > + hw.m_pLFB = (smtc_VRAMBaseAddress = > + smtc_2DBaseAddress + 0x00200000); > + hw.m_pMMIO = (smtc_RegBaseAddress = > + smtc_2DBaseAddress + 0x000c0000); > + smtc_2Ddataport = smtc_2DBaseAddress + DE_DATA_PORT_722; > + hw.m_pVPR = smtc_2DBaseAddress + 0x800; > + > + smtc_seqw(0x62, 0xff); > + smtc_seqw(0x6a, 0x0d); > + smtc_seqw(0x6b, 0x02); > + smtc_2Dacceleration = 0; > + break; > + default: > + printk(KERN_INFO > + "No valid Silicon Motion display chip was detected!\n"); > + > + smtc_free_fb_info(sfb); > + return err; > + } > + > + /* can support 32 bpp */ > + if (15 == sfb->fb.var.bits_per_pixel) > + sfb->fb.var.bits_per_pixel = 16; > + > + sfb->fb.var.xres_virtual = sfb->fb.var.xres; > + sfb->fb.var.yres_virtual = sfb->fb.var.yres; > + err = smtc_map_smem(sfb, pdev, smem_size); > + if (err) > + goto failed; > + > + smtcfb_setmode(sfb); > + /* Primary display starting from 0 postion */ > + hw.BaseAddressInVRAM = 0; > + sfb->fb.par = &hw; > + > + err = register_framebuffer(&sfb->fb); > + if (err < 0) > + goto failed; > + > + printk(KERN_INFO "Silicon Motion SM%X Rev%X primary display mode" > + "%dx%d-%d Init Complete.\n", hw.chipID, hw.chipRevID, > + sfb->fb.var.xres, sfb->fb.var.yres, > + sfb->fb.var.bits_per_pixel); > + > + return 0; > + > + failed: > + printk(KERN_INFO "Silicon Motion, Inc. primary display init fail\n"); > + > + smtc_unmap_smem(sfb); > + smtc_unmap_mmio(sfb); > + smtc_free_fb_info(sfb); > + > + return err; > +} > + > + > +/* Jason (08/11/2009) PCI_DRV wrapper essential structs */ > +static struct pci_device_id smtcfb_pci_table[] = { > + {0x126f, 0x710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, > + {0x126f, 0x712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, > + {0x126f, 0x720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, > + {0,} > +}; > + > + > +/* Jason (08/14/2009) > + * do some clean up when the driver module is removed > + */ > +static void __devexit smtcfb_pci_remove(struct pci_dev *pdev) > +{ > + struct smtcfb_info *sfb; > + > + sfb = pci_get_drvdata(pdev); > + pci_set_drvdata(pdev, NULL); > + smtc_unmap_smem(sfb); > + smtc_unmap_mmio(sfb); > + unregister_framebuffer(&sfb->fb); > + smtc_free_fb_info(sfb); > +} > + > +/* Jason (08/14/2009) > + * suspend function, called when the suspend event is triggered > + */ > +static int __maybe_unused smtcfb_suspend(struct pci_dev *pdev, pm_message_t msg) > +{ > + struct smtcfb_info *sfb; > + int retv; > + > + sfb = pci_get_drvdata(pdev); > + > + /* set the hw in sleep mode use externel clock and self memory refresh > + * so that we can turn off internal PLLs later on > + */ > + smtc_seqw(0x20, (smtc_seqr(0x20) | 0xc0)); > + smtc_seqw(0x69, (smtc_seqr(0x69) & 0xf7)); > + > + switch (msg.event) { > + case PM_EVENT_FREEZE: > + case PM_EVENT_PRETHAW: > + pdev->dev.power.power_state = msg; > + return 0; > + } > + > + /* when doing suspend, call fb apis and pci apis */ > + if (msg.event == PM_EVENT_SUSPEND) { > + acquire_console_sem(); > + fb_set_suspend(&sfb->fb, 1); > + release_console_sem(); > + retv = pci_save_state(pdev); > + pci_disable_device(pdev); > + retv = pci_choose_state(pdev, msg); > + retv = pci_set_power_state(pdev, retv); > + } > + > + pdev->dev.power.power_state = msg; > + > + /* additionaly turn off all function blocks including internal PLLs */ > + smtc_seqw(0x21, 0xff); > + > + return 0; > +} > + > +static int __maybe_unused smtcfb_resume(struct pci_dev *pdev) > +{ > + struct smtcfb_info *sfb; > + int retv; > + > + sfb = pci_get_drvdata(pdev); > + > + /* when resuming, restore pci data and fb cursor */ > + if (pdev->dev.power.power_state.event != PM_EVENT_FREEZE) { > + retv = pci_set_power_state(pdev, PCI_D0); > + retv = pci_restore_state(pdev); > + if (pci_enable_device(pdev)) > + return -1; > + pci_set_master(pdev); > + } > + > + /* reinit hardware */ > + sm7xx_init_hw(); > + switch (hw.chipID) { > + case 0x710: > + case 0x712: > + /* set MCLK = 14.31818 * (0x16 / 0x2) */ > + smtc_seqw(0x6a, 0x16); > + smtc_seqw(0x6b, 0x02); > + smtc_seqw(0x62, 0x3e); > + /* enable PCI burst */ > + smtc_seqw(0x17, 0x20); > +#ifdef __BIG_ENDIAN > + if (sfb->fb.var.bits_per_pixel == 32) > + smtc_seqw(0x17, 0x30); > +#endif > + break; > + case 0x720: > + smtc_seqw(0x62, 0xff); > + smtc_seqw(0x6a, 0x0d); > + smtc_seqw(0x6b, 0x02); > + break; > + } > + > + smtc_seqw(0x34, (smtc_seqr(0x34) | 0xc0)); > + smtc_seqw(0x33, ((smtc_seqr(0x33) | 0x08) & 0xfb)); > + > + smtcfb_setmode(sfb); > + > + acquire_console_sem(); > + fb_set_suspend(&sfb->fb, 0); > + release_console_sem(); > + > + return 0; > +} > + > +/* Jason (08/13/2009) > + * pci_driver struct used to wrap the original driver > + * so that it can be registered into the kernel and > + * the proper method would be called when suspending and resuming > + */ > +static struct pci_driver smtcfb_driver = { > + .name = "smtcfb", > + .id_table = smtcfb_pci_table, > + .probe = smtcfb_pci_probe, > + .remove = __devexit_p(smtcfb_pci_remove), > +#ifdef CONFIG_PM > + .suspend = smtcfb_suspend, > + .resume = smtcfb_resume, > +#endif > +}; > + > +static int __init smtcfb_init(void) > +{ > + return pci_register_driver(&smtcfb_driver); > +} > + > +static void __exit smtcfb_exit(void) > +{ > + pci_unregister_driver(&smtcfb_driver); > +} > + > +module_init(smtcfb_init); > +module_exit(smtcfb_exit); > + > +MODULE_AUTHOR("Siliconmotion "); > +MODULE_DESCRIPTION("Framebuffer driver for SMI Graphic Cards"); > +MODULE_LICENSE("GPL"); > diff --git a/drivers/staging/sm7xx/smtcfb.h b/drivers/staging/sm7xx/smtcfb.h > new file mode 100644 > index 0000000..7f2c341 > --- /dev/null > +++ b/drivers/staging/sm7xx/smtcfb.h > @@ -0,0 +1,793 @@ > +/* > + * Silicon Motion SM712 frame buffer device > + * > + * Copyright (C) 2006 Silicon Motion Technology Corp. > + * Authors: Ge Wang, gewang@xxxxxxxxxxxxxxxxx > + * Boyod boyod.yang@xxxxxxxxxxxxxxxxxxxx > + * > + * Copyright (C) 2009 Lemote, Inc. > + * Author: Wu Zhangjin, wuzj@xxxxxxxxxx > + * > + * This file is subject to the terms and conditions of the GNU General Public > + * License. See the file COPYING in the main directory of this archive for > + * more details. > + */ > + > +#define SMTC_LINUX_FB_VERSION "version 0.11.2619.21.01 July 27, 2008" > + > +#define NR_PALETTE 256 > +#define NR_RGB 2 > + > +#define FB_ACCEL_SMI_LYNX 88 > + > +#ifdef __BIG_ENDIAN > +#define PC_VGA 0 > +#else > +#define PC_VGA 1 > +#endif > + > +#define SCREEN_X_RES 1024 > +#define SCREEN_Y_RES 600 > +#define SCREEN_BPP 16 > + > +#ifndef FIELD_OFFSET > +#define FIELD_OFSFET(type, field) \ > + ((unsigned long) (PUCHAR) & (((type *)0)->field)) > +#endif > + > +/*Assume SM712 graphics chip has 4MB VRAM */ > +#define SM712_VIDEOMEMORYSIZE 0x00400000 > +/*Assume SM722 graphics chip has 8MB VRAM */ > +#define SM722_VIDEOMEMORYSIZE 0x00800000 > + > +#define dac_reg (0x3c8) > +#define dac_val (0x3c9) > + > +extern char *smtc_RegBaseAddress; > +#define smtc_mmiowb(dat, reg) writeb(dat, smtc_RegBaseAddress + reg) > +#define smtc_mmioww(dat, reg) writew(dat, smtc_RegBaseAddress + reg) > +#define smtc_mmiowl(dat, reg) writel(dat, smtc_RegBaseAddress + reg) > + > +#define smtc_mmiorb(reg) readb(smtc_RegBaseAddress + reg) > +#define smtc_mmiorw(reg) readw(smtc_RegBaseAddress + reg) > +#define smtc_mmiorl(reg) readl(smtc_RegBaseAddress + reg) > + > +#define SIZE_SR00_SR04 (0x04 - 0x00 + 1) > +#define SIZE_SR10_SR24 (0x24 - 0x10 + 1) > +#define SIZE_SR30_SR75 (0x75 - 0x30 + 1) > +#define SIZE_SR80_SR93 (0x93 - 0x80 + 1) > +#define SIZE_SRA0_SRAF (0xAF - 0xA0 + 1) > +#define SIZE_GR00_GR08 (0x08 - 0x00 + 1) > +#define SIZE_AR00_AR14 (0x14 - 0x00 + 1) > +#define SIZE_CR00_CR18 (0x18 - 0x00 + 1) > +#define SIZE_CR30_CR4D (0x4D - 0x30 + 1) > +#define SIZE_CR90_CRA7 (0xA7 - 0x90 + 1) > +#define SIZE_VPR (0x6C + 1) > +#define SIZE_DPR (0x44 + 1) > + > +static inline void smtc_crtcw(int reg, int val) > +{ > + smtc_mmiowb(reg, 0x3d4); > + smtc_mmiowb(val, 0x3d5); > +} > + > +static inline unsigned int smtc_crtcr(int reg) > +{ > + smtc_mmiowb(reg, 0x3d4); > + return smtc_mmiorb(0x3d5); > +} > + > +static inline void smtc_grphw(int reg, int val) > +{ > + smtc_mmiowb(reg, 0x3ce); > + smtc_mmiowb(val, 0x3cf); > +} > + > +static inline unsigned int smtc_grphr(int reg) > +{ > + smtc_mmiowb(reg, 0x3ce); > + return smtc_mmiorb(0x3cf); > +} > + > +static inline void smtc_attrw(int reg, int val) > +{ > + smtc_mmiorb(0x3da); > + smtc_mmiowb(reg, 0x3c0); > + smtc_mmiorb(0x3c1); > + smtc_mmiowb(val, 0x3c0); > +} > + > +static inline void smtc_seqw(int reg, int val) > +{ > + smtc_mmiowb(reg, 0x3c4); > + smtc_mmiowb(val, 0x3c5); > +} > + > +static inline unsigned int smtc_seqr(int reg) > +{ > + smtc_mmiowb(reg, 0x3c4); > + return smtc_mmiorb(0x3c5); > +} > + > +/* The next structure holds all information relevant for a specific video mode. > + */ > + > +struct ModeInit { > + int mmSizeX; > + int mmSizeY; > + int bpp; > + int hz; > + unsigned char Init_MISC; > + unsigned char Init_SR00_SR04[SIZE_SR00_SR04]; > + unsigned char Init_SR10_SR24[SIZE_SR10_SR24]; > + unsigned char Init_SR30_SR75[SIZE_SR30_SR75]; > + unsigned char Init_SR80_SR93[SIZE_SR80_SR93]; > + unsigned char Init_SRA0_SRAF[SIZE_SRA0_SRAF]; > + unsigned char Init_GR00_GR08[SIZE_GR00_GR08]; > + unsigned char Init_AR00_AR14[SIZE_AR00_AR14]; > + unsigned char Init_CR00_CR18[SIZE_CR00_CR18]; > + unsigned char Init_CR30_CR4D[SIZE_CR30_CR4D]; > + unsigned char Init_CR90_CRA7[SIZE_CR90_CRA7]; > +}; > + > +/********************************************************************** > + SM712 Mode table. > + **********************************************************************/ > +struct ModeInit VGAMode[] = { > + { > + /* mode#0: 640 x 480 16Bpp 60Hz */ > + 640, 480, 16, 60, > + /* Init_MISC */ > + 0xE3, > + { /* Init_SR0_SR4 */ > + 0x03, 0x01, 0x0F, 0x00, 0x0E, > + }, > + { /* Init_SR10_SR24 */ > + 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, > + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0xC4, 0x30, 0x02, 0x01, 0x01, > + }, > + { /* Init_SR30_SR75 */ > + 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, > + 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, > + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, > + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, > + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, > + 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, > + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, > + 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, > + 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, > + }, > + { /* Init_SR80_SR93 */ > + 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, > + 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, > + 0x00, 0x00, 0x00, 0x00, > + }, > + { /* Init_SRA0_SRAF */ > + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, > + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, > + }, > + { /* Init_GR00_GR08 */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, > + 0xFF, > + }, > + { /* Init_AR00_AR14 */ > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, > + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, > + 0x41, 0x00, 0x0F, 0x00, 0x00, > + }, > + { /* Init_CR00_CR18 */ > + 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, > + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, > + 0xFF, > + }, > + { /* Init_CR30_CR4D */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, > + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, > + 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, > + 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, > + }, > + { /* Init_CR90_CRA7 */ > + 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, > + 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, > + 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, > + }, > + }, > + { > + /* mode#1: 640 x 480 24Bpp 60Hz */ > + 640, 480, 24, 60, > + /* Init_MISC */ > + 0xE3, > + { /* Init_SR0_SR4 */ > + 0x03, 0x01, 0x0F, 0x00, 0x0E, > + }, > + { /* Init_SR10_SR24 */ > + 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, > + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0xC4, 0x30, 0x02, 0x01, 0x01, > + }, > + { /* Init_SR30_SR75 */ > + 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, > + 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, > + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, > + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, > + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, > + 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, > + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, > + 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, > + 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, > + }, > + { /* Init_SR80_SR93 */ > + 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, > + 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, > + 0x00, 0x00, 0x00, 0x00, > + }, > + { /* Init_SRA0_SRAF */ > + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, > + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, > + }, > + { /* Init_GR00_GR08 */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, > + 0xFF, > + }, > + { /* Init_AR00_AR14 */ > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, > + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, > + 0x41, 0x00, 0x0F, 0x00, 0x00, > + }, > + { /* Init_CR00_CR18 */ > + 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, > + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, > + 0xFF, > + }, > + { /* Init_CR30_CR4D */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, > + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, > + 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, > + 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, > + }, > + { /* Init_CR90_CRA7 */ > + 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, > + 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, > + 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, > + }, > + }, > + { > + /* mode#0: 640 x 480 32Bpp 60Hz */ > + 640, 480, 32, 60, > + /* Init_MISC */ > + 0xE3, > + { /* Init_SR0_SR4 */ > + 0x03, 0x01, 0x0F, 0x00, 0x0E, > + }, > + { /* Init_SR10_SR24 */ > + 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, > + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0xC4, 0x30, 0x02, 0x01, 0x01, > + }, > + { /* Init_SR30_SR75 */ > + 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, > + 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, > + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, > + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, > + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, > + 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, > + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, > + 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, > + 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, > + }, > + { /* Init_SR80_SR93 */ > + 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, > + 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, > + 0x00, 0x00, 0x00, 0x00, > + }, > + { /* Init_SRA0_SRAF */ > + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, > + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, > + }, > + { /* Init_GR00_GR08 */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, > + 0xFF, > + }, > + { /* Init_AR00_AR14 */ > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, > + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, > + 0x41, 0x00, 0x0F, 0x00, 0x00, > + }, > + { /* Init_CR00_CR18 */ > + 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, > + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, > + 0xFF, > + }, > + { /* Init_CR30_CR4D */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, > + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, > + 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, > + 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, > + }, > + { /* Init_CR90_CRA7 */ > + 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, > + 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, > + 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, > + }, > + }, > + > + { /* mode#2: 800 x 600 16Bpp 60Hz */ > + 800, 600, 16, 60, > + /* Init_MISC */ > + 0x2B, > + { /* Init_SR0_SR4 */ > + 0x03, 0x01, 0x0F, 0x03, 0x0E, > + }, > + { /* Init_SR10_SR24 */ > + 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, > + 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0xC4, 0x30, 0x02, 0x01, 0x01, > + }, > + { /* Init_SR30_SR75 */ > + 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24, > + 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF, > + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC, > + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24, > + 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, > + 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24, > + 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, > + 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, > + 0x02, 0x45, 0x30, 0x35, 0x40, 0x20, > + }, > + { /* Init_SR80_SR93 */ > + 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24, > + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24, > + 0x00, 0x00, 0x00, 0x00, > + }, > + { /* Init_SRA0_SRAF */ > + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, > + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, > + }, > + { /* Init_GR00_GR08 */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, > + 0xFF, > + }, > + { /* Init_AR00_AR14 */ > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, > + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, > + 0x41, 0x00, 0x0F, 0x00, 0x00, > + }, > + { /* Init_CR00_CR18 */ > + 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, > + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, > + 0xFF, > + }, > + { /* Init_CR30_CR4D */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, > + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, > + 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, > + 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, > + }, > + { /* Init_CR90_CRA7 */ > + 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, > + 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, > + 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, > + }, > + }, > + { /* mode#3: 800 x 600 24Bpp 60Hz */ > + 800, 600, 24, 60, > + 0x2B, > + { /* Init_SR0_SR4 */ > + 0x03, 0x01, 0x0F, 0x03, 0x0E, > + }, > + { /* Init_SR10_SR24 */ > + 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, > + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0xC4, 0x30, 0x02, 0x01, 0x01, > + }, > + { /* Init_SR30_SR75 */ > + 0x36, 0x03, 0x20, 0x09, 0xC0, 0x36, 0x36, 0x36, > + 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x03, 0xFF, > + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, > + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x36, 0x36, 0x36, > + 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, > + 0x04, 0x55, 0x59, 0x36, 0x36, 0x00, 0x00, 0x36, > + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, > + 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, > + 0x02, 0x45, 0x30, 0x30, 0x40, 0x20, > + }, > + { /* Init_SR80_SR93 */ > + 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x36, > + 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x36, 0x36, > + 0x00, 0x00, 0x00, 0x00, > + }, > + { /* Init_SRA0_SRAF */ > + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, > + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, > + }, > + { /* Init_GR00_GR08 */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, > + 0xFF, > + }, > + { /* Init_AR00_AR14 */ > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, > + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, > + 0x41, 0x00, 0x0F, 0x00, 0x00, > + }, > + { /* Init_CR00_CR18 */ > + 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, > + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, > + 0xFF, > + }, > + { /* Init_CR30_CR4D */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, > + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, > + 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, > + 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, > + }, > + { /* Init_CR90_CRA7 */ > + 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, > + 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, > + 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, > + }, > + }, > + { /* mode#7: 800 x 600 32Bpp 60Hz */ > + 800, 600, 32, 60, > + /* Init_MISC */ > + 0x2B, > + { /* Init_SR0_SR4 */ > + 0x03, 0x01, 0x0F, 0x03, 0x0E, > + }, > + { /* Init_SR10_SR24 */ > + 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, > + 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0xC4, 0x30, 0x02, 0x01, 0x01, > + }, > + { /* Init_SR30_SR75 */ > + 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24, > + 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF, > + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC, > + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24, > + 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, > + 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24, > + 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, > + 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, > + 0x02, 0x45, 0x30, 0x35, 0x40, 0x20, > + }, > + { /* Init_SR80_SR93 */ > + 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24, > + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24, > + 0x00, 0x00, 0x00, 0x00, > + }, > + { /* Init_SRA0_SRAF */ > + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, > + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, > + }, > + { /* Init_GR00_GR08 */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, > + 0xFF, > + }, > + { /* Init_AR00_AR14 */ > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, > + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, > + 0x41, 0x00, 0x0F, 0x00, 0x00, > + }, > + { /* Init_CR00_CR18 */ > + 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, > + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, > + 0xFF, > + }, > + { /* Init_CR30_CR4D */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, > + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, > + 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, > + 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, > + }, > + { /* Init_CR90_CRA7 */ > + 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, > + 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, > + 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, > + }, > + }, > + /* We use 1024x768 table to light 1024x600 panel for lemote */ > + { /* mode#4: 1024 x 600 16Bpp 60Hz */ > + 1024, 600, 16, 60, > + /* Init_MISC */ > + 0xEB, > + { /* Init_SR0_SR4 */ > + 0x03, 0x01, 0x0F, 0x00, 0x0E, > + }, > + { /* Init_SR10_SR24 */ > + 0xC8, 0x40, 0x14, 0x60, 0x00, 0x0A, 0x17, 0x20, > + 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0xC4, 0x30, 0x02, 0x00, 0x01, > + }, > + { /* Init_SR30_SR75 */ > + 0x22, 0x03, 0x24, 0x09, 0xC0, 0x22, 0x22, 0x22, > + 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x03, 0xFF, > + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, > + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x22, 0x22, 0x22, > + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, > + 0x00, 0x60, 0x59, 0x22, 0x22, 0x00, 0x00, 0x22, > + 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, > + 0x50, 0x03, 0x16, 0x02, 0x0D, 0x82, 0x09, 0x02, > + 0x04, 0x45, 0x3F, 0x30, 0x40, 0x20, > + }, > + { /* Init_SR80_SR93 */ > + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, > + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, > + 0x00, 0x00, 0x00, 0x00, > + }, > + { /* Init_SRA0_SRAF */ > + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, > + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, > + }, > + { /* Init_GR00_GR08 */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, > + 0xFF, > + }, > + { /* Init_AR00_AR14 */ > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, > + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, > + 0x41, 0x00, 0x0F, 0x00, 0x00, > + }, > + { /* Init_CR00_CR18 */ > + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, > + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, > + 0xFF, > + }, > + { /* Init_CR30_CR4D */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, > + 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, > + 0xA3, 0x7F, 0x00, 0x82, 0x0b, 0x6f, 0x57, 0x00, > + 0x5c, 0x0f, 0xE0, 0xe0, 0x7F, 0x57, > + }, > + { /* Init_CR90_CRA7 */ > + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, > + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, > + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, > + }, > + }, > + { /* mode#5: 1024 x 768 24Bpp 60Hz */ > + 1024, 768, 24, 60, > + /* Init_MISC */ > + 0xEB, > + { /* Init_SR0_SR4 */ > + 0x03, 0x01, 0x0F, 0x03, 0x0E, > + }, > + { /* Init_SR10_SR24 */ > + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, > + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0xC4, 0x30, 0x02, 0x01, 0x01, > + }, > + { /* Init_SR30_SR75 */ > + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, > + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, > + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, > + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, > + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, > + 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, > + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, > + 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, > + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, > + }, > + { /* Init_SR80_SR93 */ > + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, > + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, > + 0x00, 0x00, 0x00, 0x00, > + }, > + { /* Init_SRA0_SRAF */ > + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, > + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, > + }, > + { /* Init_GR00_GR08 */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, > + 0xFF, > + }, > + { /* Init_AR00_AR14 */ > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, > + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, > + 0x41, 0x00, 0x0F, 0x00, 0x00, > + }, > + { /* Init_CR00_CR18 */ > + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, > + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, > + 0xFF, > + }, > + { /* Init_CR30_CR4D */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, > + 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, > + 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, > + 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, > + }, > + { /* Init_CR90_CRA7 */ > + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, > + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, > + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, > + }, > + }, > + { /* mode#4: 1024 x 768 32Bpp 60Hz */ > + 1024, 768, 32, 60, > + /* Init_MISC */ > + 0xEB, > + { /* Init_SR0_SR4 */ > + 0x03, 0x01, 0x0F, 0x03, 0x0E, > + }, > + { /* Init_SR10_SR24 */ > + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, > + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0xC4, 0x32, 0x02, 0x01, 0x01, > + }, > + { /* Init_SR30_SR75 */ > + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, > + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, > + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, > + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, > + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, > + 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, > + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, > + 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, > + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, > + }, > + { /* Init_SR80_SR93 */ > + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, > + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, > + 0x00, 0x00, 0x00, 0x00, > + }, > + { /* Init_SRA0_SRAF */ > + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, > + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, > + }, > + { /* Init_GR00_GR08 */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, > + 0xFF, > + }, > + { /* Init_AR00_AR14 */ > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, > + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, > + 0x41, 0x00, 0x0F, 0x00, 0x00, > + }, > + { /* Init_CR00_CR18 */ > + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, > + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, > + 0xFF, > + }, > + { /* Init_CR30_CR4D */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, > + 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, > + 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, > + 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, > + }, > + { /* Init_CR90_CRA7 */ > + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, > + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, > + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, > + }, > + }, > + { /* mode#6: 320 x 240 16Bpp 60Hz */ > + 320, 240, 16, 60, > + /* Init_MISC */ > + 0xEB, > + { /* Init_SR0_SR4 */ > + 0x03, 0x01, 0x0F, 0x03, 0x0E, > + }, > + { /* Init_SR10_SR24 */ > + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, > + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0xC4, 0x32, 0x02, 0x01, 0x01, > + }, > + { /* Init_SR30_SR75 */ > + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, > + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, > + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, > + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, > + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, > + 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, > + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, > + 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43, > + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, > + }, > + { /* Init_SR80_SR93 */ > + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, > + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, > + 0x00, 0x00, 0x00, 0x00, > + }, > + { /* Init_SRA0_SRAF */ > + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, > + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, > + }, > + { /* Init_GR00_GR08 */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, > + 0xFF, > + }, > + { /* Init_AR00_AR14 */ > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, > + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, > + 0x41, 0x00, 0x0F, 0x00, 0x00, > + }, > + { /* Init_CR00_CR18 */ > + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, > + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, > + 0xFF, > + }, > + { /* Init_CR30_CR4D */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, > + 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF, > + 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00, > + 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF, > + }, > + { /* Init_CR90_CRA7 */ > + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, > + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, > + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, > + }, > + }, > + > + { /* mode#8: 320 x 240 32Bpp 60Hz */ > + 320, 240, 32, 60, > + /* Init_MISC */ > + 0xEB, > + { /* Init_SR0_SR4 */ > + 0x03, 0x01, 0x0F, 0x03, 0x0E, > + }, > + { /* Init_SR10_SR24 */ > + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, > + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0xC4, 0x32, 0x02, 0x01, 0x01, > + }, > + { /* Init_SR30_SR75 */ > + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, > + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, > + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, > + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, > + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, > + 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, > + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, > + 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43, > + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, > + }, > + { /* Init_SR80_SR93 */ > + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, > + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, > + 0x00, 0x00, 0x00, 0x00, > + }, > + { /* Init_SRA0_SRAF */ > + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, > + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, > + }, > + { /* Init_GR00_GR08 */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, > + 0xFF, > + }, > + { /* Init_AR00_AR14 */ > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, > + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, > + 0x41, 0x00, 0x0F, 0x00, 0x00, > + }, > + { /* Init_CR00_CR18 */ > + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, > + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, > + 0xFF, > + }, > + { /* Init_CR30_CR4D */ > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, > + 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF, > + 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00, > + 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF, > + }, > + { /* Init_CR90_CRA7 */ > + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, > + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, > + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, > + }, > + }, > +}; > + > +#define numVGAModes (sizeof(VGAMode) / sizeof(struct ModeInit)) _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/devel