mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
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:
@@ -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)*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
¶[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",
|
||||
¶[0], 8);
|
||||
if (ret) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user