summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugeni Dodonov <eugeni.dodonov@intel.com>2012-05-09 15:37:24 -0300
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-05-19 22:39:49 +0200
commit1f8eeabf2e6f4a6cb5afe9e90d2a705e9709f1a1 (patch)
tree47fe6297ab6872b5d3491474f2e86b6b3683c3b9
parent6b8a5eeb9f428becc88adef148518ed07bf06d02 (diff)
downloadlinux-1f8eeabf2e6f4a6cb5afe9e90d2a705e9709f1a1.tar.gz
linux-1f8eeabf2e6f4a6cb5afe9e90d2a705e9709f1a1.tar.xz
linux-1f8eeabf2e6f4a6cb5afe9e90d2a705e9709f1a1.zip
drm/i915: program WM_LINETIME on Haswell
The line time can be programmed according to the number of horizontal pixels vs effective pixel rate ratio. v2: improve comment as per Chris Wilson suggestion v3: incorporate latest changes in specs. v4: move into wm update routine, also mention that the same routine can program IPS watermarks. We do not have their enablement code yet, nor handle the required clock settings at the moment, so this patch won't program those values for now. Signed-off-by: Eugeni Dodonov <eugeni.dodonov@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_display.c2
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c37
4 files changed, 43 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e03a4f80c5c9..83a557c7bcc5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -243,6 +243,8 @@ struct drm_i915_display_funcs {
void (*update_sprite_wm)(struct drm_device *dev, int pipe,
uint32_t sprite_width, int pixel_size);
void (*sanitize_pm)(struct drm_device *dev);
+ void (*update_linetime_wm)(struct drm_device *dev, int pipe,
+ struct drm_display_mode *mode);
int (*crtc_mode_set)(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 39f122b3ce70..fb3f4aaca2c4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4609,6 +4609,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
intel_update_watermarks(dev);
+ intel_update_linetime_watermarks(dev, pipe, adjusted_mode);
+
return ret;
}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a5bb5b6ebb4f..0ad1bb383976 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -454,6 +454,8 @@ extern void intel_update_watermarks(struct drm_device *dev);
extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe,
uint32_t sprite_width,
int pixel_size);
+extern void intel_update_linetime_watermarks(struct drm_device *dev, int pipe,
+ struct drm_display_mode *mode);
extern int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 452a9bce8162..8f8d1daf1cac 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1883,6 +1883,33 @@ static void sandybridge_update_wm(struct drm_device *dev)
cursor_wm);
}
+static void
+haswell_update_linetime_wm(struct drm_device *dev, int pipe,
+ struct drm_display_mode *mode)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 temp;
+
+ temp = I915_READ(PIPE_WM_LINETIME(pipe));
+ temp &= ~PIPE_WM_LINETIME_MASK;
+
+ /* The WM are computed with base on how long it takes to fill a single
+ * row at the given clock rate, multiplied by 8.
+ * */
+ temp |= PIPE_WM_LINETIME_TIME(
+ ((mode->crtc_hdisplay * 1000) / mode->clock) * 8);
+
+ /* IPS watermarks are only used by pipe A, and are ignored by
+ * pipes B and C. They are calculated similarly to the common
+ * linetime values, except that we are using CD clock frequency
+ * in MHz instead of pixel rate for the division.
+ *
+ * This is a placeholder for the IPS watermark calculation code.
+ */
+
+ I915_WRITE(PIPE_WM_LINETIME(pipe), temp);
+}
+
static bool
sandybridge_compute_sprite_wm(struct drm_device *dev, int plane,
uint32_t sprite_width, int pixel_size,
@@ -2078,6 +2105,15 @@ void intel_update_watermarks(struct drm_device *dev)
dev_priv->display.update_wm(dev);
}
+void intel_update_linetime_watermarks(struct drm_device *dev,
+ int pipe, struct drm_display_mode *mode)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (dev_priv->display.update_linetime_wm)
+ dev_priv->display.update_linetime_wm(dev, pipe, mode);
+}
+
void intel_update_sprite_watermarks(struct drm_device *dev, int pipe,
uint32_t sprite_width, int pixel_size)
{
@@ -3689,6 +3725,7 @@ void intel_init_pm(struct drm_device *dev)
if (SNB_READ_WM0_LATENCY()) {
dev_priv->display.update_wm = sandybridge_update_wm;
dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm;
+ dev_priv->display.update_linetime_wm = haswell_update_linetime_wm;
} else {
DRM_DEBUG_KMS("Failed to read display plane latency. "
"Disable CxSR\n");