lcd: add mipi-dsi checking panel state support

PD#156734: lcd: add mipi-dsi checking panel state support
after config check_state parameters in dts,
you can get state by below sysfs node:
cat /sys/class/lcd/mpstate

Change-Id: I6e1d8452e17166cd9c04c2a4979f42308f995b9a
Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
This commit is contained in:
Evoke Zhang
2018-02-22 18:36:38 +08:00
committed by Yixun Lan
parent ae37c44fc6
commit 04c7f90950
7 changed files with 135 additions and 18 deletions

View File

@@ -113,6 +113,8 @@
0 /*clk_ss_level*/
1 /*clk_auto_generate*/
44250000>; /*pixel_clk(unit in Hz)*/
check_state = <0x04 /* check_reg */
3>; /* check_cnt */
mipi_attr = <4 /*lane_num*/
360 /*bit_rate_max(MHz)*/
0 /*factor(*100, default 0 for auto)*/
@@ -154,6 +156,8 @@
0 /*clk_ss_level*/
1 /*clk_auto_generate*/
48715200>; /*pixel_clk(unit in Hz)*/
check_state = <0x04 /* check_reg */
3>; /* check_cnt */
mipi_attr = <4 /*lane_num*/
300 /*bit_rate_max(MHz)*/
0 /*factor(*100, default 0 for auto)*/

View File

@@ -2763,6 +2763,16 @@ static ssize_t lcd_mipi_cmd_debug_store(struct class *class,
return count;
}
static ssize_t lcd_mipi_state_debug_show(struct class *class,
struct class_attribute *attr, char *buf)
{
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
return sprintf(buf, "state: %d, check_en: %d\n",
lcd_drv->lcd_config->lcd_control.mipi_config->check_state,
lcd_drv->lcd_config->lcd_control.mipi_config->check_en);
}
static struct class_attribute lcd_interface_debug_class_attrs[] = {
__ATTR(ttl, 0644,
lcd_ttl_debug_show, lcd_ttl_debug_store),
@@ -2781,9 +2791,10 @@ static struct class_attribute lcd_phy_debug_class_attrs[] = {
lcd_phy_debug_show, lcd_phy_debug_store),
};
static struct class_attribute lcd_mipi_cmd_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(mpstate, 0644, lcd_mipi_state_debug_show, NULL),
};
int lcd_class_creat(void)
@@ -2834,12 +2845,11 @@ int lcd_class_creat(void)
break;
case LCD_MIPI:
for (i = 0; i < ARRAY_SIZE
(lcd_mipi_cmd_debug_class_attrs); i++) {
(lcd_mipi_debug_class_attrs); i++) {
if (class_create_file(lcd_drv->lcd_debug_class,
&lcd_mipi_cmd_debug_class_attrs[i])) {
LCDERR("create mipi_cmd debug attr %s fail\n",
lcd_mipi_cmd_debug_class_attrs[
i].attr.name);
&lcd_mipi_debug_class_attrs[i])) {
LCDERR("create mipi debug attr %s fail\n",
lcd_mipi_debug_class_attrs[i].attr.name);
}
}
break;

View File

@@ -559,6 +559,12 @@ static void lcd_config_print(struct lcd_config_s *pconf)
LCDPR("color_fmt = %d\n",
pconf->lcd_control.vbyone_config->color_fmt);
} else if (pconf->lcd_basic.lcd_type == LCD_MIPI) {
if (pconf->lcd_control.mipi_config->check_en) {
LCDPR("check_reg = 0x%02x\n",
pconf->lcd_control.mipi_config->check_reg);
LCDPR("check_cnt = %d\n",
pconf->lcd_control.mipi_config->check_cnt);
}
LCDPR("mipi_lane_num = %d\n",
pconf->lcd_control.mipi_config->lane_num);
LCDPR("bit_rate_max = %d\n",
@@ -813,6 +819,20 @@ static int lcd_config_load_from_dts(struct lcd_config_s *pconf,
}
break;
case LCD_MIPI:
ret = of_property_read_u32_array(child, "check_state",
&para[0], 2);
if (ret) {
if (lcd_debug_print_flag)
LCDPR("failed to get check_state\n");
pconf->lcd_control.mipi_config->check_en = 0;
} else {
pconf->lcd_control.mipi_config->check_en = 1;
pconf->lcd_control.mipi_config->check_reg =
(unsigned char)(para[0]);
pconf->lcd_control.mipi_config->check_cnt =
(unsigned char)(para[1]);
}
ret = of_property_read_u32_array(child, "mipi_attr",
&para[0], 8);
if (ret) {

View File

@@ -212,6 +212,14 @@ static void mipi_dsi_host_print_info(struct lcd_config_s *pconf)
factor = dconf->factor_numerator;
factor = ((factor * 1000 / dconf->factor_denominator) + 5) / 10;
if (dconf->check_en) {
pr_info("MIPI DSI check state:\n"
" check_reg: 0x%02x\n"
" check_cnt: %d\n"
" check_state %d\n\n",
dconf->check_reg, dconf->check_cnt, dconf->check_state);
}
pr_info("MIPI DSI Config:\n"
" lane num: %d\n"
" bit rate max: %dMHz\n"
@@ -790,9 +798,10 @@ static unsigned int generic_if_wr(unsigned int address, unsigned int data_in)
* Function: wait_bta_ack
* Poll to check if the BTA ack is finished
*/
static void wait_bta_ack(void)
static int wait_bta_ack(void)
{
unsigned int phy_status, i;
unsigned int phy_status;
int i;
/* Check if phydirection is RX */
i = CMD_TIMEOUT_CNT;
@@ -801,8 +810,10 @@ static void wait_bta_ack(void)
i--;
phy_status = dsi_host_read(MIPI_DSI_DWC_PHY_STATUS_OS);
} while ((((phy_status & 0x2) >> BIT_PHY_DIRECTION) == 0x0) && (i > 0));
if (i == 0)
if (i == 0) {
LCDERR("phy direction error: RX\n");
return -1;
}
/* Check if phydirection is return to TX */
i = CMD_TIMEOUT_CNT;
@@ -810,9 +821,13 @@ static void wait_bta_ack(void)
udelay(10);
i--;
phy_status = dsi_host_read(MIPI_DSI_DWC_PHY_STATUS_OS);
} while (((phy_status & 0x2) >> BIT_PHY_DIRECTION) == 0x1);
if (i == 0)
} while ((((phy_status & 0x2) >> BIT_PHY_DIRECTION) == 0x1) && (i > 0));
if (i == 0) {
LCDERR("phy direction error: TX\n");
return -1;
}
return 0;
}
/* *************************************************************
@@ -911,6 +926,7 @@ static int dsi_generic_read_packet(struct dsi_cmd_request_s *req,
{
unsigned int d_para[2], read_data;
unsigned int i, j, done;
int ret = 0;
switch (req->data_type) {
case DT_GEN_RD_1:
@@ -938,7 +954,10 @@ static int dsi_generic_read_packet(struct dsi_cmd_request_s *req,
(d_para[0] << BIT_GEN_WC_LSBYTE) |
(((unsigned int)req->vc_id) << BIT_GEN_VC) |
(((unsigned int)req->data_type) << BIT_GEN_DT)));
wait_bta_ack();
ret = wait_bta_ack();
if (ret)
return -1;
i = 0;
done = 0;
while (done == 0) {
@@ -965,6 +984,7 @@ static int dsi_dcs_read_packet(struct dsi_cmd_request_s *req,
{
unsigned int d_command, read_data;
unsigned int i, j, done;
int ret = 0;
d_command = ((unsigned int)req->payload[2]) & 0xff;
@@ -975,7 +995,10 @@ static int dsi_dcs_read_packet(struct dsi_cmd_request_s *req,
(d_command << BIT_GEN_WC_LSBYTE) |
(((unsigned int)req->vc_id) << BIT_GEN_VC) |
(((unsigned int)req->data_type) << BIT_GEN_DT)));
wait_bta_ack();
ret = wait_bta_ack();
if (ret)
return -1;
i = 0;
done = 0;
while (done == 0) {
@@ -1276,7 +1299,7 @@ int dsi_write_cmd(unsigned char *payload)
* Function: dsi_read_single
* Supported Data Type: DT_GEN_RD_0, DT_GEN_RD_1, DT_GEN_RD_2,
* DT_DCS_RD_0
* Return: data count
* Return: data count, -1 for error
*/
int dsi_read_single(unsigned char *payload, unsigned char *rd_data,
unsigned int rd_byte_len)
@@ -1322,6 +1345,9 @@ int dsi_read_single(unsigned char *payload, unsigned char *rd_data,
break;
}
if (num < 0)
LCDERR("mipi-dsi read error\n");
return num;
}
#else
@@ -1329,7 +1355,7 @@ int dsi_read_single(unsigned char *payload, unsigned char *rd_data,
unsigned int rd_byte_len)
{
LCDPR("Don't support mipi-dsi read command\n");
return 0;
return -1;
}
#endif
@@ -1590,6 +1616,45 @@ static void mipi_dsi_host_init(struct lcd_config_s *pconf)
pconf);
}
static void mipi_dsi_check_state(struct dsi_config_s *dconf,
unsigned char reg, int cnt)
{
int ret = 0, i, len;
unsigned char *rd_data;
unsigned char payload[3] = {DT_GEN_RD_1, 1, 0x04};
char str[100];
LCDPR("%s\n", __func__);
rd_data = kmalloc_array(cnt, sizeof(unsigned char), GFP_KERNEL);
if (rd_data == NULL) {
LCDERR("%s: rd_data error\n", __func__);
return;
}
payload[2] = reg;
ret = dsi_read_single(payload, rd_data, cnt);
if (ret < 0) {
dconf->check_state = 0;
lcd_vcbus_setb(L_VCOM_VS_ADDR, 0, 12, 1);
kfree(rd_data);
return;
}
dconf->check_state = 1;
lcd_vcbus_setb(L_VCOM_VS_ADDR, 1, 12, 1);
len = sprintf(str, "read reg 0x%02x: ", reg);
for (i = 0; i < ret; i++) {
if (i == 0)
len += sprintf(str+len, "0x%02x", rd_data[i]);
else
len += sprintf(str+len, ",0x%02x", rd_data[i]);
}
pr_info("%s\n", str);
kfree(rd_data);
}
static void mipi_dsi_link_on(struct lcd_config_s *pconf)
{
unsigned int op_mode_init, op_mode_disp;
@@ -1605,6 +1670,9 @@ static void mipi_dsi_link_on(struct lcd_config_s *pconf)
op_mode_init = dconf->operation_mode_init;
op_mode_disp = dconf->operation_mode_display;
if (dconf->check_en)
mipi_dsi_check_state(dconf, dconf->check_reg, dconf->check_cnt);
#ifdef CONFIG_AMLOGIC_LCD_EXTERN
if (dconf->extern_init < LCD_EXTERN_INDEX_INVALID) {
lcd_ext = aml_lcd_extern_get_driver(dconf->extern_init);
@@ -1616,6 +1684,7 @@ static void mipi_dsi_link_on(struct lcd_config_s *pconf)
lcd_ext->config.table_init_on);
LCDPR("[extern]%s dsi init on\n",
lcd_ext->config.name);
goto mipi_dsi_link_disp;
}
}
}
@@ -1626,6 +1695,7 @@ static void mipi_dsi_link_on(struct lcd_config_s *pconf)
LCDPR("dsi init on\n");
}
mipi_dsi_link_disp:
if (op_mode_disp != op_mode_init) {
set_mipi_dsi_host(MIPI_DSI_VIRTUAL_CHAN_ID,
0, /* Chroma sub sample, only for
@@ -1787,8 +1857,9 @@ void lcd_mipi_dsi_config_post(struct lcd_config_s *pconf)
/* phy config */
mipi_dsi_phy_config(&dsi_phy_config, dconf->bit_rate);
if (lcd_debug_print_flag)
mipi_dsi_host_print_info(pconf);
/* update check_state */
if (dconf->check_en)
dconf->check_state = lcd_vcbus_getb(L_VCOM_VS_ADDR, 12, 1);
}
static void mipi_dsi_host_on(struct lcd_config_s *pconf)
@@ -1798,6 +1869,9 @@ static void mipi_dsi_host_on(struct lcd_config_s *pconf)
dsi_phy_config_set(pconf);
mipi_dsi_link_on(pconf);
if (lcd_debug_print_flag)
mipi_dsi_host_print_info(pconf);
}
static void mipi_dsi_host_off(void)

View File

@@ -530,7 +530,7 @@ struct dsi_vid_s {
};
#define DSI_CMD_SIZE_MAX 2000
/* #define DSI_CMD_READ_VALID // DPHY don't support for M8 */
#define DSI_CMD_READ_VALID
extern void mipi_dsi_print_info(struct lcd_config_s *pconf);
extern int lcd_mipi_dsi_init_table_detect(struct device_node *m_node,

View File

@@ -128,6 +128,10 @@ static struct dsi_config_s lcd_mipi_config = {
/* ext_index if needed, must match ext_config index;
* 0xff for invalid
*/
.check_en = 0,
.check_reg = 0,
.check_cnt = 0,
.check_state = 0,
};
static struct lcd_power_ctrl_s lcd_power_config = {

View File

@@ -288,6 +288,11 @@ struct dsi_config_s {
unsigned char *dsi_init_on;
unsigned char *dsi_init_off;
unsigned char extern_init;
unsigned char check_en;
unsigned char check_reg;
unsigned char check_cnt;
unsigned char check_state;
};
struct lcd_control_config_s {