[Intel-gfx] [RFC PATCH 2/2] drm/i915: Use the igd_update_wm to update watermark on IGD
yakui.zhao at intel.com
yakui.zhao at intel.com
Fri Dec 4 16:01:05 CET 2009
From: Zhao Yakui <yakui.zhao at intel.com>
Use the igd_update_wm to update the watermark on IGD. In such case only one
function is used, in which it will calculate the self-refresh watermark when
only one single display plane is used. If more than one display plane is used,
we will calculate the watermark for display plane/cursor.
Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 204 +++++++++++++++++++++-------------
1 files changed, 125 insertions(+), 79 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index fa7531f..5577976 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2403,78 +2403,6 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb,
return NULL;
}
-static void igd_disable_cxsr(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 reg;
-
- /* deactivate cxsr */
- reg = I915_READ(DSPFW3);
- reg &= ~(IGD_SELF_REFRESH_EN);
- I915_WRITE(DSPFW3, reg);
- DRM_INFO("Big FIFO is disabled\n");
-}
-
-static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock,
- int pixel_size)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 reg;
- unsigned long wm;
- struct cxsr_latency *latency;
-
- latency = intel_get_cxsr_latency(IS_IGDG(dev), dev_priv->fsb_freq,
- dev_priv->mem_freq);
- if (!latency) {
- DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
- igd_disable_cxsr(dev);
- return;
- }
-
- /* Display SR */
- wm = intel_calculate_wm(clock, &igd_display_wm, pixel_size,
- latency->display_sr);
- reg = I915_READ(DSPFW1);
- reg &= 0x7fffff;
- reg |= wm << 23;
- I915_WRITE(DSPFW1, reg);
- DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg);
-
- /* cursor SR */
- wm = intel_calculate_wm(clock, &igd_cursor_wm, pixel_size,
- latency->cursor_sr);
- reg = I915_READ(DSPFW3);
- reg &= ~(0x3f << 24);
- reg |= (wm & 0x3f) << 24;
- I915_WRITE(DSPFW3, reg);
-
- /* Display HPLL off SR */
- wm = intel_calculate_wm(clock, &igd_display_hplloff_wm,
- latency->display_hpll_disable, I915_FIFO_LINE_SIZE);
- reg = I915_READ(DSPFW3);
- reg &= 0xfffffe00;
- reg |= wm & 0x1ff;
- I915_WRITE(DSPFW3, reg);
-
- /* cursor HPLL off SR */
- wm = intel_calculate_wm(clock, &igd_cursor_hplloff_wm, pixel_size,
- latency->cursor_hpll_disable);
- reg = I915_READ(DSPFW3);
- reg &= ~(0x3f << 16);
- reg |= (wm & 0x3f) << 16;
- I915_WRITE(DSPFW3, reg);
- DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg);
-
- /* activate cxsr */
- reg = I915_READ(DSPFW3);
- reg |= IGD_SELF_REFRESH_EN;
- I915_WRITE(DSPFW3, reg);
-
- DRM_INFO("Big FIFO is enabled\n");
-
- return;
-}
-
/*
* Latency for FIFO fetches is dependent on several factors:
* - memory configuration (speed, channels)
@@ -2559,6 +2487,127 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane)
return size;
}
+static void igd_update_wm(struct drm_device *dev, int planea_clock,
+ int planeb_clock, int sr_hdisplay, int pixel_size)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 reg;
+ unsigned long wm;
+ struct cxsr_latency *latency;
+ int sr_clock;
+ struct intel_watermark_params planea_params, planeb_params;
+ int planea_wm, planeb_wm, cursora_wm, cursorb_wm;
+
+ latency = intel_get_cxsr_latency(IS_IGDG(dev), dev_priv->fsb_freq,
+ dev_priv->mem_freq);
+ if (!latency) {
+ DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
+ /* deactivate cxsr */
+ reg = I915_READ(DSPFW3);
+ reg &= ~(IGD_SELF_REFRESH_EN);
+ I915_WRITE(DSPFW3, reg);
+ return;
+ }
+
+ planea_params = planeb_params = i945_wm_info;
+ /* Update the fifo size /max_wm for display plane A */
+ planea_params.fifo_size =
+ dev_priv->display.get_fifo_size(dev, 0);
+ planea_params.max_wm = planea_params.fifo_size / 2;
+ /* update the fifo size/max_wm for display plane B */
+ planeb_params.fifo_size =
+ dev_priv->display.get_fifo_size(dev, 1);
+ planeb_params.max_wm = planeb_params.fifo_size / 2;
+
+ /*
+ * We calculate the watermark for every display plane by using the
+ * function of intel_calculate_wm.
+ * We don't touch the watermark for display C.
+ * In theory we can also use the intel_calculate_wm to get the
+ * cursor watermark. But now we use the fixed value.
+ * cursora_wm = 16
+ * cursorb_wm = 16
+ */
+ if (planea_clock)
+ planea_wm = intel_calculate_wm(planea_clock, &planea_params,
+ pixel_size, latency_ns);
+ else
+ planea_wm = 15;
+
+ if (planeb_clock)
+ planeb_wm = intel_calculate_wm(planeb_clock, &planeb_params,
+ pixel_size, latency_ns);
+ else
+ planeb_wm = 15;
+
+ cursora_wm = 16;
+ cursorb_wm = 16;
+
+ reg = I915_READ(DSPFW1);
+ reg &= ~(0x7F | (0x7F << 8) | (0x3F << 16));
+ reg |= (planea_wm | (planeb_wm << 8) | (cursorb_wm << 16));
+ I915_WRITE(DSPFW1, reg);
+
+ reg = I915_READ(DSPFW2);
+ reg &= ~(0x3f << 8);
+ reg |= (cursora_wm << 8);
+ I915_WRITE(DSPFW2, reg);
+
+ /*
+ * If both planea_clock and planeb_clock are effective, it means that
+ * the two planes are used. In such case it is unnecessary to touch
+ * the self-refresh watermark. Instead we should configure the correct
+ * watermark for display/cursor.
+ */
+
+ if (!planea_clock || !planeb_clock) {
+ sr_clock = planea_clock ? planea_clock : planeb_clock;
+
+ /* Display SR */
+ wm = intel_calculate_wm(sr_clock, &igd_display_wm, pixel_size,
+ latency->display_sr);
+ reg = I915_READ(DSPFW1);
+ reg &= 0x7fffff;
+ reg |= wm << 23;
+ I915_WRITE(DSPFW1, reg);
+ DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg);
+
+ /* cursor SR */
+ wm = intel_calculate_wm(sr_clock, &igd_cursor_wm, pixel_size,
+ latency->cursor_sr);
+ reg = I915_READ(DSPFW3);
+ reg &= ~(0x3f << 24);
+ reg |= (wm & 0x3f) << 24;
+ I915_WRITE(DSPFW3, reg);
+
+ /* Display HPLL off SR */
+ wm = intel_calculate_wm(sr_clock, &igd_display_hplloff_wm,
+ latency->display_hpll_disable, I915_FIFO_LINE_SIZE);
+ reg = I915_READ(DSPFW3);
+ reg &= 0xfffffe00;
+ reg |= wm & 0x1ff;
+ I915_WRITE(DSPFW3, reg);
+
+ /* cursor HPLL off SR */
+ wm = intel_calculate_wm(sr_clock, &igd_cursor_hplloff_wm,
+ pixel_size, latency->cursor_hpll_disable);
+ reg = I915_READ(DSPFW3);
+ reg &= ~(0x3f << 16);
+ reg |= (wm & 0x3f) << 16;
+ I915_WRITE(DSPFW3, reg);
+ DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg);
+
+ /* activate cxsr */
+ reg = I915_READ(DSPFW3);
+ reg |= IGD_SELF_REFRESH_EN;
+ I915_WRITE(DSPFW3, reg);
+
+ DRM_DEBUG_KMS("Big FIFO is enabled\n");
+ }
+ return;
+
+}
+
static void g4x_update_wm(struct drm_device *dev, int planea_clock,
int planeb_clock, int sr_hdisplay, int pixel_size)
{
@@ -2825,12 +2874,6 @@ static void intel_update_watermarks(struct drm_device *dev)
if (enabled <= 0)
return;
- /* Single plane configs can enable self refresh */
- if (enabled == 1 && IS_IGD(dev))
- igd_enable_cxsr(dev, sr_clock, pixel_size);
- else if (IS_IGD(dev))
- igd_disable_cxsr(dev);
-
dev_priv->display.update_wm(dev, planea_clock, planeb_clock,
sr_hdisplay, pixel_size);
}
@@ -4692,7 +4735,10 @@ static void intel_init_display(struct drm_device *dev)
i830_get_display_clock_speed;
/* For FIFO watermark updates */
- if (IS_IGDNG(dev))
+ if (IS_IGD(dev)) {
+ dev_priv->display.update_wm = igd_update_wm;
+ dev_priv->display.get_fifo_size = i9xx_get_fifo_size;
+ } else if (IS_IGDNG(dev))
dev_priv->display.update_wm = NULL;
else if (IS_G4X(dev))
dev_priv->display.update_wm = g4x_update_wm;
--
1.5.4.5
More information about the Intel-gfx
mailing list