From 524fead9db1b8904e7e4a414d167b75eadf331bd Mon Sep 17 00:00:00 2001 From: Shaochan Liu Date: Fri, 22 Feb 2019 14:09:00 +0800 Subject: [PATCH] lcd: add lcd_ctrl bootargs for lcd driver control [2/2] PD#SWPL-4097 Problem: add lcd_ctrl bootargs for lcd driver control Solution: add lcd_ctrl bootargs for lcd driver advance control and debug function in kernel Verify: verify by t962x2-r311 Change-Id: I4d741eef42505e259b54cd4f00e395d09edf7604 Signed-off-by: Shaochan Liu --- drivers/amlogic/media/vout/lcd/lcd_vout.c | 122 ++++++++++++++++++++---- include/linux/amlogic/media/vout/lcd/lcd_vout.h | 13 +++ 2 files changed, 117 insertions(+), 18 deletions(-) diff --git a/drivers/amlogic/media/vout/lcd/lcd_vout.c b/drivers/amlogic/media/vout/lcd/lcd_vout.c index 3966310..c87de76 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_vout.c +++ b/drivers/amlogic/media/vout/lcd/lcd_vout.c @@ -188,6 +188,16 @@ static struct lcd_power_ctrl_s lcd_power_config = { }, }; +static struct lcd_boot_ctrl_s lcd_boot_ctrl_config = { + .lcd_type = LCD_TYPE_MAX, + .lcd_bits = 0, + .advanced_flag = 0, + .debug_print_flag = 0, + .debug_test_pattern = 0, + .debug_para_source = 0, + .debug_lcd_mode = 0, +}; + /* index 0: valid flag */ static unsigned int vlock_param[LCD_VLOCK_PARAM_NUM] = {0}; @@ -228,6 +238,7 @@ static struct lcd_config_s lcd_config_dft = { .vlock_param = vlock_param, }, .lcd_power = &lcd_power_config, + .lcd_boot_ctrl = &lcd_boot_ctrl_config, .pinmux_flag = 0xff, .change_flag = 0, .retry_enable_flag = 0, @@ -1222,13 +1233,27 @@ static int lcd_config_probe(struct platform_device *pdev) lcd_driver->res_tcon_irq = NULL; /* lcd driver assign */ - ret = of_property_read_string(lcd_driver->dev->of_node, "mode", &str); - if (ret) { - str = "none"; - LCDERR("failed to get mode\n"); - return -1; + switch (lcd_boot_ctrl_config.debug_lcd_mode) { + case 1: + LCDPR("debug_lcd_mode: 1,tv mode\n"); + lcd_driver->lcd_mode = LCD_MODE_TV; + break; + case 2: + LCDPR("debug_lcd_mode: 2,tablet mode\n"); + lcd_driver->lcd_mode = LCD_MODE_TABLET; + break; + default: + ret = of_property_read_string(lcd_driver->dev->of_node, + "mode", &str); + if (ret) { + str = "none"; + LCDERR("failed to get mode\n"); + return -1; + } + lcd_driver->lcd_mode = lcd_mode_str_to_mode(str); + break; } - lcd_driver->lcd_mode = lcd_mode_str_to_mode(str); + ret = of_property_read_u32(lcd_driver->dev->of_node, "fr_auto_policy", &val); if (ret) { @@ -1238,14 +1263,29 @@ static int lcd_config_probe(struct platform_device *pdev) } else { lcd_driver->fr_auto_policy = (unsigned char)val; } - ret = of_property_read_u32(lcd_driver->dev->of_node, "key_valid", &val); - if (ret) { - if (lcd_debug_print_flag) - LCDPR("failed to get key_valid\n"); + + switch (lcd_boot_ctrl_config.debug_para_source) { + case 1: + LCDPR("debug_para_source: 1,dts\n"); lcd_driver->lcd_key_valid = 0; - } else { - lcd_driver->lcd_key_valid = (unsigned char)val; + break; + case 2: + LCDPR("debug_para_source: 2,unifykey\n"); + lcd_driver->lcd_key_valid = 1; + break; + default: + ret = of_property_read_u32(lcd_driver->dev->of_node, + "key_valid", &val); + if (ret) { + if (lcd_debug_print_flag) + LCDPR("failed to get key_valid\n"); + lcd_driver->lcd_key_valid = 0; + } else { + lcd_driver->lcd_key_valid = (unsigned char)val; + } + break; } + LCDPR("detect mode: %s, fr_auto_policy: %d, key_valid: %d\n", str, lcd_driver->fr_auto_policy, lcd_driver->lcd_key_valid); @@ -1280,7 +1320,7 @@ static int lcd_config_probe(struct platform_device *pdev) lcd_driver->lcd_info = &lcd_vinfo; lcd_driver->lcd_config = &lcd_config_dft; - lcd_driver->lcd_test_state = 0; + lcd_driver->lcd_test_state = lcd_boot_ctrl_config.debug_test_pattern; lcd_driver->lcd_test_flag = 0; lcd_driver->lcd_mute_state = 0; lcd_driver->lcd_mute_flag = 0; @@ -1312,6 +1352,26 @@ static int lcd_config_probe(struct platform_device *pdev) } } + if (lcd_driver->lcd_config->lcd_basic.lcd_type == LCD_TYPE_MAX) { + switch (lcd_boot_ctrl_config.lcd_type) { + case LCD_TTL: + lcd_driver->lcd_config->lcd_basic.lcd_bits = + lcd_boot_ctrl_config.lcd_bits; + lcd_driver->lcd_config->lcd_control.ttl_config->sync_valid = + lcd_boot_ctrl_config.advanced_flag; + lcd_ttl_pinmux_set(1); + break; + case LCD_VBYONE: + lcd_vbyone_pinmux_set(1); + break; + case LCD_MLVDS: + case LCD_P2P: + lcd_tcon_pinmux_set(1); + break; + default: + break; + } + } return 0; } @@ -1417,11 +1477,8 @@ static int lcd_probe(struct platform_device *pdev) const struct of_device_id *match; int ret = 0; -#ifdef LCD_DEBUG_INFO - lcd_debug_print_flag = 1; -#else - lcd_debug_print_flag = 0; -#endif + lcd_debug_print_flag = lcd_boot_ctrl_config.debug_print_flag; + lcd_driver = kmalloc(sizeof(struct aml_lcd_drv_s), GFP_KERNEL); if (!lcd_driver) { LCDERR("%s: lcd driver no enough memory\n", __func__); @@ -1588,7 +1645,36 @@ static int __init lcd_panel_type_para_setup(char *str) LCDPR("panel_type: %s\n", lcd_propname); return 0; } + +static int __init lcd_boot_ctrl_setup(char *str) +{ + //struct lcd_boot_ctrl_s *lcd_boot_ctrl = lcd_config_dft.lcd_boot_ctrl; + + int ret = 0; + unsigned int lcd_ctrl = 0; + + if (str == NULL) + return -EINVAL; + + ret = kstrtouint(str, 16, &lcd_ctrl); + if (ret) { + LCDERR("%s:invalid data\n", __func__); + return -EINVAL; + } + + LCDPR("lcd_ctrl: 0x%08x\n", lcd_ctrl); + lcd_boot_ctrl_config.lcd_type = 0xf & lcd_ctrl; + lcd_boot_ctrl_config.lcd_bits = 0xf & (lcd_ctrl >> 4); + lcd_boot_ctrl_config.advanced_flag = 0xff & (lcd_ctrl >> 8); + lcd_boot_ctrl_config.debug_print_flag = 0xf & (lcd_ctrl >> 16); + lcd_boot_ctrl_config.debug_test_pattern = 0xf & (lcd_ctrl >> 24); + lcd_boot_ctrl_config.debug_para_source = 0x3 & (lcd_ctrl >> 28); + lcd_boot_ctrl_config.debug_lcd_mode = 0x3 & (lcd_ctrl >> 30); + return 0; +} + __setup("panel_type=", lcd_panel_type_para_setup); +__setup("lcd_ctrl=", lcd_boot_ctrl_setup); MODULE_DESCRIPTION("Meson LCD Panel Driver"); MODULE_LICENSE("GPL"); diff --git a/include/linux/amlogic/media/vout/lcd/lcd_vout.h b/include/linux/amlogic/media/vout/lcd/lcd_vout.h index be49d60..38cff7e 100644 --- a/include/linux/amlogic/media/vout/lcd/lcd_vout.h +++ b/include/linux/amlogic/media/vout/lcd/lcd_vout.h @@ -433,6 +433,18 @@ struct lcd_power_ctrl_s { int power_off_step_max; /* internal use for debug */ }; +struct lcd_boot_ctrl_s { + unsigned char lcd_type; //bit[3:0] + unsigned char lcd_bits; //bit[7:4] bits:6 or 8 + unsigned char advanced_flag; //bit[15:8] + unsigned char debug_print_flag; //bit[19:16] + unsigned char debug_test_pattern; //bit[27:24] + unsigned char debug_para_source;//bit[29:28] + //0:normal, 1:dts, 2:unifykey, 3:TBD + unsigned char debug_lcd_mode; //bit[31:30] + //0:normal, 1:tv, 2:tablet, 3:TBD +}; + #define LCD_ENABLE_RETRY_MAX 3 struct lcd_config_s { char *lcd_propname; @@ -443,6 +455,7 @@ struct lcd_config_s { struct lcd_optical_info_s optical_info; struct lcd_control_config_s lcd_control; struct lcd_power_ctrl_s *lcd_power; + struct lcd_boot_ctrl_s *lcd_boot_ctrl; struct pinctrl *pin; unsigned char pinmux_flag; unsigned char change_flag; -- 2.7.4