diff options
author | Zhao Yakui <yakui.zhao@intel.com> | 2012-03-29 15:31:24 -0400 |
---|---|---|
committer | root <root@localhost.localdomain> | 2012-03-29 16:29:06 -0400 |
commit | 4c0bce747b245f462d5868de4d9cc21eab03cc96 (patch) | |
tree | 39d86c001ce2b1646a86443637511982791b2467 | |
parent | a4d5e83ed3d261107b6ae235ab761975295eabad (diff) |
PVR_VIDEO: Remove the limitation that flipchain only works on Pipe B
Currently the flipchain is only allowed to work on the Pipe B. This is to remove
the above limitation. And it can also work on the Pipe A when only one pipe is
enabled.
Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
5 files changed, 64 insertions, 50 deletions
diff --git a/drivers/staging/cdv/drv/psb_drv.h b/drivers/staging/cdv/drv/psb_drv.h index 507856b6e31..4bc2849b067 100644 --- a/drivers/staging/cdv/drv/psb_drv.h +++ b/drivers/staging/cdv/drv/psb_drv.h @@ -770,6 +770,11 @@ struct drm_psb_private { void * ovl_buf; uint32_t ovl_offset; + uint32_t ui32MainPipe; + uint32_t pipeEnabled; + struct timer_list flip_timer; + int flip_counter; + struct backlight_device *backlight; int child_dev_num; struct child_device_config *child_dev; diff --git a/drivers/staging/cdv/drv/psb_intel_display.c b/drivers/staging/cdv/drv/psb_intel_display.c index 9ccb932dbfd..df86f171784 100644 --- a/drivers/staging/cdv/drv/psb_intel_display.c +++ b/drivers/staging/cdv/drv/psb_intel_display.c @@ -592,26 +592,30 @@ psb_intel_pipe_set_base_exit: } #define CRTC_FLIP_TIMEOUT 100 /* ms */ -#define LVDS_PIPEB 1 #define MAX_FLIP_COUNTER 100 -static void psb_crtc_flip_timer(unsigned long arg) + +#define CRTC_PIPEA 0 +#define CRTC_PIPEB 1 +#define PIPEA_ENABLED (1 << 0) +#define PIPEB_ENABLED (1 << 1) + +static void psb_flip_timer(unsigned long arg) { - struct psb_intel_crtc *psb_crtc = (struct psb_intel_crtc *)arg; - struct drm_crtc *crtc = &psb_crtc->base; - struct drm_psb_private *dev_priv = - (struct drm_psb_private *)(crtc->dev->dev_private); + struct drm_device *dev = (struct drm_device *) arg; + struct drm_psb_private *dev_priv = (struct drm_psb_private *)(dev->dev_private); if (dev_priv->psb_vsync_handler) - (dev_priv->psb_vsync_handler)(crtc->dev, psb_crtc->pipe); + (dev_priv->psb_vsync_handler)(dev, dev_priv->ui32MainPipe); - psb_crtc->flip_counter--; - if (dev_priv->vblanksEnabledForFlips && !psb_crtc->crtc_enable && - psb_crtc->flip_counter) { - mod_timer(&psb_crtc->flip_timer, jiffies + + dev_priv->flip_counter--; + if (dev_priv->vblanksEnabledForFlips && !dev_priv->pipeEnabled && + dev_priv->flip_counter) { + mod_timer(&dev_priv->flip_timer, jiffies + msecs_to_jiffies(CRTC_FLIP_TIMEOUT)); } } + /** * Sets the power management mode of the pipe and plane. * @@ -631,6 +635,7 @@ static void psb_intel_crtc_dpms(struct drm_crtc *crtc, int mode) int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; int pipestat_reg = (pipe == 0) ? PIPEASTAT : PIPEBSTAT; u32 temp; + u32 target_pipe; /* XXX: When our outputs are all unaware of DPMS modes other than off * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. @@ -693,6 +698,7 @@ static void psb_intel_crtc_dpms(struct drm_crtc *crtc, int mode) psb_intel_crtc_load_lut(crtc); + dev_priv->pipeEnabled |= (1 << pipe); /* Give the overlay scaler a chance to enable * if it's on this pipe */ /* psb_intel_crtc_dpms_video(crtc, true); TODO */ @@ -749,20 +755,37 @@ static void psb_intel_crtc_dpms(struct drm_crtc *crtc, int mode) psb_intel_update_watermark(dev, crtc); + dev_priv->pipeEnabled &= ~(1 << pipe); break; } - + + if ((dev_priv->pipeEnabled == PIPEA_ENABLED) || + (dev_priv->pipeEnabled == PIPEB_ENABLED)) { + target_pipe = CRTC_PIPEA; + if (dev_priv->pipeEnabled == PIPEB_ENABLED) + target_pipe = CRTC_PIPEB; + } else { + target_pipe = CRTC_PIPEB; + } + if (target_pipe != dev_priv->ui32MainPipe) { + DRM_DEBUG_KMS("Main flip pipe is switched from %d to %d\n", + dev_priv->ui32MainPipe, target_pipe); + if (dev_priv->vblanksEnabledForFlips) { + if (!dev->vblank_enabled[dev_priv->ui32MainPipe]) + psb_disable_vblank(dev, dev_priv->ui32MainPipe); + psb_enable_vblank(dev, target_pipe); + } + dev_priv->ui32MainPipe = target_pipe; + } if (mode == DRM_MODE_DPMS_OFF) { - psb_intel_crtc->crtc_enable = false; - if (dev_priv->vblanksEnabledForFlips && (psb_intel_crtc->pipe == LVDS_PIPEB)) { - psb_intel_crtc->flip_counter = MAX_FLIP_COUNTER; - mod_timer(&psb_intel_crtc->flip_timer, jiffies + + if (dev_priv->vblanksEnabledForFlips && !dev_priv->pipeEnabled) { + dev_priv->flip_counter = MAX_FLIP_COUNTER; + mod_timer(&dev_priv->flip_timer, jiffies + msecs_to_jiffies(CRTC_FLIP_TIMEOUT)); } } else { - psb_intel_crtc->crtc_enable = true; - psb_intel_crtc->flip_counter = 0; - del_timer(&psb_intel_crtc->flip_timer); + dev_priv->flip_counter = 0; + del_timer(&dev_priv->flip_timer); } } @@ -1650,10 +1673,12 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe, psb_intel_cursor_init(dev, pipe); - init_timer(&psb_intel_crtc->flip_timer); - psb_intel_crtc->flip_timer.function = psb_crtc_flip_timer; - psb_intel_crtc->flip_timer.data = (unsigned long)psb_intel_crtc; - psb_intel_crtc->crtc_enable = false; + if (pipe == 0) { + init_timer(&dev_priv->flip_timer); + dev_priv->flip_timer.function = psb_flip_timer; + dev_priv->flip_timer.data = (unsigned long)dev; + dev_priv->pipeEnabled = 0; + } } int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, @@ -1714,14 +1739,9 @@ int psb_intel_connector_clones(struct drm_device *dev, int type_mask) void psb_intel_modeset_cleanup(struct drm_device *dev) { - struct drm_crtc *crtc; - struct psb_intel_crtc *psb_intel_crtc; + struct drm_psb_private *dev_priv = dev->dev_private; - /* Shut off flip_timer before the crtcs get freed. */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - psb_intel_crtc = to_psb_intel_crtc(crtc); - del_timer_sync(&psb_intel_crtc->flip_timer); - } + del_timer_sync(&dev_priv->flip_timer); drm_mode_config_cleanup(dev); } diff --git a/drivers/staging/cdv/drv/psb_intel_drv.h b/drivers/staging/cdv/drv/psb_intel_drv.h index cb9540f1fce..8ece01f53aa 100644 --- a/drivers/staging/cdv/drv/psb_intel_drv.h +++ b/drivers/staging/cdv/drv/psb_intel_drv.h @@ -158,13 +158,6 @@ struct psb_intel_crtc { /* a mode_set for fbdev users on this crtc */ struct drm_mode_set mode_set; - /* Add one flip timer that still can handle the flip operation - * when the pipe is disabled - */ - struct timer_list flip_timer; - int crtc_enable; - int flip_counter; - /* current bo we scanout from */ void *scanout_bo; diff --git a/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_displayclass.c b/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_displayclass.c index 423a9bd171b..2b7fa83f282 100644 --- a/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_displayclass.c +++ b/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_displayclass.c @@ -618,12 +618,6 @@ static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice, UNREFERENCED_PARAMETER(ui32Flags); - /* If we can't enable the vblank on the corresponding pipe, - * don't create the DC swap chain - */ - if (psb_enable_vblank(psDevInfo->psDrmDevice, psDevInfo->ui32MainPipe)) - return (PVRSRV_ERROR_NOT_SUPPORTED); - psSwapChain = (MRSTLFB_SWAPCHAIN*)MRSTLFBAllocKernelMem(sizeof(MRSTLFB_SWAPCHAIN)); if(!psSwapChain) @@ -1006,9 +1000,10 @@ ExitUnlock: static int MRSTLFBVSyncISR(struct drm_device *psDrmDevice, int iPipe) { - MRSTLFB_DEVINFO *psDevInfo = GetAnchorPtr(); - - if (iPipe == psDevInfo->ui32MainPipe) + MRSTLFB_DEVINFO *psDevInfo = GetAnchorPtr(); + struct drm_psb_private *dev_priv = psb_priv(psDrmDevice); + + if (iPipe == dev_priv->ui32MainPipe) MRSTLFBVSyncIHandler(psDevInfo); return 0; @@ -1342,7 +1337,8 @@ static MRST_ERROR InitDev(MRSTLFB_DEVINFO *psDevInfo) * Otherwise we will have to handle the scenario when the main pipe is switched. */ psDevInfo->ui32MainPipe = MRSTLFBFindMainPipe(psDevInfo->psDrmDevice); - psDevInfo->ui32MainPipe = 1; + psDrmPrivate->ui32MainPipe = psDevInfo->ui32MainPipe; + DRM_DEBUG_KMS("main pipe is %d\n", psDrmPrivate->ui32MainPipe); for(i = 0;i < MAX_SWAPCHAINS;++i) { diff --git a/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_linux.c b/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_linux.c index c0e8a8323a3..d33bfad2b88 100644 --- a/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_linux.c +++ b/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_linux.c @@ -105,7 +105,7 @@ void MRSTLFBEnableVSyncInterrupt(MRSTLFB_DEVINFO * psDevinfo) struct drm_psb_private *dev_priv = (struct drm_psb_private *) psDevinfo->psDrmDevice->dev_private; dev_priv->vblanksEnabledForFlips = true; - psb_enable_vblank(psDevinfo->psDrmDevice, psDevinfo->ui32MainPipe); + psb_enable_vblank(psDevinfo->psDrmDevice, dev_priv->ui32MainPipe); #endif } @@ -116,8 +116,8 @@ void MRSTLFBDisableVSyncInterrupt(MRSTLFB_DEVINFO * psDevinfo) struct drm_psb_private *dev_priv = (struct drm_psb_private *) psDevinfo->psDrmDevice->dev_private; dev_priv->vblanksEnabledForFlips = false; - if (!dev->vblank_enabled[psDevinfo->ui32MainPipe]) - psb_disable_vblank(psDevinfo->psDrmDevice, psDevinfo->ui32MainPipe); + if (!dev->vblank_enabled[dev_priv->ui32MainPipe]) + psb_disable_vblank(psDevinfo->psDrmDevice, dev_priv->ui32MainPipe); #endif } |