mipi: modify dsi framework and add rk616 mipi dis dirver
authorhhb <hhb@rock-chips.com>
Fri, 14 Jun 2013 08:00:08 +0000 (16:00 +0800)
committerhhb <hhb@rock-chips.com>
Fri, 14 Jun 2013 08:00:08 +0000 (16:00 +0800)
drivers/video/rockchip/screen/rk_screen.c
drivers/video/rockchip/transmitter/Kconfig
drivers/video/rockchip/transmitter/Makefile
drivers/video/rockchip/transmitter/mipi_dsi.c
drivers/video/rockchip/transmitter/mipi_dsi.h
drivers/video/rockchip/transmitter/rk616_mipi_dsi.c [new file with mode: 0644]
drivers/video/rockchip/transmitter/rk616_mipi_dsi.h [new file with mode: 0644]
drivers/video/rockchip/transmitter/ssd2828.c
drivers/video/rockchip/transmitter/tc358768.c
include/linux/rk_screen.h

index b7a4e580a58782640fbd22d2c5a71df2e5f661a6..06a0d00ad4df058f975ca31ffe218bfc98a188a9 100644 (file)
@@ -227,7 +227,13 @@ void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info )
        screen->swap_gb = SWAP_GB;
        screen->swap_delta = 0;
        screen->swap_dumy = 0;
-
+       
+#if defined(CONFIG_MIPI_DSI)
+       /* MIPI DSI */
+    screen->dsi_lane = MIPI_DSI_LANE;
+    //screen->dsi_video_mode = MIPI_DSI_VIDEO_MODE;
+    screen->hs_tx_clk = MIPI_DSI_HS_CLK;
+#endif
        /* Operation function*/
 #if defined(RK_SCREEN_INIT)  //some screen need to init by spi or i2c
        screen->init = rk_lcd_init;
index 820fc191637725213e8d677699d8f1bbf92f97c4..cbd56e27e36b6fdba564660b096ccbc3f447d83e 100644 (file)
@@ -28,17 +28,26 @@ config DP501
        bool"RGB to Display Port transmitter dp501 support"
        depends on RK_TRSM
 
-config TC358768_RGB2MIPI
-        bool "toshiba TC358768 RGB to MIPI DSI"
+config MIPI_DSI
        depends on RK_TRSM
+       bool "Rockchip MIPI DSI support"
+
+config TC358768_RGB2MIPI
+        tristate "toshiba TC358768 RGB to MIPI DSI"
+               depends on MIPI_DSI
         help
         "a chip that change RGB interface parallel signal into DSI serial signal"
 
 config SSD2828_RGB2MIPI
-        bool "solomon SSD2828 RGB to MIPI DSI"
-       depends on RK_TRSM
+        tristate "solomon SSD2828 RGB to MIPI DSI"
+               depends on MIPI_DSI
         help
         "a chip that change RGB interface parallel signal into DSI serial signal"
-       
+
+config RK616_MIPI_DSI
+        tristate "RK616(JettaB) mipi dsi support"
+        depends on MFD_RK616 && MIPI_DSI
+        help
+           RK616(Jetta B) mipi dstristatei support.            
 
                        
index 0fa2485703cbdaab2653cd6cfb4e47c3295b187e..010fc6a0d0afcfc1d3191b8a06483a91eef25f44 100644 (file)
@@ -4,7 +4,9 @@
 obj-$(CONFIG_RK2928_LVDS)          += rk2928_lvds.o
 obj-$(CONFIG_RK610_LVDS)         += rk610_lcd.o
 obj-$(CONFIG_RK616_LVDS)          += rk616_lvds.o
-obj-$(CONFIG_TC358768_RGB2MIPI)   += mipi_dsi.o tc358768.o
-obj-$(CONFIG_SSD2828_RGB2MIPI)   += mipi_dsi.o ssd2828.o
 obj-$(CONFIG_DP_ANX6345)          += dp_anx6345.o
 obj-$(CONFIG_DP501)          += dp501.o
+obj-$(CONFIG_MIPI_DSI)                         += mipi_dsi.o 
+obj-$(CONFIG_RK616_MIPI_DSI)           += rk616_mipi_dsi.o
+obj-$(CONFIG_TC358768_RGB2MIPI)     += tc358768.o
+obj-$(CONFIG_SSD2828_RGB2MIPI)      += ssd2828.o
\ No newline at end of file
index e14fd2a1800a56bb5446af662bde7a239c0b6e8b..10fcc2231ed4420d61706b459bfc60fe46b05456 100644 (file)
@@ -60,7 +60,7 @@ int del_dsi_ops(struct mipi_dsi_ops *ops) {
 EXPORT_SYMBOL(del_dsi_ops);
 
 int dsi_probe_current_chip(void) {
-
+       int ret = 0;
        u32 i = 0, id;
        struct mipi_dsi_ops *ops = NULL;
        if(cur_dsi_ops)
@@ -77,13 +77,14 @@ int dsi_probe_current_chip(void) {
                                printk("mipi dsi chip is not found, read id:%08x, but %08x is correct\n", id, ops->id);
                                dsi_ops[i] = NULL;
                                cur_dsi_ops = NULL;
+                               ret = -1;
                        }
                }       
        }
        if(i == MAX_DSI_CHIPS)
                printk("no mipi dsi chip\n");
 
-       return 0;
+       return ret;
 }
 EXPORT_SYMBOL(dsi_probe_current_chip);
 
@@ -108,7 +109,7 @@ int dsi_power_off(void) {
 }
 EXPORT_SYMBOL(dsi_power_off);
 
-int dsi_set_regs(void *array, int n) {
+int dsi_set_regs(void *array, u32 n) {
 
        if(!cur_dsi_ops)
                return -1;
@@ -118,7 +119,7 @@ int dsi_set_regs(void *array, int n) {
 }
 EXPORT_SYMBOL(dsi_set_regs);
 
-int dsi_init(void *array, int n) {
+int dsi_init(void *array, u32 n) {
 
        if(!cur_dsi_ops)
                return -1;
@@ -129,7 +130,7 @@ int dsi_init(void *array, int n) {
 EXPORT_SYMBOL(dsi_init);
 
 
-int dsi_send_dcs_packet(unsigned char *packet, int n) {
+int dsi_send_dcs_packet(unsigned char *packet, u32 n) {
 
        if(!cur_dsi_ops)
                return -1;
@@ -140,7 +141,7 @@ int dsi_send_dcs_packet(unsigned char *packet, int n) {
 EXPORT_SYMBOL(dsi_send_dcs_packet);
 
 
-int dsi_read_dcs_packet(unsigned char *packet, int n) {
+int dsi_read_dcs_packet(unsigned char *packet, u32 n) {
 
        if(!cur_dsi_ops)
                return -1;
@@ -151,7 +152,7 @@ int dsi_read_dcs_packet(unsigned char *packet, int n) {
 EXPORT_SYMBOL(dsi_read_dcs_packet);
 
 
-int dsi_send_packet(void *packet, int n) {
+int dsi_send_packet(void *packet, u32 n) {
 
        if(!cur_dsi_ops)
                return -1;
index b0d54f8035396f69a9b42d38cdf3b23a65c050b4..6a1f5596a2038d9d27dc6973fbb7e96d1b2f5706 100644 (file)
@@ -113,11 +113,11 @@ struct mipi_dsi_ops {
        u32 id;
        char *name;
        int (*get_id)(void);
-       int (*dsi_init)(void *, int n);
-       int (*dsi_set_regs)(void *, int n);
-       int (*dsi_send_dcs_packet)(unsigned char *, int n);
-       int (*dsi_read_dcs_packet)(unsigned char *, int n);
-       int (*dsi_send_packet)(void *, int n);
+       int (*dsi_init)(void *, u32 n);
+       int (*dsi_set_regs)(void *, u32 n);
+       int (*dsi_send_dcs_packet)(unsigned char *, u32 n);
+       int (*dsi_read_dcs_packet)(unsigned char *, u32 n);
+       int (*dsi_send_packet)(void *, u32 n);
        int (*power_up)(void);
        int (*power_down)(void);        
 };
@@ -128,9 +128,13 @@ int del_dsi_ops(struct mipi_dsi_ops *ops);
 int dsi_power_up(void);
 int dsi_power_off(void);
 int dsi_probe_current_chip(void);
-int dsi_init(void *array, int n);
-int dsi_set_regs(void *array, int n);
-int dsi_send_dcs_packet(unsigned char *packet, int n);
-int dsi_read_dcs_packet(unsigned char *packet, int n);
-int dsi_send_packet(void *packet, int n);
+int dsi_init(void *array, u32 n);
+
+int dsi_enable_video_mode(u32 enable);
+int dsi_set_virtual_channel(u32 channel);
+
+int dsi_set_regs(void *array, u32 n);
+int dsi_send_dcs_packet(unsigned char *packet, u32 n);
+int dsi_read_dcs_packet(unsigned char *packet, u32 n);
+int dsi_send_packet(void *packet, u32 n);
 #endif /* end of MIPI_DSI_H_ */
diff --git a/drivers/video/rockchip/transmitter/rk616_mipi_dsi.c b/drivers/video/rockchip/transmitter/rk616_mipi_dsi.c
new file mode 100644 (file)
index 0000000..5f1ef90
--- /dev/null
@@ -0,0 +1,1064 @@
+/*
+drivers/video/display/transmitter/rk616_mipi_dsi.c
+debug sys/kernel/debug/rk616/mipi
+*/
+
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/mfd/rk616.h>
+#include <linux/rk_fb.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <asm/div64.h>
+
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include<linux/earlysuspend.h>
+#include <linux/regulator/machine.h>
+
+#include "mipi_dsi.h"
+#include "rk616_mipi_dsi.h"
+
+#if 0
+#define        MIPI_DBG(x...)  printk(KERN_INFO x)
+#else
+#define        MIPI_DBG(x...)
+#endif
+
+
+static struct dsi gDsi;
+static struct mfd_rk616 *dsi_rk616;
+static struct mipi_dsi_ops rk_mipi_dsi_ops;
+static struct rk29fb_screen *g_screen = NULL;
+static unsigned char dcs_exit_sleep_mode[] = {0x11};
+static unsigned char dcs_set_diaplay_on[] = {0x29};
+static unsigned char dcs_enter_sleep_mode[] = {0x10};
+static unsigned char dcs_set_diaplay_off[] = {0x28};
+static unsigned char dcs_test[] = {0x3e, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
+static int rk_mipi_dsi_send_dcs_packet(unsigned char regs[], u32 n);
+
+static int dsi_read_reg(u16 reg, u32 *pval)
+{
+       return dsi_rk616->read_dev(dsi_rk616, reg, pval);
+}
+
+
+static int dsi_write_reg(u16 reg, u32 *pval)
+{
+       return dsi_rk616->write_dev(dsi_rk616, reg, pval);
+}
+
+static int dsi_get_bits(u32 reg)
+{
+       u32 val = 0;
+       u32 bits = (reg >> 8) & 0xff;
+       u16 reg_addr = (reg >> 16) & 0xffff;
+       u8 offset = reg & 0xff;
+       bits = (1 << bits) - 1;
+       dsi_read_reg(reg_addr, &val);    
+       val >>= offset;
+       val &= bits;
+       return val;
+}
+
+static int dsi_set_bits(u32 data, u32 reg)
+{
+       u32 val = 0;
+       u32 bits = (reg >> 8) & 0xff;
+       u16 reg_addr = (reg >> 16) & 0xffff;
+       u8 offset = reg & 0xff;
+       bits = (1 << bits) - 1;
+       
+       dsi_read_reg(reg_addr, &val);      //CAN optimise  speed and time cost   warnning
+       val &= ~(bits << offset);
+       val |= (data & bits) << offset;
+       dsi_write_reg(reg_addr, &val);
+       
+       //if(dsi_get_bits(reg) != data)
+       //      printk("write :%08x error\n", reg);
+       return 0;
+}
+
+static int rk_mipi_dsi_phy_preset_gotp(void *array, int n) {
+
+       u32 val = 0;
+       struct rk29fb_screen *screen = array;
+
+       return 0;
+}
+
+static int rk_mipi_dsi_phy_set_gotp(u32 offset, int n) {
+       
+       u32 val = 0, temp = 0, Tlpx = 0;
+       u32 ddr_clk = gDsi.phy.ddr_clk;
+       u32 Tddr_clk = gDsi.phy.Tddr_clk;
+       u32 Ttxbyte_clk = gDsi.phy.Ttxbyte_clk;
+       u32 Tsys_clk = gDsi.phy.Tsys_clk;
+       u32 Ttxclkesc = gDsi.phy.Ttxclkesc;
+       
+       
+       switch(offset) {
+               case DPHY_CLOCK_OFFSET:
+                       MIPI_DBG("******set DPHY_CLOCK_OFFSET gotp******\n");
+                       break;
+               case DPHY_LANE0_OFFSET:
+                       MIPI_DBG("******set DPHY_LANE0_OFFSET gotp******\n");
+                       break;
+               case DPHY_LANE1_OFFSET:
+                       MIPI_DBG("******set DPHY_LANE1_OFFSET gotp******\n");
+                       break;
+               case DPHY_LANE2_OFFSET:
+                       MIPI_DBG("******set DPHY_LANE2_OFFSET gotp******\n");
+                       break;
+               case DPHY_LANE3_OFFSET:
+                       MIPI_DBG("******set DPHY_LANE3_OFFSET gotp******\n");
+                       break;
+               default:
+                       break;                                  
+       }
+       
+       if(ddr_clk < 110 * MHz)
+               val = 0;
+       else if(ddr_clk < 150 * MHz)
+               val = 1;
+       else if(ddr_clk < 200 * MHz)
+               val = 2;
+       else if(ddr_clk < 250 * MHz)
+               val = 3;
+       else if(ddr_clk < 300 * MHz)
+               val = 4;
+       else if(ddr_clk < 400 * MHz)
+               val = 5;                
+       else if(ddr_clk < 500 * MHz)
+               val = 6;                
+       else if(ddr_clk < 600 * MHz)
+               val = 7;                
+       else if(ddr_clk < 700 * MHz)
+               val = 8;
+       else if(ddr_clk < 800 * MHz)
+               val = 9;                
+       else if(ddr_clk <= 1000 * MHz)
+               val = 10;                                                       
+       dsi_write_reg(reg_ths_settle + offset, &val);
+               
+       if(ddr_clk < 110 * MHz)
+               val = 0x20;
+       else if(ddr_clk < 150 * MHz)
+               val = 0x06;
+       else if(ddr_clk < 200 * MHz)
+               val = 0x18;
+       else if(ddr_clk < 250 * MHz)
+               val = 0x05;
+       else if(ddr_clk < 300 * MHz)
+               val = 0x51;
+       else if(ddr_clk < 400 * MHz)
+               val = 0x64;             
+       else if(ddr_clk < 500 * MHz)
+               val = 0x59;             
+       else if(ddr_clk < 600 * MHz)
+               val = 0x6a;             
+       else if(ddr_clk < 700 * MHz)
+               val = 0x3e;
+       else if(ddr_clk < 800 * MHz)
+               val = 0x21;             
+       else if(ddr_clk <= 1000 * MHz)
+               val = 0x09;                             
+               
+       MIPI_DBG("reg_hs_ths_prepare: %d, %d\n", val, val*Tddr_clk/1000);                               
+       dsi_write_reg(reg_hs_ths_prepare + offset, &val);
+       
+       if(offset != DPHY_CLOCK_OFFSET) {
+       
+               if(ddr_clk < 110 * MHz)
+                       val = 2;
+               else if(ddr_clk < 150 * MHz)
+                       val = 3;
+               else if(ddr_clk < 200 * MHz)
+                       val = 4;
+               else if(ddr_clk < 250 * MHz)
+                       val = 5;
+               else if(ddr_clk < 300 * MHz)
+                       val = 6;
+               else if(ddr_clk < 400 * MHz)
+                       val = 7;                
+               else if(ddr_clk < 500 * MHz)
+                       val = 7;                
+               else if(ddr_clk < 600 * MHz)
+                       val = 8;                
+               else if(ddr_clk < 700 * MHz)
+                       val = 8;
+               else if(ddr_clk < 800 * MHz)
+                       val = 9;                
+               else if(ddr_clk <= 1000 * MHz)
+                       val = 9;        
+       } else {
+       
+               if(ddr_clk < 110 * MHz)
+                       val = 0x16;
+               else if(ddr_clk < 150 * MHz)
+                       val = 0x16;
+               else if(ddr_clk < 200 * MHz)
+                       val = 0x17;
+               else if(ddr_clk < 250 * MHz)
+                       val = 0x17;
+               else if(ddr_clk < 300 * MHz)
+                       val = 0x18;
+               else if(ddr_clk < 400 * MHz)
+                       val = 0x19;             
+               else if(ddr_clk < 500 * MHz)
+                       val = 0x1b;             
+               else if(ddr_clk < 600 * MHz)
+                       val = 0x1d;             
+               else if(ddr_clk < 700 * MHz)
+                       val = 0x1e;
+               else if(ddr_clk < 800 * MHz)
+                       val = 0x1f;             
+               else if(ddr_clk <= 1000 * MHz)
+                       val = 0x20;     
+       }                       
+       
+       MIPI_DBG("reg_hs_the_zero: %d, %d\n", val, (val + 5)*Ttxbyte_clk/1000);                                 
+       dsi_write_reg(reg_hs_the_zero + offset, &val);
+       
+       if(ddr_clk < 110 * MHz)
+               val = 0x22;
+       else if(ddr_clk < 150 * MHz)
+               val = 0x45;
+       else if(ddr_clk < 200 * MHz)
+               val = 0x0b;
+       else if(ddr_clk < 250 * MHz)
+               val = 0x16;
+       else if(ddr_clk < 300 * MHz)
+               val = 0x2c;
+       else if(ddr_clk < 400 * MHz)
+               val = 0x33;             
+       else if(ddr_clk < 500 * MHz)
+               val = 0x4e;             
+       else if(ddr_clk < 600 * MHz)
+               val = 0x3a;             
+       else if(ddr_clk < 700 * MHz)
+               val = 0x6a;
+       else if(ddr_clk < 800 * MHz)
+               val = 0x29;             
+       else if(ddr_clk <= 1000 * MHz)
+               val = 0x27;             
+       dsi_write_reg(reg_hs_ths_trail + offset, &val);
+       
+       val = 120000 / Ttxbyte_clk + 1;
+       MIPI_DBG("reg_hs_ths_exit: %d, %d\n", val, val*Ttxbyte_clk/1000);
+       dsi_write_reg(reg_hs_ths_exit + offset, &val);  
+       
+       if(offset == DPHY_CLOCK_OFFSET) {
+               val = (80000 + 52*gDsi.phy.UI) / Ttxbyte_clk + 1;
+               MIPI_DBG("reg_hs_tclk_post: %d, %d\n", val, val*Ttxbyte_clk/1000);
+               dsi_write_reg(reg_hs_tclk_post + offset, &val); 
+               val = 10*gDsi.phy.UI / Ttxbyte_clk + 1;
+               MIPI_DBG("reg_hs_tclk_pre: %d, %d\n", val, val*Ttxbyte_clk/1000);
+               dsi_write_reg(reg_hs_tclk_pre + offset, &val);  
+       }
+
+       val = 1010000000 / Tsys_clk + 1;
+       MIPI_DBG("reg_hs_twakup: %d, %d\n", val, val*Tsys_clk/1000);
+       if(val > 0x3ff) {
+               val = 0x2ff;
+               MIPI_DBG("val is too large, 0x3ff is the largest\n");   
+       }       
+       temp = (val >> 8) & 0x03;
+       val &= 0xff;
+       dsi_write_reg(reg_hs_twakup_h + offset, &temp);         
+       dsi_write_reg(reg_hs_twakup_l + offset, &val);  
+       
+       if(Ttxclkesc > 50000) {
+               val = 2*Ttxclkesc;
+               MIPI_DBG("Ttxclkesc:%d\n", Ttxclkesc);
+       }
+       val = val / Ttxbyte_clk;
+       Tlpx = val*Ttxbyte_clk;
+       MIPI_DBG("reg_hs_tlpx: %d, %d\n", val, Tlpx);
+       val -= 2;
+       dsi_write_reg(reg_hs_tlpx + offset, &val);
+       
+       Tlpx = 2*Ttxclkesc;
+       val = 4*Tlpx / Ttxclkesc;
+       MIPI_DBG("reg_hs_tta_go: %d, %d\n", val, val*Ttxclkesc);
+       dsi_write_reg(reg_hs_tta_go + offset, &val);    
+
+       val = 3 * Tlpx / 2 / Ttxclkesc;
+       MIPI_DBG("reg_hs_tta_sure: %d, %d\n", val, val*Ttxclkesc);
+       dsi_write_reg(reg_hs_tta_sure + offset, &val);  
+
+       val = 5 * Tlpx / Ttxclkesc;
+       MIPI_DBG("reg_hs_tta_wait: %d, %d\n", val, val*Ttxclkesc);
+       dsi_write_reg(reg_hs_tta_wait + offset, &val);  
+#if 1
+       val = 0x5b;
+       dsi_write_reg(offset + 0x18, &val);
+       val = 0x38;
+       dsi_write_reg(offset + 0x20, &val);     
+#endif
+       return 0;
+}
+
+
+static int rk_mipi_dsi_phy_init(void *array, int n) {
+
+       u32 val = 0;
+       struct rk29fb_screen *screen = array;
+       //DPHY init
+       dsi_set_bits((gDsi.phy.fbdiv >> 8) & 0x01, reg_fbdiv_8);
+       dsi_set_bits(gDsi.phy.prediv, reg_prediv);
+       dsi_set_bits(gDsi.phy.fbdiv & 0xff, reg_fbdiv);
+       
+       val = 0xe4;       
+       dsi_write_reg(DPHY_REGISTER1, &val);
+       
+       switch(gDsi.host.lane) {
+               case 4:
+                       dsi_set_bits(1, lane_en_3);
+               case 3:
+                       dsi_set_bits(1, lane_en_2);
+               case 2:
+                       dsi_set_bits(1, lane_en_1);
+               case 1:
+                       dsi_set_bits(1, lane_en_0);
+                       dsi_set_bits(1, lane_en_ck);
+                       break;
+               default:
+                       break;  
+       }
+
+       val = 0xe0;
+       dsi_write_reg(DPHY_REGISTER1, &val);
+       udelay(10);
+
+       val = 0x1e;
+       dsi_write_reg(DPHY_REGISTER20, &val);
+       val = 0x1f;
+       dsi_write_reg(DPHY_REGISTER20, &val);
+#if 0  
+       //new temp
+       val = 0xff;
+       dsi_write_reg(0x0c24, &val);
+       
+       val = 0x77;
+       dsi_write_reg(0x0c18, &val);
+       val = 0x77;
+       dsi_write_reg(0x0c1c, &val);
+       
+       val = 0x4f;
+       dsi_write_reg(0x0c20, &val);
+       
+       val = 0xc0;
+       dsi_write_reg(0x0c28, &val);
+#endif 
+
+#if 0
+       val = 0xff;
+       dsi_write_reg(RK_ADDR(0x09), &val);
+       val = 0x4e;
+       dsi_write_reg(RK_ADDR(0x08), &val);
+       val = 0x84;
+       dsi_write_reg(RK_ADDR(0x0a), &val);
+#endif
+       
+       val = 0x30;
+       dsi_write_reg(RK_ADDR(0x05), &val);
+                       
+       //if(800 <= gDsi.phy.ddr_clk && gDsi.phy.ddr_clk <= 1000)
+       switch(gDsi.host.lane) {
+               case 4:
+                       rk_mipi_dsi_phy_set_gotp(DPHY_LANE3_OFFSET, n);
+               case 3:
+                       rk_mipi_dsi_phy_set_gotp(DPHY_LANE2_OFFSET, n);
+               case 2:
+                       rk_mipi_dsi_phy_set_gotp(DPHY_LANE1_OFFSET, n);
+               case 1:
+                       rk_mipi_dsi_phy_set_gotp(DPHY_LANE0_OFFSET, n);
+                       rk_mipi_dsi_phy_set_gotp(DPHY_CLOCK_OFFSET, n);
+                       break;
+               default:
+                       break;  
+       }       
+       return 0;
+}
+
+
+static int rk_mipi_dsi_host_init(void *array, int n) {
+
+       u32 val = 0, bytes_px = 0;
+       struct rk29fb_screen *screen = array;
+       u32 decimals = gDsi.phy.Ttxbyte_clk, temp = 0, i = 0;
+       u32 m = 1, lane = gDsi.host.lane, Tpclk = gDsi.phy.Tpclk, Ttxbyte_clk = gDsi.phy.Ttxbyte_clk;
+       
+       val = 0x04000000;
+       dsi_write_reg(CRU_CRU_CLKSEL1_CON, &val);
+       
+       dsi_set_bits(gDsi.host.lane - 1, n_lanes);
+       dsi_set_bits(gDsi.vid, dpi_vid);
+       
+       switch(screen->face) {
+               case OUT_P888:
+                       dsi_set_bits(7, dpi_color_coding);
+                       bytes_px = 3;
+                       break;
+               case OUT_D888_P666:
+               case OUT_P666:
+                       dsi_set_bits(3, dpi_color_coding);
+                       dsi_set_bits(1, en18_loosely);
+                       bytes_px = 3;
+                       break;
+               case OUT_P565:
+                       dsi_set_bits(0, dpi_color_coding);
+                       bytes_px = 2;
+               default:
+                       break;
+       }
+       
+       dsi_set_bits(!screen->pin_hsync, hsync_active_low);
+       dsi_set_bits(!screen->pin_vsync, vsync_active_low);
+       dsi_set_bits(screen->pin_den, dataen_active_low);
+       dsi_set_bits(1, colorm_active_low);
+       dsi_set_bits(1, shutd_active_low);
+       
+       dsi_set_bits(gDsi.host.video_mode, vid_mode_type);        //burst mode  //need to expand
+       switch(gDsi.host.video_mode) {
+               case VM_BM:
+                       dsi_set_bits(screen->x_res, vid_pkt_size);
+                       break;
+               case VM_NBMWSE:
+               case VM_NBMWSP:
+                       for(i = 8; i < 32; i++){
+                               temp = i * lane * Tpclk % Ttxbyte_clk;
+                               if(decimals > temp) {
+                                       decimals = temp;
+                                       m = i;
+                               }
+                               if(decimals == 0)
+                                       break;
+                       }
+                       dsi_set_bits(1, en_multi_pkt);
+                       dsi_set_bits(screen->x_res / m + 1, num_chunks);
+                       dsi_set_bits(m, vid_pkt_size);
+                       temp = m * lane * Tpclk / Ttxbyte_clk - m * bytes_px;
+                       MIPI_DBG("%s:%d, %d\n", __func__, m, temp);
+                       if(temp >= 12) {
+                               dsi_set_bits(1, en_null_pkt);
+                               dsi_set_bits(temp - 12, null_pkt_size);
+                       }
+                       break;
+               default:
+                       break;
+       }       
+       
+       val = 0x0;
+       dsi_write_reg(CMD_MODE_CFG, &val);
+       
+       dsi_set_bits(gDsi.phy.Tpclk * (screen->x_res + screen->left_margin + screen->hsync_len + screen->right_margin) \
+                                                                       / gDsi.phy.Ttxbyte_clk, hline_time);
+       dsi_set_bits(gDsi.phy.Tpclk * screen->left_margin / gDsi.phy.Ttxbyte_clk, hbp_time);
+       dsi_set_bits(gDsi.phy.Tpclk * screen->hsync_len / gDsi.phy.Ttxbyte_clk, hsa_time);
+       
+       dsi_set_bits(screen->y_res, v_active_lines);
+       dsi_set_bits(screen->lower_margin, vfp_lines);
+       dsi_set_bits(screen->upper_margin, vbp_lines);
+       dsi_set_bits(screen->vsync_len, vsa_lines);
+       
+       gDsi.phy.txclkesc = 10 * MHz;
+       val = gDsi.phy.txbyte_clk / gDsi.phy.txclkesc + 1;
+       gDsi.phy.txclkesc = gDsi.phy.txbyte_clk / val;
+       dsi_set_bits(val, TX_ESC_CLK_DIVISION);
+       
+       
+       dsi_set_bits(10, TO_CLK_DIVISION);
+       dsi_set_bits(1000, lprx_to_cnt);
+       dsi_set_bits(1000, hstx_to_cnt);        
+       dsi_set_bits(100, phy_stop_wait_time);
+
+       dsi_set_bits(4, outvact_lpcmd_time);   //byte
+       dsi_set_bits(4, invact_lpcmd_time);
+               
+       dsi_set_bits(20, phy_hs2lp_time);
+       dsi_set_bits(16, phy_lp2hs_time);       
+       
+       dsi_set_bits(10, max_rd_time);
+
+       dsi_set_bits(1, dpicolom);
+       dsi_set_bits(1, dpishutdn);
+
+       //interrupt            //need 
+       val = 0x1fffff;
+       dsi_write_reg(ERROR_MSK0, &val);
+       val = 0x1ffff;
+       dsi_write_reg(ERROR_MSK1, &val);
+
+       dsi_set_bits(1, en_lp_hfp);
+       //dsi_set_bits(1, en_lp_hbp);
+       dsi_set_bits(1, en_lp_vact);
+       dsi_set_bits(1, en_lp_vfp);
+       dsi_set_bits(1, en_lp_vbp);
+       dsi_set_bits(1, en_lp_vsa);
+       
+       //dsi_set_bits(1, frame_BTA_ack);
+       dsi_set_bits(1, shutdownz);
+       //dsi_set_bits(1, phy_enableclk);
+
+       val = 10;
+       while(!dsi_get_bits(phylock) && val--) {
+               udelay(10);
+       };
+       if(val == 0)
+               printk("%s:phylock fail\n", __func__);          
+       val = 10;
+       while(!dsi_get_bits(phystopstateclklane) && val--) {
+               udelay(10);
+       };
+       
+       dsi_set_bits(4, phy_tx_triggers);
+       //dsi_set_bits(1, phy_txexitulpslan);
+       //dsi_set_bits(1, phy_txexitulpsclk);
+       dsi_set_bits(1, phy_txrequestclkhs);
+       dsi_set_bits(0, en_video_mode);
+
+       return 0;
+}
+
+
+
+/*
+       mipi protocol layer definition
+*/
+static int rk_mipi_dsi_init(void *array, u32 n) {
+       u32 decimals = 1000, i = 0, pre = 0;
+       struct rk29fb_screen *screen = array;
+       struct rk_lcdc_device_driver *dev_drv;
+       
+       if(!g_screen && screen)
+               g_screen = screen;
+       
+       if(g_screen->type != SCREEN_MIPI) {
+               printk("only mipi dsi lcd is supported\n");
+               return -1;
+       }
+       
+       gDsi.phy.Tpclk = rk_fb_get_prmry_screen_pixclock();
+
+       if(dsi_rk616->mclk)
+               gDsi.phy.ref_clk = clk_get_rate(dsi_rk616->mclk);
+       else
+               gDsi.phy.ref_clk = 24 * MHz;
+               
+       gDsi.phy.sys_clk = gDsi.phy.ref_clk;
+       
+       if((screen->hs_tx_clk <= 80 * MHz) || (screen->hs_tx_clk >= 1000 * MHz))
+               gDsi.phy.ddr_clk = 1000 * MHz;    //default is 1HGz
+       else
+               gDsi.phy.ddr_clk = screen->hs_tx_clk;   
+       
+       if(n != 0) {
+               gDsi.phy.ddr_clk = n;
+       } 
+
+       decimals = gDsi.phy.ref_clk;
+       for(i = 1; i < 6; i++) {
+               pre = gDsi.phy.ref_clk / i;
+               if((decimals > (gDsi.phy.ddr_clk % pre)) && (gDsi.phy.ddr_clk / pre < 512)) {
+                       decimals = gDsi.phy.ddr_clk % pre;
+                       gDsi.phy.prediv = i;
+                       gDsi.phy.fbdiv = gDsi.phy.ddr_clk / pre;
+               }       
+               if(decimals == 0) 
+                       break;          
+       }
+
+       MIPI_DBG("prediv:%d, fbdiv:%d\n", gDsi.phy.prediv, gDsi.phy.fbdiv);
+       gDsi.phy.ddr_clk = gDsi.phy.ref_clk / gDsi.phy.prediv * gDsi.phy.fbdiv; 
+       gDsi.phy.txbyte_clk = gDsi.phy.ddr_clk / 8;
+       
+       gDsi.phy.txclkesc = 10 * MHz;        // < 10MHz
+       gDsi.phy.txclkesc = gDsi.phy.txbyte_clk / (gDsi.phy.txbyte_clk / gDsi.phy.txclkesc + 1);
+       
+       gDsi.phy.pclk = div_u64(1000000000000llu, gDsi.phy.Tpclk);
+       gDsi.phy.Ttxclkesc = div_u64(1000000000000llu, gDsi.phy.txclkesc);
+       gDsi.phy.Tsys_clk = div_u64(1000000000000llu, gDsi.phy.sys_clk);
+       gDsi.phy.Tddr_clk = div_u64(1000000000000llu, gDsi.phy.ddr_clk);
+       gDsi.phy.Ttxbyte_clk = div_u64(1000000000000llu, gDsi.phy.txbyte_clk);
+       
+       gDsi.phy.UI = gDsi.phy.Tddr_clk;
+       gDsi.vid = 0;
+       
+       if(screen->dsi_lane > 0 && screen->dsi_lane <= 4)
+               gDsi.host.lane = screen->dsi_lane;
+       else
+               gDsi.host.lane = 4;
+               
+       gDsi.host.video_mode = VM_BM;
+       
+       MIPI_DBG("UI:%d\n", gDsi.phy.UI);       
+       MIPI_DBG("ref_clk:%d\n", gDsi.phy.ref_clk);
+       MIPI_DBG("pclk:%d, Tpclk:%d\n", gDsi.phy.pclk, gDsi.phy.Tpclk);
+       MIPI_DBG("sys_clk:%d, Tsys_clk:%d\n", gDsi.phy.sys_clk, gDsi.phy.Tsys_clk);
+       MIPI_DBG("ddr_clk:%d, Tddr_clk:%d\n", gDsi.phy.ddr_clk, gDsi.phy.Tddr_clk);
+       MIPI_DBG("txbyte_clk:%d, Ttxbyte_clk:%d\n", gDsi.phy.txbyte_clk, gDsi.phy.Ttxbyte_clk);
+       MIPI_DBG("txclkesc:%d, Ttxclkesc:%d\n", gDsi.phy.txclkesc, gDsi.phy.Ttxclkesc);
+       
+       dsi_set_bits(0, en_video_mode);
+       dsi_set_bits(0, shutdownz);
+       
+       rk_mipi_dsi_phy_init(screen, n);
+       rk_mipi_dsi_host_init(screen, n);
+       
+       
+       if(!screen->init) { 
+               rk_mipi_dsi_send_dcs_packet(dcs_exit_sleep_mode, sizeof(dcs_exit_sleep_mode));
+               msleep(1);
+               rk_mipi_dsi_send_dcs_packet(dcs_set_diaplay_on, sizeof(dcs_set_diaplay_on));
+               msleep(10);
+       }
+       
+       dsi_set_bits(1, en_video_mode);
+       
+       msleep(10);
+       rk_mipi_dsi_send_dcs_packet(dcs_enter_sleep_mode, sizeof(dcs_enter_sleep_mode));
+       rk_mipi_dsi_send_dcs_packet(dcs_set_diaplay_off, sizeof(dcs_set_diaplay_off));
+       
+       rk616_display_router_cfg(dsi_rk616, screen, 0);
+}
+
+
+static int rk_mipi_dsi_send_dcs_packet(unsigned char regs[], u32 n) {
+
+       u32 data = 0, i = 0, j = 0;
+       if(n <= 0)
+               return -1;
+               
+       if(dsi_get_bits(gen_cmd_full) == 1) {
+               printk("gen_cmd_full\n");
+               return -1;
+       }
+       dsi_set_bits(0, lpcmden);        //send in high speed mode
+       
+       if(n <= 2) {
+               data = (gDsi.vid << 6) | ((n-1) << 4) | 0x05;
+               data |= regs[0] << 8;
+               if(n == 2)
+                       data |= regs[1] << 16;
+       } else {
+               data = 0;
+               for(i = 0; i < n; i++) {
+                       j = i % 4;
+                       data |= regs[i] << (j * 8);
+                       if(j == 3 || ((i + 1) == n)) {
+                               if(dsi_get_bits(gen_pld_w_full) == 1) {
+                                       printk("gen_pld_w_full :%d\n", i);
+                                       break;
+                               }
+                               dsi_write_reg(GEN_PLD_DATA, &data);
+                               MIPI_DBG("write GEN_PLD_DATA:%d, %08x\n", i, data);
+                               data = 0;
+                       }
+               }
+               data = (gDsi.vid << 6) | 0x39;          
+               data |= n << 8;
+       }
+       //MIPI_DBG("write GEN_HDR:%08x\n", data);
+       dsi_write_reg(GEN_HDR, &data);
+       i = 10;
+       
+       while(!dsi_get_bits(gen_cmd_empty) && i--) {
+               MIPI_DBG(".");
+               udelay(10);
+       }
+       //MIPI_DBG("send command");
+       //MIPI_DBG("\n");
+       return 0;
+}
+
+
+static int rk_mipi_dsi_send_packet(unsigned char type, unsigned char regs[], u32 n) {
+
+       return 0;
+}
+
+static int rk_mipi_dsi_read_dcs_packet(unsigned char *data, u32 n) {
+       //DCS READ 
+       unsigned int i = 0;
+       
+       return 0;
+}
+
+static int rk_mipi_dsi_power_up(void) {
+
+       return 0;
+}
+
+static int rk_mipi_dsi_power_down(void) {
+       
+       return 0;
+}
+
+static u32 rk_mipi_dsi_get_id(void) {
+       
+       u32 id = 0;
+       dsi_read_reg(VERSION, &id);
+       
+       return id;
+}
+
+static struct mipi_dsi_ops rk_mipi_dsi_ops = {
+       .id = DWC_DSI_VERSION,
+       .name = "rk_mipi_dsi",
+       .get_id = rk_mipi_dsi_get_id,
+       //.dsi_set_regs = NULL,
+       .dsi_send_dcs_packet = rk_mipi_dsi_send_dcs_packet,
+       .dsi_read_dcs_packet = rk_mipi_dsi_read_dcs_packet,
+       .power_up = rk_mipi_dsi_power_up,
+       .power_down = rk_mipi_dsi_power_down,
+       .dsi_init = rk_mipi_dsi_init,
+};
+
+
+#if MIPI_DSI_REGISTER_IO
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+#include <linux/slab.h>
+
+static struct proc_dir_entry *reg_proc_entry;
+
+int reg_proc_write(struct file *file, const char __user *buff, size_t count, loff_t *offp)
+{
+       int ret = -1, i = 0;
+       u32 read_val = 0;
+       char *buf = kmalloc(count, GFP_KERNEL);
+       char *data = buf;
+       char str[32];
+       char command = 0;
+       u64 regs_val = 0;
+       struct regulator *ldo;
+       ret = copy_from_user((void*)buf, buff, count);
+       
+       data = strstr(data, "-");
+       if(data == NULL)
+               goto reg_proc_write_exit;
+       command = *(++data);
+       
+       switch(command) {
+               case 'w':
+                       while(1) {
+               
+                               data = strstr(data, "0x");
+                               if(data == NULL)
+                                       goto reg_proc_write_exit;
+                               sscanf(data, "0x%llx", &regs_val);
+                               if((regs_val & 0xffff00000000) == 0)
+                                       goto reg_proc_write_exit;
+                               read_val = regs_val & 0xffffffff;
+                               dsi_write_reg(regs_val >> 32, &read_val);
+                               dsi_read_reg(regs_val >> 32, &read_val);
+                               regs_val &= 0xffffffff;
+                               if(read_val != regs_val)
+                                       printk("%s fail:0x%08x\n", __func__, read_val); 
+                               
+                               data += 3;
+                               msleep(1);      
+                       }
+               
+                       break;
+               case 'r':
+                               data = strstr(data, "0x");
+                               if(data == NULL)
+                                       goto reg_proc_write_exit;
+                               sscanf(data, "0x%x", &regs_val);
+                               dsi_read_reg((u16)regs_val, &read_val);
+                               printk("*%04x : %08x\n", (u16)regs_val, read_val);
+                               msleep(1);      
+                       break;  
+       
+               case 's':
+                               while(*(++data) == ' ');
+                               sscanf(data, "%d", &read_val);
+                               rk_mipi_dsi_init(g_screen, read_val * MHz);
+                       break;
+               case 'p':
+                               while(*(++data) == ' ');
+                               sscanf(data, "%d", &read_val);
+                               while(*(++data) == ' ');
+                               sscanf(data, "%s", str);
+                               printk(" get %s\n", str);
+                               ldo = regulator_get(NULL, str);
+                               if(!ldo)
+                                       break;
+                               if(read_val == 0) {
+                                       while(regulator_is_enabled(ldo)>0)
+                                               regulator_disable(ldo); 
+                               } else {
+                                       regulator_enable(ldo);
+                               }       
+                               regulator_put(ldo);
+                               
+                       break;
+       
+               default:
+                       break;
+       }
+
+reg_proc_write_exit:
+       kfree(buf);
+       msleep(10);     
+       return count;
+}
+
+
+
+int reg_proc_read(struct file *file, char __user *buff, size_t count, loff_t *offp)
+{
+       int i = 0;
+       u32 val = 0;
+       u8 buf[4] = "hhb";
+       copy_to_user(buff, buf, 4);
+       count = 4;
+       for(i = VERSION; i <= LP_CMD_TIM; i += 4) {
+               dsi_read_reg(i, &val);
+               printk("%04x: %08x\n", i, val);
+               msleep(1);
+       }
+       
+       printk("\n");
+       for(i = DPHY_REGISTER0; i <= DPHY_REGISTER4; i += 4) {
+               dsi_read_reg(i, &val);
+               printk("%04x: %08x\n", i, val);
+               msleep(1);
+       }
+       printk("\n");
+       i = DPHY_REGISTER20;
+       dsi_read_reg(i, &val);
+       printk("%04x: %08x\n", i, val);
+       msleep(1);
+#if 1
+       printk("\n");
+       for(i = DPHY_CLOCK_OFFSET; i <= (DPHY_CLOCK_OFFSET + reg_hs_tta_wait); i += 4) {
+               dsi_read_reg(i, &val);
+               printk("%04x: %08x\n", i, val);
+               msleep(1);
+       }
+
+       
+       printk("\n");
+       for(i = DPHY_LANE0_OFFSET; i <= (DPHY_LANE0_OFFSET + reg_hs_tta_wait); i += 4) {
+               dsi_read_reg(i, &val);
+               printk("%04x: %08x\n", i, val);
+               msleep(1);
+       }
+
+               printk("\n");
+       for(i = DPHY_LANE1_OFFSET; i <= (DPHY_LANE1_OFFSET + reg_hs_tta_wait); i += 4) {
+               dsi_read_reg(i, &val);
+               printk("%04x: %08x\n", i, val);
+               msleep(1);
+       }
+
+       printk("\n");
+       for(i = DPHY_LANE2_OFFSET; i <= (DPHY_LANE2_OFFSET + reg_hs_tta_wait); i += 4) {
+               dsi_read_reg(i, &val);
+               printk("%04x: %08x\n", i, val);
+               msleep(1);
+       }
+       
+               printk("\n");
+       for(i = DPHY_LANE3_OFFSET; i <= (DPHY_LANE3_OFFSET + reg_hs_tta_wait); i += 4) {
+               dsi_read_reg(i, &val);
+               printk("%04x: %08x\n", i, val);
+               msleep(1);
+       }
+#endif
+       return -1;
+}
+
+int reg_proc_open(struct inode *inode, struct file *file)
+{
+       //printk("%s\n", __func__);
+       //msleep(10);
+       return 0;
+}
+
+int reg_proc_close(struct inode *inode, struct file *file)
+{
+       //printk("%s\n", __func__);
+       //msleep(10);
+       return 0;   
+}
+
+struct file_operations reg_proc_fops = {
+       .owner = THIS_MODULE,
+       .open = reg_proc_open,
+       .release = reg_proc_close,
+       .write = reg_proc_write,
+       .read = reg_proc_read,
+};
+
+static int reg_proc_init(char *name)
+{
+       int ret = 0;
+#if 1  
+       debugfs_create_file("mipi", S_IRUSR, dsi_rk616->debugfs_dir, dsi_rk616, &reg_proc_fops);
+#else
+       reg_proc_entry = create_proc_entry(name, 0666, NULL);
+       if(reg_proc_entry == NULL) {
+               printk("Couldn't create proc entry : %s!\n", name);
+               ret = -ENOMEM;
+               return ret ;
+       }
+       else {
+               printk("Create proc entry:%s success!\n", name);
+               reg_proc_entry->proc_fops = &reg_proc_fops;
+       }
+#endif 
+       return 0;
+}
+
+static int __init rk_mipi_dsi_reg(void)
+{
+       return reg_proc_init("mipi_dsi");
+}
+module_init(rk_mipi_dsi_reg);
+
+#endif
+
+
+
+#if    defined(CONFIG_HAS_EARLYSUSPEND)
+static void rk616_mipi_dsi_early_suspend(struct early_suspend *h)
+{
+       u32 val = 0X01;   
+       struct regulator *ldo;
+       
+       dsi_set_bits(0, en_video_mode);
+       
+       dsi_write_reg(DPHY_REGISTER0, &val);
+       
+       val = 0xe3;    
+       dsi_write_reg(DPHY_REGISTER1, &val);
+       
+       dsi_set_bits(0, shutdownz);
+
+       ldo = regulator_get(NULL, "ricoh_ldo3");
+       if(ldo) {
+               while(regulator_is_enabled(ldo)>0)
+                       regulator_disable(ldo); 
+               regulator_put(ldo);     
+       }
+       
+
+       MIPI_DBG("%s\n", __func__);
+}
+
+static void rk616_mipi_dsi_late_resume(struct early_suspend *h)
+{
+       struct regulator *ldo;
+       rk_mipi_dsi_phy_init(g_screen, 0);
+       
+       //dsi_set_bits(1, shutdownz);
+       
+       rk_mipi_dsi_host_init(g_screen, 0);
+       
+       rk_mipi_dsi_send_dcs_packet(dcs_exit_sleep_mode, sizeof(dcs_exit_sleep_mode));
+       msleep(1);
+       rk_mipi_dsi_send_dcs_packet(dcs_set_diaplay_on, sizeof(dcs_set_diaplay_on));
+       msleep(10);
+       
+       dsi_set_bits(1, en_video_mode);
+       rk616_display_router_cfg(dsi_rk616, g_screen, 0);
+       
+       
+       ldo = regulator_get(NULL, "ricoh_ldo3");
+       if(ldo) {
+               regulator_enable(ldo);  
+               regulator_put(ldo);
+       }
+       MIPI_DBG("%s\n", __func__);
+}
+
+#endif
+
+
+
+static int rk616_mipi_dsi_probe(struct platform_device *pdev)
+{
+       int ret = 0;
+       u32 val;
+       rk_screen *screen; 
+       struct mfd_rk616 *rk616 = dev_get_drvdata(pdev->dev.parent);
+       if(!rk616)
+       {
+               dev_err(&pdev->dev,"null mfd device rk616!\n");
+               return -ENODEV;
+       }
+       else
+               dsi_rk616 = rk616;
+       
+       register_dsi_ops(&rk_mipi_dsi_ops);
+       
+       ret = dsi_probe_current_chip();
+       if(ret) {
+               dev_err(&pdev->dev,"mipi dsi probe fail\n");
+               return -ENODEV;
+       }
+       
+       screen = rk_fb_get_prmry_screen();
+       if(!screen)
+       {
+               dev_err(&pdev->dev,"the fb prmry screen is null!\n");
+               return -ENODEV;
+       }
+       
+       rk_mipi_dsi_init(screen, 0);
+       
+#ifdef CONFIG_HAS_EARLYSUSPEND
+       gDsi.early_suspend.suspend = rk616_mipi_dsi_early_suspend;
+       gDsi.early_suspend.resume = rk616_mipi_dsi_late_resume;
+       gDsi.early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1;
+       register_early_suspend(&gDsi.early_suspend);
+#endif
+       
+       dev_info(&pdev->dev,"rk616 mipi_dsi probe success!\n");
+       
+       return 0;
+       
+}
+
+static int rk616_mipi_dsi_remove(struct platform_device *pdev)
+{
+       
+       return 0;
+}
+
+static void rk616_mipi_dsi_shutdown(struct platform_device *pdev)
+{
+       
+       return;
+}
+
+static struct platform_driver rk616_mipi_dsi_driver = {
+       .driver         = {
+               .name   = "rk616-mipi",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = rk616_mipi_dsi_probe,
+       .remove         = rk616_mipi_dsi_remove,
+       .shutdown       = rk616_mipi_dsi_shutdown,
+};
+
+static int __init rk616_mipi_dsi_init(void)
+{
+       return platform_driver_register(&rk616_mipi_dsi_driver);
+}
+fs_initcall(rk616_mipi_dsi_init);
+
+static void __exit rk616_mipi_dsi_exit(void)
+{
+       platform_driver_unregister(&rk616_mipi_dsi_driver);
+}
+module_exit(rk616_mipi_dsi_exit);
diff --git a/drivers/video/rockchip/transmitter/rk616_mipi_dsi.h b/drivers/video/rockchip/transmitter/rk616_mipi_dsi.h
new file mode 100644 (file)
index 0000000..8513a20
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+drivers/video/display/transmitter/rk616_mipi_dsi.h
+*/
+#ifndef RK616_MIPI_DSI_H
+#define RK616_MIPI_DSI_H
+
+#define DWC_DSI_VERSION        0x3131302A
+
+
+#define MIPI_DSI_PHY_OFFSET            0X0C00
+#define MIPI_DSI_HOST_OFFSET   0x1000
+
+#define RK_ADDR(A)    (MIPI_DSI_PHY_OFFSET + (A << 2))
+
+//MIPI DSI HOST REGISTER
+#define VERSION                (MIPI_DSI_HOST_OFFSET + 0x00)           // Version of the DSI host controller 0x3130312A
+#define PWR_UP                         (MIPI_DSI_HOST_OFFSET + 0x04)           //R/W Core power up 0x0
+#define CLKMGR_CFG             (MIPI_DSI_HOST_OFFSET + 0x08)           //R/W Number of active data lanes 
+#define DPI_CFG                (MIPI_DSI_HOST_OFFSET + 0x0C)           //R/W DPI interface configuration 
+//#define DBI_CFG              (MIPI_DSI_HOST_OFFSET + 0x10)           //R/W DBI interface configuration 0x0
+//#define DBI_CMDSIZE  (MIPI_DSI_HOST_OFFSET + 0x14)           //R/W DBI command size configuration 0x0
+#define PCKHDL_CFG             (MIPI_DSI_HOST_OFFSET + 0x18)           //R/W Packet handler configuration 0x0
+#define VID_MODE_CFG   (MIPI_DSI_HOST_OFFSET + 0x1C)           //R/W Video mode Configuration 0x0
+#define VID_PKT_CFG    (MIPI_DSI_HOST_OFFSET + 0x20)           //R/W Video packet configuration 0x0
+#define CMD_MODE_CFG   (MIPI_DSI_HOST_OFFSET + 0x24)           //R/W Command mode configuration 0x0
+#define TMR_LINE_CFG   (MIPI_DSI_HOST_OFFSET + 0x28)           //R/W Line timer configuration 0x0
+#define VTIMING_CFG    (MIPI_DSI_HOST_OFFSET + 0x2C)           //R/W Vertical timing configuration 0x0
+#define PHY_TMR_CFG    (MIPI_DSI_HOST_OFFSET + 0x30)           //R/W D-PHY timing configuration 0x0
+#define GEN_HDR                (MIPI_DSI_HOST_OFFSET + 0x34)           //R/W Generic packet header configuration 0x0
+#define GEN_PLD_DATA   (MIPI_DSI_HOST_OFFSET + 0x38)           //R/W Generic payload data in/out 0x0
+#define CMD_PKT_STATUS         (MIPI_DSI_HOST_OFFSET + 0x3C)           //R Command packet status 0x1515
+#define TO_CNT_CFG             (MIPI_DSI_HOST_OFFSET + 0x40)           //R/W Timeout timers configuration 
+#define ERROR_ST0              (MIPI_DSI_HOST_OFFSET + 0x44)           //R Interrupt status register 0 
+#define ERROR_ST1              (MIPI_DSI_HOST_OFFSET + 0x48)           //R Interrupt status register 1 0x0
+#define ERROR_MSK0             (MIPI_DSI_HOST_OFFSET + 0x4C)           //R/W Masks the interrupt generation triggered 0x0
+#define ERROR_MSK1             (MIPI_DSI_HOST_OFFSET + 0x50)           //R/W Masks the interrupt generation triggered 0x0 
+#define PHY_RSTZ               (MIPI_DSI_HOST_OFFSET + 0x54)           //R/W D-PHY reset control 0x0
+#define PHY_IF_CFG             (MIPI_DSI_HOST_OFFSET + 0x58)           //R/W D-PHY interface configuration 0x0
+#define PHY_IF_CTRL    (MIPI_DSI_HOST_OFFSET + 0x5C)           //R/W D-PHY PPI interface control 0x0
+#define PHY_STATUS             (MIPI_DSI_HOST_OFFSET + 0x60)           //R D-PHY PPI status interface 0x0
+#define PHY_TST_CTRL0  (MIPI_DSI_HOST_OFFSET + 0x64)           //R/W D-PHY test interface control 0 0x1
+#define PHY_TST_CTRL1  (MIPI_DSI_HOST_OFFSET + 0x68)           //R/W D-PHY test interface control 1 0x0
+//#define EDPI_CFG             (MIPI_DSI_HOST_OFFSET + 0x6C)           //R/W eDPI interface configuration 0x0
+#define LP_CMD_TIM             (MIPI_DSI_HOST_OFFSET + 0x70)           //R/W Low-Power command timing 0x0 configuration 
+
+
+//function bits definition    register addr | bits | offest
+#define REG_ADDR(a)                    (a << 16)
+#define REG_BITS(a)                    (a << 8)
+#define BITS_OFFSET(a)         (a)
+
+#define shutdownz                                      (PWR_UP << 16 | 1 << 8 | 0 )
+#define en18_loosely                           ((DPI_CFG << 16) | (1 << 8) | (10))
+#define colorm_active_low                      ((DPI_CFG << 16) | (1 << 8) | (9))
+#define shutd_active_low                       ((DPI_CFG << 16) | (1 << 8) | (8))
+#define hsync_active_low                       ((DPI_CFG << 16) | (1 << 8) | (7))
+#define vsync_active_low                       ((DPI_CFG << 16) | (1 << 8) | (6))
+#define dataen_active_low                      ((DPI_CFG << 16) | (1 << 8) | (5))
+#define dpi_color_coding                       ((DPI_CFG << 16) | (3 << 8) | (2))
+#define dpi_vid                                                ((DPI_CFG << 16) | (1 << 8) | (0))
+
+#define hline_time                             (TMR_LINE_CFG << 16 | 14 << 8 | 18 )
+#define hbp_time                                       (TMR_LINE_CFG << 16 | 9 << 8 | 9 )
+#define hsa_time                                       (TMR_LINE_CFG << 16 | 9 << 8 | 0 )
+
+#define v_active_lines                                 (VTIMING_CFG << 16 | 11 << 8 | 16 )
+#define vfp_lines                                      (VTIMING_CFG << 16 | 6 << 8 | 10 )
+#define vbp_lines                                      (VTIMING_CFG << 16 | 6 << 8 | 4 )
+#define vsa_lines                                      (VTIMING_CFG << 16 | 4 << 8 | 0 )
+
+
+#define TO_CLK_DIVISION                        (REG_ADDR(CLKMGR_CFG) | REG_BITS(8) | BITS_OFFSET(8))
+#define TX_ESC_CLK_DIVISION            (REG_ADDR(CLKMGR_CFG) | REG_BITS(8) | BITS_OFFSET(0))
+
+#define gen_vid_rx                                     (REG_ADDR(PCKHDL_CFG) | REG_BITS(2) | BITS_OFFSET(5))
+#define en_CRC_rx                                      (REG_ADDR(PCKHDL_CFG) | REG_BITS(1) | BITS_OFFSET(4))
+#define en_ECC_rx                                      (REG_ADDR(PCKHDL_CFG) | REG_BITS(1) | BITS_OFFSET(3))
+#define en_BTA                                                 (REG_ADDR(PCKHDL_CFG) | REG_BITS(1) | BITS_OFFSET(2))
+#define en_EOTp_rx                                     (REG_ADDR(PCKHDL_CFG) | REG_BITS(1) | BITS_OFFSET(1))
+#define en_EOTp_tx                                     (REG_ADDR(PCKHDL_CFG) | REG_BITS(1) | BITS_OFFSET(0))
+
+#define lpcmden                                        (REG_ADDR(VID_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(12))
+#define frame_BTA_ack                          (REG_ADDR(VID_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(11))
+#define en_null_pkt                            (REG_ADDR(VID_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(10))
+#define en_multi_pkt                           (REG_ADDR(VID_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(9))
+#define en_lp_hfp                                      (REG_ADDR(VID_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(8))
+#define en_lp_hbp                                      (REG_ADDR(VID_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(7))
+#define en_lp_vact                                     (REG_ADDR(VID_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(6))
+#define en_lp_vfp                                      (REG_ADDR(VID_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(5))
+#define en_lp_vbp                                      (REG_ADDR(VID_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(4))
+#define en_lp_vsa                                      (REG_ADDR(VID_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(3))
+#define vid_mode_type                          (REG_ADDR(VID_MODE_CFG) | REG_BITS(2) | BITS_OFFSET(1))
+#define en_video_mode                          (REG_ADDR(VID_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(0))
+
+#define null_pkt_size                          (REG_ADDR(VID_PKT_CFG) | REG_BITS(10) | BITS_OFFSET(21))
+#define num_chunks                                     (REG_ADDR(VID_PKT_CFG) | REG_BITS(10) | BITS_OFFSET(11))
+#define vid_pkt_size                           (REG_ADDR(VID_PKT_CFG) | REG_BITS(11) | BITS_OFFSET(0))
+
+#define en_tear_fx                                     (REG_ADDR(CMD_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(14))
+#define en_ack_rqst                            (REG_ADDR(CMD_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(13))
+#define dcs_lw_tx                                      (REG_ADDR(CMD_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(12))
+#define gen_lw_tx                                      (REG_ADDR(CMD_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(11))
+#define max_rd_pkt_size                        (REG_ADDR(CMD_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(10))
+#define dcs_sr_0p_tx                           (REG_ADDR(CMD_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(9))
+#define dcs_sw_1p_tx                           (REG_ADDR(CMD_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(8))
+#define dcs_sw_0p_tx                           (REG_ADDR(CMD_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(7))
+#define gen_sr_2p_tx                           (REG_ADDR(CMD_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(6))
+#define gen_sr_1p_tx                           (REG_ADDR(CMD_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(5))
+#define gen_sr_0p_tx                           (REG_ADDR(CMD_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(4))
+#define gen_sw_2p_tx                           (REG_ADDR(CMD_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(3))
+#define gen_sw_1p_tx                           (REG_ADDR(CMD_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(2))
+#define gen_sw_0p_tx                           (REG_ADDR(CMD_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(1))
+#define en_cmd_mode                            (REG_ADDR(CMD_MODE_CFG) | REG_BITS(1) | BITS_OFFSET(0))
+
+#define phy_hs2lp_time                                 (REG_ADDR(PHY_TMR_CFG) | REG_BITS(8) | BITS_OFFSET(24))
+#define phy_lp2hs_time                                 (REG_ADDR(PHY_TMR_CFG) | REG_BITS(8) | BITS_OFFSET(16))
+#define max_rd_time                            (REG_ADDR(PHY_TMR_CFG) | REG_BITS(15) | BITS_OFFSET(0))
+
+#define lprx_to_cnt                            (REG_ADDR(TO_CNT_CFG) | REG_BITS(16) | BITS_OFFSET(16))
+#define hstx_to_cnt                            (REG_ADDR(TO_CNT_CFG) | REG_BITS(16) | BITS_OFFSET(0))
+
+#define phy_enableclk                          (REG_ADDR(PHY_RSTZ) | REG_BITS(1) | BITS_OFFSET(2))
+//#define phy_rstz                                     (REG_ADDR(PHY_RSTZ) | REG_BITS(1) | BITS_OFFSET(1))
+//#define phy_shutdownz                                (REG_ADDR(PHY_RSTZ) | REG_BITS(1) | BITS_OFFSET(0))
+
+#define phy_stop_wait_time                     (REG_ADDR(PHY_IF_CFG) | REG_BITS(8) | BITS_OFFSET(2))
+#define n_lanes                                        (REG_ADDR(PHY_IF_CFG) | REG_BITS(2) | BITS_OFFSET(0))
+
+
+#define phy_tx_triggers                        (REG_ADDR(PHY_IF_CTRL) | REG_BITS(4) | BITS_OFFSET(5))
+#define phy_txexitulpslan                      (REG_ADDR(PHY_IF_CTRL) | REG_BITS(1) | BITS_OFFSET(4))
+#define phy_txrequlpslan                       (REG_ADDR(PHY_IF_CTRL) | REG_BITS(1) | BITS_OFFSET(3))
+#define phy_txexitulpsclk                      (REG_ADDR(PHY_IF_CTRL) | REG_BITS(1) | BITS_OFFSET(2))
+#define phy_txrequlpsclk                       (REG_ADDR(PHY_IF_CTRL) | REG_BITS(1) | BITS_OFFSET(1))
+#define phy_txrequestclkhs                     (REG_ADDR(PHY_IF_CTRL) | REG_BITS(1) | BITS_OFFSET(0))
+
+
+#define phy_testclk                            (REG_ADDR(PHY_TST_CTRL0) | REG_BITS(1) | BITS_OFFSET(1))
+#define phy_testclr                            (REG_ADDR(PHY_TST_CTRL0) | REG_BITS(1) | BITS_OFFSET(0))
+
+#define phy_testen                             (REG_ADDR(PHY_TST_CTRL1) | REG_BITS(1) | BITS_OFFSET(16))
+#define phy_testdout                           (REG_ADDR(PHY_TST_CTRL1) | REG_BITS(8) | BITS_OFFSET(8))
+#define phy_testdin                            (REG_ADDR(PHY_TST_CTRL1) | REG_BITS(8) | BITS_OFFSET(0))
+
+#define outvact_lpcmd_time             (REG_ADDR(LP_CMD_TIM) | REG_BITS(8) | BITS_OFFSET(8))
+#define invact_lpcmd_time                      (REG_ADDR(LP_CMD_TIM) | REG_BITS(8) | BITS_OFFSET(0))
+
+#define gen_rd_cmd_busy                        (REG_ADDR(CMD_PKT_STATUS) | REG_BITS(1) | BITS_OFFSET(6))
+#define gen_pld_r_full                                 (REG_ADDR(CMD_PKT_STATUS) | REG_BITS(1) | BITS_OFFSET(5))
+#define gen_pld_r_empty                        (REG_ADDR(CMD_PKT_STATUS) | REG_BITS(1) | BITS_OFFSET(4))
+#define gen_pld_w_full                                 (REG_ADDR(CMD_PKT_STATUS) | REG_BITS(1) | BITS_OFFSET(3))     //800byte    write GEN_PLD_DATA
+#define gen_pld_w_empty                        (REG_ADDR(CMD_PKT_STATUS) | REG_BITS(1) | BITS_OFFSET(2))
+#define gen_cmd_full                           (REG_ADDR(CMD_PKT_STATUS) | REG_BITS(1) | BITS_OFFSET(1))     //20   write GEN_HDR
+#define gen_cmd_empty                          (REG_ADDR(CMD_PKT_STATUS) | REG_BITS(1) | BITS_OFFSET(0))
+
+#define phystopstateclklane            (REG_ADDR(PHY_STATUS) | REG_BITS(1) | BITS_OFFSET(2))
+#define phylock                                        (REG_ADDR(PHY_STATUS) | REG_BITS(1) | BITS_OFFSET(0))
+
+
+//MIPI DSI DPHY REGISTERS
+#define DPHY_REGISTER0         (MIPI_DSI_PHY_OFFSET + 0X0000)
+#define DPHY_REGISTER1         (MIPI_DSI_PHY_OFFSET + 0X0004)
+#define DPHY_REGISTER3         (MIPI_DSI_PHY_OFFSET + 0X000C)
+#define DPHY_REGISTER4         (MIPI_DSI_PHY_OFFSET + 0X0010)
+#define DPHY_REGISTER20                (MIPI_DSI_PHY_OFFSET + 0X0080)
+
+#define lane_en_ck                                     (REG_ADDR(DPHY_REGISTER0) | REG_BITS(1) | BITS_OFFSET(6))
+#define lane_en_3                                      (REG_ADDR(DPHY_REGISTER0) | REG_BITS(1) | BITS_OFFSET(5))
+#define lane_en_2                                      (REG_ADDR(DPHY_REGISTER0) | REG_BITS(1) | BITS_OFFSET(4))
+#define lane_en_1                                      (REG_ADDR(DPHY_REGISTER0) | REG_BITS(1) | BITS_OFFSET(3))
+#define lane_en_0                                      (REG_ADDR(DPHY_REGISTER0) | REG_BITS(1) | BITS_OFFSET(2))
+
+
+#define reg_da_syncrst                                 (REG_ADDR(DPHY_REGISTER1) | REG_BITS(1) | BITS_OFFSET(2))
+#define reg_da_ldopd                           (REG_ADDR(DPHY_REGISTER1) | REG_BITS(1) | BITS_OFFSET(1))
+#define reg_da_pllpd                           (REG_ADDR(DPHY_REGISTER1) | REG_BITS(1) | BITS_OFFSET(0))
+
+
+#define reg_fbdiv_8                            (REG_ADDR(DPHY_REGISTER3) | REG_BITS(1) | BITS_OFFSET(5))
+#define reg_prediv                                     (REG_ADDR(DPHY_REGISTER3) | REG_BITS(5) | BITS_OFFSET(0))
+#define reg_fbdiv                                      (REG_ADDR(DPHY_REGISTER4) | REG_BITS(8) | BITS_OFFSET(0))
+
+#define reg_dig_rstn                           (REG_ADDR(DPHY_REGISTER20) | REG_BITS(1) | BITS_OFFSET(0))
+
+
+#define DPHY_CLOCK_OFFSET              (MIPI_DSI_PHY_OFFSET + 0X0100)
+#define DPHY_LANE0_OFFSET              (MIPI_DSI_PHY_OFFSET + 0X0180)
+#define DPHY_LANE1_OFFSET              (MIPI_DSI_PHY_OFFSET + 0X0200)
+#define DPHY_LANE2_OFFSET              (MIPI_DSI_PHY_OFFSET + 0X0280)
+#define DPHY_LANE3_OFFSET              (MIPI_DSI_PHY_OFFSET + 0X0300)
+
+#define reg_ths_settle                 0x0000
+#define reg_hs_tlpx                            0x0014
+#define reg_hs_ths_prepare             0x0018
+#define reg_hs_the_zero                        0x001c
+#define reg_hs_ths_trail               0x0020
+#define reg_hs_ths_exit                        0x0024
+#define reg_hs_tclk_post               0x0028
+#define reserved                               0x002c
+#define reg_hs_twakup_h                        0x0030
+#define reg_hs_twakup_l                        0x0034
+#define reg_hs_tclk_pre                        0x0038
+#define reg_hs_tta_go                  0x0040
+#define reg_hs_tta_sure                        0x0044
+#define reg_hs_tta_wait                        0x0048
+
+
+//MISC REGISTERS
+#define CRU_CRU_CLKSEL1_CON            (0x005c)
+#define CRU_CFG_MISC_CON               (0x009c)
+
+#define cfg_mipiclk_gaten                      (REG_ADDR(CRU_CRU_CLKSEL1_CON) | REG_BITS(1) | BITS_OFFSET(10))
+
+#define mipi_int                                       (REG_ADDR(CRU_CFG_MISC_CON) | REG_BITS(1) | BITS_OFFSET(19))
+#define mipi_edpihalt                          (REG_ADDR(CRU_CFG_MISC_CON) | REG_BITS(1) | BITS_OFFSET(16))
+#define pin_forcetxstopmode_3          (REG_ADDR(CRU_CFG_MISC_CON) | REG_BITS(1) | BITS_OFFSET(11))
+#define pin_forcetxstopmode_2          (REG_ADDR(CRU_CFG_MISC_CON) | REG_BITS(1) | BITS_OFFSET(10))
+#define pin_forcetxstopmode_1          (REG_ADDR(CRU_CFG_MISC_CON) | REG_BITS(1) | BITS_OFFSET(9))
+#define pin_forcetxstopmode_0          (REG_ADDR(CRU_CFG_MISC_CON) | REG_BITS(1) | BITS_OFFSET(8))
+#define pin_forcerxmode_0                      (REG_ADDR(CRU_CFG_MISC_CON) | REG_BITS(1) | BITS_OFFSET(7))
+#define pin_turndisable_0                      (REG_ADDR(CRU_CFG_MISC_CON) | REG_BITS(1) | BITS_OFFSET(6))
+#define dpicolom                                       (REG_ADDR(CRU_CFG_MISC_CON) | REG_BITS(1) | BITS_OFFSET(2))
+#define dpishutdn                                      (REG_ADDR(CRU_CFG_MISC_CON) | REG_BITS(1) | BITS_OFFSET(1))
+
+
+
+//global operation timing parameter
+struct gotp_m {
+       //time uint is ns
+       u32 min;
+       u32 value;
+       u32 max;
+};
+
+//default time unit is ns 
+//Unit Interval, equal to the duration of any HS state on the Clock Lane
+struct gotp {
+       u32 CLK_MISS;                           //min:no    max:60
+       u32 CLK_POST;                           //min:60 ns + 52*UI    max:no
+       u32 CLK_PRE;                            //min:8*UI    max:no
+       u32 CLK_PREPARE;                        //min:38    max:95
+       u32 CLK_SETTLE;                         //min:95    max:300
+       u32 CLK_TERM_EN;                //min:Time for Dn to reach VTERM-EN    max:38
+       u32 CLK_TRAIL;                          //min:60    max:no
+       u32 CLK_ZERO;                           //min:300 - CLK_PREPARE    max:no
+       u32 D_TERM_EN;                          //min:Time for Dn to reach VTERM-EN    max:35 ns + 4*UI
+       u32 EOT;                                //min:no    max:105 ns + n*12*UI
+       u32 HS_EXIT;                            //min:100    max:no
+       u32 HS_PREPARE;                         //min:40 ns + 4*UI     max:85 ns + 6*UI 
+       u32 HS_ZERO;                            //min:145 ns + 10*UI - HS_PREPARE    max:no
+       u32 HS_SETTLE;                          //min:85 ns + 6*UI     max:145 ns + 10*UI
+       u32 HS_SKIP;                            //min:40    max:55 ns + 4*UI
+       u32 HS_TRAIL;                           //min: max( n*8*UI, 60 ns + n*4*UI )    max:no
+       u32 NIT;                                //min:100us    max:no
+       u32 LPX;                                //min:50    max:no
+       u32 TA_GET;                             //min:5*TLPX    
+       u32 TA_GO;                              //min:4*TLPX            
+       u32 TA_SURE;                            //min:TLPX    max:2*TLPX
+       u32 WAKEUP;                             //min:1ms    max:no
+};
+
+
+struct dsi_phy {
+       u32 UI;
+       u32 ref_clk;            //input_clk
+       u32 ddr_clk;            //data bit clk
+       u32 txbyte_clk;         //1/8 of ddr_clk
+       u32 sys_clk;            //
+       u32 pclk;                       //
+       u32 txclkesc;
+       
+       u32 Tddr_clk;           //ps
+       u32 Ttxbyte_clk;        //ps
+       u32 Tsys_clk;           //ps
+       u32 Tpclk;              //ps
+       u32 Ttxclkesc;          //ps
+       
+       u16 prediv;
+       u16 fbdiv;
+       u8 flag;
+       struct gotp gotp;
+
+};
+
+
+struct dsi_host {
+       u8 flag;
+       u8 lane;
+       u8 format;
+       u8 video_mode;
+       u32 clk;
+
+};
+
+struct dsi {
+
+       u8 lcdc_id;
+       u8 vid;
+       struct dsi_phy phy;
+       struct dsi_host host;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+       struct early_suspend early_suspend;
+#endif
+
+};
+
+
+
+//config
+#define MIPI_DSI_REGISTER_IO   0
+
+#ifndef MHz
+#define MHz   1000000
+#endif
+
+#endif /* end of RK616_MIPI_DSI_H */
index 74bb6b3876d26483ed9f4a86917fe3444a855a41..92e76c126ddf86d41d3ae8409e45a71023680443 100644 (file)
@@ -445,7 +445,7 @@ int ssd_set_registers(unsigned int reg_array[], int n) {
        return 0;
 }
 
-int ssd_mipi_dsi_send_dcs_packet(unsigned char regs[], int n) {
+int ssd_mipi_dsi_send_dcs_packet(unsigned char regs[], u32 n) {
        //unsigned int data = 0, i = 0;
        ssd_set_register(0x00B70343);   //
        ssd_set_register(0x00B80000);
@@ -458,17 +458,17 @@ int ssd_mipi_dsi_send_dcs_packet(unsigned char regs[], int n) {
 }
 
 
-int _ssd2828_send_packet(unsigned char type, unsigned char regs[], int n) {
+int _ssd2828_send_packet(unsigned char type, unsigned char regs[], u32 n) {
 
        
        return 0;
 }
 
-int ssd2828_send_packet(unsigned char type, unsigned char regs[], int n) {
+int ssd2828_send_packet(unsigned char type, unsigned char regs[], u32 n) {
        return _ssd2828_send_packet(type, regs, n);
 }
 
-int ssd_mipi_dsi_read_dcs_packet(unsigned char *data, int n) {
+int ssd_mipi_dsi_read_dcs_packet(unsigned char *data, u32 n) {
        //DCS READ 
        unsigned int i = 0;
        
index 5f573b3dce8e2274c3b93542dba259731cbd3f27..f001160aba2ce612cbb464e7a6abd2662b9f824f 100644 (file)
@@ -241,6 +241,7 @@ int tc358768_power_down(void) {
        tc->vddio.disable(&tc->vddio);
        tc->vdd_mipi.disable(&tc->vdd_mipi);
        tc->vddc.disable(&tc->vddc);
+       gpio_set_value(tc358768->reset.reset_pin, 0);
        
        return ret;
 }
@@ -459,7 +460,7 @@ void tc_print(u32 addr) {
 }
 
 #define tc358768_wr_regs_32bits(reg_array)  _tc358768_wr_regs_32bits(reg_array, ARRAY_SIZE(reg_array))
-int _tc358768_wr_regs_32bits(unsigned int reg_array[], int n) {
+int _tc358768_wr_regs_32bits(unsigned int reg_array[], u32 n) {
 
        int i = 0;
        dsi_debug("%s:%d\n", __func__, n);
@@ -477,7 +478,7 @@ int _tc358768_wr_regs_32bits(unsigned int reg_array[], int n) {
        return 0;
 }
 
-int tc358768_command_tx_less8bytes(unsigned char type, unsigned char *regs, int n) {
+int tc358768_command_tx_less8bytes(unsigned char type, unsigned char *regs, u32 n) {
        int i = 0;
        unsigned int command[] = {
                        0x06020000,
@@ -520,7 +521,7 @@ int tc358768_command_tx_less8bytes(unsigned char type, unsigned char *regs, int
        return 0;
 }
 
-int tc358768_command_tx_more8bytes_hs(unsigned char type, unsigned char regs[], int n) {
+int tc358768_command_tx_more8bytes_hs(unsigned char type, unsigned char regs[], u32 n) {
 
        int i = 0;
        unsigned int dbg_data = 0x00E80000, temp = 0;
@@ -560,7 +561,7 @@ int tc358768_command_tx_more8bytes_hs(unsigned char type, unsigned char regs[],
 }
 
 //low power mode only for tc358768a
-int tc358768_command_tx_more8bytes_lp(unsigned char type, unsigned char regs[], int n) {
+int tc358768_command_tx_more8bytes_lp(unsigned char type, unsigned char regs[], u32 n) {
 
        int i = 0;
        unsigned int dbg_data = 0x00E80000, temp = 0;
@@ -595,7 +596,7 @@ int tc358768_command_tx_more8bytes_lp(unsigned char type, unsigned char regs[],
        return 0;
 }
 
-int _tc358768_send_packet(unsigned char type, unsigned char regs[], int n) {
+int _tc358768_send_packet(unsigned char type, unsigned char regs[], u32 n) {
 
        if(n <= 8) {
                tc358768_command_tx_less8bytes(type, regs, n);
@@ -606,7 +607,7 @@ int _tc358768_send_packet(unsigned char type, unsigned char regs[], int n) {
        return 0;
 }
 
-int tc358768_send_packet(unsigned char type, unsigned char regs[], int n) {
+int tc358768_send_packet(unsigned char type, unsigned char regs[], u32 n) {
        return _tc358768_send_packet(type, regs, n);
 }
 
@@ -616,7 +617,7 @@ The DCS is separated into two functional areas: the User Command Set and the Man
 Set. Each command is an eight-bit code with 00h to AFh assigned to the User Command Set and all other
 codes assigned to the Manufacturer Command Set.
 */
-int _mipi_dsi_send_dcs_packet(unsigned char regs[], int n) {
+int _mipi_dsi_send_dcs_packet(unsigned char regs[], u32 n) {
 
        unsigned char type = 0;
        if(n == 1) {
@@ -630,7 +631,7 @@ int _mipi_dsi_send_dcs_packet(unsigned char regs[], int n) {
        return 0;
 }
 
-int mipi_dsi_send_dcs_packet(unsigned char regs[], int n) {
+int mipi_dsi_send_dcs_packet(unsigned char regs[], u32 n) {
        return _mipi_dsi_send_dcs_packet(regs, n);
 }
 
@@ -688,7 +689,7 @@ int _tc358768_rd_lcd_regs(unsigned char type, char comd, int size, unsigned char
        return 0;
 }
 
-int mipi_dsi_read_dcs_packet(unsigned char *data, int n) {
+int mipi_dsi_read_dcs_packet(unsigned char *data, u32 n) {
        //DCS READ 
        _tc358768_rd_lcd_regs(0x06, *data, n, data);
        return 0;
index 6f3f0469c32235ee49530d320c2c3ef4683894a0..7fbc5bccf65348f65fe3b5584e381cae66f4b670 100644 (file)
@@ -177,6 +177,13 @@ typedef struct rk29fb_screen {
        u8 swap_rb;
        u8 swap_delta;
        u8 swap_dumy;
+       
+#if defined(CONFIG_MIPI_DSI)
+       /* MIPI DSI */
+       u8 dsi_lane;
+       u8 dsi_video_mode;
+       u32 hs_tx_clk;
+#endif
 
        int xpos;  //horizontal display start position on the sceen ,then can be changed by application
        int ypos;