rk3288 hdmi: add support early suspend and resume
authorzwl <zwl@rock-chips.com>
Mon, 24 Mar 2014 14:18:12 +0000 (22:18 +0800)
committerzwl <zwl@rock-chips.com>
Mon, 24 Mar 2014 14:18:25 +0000 (22:18 +0800)
drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.c
drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.c

index 743304448757d8c19dda4394e8fc8ec2877697ac..3ec29f552b09d7da5f84eb5103a3fd183bc8d0fe 100644 (file)
@@ -190,6 +190,76 @@ static int rk3288_hdmi_drv_init(struct hdmi *hdmi_drv)
        return ret;
 }
 
+static void rk3288_hdmi_early_suspend()
+{
+       struct hdmi *hdmi_drv = &hdmi_dev->driver;
+
+       hdmi_dbg(hdmi_drv->dev, "hdmi enter early suspend pwr %d state %d\n", hdmi_drv->pwr_mode, hdmi_drv->state);
+       flush_delayed_work(&hdmi_drv->delay_work);
+       mutex_lock(&hdmi_drv->enable_mutex);
+       hdmi_drv->suspend = 1;
+       if(!hdmi_drv->enable) {
+               mutex_unlock(&hdmi_drv->enable_mutex);
+               return;
+       }
+       disable_irq(hdmi_drv->irq);
+       mutex_unlock(&hdmi_drv->enable_mutex);
+       hdmi_drv->command = HDMI_CONFIG_ENABLE;
+       init_completion(&hdmi_drv->complete);
+       hdmi_drv->wait = 1;
+       queue_delayed_work(hdmi_drv->workqueue, &hdmi_drv->delay_work, 0);
+       wait_for_completion_interruptible_timeout(&hdmi_drv->complete,
+                                                       msecs_to_jiffies(5000));
+       flush_delayed_work(&hdmi_drv->delay_work);
+       return;
+}
+
+static void rk3288_hdmi_early_resume()
+{
+       struct hdmi *hdmi_drv = &hdmi_dev->driver;
+
+       hdmi_dbg(hdmi_drv->dev, "hdmi enter early resume\n");
+       mutex_lock(&hdmi_drv->enable_mutex);
+       hdmi_drv->suspend = 0;
+       rk3288_hdmi_initial(hdmi_drv);
+       if(hdmi_drv->enable) {
+               enable_irq(hdmi_drv->irq);
+       }
+       mutex_unlock(&hdmi_drv->enable_mutex);
+       return;
+}
+
+static int rk3288_hdmi_fb_event_notify(struct notifier_block *self, unsigned long action, void *data)
+{
+       struct fb_event *event = data;
+       int blank_mode = *((int *)event->data);
+
+       if (action == FB_EARLY_EVENT_BLANK) {
+               switch (blank_mode) {
+               case FB_BLANK_UNBLANK:
+                       break;
+               default:
+                       rk3288_hdmi_early_suspend();
+                       break;
+               }
+       }
+       else if (action == FB_EVENT_BLANK) {
+               switch (blank_mode) {
+               case FB_BLANK_UNBLANK:
+                       rk3288_hdmi_early_resume();
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block rk3288_hdmi_fb_notifier = {
+        .notifier_call = rk3288_hdmi_fb_event_notify,
+};
+
 #if defined(CONFIG_OF)
 static int rk3288_hdmi_parse_dt(struct rk3288_hdmi_device *hdmi_dev)
 {
@@ -269,6 +339,8 @@ static int rk3288_hdmi_probe(struct platform_device *pdev)
        switch_dev_register(&(dev_drv->switch_hdmi));
 #endif
 
+       fb_register_client(&rk3288_hdmi_fb_notifier);
+
 #ifndef HDMI_INT_USE_POLL
        /* get and request the IRQ */
        dev_drv->irq = platform_get_irq(pdev, 0);
@@ -302,6 +374,7 @@ static int rk3288_hdmi_probe(struct platform_device *pdev)
        return 0;
 
 err2:
+       fb_unregister_client(&rk3288_hdmi_fb_notifier);
 #ifdef CONFIG_SWITCH
        switch_dev_unregister(&(dev_drv->switch_hdmi));
 #endif
@@ -334,6 +407,8 @@ static int rk3288_hdmi_remove(struct platform_device *pdev)
                flush_workqueue(hdmi_drv->workqueue);
                destroy_workqueue(hdmi_drv->workqueue);
 
+               fb_unregister_client(&rk3288_hdmi_fb_notifier);
+
                #ifdef CONFIG_SWITCH
                switch_dev_unregister(&(hdmi_drv->switch_hdmi));
                #endif
index 0f5df30d69cb97d4da34de358ee4f2aba04ca4ee..f0cb9b9840311b3b9cf7fa5d56edc5a618584507 100644 (file)
@@ -31,7 +31,6 @@ const struct phy_mpll_config_tab* get_phy_mpll_tab(int pixClock, char pixRepet,
 
 static void rk3288_hdmi_av_mute(struct hdmi *hdmi_drv, int enable)
 {
-       int value = 0;
        struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
 
        hdmi_msk_reg(hdmi_dev, FC_GCP, m_FC_SET_AVMUTE, v_FC_SET_AVMUTE(enable));
@@ -49,8 +48,8 @@ static void rk3288_hdmi_set_pwr_mode(struct hdmi *hdmi_drv, int mode)
        if(hdmi_drv->pwr_mode == mode)
                return;
 
-       hdmi_dbg(hdmi_drv->dev, "%s change pwr_mode %d --> %d\n",__FUNCTION__, hdmi_drv->pwr_mode, mode);
-       printk("%s change pwr_mode %d --> %d\n",__FUNCTION__, hdmi_drv->pwr_mode, mode);
+       dev_printk(KERN_INFO, hdmi_drv->dev, "%s change pwr_mode %d --> %d\n", __FUNCTION__, hdmi_drv->pwr_mode, mode);
+
        switch(mode)
        {
                case NORMAL:
@@ -59,8 +58,8 @@ static void rk3288_hdmi_set_pwr_mode(struct hdmi *hdmi_drv, int mode)
                        hdmi_writel(hdmi_dev, MC_CLKDIS, 0x00);
                        break;
                case LOWER_PWR:
-                       hdmi_msk_reg(hdmi_dev, MC_CLKDIS, m_AUDCLK_DISABLE | m_PREPCLK_DISABLE | m_TMDSCLK_DISABLE | m_PIXELCLK_DISABLE,
-                               v_AUDCLK_DISABLE(1) | v_PREPCLK_DISABLE(1) | v_TMDSCLK_DISABLE(1) | v_PIXELCLK_DISABLE(1));
+                       //hdmi_msk_reg(hdmi_dev, MC_CLKDIS, m_AUDCLK_DISABLE | m_PREPCLK_DISABLE | m_TMDSCLK_DISABLE | m_PIXELCLK_DISABLE,
+                               //v_AUDCLK_DISABLE(1) | v_PREPCLK_DISABLE(1) | v_TMDSCLK_DISABLE(1) | v_PIXELCLK_DISABLE(1));
                        //hdmi_msk_reg(hdmi_dev, PHY_CONF0, m_TXPWRON_SIG, v_TXPWRON_SIG(0));
                        break;
                default:
@@ -88,7 +87,7 @@ void rk3288_hdmi_reset(struct hdmi *hdmi_drv)
        hdmi_writel(hdmi_dev, MC_SWRSTZREQ_2, 0x01);
 
        rk3288_hdmi_i2cm_reset(hdmi_dev);
-#if 0
+#if 1
        //reset PHY
        hdmi_writel(hdmi_dev, PHY_CONF0, 0x3a);
        hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(1));
@@ -222,7 +221,6 @@ static int rk3288_hdmi_video_forceOutput(struct hdmi *hdmi_drv, char enable)
 
 static int rk3288_hdmi_video_frameComposer(struct hdmi *hdmi_drv, struct hdmi_video_para *vpara)       //TODO Daisen wait to add support 3D
 {
-       int i = 0, value = 0;
        int h_act = 0, v_act = 0;
        int h_syncdelay = 0, v_syncdelay = 0;
        int h_sync = 0, v_sync = 0;