lcd: optimize lcd notifier event for power sequence
authorEvoke Zhang <evoke.zhang@amlogic.com>
Mon, 22 Jan 2018 03:37:13 +0000 (11:37 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Tue, 30 Jan 2018 06:28:30 +0000 (22:28 -0800)
PD#158197: lcd: optimize lcd notifier event for power sequence

Change-Id: I6b91bf1c2c6e31dfa3133f078d37d32fdce2a5bd
Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
drivers/amlogic/media/vout/lcd/lcd_common.h
drivers/amlogic/media/vout/lcd/lcd_debug.c
drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_drv.c
drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c
drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.h
drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c
drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c
drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.h
drivers/amlogic/media/vout/lcd/lcd_vout.c
include/linux/amlogic/media/vout/lcd/lcd_notify.h
include/linux/amlogic/media/vout/lcd/lcd_vout.h

index 189b7d0..9a19c50 100644 (file)
 
 /* 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;
index e688715..8d66ecd 100644 (file)
@@ -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)) {
index e6554b9..519c4f4 100644 (file)
@@ -873,85 +873,15 @@ 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();
-}
-
-int lcd_tablet_driver_init(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 -1;
-
-       /* 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;
-       }
 
        lcd_vcbus_write(VENC_INTCTRL, 0x200);
 
        if (lcd_debug_print_flag)
                LCDPR("%s finished\n", __func__);
-
-       return 0;
 }
 
-void lcd_tablet_driver_disable(void)
+void lcd_tablet_driver_disable_post(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;
-       }
-
        lcd_vcbus_write(ENCL_VIDEO_EN, 0); /* disable encl */
 
        lcd_clk_disable();
@@ -965,7 +895,7 @@ void lcd_tablet_driver_disable(void)
                LCDPR("%s finished\n", __func__);
 }
 
-void lcd_tablet_driver_tiny_enable(void)
+int lcd_tablet_driver_init(void)
 {
        struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
        struct lcd_config_s *pconf;
@@ -974,7 +904,7 @@ void lcd_tablet_driver_tiny_enable(void)
        pconf = lcd_drv->lcd_config;
        ret = lcd_type_supported(pconf);
        if (ret)
-               return;
+               return -1;
 
        /* init driver */
        switch (pconf->lcd_basic.lcd_type) {
@@ -1000,10 +930,13 @@ void lcd_tablet_driver_tiny_enable(void)
                break;
        }
 
-       LCDPR("enable driver\n");
+       if (lcd_debug_print_flag)
+               LCDPR("%s finished\n", __func__);
+
+       return 0;
 }
 
-void lcd_tablet_driver_tiny_disable(void)
+void lcd_tablet_driver_disable(void)
 {
        struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
        struct lcd_config_s *pconf;
@@ -1035,5 +968,8 @@ void lcd_tablet_driver_tiny_disable(void)
        default:
                break;
        }
+
+       if (lcd_debug_print_flag)
+               LCDPR("%s finished\n", __func__);
 }
 
index 4a16e49..9689b6a 100644 (file)
@@ -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);
 
index 6c435dd..e678f85 100644 (file)
@@ -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
index 137af6b..1aa138b 100644 (file)
@@ -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);
-
-               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");
-               }
+               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 (!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);
-
-               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");
-               }
+               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");
        }
 
        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)
index b58b577..6889fc3 100644 (file)
@@ -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);
 
index 4a73fd2..c752a77 100644 (file)
 
 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);
index 9618f81..07bd7d8 100644 (file)
@@ -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_module_reset(void)
+static void lcd_power_screen_black(void)
 {
        mutex_lock(&lcd_vout_mutex);
 
-       lcd_driver->lcd_status = 0;
-       lcd_driver->power_ctrl(0);
+       lcd_driver->lcd_screen_black();
 
-       msleep(500);
+       mutex_unlock(&lcd_vout_mutex);
+}
 
-       lcd_driver->driver_init_pre();
-       lcd_driver->power_ctrl(1);
-       lcd_driver->lcd_status = 1;
-       lcd_driver->lcd_config->change_flag = 0;
+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_tiny_reset(void)
+static void lcd_module_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->power_ctrl(0);
+
+       msleep(500);
+
+       lcd_driver->driver_init_pre();
+       lcd_driver->power_ctrl(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;
 }
 
index 1dd69a7..f373899 100644 (file)
 
 #include <linux/notifier.h>
 
-#define LCD_PRIORITY_INIT_CONFIG       4
-#define LCD_PRIORITY_INIT_VOUT         3
-
-#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_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)
+#define LCD_PRIORITY_INIT_CONFIG       12
+#define LCD_PRIORITY_INIT_VOUT         11
+
+#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
+
+/* 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)
index 62f3e86..410f079 100644 (file)
@@ -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);