diff --git a/drivers/amlogic/media/vout/lcd/lcd_common.h b/drivers/amlogic/media/vout/lcd/lcd_common.h index 189b7d0b298c..9a19c507e95b 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_common.h +++ b/drivers/amlogic/media/vout/lcd/lcd_common.h @@ -24,11 +24,11 @@ /* 20170505: add a113 support to linux4.9 */ /* 20170905: fix coverity errors */ -#define LCD_DRV_VERSION "20171201" +/* 20180122: support txlx, optimize lcd noitfier event */ +#define LCD_DRV_VERSION "20180122" #define VPP_OUT_SATURATE (1 << 0) -extern struct mutex lcd_power_mutex; extern struct mutex lcd_vout_mutex; extern unsigned char lcd_resume_flag; extern int lcd_vout_serve_bypass; diff --git a/drivers/amlogic/media/vout/lcd/lcd_debug.c b/drivers/amlogic/media/vout/lcd/lcd_debug.c index e688715b7554..8d66ecdb6601 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_debug.c +++ b/drivers/amlogic/media/vout/lcd/lcd_debug.c @@ -952,7 +952,7 @@ static void lcd_mute_setting(unsigned char flag) } } -static void lcd_test_check(void) +static void lcd_screen_restore(void) { unsigned int h_active, video_on_pixel; struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); @@ -983,6 +983,11 @@ static void lcd_test_check(void) } } +static void lcd_screen_black(void) +{ + lcd_mute_setting(1); +} + static void lcd_vinfo_update(void) { struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); @@ -1057,6 +1062,26 @@ static void lcd_debug_clk_change(unsigned int pclk) &lcd_drv->lcd_info->mode); } +static void lcd_power_interface_ctrl(int state) +{ + struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); + + mutex_lock(&lcd_drv->power_mutex); + LCDPR("%s: %d\n", __func__, state); + if (state) { + if (lcd_drv->lcd_status & LCD_STATUS_ENCL_ON) { + aml_lcd_notifier_call_chain( + LCD_EVENT_IF_POWER_ON, NULL); + } else { + LCDERR("%s: can't power on when controller is off\n", + __func__); + } + } else { + aml_lcd_notifier_call_chain(LCD_EVENT_IF_POWER_OFF, NULL); + } + mutex_unlock(&lcd_drv->power_mutex); +} + static ssize_t lcd_debug_store(struct class *class, struct class_attribute *attr, const char *buf, size_t count) { @@ -1254,16 +1279,7 @@ static ssize_t lcd_debug_store(struct class *class, case 'p': /* power */ ret = sscanf(buf, "power %d", &temp); if (ret == 1) { - mutex_lock(&lcd_power_mutex); - LCDPR("power: %d\n", temp); - if (temp) { - aml_lcd_notifier_call_chain( - LCD_EVENT_IF_POWER_ON, NULL); - } else { - aml_lcd_notifier_call_chain( - LCD_EVENT_IF_POWER_OFF, NULL); - } - mutex_unlock(&lcd_power_mutex); + lcd_power_interface_ctrl(temp); } else { LCDERR("invalid data\n"); return -EINVAL; @@ -1450,6 +1466,7 @@ static ssize_t lcd_debug_enable_show(struct class *class, static ssize_t lcd_debug_enable_store(struct class *class, struct class_attribute *attr, const char *buf, size_t count) { + struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); int ret = 0; unsigned int temp = 1; @@ -1459,13 +1476,13 @@ static ssize_t lcd_debug_enable_store(struct class *class, return -EINVAL; } if (temp) { - mutex_lock(&lcd_power_mutex); + mutex_lock(&lcd_drv->power_mutex); aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL); - mutex_unlock(&lcd_power_mutex); + mutex_unlock(&lcd_drv->power_mutex); } else { - mutex_lock(&lcd_power_mutex); + mutex_lock(&lcd_drv->power_mutex); aml_lcd_notifier_call_chain(LCD_EVENT_POWER_OFF, NULL); - mutex_unlock(&lcd_power_mutex); + mutex_unlock(&lcd_drv->power_mutex); } return count; @@ -2673,36 +2690,14 @@ static struct class_attribute lcd_phy_debug_class_attrs[] = { lcd_phy_debug_show, lcd_phy_debug_store), }; -static int lcd_black_screen_notifier(struct notifier_block *nb, - unsigned long event, void *data) -{ - if ((event & LCD_EVENT_BLACK_SCREEN) == 0) - return NOTIFY_DONE; - if (lcd_debug_print_flag) - LCDPR("%s: 0x%lx\n", __func__, event); - - lcd_mute_setting(1); - - return NOTIFY_OK; -} - -static struct notifier_block lcd_black_screen_nb = { - .notifier_call = lcd_black_screen_notifier, - .priority = LCD_PRIORITY_BLACK_SCREEN, -}; - int lcd_class_creat(void) { int i; - int ret; struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); int type; - ret = aml_lcd_notifier_register(&lcd_black_screen_nb); - if (ret) - LCDERR("register lcd_black_screen_notifier failed\n"); - - lcd_drv->lcd_test_pattern_restore = lcd_test_check; + lcd_drv->lcd_screen_restore = lcd_screen_restore; + lcd_drv->lcd_screen_black = lcd_screen_black; lcd_drv->lcd_debug_class = class_create(THIS_MODULE, "lcd"); if (IS_ERR(lcd_drv->lcd_debug_class)) { diff --git a/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_drv.c b/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_drv.c index e6554b912cc1..519c4f4dd532 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_drv.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_drv.c @@ -873,7 +873,26 @@ void lcd_tablet_driver_init_pre(void) lcd_clk_set(pconf); lcd_venc_set(pconf); lcd_tcon_set(pconf); - lcd_drv->lcd_test_pattern_restore(); + + lcd_vcbus_write(VENC_INTCTRL, 0x200); + + if (lcd_debug_print_flag) + LCDPR("%s finished\n", __func__); +} + +void lcd_tablet_driver_disable_post(void) +{ + lcd_vcbus_write(ENCL_VIDEO_EN, 0); /* disable encl */ + + lcd_clk_disable(); + lcd_clk_gate_switch(0); +#ifdef CONFIG_AMLOGIC_VPU + switch_vpu_mem_pd_vmod(VPU_VENCL, VPU_MEM_POWER_DOWN); + release_vpu_clk_vmod(VPU_VENCL); +#endif + + if (lcd_debug_print_flag) + LCDPR("%s finished\n", __func__); } int lcd_tablet_driver_init(void) @@ -911,8 +930,6 @@ int lcd_tablet_driver_init(void) break; } - lcd_vcbus_write(VENC_INTCTRL, 0x200); - if (lcd_debug_print_flag) LCDPR("%s finished\n", __func__); @@ -952,88 +969,7 @@ void lcd_tablet_driver_disable(void) break; } - lcd_vcbus_write(ENCL_VIDEO_EN, 0); /* disable encl */ - - lcd_clk_disable(); - lcd_clk_gate_switch(0); -#ifdef CONFIG_AMLOGIC_VPU - switch_vpu_mem_pd_vmod(VPU_VENCL, VPU_MEM_POWER_DOWN); - release_vpu_clk_vmod(VPU_VENCL); -#endif - if (lcd_debug_print_flag) LCDPR("%s finished\n", __func__); } -void lcd_tablet_driver_tiny_enable(void) -{ - struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); - struct lcd_config_s *pconf; - int ret; - - pconf = lcd_drv->lcd_config; - ret = lcd_type_supported(pconf); - if (ret) - return; - - /* init driver */ - switch (pconf->lcd_basic.lcd_type) { - case LCD_TTL: - lcd_ttl_control_set(pconf); - lcd_ttl_pinmux_set(1); - break; - case LCD_LVDS: - lcd_lvds_control_set(pconf); - lcd_lvds_phy_set(pconf, 1); - break; - case LCD_VBYONE: - lcd_vbyone_pinmux_set(1); - lcd_vbyone_control_set(pconf); - lcd_vx1_wait_hpd(); - lcd_vbyone_phy_set(pconf, 1); - lcd_tablet_vbyone_wait_stable(); - case LCD_MIPI: - lcd_mipi_phy_set(pconf, 1); - lcd_mipi_control_set(pconf, 1); - break; - default: - break; - } - - LCDPR("enable driver\n"); -} - -void lcd_tablet_driver_tiny_disable(void) -{ - struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); - struct lcd_config_s *pconf; - int ret; - - LCDPR("disable driver\n"); - pconf = lcd_drv->lcd_config; - ret = lcd_type_supported(pconf); - if (ret) - return; - - switch (pconf->lcd_basic.lcd_type) { - case LCD_TTL: - lcd_ttl_pinmux_set(0); - break; - case LCD_LVDS: - lcd_lvds_phy_set(pconf, 0); - lcd_lvds_disable(); - break; - case LCD_VBYONE: - lcd_vbyone_phy_set(pconf, 0); - lcd_vbyone_pinmux_set(0); - lcd_vbyone_disable(); - case LCD_MIPI: - mipi_dsi_link_off(pconf); - lcd_mipi_phy_set(pconf, 0); - lcd_mipi_control_set(pconf, 0); - break; - default: - break; - } -} - 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 4a16e4944fe1..9689b6a09a9b 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c @@ -293,11 +293,13 @@ static int lcd_get_vframe_rate_policy(void) #ifdef CONFIG_PM static int lcd_suspend(void) { - mutex_lock(&lcd_power_mutex); + struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); + + mutex_lock(&lcd_drv->power_mutex); aml_lcd_notifier_call_chain(LCD_EVENT_POWER_OFF, NULL); lcd_resume_flag = 0; LCDPR("%s finished\n", __func__); - mutex_unlock(&lcd_power_mutex); + mutex_unlock(&lcd_drv->power_mutex); return 0; } @@ -313,20 +315,20 @@ 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"); - mutex_lock(&lcd_power_mutex); lcd_resume_flag = 1; aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL); LCDPR("%s finished\n", __func__); - mutex_unlock(&lcd_power_mutex); + mutex_unlock(&lcd_drv->power_mutex); } } else { + mutex_lock(&lcd_drv->power_mutex); LCDPR("directly lcd late resume\n"); - mutex_lock(&lcd_power_mutex); lcd_resume_flag = 1; aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL); LCDPR("%s finished\n", __func__); - mutex_unlock(&lcd_power_mutex); + mutex_unlock(&lcd_drv->power_mutex); } return 0; @@ -1292,10 +1294,9 @@ int lcd_tablet_probe(struct device *dev) lcd_drv->version = LCD_DRV_VERSION; lcd_drv->vout_server_init = lcd_tablet_vout_server_init; lcd_drv->driver_init_pre = lcd_tablet_driver_init_pre; + lcd_drv->driver_disable_post = lcd_tablet_driver_disable_post; lcd_drv->driver_init = lcd_tablet_driver_init; lcd_drv->driver_disable = lcd_tablet_driver_disable; - lcd_drv->driver_tiny_enable = lcd_tablet_driver_tiny_enable; - lcd_drv->driver_tiny_disable = lcd_tablet_driver_tiny_disable; lcd_get_config(lcd_drv->lcd_config, dev); diff --git a/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.h b/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.h index 6c435ddd356b..e678f85859d4 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.h +++ b/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.h @@ -21,9 +21,8 @@ extern void lcd_tablet_config_update(struct lcd_config_s *pconf); extern void lcd_tablet_config_post_update(struct lcd_config_s *pconf); extern void lcd_tablet_driver_init_pre(void); +extern void lcd_tablet_driver_disable_post(void); extern int lcd_tablet_driver_init(void); extern void lcd_tablet_driver_disable(void); -extern void lcd_tablet_driver_tiny_enable(void); -extern void lcd_tablet_driver_tiny_disable(void); #endif 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 137af6bd049c..1aa138b736b9 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c @@ -837,10 +837,7 @@ static void lcd_vx1_timeout_reset(unsigned long data) return; LCDPR("%s\n", __func__); - if (vx1_timeout_reset_flag == 1) - lcd_drv->module_reset(); - else - lcd_drv->module_tiny_reset(); + lcd_drv->module_reset(); if (lcd_drv->lcd_config->lcd_control.vbyone_config->intr_en) lcd_vx1_hold_reset(); vx1_timeout_reset_flag = 0; @@ -855,7 +852,7 @@ static irqreturn_t lcd_vbyone_vsync_isr(int irq, void *dev_id) struct vbyone_config_s *vx1_conf; vx1_conf = lcd_drv->lcd_config->lcd_control.vbyone_config; - if (lcd_drv->lcd_status == 0) + if ((lcd_drv->lcd_status & LCD_STATUS_IF_ON) == 0) return IRQ_HANDLED; if (lcd_vcbus_read(VBO_STATUS_L) & 0x40) /* hpd detect */ return IRQ_HANDLED; @@ -1240,7 +1237,26 @@ void lcd_tv_driver_init_pre(void) lcd_clk_set(pconf); lcd_venc_set(pconf); lcd_tcon_set(pconf); - lcd_drv->lcd_test_pattern_restore(); + + lcd_vcbus_write(VENC_INTCTRL, 0x200); + + if (lcd_debug_print_flag) + LCDPR("%s finished\n", __func__); +} + +void lcd_tv_driver_disable_post(void) +{ + lcd_vcbus_write(ENCL_VIDEO_EN, 0); /* disable encl */ + + lcd_clk_disable(); + lcd_clk_gate_switch(0); +#ifdef CONFIG_AMLOGIC_VPU + switch_vpu_mem_pd_vmod(VPU_VENCL, VPU_MEM_POWER_DOWN); + release_vpu_clk_vmod(VPU_VENCL); +#endif + + if (lcd_debug_print_flag) + LCDPR("%s finished\n", __func__); } int lcd_tv_driver_init(void) @@ -1266,15 +1282,13 @@ int lcd_tv_driver_init(void) 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)); + &lcd_drv->lcd_vx1_delayed_work, + msecs_to_jiffies(LCD_VX1_WAIT_STABLE_DELAY)); break; default: break; } - lcd_vcbus_write(VENC_INTCTRL, 0x200); - if (lcd_debug_print_flag) LCDPR("%s finished\n", __func__); return 0; @@ -1310,15 +1324,6 @@ void lcd_tv_driver_disable(void) break; } - lcd_vcbus_write(ENCL_VIDEO_EN, 0); /* disable encl */ - - lcd_clk_disable(); - lcd_clk_gate_switch(0); -#ifdef CONFIG_AMLOGIC_VPU - switch_vpu_mem_pd_vmod(VPU_VENCL, VPU_MEM_POWER_DOWN); - release_vpu_clk_vmod(VPU_VENCL); -#endif - if (lcd_debug_print_flag) LCDPR("%s finished\n", __func__); } @@ -1341,18 +1346,11 @@ int lcd_tv_driver_change(void) request_vpu_clk_vmod(pconf->lcd_timing.lcd_clk, VPU_VENCL); #endif - if (lcd_drv->lcd_status == 0) { - /* only change parameters when panel is off */ - switch (pconf->lcd_timing.clk_change) { - case LCD_CLK_PLL_CHANGE: - lcd_clk_generate_parameter(pconf); - break; - default: - break; + if (lcd_drv->lcd_status & LCD_STATUS_ENCL_ON) { + if (pconf->lcd_basic.lcd_type == LCD_VBYONE) { + if (lcd_drv->lcd_status & LCD_STATUS_IF_ON) + lcd_vbyone_interrupt_enable(0); } - } else { - if (pconf->lcd_basic.lcd_type == LCD_VBYONE) - lcd_vbyone_interrupt_enable(0); switch (pconf->lcd_timing.clk_change) { case LCD_CLK_PLL_CHANGE: @@ -1367,8 +1365,19 @@ int lcd_tv_driver_change(void) } lcd_venc_change(pconf); - if (pconf->lcd_basic.lcd_type == LCD_VBYONE) - lcd_vbyone_wait_stable(); + if (pconf->lcd_basic.lcd_type == LCD_VBYONE) { + if (lcd_drv->lcd_status & LCD_STATUS_IF_ON) + lcd_vbyone_wait_stable(); + } + } else { + /* only change parameters when panel is off */ + switch (pconf->lcd_timing.clk_change) { + case LCD_CLK_PLL_CHANGE: + lcd_clk_generate_parameter(pconf); + break; + default: + break; + } } if (lcd_debug_print_flag) @@ -1376,69 +1385,10 @@ int lcd_tv_driver_change(void) return 0; } -void lcd_tv_driver_tiny_enable(void) -{ - struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); - struct lcd_config_s *pconf; - int ret; - - pconf = lcd_drv->lcd_config; - ret = lcd_type_supported(pconf); - if (ret) - return; - - switch (pconf->lcd_basic.lcd_type) { - case LCD_LVDS: - lcd_lvds_control_set(pconf); - lcd_lvds_phy_set(pconf, 1); - break; - case LCD_VBYONE: - lcd_vbyone_pinmux_set(1); - lcd_vbyone_control_set(pconf); - lcd_vbyone_wait_hpd(pconf); - lcd_vbyone_phy_set(pconf, 1); - lcd_vbyone_power_on_wait_stable(pconf); - break; - default: - break; - } - - LCDPR("enable driver\n"); -} - -void lcd_tv_driver_tiny_disable(void) -{ - struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); - struct lcd_config_s *pconf; - int ret; - - LCDPR("disable driver\n"); - pconf = lcd_drv->lcd_config; - ret = lcd_type_supported(pconf); - if (ret) - return; - - switch (pconf->lcd_basic.lcd_type) { - case LCD_LVDS: - lcd_lvds_phy_set(pconf, 0); - lcd_lvds_disable(); - break; - case LCD_VBYONE: - lcd_vbyone_interrupt_enable(0); - lcd_vbyone_phy_set(pconf, 0); - lcd_vbyone_pinmux_set(0); - lcd_vbyone_disable(); - break; - default: - break; - } -} - #define VBYONE_IRQF IRQF_SHARED /* IRQF_DISABLED */ /* IRQF_SHARED */ int lcd_vbyone_interrupt_up(void) { - int ret = 0; unsigned int viu_vsync_irq = 0, venc_vx1_irq = 0; struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); @@ -1450,42 +1400,39 @@ int lcd_vbyone_interrupt_up(void) lcd_vx1_intr_request = 0; lcd_encl_clk_err_cnt = 0; - tasklet_init(&lcd_vx1_reset_tasklet, lcd_vx1_timeout_reset, - 123); + tasklet_init(&lcd_vx1_reset_tasklet, lcd_vx1_timeout_reset, 123); INIT_DELAYED_WORK(&lcd_drv->lcd_vx1_delayed_work, lcd_vx1_wait_stable_delayed); if (!lcd_drv->res_vsync_irq) { - ret = -ENODEV; - goto err; - } else { - viu_vsync_irq = lcd_drv->res_vsync_irq->start; - LCDPR("viu_vsync_irq: %d\n", viu_vsync_irq); + LCDERR("res_vsync_irq is null\n"); + return -1; + } + viu_vsync_irq = lcd_drv->res_vsync_irq->start; + LCDPR("viu_vsync_irq: %d\n", viu_vsync_irq); - if (request_irq(viu_vsync_irq, lcd_vbyone_vsync_isr, - IRQF_SHARED, "vbyone_vsync", (void *)"vbyone_vsync")) - LCDERR("can't request viu_vsync_irq\n"); - else { - if (lcd_debug_print_flag) - LCDPR("request viu_vsync_irq successful\n"); - } + if (request_irq(viu_vsync_irq, lcd_vbyone_vsync_isr, + IRQF_SHARED, "vbyone_vsync", (void *)"vbyone_vsync")) + LCDERR("can't request viu_vsync_irq\n"); + else { + if (lcd_debug_print_flag) + LCDPR("request viu_vsync_irq successful\n"); } if (!lcd_drv->res_vx1_irq) { - ret = -ENODEV; - goto err; - } else { - venc_vx1_irq = lcd_drv->res_vx1_irq->start; - LCDPR("venc_vx1_irq: %d\n", venc_vx1_irq); + LCDERR("res_vx1_irq is null\n"); + return -1; + } + venc_vx1_irq = lcd_drv->res_vx1_irq->start; + LCDPR("venc_vx1_irq: %d\n", venc_vx1_irq); - if (request_irq(venc_vx1_irq, lcd_vbyone_interrupt_handler, 0, - "vbyone", (void *)"vbyone")) - LCDERR("can't request venc_vx1_irq\n"); - else { - if (lcd_debug_print_flag) - LCDPR("request venc_vx1_irq successful\n"); - } + if (request_irq(venc_vx1_irq, lcd_vbyone_interrupt_handler, 0, + "vbyone", (void *)"vbyone")) + LCDERR("can't request venc_vx1_irq\n"); + else { + if (lcd_debug_print_flag) + LCDPR("request venc_vx1_irq successful\n"); } lcd_vx1_intr_request = 1; @@ -1500,10 +1447,6 @@ int lcd_vbyone_interrupt_up(void) LCDPR("add vbyone hpll timer handler\n"); return 0; - -err: - return -ENODEV; - } void lcd_vbyone_interrupt_down(void) 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 b58b5771cbfd..6889fc3a7c94 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c @@ -521,11 +521,13 @@ static int lcd_get_vframe_rate_policy(void) #ifdef CONFIG_PM static int lcd_suspend(void) { - mutex_lock(&lcd_power_mutex); + struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); + + mutex_lock(&lcd_drv->power_mutex); aml_lcd_notifier_call_chain(LCD_EVENT_POWER_OFF, NULL); lcd_resume_flag = 0; LCDPR("%s finished\n", __func__); - mutex_unlock(&lcd_power_mutex); + mutex_unlock(&lcd_drv->power_mutex); return 0; } @@ -541,20 +543,20 @@ 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"); - mutex_lock(&lcd_power_mutex); lcd_resume_flag = 1; aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL); LCDPR("%s finished\n", __func__); - mutex_unlock(&lcd_power_mutex); + mutex_unlock(&lcd_drv->power_mutex); } } else { + mutex_lock(&lcd_drv->power_mutex); LCDPR("directly lcd late resume\n"); - mutex_lock(&lcd_power_mutex); lcd_resume_flag = 1; aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL); LCDPR("%s finished\n", __func__); - mutex_unlock(&lcd_power_mutex); + mutex_unlock(&lcd_drv->power_mutex); } return 0; @@ -1413,11 +1415,10 @@ int lcd_tv_probe(struct device *dev) lcd_drv->version = LCD_DRV_VERSION; lcd_drv->vout_server_init = lcd_tv_vout_server_init; lcd_drv->driver_init_pre = lcd_tv_driver_init_pre; + lcd_drv->driver_disable_post = lcd_tv_driver_disable_post; lcd_drv->driver_init = lcd_tv_driver_init; lcd_drv->driver_disable = lcd_tv_driver_disable; lcd_drv->driver_change = lcd_tv_driver_change; - lcd_drv->driver_tiny_enable = lcd_tv_driver_tiny_enable; - lcd_drv->driver_tiny_disable = lcd_tv_driver_tiny_disable; lcd_get_config(lcd_drv->lcd_config, dev); diff --git a/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.h b/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.h index 4a73fd29c0fa..c752a77bd983 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.h +++ b/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.h @@ -21,11 +21,10 @@ extern void lcd_tv_config_update(struct lcd_config_s *pconf); extern void lcd_tv_driver_init_pre(void); +extern void lcd_tv_driver_disable_post(void); extern int lcd_tv_driver_init(void); extern void lcd_tv_driver_disable(void); extern int lcd_tv_driver_change(void); -extern void lcd_tv_driver_tiny_enable(void); -extern void lcd_tv_driver_tiny_disable(void); extern void lcd_vbyone_wait_stable(void); extern int lcd_vbyone_interrupt_up(void); diff --git a/drivers/amlogic/media/vout/lcd/lcd_vout.c b/drivers/amlogic/media/vout/lcd/lcd_vout.c index 9618f81d8336..07bd7d8fa239 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_vout.c +++ b/drivers/amlogic/media/vout/lcd/lcd_vout.c @@ -55,7 +55,6 @@ unsigned char lcd_debug_print_flag; unsigned char lcd_resume_flag; static struct aml_lcd_drv_s *lcd_driver; -struct mutex lcd_power_mutex; struct mutex lcd_vout_mutex; int lcd_vout_serve_bypass; @@ -206,76 +205,6 @@ struct aml_lcd_drv_s *aml_lcd_get_driver(void) } /* ********************************************************* */ -static void lcd_power_tiny_ctrl(int status) -{ - struct lcd_power_ctrl_s *lcd_power = lcd_driver->lcd_config->lcd_power; - struct lcd_power_step_s *power_step; -#ifdef CONFIG_AMLOGIC_LCD_EXTERN - struct aml_lcd_extern_driver_s *ext_drv; -#endif - int i, index; - - LCDPR("%s: %d\n", __func__, status); - i = 0; - while (i < LCD_PWR_STEP_MAX) { - if (status) - power_step = &lcd_power->power_on_step[i]; - else - power_step = &lcd_power->power_off_step[i]; - - if (power_step->type >= LCD_POWER_TYPE_MAX) - break; - if (lcd_debug_print_flag) { - LCDPR("power_tiny_ctrl: %d, step %d\n", status, i); - LCDPR("type=%d, index=%d, value=%d, delay=%d\n", - power_step->type, power_step->index, - power_step->value, power_step->delay); - } - switch (power_step->type) { - case LCD_POWER_TYPE_CPU: - index = power_step->index; - lcd_cpu_gpio_set(index, power_step->value); - break; - case LCD_POWER_TYPE_PMU: - LCDPR("to do\n"); - break; - case LCD_POWER_TYPE_SIGNAL: - if (status) - lcd_driver->driver_tiny_enable(); - else - lcd_driver->driver_tiny_disable(); - break; -#ifdef CONFIG_AMLOGIC_LCD_EXTERN - case LCD_POWER_TYPE_EXTERN: - index = power_step->index; - ext_drv = aml_lcd_extern_get_driver(index); - if (ext_drv) { - if (status) { - if (ext_drv->power_on) - ext_drv->power_on(); - else - LCDERR("no ext power on\n"); - } else { - if (ext_drv->power_off) - ext_drv->power_off(); - else - LCDERR("no ext power off\n"); - } - } - break; -#endif - default: - break; - } - if (power_step->delay) - mdelay(power_step->delay); - i++; - } - - if (lcd_debug_print_flag) - LCDPR("%s: %d finished\n", __func__, status); -} - static void lcd_power_ctrl(int status) { struct lcd_power_ctrl_s *lcd_power = lcd_driver->lcd_config->lcd_power; @@ -347,54 +276,77 @@ static void lcd_power_ctrl(int status) LCDPR("%s: %d finished\n", __func__, status); } -static void lcd_module_enable(void) +static void lcd_power_encl_on(void) { mutex_lock(&lcd_vout_mutex); lcd_driver->driver_init_pre(); + lcd_driver->lcd_status |= LCD_STATUS_ENCL_ON; + + mutex_unlock(&lcd_vout_mutex); +} + +static void lcd_power_encl_off(void) +{ + mutex_lock(&lcd_vout_mutex); + + lcd_driver->lcd_status &= ~LCD_STATUS_ENCL_ON; + lcd_driver->driver_disable_post(); + + mutex_unlock(&lcd_vout_mutex); +} + +static void lcd_power_if_on(void) +{ + mutex_lock(&lcd_vout_mutex); + lcd_driver->power_ctrl(1); - lcd_driver->lcd_status = 1; + lcd_driver->lcd_status |= LCD_STATUS_IF_ON; lcd_driver->lcd_config->change_flag = 0; mutex_unlock(&lcd_vout_mutex); } -static void lcd_module_disable(void) +static void lcd_power_if_off(void) { mutex_lock(&lcd_vout_mutex); - lcd_driver->lcd_status = 0; + lcd_driver->lcd_status &= ~LCD_STATUS_IF_ON; lcd_driver->power_ctrl(0); mutex_unlock(&lcd_vout_mutex); } +static void lcd_power_screen_black(void) +{ + mutex_lock(&lcd_vout_mutex); + + lcd_driver->lcd_screen_black(); + + mutex_unlock(&lcd_vout_mutex); +} + +static void lcd_power_screen_restore(void) +{ + mutex_lock(&lcd_vout_mutex); + + lcd_driver->lcd_screen_restore(); + + mutex_unlock(&lcd_vout_mutex); +} + static void lcd_module_reset(void) { mutex_lock(&lcd_vout_mutex); - lcd_driver->lcd_status = 0; + lcd_driver->lcd_status &= ~LCD_STATUS_ON; lcd_driver->power_ctrl(0); msleep(500); lcd_driver->driver_init_pre(); lcd_driver->power_ctrl(1); - lcd_driver->lcd_status = 1; - lcd_driver->lcd_config->change_flag = 0; - - mutex_unlock(&lcd_vout_mutex); -} - -static void lcd_module_tiny_reset(void) -{ - mutex_lock(&lcd_vout_mutex); - - lcd_driver->lcd_status = 0; - lcd_power_tiny_ctrl(0); - mdelay(500); - lcd_power_tiny_ctrl(1); - lcd_driver->lcd_status = 1; + lcd_driver->lcd_status |= LCD_STATUS_ON; lcd_driver->lcd_config->change_flag = 0; mutex_unlock(&lcd_vout_mutex); @@ -402,60 +354,129 @@ static void lcd_module_tiny_reset(void) static void lcd_resume_work(struct work_struct *p_work) { - mutex_lock(&lcd_power_mutex); + mutex_lock(&lcd_driver->power_mutex); aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL); LCDPR("%s finished\n", __func__); - mutex_unlock(&lcd_power_mutex); + mutex_unlock(&lcd_driver->power_mutex); } /* **************************************** * lcd notify * **************************************** */ -static int lcd_power_notifier(struct notifier_block *nb, +static int lcd_power_encl_on_notifier(struct notifier_block *nb, unsigned long event, void *data) { - if (event & LCD_EVENT_LCD_ON) { - if (lcd_debug_print_flag) - LCDPR("%s: 0x%lx\n", __func__, event); - lcd_module_enable(); - } else if (event & LCD_EVENT_LCD_OFF) { - if (lcd_debug_print_flag) - LCDPR("%s: 0x%lx\n", __func__, event); - lcd_module_disable(); - } else { + if ((event & LCD_EVENT_ENCL_ON) == 0) return NOTIFY_DONE; - } + + if (lcd_debug_print_flag) + LCDPR("%s: 0x%lx\n", __func__, event); + lcd_power_encl_on(); return NOTIFY_OK; } -static struct notifier_block lcd_power_nb = { - .notifier_call = lcd_power_notifier, - .priority = LCD_PRIORITY_POWER_LCD, +static struct notifier_block lcd_power_encl_on_nb = { + .notifier_call = lcd_power_encl_on_notifier, + .priority = LCD_PRIORITY_POWER_ENCL_ON, }; -static int lcd_interface_notifier(struct notifier_block *nb, +static int lcd_power_encl_off_notifier(struct notifier_block *nb, unsigned long event, void *data) { - if (event & LCD_EVENT_IF_ON) { - if (lcd_debug_print_flag) - LCDPR("%s: 0x%lx\n", __func__, event); - lcd_driver->power_tiny_ctrl(1); - } else if (event & LCD_EVENT_IF_OFF) { - if (lcd_debug_print_flag) - LCDPR("%s: 0x%lx\n", __func__, event); - lcd_driver->power_tiny_ctrl(0); - } else { + if ((event & LCD_EVENT_ENCL_OFF) == 0) return NOTIFY_DONE; + + if (lcd_debug_print_flag) + LCDPR("%s: 0x%lx\n", __func__, event); + lcd_power_encl_off(); + + return NOTIFY_OK; +} + +static struct notifier_block lcd_power_encl_off_nb = { + .notifier_call = lcd_power_encl_off_notifier, + .priority = LCD_PRIORITY_POWER_ENCL_OFF, +}; + +static int lcd_power_if_on_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + if ((event & LCD_EVENT_IF_ON) == 0) + return NOTIFY_DONE; + + if (lcd_debug_print_flag) + LCDPR("%s: 0x%lx\n", __func__, event); + + if (lcd_driver->lcd_status & LCD_STATUS_ENCL_ON) { + lcd_power_if_on(); + } else { + LCDERR("%s: can't power on when controller is off\n", + __func__); + return NOTIFY_DONE; } return NOTIFY_OK; } -static struct notifier_block lcd_interface_nb = { - .notifier_call = lcd_interface_notifier, - .priority = LCD_PRIORITY_POWER_LCD, +static struct notifier_block lcd_power_if_on_nb = { + .notifier_call = lcd_power_if_on_notifier, + .priority = LCD_PRIORITY_POWER_IF_ON, +}; + +static int lcd_power_if_off_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + if ((event & LCD_EVENT_IF_OFF) == 0) + return NOTIFY_DONE; + + if (lcd_debug_print_flag) + LCDPR("%s: 0x%lx\n", __func__, event); + lcd_power_if_off(); + + return NOTIFY_OK; +} + +static struct notifier_block lcd_power_if_off_nb = { + .notifier_call = lcd_power_if_off_notifier, + .priority = LCD_PRIORITY_POWER_IF_OFF, +}; + +static int lcd_power_screen_black_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + if ((event & LCD_EVENT_SCREEN_BLACK) == 0) + return NOTIFY_DONE; + + if (lcd_debug_print_flag) + LCDPR("%s: 0x%lx\n", __func__, event); + lcd_power_screen_black(); + + return NOTIFY_OK; +} + +static struct notifier_block lcd_power_screen_black_nb = { + .notifier_call = lcd_power_screen_black_notifier, + .priority = LCD_PRIORITY_SCREEN_BLACK, +}; + +static int lcd_power_screen_restore_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + if ((event & LCD_EVENT_SCREEN_RESTORE) == 0) + return NOTIFY_DONE; + + if (lcd_debug_print_flag) + LCDPR("%s: 0x%lx\n", __func__, event); + lcd_power_screen_restore(); + + return NOTIFY_OK; +} + +static struct notifier_block lcd_power_screen_restore_nb = { + .notifier_call = lcd_power_screen_restore_notifier, + .priority = LCD_PRIORITY_SCREEN_RESTORE, }; static int lcd_bl_select_notifier(struct notifier_block *nb, @@ -476,6 +497,48 @@ static int lcd_bl_select_notifier(struct notifier_block *nb, static struct notifier_block lcd_bl_select_nb = { .notifier_call = lcd_bl_select_notifier, }; + +static int lcd_notifier_register(void) +{ + int ret = 0; + + ret = aml_lcd_notifier_register(&lcd_bl_select_nb); + if (ret) + LCDERR("register aml_bl_select_notifier failed\n"); + + ret = aml_lcd_notifier_register(&lcd_power_encl_on_nb); + if (ret) + LCDERR("register lcd_power_encl_on_nb failed\n"); + ret = aml_lcd_notifier_register(&lcd_power_encl_off_nb); + if (ret) + LCDERR("register lcd_power_encl_off_nb failed\n"); + ret = aml_lcd_notifier_register(&lcd_power_if_on_nb); + if (ret) + LCDERR("register lcd_power_if_on_nb failed\n"); + ret = aml_lcd_notifier_register(&lcd_power_if_off_nb); + if (ret) + LCDERR("register lcd_power_if_off_nb failed\n"); + ret = aml_lcd_notifier_register(&lcd_power_screen_black_nb); + if (ret) + LCDERR("register lcd_power_screen_black_nb failed\n"); + ret = aml_lcd_notifier_register(&lcd_power_screen_restore_nb); + if (ret) + LCDERR("register lcd_power_screen_restore_nb failed\n"); + + return 0; +} + +static void lcd_notifier_unregister(void) +{ + aml_lcd_notifier_unregister(&lcd_power_screen_restore_nb); + aml_lcd_notifier_unregister(&lcd_power_screen_black_nb); + aml_lcd_notifier_unregister(&lcd_power_if_off_nb); + aml_lcd_notifier_unregister(&lcd_power_if_on_nb); + aml_lcd_notifier_unregister(&lcd_power_encl_off_nb); + aml_lcd_notifier_unregister(&lcd_power_encl_on_nb); + + aml_lcd_notifier_unregister(&lcd_bl_select_nb); +} /* **************************************** */ /* ************************************************************* */ @@ -656,8 +719,6 @@ static void lcd_init_vout(void) static int lcd_mode_probe(struct device *dev) { - int ret; - switch (lcd_driver->lcd_mode) { #ifdef CONFIG_AMLOGIC_LCD_TV case LCD_MODE_TV: @@ -677,15 +738,7 @@ static int lcd_mode_probe(struct device *dev) lcd_class_creat(); lcd_fops_create(); - ret = aml_lcd_notifier_register(&lcd_interface_nb); - if (ret) - LCDERR("register aml_bl_select_notifier failed\n"); - ret = aml_lcd_notifier_register(&lcd_bl_select_nb); - if (ret) - LCDERR("register aml_bl_select_notifier failed\n"); - ret = aml_lcd_notifier_register(&lcd_power_nb); - if (ret) - LCDPR("register lcd_power_notifier failed\n"); + lcd_notifier_register(); /* add notifier for video sync_duration info refresh */ vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE, @@ -696,6 +749,8 @@ static int lcd_mode_probe(struct device *dev) static int lcd_mode_remove(struct device *dev) { + lcd_notifier_unregister(); + switch (lcd_driver->lcd_mode) { #ifdef CONFIG_AMLOGIC_LCD_TV case LCD_MODE_TV: @@ -748,7 +803,7 @@ static void lcd_config_default(void) pconf->lcd_basic.v_active = lcd_vcbus_read(ENCL_VIDEO_VAVON_ELINE) - lcd_vcbus_read(ENCL_VIDEO_VAVON_BLINE) + 1; if (lcd_vcbus_read(ENCL_VIDEO_EN)) { - lcd_driver->lcd_status = 1; + lcd_driver->lcd_status = LCD_STATUS_ON; lcd_resume_flag = 1; } else { lcd_driver->lcd_status = 0; @@ -803,8 +858,6 @@ static int lcd_config_probe(struct platform_device *pdev) lcd_driver->lcd_resume_type = 1; /* default workqueue */ lcd_driver->power_ctrl = lcd_power_ctrl; lcd_driver->module_reset = lcd_module_reset; - lcd_driver->power_tiny_ctrl = lcd_power_tiny_ctrl; - lcd_driver->module_tiny_reset = lcd_module_tiny_reset; lcd_driver->res_vsync_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); lcd_driver->res_vx1_irq = platform_get_resource(pdev, @@ -924,7 +977,7 @@ static int lcd_probe(struct platform_device *pdev) lcd_driver->data->chip_name); mutex_init(&lcd_vout_mutex); - mutex_init(&lcd_power_mutex); + mutex_init(&lcd_driver->power_mutex); lcd_vout_serve_bypass = 0; /* init workqueue */ @@ -953,10 +1006,6 @@ static int lcd_remove(struct platform_device *pdev) destroy_workqueue(lcd_driver->workqueue); if (lcd_driver) { - aml_lcd_notifier_unregister(&lcd_power_nb); - aml_lcd_notifier_unregister(&lcd_bl_select_nb); - aml_lcd_notifier_unregister(&lcd_interface_nb); - lcd_fops_remove(); lcd_class_remove(); lcd_clk_config_remove(); @@ -978,19 +1027,19 @@ 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"); - mutex_lock(&lcd_power_mutex); aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL); LCDPR("%s finished\n", __func__); - mutex_unlock(&lcd_power_mutex); + mutex_unlock(&lcd_driver->power_mutex); } } else { + mutex_lock(&lcd_driver->power_mutex); LCDPR("directly lcd resume\n"); - mutex_lock(&lcd_power_mutex); lcd_resume_flag = 1; aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL); LCDPR("%s finished\n", __func__); - mutex_unlock(&lcd_power_mutex); + mutex_unlock(&lcd_driver->power_mutex); } return 0; @@ -998,13 +1047,13 @@ static int lcd_resume(struct platform_device *pdev) static int lcd_suspend(struct platform_device *pdev, pm_message_t state) { - mutex_lock(&lcd_power_mutex); + mutex_lock(&lcd_driver->power_mutex); if (lcd_driver->lcd_status) { aml_lcd_notifier_call_chain(LCD_EVENT_POWER_OFF, NULL); lcd_resume_flag = 0; LCDPR("%s finished\n", __func__); } - mutex_unlock(&lcd_power_mutex); + mutex_unlock(&lcd_driver->power_mutex); return 0; } diff --git a/include/linux/amlogic/media/vout/lcd/lcd_notify.h b/include/linux/amlogic/media/vout/lcd/lcd_notify.h index 1dd69a780e61..f373899deed1 100644 --- a/include/linux/amlogic/media/vout/lcd/lcd_notify.h +++ b/include/linux/amlogic/media/vout/lcd/lcd_notify.h @@ -20,27 +20,45 @@ #include -#define LCD_PRIORITY_INIT_CONFIG 4 -#define LCD_PRIORITY_INIT_VOUT 3 +#define LCD_PRIORITY_INIT_CONFIG 12 +#define LCD_PRIORITY_INIT_VOUT 11 -#define LCD_PRIORITY_BLACK_SCREEN 3 -#define LCD_PRIORITY_POWER_BL_OFF 2 -#define LCD_PRIORITY_POWER_LCD 1 -#define LCD_PRIORITY_POWER_BL_ON 0 +#define LCD_PRIORITY_SCREEN_BLACK 7 +#define LCD_PRIORITY_POWER_BL_OFF 6 +#define LCD_PRIORITY_POWER_IF_OFF 5 +#define LCD_PRIORITY_POWER_ENCL_OFF 4 +#define LCD_PRIORITY_POWER_ENCL_ON 3 +#define LCD_PRIORITY_POWER_IF_ON 2 +#define LCD_PRIORITY_POWER_BL_ON 1 +#define LCD_PRIORITY_SCREEN_RESTORE 0 -#define LCD_EVENT_BL_ON (1 << 0) -#define LCD_EVENT_LCD_ON (1 << 1) -#define LCD_EVENT_IF_ON (1 << 2) -#define LCD_EVENT_POWER_ON (LCD_EVENT_BL_ON | LCD_EVENT_LCD_ON) -#define LCD_EVENT_IF_POWER_ON (LCD_EVENT_BL_ON | LCD_EVENT_IF_ON) -#define LCD_EVENT_BLACK_SCREEN (1 << 3) -#define LCD_EVENT_BL_OFF (1 << 4) -#define LCD_EVENT_LCD_OFF (1 << 5) -#define LCD_EVENT_IF_OFF (1 << 6) -#define LCD_EVENT_POWER_OFF (LCD_EVENT_BL_OFF | LCD_EVENT_LCD_OFF |\ - LCD_EVENT_BLACK_SCREEN) -#define LCD_EVENT_IF_POWER_OFF (LCD_EVENT_BL_OFF | LCD_EVENT_IF_OFF |\ - LCD_EVENT_BLACK_SCREEN) +/* orignal event */ +#define LCD_EVENT_SCREEN_BLACK (1 << 0) +#define LCD_EVENT_BL_OFF (1 << 1) +#define LCD_EVENT_IF_OFF (1 << 2) +#define LCD_EVENT_ENCL_OFF (1 << 3) +#define LCD_EVENT_ENCL_ON (1 << 4) +#define LCD_EVENT_IF_ON (1 << 5) +#define LCD_EVENT_BL_ON (1 << 6) +#define LCD_EVENT_SCREEN_RESTORE (1 << 7) + +/* combined event */ +#define LCD_EVENT_POWER_ON (LCD_EVENT_BL_ON | LCD_EVENT_IF_ON | \ + LCD_EVENT_ENCL_ON | LCD_EVENT_SCREEN_RESTORE) +#define LCD_EVENT_IF_POWER_ON (LCD_EVENT_IF_ON | LCD_EVENT_BL_ON | \ + LCD_EVENT_SCREEN_RESTORE) +#define LCD_EVENT_POWER_OFF (LCD_EVENT_SCREEN_BLACK | \ + LCD_EVENT_BL_OFF | LCD_EVENT_IF_OFF | \ + LCD_EVENT_ENCL_OFF) +#define LCD_EVENT_IF_POWER_OFF (LCD_EVENT_SCREEN_BLACK | \ + LCD_EVENT_BL_OFF | LCD_EVENT_IF_OFF) + +#define LCD_EVENT_PREPARE (LCD_EVENT_ENCL_ON) +#define LCD_EVENT_ENABLE (LCD_EVENT_IF_ON | LCD_EVENT_BL_ON | \ + LCD_EVENT_SCREEN_RESTORE) +#define LCD_EVENT_DISABLE (LCD_EVENT_SCREEN_BLACK | \ + LCD_EVENT_BL_OFF | LCD_EVENT_IF_OFF) +#define LCD_EVENT_UNPREPARE (LCD_EVENT_ENCL_OFF) /* lcd backlight index select */ #define LCD_EVENT_BACKLIGHT_SEL (1 << 8) diff --git a/include/linux/amlogic/media/vout/lcd/lcd_vout.h b/include/linux/amlogic/media/vout/lcd/lcd_vout.h index 62f3e86df218..410f079cb454 100644 --- a/include/linux/amlogic/media/vout/lcd/lcd_vout.h +++ b/include/linux/amlogic/media/vout/lcd/lcd_vout.h @@ -396,6 +396,10 @@ struct lcd_duration_s { unsigned int duration_den; }; +#define LCD_STATUS_IF_ON (1 << 0) +#define LCD_STATUS_ENCL_ON (1 << 1) +#define LCD_STATUS_ON (LCD_STATUS_IF_ON | LCD_STATUS_ENCL_ON) + struct aml_lcd_drv_s { char *version; struct lcd_data_s *data; @@ -426,15 +430,14 @@ struct aml_lcd_drv_s { void (*vout_server_init)(void); void (*driver_init_pre)(void); + void (*driver_disable_post)(void); int (*driver_init)(void); void (*driver_disable)(void); int (*driver_change)(void); void (*module_reset)(void); - void (*power_tiny_ctrl)(int status); - void (*driver_tiny_enable)(void); - void (*driver_tiny_disable)(void); void (*module_tiny_reset)(void); - void (*lcd_test_pattern_restore)(void); + void (*lcd_screen_black)(void); + void (*lcd_screen_restore)(void); void (*power_ctrl)(int status); struct workqueue_struct *workqueue; @@ -443,6 +446,8 @@ struct aml_lcd_drv_s { struct work_struct lcd_resume_work; struct resource *res_vsync_irq; struct resource *res_vx1_irq; + + struct mutex power_mutex; }; extern struct aml_lcd_drv_s *aml_lcd_get_driver(void);