| From de594f8178a74406d1b7947e8adeb574821c7925 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> |
| Date: Wed, 7 Aug 2013 13:28:19 +0300 |
| Subject: drm/i915: Calculate max watermark levels for ILK+ |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| 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. |
| |
| v2: s/pipes_active/num_pipes_active |
| s/othwewise/otherwise |
| |
| Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> |
| Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> |
| Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| (cherry picked from commit 158ae64f820939473012dacfc0ae1ec782b45b60) |
| Signed-off-by: Darren Hart <dvhart@linux.intel.com> |
| --- |
| 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 d10d4c717b4a..5daa32a4e864 100644 |
| --- a/drivers/gpu/drm/i915/intel_pm.c |
| +++ b/drivers/gpu/drm/i915/intel_pm.c |
| @@ -2270,6 +2270,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 num_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 || num_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 num_pipes_active) |
| +{ |
| + /* HSW LP1+ watermarks w/ multiple pipes */ |
| + if (level > 0 && num_pipes_active > 1) |
| + return 64; |
| + |
| + /* otherwise 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 num_pipes_active, |
| + bool sprite_enabled, |
| + enum intel_ddb_partitioning ddb_partitioning, |
| + struct hsw_wm_maximums *max) |
| +{ |
| + max->pri = ilk_plane_wm_max(dev, level, num_pipes_active, |
| + sprite_enabled, ddb_partitioning, false); |
| + max->spr = ilk_plane_wm_max(dev, level, num_pipes_active, |
| + sprite_enabled, ddb_partitioning, true); |
| + max->cur = ilk_cursor_wm_max(dev, level, num_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) |
| @@ -2555,18 +2653,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, |
| -- |
| 1.8.5.rc3 |
| |