From patchwork Wed Jan 20 09:41:12 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhao, Yakui" X-Patchwork-Id: 74023 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id o0K9ggjj013870 for ; Wed, 20 Jan 2010 09:42:42 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F00729EF54; Wed, 20 Jan 2010 01:42:41 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTP id 3E7F79E7F2 for ; Wed, 20 Jan 2010 01:42:36 -0800 (PST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP; 20 Jan 2010 01:42:04 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.49,309,1262592000"; d="scan'208";a="765729738" Received: from yakui_zhao.sh.intel.com (HELO localhost.localdomain) ([10.239.13.83]) by fmsmga001.fm.intel.com with ESMTP; 20 Jan 2010 01:42:35 -0800 From: yakui.zhao@intel.com To: eric@anholt.net Date: Wed, 20 Jan 2010 17:41:12 +0800 Message-Id: <1263980478-18338-4-git-send-email-yakui.zhao@intel.com> X-Mailer: git-send-email 1.5.4.5 In-Reply-To: <1263980478-18338-3-git-send-email-yakui.zhao@intel.com> References: <1263980478-18338-1-git-send-email-yakui.zhao@intel.com> <1263980478-18338-2-git-send-email-yakui.zhao@intel.com> <1263980478-18338-3-git-send-email-yakui.zhao@intel.com> Cc: intel-gfx@lists.freedesktop.org Subject: [Intel-gfx] [PATCH v2 3/9] drm/i915: Redefine the parameters of update_wm callback function X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.9 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org 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,