lcd: mipi-dsi: optimize mipi read function for video mode
authorEvoke Zhang <evoke.zhang@amlogic.com>
Tue, 7 Aug 2018 11:13:39 +0000 (19:13 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Mon, 13 Aug 2018 11:00:47 +0000 (04:00 -0700)
PD#171352: lcd: mipi-dsi: optimize mipi read function for video mode

Change-Id: I7fec036ad568c00ca3573feb3eb5d0544050bfb2
Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
drivers/amlogic/media/vout/lcd/lcd_common.h
drivers/amlogic/media/vout/lcd/lcd_debug.c
drivers/amlogic/media/vout/lcd/lcd_reg.h
drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.c
drivers/amlogic/media/vout/lcd/lcd_vout.c
include/linux/amlogic/media/vout/lcd/lcd_vout.h

index 61a9a8f..9eda786 100644 (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);
index ffae269..d488117 100644 (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");
+
+       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");
 
-       rd_data = kcalloc(cnt, sizeof(unsigned char), GFP_KERNEL);
-       if (rd_data == NULL)
-               return sprintf(buf, "rd_data buf error\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 (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, "read reg 0x%02x: ", dread.reg);
+       for (i = 0; i < dread.cnt; i++) {
                if (i == 0)
-                       len += sprintf(buf+len, "0x%02x", rd_data[i]);
+                       len += sprintf(buf+len, "0x%02x", dread.value[i]);
                else
-                       len += sprintf(buf+len, ",0x%02x", rd_data[i]);
+                       len += sprintf(buf+len, ",0x%02x", dread.value[i]);
        }
-       len += sprintf(buf+len, "\n");
 
-       kfree(rd_data);
+       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,
index 7a5c8d5..29f5d7a 100644 (file)
  * 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
index 175a3a3..81bee22 100644 (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;
+}
index 7d21061..9cc196b 100644 (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) {
index 6b8cc4b..ccf8a91 100644 (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 {