From patchwork Fri Jul 5 08:57:34 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 2824057 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 5ABDB9F3C3 for ; Fri, 5 Jul 2013 09:08:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id F127620158 for ; Fri, 5 Jul 2013 09:08:32 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 06DF320138 for ; Fri, 5 Jul 2013 09:08:32 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 008B3E673D for ; Fri, 5 Jul 2013 02:08:32 -0700 (PDT) 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 90CA5E6749 for ; Fri, 5 Jul 2013 01:59:07 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 05 Jul 2013 02:00:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="4.87,1000,1363158000"; d="scan'208"; a="365641313" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.168]) by fmsmga002.fm.intel.com with SMTP; 05 Jul 2013 01:59:05 -0700 Received: by stinkbox (sSMTP sendmail emulation); Fri, 05 Jul 2013 11:59:04 +0300 From: ville.syrjala@linux.intel.com To: intel-gfx@lists.freedesktop.org Date: Fri, 5 Jul 2013 11:57:34 +0300 Message-Id: <1373014667-19484-23-git-send-email-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 1.8.1.5 In-Reply-To: <1373014667-19484-1-git-send-email-ville.syrjala@linux.intel.com> References: <1373014667-19484-1-git-send-email-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH 22/35] drm/i915: Calculate max watermark levels for ILK+ X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ville Syrjälä There are quite a few variables we need to take into account to determine the maximum watermark levels, so it feels a bit cleaner to calculate those rather than just have a bunch of what look like magic numbers. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_pm.c | 119 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 107 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 2415bfa..2bdb0ae 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2247,6 +2247,104 @@ static uint32_t ilk_compute_fbc_wm(struct hsw_pipe_wm_parameters *params, params->pri_bytes_per_pixel); } +static unsigned int ilk_display_fifo_size(const struct drm_device *dev) +{ + if (INTEL_INFO(dev)->gen >= 7) + return 768; + else + return 512; +} + +/* Calculate the maximum primary/sprite plane watermark */ +static unsigned int ilk_plane_wm_max(const struct drm_device *dev, + int level, + unsigned int pipes_active, + bool sprite_enabled, + enum intel_ddb_partitioning ddb_partitioning, + bool is_sprite) +{ + unsigned int fifo_size = ilk_display_fifo_size(dev); + unsigned int max; + + /* if sprites aren't enabled, sprites get nothing */ + if (is_sprite && !sprite_enabled) + return 0; + + /* HSW allows LP1+ watermarks even with multiple pipes */ + if (level == 0 || pipes_active > 1) { + fifo_size /= INTEL_INFO(dev)->num_pipes; + + /* + * For some reason the non self refresh + * FIFO size is only half of the self + * refresh FIFO size on ILK/SNB. + */ + if (INTEL_INFO(dev)->gen <= 6) + fifo_size /= 2; + } + + if (sprite_enabled) { + /* level 0 is always calculated with 1:1 split */ + if (level > 0 && ddb_partitioning == INTEL_DDB_PART_5_6) { + if (is_sprite) + fifo_size *= 5; + fifo_size /= 6; + } else { + fifo_size /= 2; + } + } + + /* clamp to max that the registers can hold */ + if (INTEL_INFO(dev)->gen >= 7) + /* IVB/HSW primary/sprite plane watermarks */ + max = level == 0 ? 127 : 1023; + else if (!is_sprite) + /* ILK/SNB primary plane watermarks */ + max = level == 0 ? 127 : 511; + else + /* ILK/SNB sprite plane watermarks */ + max = level == 0 ? 63 : 255; + + return min(fifo_size, max); +} + +/* Calculate the maximum cursor plane watermark */ +static unsigned int ilk_cursor_wm_max(const struct drm_device *dev, + int level, unsigned int pipes_active) +{ + /* HSW LP1+ watermarks w/ multiple pipes */ + if (level > 0 && pipes_active > 1) + return 64; + + /* othwewise just report max that registers can hold */ + if (INTEL_INFO(dev)->gen >= 7) + return level == 0 ? 63 : 255; + else + return level == 0 ? 31 : 63; +} + +/* Calculate the maximum FBC watermark */ +static unsigned int ilk_fbc_wm_max(void) +{ + /* max that registers can hold */ + return 15; +} + +static void ilk_wm_max(struct drm_device *dev, + int level, + unsigned int pipes_active, + bool sprite_enabled, + enum intel_ddb_partitioning ddb_partitioning, + struct hsw_wm_maximums *max) +{ + max->pri = ilk_plane_wm_max(dev, level, pipes_active, + sprite_enabled, ddb_partitioning, false); + max->spr = ilk_plane_wm_max(dev, level, pipes_active, + sprite_enabled, ddb_partitioning, true); + max->cur = ilk_cursor_wm_max(dev, level, pipes_active); + max->fbc = ilk_fbc_wm_max(); +} + static bool ilk_check_wm(int level, const struct hsw_wm_maximums *max, struct intel_wm_level *result) @@ -2508,18 +2606,15 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, sprites_enabled++; } - if (pipes_active > 1) { - lp_max_1_2->pri = lp_max_5_6->pri = sprites_enabled ? 128 : 256; - lp_max_1_2->spr = lp_max_5_6->spr = 128; - lp_max_1_2->cur = lp_max_5_6->cur = 64; - } else { - lp_max_1_2->pri = sprites_enabled ? 384 : 768; - lp_max_5_6->pri = sprites_enabled ? 128 : 768; - lp_max_1_2->spr = 384; - lp_max_5_6->spr = 640; - lp_max_1_2->cur = lp_max_5_6->cur = 255; - } - lp_max_1_2->fbc = lp_max_5_6->fbc = 15; + ilk_wm_max(dev, 1, pipes_active, sprites_enabled, + INTEL_DDB_PART_1_2, lp_max_1_2); + + /* 5/6 split only in single pipe config on IVB+ */ + if (INTEL_INFO(dev)->gen >= 7 && pipes_active <= 1) + ilk_wm_max(dev, 1, pipes_active, sprites_enabled, + INTEL_DDB_PART_5_6, lp_max_5_6); + else + *lp_max_5_6 = *lp_max_1_2; } static void hsw_compute_wm_results(struct drm_device *dev,