lcd: support enable lcd_if with different resume_type [1/1]

PD#SWPL-151191

Problem:
need support lcd_if early resume

Solution:
support lcd_if resume method by resume_type parameter

Verify:
ay301

Change-Id: If26fb11ac63ead8272c6e7f9c964483281398a20
Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
This commit is contained in:
Evoke Zhang
2025-03-04 04:03:07 +00:00
committed by gerrit autosubmit
parent 3f361fc75e
commit 6add4804e3
9 changed files with 87 additions and 17 deletions
+24 -4
View File
@@ -960,6 +960,7 @@ void bl_lcd_on_ctrl(struct aml_lcd_drv_s *pdrv)
{
struct aml_bl_drv_s *bdrv;
unsigned long long local_time[2];
unsigned int delay_ms;
if (!pdrv)
return;
@@ -972,7 +973,14 @@ void bl_lcd_on_ctrl(struct aml_lcd_drv_s *pdrv)
if (bdrv->probe_done == 0)
return;
if (pdrv->status & LCD_STATUS_BL_PRE_ON) {
bdrv->pre_on_time = local_time[0];
BLPR("[%d]: %s: pre_on\n", bdrv->index, __func__);
return;
}
if (bdrv->state & BL_STATE_BL_ON) {
bdrv->pre_on_time = 0;
BLPR("[%d]: %s already on\n", bdrv->index, __func__);
return;
}
@@ -982,13 +990,24 @@ void bl_lcd_on_ctrl(struct aml_lcd_drv_s *pdrv)
bdrv->on_request = 1;
/* lcd power on sequence control */
bl_pwm_ctrl_status_set(bdrv, 1);
if (bdrv->pre_on_time) {
local_time[1] = sched_clock();
delay_ms = lcd_do_div((local_time[1] - bdrv->pre_on_time), 1000000);
bdrv->pre_on_time = 0;
if (delay_ms < bdrv->bconf.power_on_delay)
delay_ms = bdrv->bconf.power_on_delay - delay_ms;
else
delay_ms = 0;
} else {
delay_ms = bdrv->bconf.power_on_delay;
}
if (bdrv->bconf.method < BL_CTRL_MAX) {
#ifdef BL_POWER_ON_DELAY_WORK
lcd_queue_delayed_on_work(&bdrv->delayed_on_work,
bdrv->bconf.power_on_delay);
lcd_queue_delayed_on_work(&bdrv->delayed_on_work, delay_ms);
#else
lcd_delay_ms(bdrv->bconf.power_on_delay);
if (delay_ms)
lcd_delay_ms(delay_ms);
bl_on_function(bdrv);
#endif
} else {
@@ -1014,6 +1033,8 @@ void bl_lcd_off_ctrl(struct aml_lcd_drv_s *pdrv)
if (bdrv->probe_done == 0)
return;
bdrv->pre_on_time = 0;
bdrv->on_request = 0;
if (!(bdrv->state & BL_STATE_BL_ON)) {
BLPR("[%d]: %s already off\n", bdrv->index, __func__);
return;
@@ -1021,7 +1042,6 @@ void bl_lcd_off_ctrl(struct aml_lcd_drv_s *pdrv)
if (lcd_debug_print_flag & LCD_DBG_PR_BL_NORMAL)
BLPR("[%d]: %s\n", bdrv->index, __func__);
bdrv->on_request = 0;
bdrv->state &= ~BL_STATE_LCD_ON;
mutex_lock(&bl_level_mutex);
bdrv->state |= BL_STATE_BL_INIT_ON;
+3 -1
View File
@@ -17,7 +17,8 @@
/* 20250121: initial version*/
/* 20250123: update lcd bootargs transfer by lrm */
/* 20250221: optimize vbyone interrupt handler */
#define LCD_DRV_VERSION "20250221"
/* 20250304: support lcd_if early on with resume_type control */
#define LCD_DRV_VERSION "20250304"
#define CFMT_RGB565 0x05
#define CFMT_RGB_6bit 0x06
@@ -287,6 +288,7 @@ void lcd_screen_restore(struct aml_lcd_drv_s *pdrv);
void lcd_venc_adj_vtotal(struct aml_lcd_drv_s *pdrv, unsigned int vtotal);
/* lcd driver */
void lcd_power_if_early_on(struct aml_lcd_drv_s *pdrv);
void lcd_power_screen_black(struct aml_lcd_drv_s *pdrv);
void lcd_power_screen_restore(struct aml_lcd_drv_s *pdrv);
void lcd_proc_time_clear(struct aml_lcd_drv_s *pdrv);
+1 -1
View File
@@ -343,7 +343,7 @@ int lcd_base_config_load_from_dts(struct aml_lcd_drv_s *pdrv)
ret = of_property_read_u32(np, "resume_type", &val);
if (ret)
pdrv->resume_type = 1; /* default workqueue */
pdrv->resume_type = 0x1; /* default workqueue */
else
pdrv->resume_type = (unsigned char)val;
+7 -5
View File
@@ -454,7 +454,7 @@ static int lcd_info_basic_print(struct aml_lcd_drv_s *pdrv, char *buf, int offse
"[%d]: driver version: %s\n"
"config_check_glb: %d, config_check_para: 0x%x, config_check_en: %d\n"
"panel_type: %s, chip: %d, mode: %s, status: 0x%x\n"
"viu_sel: %d, isr_cnt: %d, resume_type: %d\n"
"viu_sel: %d, isr_cnt: %d, resume_type: 0x%x\n"
"fr_auto_flag: 0x%x, fr_mode: %d, fr_duration: %d, frame_rate: %d\n"
"fr_auto_policy(global): %d, fr_auto_cus: 0x%x, custom_pinmux: %d\n"
"mute_state: %d(real %d), test_flag: 0x%x\n"
@@ -1747,8 +1747,10 @@ static ssize_t lcd_debug_resume_show(struct device *dev, struct device_attribute
{
struct aml_lcd_drv_s *pdrv = dev_get_drvdata(dev);
return sprintf(buf, "lcd resume type: %d(%s)\n",
pdrv->resume_type, pdrv->resume_type ? "workqueue" : "directly");
return sprintf(buf, "lcd resume type: 0x%x(%s %s)\n",
pdrv->resume_type,
(pdrv->resume_type & (1 << 0)) ? "workqueue" : "directly",
(pdrv->resume_type & (1 << 1)) ? "resume_if_on" : "late_resume_if_on");
}
static ssize_t lcd_debug_resume_store(struct device *dev, struct device_attribute *attr,
@@ -1758,13 +1760,13 @@ static ssize_t lcd_debug_resume_store(struct device *dev, struct device_attribut
struct aml_lcd_drv_s *pdrv = dev_get_drvdata(dev);
unsigned int temp = 1;
ret = kstrtouint(buf, 10, &temp);
ret = kstrtouint(buf, 16, &temp);
if (ret) {
LCDERR("invalid data\n");
return -EINVAL;
}
pdrv->resume_type = (unsigned char)temp;
LCDPR("set lcd resume flag: %d\n", pdrv->resume_type);
LCDPR("set lcd resume_type: 0x%x\n", pdrv->resume_type);
return count;
}
+10 -2
View File
@@ -999,10 +999,18 @@ static int lcd_resume(void *data)
if ((pdrv->status & LCD_STATUS_VMODE_ACTIVE) == 0)
return 0;
if (pdrv->status & LCD_STATUS_POWER)
if (pdrv->status & LCD_STATUS_POWER) {
if (pdrv->status & LCD_STATUS_BL_PRE_ON) {
pdrv->status &= ~LCD_STATUS_BL_PRE_ON;
#ifdef CONFIG_AMLOGIC_BACKLIGHT
bl_lcd_on_ctrl(pdrv);
#endif
lcd_power_screen_restore(pdrv);
}
return 0;
}
if (pdrv->resume_type) {
if (pdrv->resume_type & (1 << 0)) {
lcd_queue_work(&pdrv->late_resume_work);
} else {
mutex_lock(&lcd_power_mutex);
+12 -2
View File
@@ -631,6 +631,8 @@ static int lcd_set_current_vmode(enum vmode_e mode, void *data)
//workaround for drm resume
aml_lcd_notifier_call_chain(LCD_EVENT_PREPARE, (void *)pdrv);
pdrv->status |= LCD_STATUS_PREPARE;
lcd_power_if_early_on(pdrv);
}
pdrv->status |= LCD_STATUS_VMODE_ACTIVE;
LCDPR("[%d]: fixed timing, exit vmode change\n", pdrv->index);
@@ -1059,10 +1061,18 @@ static int lcd_resume(void *data)
if ((pdrv->status & LCD_STATUS_VMODE_ACTIVE) == 0)
return 0;
if (pdrv->status & LCD_STATUS_POWER)
if (pdrv->status & LCD_STATUS_POWER) {
if (pdrv->status & LCD_STATUS_BL_PRE_ON) {
pdrv->status &= ~LCD_STATUS_BL_PRE_ON;
#ifdef CONFIG_AMLOGIC_BACKLIGHT
bl_lcd_on_ctrl(pdrv);
#endif
lcd_power_screen_restore(pdrv);
}
return 0;
}
if (pdrv->resume_type) {
if (pdrv->resume_type & (1 << 0)) {
lcd_queue_work(&pdrv->late_resume_work);
} else {
mutex_lock(&lcd_power_mutex);
+24 -1
View File
@@ -911,6 +911,23 @@ static void lcd_power_if_off(struct aml_lcd_drv_s *pdrv)
lcd_power_ctrl(pdrv, 0);
}
void lcd_power_if_early_on(struct aml_lcd_drv_s *pdrv)
{
if ((pdrv->resume_type & (1 << 1)) == 0)
return;
LCDPR("[%d]: %s\n", pdrv->index, __func__);
if ((pdrv->resume_type & (1 << 0))) {
pdrv->status |= LCD_STATUS_BL_PRE_ON;
lcd_queue_work(&pdrv->late_resume_work);
} else {
LCDPR("[%d]: directly if_early_on\n", pdrv->index);
pdrv->status |= (LCD_STATUS_POWER | LCD_STATUS_BL_PRE_ON);
aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, (void *)pdrv);
lcd_if_enable_retry(pdrv);
}
}
void lcd_power_screen_black(struct aml_lcd_drv_s *pdrv)
{
unsigned long flags = 0;
@@ -949,6 +966,8 @@ void lcd_power_screen_restore(struct aml_lcd_drv_s *pdrv)
if (!pdrv || pdrv->probe_done == 0)
return;
if ((pdrv->status & LCD_STATUS_BL_PRE_ON))
return;
local_time[0] = sched_clock();
reinit_completion(&pdrv->vsync_done);
@@ -2809,13 +2828,17 @@ static int lcd_resume(struct platform_device *pdev)
if (!pdrv)
return 0;
if ((pdrv->status & LCD_STATUS_VMODE_ACTIVE) == 0)
if ((pdrv->status & LCD_STATUS_VMODE_ACTIVE) == 0) {
if (lcd_debug_print_flag & LCD_DBG_PR_NORMAL)
LCDPR("[%d]: %s: vmode inactive, exit\n", pdrv->index, __func__);
return 0;
}
mutex_lock(&lcd_power_mutex);
LCDPR("[%d]: %s\n", pdrv->index, __func__);
aml_lcd_notifier_call_chain(LCD_EVENT_PREPARE, (void *)pdrv);
pdrv->status |= LCD_STATUS_PREPARE;
lcd_power_if_early_on(pdrv);
LCDPR("[%d]: %s finished\n", pdrv->index, __func__);
mutex_unlock(&lcd_power_mutex);
@@ -239,6 +239,8 @@ struct aml_bl_drv_s {
struct pinctrl *pin;
unsigned int pinmux_flag;
unsigned long long pre_on_time;
};
struct bl_pwm_init_config_s {
@@ -788,6 +788,7 @@ struct lcd_resource_s {
#define LCD_STATUS_VMODE_ACTIVE BIT(6) //control status
#define LCD_STATUS_TCON_RDY BIT(8)
#define LCD_STATUS_BL_PRE_ON BIT(12)
#define LCD_VIU_SEL_NONE 0
@@ -888,7 +889,9 @@ struct aml_lcd_drv_s {
unsigned char key_valid;
unsigned char clk_path; /* 0=hpll, 1=gp0_pll */
unsigned char config_load;
unsigned char resume_type; /* 0=directly, 1=workqueue */
/*bit[1]: 0=lcd_if late_resume(default), 1=lcd_if resume */
/*bit[0]: 0=directly, 1=workqueue(default) */
unsigned char resume_type;
unsigned char init_flag; /* 0=none, 1=power on request */
unsigned char auto_test;
unsigned char test_state;