update rk29-fb driver
author杜坤明 <dkm@rock-chips.com>
Fri, 5 Nov 2010 12:12:47 +0000 (20:12 +0800)
committer杜坤明 <dkm@rock-chips.com>
Fri, 5 Nov 2010 12:12:47 +0000 (20:12 +0800)
22 files changed:
arch/arm/mach-rk29/board-rk29sdk.c [changed mode: 0644->0755]
arch/arm/mach-rk29/devices.c [changed mode: 0644->0755]
arch/arm/mach-rk29/devices.h [changed mode: 0644->0755]
arch/arm/mach-rk29/include/mach/board.h [changed mode: 0644->0755]
drivers/video/Kconfig [changed mode: 0644->0755]
drivers/video/Makefile [changed mode: 0644->0755]
drivers/video/display/screen/hdmi_anx7150.c
drivers/video/display/screen/hdmi_null.c
drivers/video/display/screen/lcd_a060se02.c
drivers/video/display/screen/lcd_hl070vm4.c
drivers/video/display/screen/lcd_hsd800x480.c
drivers/video/display/screen/lcd_hx8357.c
drivers/video/display/screen/lcd_nt35580.c
drivers/video/display/screen/lcd_nt35582.c
drivers/video/display/screen/lcd_null.c
drivers/video/display/screen/lcd_s1d13521.c
drivers/video/display/screen/lcd_td043mgea1.c
drivers/video/display/screen/lcd_tj048nc01ca.c
drivers/video/display/screen/screen.h
drivers/video/display/screen/tv_null.c
drivers/video/rk29_fb.c [new file with mode: 0755]
drivers/video/rk29_fb.h [new file with mode: 0755]

old mode 100644 (file)
new mode 100755 (executable)
index eb4b35e..16e21b4
@@ -76,11 +76,219 @@ static struct rk29_gpio_bank rk29_gpiobankinit[] = {
        },      \r
 };\r
 \r
+/*****************************************************************************************\r
+ * lcd  devices\r
+ * author: zyw@rock-chips.com\r
+ *****************************************************************************************/\r
+//#ifdef  CONFIG_LCD_TD043MGEA1\r
+#define LCD_TXD_PIN          RK29_PIN0_PA6   // ÂÒÌî,µÃÐÞ¸Ä\r
+#define LCD_CLK_PIN          RK29_PIN0_PA7   // ÂÒÌî,µÃÐÞ¸Ä\r
+#define LCD_CS_PIN           RK29_PIN0_PB6   // ÂÒÌî,µÃÐÞ¸Ä\r
+#define LCD_TXD_MUX_NAME     GPIOE_U1IR_I2C1_NAME\r
+#define LCD_CLK_MUX_NAME     NULL\r
+#define LCD_CS_MUX_NAME      GPIOH6_IQ_SEL_NAME\r
+#define LCD_TXD_MUX_MODE     0\r
+#define LCD_CLK_MUX_MODE     0\r
+#define LCD_CS_MUX_MODE      0\r
+//#endif\r
+static int rk29_lcd_io_init(void)\r
+{\r
+    int ret = 0;\r
+\r
+#if 0\r
+    rk29_mux_api_set(LCD_CS_MUX_NAME, LCD_CS_MUX_MODE);\r
+    if (LCD_CS_PIN != INVALID_GPIO) {\r
+        ret = gpio_request(LCD_CS_PIN, NULL);\r
+        if(ret != 0)\r
+        {\r
+            goto err1;\r
+            printk(">>>>>> lcd cs gpio_request err \n ");\r
+        }\r
+    }\r
+\r
+    rk29_mux_api_set(LCD_CLK_MUX_NAME, LCD_CLK_MUX_MODE);\r
+    if (LCD_CLK_PIN != INVALID_GPIO) {\r
+        ret = gpio_request(LCD_CLK_PIN, NULL);\r
+        if(ret != 0)\r
+        {\r
+            goto err2;\r
+            printk(">>>>>> lcd clk gpio_request err \n ");\r
+        }\r
+    }\r
+\r
+    rk29_mux_api_set(LCD_TXD_MUX_NAME, LCD_TXD_MUX_MODE);\r
+    if (LCD_TXD_PIN != INVALID_GPIO) {\r
+        ret = gpio_request(LCD_TXD_PIN, NULL);\r
+        if(ret != 0)\r
+        {\r
+            goto err3;\r
+            printk(">>>>>> lcd txd gpio_request err \n ");\r
+        }\r
+    }\r
+\r
+    return 0;\r
+\r
+err3:\r
+    if (LCD_CLK_PIN != INVALID_GPIO) {\r
+        gpio_free(LCD_CLK_PIN);\r
+    }\r
+err2:\r
+    if (LCD_CS_PIN != INVALID_GPIO) {\r
+        gpio_free(LCD_CS_PIN);\r
+    }\r
+err1:\r
+#endif\r
+    return ret;\r
+}\r
+\r
+static int rk29_lcd_io_deinit(void)\r
+{\r
+    int ret = 0;\r
+#if 0\r
+    gpio_direction_output(LCD_CLK_PIN, 0);\r
+    gpio_set_value(LCD_CLK_PIN, GPIO_HIGH);\r
+    gpio_direction_output(LCD_TXD_PIN, 0);\r
+    gpio_set_value(LCD_TXD_PIN, GPIO_HIGH);\r
+\r
+    gpio_free(LCD_CS_PIN);\r
+    rk29_mux_api_mode_resume(LCD_CS_MUX_NAME);\r
+    gpio_free(LCD_CLK_PIN);\r
+    gpio_free(LCD_TXD_PIN);\r
+    rk29_mux_api_mode_resume(LCD_TXD_MUX_NAME);\r
+    rk29_mux_api_mode_resume(LCD_CLK_MUX_NAME);\r
+#endif\r
+    return ret;\r
+}\r
+\r
+struct rk29lcd_info rk29_lcd_info = {\r
+    //.txd_pin  = LCD_TXD_PIN,\r
+    //.clk_pin = LCD_CLK_PIN,\r
+    //.cs_pin = LCD_CS_PIN,\r
+    .io_init   = rk29_lcd_io_init,\r
+    .io_deinit = rk29_lcd_io_deinit,\r
+};\r
+\r
+\r
+/*****************************************************************************************\r
+ * frame buffe  devices\r
+ * author: zyw@rock-chips.com\r
+ *****************************************************************************************/\r
+\r
+#define FB_ID                       0\r
+#define FB_DISPLAY_ON_PIN           RK29_PIN0_PB1   // ÂÒÌî,µÃÐÞ¸Ä\r
+#define FB_LCD_STANDBY_PIN          INVALID_GPIO\r
+#define FB_MCU_FMK_PIN              INVALID_GPIO\r
+\r
+#if 0\r
+#define FB_DISPLAY_ON_VALUE         GPIO_LOW\r
+#define FB_LCD_STANDBY_VALUE        0\r
+\r
+#define FB_DISPLAY_ON_MUX_NAME      GPIOB1_SMCS1_MMC0PCA_NAME\r
+#define FB_DISPLAY_ON_MUX_MODE      IOMUXA_GPIO0_B1\r
+\r
+#define FB_LCD_STANDBY_MUX_NAME     NULL\r
+#define FB_LCD_STANDBY_MUX_MODE     1\r
+\r
+#define FB_MCU_FMK_PIN_MUX_NAME     NULL\r
+#define FB_MCU_FMK_MUX_MODE         0\r
+\r
+#define FB_DATA0_16_MUX_NAME       GPIOC_LCDC16BIT_SEL_NAME\r
+#define FB_DATA0_16_MUX_MODE        1\r
+\r
+#define FB_DATA17_18_MUX_NAME      GPIOC_LCDC18BIT_SEL_NAME\r
+#define FB_DATA17_18_MUX_MODE       1\r
+\r
+#define FB_DATA19_24_MUX_NAME      GPIOC_LCDC24BIT_SEL_NAME\r
+#define FB_DATA19_24_MUX_MODE       1\r
+\r
+#define FB_DEN_MUX_NAME            CXGPIO_LCDDEN_SEL_NAME\r
+#define FB_DEN_MUX_MODE             1\r
+\r
+#define FB_VSYNC_MUX_NAME          CXGPIO_LCDVSYNC_SEL_NAME\r
+#define FB_VSYNC_MUX_MODE           1\r
+\r
+#define FB_MCU_FMK_MUX_NAME        NULL\r
+#define FB_MCU_FMK_MUX_MODE         0\r
+#endif\r
+static int rk29_fb_io_init(struct rk29_fb_setting_info *fb_setting)\r
+{\r
+    int ret = 0;\r
+#if 0\r
+    if(fb_setting->data_num <=16)\r
+        rk29_mux_api_set(FB_DATA0_16_MUX_NAME, FB_DATA0_16_MUX_MODE);\r
+    if(fb_setting->data_num >16 && fb_setting->data_num<=18)\r
+        rk29_mux_api_set(FB_DATA17_18_MUX_NAME, FB_DATA17_18_MUX_MODE);\r
+    if(fb_setting->data_num >18)\r
+        rk29_mux_api_set(FB_DATA19_24_MUX_NAME, FB_DATA19_24_MUX_MODE);\r
+\r
+    if(fb_setting->vsync_en)\r
+        rk29_mux_api_set(FB_VSYNC_MUX_NAME, FB_VSYNC_MUX_MODE);\r
+\r
+    if(fb_setting->den_en)\r
+        rk29_mux_api_set(FB_DEN_MUX_NAME, FB_DEN_MUX_MODE);\r
+\r
+    if(fb_setting->mcu_fmk_en && FB_MCU_FMK_MUX_NAME && (FB_MCU_FMK_PIN != INVALID_GPIO))\r
+    {\r
+        rk29_mux_api_set(FB_MCU_FMK_MUX_NAME, FB_MCU_FMK_MUX_MODE);\r
+        ret = gpio_request(FB_MCU_FMK_PIN, NULL);\r
+        if(ret != 0)\r
+        {\r
+            gpio_free(FB_MCU_FMK_PIN);\r
+            printk(">>>>>> FB_MCU_FMK_PIN gpio_request err \n ");\r
+        }\r
+        gpio_direction_input(FB_MCU_FMK_PIN);\r
+    }\r
+\r
+    if(fb_setting->disp_on_en && FB_DISPLAY_ON_MUX_NAME && (FB_DISPLAY_ON_PIN != INVALID_GPIO))\r
+    {\r
+        rk29_mux_api_set(FB_DISPLAY_ON_MUX_NAME, FB_DISPLAY_ON_MUX_MODE);\r
+        ret = gpio_request(FB_DISPLAY_ON_PIN, NULL);\r
+        if(ret != 0)\r
+        {\r
+            gpio_free(FB_DISPLAY_ON_PIN);\r
+            printk(">>>>>> FB_DISPLAY_ON_PIN gpio_request err \n ");\r
+        }\r
+    }\r
+\r
+    if(fb_setting->disp_on_en && FB_LCD_STANDBY_MUX_NAME && (FB_LCD_STANDBY_PIN != INVALID_GPIO))\r
+    {\r
+        rk29_mux_api_set(FB_LCD_STANDBY_MUX_NAME, FB_LCD_STANDBY_MUX_MODE);\r
+        ret = gpio_request(FB_LCD_STANDBY_PIN, NULL);\r
+        if(ret != 0)\r
+        {\r
+            gpio_free(FB_LCD_STANDBY_PIN);\r
+            printk(">>>>>> FB_LCD_STANDBY_PIN gpio_request err \n ");\r
+        }\r
+    }\r
+#endif\r
+    return ret;\r
+}\r
+\r
+struct rk29fb_info rk29_fb_info = {\r
+    .fb_id   = FB_ID,\r
+    //.disp_on_pin = FB_DISPLAY_ON_PIN,\r
+    //.disp_on_value = FB_DISPLAY_ON_VALUE,\r
+    //.standby_pin = FB_LCD_STANDBY_PIN,\r
+    //.standby_value = FB_LCD_STANDBY_VALUE,\r
+    //.mcu_fmk_pin = FB_MCU_FMK_PIN,\r
+    .lcd_info = &rk29_lcd_info,\r
+    .io_init   = rk29_fb_io_init,\r
+};\r
+\r
+\r
 static struct platform_device *devices[] __initdata = {\r
 #ifdef CONFIG_UART1_RK29       \r
        &rk29_device_uart1,\r
 #endif \r
 \r
+#ifdef CONFIG_FB_RK29\r
+    &rk29_device_fb,\r
+#endif\r
+\r
+#ifdef CONFIG_VIVANTE\r
+       &rk29_device_gpu,\r
+#endif\r
+\r
 };\r
 \r
 static void __init rk29_gic_init_irq(void)\r
old mode 100644 (file)
new mode 100755 (executable)
index 940f651..ba31c57
@@ -114,4 +114,62 @@ struct platform_device rk29_device_uart3 = {
        .num_resources  = ARRAY_SIZE(resources_uart3),
        .resource       = resources_uart3,
 };
-#endif
\ No newline at end of file
+#endif
+
+#ifdef CONFIG_VIVANTE
+static struct resource resources_gpu[] = {
+    [0] = {
+               .name   = "gpu_irq",
+        .start         = IRQ_GPU,
+        .end    = IRQ_GPU,
+        .flags  = IORESOURCE_IRQ,
+    },
+    [1] = {
+               .name = "gpu_base",
+        .start  = RK29_GPU_PHYS,
+        .end    = RK29_GPU_PHYS + (256 << 10),
+        .flags  = IORESOURCE_MEM,
+    },
+    [2] = {
+               .name = "gpu_mem",
+        .start  = 0x66400000,               //0x67C00000,
+        .end    = 0x66400000 + (28 << 20),  //0x67C00000 + (4 << 20),
+        .flags  = IORESOURCE_MEM,
+    },
+};
+struct platform_device rk29_device_gpu = {
+    .name             = "galcore",
+    .id               = 0,
+    .num_resources    = ARRAY_SIZE(resources_gpu),
+    .resource         = resources_gpu,
+};
+#endif
+
+#ifdef CONFIG_FB_RK29
+/* rk29 fb resource */
+static struct resource rk29_fb_resource[] = {
+       [0] = {
+               .start = RK29_LCDC_PHYS,
+               .end   = RK29_LCDC_PHYS + RK29_LCDC_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_LCDC,
+               .end   = IRQ_LCDC,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+/*platform_device*/
+extern struct rk29fb_info rk29_fb_info;
+struct platform_device rk29_device_fb = {
+       .name             = "rk29-fb",
+       .id               = 4,
+       .num_resources    = ARRAY_SIZE(rk29_fb_resource),
+       .resource         = rk29_fb_resource,
+       .dev            = {
+               .platform_data  = &rk29_fb_info,
+       }
+};
+#endif
+
old mode 100644 (file)
new mode 100755 (executable)
index 44766c9..e2e28e8
@@ -21,5 +21,7 @@ extern struct platform_device rk29_device_uart0;
 extern struct platform_device rk29_device_uart1;
 extern struct platform_device rk29_device_uart2;
 extern struct platform_device rk29_device_uart3;
+extern struct platform_device rk29_device_gpu;
+extern struct platform_device rk29_device_fb;
 
 #endif
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index 476a4d4..6598fc1
 
 #include <linux/types.h>
 
+#define INVALID_GPIO        -1
+
+struct rk29lcd_info{
+    u32 lcd_id;
+    u32 txd_pin;
+    u32 clk_pin;
+    u32 cs_pin;
+    int (*io_init)(void);
+    int (*io_deinit)(void);
+};
+
+struct rk29_fb_setting_info{
+    u8 data_num;
+    u8 vsync_en;
+    u8 den_en;
+    u8 mcu_fmk_en;
+    u8 disp_on_en;
+    u8 standby_en;
+};
+
+struct rk29fb_info{
+    u32 fb_id;
+    u32 disp_on_pin;
+    u8 disp_on_value;
+    u32 standby_pin;
+    u8 standby_value;
+    u32 mcu_fmk_pin;
+    struct rk29lcd_info *lcd_info;
+    int (*io_init)(struct rk29_fb_setting_info *fb_setting);
+    int (*io_deinit)(void);
+};
+
 void __init rk29_map_common_io(void);
 void __init rk29_clock_init(void);
 
old mode 100644 (file)
new mode 100755 (executable)
index b283706..cab6a9a
@@ -18,7 +18,7 @@ config VGASTATE
 config VIDEO_OUTPUT_CONTROL
        tristate "Lowlevel video output switch controls"
        help
-         This framework adds support for low-level control of the video 
+         This framework adds support for low-level control of the video
          output switch.
 
 menuconfig FB
@@ -626,7 +626,7 @@ config FB_STI
          BIOS routines contained in a ROM chip in HP PA-RISC based machines.
          Enabling this option will implement the linux framebuffer device
          using calls to the STI BIOS routines for initialisation.
-       
+
          If you enable this option, you will get a planar framebuffer device
          /dev/fb which will work on the most common HP graphic cards of the
          NGLE family, including the artist chips (in the 7xx and Bxxx series),
@@ -1065,36 +1065,36 @@ config FB_I810
        select FB_CFB_IMAGEBLIT
        select VGASTATE
        help
-         This driver supports the on-board graphics built in to the Intel 810 
+         This driver supports the on-board graphics built in to the Intel 810
           and 815 chipsets.  Say Y if you have and plan to use such a board.
 
           To compile this driver as a module, choose M here: the
          module will be called i810fb.
 
-          For more information, please read 
+          For more information, please read
          <file:Documentation/fb/intel810.txt>
 
 config FB_I810_GTF
        bool "use VESA Generalized Timing Formula"
        depends on FB_I810
        help
-         If you say Y, then the VESA standard, Generalized Timing Formula 
+         If you say Y, then the VESA standard, Generalized Timing Formula
           or GTF, will be used to calculate the required video timing values
-         per video mode.  Since the GTF allows nondiscrete timings 
+         per video mode.  Since the GTF allows nondiscrete timings
           (nondiscrete being a range of values as opposed to discrete being a
-          set of values), you'll be able to use any combination of horizontal 
+          set of values), you'll be able to use any combination of horizontal
          and vertical resolutions, and vertical refresh rates without having
          to specify your own timing parameters.  This is especially useful
-         to maximize the performance of an aging display, or if you just 
-          have a display with nonstandard dimensions. A VESA compliant 
+         to maximize the performance of an aging display, or if you just
+          have a display with nonstandard dimensions. A VESA compliant
          monitor is recommended, but can still work with non-compliant ones.
-         If you need or want this, then select this option. The timings may 
-         not be compliant with Intel's recommended values. Use at your own 
+         If you need or want this, then select this option. The timings may
+         not be compliant with Intel's recommended values. Use at your own
          risk.
 
-          If you say N, the driver will revert to discrete video timings 
+          If you say N, the driver will revert to discrete video timings
          using a set recommended by Intel in their documentation.
-  
+
           If unsure, say N.
 
 config FB_I810_I2C
@@ -1212,10 +1212,10 @@ config FB_MATROX_G
          G450/G550 secondary head and digital output are supported without
          additional modules.
 
-         The driver starts in monitor mode. You must use the matroxset tool 
-         (available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to 
-         swap primary and secondary head outputs, or to change output mode.  
-         Secondary head driver always start in 640x480 resolution and you 
+         The driver starts in monitor mode. You must use the matroxset tool
+         (available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to
+         swap primary and secondary head outputs, or to change output mode.
+         Secondary head driver always start in 640x480 resolution and you
          must use fbset to change it.
 
          Do not forget that second head supports only 16 and 32 bpp
@@ -1298,7 +1298,7 @@ config FB_RADEON_I2C
        select FB_DDC
        default y
        help
-         Say Y here if you want DDC/I2C support for your Radeon board. 
+         Say Y here if you want DDC/I2C support for your Radeon board.
 
 config FB_RADEON_BACKLIGHT
        bool "Support for backlight control"
@@ -1498,7 +1498,7 @@ config FB_NEOMAGIC
        select VGASTATE
        help
          This driver supports notebooks with NeoMagic PCI chips.
-         Say Y if you have such a graphics card. 
+         Say Y if you have such a graphics card.
 
          To compile this driver as a module, choose M here: the
          module will be called neofb.
@@ -1553,7 +1553,7 @@ config FB_VOODOO1
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
        ---help---
-         Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or 
+         Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or
          Voodoo2 (cvg) based graphics card.
 
          To compile this driver as a module, choose M here: the
@@ -1935,7 +1935,17 @@ config FB_RK2818
        select FB_CFB_IMAGEBLIT
        ---help---
          Framebuffer driver for RK2818 Platform,select it if you using rk2818
-         
+
+config FB_RK29
+       tristate "RK29 lcd control"
+       depends on FB
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       ---help---
+         Framebuffer driver for RK29 Platform,select it if you using rk29
+
+
 config FB_SM501
        tristate "Silicon Motion SM501 framebuffer support"
        depends on FB && MFD_SM501
old mode 100644 (file)
new mode 100755 (executable)
index 6777b5a..6a0202b
@@ -121,6 +121,7 @@ obj-$(CONFIG_FB_PNX4008_DUM_RGB)  += pnx4008/
 obj-$(CONFIG_FB_IBM_GXT4500)     += gxt4500.o
 obj-$(CONFIG_FB_PS3)             += ps3fb.o
 obj-$(CONFIG_FB_RK2818)       += rk2818_fb.o
+obj-$(CONFIG_FB_RK29)         += rk29_fb.o
 obj-$(CONFIG_FB_SM501)            += sm501fb.o
 obj-$(CONFIG_FB_XILINX)           += xilinxfb.o
 obj-$(CONFIG_FB_SH_MOBILE_LCDC)          += sh_mobile_lcdcfb.o
index 5752803189fa00c177b34516d8f8c49678c6ea88..eed53ae54544a3e286f3daa6819d021402dbcbc3 100755 (executable)
@@ -1,6 +1,6 @@
 #include <linux/fb.h>
 #include <linux/delay.h>
-#include "../../rk2818_fb.h"
+#include "../../rk29_fb.h"
 #include <mach/gpio.h>
 #include <mach/iomux.h>
 #include "screen.h"
@@ -39,9 +39,9 @@ int anx7150_init(void);
 int anx7150_standby(u8 enable);
 
 
-void set_hdmi_info(struct rk28fb_screen *screen)
+void set_hdmi_info(struct rk29fb_screen *screen)
 {
-    struct rk28fb_screen *screen2 = screen + 1;
+    struct rk29fb_screen *screen2 = screen + 1;
 
     /* ****************** 576p ******************* */
     /* screen type & face */
index c39836d4e44eab594d57127aa4de8d6fb89641df..5aa9f3f4c72e0ddad86082fd557b179703276cd8 100755 (executable)
@@ -1,14 +1,14 @@
 
 #include <linux/fb.h>
 #include <linux/delay.h>
-#include "../../rk2818_fb.h"
+#include "../../rk29_fb.h"
 #include <mach/gpio.h>
 #include <mach/iomux.h>
 #include "screen.h"
 
 
-void set_hdmi_info(struct rk28fb_screen *screen)
+void set_hdmi_info(struct rk29fb_screen *screen)
 {
-    memset(screen, 0, sizeof(struct rk28fb_screen));
+    memset(screen, 0, sizeof(struct rk29fb_screen));
     screen->face = OUT_P666;
 }
index ac386386f5be8f3b107ff7723c9b1a8b35eaf818..b24540b5f31a17a7aa7ac5459971d00c08d8809d 100755 (executable)
@@ -1,6 +1,6 @@
 #include <linux/fb.h>
 #include <linux/delay.h>
-#include "../../rk2818_fb.h"
+#include "../../rk29_fb.h"
 #include <mach/gpio.h>
 #include <mach/iomux.h>
 #include "screen.h"
@@ -117,7 +117,7 @@ int lcd_refresh(u8 arg)
 
 
 
-void set_lcd_info(struct rk28fb_screen *screen)
+void set_lcd_info(struct rk29fb_screen *screen)
 {
     /* screen type & face */
     screen->type = OUT_TYPE;
index e9e51124141b9d3cd6deeef7597bf532ad3aca66..f81aadaf59542e45202809d1676f02fadc1793e4 100755 (executable)
@@ -1,6 +1,6 @@
 #include <linux/fb.h>
 #include <linux/delay.h>
-#include "../../rk2818_fb.h"
+#include "../../rk29_fb.h"
 #include <mach/gpio.h>
 #include <mach/iomux.h>
 #include <mach/board.h>
@@ -13,7 +13,7 @@
 
 /* Timing */
 #define H_PW                   10
-#define H_BP                   206  
+#define H_BP                   206
 #define H_VD                   800
 #define H_FP                   40
 
 #define CS_OUT()        gpio_direction_output(CS_PORT, 0)
 #define CS_SET()        gpio_set_value(CS_PORT, GPIO_HIGH)
 #define CS_CLR()        gpio_set_value(CS_PORT, GPIO_LOW)
-#define CLK_OUT()       gpio_direction_output(CLK_PORT, 0) 
+#define CLK_OUT()       gpio_direction_output(CLK_PORT, 0)
 #define CLK_SET()       gpio_set_value(CLK_PORT, GPIO_HIGH)
 #define CLK_CLR()       gpio_set_value(CLK_PORT, GPIO_LOW)
-#define TXD_OUT()       gpio_direction_output(TXD_PORT, 0) 
+#define TXD_OUT()       gpio_direction_output(TXD_PORT, 0)
 #define TXD_SET()       gpio_set_value(TXD_PORT, GPIO_HIGH)
 #define TXD_CLR()       gpio_set_value(TXD_PORT, GPIO_LOW)
 
-static struct rk2818lcd_info *gLcd_info = NULL;
+static struct rk29lcd_info *gLcd_info = NULL;
 
 #define DRVDelayUs(i)   udelay(i*2)
 
 int init(void);
 int standby(u8 enable);
 
-void set_lcd_info(struct rk28fb_screen *screen, struct rk2818lcd_info *lcd_info )
+void set_lcd_info(struct rk29fb_screen *screen, struct rk2918lcd_info *lcd_info )
 {
     /* screen type & face */
     screen->type = OUT_TYPE;
@@ -153,7 +153,7 @@ void spi_screenreg_set(u32 Data)
        CS_SET();
        CLK_CLR();
        TXD_CLR();
-       DRVDelayUs(2); 
+       DRVDelayUs(2);
 
 }
 
index 1a3816d5e065a2476bdcf4d213710a73e4e53212..43b96070b0c8d50c0a7b175529f5b4681962d9d3 100755 (executable)
@@ -1,7 +1,7 @@
 /* This Lcd Driver is HSD070IDW1 write by cst 2009.10.27 */
 #include <linux/fb.h>
 #include <linux/delay.h>
-#include "../../rk2818_fb.h"
+#include "../../rk29_fb.h"
 #include <mach/gpio.h>
 #include <mach/iomux.h>
 #include <mach/board.h>
 #define CS_OUT()        gpio_direction_output(CS_PORT, 0)
 #define CS_SET()        gpio_set_value(CS_PORT, GPIO_HIGH)
 #define CS_CLR()        gpio_set_value(CS_PORT, GPIO_LOW)
-#define CLK_OUT()       gpio_direction_output(CLK_PORT, 0) 
+#define CLK_OUT()       gpio_direction_output(CLK_PORT, 0)
 #define CLK_SET()       gpio_set_value(CLK_PORT, GPIO_HIGH)
 #define CLK_CLR()       gpio_set_value(CLK_PORT, GPIO_LOW)
-#define TXD_OUT()       gpio_direction_output(TXD_PORT, 0) 
+#define TXD_OUT()       gpio_direction_output(TXD_PORT, 0)
 #define TXD_SET()       gpio_set_value(TXD_PORT, GPIO_HIGH)
 #define TXD_CLR()       gpio_set_value(TXD_PORT, GPIO_LOW)
 
-static struct rk2818lcd_info *gLcd_info = NULL;
+static struct rk29lcd_info *gLcd_info = NULL;
 
 #define DRVDelayUs(i)   udelay(i*2)
 
 int init(void);
 int standby(u8 enable);
 
-void set_lcd_info(struct rk28fb_screen *screen, struct rk2818lcd_info *lcd_info )
+void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info )
 {
     /* screen type & face */
     screen->type = OUT_TYPE;
@@ -83,12 +83,12 @@ void set_lcd_info(struct rk28fb_screen *screen, struct rk2818lcd_info *lcd_info
 
     /* Operation function*/
     /*screen->init = init;*/
-    screen->init = NULL; 
+    screen->init = NULL;
     screen->standby = standby;
     if(lcd_info)
         gLcd_info = lcd_info;
 }
-//cannot need init,so set screen->init = null at rk28_fb.c file 
+//cannot need init,so set screen->init = null at rk29_fb.c file
 
 void spi_screenreg_set(u32 Addr, u32 Data)
 {
@@ -218,19 +218,19 @@ int standby(u8 enable)
     if(gLcd_info)
         gLcd_info->io_deinit();
 #else
-    
+
     GPIOSetPinDirection(GPIOPortB_Pin3, GPIO_OUT);
     GPIOSetPinDirection(GPIOPortB_Pin2, GPIO_OUT);
 
     if(enable)
        {
-        GPIOSetPinLevel(GPIOPortB_Pin3, GPIO_LOW);          
-        GPIOSetPinLevel(GPIOPortB_Pin2, GPIO_HIGH);          
+        GPIOSetPinLevel(GPIOPortB_Pin3, GPIO_LOW);
+        GPIOSetPinLevel(GPIOPortB_Pin2, GPIO_HIGH);
        }
     else
        {
-        GPIOSetPinLevel(GPIOPortB_Pin3, GPIO_HIGH);          
-        GPIOSetPinLevel(GPIOPortB_Pin2, GPIO_LOW);          
+        GPIOSetPinLevel(GPIOPortB_Pin3, GPIO_HIGH);
+        GPIOSetPinLevel(GPIOPortB_Pin2, GPIO_LOW);
         }
 #endif
     return 0;
index f84ed97ceaa594384a9a72ccc645b6d7f375a88b..4990d9aeee5376f42b003c6cfe280f7c1770d92d 100755 (executable)
@@ -1,6 +1,6 @@
 #include <linux/fb.h>
 #include <linux/delay.h>
-#include "../../rk2818_fb.h"
+#include "../../rk29_fb.h"
 #include <mach/gpio.h>
 #include <mach/iomux.h>
 #include <mach/board.h>
@@ -15,7 +15,7 @@
 /* Timing */
 #define H_PW                   8
 #define H_BP                   6
-#define H_VD                   320     //***800 
+#define H_VD                   320     //***800
 #define H_FP                   60
 
 #define V_PW                   12
 #define V_FP                   40
 
 /* Other */
-#define DCLK_POL               0 
+#define DCLK_POL               0
 #define SWAP_RB                        0
 
-static struct rk2818lcd_info *gLcd_info = NULL;
+static struct rk29lcd_info *gLcd_info = NULL;
 int init(void);
 int standby(u8 enable);
 
@@ -39,10 +39,10 @@ int standby(u8 enable);
 #define CS_OUT()        gpio_direction_output(CS_PORT, 0)
 #define CS_SET()        gpio_set_value(CS_PORT, GPIO_HIGH)
 #define CS_CLR()        gpio_set_value(CS_PORT, GPIO_LOW)
-#define CLK_OUT()       gpio_direction_output(CLK_PORT, 0) 
+#define CLK_OUT()       gpio_direction_output(CLK_PORT, 0)
 #define CLK_SET()       gpio_set_value(CLK_PORT, GPIO_HIGH)
 #define CLK_CLR()       gpio_set_value(CLK_PORT, GPIO_LOW)
-#define TXD_OUT()       gpio_direction_output(TXD_PORT, 0) 
+#define TXD_OUT()       gpio_direction_output(TXD_PORT, 0)
 #define TXD_SET()       gpio_set_value(TXD_PORT, GPIO_HIGH)
 #define TXD_CLR()       gpio_set_value(TXD_PORT, GPIO_LOW)
 
@@ -52,41 +52,41 @@ static void screen_set_iomux(u8 enable)
     int ret=-1;
     if(enable)
     {
-        rk2818_mux_api_set(GPIOH6_IQ_SEL_NAME, 0);
-        ret = gpio_request(RK2818_PIN_PH6, NULL); 
+        rk29_mux_api_set(GPIOH6_IQ_SEL_NAME, 0);
+        ret = gpio_request(RK29_PIN_PH6, NULL);
         if(0)//(ret != 0)
         {
-            gpio_free(RK2818_PIN_PH6);
-            printk(">>>>>> lcd cs gpio_request err \n ");           
+            gpio_free(RK29_PIN_PH6);
+            printk(">>>>>> lcd cs gpio_request err \n ");
             goto pin_err;
-        }  
-        
-        rk2818_mux_api_set(GPIOE_I2C0_SEL_NAME, 1);                   
+        }
 
-        ret = gpio_request(RK2818_PIN_PE5, NULL); 
+        rk29_mux_api_set(GPIOE_I2C0_SEL_NAME, 1);
+
+        ret = gpio_request(RK29_PIN_PE5, NULL);
         if(0)//(ret != 0)
         {
-            gpio_free(RK2818_PIN_PE5);
-            printk(">>>>>> lcd clk gpio_request err \n "); 
+            gpio_free(RK29_PIN_PE5);
+            printk(">>>>>> lcd clk gpio_request err \n ");
             goto pin_err;
-        }  
-        
-        ret = gpio_request(RK2818_PIN_PE4, NULL); 
+        }
+
+        ret = gpio_request(RK29_PIN_PE4, NULL);
         if(0)//(ret != 0)
         {
-            gpio_free(RK2818_PIN_PE4);
-            printk(">>>>>> lcd txd gpio_request err \n "); 
+            gpio_free(RK29_PIN_PE4);
+            printk(">>>>>> lcd txd gpio_request err \n ");
             goto pin_err;
-        }        
+        }
     }
     else
     {
-         gpio_free(RK2818_PIN_PH6); 
-       //  rk2818_mux_api_set(CXGPIO_HSADC_SEL_NAME, 1);
+         gpio_free(RK29_PIN_PH6);
+       //  rk29_mux_api_set(CXGPIO_HSADC_SEL_NAME, 1);
 
-         gpio_free(RK2818_PIN_PE5);   
-         gpio_free(RK2818_PIN_PE4); 
-         rk2818_mux_api_set(GPIOE_I2C0_SEL_NAME, 0);
+         gpio_free(RK29_PIN_PE5);
+         gpio_free(RK29_PIN_PE4);
+         rk29_mux_api_set(GPIOE_I2C0_SEL_NAME, 0);
     }
     return ;
 pin_err:
@@ -100,8 +100,8 @@ void spi_screenreg_set(u32 Addr, u32 Data)
 #define DRVDelayUs(i)   udelay(i*2)
 
     u32 i;
-    u32 control_bit; 
-       
+    u32 control_bit;
+
 
     TXD_OUT();
     CLK_OUT();
@@ -114,10 +114,10 @@ void spi_screenreg_set(u32 Addr, u32 Data)
     CLK_SET();
     DRVDelayUs(2);
 
-       CS_CLR(); 
-       control_bit = 0x70<<8; 
-       Addr = (control_bit | Addr); 
-       //printk("addr is 0x%x \n", Addr); 
+       CS_CLR();
+       control_bit = 0x70<<8;
+       Addr = (control_bit | Addr);
+       //printk("addr is 0x%x \n", Addr);
        for(i = 0; i < 16; i++)  //reg
        {
                if(Addr &(1<<(15-i)))
@@ -130,17 +130,17 @@ void spi_screenreg_set(u32 Addr, u32 Data)
                DRVDelayUs(2);
                CLK_SET();
                DRVDelayUs(2);
-       } 
+       }
 
        CS_SET();
-       TXD_SET(); 
-       CLK_SET(); 
+       TXD_SET();
+       CLK_SET();
        DRVDelayUs(2);
-       CS_CLR(); 
-       
-       control_bit = 0x72<<8; 
-       Data = (control_bit | Data); 
-       //printk("data is 0x%x \n", Data); 
+       CS_CLR();
+
+       control_bit = 0x72<<8;
+       Data = (control_bit | Data);
+       //printk("data is 0x%x \n", Data);
        for(i = 0; i < 16; i++)  //data
        {
                if(Data &(1<<(15-i)))
@@ -161,29 +161,29 @@ void spi_screenreg_set(u32 Addr, u32 Data)
        DRVDelayUs(2);
 }
 
-void set_lcd_info(struct rk28fb_screen *screen, struct rk2818lcd_info *lcd_info )
+void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info )
 {
-       //printk("lcd_hx8357 set_lcd_info \n"); 
+       //printk("lcd_hx8357 set_lcd_info \n");
     /* screen type & face */
     screen->type = OUT_TYPE;
     screen->face = OUT_FACE;
+
     /* Screen size */
     screen->x_res = H_VD;
     screen->y_res = V_VD;
 
     /* Timing */
     screen->pixclock = OUT_CLK;
-       screen->left_margin = H_BP;             /*>2*/ 
-       screen->right_margin = H_FP;    /*>2*/ 
-       screen->hsync_len = H_PW;               /*>2*/ //***all > 326, 4<PW+BP<15, 
-       screen->upper_margin = V_BP;    /*>2*/ 
-       screen->lower_margin = V_FP;    /*>2*/ 
-       screen->vsync_len = V_PW;               /*>6*/ 
+       screen->left_margin = H_BP;             /*>2*/
+       screen->right_margin = H_FP;    /*>2*/
+       screen->hsync_len = H_PW;               /*>2*/ //***all > 326, 4<PW+BP<15,
+       screen->upper_margin = V_BP;    /*>2*/
+       screen->lower_margin = V_FP;    /*>2*/
+       screen->vsync_len = V_PW;               /*>6*/
 
        /* Pin polarity */
-       screen->pin_hsync = 0; 
-       screen->pin_vsync = 0; 
+       screen->pin_hsync = 0;
+       screen->pin_vsync = 0;
        screen->pin_den = 0;
        screen->pin_dclk = DCLK_POL;
 
@@ -202,12 +202,12 @@ void set_lcd_info(struct rk28fb_screen *screen, struct rk2818lcd_info *lcd_info
 }
 
 int init(void)
-{ 
+{
 
     if(gLcd_info)
         gLcd_info->io_init();
 
-#if 0                                                                                  //***Õâ¾ä´úÂëÊDz»ÊÇд´íÁË 
+#if 0                                                                                  //***Õâ¾ä´úÂëÊDz»ÊÇд´íÁË
     spi_screenreg_set(0x02, 0x07);
     spi_screenreg_set(0x03, 0x5f);
     spi_screenreg_set(0x04, 0x17);
@@ -243,136 +243,136 @@ int init(void)
     spi_screenreg_set(0x20, 0xF0);
     spi_screenreg_set(0x21, 0xF0);
     spi_screenreg_set(0x22, 0x09);
-#else 
-       spi_screenreg_set(0xff, 0x00); 
-       spi_screenreg_set(0x16, 0x08); 
-       spi_screenreg_set(0x01, 0x02); 
-       spi_screenreg_set(0xe2, 0x00); 
-       spi_screenreg_set(0xe3, 0x00); 
-       spi_screenreg_set(0xf2, 0x00); 
-       spi_screenreg_set(0xe4, 0x1c); 
-       spi_screenreg_set(0xe5, 0x1c); 
-       spi_screenreg_set(0xe6, 0x00); 
-       spi_screenreg_set(0xe7, 0x1c); 
-       
-       spi_screenreg_set(0x19, 0x01); 
-       mdelay(10); 
-       spi_screenreg_set(0x2a, 0x00); 
-       spi_screenreg_set(0x2b, 0x13); 
-       spi_screenreg_set(0x2f, 0x01); 
-       spi_screenreg_set(0x02, 0x00); 
-       spi_screenreg_set(0x03, 0x00); 
-       spi_screenreg_set(0x04, 0x01); 
-       spi_screenreg_set(0x05, 0x3f); 
-       spi_screenreg_set(0x06, 0x00); 
-       spi_screenreg_set(0x07, 0x00); 
-
-       spi_screenreg_set(0x08, 0x01); 
-       spi_screenreg_set(0x09, 0xdf); 
-       spi_screenreg_set(0x24, 0x91); 
-       spi_screenreg_set(0x25, 0x8a); 
-       spi_screenreg_set(0x29, 0x01); 
-       spi_screenreg_set(0x18, 0x22); 
-       spi_screenreg_set(0x1b, 0x30); 
-       mdelay(10); 
-       spi_screenreg_set(0x1d, 0x22); 
-       mdelay(10); 
-       spi_screenreg_set(0x40, 0x00); 
-       spi_screenreg_set(0x41, 0x3c); 
-       spi_screenreg_set(0x42, 0x38); 
-       spi_screenreg_set(0x43, 0x34); 
-       spi_screenreg_set(0x44, 0x2e); 
-       spi_screenreg_set(0x45, 0x2f); 
-       spi_screenreg_set(0x46, 0x41); 
-       spi_screenreg_set(0x47, 0x7d); 
-       spi_screenreg_set(0x48, 0x0b); 
-       spi_screenreg_set(0x49, 0x05); 
-       spi_screenreg_set(0x4a, 0x06); 
-       spi_screenreg_set(0x4b, 0x12); 
-       spi_screenreg_set(0x4c, 0x16); 
-       spi_screenreg_set(0x50, 0x10); 
-       spi_screenreg_set(0x51, 0x11); 
-       spi_screenreg_set(0x52, 0x0b); 
-       spi_screenreg_set(0x53, 0x07); 
-       spi_screenreg_set(0x54, 0x03); 
-       spi_screenreg_set(0x55, 0x3f); 
-       spi_screenreg_set(0x56, 0x02); 
-       spi_screenreg_set(0x57, 0x3e); 
-       spi_screenreg_set(0x58, 0x09); 
-       spi_screenreg_set(0x59, 0x0d); 
-       spi_screenreg_set(0x5a, 0x19); 
-       spi_screenreg_set(0x5b, 0x1a); 
-       spi_screenreg_set(0x5c, 0x14); 
-       spi_screenreg_set(0x5d, 0xc0); 
-       spi_screenreg_set(0x1a, 0x05); 
-       mdelay(10); 
-       
-       spi_screenreg_set(0x1c, 0x03); 
-       mdelay(10); 
-       spi_screenreg_set(0x1f, 0x90); 
-       mdelay(10); 
-       spi_screenreg_set(0x1f, 0xd2); 
-       mdelay(10); 
-       spi_screenreg_set(0x28, 0x04); 
-       mdelay(40); 
-       spi_screenreg_set(0x28, 0x38); 
-       mdelay(40); 
-       spi_screenreg_set(0x28, 0x3c); 
-       mdelay(40); 
-       spi_screenreg_set(0x80, 0x00); 
-       spi_screenreg_set(0x81, 0x00); 
-       spi_screenreg_set(0x82, 0x00); 
-       spi_screenreg_set(0x83, 0x00); 
-       
-       spi_screenreg_set(0x60, 0x08); 
-       spi_screenreg_set(0x31, 0x02); 
-       spi_screenreg_set(0x32, 0x08 /*0x00*/); 
-       spi_screenreg_set(0x17, 0x60);  //***RGB666 
-       spi_screenreg_set(0x2d, 0x1f); 
-       spi_screenreg_set(0xe8, 0x90); 
-#endif 
+#else
+       spi_screenreg_set(0xff, 0x00);
+       spi_screenreg_set(0x16, 0x08);
+       spi_screenreg_set(0x01, 0x02);
+       spi_screenreg_set(0xe2, 0x00);
+       spi_screenreg_set(0xe3, 0x00);
+       spi_screenreg_set(0xf2, 0x00);
+       spi_screenreg_set(0xe4, 0x1c);
+       spi_screenreg_set(0xe5, 0x1c);
+       spi_screenreg_set(0xe6, 0x00);
+       spi_screenreg_set(0xe7, 0x1c);
+
+       spi_screenreg_set(0x19, 0x01);
+       mdelay(10);
+       spi_screenreg_set(0x2a, 0x00);
+       spi_screenreg_set(0x2b, 0x13);
+       spi_screenreg_set(0x2f, 0x01);
+       spi_screenreg_set(0x02, 0x00);
+       spi_screenreg_set(0x03, 0x00);
+       spi_screenreg_set(0x04, 0x01);
+       spi_screenreg_set(0x05, 0x3f);
+       spi_screenreg_set(0x06, 0x00);
+       spi_screenreg_set(0x07, 0x00);
+
+       spi_screenreg_set(0x08, 0x01);
+       spi_screenreg_set(0x09, 0xdf);
+       spi_screenreg_set(0x24, 0x91);
+       spi_screenreg_set(0x25, 0x8a);
+       spi_screenreg_set(0x29, 0x01);
+       spi_screenreg_set(0x18, 0x22);
+       spi_screenreg_set(0x1b, 0x30);
+       mdelay(10);
+       spi_screenreg_set(0x1d, 0x22);
+       mdelay(10);
+       spi_screenreg_set(0x40, 0x00);
+       spi_screenreg_set(0x41, 0x3c);
+       spi_screenreg_set(0x42, 0x38);
+       spi_screenreg_set(0x43, 0x34);
+       spi_screenreg_set(0x44, 0x2e);
+       spi_screenreg_set(0x45, 0x2f);
+       spi_screenreg_set(0x46, 0x41);
+       spi_screenreg_set(0x47, 0x7d);
+       spi_screenreg_set(0x48, 0x0b);
+       spi_screenreg_set(0x49, 0x05);
+       spi_screenreg_set(0x4a, 0x06);
+       spi_screenreg_set(0x4b, 0x12);
+       spi_screenreg_set(0x4c, 0x16);
+       spi_screenreg_set(0x50, 0x10);
+       spi_screenreg_set(0x51, 0x11);
+       spi_screenreg_set(0x52, 0x0b);
+       spi_screenreg_set(0x53, 0x07);
+       spi_screenreg_set(0x54, 0x03);
+       spi_screenreg_set(0x55, 0x3f);
+       spi_screenreg_set(0x56, 0x02);
+       spi_screenreg_set(0x57, 0x3e);
+       spi_screenreg_set(0x58, 0x09);
+       spi_screenreg_set(0x59, 0x0d);
+       spi_screenreg_set(0x5a, 0x19);
+       spi_screenreg_set(0x5b, 0x1a);
+       spi_screenreg_set(0x5c, 0x14);
+       spi_screenreg_set(0x5d, 0xc0);
+       spi_screenreg_set(0x1a, 0x05);
+       mdelay(10);
+
+       spi_screenreg_set(0x1c, 0x03);
+       mdelay(10);
+       spi_screenreg_set(0x1f, 0x90);
+       mdelay(10);
+       spi_screenreg_set(0x1f, 0xd2);
+       mdelay(10);
+       spi_screenreg_set(0x28, 0x04);
+       mdelay(40);
+       spi_screenreg_set(0x28, 0x38);
+       mdelay(40);
+       spi_screenreg_set(0x28, 0x3c);
+       mdelay(40);
+       spi_screenreg_set(0x80, 0x00);
+       spi_screenreg_set(0x81, 0x00);
+       spi_screenreg_set(0x82, 0x00);
+       spi_screenreg_set(0x83, 0x00);
+
+       spi_screenreg_set(0x60, 0x08);
+       spi_screenreg_set(0x31, 0x02);
+       spi_screenreg_set(0x32, 0x08 /*0x00*/);
+       spi_screenreg_set(0x17, 0x60);  //***RGB666
+       spi_screenreg_set(0x2d, 0x1f);
+       spi_screenreg_set(0xe8, 0x90);
+#endif
     if(gLcd_info)
         gLcd_info->io_deinit();
 
     return 0;
 }
 
-int standby(u8 enable) //***enable =1 means suspend, 0 means resume 
+int standby(u8 enable) //***enable =1 means suspend, 0 means resume
 {
-       
+
     if(gLcd_info)
         gLcd_info->io_init();
        if(enable) {
                //printk("---------hx8357   screen suspend--------------\n");
-               #if 0 
-               spi_screenreg_set(0x03, 0xde); 
+               #if 0
+               spi_screenreg_set(0x03, 0xde);
                #else
                //modify by robert
                #if 0
-               spi_screenreg_set(0x1f, 0x91); 
+               spi_screenreg_set(0x1f, 0x91);
                spi_screenreg_set(0x19, 0x00);
                #else
-               spi_screenreg_set(0x28, 0x38); 
+               spi_screenreg_set(0x28, 0x38);
                msleep(10);
                spi_screenreg_set(0x28, 0x24);
                msleep(10);
                spi_screenreg_set(0x28, 0x04);
                #endif
                //modify end
-               #endif 
-       } else { 
+               #endif
+       } else {
                //printk("---------  hx8357 screen resume--------------\n ");
-               #if 0 
-               spi_screenreg_set(0x03, 0x5f); 
-               #else 
+               #if 0
+               spi_screenreg_set(0x03, 0x5f);
+               #else
                //modify by robert
                #if 0
-               spi_screenreg_set(0x19, 0x01); 
-               spi_screenreg_set(0x1f, 0x90); 
-               mdelay(10); 
+               spi_screenreg_set(0x19, 0x01);
+               spi_screenreg_set(0x1f, 0x90);
+               mdelay(10);
                spi_screenreg_set(0x1f, 0xd2);
                #else
-               spi_screenreg_set(0x28, 0x38); 
+               spi_screenreg_set(0x28, 0x38);
                msleep(10);
                spi_screenreg_set(0x28, 0x3c);
                msleep(10);
@@ -380,10 +380,10 @@ int standby(u8 enable)    //***enable =1 means suspend, 0 means resume
                spi_screenreg_set(0x81, 0x00);
                spi_screenreg_set(0x82, 0x00);
                spi_screenreg_set(0x83, 0x00);
-               
+
                #endif
                //modify end
-               #endif 
+               #endif
        }
 
     if(gLcd_info)
index aadad64f8426d0c5ff764f90aa55061680bf5e81..e1b63fef9569f662ad8521e1832bd1cc6d740efa 100755 (executable)
@@ -1,6 +1,6 @@
 #include <linux/fb.h>
 #include <linux/delay.h>
-#include "../../rk2818_fb.h"
+#include "../../rk29_fb.h"
 #include <mach/gpio.h>
 #include <mach/iomux.h>
 #include <mach/board.h>
 #define CS_OUT()        gpio_direction_output(CS_PORT, 0)
 #define CS_SET()        gpio_set_value(CS_PORT, GPIO_HIGH)
 #define CS_CLR()        gpio_set_value(CS_PORT, GPIO_LOW)
-#define CLK_OUT()       gpio_direction_output(CLK_PORT, 0) 
+#define CLK_OUT()       gpio_direction_output(CLK_PORT, 0)
 #define CLK_SET()       gpio_set_value(CLK_PORT, GPIO_HIGH)
 #define CLK_CLR()       gpio_set_value(CLK_PORT, GPIO_LOW)
-#define TXD_OUT()       gpio_direction_output(TXD_PORT, 0) 
+#define TXD_OUT()       gpio_direction_output(TXD_PORT, 0)
 #define TXD_SET()       gpio_set_value(TXD_PORT, GPIO_HIGH)
 #define TXD_CLR()       gpio_set_value(TXD_PORT, GPIO_LOW)
 #define TXD_IN()        gpio_direction_input(TXD_PORT)
@@ -45,7 +45,7 @@
 
 
 #define delay_us(i)      udelay(i)
-static struct rk2818lcd_info *gLcd_info = NULL;
+static struct rk29lcd_info *gLcd_info = NULL;
 
 u32 spi_screenreg_get(u32 Addr)
 {
@@ -422,7 +422,7 @@ int lcd_standby(u8 enable)
 }
 
 
-void set_lcd_info(struct rk28fb_screen *screen, struct rk2818lcd_info *lcd_info )
+void set_lcd_info(struct rk29fb_screen *screen, struct rk2918lcd_info *lcd_info )
 {
     /* screen type & face */
     screen->type = OUT_TYPE;
index 99ed77bc62fac55d8b91452e79044709479b046a..66941e23910c3345af8e0ebac49a5fd38cfffb0d 100755 (executable)
@@ -1,6 +1,6 @@
 #include <linux/fb.h>
 #include <linux/delay.h>
-#include "../../rk2818_fb.h"
+#include "../../rk29_fb.h"
 #include <mach/gpio.h>
 #include <mach/iomux.h>
 #include "screen.h"
@@ -378,7 +378,7 @@ int lcd_disparea(u8 area)
 
 }
 
-void set_lcd_info(struct rk28fb_screen *screen)
+void set_lcd_info(struct rk29fb_screen *screen)
 {
     /* screen type & face */
     screen->type = OUT_TYPE;
index f363e5cc622e1bcc7a59518d37be2543c647c4bf..d03cbd615d1e64d23f1a04accbb4d86802183b45 100755 (executable)
@@ -1,13 +1,13 @@
 
 #include <linux/fb.h>
 #include <linux/delay.h>
-#include "../../rk2818_fb.h"
+#include "../../rk29_fb.h"
 #include <mach/gpio.h>
 #include <mach/iomux.h>
 #include "screen.h"
 
-void set_lcd_info(struct rk28fb_screen *screen)
+void set_lcd_info(struct rk29fb_screen *screen)
 {
-    memset(screen, 0, sizeof(struct rk28fb_screen));
+    memset(screen, 0, sizeof(struct rk29fb_screen));
     screen->face = OUT_P666;
 }
index cf4b6adea87a36de30e1a353abcb16d713b293bc..804170aeb25a32fa65f2b88a2b3295b9199029f6 100755 (executable)
@@ -1,6 +1,6 @@
 #include <linux/fb.h>
 #include <linux/delay.h>
-#include "../../rk2818_fb.h"
+#include "../../rk29_fb.h"
 #include <mach/gpio.h>
 #include <mach/iomux.h>
 #include "screen.h"
@@ -118,41 +118,41 @@ void s1d13521if_init_gpio(void)
 {
     int i;
     int ret=0;
-    
-       rk2818_mux_api_set(GPIOC_LCDC18BIT_SEL_NAME, IOMUXB_GPIO0_C01);
-       rk2818_mux_api_set(GPIOC_LCDC24BIT_SEL_NAME, IOMUXB_GPIO0_C2_7);
-    
+
+       rk29_mux_api_set(GPIOC_LCDC18BIT_SEL_NAME, IOMUXB_GPIO0_C01);
+       rk29_mux_api_set(GPIOC_LCDC24BIT_SEL_NAME, IOMUXB_GPIO0_C2_7);
+
        for(i = 0; i < 8; i++)
     {
                if(i == 1 || i == 6)//HIRQ, HRDY
         {
-               ret = gpio_request(GPIO_RESET_L+i, NULL); 
+               ret = gpio_request(GPIO_RESET_L+i, NULL);
             if(ret != 0)
             {
                 gpio_free(GPIO_RESET_L+i);
-                printk(">>>>>> lcd cs gpio_request err \n ");                        
-            } 
+                printk(">>>>>> lcd cs gpio_request err \n ");
+            }
             gpio_direction_input(GPIO_RESET_L+i);
             gpio_free(GPIO_RESET_L+i);
-               } 
+               }
         else  //RESET_L, HD/C, HCS_L, HRD_L, HWE_L, RMODE
                {
             ret = gpio_request(GPIO_RESET_L+i, NULL);
             if(ret != 0)
             {
                 gpio_free(GPIO_RESET_L+i);
-                printk(">>>>>> lcd cs gpio_request err \n ");                        
-            } 
+                printk(">>>>>> lcd cs gpio_request err \n ");
+            }
             gpio_direction_output(GPIO_RESET_L+i, 0);
             gpio_set_value(GPIO_RESET_L+i, GPIO_HIGH);
-            gpio_free(GPIO_RESET_L+i);                 
+            gpio_free(GPIO_RESET_L+i);
                }
        }
 }
 
 void s1d13521if_set_reset(void)
 {
-    gpio_request(GPIO_RMODE, 0); 
+    gpio_request(GPIO_RMODE, 0);
        gpio_set_value(GPIO_RMODE, GPIO_HIGH);
     gpio_request(GPIO_RESET_L, 0);
 
index cbaee4902beae50414f208f4f3efb9d48d3b0d34..6764031d92981f854fffd977907ebc23891e22f6 100755 (executable)
@@ -1,6 +1,6 @@
 #include <linux/fb.h>
 #include <linux/delay.h>
-#include "../../rk2818_fb.h"
+#include "../../rk29_fb.h"
 #include <mach/gpio.h>
 #include <mach/iomux.h>
 #include <mach/board.h>
 #define CLK_PORT        gLcd_info->clk_pin
 #define CS_PORT         gLcd_info->cs_pin
 
+#if 0
 #define CS_OUT()        gpio_direction_output(CS_PORT, 0)
 #define CS_SET()        gpio_set_value(CS_PORT, GPIO_HIGH)
 #define CS_CLR()        gpio_set_value(CS_PORT, GPIO_LOW)
-#define CLK_OUT()       gpio_direction_output(CLK_PORT, 0) 
+#define CLK_OUT()       gpio_direction_output(CLK_PORT, 0)
 #define CLK_SET()       gpio_set_value(CLK_PORT, GPIO_HIGH)
 #define CLK_CLR()       gpio_set_value(CLK_PORT, GPIO_LOW)
-#define TXD_OUT()       gpio_direction_output(TXD_PORT, 0) 
+#define TXD_OUT()       gpio_direction_output(TXD_PORT, 0)
 #define TXD_SET()       gpio_set_value(TXD_PORT, GPIO_HIGH)
 #define TXD_CLR()       gpio_set_value(TXD_PORT, GPIO_LOW)
+#endif
 
-static struct rk2818lcd_info *gLcd_info = NULL;
+
+static struct rk29lcd_info *gLcd_info = NULL;
 int init(void);
 int standby(u8 enable);
 
-void set_lcd_info(struct rk28fb_screen *screen, struct rk2818lcd_info *lcd_info )
+void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info )
 {
     /* screen type & face */
     screen->type = OUT_TYPE;
@@ -84,7 +87,7 @@ void set_lcd_info(struct rk28fb_screen *screen, struct rk2818lcd_info *lcd_info
         gLcd_info = lcd_info;
 }
 
-
+#if 0
 void spi_screenreg_set(u32 Addr, u32 Data)
 {
 
@@ -155,13 +158,15 @@ void spi_screenreg_set(u32 Addr, u32 Data)
        DRVDelayUs(2);
 
 }
+#endif
 
 
 int init(void)
-{    
+{
     if(gLcd_info)
         gLcd_info->io_init();
 
+#if 0
     spi_screenreg_set(0x02, 0x07);
     spi_screenreg_set(0x03, 0x5f);
     spi_screenreg_set(0x04, 0x17);
@@ -197,6 +202,7 @@ int init(void)
     spi_screenreg_set(0x20, 0xF0);
     spi_screenreg_set(0x21, 0xF0);
     spi_screenreg_set(0x22, 0x09);
+#endif
 
     if(gLcd_info)
         gLcd_info->io_deinit();
@@ -204,14 +210,16 @@ int init(void)
 }
 
 int standby(u8 enable)
-{       
+{
     if(gLcd_info)
         gLcd_info->io_init();
+#if 0
        if(enable) {
                spi_screenreg_set(0x03, 0xde);
        } else {
                spi_screenreg_set(0x03, 0x5f);
        }
+#endif
     if(gLcd_info)
         gLcd_info->io_deinit();
     return 0;
index b952281443e661c8f6c794b7d4a938ea4908fce8..d9f0e133e1b222fe489bc9edf3b2548474432360 100755 (executable)
@@ -1,12 +1,12 @@
 #include <linux/fb.h>
 #include <linux/delay.h>
-#include "../../rk2818_fb.h"
+#include "../../rk29_fb.h"
 #include <mach/gpio.h>
 #include <mach/iomux.h>
 #include <mach/board.h>
 #include "screen.h"
 
+
 /* Base */
 #define OUT_TYPE               SCREEN_RGB
 #define OUT_FACE               OUT_P888
 #define CS_OUT()        gpio_direction_output(CS_PORT, 0)
 #define CS_SET()        gpio_set_value(CS_PORT, GPIO_HIGH)
 #define CS_CLR()        gpio_set_value(CS_PORT, GPIO_LOW)
-#define CLK_OUT()       gpio_direction_output(CLK_PORT, 0) 
+#define CLK_OUT()       gpio_direction_output(CLK_PORT, 0)
 #define CLK_SET()       gpio_set_value(CLK_PORT, GPIO_HIGH)
 #define CLK_CLR()       gpio_set_value(CLK_PORT, GPIO_LOW)
-#define TXD_OUT()       gpio_direction_output(TXD_PORT, 0) 
+#define TXD_OUT()       gpio_direction_output(TXD_PORT, 0)
 #define TXD_SET()       gpio_set_value(TXD_PORT, GPIO_HIGH)
 #define TXD_CLR()       gpio_set_value(TXD_PORT, GPIO_LOW)
 
 #define DRVDelayUs(i)   udelay(i*2)
 
-static struct rk2818lcd_info *gLcd_info = NULL;
+static struct rk29lcd_info *gLcd_info = NULL;
 int lcd_init(void);
 int lcd_standby(u8 enable);
 
-void set_lcd_info(struct rk28fb_screen *screen, struct rk2818lcd_info *lcd_info )
+void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info )
 {
     /* screen type & face */
     screen->type = OUT_TYPE;
index 5794c3d708db4cfa9332c2f691de25390739f46a..b56e40841cd2efd4a60c3119806aad2fcc095113 100755 (executable)
@@ -33,7 +33,7 @@ typedef enum _MCU_STATUS {
 
 
 /* Sceen description */
-struct rk28fb_screen {
+struct rk29fb_screen {
     /* screen type & out face */
     u16 type;
     u16 face;
@@ -79,8 +79,8 @@ struct rk28fb_screen {
 
 };
 
-extern void set_lcd_info(struct rk28fb_screen *screen, struct rk2818lcd_info *lcd_info);
-extern void set_tv_info(struct rk28fb_screen *screen);
-extern void set_hdmi_info(struct rk28fb_screen *screen);
+extern void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info);
+extern void set_tv_info(struct rk29fb_screen *screen);
+extern void set_hdmi_info(struct rk29fb_screen *screen);
 
 
index 80064b19e2c0544f3030274acb0cf7a7da47bfb1..ac80ccfb987cedab411ae177000448cdbaedd86c 100755 (executable)
@@ -1,15 +1,15 @@
 
 #include <linux/fb.h>
 #include <linux/delay.h>
-#include "../../rk2818_fb.h"
+#include "../../rk29_fb.h"
 #include <mach/gpio.h>
 #include <mach/iomux.h>
 #include "screen.h"
 
 
 
-void set_tv_info(struct rk28fb_screen *screen)
+void set_tv_info(struct rk29fb_screen *screen)
 {
-    memset(screen, 0, sizeof(struct rk28fb_screen));
+    memset(screen, 0, sizeof(struct rk29fb_screen));
     screen->face = OUT_P666;
 }
diff --git a/drivers/video/rk29_fb.c b/drivers/video/rk29_fb.c
new file mode 100755 (executable)
index 0000000..e11f57f
--- /dev/null
@@ -0,0 +1,2150 @@
+/*
+ * drivers/video/rk29_fb.c
+ *
+ * Copyright (C) 2010 ROCKCHIP, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#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/device.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/backlight.h>
+#include <linux/timer.h>
+#include <linux/time.h>
+#include <linux/wait.h>
+#include <linux/earlysuspend.h>
+#include <linux/cpufreq.h>
+
+
+#include <asm/io.h>
+#include <asm/div64.h>
+#include <asm/uaccess.h>
+
+#include "rk29_fb.h"
+
+#ifdef CONFIG_PM
+#include <linux/pm.h>
+#endif
+
+#include <mach/iomux.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/rk29_iomap.h>
+//#include <asm/uaccess.h>
+
+#include "./display/screen/screen.h"
+
+
+#define WIN1_USE_DOUBLE_BUF     0       //win1 use double buf to accelerate display
+#define CURSOR_BUF_SIZE         256     //rk29 cursor need 256B buf
+
+#if 0
+       #define fbprintk(msg...)        printk(msg);
+#else
+       #define fbprintk(msg...)
+#endif
+
+
+#if 0
+       #define fbprintk2(msg...)       printk(msg);
+#else
+       #define fbprintk2(msg...)
+#endif
+
+#define LcdReadBit(inf, addr, msk)      ((inf->regbak.addr=inf->preg->addr)&(msk))
+#define LcdWrReg(inf, addr, val)        inf->preg->addr=inf->regbak.addr=(val)
+#define LcdRdReg(inf, addr)             (inf->preg->addr)
+#define LcdSetBit(inf, addr, msk)       inf->preg->addr=((inf->regbak.addr) |= (msk))
+#define LcdClrBit(inf, addr, msk)       inf->preg->addr=((inf->regbak.addr) &= ~(msk))
+#define LcdSetRegBit(inf, addr, msk)    inf->preg->addr=((inf->preg->addr) |= (msk))
+#define LcdMskReg(inf, addr, msk, val)  (inf->regbak.addr)&=~(msk);   inf->preg->addr=(inf->regbak.addr|=(val))
+
+
+#define IsMcuLandscape()                ((SCREEN_MCU==inf->cur_screen->type) && (0==inf->mcu_scandir))
+#define IsMcuUseFmk()                   ( (2==inf->cur_screen->mcu_usefmk) || (1==inf->cur_screen->mcu_usefmk))
+
+#define CalScaleW0(x, y)                    (((u32)x*0x1000)/y)
+
+struct rk29fb_rgb {
+       struct fb_bitfield      red;
+       struct fb_bitfield      green;
+       struct fb_bitfield      blue;
+       struct fb_bitfield      transp;
+};
+
+static struct rk29fb_rgb def_rgb_16 = {
+     red:    { offset: 11, length: 5, },
+     green:  { offset: 5,  length: 6, },
+     blue:   { offset: 0,  length: 5, },
+     transp: { offset: 0,  length: 0, },
+};
+
+struct win0_par {
+       u32 refcount;
+       u32     pseudo_pal[16];
+       u32 y_offset;
+       u32 uv_offset;
+
+    u8 par_seted;
+    u8 addr_seted;
+};
+
+struct win1_par {
+       u32 refcount;
+       u32     pseudo_pal[16];
+       int lstblank;
+};
+
+struct rk29fb_inf {
+    struct fb_info *win0fb;
+    struct fb_info *win1fb;
+
+    void __iomem *reg_vir_base;  // virtual basic address of lcdc register
+       u32 reg_phy_base;       // physical basic address of lcdc register
+       u32 len;               // physical map length of lcdc register
+
+    struct clk      *clk;
+    struct clk      *dclk;            //lcdc dclk
+    struct clk      *dclk_parent;     //lcdc dclk divider frequency source
+    struct clk      *dclk_divider;    //lcdc demodulator divider frequency
+    struct clk      *clk_share_mem;   //lcdc share memory frequency
+    unsigned long      dclk_rate;
+
+    /* lcdc reg base address and backup reg */
+    LCDC_REG *preg;
+    LCDC_REG regbak;
+
+       int in_suspend;
+
+    /* variable used in mcu panel */
+       int mcu_needflush;
+       int mcu_isrcnt;
+       u16 mcu_scandir;
+       struct timer_list mcutimer;
+       int mcu_status;
+       u8 mcu_fmksync;
+       int mcu_usetimer;
+       int mcu_stopflush;
+
+    /* external memery */
+       char __iomem *screen_base2;
+    __u32 smem_len2;
+    unsigned long  smem_start2;
+
+    char __iomem *cursor_base;   /* cursor Virtual address*/
+    __u32 cursor_size;           /* Amount of ioremapped VRAM or 0 */
+    unsigned long  cursor_start;
+
+    struct rk29fb_screen lcd_info;
+    struct rk29fb_screen tv_info[5];
+    struct rk29fb_screen hdmi_info[2];
+    struct rk29fb_screen *cur_screen;
+#ifdef CONFIG_CPU_FREQ
+    struct notifier_block freq_transition;
+#endif
+
+};
+
+typedef enum _TRSP_MODE
+{
+    TRSP_CLOSE = 0,
+    TRSP_FMREG,
+    TRSP_FMREGEX,
+    TRSP_FMRAM,
+    TRSP_FMRAMEX,
+    TRSP_MASK,
+    TRSP_INVAL
+} TRSP_MODE;
+
+
+struct platform_device *g_pdev = NULL;
+static int win1fb_set_par(struct fb_info *info);
+
+#if 0
+#define CHK_SUSPEND(inf)       \
+       if(inf->in_suspend)     {       \
+               fbprintk(">>>>>> fb is in suspend! return! \n");        \
+               return -EPERM;  \
+       }
+#else
+#define CHK_SUSPEND(inf)
+#endif
+
+static DECLARE_WAIT_QUEUE_HEAD(wq);
+static int wq_condition = 0;
+
+void set_lcd_pin(struct platform_device *pdev, int enable)
+{
+       struct rk29fb_info *mach_info = pdev->dev.platform_data;
+
+       unsigned display_on = mach_info->disp_on_pin;
+       unsigned lcd_standby = mach_info->standby_pin;
+
+       int display_on_pol = mach_info->disp_on_value;
+       int lcd_standby_pol = mach_info->standby_value;
+
+       fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
+       fbprintk(">>>>>> display_on(%d) = %d \n", display_on, enable ? display_on_pol : !display_on_pol);
+       fbprintk(">>>>>> lcd_standby(%d) = %d \n", lcd_standby, enable ? lcd_standby_pol : !lcd_standby_pol);
+
+    // set display_on
+
+    if(display_on != INVALID_GPIO)
+        {
+        gpio_direction_output(display_on, 0);
+               gpio_set_value(display_on, enable ? display_on_pol : !display_on_pol);
+    }
+    if(lcd_standby != INVALID_GPIO)
+    {
+        gpio_direction_output(lcd_standby, 0);
+               gpio_set_value(lcd_standby, enable ? lcd_standby_pol : !lcd_standby_pol);
+    }
+}
+
+int mcu_do_refresh(struct rk29fb_inf *inf)
+{
+    if(inf->mcu_stopflush)  return 0;
+
+    if(SCREEN_MCU!=inf->cur_screen->type)   return 0;
+
+    // use frame mark
+    if(IsMcuUseFmk())
+    {
+        inf->mcu_needflush = 1;
+        return 0;
+    }
+
+    // not use frame mark
+    if(LcdReadBit(inf, MCU_TIMING_CTRL, m_MCU_HOLDMODE_SELECT))
+    {
+        if(!LcdReadBit(inf, MCU_TIMING_CTRL, m_MCU_HOLD_STATUS))
+        {
+            inf->mcu_needflush = 1;
+        }
+        else
+        {
+            if(inf->cur_screen->refresh)    inf->cur_screen->refresh(REFRESH_PRE);
+            inf->mcu_needflush = 0;
+            inf->mcu_isrcnt = 0;
+            LcdSetRegBit(inf, MCU_TIMING_CTRL, m_MCU_HOLDMODE_FRAME_ST);
+        }
+    }
+    return 0;
+}
+
+
+void mcutimer_callback(unsigned long arg)
+{
+    struct rk29fb_inf *inf = platform_get_drvdata(g_pdev);
+    static int waitcnt = 0;
+
+    mod_timer(&inf->mcutimer, jiffies + HZ/10);
+
+    switch(inf->mcu_status)
+    {
+    case MS_IDLE:
+        inf->mcu_status = MS_MCU;
+        break;
+    case MS_MCU:
+        if(inf->mcu_usetimer)   mcu_do_refresh(inf);
+        break;
+    case MS_EWAITSTART:
+        inf->mcu_status = MS_EWAITEND;
+        waitcnt = 0;
+        break;
+    case MS_EWAITEND:
+        if(0==waitcnt) {
+            mcu_do_refresh(inf);
+        }
+        if(waitcnt++>14) {
+            inf->mcu_status = MS_EEND;
+        }
+        break;
+    case MS_EEND:
+        inf->mcu_status = MS_MCU;
+        break;
+    default:
+        inf->mcu_status = MS_MCU;
+        break;
+    }
+}
+
+int mcu_refresh(struct rk29fb_inf *inf)
+{
+    static int mcutimer_inited = 0;
+
+    if(SCREEN_MCU!=inf->cur_screen->type)   return 0;
+
+    if(!mcutimer_inited)
+    {
+        mcutimer_inited = 1;
+        init_timer(&inf->mcutimer);
+        inf->mcutimer.function = mcutimer_callback;
+        inf->mcutimer.expires = jiffies + HZ/5;
+        inf->mcu_status = MS_IDLE;
+        add_timer(&inf->mcutimer);
+    }
+
+    if(MS_MCU==inf->mcu_status)     mcu_do_refresh(inf);
+
+    return 0;
+}
+
+int mcu_ioctl(unsigned int cmd, unsigned long arg)
+{
+    struct rk29fb_inf *inf = NULL;
+    if(!g_pdev)     return -1;
+
+    inf = dev_get_drvdata(&g_pdev->dev);
+
+    switch(cmd)
+    {
+    case MCU_WRCMD:
+        LcdClrBit(inf, MCU_TIMING_CTRL, m_MCU_RS_SELECT);
+        LcdWrReg(inf, MCU_BYPASS_WPORT, arg);
+        LcdSetBit(inf, MCU_TIMING_CTRL, m_MCU_RS_SELECT);
+        break;
+
+    case MCU_WRDATA:
+        LcdSetBit(inf, MCU_TIMING_CTRL, m_MCU_RS_SELECT);
+        LcdWrReg(inf, MCU_BYPASS_WPORT, arg);
+        break;
+
+    case MCU_SETBYPASS:
+        LcdMskReg(inf, MCU_TIMING_CTRL, m_MCU_BYPASSMODE_SELECT, v_MCU_BYPASSMODE_SELECT(arg));
+        LcdWrReg(inf, REG_CFG_DONE, 0x01);
+        break;
+
+    default:
+        break;
+    }
+
+    return 0;
+}
+
+static irqreturn_t mcu_irqfmk(int irq, void *dev_id)
+{
+       struct platform_device *pdev = (struct platform_device*)dev_id;
+    struct rk29fb_inf *inf = platform_get_drvdata(pdev);
+    struct rk29fb_screen *screen;
+
+    if(!inf)    return IRQ_HANDLED;
+
+    screen = inf->cur_screen;
+
+    if(0==screen->mcu_usefmk) {
+        return IRQ_HANDLED;
+    }
+
+    if(inf->mcu_fmksync == 1)
+        return IRQ_HANDLED;
+
+    inf->mcu_fmksync = 1;
+    if(inf->mcu_needflush)
+    {
+        inf->mcu_needflush = 0;
+        inf->mcu_isrcnt = 0;
+        if(inf->cur_screen->refresh)
+           inf->cur_screen->refresh(REFRESH_PRE);
+        LcdSetBit(inf, MCU_TIMING_CTRL, m_MCU_HOLDMODE_FRAME_ST);
+    }
+    inf->mcu_fmksync = 0;
+
+       return IRQ_HANDLED;
+}
+
+int init_lcdc(struct fb_info *info)
+{
+    struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+    u32 msk=0, clr=0;
+
+       fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
+
+       // set AHB access rule and disable all windows
+    LcdWrReg(inf, SYS_CONFIG, 0x20000000);
+    LcdWrReg(inf, SWAP_CTRL, 0);
+    LcdWrReg(inf, FIFO_WATER_MARK, 0x00000860);
+
+       // and mcu holdmode; and set win1 top.
+    LcdMskReg(inf, MCU_TIMING_CTRL, m_MCU_HOLDMODE_SELECT | m_MCU_HOLDMODE_FRAME_ST | m_MCU_BYPASSMODE_SELECT ,
+            v_MCU_HOLDMODE_SELECT(0)| v_MCU_HOLDMODE_FRAME_ST(0) |v_MCU_BYPASSMODE_SELECT(0));
+
+    // disable blank out, black out, tristate out, yuv2rgb bypass
+    LcdMskReg(inf, BLEND_CTRL,m_W2_BLEND_EN | m_W1_BLEND_EN | m_W0_BLEND_EN | m_HWC_BLEND_EN |
+             m_HWC_BLEND_FACTOR | m_W1_BLEND_FACTOR | m_W0_BLEND_FACTOR,
+             v_W2_BLEND_EN(0) |v_W1_BLEND_EN(0) | v_W0_BLEND_EN(0) | v_HWC_BLEND_EN(0) |
+             v_HWC_BLEND_FACTOR(0) | v_W2_BLEND_FACTOR(0) | v_W1_BLEND_FACTOR(0) | v_W0_BLEND_FACTOR(0)
+             );
+
+    LcdMskReg(inf, WIN0_COLOR_KEY_CTRL, m_COLORKEY_EN, v_COLORKEY_EN(0));
+    LcdMskReg(inf, WIN1_COLOR_KEY_CTRL, m_COLORKEY_EN, v_COLORKEY_EN(0));
+
+    LcdWrReg(inf, DSP_CTRL0, 0);
+    LcdWrReg(inf, DSP_CTRL1, 0);
+
+    // initialize all interrupt
+    clr = v_HOR_STARTCLEAR(1) | v_FRM_STARTCLEAR(1) | v_SCANNING_CLEAR(1);
+
+    msk = v_HOR_STARTMASK(1) | v_FRM_STARTMASK(0) | v_SCANNING_MASK(1);
+
+    LcdWrReg(inf, INT_STATUS, clr | msk);
+
+       // let above to take effect
+    LcdWrReg(inf, REG_CFG_DONE, 0x01);
+
+    return 0;
+}
+
+void load_screen(struct fb_info *info, bool initscreen)
+{
+    int ret = -EINVAL;
+    struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+    struct rk29fb_screen *screen = inf->cur_screen;
+    u16 face = screen->face;
+    u16 mcu_total, mcu_rwstart, mcu_csstart, mcu_rwend, mcu_csend;
+    u16 right_margin = screen->right_margin, lower_margin = screen->lower_margin;
+    u16 x_res = screen->x_res, y_res = screen->y_res;
+    u32 clk_rate = 0;
+    u32 dclk_rate = 0;
+
+       fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
+
+    // set the rgb or mcu
+    LcdMskReg(inf, MCU_TIMING_CTRL, m_MCU_OUTPUT_SELECT, v_MCU_OUTPUT_SELECT((SCREEN_MCU==screen->type)?(1):(0)));
+
+       // set out format and mcu timing
+    mcu_total  = (screen->mcu_wrperiod*150*1000)/1000000;
+    if(mcu_total>31)    mcu_total = 31;
+    if(mcu_total<3)     mcu_total = 3;
+    mcu_rwstart = (mcu_total+1)/4 - 1;
+    mcu_rwend = ((mcu_total+1)*3)/4 - 1;
+    mcu_csstart = (mcu_rwstart>2) ? (mcu_rwstart-3) : (0);
+    mcu_csend = (mcu_rwend>15) ? (mcu_rwend-1) : (mcu_rwend);
+
+    fbprintk(">> mcu_total=%d, mcu_rwstart=%d, mcu_csstart=%d, mcu_rwend=%d, mcu_csend=%d \n",
+        mcu_total, mcu_rwstart, mcu_csstart, mcu_rwend, mcu_csend);
+
+    LcdMskReg(inf, MCU_TIMING_CTRL,
+             m_MCU_CS_ST | m_MCU_CS_END| m_MCU_RW_ST | m_MCU_RW_END |
+             m_MCU_WRITE_PERIOD | m_MCU_HOLDMODE_SELECT | m_MCU_HOLDMODE_FRAME_ST,
+            v_MCU_CS_ST(mcu_csstart) | v_MCU_CS_END(mcu_csend) | v_MCU_RW_ST(mcu_rwstart) |
+            v_MCU_RW_END(mcu_rwend) |  v_MCU_WRITE_PERIOD(mcu_total) |
+            v_MCU_HOLDMODE_SELECT((SCREEN_MCU==screen->type)?(1):(0)) | v_MCU_HOLDMODE_FRAME_ST(0)
+           );
+
+       // set synchronous pin polarity and data pin swap rule
+     LcdMskReg(inf, DSP_CTRL0,
+        m_DISPLAY_FORMAT | m_HSYNC_POLARITY | m_VSYNC_POLARITY | m_DEN_POLARITY |
+        m_DCLK_POLARITY | m_COLOR_SPACE_CONVERSION,
+        v_DISPLAY_FORMAT(face) | v_HSYNC_POLARITY(screen->pin_hsync) | v_VSYNC_POLARITY(screen->pin_vsync) |
+        v_DEN_POLARITY(screen->pin_den) | v_DCLK_POLARITY(screen->pin_dclk) | v_COLOR_SPACE_CONVERSION(0)
+        );
+
+     LcdMskReg(inf, DSP_CTRL1, m_BG_COLOR,  v_BG_COLOR(0x000000) );
+
+     LcdMskReg(inf, SWAP_CTRL, m_OUTPUT_RB_SWAP | m_OUTPUT_RG_SWAP | m_DELTA_SWAP | m_DUMMY_SWAP,
+            v_OUTPUT_RB_SWAP(screen->swap_rb) | v_OUTPUT_RG_SWAP(screen->swap_rg) | v_DELTA_SWAP(screen->swap_delta) | v_DUMMY_SWAP(screen->swap_dumy));
+
+       // set horizontal & vertical out timing
+       if(SCREEN_MCU==inf->cur_screen->type)
+    {
+           right_margin = x_res/6;
+       }
+
+    printk("screen->hsync_len =%d,  screen->left_margin =%d, x_res =%d,  right_margin = %d \n",
+        screen->hsync_len , screen->left_margin , x_res , right_margin );
+    LcdMskReg(inf, DSP_HTOTAL_HS_END, m_BIT11LO | m_BIT11HI, v_BIT11LO(screen->hsync_len) |
+             v_BIT11HI(screen->hsync_len + screen->left_margin + x_res + right_margin));
+    LcdMskReg(inf, DSP_HACT_ST_END, m_BIT11LO | m_BIT11HI, v_BIT11LO(screen->hsync_len + screen->left_margin + x_res) |
+             v_BIT11HI(screen->hsync_len + screen->left_margin));
+
+    LcdMskReg(inf, DSP_VTOTAL_VS_END, m_BIT11LO | m_BIT11HI, v_BIT11LO(screen->vsync_len) |
+              v_BIT11HI(screen->vsync_len + screen->upper_margin + y_res + lower_margin));
+    LcdMskReg(inf, DSP_VACT_ST_END, m_BIT11LO | m_BIT11HI,  v_BIT11LO(screen->vsync_len + screen->upper_margin+y_res)|
+              v_BIT11HI(screen->vsync_len + screen->upper_margin));
+
+    LcdMskReg(inf, DSP_VS_ST_END_F1, m_BIT11LO | m_BIT11HI, v_BIT11LO(0) | v_BIT11HI(0));
+    LcdMskReg(inf, DSP_VACT_ST_END_F1, m_BIT11LO | m_BIT11HI, v_BIT11LO(0) | v_BIT11HI(0));
+
+       // let above to take effect
+    LcdWrReg(inf, REG_CFG_DONE, 0x01);
+
+    // set lcdc clk
+    if(SCREEN_MCU==screen->type)    screen->pixclock = 150; //mcu fix to 150 MHz
+
+    clk_set_parent(inf->dclk_divider, inf->dclk_parent);
+    clk_set_parent(inf->dclk, inf->dclk_divider);
+
+    dclk_rate = screen->pixclock * 1000000;
+
+    fbprintk(">>>>>> set lcdc dclk need %d HZ, clk_parent = %d hz \n ", screen->pixclock, clk_rate);
+
+#if 0
+    ret = clk_set_rate(inf->dclk_divider, dclk_rate);
+
+    if(ret)
+    {
+        printk(KERN_ERR ">>>>>> set lcdc dclk_divider faild \n ");
+    }
+
+    clk_enable(inf->dclk);
+    clk_enable(inf->clk);
+    clk_enable(inf->clk_share_mem);
+#endif
+
+    // init screen panel
+    if(screen->init && initscreen)
+    {
+       screen->init();
+    }
+}
+#ifdef CONFIG_CPU_FREQ
+/*
+* CPU clock speed change handler. We need to adjust the LCD timing
+* parameters when the CPU clock is adjusted by the power management
+* subsystem.
+*/
+#define TO_INF(ptr,member) container_of(ptr,struct rk29fb_inf,member)
+
+static int
+rk29fb_freq_transition(struct notifier_block *nb, unsigned long val, void *data)
+{
+    struct rk29fb_inf *inf = TO_INF(nb, freq_transition);
+    struct rk29fb_screen *screen = inf->cur_screen;
+    u32 dclk_rate = 0;
+
+    switch (val)
+    {
+    case CPUFREQ_PRECHANGE:
+          break;
+    case CPUFREQ_POSTCHANGE:
+        {
+         dclk_rate = screen->pixclock * 1000000;
+
+         fbprintk(">>>>>> set lcdc dclk need %d HZ, clk_parent = %d hz \n ", screen->pixclock, dclk_rate);
+
+         clk_set_rate(inf->dclk_divider, dclk_rate);
+         break;
+        }
+    }
+    return 0;
+}
+#endif
+
+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 fb_setcolreg(unsigned regno,
+                              unsigned red, unsigned green, unsigned blue,
+                              unsigned transp, struct fb_info *info)
+{
+       unsigned int val;
+//     fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
+
+       switch (info->fix.visual) {
+       case FB_VISUAL_TRUECOLOR:
+               /* true-colour, use pseudo-palette */
+               if (regno < 16) {
+                       u32 *pal = info->pseudo_palette;
+                       val  = chan_to_field(red,   &info->var.red);
+                       val |= chan_to_field(green, &info->var.green);
+                       val |= chan_to_field(blue,  &info->var.blue);
+                       pal[regno] = val;
+               }
+               break;
+       default:
+               return -1;      /* unknown type */
+       }
+
+       return 0;
+}
+#if 0
+
+int rk29_set_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+    struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+
+    //fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
+
+    /* check not being asked to exceed capabilities */
+
+    if (cursor->image.width > 32)
+        return -EINVAL;
+
+    if (cursor->image.height > 32)
+        return -EINVAL;
+
+    if (cursor->image.depth > 1)
+        return -EINVAL;
+
+    if (cursor->enable)
+        LcdSetBit(inf, SYS_CONFIG, m_HWC_ENABLE);
+    else
+        LcdClrBit(inf, SYS_CONFIG, m_HWC_ENABLE);
+
+    /* set data */
+    if (cursor->set & FB_CUR_SETPOS)
+    {
+        unsigned int x = cursor->image.dx;
+        unsigned int y = cursor->image.dy;
+
+        if (x >= 0x800 || y >= 0x800 )
+            return -EINVAL;
+        LcdWrReg(inf, HWC_DSP_ST, v_BIT11LO(x)|v_BIT11HI(y));
+    }
+
+
+    if (cursor->set & FB_CUR_SETCMAP)
+    {
+        unsigned int bg_col = cursor->image.bg_color;
+        unsigned int fg_col = cursor->image.fg_color;
+
+        fbprintk("%s: update cmap (%08x,%08x)\n",
+            __func__, bg_col, fg_col);
+
+        LcdMskReg(inf, HWC_COLOR_LUT0, m_HWC_R|m_HWC_G|m_HWC_B,
+                  v_HWC_R(info->cmap.red[bg_col]>>8) | v_HWC_G(info->cmap.green[bg_col]>>8) | v_HWC_B(info->cmap.blue[bg_col]>>8));
+
+        LcdMskReg(inf, HWC_COLOR_LUT2, m_HWC_R|m_HWC_G|m_HWC_B,
+                         v_HWC_R(info->cmap.red[fg_col]>>8) | v_HWC_G(info->cmap.green[fg_col]>>8) | v_HWC_B(info->cmap.blue[fg_col]>>8));
+    }
+
+    if ((cursor->set & FB_CUR_SETSIZE ||
+        cursor->set & (FB_CUR_SETIMAGE | FB_CUR_SETSHAPE))
+        && info->screen_base && info->fix.smem_start && info->fix.smem_len)
+    {
+        /* rk29 cursor is a 2 bpp 32x32 bitmap this routine
+         * clears it to transparent then combines the cursor
+         * shape plane with the colour plane to set the
+         * cursor */
+        int x, y;
+        const unsigned char *pcol = cursor->image.data;
+        const unsigned char *pmsk = cursor->mask;
+        void __iomem   *dst;
+        unsigned long cursor_mem_start;
+        unsigned char  dcol = 0;
+        unsigned char  dmsk = 0;
+        unsigned int   op;
+
+        dst = info->screen_base + info->fix.smem_len - CURSOR_BUF_SIZE;
+           cursor_mem_start = info->fix.smem_start + info->fix.smem_len - CURSOR_BUF_SIZE;
+
+        fbprintk("%s: setting shape (%d,%d)\n",
+            __func__, cursor->image.width, cursor->image.height);
+
+        memset(dst, 0, CURSOR_BUF_SIZE);
+
+        for (y = 0; y < cursor->image.height; y++)
+        {
+            for (x = 0; x < cursor->image.width; x++)
+            {
+                if ((x % 8) == 0) {
+                    dcol = *pcol++;
+                    dmsk = *pmsk++;
+                } else {
+                    dcol >>= 1;
+                    dmsk >>= 1;
+                }
+
+                if (dmsk & 1) {
+                    op = (dcol & 1) ? 1 : 3;
+                    op <<= ((x % 4) * 2);
+                    *(u8*)(dst+(x/4)) |= op;
+                }
+            }
+            dst += (32*2)/8;
+        }
+        LcdSetBit(inf, SYS_CONFIG,m_HWC_RELOAD_EN);
+        LcdWrReg(inf, HWC_MST, cursor_mem_start);
+        // flush end when wq_condition=1 in mcu panel, but not in rgb panel
+        if(SCREEN_MCU == inf->cur_screen->type) {
+            wait_event_interruptible_timeout(wq, wq_condition, HZ/20);
+            wq_condition = 0;
+        } else {
+            wq_condition = 0;
+            wait_event_interruptible_timeout(wq, wq_condition, HZ/20);
+        }
+        LcdClrBit(inf, SYS_CONFIG, m_HWC_RELOAD_EN);
+    }
+
+    return 0;
+}
+#endif
+
+static int win0fb_blank(int blank_mode, struct fb_info *info)
+{
+    struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+
+    fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
+
+       CHK_SUSPEND(inf);
+
+    switch(blank_mode)
+    {
+    case FB_BLANK_UNBLANK:
+        LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE, v_W0_ENABLE(1));
+        break;
+    default:
+        LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE, v_W0_ENABLE(0));
+        break;
+    }
+    LcdWrReg(inf, REG_CFG_DONE, 0x01);
+
+       mcu_refresh(inf);
+    return 0;
+}
+
+static int win0fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+    struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+    struct rk29fb_screen *screen = inf->cur_screen;
+
+    u32 ScaleYRGBY=0x1000;
+    u16 xpos = (var->nonstd>>8) & 0xfff;   //offset in panel
+    u16 ypos = (var->nonstd>>20) & 0xfff;
+    u16 xsize = (var->grayscale>>8) & 0xfff;   //visiable size in panel
+    u16 ysize = (var->grayscale>>20) & 0xfff;
+    u16 xlcd = screen->x_res;        //size of panel
+    u16 ylcd = screen->y_res;
+    u16 yres = 0;
+
+    if(inf->win0fb->var.rotate == 270) {
+        xlcd = screen->y_res;
+        ylcd = screen->x_res;
+    }
+
+    fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
+
+       CHK_SUSPEND(inf);
+
+    if( 0==var->xres_virtual || 0==var->yres_virtual ||
+        0==var->xres || 0==var->yres || var->xres<16 ||
+        0==xsize || 0==ysize || xsize<16 ||
+        ((16!=var->bits_per_pixel)&&(32!=var->bits_per_pixel)) )
+    {
+        printk(">>>>>> win0fb_check_var fail 1!!! \n");
+               printk("0==%d || 0==%d || 0==%d || 0==%d || %d<16 \n ||0==%d || 0==%d || %d<16 ||((16!=%d)&&(32!=%d)) \n",
+                               var->xres_virtual, var->yres_virtual, var->xres, var->yres, var->xres, xsize, ysize, xsize,
+                       var->bits_per_pixel, var->bits_per_pixel);
+        return -EINVAL;
+    }
+
+    if( (var->xoffset+var->xres)>var->xres_virtual ||
+        (var->yoffset+var->yres)>var->yres_virtual ||
+        (xpos+xsize)>xlcd || (ypos+ysize)>ylcd )
+    {
+        printk(">>>>>> win0fb_check_var fail 2!!! \n");
+               printk("(%d+%d)>%d || (%d+%d)>%d || (%d+%d)>%d || (%d+%d)>%d \n ",
+                               var->xoffset, var->xres, var->xres_virtual, var->yoffset, var->yres,
+                               var->yres_virtual, xpos, xsize, xlcd, ypos, ysize, ylcd);
+        return -EINVAL;
+    }
+
+    switch(var->nonstd&0x0f)
+    {
+    case 0: // rgb
+        switch(var->bits_per_pixel)
+        {
+        case 16:    // rgb565
+            var->xres_virtual = (var->xres_virtual + 0x1) & (~0x1);
+            var->xres = (var->xres + 0x1) & (~0x1);
+            var->xoffset = (var->xoffset) & (~0x1);
+            break;
+        default:    // rgb888
+            var->bits_per_pixel = 32;
+            break;
+        }
+        var->nonstd &= ~0xc0;  //not support I2P in this format
+        break;
+    case 1: // yuv422
+        var->xres_virtual = (var->xres_virtual + 0x3) & (~0x3);
+        var->xres = (var->xres + 0x3) & (~0x3);
+        var->xoffset = (var->xoffset) & (~0x3);
+        break;
+    case 2: // yuv4200
+        var->xres_virtual = (var->xres_virtual + 0x3) & (~0x3);
+        var->yres_virtual = (var->yres_virtual + 0x1) & (~0x1);
+        var->xres = (var->xres + 0x3) & (~0x3);
+        var->yres = (var->yres + 0x1) & (~0x1);
+        var->xoffset = (var->xoffset) & (~0x3);
+        var->yoffset = (var->yoffset) & (~0x1);
+        break;
+    case 3: // yuv4201
+        var->xres_virtual = (var->xres_virtual + 0x3) & (~0x3);
+        var->yres_virtual = (var->yres_virtual + 0x1) & (~0x1);
+        var->xres = (var->xres + 0x3) & (~0x3);
+        var->yres = (var->yres + 0x1) & (~0x1);
+        var->xoffset = (var->xoffset) & (~0x3);
+        var->yoffset = (var->yoffset) & (~0x1);
+        var->nonstd &= ~0xc0;   //not support I2P in this format
+        break;
+    case 4: // yuv420m
+        var->xres_virtual = (var->xres_virtual + 0x7) & (~0x7);
+        var->yres_virtual = (var->yres_virtual + 0x1) & (~0x1);
+        var->xres = (var->xres + 0x7) & (~0x7);
+        var->yres = (var->yres + 0x1) & (~0x1);
+        var->xoffset = (var->xoffset) & (~0x7);
+        var->yoffset = (var->yoffset) & (~0x1);
+        var->nonstd &= ~0xc0;   //not support I2P in this format
+        break;
+    case 5: // yuv444
+        var->xres_virtual = (var->xres_virtual + 0x3) & (~0x3);
+        var->xres = (var->xres + 0x3) & (~0x3);
+        var->xoffset = (var->xoffset) & (~0x3);
+        var->nonstd &= ~0xc0;   //not support I2P in this format
+        break;
+    default:
+        printk(">>>>>> win0fb var->nonstd=%d is invalid! \n", var->nonstd);
+        return -EINVAL;
+    }
+
+    if(var->rotate == 270)
+    {
+        yres = var->xres;
+    }
+    else
+    {
+        yres = var->yres;
+    }
+    ScaleYRGBY = CalScaleW0(yres, ysize);
+
+    if((ScaleYRGBY>0x8000) || (ScaleYRGBY<0x200))
+    {
+        return -EINVAL;        // multiple of scale down or scale up can't exceed 8
+    }
+
+    return 0;
+}
+
+static int win0fb_set_par(struct fb_info *info)
+{
+    struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+    struct rk29fb_screen *screen = inf->cur_screen;
+    struct fb_var_screeninfo *var = &info->var;
+    struct fb_fix_screeninfo *fix = &info->fix;
+    struct win0_par *par = info->par;
+
+    u8 format = 0;
+    u32 cblen=0, crlen=0, map_size=0, smem_len=0;
+
+       u32 xact = var->xres;                       /* visible resolution               */
+       u32 yact = var->yres;
+       u32 xvir = var->xres_virtual;           /* virtual resolution           */
+       u32 yvir = var->yres_virtual;
+       u32 xact_st = var->xoffset;                     /* offset from virtual to visible */
+       u32 yact_st = var->yoffset;                     /* resolution                   */
+
+    u16 xpos = (var->nonstd>>8) & 0xfff;      //visiable pos in panel
+    u16 ypos = (var->nonstd>>20) & 0xfff;
+    u16 xsize = (var->grayscale>>8) & 0xfff;  //visiable size in panel
+    u16 ysize = (var->grayscale>>20) & 0xfff;
+
+    u32 ScaleYrgbX=0x1000,ScaleYrgbY=0x1000;
+    u32 ScaleCbrX=0x1000, ScaleCbrY=0x1000;
+
+    u8 data_format = var->nonstd&0x0f;
+    u32 win0_en = var->reserved[2];
+    u32 y_addr = var->reserved[3];       //user alloc buf addr y
+    u32 uv_addr = var->reserved[4];
+
+    fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
+
+       CHK_SUSPEND(inf);
+
+       /* calculate y_offset,uv_offset,line_length,cblen and crlen  */
+    switch (data_format)
+    {
+    case 0: // rgb
+        switch(var->bits_per_pixel)
+        {
+        case 16:    // rgb565
+            format = 1;
+            fix->line_length = 2 * xvir;
+            par->y_offset = (yact_st*xvir + xact_st)*2;
+            break;
+        case 32:    // rgb888
+            format = 0;
+            fix->line_length = 4 * xvir;
+            par->y_offset = (yact_st*xvir + xact_st)*4;
+            break;
+        default:
+            return -EINVAL;
+        }
+        break;
+    case 1: // yuv422
+        format = 2;
+        fix->line_length = xvir;
+        cblen = crlen = (xvir*yvir)/2;
+        par->y_offset = yact_st*xvir + xact_st;
+        par->uv_offset = yact_st*xvir + xact_st;
+        break;
+    case 2: // yuv4200
+        format = 3;
+        fix->line_length = xvir;
+        cblen = crlen = (xvir*yvir)/4;
+
+        par->y_offset = yact_st*xvir + xact_st;
+        par->uv_offset = (yact_st/2)*xvir + xact_st;
+
+        break;
+    case 3: // yuv4201
+        format = 4;
+        fix->line_length = xvir;
+        par->y_offset = (yact_st/2)*2*xvir + (xact_st)*2;
+        par->uv_offset = (yact_st/2)*xvir + xact_st;
+        cblen = crlen = (xvir*yvir)/4;
+        break;
+    case 4: // yuv420m
+        format = 5;
+        fix->line_length = xvir;
+        par->y_offset = (yact_st/2)*3*xvir + (xact_st)*3;
+        cblen = crlen = (xvir*yvir)/4;
+        break;
+    case 5: // yuv444
+        format = 6;
+        fix->line_length = xvir;
+        par->y_offset = yact_st*xvir + xact_st;
+        par->uv_offset = yact_st*2*xvir + xact_st*2;
+        cblen = crlen = (xvir*yvir);
+        break;
+    default:
+        return -EINVAL;
+    }
+
+    smem_len = fix->line_length * yvir + cblen + crlen;
+    map_size = PAGE_ALIGN(smem_len);
+
+    if (info->screen_base) {
+        printk(">>>>>> win0fb unmap memory(%d)! \n", info->fix.smem_len);
+        dma_free_writecombine(NULL, PAGE_ALIGN(info->fix.smem_len),info->screen_base, info->fix.smem_start);
+        info->screen_base = 0;
+    }
+    fix->smem_start = y_addr;
+    fix->smem_len = smem_len;
+    fix->mmio_start = uv_addr;
+
+    par->addr_seted = ((-1==(int)y_addr)&&(-1==(int)uv_addr)) ? 0 : 1;
+    fbprintk("buffer alloced by user fix->smem_start = %8x, fix->smem_len = %8x, fix->mmio_start = %8x \n", (u32)fix->smem_start, (u32)fix->smem_len, (u32)fix->mmio_start);
+
+       // calculate the display phy address
+    y_addr = fix->smem_start + par->y_offset;
+    uv_addr = fix->mmio_start + par->uv_offset;
+
+    fbprintk("y_addr 0x%08x = 0x%08x + %d\n", y_addr, (u32)fix->smem_start, par->y_offset);
+    fbprintk("uv_addr 0x%08x = 0x%08x + %d\n", uv_addr, (u32)fix->mmio_start , par->uv_offset);
+
+    ScaleYrgbX = CalScaleW0(xact, xsize);
+    ScaleYrgbY = CalScaleW0(yact, ysize);
+
+    switch (data_format)
+    {
+       case 1:// yuv422
+           ScaleCbrX= CalScaleW0((xact/2), xsize);
+           ScaleCbrY =  CalScaleW0(yact, ysize);
+           break;
+       case 2: // yuv4200
+       case 3: // yuv4201
+       case 4: // yuv420m
+           ScaleCbrX= CalScaleW0(xact/2, xsize);
+           ScaleCbrY =  CalScaleW0(yact/2, ysize);
+           break;
+       case 5:// yuv444
+           ScaleCbrX= CalScaleW0(xact, xsize);
+           ScaleCbrY =  CalScaleW0(yact, ysize);
+           break;
+    }
+
+    xpos += (screen->left_margin + screen->hsync_len);
+    ypos += (screen->upper_margin + screen->vsync_len);
+
+    LcdWrReg(inf, WIN0_YRGB_MST, y_addr);
+    LcdWrReg(inf, WIN0_CBR_MST, uv_addr);
+
+    LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE | m_W0_FORMAT, v_W0_ENABLE(win0_en) | v_W0_FORMAT(format));
+
+    LcdMskReg(inf, WIN0_VIR, m_WORDLO | m_WORDHI, v_VIRWIDTH(xvir) | v_VIRHEIGHT((yvir)) );
+    LcdMskReg(inf, WIN0_ACT_INFO, m_WORDLO | m_WORDHI, v_WORDLO(xact) | v_WORDHI(yact));
+    LcdMskReg(inf, WIN0_DSP_ST, m_BIT11LO | m_BIT11HI, v_BIT11LO(xpos) | v_BIT11HI(ypos));
+    LcdMskReg(inf, WIN0_DSP_INFO, m_BIT11LO | m_BIT11HI,  v_BIT11LO(xsize) | v_BIT11HI(ysize));
+    LcdMskReg(inf, WIN0_SCL_FACTOR_YRGB, m_WORDLO | m_WORDHI, v_WORDLO(ScaleYrgbX) | v_WORDHI(ScaleYrgbY));
+    LcdMskReg(inf, WIN0_SCL_FACTOR_CBR, m_WORDLO | m_WORDHI, v_WORDLO(ScaleCbrX) | v_WORDHI(ScaleCbrY));
+
+    switch(format)
+    {
+    case 1:  //rgb565
+        LcdMskReg(inf, SWAP_CTRL, m_W0_YRGB_8_SWAP | m_W0_YRGB_16_SWAP | m_W0_YRGB_R_SHIFT_SWAP | m_W0_565_RB_SWAP | m_W0_YRGB_M8_SWAP | m_W0_CBR_8_SWAP,
+            v_W0_YRGB_8_SWAP(0) | v_W0_YRGB_16_SWAP(0) | v_W0_YRGB_R_SHIFT_SWAP(0) | v_W0_565_RB_SWAP(1) | v_W0_YRGB_M8_SWAP(0) | v_W0_CBR_8_SWAP(0));
+        break;
+    case 4:   //yuv4201
+        LcdMskReg(inf, SWAP_CTRL, m_W0_YRGB_8_SWAP | m_W0_YRGB_16_SWAP | m_W0_YRGB_R_SHIFT_SWAP | m_W0_565_RB_SWAP | m_W0_YRGB_M8_SWAP | m_W0_CBR_8_SWAP,
+            v_W0_YRGB_8_SWAP(0) | v_W0_YRGB_16_SWAP(0) | v_W0_YRGB_R_SHIFT_SWAP(0) | v_W0_565_RB_SWAP(0) |
+            v_W0_YRGB_M8_SWAP((var->rotate==0)) | v_W0_CBR_8_SWAP(0));
+        break;
+    default:
+        LcdMskReg(inf, SWAP_CTRL, m_W0_YRGB_8_SWAP | m_W0_YRGB_16_SWAP | m_W0_YRGB_R_SHIFT_SWAP | m_W0_565_RB_SWAP | m_W0_YRGB_M8_SWAP | m_W0_CBR_8_SWAP,
+            v_W0_YRGB_8_SWAP(0) | v_W0_YRGB_16_SWAP(0) | v_W0_YRGB_R_SHIFT_SWAP(0) | v_W0_565_RB_SWAP(0) | v_W0_YRGB_M8_SWAP(0) | v_W0_CBR_8_SWAP(0) );
+    }
+
+    LcdWrReg(inf, REG_CFG_DONE, 0x01);
+
+    return 0;
+}
+
+static int win0fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+    struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+   // struct fb_var_screeninfo *var0 = &info->var;
+    struct fb_fix_screeninfo *fix0 = &info->fix;
+    struct win0_par *par = info->par;
+    u32 y_addr=0, uv_addr=0;
+
+    fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
+
+       CHK_SUSPEND(inf);
+
+    y_addr = fix0->smem_start +  par->y_offset;//y_offset;
+    uv_addr = fix0->mmio_start + par->uv_offset ;//uv_offset;
+
+    LcdWrReg(inf, WIN0_YRGB_MST, y_addr);
+    LcdWrReg(inf, WIN0_CBR_MST, uv_addr);
+    LcdWrReg(inf, REG_CFG_DONE, 0x01);
+
+     // enable win0 after the win0 addr is seted
+    par->par_seted = 1;
+       LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE, v_W0_ENABLE((1==par->addr_seted)?(1):(0)));
+       mcu_refresh(inf);
+
+    return 0;
+}
+
+int win0fb_open(struct fb_info *info, int user)
+{
+    struct win0_par *par = info->par;
+
+    fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
+
+    par->par_seted = 0;
+    par->addr_seted = 0;
+
+    if(par->refcount) {
+        printk(">>>>>> win0fb has opened! \n");
+        return -EACCES;
+    } else {
+        par->refcount++;
+        return 0;
+    }
+}
+
+int win0fb_release(struct fb_info *info, int user)
+{
+    struct win0_par *par = info->par;
+       struct fb_var_screeninfo *var0 = &info->var;
+
+    fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
+
+    if(par->refcount) {
+        par->refcount--;
+
+        win0fb_blank(FB_BLANK_POWERDOWN, info);
+        // wait for lcdc stop access memory
+        msleep(50);
+
+        // unmap memory
+        if (info->screen_base) {
+            printk(">>>>>> win0fb unmap memory(%d)! \n", info->fix.smem_len);
+           dma_free_writecombine(NULL, PAGE_ALIGN(info->fix.smem_len),info->screen_base, info->fix.smem_start);
+           info->screen_base = 0;
+           info->fix.smem_start = 0;
+           info->fix.smem_len = 0;
+        }
+
+               // clean the var param
+               memset(var0, 0, sizeof(struct fb_var_screeninfo));
+    }
+
+    return 0;
+}
+
+static int win0fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+{
+    struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+    struct win0_par *par = info->par;
+    void __user *argp = (void __user *)arg;
+
+       fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
+    fbprintk("win0fb_ioctl cmd = %8x, arg = %8x \n", (u32)cmd, (u32)arg);
+
+       CHK_SUSPEND(inf);
+
+    switch(cmd)
+    {
+    case FB1_IOCTL_GET_PANEL_SIZE:    //get panel size
+        {
+            u32 panel_size[2];
+             if(inf->win0fb->var.rotate == 270) {
+                panel_size[0] = inf->cur_screen->y_res;
+                panel_size[1] = inf->cur_screen->x_res;
+            } else {
+                panel_size[0] = inf->cur_screen->x_res;
+                panel_size[1] = inf->cur_screen->y_res;
+            }
+
+            if(copy_to_user(argp, panel_size, 8))  return -EFAULT;
+        }
+        break;
+
+    case FB1_IOCTL_SET_YUV_ADDR:    //set y&uv address to register direct
+        {
+            u32 yuv_phy[2];
+            if (copy_from_user(yuv_phy, argp, 8))
+                           return -EFAULT;
+
+            yuv_phy[0] += par->y_offset;
+            yuv_phy[1] += par->uv_offset;
+
+            LcdWrReg(inf, WIN0_YRGB_MST, yuv_phy[0]);
+            LcdWrReg(inf, WIN0_CBR_MST, yuv_phy[1]);
+            LcdWrReg(inf, REG_CFG_DONE, 0x01);
+            // enable win0 after the win0 par is seted
+            par->addr_seted = 1;
+            if(par->par_seted) {
+               LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE, v_W0_ENABLE(1));
+                mcu_refresh(inf);
+            }
+        }
+        break;
+
+    case FB1_IOCTL_SET_ROTATE:    //change MCU panel scan direction
+        fbprintk(">>>>>> change lcdc direction(%d) \n", (int)arg);
+        return -1;
+        break;
+    default:
+        break;
+    }
+    return 0;
+}
+
+static struct fb_ops win0fb_ops = {
+       .owner          = THIS_MODULE,
+       .fb_open    = win0fb_open,
+       .fb_release = win0fb_release,
+       .fb_check_var   = win0fb_check_var,
+       .fb_set_par     = win0fb_set_par,
+       .fb_blank       = win0fb_blank,
+    .fb_pan_display = win0fb_pan_display,
+    .fb_ioctl = win0fb_ioctl,
+       .fb_setcolreg   = fb_setcolreg,
+       .fb_fillrect    = cfb_fillrect,
+       .fb_copyarea    = cfb_copyarea,
+       .fb_imageblit   = cfb_imageblit,
+};
+
+static int win1fb_blank(int blank_mode, struct fb_info *info)
+{
+    struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+
+    fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
+
+       CHK_SUSPEND(inf);
+
+       switch(blank_mode)
+    {
+    case FB_BLANK_UNBLANK:
+        LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE, v_W1_ENABLE(1));
+        break;
+    default:
+        LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE, v_W1_ENABLE(0));
+        break;
+    }
+    LcdWrReg(inf, REG_CFG_DONE, 0x01);
+
+       mcu_refresh(inf);
+    return 0;
+}
+
+static int win1fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+    struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+    struct rk29fb_screen *screen = inf->cur_screen;
+    u16 xpos = (var->nonstd>>8) & 0xfff;
+    u16 ypos = (var->nonstd>>20) & 0xfff;
+    u16 xlcd = screen->x_res;
+    u16 ylcd = screen->y_res;
+    u8 trspmode = (var->grayscale>>8) & 0xff;
+    u8 trspval = (var->grayscale) & 0xff;
+
+    fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
+
+       CHK_SUSPEND(inf);
+
+#if (0==WIN1_USE_DOUBLE_BUF)
+    if(var->yres_virtual>ylcd)
+        var->yres_virtual = ylcd;
+#endif
+
+    if( 0==var->xres_virtual || 0==var->yres_virtual ||
+        0==var->xres || 0==var->yres || var->xres<16 ||
+        trspmode>5 || trspval>16 ||
+        ((16!=var->bits_per_pixel)&&(32!=var->bits_per_pixel)) )
+    {
+        printk(">>>>>> win1fb_check_var fail 1!!! \n");
+        printk(">>>>>> 0==%d || 0==%d ", var->xres_virtual,var->yres_virtual);
+        printk("0==%d || 0==%d || %d<16 || ", var->xres,var->yres,var->xres<16);
+        printk("%d>5 || %d>16 \n", trspmode,trspval);
+        printk("bits_per_pixel=%d \n", var->bits_per_pixel);
+        return -EINVAL;
+    }
+
+    if( (var->xoffset+var->xres)>var->xres_virtual ||
+        (var->yoffset+var->yres)>var->yres_virtual ||
+        (xpos+var->xres)>xlcd || (ypos+var->yres)>ylcd )
+    {
+        printk(">>>>>> win1fb_check_var fail 2!!! \n");
+        printk(">>>>>> (%d+%d)>%d || ", var->xoffset,var->xres,var->xres_virtual);
+        printk("(%d+%d)>%d || ", var->yoffset,var->yres,var->yres_virtual);
+        printk("(%d+%d)>%d || (%d+%d)>%d \n", xpos,var->xres,xlcd,ypos,var->yres,ylcd);
+        return -EINVAL;
+    }
+
+    switch(var->bits_per_pixel)
+    {
+    case 16:    // rgb565
+        var->xres_virtual = (var->xres_virtual + 0x1) & (~0x1);
+        var->xres = (var->xres + 0x1) & (~0x1);
+        var->xoffset = (var->xoffset) & (~0x1);
+        break;
+    default:    // rgb888
+        var->bits_per_pixel = 32;
+        break;
+    }
+
+    return 0;
+}
+
+static int win1fb_set_par(struct fb_info *info)
+{
+    struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+    struct fb_var_screeninfo *var = &info->var;
+    struct fb_fix_screeninfo *fix = &info->fix;
+    struct rk29fb_screen *screen = inf->cur_screen;
+
+
+    u8 format = 0;
+    dma_addr_t map_dma;
+    u32 offset=0, addr=0, map_size=0, smem_len=0;
+
+    u16 xres_virtual = var->xres_virtual;      //virtual screen size
+    //u16 yres_virtual = var->yres_virtual;
+
+    u16 xpos_virtual = var->xoffset;           //visiable offset in virtual screen
+    u16 ypos_virtual = var->yoffset;
+
+    u16 xpos = 0;                 //visiable offset in panel
+    u16 ypos = 0;
+    u16 xsize = screen->x_res;    //visiable size in panel
+    u16 ysize = screen->y_res;
+    u8 trspmode = TRSP_CLOSE;
+    u8 trspval = 0;
+
+    fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
+
+       CHK_SUSPEND(inf);
+
+    switch(var->bits_per_pixel)
+    {
+    case 16:    // rgb565
+        format = 1;
+        fix->line_length = 2 * xres_virtual;
+        offset = (ypos_virtual*xres_virtual + xpos_virtual)*2;
+        break;
+    case 32:    // rgb888
+    default:
+        format = 0;
+        fix->line_length = 4 * xres_virtual;
+        offset = (ypos_virtual*xres_virtual + xpos_virtual)*4;
+        break;
+    }
+
+    smem_len = fix->line_length * var->yres_virtual + CURSOR_BUF_SIZE;   //cursor buf also alloc here
+    map_size = PAGE_ALIGN(smem_len);
+
+#if WIN1_USE_DOUBLE_BUF
+    if( var->yres_virtual == 2*screen->y_res ) {
+        inf->mcu_usetimer = 0;
+    }
+    if(0==fix->smem_len) {
+        smem_len = smem_len*2;
+        map_size = PAGE_ALIGN(smem_len);
+        fbprintk(">>>>>> first alloc, alloc double!!! \n ");
+    }
+#endif
+
+#if WIN1_USE_DOUBLE_BUF
+    if (smem_len > fix->smem_len)     // buffer need realloc
+#else
+    if (smem_len != fix->smem_len)     // buffer need realloc
+#endif
+    {
+        fbprintk(">>>>>> win1 buffer size is change(%d->%d)! remap memory!\n",fix->smem_len, smem_len);
+        fbprintk(">>>>>> smem_len %d = %d * %d \n", smem_len, fix->line_length, var->yres_virtual);
+        fbprintk(">>>>>> map_size = %d\n", map_size);
+        LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE, v_W1_ENABLE(0));
+        LcdWrReg(inf, REG_CFG_DONE, 0x01);
+        msleep(50);
+        if (info->screen_base) {
+            printk(">>>>>> win1fb unmap memory(%d)! \n", info->fix.smem_len);
+               dma_free_writecombine(NULL, PAGE_ALIGN(info->fix.smem_len), info->screen_base, info->fix.smem_start);
+               info->screen_base = 0;
+               fix->smem_start = 0;
+               fix->smem_len = 0;
+        }
+
+        info->screen_base = dma_alloc_writecombine(NULL, map_size, &map_dma, GFP_KERNEL);
+        if(!info->screen_base) {
+            printk(">>>>>> win1fb dma_alloc_writecombine fail!\n");
+            return -ENOMEM;
+        }
+        memset(info->screen_base, 0, map_size);
+        fix->smem_start = map_dma;
+        fix->smem_len = smem_len;
+        fbprintk(">>>>>> alloc succ, mem=%08x, len=%d!\n", (u32)fix->smem_start, fix->smem_len);
+    }
+
+    addr = fix->smem_start + offset;
+
+
+    LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE|m_W1_FORMAT, v_W1_ENABLE(1)|v_W1_FORMAT(format));
+
+    xpos += (screen->left_margin + screen->hsync_len);
+    ypos += (screen->upper_margin + screen->vsync_len);
+
+    LcdWrReg(inf, WIN1_YRGB_MST, addr);
+
+    LcdMskReg(inf, WIN1_DSP_ST, m_BIT11LO|m_BIT11HI, v_BIT11LO(xpos) | v_BIT11HI(ypos));
+    LcdMskReg(inf, WIN1_DSP_INFO, m_BIT11LO|m_BIT11HI, v_BIT11LO(xsize) | v_BIT11HI(ysize));
+
+    LcdMskReg(inf, WIN1_VIR, m_WORDLO | m_WORDHI , v_WORDLO(xres_virtual) | v_WORDHI(var->yres_virtual));
+
+    LcdMskReg(inf, BLEND_CTRL, m_W1_BLEND_EN |  m_W1_BLEND_FACTOR,
+        v_W1_BLEND_EN((TRSP_FMREG==trspmode) || (TRSP_MASK==trspmode)) | v_W1_BLEND_FACTOR(trspval));
+
+     // enable win1 color key and set the color to black(rgb=0)
+    LcdMskReg(inf, WIN1_COLOR_KEY_CTRL, m_COLORKEY_EN | m_KEYCOLOR, v_COLORKEY_EN(1) | v_KEYCOLOR(0));
+
+    if(1==format) //rgb565
+    {
+        LcdMskReg(inf, SWAP_CTRL, m_W1_8_SWAP | m_W1_16_SWAP | m_W1_R_SHIFT_SWAP | m_W1_565_RB_SWAP,
+            v_W1_8_SWAP(0) | v_W1_16_SWAP(0) | v_W1_R_SHIFT_SWAP(0) | v_W1_565_RB_SWAP(0) );
+    }
+    else
+    {
+     LcdMskReg(inf, SWAP_CTRL, m_W1_8_SWAP | m_W1_16_SWAP | m_W1_R_SHIFT_SWAP | m_W1_565_RB_SWAP,
+            v_W1_8_SWAP(0) | v_W1_16_SWAP(0) | v_W1_R_SHIFT_SWAP(0) | v_W1_565_RB_SWAP(0) );
+
+     LcdMskReg(inf, DSP_CTRL0, m_W1_TRANSP_FROM, v_W1_TRANSP_FROM(TRSP_FMRAM==trspmode) );
+    }
+
+       LcdWrReg(inf, REG_CFG_DONE, 0x01);
+
+    return 0;
+}
+
+static int win1fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+    struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+    struct fb_var_screeninfo *var1 = &info->var;
+    struct fb_fix_screeninfo *fix1 = &info->fix;
+    int i;
+    u32 offset = 0, addr = 0;
+
+       fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
+
+       CHK_SUSPEND(inf);
+
+    switch(var1->bits_per_pixel)
+    {
+    case 16:    // rgb565
+        var->xoffset = (var->xoffset) & (~0x1);
+        offset = (var->yoffset*var1->xres_virtual + var->xoffset)*2;
+        break;
+    case 32:    // rgb888
+        offset = (var->yoffset*var1->xres_virtual + var->xoffset)*4;
+        break;
+    default:
+        return -EINVAL;
+    }
+
+    addr = fix1->smem_start + offset;
+
+    fbprintk("info->screen_base = %8x ; fix1->smem_len = %d , addr = %8x\n",(u32)info->screen_base, fix1->smem_len, addr);
+
+    LcdWrReg(inf, WIN1_YRGB_MST, addr);
+    LcdWrReg(inf, REG_CFG_DONE, 0x01);
+
+       mcu_refresh(inf);
+
+    // flush end when wq_condition=1 in mcu panel, but not in rgb panel
+    if(SCREEN_MCU == inf->cur_screen->type) {
+        wait_event_interruptible_timeout(wq, wq_condition, HZ/20);
+        wq_condition = 0;
+    } else {
+        wq_condition = 0;
+        wait_event_interruptible_timeout(wq, wq_condition, HZ/20);
+    }
+
+#if 0
+    for(i=0;i<=(0xc0/4);i+=4)
+    {
+        fbprintk("0x%02X: 0x%08X 0x%08X 0x%08X 0x%08X \n", i*4,
+            *((u32*)inf->reg_vir_base+i),
+            *((u32*)inf->reg_vir_base+i+1),
+            *((u32*)inf->reg_vir_base+i+2),
+            *((u32*)inf->reg_vir_base+i+3));
+    }
+#endif
+
+    return 0;
+}
+
+
+static int win1fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+{
+    struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+    struct rk29fb_info *mach_info = info->device->platform_data;
+    unsigned display_on;
+    int display_on_pol;
+
+       fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
+
+       CHK_SUSPEND(inf);
+
+    switch(cmd)
+    {
+    case FB0_IOCTL_STOP_TIMER_FLUSH:    //stop timer flush mcu panel after android is runing
+        if(1==arg)
+        {
+            inf->mcu_usetimer = 0;
+        }
+        break;
+
+    case FB0_IOCTL_SET_PANEL:
+        if(arg>7)   return -1;
+
+        /* Black out, because some display device need clock to standby */
+        //LcdMskReg(inf, DSP_CTRL_REG1, m_BLACK_OUT, v_BLACK_OUT(1));
+        LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE, v_W0_ENABLE(0));
+        LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE, v_W1_ENABLE(0));
+        LcdMskReg(inf, DSP_CTRL1, m_BLACK_MODE,  v_BLACK_MODE(1));
+        LcdWrReg(inf, REG_CFG_DONE, 0x01);
+        if(inf->cur_screen)
+        {
+            if(inf->cur_screen->standby)    inf->cur_screen->standby(1);
+            // operate the display_on pin to power down the lcd
+            if(SCREEN_RGB==inf->cur_screen->type || SCREEN_MCU==inf->cur_screen->type)
+            {
+                if(mach_info && mach_info->disp_on_pin)
+                {
+                    display_on = mach_info->disp_on_pin;
+                    display_on_pol = mach_info->disp_on_value;
+                    gpio_direction_output(display_on, 0);
+                       gpio_set_value(display_on, !display_on_pol);
+                }
+            }
+        }
+
+        /* Load the new device's param */
+        switch(arg)
+        {
+        case 0: inf->cur_screen = &inf->lcd_info;   break;  //lcd
+        case 1: inf->cur_screen = &inf->tv_info[0]; break;  //tv ntsc cvbs
+        case 2: inf->cur_screen = &inf->tv_info[1]; break;  //tv pal cvbs
+        case 3: inf->cur_screen = &inf->tv_info[2]; break;  //tv 480 ypbpr
+        case 4: inf->cur_screen = &inf->tv_info[3]; break;  //tv 576 ypbpr
+        case 5: inf->cur_screen = &inf->tv_info[4]; break;  //tv 720 ypbpr
+        case 6: inf->cur_screen = &inf->hdmi_info[0];  break;  //hdmi 576
+        case 7: inf->cur_screen = &inf->hdmi_info[1];  break;  //hdmi 720
+        default: break;
+        }
+        load_screen(info, 1);
+               mcu_refresh(inf);
+        break;
+    default:
+        break;
+    }
+    return 0;
+}
+
+
+static struct fb_ops win1fb_ops = {
+       .owner          = THIS_MODULE,
+       .fb_check_var   = win1fb_check_var,
+       .fb_set_par = win1fb_set_par,
+       .fb_blank   = win1fb_blank,
+       .fb_pan_display = win1fb_pan_display,
+    .fb_ioctl = win1fb_ioctl,
+       .fb_setcolreg   = fb_setcolreg,
+       .fb_fillrect    = cfb_fillrect,
+       .fb_copyarea    = cfb_copyarea,
+       .fb_imageblit   = cfb_imageblit,
+       //.fb_cursor      = rk29_set_cursor,
+};
+
+
+static irqreturn_t rk29fb_irq(int irq, void *dev_id)
+{
+       struct platform_device *pdev = (struct platform_device*)dev_id;
+    struct rk29fb_inf *inf = platform_get_drvdata(pdev);
+    if(!inf)
+        return IRQ_HANDLED;
+
+       //fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
+
+    LcdMskReg(inf, INT_STATUS, m_FRM_STARTCLEAR, v_FRM_STARTCLEAR(1));
+
+       if(SCREEN_MCU == inf->cur_screen->type)
+       {
+        inf->mcu_isrcnt = !inf->mcu_isrcnt;
+        if(inf->mcu_isrcnt)
+            return IRQ_HANDLED;
+
+        if(IsMcuUseFmk())
+        {
+            if(LcdReadBit(inf, MCU_TIMING_CTRL, m_MCU_HOLD_STATUS) && (inf->mcu_fmksync == 0))
+            {
+                inf->mcu_fmksync = 1;
+                 if(inf->cur_screen->refresh)
+                   inf->cur_screen->refresh(REFRESH_END);
+                inf->mcu_fmksync = 0;
+            }
+            else
+            {
+                return IRQ_HANDLED;
+            }
+        }
+        else
+        {
+            if(inf->mcu_needflush) {
+                if(inf->cur_screen->refresh)
+                    inf->cur_screen->refresh(REFRESH_PRE);
+                inf->mcu_needflush = 0;
+                inf->mcu_isrcnt = 0;
+                LcdSetRegBit(inf, MCU_TIMING_CTRL, m_MCU_HOLDMODE_FRAME_ST);
+            } else {
+                if(inf->cur_screen->refresh)
+                    inf->cur_screen->refresh(REFRESH_END);
+            }
+        }
+       }
+
+       wq_condition = 1;
+       wake_up_interruptible(&wq);
+
+       return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+
+struct suspend_info {
+       struct early_suspend early_suspend;
+       struct rk29fb_inf *inf;
+};
+
+void suspend(struct early_suspend *h)
+{
+       struct suspend_info *info = container_of(h, struct suspend_info,
+                                               early_suspend);
+
+    struct rk29fb_inf *inf = info->inf;
+
+    fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
+
+    if(!inf) {
+        printk("inf==0, rk29fb_suspend fail! \n");
+        return;
+    }
+
+    set_lcd_pin(g_pdev, 0);
+
+       if(inf->cur_screen->standby)
+       {
+               fbprintk(">>>>>> power down the screen! \n");
+               inf->cur_screen->standby(1);
+       }
+
+    LcdMskReg(inf, DSP_CTRL1, m_BLANK_MODE , v_BLANK_MODE(1));
+    LcdMskReg(inf, SYS_CONFIG, m_STANDBY, v_STANDBY(1));
+       LcdWrReg(inf, REG_CFG_DONE, 0x01);
+
+       if(!inf->in_suspend)
+       {
+               fbprintk(">>>>>> diable the lcdc clk! \n");
+               msleep(100);
+       if (inf->dclk){
+            clk_disable(inf->dclk);
+        }
+        if(inf->clk){
+            clk_disable(inf->clk);
+        }
+
+               inf->in_suspend = 1;
+       }
+
+}
+
+void resume(struct early_suspend *h)
+{
+       struct suspend_info *info = container_of(h, struct suspend_info,
+                                       early_suspend);
+
+    struct rk29fb_inf *inf = info->inf;
+
+    fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
+    if(!inf) {
+        printk("inf==0, rk29fb_resume fail! \n");
+        return ;
+    }
+
+       if(inf->in_suspend)
+       {
+           inf->in_suspend = 0;
+       fbprintk(">>>>>> enable the lcdc clk! \n");
+        if (inf->dclk){
+            clk_enable(inf->dclk);
+        }
+        if(inf->clk){
+            clk_enable(inf->clk);
+        }
+        msleep(100);
+       }
+    LcdMskReg(inf, DSP_CTRL1, m_BLANK_MODE , v_BLANK_MODE(0));
+    LcdMskReg(inf, SYS_CONFIG, m_STANDBY, v_STANDBY(0));
+    LcdWrReg(inf, REG_CFG_DONE, 0x01);
+
+       if(inf->cur_screen->standby)
+       {
+               fbprintk(">>>>>> power on the screen! \n");
+               inf->cur_screen->standby(0);
+       }
+    msleep(100);
+    set_lcd_pin(g_pdev, 1);
+       memcpy(inf->preg, &inf->regbak, 0xa4);  //resume reg
+}
+
+struct suspend_info suspend_info = {
+       .early_suspend.suspend = suspend,
+       .early_suspend.resume = resume,
+       .early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB,
+};
+#endif
+
+static int __init rk29fb_probe (struct platform_device *pdev)
+{
+    struct rk29fb_inf *inf = NULL;
+    struct resource *res = NULL;
+    struct resource *mem = NULL;
+    struct rk29fb_info *mach_info = NULL;
+    struct rk29fb_screen *screen = NULL;
+       int irq = 0;
+    int ret = 0;
+
+    fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
+
+    /* Malloc rk29fb_inf and set it to pdev for drvdata */
+    fbprintk(">> Malloc rk29fb_inf and set it to pdev for drvdata \n");
+    inf = kmalloc(sizeof(struct rk29fb_inf), GFP_KERNEL);
+    if(!inf)
+    {
+        dev_err(&pdev->dev, ">> inf kmalloc fail!");
+        ret = -ENOMEM;
+               goto release_drvdata;
+    }
+    memset(inf, 0, sizeof(struct rk29fb_inf));
+       platform_set_drvdata(pdev, inf);
+
+    mach_info = pdev->dev.platform_data;
+    /* Fill screen info and set current screen */
+    fbprintk(">> Fill screen info and set current screen \n");
+    set_lcd_info(&inf->lcd_info, mach_info->lcd_info);
+    set_tv_info(&inf->tv_info[0]);
+    set_hdmi_info(&inf->hdmi_info[0]);
+    inf->cur_screen = &inf->lcd_info;
+    screen = inf->cur_screen;
+    if(SCREEN_NULL==screen->type)
+    {
+        dev_err(&pdev->dev, ">> Please select a display device! \n");
+        ret = -EINVAL;
+               goto release_drvdata;
+    }
+
+    /* get virtual basic address of lcdc register */
+    fbprintk(">> get virtual basic address of lcdc register \n");
+    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+    if (res == NULL)
+    {
+        dev_err(&pdev->dev, "failed to get memory registers\n");
+        ret = -ENOENT;
+               goto release_drvdata;
+    }
+    inf->reg_phy_base = res->start;
+    inf->len = (res->end - res->start) + 1;
+    mem = request_mem_region(inf->reg_phy_base, inf->len, pdev->name);
+    if (mem == NULL)
+    {
+        dev_err(&pdev->dev, "failed to get memory region\n");
+        ret = -ENOENT;
+               goto release_drvdata;
+    }
+    fbprintk("inf->reg_phy_base = 0x%08x, inf->len = %d \n", inf->reg_phy_base, inf->len);
+    inf->reg_vir_base = ioremap(inf->reg_phy_base, inf->len);
+    if (inf->reg_vir_base == NULL)
+    {
+        dev_err(&pdev->dev, "ioremap() of registers failed\n");
+        ret = -ENXIO;
+               goto release_drvdata;
+    }
+    inf->preg = (LCDC_REG*)inf->reg_vir_base;
+
+    if(0)
+    {
+        struct resource *rtc_mem = NULL;
+        u32 rtc_reg_vir_base = NULL;
+        rtc_mem = request_mem_region(RK29_RTC_PHYS, RK29_RTC_SIZE, NULL);
+        rtc_reg_vir_base = (u32)ioremap(RK29_RTC_PHYS, RK29_RTC_SIZE);
+        u32 rtc_reg = __raw_readl(rtc_reg_vir_base+0x04);
+        __raw_writel( rtc_reg | 0x02, rtc_reg_vir_base+0x04 );
+        rtc_reg = __raw_readl(rtc_reg_vir_base+0x04);
+    }
+
+
+    /* Prepare win1 info */
+    fbprintk(">> Prepare win1 info \n");
+       inf->win1fb = framebuffer_alloc(sizeof(struct win1_par), &pdev->dev);
+    if(!inf->win1fb)
+    {
+        dev_err(&pdev->dev, ">> win1fb framebuffer_alloc fail!");
+               inf->win1fb = NULL;
+        ret = -ENOMEM;
+               goto release_win1fb;
+    }
+
+    strcpy(inf->win1fb->fix.id, "win1fb");
+    inf->win1fb->fix.type        = FB_TYPE_PACKED_PIXELS;
+    inf->win1fb->fix.type_aux    = 0;
+    inf->win1fb->fix.xpanstep    = 1;
+    inf->win1fb->fix.ypanstep    = 1;
+    inf->win1fb->fix.ywrapstep   = 0;
+    inf->win1fb->fix.accel       = FB_ACCEL_NONE;
+    inf->win1fb->fix.visual      = FB_VISUAL_TRUECOLOR;
+    inf->win1fb->fix.smem_len    = 0;
+    inf->win1fb->fix.line_length = 0;
+    inf->win1fb->fix.smem_start  = 0;
+
+    inf->win1fb->var.xres = screen->x_res;
+    inf->win1fb->var.yres = screen->y_res;
+    inf->win1fb->var.bits_per_pixel = 16;
+    inf->win1fb->var.xres_virtual = screen->x_res;
+    inf->win1fb->var.yres_virtual = screen->y_res;
+    inf->win1fb->var.width = screen->x_res;
+    inf->win1fb->var.height = screen->y_res;
+    inf->win1fb->var.pixclock = screen->pixclock;
+    inf->win1fb->var.left_margin = screen->left_margin;
+    inf->win1fb->var.right_margin = screen->right_margin;
+    inf->win1fb->var.upper_margin = screen->upper_margin;
+    inf->win1fb->var.lower_margin = screen->lower_margin;
+    inf->win1fb->var.vsync_len = screen->vsync_len;
+    inf->win1fb->var.hsync_len = screen->hsync_len;
+    inf->win1fb->var.red    = def_rgb_16.red;
+    inf->win1fb->var.green  = def_rgb_16.green;
+    inf->win1fb->var.blue   = def_rgb_16.blue;
+    inf->win1fb->var.transp = def_rgb_16.transp;
+
+    inf->win1fb->var.nonstd      = 0;  //win1 format & ypos & xpos (ypos<<20 + xpos<<8 + format)
+    inf->win1fb->var.grayscale   = 0;  //win1 transprent mode & value(mode<<8 + value)
+    inf->win1fb->var.activate    = FB_ACTIVATE_NOW;
+    inf->win1fb->var.accel_flags = 0;
+    inf->win1fb->var.vmode       = FB_VMODE_NONINTERLACED;
+
+    inf->win1fb->fbops           = &win1fb_ops;
+    inf->win1fb->flags           = FBINFO_FLAG_DEFAULT;
+    inf->win1fb->pseudo_palette  = ((struct win1_par*)inf->win1fb->par)->pseudo_pal;
+    inf->win1fb->screen_base     = 0;
+
+    memset(inf->win1fb->par, 0, sizeof(struct win1_par));
+       ret = fb_alloc_cmap(&inf->win1fb->cmap, 256, 0);
+       if (ret < 0)
+               goto release_cmap;
+
+    /* Prepare win0 info */
+    fbprintk(">> Prepare win0 info \n");
+    inf->win0fb = framebuffer_alloc(sizeof(struct win0_par), &pdev->dev);
+    if(!inf->win0fb)
+    {
+        dev_err(&pdev->dev, ">> win0fb framebuffer_alloc fail!");
+               inf->win0fb = NULL;
+               ret = -ENOMEM;
+               goto release_win0fb;
+    }
+
+    strcpy(inf->win0fb->fix.id, "win0fb");
+       inf->win0fb->fix.type         = FB_TYPE_PACKED_PIXELS;
+       inf->win0fb->fix.type_aux    = 0;
+       inf->win0fb->fix.xpanstep    = 1;
+       inf->win0fb->fix.ypanstep    = 1;
+       inf->win0fb->fix.ywrapstep   = 0;
+       inf->win0fb->fix.accel       = FB_ACCEL_NONE;
+    inf->win0fb->fix.visual      = FB_VISUAL_TRUECOLOR;
+    inf->win0fb->fix.smem_len    = 0;
+    inf->win0fb->fix.line_length = 0;
+    inf->win0fb->fix.smem_start  = 0;
+
+    inf->win0fb->var.xres = screen->x_res;
+    inf->win0fb->var.yres = screen->y_res;
+    inf->win0fb->var.bits_per_pixel = 16;
+    inf->win0fb->var.xres_virtual = screen->x_res;
+    inf->win0fb->var.yres_virtual = screen->y_res;
+    inf->win0fb->var.width = screen->x_res;
+    inf->win0fb->var.height = screen->y_res;
+    inf->win0fb->var.pixclock = screen->pixclock;
+    inf->win0fb->var.left_margin = screen->left_margin;
+    inf->win0fb->var.right_margin = screen->right_margin;
+    inf->win0fb->var.upper_margin = screen->upper_margin;
+    inf->win0fb->var.lower_margin = screen->lower_margin;
+    inf->win0fb->var.vsync_len = screen->vsync_len;
+    inf->win0fb->var.hsync_len = screen->hsync_len;
+    inf->win0fb->var.red    = def_rgb_16.red;
+    inf->win0fb->var.green  = def_rgb_16.green;
+    inf->win0fb->var.blue   = def_rgb_16.blue;
+    inf->win0fb->var.transp = def_rgb_16.transp;
+
+    inf->win0fb->var.nonstd      = 0;  //win0 format & ypos & xpos (ypos<<20 + xpos<<8 + format)
+    inf->win0fb->var.grayscale   = ((inf->win0fb->var.yres<<20)&0xfff00000) + ((inf->win0fb->var.xres<<8)&0xfff00);//win0 xsize & ysize
+    inf->win0fb->var.activate    = FB_ACTIVATE_NOW;
+    inf->win0fb->var.accel_flags = 0;
+    inf->win0fb->var.vmode       = FB_VMODE_NONINTERLACED;
+
+    inf->win0fb->fbops           = &win0fb_ops;
+       inf->win0fb->flags                    = FBINFO_FLAG_DEFAULT;
+       inf->win0fb->pseudo_palette  = ((struct win0_par*)inf->win0fb->par)->pseudo_pal;
+       inf->win0fb->screen_base     = 0;
+
+    memset(inf->win0fb->par, 0, sizeof(struct win0_par));
+
+       /* Init all lcdc and lcd before register_framebuffer. */
+       /* because after register_framebuffer, the win1fb_check_par and winfb_set_par execute immediately */
+       fbprintk(">> Init all lcdc and lcd before register_framebuffer \n");
+    init_lcdc(inf->win1fb);
+#if 0
+    inf->clk = clk_get(&pdev->dev, "lcdc_hclk");
+    if (!inf->clk || IS_ERR(inf->clk))
+    {
+        printk(KERN_ERR "failed to get lcdc_hclk source\n");
+        ret = -ENOENT;
+        goto unregister_win1fb;
+    }
+
+    inf->dclk = clk_get(&pdev->dev, "lcdc");
+       if (!inf->dclk || IS_ERR(inf->dclk))
+    {
+               printk(KERN_ERR "failed to get lcd dclock source\n");
+               ret = -ENOENT;
+               goto unregister_win1fb;
+       }
+    inf->dclk_parent = clk_get(&pdev->dev, "arm_pll");
+    if (!inf->dclk_parent || IS_ERR(inf->dclk_parent))
+    {
+               printk(KERN_ERR "failed to get lcd dclock parent source\n");
+               ret = -ENOENT;
+               goto unregister_win1fb;
+       }
+    inf->dclk_divider= clk_get(&pdev->dev, "lcdc_divider");
+    if (!inf->dclk_divider || IS_ERR(inf->dclk_divider))
+    {
+               printk(KERN_ERR "failed to get lcd clock lcdc_divider source \n");
+               ret = -ENOENT;
+               goto unregister_win1fb;
+       }
+
+    inf->clk_share_mem = clk_get(&pdev->dev, "lcdc_share_memory");
+    if (!inf->clk_share_mem || IS_ERR(inf->clk_share_mem))
+    {
+               dev_err(&pdev->dev,  "failed to get lcd clock clk_share_mem source \n");
+               ret = -ENOENT;
+               goto unregister_win1fb;
+       }
+  #ifdef CONFIG_CPU_FREQ
+    inf->freq_transition.notifier_call = rk29fb_freq_transition;
+    cpufreq_register_notifier(&inf->freq_transition, CPUFREQ_TRANSITION_NOTIFIER);
+  #endif
+       fbprintk("got clock\n");
+#endif
+
+       if(mach_info)
+    {
+        struct rk29_fb_setting_info fb_setting;
+        if( OUT_P888==inf->lcd_info.face ||
+            OUT_P888==inf->tv_info[0].face ||
+            OUT_P888==inf->hdmi_info[0].face )     // set lcdc iomux
+        {
+            fb_setting.data_num = 24;
+        }
+        else if(OUT_P666 == inf->lcd_info.face )
+        {
+            fb_setting.data_num = 18;
+        }
+        else
+        {
+            fb_setting.data_num = 16;
+        }
+        fb_setting.den_en = 1;
+        fb_setting.vsync_en = 1;
+        fb_setting.disp_on_en = 1;
+        fb_setting.standby_en = 1;
+        if( inf->lcd_info.mcu_usefmk )
+            fb_setting.mcu_fmk_en =1;
+        mach_info->io_init(&fb_setting);
+    }
+
+       //set_lcd_pin(pdev, 1);
+       mdelay(10);
+       g_pdev = pdev;
+       inf->mcu_usetimer = 1;
+    inf->mcu_fmksync = 0;
+       load_screen(inf->win1fb, 1);
+
+    /* Register framebuffer(win1fb & win0fb) */
+    fbprintk(">> Register framebuffer(win1fb) \n");
+    ret = register_framebuffer(inf->win1fb);
+    if(ret<0)
+    {
+        printk(">> win1fb register_framebuffer fail!\n");
+        ret = -EINVAL;
+               goto release_win0fb;
+    }
+    fbprintk(">> Register framebuffer(win0fb) \n");
+
+    ret = register_framebuffer(inf->win0fb);
+    if(ret<0)
+    {
+        printk(">> win0fb register_framebuffer fail!\n");
+        ret = -EINVAL;
+               goto unregister_win1fb;
+    }
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+       suspend_info.inf = inf;
+       register_early_suspend(&suspend_info.early_suspend);
+#endif
+
+    /* get and request irq */
+    fbprintk(">> get and request irq \n");
+    irq = platform_get_irq(pdev, 0);
+    if (irq < 0) {
+        dev_err(&pdev->dev, "no irq for device\n");
+        ret = -ENOENT;
+        goto unregister_win1fb;
+    }
+    ret = request_irq(irq, rk29fb_irq, IRQF_DISABLED, pdev->name, pdev);
+    if (ret) {
+        dev_err(&pdev->dev, "cannot get irq %d - err %d\n", irq, ret);
+        ret = -EBUSY;
+        goto release_irq;
+    }
+
+    if( inf->lcd_info.mcu_usefmk && (mach_info->mcu_fmk_pin != -1) )
+    {
+        ret = request_irq(gpio_to_irq(mach_info->mcu_fmk_pin), mcu_irqfmk, GPIOEdgelFalling, pdev->name, pdev);
+        if (ret)
+        {
+            dev_err(&pdev->dev, "cannot get fmk irq %d - err %d\n", irq, ret);
+            ret = -EBUSY;
+            goto release_irq;
+        }
+    }
+
+    printk(" %s ok\n", __FUNCTION__);
+    return ret;
+
+release_irq:
+       if(irq>=0)
+       free_irq(irq, pdev);
+unregister_win1fb:
+    unregister_framebuffer(inf->win1fb);
+release_win0fb:
+       if(inf->win0fb)
+               framebuffer_release(inf->win0fb);
+       inf->win0fb = NULL;
+release_cmap:
+    if(&inf->win1fb->cmap)
+        fb_dealloc_cmap(&inf->win1fb->cmap);
+release_win1fb:
+       if(inf->win1fb)
+               framebuffer_release(inf->win1fb);
+       inf->win1fb = NULL;
+release_drvdata:
+       if(inf && inf->reg_vir_base)
+       iounmap(inf->reg_vir_base);
+       if(inf && mem)
+       release_mem_region(inf->reg_phy_base, inf->len);
+       if(inf)
+       kfree(inf);
+       platform_set_drvdata(pdev, NULL);
+       return ret;
+}
+
+static int rk29fb_remove(struct platform_device *pdev)
+{
+    struct rk29fb_inf *inf = platform_get_drvdata(pdev);
+    struct fb_info *info = NULL;
+       //pm_message_t msg;
+    struct rk29fb_info *mach_info = NULL;
+    int irq = 0;
+
+       fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
+
+    if(!inf) {
+        printk("inf==0, rk29_fb_remove fail! \n");
+        return -EINVAL;
+    }
+
+    irq = platform_get_irq(pdev, 0);
+    if (irq >0)
+    {
+    free_irq(irq, pdev);
+    }
+
+    mach_info = pdev->dev.platform_data;
+    if(mach_info->mcu_fmk_pin)
+    {
+        free_irq(gpio_to_irq(mach_info->mcu_fmk_pin), pdev);
+    }
+
+       set_lcd_pin(pdev, 0);
+
+    // blank the lcdc
+    if(inf->win0fb)
+        win0fb_blank(FB_BLANK_POWERDOWN, inf->win0fb);
+    if(inf->win1fb)
+        win1fb_blank(FB_BLANK_POWERDOWN, inf->win1fb);
+
+       // suspend the lcdc
+       //rk29fb_suspend(pdev, msg);
+    // unmap memory and release framebuffer
+    if(inf->win0fb) {
+        info = inf->win0fb;
+        if (info->screen_base) {
+               //dma_free_writecombine(NULL, PAGE_ALIGN(info->fix.smem_len),info->screen_base, info->fix.smem_start);
+               info->screen_base = 0;
+               info->fix.smem_start = 0;
+               info->fix.smem_len = 0;
+        }
+        unregister_framebuffer(inf->win0fb);
+        framebuffer_release(inf->win0fb);
+        inf->win0fb = NULL;
+    }
+    if(inf->win1fb) {
+        info = inf->win1fb;
+        if (info->screen_base) {
+               dma_free_writecombine(NULL, PAGE_ALIGN(info->fix.smem_len),info->screen_base, info->fix.smem_start);
+               info->screen_base = 0;
+               info->fix.smem_start = 0;
+               info->fix.smem_len = 0;
+        }
+        unregister_framebuffer(inf->win1fb);
+        framebuffer_release(inf->win1fb);
+        inf->win1fb = NULL;
+    }
+
+  #ifdef CONFIG_CPU_FREQ
+    cpufreq_unregister_notifier(&inf->freq_transition, CPUFREQ_TRANSITION_NOTIFIER);
+  #endif
+
+       if (inf->clk)
+    {
+               clk_disable(inf->clk);
+               clk_put(inf->clk);
+               inf->clk = NULL;
+       }
+    if (inf->dclk)
+    {
+               clk_disable(inf->dclk);
+               clk_put(inf->dclk);
+               inf->dclk = NULL;
+       }
+
+    kfree(inf);
+    platform_set_drvdata(pdev, NULL);
+
+    return 0;
+}
+
+static void rk29fb_shutdown(struct platform_device *pdev)
+{
+    struct rk29fb_inf *inf = platform_get_drvdata(pdev);
+    mdelay(300);
+       //printk("----------------------------rk29fb_shutdown----------------------------\n");
+       set_lcd_pin(pdev, 0);
+    if (inf->dclk)
+    {
+        clk_disable(inf->dclk);
+    }
+    if (inf->clk)
+    {
+        clk_disable(inf->clk);
+    }
+}
+
+static struct platform_driver rk29fb_driver = {
+       .probe          = rk29fb_probe,
+       .remove         = rk29fb_remove,
+       .driver         = {
+               .name   = "rk29-fb",
+               .owner  = THIS_MODULE,
+       },
+       .shutdown   = rk29fb_shutdown,
+};
+
+static int __init rk29fb_init(void)
+{
+    return platform_driver_register(&rk29fb_driver);
+}
+
+static void __exit rk29fb_exit(void)
+{
+    platform_driver_unregister(&rk29fb_driver);
+}
+
+//subsys_initcall(rk29fb_init);
+
+module_init(rk29fb_init);
+module_exit(rk29fb_exit);
+
+
+MODULE_AUTHOR("  zyw@rock-chips.com");
+MODULE_DESCRIPTION("Driver for rk29 fb device");
+MODULE_LICENSE("GPL");
+
+
diff --git a/drivers/video/rk29_fb.h b/drivers/video/rk29_fb.h
new file mode 100755 (executable)
index 0000000..74bd6ba
--- /dev/null
@@ -0,0 +1,436 @@
+/* drivers/video/rk29_fb.h
+ *
+ * Copyright (C) 2010 ROCKCHIP, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_RK29_FB_H
+#define __ARCH_ARM_MACH_RK29_FB_H
+
+/********************************************************************
+**                            ºê¶¨Òå                                *
+********************************************************************/
+/* ÊäÍùÆÁµÄÊý¾Ý¸ñʽ */
+#define OUT_P888            0
+#define OUT_P666            1
+#define OUT_P565            2
+#define OUT_S888x           4
+#define OUT_CCIR656         6
+#define OUT_S888            8
+#define OUT_S888DUMY        12
+#define OUT_P16BPP4         24  //Ä£Äⷽʽ,¿ØÖÆÆ÷²¢²»Ö§³Ö
+
+
+/* SYS_CONFIG */
+#define m_W2_FORMAT          (3<<0)
+#define m_W1_FORMAT          (1<<2)
+#define m_W0_FORMAT          (7<<3)
+#define m_W0_CBR_DEFLICK_EN  (1<<6)
+#define m_W0_YRGB_DEFLICK_EN  (1<<7)
+#define m_INTERIACE_EN       (1<<8)
+#define m_W2_ENABLE          (1<<9)
+#define m_W1_ENABLE          (1<<10)
+#define m_W0_ENABLE          (1<<11)
+#define m_HWC_ENABLE         (1<<12)
+#define m_HWC_RELOAD_EN         (1<<13)
+#define m_W2_INTERLACE_READ    (1<<14)
+#define m_W1_INTERLACE_READ    (1<<15)
+#define m_W0_INTERLACE_READ    (1<<16)
+#define m_STANDBY            (1<<17)
+#define m_HWC_BURST          (3<<18)
+#define m_W2_BURST           (3<<20)
+#define m_W1_BURST           (3<<22)
+#define m_W0_BURST           (3<<24)
+#define m_W2_LUT_CTL         (1<<26)
+#define m_DSIP_LUT_CTL       (1<<27)
+#define m_HWC_REVERSED_COLOR   (1<<28)
+#define m_W1_AXI_OUTSTANDING2     (1<<29)
+#define m_W0_AXI_OUTSTANDING2     (1<<30)
+
+#define v_W2_FORMAT(x)         (((x)&3)<<0)
+#define v_W1_FORMAT(x)          (((x)&1)<<2)
+#define v_W0_FORMAT(x)          (((x)&7)<<3)
+#define v_W0_CBR_DEFLICK_EN(x)  (((x)&1)<<6)
+#define v_W0_YRGB_DEFLICK_EN(x)  (((x)&1)<<7)
+#define v_INTERIACE_EN(x)       (((x)&1)<<8)
+#define v_W2_ENABLE(x)          (((x)&)1<<9)
+#define v_W1_ENABLE(x)          (((x)&1)<<10)
+#define v_W0_ENABLE(x)          (((x)&1)<<11)
+#define v_HWC_ENABLE(x)         (((x)&1)<<12)
+#define v_HWC_RELOAD_EN(x)         (((x)&1)<<13)
+#define v_W2_INTERLACE_READ(x)    (((x)&1)<<14)
+#define v_W1_INTERLACE_READ(x)    (((x)&1)<<15)
+#define v_W0_INTERLACE_READ(x)    (((x)&1)<<16)
+#define v_STANDBY(x)            (((x)&1)<<17)
+#define v_HWC_BURST(x)          (((x)&3)<<18)
+#define v_W2_BURST(x)           (((x)&3)<<20)
+#define v_W1_BURST(x)           (((x)&3)<<22)
+#define v_W0_BURST(x)           (((x)&3)<<24)
+#define v_W2_LUT_CTL(x)         (((x)&1)<<26)
+#define v_DSIP_LUT_CTL(x)       (((x)&1)<<27)
+#define v_HWC_REVERSED_COLOR(x)   (((x)&1)<<28)
+#define v_W1_AXI_OUTSTANDING2(x)     (((x)&1)<<29)
+#define v_W0_AXI_OUTSTANDING2(x)     (((x)&1)<<30)
+
+//LCDC_SWAP_CTRL
+#define m_W1_565_RB_SWAP        (1<<0)
+#define m_W0_565_RB_SWAP        (1<<1)
+#define m_W0_YRGB_M8_SWAP       (1<<2)
+#define m_W0_YRGB_R_SHIFT_SWAP  (1<<3)
+#define m_W0_CBR_R_SHIFT_SWAP   (1<<4)
+#define m_W0_YRGB_16_SWAP       (1<<5)
+#define m_W0_YRGB_8_SWAP        (1<<6)
+#define m_W0_CBR_16_SWAP        (1<<7)
+#define m_W0_CBR_8_SWAP         (1<<8)
+#define m_W1_16_SWAP            (1<<9)
+#define m_W1_8_SWAP             (1<<10)
+#define m_W1_R_SHIFT_SWAP       (1<<11)
+#define m_OUTPUT_BG_SWAP        (1<<12)
+#define m_OUTPUT_RB_SWAP        (1<<13)
+#define m_OUTPUT_RG_SWAP        (1<<14)
+#define m_DELTA_SWAP            (1<<15)
+#define m_DUMMY_SWAP            (1<<16)
+#define m_W2_BYTE_SWAP          (1<<17)
+#define v_W1_565_RB_SWAP(x)        (((x)&1)<<0)
+#define v_W0_565_RB_SWAP(x)        (((x)&1)<<1)
+#define v_W0_YRGB_M8_SWAP(x)       (((x)&1)<<2)
+#define v_W0_YRGB_R_SHIFT_SWAP(x)  (((x)&1)<<3)
+#define v_W0_CBR_R_SHIFT_SWAP(x)   (((x)&1)<<4)
+#define v_W0_YRGB_16_SWAP(x)       (((x)&1)<<5)
+#define v_W0_YRGB_8_SWAP(x)        (((x)&1)<<6)
+#define v_W0_CBR_16_SWAP(x)        (((x)&1)<<7)
+#define v_W0_CBR_8_SWAP(x)         (((x)&1)<<8)
+#define v_W1_16_SWAP(x)            (((x)&1)<<9)
+#define v_W1_8_SWAP(x)             (((x)&1)<<10)
+#define v_W1_R_SHIFT_SWAP(x)       (((x)&1)<<11)
+#define v_OUTPUT_BG_SWAP(x)        (((x)&1)<<12)
+#define v_OUTPUT_RB_SWAP(x)        (((x)&1)<<13)
+#define v_OUTPUT_RG_SWAP(x)        (((x)&1)<<14)
+#define v_DELTA_SWAP(x)            (((x)&1)<<15)
+#define v_DUMMY_SWAP(x)            (((x)&1)<<16)
+#define v_W2_BYTE_SWAP(x)      (((x)&1)<<17)
+
+//LCDC_MCU_TIMING_CTRL
+#define m_MCU_WRITE_PERIOD      (31<<0)
+#define m_MCU_CS_ST             (31<<5)
+#define m_MCU_CS_END            (31<<10)
+#define m_MCU_RW_ST             (31<<15)
+#define m_MCU_RW_END            (31<<20)
+#define m_MCU_HOLD_STATUS          (1<<26)
+#define m_MCU_HOLDMODE_SELECT     (1<<27)
+#define m_MCU_HOLDMODE_FRAME_ST   (1<<28)
+#define m_MCU_RS_SELECT            (1<<29)
+#define m_MCU_BYPASSMODE_SELECT   (1<<30)
+#define m_MCU_OUTPUT_SELECT        (1<<31)
+#define v_MCU_WRITE_PERIOD(x)      (((x)&31)<<0)
+#define v_MCU_CS_ST(x)          (((x)&31)<<5)
+#define v_MCU_CS_END(x)         (((x)&31)<<10)
+#define v_MCU_RW_ST(x)          (((x)&31)<<15)
+#define v_MCU_RW_END(x)         (((x)&31)<<20)
+#define v_MCU_HOLD_STATUS(x)          (((x)&1)<<26)
+#define v_MCU_HOLDMODE_SELECT(x)     (((x)&1)<<27)
+#define v_MCU_HOLDMODE_FRAME_ST(x)   (((x)&1)<<28)
+#define v_MCU_RS_SELECT(x)            (((x)&1)<<29)
+#define v_MCU_BYPASSMODE_SELECT(x)   (((x)&1)<<30)
+#define v_MCU_OUTPUT_SELECT(x)        (((x)&1)<<31)
+
+//LCDC_ BLEND_CTRL
+#define m_HWC_BLEND_EN         (1<<0)
+#define m_W2_BLEND_EN          (1<<1)
+#define m_W1_BLEND_EN          (1<<2)
+#define m_W0_BLEND_EN          (1<<3)
+#define m_HWC_BLEND_FACTOR     (15<<4)
+#define m_W2_BLEND_FACTOR     (0xff<<8)
+#define m_W1_BLEND_FACTOR     (0xff<<16)
+#define m_W0_BLEND_FACTOR     (0xff<<24)
+
+#define v_HWC_BLEND_EN(x)         (((x)&1)<<0)
+#define v_W2_BLEND_EN(x)          (((x)&1)<<1)
+#define v_W1_BLEND_EN(x)          (((x)&1)<<2)
+#define v_W0_BLEND_EN(x)          (((x)&1)<<3)
+#define v_HWC_BLEND_FACTOR(x)    (((x)&15)<<4)
+#define v_W2_BLEND_FACTOR(x)     (((x)&0xff)<<8)
+#define v_W1_BLEND_FACTOR(x)     (((x)&0xff)<<16)
+#define v_W0_BLEND_FACTOR(x)     (((x)&0xff)<<24)
+
+
+//LCDC_WIN0_COLOR_KEY_CTRL / LCDC_WIN1_COLOR_KEY_CTRL
+#define m_KEYCOLOR          (0xffffff<<0)
+#define m_KEYCOLOR_B          (0xff<<0)
+#define m_KEYCOLOR_G          (0xff<<8)
+#define m_KEYCOLOR_R          (0xff<<16)
+#define m_COLORKEY_EN         (1<<24)
+#define v_KEYCOLOR(x)          (((x)&0xffffff)<<0)
+#define v_KEYCOLOR_B(x)          (((x)&0xff)<<0)
+#define v_KEYCOLOR_G(x)         (((x)&0xff)<<8)
+#define v_KEYCOLOR_R(x)          (((x)&0xff)<<16)
+#define v_COLORKEY_EN(x)         (((x)&1)<<24)
+
+//LCDC_DEFLICKER_SCL_OFFSET
+#define m_W0_YRGB_VSD_OFFSET      (0xff<<0)
+#define m_W0_YRGB_VSP_OFFSET      (0xff<<8)
+#define m_W1_VSD_OFFSET           (0xff<<16)
+#define m_W1_VSP_OFFSET           (0xff<<24)
+#define v_W0_YRGB_VSD_OFFSET(x)      (((x)&0xff)<<0)
+#define v_W0_YRGB_VSP_OFFSET(x)      (((x)&0xff)<<8)
+#define v_W1_VSD_OFFSET(x)           (((x)&0xff)<<16)
+#define v_W1_VSP_OFFSET(x)           (((x)&0xff)<<24)
+
+//LCDC_DSP_CTRL_REG0
+#define m_DISPLAY_FORMAT             (0xf<<0)
+#define m_HSYNC_POLARITY             (1<<4)
+#define m_VSYNC_POLARITY             (1<<5)
+#define m_DEN_POLARITY               (1<<6)
+#define m_DCLK_POLARITY              (1<<7)
+#define m_COLOR_SPACE_CONVERSION     (3<<8)
+#define m_DITHER_UP_EN               (1<<10)
+#define m_DITHER_DOWN_MODE           (1<<11)
+#define m_DITHER_DOWN_EN             (1<<12)
+#define m_INTERLACE_FIELD_POLARITY   (1<<13)
+#define m_YUV_CLIP                   (1<<14)
+#define m_W1_TRANSP_FROM             (1<<15)
+#define m_W0_TRANSP_FROM             (1<<16)
+#define m_W0_ON_TOP                  (1<<17)
+#define m_W1_CLIP_EN                 (1<<18)
+#define m_W0_CLIP_EN                 (1<<19)
+#define m_W0_YCBR_PRIORITY_MODE      (1<<20)
+#define m_CBR_FILTER_656             (1<<21)
+#define m_W2_CHIP_EN                 (1<<22)
+
+#define v_DISPLAY_FORMAT(x)            (((x)&0xf)<<0)
+#define v_HSYNC_POLARITY(x)             (((x)&1)<<4)
+#define v_VSYNC_POLARITY(x)             (((x)&1)<<5)
+#define v_DEN_POLARITY(x)               (((x)&1)<<6)
+#define v_DCLK_POLARITY(x)              (((x)&1)<<7)
+#define v_COLOR_SPACE_CONVERSION(x)     (((x)&3)<<8)
+#define v_DITHER_UP_EN(x)               (((x)&1)<<10)
+#define v_DITHER_DOWN_MODE(x)           (((x)&1)<<11)
+#define v_DITHER_DOWN_EN(x)             (((x)&1)<<12)
+#define v_INTERLACE_FIELD_POLARITY(x)   (((x)&1)<<13)
+#define v_YUV_CLIP(x)                   (((x)&1)<<14)
+#define v_W1_TRANSP_FROM(x)             (((x)&1)<<15)
+#define v_W0_TRANSP_FROM(x)             (((x)&1)<<16)
+#define v_W0_ON_TOP(x)                  (((x)&1)<<17)
+#define v_W1_CLIP_EN(x)                 (((x)&1)<<18)
+#define v_W0_CLIP_EN(x)                 (((x)&1)<<19)
+#define v_W0_YCBR_PRIORITY_MODE(x)      (((x)&1)<<20)
+#define v_CBR_FILTER_656(x)             (((x)&1)<<21)
+#define v_W2_CHIP_EN(x)                 (((x)&1)<<22)
+
+
+//LCDC_DSP_CTRL_REG1
+#define m_BG_COLOR                    (0xffffff<<0)
+#define m_BG_B                        (0xff<<0)
+#define m_BG_G                        (0xff<<8)
+#define m_BG_R                        (0xff<<16)
+#define m_BLANK_MODE                  (1<<24)
+#define m_BLACK_MODE                  (1<<25)
+#define m_DISP_FILTER_FACTOR          (3<<26)
+#define m_DISP_FILTER_MODE            (1<<28)
+#define m_DISP_FILTER_EN              (1<<29)
+#define v_BG_COLOR(x)                 (((x)&0xffffff)<<0)
+#define v_BG_B(x)                     (((x)&0xff)<<0)
+#define v_BG_G(x)                     (((x)&0xff)<<8)
+#define v_BG_R(x)                     (((x)&0xff)<<16)
+#define v_BLANK_MODE(x)               (((x)&1)<<24)
+#define v_BLACK_MODE(x)               (((x)&1)<<25)
+#define v_DISP_FILTER_FACTOR(x)       (((x)&3)<<26)
+#define v_DISP_FILTER_MODE(x)         (((x)&1)<<28)
+#define v_DISP_FILTER_EN(x)           (((x)&1)<<29)
+
+//LCDC_INT_STATUS
+#define m_HOR_START         (1<<0)
+#define m_FRM_START         (1<<1)
+#define m_SCANNING_FLAG     (1<<2)
+#define m_HOR_STARTMASK     (1<<3)
+#define m_FRM_STARTMASK     (1<<4)
+#define m_SCANNING_MASK     (1<<5)
+#define m_HOR_STARTCLEAR    (1<<6)
+#define m_FRM_STARTCLEAR    (1<<7)
+#define m_SCANNING_CLEAR    (1<<8)
+#define m_SCAN_LINE_NUM     (0x7ff<<9)
+#define v_HOR_START(x)         (((x)&1)<<0)
+#define v_FRM_START(x)         (((x)&1)<<1)
+#define v_SCANNING_FLAG(x)     (((x)&1)<<2)
+#define v_HOR_STARTMASK(x)     (((x)&1)<<3)
+#define v_FRM_STARTMASK(x)     (((x)&1)<<4)
+#define v_SCANNING_MASK(x)     (((x)&1)<<5)
+#define v_HOR_STARTCLEAR(x)    (((x)&1)<<6)
+#define v_FRM_STARTCLEAR(x)    (((x)&1)<<7)
+#define v_SCANNING_CLEAR(x)    (((x)&1)<<8)
+#define v_SCAN_LINE_NUM(x)     (((x)&0x7ff)<<9)
+
+//AXI MS ID
+#define m_W0_YRGB_CH_ID        (0xF<<0)
+#define m_W0_CBR_CH_ID         (0xF<<4)
+#define m_W1_YRGB_CH_ID        (0xF<<8)
+#define m_W2_CH_ID             (0xF<<12)
+#define m_HWC_CH_ID            (0xF<<16)
+#define v_W0_YRGB_CH_ID(x)        (((x)&0xF)<<0)
+#define v_W0_CBR_CH_ID(x)         (((x)&0xF)<<4)
+#define v_W1_YRGB_CH_ID(x)        (((x)&0xF)<<8)
+#define v_W2_CH_ID(x)             (((x)&0xF)<<12)
+#define v_HWC_CH_ID(x)            (((x)&0xF)<<16)
+
+
+/* Low Bits Mask */
+#define m_WORDLO            (0xffff<<0)
+#define m_WORDHI            (0xffff<<16)
+#define v_WORDLO(x)         (((x)&0xffff)<<0)
+#define v_WORDHI(x)         (((x)&0xffff)<<16)
+
+#define m_BIT11LO           (0x7ff<<0)
+#define m_BIT11HI           (0x7ff<<16)
+#define v_BIT11LO(x)        (((x)&0x7ff)<<0)
+#define v_BIT11HI(x)        (((x)&0x7ff)<<16)
+
+
+#define m_VIRWIDTH       (0xffff<<0)
+#define m_VIRHEIGHT      (0xffff<<16)
+#define v_VIRWIDTH(x)       (((x)&0xffff)<<0)
+#define v_VIRHEIGHT(x)      (((x)&0xffff)<<16)
+
+#define m_ACTWIDTH       (0xffff<<0)
+#define m_ACTHEIGHT      (0xffff<<16)
+#define v_ACTWIDTH(x)       (((x)&0xffff)<<0)
+#define v_ACTHEIGHT(x)      (((x)&0xffff)<<16)
+
+#define m_VIRST_X      (0xffff<<0)
+#define m_VIRST_Y      (0xffff<<16)
+#define v_VIRST_X(x)      (((x)&0xffff)<<0)
+#define v_VIRST_Y(x)      (((x)&0xffff)<<16)
+
+#define m_PANELST_X      (0x3ff<<0)
+#define m_PANELST_Y      (0x3ff<<16)
+#define v_PANELST_X(x)      (((x)&0x3ff)<<0)
+#define v_PANELST_Y(x)      (((x)&0x3ff)<<16)
+
+#define m_PANELWIDTH       (0x3ff<<0)
+#define m_PANELHEIGHT      (0x3ff<<16)
+#define v_PANELWIDTH(x)       (((x)&0x3ff)<<0)
+#define v_PANELHEIGHT(x)      (((x)&0x3ff)<<16)
+
+#define m_HWC_B                 (0xff<<0)
+#define m_HWC_G                 (0xff<<8)
+#define m_HWC_R                 (0xff<<16)
+#define m_W0_YRGB_HSP_OFFSET    (0xff<<24)
+#define m_W0_YRGB_HSD_OFFSET    (0xff<<24)
+#define v_HWC_B(x)                 (((x)&0xff)<<0)
+#define v_HWC_G(x)                 (((x)&0xff)<<8)
+#define v_HWC_R(x)                 (((x)&0xff)<<16)
+#define v_W0_YRGB_HSP_OFFSET(x)    (((x)&0xff)<<24)
+#define v_W0_YRGB_HSD_OFFSET(x)    (((x)&0xff)<<24)
+
+
+//Panel display scanning
+#define m_PANEL_HSYNC_WIDTH             (0x3ff<<0)
+#define m_PANEL_HORIZONTAL_PERIOD       (0x3ff<<16)
+#define v_PANEL_HSYNC_WIDTH(x)             (((x)&0x3ff)<<0)
+#define v_PANEL_HORIZONTAL_PERIOD(x)       (((x)&0x3ff)<<16)
+
+#define m_PANEL_END              (0x3ff<<0)
+#define m_PANEL_START            (0x3ff<<16)
+#define v_PANEL_END(x)              (((x)&0x3ff)<<0)
+#define v_PANEL_START(x)            (((x)&0x3ff)<<16)
+
+#define m_PANEL_VSYNC_WIDTH             (0x3ff<<0)
+#define m_PANEL_VERTICAL_PERIOD       (0x3ff<<16)
+#define v_PANEL_VSYNC_WIDTH(x)             (((x)&0x3ff)<<0)
+#define v_PANEL_VERTICAL_PERIOD(x)       (((x)&0x3ff)<<16)
+//-----------
+
+#define m_HSCALE_FACTOR        (0xffff<<0)
+#define m_VSCALE_FACTOR        (0xffff<<16)
+#define v_HSCALE_FACTOR(x)        (((x)&0xffff)<<0)
+#define v_VSCALE_FACTOR(x)        (((x)&0xffff)<<16)
+
+#define m_W0_CBR_HSD_OFFSET   (0xff<<0)
+#define m_W0_CBR_HSP_OFFSET   (0xff<<8)
+#define m_W0_CBR_VSD_OFFSET   (0xff<<16)
+#define m_W0_CBR_VSP_OFFSET   (0xff<<24)
+#define v_W0_CBR_HSD_OFFSET(x)   (((x)&0xff)<<0)
+#define v_W0_CBR_HSP_OFFSET(x)   (((x)&0xff)<<8)
+#define v_W0_CBR_VSD_OFFSET(x)   (((x)&0xff)<<16)
+#define v_W0_CBR_VSP_OFFSET(x)   (((x)&0xff)<<24)
+
+
+#define FB0_IOCTL_STOP_TIMER_FLUSH             0x6001
+#define FB0_IOCTL_SET_PANEL                            0x6002
+
+#define FB1_IOCTL_GET_PANEL_SIZE               0x5001
+#define FB1_IOCTL_SET_YUV_ADDR                 0x5002
+//#define FB1_TOCTL_SET_MCU_DIR                        0x5003
+#define FB1_IOCTL_SET_ROTATE            0x5003
+#define FB1_IOCTL_SET_I2P_ODD_ADDR      0x5005
+#define FB1_IOCTL_SET_I2P_EVEN_ADDR     0x5006
+
+
+/********************************************************************
+**                          ½á¹¹¶¨Òå                                *
+********************************************************************/
+/* LCDCµÄ¼Ä´æÆ÷½á¹¹ */
+
+typedef volatile struct tagLCDC_REG
+{
+    /* offset 0x00~0xc0 */
+    unsigned int SYS_CONFIG;              //0x00 SYSTEM configure register
+    unsigned int SWAP_CTRL;               //0x04 Data SWAP control
+    unsigned int MCU_TIMING_CTRL;         //0x08 MCU TIMING control register
+    unsigned int BLEND_CTRL;              //0x0c Blending control register
+    unsigned int WIN0_COLOR_KEY_CTRL;     //0x10 Win0 blending control register
+    unsigned int WIN1_COLOR_KEY_CTRL;     //0x14 Win1 blending control register
+    unsigned int WIN2_VIR;                //0x18 WIN2 virtual display width
+    unsigned int DSP_CTRL0;               //0x1c Display control register0
+    unsigned int DSP_CTRL1;               //0x20 Display control register1
+    unsigned int INT_STATUS;              //0x24 Interrupt status register
+    unsigned int WIN0_VIR;                //0x28 WIN0 virtual display width/height
+    unsigned int WIN0_YRGB_MST;           //0x2c Win0 active YRGB memory start address
+    unsigned int WIN0_CBR_MST;            //0x30 Win0 active Cbr memory start address
+    unsigned int WIN0_ACT_INFO;           //0x34 Win0 active window width/height
+    unsigned int WIN0_DSP_ST;             //0x38 Win0 display start point on panel
+    unsigned int WIN0_DSP_INFO;           //0x3c Win0 display width/height on panel
+    unsigned int WIN1_VIR;                //0x40 Win1 virtual display width/height
+    unsigned int WIN1_YRGB_MST;           //0x44 Win1 active  memory start address
+    unsigned int WIN1_DSP_INFO;           //0x48 Win1 display width/height on panel
+    unsigned int WIN1_DSP_ST;             //0x4c Win1 display start point on panel
+    unsigned int WIN2_MST;                //0X50 Win2 memory start address
+    unsigned int WIN2_DSP_INFO;           //0x54 Win1 display width/height on panel
+    unsigned int WIN2_DSP_ST;             //0x58 Win1 display start point on panel
+    unsigned int HWC_MST;                 //0x5C HWC memory start address
+    unsigned int HWC_DSP_ST;              //0x60 HWC display start point on panel
+    unsigned int HWC_COLOR_LUT0;          //0x64 Hardware cursor color 2¡¯b01 look up table 0
+    unsigned int HWC_COLOR_LUT1;          //0x68 Hardware cursor color 2¡¯b10 look up table 1
+    unsigned int HWC_COLOR_LUT2;          //0x6c Hardware cursor color 2¡¯b11 look up table 2
+    unsigned int DSP_HTOTAL_HS_END;       //0x70 Panel scanning horizontal width and hsync pulse end point
+    unsigned int DSP_HACT_ST_END;         //0x74 Panel active horizontal scanning start/end point
+    unsigned int DSP_VTOTAL_VS_END;       //0x78 Panel scanning vertical height and vsync pulse end point
+    unsigned int DSP_VACT_ST_END;         //0x7c Panel active vertical scanning start/end point
+    unsigned int DSP_VS_ST_END_F1;        //0x80 Vertical scanning start point and vsync pulse end point of even filed in interlace mode
+    unsigned int DSP_VACT_ST_END_F1;      //0x84 Vertical scanning active start/end point of even filed in interlace mode
+    unsigned int WIN0_SCL_FACTOR_YRGB;    //0x88 Win0 YRGB scaling down factor setting
+    unsigned int WIN0_SCL_FACTOR_CBR;     //0x8c Win0 YRGB scaling up factor setting
+    unsigned int WIN0_SCL_OFFSET;         //0x90 Win0 Cbr scaling start point offset
+    unsigned int FIFO_WATER_MARK;         //0x94 Fifo water mark
+    unsigned int AXI_MS_ID;               //0x98 Axi master ID
+    unsigned int reserved0;               //0x9c
+    unsigned int REG_CFG_DONE;            //0xa0 REGISTER CONFIG FINISH
+    unsigned int reserved1[(0x100-0xa4)/4];
+    unsigned int MCU_BYPASS_WPORT;         //0x100 MCU BYPASS MODE, DATA Write Only Port
+    unsigned int reserved2[(0x200-0x104)/4];
+    unsigned int MCU_BYPASS_RPORT;         //0x200 MCU BYPASS MODE, DATA Read Only Port
+} LCDC_REG, *pLCDC_REG;
+
+
+extern void __init rk29_add_device_lcdc(void);
+extern int mcu_ioctl(unsigned int cmd, unsigned long arg);
+
+#endif