summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2012-03-29 15:31:24 -0400
committerroot <root@localhost.localdomain>2012-03-29 16:29:06 -0400
commit4c0bce747b245f462d5868de4d9cc21eab03cc96 (patch)
tree39d86c001ce2b1646a86443637511982791b2467
parenta4d5e83ed3d261107b6ae235ab761975295eabad (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>
-rw-r--r--drivers/staging/cdv/drv/psb_drv.h5
-rw-r--r--drivers/staging/cdv/drv/psb_intel_display.c80
-rw-r--r--drivers/staging/cdv/drv/psb_intel_drv.h7
-rw-r--r--drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_displayclass.c16
-rw-r--r--drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_linux.c6
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
}