Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915/gen9+: Kill off hw_ddb from intel_crtc.

dev_priv->hw_ddb is only used by skl_update_crtcs, but the ddb
allocation for each pipe is calculated in crtc_state.

We can rid of the global member by looking at crtc_state.
Do this by saving all active old ddb allocations from the old crtc_state
in an array, and then point them to the new allocation every time we update
a crtc.

This will allow us to keep track of the intermediate ddb allocations,
which is what hw_ddb was previously used for. With hw_ddb gone all
SKL-style watermark values are properly maintained only in crtc_state.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1478609742-13603-5-git-send-email-maarten.lankhorst@linux.intel.com
[mlankhorst: Reword commit message.]
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

+21 -28
+12 -3
drivers/gpu/drm/i915/intel_display.c
··· 14304 14304 unsigned int updated = 0; 14305 14305 bool progress; 14306 14306 enum pipe pipe; 14307 + int i; 14308 + 14309 + const struct skl_ddb_entry *entries[I915_MAX_PIPES] = {}; 14310 + 14311 + for_each_crtc_in_state(state, crtc, old_crtc_state, i) 14312 + /* ignore allocations for crtc's that have been turned off. */ 14313 + if (crtc->state->active) 14314 + entries[i] = &to_intel_crtc_state(old_crtc_state)->wm.skl.ddb; 14307 14315 14308 14316 /* 14309 14317 * Whenever the number of active pipes changes, we need to make sure we ··· 14320 14312 * cause pipe underruns and other bad stuff. 14321 14313 */ 14322 14314 do { 14323 - int i; 14324 14315 progress = false; 14325 14316 14326 14317 for_each_crtc_in_state(state, crtc, old_crtc_state, i) { ··· 14330 14323 cstate = to_intel_crtc_state(crtc->state); 14331 14324 pipe = intel_crtc->pipe; 14332 14325 14333 - if (updated & cmask || !crtc->state->active) 14326 + if (updated & cmask || !cstate->base.active) 14334 14327 continue; 14335 - if (skl_ddb_allocation_overlaps(state, intel_crtc)) 14328 + 14329 + if (skl_ddb_allocation_overlaps(entries, &cstate->wm.skl.ddb, i)) 14336 14330 continue; 14337 14331 14338 14332 updated |= cmask; 14333 + entries[i] = &cstate->wm.skl.ddb; 14339 14334 14340 14335 /* 14341 14336 * If this is an already active pipe, it's DDB changed,
+3 -8
drivers/gpu/drm/i915/intel_drv.h
··· 727 727 bool cxsr_allowed; 728 728 } wm; 729 729 730 - /* gen9+: ddb allocation currently being used */ 731 - struct skl_ddb_entry hw_ddb; 732 - 733 730 int scanline_offset; 734 731 735 732 struct { ··· 1736 1739 int intel_disable_sagv(struct drm_i915_private *dev_priv); 1737 1740 bool skl_wm_level_equals(const struct skl_wm_level *l1, 1738 1741 const struct skl_wm_level *l2); 1739 - bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old, 1740 - const struct skl_ddb_allocation *new, 1741 - enum pipe pipe); 1742 - bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state, 1743 - struct intel_crtc *intel_crtc); 1742 + bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry **entries, 1743 + const struct skl_ddb_entry *ddb, 1744 + int ignore); 1744 1745 uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config); 1745 1746 bool ilk_disable_lp_wm(struct drm_device *dev); 1746 1747 int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6);
+6 -17
drivers/gpu/drm/i915/intel_pm.c
··· 3913 3913 return a->start < b->end && b->start < a->end; 3914 3914 } 3915 3915 3916 - bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state, 3917 - struct intel_crtc *intel_crtc) 3916 + bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry **entries, 3917 + const struct skl_ddb_entry *ddb, 3918 + int ignore) 3918 3919 { 3919 - struct drm_crtc *other_crtc; 3920 - struct drm_crtc_state *other_cstate; 3921 - struct intel_crtc *other_intel_crtc; 3922 - const struct skl_ddb_entry *ddb = 3923 - &to_intel_crtc_state(intel_crtc->base.state)->wm.skl.ddb; 3924 3920 int i; 3925 3921 3926 - for_each_crtc_in_state(state, other_crtc, other_cstate, i) { 3927 - other_intel_crtc = to_intel_crtc(other_crtc); 3928 - 3929 - if (other_intel_crtc == intel_crtc) 3930 - continue; 3931 - 3932 - if (skl_ddb_entries_overlap(ddb, &other_intel_crtc->hw_ddb)) 3922 + for (i = 0; i < I915_MAX_PIPES; i++) 3923 + if (i != ignore && entries[i] && 3924 + skl_ddb_entries_overlap(ddb, entries[i])) 3933 3925 return true; 3934 - } 3935 3926 3936 3927 return false; 3937 3928 } ··· 4231 4240 skl_atomic_update_crtc_wm(state, cstate); 4232 4241 4233 4242 skl_copy_wm_for_pipe(hw_vals, results, pipe); 4234 - 4235 - intel_crtc->hw_ddb = cstate->wm.skl.ddb; 4236 4243 4237 4244 mutex_unlock(&dev_priv->wm.wm_mutex); 4238 4245 }