[Intel-gfx] [PATCH v2 3/9] drm/i915: Redefine the parameters of update_wm callback function
yakui.zhao at intel.com
yakui.zhao at intel.com
Wed Jan 20 10:41:12 CET 2010
From: Zhao Yakui <yakui.zhao at intel.com>
When we calculate the display plane/cursor self-refresh watermark, we will
use another parameter to calculate the line_time. For example: htotal
So we will redefine the parameters of update_wm callback function.
Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
Reviewd-by: Jesse Barnes <jbarnes at virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_drv.h | 6 +-
drivers/gpu/drm/i915/intel_display.c | 150 ++++++++++++++++++++++------------
2 files changed, 103 insertions(+), 53 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a9e571f..e070dc9 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -160,8 +160,10 @@ struct drm_i915_display_funcs {
void (*disable_fbc)(struct drm_device *dev);
int (*get_display_clock_speed)(struct drm_device *dev);
int (*get_fifo_size)(struct drm_device *dev, int plane);
- void (*update_wm)(struct drm_device *dev, int planea_clock,
- int planeb_clock, int sr_hdisplay, int pixel_size);
+ void (*update_wm)(struct drm_device *dev,
+ struct drm_display_mode *modea_clock,
+ struct drm_display_mode *modeb_clock,
+ int pixel_size);
/* clock updates for mode set */
/* cursor updates */
/* render clock increase/decrease */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a04ccec..43ec351 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2396,8 +2396,10 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane)
return size;
}
-static void pineview_update_wm(struct drm_device *dev, int planea_clock,
- int planeb_clock, int sr_hdisplay, int pixel_size)
+static void pineview_update_wm(struct drm_device *dev,
+ struct drm_display_mode *crtc_modea,
+ struct drm_display_mode *crtc_modeb,
+ int pixel_size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 reg;
@@ -2433,15 +2435,15 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock,
* function of intel_calculate_wm.
* We don't touch the watermark for display C.
*/
- if (planea_clock)
- planea_wm = intel_calculate_wm(planea_clock, &planea_params,
- pixel_size, latency_ns);
+ if (crtc_modea->clock)
+ planea_wm = intel_calculate_wm(crtc_modea->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);
+ if (crtc_modeb->clock)
+ planeb_wm = intel_calculate_wm(crtc_modeb->clock,
+ &planeb_params, pixel_size, latency_ns);
else
planeb_wm = 15;
@@ -2465,9 +2467,12 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock,
* watermark for display/cursor.
*/
- if (!planea_clock || !planeb_clock) {
- sr_clock = planea_clock ? planea_clock : planeb_clock;
-
+ if (!crtc_modea->clock || !crtc_modeb->clock) {
+ if (crtc_modea->clock) {
+ sr_clock = crtc_modea->clock;
+ } else {
+ sr_clock = crtc_modeb->clock;
+ }
/* Display SR */
wm = intel_calculate_wm(sr_clock, &pineview_display_wm,
pixel_size, latency->display_sr);
@@ -2513,15 +2518,17 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock,
}
-static void g4x_update_wm(struct drm_device *dev, int planea_clock,
- int planeb_clock, int sr_hdisplay, int pixel_size)
+static void g4x_update_wm(struct drm_device *dev,
+ struct drm_display_mode *crtc_modea,
+ struct drm_display_mode *crtc_modeb,
+ int pixel_size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int total_size, cacheline_size;
int planea_wm, planeb_wm, cursora_wm, cursorb_wm, cursor_sr;
struct intel_watermark_params planea_params, planeb_params;
unsigned long line_time_us;
- int sr_clock, sr_entries = 0, entries_required;
+ int sr_clock, sr_entries = 0, entries_required, sr_hdisplay;
/* Create copies of the base settings for each pipe */
planea_params = planeb_params = g4x_wm_info;
@@ -2536,15 +2543,21 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock,
* clocks go from a few thousand to several hundred thousand.
* latency is usually a few thousand
*/
- entries_required = ((planea_clock / 1000) * pixel_size * latency_ns) /
- 1000;
- entries_required /= G4X_FIFO_LINE_SIZE;
- planea_wm = entries_required + planea_params.guard_size;
-
- entries_required = ((planeb_clock / 1000) * pixel_size * latency_ns) /
- 1000;
- entries_required /= G4X_FIFO_LINE_SIZE;
- planeb_wm = entries_required + planeb_params.guard_size;
+ if (crtc_modea->clock) {
+ entries_required = ((crtc_modea->clock / 1000) * pixel_size *
+ latency_ns) / 1000;
+ entries_required /= G4X_FIFO_LINE_SIZE;
+ planea_wm = entries_required + planea_params.guard_size;
+ } else
+ planea_wm = 16;
+
+ if (crtc_modeb->clock) {
+ entries_required = ((crtc_modeb->clock / 1000) * pixel_size *
+ latency_ns) / 1000;
+ entries_required /= G4X_FIFO_LINE_SIZE;
+ planeb_wm = entries_required + planeb_params.guard_size;
+ } else
+ planeb_wm = 16;
cursora_wm = cursorb_wm = 16;
cursor_sr = 32;
@@ -2552,11 +2565,16 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock,
DRM_DEBUG("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
/* Calc sr entries for one plane configs */
- if (sr_hdisplay && (!planea_clock || !planeb_clock)) {
+ if (!crtc_modea->clock || !crtc_modeb->clock) {
/* self-refresh has much higher latency */
static const int sr_latency_ns = 12000;
-
- sr_clock = planea_clock ? planea_clock : planeb_clock;
+ if (crtc_modea->clock) {
+ sr_clock = crtc_modea->clock;
+ sr_hdisplay = crtc_modea->hdisplay;
+ } else {
+ sr_clock = crtc_modeb->clock;
+ sr_hdisplay = crtc_modeb->hdisplay;
+ }
line_time_us = ((sr_hdisplay * 1000) / sr_clock);
/* Use ns/us then divide to preserve precision */
@@ -2583,19 +2601,28 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock,
(cursor_sr << DSPFW_CURSOR_SR_SHIFT));
}
-static void i965_update_wm(struct drm_device *dev, int planea_clock,
- int planeb_clock, int sr_hdisplay, int pixel_size)
+static void i965_update_wm(struct drm_device *dev,
+ struct drm_display_mode *crtc_modea,
+ struct drm_display_mode *crtc_modeb,
+ int pixel_size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long line_time_us;
- int sr_clock, sr_entries, srwm = 1;
+ int sr_clock, sr_entries, srwm = 1, sr_hdisplay;
/* Calc sr entries for one plane configs */
- if (sr_hdisplay && (!planea_clock || !planeb_clock)) {
+ if (!crtc_modea->clock || !crtc_modeb->clock) {
/* self-refresh has much higher latency */
static const int sr_latency_ns = 12000;
- sr_clock = planea_clock ? planea_clock : planeb_clock;
+ if (crtc_modea->clock) {
+ sr_hdisplay = crtc_modea->hdisplay;
+ sr_clock = crtc_modea->clock;
+ } else {
+ sr_hdisplay = crtc_modeb->hdisplay;
+ sr_clock = crtc_modeb->clock;
+ }
+
line_time_us = ((sr_hdisplay * 1000) / sr_clock);
/* Use ns/us then divide to preserve precision */
@@ -2619,8 +2646,10 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock,
I915_WRITE(DSPFW2, (8 << 8) | (8 << 0));
}
-static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
- int planeb_clock, int sr_hdisplay, int pixel_size)
+static void i9xx_update_wm(struct drm_device *dev,
+ struct drm_display_mode *crtc_modea,
+ struct drm_display_mode *crtc_modeb,
+ int pixel_size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t fwater_lo;
@@ -2629,7 +2658,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
int planea_wm, planeb_wm;
struct intel_watermark_params planea_params, planeb_params;
unsigned long line_time_us;
- int sr_clock, sr_entries = 0;
+ int sr_clock, sr_hdisplay, sr_entries = 0;
/* Create copies of the base settings for each pipe */
if (IS_I965GM(dev) || IS_I945GM(dev))
@@ -2647,10 +2676,17 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
planea_params.fifo_size = dev_priv->display.get_fifo_size(dev, 0);
planeb_params.fifo_size = dev_priv->display.get_fifo_size(dev, 1);
- planea_wm = intel_calculate_wm(planea_clock, &planea_params,
- pixel_size, latency_ns);
- planeb_wm = intel_calculate_wm(planeb_clock, &planeb_params,
- pixel_size, latency_ns);
+ if (crtc_modea->clock)
+ planea_wm = intel_calculate_wm(crtc_modea->clock,
+ &planea_params, pixel_size, latency_ns);
+ else
+ planea_wm = 8;
+
+ if (crtc_modeb->clock)
+ planeb_wm = intel_calculate_wm(crtc_modeb->clock,
+ &planeb_params, pixel_size, latency_ns);
+ else
+ planeb_wm = 8;
DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
/*
@@ -2659,12 +2695,19 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
cwm = 2;
/* Calc sr entries for one plane configs */
- if (HAS_FW_BLC(dev) && sr_hdisplay &&
- (!planea_clock || !planeb_clock)) {
+ if (HAS_FW_BLC(dev) &&
+ (!crtc_modea->clock || !crtc_modeb->clock)) {
/* self-refresh has much higher latency */
static const int sr_latency_ns = 6000;
- sr_clock = planea_clock ? planea_clock : planeb_clock;
+ if (crtc_modea->clock) {
+ sr_clock = crtc_modea->clock;
+ sr_hdisplay = crtc_modea->hdisplay;
+ } else {
+ sr_clock = crtc_modeb->clock;
+ sr_hdisplay = crtc_modeb->hdisplay;
+ }
+
line_time_us = ((sr_hdisplay * 1000) / sr_clock);
/* Use ns/us then divide to preserve precision */
@@ -2692,12 +2735,17 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
I915_WRITE(FW_BLC2, fwater_hi);
}
-static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused,
- int unused2, int pixel_size)
+static void i830_update_wm(struct drm_device *dev,
+ struct drm_display_mode *crtc_modea,
+ struct drm_display_mode *crtc_modeb,
+ int pixel_size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t fwater_lo = I915_READ(FW_BLC) & ~0xfff;
int planea_wm;
+ int planea_clock;
+
+ planea_clock = crtc_modea->clock;
i830_wm_info.fifo_size = dev_priv->display.get_fifo_size(dev, 0);
@@ -2746,13 +2794,14 @@ static void intel_update_watermarks(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc;
struct intel_crtc *intel_crtc;
- int sr_hdisplay = 0;
- unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0;
int enabled = 0, pixel_size = 0;
+ struct drm_display_mode crtc_modea, crtc_modeb;
if (!dev_priv->display.update_wm)
return;
+ memset(&crtc_modea, 0, sizeof(struct drm_display_mode));
+ memset(&crtc_modeb, 0, sizeof(struct drm_display_mode));
/* Get the clock config from both planes */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
intel_crtc = to_intel_crtc(crtc);
@@ -2761,14 +2810,14 @@ static void intel_update_watermarks(struct drm_device *dev)
if (intel_crtc->plane == 0) {
DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n",
intel_crtc->pipe, crtc->mode.clock);
- planea_clock = crtc->mode.clock;
+ memcpy(&crtc_modea, &crtc->mode,
+ sizeof(struct drm_display_mode));
} else {
DRM_DEBUG_KMS("plane B (pipe %d) clock: %d\n",
intel_crtc->pipe, crtc->mode.clock);
- planeb_clock = crtc->mode.clock;
+ memcpy(&crtc_modeb, &crtc->mode,
+ sizeof(struct drm_display_mode));
}
- sr_hdisplay = crtc->mode.hdisplay;
- sr_clock = crtc->mode.clock;
if (crtc->fb)
pixel_size = crtc->fb->bits_per_pixel / 8;
else
@@ -2779,8 +2828,7 @@ static void intel_update_watermarks(struct drm_device *dev)
if (enabled <= 0)
return;
- dev_priv->display.update_wm(dev, planea_clock, planeb_clock,
- sr_hdisplay, pixel_size);
+ dev_priv->display.update_wm(dev, &crtc_modea, &crtc_modeb, pixel_size);
}
static int intel_crtc_mode_set(struct drm_crtc *crtc,
--
1.5.4.5
More information about the Intel-gfx
mailing list