lcd: mipi-dsi: add operation_mode and read debug command support
authorEvoke Zhang <evoke.zhang@amlogic.com>
Wed, 27 Jun 2018 05:49:13 +0000 (13:49 +0800)
committerYixun Lan <yixun.lan@amlogic.com>
Mon, 2 Jul 2018 13:59:35 +0000 (06:59 -0700)
PD#169193: lcd: mipi-dsi: add operation_mode and read debug command support

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

index 44ad2ef..a410dfa 100644 (file)
@@ -2880,6 +2880,80 @@ 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};
+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};
+
+       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");
+
+       rd_data = kcalloc(cnt, sizeof(unsigned char), GFP_KERNEL);
+       if (rd_data == NULL)
+               return sprintf(buf, "rd_data buf error\n");
+
+       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);
+       }
+#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]);
+       }
+       len += sprintf(buf+len, "\n");
+
+       kfree(rd_data);
+       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) {
+               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];
+
+       return count;
+}
+
 static ssize_t lcd_mipi_state_debug_show(struct class *class,
                struct class_attribute *attr, char *buf)
 {
@@ -2894,6 +2968,46 @@ static ssize_t lcd_mipi_state_debug_show(struct class *class,
                state_save);
 }
 
+static ssize_t lcd_mipi_mode_debug_show(struct class *class,
+               struct class_attribute *attr, char *buf)
+{
+       struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
+       unsigned char mode;
+
+       if ((lcd_drv->lcd_status & LCD_STATUS_IF_ON) == 0)
+               return sprintf(buf, "error: panel is disabled\n");
+
+       mode = lcd_drv->lcd_config->lcd_control.mipi_config->current_mode;
+       return sprintf(buf, "current mipi-dsi operation mode: %s(%d)\n",
+               (mode ? "command" : "video"), mode);
+}
+
+static ssize_t lcd_mipi_mode_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 temp;
+       unsigned char mode;
+       int ret = 0;
+
+       if ((lcd_drv->lcd_status & LCD_STATUS_IF_ON) == 0) {
+               LCDERR("panel is disabled\n");
+               return count;
+       }
+
+       ret = kstrtouint(buf, 10, &temp);
+       if (ret) {
+               pr_info("invalid data\n");
+               return -EINVAL;
+       }
+       mode = (unsigned char)temp;
+#ifdef CONFIG_AMLOGIC_LCD_TABLET
+       dsi_set_operation_mode(mode);
+#endif
+
+       return count;
+}
+
 static struct class_attribute lcd_interface_debug_class_attrs[] = {
        __ATTR(ttl,    0644,
                lcd_ttl_debug_show, lcd_ttl_debug_store),
@@ -2915,7 +3029,11 @@ static struct class_attribute lcd_phy_debug_class_attrs[] = {
 static struct class_attribute lcd_mipi_debug_class_attrs[] = {
        __ATTR(mpcmd,    0644,
                lcd_mipi_cmd_debug_show, lcd_mipi_cmd_debug_store),
+       __ATTR(mpread,   0644,
+               lcd_mipi_read_debug_show, lcd_mipi_read_debug_store),
        __ATTR(mpstate,  0644, lcd_mipi_state_debug_show, NULL),
+       __ATTR(mpmode,   0644,
+               lcd_mipi_mode_debug_show, lcd_mipi_mode_debug_store),
 };
 
 int lcd_class_creat(void)
index 4723b47..e0737a0 100644 (file)
@@ -614,6 +614,7 @@ static void set_mipi_dsi_host(unsigned int vcid, unsigned int chroma_subsample,
        struct dsi_config_s *dconf;
 
        dconf = p->lcd_control.mipi_config;
+       dconf->current_mode = operation_mode;
        venc_data_width = dconf->venc_data_width;
        dpi_data_format = dconf->dpi_data_format;
        lane_num        = (unsigned int)(dconf->lane_num);
@@ -759,6 +760,32 @@ static void set_mipi_dsi_host(unsigned int vcid, unsigned int chroma_subsample,
                dsi_host_write(MIPI_DSI_DWC_PHY_TMR_LPCLK_CFG_OS, 0x260017);
 }
 
+int dsi_set_operation_mode(unsigned char op_mode)
+{
+       struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
+       struct lcd_config_s *pconf;
+       unsigned char cur_mode;
+
+       op_mode = (op_mode == 0) ? 0 : 1;
+       pconf = lcd_drv->lcd_config;
+       cur_mode = pconf->lcd_control.mipi_config->current_mode;
+       if (cur_mode != op_mode) {
+               set_mipi_dsi_host(MIPI_DSI_VIRTUAL_CHAN_ID,
+                       0, /* Chroma sub sample, only for
+                           * YUV 422 or 420, even or odd
+                           */
+                       op_mode, /* DSI operation mode, video or command */
+                       pconf);
+               LCDPR("set mipi-dsi operation mode: %s(%d)\n",
+                       operation_mode_table[op_mode], op_mode);
+       } else {
+               LCDPR("same mipi-dsi operation mode: %s(%d), exit\n",
+                       operation_mode_table[op_mode], op_mode);
+       }
+
+       return 0;
+}
+
 /* *************************************************************
  * mipi dsi command support
  */
index 99f09ec..36d0f33 100644 (file)
@@ -49,4 +49,7 @@ extern int dsi_write_cmd(unsigned char *payload);
  */
 extern int dsi_read_single(unsigned char *payload, unsigned char *rd_data,
                unsigned int rd_byte_len);
+
+extern int dsi_set_operation_mode(unsigned char op_mode);
+
 #endif
index 3230411..2ab2e5d 100644 (file)
@@ -291,6 +291,8 @@ struct dsi_config_s {
        unsigned char check_reg;
        unsigned char check_cnt;
        unsigned char check_state;
+
+       unsigned char current_mode;
 };
 
 struct lcd_control_config_s {