On Fri, Aug 24, 2012 at 10:35:00AM +0800, Aaron.Chen  ??? wrote:
> Hi,
> 
> >What's with the #ifdef 0 or #ifdef 1?
> 
> >Why is there a bunch of ddkxxx something? Can those header files be squashed 
> >together?
> 
> We have deleted all the "#ifdef 0 or #ifdef 1" and cut our codes into smaller 
> parts in order to get reviewed easier. There are less ddkxxx something in 
> this patch.

Please next time post it inline, not as attachment.

Also explain why/where what machines this runs on.

>From 35c8c1675e2bf6d8e7a702d61558b99316aaeabe Mon Sep 17 00:00:00 2001
>From: Aaron Chen <aaron.chen at siliconmotion.com>
>Date: Fri, 24 Aug 2012 10:03:54 +0800
>Subject: [PATCH] siliconmotion kernel driver initial patch
>
>This is the initial patch for siliconmotion kernel driver. It can support 
>SM750 and SM718. It is a framebuffer driver.
>
>Signed-off-by: Aaron Chen <aaron.chen at siliconmotion.com>
>---
> drivers/video/Kconfig                 |   13 +
> drivers/video/Makefile                |    1 +
> drivers/video/lynxfb/Makefile         |   63 ++
> drivers/video/lynxfb/ddk750.h         |   31 +
> drivers/video/lynxfb/ddk750_chip.c    |  586 ++++++++++++
> drivers/video/lynxfb/ddk750_chip.h    |   97 ++
> drivers/video/lynxfb/ddk750_display.c |  295 ++++++
> drivers/video/lynxfb/ddk750_display.h |  124 +++
> drivers/video/lynxfb/ddk750_dvi.c     |  114 +++
> drivers/video/lynxfb/ddk750_dvi.h     |   84 ++
> drivers/video/lynxfb/ddk750_help.c    |   37 +
> drivers/video/lynxfb/ddk750_help.h    |   42 +
> drivers/video/lynxfb/ddk750_hwi2c.c   |  290 ++++++
> drivers/video/lynxfb/ddk750_hwi2c.h   |   28 +
> drivers/video/lynxfb/ddk750_mode.c    |  213 +++++
> drivers/video/lynxfb/ddk750_mode.h    |   59 ++
> drivers/video/lynxfb/ddk750_power.c   |  243 +++++
> drivers/video/lynxfb/ddk750_power.h   |   85 ++
> drivers/video/lynxfb/ddk750_reg.h     |  362 +++++++
> drivers/video/lynxfb/ddk750_sii164.c  |  435 +++++++++
> drivers/video/lynxfb/ddk750_sii164.h  |  187 ++++
> drivers/video/lynxfb/ddk750_swi2c.c   |  522 ++++++++++
> drivers/video/lynxfb/ddk750_swi2c.h   |   98 ++
> drivers/video/lynxfb/lynx_accel.c     |  417 ++++++++
> drivers/video/lynxfb/lynx_accel.h     |  161 ++++
> drivers/video/lynxfb/lynx_cursor.c    |  223 +++++
> drivers/video/lynxfb/lynx_cursor.h    |   36 +
> drivers/video/lynxfb/lynx_drv.c       | 1688 +++++++++++++++++++++++++++++++++
> drivers/video/lynxfb/lynx_drv.h       |  271 ++++++
> drivers/video/lynxfb/lynx_help.h      |  115 +++
> drivers/video/lynxfb/lynx_hw750.c     |  633 +++++++++++++
> drivers/video/lynxfb/lynx_hw750.h     |  120 +++
> drivers/video/lynxfb/modedb.c         |  238 +++++
> drivers/video/lynxfb/ver.h            |   38 +
> 34 files changed, 7949 insertions(+)
> create mode 100644 drivers/video/lynxfb/Makefile
> create mode 100644 drivers/video/lynxfb/ddk750.h
> create mode 100644 drivers/video/lynxfb/ddk750_chip.c
> create mode 100644 drivers/video/lynxfb/ddk750_chip.h
> create mode 100644 drivers/video/lynxfb/ddk750_display.c
> create mode 100644 drivers/video/lynxfb/ddk750_display.h
> create mode 100644 drivers/video/lynxfb/ddk750_dvi.c
> create mode 100644 drivers/video/lynxfb/ddk750_dvi.h
> create mode 100644 drivers/video/lynxfb/ddk750_help.c
> create mode 100644 drivers/video/lynxfb/ddk750_help.h
> create mode 100644 drivers/video/lynxfb/ddk750_hwi2c.c
> create mode 100644 drivers/video/lynxfb/ddk750_hwi2c.h
> create mode 100644 drivers/video/lynxfb/ddk750_mode.c
> create mode 100644 drivers/video/lynxfb/ddk750_mode.h
> create mode 100644 drivers/video/lynxfb/ddk750_power.c
> create mode 100644 drivers/video/lynxfb/ddk750_power.h
> create mode 100644 drivers/video/lynxfb/ddk750_reg.h
> create mode 100644 drivers/video/lynxfb/ddk750_sii164.c
> create mode 100644 drivers/video/lynxfb/ddk750_sii164.h
> create mode 100644 drivers/video/lynxfb/ddk750_swi2c.c
> create mode 100644 drivers/video/lynxfb/ddk750_swi2c.h
> create mode 100644 drivers/video/lynxfb/lynx_accel.c
> create mode 100644 drivers/video/lynxfb/lynx_accel.h
> create mode 100644 drivers/video/lynxfb/lynx_cursor.c
> create mode 100644 drivers/video/lynxfb/lynx_cursor.h
> create mode 100644 drivers/video/lynxfb/lynx_drv.c
> create mode 100644 drivers/video/lynxfb/lynx_drv.h
> create mode 100644 drivers/video/lynxfb/lynx_help.h
> create mode 100644 drivers/video/lynxfb/lynx_hw750.c
> create mode 100644 drivers/video/lynxfb/lynx_hw750.h
> create mode 100644 drivers/video/lynxfb/modedb.c
> create mode 100644 drivers/video/lynxfb/ver.h
>
>diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
>index 0217f74..8c52b1a 100644
>--- a/drivers/video/Kconfig
>+++ b/drivers/video/Kconfig
>@@ -2444,6 +2444,19 @@ config FB_PUV3_UNIGFX
>         Choose this option if you want to use the Unigfx device as a
>         framebuffer device. Without the support of PCI & AGP.
> 
>+config FB_LYNXFB
>+      tristate "SMI lynx sm750/718/712/722/502 display support"
>+      depends on FB && PCI
>+      select FB_CFB_IMAGEBLIT
>+      select FB_CFB_FILLRECT
>+      select FB_CFB_COPYAREA
>+      ---help---
>+        This driver supports graphic board with the siliconmotion
>+        sm750/sm718/sm712/sm722/sm502. Say Y if you have such a
>+        graphic board.
>+        To compile this driver as a module, choose M here: the
>+        module will be called lynxfb.
>+
> source "drivers/video/omap/Kconfig"
> source "drivers/video/omap2/Kconfig"
> source "drivers/video/exynos/Kconfig"
>diff --git a/drivers/video/Makefile b/drivers/video/Makefile
>index ee8dafb..b402bfb 100644
>--- a/drivers/video/Makefile
>+++ b/drivers/video/Makefile
>@@ -149,6 +149,7 @@ obj-$(CONFIG_FB_MSM)              += msm/
> obj-$(CONFIG_FB_NUC900)           += nuc900fb.o
> obj-$(CONFIG_FB_JZ4740)                 += jz4740_fb.o
> obj-$(CONFIG_FB_PUV3_UNIGFX)      += fb-puv3.o
>+obj-$(CONFIG_FB_LYNXFB)                 += lynxfb/
> 
> # Platform or fallback drivers go here
> obj-$(CONFIG_FB_UVESA)            += uvesafb.o
>diff --git a/drivers/video/lynxfb/Makefile b/drivers/video/lynxfb/Makefile
>new file mode 100644
>index 0000000..8853097
>--- /dev/null
>+++ b/drivers/video/lynxfb/Makefile
>@@ -0,0 +1,63 @@
>+#
>+# Makefile for lynx frame buffer
>+#                                     -by Monk.liu
>+#
>+ifeq ($(KERNELRELEASE),)
>+
>+ifeq ($(kernel),)
>+# build the driver with kernel version currerntly using
>+knv :=$(shell uname -r)
>+else
>+# user want to build the driver based on specific kernel version
>+knv :=$(kernel)
>+endif
>+
>+KERNELDIR :=/lib/modules/$(knv)/build
>+PWD := $(shell pwd)
>+
>+default:
>+      $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_FB_LYNXFB=m modules
>+install:default
>+      $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_FB_LYNXFB=m modules_install
>+clean:
>+      $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
>+else
>+

You don't need all of that.

>+obj-$(CONFIG_FB_LYNXFB) += lynxfb.o
>+
>+lynxfb-y := lynx_drv.o lynx_hw750.o lynx_accel.o lynx_cursor.o
>+lynxfb-y += ddk750_chip.o ddk750_power.o ddk750_mode.o ddk750_display.o 
>ddk750_help.o
>+lynxfb-y +=  ddk750_swi2c.o

Those should suffice. Or perhaps:
obj-$(CONFIG_FB_LYNXFB) += lynxfb.o lynx_drv.o lynx_hw750.o lynx_accel.o 
lynx_cursor.o
                        ddk750_chip.o ddk750_power.o ddk750_mode.o 
ddk750_display.o ddk750_help.o

and that is it.

>+
>+
>+EXTRA_CFLAGS += -DOPENSOURCE
>+
>+ifneq ($(nodvi),1)
>+lynxfb-y += ddk750_sii164.o
>+lynxfb-y += ddk750_dvi.o
>+EXTRA_CFLAGS += -DUSE_DVICHIP
>+else
>+endif
>+
>+# if user define swi2c=1,then for sm750/sm718,its dvi chip (sii164) will be 
>initilized by swi2c
>+# but for 750le, always swi2c used to setup its 7301 dvi chip
>+ifneq ($(swi2c),1)
>+lynxfb-y += ddk750_hwi2c.o
>+EXTRA_CFLAGS += -DUSE_HW_I2C
>+endif
>+
>+lynxfb-objs := $(lynxfb-y)
>+
>+ifeq ($(debug),1)
>+#CONFIG_FB_LYNXFB_DEBUG=y
>+EXTRA_CFLAGS += -DDEBUG=1
>+endif
>+
>+ifeq ($(debug),2)
>+EXTRA_CFLAGS += -DDEBUG=2
>+endif
>+
>+#ifdef CONFIG_FB_LYNXFB_DEBUG
>+#endif
>+
>+endif
>diff --git a/drivers/video/lynxfb/ddk750.h b/drivers/video/lynxfb/ddk750.h
>new file mode 100644
>index 0000000..fd3e279
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750.h
>@@ -0,0 +1,31 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef DDK750_H__
>+#define DDK750_H__
>+#include "ddk750_reg.h"
>+#include "ddk750_mode.h"
>+#include "ddk750_chip.h"
>+#include "ddk750_display.h"
>+#include "ddk750_power.h"
>+#include "ddk750_help.h"
>+#ifdef USE_HW_I2C
>+#include "ddk750_hwi2c.h"
>+#endif
>+#include "ddk750_swi2c.h"
>+#endif

This header file is not adding anyting to the driver. Why don't you just
include those #includes in the C code?

>diff --git a/drivers/video/lynxfb/ddk750_chip.c 
>b/drivers/video/lynxfb/ddk750_chip.c
>new file mode 100644
>index 0000000..4eff5c6
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_chip.c
>@@ -0,0 +1,586 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#include "ddk750_help.h"
>+#include "ddk750_reg.h"
>+#include "ddk750_chip.h"
>+#include "ddk750_power.h"
>+typedef struct _pllcalparam{

You didn't run cleanpatch on this patch series at all did you? Please
do that and then repost it.
>+      unsigned char power;/* d : 0~ 6*/
>+      unsigned char pod;
>+      unsigned char od;
>+      unsigned char value;/* value of  2 power d (2^d) */
>+}
>+pllcalparam;
>+
>+
>+logical_chip_type_t getChipType()
>+{
>+      unsigned short physicalID;
>+      char physicalRev;
>+      logical_chip_type_t chip;
>+
>+      physicalID = devId750;/* either 0x718 or 0x750 */
>+      physicalRev = revId750;
>+
>+      if (physicalID == 0x718) {
>+              chip = SM718;
>+      } else if (physicalID == 0x750) {
>+              chip = SM750;
>+              /* SM750 and SM750LE are different in their revision ID only. */
>+              if (physicalRev == SM750LE_REVISION_ID) {
>+                      chip = SM750LE;
>+              }
>+      } else{
>+              chip = SM_UNKNOWN;
>+      }
>+
>+      return chip;
>+}
>+
>+
>+inline unsigned int twoToPowerOfx(unsigned long x)

I think there is a nice macro for this. Did you search in the 
code already for this?

>+{
>+      unsigned long i;
>+      unsigned long result = 1;
>+
>+      for (i = 1; i <= x; i++)
>+              result *= 2;
>+      return result;
>+}
>+
>+inline unsigned int calcPLL(pll_value_t *pPLL)
>+{
>+      return pPLL->inputFreq * pPLL->M / pPLL->N / twoToPowerOfx(pPLL->OD) / 
>twoToPowerOfx(pPLL->POD);
>+}
>+
>+unsigned int getPllValue(clock_type_t clockType, pll_value_t *pPLL)
>+{
>+      unsigned int ulPllReg = 0;
>+
>+      pPLL->inputFreq = DEFAULT_INPUT_CLOCK;
>+      pPLL->clockType = clockType;
>+
>+      switch (clockType) {
>+      case MXCLK_PLL:
>+              ulPllReg = PEEK32(MXCLK_PLL_CTRL);
>+              break;
>+      case PRIMARY_PLL:
>+              ulPllReg = PEEK32(PANEL_PLL_CTRL);
>+              break;
>+      case SECONDARY_PLL:
>+              ulPllReg = PEEK32(CRT_PLL_CTRL);
>+              break;
>+      case VGA0_PLL:
>+              ulPllReg = PEEK32(VGA_PLL0_CTRL);
>+              break;
>+      case VGA1_PLL:
>+              ulPllReg = PEEK32(VGA_PLL1_CTRL);
>+              break;
>+      }
>+      pPLL->M = 255&(ulPllReg >> PANEL_PLL_CTRL_M_LSB);
>+      pPLL->N = 15&(ulPllReg >> PANEL_PLL_CTRL_N_LSB);
>+      pPLL->OD = 3&(ulPllReg >> PANEL_PLL_CTRL_OD_LSB);
>+      pPLL->POD = 3&(ulPllReg >> PANEL_PLL_CTRL_POD_LSB);
>+
>+      return calcPLL(pPLL);
>+}
>+
>+
>+unsigned int getChipClock()
>+{
>+      pll_value_t pll;
>+      if (getChipType() == SM750LE)
>+              return MHz(130);
>+
>+      return getPllValue(MXCLK_PLL, &pll);
>+}
>+
>+
>+/*
>+ * This function set up the main chip clock.
>+ *
>+ * Input: Frequency to be set.
>+ */
>+void setChipClock(unsigned int frequency)
>+{
>+      pll_value_t pll;
>+      unsigned int ulActualMxClk;
>+
>+      /* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */
>+      if (getChipType() == SM750LE)
>+              return;
>+
>+
>+      if (frequency != 0) {
>+              /*
>+               * Set up PLL, a structure to hold the value to be set in 
>clocks.
>+               */
>+              pll.inputFreq = DEFAULT_INPUT_CLOCK; /* Defined in CLOCK.H */

I don't think the 'CLOCK.H' file is present there.
>+              pll.clockType = MXCLK_PLL;
>+
>+              /*
>+               * Call calcPllValue() to fill up the other fields for PLL 
>structure.
>+               * Sometime, the chip cannot set up the exact clock required by 
>User.
>+               * Return value from calcPllValue() gives the actual possible 
>clock.

So an estimation then? 
>+               */
>+              ulActualMxClk = calcPllValue(frequency, &pll);
>+
>+              /* Master Clock Control: MXCLK_PLL */
>+              POKE32(MXCLK_PLL_CTRL, formatPllReg(&pll));
>+      }
>+}
>+
>+
>+
>+void setMemoryClock(unsigned int frequency)
>+{
>+      unsigned int ulReg, divisor;
>+
>+      /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. 
>*/
>+      if (getChipType() == SM750LE)
>+              return;
>+
>+      if (frequency != 0) {
>+              /* Set the frequency to the maximum frequency that the DDR 
>Memory can take
>+                 which is 336MHz. */
>+              if (frequency > MHz(336))
>+                      frequency = MHz(336);
>+              /* Calculate the divisor */
>+              divisor = (unsigned int) roundedDiv(getChipClock(), frequency);
>+              /* Set the corresponding divisor in the register. */
>+              ulReg = PEEK32(CURRENT_GATE);
>+              switch (divisor) {
>+              default:
>+              case 1:
>+                      ulReg = ulReg&(~(1 << CURRENT_GATE_M2XCLK_LSB));
>+                      break;
>+              case 2:
>+                      ulReg = ulReg|(1 << CURRENT_GATE_M2XCLK_LSB);
>+                      break;
>+              case 3:
>+                      ulReg = ulReg&(~(3 << CURRENT_GATE_M2XCLK_LSB));
>+                      ulReg = ulReg|(2 << CURRENT_GATE_M2XCLK_LSB);
>+                      break;
>+              case 4:
>+                      ulReg = ulReg|(3 << CURRENT_GATE_M2XCLK_LSB);
>+                      break;
>+              }
>+              setCurrentGate(ulReg);
>+      }
>+}
>+
>+
>+/*
>+ * This function set up the master clock (MCLK).
>+ *
>+ * Input: Frequency to be set.
>+ *
>+ * NOTE:
>+ *      The maximum frequency the engine can run is 168MHz.
>+ */
>+void setMasterClock(unsigned int frequency)
>+{
>+      unsigned int ulReg, divisor;
>+
>+      /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. 
>*/
>+      if (getChipType() == SM750LE)
>+              return;
>+
>+      if (frequency != 0) {
>+              /* Set the frequency to the maximum frequency that the SM750 
>engine can
>+                 run, which is about 190 MHz. */
>+              if (frequency > MHz(190))
>+                      frequency = MHz(190);
>+              /* Calculate the divisor */
>+              divisor = (unsigned int) roundedDiv(getChipClock(), frequency);
>+              /* Set the corresponding divisor in the register. */
>+              ulReg = PEEK32(CURRENT_GATE);
>+              switch (divisor) {
>+              default:
>+              case 3:
>+                      ulReg = ulReg&(~(1 << CURRENT_GATE_MCLK_LSB));
>+                      break;
>+              case 4:
>+                      ulReg = ulReg|(1 << CURRENT_GATE_MCLK_LSB);
>+                      break;
>+              case 6:
>+                      ulReg = ulReg&(~(3 << CURRENT_GATE_MCLK_LSB));
>+                      ulReg = ulReg|(2 << CURRENT_GATE_MCLK_LSB);
>+                      break;
>+              case 8:
>+                      ulReg = ulReg|(3 << CURRENT_GATE_MCLK_LSB);
>+                      break;
>+              }
>+              setCurrentGate(ulReg);
>+      }
>+}
>+
>+
>+unsigned int ddk750_getVMSize()
>+{
>+      unsigned int reg;
>+      unsigned int data;
>+
>+      /* sm750le only use 64 mb memory*/
>+      if (getChipType() == SM750LE)
>+              return MB(64);
>+
>+      /* for 750, always use power mode0*/
>+      reg = PEEK32(MODE0_GATE);
>+      reg = reg|(1 << MODE0_GATE_GPIO_LSB);
>+      POKE32(MODE0_GATE, reg);
>+
>+      /* get frame buffer size from GPIO */
>+      reg = 3&(PEEK32(MISC_CTRL) >> MISC_CTRL_LOCALMEM_SIZE_LSB);
>+      switch (reg) {
>+      case MISC_CTRL_LOCALMEM_SIZE_8M:
>+              data = MB(8);
>+              break; /* 8  Mega byte */
>+      case MISC_CTRL_LOCALMEM_SIZE_16M:
>+              data = MB(16);
>+              break; /* 16 Mega byte */
>+      case MISC_CTRL_LOCALMEM_SIZE_32M:
>+              data = MB(32);
>+              break; /* 32 Mega byte */
>+      case MISC_CTRL_LOCALMEM_SIZE_64M:
>+              data = MB(64);
>+              break; /* 64 Mega byte */
>+      default:
>+              data = 0;
>+              break;
>+      }
>+      return data;
>+
>+}
>+
>+int ddk750_initHw(initchip_param_t *pInitParam)
>+{
>+
>+      unsigned int ulReg;
>+
>+      if (pInitParam->powerMode != 0)
>+              pInitParam->powerMode = 0;
>+      setPowerMode(pInitParam->powerMode);
>+
>+      /* Enable display power gate & LOCALMEM power gate*/
>+      ulReg = PEEK32(CURRENT_GATE);
>+      ulReg = ulReg|(1 << CURRENT_GATE_DISPLAY_LSB);
>+      ulReg = ulReg|(1 << CURRENT_GATE_LOCALMEM_LSB);
>+      setCurrentGate(ulReg);
>+
>+      if (getChipType() != SM750LE) {
>+              /*      set panel pll and graphic mode via mmio_88 */
>+              ulReg = PEEK32(VGA_CONFIGURATION);
>+              ulReg = ulReg|(1 << VGA_CONFIGURATION_PLL_LSB);
>+              ulReg = ulReg|(1 << VGA_CONFIGURATION_MODE_LSB);
>+
>+              POKE32(VGA_CONFIGURATION, ulReg);
>+      } else{
>+#if defined(__i386__) || defined(__x86_64__)
>+              /* set graphic mode via IO method */
>+              outb_p(0x88, 0x3d4);
>+              outb_p(0x06, 0x3d5);
>+#endif
>+      }
>+
>+      /* Set the Main Chip Clock */
>+      setChipClock(MHz((unsigned int)pInitParam->chipClock));
>+
>+      /* Set up memory clock. */
>+      setMemoryClock(MHz(pInitParam->memClock));
>+
>+      /* Set up master clock */
>+      setMasterClock(MHz(pInitParam->masterClock));
>+
>+
>+      /* Reset the memory controller. If the memory controller is not reset 
>in SM750,
>+         the system might hang when sw accesses the memory.
>+         The memory should be resetted after changing the MXCLK.
>+         */
>+      if (pInitParam->resetMemory == 1) {
>+              ulReg = PEEK32(MISC_CTRL);
>+              ulReg = ulReg&(~(1 << MISC_CTRL_LOCALMEM_RESET_LSB));
>+              POKE32(MISC_CTRL, ulReg);
>+
>+              ulReg = ulReg|(1 << MISC_CTRL_LOCALMEM_RESET_LSB);
>+              POKE32(MISC_CTRL, ulReg);
>+      }
>+
>+      if (pInitParam->setAllEngOff == 1) {
>+              enable2DEngine(0);
>+
>+              /* Disable Overlay, if a former application left it on */
>+              ulReg = PEEK32(VIDEO_DISPLAY_CTRL);
>+              ulReg = ulReg&(~(1 << VIDEO_DISPLAY_CTRL_PLANE_LSB));
>+              POKE32(VIDEO_DISPLAY_CTRL, ulReg);
>+
>+              /* Disable video alpha, if a former application left it on */
>+              ulReg = PEEK32(VIDEO_ALPHA_DISPLAY_CTRL);
>+              ulReg = ulReg&(~(1 << VIDEO_ALPHA_DISPLAY_CTRL_PLANE_LSB));
>+              POKE32(VIDEO_ALPHA_DISPLAY_CTRL, ulReg);
>+
>+              /* Disable alpha plane, if a former application left it on */
>+              ulReg = PEEK32(ALPHA_DISPLAY_CTRL);
>+              ulReg = ulReg&(~(1 << ALPHA_DISPLAY_CTRL_PLANE_LSB));
>+              POKE32(ALPHA_DISPLAY_CTRL, ulReg);
>+
>+              /* Disable DMA Channel, if a former application left it on */
>+              ulReg = PEEK32(DMA_ABORT_INTERRUPT);
>+              ulReg = ulReg|(1 << DMA_ABORT_INTERRUPT_ABORT_1_LSB);
>+              POKE32(DMA_ABORT_INTERRUPT, ulReg);
>+
>+              /* Disable DMA Power, if a former application left it on */
>+              enableDMA(0);
>+      }
>+
>+      /* We can add more initialization as needed. */
>+
>+      return 0;
>+}
>+
>+/*
>+   monk liu @ 4/6/2011:
>+   re-write the calculatePLL function of ddk750.
>+   the original version function does not use some mathematics tricks and 
>shortcut
>+   when it doing the calculation of the best N,M,D combination
>+   I think this version gives a little upgrade in speed
>+
>+   750 pll clock formular:
>+   Request Clock = (Input Clock * M )/(N * X)
>+
>+   Input Clock = 14318181 hz
>+   X = 2 power D
>+   D ={0,1,2,3,4,5,6}
>+   M = {1,...,255}
>+   N = {2,...,15}
>+   */
>+unsigned int calcPllValue(unsigned int request_orig, pll_value_t *pll)
>+{
>+      /* used for primary and secondary channel pixel clock pll */
>+      static pllcalparam xparm_PIXEL[] = {
>+              /* 2^0 = 1*/                    {0, 0, 0, 1},
>+              /* 2^ 1 =2*/                    {1, 0, 1, 2},
>+              /* 2^ 2  = 4*/          {2, 0, 2, 4},
>+              {3, 0, 3, 8},
>+              {4, 1, 3, 16},
>+              {5, 2, 3, 32},
>+              /* 2^6 = 64  */         {6, 3, 3, 64},
>+      };
>+
>+      /* used for MXCLK (chip clock) */
>+      static pllcalparam xparm_MXCLK[] = {
>+              /* 2^0 = 1*/                    {0, 0, 0, 1},
>+              /* 2^ 1 =2*/                    {1, 0, 1, 2},
>+              /* 2^ 2  = 4*/          {2, 0, 2, 4},
>+              {3, 0, 3, 8},
>+      };
>+
>+      /*      as sm750 register definition,  N located in 2, 15 and M located 
>in 1, 255       */
>+      int N, M, X, d;
>+      int xcnt;
>+      int miniDiff;
>+      unsigned int RN, quo, rem, fl_quo;
>+      unsigned int input, request;
>+      unsigned int tmpClock, ret;
>+      pllcalparam *xparm;
>+
>+
>+      if (getChipType() == SM750LE) {
>+              /* SM750LE don't have prgrammable PLL and M/N values to work on.
>+                 Just return the requested clock. */
>+              return request_orig;
>+      }
>+
>+
>+      ret = 0;
>+      miniDiff = ~0;
>+      request = request_orig / 1000;
>+      input = pll->inputFreq / 1000;
>+
>+      /* for MXCLK register , no POD provided, so need be treated differently 
>*/
>+
>+      if (pll->clockType != MXCLK_PLL) {
>+              xparm = &xparm_PIXEL[0];
>+              xcnt = sizeof(xparm_PIXEL)/sizeof(xparm_PIXEL[0]);
>+      } else{
>+              xparm = &xparm_MXCLK[0];
>+              xcnt = sizeof(xparm_MXCLK)/sizeof(xparm_MXCLK[0]);
>+      }
>+
>+
>+      for (N = 15; N > 1; N--) {
>+              /* RN will not exceed maximum long if @request <= 285 MHZ (for 
>32bit cpu) */
>+              RN = N * request;
>+              quo = RN / input;
>+              rem = RN % input;/* rem always small than 14318181 */
>+              fl_quo = (rem * 10000 / input);
>+
>+              for (d = xcnt - 1; d >= 0; d--) {
>+                      X = xparm[d].value;
>+                      M = quo*X;
>+                      M += fl_quo * X / 10000;
>+                      /* round step */
>+                      M += (fl_quo*X % 10000) > 5000 ? 1 : 0;
>+                      if (M < 256 && M > 0) {
>+                              unsigned int diff;
>+                              tmpClock = pll->inputFreq * M / N / X;
>+                              diff = absDiff(tmpClock, request_orig);
>+                              if (diff < miniDiff) {
>+                                      pll->M = M;
>+                                      pll->N = N;
>+                                      pll->OD = xparm[d].od;
>+                                      pll->POD = xparm[d].pod;
>+                                      miniDiff = diff;
>+                                      ret = tmpClock;
>+                              }
>+                      }
>+              }
>+      }
>+
>+      /* printk("Finally:  
>pll->n[%lu],m[%lu],od[%lu],pod[%lu]\n",pll->N,pll->M,pll->OD,pll->POD); */
>+      return ret;
>+}
>+
>+unsigned int calcPllValue2(
>+              unsigned int ulRequestClk, /* Required pixel clock in Hz unit */
>+              pll_value_t *pPLL           /* Structure to hold the value to 
>be set in PLL */
>+              )
>+{
>+
>+      unsigned int M, N, OD, POD = 0, diff, pllClk, odPower, podPower;
>+      unsigned int bestDiff = 0xffffffff; /* biggest 32 bit unsigned number */
>+      unsigned int ret;
>+      /* Init PLL structure to know states */
>+      pPLL->M = 0;
>+      pPLL->N = 0;
>+      pPLL->OD = 0;
>+      pPLL->POD = 0;
>+
>+      /* Sanity check: None at the moment */
>+
>+      /* Convert everything in Khz range in order to avoid calculation 
>overflow */
>+      pPLL->inputFreq /= 1000;
>+      ulRequestClk /= 1000;
>+
>+#ifndef VALIDATION_CHIP

So.. what are those? Should these #ifdef's be removed?

I stopped here.. You should read the Documentation/Submitting* files and
follow what they mention there. Please fix the syntax, remove the usage
of templates, and user 'pr_info' instead of 'printk'.


>+      /* The maximum of post divider is 8. */
>+      for (POD = 0; POD <= 3; POD++)
>+#endif
>+      {
>+
>+#ifndef VALIDATION_CHIP
>+              /* MXCLK_PLL does not have post divider. */
>+              if ((POD > 0) && (pPLL->clockType == MXCLK_PLL))
>+                      break;
>+#endif
>+
>+              /* Work out 2 to the power of POD */
>+              podPower = twoToPowerOfx(POD);
>+              /* OD has only 2 bits [15:14] and its value must between 0 to 3 
>*/
>+              for (OD = 0; OD <= 3; OD++) {
>+                      /* Work out 2 to the power of OD */
>+                      odPower = twoToPowerOfx(OD);
>+
>+#ifdef VALIDATION_CHIP
>+                      if (odPower > 4)
>+                              podPower = 4;
>+                      else
>+                              podPower = odPower;
>+#endif
>+
>+                      /* N has 4 bits [11:8] and its value must between 2 and 
>15.
>+                         The N == 1 will behave differently --> Result is not 
>correct. */
>+                      for (N = 2; N <= 15; N++) {
>+                              /* The formula for PLL is ulRequestClk = 
>inputFreq * M / N / (2^OD)
>+                                 In the following steps, we try to work out a 
>best M value given the others are known.
>+                                 To avoid decimal calculation, we use 1000 as 
>multiplier for up to 3 decimal places of accuracy.
>+                                 */
>+                              M = ulRequestClk * N * odPower * 1000 / 
>pPLL->inputFreq;
>+                              M = roundedDiv(M, 1000);
>+
>+                              /* M field has only 8 bits, reject value bigger 
>than 8 bits */
>+                              if (M < 256) {
>+                                      /* Calculate the actual clock for a 
>given M & N */
>+                                      pllClk = pPLL->inputFreq * M / N / 
>odPower / podPower;
>+
>+                                      /* How much are we different from the 
>requirement */
>+                                      diff = absDiff(pllClk, ulRequestClk);
>+
>+                                      if (diff < bestDiff) {
>+                                              bestDiff = diff;
>+
>+                                              /* Store M and N values */
>+                                              pPLL->M  = M;
>+                                              pPLL->N  = N;
>+                                              pPLL->OD = OD;
>+
>+#ifdef VALIDATION_CHIP
>+                                              if (OD > 2)
>+                                                      POD = 2;
>+                                              else
>+                                                      POD = OD;
>+#endif
>+
>+                                              pPLL->POD = POD;
>+                                      }
>+                              }
>+                      }
>+              }
>+      }
>+
>+      /* Restore input frequency from Khz to hz unit */
>+      /*    pPLL->inputFreq *= 1000;*/
>+      ulRequestClk *= 1000;
>+      pPLL->inputFreq = DEFAULT_INPUT_CLOCK; /* Default reference clock */
>+
>+      /* Output debug information */
>+      /* DDKDEBUGPRINT((DISPLAY_LEVEL, "calcPllValue: Requested Frequency = 
>%d\n", ulRequestClk));i
>+         DDKDEBUGPRINT((DISPLAY_LEVEL, "calcPllValue: Input CLK = %dHz, M=%d, 
>N=%d, OD=%d, POD=%d\n", pPLL->inputFreq, pPLL->M, pPLL->N, pPLL->OD, 
>pPLL->POD));i */
>+
>+      /* Return actual frequency that the PLL can set */
>+      ret = calcPLL(pPLL);
>+      return ret;
>+}
>+
>+
>+
>+
>+
>+unsigned int formatPllReg(pll_value_t *pPLL)
>+{
>+      unsigned int ulPllReg = 0;
>+
>+      /* Note that all PLL's have the same format. Here, we just use Panel 
>PLL parameter
>+         to work out the bit fields in the register.
>+         On returning a 32 bit number, the value can be applied to any PLL in 
>the calling function.
>+         */
>+      ulPllReg =
>+              (0 << PANEL_PLL_CTRL_BYPASS_LSB)
>+              | (1 << PANEL_PLL_CTRL_POWER_LSB)
>+              | (0 << PANEL_PLL_CTRL_INPUT_LSB)
>+#ifndef VALIDATION_CHIP
>+              | (pPLL->POD << PANEL_PLL_CTRL_POD_LSB)
>+#endif
>+              | (pPLL->OD << PANEL_PLL_CTRL_OD_LSB)
>+              | (pPLL->N << PANEL_PLL_CTRL_N_LSB)
>+              | (pPLL->M << PANEL_PLL_CTRL_M_LSB);
>+      return ulPllReg;
>+}
>+
>+
>diff --git a/drivers/video/lynxfb/ddk750_chip.h 
>b/drivers/video/lynxfb/ddk750_chip.h
>new file mode 100644
>index 0000000..f24af16
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_chip.h
>@@ -0,0 +1,97 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef DDK750_CHIP_H__
>+#define DDK750_CHIP_H__
>+#define DEFAULT_INPUT_CLOCK 14318181 /* Default reference clock */
>+#define SM750LE_REVISION_ID ((char)0xfe)
>+
>+/* This is all the chips recognized by this library */
>+typedef enum _logical_chip_type_t{
>+      SM_UNKNOWN,
>+      SM718,
>+      SM750,
>+      SM750LE,
>+}
>+logical_chip_type_t;
>+
>+
>+typedef enum _clock_type_t{
>+      MXCLK_PLL,
>+      PRIMARY_PLL,
>+      SECONDARY_PLL,
>+      VGA0_PLL,
>+      VGA1_PLL,
>+}
>+clock_type_t;
>+
>+typedef struct _pll_value_t{
>+      clock_type_t clockType;
>+      unsigned long inputFreq; /* Input clock frequency to the PLL */
>+
>+      /* Use this when clockType = PANEL_PLL */
>+      unsigned long M;
>+      unsigned long N;
>+      unsigned long OD;
>+      unsigned long POD;
>+}
>+pll_value_t;
>+
>+/* input struct to initChipParam() function */
>+typedef struct _initchip_param_t{
>+      unsigned short powerMode;    /* Use power mode 0 or 1 */
>+      unsigned short chipClock;    /* Speed of main chip clock in MHz unit
>+                                      0 = keep the current clock setting
>+                                      Others = the new main chip clock
>+                                      */
>+      unsigned short memClock;     /* Speed of memory clock in MHz unit
>+                                      0 = keep the current clock setting
>+                                      Others = the new memory clock
>+                                      */
>+      unsigned short masterClock;  /* Speed of master clock in MHz unit
>+                                      0 = keep the current clock setting
>+                                      Others = the new master clock
>+                                      */
>+      unsigned short setAllEngOff; /* 0 = leave all engine state untouched.
>+                                      1 = make sure they are off: 2D, Overlay,
>+                                      video alpha, alpha, hardware cursors
>+                                      */
>+      unsigned char resetMemory;   /* 0 = Do not reset the memory controller
>+                                      1 = Reset the memory controller
>+                                      */
>+
>+      /* More initialization parameter can be added if needed */
>+}
>+initchip_param_t;
>+
>+
>+logical_chip_type_t getChipType(void);
>+unsigned int calcPllValue(unsigned int request, pll_value_t *pll);
>+unsigned int calcPllValue2(unsigned int, pll_value_t *);
>+unsigned int formatPllReg(pll_value_t *pPLL);
>+void ddk750_set_mmio(volatile unsigned char *, unsigned short, char);
>+unsigned int ddk750_getVMSize(void);
>+int ddk750_initHw(initchip_param_t *);
>+unsigned int getPllValue(clock_type_t clockType, pll_value_t *pPLL);
>+unsigned int getChipClock(void);
>+void setChipClock(unsigned int);
>+void setMemoryClock(unsigned int frequency);
>+void setMasterClock(unsigned int frequency);
>+
>+
>+#endif
>diff --git a/drivers/video/lynxfb/ddk750_display.c 
>b/drivers/video/lynxfb/ddk750_display.c
>new file mode 100644
>index 0000000..6e973cc
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_display.c
>@@ -0,0 +1,295 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#include "ddk750_reg.h"
>+#include "ddk750_help.h"
>+#include "ddk750_display.h"
>+#include "ddk750_power.h"
>+#include "ddk750_dvi.h"
>+
>+#define primaryWaitVerticalSync(delay) waitNextVerticalSync(0, delay)
>+
>+static void setDisplayControl(int ctrl, int dispState)
>+{
>+      /* state != 0 means turn on both timing & plane en_bit */
>+      unsigned long ulDisplayCtrlReg, ulReservedBits = 0;
>+      int cnt;
>+
>+      cnt = 0;
>+
>+      /* Set the primary display control */
>+      if (!ctrl) {
>+              ulDisplayCtrlReg = PEEK32(PANEL_DISPLAY_CTRL);
>+              /* Turn on/off the Panel display control */
>+              if (dispState) {
>+                      /* Timing should be enabled first before enabling the 
>plane
>+                       * because changing at the same time does not guarantee 
>that
>+                       * the plane will also enabled or disabled.
>+                       */
>+                      ulDisplayCtrlReg = ulDisplayCtrlReg|(1 << 
>PANEL_DISPLAY_CTRL_TIMING_LSB);
>+                      POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg);
>+
>+                      ulDisplayCtrlReg = ulDisplayCtrlReg|(1 << 
>PANEL_DISPLAY_CTRL_PLANE_LSB);
>+                      /* Added some masks to mask out the reserved bits.
>+                       * Sometimes, the reserved bits are set/reset randomly 
>when
>+                       * writing to the PRIMARY_DISPLAY_CTRL, therefore, the 
>register
>+                       * reserved bits are needed to be masked out.
>+                       */
>+                      ulReservedBits = (3 << 
>PANEL_DISPLAY_CTRL_RESERVED_1_MASK_LSB)|
>+                                      (15 << 
>PANEL_DISPLAY_CTRL_RESERVED_2_MASK_LSB)|
>+                                      (1 << 
>PANEL_DISPLAY_CTRL_RESERVED_3_MASK_LSB);
>+
>+                      /* Somehow the register value on the plane is not set
>+                       * until a few delay. Need to write
>+                       * and read it a couple times
>+                       */
>+                      do {
>+                              cnt++;
>+                              POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg);
>+                      } while ((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) 
>!=
>+                                      (ulDisplayCtrlReg & ~ulReservedBits));
>+                      printk("Set Panel Plane enbit:after tried %d times\n", 
>cnt);
>+              } else{
>+                      /* When turning off, there is no rule on the programming
>+                       * sequence since whenever the clock is off, then it 
>does not
>+                       * matter whether the plane is enabled or disabled.
>+                       * Note: Modifying the plane bit will take effect on the
>+                       * next vertical sync. Need to find out if it is 
>necessary to
>+                       * wait for 1 vsync before modifying the timing enable 
>bit.
>+                       * */
>+                      ulDisplayCtrlReg = ulDisplayCtrlReg&(~(1 << 
>PANEL_DISPLAY_CTRL_PLANE_LSB));
>+                      POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg);
>+
>+                      ulDisplayCtrlReg = ulDisplayCtrlReg&(~(1 << 
>PANEL_DISPLAY_CTRL_TIMING_LSB));
>+                      POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg);
>+              }
>+
>+      } else{
>+              /* Set the secondary display control */
>+              ulDisplayCtrlReg = PEEK32(CRT_DISPLAY_CTRL);
>+
>+              if (dispState) {
>+                      /* Timing should be enabled first before enabling the 
>plane because changing at the
>+                         same time does not guarantee that the plane will 
>also enabled or disabled.
>+                         */
>+                      ulDisplayCtrlReg = ulDisplayCtrlReg|(1 << 
>CRT_DISPLAY_CTRL_TIMING_LSB);
>+                      POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg);
>+
>+                      ulDisplayCtrlReg = ulDisplayCtrlReg|(1 << 
>CRT_DISPLAY_CTRL_PLANE_LSB);
>+
>+                      /* Added some masks to mask out the reserved bits.
>+                       * Sometimes, the reserved bits are set/reset randomly 
>when
>+                       * writing to the PRIMARY_DISPLAY_CTRL, therefore, the 
>register
>+                       * reserved bits are needed to be masked out.
>+                       */
>+
>+                      ulReservedBits = (0X1F << 
>CRT_DISPLAY_CTRL_RESERVED_1_MASK_LSB)|
>+                                      (3 << 
>CRT_DISPLAY_CTRL_RESERVED_2_MASK_LSB)|
>+                                      (1 << 
>CRT_DISPLAY_CTRL_RESERVED_3_MASK_LSB)|
>+                                      (1 << 
>CRT_DISPLAY_CTRL_RESERVED_4_MASK_LSB);
>+                      do {
>+                              cnt++;
>+                              POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg);
>+                      } while ((PEEK32(CRT_DISPLAY_CTRL) & ~ulReservedBits) !=
>+                                      (ulDisplayCtrlReg & ~ulReservedBits));
>+                      printk("Set Crt Plane enbit:after tried %d times\n", 
>cnt);
>+              } else{
>+                      /* When turning off, there is no rule on the programming
>+                       * sequence since whenever the clock is off, then it 
>does not
>+                       * matter whether the plane is enabled or disabled.
>+                       * Note: Modifying the plane bit will take effect on 
>the next
>+                       * vertical sync. Need to find out if it is necessary to
>+                       * wait for 1 vsync before modifying the timing enable 
>bit.
>+                       */
>+                      ulDisplayCtrlReg = ulDisplayCtrlReg&(~(1 << 
>CRT_DISPLAY_CTRL_PLANE_LSB));
>+                      POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg);
>+
>+                      ulDisplayCtrlReg = ulDisplayCtrlReg&(~(1 << 
>CRT_DISPLAY_CTRL_TIMING_LSB));
>+                      POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg);
>+              }
>+      }
>+}
>+
>+
>+static void waitNextVerticalSync(int ctrl, int delay)
>+{
>+      unsigned int status;
>+      if (!ctrl) {
>+              /* primary controller */
>+
>+              /* Do not wait when the Primary PLL is off or display control 
>is already off.
>+                 This will prevent the software to wait forever. */
>+              if (((1&(PEEK32(PANEL_PLL_CTRL) >> PANEL_PLL_CTRL_POWER_LSB)) ==
>+                                      PANEL_PLL_CTRL_POWER_OFF) ||
>+                              ((1&(PEEK32(PANEL_DISPLAY_CTRL) >> 
>PANEL_DISPLAY_CTRL_TIMING_LSB)) ==
>+                               PANEL_DISPLAY_CTRL_TIMING_DISABLE)) {
>+                      return;
>+              }
>+              while (delay-- > 0) {
>+                      /* Wait for end of vsync. */
>+                      do {
>+                              status = 1&(PEEK32(SYSTEM_CTRL) >> 
>SYSTEM_CTRL_PANEL_VSYNC_LSB);
>+                      } while (status == SYSTEM_CTRL_PANEL_VSYNC_ACTIVE);
>+
>+                      /* Wait for start of vsync. */
>+                      do {
>+                              status = 1&(PEEK32(SYSTEM_CTRL) >> 
>SYSTEM_CTRL_PANEL_VSYNC_LSB);
>+                      } while (status == SYSTEM_CTRL_PANEL_VSYNC_INACTIVE);
>+              }
>+
>+      } else{
>+
>+              /* Do not wait when the Primary PLL is off or display control 
>is already off.
>+                 This will prevent the software to wait forever. */
>+              if ((1&(PEEK32(CRT_PLL_CTRL) >> CRT_PLL_CTRL_POWER_LSB) ==
>+                                      CRT_PLL_CTRL_POWER_OFF) ||
>+                              (1&(PEEK32(CRT_DISPLAY_CTRL) >> 
>CRT_DISPLAY_CTRL_TIMING_LSB) ==
>+                               CRT_DISPLAY_CTRL_TIMING_DISABLE)) {
>+                      return;
>+              }
>+
>+              while (delay-- > 0) {
>+                      /* Wait for end of vsync. */
>+                      do {
>+                              status = 1&(PEEK32(SYSTEM_CTRL) >> 
>SYSTEM_CTRL_CRT_VSYNC_LSB);
>+                      } while (status == SYSTEM_CTRL_CRT_VSYNC_ACTIVE);
>+
>+                      /* Wait for start of vsync. */
>+                      do {
>+                              status = 1&(PEEK32(SYSTEM_CTRL) >> 
>SYSTEM_CTRL_CRT_VSYNC_LSB);
>+                      } while (status == SYSTEM_CTRL_CRT_VSYNC_INACTIVE);
>+              }
>+      }
>+}
>+
>+static void swPanelPowerSequence_sm750le(int disp, int delay)
>+{
>+      unsigned int reg;
>+      reg = PEEK32(DISPLAY_CONTROL_750LE);
>+      if (disp)
>+              reg |= 0xf;
>+      else
>+              reg &= ~0xf;
>+      POKE32(DISPLAY_CONTROL_750LE, reg);
>+}
>+
>+static void swPanelPowerSequence(int disp, int delay)
>+{
>+      unsigned int reg;
>+
>+      /* disp should be 1 to open sequence */
>+      reg = PEEK32(PANEL_DISPLAY_CTRL);
>+      reg &= ~(1 << PANEL_DISPLAY_CTRL_FPEN_LSB);
>+      reg = reg|(disp << PANEL_DISPLAY_CTRL_FPEN_LSB);
>+      POKE32(PANEL_DISPLAY_CTRL, reg);
>+      primaryWaitVerticalSync(delay);
>+
>+      reg = PEEK32(PANEL_DISPLAY_CTRL);
>+      reg &= ~(1 << PANEL_DISPLAY_CTRL_DATA_LSB);
>+      reg = reg|(disp << PANEL_DISPLAY_CTRL_DATA_LSB);
>+      POKE32(PANEL_DISPLAY_CTRL, reg);
>+      primaryWaitVerticalSync(delay);
>+
>+      reg = PEEK32(PANEL_DISPLAY_CTRL);
>+      reg &= ~(1 << PANEL_DISPLAY_CTRL_VBIASEN_LSB);
>+      reg = reg|(disp << PANEL_DISPLAY_CTRL_VBIASEN_LSB);
>+      POKE32(PANEL_DISPLAY_CTRL, reg);
>+      primaryWaitVerticalSync(delay);
>+
>+      reg = PEEK32(PANEL_DISPLAY_CTRL);
>+      reg &= ~(1 << PANEL_DISPLAY_CTRL_FPEN_LSB);
>+      reg = reg|(disp << PANEL_DISPLAY_CTRL_FPEN_LSB);
>+      POKE32(PANEL_DISPLAY_CTRL, reg);
>+      primaryWaitVerticalSync(delay);
>+
>+}
>+
>+void ddk750_setLogicalDispOut(disp_output_t output)
>+{
>+      unsigned int reg;
>+      if (output & PNL_2_USAGE) {
>+              /* set panel path controller select */
>+              reg = PEEK32(PANEL_DISPLAY_CTRL);
>+              reg &= ~(3 << PANEL_DISPLAY_CTRL_SELECT_LSB);
>+              reg = reg|((output & PNL_2_MASK) >> PNL_2_OFFSET) << 
>PANEL_DISPLAY_CTRL_SELECT_LSB;
>+              POKE32(PANEL_DISPLAY_CTRL, reg);
>+      }
>+
>+      if (output & CRT_2_USAGE) {
>+              /* set crt path controller select */
>+              reg = PEEK32(CRT_DISPLAY_CTRL);
>+              reg &= ~(3 << CRT_DISPLAY_CTRL_SELECT_LSB);
>+              reg = reg|((output & CRT_2_MASK) >> CRT_2_OFFSET) << 
>CRT_DISPLAY_CTRL_SELECT_LSB;
>+              /*se blank off */
>+              reg = reg&(~(1 << CRT_DISPLAY_CTRL_BLANK_LSB));
>+              POKE32(CRT_DISPLAY_CTRL, reg);
>+      }
>+      if (output & PRI_TP_USAGE) {
>+              /* set primary timing and plane en_bit */
>+              setDisplayControl(0, (output&PRI_TP_MASK) >> PRI_TP_OFFSET);
>+      }
>+
>+      if (output & SEC_TP_USAGE) {
>+              /* set secondary timing and plane en_bit*/
>+              setDisplayControl(1, (output&SEC_TP_MASK) >> SEC_TP_OFFSET);
>+      }
>+
>+      if (output & PNL_SEQ_USAGE) {
>+              /* set  panel sequence */
>+              swPanelPowerSequence((output&PNL_SEQ_MASK) >> PNL_SEQ_OFFSET, 
>4);
>+      }
>+
>+      if (output & DAC_USAGE)
>+              setDAC((output & DAC_MASK) >> DAC_OFFSET);
>+
>+      if (output & DPMS_USAGE)
>+              ddk750_setDPMS((output & DPMS_MASK) >> DPMS_OFFSET);
>+}
>+
>+
>+int ddk750_initDVIDisp()
>+{
>+      /* Initialize DVI. If the dviInit fail and the VendorID or the DeviceID 
>are
>+         not zeroed, then set the failure flag. If it is zeroe, it might mean
>+         that the system is in Dual CRT Monitor configuration. */
>+
>+      /* De-skew enabled with default 111b value.
>+         This will fix some artifacts problem in some mode on board 2.2.
>+         Somehow this fix does not affect board 2.1.
>+         */
>+      if ((dviInit(1, /* Select Rising Edge */
>+                                      1, /* Select 24-bit bus */
>+                                      0, /* Select Single Edge clock */
>+                                      1, /* Enable HSync as is */
>+                                      1, /* Enable VSync as is */
>+                                      1, /* Enable De-skew */
>+                                      7, /* Set the de-skew setting to 
>maximum setup */
>+                                      1, /* Enable continuous Sync */
>+                                      1, /* Enable PLL Filter */
>+                                      4   /* Use the recommended value for 
>PLL Filter value */
>+                  ) != 0) && (dviGetVendorID() != 0x0000) && 
>(dviGetDeviceID() != 0x0000)) {
>+              return -1;
>+      }
>+
>+      /* TODO: Initialize other display component */
>+
>+      /* Success */
>+      return 0;
>+
>+}
>+
>diff --git a/drivers/video/lynxfb/ddk750_display.h 
>b/drivers/video/lynxfb/ddk750_display.h
>new file mode 100644
>index 0000000..abc2a93
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_display.h
>@@ -0,0 +1,124 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef DDK750_DISPLAY_H__
>+#define DDK750_DISPLAY_H__
>+
>+/* panel path select
>+   80000[29:28]
>+   */
>+
>+#define PNL_2_OFFSET 0
>+#define PNL_2_MASK (3 << PNL_2_OFFSET)
>+#define PNL_2_USAGE   (PNL_2_MASK << 16)
>+#define PNL_2_PRI     ((0 << PNL_2_OFFSET)|PNL_2_USAGE)
>+#define PNL_2_SEC     ((2 << PNL_2_OFFSET)|PNL_2_USAGE)
>+
>+
>+/* primary timing & plane enable bit
>+1: 80000[8] & 80000[2] on
>+0: both off
>+*/
>+#define PRI_TP_OFFSET 4
>+#define PRI_TP_MASK (1 << PRI_TP_OFFSET)
>+#define PRI_TP_USAGE (PRI_TP_MASK << 16)
>+#define PRI_TP_ON ((0x1 << PRI_TP_OFFSET)|PRI_TP_USAGE)
>+#define PRI_TP_OFF ((0x0 << PRI_TP_OFFSET)|PRI_TP_USAGE)
>+
>+
>+/* panel sequency status
>+   80000[27:24]
>+   */
>+#define PNL_SEQ_OFFSET 6
>+#define PNL_SEQ_MASK (1 << PNL_SEQ_OFFSET)
>+#define PNL_SEQ_USAGE (PNL_SEQ_MASK << 16)
>+#define PNL_SEQ_ON ((1 << PNL_SEQ_OFFSET)|PNL_SEQ_USAGE)
>+#define PNL_SEQ_OFF ((0 << PNL_SEQ_OFFSET)|PNL_SEQ_USAGE)
>+
>+/* dual digital output
>+   80000[19]
>+   */
>+#define DUAL_TFT_OFFSET 8
>+#define DUAL_TFT_MASK (1 << DUAL_TFT_OFFSET)
>+#define DUAL_TFT_USAGE (DUAL_TFT_MASK << 16)
>+#define DUAL_TFT_ON ((1 << DUAL_TFT_OFFSET)|DUAL_TFT_USAGE)
>+#define DUAL_TFT_OFF ((0 << DUAL_TFT_OFFSET)|DUAL_TFT_USAGE)
>+
>+/* secondary timing & plane enable bit
>+1:80200[8] & 80200[2] on
>+0: both off
>+*/
>+#define SEC_TP_OFFSET 5
>+#define SEC_TP_MASK (1 << SEC_TP_OFFSET)
>+#define SEC_TP_USAGE (SEC_TP_MASK << 16)
>+#define SEC_TP_ON  ((0x1 << SEC_TP_OFFSET)|SEC_TP_USAGE)
>+#define SEC_TP_OFF ((0x0 << SEC_TP_OFFSET)|SEC_TP_USAGE)
>+
>+/* crt path select
>+   80200[19:18]
>+   */
>+#define CRT_2_OFFSET 2
>+#define CRT_2_MASK (3 << CRT_2_OFFSET)
>+#define CRT_2_USAGE (CRT_2_MASK << 16)
>+#define CRT_2_PRI ((0x0 << CRT_2_OFFSET)|CRT_2_USAGE)
>+#define CRT_2_SEC ((0x2 << CRT_2_OFFSET)|CRT_2_USAGE)
>+
>+
>+/* DAC affect both DVI and DSUB
>+   4[20]
>+   */
>+#define DAC_OFFSET 7
>+#define DAC_MASK (1 << DAC_OFFSET)
>+#define DAC_USAGE (DAC_MASK << 16)
>+#define DAC_ON ((0x0 << DAC_OFFSET)|DAC_USAGE)
>+#define DAC_OFF ((0x1 << DAC_OFFSET)|DAC_USAGE)
>+
>+/* DPMS only affect D-SUB head
>+   0[31:30]
>+   */
>+#define DPMS_OFFSET 9
>+#define DPMS_MASK (3 << DPMS_OFFSET)
>+#define DPMS_USAGE (DPMS_MASK << 16)
>+#define DPMS_OFF ((3 << DPMS_OFFSET)|DPMS_USAGE)
>+#define DPMS_ON ((0 << DPMS_OFFSET)|DPMS_USAGE)
>+
>+
>+
>+/*
>+   LCD1 means panel path TFT1  & panel path DVI (so enable DAC)
>+   CRT means crt path DSUB
>+   */
>+
>+typedef enum _disp_output_t{
>+      do_LCD1_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON|DAC_ON,
>+      do_LCD1_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON|DAC_ON,
>+      do_LCD2_PRI = CRT_2_PRI|PRI_TP_ON|DUAL_TFT_ON,
>+      do_LCD2_SEC = CRT_2_SEC|SEC_TP_ON|DUAL_TFT_ON,
>+      /*
>+         do_DSUB_PRI = CRT_2_PRI|PRI_TP_ON|DPMS_ON|DAC_ON,
>+         do_DSUB_SEC = CRT_2_SEC|SEC_TP_ON|DPMS_ON|DAC_ON,
>+         */
>+      do_CRT_PRI = CRT_2_PRI|PRI_TP_ON|DPMS_ON|DAC_ON,
>+      do_CRT_SEC = CRT_2_SEC|SEC_TP_ON|DPMS_ON|DAC_ON,
>+}
>+disp_output_t;
>+
>+void ddk750_setLogicalDispOut(disp_output_t);
>+int ddk750_initDVIDisp(void);
>+
>+#endif
>diff --git a/drivers/video/lynxfb/ddk750_dvi.c 
>b/drivers/video/lynxfb/ddk750_dvi.c
>new file mode 100644
>index 0000000..0663009
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_dvi.c
>@@ -0,0 +1,114 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifdef USE_DVICHIP
>+#include "ddk750_help.h"
>+#include "ddk750_reg.h"
>+#include "ddk750_dvi.h"
>+#include "ddk750_sii164.h"
>+
>+
>+/* This global variable contains all the supported driver and its 
>corresponding
>+   function API. Please set the function pointer to NULL whenever the function
>+   is not supported. */
>+static dvi_ctrl_device_t g_dcftSupportedDviController[] = {
>+#ifdef DVI_CTRL_SII164
>+      {
>+              .pfnInit = sii164InitChip,
>+              .pfnGetVendorId = sii164GetVendorID,
>+              .pfnGetDeviceId = sii164GetDeviceID,
>+#ifdef SII164_FULL_FUNCTIONS
>+              .pfnResetChip = sii164ResetChip,
>+              .pfnGetChipString = sii164GetChipString,
>+              .pfnSetPower = sii164SetPower,
>+              .pfnEnableHotPlugDetection = sii164EnableHotPlugDetection,
>+              .pfnIsConnected = sii164IsConnected,
>+              .pfnCheckInterrupt = sii164CheckInterrupt,
>+              .pfnClearInterrupt = sii164ClearInterrupt,
>+#endif
>+      },
>+#endif
>+};
>+
>+
>+int dviInit(
>+              unsigned char edgeSelect,
>+              unsigned char busSelect,
>+              unsigned char dualEdgeClkSelect,
>+              unsigned char hsyncEnable,
>+              unsigned char vsyncEnable,
>+              unsigned char deskewEnable,
>+              unsigned char deskewSetting,
>+              unsigned char continuousSyncEnable,
>+              unsigned char pllFilterEnable,
>+              unsigned char pllFilterValue
>+         )
>+{
>+      dvi_ctrl_device_t *pCurrentDviCtrl;
>+      pCurrentDviCtrl = g_dcftSupportedDviController;
>+      if (pCurrentDviCtrl->pfnInit != NULL) {
>+              return pCurrentDviCtrl->pfnInit(edgeSelect, busSelect, 
>dualEdgeClkSelect, hsyncEnable,
>+                              vsyncEnable, deskewEnable, deskewSetting, 
>continuousSyncEnable,
>+                              pllFilterEnable, pllFilterValue);
>+      }
>+      return -1; /* error */
>+}
>+
>+
>+/*
>+ *  dviGetVendorID
>+ *      This function gets the vendor ID of the DVI controller chip.
>+ *
>+ *  Output:
>+ *      Vendor ID
>+ */
>+unsigned short dviGetVendorID()
>+{
>+      dvi_ctrl_device_t *pCurrentDviCtrl;
>+
>+      /*pCurrentDviCtrl = getDviCtrl();*/
>+      pCurrentDviCtrl = g_dcftSupportedDviController;
>+      if (pCurrentDviCtrl != (dvi_ctrl_device_t *)0)
>+              return pCurrentDviCtrl->pfnGetVendorId();
>+
>+      return 0x0000;
>+}
>+
>+
>+/*
>+ *  dviGetDeviceID
>+ *      This function gets the device ID of the DVI controller chip.
>+ *
>+ *  Output:
>+ *      Device ID
>+ */
>+unsigned short dviGetDeviceID()
>+{
>+      dvi_ctrl_device_t *pCurrentDviCtrl;
>+
>+      /*    pCurrentDviCtrl = getDviCtrl();*/
>+      pCurrentDviCtrl = g_dcftSupportedDviController;
>+      if (pCurrentDviCtrl != (dvi_ctrl_device_t *)0)
>+              return pCurrentDviCtrl->pfnGetDeviceId();
>+
>+      return 0x0000;
>+}
>+
>+#endif
>+
>+
>diff --git a/drivers/video/lynxfb/ddk750_dvi.h 
>b/drivers/video/lynxfb/ddk750_dvi.h
>new file mode 100644
>index 0000000..64773fd
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_dvi.h
>@@ -0,0 +1,84 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef DDK750_DVI_H__
>+#define DDK750_DVI_H__
>+
>+/* dvi chip stuffs structros */
>+
>+typedef long (*PFN_DVICTRL_INIT)(
>+              unsigned char edgeSelect,
>+              unsigned char busSelect,
>+              unsigned char dualEdgeClkSelect,
>+              unsigned char hsyncEnable,
>+              unsigned char vsyncEnable,
>+              unsigned char deskewEnable,
>+              unsigned char deskewSetting,
>+              unsigned char continuousSyncEnable,
>+              unsigned char pllFilterEnable,
>+              unsigned char pllFilterValue);
>+typedef void (*PFN_DVICTRL_RESETCHIP)(void);
>+typedef char* (*PFN_DVICTRL_GETCHIPSTRING)(void);
>+typedef unsigned short (*PFN_DVICTRL_GETVENDORID)(void);
>+typedef unsigned short (*PFN_DVICTRL_GETDEVICEID)(void);
>+typedef void (*PFN_DVICTRL_SETPOWER)(unsigned char powerUp);
>+typedef void (*PFN_DVICTRL_HOTPLUGDETECTION)(unsigned char enableHotPlug);
>+typedef unsigned char (*PFN_DVICTRL_ISCONNECTED)(void);
>+typedef unsigned char (*PFN_DVICTRL_CHECKINTERRUPT)(void);
>+typedef void (*PFN_DVICTRL_CLEARINTERRUPT)(void);
>+
>+
>+
>+/* Structure to hold all the function pointer to the DVI Controller. */
>+typedef struct _dvi_ctrl_device_t{
>+      PFN_DVICTRL_INIT                pfnInit;
>+      PFN_DVICTRL_RESETCHIP           pfnResetChip;
>+      PFN_DVICTRL_GETCHIPSTRING       pfnGetChipString;
>+      PFN_DVICTRL_GETVENDORID         pfnGetVendorId;
>+      PFN_DVICTRL_GETDEVICEID         pfnGetDeviceId;
>+      PFN_DVICTRL_SETPOWER            pfnSetPower;
>+      PFN_DVICTRL_HOTPLUGDETECTION    pfnEnableHotPlugDetection;
>+      PFN_DVICTRL_ISCONNECTED         pfnIsConnected;
>+      PFN_DVICTRL_CHECKINTERRUPT      pfnCheckInterrupt;
>+      PFN_DVICTRL_CLEARINTERRUPT      pfnClearInterrupt;
>+} dvi_ctrl_device_t;
>+#define DVI_CTRL_SII164
>+
>+
>+
>+/* dvi functions prototype */
>+int dviInit(
>+              unsigned char edgeSelect,
>+              unsigned char busSelect,
>+              unsigned char dualEdgeClkSelect,
>+              unsigned char hsyncEnable,
>+              unsigned char vsyncEnable,
>+              unsigned char deskewEnable,
>+              unsigned char deskewSetting,
>+              unsigned char continuousSyncEnable,
>+              unsigned char pllFilterEnable,
>+              unsigned char pllFilterValue
>+         );
>+
>+unsigned short dviGetVendorID(void);
>+unsigned short dviGetDeviceID(void);
>+
>+
>+
>+#endif
>+
>diff --git a/drivers/video/lynxfb/ddk750_help.c 
>b/drivers/video/lynxfb/ddk750_help.c
>new file mode 100644
>index 0000000..2e95b58
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_help.c
>@@ -0,0 +1,37 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+/*#include "ddk750_reg.h" */
>+/*#include "ddk750_chip.h" */
>+#include "ddk750_help.h"
>+
>+volatile unsigned char __iomem *mmio750;
>+char revId750;
>+unsigned short devId750;
>+
>+/* after driver mapped io registers, use this function first */
>+void ddk750_set_mmio(volatile unsigned char *addr, unsigned short devId, char 
>revId)
>+{
>+      mmio750 = addr;
>+      devId750 = devId;
>+      revId750 = revId;
>+      if (revId == 0xfe)
>+              printk("found sm750le\n");
>+}
>+
>+
>diff --git a/drivers/video/lynxfb/ddk750_help.h 
>b/drivers/video/lynxfb/ddk750_help.h
>new file mode 100644
>index 0000000..860c0c1
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_help.h
>@@ -0,0 +1,42 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef DDK750_HELP_H__
>+#define DDK750_HELP_H__
>+#include "ddk750_chip.h"
>+#ifndef USE_INTERNAL_REGISTER_ACCESS
>+
>+#include <linux/ioport.h>
>+#include <asm/io.h>
>+#include <asm/uaccess.h>
>+#include "lynx_help.h"
>+
>+
>+ /* software control endianess */
>+#define PEEK32(addr) readl((addr)+mmio750)
>+#define POKE32(addr, data) writel((data), (addr)+mmio750)
>+
>+
>+extern volatile unsigned  char __iomem *mmio750;
>+extern char revId750;
>+extern unsigned short devId750;
>+#else
>+/* implement if you want use it*/
>+#endif
>+
>+#endif
>diff --git a/drivers/video/lynxfb/ddk750_hwi2c.c 
>b/drivers/video/lynxfb/ddk750_hwi2c.c
>new file mode 100644
>index 0000000..c37ff82
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_hwi2c.c
>@@ -0,0 +1,290 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifdef USE_HW_I2C
>+#include "ddk750_help.h"
>+#include "ddk750_reg.h"
>+#include "ddk750_hwi2c.h"
>+#include "ddk750_power.h"
>+
>+#define MAX_HWI2C_FIFO                  16
>+#define HWI2C_WAIT_TIMEOUT              0xF0000
>+
>+
>+int hwI2CInit(
>+              unsigned char busSpeedMode
>+)
>+{
>+      unsigned int value;
>+
>+      /* Enable GPIO 30 & 31 as IIC clock & data */
>+      value = PEEK32(GPIO_MUX);
>+
>+      value |= (1 << GPIO_MUX_30_LSB)|(1 << GPIO_MUX_31_LSB);
>+      POKE32(GPIO_MUX, value);
>+
>+      /* Enable Hardware I2C power.
>+TODO: Check if we need to enable GPIO power?
>+*/
>+      enableI2C(1);
>+
>+      /* Enable the I2C Controller and set the bus speed mode */
>+      value = PEEK32(I2C_CTRL);
>+
>+      if (busSpeedMode == 0)
>+              value &= ~(1 << I2C_CTRL_MODE_LSB);
>+      else
>+              value |= 1 << I2C_CTRL_MODE_LSB;
>+      value |= 1 << I2C_CTRL_EN_LSB;
>+
>+      POKE32(I2C_CTRL, value);
>+
>+      return 0;
>+}
>+
>+
>+void hwI2CClose(void)
>+{
>+      unsigned int value;
>+
>+      /* Disable I2C controller */
>+      value = PEEK32(I2C_CTRL);
>+
>+      value &= ~(1 << I2C_CTRL_EN_LSB);
>+      POKE32(I2C_CTRL, value);
>+
>+      /* Disable I2C Power */
>+      enableI2C(0);
>+
>+      /* Set GPIO 30 & 31 back as GPIO pins */
>+      value = PEEK32(GPIO_MUX);
>+      value &= ~(1 << GPIO_MUX_30_LSB);
>+      value &= ~(1 << GPIO_MUX_31_LSB);
>+      POKE32(GPIO_MUX, value);
>+}
>+
>+
>+long hwI2CWaitTXDone(void)
>+{
>+      unsigned int timeout;
>+
>+      /* Wait until the transfer is completed. */
>+      timeout = HWI2C_WAIT_TIMEOUT;
>+
>+      while (((1&(PEEK32(I2C_STATUS) >> I2C_STATUS_TX_LSB)) != 
>I2C_STATUS_TX_COMPLETED) &&
>+                      (timeout != 0))
>+              timeout--;
>+
>+      if (timeout == 0)
>+              return -1;
>+
>+      return 0;
>+}
>+
>+
>+
>+/*
>+ *  This function writes data to the i2c slave device registers.
>+ *
>+ *  Parameters:
>+ *      deviceAddress   - i2c Slave device address
>+ *      length          - Total number of bytes to be written to the device
>+ *      pBuffer         - The buffer that contains the data to be written to 
>the
>+ *                     i2c device.
>+ *
>+ *  Return Value:
>+ *      Total number of bytes those are actually written.
>+ */
>+unsigned int hwI2CWriteData(
>+              unsigned char deviceAddress,
>+              unsigned int length,
>+              unsigned char *pBuffer
>+              )
>+{
>+      unsigned char count, i;
>+      unsigned int totalBytes = 0;
>+
>+      /* Set the Device Address */
>+      POKE32(I2C_SLAVE_ADDRESS, deviceAddress & ~0x01);
>+
>+      /* Write data.
>+       * Note:
>+       *      Only 16 byte can be accessed per i2c start instruction.
>+       */
>+      do {
>+              /* Reset I2C by writing 0 to I2C_RESET register to clear the 
>previous status. */
>+              POKE32(I2C_RESET, 0);
>+
>+              /* Set the number of bytes to be written */
>+              if (length < MAX_HWI2C_FIFO)
>+                      count = length - 1;
>+              else
>+                      count = MAX_HWI2C_FIFO - 1;
>+              POKE32(I2C_BYTE_COUNT, count);
>+
>+              /* Move the data to the I2C data register */
>+              for (i = 0; i <= count; i++)
>+                      POKE32(I2C_DATA0 + i, *pBuffer++);
>+
>+              /* Start the I2C */
>+
>+              POKE32(I2C_CTRL, PEEK32(I2C_CTRL)|(1 << I2C_CTRL_CTRL_LSB));
>+
>+              /* Wait until the transfer is completed. */
>+              if (hwI2CWaitTXDone() != 0)
>+                      break;
>+
>+              /* Substract length */
>+              length -= (count + 1);
>+
>+              /* Total byte written */
>+              totalBytes += (count + 1);
>+
>+      } while (length > 0);
>+
>+      return totalBytes;
>+}
>+
>+
>+
>+
>+/*
>+ *  This function reads data from the slave device and stores them
>+ *  in the given buffer
>+ *
>+ *  Parameters:
>+ *      deviceAddress   - i2c Slave device address
>+ *      length          - Total number of bytes to be read
>+ *      pBuffer         - Pointer to a buffer to be filled with the data read
>+ *                     from the slave device. It has to be the same size as 
>the
>+ *                     length to make sure that it can keep all the data read.
>+ *
>+ *  Return Value:
>+ *      Total number of actual bytes read from the slave device
>+ */
>+unsigned int hwI2CReadData(
>+              unsigned char deviceAddress,
>+              unsigned int length,
>+              unsigned char *pBuffer
>+              )
>+{
>+      unsigned char count, i;
>+      unsigned int totalBytes = 0;
>+
>+      /* Set the Device Address */
>+      POKE32(I2C_SLAVE_ADDRESS, deviceAddress | 0x01);
>+
>+      /* Read data and save them to the buffer.
>+       * Note:
>+       *      Only 16 byte can be accessed per i2c start instruction.
>+       */
>+      do {
>+              /* Reset I2C by writing 0 to I2C_RESET register to clear all 
>the status. */
>+              POKE32(I2C_RESET, 0);
>+
>+              /* Set the number of bytes to be read */
>+              if (length <= MAX_HWI2C_FIFO)
>+                      count = length - 1;
>+              else
>+                      count = MAX_HWI2C_FIFO - 1;
>+              POKE32(I2C_BYTE_COUNT, count);
>+
>+              /* Start the I2C */
>+              POKE32(I2C_CTRL, PEEK32(I2C_CTRL)|(1 << I2C_CTRL_CTRL_LSB));
>+
>+              /* Wait until transaction done. */
>+              if (hwI2CWaitTXDone() != 0)
>+                      break;
>+
>+              /* Save the data to the given buffer */
>+              for (i = 0; i <= count; i++)
>+                      *pBuffer++ = PEEK32(I2C_DATA0 + i);
>+
>+              /* Substract length by 16 */
>+              length -= (count + 1);
>+
>+              /* Number of bytes read. */
>+              totalBytes += (count + 1);
>+
>+      } while (length > 0);
>+
>+      return totalBytes;
>+}
>+
>+
>+
>+
>+/*
>+ *  This function reads the slave device's register
>+ *
>+ *  Parameters:
>+ *      deviceAddress   - i2c Slave device address which register
>+ *                        to be read from
>+ *      registerIndex   - Slave device's register to be read
>+ *
>+ *  Return Value:
>+ *      Register value
>+ */
>+unsigned char hwI2CReadReg(
>+              unsigned char deviceAddress,
>+              unsigned char registerIndex
>+              )
>+{
>+      unsigned char value = (0xFF);
>+
>+      if (hwI2CWriteData(deviceAddress, 1, &registerIndex) == 1)
>+              hwI2CReadData(deviceAddress, 1, &value);
>+
>+      return value;
>+}
>+
>+
>+
>+
>+
>+/*
>+ *  This function writes a value to the slave device's register
>+ *
>+ *  Parameters:
>+ *      deviceAddress   - i2c Slave device address which register
>+ *                        to be written
>+ *      registerIndex   - Slave device's register to be written
>+ *      data            - Data to be written to the register
>+ *
>+ *  Result:
>+ *          0   - Success
>+ *         -1   - Fail
>+ */
>+int hwI2CWriteReg(
>+              unsigned char deviceAddress,
>+              unsigned char registerIndex,
>+              unsigned char data
>+              )
>+{
>+      unsigned char value[2];
>+
>+      value[0] = registerIndex;
>+      value[1] = data;
>+      if (hwI2CWriteData(deviceAddress, 2, value) == 2)
>+              return 0;
>+
>+      return -1;
>+}
>+
>+
>+#endif
>diff --git a/drivers/video/lynxfb/ddk750_hwi2c.h 
>b/drivers/video/lynxfb/ddk750_hwi2c.h
>new file mode 100644
>index 0000000..6cbd292
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_hwi2c.h
>@@ -0,0 +1,28 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef DDK750_HWI2C_H__
>+#define DDK750_HWI2C_H__
>+
>+/* hwi2c functions */
>+int hwI2CInit(unsigned char busSpeedMode);
>+void hwI2CClose(void);
>+
>+unsigned char hwI2CReadReg(unsigned char deviceAddress, unsigned char 
>registerIndex);
>+int hwI2CWriteReg(unsigned char deviceAddress, unsigned char registerIndex, 
>unsigned char data);
>+#endif
>diff --git a/drivers/video/lynxfb/ddk750_mode.c 
>b/drivers/video/lynxfb/ddk750_mode.c
>new file mode 100644
>index 0000000..ecb55c2
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_mode.c
>@@ -0,0 +1,213 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#include "ddk750_help.h"
>+#include "ddk750_reg.h"
>+#include "ddk750_mode.h"
>+#include "ddk750_chip.h"
>+
>+/*
>+   SM750LE only:
>+   This function takes care extra registers and bit fields required to set
>+   up a mode in SM750LE
>+
>+   Explanation about Display Control register:
>+   HW only supports 7 predefined pixel clocks, and clock select is
>+   in bit 29:27 of    Display Control register.
>+   */
>+static unsigned long displayControlAdjust_SM750LE(mode_parameter_t 
>*pModeParam, unsigned long dispControl)
>+{
>+      unsigned long x, y;
>+
>+      x = pModeParam->horizontal_display_end;
>+      y = pModeParam->vertical_display_end;
>+
>+      /* SM750LE has to set up the top-left and bottom-right
>+         registers as well.
>+         Note that normal SM750/SM718 only use those two register for
>+         auto-centering mode.
>+         */
>+      POKE32(CRT_AUTO_CENTERING_TL,
>+                      (~(0x7FF << CRT_AUTO_CENTERING_TL_TOP_LSB))&
>+                      (~(0x7FF << CRT_AUTO_CENTERING_TL_LEFT_LSB)));
>+
>+      /*clear*/
>+      POKE32(CRT_AUTO_CENTERING_BR,
>+                      (~(0x7FF << CRT_AUTO_CENTERING_BR_BOTTOM_LSB))|
>+                      (~(0x7FF << CRT_AUTO_CENTERING_BR_RIGHT_LSB)));
>+      POKE32(CRT_AUTO_CENTERING_BR,
>+                      (y-1 << CRT_AUTO_CENTERING_BR_BOTTOM_LSB)|
>+                      (x-1 << CRT_AUTO_CENTERING_BR_RIGHT_LSB));
>+      /* Clear bit 29:27 of display control register */
>+      dispControl &= ~(7 << CRT_DISPLAY_CTRL_CLK_LSB);
>+      /* Assume common fields in dispControl have been properly set before
>+         calling this function.
>+         This function only sets the extra fields in dispControl.
>+         */
>+
>+
>+      /* Set bit 29:27 of display control register for the right clock */
>+      /* Note that SM750LE only need to supported 7 resoluitons. */
>+      dispControl &= (~(7 << CRT_DISPLAY_CTRL_CLK_LSB));
>+      if (x == 800 && y == 600)
>+              dispControl |= 1 << CRT_DISPLAY_CTRL_CLK_LSB;
>+      else if (x == 1024 && y == 768)
>+              dispControl |= 3 << CRT_DISPLAY_CTRL_CLK_LSB;
>+      else if (x == 1152 && y == 864)
>+              dispControl |= 5 << CRT_DISPLAY_CTRL_CLK_LSB;
>+      else if (x == 1280 && y == 768)
>+              dispControl |= 5 << CRT_DISPLAY_CTRL_CLK_LSB;
>+      else if (x == 1280 && y == 720)
>+              dispControl |= 4 << CRT_DISPLAY_CTRL_CLK_LSB;
>+      else if (x == 1280 && y == 960)
>+              dispControl |= 6 << CRT_DISPLAY_CTRL_CLK_LSB;
>+      else if (x == 1280 && y == 1024)
>+              dispControl |= 6 << CRT_DISPLAY_CTRL_CLK_LSB;
>+      else /* default to VGA clock */
>+              dispControl &= ~(7 << CRT_DISPLAY_CTRL_CLK_LSB);
>+
>+      /* Set bit 25:24 of display controller */
>+      dispControl |= 1 << CRT_DISPLAY_CTRL_CRTSELECT_LSB;
>+      dispControl &= ~(1 << CRT_DISPLAY_CTRL_RGBBIT_LSB);
>+
>+      /* Set bit 14 of display controller */
>+      dispControl |= 1 << CRT_DISPLAY_CTRL_CLOCK_PHASE_LSB;
>+      POKE32(CRT_DISPLAY_CTRL, dispControl);
>+
>+      return dispControl;
>+
>+}
>+
>+
>+
>+/* only timing related registers will be  programed */
>+static int programModeRegisters(mode_parameter_t *pModeParam, pll_value_t 
>*pll)
>+{
>+      int ret = 0;
>+      int cnt = 0;
>+      unsigned int ulTmpValue, ulReg;
>+      if (pll->clockType == SECONDARY_PLL) {
>+              /* programe secondary pixel clock */
>+              POKE32(CRT_PLL_CTRL, formatPllReg(pll));
>+              POKE32(CRT_HORIZONTAL_TOTAL,
>+                      ((pModeParam->horizontal_total - 1) << 
>CRT_HORIZONTAL_TOTAL_TOTAL_LSB)
>+                      |((pModeParam->horizontal_display_end - 1) << 
>CRT_HORIZONTAL_TOTAL_DISPLAY_END_LSB));
>+
>+              POKE32(CRT_HORIZONTAL_SYNC,
>+                      (pModeParam->horizontal_sync_width << 
>CRT_HORIZONTAL_SYNC_WIDTH_LSB)
>+                      |((pModeParam->horizontal_sync_start - 1) << 
>CRT_HORIZONTAL_SYNC_START_LSB));
>+
>+              POKE32(CRT_VERTICAL_TOTAL,
>+                              ((pModeParam->vertical_total - 1) << 
>CRT_VERTICAL_TOTAL_TOTAL_LSB)
>+                              |((pModeParam->vertical_display_end - 1) << 
>CRT_VERTICAL_TOTAL_DISPLAY_END_LSB));
>+              POKE32(CRT_VERTICAL_SYNC,
>+                              (pModeParam->vertical_sync_height << 
>CRT_VERTICAL_SYNC_HEIGHT_LSB)
>+                              |((pModeParam->vertical_sync_start - 1) << 
>CRT_VERTICAL_SYNC_START_LSB));
>+
>+
>+              ulTmpValue = (pModeParam->vertical_sync_polarity << 
>CRT_DISPLAY_CTRL_VSYNC_PHASE_LSB)|
>+                              (pModeParam->horizontal_sync_polarity << 
>CRT_DISPLAY_CTRL_HSYNC_PHASE_LSB)|
>+                              (1 << CRT_DISPLAY_CTRL_TIMING_LSB)|
>+                              (1 << CRT_DISPLAY_CTRL_PLANE_LSB);
>+
>+              if (getChipType() == SM750LE) {
>+                      displayControlAdjust_SM750LE(pModeParam, ulTmpValue);
>+              } else{
>+                      ulReg = PEEK32(CRT_DISPLAY_CTRL)
>+                              & (~(1 << CRT_DISPLAY_CTRL_VSYNC_PHASE_LSB))
>+                              & (~(1 << CRT_DISPLAY_CTRL_HSYNC_PHASE_LSB))
>+                              & (~(1 << CRT_DISPLAY_CTRL_TIMING_LSB))
>+                              & (~(1 << CRT_DISPLAY_CTRL_PLANE_LSB));
>+                      POKE32(CRT_DISPLAY_CTRL, ulTmpValue|ulReg);
>+              }
>+
>+      } else if (pll->clockType == PRIMARY_PLL) {
>+              unsigned int ulReservedBits;
>+              POKE32(PANEL_PLL_CTRL, formatPllReg(pll));
>+              POKE32(PANEL_HORIZONTAL_TOTAL,
>+                              ((pModeParam->horizontal_total - 1) << 
>PANEL_HORIZONTAL_TOTAL_TOTAL_LSB)
>+                              |((pModeParam->horizontal_display_end - 1) << 
>PANEL_HORIZONTAL_TOTAL_DISPLAY_END_LSB));
>+
>+              POKE32(PANEL_HORIZONTAL_SYNC,
>+                              (pModeParam->horizontal_sync_width << 
>PANEL_HORIZONTAL_SYNC_WIDTH_LSB)
>+                              |((pModeParam->horizontal_sync_start - 1) << 
>PANEL_HORIZONTAL_SYNC_START_LSB));
>+
>+              POKE32(PANEL_VERTICAL_TOTAL,
>+                              ((pModeParam->vertical_total - 1) << 
>PANEL_VERTICAL_TOTAL_TOTAL_LSB)
>+                              |((pModeParam->vertical_display_end - 1) << 
>PANEL_VERTICAL_TOTAL_DISPLAY_END_LSB));
>+
>+              POKE32(PANEL_VERTICAL_SYNC,
>+                              (pModeParam->vertical_sync_height << 
>PANEL_VERTICAL_SYNC_HEIGHT_LSB)
>+                              |((pModeParam->vertical_sync_start - 1) << 
>PANEL_VERTICAL_SYNC_START_LSB));
>+              ulTmpValue |= (pModeParam->vertical_sync_polarity << 
>PANEL_DISPLAY_CTRL_VSYNC_PHASE_LSB)
>+                              |(pModeParam->horizontal_sync_polarity << 
>PANEL_DISPLAY_CTRL_HSYNC_PHASE_LSB)
>+                              |(pModeParam->clock_phase_polarity << 
>PANEL_DISPLAY_CTRL_CLOCK_PHASE_LSB)
>+                              |(1 << PANEL_DISPLAY_CTRL_TIMING_LSB)
>+                              |(1 << PANEL_DISPLAY_CTRL_PLANE_LSB);
>+              ulReservedBits = (3 <<  PANEL_DISPLAY_CTRL_RESERVED_1_MASK_LSB)|
>+                              (15 << PANEL_DISPLAY_CTRL_RESERVED_2_MASK_LSB)|
>+                              (1 << PANEL_DISPLAY_CTRL_RESERVED_3_MASK_LSB)|
>+                              (1 << PANEL_DISPLAY_CTRL_VSYNC_LSB);
>+              ulReg = (PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits)
>+                      & (~(1 << PANEL_DISPLAY_CTRL_CLOCK_PHASE_LSB))
>+                      & (~(1 << PANEL_DISPLAY_CTRL_VSYNC_PHASE_LSB))
>+                      & (~(1 << PANEL_DISPLAY_CTRL_HSYNC_PHASE_LSB))
>+                      & (~(1 << PANEL_DISPLAY_CTRL_TIMING_LSB))
>+                      & (~(1 << PANEL_DISPLAY_CTRL_PLANE_LSB));
>+
>+              /* May a hardware bug or just my test chip (not confirmed).
>+               * PANEL_DISPLAY_CTRL register seems requiring few writes
>+               * before a value can be succesfully written in.
>+               * Added some masks to mask out the reserved bits.
>+               * Note: This problem happens by design. The hardware will wait 
>for the
>+               *       next vertical sync to turn on/off the plane.
>+               */
>+
>+              POKE32(PANEL_DISPLAY_CTRL, ulTmpValue|ulReg);
>+
>+              while ((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != 
>(ulTmpValue|ulReg)) {
>+                      cnt++;
>+                      if (cnt > 1000)
>+                              break;
>+                      POKE32(PANEL_DISPLAY_CTRL, ulTmpValue|ulReg);
>+              }
>+
>+      } else{
>+              ret = -1;
>+      }
>+      return ret;
>+}
>+
>+int ddk750_setModeTiming(mode_parameter_t *parm, clock_type_t clock)
>+{
>+      pll_value_t pll;
>+      unsigned int uiActualPixelClk;
>+      pll.inputFreq = DEFAULT_INPUT_CLOCK;
>+      pll.clockType = clock;
>+
>+      uiActualPixelClk = calcPllValue(parm->pixel_clock, &pll);
>+      if (getChipType() == SM750LE) {
>+              /* set graphic mode via IO method */
>+              outb_p(0x88, 0x3d4);
>+              outb_p(0x06, 0x3d5);
>+      }
>+      programModeRegisters(parm, &pll);
>+      return 0;
>+}
>+
>+
>diff --git a/drivers/video/lynxfb/ddk750_mode.h 
>b/drivers/video/lynxfb/ddk750_mode.h
>new file mode 100644
>index 0000000..7c12b46
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_mode.h
>@@ -0,0 +1,59 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef DDK750_MODE_H__
>+#define DDK750_MODE_H__
>+
>+#include "ddk750_chip.h"
>+
>+typedef enum _spolarity_t{
>+    POS = 0, /* positive */
>+    NEG, /* negative */
>+}
>+spolarity_t;
>+
>+
>+typedef struct _mode_parameter_t{
>+    /* Horizontal timing. */
>+    unsigned long horizontal_total;
>+    unsigned long horizontal_display_end;
>+    unsigned long horizontal_sync_start;
>+    unsigned long horizontal_sync_width;
>+    spolarity_t horizontal_sync_polarity;
>+
>+    /* Vertical timing. */
>+    unsigned long vertical_total;
>+    unsigned long vertical_display_end;
>+    unsigned long vertical_sync_start;
>+    unsigned long vertical_sync_height;
>+    spolarity_t vertical_sync_polarity;
>+
>+    /* Refresh timing. */
>+    unsigned long pixel_clock;
>+    unsigned long horizontal_frequency;
>+    unsigned long vertical_frequency;
>+
>+    /* Clock Phase. This clock phase only applies to Panel. */
>+    spolarity_t clock_phase_polarity;
>+}
>+mode_parameter_t;
>+
>+int ddk750_setModeTiming(mode_parameter_t *, clock_type_t);
>+
>+
>+#endif
>diff --git a/drivers/video/lynxfb/ddk750_power.c 
>b/drivers/video/lynxfb/ddk750_power.c
>new file mode 100644
>index 0000000..ad4fbd1
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_power.c
>@@ -0,0 +1,243 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALLMill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#include "ddk750_help.h"
>+#include "ddk750_reg.h"
>+#include "ddk750_power.h"
>+
>+void ddk750_setDPMS(DPMS_t state)
>+{
>+      unsigned int value;
>+      if (getChipType() == SM750LE) {
>+              value = PEEK32(CRT_DISPLAY_CTRL);
>+              value &= (~(3 << CRT_DISPLAY_CTRL_DPMS_LSB));
>+              POKE32(CRT_DISPLAY_CTRL, value|(state << 
>CRT_DISPLAY_CTRL_DPMS_LSB));
>+      } else{
>+              value = PEEK32(SYSTEM_CTRL);
>+              value &= (~(3 << SYSTEM_CTRL_DPMS_LSB));
>+              value |= state << SYSTEM_CTRL_DPMS_LSB;
>+              POKE32(SYSTEM_CTRL,  value);
>+      }
>+}
>+
>+unsigned int getPowerMode()
>+{
>+      if (getChipType() == SM750LE)
>+              return 0;
>+      return 2&(PEEK32(POWER_MODE_CTRL) >> POWER_MODE_CTRL_MODE_LSB);
>+}
>+
>+
>+/*
>+ * SM50x can operate in one of three modes: 0, 1 or Sleep.
>+ * On hardware reset, power mode 0 is default.
>+ */
>+void setPowerMode(unsigned int powerMode)
>+{
>+      unsigned int control_value = 0;
>+
>+      control_value = PEEK32(POWER_MODE_CTRL);
>+      control_value &= (~(3 << POWER_MODE_CTRL_MODE_LSB));
>+      if (getChipType() == SM750LE)
>+              return;
>+
>+      switch (powerMode) {
>+      case POWER_MODE_CTRL_MODE_MODE0:
>+              control_value &= (~(3 << POWER_MODE_CTRL_MODE_LSB));
>+              break;
>+      case POWER_MODE_CTRL_MODE_MODE1:
>+              control_value |= 1 << POWER_MODE_CTRL_MODE_LSB;
>+              break;
>+
>+      case POWER_MODE_CTRL_MODE_SLEEP:
>+              control_value |= 2 << POWER_MODE_CTRL_MODE_LSB;
>+              break;
>+
>+      default:
>+              break;
>+      }
>+
>+      /* Set up other fields in Power Control Register */
>+      if (powerMode == POWER_MODE_CTRL_MODE_SLEEP) {
>+              control_value &=
>+#ifdef VALIDATION_CHIP
>+                      (~(1 << POWER_MODE_CTRL_336CLK_LSB))|
>+#endif
>+                      (~(1 << POWER_MODE_CTRL_OSC_INPUT_LSB));
>+      } else{
>+              control_value |=
>+#ifdef VALIDATION_CHIP
>+                      (1 << POWER_MODE_CTRL_336CLK_LSB)|
>+#endif
>+                      (1 << POWER_MODE_CTRL_OSC_INPUT_LSB);
>+      }
>+
>+      /* Program new power mode. */
>+      POKE32(POWER_MODE_CTRL, control_value);
>+}
>+
>+void setCurrentGate(unsigned int gate)
>+{
>+      unsigned int gate_reg;
>+      unsigned int mode;
>+
>+      /* Get current power mode. */
>+      mode = getPowerMode();
>+
>+      switch (mode) {
>+      case POWER_MODE_CTRL_MODE_MODE0:
>+              gate_reg = MODE0_GATE;
>+              break;
>+
>+      case POWER_MODE_CTRL_MODE_MODE1:
>+              gate_reg = MODE1_GATE;
>+              break;
>+
>+      default:
>+              gate_reg = MODE0_GATE;
>+              break;
>+      }
>+      POKE32(gate_reg, gate);
>+}
>+
>+
>+
>+/*
>+ * This function enable/disable the 2D engine.
>+ */
>+void enable2DEngine(unsigned int enable)
>+{
>+      uint32_t gate;
>+
>+      gate = PEEK32(CURRENT_GATE);
>+      if (enable) {
>+              gate |= 1 << CURRENT_GATE_DE_LSB;
>+              gate |= 1 << CURRENT_GATE_CSC_LSB;
>+      } else{
>+              gate &= (~(1 << CURRENT_GATE_DE_LSB));
>+              gate &= (~(1 << CURRENT_GATE_CSC_LSB));
>+      }
>+      setCurrentGate(gate);
>+}
>+
>+
>+/*
>+ * This function enable/disable the ZV Port.
>+ */
>+void enableZVPort(unsigned int enable)
>+{
>+      uint32_t gate;
>+
>+      /* Enable ZV Port Gate */
>+      gate = PEEK32(CURRENT_GATE);
>+      if (enable) {
>+              gate |= 1 << CURRENT_GATE_ZVPORT_LSB;
>+
>+              /* Using Software I2C */
>+              gate |= 1 << CURRENT_GATE_GPIO_LSB;
>+
>+      } else{
>+              /* Disable ZV Port Gate. There is no way to know whether the 
>GPIO pins are being used
>+                 or not. Therefore, do not disable the GPIO gate. */
>+              gate &= (~(1 << CURRENT_GATE_ZVPORT_LSB));
>+      }
>+
>+      setCurrentGate(gate);
>+}
>+
>+
>+void enableSSP(unsigned int enable)
>+{
>+      uint32_t gate;
>+
>+      /* Enable SSP Gate */
>+      gate = PEEK32(CURRENT_GATE);
>+      if (enable)
>+              gate |= 1 << CURRENT_GATE_SSP_LSB;
>+      else
>+              gate &= (~(1 <<  CURRENT_GATE_SSP_LSB));
>+
>+      setCurrentGate(gate);
>+}
>+
>+void enableDMA(unsigned int enable)
>+{
>+      uint32_t gate;
>+
>+      /* Enable DMA Gate */
>+      gate = PEEK32(CURRENT_GATE);
>+      if (enable)
>+              gate |= 1 << CURRENT_GATE_DMA_LSB;
>+      else
>+              gate &= (~(1 << CURRENT_GATE_DMA_LSB));
>+
>+      setCurrentGate(gate);
>+}
>+
>+/*
>+ * This function enable/disable the GPIO Engine
>+ */
>+void enableGPIO(unsigned int enable)
>+{
>+      uint32_t gate;
>+
>+      /* Enable GPIO Gate */
>+      gate = PEEK32(CURRENT_GATE);
>+      if (enable)
>+              gate |= 1 << CURRENT_GATE_GPIO_LSB;
>+      else
>+              gate &= (~(1 << CURRENT_GATE_GPIO_LSB));
>+
>+      setCurrentGate(gate);
>+}
>+
>+/*
>+ * This function enable/disable the PWM Engine
>+ */
>+void enablePWM(unsigned int enable)
>+{
>+      uint32_t gate;
>+
>+      /* Enable PWM Gate */
>+      gate = PEEK32(CURRENT_GATE);
>+      if (enable)
>+              gate |= 1 << CURRENT_GATE_PWM_LSB;
>+      else
>+              gate &= (~(1 << CURRENT_GATE_PWM_LSB));
>+
>+      setCurrentGate(gate);
>+}
>+
>+/*
>+ * This function enable/disable the I2C Engine
>+ */
>+void enableI2C(unsigned int enable)
>+{
>+      uint32_t gate;
>+
>+      /* Enable I2C Gate */
>+      gate = PEEK32(CURRENT_GATE);
>+      if (enable)
>+              gate |= 1 << CURRENT_GATE_I2C_LSB;
>+      else
>+              gate &= (~(1 << CURRENT_GATE_I2C_LSB));
>+
>+      setCurrentGate(gate);
>+}
>+
>+
>diff --git a/drivers/video/lynxfb/ddk750_power.h 
>b/drivers/video/lynxfb/ddk750_power.h
>new file mode 100644
>index 0000000..da65b00
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_power.h
>@@ -0,0 +1,85 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef DDK750_POWER_H__
>+#define DDK750_POWER_H__
>+
>+typedef enum _DPMS_t{
>+      crtDPMS_ON = 0x0,
>+      crtDPMS_STANDBY = 0x1,
>+      crtDPMS_SUSPEND = 0x2,
>+      crtDPMS_OFF = 0x3,
>+}
>+DPMS_t;
>+
>+#define setDAC(off) \
>+{     \
>+      POKE32(MISC_CTRL, PEEK32(MISC_CTRL)|(off << MISC_CTRL_DAC_POWER_LSB));  
>\
>+}
>+
>+void ddk750_setDPMS(DPMS_t);
>+
>+unsigned int getPowerMode(void);
>+
>+/*
>+ * This function sets the current power mode
>+ */
>+void setPowerMode(unsigned int powerMode);
>+
>+/*
>+ * This function sets current gate
>+ */
>+void setCurrentGate(unsigned int gate);
>+
>+/*
>+ * This function enable/disable the 2D engine.
>+ */
>+void enable2DEngine(unsigned int enable);
>+
>+/*
>+ * This function enable/disable the ZV Port
>+ */
>+void enableZVPort(unsigned int enable);
>+
>+/*
>+ * This function enable/disable the DMA Engine
>+ */
>+void enableDMA(unsigned int enable);
>+
>+/*
>+ * This function enable/disable the GPIO Engine
>+ */
>+void enableGPIO(unsigned int enable);
>+
>+/*
>+ * This function enable/disable the PWM Engine
>+ */
>+void enablePWM(unsigned int enable);
>+
>+/*
>+ * This function enable/disable the I2C Engine
>+ */
>+void enableI2C(unsigned int enable);
>+
>+/*
>+ * This function enable/disable the SSP.
>+ */
>+void enableSSP(unsigned int enable);
>+
>+
>+#endif
>diff --git a/drivers/video/lynxfb/ddk750_reg.h 
>b/drivers/video/lynxfb/ddk750_reg.h
>new file mode 100644
>index 0000000..e2560bf
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_reg.h
>@@ -0,0 +1,362 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef DDK750_REG_H__
>+#define DDK750_REG_H__
>+
>+/* New register for SM750LE */
>+#ifdef OPENSOURCE
>+#define MISC_CTRL                                     0x000004
>+#define MISC_CTRL_DAC_POWER_LSB                       20
>+#define MISC_CTRL_LOCALMEM_SIZE_LSB                   12
>+#define MISC_CTRL_LOCALMEM_SIZE_8M                    3
>+#define MISC_CTRL_LOCALMEM_SIZE_16M                   0
>+#define MISC_CTRL_LOCALMEM_SIZE_32M                   1
>+#define MISC_CTRL_LOCALMEM_SIZE_64M                   2
>+#define MISC_CTRL_LOCALMEM_RESET_LSB                  6
>+#define SYSTEM_CTRL                                   0x000000
>+#define SYSTEM_CTRL_DPMS_LSB                          30
>+#define SYSTEM_CTRL_DPMS_VPHP                         0
>+#define SYSTEM_CTRL_DPMS_VPHN                         1
>+#define SYSTEM_CTRL_DPMS_VNHP                         2
>+#define SYSTEM_CTRL_DPMS_VNHN                         3
>+#define SYSTEM_CTRL_PCI_BURST_LSB                     29
>+#define SYSTEM_CTRL_DE_FIFO_LSB                       23
>+#define SYSTEM_CTRL_DE_FIFO_NOTEMPTY                  0
>+#define SYSTEM_CTRL_DE_FIFO_EMPTY                     1
>+#define SYSTEM_CTRL_DE_STATUS_LSB                     22
>+#define SYSTEM_CTRL_DE_STATUS_IDLE                    0
>+#define SYSTEM_CTRL_DE_STATUS_BUSY                    1
>+#define SYSTEM_CTRL_DE_MEM_FIFO_LSB                   21
>+#define SYSTEM_CTRL_DE_MEM_FIFO_NOTEMPTY              0
>+#define SYSTEM_CTRL_DE_MEM_FIFO_EMPTY                 1
>+#define SYSTEM_CTRL_PANEL_VSYNC_LSB                   18
>+#define SYSTEM_CTRL_PANEL_VSYNC_INACTIVE              0
>+#define SYSTEM_CTRL_PANEL_VSYNC_ACTIVE                1
>+#define SYSTEM_CTRL_CRT_VSYNC_LSB                     19
>+#define SYSTEM_CTRL_CRT_VSYNC_INACTIVE                0
>+#define SYSTEM_CTRL_CRT_VSYNC_ACTIVE                  1
>+#define SYSTEM_CTRL_DE_ABORT_LSB                          13
>+
>+#define DE_STATE1                                        0x100054
>+#define DE_STATE1_DE_ABORT_LSB                               0
>+
>+#define DE_STATE2                                        0x100058
>+#define DE_STATE2_DE_FIFO_LSB                            3
>+#define DE_STATE2_DE_FIFO_NOTEMPTY                       0
>+#define DE_STATE2_DE_FIFO_EMPTY                          1
>+#define DE_STATE2_DE_STATUS_LSB                          2
>+#define DE_STATE2_DE_STATUS_IDLE                         0
>+#define DE_STATE2_DE_STATUS_BUSY                         1
>+#define DE_STATE2_DE_MEM_FIFO_LSB                        1
>+#define DE_STATE2_DE_MEM_FIFO_NOTEMPTY                   0
>+#define DE_STATE2_DE_MEM_FIFO_EMPTY                      1
>+#endif
>+
>+#ifdef OPENSOURCE
>+#define GPIO_MUX                                      0x000008
>+#define GPIO_MUX_31_LSB                                   31
>+#define GPIO_MUX_30_LSB                                   30
>+#endif
>+#define CURRENT_GATE                                  0x000040
>+#ifdef OPENSOURCE
>+#define CURRENT_GATE_M2XCLK_LSB                         12
>+#define CURRENT_GATE_MCLK_LSB                           14
>+#define CURRENT_GATE_PWM_LSB                            9
>+#define CURRENT_GATE_I2C_LSB                            8
>+#define CURRENT_GATE_SSP_LSB                            7
>+#define CURRENT_GATE_GPIO_LSB                           6
>+#define CURRENT_GATE_ZVPORT_LSB                         5
>+#define CURRENT_GATE_CSC_LSB                            4
>+#define CURRENT_GATE_DE_LSB                             3
>+#define MODE0_GATE                                    0x000044
>+#define CURRENT_GATE_DISPLAY_LSB                           2
>+#define CURRENT_GATE_LOCALMEM_LSB                          1
>+#define CURRENT_GATE_DMA_LSB                               0
>+#endif
>+#ifdef OPENSOURCE
>+#define MODE0_GATE                                    0x000044
>+#define MODE0_GATE_I2C_LSB                            8
>+#define MODE0_GATE_GPIO_LSB                           6
>+#endif
>+
>+
>+#ifdef OPENSOURCE
>+#define MODE1_GATE                                    0x000048
>+#define POWER_MODE_CTRL                               0x00004C
>+#define POWER_MODE_CTRL_MODE_LSB                          0
>+#define POWER_MODE_CTRL_MODE_MODE0                    0
>+#define POWER_MODE_CTRL_MODE_MODE1                    1
>+#define POWER_MODE_CTRL_MODE_SLEEP                    2
>+#ifdef VALIDATION_CHIP
>+    #define POWER_MODE_CTRL_336CLK_LSB                    4
>+#endif
>+#define POWER_MODE_CTRL_OSC_INPUT_LSB                     3
>+#endif
>+
>+#define PLL_CLK_COUNT                                 0x000058
>+
>+#ifdef OPENSOURCE
>+#define PANEL_PLL_CTRL                                0x00005C
>+#ifdef VALIDATION_CHIP
>+    #define PANEL_PLL_CTRL_OD_LSB                     14
>+#else
>+    #define PANEL_PLL_CTRL_POD_LSB                    14
>+    #define PANEL_PLL_CTRL_OD_LSB                     12
>+#endif
>+#define PANEL_PLL_CTRL_N_LSB                           8
>+#define PANEL_PLL_CTRL                                0x00005C
>+#define PANEL_PLL_CTRL_BYPASS_LSB                     18
>+#define PANEL_PLL_CTRL_POWER_LSB                      17
>+#define PANEL_PLL_CTRL_POWER_OFF                      0
>+#define PANEL_PLL_CTRL_POWER_ON                       1
>+#define PANEL_PLL_CTRL_INPUT_LSB                      16
>+#ifdef VALIDATION_CHIP
>+    #define PANEL_PLL_CTRL_OD_LSB                     14
>+#else
>+    #define PANEL_PLL_CTRL_POD_LSB                    14
>+    #define PANEL_PLL_CTRL_OD_LSB                     12
>+#endif
>+#define PANEL_PLL_CTRL_N_LSB                           8
>+#define PANEL_PLL_CTRL_M_LSB                           0
>+#define CRT_PLL_CTRL_POWER_LSB                        17
>+#define CRT_PLL_CTRL_POWER_OFF                        0
>+#define CRT_PLL_CTRL_POWER_ON                         1
>+#endif
>+#define MXCLK_PLL_CTRL                                0x000070
>+#define CRT_PLL_CTRL                                  0x000060
>+#define VGA_PLL0_CTRL                                 0x000064
>+#define VGA_PLL1_CTRL                                 0x000068
>+
>+#ifdef OPENSOURCE
>+#define VGA_CONFIGURATION                             0x000088
>+#define VGA_CONFIGURATION_PLL_LSB                         2
>+#define VGA_CONFIGURATION_MODE_LSB                        1
>+#endif
>+
>+#define GPIO_DATA                                       0x010000
>+#define GPIO_DATA_DIRECTION                             0x010004
>+
>+
>+#ifdef OPENSOURCE
>+#define PANEL_DISPLAY_CTRL                            0x080000
>+#define PANEL_DISPLAY_CTRL_RESERVED_1_MASK_LSB        30
>+#define PANEL_DISPLAY_CTRL_SELECT_LSB                 28
>+#define PANEL_DISPLAY_CTRL_RESERVED_2_MASK_LSB        20
>+#define PANEL_DISPLAY_CTRL_RESERVED_3_MASK_LSB        15
>+#define PANEL_DISPLAY_CTRL_FPEN_LSB                   27
>+#define PANEL_DISPLAY_CTRL_VBIASEN_LSB                26
>+#define PANEL_DISPLAY_CTRL_DATA_LSB                   25
>+#define PANEL_DISPLAY_CTRL_DATA_DISABLE               0
>+#define PANEL_DISPLAY_CTRL_DATA_ENABLE                1
>+#define PANEL_DISPLAY_CTRL_TFT_DISP_LSB                     18
>+#define PANEL_DISPLAY_CTRL_TIMING_LSB                 8
>+#define PANEL_DISPLAY_CTRL_TIMING_DISABLE             0
>+#define PANEL_DISPLAY_CTRL_TIMING_ENABLE              1
>+#define PANEL_DISPLAY_CTRL_CLOCK_PHASE_LSB            14
>+#define PANEL_DISPLAY_CTRL_VSYNC_PHASE_LSB            13
>+#define PANEL_DISPLAY_CTRL_HSYNC_PHASE_LSB            12
>+#define PANEL_DISPLAY_CTRL_VSYNC_LSB                  11
>+#define PANEL_DISPLAY_CTRL_PLANE_LSB                  2
>+#define PANEL_DISPLAY_CTRL_FORMAT_LSB                 0
>+#endif
>+
>+
>+#ifdef OPENSOURCE
>+#define PANEL_FB_ADDRESS                             0x08000C
>+#define PANEL_FB_ADDRESS_STATUS_LSB                  31
>+#define PANEL_FB_ADDRESS_EXT_LSB                     27
>+#define PANEL_FB_ADDRESS_ADDRESS_LSB                 0
>+
>+#define PANEL_FB_WIDTH                                0x080010
>+#define PANEL_FB_WIDTH_WIDTH_LSB                      16
>+#define PANEL_FB_WIDTH_OFFSET_LSB                     0
>+
>+#define PANEL_WINDOW_WIDTH                            0x080014
>+#define PANEL_WINDOW_WIDTH_WIDTH_LSB                  16
>+#define PANEL_WINDOW_WIDTH_X_LSB                      0
>+
>+#define PANEL_WINDOW_HEIGHT                           0x080018
>+#define PANEL_WINDOW_HEIGHT_HEIGHT_LSB                16
>+#define PANEL_WINDOW_HEIGHT_Y_LSB                     0
>+
>+#define PANEL_PLANE_TL                                0x08001C
>+#define PANEL_PLANE_TL_TOP_LSB                        16
>+#define PANEL_PLANE_TL_LEFT_LSB                       0
>+
>+#define PANEL_PLANE_BR                                0x080020
>+#define PANEL_PLANE_BR_BOTTOM_LSB                     16
>+#define PANEL_PLANE_BR_RIGHT_LSB                      0
>+#endif
>+
>+
>+#ifdef OPENSOURCE
>+#define PANEL_HORIZONTAL_TOTAL                        0x080024
>+#define PANEL_HORIZONTAL_TOTAL_TOTAL_LSB                  16
>+#define PANEL_HORIZONTAL_TOTAL_DISPLAY_END_LSB            0
>+#define PANEL_HORIZONTAL_SYNC                         0x080028
>+#define PANEL_HORIZONTAL_SYNC_WIDTH_LSB                   16
>+#define PANEL_HORIZONTAL_SYNC_START_LSB                   0
>+#define PANEL_VERTICAL_TOTAL                          0x08002C
>+#define PANEL_VERTICAL_TOTAL_TOTAL_LSB                    16
>+#define PANEL_VERTICAL_TOTAL_DISPLAY_END_LSB              0
>+#define PANEL_VERTICAL_SYNC                           0x080030
>+#define PANEL_VERTICAL_SYNC_HEIGHT_LSB                    16
>+#define PANEL_VERTICAL_SYNC_START_LSB                     0
>+#endif
>+
>+
>+/* Video Control */
>+#ifdef OPENSOURCE
>+#define VIDEO_DISPLAY_CTRL                              0x080040
>+#define VIDEO_DISPLAY_CTRL_PLANE_LSB                    2
>+#endif
>+/* Alpha Control */
>+#ifdef OPENSOURCE
>+#define ALPHA_DISPLAY_CTRL                            0x080100
>+#define ALPHA_DISPLAY_CTRL_PLANE_LSB                      2
>+#endif
>+
>+/* Video Alpha Control */
>+#ifdef OPENSOURCE
>+#define VIDEO_ALPHA_DISPLAY_CTRL                        0x080080
>+#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_LSB              2
>+#endif
>+
>+/* CRT Graphics Control */
>+#ifdef OPENSOURCE
>+#define CRT_DISPLAY_CTRL                              0x080200
>+#define CRT_DISPLAY_CTRL_TIMING_LSB                   8
>+#define CRT_DISPLAY_CTRL_TIMING_DISABLE               0
>+#define CRT_DISPLAY_CTRL_TIMING_ENABLE                1
>+#define CRT_DISPLAY_CTRL_PLANE_LSB                    2
>+#define CRT_DISPLAY_CTRL_CLK_LSB                         27
>+#define CRT_DISPLAY_CTRL_RESERVED_1_MASK_LSB        27
>+#define CRT_DISPLAY_CTRL_RESERVED_2_MASK_LSB        24
>+#define CRT_DISPLAY_CTRL_SELECT_LSB                   18
>+#define CRT_DISPLAY_CTRL_RESERVED_3_MASK_LSB        15
>+#define CRT_DISPLAY_CTRL_CLOCK_PHASE_LSB              14
>+#define CRT_DISPLAY_CTRL_BLANK_LSB                    10
>+#define CRT_DISPLAY_CTRL_BLANK_OFF                    0
>+#define CRT_DISPLAY_CTRL_BLANK_ON                     1
>+#define CRT_DISPLAY_CTRL_RESERVED_4_MASK_LSB         9
>+/* SM750LE definition */
>+#define CRT_DISPLAY_CTRL_DPMS_LSB                      30
>+#define CRT_DISPLAY_CTRL_DPMS_0                       0
>+#define CRT_DISPLAY_CTRL_DPMS_1                       1
>+#define CRT_DISPLAY_CTRL_DPMS_2                       2
>+#define CRT_DISPLAY_CTRL_DPMS_3                       3
>+#define CRT_DISPLAY_CTRL_CLK_LSB                       27
>+#define CRT_DISPLAY_CTRL_CRTSELECT_LSB                 25
>+#define CRT_DISPLAY_CTRL_RGBBIT_LSB                    24
>+#define CRT_DISPLAY_CTRL_VSYNC_PHASE_LSB               13
>+#define CRT_DISPLAY_CTRL_HSYNC_PHASE_LSB               12
>+#define CRT_DISPLAY_CTRL_FORMAT_LSB                    0
>+#endif
>+
>+
>+#ifdef OPENSOURCE
>+#define CRT_FB_ADDRESS                                0x080204
>+#define CRT_FB_ADDRESS_STATUS_LSB                     31
>+#define CRT_FB_ADDRESS_STATUS_CURRENT                 0
>+#define CRT_FB_ADDRESS_STATUS_PENDING                 1
>+#define CRT_FB_ADDRESS_EXT_LSB                        27
>+#define CRT_FB_ADDRESS_EXT_LOCAL                      0
>+#define CRT_FB_ADDRESS_EXT_EXTERNAL                   1
>+#define CRT_FB_ADDRESS_ADDRESS_LSB                    0
>+#endif
>+
>+
>+#ifdef OPENSOURCE
>+#define CRT_FB_WIDTH                                  0x080208
>+#define CRT_FB_WIDTH_WIDTH_LSB                        16
>+#define CRT_FB_WIDTH_OFFSET_LSB                       0
>+#endif
>+
>+#ifdef OPENSOURCE
>+#define CRT_HORIZONTAL_TOTAL                          0x08020C
>+#define CRT_HORIZONTAL_TOTAL_TOTAL_LSB                16
>+#define CRT_HORIZONTAL_TOTAL_DISPLAY_END_LSB          0
>+#define CRT_HORIZONTAL_SYNC                           0x080210
>+#define CRT_HORIZONTAL_SYNC_WIDTH_LSB                 16
>+#define CRT_HORIZONTAL_SYNC_START_LSB                 0
>+#define CRT_VERTICAL_TOTAL                            0x080214
>+#define CRT_VERTICAL_TOTAL_TOTAL_LSB                  16
>+#define CRT_VERTICAL_TOTAL_DISPLAY_END_LSB            0
>+#define CRT_VERTICAL_SYNC                             0x080218
>+#define CRT_VERTICAL_SYNC_HEIGHT_LSB                  16
>+#define CRT_VERTICAL_SYNC_START_LSB                   0
>+#endif
>+
>+
>+#ifndef VALIDATION_CHIP
>+    /* Auto Centering */
>+#ifdef OPENSOURCE
>+    #define CRT_AUTO_CENTERING_TL                     0x080280
>+    #define CRT_AUTO_CENTERING_TL_TOP_LSB             16
>+    #define CRT_AUTO_CENTERING_TL_LEFT_LSB            0
>+    #define CRT_AUTO_CENTERING_BR                     0x080284
>+    #define CRT_AUTO_CENTERING_BR_BOTTOM_LSB              16
>+    #define CRT_AUTO_CENTERING_BR_RIGHT_LSB               0
>+#endif
>+#endif
>+
>+/* sm750le new register to control panel output */
>+#define DISPLAY_CONTROL_750LE         0x80288
>+/* Palette RAM */
>+
>+/* Panel Pallete register starts at 0x080400 ~ 0x0807FC */
>+#define PANEL_PALETTE_RAM                             0x080400
>+
>+/* Panel Pallete register starts at 0x080C00 ~ 0x080FFC */
>+#define CRT_PALETTE_RAM                               0x080C00
>+
>+/* 2D registers
>+ * move their defination into general lynx_accel.h file
>+ * because all smi graphic chip share the same drawing engine
>+ * register format */
>+
>+#ifdef OPENSOURCE
>+#define I2C_CTRL                                        0x010041
>+#define I2C_CTRL_MODE_LSB                               1
>+#define I2C_CTRL_EN_LSB                                 0
>+#define I2C_STATUS                                      0x010042
>+#define I2C_STATUS_TX_LSB                               3
>+#define I2C_CTRL_CTRL_LSB                               2
>+#define I2C_STATUS_TX_COMPLETED                         1
>+#define I2C_SLAVE_ADDRESS                               0x010043
>+#define I2C_RESET                                       0x010042
>+#define I2C_SLAVE_ADDRESS                               0x010043
>+#define I2C_DATA0                                       0x010044
>+#define I2C_BYTE_COUNT                                  0x010040
>+#endif
>+
>+#ifdef OPENSOURCE
>+#define DMA_ABORT_INTERRUPT                             0x0D0020
>+#define DMA_ABORT_INTERRUPT_ABORT_1_LSB                     5
>+#endif
>+
>+
>+
>+/* Default i2c CLK and Data GPIO. These are the default i2c pins */
>+#define DEFAULT_I2C_SCL                     30
>+#define DEFAULT_I2C_SDA                     31
>+
>+#define GPIO_DATA_SM750LE                               0x020018
>+#define GPIO_DATA_DIRECTION_SM750LE                     0x02001C
>+#endif
>diff --git a/drivers/video/lynxfb/ddk750_sii164.c 
>b/drivers/video/lynxfb/ddk750_sii164.c
>new file mode 100644
>index 0000000..6915939
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_sii164.c
>@@ -0,0 +1,435 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifdef USE_DVICHIP
>+
>+#include "ddk750_sii164.h"
>+#include "ddk750_hwi2c.h"
>+
>+/* I2C Address of each SII164 chip */
>+#define SII164_I2C_ADDRESS                  0x70
>+
>+/* Define this definition to use hardware i2c. */
>+/*#define USE_HW_I2C*/
>+#ifdef USE_HW_I2C
>+#define i2cWriteReg hwI2CWriteReg
>+#define i2cReadReg  hwI2CReadReg
>+#else
>+#define i2cWriteReg swI2CWriteReg
>+#define i2cReadReg  swI2CReadReg
>+#endif
>+
>+/* SII164 Vendor and Device ID */
>+#define SII164_VENDOR_ID                    0x0001
>+#define SII164_DEVICE_ID                    0x0006
>+
>+#ifdef SII164_FULL_FUNCTIONS
>+/* Name of the DVI Controller chip */
>+static char *gDviCtrlChipName = "Silicon Image SiI 164";
>+#endif
>+
>+/*
>+ *  sii164GetVendorID
>+ *      This function gets the vendor ID of the DVI controller chip.
>+ *
>+ *  Output:
>+ *      Vendor ID
>+ */
>+unsigned short sii164GetVendorID()
>+{
>+      unsigned short vendorID;
>+
>+      vendorID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, 
>SII164_VENDOR_ID_HIGH) << 8) |
>+              (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, 
>SII164_VENDOR_ID_LOW);
>+
>+      return vendorID;
>+}
>+
>+/*
>+ *  sii164GetDeviceID
>+ *      This function gets the device ID of the DVI controller chip.
>+ *
>+ *  Output:
>+ *      Device ID
>+ */
>+unsigned short sii164GetDeviceID()
>+{
>+      unsigned short deviceID;
>+
>+      deviceID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, 
>SII164_DEVICE_ID_HIGH) << 8) |
>+              (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, 
>SII164_DEVICE_ID_LOW);
>+
>+      return deviceID;
>+}
>+
>+
>+
>+/* DVI.C will handle all SiI164 chip stuffs and try it best to make code 
>minimal and useful */
>+
>+/*
>+ *  sii164InitChip
>+ *      This function initialize and detect the DVI controller chip.
>+ *
>+ *  Input:
>+ *      edgeSelect          - Edge Select:
>+ *                              0 = Input data is falling edge latched 
>(falling edge
>+ *                                  latched first in dual edge mode)
>+ *                              1 = Input data is rising edge latched (rising 
>edge
>+ *                                  latched first in dual edge mode)
>+ *      busSelect           - Input Bus Select:
>+ *                              0 = Input data bus is 12-bits wide
>+ *                              1 = Input data bus is 24-bits wide
>+ *      dualEdgeClkSelect   - Dual Edge Clock Select
>+ *                              0 = Input data is single edge latched
>+ *                              1 = Input data is dual edge latched
>+ *      hsyncEnable         - Horizontal Sync Enable:
>+ *                              0 = HSYNC input is transmitted as fixed LOW
>+ *                              1 = HSYNC input is transmitted as is
>+ *      vsyncEnable         - Vertical Sync Enable:
>+ *                              0 = VSYNC input is transmitted as fixed LOW
>+ *                              1 = VSYNC input is transmitted as is
>+ *      deskewEnable        - De-skewing Enable:
>+ *                              0 = De-skew disabled
>+ *                              1 = De-skew enabled
>+ *      deskewSetting       - De-skewing Setting (increment of 260psec)
>+ *                              0 = 1 step --> minimum setup / maximum hold
>+ *                              1 = 2 step
>+ *                              2 = 3 step
>+ *                              3 = 4 step
>+ *                              4 = 5 step
>+ *                              5 = 6 step
>+ *                              6 = 7 step
>+ *                              7 = 8 step --> maximum setup / minimum hold
>+ *      continuousSyncEnable- SYNC Continuous:
>+ *                              0 = Disable
>+ *                              1 = Enable
>+ *      pllFilterEnable     - PLL Filter Enable
>+ *                              0 = Disable PLL Filter
>+ *                              1 = Enable PLL Filter
>+ *      pllFilterValue      - PLL Filter characteristics:
>+ *                              0~7 (recommended value is 4)
>+ *
>+ *  Output:
>+ *      0   - Success
>+ *     -1   - Fail.
>+ */
>+long sii164InitChip(
>+              unsigned char edgeSelect,
>+              unsigned char busSelect,
>+              unsigned char dualEdgeClkSelect,
>+              unsigned char hsyncEnable,
>+              unsigned char vsyncEnable,
>+              unsigned char deskewEnable,
>+              unsigned char deskewSetting,
>+              unsigned char continuousSyncEnable,
>+              unsigned char pllFilterEnable,
>+              unsigned char pllFilterValue
>+              )
>+{
>+      /* unsigned char ucRegIndex, ucRegValue;
>+      unsigned char ucDeviceAddress, */
>+      unsigned char config;
>+      /* unsigned long delayCount; */
>+
>+      /* Initialize the i2c bus */
>+#ifdef USE_HW_I2C
>+      /* Use fast mode. */
>+      hwI2CInit(1);
>+#else
>+      swI2CInit(DEFAULT_I2C_SCL, DEFAULT_I2C_SDA);
>+#endif
>+
>+      /* Check if SII164 Chip exists */
>+      if ((sii164GetVendorID() == SII164_VENDOR_ID) && (sii164GetDeviceID() 
>== SII164_DEVICE_ID)) {
>+
>+#ifdef DDKDEBUG
>+              /* sii164PrintRegisterValues(); */
>+#endif
>+              /*
>+               *  Initialize SII164 controller chip.
>+               */
>+
>+              /* Select the edge */
>+              if (edgeSelect == 0)
>+                      config = SII164_CONFIGURATION_LATCH_FALLING;
>+              else
>+                      config = SII164_CONFIGURATION_LATCH_RISING;
>+
>+              /* Select bus wide */
>+              if (busSelect == 0)
>+                      config |= SII164_CONFIGURATION_BUS_12BITS;
>+              else
>+                      config |= SII164_CONFIGURATION_BUS_24BITS;
>+
>+              /* Select Dual/Single Edge Clock */
>+              if (dualEdgeClkSelect == 0)
>+                      config |= SII164_CONFIGURATION_CLOCK_SINGLE;
>+              else
>+                      config |= SII164_CONFIGURATION_CLOCK_DUAL;
>+
>+              /* Select HSync Enable */
>+              if (hsyncEnable == 0)
>+                      config |= SII164_CONFIGURATION_HSYNC_FORCE_LOW;
>+              else
>+                      config |= SII164_CONFIGURATION_HSYNC_AS_IS;
>+
>+              /* Select VSync Enable */
>+              if (vsyncEnable == 0)
>+                      config |= SII164_CONFIGURATION_VSYNC_FORCE_LOW;
>+              else
>+                      config |= SII164_CONFIGURATION_VSYNC_AS_IS;
>+
>+              i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
>+
>+              /* De-skew enabled with default 111b value.
>+                 This will fix some artifacts problem in some mode on board 
>2.2.
>+                 Somehow this fix does not affect board 2.1.
>+                 */
>+              if (deskewEnable == 0)
>+                      config = SII164_DESKEW_DISABLE;
>+              else
>+                      config = SII164_DESKEW_ENABLE;
>+
>+              switch (deskewSetting) {
>+              case 0:
>+                      config |= SII164_DESKEW_1_STEP;
>+                      break;
>+              case 1:
>+                      config |= SII164_DESKEW_2_STEP;
>+                      break;
>+              case 2:
>+                      config |= SII164_DESKEW_3_STEP;
>+                      break;
>+              case 3:
>+                      config |= SII164_DESKEW_4_STEP;
>+                      break;
>+              case 4:
>+                      config |= SII164_DESKEW_5_STEP;
>+                      break;
>+              case 5:
>+                      config |= SII164_DESKEW_6_STEP;
>+                      break;
>+              case 6:
>+                      config |= SII164_DESKEW_7_STEP;
>+                      break;
>+              case 7:
>+                      config |= SII164_DESKEW_8_STEP;
>+                      break;
>+              }
>+              i2cWriteReg(SII164_I2C_ADDRESS, SII164_DESKEW, config);
>+
>+              /* Enable/Disable Continuous Sync. */
>+              if (continuousSyncEnable == 0)
>+                      config = SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE;
>+              else
>+                      config = SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE;
>+
>+              /* Enable/Disable PLL Filter */
>+              if (pllFilterEnable == 0)
>+                      config |= SII164_PLL_FILTER_DISABLE;
>+              else
>+                      config |= SII164_PLL_FILTER_ENABLE;
>+
>+              /* Set the PLL Filter value */
>+              config |= ((pllFilterValue & 0x07) << 1);
>+
>+              i2cWriteReg(SII164_I2C_ADDRESS, SII164_PLL, config);
>+
>+              /* Recover from Power Down and enable output. */
>+              config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
>+              config |= SII164_CONFIGURATION_POWER_NORMAL;
>+              i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
>+
>+#ifdef DDKDEBUG
>+              /* sii164PrintRegisterValues(); */
>+#endif
>+
>+              return 0;
>+      }
>+
>+      /* Return -1 if initialization fails. */
>+      return -1;
>+}
>+
>+
>+
>+
>+
>+/* below sii164 function is not neccessary */
>+
>+#ifdef SII164_FULL_FUNCTIONS
>+
>+/*
>+ *  sii164ResetChip
>+ *      This function resets the DVI Controller Chip.
>+ */
>+void sii164ResetChip()
>+{
>+      /* Power down */
>+      sii164SetPower(0);
>+      sii164SetPower(1);
>+}
>+
>+
>+/*
>+ * sii164GetChipString
>+ *      This function returns a char string name of the current DVI 
>Controller chip.
>+ *      It's convenient for application need to display the chip name.
>+ */
>+char *sii164GetChipString()
>+{
>+      return gDviCtrlChipName;
>+}
>+
>+
>+/*
>+ *  sii164SetPower
>+ *      This function sets the power configuration of the DVI Controller Chip.
>+ *
>+ *  Input:
>+ *      powerUp - Flag to set the power down or up
>+ */
>+void sii164SetPower(
>+              unsigned char powerUp
>+              )
>+{
>+      unsigned char config;
>+
>+      config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
>+      if (powerUp == 1) {
>+              /* Power up the chip */
>+              config &= ~SII164_CONFIGURATION_POWER_MASK;
>+              config |= SII164_CONFIGURATION_POWER_NORMAL;
>+              i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
>+      } else{
>+              /* Power down the chip */
>+              config &= ~SII164_CONFIGURATION_POWER_MASK;
>+              config |= SII164_CONFIGURATION_POWER_DOWN;
>+              i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
>+      }
>+}
>+
>+
>+/*
>+ *  sii164SelectHotPlugDetectionMode
>+ *      This function selects the mode of the hot plug detection.
>+ */
>+static void sii164SelectHotPlugDetectionMode(
>+              sii164_hot_plug_mode_t hotPlugMode
>+              )
>+{
>+      unsigned char detectReg;
>+
>+      detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & 
>~SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG;
>+      switch (hotPlugMode) {
>+      case SII164_HOTPLUG_DISABLE:
>+              detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH;
>+              break;
>+      case SII164_HOTPLUG_USE_MDI:
>+              detectReg &= ~SII164_DETECT_INTERRUPT_MASK;
>+              detectReg |= SII164_DETECT_INTERRUPT_BY_HTPLG_PIN;
>+              detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI;
>+              break;
>+      case SII164_HOTPLUG_USE_RSEN:
>+              detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN;
>+              break;
>+      case SII164_HOTPLUG_USE_HTPLG:
>+              detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG;
>+              break;
>+      }
>+
>+      i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg);
>+}
>+
>+/*
>+ *  sii164EnableHotPlugDetection
>+ *      This function enables the Hot Plug detection.
>+ *
>+ *  enableHotPlug   - Enable (=1) / disable (=0) Hot Plug detection
>+ */
>+void sii164EnableHotPlugDetection(
>+              unsigned char enableHotPlug
>+              )
>+{
>+      unsigned char detectReg;
>+      detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
>+
>+      /* Depending on each DVI controller, need to enable the hot plug based 
>on each
>+         individual chip design. */
>+      if (enableHotPlug != 0)
>+              sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_USE_MDI);
>+      else
>+              sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_DISABLE);
>+}
>+
>+/*
>+ *  sii164IsConnected
>+ *      Check if the DVI Monitor is connected.
>+ *
>+ *  Output:
>+ *      0   - Not Connected
>+ *      1   - Connected
>+ */
>+unsigned char sii164IsConnected()
>+{
>+      unsigned char hotPlugValue;
>+
>+      hotPlugValue = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & 
>SII164_DETECT_HOT_PLUG_STATUS_MASK;
>+      if (hotPlugValue == SII164_DETECT_HOT_PLUG_STATUS_ON)
>+              return 1;
>+      else
>+              return 0;
>+}
>+
>+/*
>+ *  sii164CheckInterrupt
>+ *      Checks if interrupt has occured.
>+ *
>+ *  Output:
>+ *      0   - No interrupt
>+ *      1   - Interrupt occurs
>+ */
>+unsigned char sii164CheckInterrupt()
>+{
>+      unsigned char detectReg;
>+
>+      detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & 
>SII164_DETECT_MONITOR_STATE_MASK;
>+      if (detectReg == SII164_DETECT_MONITOR_STATE_CHANGE)
>+              return 1;
>+      else
>+              return 0;
>+}
>+
>+/*
>+ *  sii164ClearInterrupt
>+ *      Clear the hot plug interrupt.
>+ */
>+void sii164ClearInterrupt()
>+{
>+      unsigned char detectReg;
>+
>+      /* Clear the MDI interrupt */
>+      detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
>+      i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg | 
>SII164_DETECT_MONITOR_STATE_CLEAR);
>+}
>+
>+#endif
>+
>+#endif
>+
>+
>diff --git a/drivers/video/lynxfb/ddk750_sii164.h 
>b/drivers/video/lynxfb/ddk750_sii164.h
>new file mode 100644
>index 0000000..a279286
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_sii164.h
>@@ -0,0 +1,187 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef DDK750_SII164_H__
>+#define DDK750_SII164_H__
>+
>+/* Hot Plug detection mode structure */
>+typedef enum _sii164_hot_plug_mode_t{
>+    SII164_HOTPLUG_DISABLE = 0,         /* Disable Hot Plug output bit 
>(always high). */
>+    SII164_HOTPLUG_USE_MDI,             /* Use Monitor Detect Interrupt bit. 
>*/
>+    SII164_HOTPLUG_USE_RSEN,            /* Use Receiver Sense detect bit. */
>+    SII164_HOTPLUG_USE_HTPLG            /* Use Hot Plug detect bit. */
>+} sii164_hot_plug_mode_t;
>+
>+
>+/* Silicon Image SiI164 chip prototype */
>+long sii164InitChip(
>+    unsigned char edgeSelect,
>+    unsigned char busSelect,
>+    unsigned char dualEdgeClkSelect,
>+    unsigned char hsyncEnable,
>+    unsigned char vsyncEnable,
>+    unsigned char deskewEnable,
>+    unsigned char deskewSetting,
>+    unsigned char continuousSyncEnable,
>+    unsigned char pllFilterEnable,
>+    unsigned char pllFilterValue
>+);
>+
>+unsigned short sii164GetVendorID(void);
>+unsigned short sii164GetDeviceID(void);
>+
>+
>+#ifdef SII164_FULL_FUNCTIONS
>+void sii164ResetChip(void);
>+char *sii164GetChipString(void);
>+void sii164SetPower(unsigned char powerUp);
>+void sii164EnableHotPlugDetection(unsigned char enableHotPlug);
>+unsigned char sii164IsConnected(void);
>+unsigned char sii164CheckInterrupt(void);
>+void sii164ClearInterrupt(void);
>+#endif
>+/* below register definination is used for Silicon Image SiI164 DVI 
>controller chip */
>+/*
>+ * Vendor ID registers
>+ */
>+#define SII164_VENDOR_ID_LOW                        0x00
>+#define SII164_VENDOR_ID_HIGH                       0x01
>+
>+/*
>+ * Device ID registers
>+ */
>+#define SII164_DEVICE_ID_LOW                        0x02
>+#define SII164_DEVICE_ID_HIGH                       0x03
>+
>+/*
>+ * Device Revision
>+ */
>+#define SII164_DEVICE_REVISION                      0x04
>+
>+/*
>+ * Frequency Limitation registers
>+ */
>+#define SII164_FREQUENCY_LIMIT_LOW                  0x06
>+#define SII164_FREQUENCY_LIMIT_HIGH                 0x07
>+
>+/*
>+ * Power Down and Input Signal Configuration registers
>+ */
>+#define SII164_CONFIGURATION                        0x08
>+
>+/* Power down (PD) */
>+#define SII164_CONFIGURATION_POWER_DOWN             0x00
>+#define SII164_CONFIGURATION_POWER_NORMAL           0x01
>+#define SII164_CONFIGURATION_POWER_MASK             0x01
>+
>+/* Input Edge Latch Select (EDGE) */
>+#define SII164_CONFIGURATION_LATCH_FALLING          0x00
>+#define SII164_CONFIGURATION_LATCH_RISING           0x02
>+
>+/* Bus Select (BSEL) */
>+#define SII164_CONFIGURATION_BUS_12BITS             0x00
>+#define SII164_CONFIGURATION_BUS_24BITS             0x04
>+
>+/* Dual Edge Clock Select (DSEL) */
>+#define SII164_CONFIGURATION_CLOCK_SINGLE           0x00
>+#define SII164_CONFIGURATION_CLOCK_DUAL             0x08
>+
>+/* Horizontal Sync Enable (HEN) */
>+#define SII164_CONFIGURATION_HSYNC_FORCE_LOW        0x00
>+#define SII164_CONFIGURATION_HSYNC_AS_IS            0x10
>+
>+/* Vertical Sync Enable (VEN) */
>+#define SII164_CONFIGURATION_VSYNC_FORCE_LOW        0x00
>+#define SII164_CONFIGURATION_VSYNC_AS_IS            0x20
>+
>+/*
>+ * Detection registers
>+ */
>+#define SII164_DETECT                               0x09
>+
>+/* Monitor Detect Interrupt (MDI) */
>+#define SII164_DETECT_MONITOR_STATE_CHANGE          0x00
>+#define SII164_DETECT_MONITOR_STATE_NO_CHANGE       0x01
>+#define SII164_DETECT_MONITOR_STATE_CLEAR           0x01
>+#define SII164_DETECT_MONITOR_STATE_MASK            0x01
>+
>+/* Hot Plug detect Input (HTPLG) */
>+#define SII164_DETECT_HOT_PLUG_STATUS_OFF           0x00
>+#define SII164_DETECT_HOT_PLUG_STATUS_ON            0x02
>+#define SII164_DETECT_HOT_PLUG_STATUS_MASK          0x02
>+
>+/* Receiver Sense (RSEN) */
>+#define SII164_DETECT_RECEIVER_SENSE_NOT_DETECTED   0x00
>+#define SII164_DETECT_RECEIVER_SENSE_DETECTED       0x04
>+
>+/* Interrupt Generation Method (TSEL) */
>+#define SII164_DETECT_INTERRUPT_BY_RSEN_PIN         0x00
>+#define SII164_DETECT_INTERRUPT_BY_HTPLG_PIN        0x08
>+#define SII164_DETECT_INTERRUPT_MASK                0x08
>+
>+/* Monitor Sense Output (MSEN) */
>+#define SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH     0x00
>+#define SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI      0x10
>+#define SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN     0x20
>+#define SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG    0x30
>+#define SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG     0x30
>+
>+/*
>+ * Skewing registers
>+ */
>+#define SII164_DESKEW                               0x0A
>+
>+/* General Purpose Input (CTL[3:1]) */
>+#define SII164_DESKEW_GENERAL_PURPOSE_INPUT_MASK    0x0E
>+
>+/* De-skewing Enable bit (DKEN) */
>+#define SII164_DESKEW_DISABLE                       0x00
>+#define SII164_DESKEW_ENABLE                        0x10
>+
>+/* De-skewing Setting (DK[3:1])*/
>+#define SII164_DESKEW_1_STEP                        0x00
>+#define SII164_DESKEW_2_STEP                        0x20
>+#define SII164_DESKEW_3_STEP                        0x40
>+#define SII164_DESKEW_4_STEP                        0x60
>+#define SII164_DESKEW_5_STEP                        0x80
>+#define SII164_DESKEW_6_STEP                        0xA0
>+#define SII164_DESKEW_7_STEP                        0xC0
>+#define SII164_DESKEW_8_STEP                        0xE0
>+
>+/*
>+ * User Configuration Data registers (CFG 7:0)
>+ */
>+#define SII164_USER_CONFIGURATION                   0x0B
>+
>+/*
>+ * PLL registers
>+ */
>+#define SII164_PLL                                  0x0C
>+
>+/* PLL Filter Value (PLLF) */
>+#define SII164_PLL_FILTER_VALUE_MASK                0x0E
>+
>+/* PLL Filter Enable (PFEN) */
>+#define SII164_PLL_FILTER_DISABLE                   0x00
>+#define SII164_PLL_FILTER_ENABLE                    0x01
>+
>+/* Sync Continuous (SCNT) */
>+#define SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE   0x00
>+#define SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE    0x80
>+
>+#endif
>diff --git a/drivers/video/lynxfb/ddk750_swi2c.c 
>b/drivers/video/lynxfb/ddk750_swi2c.c
>new file mode 100644
>index 0000000..ff532c7
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_swi2c.c
>@@ -0,0 +1,522 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#include "ddk750_help.h"
>+#include "ddk750_reg.h"
>+#include "ddk750_swi2c.h"
>+#include "ddk750_power.h"
>+
>+
>+/*******************************************************************
>+ * I2C Software Master Driver:
>+ * ===========================
>+ * Each i2c cycle is split into 4 sections. Each of these section marks
>+ * a point in time where the SCL or SDA may be changed.
>+ *
>+ * 1 Cycle == |  Section I. |  Section 2. |  Section 3. |  Section 4. |
>+ *            +-------------+-------------+-------------+-------------+
>+ *            | SCL set LOW |SCL no change| SCL set HIGH|SCL no change|
>+ *
>+ *                                          ____________ _____________
>+ * SCL == XXXX _____________ ____________ /
>+ *
>+ * I.e. the SCL may only be changed in section 1. and section 3. while
>+ * the SDA may only be changed in section 2. and section 4. The table
>+ * below gives the changes for these 2 lines in the varios sections.
>+ *
>+ * Section changes Table:
>+ * ======================
>+ * blank = no change, L = set bit LOW, H = set bit HIGH
>+ *
>+ *                                | 1.| 2.| 3.| 4.|
>+ *                 ---------------+---+---+---+---+
>+ *                 Tx Start   SDA |   | H |   | L |
>+ *                            SCL | L |   | H |   |
>+ *                 ---------------+---+---+---+---+
>+ *                 Tx Stop    SDA |   | L |   | H |
>+ *                            SCL | L |   | H |   |
>+ *                 ---------------+---+---+---+---+
>+ *                 Tx bit H   SDA |   | H |   |   |
>+ *                            SCL | L |   | H |   |
>+ *                 ---------------+---+---+---+---+
>+ *                 Tx bit L   SDA |   | L |   |   |
>+ *                            SCL | L |   | H |   |
>+ *                 ---------------+---+---+---+---+
>+ *
>+ ******************************************************************/
>+
>+/* GPIO pins used for this I2C. It ranges from 0 to 63. */
>+static unsigned char g_i2cClockGPIO = DEFAULT_I2C_SCL;
>+static unsigned char g_i2cDataGPIO = DEFAULT_I2C_SDA;
>+
>+/*
>+ *  Below is the variable declaration for the GPIO pin register usage
>+ *  for the i2c Clock and i2c Data.
>+ *
>+ *  Note:
>+ *      Notice that the GPIO usage for the i2c clock and i2c Data are
>+ *      separated. This is to make this code flexible enough when
>+ *      two separate GPIO pins for the clock and data are located
>+ *      in two different GPIO register set (worst case).
>+ */
>+
>+/* i2c Clock GPIO Register usage */
>+static unsigned long g_i2cClkGPIOMuxReg = GPIO_MUX;
>+static unsigned long g_i2cClkGPIODataReg = GPIO_DATA;
>+static unsigned long g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION;
>+
>+/* i2c Data GPIO Register usage */
>+static unsigned long g_i2cDataGPIOMuxReg = GPIO_MUX;
>+static unsigned long g_i2cDataGPIODataReg = GPIO_DATA;
>+static unsigned long g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION;
>+
>+static unsigned char peekIO(unsigned short port, unsigned short index)
>+{
>+#if defined(__i386__) || defined(__x86_64__)
>+      outb_p(index, port);
>+      return inb_p(port+1);
>+#endif
>+}
>+
>+/*
>+ *  This function puts a delay between command
>+ */
>+static void swI2CWait(void)
>+{
>+      /* find a bug:
>+       * peekIO method works well before suspend/resume
>+       * but after suspend, peekIO(0x3ce,0x61) & 0x10
>+       * always be non-zero,which makes the while loop
>+       * never finish.
>+       * use non-ultimate for loop below is safe
>+       * */
>+      int i, Temp;
>+
>+      for (i = 0; i < 600; i++) {
>+              Temp = i;
>+              Temp += i;
>+      }
>+}
>+
>+/*
>+ *  This function set/reset the SCL GPIO pin
>+ *
>+ *  Parameters:
>+ *      value    - Bit value to set to the SCL or SDA (0 = low, 1 = high)
>+ *
>+ *  Notes:
>+ *      When setting SCL to high, just set the GPIO as input where the pull up
>+ *      resistor will pull the signal up. Do not use software to pull up the
>+ *      signal because the i2c will fail when other device try to drive the
>+ *      signal due to SM50x will drive the signal to always high.
>+ */
>+void swI2CSCL(unsigned char value)
>+{
>+      unsigned long ulGPIOData;
>+      unsigned long ulGPIODirection;
>+
>+      ulGPIODirection = PEEK32(g_i2cClkGPIODataDirReg);
>+      if (value) {     /* High */
>+              /* Set direction as input. This will automatically pull the 
>signal up. */
>+              ulGPIODirection &= ~(1 << g_i2cClockGPIO);
>+              POKE32(g_i2cClkGPIODataDirReg, ulGPIODirection);
>+      } else{            /* Low */
>+              /* Set the signal down */
>+              ulGPIOData = PEEK32(g_i2cClkGPIODataReg);
>+              ulGPIOData &= ~(1 << g_i2cClockGPIO);
>+              POKE32(g_i2cClkGPIODataReg, ulGPIOData);
>+
>+              /* Set direction as output */
>+              ulGPIODirection |= (1 << g_i2cClockGPIO);
>+              POKE32(g_i2cClkGPIODataDirReg, ulGPIODirection);
>+      }
>+}
>+
>+/*
>+ *  This function set/reset the SDA GPIO pin
>+ *
>+ *  Parameters:
>+ *      value    - Bit value to set to the SCL or SDA (0 = low, 1 = high)
>+ *
>+ *  Notes:
>+ *      When setting SCL to high, just set the GPIO as input where the pull up
>+ *      resistor will pull the signal up. Do not use software to pull up the
>+ *      signal because the i2c will fail when other device try to drive the
>+ *      signal due to SM50x will drive the signal to always high.
>+ */
>+void swI2CSDA(unsigned char value)
>+{
>+      unsigned long ulGPIOData;
>+      unsigned long ulGPIODirection;
>+
>+      ulGPIODirection = PEEK32(g_i2cDataGPIODataDirReg);
>+      if (value) {      /* High */
>+              /* Set direction as input. This will automatically pull the 
>signal up. */
>+              ulGPIODirection &= ~(1 << g_i2cDataGPIO);
>+              POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection);
>+      } else{            /* Low */
>+              /* Set the signal down */
>+              ulGPIOData = PEEK32(g_i2cDataGPIODataReg);
>+              ulGPIOData &= ~(1 << g_i2cDataGPIO);
>+              POKE32(g_i2cDataGPIODataReg, ulGPIOData);
>+
>+              /* Set direction as output */
>+              ulGPIODirection |= (1 << g_i2cDataGPIO);
>+              POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection);
>+      }
>+}
>+
>+/*
>+ *  This function read the data from the SDA GPIO pin
>+ *
>+ *  Return Value:
>+ *      The SDA data bit sent by the Slave
>+ */
>+static unsigned char swI2CReadSDA()
>+{
>+      unsigned long ulGPIODirection;
>+      unsigned long ulGPIOData;
>+
>+      /* Make sure that the direction is input (High) */
>+      ulGPIODirection = PEEK32(g_i2cDataGPIODataDirReg);
>+      if ((ulGPIODirection & (1 << g_i2cDataGPIO))
>+      != (~(1 << g_i2cDataGPIO))) {
>+              ulGPIODirection &= ~(1 << g_i2cDataGPIO);
>+              POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection);
>+      }
>+
>+      /* Now read the SDA line */
>+      ulGPIOData = PEEK32(g_i2cDataGPIODataReg);
>+      if (ulGPIOData & (1 << g_i2cDataGPIO))
>+              return 1;
>+      else
>+              return 0;
>+}
>+
>+#pragma optimize("", off)
>+
>+/*
>+ *  This function sends ACK signal
>+ */
>+static void swI2CAck(void)
>+{
>+      return;  /* Single byte read is ok without it. */
>+}
>+
>+/*
>+ *  This function sends the start command to the slave device
>+ */
>+void swI2CStart(void)
>+{
>+      /* Start I2C */
>+      swI2CSDA(1);
>+      swI2CSCL(1);
>+      swI2CSDA(0);
>+}
>+
>+/*
>+ *  This function sends the stop command to the slave device
>+ */
>+void swI2CStop()
>+{
>+      /* Stop the I2C */
>+      swI2CSCL(1);
>+      swI2CSDA(0);
>+      swI2CSDA(1);
>+}
>+
>+/*
>+ *  This function writes one byte to the slave device
>+ *
>+ *  Parameters:
>+ *      data    - Data to be write to the slave device
>+ *
>+ *  Return Value:
>+ *       0   - Success
>+ *      -1   - Fail to write byte
>+ */
>+long swI2CWriteByte(unsigned char data)
>+{
>+      unsigned char value = data;
>+      int i;
>+
>+      /* Sending the data bit by bit */
>+      for (i = 0; i < 8; i++) {
>+              /* Set SCL to low */
>+              swI2CSCL(0);
>+
>+              /* Send data bit */
>+              if ((value & 0x80) != 0)
>+                      swI2CSDA(1);
>+              else
>+                      swI2CSDA(0);
>+
>+              swI2CWait();
>+
>+              /* Toggle clk line to one */
>+              swI2CSCL(1);
>+              swI2CWait();
>+
>+              /* Shift byte to be sent */
>+              value = value << 1;
>+      }
>+
>+      /* Set the SCL Low and SDA High (prepare to get input) */
>+      swI2CSCL(0);
>+      swI2CSDA(1);
>+
>+      /* Set the SCL High for ack */
>+      swI2CWait();
>+      swI2CSCL(1);
>+      swI2CWait();
>+
>+      /* Read SDA, until SDA==0 */
>+      for (i = 0; i < 0xff; i++) {
>+              if (!swI2CReadSDA())
>+                      break;
>+
>+              swI2CSCL(0);
>+              swI2CWait();
>+              swI2CSCL(1);
>+              swI2CWait();
>+      }
>+
>+      /* Set the SCL Low and SDA High */
>+      swI2CSCL(0);
>+      swI2CSDA(1);
>+
>+      if (i < 0xff)
>+              return 0;
>+      else
>+              return -1;
>+}
>+
>+/*
>+ *  This function reads one byte from the slave device
>+ *
>+ *  Parameters:
>+ *      ack    - Flag to indicate either to send the acknowledge
>+ *            message to the slave device or not
>+ *
>+ *  Return Value:
>+ *      One byte data read from the Slave device
>+ */
>+unsigned char swI2CReadByte(unsigned char ack)
>+{
>+      int i;
>+      unsigned char data = 0;
>+
>+      for (i = 7; i >= 0; i--) {
>+              /* Set the SCL to Low and SDA to High (Input) */
>+              swI2CSCL(0);
>+              swI2CSDA(1);
>+              swI2CWait();
>+
>+              /* Set the SCL High */
>+              swI2CSCL(1);
>+              swI2CWait();
>+
>+              /* Read data bits from SDA */
>+              data |= (swI2CReadSDA() << i);
>+      }
>+
>+      if (ack)
>+              swI2CAck();
>+
>+      /* Set the SCL Low and SDA High */
>+      swI2CSCL(0);
>+      swI2CSDA(1);
>+
>+      return data;
>+}
>+#pragma optimize("", on)
>+
>+/*
>+ * This function initializes GPIO port for SW I2C communication.
>+ *
>+ * Parameters:
>+ *      i2cClkGPIO      - The GPIO pin to be used as i2c SCL
>+ *      i2cDataGPIO     - The GPIO pin to be used as i2c SDA
>+ *
>+ * Return Value:
>+ *      -1   - Fail to initialize the i2c
>+ *       0   - Success
>+ */
>+long swI2CInit_SM750LE(
>+              unsigned char i2cClkGPIO,
>+              unsigned char i2cDataGPIO
>+              )
>+{
>+      int i;
>+
>+      /* Initialize the GPIO pin for the i2c Clock Register */
>+      g_i2cClkGPIODataReg = GPIO_DATA_SM750LE;
>+      g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION_SM750LE;
>+
>+      /* Initialize the Clock GPIO Offset */
>+      g_i2cClockGPIO = i2cClkGPIO;
>+
>+      /* Initialize the GPIO pin for the i2c Data Register */
>+      g_i2cDataGPIODataReg = GPIO_DATA_SM750LE;
>+      g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION_SM750LE;
>+
>+      /* Initialize the Data GPIO Offset */
>+      g_i2cDataGPIO = i2cDataGPIO;
>+
>+      /* Note that SM750LE don't have GPIO MUX and power is always on */
>+
>+      /* Clear the i2c lines. */
>+      for (i = 0; i < 9; i++)
>+              swI2CStop();
>+
>+      return 0;
>+}
>+
>+/*
>+ * This function initializes the i2c attributes and bus
>+ *
>+ * Parameters:
>+ *      i2cClkGPIO      - The GPIO pin to be used as i2c SCL
>+ *      i2cDataGPIO     - The GPIO pin to be used as i2c SDA
>+ *
>+ * Return Value:
>+ *      -1   - Fail to initialize the i2c
>+ *       0   - Success
>+ */
>+long swI2CInit(
>+              unsigned char i2cClkGPIO,
>+              unsigned char i2cDataGPIO
>+            )
>+{
>+      int i;
>+
>+      /* Return 0 if the GPIO pins to be used is out of range. The range is 
>only from [0..63] */
>+      if ((i2cClkGPIO > 31) || (i2cDataGPIO > 31))
>+              return -1;
>+
>+      if (getChipType() == SM750LE)
>+              return swI2CInit_SM750LE(i2cClkGPIO, i2cDataGPIO);
>+
>+      /* Initialize the GPIO pin for the i2c Clock Register */
>+      g_i2cClkGPIOMuxReg = GPIO_MUX;
>+      g_i2cClkGPIODataReg = GPIO_DATA;
>+      g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION;
>+
>+      /* Initialize the Clock GPIO Offset */
>+      g_i2cClockGPIO = i2cClkGPIO;
>+
>+      /* Initialize the GPIO pin for the i2c Data Register */
>+      g_i2cDataGPIOMuxReg = GPIO_MUX;
>+      g_i2cDataGPIODataReg = GPIO_DATA;
>+      g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION;
>+
>+      /* Initialize the Data GPIO Offset */
>+      g_i2cDataGPIO = i2cDataGPIO;
>+
>+      /* Enable the GPIO pins for the i2c Clock and Data (GPIO MUX) */
>+      POKE32(g_i2cClkGPIOMuxReg,
>+                      PEEK32(g_i2cClkGPIOMuxReg) & ~(1 << g_i2cClockGPIO));
>+      POKE32(g_i2cDataGPIOMuxReg,
>+                      PEEK32(g_i2cDataGPIOMuxReg) & ~(1 << g_i2cDataGPIO));
>+
>+      /* Enable GPIO power */
>+      enableGPIO(1);
>+
>+      /* Clear the i2c lines. */
>+      for (i = 0; i < 9; i++)
>+              swI2CStop();
>+
>+      return 0;
>+}
>+
>+/*
>+ *  This function reads the slave device's register
>+ *
>+ *  Parameters:
>+ *      deviceAddress   - i2c Slave device address which register
>+ *                        to be read from
>+ *      registerIndex   - Slave device's register to be read
>+ *
>+ *  Return Value:
>+ *      Register value
>+ */
>+unsigned char swI2CReadReg(
>+              unsigned char deviceAddress,
>+              unsigned char registerIndex
>+              )
>+{
>+      unsigned char data;
>+
>+      /* Send the Start signal */
>+      swI2CStart();
>+
>+      /* Send the device address */
>+      swI2CWriteByte(deviceAddress);
>+
>+      /* Send the register index */
>+      swI2CWriteByte(registerIndex);
>+
>+      /* Get the bus again and get the data from the device read address */
>+      swI2CStart();
>+      swI2CWriteByte(deviceAddress + 1);
>+      data = swI2CReadByte(1);
>+
>+      /* Stop swI2C and release the bus */
>+      swI2CStop();
>+
>+      return data;
>+}
>+
>+/*
>+ *  This function writes a value to the slave device's register
>+ *
>+ *  Parameters:
>+ *      deviceAddress   - i2c Slave device address which register
>+ *                        to be written
>+ *      registerIndex   - Slave device's register to be written
>+ *      data            - Data to be written to the register
>+ *
>+ *  Result:
>+ *          0   - Success
>+ *         -1   - Fail
>+ */
>+long swI2CWriteReg(
>+              unsigned char deviceAddress,
>+              unsigned char registerIndex,
>+              unsigned char data
>+              )
>+{
>+      long returnValue = 0;
>+
>+      /* Send the Start signal */
>+      swI2CStart();
>+
>+      /* Send the device address and read the data. All should return success
>+         in order for the writing processed to be successful
>+         */
>+      if ((swI2CWriteByte(deviceAddress) != 0) ||
>+                      (swI2CWriteByte(registerIndex) != 0) ||
>+                      (swI2CWriteByte(data) != 0)) {
>+              returnValue = -1;
>+      }
>+
>+      /* Stop i2c and release the bus */
>+      swI2CStop();
>+
>+      return returnValue;
>+}
>diff --git a/drivers/video/lynxfb/ddk750_swi2c.h 
>b/drivers/video/lynxfb/ddk750_swi2c.h
>new file mode 100644
>index 0000000..cf42753
>--- /dev/null
>+++ b/drivers/video/lynxfb/ddk750_swi2c.h
>@@ -0,0 +1,98 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef _SWI2C_H_
>+#define _SWI2C_H_
>+
>+/* Default i2c CLK and Data GPIO. These are the default i2c pins */
>+#define DEFAULT_I2C_SCL                     30
>+#define DEFAULT_I2C_SDA                     31
>+
>+/*
>+ * This function initializes the i2c attributes and bus
>+ *
>+ * Parameters:
>+ *      i2cClkGPIO  - The GPIO pin to be used as i2c SCL
>+ *      i2cDataGPIO - The GPIO pin to be used as i2c SDA
>+ *
>+ * Return Value:
>+ *      -1   - Fail to initialize the i2c
>+ *       0   - Success
>+ */
>+long swI2CInit(
>+    unsigned char i2cClkGPIO,
>+    unsigned char i2cDataGPIO
>+);
>+
>+/*
>+ *  This function reads the slave device's register
>+ *
>+ *  Parameters:
>+ *      deviceAddress   - i2c Slave device address which register
>+ *                        to be read from
>+ *      registerIndex   - Slave device's register to be read
>+ *
>+ *  Return Value:
>+ *      Register value
>+ */
>+unsigned char swI2CReadReg(
>+    unsigned char deviceAddress,
>+    unsigned char registerIndex
>+);
>+
>+/*
>+ *  This function writes a value to the slave device's register
>+ *
>+ *  Parameters:
>+ *      deviceAddress   - i2c Slave device address which register
>+ *                        to be written
>+ *      registerIndex   - Slave device's register to be written
>+ *      data            - Data to be written to the register
>+ *
>+ *  Result:
>+ *          0   - Success
>+ *         -1   - Fail
>+ */
>+long swI2CWriteReg(
>+    unsigned char deviceAddress,
>+    unsigned char registerIndex,
>+    unsigned char data
>+);
>+
>+/*
>+ *  These two functions are used to toggle the data on the SCL and SDA I2C 
>lines.
>+ *  The used of these two functions are not recommended unless it is 
>necessary.
>+ */
>+
>+/*
>+ *  This function set/reset the SCL GPIO pin
>+ *
>+ *  Parameters:
>+ *      value - Bit value to set to the SCL or SDA (0 = low, 1 = high)
>+ */
>+void swI2CSCL(unsigned char value);
>+
>+/*
>+ *  This function set/reset the SDA GPIO pin
>+ *
>+ *  Parameters:
>+ *      value - Bit value to set to the SCL or SDA (0 = low, 1 = high)
>+ */
>+void swI2CSDA(unsigned char value);
>+
>+#endif  /* _SWI2C_H_ */
>diff --git a/drivers/video/lynxfb/lynx_accel.c 
>b/drivers/video/lynxfb/lynx_accel.c
>new file mode 100644
>index 0000000..844f90e
>--- /dev/null
>+++ b/drivers/video/lynxfb/lynx_accel.c
>@@ -0,0 +1,417 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#include <linux/version.h>
>+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
>+#include <linux/config.h>
>+#endif
>+#include <linux/module.h>
>+#include <linux/kernel.h>
>+#include <linux/errno.h>
>+#include <linux/string.h>
>+#include <linux/mm.h>
>+#include <linux/slab.h>
>+#include <linux/delay.h>
>+#include <linux/fb.h>
>+#include <linux/ioport.h>
>+#include <linux/init.h>
>+#include <linux/pci.h>
>+#include <linux/vmalloc.h>
>+#include <linux/pagemap.h>
>+#include <linux/console.h>
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+/* no below two header files in 2.6.9 */
>+#include <linux/platform_device.h>
>+#include <linux/screen_info.h>
>+#else
>+/* nothing by far */
>+#endif
>+
>+#include "lynx_drv.h"
>+#include "lynx_accel.h"
>+#include "lynx_help.h"
>+static inline void write_dpr(struct lynx_accel *accel, int offset, u32 
>regValue)
>+{
>+      writel(regValue, accel->dprBase + offset);
>+}
>+
>+static inline u32 read_dpr(struct lynx_accel *accel, int offset)
>+{
>+      return readl(accel->dprBase + offset);
>+}
>+
>+static inline void write_dpPort(struct lynx_accel *accel, u32 data)
>+{
>+      writel(data, accel->dpPortBase);
>+}
>+
>+void hw_de_init(struct lynx_accel *accel)
>+{
>+      /* setup 2d engine registers */
>+      u32 reg, clr;
>+      ENTER();
>+      write_dpr(accel, DE_MASKS, 0xFFFFFFFF);
>+
>+      /* dpr1c */
>+      reg = (~(1 << DE_STRETCH_FORMAT_PATTERN_XY_LSB))&
>+              (~(1 << DE_STRETCH_FORMAT_PATTERN_Y_LSB))&
>+              (~(1 << DE_STRETCH_FORMAT_PATTERN_X_LSB))&
>+              (~(15 << DE_STRETCH_FORMAT_ADDRESSING_LSB))|
>+              (3 << DE_STRETCH_FORMAT_SOURCE_HEIGHT_LSB);
>+
>+      clr &= (~(1 << DE_STRETCH_FORMAT_PATTERN_XY_LSB))&
>+              (~(7 << DE_STRETCH_FORMAT_PATTERN_Y_LSB))&
>+              (~(7 << DE_STRETCH_FORMAT_PATTERN_X_LSB))&
>+              (~(15 << DE_STRETCH_FORMAT_ADDRESSING_LSB))&
>+              (~(0xFFF << DE_STRETCH_FORMAT_SOURCE_HEIGHT_LSB));
>+
>+      /* DE_STRETCH bpp format need be initilized in setMode routine */
>+      write_dpr(accel, DE_STRETCH_FORMAT, (read_dpr(accel, DE_STRETCH_FORMAT) 
>& clr) | reg);
>+
>+      /* disable clipping and transparent */
>+      write_dpr(accel, DE_CLIP_TL, 0);
>+      write_dpr(accel, DE_CLIP_BR, 0);
>+
>+      write_dpr(accel, DE_COLOR_COMPARE_MASK, 0);
>+      write_dpr(accel, DE_COLOR_COMPARE, 0);
>+
>+      reg = (~(1 << DE_CONTROL_TRANSPARENCY_LSB))&
>+              (~(1 << DE_CONTROL_TRANSPARENCY_MATCH_LSB))&
>+              (~(1 << DE_CONTROL_TRANSPARENCY_SELECT_LSB));
>+
>+      clr = (~(1 << DE_CONTROL_TRANSPARENCY_LSB))&
>+              (~(1 << DE_CONTROL_TRANSPARENCY_MATCH_LSB))&
>+              (~(1 << DE_CONTROL_TRANSPARENCY_SELECT_LSB));
>+
>+      /* dpr0c */
>+      write_dpr(accel, DE_CONTROL, (read_dpr(accel, DE_CONTROL)&clr)|reg);
>+      LEAVE();
>+}
>+
>+/* set2dformat only be called from setmode functions
>+ * but if you need dual framebuffer driver, need call set2dformat
>+ * every time you use 2d function */
>+
>+void hw_set2dformat(struct lynx_accel *accel, int fmt)
>+{
>+      u32 reg;
>+      ENTER();
>+      /* fmt=0, 1, 2 for 8, 16, 32, bpp on sm718/750/502 */
>+      reg = read_dpr(accel, DE_STRETCH_FORMAT);
>+      reg &= (~(3 << DE_STRETCH_FORMAT_PIXEL_FORMAT_LSB));
>+      reg |= fmt << DE_STRETCH_FORMAT_PIXEL_FORMAT_LSB;
>+      write_dpr(accel, DE_STRETCH_FORMAT, reg);
>+      LEAVE();
>+}
>+
>+int hw_fillrect(struct lynx_accel *accel,
>+              u32 base, u32 pitch, u32 Bpp,
>+              u32 x, u32 y, u32 width, u32 height,
>+              u32 color, u32 rop)
>+{
>+      u32 deCtrl;
>+
>+      if (accel->de_wait() != 0) {
>+              /* int time wait and always busy, seems hardware
>+               * got something error */
>+              dbg_msg("%s:De engine always bussy\n", __func__);
>+              return -1;
>+      }
>+
>+      write_dpr(accel, DE_WINDOW_DESTINATION_BASE, base);
>+      write_dpr(accel, DE_PITCH,
>+                      (pitch/Bpp << DE_PITCH_DESTINATION_LSB)|
>+                      (pitch/Bpp << DE_PITCH_SOURCE_LSB));
>+
>+      write_dpr(accel, DE_WINDOW_WIDTH,
>+                      (pitch/Bpp << DE_WINDOW_WIDTH_DESTINATION_LSB)|
>+                      (pitch/Bpp << DE_WINDOW_WIDTH_SOURCE_LSB));
>+      write_dpr(accel, DE_FOREGROUND, color);
>+
>+      write_dpr(accel, DE_DESTINATION, (x << DE_DESTINATION_X_LSB)|
>+                      (y << DE_DESTINATION_Y_LSB));
>+
>+      write_dpr(accel, DE_DIMENSION,
>+                      (width << DE_DIMENSION_X_LSB)|
>+                      (height << DE_DIMENSION_Y_ET_LSB));
>+
>+      deCtrl |=
>+              (1 << DE_CONTROL_STATUS_LSB)&
>+              (~(1 << DE_CONTROL_DIRECTION_LSB))|
>+              (1 << DE_CONTROL_LAST_PIXEL_LSB)|
>+              (1 << DE_CONTROL_COMMAND_LSB)|
>+              (1 << DE_CONTROL_ROP_SELECT_LSB)|
>+              (rop << DE_CONTROL_ROP_LSB);
>+      write_dpr(accel, DE_CONTROL, deCtrl);
>+      return 0;
>+}
>+
>+int hw_copyarea(
>+              struct lynx_accel *accel,
>+              unsigned int sBase, /* Address of source: offset in frame 
>buffer */
>+              unsigned int sPitch, /* Pitch value of source surface in BYTE */
>+              unsigned int sx,
>+              unsigned int sy, /* Starting coordinate of source surface */
>+              unsigned int dBase, /* Address of destination: offset in frame 
>buffer */
>+              unsigned int dPitch, /* Pitch value of destination surface in 
>BYTE */
>+              unsigned int Bpp, /* Color depth of destination surface */
>+              unsigned int dx,
>+              unsigned int dy, /* Starting coordinate of destination surface 
>*/
>+              unsigned int width,
>+              unsigned int height, /* width and height of rectangle in pixel 
>value */
>+              unsigned int rop2)   /* ROP value */
>+{
>+      unsigned int nDirection, de_ctrl;
>+      int opSign;
>+      nDirection = LEFT_TO_RIGHT;
>+      /* Direction of ROP2 operation: 1 = Left to Right, (-1) = Right to Left 
>*/
>+      opSign = 1;
>+      de_ctrl = 0;
>+
>+      /* If source and destination are the same surface, need to check for 
>overlay cases */
>+      if (sBase == dBase && sPitch == dPitch) {
>+
>+              /* Determine direction of operation */
>+              if (sy < dy) {
>+
>+                      /* +----------+
>+                         |S         |
>+                         |   +----------+
>+                         |   |      |   |
>+                         |   |      |   |
>+                         +---|------+   |
>+                         |         D|
>+                         +----------+ */
>+
>+                      nDirection = BOTTOM_TO_TOP;
>+              } else if (sy > dy)     {
>+
>+                      /* +----------+
>+                         |D         |
>+                         |   +----------+
>+                         |   |      |   |
>+                         |   |      |   |
>+                         +---|------+   |
>+                         |         S|
>+                         +----------+ */
>+
>+                      nDirection = TOP_TO_BOTTOM;
>+              } else{
>+
>+                      /* sy == dy */
>+
>+                      if (sx <= dx) {
>+
>+                              /* +------+---+------+
>+                                 |S     |   |     D|
>+                                 |      |   |      |
>+                                 |      |   |      |
>+                                 |      |   |      |
>+                                 +------+---+------+ */
>+
>+                              nDirection = RIGHT_TO_LEFT;
>+                      } else{
>+
>+                              /* sx > dx */
>+
>+                              /* +------+---+------+
>+                                 |D     |   |     S|
>+                                 |      |   |      |
>+                                 |      |   |      |
>+                                 |      |   |      |
>+                                 +------+---+------+ */
>+
>+                              nDirection = LEFT_TO_RIGHT;
>+                      }
>+              }
>+      }
>+
>+      if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) {
>+
>+              sx += width - 1;
>+              sy += height - 1;
>+              dx += width - 1;
>+              dy += height - 1;
>+              opSign = (-1);
>+      }
>+
>+      /* Note:
>+         DE_FOREGROUND are DE_BACKGROUND are don't care.
>+         DE_COLOR_COMPARE and DE_COLOR_COMPARE_MAKS are set by set 
>deSetTransparency().
>+         */
>+
>+      /* 2D Source Base.
>+         It is an address offset (128 bit aligned) from the beginning of 
>frame buffer.
>+         */
>+      write_dpr(accel, DE_WINDOW_SOURCE_BASE, sBase);
>+
>+      /* 2D Destination Base.
>+         It is an address offset (128 bit aligned) from the beginning of 
>frame buffer.
>+         */
>+      write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dBase);
>+
>+
>+      {
>+              write_dpr(accel, DE_PITCH,
>+                              ((dPitch/Bpp) << DE_PITCH_DESTINATION_LSB) |
>+                              ((sPitch/Bpp) << DE_PITCH_SOURCE_LSB));
>+      }
>+
>+      /* Screen Window width in Pixels.
>+         2D engine uses this value to calculate the linear address in frame 
>buffer for a given point.
>+         */
>+      write_dpr(accel, DE_WINDOW_WIDTH,
>+                      ((dPitch/Bpp) << DE_WINDOW_WIDTH_DESTINATION_LSB) |
>+                      ((sPitch/Bpp) << DE_WINDOW_WIDTH_SOURCE_LSB));
>+
>+      if (accel->de_wait() != 0) {
>+              return -1;
>+      }
>+
>+      {
>+              write_dpr(accel, DE_SOURCE, (~(1 << DE_SOURCE_WRAP_LSB))&
>+                              (sx << DE_SOURCE_X_K1_LSB)|
>+                              (sy << DE_SOURCE_Y_K2_LSB));
>+
>+              write_dpr(accel, DE_DESTINATION, (dx << DE_DESTINATION_X_LSB)|
>+                              (dy << DE_DESTINATION_Y_LSB));
>+
>+              write_dpr(accel, DE_DIMENSION,
>+                              (width << DE_DIMENSION_X_LSB)|
>+                              (height << DE_DIMENSION_Y_ET_LSB));
>+
>+              de_ctrl = (rop2 << DE_CONTROL_ROP_LSB)|
>+                      (1 << DE_CONTROL_ROP_SELECT_LSB)&
>+                      (~(0x1f << DE_CONTROL_COMMAND_LSB))|
>+                      (1 << DE_CONTROL_STATUS_LSB);
>+
>+              if (nDirection == RIGHT_TO_LEFT)
>+                      de_ctrl |= 1 << DE_CONTROL_DIRECTION_LSB;
>+              else
>+                      de_ctrl &= ~(1 << DE_CONTROL_DIRECTION_LSB);
>+
>+              write_dpr(accel, DE_CONTROL, de_ctrl);
>+      }
>+
>+      return 0;
>+}
>+
>+static unsigned int deGetTransparency(struct lynx_accel *accel)
>+{
>+      unsigned int de_ctrl;
>+
>+      de_ctrl = read_dpr(accel, DE_CONTROL);
>+      de_ctrl &=
>+              (1 << DE_CONTROL_TRANSPARENCY_MATCH_LSB) |
>+              (1 << DE_CONTROL_TRANSPARENCY_SELECT_LSB)|
>+              (1 << DE_CONTROL_TRANSPARENCY_LSB);
>+      return de_ctrl;
>+}
>+
>+int hw_imageblit(
>+              struct lynx_accel *accel,
>+              unsigned char *pSrcbuf, /* pointer to start of source buffer in 
>system memory */
>+              int srcDelta, /* Pitch value (in bytes) of the source buffer, 
>+ive means top down and -ive mean button up */
>+              unsigned int startBit, /* Mono data can start at any bit in a 
>byte, this value should be 0 to 7 */
>+              unsigned int dBase, /* Address of destination: offset in frame 
>buffer */
>+              unsigned int dPitch, /* Pitch value of destination surface in 
>BYTE */
>+              unsigned int bytePerPixel, /* Color depth of destination 
>surface */
>+              unsigned int dx,
>+              unsigned int dy, /* Starting coordinate of destination surface 
>*/
>+              unsigned int width,
>+              unsigned int height, /* width and height of rectange in pixel 
>value */
>+              unsigned int fColor, /* Foreground color (corresponding to a 1 
>in the monochrome data */
>+              unsigned int bColor, /* Background color (corresponding to a 0 
>in the monochrome data */
>+              unsigned int rop2)     /* ROP value */
>+{
>+      unsigned int ulBytesPerScan;
>+      unsigned int ul4BytesPerScan;
>+      unsigned int ulBytesRemain;
>+      unsigned int de_ctrl = 0;
>+      unsigned char ajRemain[4];
>+      int i, j;
>+
>+      startBit &= 7; /* Just make sure the start bit is within legal range */
>+      ulBytesPerScan = (width + startBit + 7) / 8;
>+      ul4BytesPerScan = ulBytesPerScan & ~3;
>+      ulBytesRemain = ulBytesPerScan & 3;
>+
>+      if (accel->de_wait() != 0) {
>+              /* inf_msg("*** ImageBlit return -1 ***\n"); */
>+              return -1;
>+      }
>+
>+      /* 2D Source Base.
>+         Use 0 for HOST Blt.
>+         */
>+      write_dpr(accel, DE_WINDOW_SOURCE_BASE, 0);
>+
>+      /* 2D Destination Base.
>+         It is an address offset (128 bit aligned) from the beginning of 
>frame buffer.
>+         */
>+      write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dBase);
>+      {
>+              write_dpr(accel, DE_PITCH,
>+                              (dPitch/bytePerPixel << 
>DE_PITCH_DESTINATION_LSB) |
>+                              (dPitch/bytePerPixel << DE_PITCH_SOURCE_LSB));
>+      }
>+
>+      /* Screen Window width in Pixels.
>+         2D engine uses this value to calculate the linear address in frame 
>buffer for a given point.
>+         */
>+      write_dpr(accel, DE_WINDOW_WIDTH,
>+                      ((dPitch/bytePerPixel) << 
>DE_WINDOW_WIDTH_DESTINATION_LSB) |
>+                      ((dPitch/bytePerPixel) << DE_WINDOW_WIDTH_SOURCE_LSB));
>+
>+      /* Note: For 2D Source in Host Write, only X_K1_MONO field is needed, 
>and Y_K2 field is not used.
>+         For mono bitmap, use startBit for X_K1. */
>+      write_dpr(accel, DE_SOURCE, startBit << DE_SOURCE_X_K1_MONO);
>+      write_dpr(accel, DE_DESTINATION, (dx << DE_DESTINATION_X_LSB)|
>+                      (dy << DE_DESTINATION_Y_LSB));
>+
>+      write_dpr(accel, DE_DIMENSION,
>+                      (width << DE_DIMENSION_X_LSB)|
>+                      (height << DE_DIMENSION_Y_ET_LSB));
>+      write_dpr(accel, DE_FOREGROUND, fColor);
>+      write_dpr(accel, DE_BACKGROUND, bColor);
>+
>+      de_ctrl = (rop2 << DE_CONTROL_ROP_LSB)|
>+              (1 << DE_CONTROL_ROP_SELECT_LSB)|
>+              (8 << DE_CONTROL_COMMAND_LSB)|
>+              (1 << DE_CONTROL_HOST_LSB)|
>+              (1 << DE_CONTROL_STATUS_LSB);
>+      write_dpr(accel, DE_CONTROL, de_ctrl | deGetTransparency(accel));
>+
>+      /* 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++)       {
>+                      write_dpPort(accel, *(unsigned int *)(pSrcbuf + (j * 
>4)));
>+              }
>+
>+              if (ulBytesRemain) {
>+                      memcpy(ajRemain, pSrcbuf+ul4BytesPerScan, 
>ulBytesRemain);
>+                      write_dpPort(accel, *(unsigned int *)ajRemain);
>+              }
>+
>+              pSrcbuf += srcDelta;
>+      }
>+
>+      return 0;
>+}
>+
>diff --git a/drivers/video/lynxfb/lynx_accel.h 
>b/drivers/video/lynxfb/lynx_accel.h
>new file mode 100644
>index 0000000..328157c
>--- /dev/null
>+++ b/drivers/video/lynxfb/lynx_accel.h
>@@ -0,0 +1,161 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef ACCEL_H__
>+#define ACCEL_H__
>+
>+#define HW_ROP2_COPY 0xc
>+#define HW_ROP2_XOR 0x6
>+
>+/* notes: below address are the offset value from de_base_address (0x100000)*/
>+
>+/* for sm718/750/502 de_base is at mmreg_1mb*/
>+#define DE_BASE_ADDR_TYPE1    0x100000
>+/* for sm712, de_base is at mmreg_32kb */
>+#define DE_BASE_ADDR_TYPE2    0x8000
>+/* for sm722, de_base is at mmreg_0 */
>+#define DE_BASE_ADDR_TYPE3 0
>+
>+/* type1 data port address is at mmreg_0x110000*/
>+#define DE_PORT_ADDR_TYPE1 0x110000
>+/* for sm712, data port address is at mmreg_0 */
>+#define DE_PORT_ADDR_TYPE2 0x100000
>+/* for sm722, data port address is at mmreg_1mb */
>+#define DE_PORT_ADDR_TYPE3 0x100000
>+
>+#define DE_SOURCE 0
>+#define DE_SOURCE_WRAP_LSB    31
>+#define DE_SOURCE_X_K1_LSB    16
>+#define DE_SOURCE_Y_K2_LSB    0
>+#define DE_SOURCE_X_K1_MONO 0
>+
>+#define DE_DESTINATION                0x4
>+#define DE_DESTINATION_WRAP_LSB 31
>+#define DE_DESTINATION_X_LSB 16
>+#define DE_DESTINATION_Y_LSB 0
>+
>+#define DE_DIMENSION                                    0x8
>+#define DE_DIMENSION_X_LSB                              16
>+#define DE_DIMENSION_Y_ET_LSB                           0
>+
>+#define DE_CONTROL                                      0xC
>+#define DE_CONTROL_STATUS_LSB                           31
>+#define DE_CONTROL_DIRECTION_LSB                            27
>+#define DE_CONTROL_HOST_LSB                                 22
>+#define DE_CONTROL_LAST_PIXEL_LSB                           21
>+#define DE_CONTROL_COMMAND_LSB                          16
>+#define DE_CONTROL_ROP_SELECT_LSB                       15
>+#define DE_CONTROL_ROP2_SOURCE_LSB                      14
>+#define DE_CONTROL_TRANSPARENCY_MATCH_LSB               10
>+#define DE_CONTROL_TRANSPARENCY_SELECT_LSB              9
>+#define DE_CONTROL_TRANSPARENCY_LSB                                   8
>+#define DE_CONTROL_ROP_LSB                              0
>+#define DE_MASKS                                        0x000028
>+#define DE_CLIP_TL                                      0x00002C
>+#define DE_CLIP_BR                                      0x000030
>+#define DE_COLOR_COMPARE                                0x000020
>+#define DE_COLOR_COMPARE_MASK                           0x000024
>+#define DE_MONO_PATTERN_LOW                             0x000034
>+#define DE_MONO_PATTERN_HIGH                            0x000038
>+#define DE_WINDOW_SOURCE_BASE                           0x000040
>+#define DE_WINDOW_DESTINATION_BASE                      0x000044
>+
>+#define DE_PITCH                                        0x000010
>+#define DE_PITCH_DESTINATION_LSB                        16
>+#define DE_PITCH_SOURCE_LSB                             0
>+
>+
>+#define DE_FOREGROUND                                   0x000014
>+#define DE_BACKGROUND                                   0x000018
>+
>+#define DE_STRETCH_FORMAT                               0x00001C
>+#define DE_STRETCH_FORMAT_PATTERN_XY_LSB                30
>+#define DE_STRETCH_FORMAT_PATTERN_Y_LSB                 27
>+#define DE_STRETCH_FORMAT_PATTERN_X_LSB                 23
>+#define DE_STRETCH_FORMAT_PIXEL_FORMAT_LSB              20
>+#define DE_STRETCH_FORMAT_ADDRESSING_LSB                16
>+#define DE_STRETCH_FORMAT_SOURCE_HEIGHT_LSB             0
>+#define DE_MASKS                                        0x000028
>+#define DE_CLIP_TL                                      0x00002C
>+#define DE_CLIP_BR                                      0x000030
>+#define DE_COLOR_COMPARE                                0x000020
>+#define DE_COLOR_COMPARE_MASK                           0x000024
>+#define DE_MONO_PATTERN_LOW                             0x000034
>+#define DE_MONO_PATTERN_HIGH                            0x000038
>+#define DE_WINDOW_SOURCE_BASE                           0x000040
>+#define DE_WINDOW_DESTINATION_BASE                      0x000044
>+
>+
>+
>+#define DE_WINDOW_WIDTH                                 0x00003C
>+#define DE_WINDOW_WIDTH_DESTINATION_LSB                     16
>+#define DE_WINDOW_WIDTH_SOURCE_LSB                          0
>+
>+
>+
>+/* blt direction */
>+#define TOP_TO_BOTTOM 0
>+#define LEFT_TO_RIGHT 0
>+#define BOTTOM_TO_TOP 1
>+#define RIGHT_TO_LEFT 1
>+
>+void hw_set2dformat(struct lynx_accel *accel, int fmt);
>+
>+void hw_de_init(struct lynx_accel *accel);
>+
>+int hw_fillrect(struct lynx_accel *accel,
>+                              u32 base, u32 pitch, u32 Bpp,
>+                              u32 x, u32 y, u32 width, u32 height,
>+                              u32 color, u32 rop);
>+
>+int hw712_fillrect(struct lynx_accel *accel,
>+                              u32 base, u32 pitch, u32 Bpp,
>+                              u32 x, u32 y, u32 width, u32 height,
>+                              u32 color, u32 rop);
>+
>+int hw_copyarea(
>+struct lynx_accel *accel,
>+unsigned int sBase,  /* Address of source: offset in frame buffer */
>+unsigned int sPitch, /* Pitch value of source surface in BYTE */
>+unsigned int sx,
>+unsigned int sy,     /* Starting coordinate of source surface */
>+unsigned int dBase,  /* Address of destination: offset in frame buffer */
>+unsigned int dPitch, /* Pitch value of destination surface in BYTE */
>+unsigned int bpp,    /* Color depth of destination surface */
>+unsigned int dx,
>+unsigned int dy,     /* Starting coordinate of destination surface */
>+unsigned int width,
>+unsigned int height, /* width and height of rectangle in pixel value */
>+unsigned int rop2);
>+
>+int hw_imageblit(
>+struct lynx_accel *accel,
>+unsigned char *pSrcbuf, /* pointer to start of source buffer in system memory 
>*/
>+int srcDelta,          /* Pitch value (in bytes) of the source buffer, +ive 
>means top down and -ive mean button up */
>+unsigned int startBit, /* Mono data can start at any bit in a byte, this 
>value should be 0 to 7 */
>+unsigned int dBase,    /* Address of destination: offset in frame buffer */
>+unsigned int dPitch,   /* Pitch value of destination surface in BYTE */
>+unsigned int bytePerPixel,      /* Color depth of destination surface */
>+unsigned int dx,
>+unsigned int dy,       /* Starting coordinate of destination surface */
>+unsigned int width,
>+unsigned int height,   /* width and height of rectange in pixel value */
>+unsigned int fColor,   /* Foreground color (corresponding to a 1 in the 
>monochrome data */
>+unsigned int bColor,   /* Background color (corresponding to a 0 in the 
>monochrome data */
>+unsigned int rop2);
>+#endif
>diff --git a/drivers/video/lynxfb/lynx_cursor.c 
>b/drivers/video/lynxfb/lynx_cursor.c
>new file mode 100644
>index 0000000..8aa471f
>--- /dev/null
>+++ b/drivers/video/lynxfb/lynx_cursor.c
>@@ -0,0 +1,223 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#include <linux/version.h>
>+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
>+#include <linux/config.h>
>+#endif
>+#include <linux/module.h>
>+#include <linux/kernel.h>
>+#include <linux/errno.h>
>+#include <linux/string.h>
>+#include <linux/mm.h>
>+#include <linux/slab.h>
>+#include <linux/delay.h>
>+#include <linux/fb.h>
>+#include <linux/ioport.h>
>+#include <linux/init.h>
>+#include <linux/pci.h>
>+#include <linux/vmalloc.h>
>+#include <linux/pagemap.h>
>+#include <linux/console.h>
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+/* no below two header files in 2.6.9 */
>+#include <linux/platform_device.h>
>+#include <linux/screen_info.h>
>+#else
>+/* nothing by far */
>+#endif
>+
>+#include "lynx_drv.h"
>+#include "lynx_help.h"
>+#include "lynx_cursor.h"
>+
>+#define PEEK32(addr) \
>+readl(cursor->mmio + (addr))
>+
>+#define POKE32(addr, data) \
>+writel((data), cursor->mmio + (addr))
>+
>+/* cursor control for voyager and 718/750*/
>+
>+#define HWC_ADDRESS                         0x0
>+#define HWC_ADDRESS_ENABLE_LSB              31
>+#define HWC_ADDRESS_EXT_LSB                 27
>+#define HWC_ADDRESS_CS                      26
>+#define HWC_ADDRESS_ADDRESS_LSB             0
>+#define HWC_LOCATION                        0x4
>+#define HWC_LOCATION_TOP_LSB                27
>+#define HWC_LOCATION_Y_LSB                  16
>+#define HWC_LOCATION_LEFT                   11
>+#define HWC_LOCATION_X_LSB                  0
>+#define HWC_COLOR_12                        0x8
>+#define HWC_COLOR_3                         0xC
>+
>+/* hw_cursor_xxx works for voyager, 718 and 750 */
>+void hw_cursor_enable(struct lynx_cursor *cursor)
>+{
>+      u32 reg;
>+      reg =  (cursor->offset << HWC_ADDRESS_ADDRESS_LSB)&
>+                      (~(1 << HWC_ADDRESS_EXT_LSB))|
>+                      (1 << HWC_ADDRESS_ENABLE_LSB);
>+      POKE32(HWC_ADDRESS, reg);
>+}
>+void hw_cursor_disable(struct lynx_cursor *cursor)
>+{
>+      POKE32(HWC_ADDRESS, 0);
>+}
>+
>+void hw_cursor_setSize(struct lynx_cursor *cursor,
>+                                              int w, int h)
>+{
>+      cursor->w = w;
>+      cursor->h = h;
>+}
>+void hw_cursor_setPos(struct lynx_cursor *cursor,
>+                                              int x, int y)
>+{
>+      u32 reg;
>+      reg = (y << HWC_LOCATION_Y_LSB)|
>+                      (x << HWC_LOCATION_X_LSB);
>+      POKE32(HWC_LOCATION, reg);
>+}
>+void hw_cursor_setColor(struct lynx_cursor *cursor,
>+                                              u32 fg, u32 bg)
>+{
>+      POKE32(HWC_COLOR_12, (fg<<16)|(bg&0xffff));
>+      POKE32(HWC_COLOR_3, 0xffe0);
>+}
>+
>+void hw_cursor_setData(struct lynx_cursor *cursor,
>+                      u16 rop, const u8 *pcol, const u8 *pmsk)
>+{
>+      int i, j, count, pitch, offset;
>+      u8 color, mask, opr;
>+      u16 data;
>+      u16 *pbuffer, *pstart;
>+      static ulong odd;
>+
>+      /*  in byte*/
>+      pitch = cursor->w >> 3;
>+
>+      /* in byte      */
>+      count = pitch * cursor->h;
>+
>+      /* in ushort */
>+      offset = cursor->maxW * 2 / 8 / 2;
>+
>+      data = 0;
>+      pstart = (u16 *)cursor->vstart;
>+      pbuffer = pstart;
>+
>+/*
>+      if (odd &1) {
>+              hw_cursor_setData2(cursor, rop, pcol, pmsk);
>+      }
>+      odd++;
>+      if (odd > 0xfffffff0)
>+              odd=0;
>+*/
>+
>+      for (i = 0; i < count; i++) {
>+
>+              color = *pcol++;
>+              mask = *pmsk++;
>+              data = 0;
>+
>+              /* either method below works well,
>+               * but method 2 shows no lag
>+               * and method 1 seems a bit wrong*/
>+
>+              for (j = 0; j < 8; j++) {
>+                      if (mask & (0x80>>j)) {
>+                              if (rop == ROP_XOR)
>+                                      opr = mask ^ color;
>+                              else
>+                                      opr = mask & color;
>+
>+                              /* 2 stands for forecolor and 1 for backcolor */
>+                              data |= ((opr & (0x80>>j)) ? 2 : 1)<<(j*2);
>+                      }
>+              }
>+
>+              *pbuffer = data;
>+
>+              /* assume pitch is 1, 2, 4, 8, ...*/
>+              if ((i+1) % pitch == 0) {
>+                      /* need a return */
>+                      pstart += offset;
>+                      pbuffer = pstart;
>+              } else{
>+                      pbuffer++;
>+              }
>+
>+      }
>+
>+
>+}
>+
>+void hw_cursor_setData2(struct lynx_cursor *cursor,
>+                      u16 rop, const u8 *pcol, const u8 *pmsk)
>+{
>+      int i, j, count, pitch, offset;
>+      u8 color, mask, opr;
>+      u16 data;
>+      u16 *pbuffer, *pstart;
>+
>+      /*  in byte*/
>+      pitch = cursor->w >> 3;
>+
>+      /* in byte      */
>+      count = pitch * cursor->h;
>+
>+      /* in ushort */
>+      offset = cursor->maxW * 2 / 8 / 2;
>+
>+      data = 0;
>+      pstart = (u16 *)cursor->vstart;
>+      pbuffer = pstart;
>+
>+      for (i = 0; i < count; i++) {
>+
>+              color = *pcol++;
>+              mask = *pmsk++;
>+              data = 0;
>+
>+              /* either method below works well,  but method 2 shows no lag */
>+
>+              for (j = 0; j < 8; j++) {
>+                      if (mask & (1 << j))
>+                              data |= ((color & (1<<j)) ? 1 : 2)<<(j*2);
>+              }
>+
>+              *pbuffer = data;
>+
>+              /* assume pitch is 1, 2, 4, 8, ...*/
>+              if (!(i&(pitch-1))) {
>+
>+
>+                      /* need a return */
>+                      pstart += offset;
>+                      pbuffer = pstart;
>+              } else{
>+                      pbuffer++;
>+              }
>+
>+      }
>+      return 0;
>+}
>diff --git a/drivers/video/lynxfb/lynx_cursor.h 
>b/drivers/video/lynxfb/lynx_cursor.h
>new file mode 100644
>index 0000000..c9aa096
>--- /dev/null
>+++ b/drivers/video/lynxfb/lynx_cursor.h
>@@ -0,0 +1,36 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef LYNX_CURSOR_H__
>+#define LYNX_CURSOR_H__
>+
>+/* hw_cursor_xxx works for voyager, 718 and 750 */
>+void hw_cursor_enable(struct lynx_cursor *cursor);
>+void hw_cursor_disable(struct lynx_cursor *cursor);
>+void hw_cursor_setSize(struct lynx_cursor *cursor,
>+                                              int w, int h);
>+void hw_cursor_setPos(struct lynx_cursor *cursor,
>+                                              int x, int y);
>+void hw_cursor_setColor(struct lynx_cursor *cursor,
>+                                              u32 fg, u32 bg);
>+void hw_cursor_setData(struct lynx_cursor *cursor,
>+                      u16 rop, const u8 *data, const u8 *mask);
>+void hw_cursor_setData2(struct lynx_cursor *cursor,
>+                      u16 rop, const u8 *data, const u8 *mask);
>+
>+#endif
>diff --git a/drivers/video/lynxfb/lynx_drv.c b/drivers/video/lynxfb/lynx_drv.c
>new file mode 100644
>index 0000000..556902d
>--- /dev/null
>+++ b/drivers/video/lynxfb/lynx_drv.c
>@@ -0,0 +1,1688 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#include <linux/version.h>
>+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
>+#include <linux/config.h>
>+#endif
>+#include <linux/kernel.h>
>+#include <linux/module.h>
>+#include <linux/errno.h>
>+#include <linux/string.h>
>+#include <linux/mm.h>
>+#include <linux/slab.h>
>+#include <linux/delay.h>
>+#include <linux/fb.h>
>+#include <linux/ioport.h>
>+#include <linux/init.h>
>+#include <linux/pci.h>
>+
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+/* no below two header files in 2.6.9 */
>+#include <linux/platform_device.h>
>+#include <linux/vmalloc.h>
>+#include <linux/pagemap.h>
>+#include <linux/screen_info.h>
>+#else
>+/* nothing by far */
>+#endif
>+#include <linux/vmalloc.h> #include<linux/pagemap.h>
>+#include <linux/console.h>
>+#ifdef CONFIG_MTRR
>+#include <asm/mtrr.h>
>+#endif
>+
>+#include "lynx_drv.h"
>+#include "ver.h"
>+#include "lynx_hw750.h"
>+#include "lynx_accel.h"
>+#include "lynx_cursor.h"
>+
>+#include "modedb.c"
>+
>+int smi_indent;
>+#ifdef MODULE
>+static void __exit lynxfb_exit(void);
>+#endif
>+
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+static int  lynxfb_setup(char *);
>+static int __init lynxfb_init(void);
>+#else
>+int __init lynxfb_setup(char *);
>+int __init lynxfb_init(void);
>+#endif
>+
>+/* chip specific setup routine */
>+static void sm750fb_setup(struct lynx_share *, char *);
>+static int __devinit lynxfb_pci_probe(struct pci_dev *, const struct 
>pci_device_id *);
>+static void __devexit lynxfb_pci_remove(struct pci_dev *);
>+
>+#ifdef CONFIG_PM
>+static int lynxfb_suspend(struct pci_dev *, pm_message_t);
>+static int lynxfb_resume(struct pci_dev *);
>+#endif
>+
>+static int __devinit lynxfb_set_fbinfo(struct fb_info *, int);
>+static int lynxfb_ops_check_var(struct fb_var_screeninfo *, struct fb_info *);
>+static int lynxfb_ops_set_par(struct fb_info *);
>+static int lynxfb_ops_setcolreg(unsigned, unsigned, unsigned, unsigned, 
>unsigned, struct fb_info *);
>+static int lynxfb_ops_blank(int, struct fb_info *);
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+static int lynxfb_ops_cursor(struct fb_info *, struct fb_cursor *);
>+#endif
>+/*
>+#ifdef __BIG_ENDIAN
>+ssize_t lynxfb_ops_write(struct fb_info *info, const char __user *buf,
>+size_t count, loff_t *ppos);
>+ssize_t lynxfb_ops_read(struct fb_info *info, char __user *buf,
>+size_t count, loff_t *ppos);
>+#endif
>+*/
>+
>+typedef void (*PROC_SPEC_SETUP)(struct lynx_share *, char *);
>+typedef int (*PROC_SPEC_MAP)(struct lynx_share *, struct pci_dev *);
>+typedef int (*PROC_SPEC_INITHW)(struct lynx_share *, struct pci_dev *);
>+
>+/* common var for all device */
>+int g_hwcursor = 1;
>+int g_noaccel;
>+#ifdef CONFIG_MTRR
>+int g_nomtrr;
>+#endif
>+const char *g_fbmode[] = {NULL, NULL};
>+const char *g_def_fbmode = "800x600-16 at 60";
>+char *g_settings;
>+int g_dualview;
>+#ifdef MODULE
>+char *g_option;
>+#endif
>+
>+/* if not use spin_lock, system will die if user load driver
>+ *and immediatly unload driver frequently (dual)*/
>+static inline void myspin_lock(spinlock_t *sl)
>+{
>+      struct lynx_share *share;
>+      share = container_of(sl, struct lynx_share, slock);
>+      if (share->dual) {
>+              spin_lock(sl);
>+      }
>+}
>+
>+static inline void myspin_unlock(spinlock_t *sl)
>+{
>+      struct lynx_share *share;
>+      share = container_of(sl, struct lynx_share, slock);
>+      if (share->dual) {
>+              spin_unlock(sl);
>+      }
>+}
>+
>+static const struct fb_videomode lynx750_ext[] = {
>+      /*      1024x600-60 VESA        [1.71:1]        */
>+      {NULL, 60, 1024, 600, 20423, 144, 40, 18, 1, 104, 3,
>+              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 
>FB_VMODE_NONINTERLACED},
>+
>+      /*      1024x600-70 VESA */
>+      {NULL, 70, 1024, 600, 17211, 152, 48, 21, 1, 104, 3,
>+              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 
>FB_VMODE_NONINTERLACED},
>+
>+      /*      1024x600-75 VESA */
>+      {NULL, 75, 1024, 600, 15822, 160, 56, 23, 1, 104, 3,
>+              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 
>FB_VMODE_NONINTERLACED},
>+
>+      /*      1024x600-85 VESA */
>+      {NULL, 85, 1024, 600, 13730, 168, 56, 26, 1, 112, 3,
>+              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 
>FB_VMODE_NONINTERLACED},
>+
>+      /*      720x480 */
>+      {NULL, 60, 720, 480, 37427, 88, 16, 13, 1, 72, 3,
>+              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 
>FB_VMODE_NONINTERLACED},
>+
>+      /*      1280x720                [1.78:1]        */
>+      {NULL, 60, 1280, 720, 13426, 162, 86, 22, 1, 136, 3,
>+              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 
>FB_VMODE_NONINTERLACED},
>+
>+      /* 1280x768 at 60 */
>+      {NULL, 60, 1280, 768, 12579, 192, 64, 20, 3, 128, 7,
>+              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 
>FB_VMODE_NONINTERLACED},
>+
>+      {NULL, 60, 1360, 768, 11804, 208, 64, 23, 1, 144, 3,
>+              FB_SYNC_HOR_HIGH_ACT|FB_VMODE_NONINTERLACED},
>+
>+      /*      1360 x 768      [1.77083:1]     */
>+      {NULL, 60, 1360, 768, 11804, 208, 64, 23, 1, 144, 3,
>+              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 
>FB_VMODE_NONINTERLACED},
>+
>+      /*      1368 x 768      [1.78:1]        */
>+      {NULL, 60, 1368, 768, 11647, 216, 72, 23, 1, 144, 3,
>+              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 
>FB_VMODE_NONINTERLACED},
>+
>+      /*      1440 x 900              [16:10] */
>+      {NULL, 60, 1440, 900, 9392, 232, 80, 28, 1, 152, 3,
>+              FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED},
>+
>+      /*      1440x960                [15:10] */
>+      {NULL, 60, 1440, 960, 8733, 240, 88, 30, 1, 152, 3,
>+              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 
>FB_VMODE_NONINTERLACED},
>+
>+      /*      1920x1080       [16:9]  */
>+      {NULL, 60, 1920, 1080, 6734, 148, 88, 41, 1, 44, 3,
>+              FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED},
>+};
>+
>+
>+static struct pci_device_id smi_pci_table[] = {
>+      {PCI_VENDOR_ID_SMI, PCI_DEVID_LYNX_EXP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
>0},
>+      {PCI_VENDOR_ID_SMI, PCI_DEVID_LYNX_SE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
>+      {PCI_VENDOR_ID_SMI, PCI_DEVID_LYNX_EM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
>+      {PCI_VENDOR_ID_SMI, PCI_DEVID_LYNX_3DM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
>0},
>+      {PCI_VENDOR_ID_SMI, PCI_DEVID_VOYAGER, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
>+      {0, }
>+};
>+
>+static struct pci_driver lynxfb_driver = {
>+      .name = _moduleName_,
>+      .id_table =     smi_pci_table,
>+      .probe =        lynxfb_pci_probe,
>+      .remove =       __devexit_p(lynxfb_pci_remove),
>+#ifdef CONFIG_PM
>+      .suspend = lynxfb_suspend,
>+      .resume = lynxfb_resume,
>+#endif
>+};
>+
>+
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+/* no hardware cursor supported under version 2.6.10, kernel bug */
>+static int lynxfb_ops_cursor(struct fb_info *info, struct fb_cursor *fbcursor)
>+{
>+      struct lynxfb_par *par;
>+      struct lynxfb_crtc *crtc;
>+      struct lynx_cursor *cursor;
>+
>+      par = info->par;
>+      crtc = &par->crtc;
>+      cursor = &crtc->cursor;
>+
>+      if (fbcursor->image.width > cursor->maxW ||
>+                      fbcursor->image.height > cursor->maxH ||
>+                      fbcursor->image.depth > 1) {
>+              return -ENXIO;
>+      }
>+
>+      cursor->disable(cursor);
>+      if (fbcursor->set & FB_CUR_SETSIZE) {
>+              cursor->setSize(cursor, fbcursor->image.width, 
>fbcursor->image.height);
>+      }
>+
>+      if (fbcursor->set & FB_CUR_SETPOS) {
>+              cursor->setPos(cursor, fbcursor->image.dx - info->var.xoffset,
>+                              fbcursor->image.dy - info->var.yoffset);
>+      }
>+
>+      if (fbcursor->set & FB_CUR_SETCMAP) {
>+              /* get the 16bit color of kernel means */
>+              u16 fg, bg;
>+              fg = ((info->cmap.red[fbcursor->image.fg_color] & 0xf800))|
>+                      ((info->cmap.green[fbcursor->image.fg_color] & 0xfc00) 
>>> 5)|
>+                      ((info->cmap.blue[fbcursor->image.fg_color] & 0xf800) 
>>> 11);
>+
>+              bg = ((info->cmap.red[fbcursor->image.bg_color] & 0xf800))|
>+                      ((info->cmap.green[fbcursor->image.bg_color] & 0xfc00) 
>>> 5)|
>+                      ((info->cmap.blue[fbcursor->image.bg_color] & 0xf800) 
>>> 11);
>+
>+              cursor->setColor(cursor, fg, bg);
>+      }
>+
>+
>+      if (fbcursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
>+
>+              cursor->setData(cursor,
>+                              fbcursor->rop,
>+                              fbcursor->image.data,
>+                              fbcursor->mask);
>+      }
>+
>+      if (fbcursor->enable) {
>+              cursor->enable(cursor);
>+      }
>+
>+      return 0;
>+}
>+
>+#endif
>+
>+static void lynxfb_ops_fillrect(struct fb_info *info, const struct 
>fb_fillrect *region)
>+{
>+      struct lynxfb_par *par;
>+      struct lynx_share *share;
>+      unsigned int base, pitch, Bpp, rop;
>+      u32 color;
>+
>+      if (info->state != FBINFO_STATE_RUNNING) {
>+              return;
>+      }
>+
>+      par = info->par;
>+      share = par->share;
>+
>+      /* each time 2d function begin to work, below three variable always need
>+       *be set, seems we can put them together in some place  */
>+      base = par->crtc.oScreen;
>+      pitch = info->fix.line_length;
>+      Bpp = info->var.bits_per_pixel >> 3;
>+
>+      color = (Bpp == 1) ? region->color : ((u32 
>*)info->pseudo_palette)[region->color];
>+      rop = (region->rop != ROP_COPY) ? HW_ROP2_XOR : HW_ROP2_COPY;
>+
>+      myspin_lock(&share->slock);
>+      share->accel.de_fillrect(&share->accel,
>+                      base, pitch, Bpp,
>+                      region->dx, region->dy,
>+                      region->width, region->height,
>+                      color, rop);
>+      myspin_unlock(&share->slock);
>+}
>+
>+static void lynxfb_ops_copyarea(struct fb_info *info, const struct 
>fb_copyarea *region)
>+{
>+      struct lynxfb_par *par;
>+      struct lynx_share *share;
>+      unsigned int base, pitch, Bpp;
>+
>+      par = info->par;
>+      share = par->share;
>+
>+      /* each time 2d function begin to work, below three variable always need
>+       *be set, seems we can put them together in some place  */
>+      base = par->crtc.oScreen;
>+      pitch = info->fix.line_length;
>+      Bpp = info->var.bits_per_pixel >> 3;
>+
>+      myspin_lock(&share->slock);
>+      share->accel.de_copyarea(&share->accel,
>+                      base, pitch, region->sx, region->sy,
>+                      base, pitch, Bpp, region->dx, region->dy,
>+                      region->width, region->height, HW_ROP2_COPY);
>+      myspin_unlock(&share->slock);
>+}
>+
>+static void lynxfb_ops_imageblit(struct fb_info *info, const struct fb_image 
>*image)
>+{
>+      unsigned int base, pitch, Bpp;
>+      unsigned int fgcol, bgcol;
>+      struct lynxfb_par *par;
>+      struct lynx_share *share;
>+
>+      par = info->par;
>+      share = par->share;
>+      /* each time 2d function begin to work, below three variable always need
>+       *be set, seems we can put them together in some place  */
>+      base = par->crtc.oScreen;
>+      pitch = info->fix.line_length;
>+      Bpp = info->var.bits_per_pixel >> 3;
>+
>+      if (image->depth == 1) {
>+              if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
>+                              info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
>+                      fgcol = ((u32 *)info->pseudo_palette)[image->fg_color];
>+                      bgcol = ((u32 *)info->pseudo_palette)[image->bg_color];
>+              } else{
>+                      fgcol = image->fg_color;
>+                      bgcol = image->bg_color;
>+              }
>+              goto _do_work;
>+      }
>+      return;
>+_do_work:
>+      myspin_lock(&share->slock);
>+      share->accel.de_imageblit(&share->accel,
>+                      image->data, image->width>>3, 0,
>+                      base, pitch, Bpp,
>+                      image->dx, image->dy,
>+                      image->width, image->height,
>+                      fgcol, bgcol, HW_ROP2_COPY);
>+      myspin_unlock(&share->slock);
>+}
>+
>+static int lynxfb_ops_pan_display(struct fb_var_screeninfo *var,
>+              struct fb_info *info)
>+{
>+      struct lynxfb_par *par;
>+      struct lynxfb_crtc *crtc;
>+      int ret;
>+      ENTER();
>+
>+      if (!info)
>+              LEAVE(-EINVAL);
>+
>+      ret = 0;
>+      par = info->par;
>+      crtc = &par->crtc;
>+      ret = crtc->proc_panDisplay(crtc, var, info);
>+
>+      LEAVE(ret);
>+}
>+
>+static struct fb_ops lynxfb_ops = {
>+      .owner = THIS_MODULE,
>+      .fb_check_var =  lynxfb_ops_check_var,
>+      .fb_set_par = lynxfb_ops_set_par,
>+      .fb_setcolreg = lynxfb_ops_setcolreg,
>+      .fb_blank = lynxfb_ops_blank,
>+      /* will be hooked by hardware */
>+      .fb_fillrect = cfb_fillrect,
>+      .fb_imageblit = cfb_imageblit,
>+      .fb_copyarea = cfb_copyarea,
>+      /* cursor */
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+      .fb_cursor = lynxfb_ops_cursor,
>+#else
>+      .fb_cursor = soft_cursor,
>+#endif
>+};
>+
>+static size_t spec_size[] = {
>+      [SPC_SM750] = sizeof(struct sm750_share),
>+};
>+
>+static PROC_SPEC_SETUP setup_rout[] = {
>+      [SPC_SM750] = sm750fb_setup,
>+};
>+
>+static PROC_SPEC_MAP map_rout[] = {
>+      [SPC_SM750] = hw_sm750_map,
>+};
>+
>+static PROC_SPEC_INITHW inithw_rout[] = {
>+      [SPC_SM750] = hw_sm750_inithw,
>+};
>+static int g_specId;
>+
>+#ifdef CONFIG_PM
>+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
>+static u32 pci_state[16];
>+
>+static int lynxfb_suspend(struct pci_dev *pdev, pm_message_t mesg)
>+{
>+      int ret;
>+      struct fb_info *info;
>+      struct lynx_share *share;
>+
>+      ENTER();
>+      ret = 0;
>+      share = pci_get_drvdata(pdev);
>+
>+      if (mesg != 2 || mesg == pdev->dev.power_state)
>+              return ret;
>+
>+      /* suspend */
>+      acquire_console_sem();
>+
>+      info = share->fbinfo[0];
>+      if (info) {
>+              fb_set_suspend(info, 1);
>+      }
>+
>+      info = share->fbinfo[1];
>+
>+      if (info) {
>+              fb_set_suspend(info, 1);
>+      }
>+
>+      /* hardware suspend stuffs */
>+      if (mesg == 2 && share->suspend)
>+              share->suspend(share);
>+
>+      pci_save_state(pdev, &pci_state);
>+      pci_disable_device(pdev);
>+      ret = pci_set_power_state(pdev, mesg);
>+
>+      release_console_sem();
>+      pdev->dev.power_state = mesg;
>+      LEAVE(ret);
>+}
>+
>+static int lynxfb_resume(struct pci_dev *pdev)
>+{
>+      int ret;
>+      struct fb_info *info;
>+      struct lynx_share *share;
>+      struct lynxfb_par *par;
>+      struct lynxfb_crtc *crtc;
>+      struct lynx_cursor *cursor;
>+
>+      ENTER();
>+      share = pci_get_drvdata(pdev);
>+      ret = 0;
>+
>+      acquire_console_sem();
>+
>+      pci_set_power_state(pdev, 0);
>+      pci_restore_state(pdev, &pci_state);
>+      pci_enable_device(pdev);
>+
>+      if (pdev->dev.power_state == 2 && share->resume)
>+              share->resume(share);
>+
>+      (*inithw_rout[g_specId])(share, pdev);
>+
>+      info = share->fbinfo[0];
>+      if (info) {
>+              par = info->par;
>+              crtc = &par->crtc;
>+              cursor = &crtc->cursor;
>+              memset(cursor->vstart, 0x0, cursor->size);
>+              memset(crtc->vScreen, 0x0, crtc->vidmem_size);
>+              lynxfb_ops_set_par(info);
>+              fb_set_suspend(info, 0);
>+      }
>+
>+      info = share->fbinfo[1];
>+
>+      if (info) {
>+              par = info->par;
>+              crtc = &par->crtc;
>+              cursor = &crtc->cursor;
>+              memset(cursor->vstart, 0x0, cursor->size);
>+              memset(crtc->vScreen, 0x0, crtc->vidmem_size);
>+              lynxfb_ops_set_par(info);
>+              fb_set_suspend(info, 0);
>+      }
>+
>+      release_console_sem();
>+      pdev->dev.power_state = 0;
>+      LEAVE(ret);
>+}
>+
>+
>+#else
>+static int lynxfb_suspend(struct pci_dev *pdev, pm_message_t mesg)
>+{
>+      struct fb_info *info;
>+      struct lynx_share *share;
>+      int ret;
>+      ENTER();
>+
>+      if (mesg.event == pdev->dev.power.power_state.event)
>+              LEAVE(0);
>+
>+      ret = 0;
>+      share = pci_get_drvdata(pdev);
>+      switch (mesg.event) {
>+      case PM_EVENT_FREEZE:
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
>+      case PM_EVENT_PRETHAW:
>+#endif
>+                      pdev->dev.power.power_state = mesg;
>+                      LEAVE(0);
>+      }
>+
>+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)
>+      acquire_console_sem();
>+#else
>+      console_lock();
>+#endif
>+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
>+      if (mesg.event & PM_EVENT_SUSPEND) {
>+#else
>+              if (mesg.event & PM_EVENT_SLEEP) {
>+#endif
>+                      info = share->fbinfo[0];
>+                      if (info)
>+                              fb_set_suspend(info, 1);/* 1 means do suspend*/
>+
>+                      info = share->fbinfo[1];
>+                      if (info)
>+                              fb_set_suspend(info, 1);/* 1 means do suspend*/
>+
>+                      ret = pci_save_state(pdev);
>+                      if (ret) {
>+                              err_msg("error:%d occured in pci_save_state\n", 
>ret);
>+                              LEAVE(ret);
>+                      }
>+
>+                      /* set chip to sleep mode       */
>+                      if (share->suspend)
>+                              (*share->suspend)(share);
>+
>+                      pci_disable_device(pdev);
>+                      ret = pci_set_power_state(pdev, pci_choose_state(pdev, 
>mesg));
>+                      if (ret) {
>+                              err_msg("error:%d occured in 
>pci_set_power_state\n", ret);
>+                              LEAVE(ret);
>+                      }
>+              }
>+
>+              pdev->dev.power.power_state = mesg;
>+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)
>+              release_console_sem();
>+#else
>+              console_unlock();
>+#endif
>+              LEAVE(ret);
>+      }
>+
>+      static int lynxfb_resume(struct pci_dev *pdev)
>+      {
>+              struct fb_info *info;
>+              struct lynx_share *share;
>+
>+              struct lynxfb_par *par;
>+              struct lynxfb_crtc *crtc;
>+              struct lynx_cursor *cursor;
>+
>+              int ret;
>+              ENTER();
>+
>+              ret = 0;
>+              share = pci_get_drvdata(pdev);
>+
>+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)
>+              acquire_console_sem();
>+#else
>+              console_lock();
>+#endif
>+
>+              ret = pci_set_power_state(pdev, PCI_D0);
>+              if (ret != 0) {
>+                      err_msg("error:%d occured in pci_set_power_state\n", 
>ret);
>+                      LEAVE(ret);
>+              }
>+
>+
>+              if (pdev->dev.power.power_state.event != PM_EVENT_FREEZE) {
>+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)
>+                      /* for linux 2.6.35 and lower */
>+                      ret = pci_restore_state(pdev);
>+                      if (ret != 0) {
>+                              err_msg("error:%d occured in 
>pci_restore_state\n", ret);
>+                              LEAVE(ret);
>+                      }
>+#else
>+                      pci_restore_state(pdev);
>+#endif
>+                      ret = pci_enable_device(pdev);
>+                      if (ret != 0) {
>+                              err_msg("error:%d occured in 
>pci_enable_device\n", ret);
>+                              LEAVE(ret);
>+                      }
>+                      pci_set_master(pdev);
>+              }
>+              if (share->resume)
>+                      (*share->resume)(share);
>+
>+              (*inithw_rout[g_specId])(share, pdev);
>+
>+
>+              info = share->fbinfo[0];
>+
>+              if (info) {
>+                      par = info->par;
>+                      crtc = &par->crtc;
>+                      cursor = &crtc->cursor;
>+                      memset(cursor->vstart, 0x0, cursor->size);
>+                      memset(crtc->vScreen, 0x0, crtc->vidmem_size);
>+                      lynxfb_ops_set_par(info);
>+                      fb_set_suspend(info, 0);
>+              }
>+
>+              info = share->fbinfo[1];
>+
>+              if (info) {
>+                      par = info->par;
>+                      crtc = &par->crtc;
>+                      cursor = &crtc->cursor;
>+                      memset(cursor->vstart, 0x0, cursor->size);
>+                      memset(crtc->vScreen, 0x0, crtc->vidmem_size);
>+                      lynxfb_ops_set_par(info);
>+                      fb_set_suspend(info, 0);
>+              }
>+
>+
>+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)
>+              release_console_sem();
>+#else
>+              console_unlock();
>+#endif
>+              LEAVE(ret);
>+      }
>+#endif
>+#endif
>+
>+static int lynxfb_ops_check_var(struct fb_var_screeninfo *var, struct fb_info 
>*info)
>+{
>+      struct lynxfb_par *par;
>+      struct lynxfb_crtc *crtc;
>+      struct lynxfb_output *output;
>+      struct lynx_share *share;
>+      int ret;
>+      resource_size_t request;
>+
>+      ENTER();
>+      par = info->par;
>+      crtc = &par->crtc;
>+      output = &par->output;
>+      share = par->share;
>+      ret = 0;
>+
>+      dbg_msg("check var:%dx%d-%d\n",
>+                      var->xres,
>+                      var->yres,
>+                      var->bits_per_pixel);
>+
>+
>+      switch (var->bits_per_pixel) {
>+      case 8:
>+      case 16:
>+      case 24: /* support 24 bpp for only lynx712/722/720 */
>+      case 32:
>+              break;
>+      default:
>+              err_msg("bpp %d not supported\n", var->bits_per_pixel);
>+              ret = -EINVAL;
>+              goto exit;
>+      }
>+
>+      switch (var->bits_per_pixel) {
>+      case 8:
>+              info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
>+              var->red.offset = 0;
>+              var->red.length = 8;
>+              var->green.offset = 0;
>+              var->green.length = 8;
>+              var->blue.offset = 0;
>+              var->blue.length = 8;
>+              var->transp.length = 0;
>+              var->transp.offset = 0;
>+              break;
>+      case 16:
>+              var->red.offset = 11;
>+              var->red.length = 5;
>+              var->green.offset = 5;
>+              var->green.length = 6;
>+              var->blue.offset = 0;
>+              var->blue.length = 5;
>+              var->transp.length = 0;
>+              var->transp.offset = 0;
>+              info->fix.visual = FB_VISUAL_TRUECOLOR;
>+              break;
>+      case 24:
>+      case 32:
>+              var->red.offset = 16;
>+              var->red.length = 8;
>+              var->green.offset = 8;
>+              var->green.length = 8;
>+              var->blue.offset = 0 ;
>+              var->blue.length = 8;
>+              info->fix.visual = FB_VISUAL_TRUECOLOR;
>+              break;
>+      default:
>+              ret = -EINVAL;
>+              break;
>+      }
>+      var->height = var->width = -1;
>+      var->accel_flags = FB_ACCELF_TEXT;
>+
>+      /* check if current fb's video memory big enought to hold the onscreen 
>*/
>+      request = var->xres_virtual * (var->bits_per_pixel >> 3);
>+      /* defaulty crtc->channel go with par->index */
>+
>+      request = PADDING(crtc->line_pad, request);
>+      request = request * var->yres_virtual;
>+      if (crtc->vidmem_size < request) {
>+              err_msg("not enough video memory for mode\n");
>+              LEAVE(-ENOMEM);
>+      }
>+
>+      ret = output->proc_checkMode(output, var);
>+      if (!ret)
>+              ret = crtc->proc_checkMode(crtc, var);
>+exit:
>+      LEAVE(ret);
>+}
>+
>+static int lynxfb_ops_set_par(struct fb_info *info)
>+{
>+      struct lynxfb_par *par;
>+      struct lynx_share *share;
>+      struct lynxfb_crtc *crtc;
>+      struct lynxfb_output *output;
>+      struct fb_var_screeninfo *var;
>+      struct fb_fix_screeninfo *fix;
>+      int ret;
>+      unsigned int line_length;
>+      ENTER();
>+
>+      if (!info)
>+              LEAVE(-EINVAL);
>+
>+      ret = 0;
>+      par = info->par;
>+      share = par->share;
>+      crtc = &par->crtc;
>+      output = &par->output;
>+      var = &info->var;
>+      fix = &info->fix;
>+
>+      /* fix structur is not so FIX ... */
>+      line_length = var->xres_virtual * var->bits_per_pixel / 8;
>+      line_length = PADDING(crtc->line_pad, line_length);
>+      fix->line_length = line_length;
>+      err_msg("fix->line_length = %d\n", fix->line_length);
>+
>+      /* var->red, green, blue, transp are need to be set by driver
>+       *and these data should be set before setcolreg routine
>+       **/
>+
>+      switch (var->bits_per_pixel) {
>+      case 8:
>+              fix->visual = FB_VISUAL_PSEUDOCOLOR;
>+              var->red.offset = 0;
>+              var->red.length = 8;
>+              var->green.offset = 0;
>+              var->green.length = 8;
>+              var->blue.offset = 0;
>+              var->blue.length = 8;
>+              var->transp.length = 0;
>+              var->transp.offset = 0;
>+              break;
>+      case 16:
>+              var->red.offset = 11;
>+              var->red.length = 5;
>+              var->green.offset = 5;
>+              var->green.length = 6;
>+              var->blue.offset = 0;
>+              var->blue.length = 5;
>+              var->transp.length = 0;
>+              var->transp.offset = 0;
>+              fix->visual = FB_VISUAL_TRUECOLOR;
>+              break;
>+      case 24:
>+      case 32:
>+              var->red.offset = 16;
>+              var->red.length = 8;
>+              var->green.offset = 8;
>+              var->green.length = 8;
>+              var->blue.offset = 0 ;
>+              var->blue.length = 8;
>+              fix->visual = FB_VISUAL_TRUECOLOR;
>+              break;
>+      default:
>+              ret = -EINVAL;
>+              break;
>+      }
>+      var->height = var->width = -1;
>+      var->accel_flags = FB_ACCELF_TEXT;
>+
>+      if (ret) {
>+              err_msg("pixel bpp format not satisfied\n.");
>+              LEAVE(ret);
>+      }
>+      ret = crtc->proc_setMode(crtc, var, fix);
>+      if (!ret)
>+              ret = output->proc_setMode(output, var, fix);
>+      LEAVE(ret);
>+}
>+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 lynxfb_ops_setcolreg(unsigned regno, unsigned red,
>+              unsigned green, unsigned blue,
>+              unsigned transp, struct fb_info *info)
>+{
>+      struct lynxfb_par *par;
>+      struct lynxfb_crtc *crtc;
>+      struct fb_var_screeninfo *var;
>+      int ret;
>+
>+      par = info->par;
>+      crtc = &par->crtc;
>+      var = &info->var;
>+      ret = 0;
>+
>+      /*dbg_msg("regno=%d, red=%d, green=%d, blue=%d\n", regno, red, green, 
>blue);*/
>+      if (regno > 256) {
>+              err_msg("regno = %d\n", regno);
>+              LEAVE(-EINVAL);
>+      }
>+
>+      if (info->var.grayscale)
>+              red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
>+
>+      if (var->bits_per_pixel == 8 && info->fix.visual == 
>FB_VISUAL_PSEUDOCOLOR) {
>+              red >>= 8;
>+              green >>= 8;
>+              blue >>= 8;
>+              ret = crtc->proc_setColReg(crtc, regno, red, green, blue);
>+              goto exit;
>+      }
>+
>+
>+      if (info->fix.visual == FB_VISUAL_TRUECOLOR && regno < 256) {
>+              u32 val;
>+              if (var->bits_per_pixel == 16 ||
>+                              var->bits_per_pixel == 32 ||
>+                              var->bits_per_pixel == 24) {
>+                      val = chan_to_field(red, &var->red);
>+                      val |= chan_to_field(green, &var->green);
>+                      val |= chan_to_field(blue, &var->blue);
>+                      par->pseudo_palette[regno] = val;
>+                      goto exit;
>+              }
>+      }
>+
>+      ret = -EINVAL;
>+
>+exit:
>+      return ret;
>+      LEAVE(ret);
>+
>+}
>+
>+static int lynxfb_ops_blank(int blank, struct fb_info *info)
>+{
>+      struct lynxfb_par *par;
>+      struct lynxfb_output *output;
>+      ENTER();
>+      dbg_msg("blank = %d.\n", blank);
>+      par = info->par;
>+      output = &par->output;
>+      LEAVE(output->proc_setBLANK(output, blank));
>+}
>+static int sm750fb_set_drv(struct lynxfb_par *par)
>+{
>+      int ret;
>+      struct lynx_share *share;
>+      struct sm750_share *spec_share;
>+      struct lynxfb_output *output;
>+      struct lynxfb_crtc *crtc;
>+      ENTER();
>+      ret = 0;
>+
>+      share = par->share;
>+      spec_share = container_of(share, struct sm750_share, share);
>+      output = &par->output;
>+      crtc = &par->crtc;
>+
>+      crtc->vidmem_size = (share->dual) ? share->vidmem_size>>1 : 
>share->vidmem_size;
>+      /* setup crtc and output member */
>+      spec_share->hwCursor = g_hwcursor;
>+
>+      crtc->proc_setMode = hw_sm750_crtc_setMode;
>+      crtc->proc_checkMode = hw_sm750_crtc_checkMode;
>+      crtc->proc_setColReg = hw_sm750_setColReg;
>+      crtc->proc_panDisplay = hw_sm750_pan_display;
>+      crtc->clear = hw_sm750_crtc_clear;
>+      crtc->line_pad = 16;
>+      /*crtc->xpanstep = crtc->ypanstep = crtc->ywrapstep = 0;*/
>+      crtc->xpanstep = 8;
>+      crtc->ypanstep = 1;
>+      crtc->ywrapstep = 0;
>+
>+      output->proc_setMode = hw_sm750_output_setMode;
>+      output->proc_checkMode = hw_sm750_output_checkMode;
>+
>+      output->proc_setBLANK = (share->revid == SM750LE_REVISION_ID) ? 
>hw_sm750le_setBLANK : hw_sm750_setBLANK;
>+      output->clear = hw_sm750_output_clear;
>+      /* chip specific phase */
>+      share->accel.de_wait = (share->revid == SM750LE_REVISION_ID) ? 
>hw_sm750le_deWait : hw_sm750_deWait;
>+      switch (spec_share->state.dataflow) {
>+      case sm750_simul_pri:
>+                      output->paths = sm750_pnc;
>+                      crtc->channel = sm750_primary;
>+                      crtc->oScreen = 0;
>+                      crtc->vScreen = share->pvMem;
>+                      inf_msg("use simul primary mode\n");
>+                      break;
>+      case sm750_simul_sec:
>+                      output->paths = sm750_pnc;
>+                      crtc->channel = sm750_secondary;
>+                      crtc->oScreen = 0;
>+                      crtc->vScreen = share->pvMem;
>+                      break;
>+      case sm750_dual_normal:
>+                      if (par->index == 0) {
>+                              output->paths = sm750_panel;
>+                              crtc->channel = sm750_primary;
>+                              crtc->oScreen = 0;
>+                              crtc->vScreen = share->pvMem;
>+                      } else{
>+                              output->paths = sm750_crt;
>+                              crtc->channel = sm750_secondary;
>+                              /* not consider of padding stuffs for oScreen, 
>need fix*/
>+                              crtc->oScreen = (share->vidmem_size >> 1);
>+                              crtc->vScreen = share->pvMem + crtc->oScreen;
>+                      }
>+                      break;
>+      case sm750_dual_swap:
>+                      if (par->index == 0) {
>+                              output->paths = sm750_panel;
>+                              crtc->channel = sm750_secondary;
>+                              crtc->oScreen = 0;
>+                              crtc->vScreen = share->pvMem;
>+                      } else{
>+                              output->paths = sm750_crt;
>+                              crtc->channel = sm750_primary;
>+                              /* not consider of padding stuffs for oScreen, 
>need fix*/
>+                              crtc->oScreen = (share->vidmem_size >> 1);
>+                              crtc->vScreen = share->pvMem + crtc->oScreen;
>+                      }
>+                      break;
>+      default:
>+                      ret = -EINVAL;
>+      }
>+
>+      LEAVE(ret);
>+}
>+
>+static int __devinit lynxfb_set_fbinfo(struct fb_info *info, int index)
>+{
>+      int i;
>+      struct lynxfb_par *par;
>+      struct lynx_share *share;
>+      struct lynxfb_crtc *crtc;
>+      struct lynxfb_output *output;
>+      struct fb_var_screeninfo *var;
>+      struct fb_fix_screeninfo *fix;
>+
>+      const struct fb_videomode *pdb[] = {
>+              NULL, NULL, vesa_modes,
>+      };
>+      int cdb[] = {0, 0, VESA_MODEDB_SIZE};
>+      static const char *mdb_desc[] = {
>+              "driver prepared modes",
>+              "kernel prepared default modedb",
>+              "kernel HELPERS prepared vesa_modes",
>+      };
>+
>+#define sm502_ext lynx750_ext
>+      static const struct fb_videomode *ext_table[] = {lynx750_ext, NULL, 
>sm502_ext};
>+      static size_t ext_size[] = {ARRAY_SIZE(lynx750_ext), 0, 
>ARRAY_SIZE(sm502_ext)};
>+
>+      static const char *fixId[][2] = {
>+              {"sm750_fb1", "sm750_fb2"},
>+      };
>+
>+      int ret, line_length;
>+      ENTER();
>+      ret = 0;
>+      par = (struct lynxfb_par *)info->par;
>+      share = par->share;
>+      crtc = &par->crtc;
>+      output = &par->output;
>+      var = &info->var;
>+      fix = &info->fix;
>+
>+      /* set index */
>+      par->index = index;
>+      output->channel = &crtc->channel;
>+
>+      sm750fb_set_drv(par);
>+      lynxfb_ops.fb_pan_display = lynxfb_ops_pan_display;
>+
>+      /* set current cursor variable and proc pointer,
>+       *must be set after crtc member initialized */
>+
>+      crtc->cursor.offset = crtc->oScreen + crtc->vidmem_size - 1024;
>+      crtc->cursor.mmio = share->pvReg + 0x800f0 + (int)crtc->channel * 0x140;
>+
>+      inf_msg("crtc->cursor.mmio = %p\n", crtc->cursor.mmio);
>+      crtc->cursor.maxH = crtc->cursor.maxW = 64;
>+      crtc->cursor.size = crtc->cursor.maxH*crtc->cursor.maxW*2/8;
>+      crtc->cursor.disable = hw_cursor_disable;
>+      crtc->cursor.enable = hw_cursor_enable;
>+      crtc->cursor.setColor = hw_cursor_setColor;
>+      crtc->cursor.setPos = hw_cursor_setPos;
>+      crtc->cursor.setSize = hw_cursor_setSize;
>+      crtc->cursor.setData = hw_cursor_setData;
>+      crtc->cursor.vstart = share->pvMem + crtc->cursor.offset;
>+
>+      crtc->cursor.share = share;
>+      memset(crtc->cursor.vstart, 0, crtc->cursor.size);
>+      if (!g_hwcursor) {
>+              lynxfb_ops.fb_cursor = NULL;
>+              crtc->cursor.disable(&crtc->cursor);
>+      }
>+
>+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
>+              /* hardware cursor broken under low version kernel*/
>+              lynxfb_ops.fb_cursor = soft_cursor;
>+#endif
>+
>+              /* set info->fbops, must be set before fb_find_mode */
>+              if (!share->accel_off) {
>+                      /* use 2d acceleration */
>+                      lynxfb_ops.fb_fillrect = lynxfb_ops_fillrect;
>+                      lynxfb_ops.fb_copyarea = lynxfb_ops_copyarea;
>+                      lynxfb_ops.fb_imageblit = lynxfb_ops_imageblit;
>+              }
>+              info->fbops = &lynxfb_ops;
>+
>+              if (!g_fbmode[index]) {
>+                      g_fbmode[index] = g_def_fbmode;
>+                      if (index)
>+                              g_fbmode[index] = g_fbmode[0];
>+              }
>+
>+              pdb[0] = ext_table[g_specId];
>+              cdb[0] = ext_size[g_specId];
>+
>+              for (i = 0; i < 3; i++) {
>+                      /* no NULL pointer passed to fb_find_mode @4 */
>+                      if (pdb[i] == NULL) {
>+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
>+                              pdb[i] = &modedb2[0];
>+                              cdb[i] = nmodedb2;
>+#endif
>+                      }
>+
>+                      ret = fb_find_mode(var, info, g_fbmode[index],
>+                                      pdb[i], cdb[i], NULL, 8);
>+
>+                      if (ret == 1) {
>+                              inf_msg("success! use specified mode:%s in 
>%s\n",
>+                                              g_fbmode[index],
>+                                              mdb_desc[i]);
>+                              break;
>+                      } else if (ret == 2) {
>+                              war_msg("use specified mode:%s in %s, with an 
>ignored refresh rate\n",
>+                                              g_fbmode[index],
>+                                              mdb_desc[i]);
>+                              break;
>+                      } else if (ret == 3) {
>+                              war_msg("wanna use default mode\n");
>+                              /*                      break;*/
>+                      } else if (ret == 4) {
>+                              war_msg("fall back to any valid mode\n");
>+                      } else{
>+                              war_msg("ret = %d, fb_find_mode failed, with 
>%s\n", ret, mdb_desc[i]);
>+                      }
>+              }
>+
>+              /* some member of info->var had been set by fb_find_mode */
>+
>+              inf_msg("Member of info->var is :\n\
>+                              xres=%d\n\
>+                              yres=%d\n\
>+                              xres_virtual=%d\n\
>+                              yres_virtual=%d\n\
>+                              xoffset=%d\n\
>+                              yoffset=%d\n\
>+                              bits_per_pixel=%d\n \
>+                              ...\n", var->xres, var->yres, 
>var->xres_virtual, var->yres_virtual,
>+                              var->xoffset, var->yoffset, 
>var->bits_per_pixel);
>+
>+              /* set par */
>+              par->info = info;
>+
>+              /* set info */
>+              line_length = PADDING(crtc->line_pad,
>+                              (var->xres_virtual * var->bits_per_pixel/8));
>+
>+              info->pseudo_palette = &par->pseudo_palette[0];
>+              info->screen_base = crtc->vScreen;
>+              dbg_msg("screen_base vaddr = %p\n", info->screen_base);
>+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 10)
>+              info->screen_size = line_length * var->yres_virtual;
>+#endif
>+              info->flags = FBINFO_FLAG_DEFAULT|0;
>+
>+              /* set info->fix */
>+              fix->type = FB_TYPE_PACKED_PIXELS;
>+              fix->type_aux = 0;
>+              fix->xpanstep = crtc->xpanstep;
>+              fix->ypanstep = crtc->ypanstep;
>+              fix->ywrapstep = crtc->ywrapstep;
>+              fix->accel = FB_ACCEL_NONE;
>+
>+              strlcpy(fix->id, fixId[g_specId][index], sizeof(fix->id));
>+
>+
>+              fix->smem_start = crtc->oScreen + share->vidmem_start;
>+              inf_msg("fix->smem_start = %lx\n", fix->smem_start);
>+
>+              /* according to mmap experiment from user space application,
>+               *fix->mmio_len should not larger than virtual size
>+               *(xres_virtual x yres_virtual x ByPP)
>+               *Below line maybe buggy when user mmap fb dev node and write
>+               *data into the bound over virtual size
>+               **/
>+              fix->smem_len = crtc->vidmem_size;
>+              inf_msg("fix->smem_len = %x\n", fix->smem_len);
>+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 10)
>+              info->screen_size = fix->smem_len;
>+#endif
>+
>+              fix->line_length = line_length;
>+              fix->mmio_start = share->vidreg_start;
>+              inf_msg("fix->mmio_start = %lx\n", fix->mmio_start);
>+              fix->mmio_len = share->vidreg_size;
>+              inf_msg("fix->mmio_len = %x\n", fix->mmio_len);
>+              switch (var->bits_per_pixel) {
>+              case 8:
>+                              fix->visual = FB_VISUAL_PSEUDOCOLOR;
>+                              break;
>+              case 16:
>+              case 32:
>+                              fix->visual = FB_VISUAL_TRUECOLOR;
>+                              break;
>+              }
>+
>+              /* set var */
>+              var->activate = FB_ACTIVATE_NOW;
>+              var->accel_flags = 0;
>+              var->vmode = FB_VMODE_NONINTERLACED;
>+
>+              dbg_msg("#1 show info->cmap : \nstart=%d, len=%d, red=%p, 
>green=%p, blue=%p, transp=%p\n",
>+                              info->cmap.start, info->cmap.len,
>+                              info->cmap.red, info->cmap.green, 
>info->cmap.blue,
>+                              info->cmap.transp);
>+
>+              ret = fb_alloc_cmap(&info->cmap, 256, 0);
>+              if (ret < 0) {
>+                      err_msg("Could not allcate memory for cmap.\n");
>+                      goto exit;
>+              }
>+
>+              dbg_msg("#2 show info->cmap : \nstart=%d, len=%d, red=%p, 
>green=%p, blue=%p, transp=%p\n",
>+                              info->cmap.start, info->cmap.len,
>+                              info->cmap.red, info->cmap.green, 
>info->cmap.blue,
>+                              info->cmap.transp);
>+
>+exit:
>+              lynxfb_ops_check_var(var, info);
>+              /*    lynxfb_ops_set_par(info);*/
>+              LEAVE(ret);
>+      }
>+
>+      static int __devinit lynxfb_pci_probe(struct pci_dev *pdev,
>+                      const struct pci_device_id *ent)
>+      {
>+              struct fb_info *info[] = {NULL, NULL};
>+              struct lynx_share *share = NULL;
>+
>+              void *spec_share = NULL;
>+              size_t spec_offset = 0;
>+              int fbidx;
>+              ENTER();
>+
>+              /* enable device */
>+              if (pci_enable_device(pdev)) {
>+                      err_msg("can not enable device.\n");
>+                      goto err_enable;
>+              }
>+
>+              switch (ent->device) {
>+              case PCI_DEVID_LYNX_EXP:
>+              case PCI_DEVID_LYNX_SE:
>+                      g_specId = SPC_SM750;
>+                              /* though offset of share in sm750_share is 0,
>+                               *we use this marcro as the same */
>+                      spec_offset = offsetof(struct sm750_share, share);
>+                      break;
>+              default:
>+                      break;
>+              }
>+
>+              dbg_msg("spec_offset = %d\n", spec_offset);
>+              spec_share = kzalloc(spec_size[g_specId], GFP_KERNEL);
>+              if (!spec_share) {
>+                      err_msg("Could not allocate memory for share.\n");
>+                      goto err_share;
>+              }
>+
>+              /* setting share structure */
>+              share = (struct lynx_share *)(spec_share + spec_offset);
>+              share->fbinfo[0] = share->fbinfo[1] = NULL;
>+              share->devid = pdev->device;
>+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
>+              u32 temp;
>+              pci_read_config_dword(pdev, PCI_CLASS_REVISION, &temp);
>+              share->revid = temp&0xFF;
>+#else
>+              share->revid = pdev->revision;
>+#endif
>+
>+              inf_msg("share->revid = %02x\n", share->revid);
>+              share->pdev = pdev;
>+#ifdef CONFIG_MTRR
>+              share->mtrr_off = g_nomtrr;
>+              share->mtrr.vram = 0;
>+              share->mtrr.vram_added = 0;
>+#endif
>+              share->accel_off = g_noaccel;
>+              share->dual = g_dualview;
>+              spin_lock_init(&share->slock);
>+
>+              if (!share->accel_off) {
>+                      /* hook deInit and 2d routines, notes that below hw_xxx
>+                       *routine can work on most of lynx chips
>+                       *if some chip need specific function, please hook it 
>in smXXX_set_drv
>+                       *routine */
>+                      share->accel.de_init = hw_de_init;
>+                      share->accel.de_fillrect = hw_fillrect;
>+                      share->accel.de_copyarea = hw_copyarea;
>+                      share->accel.de_imageblit = hw_imageblit;
>+                      inf_msg("enable 2d acceleration\n");
>+              } else{
>+                      inf_msg("disable 2d acceleration\n");
>+              }
>+
>+              /* call chip specific setup routine  */
>+              (*setup_rout[g_specId])(share, g_settings);
>+
>+              /* call chip specific mmap routine */
>+              if ((*map_rout[g_specId])(share, pdev)) {
>+                      err_msg("Memory map failed\n");
>+                      goto err_map;
>+              }
>+
>+#ifdef CONFIG_MTRR
>+              if (!share->mtrr_off) {
>+                      inf_msg("enable mtrr\n");
>+                      share->mtrr.vram = mtrr_add(share->vidmem_start,
>+                                      share->vidmem_size,
>+                                      MTRR_TYPE_WRCOMB, 1);
>+
>+                      if (share->mtrr.vram < 0) {
>+                              /* don't block driver with the failure of MTRR 
>*/
>+                              err_msg("Unable to setup MTRR.\n");
>+                      } else{
>+                              share->mtrr.vram_added = 1;
>+                              inf_msg("MTRR added succesfully\n");
>+                      }
>+              }
>+#endif
>+
>+              memset(share->pvMem, 0, share->vidmem_size);
>+
>+              inf_msg("sm%3x mmio address = %p\n", share->devid, 
>share->pvReg);
>+
>+              pci_set_drvdata(pdev, share);
>+
>+              /* call chipInit routine */
>+              (*inithw_rout[g_specId])(share, pdev);
>+
>+              /* detect 502 need no disp driver
>+               *beware that other chips except 502 should not touch 
>g_502nodisp
>+               *(remain g_502nodisp always 0)
>+               *so regularily, below if line will not affect other chips' 
>behaviour
>+               **/
>+      /*      if (!g_no502disp) {*/
>+                      /* allocate frame buffer info structor according to 
>g_dualview */
>+                      fbidx = 0;
>+ALLOC_FB:
>+                      info[fbidx] = framebuffer_alloc(sizeof(struct 
>lynxfb_par), &pdev->dev);
>+                      if (!info[fbidx]) {
>+                              err_msg("Could not allocate framebuffer 
>#%d.\n", fbidx);
>+                              if (fbidx == 0)
>+                                      goto err_info0_alloc;
>+                              else
>+                                      goto err_info1_alloc;
>+                      } else{
>+                              struct lynxfb_par *par;
>+                              inf_msg("framebuffer #%d alloc okay\n", fbidx);
>+                              share->fbinfo[fbidx] = info[fbidx];
>+                              par = info[fbidx]->par;
>+                              par->share = share;
>+
>+                              /* set fb_info structure */
>+                              if (lynxfb_set_fbinfo(info[fbidx], fbidx)) {
>+                                      err_msg("Failed to initial fb_info 
>#%d.\n", fbidx);
>+                                      if (fbidx == 0)
>+                                              goto err_info0_set;
>+                                      else
>+                                              goto err_info1_set;
>+                              }
>+
>+                              /* register frame buffer*/
>+                              inf_msg("Ready to register framebuffer #%d.\n", 
>fbidx);
>+                              int errno = register_framebuffer(info[fbidx]);
>+                              if (errno < 0) {
>+                                      err_msg("Failed to register fb_info 
>#%d. err %d\n", fbidx, errno);
>+                                      if (fbidx == 0)
>+                                              goto err_register0;
>+                                      else
>+                                              goto err_register1;
>+                              }
>+                              inf_msg("Accomplished register framebuffer 
>#%d.\n", fbidx);
>+                      }
>+
>+                      /* no dual view by far */
>+                      fbidx++;
>+                      if (share->dual && fbidx < 2)
>+                              goto ALLOC_FB;
>+/*            }*/
>+
>+              LEAVE(0);
>+
>+err_register1:
>+err_info1_set:
>+              framebuffer_release(info[1]);
>+err_info1_alloc:
>+              unregister_framebuffer(info[0]);
>+err_register0:
>+err_info0_set:
>+              framebuffer_release(info[0]);
>+err_info0_alloc:
>+err_map:
>+              kfree(spec_share);
>+err_share:
>+err_enable:
>+              LEAVE(-ENODEV);
>+      }
>+
>+static void __devexit lynxfb_pci_remove(struct pci_dev *pdev)
>+{
>+      struct fb_info *info;
>+      struct lynx_share *share;
>+      void *spec_share;
>+      struct lynxfb_par *par;
>+      int cnt;
>+      ENTER();
>+
>+      cnt = 2;
>+      share = pci_get_drvdata(pdev);
>+
>+      while (cnt-- > 0) {
>+              info = share->fbinfo[cnt];
>+              if (!info)
>+                      continue;
>+              par = info->par;
>+
>+              unregister_framebuffer(info);
>+              /* clean crtc & output allocations*/
>+              par->crtc.clear(&par->crtc);
>+              par->output.clear(&par->output);
>+              /* release frame buffer*/
>+              framebuffer_release(info);
>+      }
>+#ifdef CONFIG_MTRR
>+      if (share->mtrr.vram_added)
>+              mtrr_del(share->mtrr.vram, share->vidmem_start, 
>share->vidmem_size);
>+#endif
>+      /*      pci_release_regions(pdev);*/
>+
>+      iounmap(share->pvReg);
>+      iounmap(share->pvMem);
>+
>+      switch (share->devid) {
>+      case PCI_DEVID_LYNX_EXP:
>+      case PCI_DEVID_LYNX_SE:
>+                      spec_share = container_of(share, struct sm750_share, 
>share);
>+                      break;
>+      default:
>+                      spec_share = share;
>+      }
>+      kfree(g_settings);
>+      kfree(spec_share);
>+      pci_set_drvdata(pdev, NULL);
>+      LEAVE();
>+}
>+
>+
>+/*    chip specific g_option configuration routine */
>+static void sm750fb_setup(struct lynx_share *share, char *src)
>+{
>+      struct sm750_share *spec_share;
>+      char *opt;
>+#ifdef CAP_EXPENSION
>+      char *exp_res;
>+#endif
>+      int swap;
>+      ENTER();
>+
>+      spec_share = container_of(share, struct sm750_share, share);
>+#ifdef CAP_EXPENSIION
>+      exp_res = NULL;
>+#endif
>+      swap = 0;
>+
>+      spec_share->state.initParm.chip_clk = 0;
>+      spec_share->state.initParm.mem_clk = 0;
>+      spec_share->state.initParm.master_clk = 0;
>+      spec_share->state.initParm.powerMode = 0;
>+      spec_share->state.initParm.setAllEngOff = 0;
>+      spec_share->state.initParm.resetMemory = 1;
>+
>+      /*defaultly turn g_hwcursor on for both view */
>+      g_hwcursor = 3;
>+
>+      if (!src || !*src) {
>+              war_msg("no specific g_option.\n");
>+              goto NO_PARAM;
>+      }
>+
>+      while ((opt = strsep(&src, ":")) != NULL && *opt != NULL) {
>+              err_msg("opt=%s\n", opt);
>+              err_msg("src=%s\n", src);
>+
>+              if (!strncmp(opt, "swap", strlen("swap")))
>+                      swap = 1;
>+              else if (!strncmp(opt, "nocrt", strlen("nocrt")))
>+                      spec_share->state.nocrt = 1;
>+              else if (!strncmp(opt, "36bit", strlen("36bit")))
>+                      spec_share->state.pnltype = sm750_doubleTFT;
>+              else if (!strncmp(opt, "18bit", strlen("18bit")))
>+                      spec_share->state.pnltype = sm750_dualTFT;
>+              else if (!strncmp(opt, "24bit", strlen("24bit")))
>+                      spec_share->state.pnltype = sm750_24TFT;
>+#ifdef CAP_EXPANSION
>+              else if (!strncmp(opt, "exp:", strlen("exp:")))
>+                      exp_res = opt + strlen("exp:");
>+#endif
>+              else if (!strncmp(opt, "nohwc0", strlen("nohwc0")))
>+                      g_hwcursor &= ~0x1;
>+              else if (!strncmp(opt, "nohwc1", strlen("nohwc1")))
>+                      g_hwcursor &= ~0x2;
>+              else if (!strncmp(opt, "nohwc", strlen("nohwc")))
>+                      g_hwcursor = 0;
>+              else{
>+                      if (!g_fbmode[0]) {
>+                              g_fbmode[0] = opt;
>+                              inf_msg("find fbmode0 : %s\n", g_fbmode[0]);
>+                      } else if (!g_fbmode[1]) {
>+                              g_fbmode[1] = opt;
>+                              inf_msg("find fbmode1 : %s\n", g_fbmode[1]);
>+                      } else{
>+                              war_msg("How many view you wann set?\n");
>+                      }
>+              }
>+      }
>+#ifdef CAP_EXPANSION
>+      if (getExpRes(exp_res, &spec_share->state.xLCD, 
>&spec_share->state.yLCD)) {
>+              /* seems exp_res is not valid*/
>+              spec_share->state.xLCD = spec_share->state.yLCD = 0;
>+      }
>+#endif
>+
>+NO_PARAM:
>+      if (share->revid != SM750LE_REVISION_ID) {
>+              if (share->dual) {
>+                      if (swap)
>+                              spec_share->state.dataflow = sm750_dual_swap;
>+                      else
>+                              spec_share->state.dataflow = sm750_dual_normal;
>+              } else{
>+                      if (swap)
>+                              spec_share->state.dataflow = sm750_simul_sec;
>+                      else
>+                              spec_share->state.dataflow = sm750_simul_pri;
>+              }
>+      } else{
>+              /* SM750LE only have one crt channel */
>+              spec_share->state.dataflow = sm750_simul_sec;
>+              /* sm750le do not have complex attributes*/
>+              spec_share->state.nocrt = 0;
>+      }
>+
>+      LEAVE();
>+}
>+
>+
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+static int __init lynxfb_setup(char *options)
>+#else
>+int __init lynxfb_setup(char *options)
>+#endif
>+{
>+      int len;
>+      char *opt, *tmp;
>+      ENTER();
>+
>+      if (!options || !*options) {
>+              war_msg("no options.\n");
>+              LEAVE(0);
>+      }
>+
>+      inf_msg("options:%s\n", options);
>+
>+      len = strlen(options) + 1;
>+      g_settings = kmalloc(len, GFP_KERNEL);
>+      if (!g_settings)
>+              LEAVE(-ENOMEM);
>+
>+      memset(g_settings, 0, len);
>+      tmp = g_settings;
>+
>+      /*      Notes:
>+              char *strsep(char **s, const char *ct);
>+              @s: the string to be searched
>+              @ct :the characters to search for
>+
>+              strsep() updates @options to pointer after the first found token
>+              it also returns the pointer ahead the token.
>+              */
>+      while ((opt = strsep(&options, ":")) != NULL) {
>+              /* options that mean for any lynx chips are configured here */
>+              if (!strncmp(opt, "noaccel", strlen("noaccel")))
>+                      g_noaccel = 1;
>+#ifdef CONFIG_MTRR
>+              else if (!strncmp(opt, "nomtrr", strlen("nomtrr")))
>+                      g_nomtrr = 1;
>+#endif
>+              else if (!strncmp(opt, "dual", strlen("dual")))
>+                      g_dualview = 1;
>+              else{
>+                      strcat(tmp, opt);
>+                      tmp += strlen(opt);
>+                      if (options != NULL)
>+                              *tmp++ = ':';
>+                      else
>+                              *tmp++ = 0;
>+              }
>+      }
>+
>+      /* misc g_settings are transport to chip specific routines */
>+      inf_msg("parameter left for chip specific analysis:%s\n", g_settings);
>+      LEAVE(0);
>+}
>+
>+
>+static void claim(void)
>+{
>+      inf_msg("+-------------SMI Driver Information------------+");
>+      inf_msg("Release type : " RELEASE_TYPE "\n");
>+      inf_msg("Driver version: v" _version_ "\n");
>+      inf_msg("Support products:\n"
>+                      SUPPORT_CHIP);
>+      inf_msg("Support OS:\n"
>+                      SUPPORT_OS);
>+      inf_msg("Support ARCH: " SUPPORT_ARCH "\n");
>+      inf_msg("+-----------------------------------------------+");
>+}
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+static int __init lynxfb_init()
>+{
>+      char *option ;
>+      int ret;
>+      smi_indent = 0;
>+      ENTER();
>+      claim();
>+#ifdef MODULE
>+      option = g_option;
>+#else
>+      if (fb_get_options("lynxfb", &option))
>+              LEAVE(-ENODEV);
>+#endif
>+
>+      lynxfb_setup(option);
>+      ret = pci_register_driver(&lynxfb_driver);
>+      LEAVE(ret);
>+}
>+#else /* kernel version >= 2.6.10*/
>+int __init lynxfb_init(void)
>+{
>+      char *option;
>+      int ret;
>+      smi_indent = 0;
>+      ENTER();
>+      claim();
>+#ifdef MODULE
>+      option = g_option;
>+      lynxfb_setup(option);
>+#else
>+      /* do nothing */
>+#endif
>+      ret = pci_register_driver(&lynxfb_driver);
>+      LEAVE(ret);
>+}
>+#endif
>+      module_init(lynxfb_init);
>+
>+#ifdef MODULE
>+static void __exit lynxfb_exit()
>+{
>+      ENTER();
>+      inf_msg(_moduleName_ " exit\n");
>+      pci_unregister_driver(&lynxfb_driver);
>+      LEAVE();
>+}
>+      module_exit(lynxfb_exit);
>+#endif
>+
>+#ifdef MODULE
>+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 10)
>+      module_param(g_option, charp, S_IRUGO);
>+#else
>+      /* be ware that PARM and param */
>+      MODULE_PARM(g_option, "s");
>+#endif
>+
>+      MODULE_PARM_DESC(g_option,
>+                      "\n\t\tCommon options:\n"
>+                      "\t\tnoaccel:disable 2d capabilities\n"
>+                      "\t\tnomtrr:disable MTRR attribute for video memory\n"
>+                      "\t\tdualview:dual frame buffer feature enabled\n"
>+                      "\t\tnohwc:disable hardware cursor\n"
>+                      "\t\tUsual example:\n"
>+                      "\t\tinsmod ./lynxfb.ko g_option=\"noaccel, nohwc, 
>1280x1024-8 at 60\"\n"
>+                      "\t\tFor more detail chip specific options, please 
>refer to \"Lynxfb User Mnual\" or readme\n"
>+                      );
>+#endif
>+
>+      MODULE_AUTHOR("monk liu<monk.liu at siliconmotion.com>");
>+      MODULE_DESCRIPTION("Frame buffer driver for SMI(R) " SUPPORT_CHIP " 
>chipsets");
>+      MODULE_LICENSE("Dual BSD/GPL");
>+      MODULE_DEVICE_TABLE(pci, smi_pci_table);
>diff --git a/drivers/video/lynxfb/lynx_drv.h b/drivers/video/lynxfb/lynx_drv.h
>new file mode 100644
>index 0000000..7cf5f1b
>--- /dev/null
>+++ b/drivers/video/lynxfb/lynx_drv.h
>@@ -0,0 +1,271 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef LYNXDRV_H_
>+#define LYNXDRV_H_
>+
>+
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
>+#else
>+typedef unsigned long resource_size_t;
>+#endif
>+
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+#else
>+#define SEPARATOR 1
>+typedef int pm_message_t;
>+#endif
>+
>+/* please use revision id to distinguish sm750le and sm750*/
>+#define SPC_SM750     0
>+#define SPC_SM712     1
>+#define SPC_SM502   2
>+/*#define SPC_SM750LE 8*/
>+
>+#define PCI_VENDOR_ID_SMI     0x126f
>+#define PCI_DEVID_LYNX_EXP    0x0750
>+#define PCI_DEVID_LYNX_SE     0x0718
>+#define PCI_DEVID_LYNX_EM     0x0712
>+#define PCI_DEVID_LYNX_3DM    0x0720
>+#define PCI_DEVID_VOYAGER     0x0501
>+
>+/*#define SUPPORT_ARCH "x86, x86_64"*/
>+/*#define SUPPORT_CHIP "lynx Express(750)/lynx 750LE/Lynx SE(718)/Lynx 
>EM(712)/lynx 3DM(720/722) voyager(502/107)"*/
>+
>+/*#define _version_   "4.0.1"*/
>+#define _moduleName_ "lynxfb"
>+#define PFX _moduleName_ ": "
>+#define err_msg(fmt, args...) printk(KERN_ERR PFX fmt, ## args)
>+#define war_msg(fmt, args...) printk(KERN_WARNING PFX fmt, ## args)
>+#define inf_msg(fmt, args...) printk(KERN_INFO PFX fmt, ## args)
>+/* below code also works ok, but there must be no KERN_INFO prefix */
>+/*#define inf_msg(...) printk(__VA_ARGS__)*/
>+
>+#if (DEBUG == 1)
>+/* debug level == 1 */
>+#define dbg_msg(fmt, args...) printk(KERN_DEBUG PFX fmt, ## args)
>+#define ENTER()       printk(KERN_DEBUG PFX "%*c %s\n", smi_indent++, '>', 
>__func__)
>+#define LEAVE(...)    \
>+      do {                            \
>+      printk(KERN_DEBUG PFX "%*c %s\n", --smi_indent, '<', __func__); \
>+      return __VA_ARGS__; \
>+      } while (0)
>+
>+#elif (DEBUG == 2)
>+/* debug level == 2*/
>+#define dbg_msg(fmt, args...) printk(KERN_ERR PFX fmt, ## args)
>+#define ENTER()       printk(KERN_ERR PFX "%*c %s\n", smi_indent++, '>', 
>__func__)
>+
>+#define LEAVE(...)    \
>+      do {                            \
>+      printk(KERN_ERR PFX "%*c %s\n", --smi_indent, '<', __func__); \
>+      return __VA_ARGS__; \
>+      } while (0)
>+
>+#ifdef inf_msg
>+#undef inf_msg
>+#endif
>+
>+#define inf_msg(fmt, args...) printk(KERN_ERR PFX fmt, ## args)
>+#else
>+/* no debug */
>+#define dbg_msg(...)
>+#define ENTER()
>+#define LEAVE(...)    \
>+      do {    \
>+      return __VA_ARGS__; \
>+      } while (0)     \
>+
>+#endif
>+
>+#define MB(x) ((x)<<20)
>+#define MHZ(x) ((x) * 1000000)
>+/* align should be 2, 4, 8, 16 */
>+#define PADDING(align, data) (((data)+(align)-1)&(~((align)-1)))
>+extern int smi_indent;
>+
>+
>+struct lynx_accel{
>+      /* base virtual address of DPR registers */
>+      volatile unsigned char __iomem *dprBase;
>+      /* base virtual address of de data port */
>+      volatile unsigned char __iomem *dpPortBase;
>+
>+      /* function fointers */
>+      int (*de_init)(struct lynx_accel *);
>+
>+      int (*de_wait)(void);/* see if hardware ready to work */
>+
>+      int (*de_fillrect)(struct lynx_accel *, u32, u32, u32,
>+                                                      u32, u32, u32, u32, 
>u32, u32);
>+
>+      int (*de_copyarea)(struct lynx_accel *, u32, u32, u32, u32,
>+                                              u32, u32, u32, u32,
>+                                              u32, u32, u32, u32);
>+
>+      int (*de_imageblit)(struct lynx_accel *, const char *, u32, u32, u32,
>+                                              u32, u32, u32, u32, u32, u32, 
>u32, u32, u32);
>+
>+};
>+
>+/*    lynx_share stands for a presentation of two frame buffer
>+      that use one smi adaptor , it is similar to a basic class of C++
>+*/
>+struct lynx_share{
>+      /* common members */
>+      u16 devid;
>+      u8 revid;
>+      struct pci_dev *pdev;
>+      struct fb_info *fbinfo[2];
>+      struct lynx_accel accel;
>+      int accel_off;
>+      int dual;
>+#ifdef CONFIG_MTRR
>+              int mtrr_off;
>+              struct{
>+                      int vram;
>+                      int vram_added;
>+              } mtrr;
>+#endif
>+      /* all smi graphic adaptor got below attributes */
>+      resource_size_t vidmem_start;
>+      resource_size_t vidreg_start;
>+      resource_size_t vidmem_size;
>+      resource_size_t vidreg_size;
>+      volatile unsigned char __iomem *pvReg;
>+      unsigned char __iomem *pvMem;
>+      /* locks*/
>+      spinlock_t slock;
>+      /* function pointers */
>+      void (*suspend)(struct lynx_share *);
>+      void (*resume)(struct lynx_share *);
>+};
>+
>+struct lynx_cursor{
>+      /* cursor width , height and size */
>+      int w;
>+      int h;
>+      int size;
>+      /* hardware limitation */
>+      int maxW;
>+      int maxH;
>+      /* base virtual address and offset  of cursor image */
>+      char __iomem *vstart;
>+      int offset;
>+      /* mmio addr of hw cursor */
>+      volatile char __iomem *mmio;
>+      /* the lynx_share of this adaptor */
>+      struct lynx_share *share;
>+      /* proc_routines */
>+      void (*enable)(struct lynx_cursor *);
>+      void (*disable)(struct lynx_cursor *);
>+      void (*setSize)(struct lynx_cursor *, int, int);
>+      void (*setPos)(struct lynx_cursor *, int, int);
>+      void (*setColor)(struct lynx_cursor *, u32, u32);
>+      void (*setData)(struct lynx_cursor *, u16, const u8 *, const u8 *);
>+};
>+
>+struct lynxfb_crtc{
>+      unsigned char __iomem *vCursor;/*virtual address of cursor*/
>+      unsigned char __iomem *vScreen;/*virtual address of on_screen*/
>+      int oCursor;/*cursor address offset in vidmem*/
>+      int oScreen;/*onscreen address offset in vidmem*/
>+      int channel;/* which channel this crtc stands for*/
>+      resource_size_t vidmem_size;/* this view's video memory max size */
>+
>+      /* below attributes belong to info->fix, their value depends on 
>specific adaptor*/
>+      u16 line_pad;/* padding information:0, 1, 2, 4, 8, 16, ... */
>+      u16 xpanstep;
>+      u16 ypanstep;
>+      u16 ywrapstep;
>+
>+      void *priv;
>+
>+      int(*proc_setMode)(struct lynxfb_crtc*,
>+                                              struct fb_var_screeninfo*,
>+                                              struct fb_fix_screeninfo*);
>+
>+      int(*proc_checkMode)(struct lynxfb_crtc *, struct fb_var_screeninfo *);
>+      int(*proc_setColReg)(struct lynxfb_crtc *, ushort, ushort, ushort, 
>ushort);
>+      void (*clear)(struct lynxfb_crtc *);
>+      /* pan display */
>+      int(*proc_panDisplay)(struct lynxfb_crtc *, struct fb_var_screeninfo *,
>+              struct fb_info *);
>+      /* cursor information */
>+      struct lynx_cursor cursor;
>+};
>+
>+struct lynxfb_output{
>+      int dpms;
>+      int paths;
>+      /*      which paths(s) this output stands for, for sm750:
>+              paths=1:means output for panel paths
>+              paths=2:means output for crt paths
>+              paths=3:means output for both panel and crt paths
>+      */
>+
>+      int *channel;
>+      /*      which channel these outputs linked with, for sm750:
>+              *channel=0 means primary channel
>+              *channel=1 means secondary channel
>+              output->channel ==> &crtc->channel
>+      */
>+      void *priv;
>+
>+      int(*proc_setMode)(struct lynxfb_output *,
>+                                              struct fb_var_screeninfo *,
>+                                              struct fb_fix_screeninfo *);
>+
>+      int(*proc_checkMode)(struct lynxfb_output *, struct fb_var_screeninfo 
>*);
>+      int(*proc_setBLANK)(struct lynxfb_output *, int);
>+      void  (*clear)(struct lynxfb_output *);
>+};
>+
>+struct lynxfb_par{
>+      /* either 0 or 1 for dual head adaptor, 0 is the older one registered */
>+      int index;
>+      unsigned int pseudo_palette[256];
>+      struct lynxfb_crtc crtc;
>+      struct lynxfb_output output;
>+      struct fb_info *info;
>+      struct lynx_share *share;
>+};
>+
>+#ifndef offsetof
>+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
>+#endif
>+
>+
>+#define PS_TO_HZ(ps)  \
>+                      ({      \
>+                      unsigned long long hz = 1000*1000*1000*1000ULL; \
>+                      do_div(hz, ps); \
>+                      (unsigned long)hz; `})
>+
>+
>+static inline unsigned long ps_to_hz(unsigned int psvalue)
>+{
>+      unsigned long long numerator = 1000*1000*1000*1000ULL;
>+      /* 10^12 / picosecond period gives frequency in Hz */
>+      do_div(numerator, psvalue);
>+      return (unsigned long)numerator;
>+}
>+
>+
>+
>+#endif
>diff --git a/drivers/video/lynxfb/lynx_help.h 
>b/drivers/video/lynxfb/lynx_help.h
>new file mode 100644
>index 0000000..2d80365
>--- /dev/null
>+++ b/drivers/video/lynxfb/lynx_help.h
>@@ -0,0 +1,115 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef LYNX_HELP_H__
>+#define LYNX_HELP_H__
>+ /*                                FIELD MACROS                               
>*/
>+
>+#define _LSB(f)             (0 ? f)
>+#define _MSB(f)             (1 ? f)
>+#define _COUNT(f)           (_MSB(f) - _LSB(f) + 1)
>+
>+#define RAW_MASK(f)         (0xFFFFFFFF >> (32 - _COUNT(f)))
>+#define GET_MASK(f)         (RAW_MASK(f) << _LSB(f))
>+#define GET_FIELD(d, f)      (((d) >> _LSB(f)) & RAW_MASK(f))
>+#define TEST_FIELD(d, f, v)   (GET_FIELD(d, f) == f ## _ ## v)
>+#define SET_FIELD(d, f, v)    (((d) & ~GET_MASK(f)) | \
>+              (((f ## _ ## v) & RAW_MASK(f)) << _LSB(f)))
>+#define SET_FIELDV(d, f, v)   (((d) & ~GET_MASK(f)) | \
>+              (((v) & RAW_MASK(f)) << _LSB(f)))
>+
>+
>+/* 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)              (((1 << _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)) \
>+      )
>+
>+#define RGB16(r, g, b) \
>+      ( \
>+        (unsigned short) ((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | (((b) & 
>0xF8) >> 3)) \
>+      )
>+
>+static inline unsigned int absDiff(unsigned int a, unsigned int b)
>+{
>+      if (a < b)
>+              return b-a;
>+      else
>+              return a-b;
>+}
>+
>+/* n / d + 1 / 2 = (2n + d) / 2d */
>+#define roundedDiv(num, denom)        ((2 * (num) + (denom)) / (2 * (denom)))
>+#define MB(x) ((x)<<20)
>+#define KB(x) ((x)<<10)
>+#define MHz(x) ((x) * 1000000)
>+
>+
>+
>+
>+#endif
>diff --git a/drivers/video/lynxfb/lynx_hw750.c 
>b/drivers/video/lynxfb/lynx_hw750.c
>new file mode 100644
>index 0000000..019eb68
>--- /dev/null
>+++ b/drivers/video/lynxfb/lynx_hw750.c
>@@ -0,0 +1,633 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#include<linux/version.h>
>+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
>+#include<linux/config.h>
>+#endif
>+#include <linux/version.h>
>+#include<linux/module.h>
>+#include<linux/kernel.h>
>+#include<linux/errno.h>
>+#include<linux/string.h>
>+#include<linux/mm.h>
>+#include<linux/slab.h>
>+#include<linux/delay.h>
>+#include<linux/fb.h>
>+#include<linux/ioport.h>
>+#include<linux/init.h>
>+#include<linux/pci.h>
>+#include<linux/vmalloc.h>
>+#include<linux/pagemap.h>
>+#include <linux/console.h>
>+#ifdef CONFIG_MTRR
>+#include <asm/mtrr.h>
>+#endif
>+
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+/* no below two header files in 2.6.9 */
>+#include<linux/platform_device.h>
>+#include<linux/screen_info.h>
>+#else
>+/* nothing by far */
>+#endif
>+
>+#include "lynx_drv.h"
>+#include "lynx_hw750.h"
>+#include "ddk750.h"
>+#include "lynx_accel.h"
>+
>+int hw_sm750_map(struct lynx_share *share, struct pci_dev *pdev)
>+{
>+      int ret;
>+      struct sm750_share *spec_share;
>+      ENTER();
>+
>+      spec_share = container_of(share, struct sm750_share, share);
>+      ret = 0;
>+
>+      share->vidreg_start  = pci_resource_start(pdev, 1);
>+      share->vidreg_size = MB(2);
>+
>+      /* reserve the vidreg space of smi adaptor
>+       * if you do this, u need to add release region code
>+       * in lynxfb_remove, or memory will not be mapped again
>+       * successfully
>+       * */
>+
>+
>+      /* now map mmio and vidmem*/
>+      share->pvReg = ioremap_nocache(share->vidreg_start, share->vidreg_size);
>+      if (!share->pvReg) {
>+              err_msg("mmio failed\n");
>+              ret = -EFAULT;
>+              goto exit;
>+      }
>+
>+      share->accel.dprBase = share->pvReg + DE_BASE_ADDR_TYPE1;
>+      share->accel.dpPortBase = share->pvReg + DE_PORT_ADDR_TYPE1;
>+
>+      ddk750_set_mmio(share->pvReg, share->devid, share->revid);
>+
>+      share->vidmem_start = pci_resource_start(pdev, 0);
>+      /* don't use pdev_resource[x].end - resource[x].start to
>+       * calculate the resource size, its only the maximum available
>+       * size but not the actual size, use
>+       * @hw_sm750_getVMSize function can be safe.
>+       * */
>+      share->vidmem_size = hw_sm750_getVMSize(share);
>+      inf_msg("video memory size = %d mb\n", share->vidmem_size >> 20);
>+
>+      /* reserve the vidmem space of smi adaptor */
>+
>+      share->pvMem = ioremap(share->vidmem_start,
>+                      share->vidmem_size);
>+
>+      if (!share->pvMem) {
>+              err_msg("Map video memory failed\n");
>+              ret = -EFAULT;
>+              goto exit;
>+      }
>+
>+      inf_msg("video memory vaddr = %p\n", share->pvMem);
>+exit:
>+      LEAVE(ret);
>+}
>+
>+
>+
>+int hw_sm750_inithw(struct lynx_share *share, struct pci_dev *pdev)
>+{
>+      struct sm750_share *spec_share;
>+      struct init_status *parm;
>+      ENTER();
>+      spec_share = container_of(share, struct sm750_share, share);
>+      parm = &spec_share->state.initParm;
>+      if (parm->chip_clk == 0)
>+              parm->chip_clk = (getChipType() == SM750LE) ?
>+                      DEFAULT_SM750LE_CHIP_CLOCK :
>+                      DEFAULT_SM750_CHIP_CLOCK;
>+
>+      if (parm->mem_clk == 0)
>+              parm->mem_clk = parm->chip_clk;
>+      if (parm->master_clk == 0)
>+              parm->master_clk = parm->chip_clk/3;
>+
>+      ddk750_initHw((initchip_param_t *)&spec_share->state.initParm);
>+      /* for sm718, open pci burst */
>+      if (share->devid == 0x718) {
>+              POKE32(SYSTEM_CTRL,
>+                      PEEK32(SYSTEM_CTRL)|(1 << SYSTEM_CTRL_PCI_BURST_LSB));
>+      }
>+
>+      /* sm750 use sii164, it can be setup with default value
>+       * by on power, so initDVIDisp can be skipped */
>+
>+      if (getChipType() != SM750LE) {
>+              /* does user need CRT ?*/
>+              if (spec_share->state.nocrt) {
>+                      POKE32(MISC_CTRL,
>+                                      PEEK32(MISC_CTRL)|
>+                                      (1 << MISC_CTRL_DAC_POWER_LSB));
>+                      /* shut off dpms */
>+                      POKE32(SYSTEM_CTRL,
>+                                      PEEK32(SYSTEM_CTRL)|
>+                                      (3 << SYSTEM_CTRL_DPMS_LSB));
>+              } else{
>+                      POKE32(MISC_CTRL,
>+                                      PEEK32(MISC_CTRL)&
>+                                      (~(1 << MISC_CTRL_DAC_POWER_LSB)));
>+                      /* turn on dpms */
>+                      POKE32(SYSTEM_CTRL,
>+                                      PEEK32(SYSTEM_CTRL)&
>+                                      (~(3 << SYSTEM_CTRL_DPMS_LSB)));
>+              }
>+
>+              switch (spec_share->state.pnltype) {
>+              case sm750_doubleTFT:
>+              case sm750_24TFT:
>+              case sm750_dualTFT:
>+                              POKE32(PANEL_DISPLAY_CTRL,
>+                                              PEEK32(PANEL_DISPLAY_CTRL)&
>+                                              (~(3 << 
>PANEL_DISPLAY_CTRL_TFT_DISP_LSB)));
>+                              POKE32(PANEL_DISPLAY_CTRL,
>+                                              PEEK32(PANEL_DISPLAY_CTRL)|
>+                                              (spec_share->state.pnltype << 
>PANEL_DISPLAY_CTRL_TFT_DISP_LSB));                                        
>break;
>+              }
>+      } else{
>+              /* for 750LE , no DVI chip initilization makes Monitor no 
>signal */
>+              /* Set up GPIO for software I2C to program DVI chip in the
>+                 Xilinx SP605 board, in order to have video signal.
>+                 */
>+              swI2CInit(0, 1);
>+
>+
>+              /* Customer may NOT use CH7301 DVI chip, which has to be
>+                 initialized differently.
>+                 */
>+              if (swI2CReadReg(0xec, 0x4a) == 0x95) {
>+                      /* The following register values for CH7301 are from
>+                         Chrontel app note and our experiment.
>+                         */
>+                      inf_msg("yes, CH7301 DVI chip found\n");
>+                      swI2CWriteReg(0xec, 0x1d, 0x16);
>+                      swI2CWriteReg(0xec, 0x21, 0x9);
>+                      swI2CWriteReg(0xec, 0x49, 0xC0);
>+                      inf_msg("okay, CH7301 DVI chip setup done\n");
>+              }
>+      }
>+
>+      /* init 2d engine */
>+      if (!share->accel_off) {
>+              hw_sm750_initAccel(share);
>+      }
>+
>+      LEAVE(0);
>+}
>+
>+
>+resource_size_t hw_sm750_getVMSize(struct lynx_share *share)
>+{
>+      resource_size_t ret;
>+      ENTER();
>+      ret = ddk750_getVMSize();
>+      LEAVE(ret);
>+}
>+
>+
>+
>+int hw_sm750_output_checkMode(struct lynxfb_output *output, struct 
>fb_var_screeninfo *var)
>+{
>+      ENTER();
>+      LEAVE(0);
>+}
>+
>+
>+int hw_sm750_output_setMode(struct lynxfb_output *output,
>+              struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix)
>+{
>+      int ret;
>+      disp_output_t dispSet;
>+      int channel;
>+      ENTER();
>+      ret = 0;
>+      dispSet = 0;
>+      channel = *output->channel;
>+
>+
>+      if (getChipType() != SM750LE) {
>+              if (channel == sm750_primary) {
>+                      inf_msg("primary channel\n");
>+                      if (output->paths & sm750_panel)
>+                              dispSet |= do_LCD1_PRI;
>+                      if (output->paths & sm750_crt)
>+                              dispSet |= do_CRT_PRI;
>+
>+              } else{
>+                      inf_msg("secondary channel\n");
>+                      if (output->paths & sm750_panel)
>+                              dispSet |= do_LCD1_SEC;
>+                      if (output->paths & sm750_crt)
>+                              dispSet |= do_CRT_SEC;
>+
>+              }
>+              ddk750_setLogicalDispOut(dispSet);
>+      } else{
>+              /* just open DISPLAY_CONTROL_750LE register bit 3:0*/
>+              u32 reg;
>+              reg = PEEK32(DISPLAY_CONTROL_750LE);
>+              reg |= 0xf;
>+              POKE32(DISPLAY_CONTROL_750LE, reg);
>+      }
>+
>+      inf_msg("ddk setlogicdispout done \n");
>+      LEAVE(ret);
>+}
>+
>+void hw_sm750_output_clear(struct lynxfb_output *output)
>+{
>+      ENTER();
>+      LEAVE();
>+}
>+
>+int hw_sm750_crtc_checkMode(struct lynxfb_crtc *crtc, struct 
>fb_var_screeninfo *var)
>+{
>+      struct lynx_share *share;
>+      ENTER();
>+
>+      share = container_of(crtc, struct lynxfb_par, crtc)->share;
>+
>+      switch (var->bits_per_pixel) {
>+      case 8:
>+      case 16:
>+              break;
>+      case 32:
>+              if (share->revid == (unsigned char)SM750LE_REVISION_ID) {
>+                      dbg_msg("750le do not support 32bpp\n");
>+                      LEAVE (-EINVAL);
>+              }
>+              break;
>+      default:
>+                      LEAVE(-EINVAL);
>+
>+      }
>+
>+      LEAVE(0);
>+}
>+
>+
>+/*
>+   set the controller's mode for @crtc charged with @var and @fix parameters
>+   */
>+int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc,
>+              struct fb_var_screeninfo *var,
>+              struct fb_fix_screeninfo *fix)
>+{
>+      int ret, fmt;
>+      u32 reg;
>+      mode_parameter_t modparm;
>+      clock_type_t clock;
>+      struct lynx_share *share;
>+      struct lynxfb_par *par;
>+
>+      ENTER();
>+      ret = 0;
>+      par = container_of(crtc, struct lynxfb_par, crtc);
>+      share = par->share;
>+
>+      if (!share->accel_off) {
>+              /* set 2d engine pixel format according to mode bpp */
>+              switch (var->bits_per_pixel) {
>+              case 8:
>+                      fmt = 0;
>+                      break;
>+              case 16:
>+                      fmt = 1;
>+                      break;
>+              case 32:
>+              default:
>+                      fmt = 2;
>+                      break;
>+              }
>+              hw_set2dformat(&share->accel, fmt);
>+      }
>+
>+
>+      /* set timing */
>+      modparm.pixel_clock = ps_to_hz(var->pixclock);
>+      modparm.vertical_sync_polarity = (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 
>POS : NEG;
>+      modparm.horizontal_sync_polarity = (var->sync & FB_SYNC_VERT_HIGH_ACT) 
>? POS : NEG;
>+      modparm.clock_phase_polarity = (var->sync & FB_SYNC_COMP_HIGH_ACT) ? 
>POS : NEG;
>+      modparm.horizontal_display_end = var->xres;
>+      modparm.horizontal_sync_width = var->hsync_len;
>+      modparm.horizontal_sync_start = var->xres + var->right_margin;
>+      modparm.horizontal_total = var->xres + var->left_margin + 
>var->right_margin + var->hsync_len;
>+      modparm.vertical_display_end = var->yres;
>+      modparm.vertical_sync_height = var->vsync_len;
>+      modparm.vertical_sync_start = var->yres + var->lower_margin;
>+      modparm.vertical_total = var->yres + var->upper_margin + 
>var->lower_margin + var->vsync_len;
>+
>+      /* choose pll */
>+      if (crtc->channel != sm750_secondary)
>+              clock = PRIMARY_PLL;
>+      else
>+              clock = SECONDARY_PLL;
>+
>+      dbg_msg("Request pixel clock = %lu\n", modparm.pixel_clock);
>+      ret = ddk750_setModeTiming(&modparm, clock);
>+      if (ret) {
>+              err_msg("Set mode timing failed\n");
>+              goto exit;
>+      }
>+
>+      if (crtc->channel != sm750_secondary) {
>+              /* set pitch, offset , width, start address , etc... */
>+              POKE32(PANEL_FB_ADDRESS,
>+                              (~(1 << PANEL_FB_ADDRESS_STATUS_LSB))&
>+                              (~(1 << PANEL_FB_ADDRESS_EXT_LSB))&
>+                              (~(0X3FFFFFF << PANEL_FB_ADDRESS_ADDRESS_LSB))|
>+                              (crtc->oScreen << 
>PANEL_FB_ADDRESS_ADDRESS_LSB));
>+              reg = var->xres * (var->bits_per_pixel >> 3);
>+              /* crtc->channel is not equal to par->index on numeric, be 
>aware of that */
>+              reg = PADDING(crtc->line_pad, reg);
>+              POKE32(PANEL_FB_WIDTH,
>+                              (reg << PANEL_FB_WIDTH_WIDTH_LSB)|
>+                              (fix->line_length << 
>PANEL_FB_WIDTH_OFFSET_LSB));
>+
>+              POKE32(PANEL_WINDOW_WIDTH,
>+                              (var->xres - 1 << PANEL_WINDOW_WIDTH_WIDTH_LSB)|
>+                              (var->xoffset << PANEL_WINDOW_WIDTH_X_LSB));
>+
>+              POKE32(PANEL_WINDOW_HEIGHT,
>+                              (var->yres_virtual - 1 << 
>PANEL_WINDOW_HEIGHT_HEIGHT_LSB)|
>+                              (var->yoffset << PANEL_WINDOW_HEIGHT_Y_LSB));
>+              POKE32(PANEL_PLANE_TL, 0);
>+
>+              POKE32(PANEL_PLANE_BR,
>+                              (var->yres - 1 << PANEL_PLANE_BR_BOTTOM_LSB)|
>+                              (var->xres - 1 << PANEL_PLANE_BR_RIGHT_LSB));
>+
>+              /* set pixel format */
>+              reg = PEEK32(PANEL_DISPLAY_CTRL);
>+              POKE32(PANEL_DISPLAY_CTRL,
>+                              reg&(~(3 << PANEL_DISPLAY_CTRL_FORMAT_LSB))|
>+                              ((var->bits_per_pixel >> 4) << 
>PANEL_DISPLAY_CTRL_FORMAT_LSB));
>+      } else{
>+              /* not implemented now */
>+              POKE32(CRT_FB_ADDRESS, crtc->oScreen);
>+              reg = var->xres * (var->bits_per_pixel >> 3);
>+              /* crtc->channel is not equal to par->index on numeric, be 
>aware of that */
>+              reg = PADDING(crtc->line_pad, reg);
>+              POKE32(CRT_FB_WIDTH,
>+                              (reg << CRT_FB_WIDTH_WIDTH_LSB)|
>+                              (fix->line_length << CRT_FB_WIDTH_OFFSET_LSB));
>+
>+              /* SET PIXEL FORMAT */
>+              reg = PEEK32(CRT_DISPLAY_CTRL);
>+              reg |= (var->bits_per_pixel >> 4) << 
>CRT_DISPLAY_CTRL_FORMAT_LSB;
>+              POKE32(CRT_DISPLAY_CTRL, reg);
>+      }
>+
>+
>+exit:
>+      LEAVE(ret);
>+}
>+
>+void hw_sm750_crtc_clear(struct lynxfb_crtc *crtc)
>+{
>+      ENTER();
>+      LEAVE();
>+}
>+
>+int hw_sm750_setColReg(struct lynxfb_crtc *crtc, ushort index,
>+              ushort red, ushort green, ushort blue)
>+{
>+      static unsigned int add[] = {PANEL_PALETTE_RAM, CRT_PALETTE_RAM};
>+      POKE32(add[crtc->channel] + index*4, (red<<16)|(green<<8)|blue);
>+      return 0;
>+}
>+
>+int hw_sm750le_setBLANK(struct lynxfb_output *output, int blank)
>+{
>+      int dpms, crtdb;
>+      ENTER();
>+      switch (blank) {
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+      case FB_BLANK_UNBLANK:
>+#else
>+      case VESA_NO_BLANKING:
>+#endif
>+              dpms = CRT_DISPLAY_CTRL_DPMS_0;
>+              crtdb = CRT_DISPLAY_CTRL_BLANK_OFF;
>+              break;
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+      case FB_BLANK_NORMAL:
>+              dpms = CRT_DISPLAY_CTRL_DPMS_0;
>+              crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
>+              break;
>+#endif
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+      case FB_BLANK_VSYNC_SUSPEND:
>+#else
>+      case VESA_VSYNC_SUSPEND:
>+#endif
>+              dpms = CRT_DISPLAY_CTRL_DPMS_2;
>+              crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
>+              break;
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+      case FB_BLANK_HSYNC_SUSPEND:
>+#else
>+      case VESA_HSYNC_SUSPEND:
>+#endif
>+              dpms = CRT_DISPLAY_CTRL_DPMS_1;
>+              crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
>+              break;
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+      case FB_BLANK_POWERDOWN:
>+#else
>+      case VESA_POWERDOWN:
>+#endif
>+              dpms = CRT_DISPLAY_CTRL_DPMS_3;
>+              crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
>+              break;
>+      }
>+
>+      if (output->paths & sm750_crt) {
>+              POKE32(CRT_DISPLAY_CTRL, PEEK32(CRT_DISPLAY_CTRL)&(~(3 << 
>CRT_DISPLAY_CTRL_DPMS_LSB))|(dpms << CRT_DISPLAY_CTRL_DPMS_LSB));
>+              POKE32(CRT_DISPLAY_CTRL, PEEK32(CRT_DISPLAY_CTRL)&(~(1 << 
>CRT_DISPLAY_CTRL_BLANK_LSB))|(crtdb << CRT_DISPLAY_CTRL_BLANK_LSB));
>+      }
>+      LEAVE(0);
>+}
>+
>+int hw_sm750_setBLANK(struct lynxfb_output *output, int blank)
>+{
>+      unsigned int dpms, pps, crtdb;
>+      ENTER();
>+      dpms = pps = crtdb = 0;
>+
>+      switch (blank) {
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+      case FB_BLANK_UNBLANK:
>+#else
>+      case VESA_NO_BLANKING:
>+#endif
>+              inf_msg("flag = FB_BLANK_UNBLANK \n");
>+              dpms = SYSTEM_CTRL_DPMS_VPHP;
>+              pps = PANEL_DISPLAY_CTRL_DATA_ENABLE;
>+              crtdb = CRT_DISPLAY_CTRL_BLANK_OFF;
>+              break;
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+      case FB_BLANK_NORMAL:
>+              inf_msg("flag = FB_BLANK_NORMAL \n");
>+              dpms = SYSTEM_CTRL_DPMS_VPHP;
>+              pps = PANEL_DISPLAY_CTRL_DATA_DISABLE;
>+              crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
>+              break;
>+#endif
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+      case FB_BLANK_VSYNC_SUSPEND:
>+#else
>+      case VESA_VSYNC_SUSPEND:
>+#endif
>+              dpms = SYSTEM_CTRL_DPMS_VNHP;
>+              pps = PANEL_DISPLAY_CTRL_DATA_DISABLE;
>+              crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
>+              break;
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+      case FB_BLANK_HSYNC_SUSPEND:
>+#else
>+      case VESA_HSYNC_SUSPEND:
>+#endif
>+              dpms = SYSTEM_CTRL_DPMS_VPHN;
>+              pps = PANEL_DISPLAY_CTRL_DATA_DISABLE;
>+              crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
>+              break;
>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
>+      case FB_BLANK_POWERDOWN:
>+#else
>+      case VESA_POWERDOWN:
>+#endif
>+              dpms = SYSTEM_CTRL_DPMS_VNHN;
>+              pps = PANEL_DISPLAY_CTRL_DATA_DISABLE;
>+              crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
>+              break;
>+      }
>+
>+      if (output->paths & sm750_crt) {
>+              POKE32(SYSTEM_CTRL, PEEK32(SYSTEM_CTRL)&(~(3 << 
>SYSTEM_CTRL_DPMS_LSB))
>+                              |(dpms << SYSTEM_CTRL_DPMS_LSB));
>+              POKE32(CRT_DISPLAY_CTRL, PEEK32(CRT_DISPLAY_CTRL)&(~(1 << 
>CRT_DISPLAY_CTRL_BLANK_LSB))
>+                              |(crtdb << CRT_DISPLAY_CTRL_BLANK_LSB));
>+      }
>+
>+      if (output->paths & sm750_panel) {
>+              POKE32(PANEL_DISPLAY_CTRL, PEEK32(PANEL_DISPLAY_CTRL)&(~(1 << 
>PANEL_DISPLAY_CTRL_DATA_LSB))
>+                              |(pps << PANEL_DISPLAY_CTRL_DATA_LSB));
>+      }
>+
>+      LEAVE(0);
>+}
>+
>+
>+void hw_sm750_initAccel(struct lynx_share *share)
>+{
>+      u32 reg;
>+      enable2DEngine(1);
>+
>+      if (getChipType() == SM750LE) {
>+              reg = PEEK32(DE_STATE1);
>+              reg |= 1 << DE_STATE1_DE_ABORT_LSB;
>+              POKE32(DE_STATE1, reg);
>+
>+              reg = PEEK32(DE_STATE1);
>+              reg &= ~(1 << DE_STATE1_DE_ABORT_LSB);
>+              POKE32(DE_STATE1, reg);
>+
>+      } else{
>+              /* engine reset */
>+              reg = PEEK32(SYSTEM_CTRL);
>+              reg |= 1 << SYSTEM_CTRL_DE_ABORT_LSB;
>+              POKE32(SYSTEM_CTRL, reg);
>+
>+              reg = PEEK32(SYSTEM_CTRL);
>+              reg &= ~(1 << SYSTEM_CTRL_DE_ABORT_LSB);
>+              POKE32(SYSTEM_CTRL, reg);
>+      }
>+
>+      /* call 2d init */
>+      share->accel.de_init(&share->accel);
>+}
>+
>+int hw_sm750le_deWait()
>+{
>+      int i = 0x10000000;
>+      while (i--) {
>+              unsigned int dwVal = PEEK32(DE_STATE2);
>+              if (((1&(dwVal >> DE_STATE2_DE_STATUS_LSB)) == 
>DE_STATE2_DE_STATUS_IDLE) &&
>+                              ((1&(dwVal >> DE_STATE2_DE_FIFO_LSB))  == 
>DE_STATE2_DE_FIFO_EMPTY) &&
>+                              ((1&(dwVal >> DE_STATE2_DE_MEM_FIFO_LSB)) == 
>DE_STATE2_DE_MEM_FIFO_EMPTY)) {
>+                              return 0;
>+                      }
>+      }
>+      /* timeout error */
>+      return -1;
>+}
>+
>+
>+int hw_sm750_deWait()
>+{
>+      int i = 0x10000000;
>+      while (i--) {
>+              unsigned int dwVal = PEEK32(SYSTEM_CTRL);
>+              if (((1&(dwVal >> SYSTEM_CTRL_DE_STATUS_LSB)) == 
>SYSTEM_CTRL_DE_STATUS_IDLE) &&
>+                              ((1&(dwVal >> SYSTEM_CTRL_DE_FIFO_LSB))  == 
>SYSTEM_CTRL_DE_FIFO_EMPTY) &&
>+                              ((1&(dwVal >> SYSTEM_CTRL_DE_MEM_FIFO_LSB)) == 
>SYSTEM_CTRL_DE_MEM_FIFO_EMPTY)) {
>+                              return 0;
>+                      }
>+      }
>+      /* timeout error */
>+      return -1;
>+}
>+
>+int hw_sm750_pan_display(struct lynxfb_crtc *crtc,
>+              const struct fb_var_screeninfo *var,
>+              const struct fb_info *info)
>+{
>+      uint32_t total;
>+      if ((var->xoffset + var->xres > var->xres_virtual) ||
>+                      (var->yoffset + var->yres > var->yres_virtual)) {
>+              return -EINVAL;
>+      }
>+
>+      total = var->yoffset * info->fix.line_length +
>+              ((var->xoffset * var->bits_per_pixel) >> 3);
>+      total += crtc->oScreen;
>+      if (crtc->channel == sm750_primary) {
>+              POKE32(PANEL_FB_ADDRESS,
>+                              PEEK32(PANEL_FB_ADDRESS)&
>+                              (~(0x3ffffff << PANEL_FB_ADDRESS_ADDRESS_LSB))|
>+                              (total << PANEL_FB_ADDRESS_ADDRESS_LSB));
>+      } else{
>+              POKE32(CRT_FB_ADDRESS,
>+                              PEEK32(CRT_FB_ADDRESS)&
>+                              (~(0x3ffffff << CRT_FB_ADDRESS_ADDRESS_LSB))|
>+                              (total << CRT_FB_ADDRESS_ADDRESS_LSB));
>+      }
>+      return 0;
>+}
>+
>diff --git a/drivers/video/lynxfb/lynx_hw750.h 
>b/drivers/video/lynxfb/lynx_hw750.h
>new file mode 100644
>index 0000000..9f91ad1
>--- /dev/null
>+++ b/drivers/video/lynxfb/lynx_hw750.h
>@@ -0,0 +1,120 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef LYNX_HW750_H__
>+#define LYNX_HW750_H__
>+
>+
>+#define DEFAULT_SM750_CHIP_CLOCK              290
>+#define DEFAULT_SM750LE_CHIP_CLOCK    333
>+#ifndef SM750LE_REVISION_ID
>+#define SM750LE_REVISION_ID ((unsigned char)0xfe)
>+#endif
>+
>+
>+
>+enum sm750_pnltype{
>+
>+      sm750_24TFT = 0, /* 24bit tft */
>+
>+      sm750_dualTFT = 2, /* dual 18 bit tft */
>+
>+      sm750_doubleTFT = 1, /* 36 bit double pixel tft */
>+};
>+
>+/* vga channel is not concerned  */
>+enum sm750_dataflow{
>+      sm750_simul_pri, /* primary => all head */
>+
>+      sm750_simul_sec, /* secondary => all head */
>+
>+      sm750_dual_normal, /*   primary => panel head and secondary => crt */
>+
>+      sm750_dual_swap, /*     primary => crt head and secondary => panel */
>+};
>+
>+
>+enum sm750_channel{
>+      sm750_primary = 0,
>+      /* enum value equal to the register filed data */
>+      sm750_secondary = 1,
>+};
>+
>+enum sm750_path{
>+      sm750_panel = 1,
>+      sm750_crt = 2,
>+      sm750_pnc = 3, /* panel and crt */
>+};
>+
>+struct init_status{
>+      ushort powerMode;
>+      /* below three clocks are in unit of MHZ*/
>+      ushort chip_clk;
>+      ushort mem_clk;
>+      ushort master_clk;
>+      ushort setAllEngOff;
>+      ushort resetMemory;
>+};
>+
>+struct sm750_state{
>+      struct init_status initParm;
>+      enum sm750_pnltype pnltype;
>+      enum sm750_dataflow dataflow;
>+      int nocrt;
>+      int xLCD;
>+      int yLCD;
>+};
>+
>+/*    sm750_share stands for a presentation of two frame buffer
>+      that use one sm750 adaptor, it is similiar to the super class of 
>lynx_share
>+      in C++
>+*/
>+
>+struct sm750_share{
>+      /* it's better to put lynx_share struct to the first place of 
>sm750_share */
>+      struct lynx_share share;
>+      struct sm750_state state;
>+      int hwCursor;
>+      /*      0: no hardware cursor
>+              1: primary crtc hw cursor enabled,
>+              2: secondary crtc hw cursor enabled
>+              3: both ctrc hw cursor enabled
>+      */
>+};
>+
>+int hw_sm750_map(struct lynx_share *share, struct pci_dev *pdev);
>+int hw_sm750_inithw(struct lynx_share *, struct pci_dev *);
>+void hw_sm750_initAccel(struct lynx_share *);
>+int hw_sm750_deWait(void);
>+int hw_sm750le_deWait(void);
>+
>+resource_size_t hw_sm750_getVMSize(struct lynx_share *);
>+int hw_sm750_output_checkMode(struct lynxfb_output *, struct 
>fb_var_screeninfo *);
>+int hw_sm750_output_setMode(struct lynxfb_output *, struct fb_var_screeninfo 
>*, struct fb_fix_screeninfo *);
>+int hw_sm750_crtc_checkMode(struct lynxfb_crtc *, struct fb_var_screeninfo *);
>+int hw_sm750_crtc_setMode(struct lynxfb_crtc *, struct fb_var_screeninfo *, 
>struct fb_fix_screeninfo *);
>+int hw_sm750_setColReg(struct lynxfb_crtc *, ushort, ushort, ushort, ushort);
>+int hw_sm750_setBLANK(struct lynxfb_output *, int);
>+int hw_sm750le_setBLANK(struct lynxfb_output *, int);
>+void hw_sm750_crtc_clear(struct lynxfb_crtc *);
>+void hw_sm750_output_clear(struct lynxfb_output *);
>+int hw_sm750_pan_display(struct lynxfb_crtc *crtc,
>+      const struct fb_var_screeninfo *var,
>+      const struct fb_info *info);
>+
>+#endif
>diff --git a/drivers/video/lynxfb/modedb.c b/drivers/video/lynxfb/modedb.c
>new file mode 100644
>index 0000000..50fc8b9
>--- /dev/null
>+++ b/drivers/video/lynxfb/modedb.c
>@@ -0,0 +1,238 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+static const struct fb_videomode modedb2[] = {
>+    {
>+      /* 640x400 @ 70 Hz, 31.5 kHz hsync */
>+      NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 640x480 @ 60 Hz, 31.5 kHz hsync */
>+      NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 800x600 @ 56 Hz, 35.15 kHz hsync */
>+      NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
>+      NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
>+      0, FB_VMODE_INTERLACED
>+    }, {
>+      /* 640x400 @ 85 Hz, 37.86 kHz hsync */
>+      NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
>+      FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 640x480 @ 72 Hz, 36.5 kHz hsync */
>+      NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 640x480 @ 75 Hz, 37.50 kHz hsync */
>+      NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 800x600 @ 60 Hz, 37.8 kHz hsync */
>+      NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
>+      FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 640x480 @ 85 Hz, 43.27 kHz hsync */
>+      NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
>+      NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
>+      0, FB_VMODE_INTERLACED
>+    }, {
>+      /* 800x600 @ 72 Hz, 48.0 kHz hsync */
>+      NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
>+      FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
>+      NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 640x480 @ 100 Hz, 53.01 kHz hsync */
>+      NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
>+      NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 800x600 @ 85 Hz, 55.84 kHz hsync */
>+      NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
>+      NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /*  1280x960-60 VESA */
>+      NULL, 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3,
>+      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,  FB_VMODE_NONINTERLACED, 
>FB_MODE_IS_VESA
>+    }, {
>+      /*  1280x1024-60 VESA */
>+      NULL, 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
>+      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 
>FB_MODE_IS_VESA
>+    }, {
>+      /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
>+      NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
>+      0, FB_VMODE_INTERLACED
>+    }, {
>+      /* 800x600 @ 100 Hz, 64.02 kHz hsync */
>+      NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
>+      NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
>+      NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
>+      NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
>+      NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
>+      NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3,
>+      FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
>+      NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
>+      FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
>+      NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
>+      NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
>+      NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
>+      NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
>+      FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
>+      NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
>+      NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1024x768 @ 100Hz, 80.21 kHz hsync */
>+      NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
>+      NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
>+      NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
>+      NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
>+      NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
>+      FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
>+      NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
>+      FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
>+      NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
>+      FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
>+      NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1800x1440 @ 64Hz, 96.15 kHz hsync  */
>+      NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
>+      FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 1800x1440 @ 70Hz, 104.52 kHz hsync  */
>+      NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
>+      FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 512x384 @ 78 Hz, 31.50 kHz hsync */
>+      NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 512x384 @ 85 Hz, 34.38 kHz hsync */
>+      NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
>+      0, FB_VMODE_NONINTERLACED
>+    }, {
>+      /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
>+      NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
>+      0, FB_VMODE_DOUBLE
>+    }, {
>+      /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
>+      NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
>+      0, FB_VMODE_DOUBLE
>+    }, {
>+      /* 320x240 @ 72 Hz, 36.5 kHz hsync */
>+      NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
>+      0, FB_VMODE_DOUBLE
>+    }, {
>+      /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
>+      NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
>+      0, FB_VMODE_DOUBLE
>+    }, {
>+      /* 400x300 @ 60 Hz, 37.8 kHz hsync */
>+      NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
>+      0, FB_VMODE_DOUBLE
>+    }, {
>+      /* 400x300 @ 72 Hz, 48.0 kHz hsync */
>+      NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
>+      0, FB_VMODE_DOUBLE
>+    }, {
>+      /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
>+      NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
>+      0, FB_VMODE_DOUBLE
>+    }, {
>+      /* 480x300 @ 60 Hz, 37.8 kHz hsync */
>+      NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
>+      0, FB_VMODE_DOUBLE
>+    }, {
>+      /* 480x300 @ 63 Hz, 39.6 kHz hsync */
>+      NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
>+      0, FB_VMODE_DOUBLE
>+    }, {
>+      /* 480x300 @ 72 Hz, 48.0 kHz hsync */
>+      NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
>+      0, FB_VMODE_DOUBLE
>+    },
>+};
>+static const int nmodedb2 = sizeof(modedb2);
>diff --git a/drivers/video/lynxfb/ver.h b/drivers/video/lynxfb/ver.h
>new file mode 100644
>index 0000000..d11362a
>--- /dev/null
>+++ b/drivers/video/lynxfb/ver.h
>@@ -0,0 +1,38 @@
>+/*******************************************************************
>+*Copyright (c) 2012 by Silicon Motion, Inc. (SMI)
>+*Permission is hereby granted, free of charge, to any person obtaining a copy
>+*of this software and associated documentation files (the "Software"), to deal
>+*in the Software without restriction, including without limitation the rights 
>to
>+*use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
>+*of the Software, and to permit persons to whom the Software is furnished to
>+*do so, subject to the following conditions:
>+*
>+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>+*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>+*OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>+*NONINFRINGEMENT.  IN NO EVENT SHALL Mill.Chen and Monk.Liu OR COPYRIGHT
>+*HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>+*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+*FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>+*OTHER DEALINGS IN THE SOFTWARE.
>+*******************************************************************/
>+#ifndef __VER_H_
>+#define __VER_H_
>+
>+#define RELEASE_TYPE "Electra(formal release)"
>+#define SUPPORT_ARCH "x86,x86_64"
>+#define SUPPORT_CHIP "lynx Express(750)/lynx 750LE/Lynx SE(718)"
>+/*#define SUPPORT_CHIP " \
>+\tlynx 750LE\n"*/
>+
>+#define SUPPORT_OS " \
>+\tRHEL 4.3 i386 and x86_64\n \
>+\tRHEL 5.3 i386 and x86_64\n \
>+\tRHEL 6.0 i386 and x86_64\n \
>+\tSLES 9   i386 and x86_64\n \
>+\tSLES 10  i386 and x86_64\n \
>+\tSLES 11  i386 and x86_64\n"
>+#define _version_     "4.1.3"
>+
>+#endif
>+
>-- 
>1.7.9.5
>

Reply via email to