From: Hitesh K. Patel <[email protected]> Enable video decoder driver support for Linux Runtime PM
1. psb_drv.c enable pm_runtime_allow 2. psb_powermgmt.c temporarily disable topaz Linux Runtime PM idle and suspend for debug Enable video encoder driver support for Linux Runtime PM 1. add fork to handle power suspend/resume for Moorestown and Medfield 2. add fork to check topaz idle for Moorestown and Medfield 3.comment all debug info Change-Id: I357d6b31d3ffe5c39b2dc7deee8c20899c99a301 Signed-off-by: Hitesh K. Patel <[email protected]> --- drivers/staging/mrst/drv/psb_drv.c | 10 +- drivers/staging/mrst/drv/psb_powermgmt.c | 221 ++++++++++++++++++------------ 2 files changed, 135 insertions(+), 96 deletions(-) diff --git a/drivers/staging/mrst/drv/psb_drv.c b/drivers/staging/mrst/drv/psb_drv.c index c17d3b8..b296ef8 100644 --- a/drivers/staging/mrst/drv/psb_drv.c +++ b/drivers/staging/mrst/drv/psb_drv.c @@ -2462,15 +2462,15 @@ static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd, { struct drm_file *file_priv = filp->private_data; struct drm_device *dev = file_priv->minor->dev; - /*struct drm_psb_private *dev_priv = dev->dev_private;*/ - /*static unsigned int runtime_allowed = 0;*/ + struct drm_psb_private *dev_priv = dev->dev_private; + static unsigned int runtime_allowed = 0; unsigned int nr = DRM_IOCTL_NR(cmd); long ret; DRM_DEBUG("cmd = %x, nr = %x\n", cmd, nr); /*Simple (work around)Ugly hack to make runtime pm start only after X is initialized*/ - //This doesn't work with Medfield RT PM. -#ifdef FIX_OSPM_POWER_DOWN + /*This doesn't work with Medfield RT PM.*/ + if(!runtime_allowed && !(dev_priv->is_lvds_on || dev_priv->is_mipi_on)) { runtime_allowed ++; } @@ -2478,7 +2478,7 @@ static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd, runtime_allowed ++; pm_runtime_allow(&dev->pdev->dev); } -#endif + /* * The driver private ioctls and TTM ioctls should be * thread-safe. diff --git a/drivers/staging/mrst/drv/psb_powermgmt.c b/drivers/staging/mrst/drv/psb_powermgmt.c index 6a7e976..1df07e1 100644 --- a/drivers/staging/mrst/drv/psb_powermgmt.c +++ b/drivers/staging/mrst/drv/psb_powermgmt.c @@ -91,23 +91,37 @@ static int ospm_runtime_check_topaz_hw_busy(struct drm_device *dev) //struct drm_psb_private *dev_priv = dev->dev_private; //struct topaz_private *topaz_priv = dev_priv->topaz_private; int ret = 1; - + if (!ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND)) { //printk(KERN_ALERT "%s VIDEO ENC HW is not on\n", __func__); ret = -1; goto out; } - + //topaz_priv->topaz_hw_busy = REG_READ(0x20D0) & (0x1 << 11); - if (lnc_check_topaz_idle(dev)) { - //printk(KERN_ALERT "%s video encode hw busy %d\n", __func__, - // topaz_priv->topaz_hw_busy); - ret = 1; - } - else { - //printk(KERN_ALERT "%s video encode hw idle\n", __func__); - ret = 0; - } + if (IS_MRST(dev)) { + if (lnc_check_topaz_idle(dev)) { + //printk(KERN_ALERT "%s video encode hw busy %d\n", __func__, + // topaz_priv->topaz_hw_busy); + ret = 1; + } + else { + //printk(KERN_ALERT "%s video encode hw idle\n", __func__); + ret = 0; + } + } + + if (IS_MDFLD(dev)) { + if (pnw_check_topaz_idle(dev)) { + //printk(KERN_ALERT "%s video encode hw busy %d\n", __func__, + // topaz_priv->topaz_hw_busy); + ret = 1; + } + else { + //printk(KERN_ALERT "%s video encode hw idle\n", __func__); + ret = 0; + } + } out: return ret; } @@ -117,20 +131,20 @@ static int ospm_runtime_pm_msvdx_suspend(struct drm_device *dev) int ret = 0; struct drm_psb_private *dev_priv = dev->dev_private; struct msvdx_private *msvdx_priv = dev_priv->msvdx_private; - - //printk(KERN_ALERT "enter %s\n", __func__); - + + //printk(KERN_ALERT "enter %s\n", __func__); + if (!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) { //printk(KERN_ALERT "%s VIDEO DEC HW is not on\n", __func__); goto out; } - + if (atomic_read(&g_videodec_access_count)) { //printk(KERN_ALERT "%s videodec access count exit\n", __func__); ret = -1; goto out; } - + msvdx_priv->msvdx_hw_busy = REG_READ(0x20D0) & (0x1 << 9); if (psb_check_msvdx_idle(dev)){ //printk(KERN_ALERT "%s video decode hw busy exit\n", __func__); @@ -157,7 +171,7 @@ static int ospm_runtime_pm_msvdx_resume(struct drm_device *dev) MSVDX_NEW_PMSTATE(dev, msvdx_priv, PSB_PMSTATE_POWERUP); psb_msvdx_restore_context(dev); - + return 0; } @@ -166,32 +180,49 @@ static int ospm_runtime_pm_topaz_suspend(struct drm_device *dev) int ret = 0; struct drm_psb_private *dev_priv = dev->dev_private; struct topaz_private *topaz_priv = dev_priv->topaz_private; - - //printk(KERN_ALERT "enter %s\n", __func__); - + + //printk(KERN_ALERT "enter %s\n", __func__); + if (!ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND)) { //printk(KERN_ALERT "%s VIDEO ENC HW is not on\n", __func__); goto out; } - + if (atomic_read(&g_videoenc_access_count)) { //printk(KERN_ALERT "%s videoenc access count exit\n", __func__); ret = -1; goto out; } - + //topaz_priv->topaz_hw_busy = REG_READ(0x20D0) & (0x1 << 11); - if (lnc_check_topaz_idle(dev)){ - //printk(KERN_ALERT "%s video encode hw busy exit\n", __func__); - ret = -2; - goto out; - } - + if (IS_MRST(dev)) { + if (lnc_check_topaz_idle(dev)){ + //printk(KERN_ALERT "%s video encode hw busy exit\n", __func__); + ret = -2; + goto out; + } + } + + if (IS_MDFLD(dev)) { + if (pnw_check_topaz_idle(dev)){ + //printk(KERN_ALERT "%s video encode hw busy exit\n", __func__); + ret = -2; + goto out; + } + } + TOPAZ_NEW_PMSTATE(dev, topaz_priv, PSB_PMSTATE_POWERDOWN); - + psb_irq_uninstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND); - lnc_topaz_save_mtx_state(gpDrmDevice); - lnc_unmap_topaz_reg(gpDrmDevice); + if(IS_MRST(dev)) { + lnc_topaz_save_mtx_state(gpDrmDevice); + lnc_unmap_topaz_reg(gpDrmDevice); + } + + if(IS_MDFLD(dev)) { + pnw_topaz_save_mtx_state(gpDrmDevice); + pnw_unmap_topaz_reg(gpDrmDevice); + } ospm_power_island_down(OSPM_VIDEO_ENC_ISLAND); //printk(KERN_ALERT "%s done\n", __func__); out: @@ -207,9 +238,17 @@ static int ospm_runtime_pm_topaz_resume(struct drm_device *dev) TOPAZ_NEW_PMSTATE(dev, topaz_priv, PSB_PMSTATE_POWERUP); - lnc_map_topaz_reg(gpDrmDevice); - psb_irq_uninstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND); - lnc_topaz_restore_mtx_state(gpDrmDevice); + if (IS_MRST(dev)) { + lnc_map_topaz_reg(gpDrmDevice); + psb_irq_uninstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND); + lnc_topaz_restore_mtx_state(gpDrmDevice); + } + + if (IS_MDFLD(dev)) { + pnw_map_topaz_reg(gpDrmDevice); + psb_irq_uninstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND); + pnw_topaz_restore_mtx_state(gpDrmDevice); + } return 0; } @@ -1552,14 +1591,15 @@ int ospm_power_suspend(struct pci_dev *pdev, pm_message_t state) psb_irq_uninstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); ospm_suspend_display(gpDrmDevice); #if 1 - // FIXME: for video decode support new Linux runtime PM + /* FIXME: video driver support for Linux Runtime PM */ if (ospm_runtime_pm_msvdx_suspend(gpDrmDevice) != 0) { suspend_pci = false; } - + if (ospm_runtime_pm_topaz_suspend(gpDrmDevice) != 0) { suspend_pci = false; } + #endif if (suspend_pci == true) { ospm_suspend_pci(pdev); @@ -1829,54 +1869,54 @@ bool ospm_power_using_hw_begin(int hw_island, bool force_on) psb_irq_postinstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND); break; #if 1 - case OSPM_VIDEO_DEC_ISLAND: - if(!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) { - //printk(KERN_ALERT "%s power on display for video decode use\n", __func__); - deviceID = gui32MRSTDisplayDeviceID; - ospm_resume_display(pdev); - psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); - psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); - } - else{ - //printk(KERN_ALERT "%s display is already on for video decode use\n", __func__); - } - - if(!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) { - //printk(KERN_ALERT "%s power on video decode\n", __func__); - deviceID = gui32MRSTMSVDXDeviceID; - ospm_power_island_up(OSPM_VIDEO_DEC_ISLAND); - ospm_runtime_pm_msvdx_resume(gpDrmDevice); - psb_irq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND); - psb_irq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND); - } - else{ - //printk(KERN_ALERT "%s video decode is already on\n", __func__); - } - - break; - case OSPM_VIDEO_ENC_ISLAND: - if(!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) { - //printk(KERN_ALERT "%s power on display for video encode\n", __func__); - deviceID = gui32MRSTDisplayDeviceID; - ospm_resume_display(pdev); - psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); - psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); - } - else{ - //printk(KERN_ALERT "%s display is already on for video encode use\n", __func__); - } - - if(!ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND)) { - //printk(KERN_ALERT "%s power on video encode\n", __func__); - deviceID = gui32MRSTTOPAZDeviceID; - ospm_power_island_up(OSPM_VIDEO_ENC_ISLAND); - ospm_runtime_pm_topaz_resume(gpDrmDevice); - psb_irq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND); - psb_irq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND); - } - else{ - //printk(KERN_ALERT "%s video decode is already on\n", __func__); - } + case OSPM_VIDEO_DEC_ISLAND: + if(!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) { + //printk(KERN_ALERT "%s power on display for video decode use\n", __func__); + deviceID = gui32MRSTDisplayDeviceID; + ospm_resume_display(pdev); + psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); + psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); + } + else{ + //printk(KERN_ALERT "%s display is already on for video decode use\n", __func__); + } + + if(!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) { + //printk(KERN_ALERT "%s power on video decode\n", __func__); + deviceID = gui32MRSTMSVDXDeviceID; + ospm_power_island_up(OSPM_VIDEO_DEC_ISLAND); + ospm_runtime_pm_msvdx_resume(gpDrmDevice); + psb_irq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND); + psb_irq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND); + } + else{ + //printk(KERN_ALERT "%s video decode is already on\n", __func__); + } + + break; + case OSPM_VIDEO_ENC_ISLAND: + if(!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) { + //printk(KERN_ALERT "%s power on display for video encode\n", __func__); + deviceID = gui32MRSTDisplayDeviceID; + ospm_resume_display(pdev); + psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); + psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); + } + else{ + //printk(KERN_ALERT "%s display is already on for video encode use\n", __func__); + } + + if(!ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND)) { + //printk(KERN_ALERT "%s power on video encode\n", __func__); + deviceID = gui32MRSTTOPAZDeviceID; + ospm_power_island_up(OSPM_VIDEO_ENC_ISLAND); + ospm_runtime_pm_topaz_resume(gpDrmDevice); + psb_irq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND); + psb_irq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND); + } + else{ + //printk(KERN_ALERT "%s video decode is already on\n", __func__); + } #endif break; @@ -1901,10 +1941,10 @@ bool ospm_power_using_hw_begin(int hw_island, bool force_on) break; case OSPM_VIDEO_ENC_ISLAND: atomic_inc(&g_videoenc_access_count); - break; + break; case OSPM_VIDEO_DEC_ISLAND: atomic_inc(&g_videodec_access_count); - break; + break; case OSPM_DISPLAY_ISLAND: atomic_inc(&g_display_access_count); break; @@ -1938,10 +1978,10 @@ void ospm_power_using_hw_end(int hw_island) break; case OSPM_VIDEO_ENC_ISLAND: atomic_dec(&g_videoenc_access_count); - break; + break; case OSPM_VIDEO_DEC_ISLAND: atomic_dec(&g_videodec_access_count); - break; + break; case OSPM_DISPLAY_ISLAND: atomic_dec(&g_display_access_count); break; @@ -1990,10 +2030,9 @@ int psb_runtime_resume(struct device *dev) int psb_runtime_idle(struct device *dev) { struct drm_psb_private* dev_priv = gpDrmDevice->dev_private; - //printk(KERN_ALERT "Mrst Runtime PM: %s \n", __func__); #if 1 - int msvdx_hw_busy = 1; - int topaz_hw_busy = 1; + int msvdx_hw_busy = 0; + int topaz_hw_busy = 0; msvdx_hw_busy = ospm_runtime_check_msvdx_hw_busy(gpDrmDevice); topaz_hw_busy = ospm_runtime_check_topaz_hw_busy(gpDrmDevice); -- 1.7.1 _______________________________________________ MeeGo-kernel mailing list [email protected] http://lists.meego.com/listinfo/meego-kernel
