mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
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:
@@ -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);
|
||||
|
||||
@@ -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", ¶[0], ¶[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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user