From patchwork Wed Jan 20 09:41:14 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhao, Yakui" X-Patchwork-Id: 74025 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 o0K9gjNW013883 for ; Wed, 20 Jan 2010 09:42:45 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6ED4D9EF5D; Wed, 20 Jan 2010 01:42:45 -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 0050E9EE25 for ; Wed, 20 Jan 2010 01:42:38 -0800 (PST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP; 20 Jan 2010 01:42:05 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.49,309,1262592000"; d="scan'208";a="765729744" 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:37 -0800 From: yakui.zhao@intel.com To: eric@anholt.net Date: Wed, 20 Jan 2010 17:41:14 +0800 Message-Id: <1263980478-18338-6-git-send-email-yakui.zhao@intel.com> X-Mailer: git-send-email 1.5.4.5 In-Reply-To: <1263980478-18338-5-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> <1263980478-18338-4-git-send-email-yakui.zhao@intel.com> <1263980478-18338-5-git-send-email-yakui.zhao@intel.com> Cc: intel-gfx@lists.freedesktop.org Subject: [Intel-gfx] [PATCH v2 5/9] drm/i915: Add a new method to calculate the required fifo entry size 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/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 167b35a..fbfe942 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2136,6 +2136,10 @@ enum wm_fifo_type { WM_USE_OFFSET = 0, WM_USE_ENTRY_COUNT, }; +enum wm_calc_method { + WM_USE_NORMAL = 0, + WM_USE_LARGE_BUFFER, +}; struct intel_watermark_params { unsigned long fifo_size; @@ -2224,10 +2228,11 @@ static struct intel_watermark_params i830_wm_info = { /** * intel_calculate_wm - calculate watermark level - * @clock_in_khz: pixel clock * @wm: chip FIFO params + * @crtc_mode: the display mode for the crtc * @pixel_size: display pixel size * @latency_ns: memory latency for the platform + * @calc_method: the used method to calculate the watermark * * Calculate the watermark level (the level at which the display plane will * start fetching from memory again). Each chip has a different display @@ -2239,23 +2244,50 @@ static struct intel_watermark_params i830_wm_info = { * fetching FIFO line sized based chunks from memory until the FIFO fills * past the watermark point. If the FIFO drains completely, a FIFO underrun * will occur, and a display engine hang could result. + * + * calc_method: This is to indicate which method is used to calculate the + * watermark. + * WM_USE_NORMAL is the normal calculation(called as small buffer). + * WM_USE_LARGE_BUFFER is the SR calculatiion (called as the large buffer). + * The normal calculation is: + * watermark = dotclock * bytes per pixel * latency + * where latency is platform & configuration dependent (we assume pessimal + * values here). + * + * The SR calculation is: + * watermark = (trunc(latency/line time)+1) * surface width * + * bytes per pixel + * where + * line time = htotal / dotclock + * */ -static unsigned long intel_calculate_wm(unsigned long clock_in_khz, - struct intel_watermark_params *wm, +static unsigned long intel_calculate_wm(struct intel_watermark_params *wm, + struct drm_display_mode *crtc_mode, int pixel_size, - unsigned long latency_ns) + unsigned long latency_ns, + enum wm_calc_method calc_method) { long entries_required, wm_size; - int sr_entries; + int sr_entries, hdisplay; + unsigned long line_time_us; + hdisplay = crtc_mode->hdisplay; /* * Note: we need to make sure we don't overflow for various clock & * latency values. * clocks go from a few thousand to several hundred thousand. * latency is usually a few thousand */ - entries_required = ((clock_in_khz / 1000) * pixel_size * latency_ns) / - 1000; + if (calc_method == WM_USE_LARGE_BUFFER) { + /* calculate the line time. The unit is us */ + line_time_us = (crtc_mode->htotal * 1000) / crtc_mode->clock; + + /* Use ns/us then divide to preserve precision */ + entries_required = (((latency_ns / line_time_us) + 1000) / + 1000) * pixel_size * hdisplay; + } else + entries_required = ((crtc_mode->clock / 1000) * pixel_size * + latency_ns) / 1000; /* Round up to the next cacheline boundary */ sr_entries = DIV_ROUND_UP(entries_required, wm->cacheline_size); @@ -2458,14 +2490,16 @@ static void pineview_update_wm(struct drm_device *dev, * We don't touch the watermark for display C. */ if (crtc_modea->clock) - planea_wm = intel_calculate_wm(crtc_modea->clock, - &planea_params, pixel_size, latency_ns); + planea_wm = intel_calculate_wm(&planea_params, crtc_modea, + pixel_size, latency_ns, + WM_USE_NORMAL); else planea_wm = 15; if (crtc_modeb->clock) - planeb_wm = intel_calculate_wm(crtc_modeb->clock, - &planeb_params, pixel_size, latency_ns); + planeb_wm = intel_calculate_wm(&planeb_params, crtc_modeb, + pixel_size, latency_ns, + WM_USE_NORMAL); else planeb_wm = 15; @@ -2490,14 +2524,18 @@ static void pineview_update_wm(struct drm_device *dev, */ if (!crtc_modea->clock || !crtc_modeb->clock) { + struct drm_display_mode *crtc_mode; if (crtc_modea->clock) { sr_clock = crtc_modea->clock; + crtc_mode = crtc_modea; } else { sr_clock = crtc_modeb->clock; + crtc_mode = crtc_modeb; } /* Display SR */ - wm = intel_calculate_wm(sr_clock, &pineview_display_wm, - pixel_size, latency->display_sr); + wm = intel_calculate_wm(&pineview_display_wm, crtc_mode, + pixel_size, latency->display_sr, + WM_USE_NORMAL); reg = I915_READ(DSPFW1); reg &= 0x7fffff; reg |= wm << 23; @@ -2505,24 +2543,28 @@ static void pineview_update_wm(struct drm_device *dev, DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg); /* cursor SR */ - wm = intel_calculate_wm(sr_clock, &pineview_cursor_wm, - pixel_size, latency->cursor_sr); + wm = intel_calculate_wm(&pineview_cursor_wm, crtc_mode, + pixel_size, latency->cursor_sr, + WM_USE_NORMAL); 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, &pineview_display_hplloff_wm, - pixel_size, latency->display_hpll_disable); + wm = intel_calculate_wm(&pineview_display_hplloff_wm, + crtc_mode, pixel_size, + latency->display_hpll_disable, + WM_USE_NORMAL); reg = I915_READ(DSPFW3); reg &= 0xfffffe00; reg |= wm & 0x1ff; I915_WRITE(DSPFW3, reg); /* cursor HPLL off SR */ - wm = intel_calculate_wm(sr_clock, &pineview_cursor_hplloff_wm, - pixel_size, latency->cursor_hpll_disable); + wm = intel_calculate_wm(&pineview_cursor_hplloff_wm, crtc_mode, + pixel_size, latency->cursor_hpll_disable, + WM_USE_NORMAL); reg = I915_READ(DSPFW3); reg &= ~(0x3f << 16); reg |= (wm & 0x3f) << 16; @@ -2699,14 +2741,16 @@ static void i9xx_update_wm(struct drm_device *dev, planeb_params.fifo_size = dev_priv->display.get_fifo_size(dev, 1); if (crtc_modea->clock) - planea_wm = intel_calculate_wm(crtc_modea->clock, - &planea_params, pixel_size, latency_ns); + planea_wm = intel_calculate_wm(&planea_params, crtc_modea, + pixel_size, latency_ns, + WM_USE_NORMAL); else planea_wm = 8; if (crtc_modeb->clock) - planeb_wm = intel_calculate_wm(crtc_modeb->clock, - &planeb_params, pixel_size, latency_ns); + planeb_wm = intel_calculate_wm(&planeb_params, crtc_modeb, + pixel_size, latency_ns, + WM_USE_NORMAL); else planeb_wm = 8; DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); @@ -2771,8 +2815,9 @@ static void i830_update_wm(struct drm_device *dev, i830_wm_info.fifo_size = dev_priv->display.get_fifo_size(dev, 0); - planea_wm = intel_calculate_wm(planea_clock, &i830_wm_info, - pixel_size, latency_ns); + planea_wm = intel_calculate_wm(&i830_wm_info, crtc_modea, + pixel_size, latency_ns, + WM_USE_NORMAL); fwater_lo |= (3<<8) | planea_wm; DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d\n", planea_wm);