From: hhb Date: Fri, 21 Jun 2013 03:34:14 +0000 (+0800) Subject: mipi dsi: add new interfaces of dsi X-Git-Tag: firefly_0821_release~6965^2~41 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e2283d1ce0f6940f44895a8e5bc7927f6fe8caa1;p=firefly-linux-kernel-4.4.55.git mipi dsi: add new interfaces of dsi --- diff --git a/drivers/video/rockchip/transmitter/mipi_dsi.c b/drivers/video/rockchip/transmitter/mipi_dsi.c index 10fcc2231ed4..0029a96086d9 100644 --- a/drivers/video/rockchip/transmitter/mipi_dsi.c +++ b/drivers/video/rockchip/transmitter/mipi_dsi.c @@ -129,6 +129,49 @@ int dsi_init(void *array, u32 n) { } EXPORT_SYMBOL(dsi_init); +int dsi_enable_video_mode(u32 enable) { + if(!cur_dsi_ops) + return -1; + if(cur_dsi_ops->dsi_enable_video_mode) + cur_dsi_ops->dsi_enable_video_mode(enable); + return 0; + +} +EXPORT_SYMBOL(dsi_enable_video_mode); + +int dsi_enable_command_mode(u32 enable) { + + if(!cur_dsi_ops) + return -1; + if(cur_dsi_ops->dsi_enable_command_mode) + cur_dsi_ops->dsi_enable_command_mode(enable); + return 0; + +} +EXPORT_SYMBOL(dsi_enable_command_mode); + +int dsi_enable_hs_clk(u32 enable) { + + if(!cur_dsi_ops) + return -1; + if(cur_dsi_ops->dsi_enable_hs_clk) + cur_dsi_ops->dsi_enable_hs_clk(enable); + return 0; + +} +EXPORT_SYMBOL(dsi_enable_hs_clk); + +int dsi_is_active(void) { + + if(!cur_dsi_ops) + return -1; + if(cur_dsi_ops->dsi_is_active) + return cur_dsi_ops->dsi_is_active(); + else + return -1; +} +EXPORT_SYMBOL(dsi_is_active); + int dsi_send_dcs_packet(unsigned char *packet, u32 n) { diff --git a/drivers/video/rockchip/transmitter/mipi_dsi.h b/drivers/video/rockchip/transmitter/mipi_dsi.h index 6a1f5596a203..6a52ab1888b1 100644 --- a/drivers/video/rockchip/transmitter/mipi_dsi.h +++ b/drivers/video/rockchip/transmitter/mipi_dsi.h @@ -31,6 +31,49 @@ #define VPF_18BPPL 0X02 //loosely packed #define VPF_24BPP 0X03 +//Display Command Set +#define dcs_enter_idle_mode 0x39 +#define dcs_enter_invert_mode 0x21 +#define dcs_enter_normal_mode 0x13 +#define dcs_enter_partial_mode 0x12 +#define dcs_enter_sleep_mode 0x10 +#define dcs_exit_idle_mode 0x38 +#define dcs_exit_invert_mode 0x20 +#define dcs_exit_sleep_mode 0x11 +#define dcs_get_address_mode 0x0b +#define dcs_get_blue_channel 0x08 +#define dcs_get_diagnostic_result 0x0f +#define dcs_get_display_mode 0x0d +#define dcs_get_green_channel 0x07 +#define dcs_get_pixel_format 0x0c +#define dcs_get_power_mode 0x0a +#define dcs_get_red_channel 0x06 +#define dcs_get_scanline 0x45 +#define dcs_get_signal_mode 0x0e +#define dcs_nop 0x00 +#define dcs_read_DDB_continue 0xa8 +#define dcs_read_DDB_start 0xa1 +#define dcs_read_memory_continue 0x3e +#define dcs_read_memory_start 0x2e +#define dcs_set_address_mode 0x36 +#define dcs_set_column_address 0x2a +#define dcs_set_display_off 0x28 +#define dcs_set_display_on 0x29 +#define dcs_set_gamma_curve 0x26 +#define dcs_set_page_address 0x2b +#define dcs_set_partial_area 0x30 +#define dcs_set_pixel_format 0x3a +#define dcs_set_scroll_area 0x33 +#define dcs_set_scroll_start 0x37 +#define dcs_set_tear_off 0x34 +#define dcs_set_tear_on 0x35 +#define dcs_set_tear_scanline 0x44 +#define dcs_soft_reset 0x01 +#define dcs_write_LUT 0x2d +#define dcs_write_memory_continue 0x3c +#define dcs_write_memory_start 0x2c + + //iomux #define OLD_RK_IOMUX 0 @@ -115,9 +158,13 @@ struct mipi_dsi_ops { int (*get_id)(void); int (*dsi_init)(void *, u32 n); int (*dsi_set_regs)(void *, u32 n); + int (*dsi_enable_video_mode)(u32 enable); + int (*dsi_enable_command_mode)(u32 enable); + int (*dsi_enable_hs_clk)(u32 enable); 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 (*dsi_is_active)(void); int (*power_up)(void); int (*power_down)(void); }; @@ -129,8 +176,10 @@ int dsi_power_up(void); int dsi_power_off(void); int dsi_probe_current_chip(void); int dsi_init(void *array, u32 n); - +int dsi_is_active(void); int dsi_enable_video_mode(u32 enable); +int dsi_enable_command_mode(u32 enable); +int dsi_enable_hs_clk(u32 enable); int dsi_set_virtual_channel(u32 channel); int dsi_set_regs(void *array, u32 n); diff --git a/drivers/video/rockchip/transmitter/rk616_mipi_dsi.c b/drivers/video/rockchip/transmitter/rk616_mipi_dsi.c index e8123746e09c..cd79feb7f21c 100644 --- a/drivers/video/rockchip/transmitter/rk616_mipi_dsi.c +++ b/drivers/video/rockchip/transmitter/rk616_mipi_dsi.c @@ -34,11 +34,9 @@ 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_enable_hs_clk(u32 enable); +static int rk_mipi_dsi_enable_video_mode(u32 enable); static int rk_mipi_dsi_send_dcs_packet(unsigned char regs[], u32 n); static int dsi_read_reg(u16 reg, u32 *pval) @@ -52,8 +50,8 @@ 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) -{ +static int dsi_get_bits(u32 reg) { + u32 val = 0; u32 bits = (reg >> 8) & 0xff; u16 reg_addr = (reg >> 16) & 0xffff; @@ -65,8 +63,8 @@ static int dsi_get_bits(u32 reg) return val; } -static int dsi_set_bits(u32 data, u32 reg) -{ +static int dsi_set_bits(u32 data, u32 reg) { + u32 val = 0; u32 bits = (reg >> 8) & 0xff; u16 reg_addr = (reg >> 16) & 0xffff; @@ -304,15 +302,9 @@ static int rk_mipi_dsi_phy_set_gotp(u32 offset, int n) { } -static int rk_mipi_dsi_phy_init(void *array, int n) { +static int rk_mipi_dsi_phy_power_up(void) { - u32 val = 0; - //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; + u32 val = 0xe4; dsi_write_reg(DPHY_REGISTER1, &val); switch(gDsi.host.lane) { @@ -338,6 +330,28 @@ static int rk_mipi_dsi_phy_init(void *array, int n) { dsi_write_reg(DPHY_REGISTER20, &val); val = 0x1f; dsi_write_reg(DPHY_REGISTER20, &val); + return 0; +} + +static int rk_mipi_dsi_phy_power_down(void) { + + u32 val = 0X01; + dsi_write_reg(DPHY_REGISTER0, &val); + + val = 0xe3; + dsi_write_reg(DPHY_REGISTER1, &val); + return 0; +} + + +static int rk_mipi_dsi_phy_init(void *array, int n) { + + u32 val = 0; + //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); + #if 0 //new temp val = 0xff; @@ -385,6 +399,34 @@ static int rk_mipi_dsi_phy_init(void *array, int n) { return 0; } +static int rk_mipi_dsi_host_power_up(void) { + int ret = 0; + u32 val = 0; + + dsi_set_bits(1, shutdownz); + + val = 10; + while(!dsi_get_bits(phylock) && val--) { + udelay(10); + }; + if(val == 0) { + ret = -1; + printk("%s:phylock fail\n", __func__); + } + val = 10; + while(!dsi_get_bits(phystopstateclklane) && val--) { + udelay(10); + }; + + return ret; +} + +static int rk_mipi_dsi_host_power_down(void) { + + dsi_set_bits(0, shutdownz); + return 0; +} + static int rk_mipi_dsi_host_init(void *array, int n) { @@ -483,7 +525,7 @@ static int rk_mipi_dsi_host_init(void *array, int n) { dsi_set_bits(20, phy_hs2lp_time); dsi_set_bits(16, phy_lp2hs_time); - dsi_set_bits(10, max_rd_time); + dsi_set_bits(50, max_rd_time); dsi_set_bits(1, dpicolom); dsi_set_bits(1, dpishutdn); @@ -502,26 +544,11 @@ static int rk_mipi_dsi_host_init(void *array, int n) { 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; } @@ -531,6 +558,7 @@ static int rk_mipi_dsi_host_init(void *array, int n) { mipi protocol layer definition */ static int rk_mipi_dsi_init(void *array, u32 n) { + u8 dcs[1] = {0}; u32 decimals = 1000, i = 0, pre = 0; struct rk29fb_screen *screen = array; @@ -608,21 +636,51 @@ static int rk_mipi_dsi_init(void *array, u32 n) { rk_mipi_dsi_phy_init(screen, n); rk_mipi_dsi_host_init(screen, n); + rk_mipi_dsi_phy_power_up(); + rk_mipi_dsi_host_power_up(); if(!screen->init) { - rk_mipi_dsi_send_dcs_packet(dcs_exit_sleep_mode, sizeof(dcs_exit_sleep_mode)); + rk_mipi_dsi_enable_hs_clk(1); + rk_mipi_dsi_enable_video_mode(1); + dcs[0] = dcs_exit_sleep_mode; + rk_mipi_dsi_send_dcs_packet(dcs, 1); msleep(1); - rk_mipi_dsi_send_dcs_packet(dcs_set_diaplay_on, sizeof(dcs_set_diaplay_on)); + dcs[0] = dcs_set_display_on; + rk_mipi_dsi_send_dcs_packet(dcs, 1); msleep(10); + } else { + screen->init(); } - dsi_set_bits(1, en_video_mode); rk616_display_router_cfg(dsi_rk616, screen, 0); - return 0; } +static int rk_mipi_dsi_enable_video_mode(u32 enable) { + + dsi_set_bits(enable, en_video_mode); + return 0; +} + + +static int rk_mipi_dsi_enable_command_mode(u32 enable) { + + dsi_set_bits(enable, en_cmd_mode); + return 0; +} + +static int rk_mipi_dsi_enable_hs_clk(u32 enable) { + + dsi_set_bits(enable, phy_txrequestclkhs); + return 0; +} + +static int rk_mipi_dsi_is_active(void) { + + return dsi_get_bits(shutdownz); +} + static int rk_mipi_dsi_send_dcs_packet(unsigned char regs[], u32 n) { u32 data = 0, i = 0, j = 0; @@ -656,7 +714,7 @@ static int rk_mipi_dsi_send_dcs_packet(unsigned char regs[], u32 n) { } } data = (gDsi.vid << 6) | 0x39; - data |= n << 8; + data |= (n & 0xffff) << 8; } //MIPI_DBG("write GEN_HDR:%08x\n", data); dsi_write_reg(GEN_HDR, &data); @@ -685,11 +743,13 @@ static int rk_mipi_dsi_read_dcs_packet(unsigned char *data, u32 n) { static int rk_mipi_dsi_power_up(void) { + dsi_set_bits(1, shutdownz); return 0; } static int rk_mipi_dsi_power_down(void) { + dsi_set_bits(0, shutdownz); return 0; } @@ -707,6 +767,10 @@ static struct mipi_dsi_ops rk_mipi_dsi_ops = { .get_id = rk_mipi_dsi_get_id, .dsi_send_dcs_packet = rk_mipi_dsi_send_dcs_packet, .dsi_read_dcs_packet = rk_mipi_dsi_read_dcs_packet, + .dsi_enable_video_mode = rk_mipi_dsi_enable_video_mode, + .dsi_enable_command_mode = rk_mipi_dsi_enable_command_mode, + .dsi_enable_hs_clk = rk_mipi_dsi_enable_hs_clk, + .dsi_is_active = rk_mipi_dsi_is_active, .power_up = rk_mipi_dsi_power_up, .power_down = rk_mipi_dsi_power_down, .dsi_init = rk_mipi_dsi_init, @@ -924,29 +988,48 @@ module_init(rk_mipi_dsi_reg); #if defined(CONFIG_HAS_EARLYSUSPEND) static void rk616_mipi_dsi_early_suspend(struct early_suspend *h) { - u32 val = 0X01; - dsi_set_bits(0, en_video_mode); - dsi_write_reg(DPHY_REGISTER0, &val); + u8 dcs[1] = {0}; - val = 0xe3; - dsi_write_reg(DPHY_REGISTER1, &val); - dsi_set_bits(0, shutdownz); + if(!g_screen->standby) { + dcs[0] = dcs_set_display_off; + dsi_send_dcs_packet(dcs, 1); + msleep(1); + dcs[0] = dcs_enter_sleep_mode; + dsi_send_dcs_packet(dcs, 1); + msleep(1); + } else { + g_screen->standby(1); + } + + rk_mipi_dsi_phy_power_down(); + rk_mipi_dsi_host_power_down(); + rk_mipi_dsi_enable_video_mode(0); + //printk("%s:%d\n", __func__, __LINE__); } static void rk616_mipi_dsi_late_resume(struct early_suspend *h) { + u8 dcs[1] = {0}; rk_mipi_dsi_phy_init(g_screen, 0); - //dsi_set_bits(1, shutdownz); rk_mipi_dsi_host_init(g_screen, 0); - - if(!g_screen->init) { - rk_mipi_dsi_send_dcs_packet(dcs_exit_sleep_mode, sizeof(dcs_exit_sleep_mode)); + rk_mipi_dsi_phy_power_up(); + rk_mipi_dsi_host_power_up(); + + if(!g_screen->standby) { + rk_mipi_dsi_enable_hs_clk(1); + rk_mipi_dsi_enable_video_mode(1); + dcs[0] = dcs_exit_sleep_mode; + rk_mipi_dsi_send_dcs_packet(dcs, 1); msleep(1); - rk_mipi_dsi_send_dcs_packet(dcs_set_diaplay_on, sizeof(dcs_set_diaplay_on)); + dcs[0] = dcs_set_display_on; + rk_mipi_dsi_send_dcs_packet(dcs, 1); msleep(10); + + } else { + g_screen->standby(0); } - dsi_set_bits(1, en_video_mode); rk616_display_router_cfg(dsi_rk616, g_screen, 0); + //printk("%s:%d\n", __func__, __LINE__); } #endif