From: zwl Date: Mon, 24 Mar 2014 14:18:12 +0000 (+0800) Subject: rk3288 hdmi: add support early suspend and resume X-Git-Tag: firefly_0821_release~5863 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=127d52bf36236c59746712b2a6ad45dbd204ee17;p=firefly-linux-kernel-4.4.55.git rk3288 hdmi: add support early suspend and resume --- diff --git a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.c b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.c index 743304448757..3ec29f552b09 100644 --- a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.c +++ b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.c @@ -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 diff --git a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.c b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.c index 0f5df30d69cb..f0cb9b984031 100644 --- a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.c +++ b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.c @@ -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;