diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 57 |
1 files changed, 46 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index a29e6d512771..3e72e9eb736e 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -3771,9 +3771,42 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state) | |||
3771 | return true; | 3771 | return true; |
3772 | } | 3772 | } |
3773 | 3773 | ||
3774 | static unsigned int intel_get_ddb_size(struct drm_i915_private *dev_priv, | ||
3775 | const struct intel_crtc_state *cstate, | ||
3776 | const unsigned int total_data_rate, | ||
3777 | const int num_active, | ||
3778 | struct skl_ddb_allocation *ddb) | ||
3779 | { | ||
3780 | const struct drm_display_mode *adjusted_mode; | ||
3781 | u64 total_data_bw; | ||
3782 | u16 ddb_size = INTEL_INFO(dev_priv)->ddb_size; | ||
3783 | |||
3784 | WARN_ON(ddb_size == 0); | ||
3785 | |||
3786 | if (INTEL_GEN(dev_priv) < 11) | ||
3787 | return ddb_size - 4; /* 4 blocks for bypass path allocation */ | ||
3788 | |||
3789 | adjusted_mode = &cstate->base.adjusted_mode; | ||
3790 | total_data_bw = (u64)total_data_rate * drm_mode_vrefresh(adjusted_mode); | ||
3791 | |||
3792 | /* | ||
3793 | * 12GB/s is maximum BW supported by single DBuf slice. | ||
3794 | */ | ||
3795 | if (total_data_bw >= GBps(12) || num_active > 1) { | ||
3796 | ddb->enabled_slices = 2; | ||
3797 | } else { | ||
3798 | ddb->enabled_slices = 1; | ||
3799 | ddb_size /= 2; | ||
3800 | } | ||
3801 | |||
3802 | return ddb_size; | ||
3803 | } | ||
3804 | |||
3774 | static void | 3805 | static void |
3775 | skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, | 3806 | skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, |
3776 | const struct intel_crtc_state *cstate, | 3807 | const struct intel_crtc_state *cstate, |
3808 | const unsigned int total_data_rate, | ||
3809 | struct skl_ddb_allocation *ddb, | ||
3777 | struct skl_ddb_entry *alloc, /* out */ | 3810 | struct skl_ddb_entry *alloc, /* out */ |
3778 | int *num_active /* out */) | 3811 | int *num_active /* out */) |
3779 | { | 3812 | { |
@@ -3796,11 +3829,8 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, | |||
3796 | else | 3829 | else |
3797 | *num_active = hweight32(dev_priv->active_crtcs); | 3830 | *num_active = hweight32(dev_priv->active_crtcs); |
3798 | 3831 | ||
3799 | ddb_size = INTEL_INFO(dev_priv)->ddb_size; | 3832 | ddb_size = intel_get_ddb_size(dev_priv, cstate, total_data_rate, |
3800 | WARN_ON(ddb_size == 0); | 3833 | *num_active, ddb); |
3801 | |||
3802 | if (INTEL_GEN(dev_priv) < 11) | ||
3803 | ddb_size -= 4; /* 4 blocks for bypass path allocation */ | ||
3804 | 3834 | ||
3805 | /* | 3835 | /* |
3806 | * If the state doesn't change the active CRTC's, then there's | 3836 | * If the state doesn't change the active CRTC's, then there's |
@@ -4261,7 +4291,11 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, | |||
4261 | return 0; | 4291 | return 0; |
4262 | } | 4292 | } |
4263 | 4293 | ||
4264 | skl_ddb_get_pipe_allocation_limits(dev, cstate, alloc, &num_active); | 4294 | total_data_rate = skl_get_total_relative_data_rate(cstate, |
4295 | plane_data_rate, | ||
4296 | uv_plane_data_rate); | ||
4297 | skl_ddb_get_pipe_allocation_limits(dev, cstate, total_data_rate, ddb, | ||
4298 | alloc, &num_active); | ||
4265 | alloc_size = skl_ddb_entry_size(alloc); | 4299 | alloc_size = skl_ddb_entry_size(alloc); |
4266 | if (alloc_size == 0) | 4300 | if (alloc_size == 0) |
4267 | return 0; | 4301 | return 0; |
@@ -4296,9 +4330,6 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, | |||
4296 | * | 4330 | * |
4297 | * FIXME: we may not allocate every single block here. | 4331 | * FIXME: we may not allocate every single block here. |
4298 | */ | 4332 | */ |
4299 | total_data_rate = skl_get_total_relative_data_rate(cstate, | ||
4300 | plane_data_rate, | ||
4301 | uv_plane_data_rate); | ||
4302 | if (total_data_rate == 0) | 4333 | if (total_data_rate == 0) |
4303 | return 0; | 4334 | return 0; |
4304 | 4335 | ||
@@ -5492,8 +5523,12 @@ void skl_wm_get_hw_state(struct drm_device *dev) | |||
5492 | /* Fully recompute DDB on first atomic commit */ | 5523 | /* Fully recompute DDB on first atomic commit */ |
5493 | dev_priv->wm.distrust_bios_wm = true; | 5524 | dev_priv->wm.distrust_bios_wm = true; |
5494 | } else { | 5525 | } else { |
5495 | /* Easy/common case; just sanitize DDB now if everything off */ | 5526 | /* |
5496 | memset(ddb, 0, sizeof(*ddb)); | 5527 | * Easy/common case; just sanitize DDB now if everything off |
5528 | * Keep dbuf slice info intact | ||
5529 | */ | ||
5530 | memset(ddb->plane, 0, sizeof(ddb->plane)); | ||
5531 | memset(ddb->uv_plane, 0, sizeof(ddb->uv_plane)); | ||
5497 | } | 5532 | } |
5498 | } | 5533 | } |
5499 | 5534 | ||