mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 04:48:04 +09:00
mipi dsi: add new interfaces of dsi
This commit is contained in:
@@ -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) {
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
rk_mipi_dsi_phy_power_up();
|
||||
rk_mipi_dsi_host_power_up();
|
||||
|
||||
if(!g_screen->init) {
|
||||
rk_mipi_dsi_send_dcs_packet(dcs_exit_sleep_mode, sizeof(dcs_exit_sleep_mode));
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user