From 6d24fb375706fd142360b6625eebf6d08c022ed4 Mon Sep 17 00:00:00 2001 From: Evoke Zhang Date: Tue, 2 Jun 2020 14:49:01 +0800 Subject: [PATCH] lcd: support more init_level [2/2] PD#SWPL-27213 Problem: need different lcd init_level policy Solution: support more init_level Verify: x301 Change-Id: I28d39d50066494fc0aed640fe3c93986f6fd394e Signed-off-by: Evoke Zhang --- drivers/amlogic/media/vout/backlight/aml_bl.c | 42 +++++++++++++++---- drivers/amlogic/media/vout/lcd/lcd_vout.c | 39 ++++++++++++++--- .../linux/amlogic/media/vout/lcd/lcd_vout.h | 8 +++- 3 files changed, 72 insertions(+), 17 deletions(-) diff --git a/drivers/amlogic/media/vout/backlight/aml_bl.c b/drivers/amlogic/media/vout/backlight/aml_bl.c index 1528501f8de2..c1c8f226c0ee 100644 --- a/drivers/amlogic/media/vout/backlight/aml_bl.c +++ b/drivers/amlogic/media/vout/backlight/aml_bl.c @@ -3452,24 +3452,48 @@ static const struct of_device_id bl_dt_match_table[] = { }; #endif +static void aml_bl_power_init(void) +{ + struct bl_config_s *bconf = bl_drv->bconf; + unsigned long m_jif; + + bl_on_request = 1; + m_jif = msecs_to_jiffies(bconf->power_on_delay); + /* lcd power on sequence control */ + if (bconf->method < BL_CTRL_MAX) { + if (bl_drv->workqueue) { + queue_delayed_work(bl_drv->workqueue, + &bl_drv->bl_delayed_work, + m_jif); + } else { + schedule_delayed_work(&bl_drv->bl_delayed_work, m_jif); + } + } else { + BLERR("wrong backlight control method\n"); + } +} + static void aml_bl_init_status_update(void) { struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); - unsigned int state; if (!lcd_drv) return; - if (!lcd_drv->lcd_config) - return; - if (lcd_drv->lcd_config->lcd_boot_ctrl) { - if (lcd_drv->lcd_config->lcd_boot_ctrl->lcd_init_level) - return; - } - state = bl_vcbus_read(ENCL_VIDEO_EN); - if (state == 0) /* default disable lcd & backlight */ + /* default disable lcd & backlight */ + if ((lcd_drv->lcd_status & LCD_STATUS_IF_ON) == 0) return; + if (lcd_drv->boot_ctrl) { + if (lcd_drv->boot_ctrl->lcd_init_level == + LCD_INIT_LEVEL_KERNEL_ON) { + BLPR("power on for init_level %d\n", + lcd_drv->boot_ctrl->lcd_init_level); + aml_bl_power_init(); + return; + } + } + /* update bl status */ bl_drv->state = (BL_STATE_LCD_ON | BL_STATE_BL_POWER_ON | BL_STATE_BL_ON); diff --git a/drivers/amlogic/media/vout/lcd/lcd_vout.c b/drivers/amlogic/media/vout/lcd/lcd_vout.c index a2efb3e67e82..d943a34294e0 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_vout.c +++ b/drivers/amlogic/media/vout/lcd/lcd_vout.c @@ -54,6 +54,11 @@ unsigned char lcd_debug_print_flag; unsigned char lcd_resume_flag; +/* for driver probe init: + * 0: none + * 1: power on request + */ +static unsigned char lcd_init_flag; static struct aml_lcd_drv_s *lcd_driver; struct mutex lcd_vout_mutex; @@ -242,7 +247,6 @@ 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, @@ -1132,6 +1136,15 @@ static int lcd_mode_probe(struct device *dev) lcd_notifier_register(); lcd_vsync_irq_init(); + if (lcd_init_flag) { + LCDPR("power on for init_flag\n"); + lcd_init_flag = 0; + mutex_lock(&lcd_driver->power_mutex); + aml_lcd_notifier_call_chain(LCD_EVENT_IF_POWER_ON, NULL); + lcd_if_enable_retry(lcd_driver->lcd_config); + mutex_unlock(&lcd_driver->power_mutex); + } + /* add notifier for video sync_duration info refresh */ vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE, &lcd_driver->lcd_info->mode); @@ -1237,17 +1250,30 @@ static void lcd_config_default(void) - lcd_vcbus_read(ENCL_VIDEO_HAVON_BEGIN) + 1; pconf->lcd_basic.v_active = lcd_vcbus_read(ENCL_VIDEO_VAVON_ELINE) - lcd_vcbus_read(ENCL_VIDEO_VAVON_BLINE) + 1; + lcd_init_flag = 0; if (lcd_vcbus_read(ENCL_VIDEO_EN)) { - if (lcd_boot_ctrl_config.lcd_init_level) - lcd_driver->lcd_status = LCD_STATUS_ENCL_ON; - else + switch (lcd_boot_ctrl_config.lcd_init_level) { + case LCD_INIT_LEVEL_NORMAL: lcd_driver->lcd_status = LCD_STATUS_ON; + break; + case LCD_INIT_LEVEL_PWR_OFF: + lcd_driver->lcd_status = LCD_STATUS_ENCL_ON; + break; + case LCD_INIT_LEVEL_KERNEL_ON: + lcd_init_flag = 1; + lcd_driver->lcd_status = LCD_STATUS_ENCL_ON; + break; + default: + lcd_driver->lcd_status = LCD_STATUS_ON; + break; + } lcd_resume_flag = 1; } else { lcd_driver->lcd_status = 0; lcd_resume_flag = 0; } - LCDPR("status: %d\n", lcd_driver->lcd_status); + LCDPR("status: %d, init_flag: %d\n", + lcd_driver->lcd_status, lcd_init_flag); } static int lcd_config_probe(struct platform_device *pdev) @@ -1549,6 +1575,7 @@ static int lcd_probe(struct platform_device *pdev) return -1; } lcd_driver->data = (struct lcd_data_s *)match->data; + lcd_driver->boot_ctrl = &lcd_boot_ctrl_config, strcpy(lcd_driver->version, LCD_DRV_VERSION); LCDPR("driver version: %s(%d-%s)\n", lcd_driver->version, @@ -1723,7 +1750,7 @@ static int __init lcd_boot_ctrl_setup(char *str) 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.lcd_init_level = 0x1 & (lcd_ctrl >> 19); + lcd_boot_ctrl_config.lcd_init_level = 0x3 & (lcd_ctrl >> 18); lcd_boot_ctrl_config.debug_print_flag = 0xf & (lcd_ctrl >> 20); lcd_boot_ctrl_config.debug_test_pattern = 0xf & (lcd_ctrl >> 24); lcd_boot_ctrl_config.debug_para_source = 0x3 & (lcd_ctrl >> 28); diff --git a/include/linux/amlogic/media/vout/lcd/lcd_vout.h b/include/linux/amlogic/media/vout/lcd/lcd_vout.h index e84d46b186f7..6d1e7fd302b4 100644 --- a/include/linux/amlogic/media/vout/lcd/lcd_vout.h +++ b/include/linux/amlogic/media/vout/lcd/lcd_vout.h @@ -433,11 +433,15 @@ struct lcd_power_ctrl_s { int power_off_step_max; /* internal use for debug */ }; +#define LCD_INIT_LEVEL_NORMAL 0 +#define LCD_INIT_LEVEL_PWR_OFF 1 +#define LCD_INIT_LEVEL_KERNEL_ON 2 + 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 lcd_init_level; //bit[19] + unsigned char lcd_init_level; //bit[19:18] unsigned char debug_print_flag; //bit[23:20] unsigned char debug_test_pattern; //bit[27:24] unsigned char debug_para_source;//bit[29:28] @@ -456,7 +460,6 @@ 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; @@ -499,6 +502,7 @@ struct aml_lcd_drv_s { struct lcd_config_s *lcd_config; struct vinfo_s *lcd_info; struct class *lcd_debug_class; + struct lcd_boot_ctrl_s *boot_ctrl; int fr_auto_policy; int fr_mode;