lcd: mipi-dsi: optimize mipi read function for video mode

PD#171352: lcd: mipi-dsi: optimize mipi read function for video mode

Change-Id: I7fec036ad568c00ca3573feb3eb5d0544050bfb2
Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
This commit is contained in:
Evoke Zhang
2018-08-07 19:13:39 +08:00
committed by Jianxin Pan
parent ce824cd479
commit 3367113918
6 changed files with 133 additions and 41 deletions

View File

@@ -114,6 +114,7 @@ extern int lcd_tv_probe(struct device *dev);
extern int lcd_tv_remove(struct device *dev);
#endif
#ifdef CONFIG_AMLOGIC_LCD_TABLET
int lcd_mipi_test_read(struct dsi_read_s *dread);
extern void lcd_tablet_vout_server_init(void);
extern void lcd_tablet_vout_server_remove(void);
extern void lcd_tablet_clk_config_change(struct lcd_config_s *pconf);

View File

@@ -1054,7 +1054,7 @@ static void lcd_screen_restore(void)
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
unsigned int num;
num = lcd_drv->lcd_test_flag;
num = lcd_drv->lcd_test_state;
num = (num >= LCD_ENC_TST_NUM_MAX) ? 0 : num;
if (lcd_drv->workqueue)
@@ -2902,76 +2902,110 @@ static ssize_t lcd_mipi_cmd_debug_store(struct class *class,
return count;
}
/* [0]=reg_addr, [1]=read_cnt */
static unsigned char lcd_mipi_read_buf[2] = {0xff, 0};
#define MIPI_RD_RET_CODE_MAX 5
static char *mipi_read_ret_code_table[] = {
"success",
"read null",
"read error",
"read back cnt is wrong",
"timeout",
"unknown error",
};
static struct dsi_read_s dread = {
.flag = 0,
.reg = 0xff,
.cnt = 0,
.value = NULL,
.ret_code = 4,
.line_start = 0x1fff,
.line_end = 0x1fff,
};
static ssize_t lcd_mipi_read_debug_show(struct class *class,
struct class_attribute *attr, char *buf)
{
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
int ret = 0, i, len;
unsigned char reg, cnt, *rd_data;
unsigned char payload[3] = {DT_GEN_RD_1, 1, 0x04};
unsigned int i = 0, len;
if ((lcd_drv->lcd_status & LCD_STATUS_IF_ON) == 0)
return sprintf(buf, "error: panel is disabled\n");
reg = lcd_mipi_read_buf[0];
cnt = lcd_mipi_read_buf[1];
if (reg == 0xff)
return sprintf(buf, "reg address is invalid\n");
if (cnt == 0)
return sprintf(buf, "read count is invalid\n");
if (dread.reg == 0xff)
return sprintf(buf, "error: reg address is invalid\n");
if (dread.cnt == 0)
return sprintf(buf, "error: read count is invalid\n");
rd_data = kcalloc(cnt, sizeof(unsigned char), GFP_KERNEL);
if (rd_data == NULL)
return sprintf(buf, "rd_data buf error\n");
if (dread.cnt > DSI_READ_CNT_MAX)
return sprintf(buf, "error: mipi read cnt is out of support\n");
if (dread.value == NULL)
return sprintf(buf, "error: mipi read return value is null\n");
dread.line_start = 0x1fff;
dread.line_end = 0x1fff;
dread.ret_code = 4;
payload[2] = reg;
#ifdef CONFIG_AMLOGIC_LCD_TABLET
ret = dsi_read_single(payload, rd_data, cnt);
if (ret < 0) {
kfree(rd_data);
return sprintf(buf, "mipi-dsi read error\n");
}
if (ret > cnt) {
kfree(rd_data);
return sprintf(buf, "mipi-dsi read 0x%02x back cnt is wrong\n",
reg);
if (lcd_drv->lcd_config->lcd_control.mipi_config->current_mode == 0) {
dread.flag = 1;
while (i++ < 5000) {
if (dread.flag == 0)
break;
udelay(20);
}
} else {
lcd_mipi_test_read(&dread);
}
#endif
len = sprintf(buf, "read reg 0x%02x: ", reg);
for (i = 0; i < ret; i++) {
if (i == 0)
len += sprintf(buf+len, "0x%02x", rd_data[i]);
else
len += sprintf(buf+len, ",0x%02x", rd_data[i]);
if (dread.ret_code) {
dread.ret_code = (dread.ret_code >= MIPI_RD_RET_CODE_MAX) ?
MIPI_RD_RET_CODE_MAX : dread.ret_code;
return sprintf(buf, "read error: %s(%d)\n",
mipi_read_ret_code_table[dread.ret_code],
dread.ret_code);
}
len += sprintf(buf+len, "\n");
kfree(rd_data);
len = sprintf(buf, "read reg 0x%02x: ", dread.reg);
for (i = 0; i < dread.cnt; i++) {
if (i == 0)
len += sprintf(buf+len, "0x%02x", dread.value[i]);
else
len += sprintf(buf+len, ",0x%02x", dread.value[i]);
}
len += sprintf(buf+len, "\nread line start=%d, end=%d\n",
dread.line_start, dread.line_end);
return len;
}
static ssize_t lcd_mipi_read_debug_store(struct class *class,
struct class_attribute *attr, const char *buf, size_t count)
{
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
unsigned int para[2];
int ret = 0;
if ((lcd_drv->lcd_status & LCD_STATUS_IF_ON) == 0) {
LCDERR("panel is disabled\n");
return count;
}
ret = sscanf(buf, "%x %d", &para[0], &para[1]);
if (ret < 2) {
dread.reg = 0xff;
dread.cnt = 0;
pr_info("invalid data\n");
return count;
}
lcd_mipi_read_buf[0] = (unsigned char)para[0];
lcd_mipi_read_buf[1] = (unsigned char)para[1];
dread.reg = (unsigned char)para[0];
dread.cnt = (unsigned char)para[1];
if (dread.cnt > DSI_READ_CNT_MAX) {
LCDERR("mipi read cnt is out of support\n");
return count;
}
if (dread.value == NULL) {
LCDERR("mipi read return value is null\n");
return count;
}
pr_info("set mipi read reg: 0x%02x, cnt: %d\n", dread.reg, dread.cnt);
return count;
}
@@ -3107,6 +3141,9 @@ int lcd_class_creat(void)
}
break;
case LCD_MIPI:
dread.value = kcalloc(DSI_READ_CNT_MAX, sizeof(unsigned char),
GFP_KERNEL);
lcd_drv->lcd_config->lcd_control.mipi_config->dread = &dread;
for (i = 0; i < ARRAY_SIZE
(lcd_mipi_debug_class_attrs); i++) {
if (class_create_file(lcd_drv->lcd_debug_class,

View File

@@ -1119,6 +1119,7 @@
* 0=ENCL, 1=ENCI, 2=ENCP, 3=ENCT.
*/
#define VPU_VIU_VENC_MUX_CTRL 0x271a
#define ENCL_INFO_READ 0x271f
/* Bit 6 RW, gclk_mpeg_vpu_misc
* Bit 5 RW, gclk_mpeg_venc_l_top

View File

@@ -2169,3 +2169,29 @@ void lcd_mipi_control_set(struct lcd_config_s *pconf, int status)
mipi_dsi_host_off();
}
int lcd_mipi_test_read(struct dsi_read_s *dread)
{
int ret = 0;
unsigned char payload[3] = {DT_GEN_RD_1, 1, 0x04};
if (dread == NULL)
return 1;
dread->line_start = lcd_vcbus_getb(ENCL_INFO_READ, 16, 13);
payload[2] = dread->reg;
ret = dsi_read_single(payload, dread->value, dread->cnt);
if (ret < 0) {
dread->ret_code = 2;
return 2;
}
if (ret > dread->cnt) {
dread->ret_code = 3;
return 3;
}
dread->line_end = lcd_vcbus_getb(ENCL_INFO_READ, 16, 13);
dread->ret_code = 0;
return 0;
}

View File

@@ -373,10 +373,23 @@ static void lcd_resume_work(struct work_struct *p_work)
static irqreturn_t lcd_vsync_isr(int irq, void *dev_id)
{
int flag;
#ifdef CONFIG_AMLOGIC_LCD_TABLET
struct lcd_config_s *pconf = lcd_driver->lcd_config;
#endif
if ((lcd_driver->lcd_status & LCD_STATUS_ENCL_ON) == 0)
return IRQ_HANDLED;
#ifdef CONFIG_AMLOGIC_LCD_TABLET
if (pconf->lcd_control.mipi_config->dread) {
if (pconf->lcd_control.mipi_config->dread->flag) {
lcd_mipi_test_read(
pconf->lcd_control.mipi_config->dread);
pconf->lcd_control.mipi_config->dread->flag = 0;
}
}
#endif
if (lcd_driver->lcd_mute_flag & LCD_MUTE_UPDATE) {
flag = lcd_driver->lcd_mute_flag & 0x1;
if (flag) {

View File

@@ -267,6 +267,18 @@ struct vbyone_config_s {
#define DSI_INIT_ON_MAX 100
#define DSI_INIT_OFF_MAX 30
#define DSI_READ_CNT_MAX 30
struct dsi_read_s {
unsigned char flag;
unsigned char reg;
unsigned char cnt;
unsigned char *value;
unsigned char ret_code;
unsigned int line_start;
unsigned int line_end;
};
struct dsi_config_s {
unsigned char lane_num;
unsigned int bit_rate_max; /* MHz */
@@ -294,6 +306,8 @@ struct dsi_config_s {
unsigned char check_state;
unsigned char current_mode;
struct dsi_read_s *dread;
};
struct lcd_control_config_s {