gfx: fix early_suspend/late_resume for TMD_6X10_VID panel
authorLi Peng <peng.li@intel.com>
Tue, 22 May 2012 06:11:05 +0000 (14:11 +0800)
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Thu, 12 Jul 2012 11:45:37 +0000 (14:45 +0300)
most code come from MCG, which use dsi_hw_context to save/restore
panel registers at early_suspend/late_resume.

Test method

early_suspend: echo mem > /sys/power/state
late_resume: echo on > /sys/power/state

Signed-off-by: Li Peng <peng.li@intel.com>
drivers/staging/mrst.mcg/drv/mdfld_dsi_dpi.c
drivers/staging/mrst/drv/psb_drv.c
drivers/staging/mrst/drv/psb_drv.h
drivers/staging/mrst/drv/psb_powermgmt.c

index a2cf8b2..1655b71 100644 (file)
@@ -1759,10 +1759,13 @@ static int __dpi_panel_power_off(struct mdfld_dsi_config *dsi_config,
                                        OSPM_UHB_FORCE_POWER_ON))
                return -EAGAIN;
 
+       ctx->lastbrightnesslevel = dev_priv->brightness;
        if (p_funcs->set_brightness(dsi_config, 0))
                DRM_ERROR("Failed to set panel brightness\n");
 
        /*save the plane informaton, for it will updated*/
+       ctx->dspsurf = REG_READ(regs->dspsurf_reg);
+       ctx->dsplinoff = REG_READ(regs->dsplinoff_reg);
        ctx->pipestat = REG_READ(regs->pipestat_reg);
        ctx->dspcntr = REG_READ(regs->dspcntr_reg);
        ctx->dspstride= REG_READ(regs->dspstride_reg);
@@ -1934,12 +1937,17 @@ static int __mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
                if (dsi_config->dsi_hw_context.panel_on)
                        goto fun_exit;
                /* For DPMS case, just turn on/off panel */
-               {
+               if (dev_priv->dpms_on_off) {
                        if (mdfld_dsi_dpi_panel_turn_on(dsi_config)) {
                                DRM_ERROR("Faild to turn on panel\n");
                                goto set_power_err;
                        }
-               } 
+               } else {
+                       if (__dpi_panel_power_on(dsi_config, p_funcs)) {
+                               DRM_ERROR("Faild to turn on panel\n");
+                               goto set_power_err;
+                       }
+               }
 
                /**
                 * If power on, turn off color mode by default,
@@ -1950,9 +1958,15 @@ static int __mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
                dsi_config->dsi_hw_context.panel_on = 1;
                break;
        case false:
-               if (dsi_config->dsi_hw_context.panel_on) {
+               if (dev_priv->dpms_on_off &&
+                   dsi_config->dsi_hw_context.panel_on) {
                        if (mdfld_dsi_dpi_panel_shut_down(dsi_config))
                                DRM_ERROR("Faild to shutdown panel\n");
+               } else if (!dev_priv->dpms_on_off) {
+                       if (__dpi_panel_power_off(dsi_config, p_funcs)) {
+                               DRM_ERROR("Faild to turn off panel\n");
+                               goto set_power_err;
+                       }
                }
 
                dsi_config->dsi_hw_context.panel_on = 0;
@@ -2056,10 +2070,14 @@ void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode)
        PSB_DEBUG_ENTRY(
                        "%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off"));
 
+       mutex_lock(&dev_priv->dpms_mutex);
+       dev_priv->dpms_on_off = true;
        if (mode == DRM_MODE_DPMS_ON)
                mdfld_dsi_dpi_set_power(encoder, true);
        else
                mdfld_dsi_dpi_set_power(encoder, false);
+       dev_priv->dpms_on_off = false;
+       mutex_unlock(&dev_priv->dpms_mutex);
 }
 
 bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder,
@@ -2538,12 +2556,24 @@ mode_set_err:
 
 void mdfld_dsi_dpi_save(struct drm_encoder *encoder)
 {
-       return;
+       printk(KERN_ALERT"%s\n", __func__);
+
+       if (!encoder)
+               return;
+
+       /*turn off*/
+       __mdfld_dsi_dpi_set_power(encoder, false);
 }
 
 void mdfld_dsi_dpi_restore(struct drm_encoder *encoder)
 {
-       return;
+       printk(KERN_ALERT"%s\n", __func__);
+
+       if (!encoder)
+               return;
+
+       /*turn on*/
+       __mdfld_dsi_dpi_set_power(encoder, true);
 }
 
 /*
index 6c207dc..3ff2aa7 100644 (file)
@@ -64,6 +64,8 @@
 
 int drm_psb_debug;
 int drm_psb_enable_pr2_cabc = 1;
+int drm_psb_enable_gamma;
+int drm_psb_enable_color_conversion;
 /*EXPORT_SYMBOL(drm_psb_debug); */
 static int drm_psb_trap_pagefaults;
 
@@ -1060,6 +1062,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
        dev_priv->psb_hotplug_state = NULL;
        dev_priv->hdmi_done_reading_edid = false;
        dev_priv->xserver_start = false;
+       dev_priv->dpms_on_off = false;
 
        dev_priv->dev = dev;
        bdev = &dev_priv->bdev;
@@ -1077,6 +1080,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
        mutex_init(&dev_priv->temp_mem);
        mutex_init(&dev_priv->cmdbuf_mutex);
        mutex_init(&dev_priv->reset_mutex);
+       mutex_init(&dev_priv->dpms_mutex);
        INIT_LIST_HEAD(&dev_priv->context.validate_list);
        INIT_LIST_HEAD(&dev_priv->context.kern_validate_list);
 
index 7bbb245..b109d22 100644 (file)
@@ -934,6 +934,9 @@ struct drm_psb_private {
 
        uint32_t hdmi_audio_interrupt_mask;
 
+       bool dpms_on_off;
+       struct mutex dpms_mutex;
+
        /*psb fb dev*/
        void * fbdev;
        bool b_pmic_backlight;
@@ -1149,6 +1152,8 @@ struct backlight_device * psb_get_backlight_device(void);
 
 extern int drm_psb_debug;
 extern int drm_psb_enable_pr2_cabc ;
+extern int drm_psb_enable_gamma;
+extern int drm_psb_enable_color_conversion;
 extern int drm_tc35876x_debug;
 extern int drm_psb_no_fb;
 extern int drm_topaz_sbuswa;
index 30642ab..31cbea6 100644 (file)
@@ -348,26 +348,12 @@ static void gfx_early_suspend(struct early_suspend *es)
        struct drm_encoder *encoder;
 
        dev_dbg(&dev->pdev->dev, "%s\n", __func__);
-       dev_priv->hdmi_audio_busy =
-                       psb_runtime_hdmi_audio_suspend(dev) == -EBUSY;
 
        mutex_lock(&dev->mode_config.mutex);
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
                struct drm_encoder_helper_funcs *ehf = encoder->helper_private;
-               if (drm_helper_encoder_in_use(encoder) && ehf && ehf->dpms
-#ifndef JIRA_ANDROID-1553
-       /*
-        * Local MIPI fails to turn back on from a DPMS off/on cycle if
-        * HDMI audio returns busy to disallow system suspend.
-        * Once ANDROID-1553 is fixed, the expectation is to turn off
-        * MIPI but keep display island on if there is active audio
-        * playback over HDMI.
-        * Refer Jira bug# Android-1553 for more details.
-        */
-                       && !dev_priv->hdmi_audio_busy
-#endif
-               )
-                       ehf->dpms(encoder, DRM_MODE_DPMS_OFF);
+               if (drm_helper_encoder_in_use(encoder) && ehf && ehf->save)
+                       ehf->save(encoder);
        }
        mutex_unlock(&dev->mode_config.mutex);
 
@@ -389,26 +375,8 @@ static void gfx_late_resume(struct early_suspend *es)
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
                struct drm_encoder_helper_funcs *ehf = encoder->helper_private;
 
-               if (drm_helper_encoder_in_use(encoder) && ehf && ehf->mode_set
-                   && ehf->dpms
-#ifndef JIRA_ANDROID-1553
-       /*
-         Local MIPI fails to turn back on from a DPMS off/on cycle if HDMI
-         audio returns busy to disallow system suspend.
-         Once ANDROID-1553 is fixed, the expectation is to turn off MIPI but
-         keep display island on if there is active audio playback over HDMI
-         Refer Jira bug# Android-1553 for more details.
-       */
-                       && !(dev_priv->hdmi_audio_busy)
-#endif
-               ) {
-                       struct drm_crtc *crtc = encoder->crtc;
-
-                       if (crtc)
-                               ehf->mode_set(encoder,
-                                             &crtc->mode,
-                                             &crtc->hwmode);
-                       ehf->dpms(encoder, DRM_MODE_DPMS_ON);
+               if (drm_helper_encoder_in_use(encoder) && ehf && ehf->restore) {
+                       ehf->restore(encoder);
                }
        }
        mutex_unlock(&dev->mode_config.mutex);
@@ -448,6 +416,16 @@ static int mdfld_save_pipe_registers(struct drm_device *dev, int pipe)
 
        PSB_DEBUG_ENTRY("\n");
 
+       /**
+        * For MIPI panels, all plane/pipe/port/DSI controller values
+        * were already saved in dsi_hw_context, no need to save/restore
+        * for these registers.
+        * NOTE: only support TMD panel now, add support for other MIPI
+        * panels later
+        */
+       if (pipe != 1 && ((get_panel_type(dev, pipe) == TMD_6X10_VID)))
+               return 0;
+
        switch (pipe) {
        case 0:
                pr->pll_ctrl = PSB_RVDC32(PSB_DSI_PLL_CTRL);
@@ -548,6 +526,16 @@ static int mdfld_restore_pipe_registers(struct drm_device *dev, int pipe)
 
        PSB_DEBUG_ENTRY("\n");
 
+       /**
+        * For MIPI panels, all plane/pipe/port/DSI controller values
+        * were already saved in dsi_hw_context, no need to save/restore
+        * for these registers.
+        * NOTE: only support TMD panel now, add support for other MIPI
+        * panels later
+        */
+       if (pipe != 1 && ((get_panel_type(dev, pipe) == TMD_6X10_VID)))
+               return 0;
+
        switch (pipe) {
        case 0:
                dpll_reg = PSB_DSI_PLL_CTRL;