From 882ed0addc65c5e26bf08d8bc875d1f8356dbe4f Mon Sep 17 00:00:00 2001 From: Evoke Zhang Date: Tue, 5 Jun 2018 10:13:43 +0800 Subject: [PATCH] lcd: avoid frequently reset panel without vbyone connected PD#167723: lcd: avoid frequently reset panel without vbyone connected Change-Id: I1ba64f6f38a505942d8303ddd564abddab131c21 Signed-off-by: Evoke Zhang --- drivers/amlogic/media/vout/backlight/aml_bl.c | 7 ++- .../amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c | 8 +-- drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c | 61 +++++++++++++--------- drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c | 8 +-- drivers/amlogic/media/vout/lcd/lcd_vout.c | 18 ++----- include/linux/amlogic/media/vout/lcd/lcd_vout.h | 1 - 6 files changed, 45 insertions(+), 58 deletions(-) diff --git a/drivers/amlogic/media/vout/backlight/aml_bl.c b/drivers/amlogic/media/vout/backlight/aml_bl.c index e55c2bb..06e7b87 100644 --- a/drivers/amlogic/media/vout/backlight/aml_bl.c +++ b/drivers/amlogic/media/vout/backlight/aml_bl.c @@ -2141,10 +2141,9 @@ static int aml_bl_on_notifier(struct notifier_block *nb, &bl_drv->bl_delayed_work, msecs_to_jiffies(bconf->power_on_delay)); } else { - BLPR("Warning: no bl workqueue\n"); - if (bconf->power_on_delay) - msleep(bconf->power_on_delay); - aml_bl_on_function(); + schedule_delayed_work( + &bl_drv->bl_delayed_work, + msecs_to_jiffies(bconf->power_on_delay)); } } else BLERR("wrong backlight control method\n"); diff --git a/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c b/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c index 4819a91..e88b484 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c @@ -343,13 +343,7 @@ static int lcd_resume(void) queue_work(lcd_drv->workqueue, &(lcd_drv->lcd_resume_work)); } else { - mutex_lock(&lcd_drv->power_mutex); - LCDPR("Warning: no lcd workqueue\n"); - lcd_resume_flag = 1; - aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL); - lcd_if_enable_retry(lcd_drv->lcd_config); - LCDPR("%s finished\n", __func__); - mutex_unlock(&lcd_drv->power_mutex); + schedule_work(&(lcd_drv->lcd_resume_work)); } } else { mutex_lock(&lcd_drv->power_mutex); diff --git a/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c b/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c index 8f5d21c..2da4b90 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c @@ -39,6 +39,8 @@ #include "../lcd_reg.h" #include "../lcd_common.h" +static struct delayed_work lcd_vx1_stable_delayed_work; + static int vx1_fsm_acq_st; #define VX1_TRAINING_TIMEOUT 60 /* vsync cnt */ @@ -797,9 +799,10 @@ static void lcd_vbyone_wait_hpd(struct lcd_config_s *pconf) } else { LCDPR("%s: hpd=%d, i=%d\n", __func__, ((lcd_vcbus_read(VBO_STATUS_L) >> 6) & 0x1), i); + /* force low only actived for actual hpd is low */ + lcd_vcbus_setb(VBO_INSGN_CTRL, 1, 2, 2); } - lcd_vcbus_setb(VBO_INSGN_CTRL, 1, 2, 2); if ((pconf->lcd_control.vbyone_config->ctrl_flag) & 0x2) { LCDPR("ctrl_flag for hpd_data delay\n"); msleep(pconf->lcd_control.vbyone_config->hpd_data_delay); @@ -893,7 +896,7 @@ static void lcd_vx1_timeout_reset(struct work_struct *p_work) vx1_timeout_reset_flag = 0; } -#define VSYNC_CNT_VX1_RESET 5 +#define VSYNC_CNT_VX1_RESET 5 #define VSYNC_CNT_VX1_STABLE 20 static unsigned short vsync_cnt = VSYNC_CNT_VX1_STABLE; static irqreturn_t lcd_vbyone_vsync_isr(int irq, void *dev_id) @@ -927,7 +930,7 @@ static irqreturn_t lcd_vbyone_vsync_isr(int irq, void *dev_id) vsync_cnt = VSYNC_CNT_VX1_STABLE; else vsync_cnt++; - } + } } else if (vx1_conf->vsync_intr_en == 2) { if (vsync_cnt >= 5) { vsync_cnt = 0; @@ -939,31 +942,32 @@ static irqreturn_t lcd_vbyone_vsync_isr(int irq, void *dev_id) lcd_vcbus_setb(VBO_INTR_STATE_CTRL, 0, 15, 1); lcd_vcbus_setb(VBO_INTR_STATE_CTRL, 1, 15, 1); - } + } } else vsync_cnt++; } else { - if (vx1_training_wait_cnt >= VX1_TRAINING_TIMEOUT) { - if ((lcd_vcbus_read(VBO_STATUS_L) & 0x3f) != 0x20) { - if (vx1_timeout_reset_flag == 0) { - vx1_timeout_reset_flag = 1; - if (lcd_drv->workqueue) { - queue_work(lcd_drv->workqueue, - &lcd_vx1_reset_work); - } else { - schedule_work(&lcd_vx1_reset_work); + if (vx1_training_wait_cnt >= VX1_TRAINING_TIMEOUT) { + if ((lcd_vcbus_read(VBO_STATUS_L) & 0x3f) != 0x20) { + if (vx1_timeout_reset_flag == 0) { + vx1_timeout_reset_flag = 1; + if (lcd_drv->workqueue) { + queue_work(lcd_drv->workqueue, + &lcd_vx1_reset_work); + } else { + schedule_work( + &lcd_vx1_reset_work); + } + } + } else { + vx1_training_stable_cnt++; + if (vx1_training_stable_cnt >= 5) { + vx1_training_wait_cnt = 0; + vx1_training_stable_cnt = 0; } } } else { - vx1_training_stable_cnt++; - if (vx1_training_stable_cnt >= 5) { - vx1_training_wait_cnt = 0; - vx1_training_stable_cnt = 0; - } + vx1_training_wait_cnt++; } - } else { - vx1_training_wait_cnt++; - } } return IRQ_HANDLED; @@ -1304,9 +1308,14 @@ int lcd_tv_driver_init(void) lcd_vbyone_wait_hpd(pconf); lcd_vbyone_phy_set(pconf, 1); lcd_vx1_intr_request = 1; - queue_delayed_work(lcd_drv->workqueue, - &lcd_drv->lcd_vx1_delayed_work, - msecs_to_jiffies(LCD_VX1_WAIT_STABLE_DELAY)); + if (lcd_drv->workqueue) { + queue_delayed_work(lcd_drv->workqueue, + &lcd_vx1_stable_delayed_work, + msecs_to_jiffies(LCD_VX1_WAIT_STABLE_DELAY)); + } else { + schedule_delayed_work(&lcd_vx1_stable_delayed_work, + msecs_to_jiffies(LCD_VX1_WAIT_STABLE_DELAY)); + } break; default: break; @@ -1425,7 +1434,7 @@ int lcd_vbyone_interrupt_up(void) INIT_WORK(&lcd_vx1_reset_work, lcd_vx1_timeout_reset); - INIT_DELAYED_WORK(&lcd_drv->lcd_vx1_delayed_work, + INIT_DELAYED_WORK(&lcd_vx1_stable_delayed_work, lcd_vx1_wait_stable_delayed); if (!lcd_drv->res_vsync_irq) { @@ -1482,7 +1491,7 @@ void lcd_vbyone_interrupt_down(void) free_irq(lcd_drv->res_vx1_irq->start, (void *)"vbyone"); free_irq(lcd_drv->res_vsync_irq->start, (void *)"vbyone_vsync"); cancel_work_sync(&lcd_vx1_reset_work); - cancel_delayed_work(&lcd_drv->lcd_vx1_delayed_work); + cancel_delayed_work(&lcd_vx1_stable_delayed_work); if (lcd_debug_print_flag) LCDPR("free vbyone irq\n"); diff --git a/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c b/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c index 696de28..c38b340 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c @@ -597,13 +597,7 @@ static int lcd_resume(void) queue_work(lcd_drv->workqueue, &(lcd_drv->lcd_resume_work)); } else { - mutex_lock(&lcd_drv->power_mutex); - LCDPR("Warning: no lcd workqueue\n"); - lcd_resume_flag = 1; - aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL); - lcd_if_enable_retry(lcd_drv->lcd_config); - LCDPR("%s finished\n", __func__); - mutex_unlock(&lcd_drv->power_mutex); + schedule_work(&(lcd_drv->lcd_resume_work)); } } else { mutex_lock(&lcd_drv->power_mutex); diff --git a/drivers/amlogic/media/vout/lcd/lcd_vout.c b/drivers/amlogic/media/vout/lcd/lcd_vout.c index 4c7a9c6..7bc8f45 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_vout.c +++ b/drivers/amlogic/media/vout/lcd/lcd_vout.c @@ -906,13 +906,9 @@ static int lcd_config_probe(struct platform_device *pdev) &lcd_driver->lcd_probe_delayed_work, msecs_to_jiffies(2000)); } else { - LCDPR("Warning: no lcd_probe_delayed workqueue\n"); - ret = lcd_mode_probe(lcd_driver->dev); - if (ret) { - kfree(lcd_driver); - lcd_driver = NULL; - LCDERR("probe exit\n"); - } + schedule_delayed_work( + &lcd_driver->lcd_probe_delayed_work, + msecs_to_jiffies(2000)); } } else { ret = lcd_mode_probe(lcd_driver->dev); @@ -1044,6 +1040,7 @@ static int lcd_probe(struct platform_device *pdev) static int lcd_remove(struct platform_device *pdev) { cancel_delayed_work(&lcd_driver->lcd_probe_delayed_work); + cancel_work_sync(&(lcd_driver->lcd_resume_work)); if (lcd_driver->workqueue) destroy_workqueue(lcd_driver->workqueue); @@ -1071,12 +1068,7 @@ static int lcd_resume(struct platform_device *pdev) queue_work(lcd_driver->workqueue, &(lcd_driver->lcd_resume_work)); } else { - mutex_lock(&lcd_driver->power_mutex); - LCDPR("Warning: no lcd workqueue\n"); - aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL); - lcd_if_enable_retry(lcd_driver->lcd_config); - LCDPR("%s finished\n", __func__); - mutex_unlock(&lcd_driver->power_mutex); + schedule_work(&(lcd_driver->lcd_resume_work)); } } else { mutex_lock(&lcd_driver->power_mutex); diff --git a/include/linux/amlogic/media/vout/lcd/lcd_vout.h b/include/linux/amlogic/media/vout/lcd/lcd_vout.h index a9ccd60..c7b0441 100644 --- a/include/linux/amlogic/media/vout/lcd/lcd_vout.h +++ b/include/linux/amlogic/media/vout/lcd/lcd_vout.h @@ -432,7 +432,6 @@ struct aml_lcd_drv_s { struct workqueue_struct *workqueue; struct delayed_work lcd_probe_delayed_work; - struct delayed_work lcd_vx1_delayed_work; struct work_struct lcd_resume_work; struct resource *res_vsync_irq; struct resource *res_vx1_irq; -- 2.7.4