aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c57
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
3774static 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
3774static void 3805static void
3775skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, 3806skl_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