From 1702754d80776da33fb1b6cd53c934f9153d21d7 Mon Sep 17 00:00:00 2001 From: Evoke Zhang Date: Wed, 27 Jun 2018 13:49:13 +0800 Subject: [PATCH] lcd: mipi-dsi: add operation_mode and read debug command support PD#169193: lcd: mipi-dsi: add operation_mode and read debug command support Change-Id: I5b1b781bc7700d0ced109c4e3ec171c91196604b Signed-off-by: Evoke Zhang --- drivers/amlogic/media/vout/lcd/lcd_debug.c | 118 +++++++++++++++++++++ .../media/vout/lcd/lcd_tablet/mipi_dsi_util.c | 27 +++++ include/linux/amlogic/media/vout/lcd/lcd_mipi.h | 3 + include/linux/amlogic/media/vout/lcd/lcd_vout.h | 2 + 4 files changed, 150 insertions(+) diff --git a/drivers/amlogic/media/vout/lcd/lcd_debug.c b/drivers/amlogic/media/vout/lcd/lcd_debug.c index 44ad2ef..a410dfa 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_debug.c +++ b/drivers/amlogic/media/vout/lcd/lcd_debug.c @@ -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", ¶[0], ¶[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) diff --git a/drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.c b/drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.c index 4723b47..e0737a0 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.c @@ -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 */ diff --git a/include/linux/amlogic/media/vout/lcd/lcd_mipi.h b/include/linux/amlogic/media/vout/lcd/lcd_mipi.h index 99f09ec..36d0f33 100644 --- a/include/linux/amlogic/media/vout/lcd/lcd_mipi.h +++ b/include/linux/amlogic/media/vout/lcd/lcd_mipi.h @@ -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 diff --git a/include/linux/amlogic/media/vout/lcd/lcd_vout.h b/include/linux/amlogic/media/vout/lcd/lcd_vout.h index 3230411..2ab2e5d 100644 --- a/include/linux/amlogic/media/vout/lcd/lcd_vout.h +++ b/include/linux/amlogic/media/vout/lcd/lcd_vout.h @@ -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 { -- 2.7.4