1 // SPDX-License-Identifier: MIT
2 /*
3 * Copyright © 2022 Intel Corporation
4 */
5
6 #include <drm/drm_blend.h>
7
8 #include "intel_atomic.h"
9 #include "intel_atomic_plane.h"
10 #include "intel_bw.h"
11 #include "intel_de.h"
12 #include "intel_display.h"
13 #include "intel_display_power.h"
14 #include "intel_display_types.h"
15 #include "intel_fb.h"
16 #include "skl_watermark.h"
17
18 #include "i915_drv.h"
19 #include "i915_fixed.h"
20 #include "i915_reg.h"
21 #include "intel_pcode.h"
22 #include "intel_pm.h"
23
24 static void skl_sagv_disable(struct drm_i915_private *i915);
25
26 /* Stores plane specific WM parameters */
27 struct skl_wm_params {
28 bool x_tiled, y_tiled;
29 bool rc_surface;
30 bool is_planar;
31 u32 width;
32 u8 cpp;
33 u32 plane_pixel_rate;
34 u32 y_min_scanlines;
35 u32 plane_bytes_per_line;
36 uint_fixed_16_16_t plane_blocks_per_line;
37 uint_fixed_16_16_t y_tile_minimum;
38 u32 linetime_us;
39 u32 dbuf_block_size;
40 };
41
intel_enabled_dbuf_slices_mask(struct drm_i915_private * i915)42 u8 intel_enabled_dbuf_slices_mask(struct drm_i915_private *i915)
43 {
44 u8 enabled_slices = 0;
45 enum dbuf_slice slice;
46
47 for_each_dbuf_slice(i915, slice) {
48 if (intel_uncore_read(&i915->uncore,
49 DBUF_CTL_S(slice)) & DBUF_POWER_STATE)
50 enabled_slices |= BIT(slice);
51 }
52
53 return enabled_slices;
54 }
55
56 /*
57 * FIXME: We still don't have the proper code detect if we need to apply the WA,
58 * so assume we'll always need it in order to avoid underruns.
59 */
skl_needs_memory_bw_wa(struct drm_i915_private * i915)60 static bool skl_needs_memory_bw_wa(struct drm_i915_private *i915)
61 {
62 return DISPLAY_VER(i915) == 9;
63 }
64
65 static bool
intel_has_sagv(struct drm_i915_private * i915)66 intel_has_sagv(struct drm_i915_private *i915)
67 {
68 return DISPLAY_VER(i915) >= 9 && !IS_LP(i915) &&
69 i915->display.sagv.status != I915_SAGV_NOT_CONTROLLED;
70 }
71
72 static u32
intel_sagv_block_time(struct drm_i915_private * i915)73 intel_sagv_block_time(struct drm_i915_private *i915)
74 {
75 if (DISPLAY_VER(i915) >= 14) {
76 u32 val;
77
78 val = intel_uncore_read(&i915->uncore, MTL_LATENCY_SAGV);
79
80 return REG_FIELD_GET(MTL_LATENCY_QCLK_SAGV, val);
81 } else if (DISPLAY_VER(i915) >= 12) {
82 u32 val = 0;
83 int ret;
84
85 ret = snb_pcode_read(&i915->uncore,
86 GEN12_PCODE_READ_SAGV_BLOCK_TIME_US,
87 &val, NULL);
88 if (ret) {
89 drm_dbg_kms(&i915->drm, "Couldn't read SAGV block time!\n");
90 return 0;
91 }
92
93 return val;
94 } else if (DISPLAY_VER(i915) == 11) {
95 return 10;
96 } else if (DISPLAY_VER(i915) == 9 && !IS_LP(i915)) {
97 return 30;
98 } else {
99 return 0;
100 }
101 }
102
intel_sagv_init(struct drm_i915_private * i915)103 static void intel_sagv_init(struct drm_i915_private *i915)
104 {
105 if (!intel_has_sagv(i915))
106 i915->display.sagv.status = I915_SAGV_NOT_CONTROLLED;
107
108 /*
109 * Probe to see if we have working SAGV control.
110 * For icl+ this was already determined by intel_bw_init_hw().
111 */
112 if (DISPLAY_VER(i915) < 11)
113 skl_sagv_disable(i915);
114
115 drm_WARN_ON(&i915->drm, i915->display.sagv.status == I915_SAGV_UNKNOWN);
116
117 i915->display.sagv.block_time_us = intel_sagv_block_time(i915);
118
119 drm_dbg_kms(&i915->drm, "SAGV supported: %s, original SAGV block time: %u us\n",
120 str_yes_no(intel_has_sagv(i915)), i915->display.sagv.block_time_us);
121
122 /* avoid overflow when adding with wm0 latency/etc. */
123 if (drm_WARN(&i915->drm, i915->display.sagv.block_time_us > U16_MAX,
124 "Excessive SAGV block time %u, ignoring\n",
125 i915->display.sagv.block_time_us))
126 i915->display.sagv.block_time_us = 0;
127
128 if (!intel_has_sagv(i915))
129 i915->display.sagv.block_time_us = 0;
130 }
131
132 /*
133 * SAGV dynamically adjusts the system agent voltage and clock frequencies
134 * depending on power and performance requirements. The display engine access
135 * to system memory is blocked during the adjustment time. Because of the
136 * blocking time, having this enabled can cause full system hangs and/or pipe
137 * underruns if we don't meet all of the following requirements:
138 *
139 * - <= 1 pipe enabled
140 * - All planes can enable watermarks for latencies >= SAGV engine block time
141 * - We're not using an interlaced display configuration
142 */
skl_sagv_enable(struct drm_i915_private * i915)143 static void skl_sagv_enable(struct drm_i915_private *i915)
144 {
145 int ret;
146
147 if (!intel_has_sagv(i915))
148 return;
149
150 if (i915->display.sagv.status == I915_SAGV_ENABLED)
151 return;
152
153 drm_dbg_kms(&i915->drm, "Enabling SAGV\n");
154 ret = snb_pcode_write(&i915->uncore, GEN9_PCODE_SAGV_CONTROL,
155 GEN9_SAGV_ENABLE);
156
157 /* We don't need to wait for SAGV when enabling */
158
159 /*
160 * Some skl systems, pre-release machines in particular,
161 * don't actually have SAGV.
162 */
163 if (IS_SKYLAKE(i915) && ret == -ENXIO) {
164 drm_dbg(&i915->drm, "No SAGV found on system, ignoring\n");
165 i915->display.sagv.status = I915_SAGV_NOT_CONTROLLED;
166 return;
167 } else if (ret < 0) {
168 drm_err(&i915->drm, "Failed to enable SAGV\n");
169 return;
170 }
171
172 i915->display.sagv.status = I915_SAGV_ENABLED;
173 }
174
skl_sagv_disable(struct drm_i915_private * i915)175 static void skl_sagv_disable(struct drm_i915_private *i915)
176 {
177 int ret;
178
179 if (!intel_has_sagv(i915))
180 return;
181
182 if (i915->display.sagv.status == I915_SAGV_DISABLED)
183 return;
184
185 drm_dbg_kms(&i915->drm, "Disabling SAGV\n");
186 /* bspec says to keep retrying for at least 1 ms */
187 ret = skl_pcode_request(&i915->uncore, GEN9_PCODE_SAGV_CONTROL,
188 GEN9_SAGV_DISABLE,
189 GEN9_SAGV_IS_DISABLED, GEN9_SAGV_IS_DISABLED,
190 1);
191 /*
192 * Some skl systems, pre-release machines in particular,
193 * don't actually have SAGV.
194 */
195 if (IS_SKYLAKE(i915) && ret == -ENXIO) {
196 drm_dbg(&i915->drm, "No SAGV found on system, ignoring\n");
197 i915->display.sagv.status = I915_SAGV_NOT_CONTROLLED;
198 return;
199 } else if (ret < 0) {
200 drm_err(&i915->drm, "Failed to disable SAGV (%d)\n", ret);
201 return;
202 }
203
204 i915->display.sagv.status = I915_SAGV_DISABLED;
205 }
206
skl_sagv_pre_plane_update(struct intel_atomic_state * state)207 static void skl_sagv_pre_plane_update(struct intel_atomic_state *state)
208 {
209 struct drm_i915_private *i915 = to_i915(state->base.dev);
210 const struct intel_bw_state *new_bw_state =
211 intel_atomic_get_new_bw_state(state);
212
213 if (!new_bw_state)
214 return;
215
216 if (!intel_can_enable_sagv(i915, new_bw_state))
217 skl_sagv_disable(i915);
218 }
219
skl_sagv_post_plane_update(struct intel_atomic_state * state)220 static void skl_sagv_post_plane_update(struct intel_atomic_state *state)
221 {
222 struct drm_i915_private *i915 = to_i915(state->base.dev);
223 const struct intel_bw_state *new_bw_state =
224 intel_atomic_get_new_bw_state(state);
225
226 if (!new_bw_state)
227 return;
228
229 if (intel_can_enable_sagv(i915, new_bw_state))
230 skl_sagv_enable(i915);
231 }
232
icl_sagv_pre_plane_update(struct intel_atomic_state * state)233 static void icl_sagv_pre_plane_update(struct intel_atomic_state *state)
234 {
235 struct drm_i915_private *i915 = to_i915(state->base.dev);
236 const struct intel_bw_state *old_bw_state =
237 intel_atomic_get_old_bw_state(state);
238 const struct intel_bw_state *new_bw_state =
239 intel_atomic_get_new_bw_state(state);
240 u16 old_mask, new_mask;
241
242 if (!new_bw_state)
243 return;
244
245 old_mask = old_bw_state->qgv_points_mask;
246 new_mask = old_bw_state->qgv_points_mask | new_bw_state->qgv_points_mask;
247
248 if (old_mask == new_mask)
249 return;
250
251 WARN_ON(!new_bw_state->base.changed);
252
253 drm_dbg_kms(&i915->drm, "Restricting QGV points: 0x%x -> 0x%x\n",
254 old_mask, new_mask);
255
256 /*
257 * Restrict required qgv points before updating the configuration.
258 * According to BSpec we can't mask and unmask qgv points at the same
259 * time. Also masking should be done before updating the configuration
260 * and unmasking afterwards.
261 */
262 icl_pcode_restrict_qgv_points(i915, new_mask);
263 }
264
icl_sagv_post_plane_update(struct intel_atomic_state * state)265 static void icl_sagv_post_plane_update(struct intel_atomic_state *state)
266 {
267 struct drm_i915_private *i915 = to_i915(state->base.dev);
268 const struct intel_bw_state *old_bw_state =
269 intel_atomic_get_old_bw_state(state);
270 const struct intel_bw_state *new_bw_state =
271 intel_atomic_get_new_bw_state(state);
272 u16 old_mask, new_mask;
273
274 if (!new_bw_state)
275 return;
276
277 old_mask = old_bw_state->qgv_points_mask | new_bw_state->qgv_points_mask;
278 new_mask = new_bw_state->qgv_points_mask;
279
280 if (old_mask == new_mask)
281 return;
282
283 WARN_ON(!new_bw_state->base.changed);
284
285 drm_dbg_kms(&i915->drm, "Relaxing QGV points: 0x%x -> 0x%x\n",
286 old_mask, new_mask);
287
288 /*
289 * Allow required qgv points after updating the configuration.
290 * According to BSpec we can't mask and unmask qgv points at the same
291 * time. Also masking should be done before updating the configuration
292 * and unmasking afterwards.
293 */
294 icl_pcode_restrict_qgv_points(i915, new_mask);
295 }
296
intel_sagv_pre_plane_update(struct intel_atomic_state * state)297 void intel_sagv_pre_plane_update(struct intel_atomic_state *state)
298 {
299 struct drm_i915_private *i915 = to_i915(state->base.dev);
300
301 /*
302 * Just return if we can't control SAGV or don't have it.
303 * This is different from situation when we have SAGV but just can't
304 * afford it due to DBuf limitation - in case if SAGV is completely
305 * disabled in a BIOS, we are not even allowed to send a PCode request,
306 * as it will throw an error. So have to check it here.
307 */
308 if (!intel_has_sagv(i915))
309 return;
310
311 if (DISPLAY_VER(i915) >= 11)
312 icl_sagv_pre_plane_update(state);
313 else
314 skl_sagv_pre_plane_update(state);
315 }
316
intel_sagv_post_plane_update(struct intel_atomic_state * state)317 void intel_sagv_post_plane_update(struct intel_atomic_state *state)
318 {
319 struct drm_i915_private *i915 = to_i915(state->base.dev);
320
321 /*
322 * Just return if we can't control SAGV or don't have it.
323 * This is different from situation when we have SAGV but just can't
324 * afford it due to DBuf limitation - in case if SAGV is completely
325 * disabled in a BIOS, we are not even allowed to send a PCode request,
326 * as it will throw an error. So have to check it here.
327 */
328 if (!intel_has_sagv(i915))
329 return;
330
331 if (DISPLAY_VER(i915) >= 11)
332 icl_sagv_post_plane_update(state);
333 else
334 skl_sagv_post_plane_update(state);
335 }
336
skl_crtc_can_enable_sagv(const struct intel_crtc_state * crtc_state)337 static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
338 {
339 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
340 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
341 enum plane_id plane_id;
342 int max_level = INT_MAX;
343
344 if (!intel_has_sagv(i915))
345 return false;
346
347 if (!crtc_state->hw.active)
348 return true;
349
350 if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
351 return false;
352
353 for_each_plane_id_on_crtc(crtc, plane_id) {
354 const struct skl_plane_wm *wm =
355 &crtc_state->wm.skl.optimal.planes[plane_id];
356 int level;
357
358 /* Skip this plane if it's not enabled */
359 if (!wm->wm[0].enable)
360 continue;
361
362 /* Find the highest enabled wm level for this plane */
363 for (level = ilk_wm_max_level(i915);
364 !wm->wm[level].enable; --level)
365 { }
366
367 /* Highest common enabled wm level for all planes */
368 max_level = min(level, max_level);
369 }
370
371 /* No enabled planes? */
372 if (max_level == INT_MAX)
373 return true;
374
375 for_each_plane_id_on_crtc(crtc, plane_id) {
376 const struct skl_plane_wm *wm =
377 &crtc_state->wm.skl.optimal.planes[plane_id];
378
379 /*
380 * All enabled planes must have enabled a common wm level that
381 * can tolerate memory latencies higher than sagv_block_time_us
382 */
383 if (wm->wm[0].enable && !wm->wm[max_level].can_sagv)
384 return false;
385 }
386
387 return true;
388 }
389
tgl_crtc_can_enable_sagv(const struct intel_crtc_state * crtc_state)390 static bool tgl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
391 {
392 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
393 enum plane_id plane_id;
394
395 if (!crtc_state->hw.active)
396 return true;
397
398 for_each_plane_id_on_crtc(crtc, plane_id) {
399 const struct skl_plane_wm *wm =
400 &crtc_state->wm.skl.optimal.planes[plane_id];
401
402 if (wm->wm[0].enable && !wm->sagv.wm0.enable)
403 return false;
404 }
405
406 return true;
407 }
408
intel_crtc_can_enable_sagv(const struct intel_crtc_state * crtc_state)409 static bool intel_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
410 {
411 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
412 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
413
414 if (DISPLAY_VER(i915) >= 12)
415 return tgl_crtc_can_enable_sagv(crtc_state);
416 else
417 return skl_crtc_can_enable_sagv(crtc_state);
418 }
419
intel_can_enable_sagv(struct drm_i915_private * i915,const struct intel_bw_state * bw_state)420 bool intel_can_enable_sagv(struct drm_i915_private *i915,
421 const struct intel_bw_state *bw_state)
422 {
423 if (DISPLAY_VER(i915) < 11 &&
424 bw_state->active_pipes && !is_power_of_2(bw_state->active_pipes))
425 return false;
426
427 return bw_state->pipe_sagv_reject == 0;
428 }
429
intel_compute_sagv_mask(struct intel_atomic_state * state)430 static int intel_compute_sagv_mask(struct intel_atomic_state *state)
431 {
432 struct drm_i915_private *i915 = to_i915(state->base.dev);
433 int ret;
434 struct intel_crtc *crtc;
435 struct intel_crtc_state *new_crtc_state;
436 struct intel_bw_state *new_bw_state = NULL;
437 const struct intel_bw_state *old_bw_state = NULL;
438 int i;
439
440 for_each_new_intel_crtc_in_state(state, crtc,
441 new_crtc_state, i) {
442 new_bw_state = intel_atomic_get_bw_state(state);
443 if (IS_ERR(new_bw_state))
444 return PTR_ERR(new_bw_state);
445
446 old_bw_state = intel_atomic_get_old_bw_state(state);
447
448 if (intel_crtc_can_enable_sagv(new_crtc_state))
449 new_bw_state->pipe_sagv_reject &= ~BIT(crtc->pipe);
450 else
451 new_bw_state->pipe_sagv_reject |= BIT(crtc->pipe);
452 }
453
454 if (!new_bw_state)
455 return 0;
456
457 new_bw_state->active_pipes =
458 intel_calc_active_pipes(state, old_bw_state->active_pipes);
459
460 if (new_bw_state->active_pipes != old_bw_state->active_pipes) {
461 ret = intel_atomic_lock_global_state(&new_bw_state->base);
462 if (ret)
463 return ret;
464 }
465
466 if (intel_can_enable_sagv(i915, new_bw_state) !=
467 intel_can_enable_sagv(i915, old_bw_state)) {
468 ret = intel_atomic_serialize_global_state(&new_bw_state->base);
469 if (ret)
470 return ret;
471 } else if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) {
472 ret = intel_atomic_lock_global_state(&new_bw_state->base);
473 if (ret)
474 return ret;
475 }
476
477 for_each_new_intel_crtc_in_state(state, crtc,
478 new_crtc_state, i) {
479 struct skl_pipe_wm *pipe_wm = &new_crtc_state->wm.skl.optimal;
480
481 /*
482 * We store use_sagv_wm in the crtc state rather than relying on
483 * that bw state since we have no convenient way to get at the
484 * latter from the plane commit hooks (especially in the legacy
485 * cursor case)
486 */
487 pipe_wm->use_sagv_wm = !HAS_HW_SAGV_WM(i915) &&
488 DISPLAY_VER(i915) >= 12 &&
489 intel_can_enable_sagv(i915, new_bw_state);
490 }
491
492 return 0;
493 }
494
skl_ddb_entry_init(struct skl_ddb_entry * entry,u16 start,u16 end)495 static u16 skl_ddb_entry_init(struct skl_ddb_entry *entry,
496 u16 start, u16 end)
497 {
498 entry->start = start;
499 entry->end = end;
500
501 return end;
502 }
503
intel_dbuf_slice_size(struct drm_i915_private * i915)504 static int intel_dbuf_slice_size(struct drm_i915_private *i915)
505 {
506 return INTEL_INFO(i915)->display.dbuf.size /
507 hweight8(INTEL_INFO(i915)->display.dbuf.slice_mask);
508 }
509
510 static void
skl_ddb_entry_for_slices(struct drm_i915_private * i915,u8 slice_mask,struct skl_ddb_entry * ddb)511 skl_ddb_entry_for_slices(struct drm_i915_private *i915, u8 slice_mask,
512 struct skl_ddb_entry *ddb)
513 {
514 int slice_size = intel_dbuf_slice_size(i915);
515
516 if (!slice_mask) {
517 ddb->start = 0;
518 ddb->end = 0;
519 return;
520 }
521
522 ddb->start = (ffs(slice_mask) - 1) * slice_size;
523 ddb->end = fls(slice_mask) * slice_size;
524
525 WARN_ON(ddb->start >= ddb->end);
526 WARN_ON(ddb->end > INTEL_INFO(i915)->display.dbuf.size);
527 }
528
mbus_ddb_offset(struct drm_i915_private * i915,u8 slice_mask)529 static unsigned int mbus_ddb_offset(struct drm_i915_private *i915, u8 slice_mask)
530 {
531 struct skl_ddb_entry ddb;
532
533 if (slice_mask & (BIT(DBUF_S1) | BIT(DBUF_S2)))
534 slice_mask = BIT(DBUF_S1);
535 else if (slice_mask & (BIT(DBUF_S3) | BIT(DBUF_S4)))
536 slice_mask = BIT(DBUF_S3);
537
538 skl_ddb_entry_for_slices(i915, slice_mask, &ddb);
539
540 return ddb.start;
541 }
542
skl_ddb_dbuf_slice_mask(struct drm_i915_private * i915,const struct skl_ddb_entry * entry)543 u32 skl_ddb_dbuf_slice_mask(struct drm_i915_private *i915,
544 const struct skl_ddb_entry *entry)
545 {
546 int slice_size = intel_dbuf_slice_size(i915);
547 enum dbuf_slice start_slice, end_slice;
548 u8 slice_mask = 0;
549
550 if (!skl_ddb_entry_size(entry))
551 return 0;
552
553 start_slice = entry->start / slice_size;
554 end_slice = (entry->end - 1) / slice_size;
555
556 /*
557 * Per plane DDB entry can in a really worst case be on multiple slices
558 * but single entry is anyway contigious.
559 */
560 while (start_slice <= end_slice) {
561 slice_mask |= BIT(start_slice);
562 start_slice++;
563 }
564
565 return slice_mask;
566 }
567
intel_crtc_ddb_weight(const struct intel_crtc_state * crtc_state)568 static unsigned int intel_crtc_ddb_weight(const struct intel_crtc_state *crtc_state)
569 {
570 const struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode;
571 int hdisplay, vdisplay;
572
573 if (!crtc_state->hw.active)
574 return 0;
575
576 /*
577 * Watermark/ddb requirement highly depends upon width of the
578 * framebuffer, So instead of allocating DDB equally among pipes
579 * distribute DDB based on resolution/width of the display.
580 */
581 drm_mode_get_hv_timing(pipe_mode, &hdisplay, &vdisplay);
582
583 return hdisplay;
584 }
585
intel_crtc_dbuf_weights(const struct intel_dbuf_state * dbuf_state,enum pipe for_pipe,unsigned int * weight_start,unsigned int * weight_end,unsigned int * weight_total)586 static void intel_crtc_dbuf_weights(const struct intel_dbuf_state *dbuf_state,
587 enum pipe for_pipe,
588 unsigned int *weight_start,
589 unsigned int *weight_end,
590 unsigned int *weight_total)
591 {
592 struct drm_i915_private *i915 =
593 to_i915(dbuf_state->base.state->base.dev);
594 enum pipe pipe;
595
596 *weight_start = 0;
597 *weight_end = 0;
598 *weight_total = 0;
599
600 for_each_pipe(i915, pipe) {
601 int weight = dbuf_state->weight[pipe];
602
603 /*
604 * Do not account pipes using other slice sets
605 * luckily as of current BSpec slice sets do not partially
606 * intersect(pipes share either same one slice or same slice set
607 * i.e no partial intersection), so it is enough to check for
608 * equality for now.
609 */
610 if (dbuf_state->slices[pipe] != dbuf_state->slices[for_pipe])
611 continue;
612
613 *weight_total += weight;
614 if (pipe < for_pipe) {
615 *weight_start += weight;
616 *weight_end += weight;
617 } else if (pipe == for_pipe) {
618 *weight_end += weight;
619 }
620 }
621 }
622
623 static int
skl_crtc_allocate_ddb(struct intel_atomic_state * state,struct intel_crtc * crtc)624 skl_crtc_allocate_ddb(struct intel_atomic_state *state, struct intel_crtc *crtc)
625 {
626 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
627 unsigned int weight_total, weight_start, weight_end;
628 const struct intel_dbuf_state *old_dbuf_state =
629 intel_atomic_get_old_dbuf_state(state);
630 struct intel_dbuf_state *new_dbuf_state =
631 intel_atomic_get_new_dbuf_state(state);
632 struct intel_crtc_state *crtc_state;
633 struct skl_ddb_entry ddb_slices;
634 enum pipe pipe = crtc->pipe;
635 unsigned int mbus_offset = 0;
636 u32 ddb_range_size;
637 u32 dbuf_slice_mask;
638 u32 start, end;
639 int ret;
640
641 if (new_dbuf_state->weight[pipe] == 0) {
642 skl_ddb_entry_init(&new_dbuf_state->ddb[pipe], 0, 0);
643 goto out;
644 }
645
646 dbuf_slice_mask = new_dbuf_state->slices[pipe];
647
648 skl_ddb_entry_for_slices(i915, dbuf_slice_mask, &ddb_slices);
649 mbus_offset = mbus_ddb_offset(i915, dbuf_slice_mask);
650 ddb_range_size = skl_ddb_entry_size(&ddb_slices);
651
652 intel_crtc_dbuf_weights(new_dbuf_state, pipe,
653 &weight_start, &weight_end, &weight_total);
654
655 start = ddb_range_size * weight_start / weight_total;
656 end = ddb_range_size * weight_end / weight_total;
657
658 skl_ddb_entry_init(&new_dbuf_state->ddb[pipe],
659 ddb_slices.start - mbus_offset + start,
660 ddb_slices.start - mbus_offset + end);
661
662 out:
663 if (old_dbuf_state->slices[pipe] == new_dbuf_state->slices[pipe] &&
664 skl_ddb_entry_equal(&old_dbuf_state->ddb[pipe],
665 &new_dbuf_state->ddb[pipe]))
666 return 0;
667
668 ret = intel_atomic_lock_global_state(&new_dbuf_state->base);
669 if (ret)
670 return ret;
671
672 crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
673 if (IS_ERR(crtc_state))
674 return PTR_ERR(crtc_state);
675
676 /*
677 * Used for checking overlaps, so we need absolute
678 * offsets instead of MBUS relative offsets.
679 */
680 crtc_state->wm.skl.ddb.start = mbus_offset + new_dbuf_state->ddb[pipe].start;
681 crtc_state->wm.skl.ddb.end = mbus_offset + new_dbuf_state->ddb[pipe].end;
682
683 drm_dbg_kms(&i915->drm,
684 "[CRTC:%d:%s] dbuf slices 0x%x -> 0x%x, ddb (%d - %d) -> (%d - %d), active pipes 0x%x -> 0x%x\n",
685 crtc->base.base.id, crtc->base.name,
686 old_dbuf_state->slices[pipe], new_dbuf_state->slices[pipe],
687 old_dbuf_state->ddb[pipe].start, old_dbuf_state->ddb[pipe].end,
688 new_dbuf_state->ddb[pipe].start, new_dbuf_state->ddb[pipe].end,
689 old_dbuf_state->active_pipes, new_dbuf_state->active_pipes);
690
691 return 0;
692 }
693
694 static int skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
695 int width, const struct drm_format_info *format,
696 u64 modifier, unsigned int rotation,
697 u32 plane_pixel_rate, struct skl_wm_params *wp,
698 int color_plane);
699
700 static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
701 struct intel_plane *plane,
702 int level,
703 unsigned int latency,
704 const struct skl_wm_params *wp,
705 const struct skl_wm_level *result_prev,
706 struct skl_wm_level *result /* out */);
707
708 static unsigned int
skl_cursor_allocation(const struct intel_crtc_state * crtc_state,int num_active)709 skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
710 int num_active)
711 {
712 struct intel_plane *plane = to_intel_plane(crtc_state->uapi.crtc->cursor);
713 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
714 int level, max_level = ilk_wm_max_level(i915);
715 struct skl_wm_level wm = {};
716 int ret, min_ddb_alloc = 0;
717 struct skl_wm_params wp;
718
719 ret = skl_compute_wm_params(crtc_state, 256,
720 drm_format_info(DRM_FORMAT_ARGB8888),
721 DRM_FORMAT_MOD_LINEAR,
722 DRM_MODE_ROTATE_0,
723 crtc_state->pixel_rate, &wp, 0);
724 drm_WARN_ON(&i915->drm, ret);
725
726 for (level = 0; level <= max_level; level++) {
727 unsigned int latency = i915->display.wm.skl_latency[level];
728
729 skl_compute_plane_wm(crtc_state, plane, level, latency, &wp, &wm, &wm);
730 if (wm.min_ddb_alloc == U16_MAX)
731 break;
732
733 min_ddb_alloc = wm.min_ddb_alloc;
734 }
735
736 return max(num_active == 1 ? 32 : 8, min_ddb_alloc);
737 }
738
skl_ddb_entry_init_from_hw(struct skl_ddb_entry * entry,u32 reg)739 static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg)
740 {
741 skl_ddb_entry_init(entry,
742 REG_FIELD_GET(PLANE_BUF_START_MASK, reg),
743 REG_FIELD_GET(PLANE_BUF_END_MASK, reg));
744 if (entry->end)
745 entry->end++;
746 }
747
748 static void
skl_ddb_get_hw_plane_state(struct drm_i915_private * i915,const enum pipe pipe,const enum plane_id plane_id,struct skl_ddb_entry * ddb,struct skl_ddb_entry * ddb_y)749 skl_ddb_get_hw_plane_state(struct drm_i915_private *i915,
750 const enum pipe pipe,
751 const enum plane_id plane_id,
752 struct skl_ddb_entry *ddb,
753 struct skl_ddb_entry *ddb_y)
754 {
755 u32 val;
756
757 /* Cursor doesn't support NV12/planar, so no extra calculation needed */
758 if (plane_id == PLANE_CURSOR) {
759 val = intel_uncore_read(&i915->uncore, CUR_BUF_CFG(pipe));
760 skl_ddb_entry_init_from_hw(ddb, val);
761 return;
762 }
763
764 val = intel_uncore_read(&i915->uncore, PLANE_BUF_CFG(pipe, plane_id));
765 skl_ddb_entry_init_from_hw(ddb, val);
766
767 if (DISPLAY_VER(i915) >= 11)
768 return;
769
770 val = intel_uncore_read(&i915->uncore, PLANE_NV12_BUF_CFG(pipe, plane_id));
771 skl_ddb_entry_init_from_hw(ddb_y, val);
772 }
773
skl_pipe_ddb_get_hw_state(struct intel_crtc * crtc,struct skl_ddb_entry * ddb,struct skl_ddb_entry * ddb_y)774 static void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc,
775 struct skl_ddb_entry *ddb,
776 struct skl_ddb_entry *ddb_y)
777 {
778 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
779 enum intel_display_power_domain power_domain;
780 enum pipe pipe = crtc->pipe;
781 intel_wakeref_t wakeref;
782 enum plane_id plane_id;
783
784 power_domain = POWER_DOMAIN_PIPE(pipe);
785 wakeref = intel_display_power_get_if_enabled(i915, power_domain);
786 if (!wakeref)
787 return;
788
789 for_each_plane_id_on_crtc(crtc, plane_id)
790 skl_ddb_get_hw_plane_state(i915, pipe,
791 plane_id,
792 &ddb[plane_id],
793 &ddb_y[plane_id]);
794
795 intel_display_power_put(i915, power_domain, wakeref);
796 }
797
798 struct dbuf_slice_conf_entry {
799 u8 active_pipes;
800 u8 dbuf_mask[I915_MAX_PIPES];
801 bool join_mbus;
802 };
803
804 /*
805 * Table taken from Bspec 12716
806 * Pipes do have some preferred DBuf slice affinity,
807 * plus there are some hardcoded requirements on how
808 * those should be distributed for multipipe scenarios.
809 * For more DBuf slices algorithm can get even more messy
810 * and less readable, so decided to use a table almost
811 * as is from BSpec itself - that way it is at least easier
812 * to compare, change and check.
813 */
814 static const struct dbuf_slice_conf_entry icl_allowed_dbufs[] =
815 /* Autogenerated with igt/tools/intel_dbuf_map tool: */
816 {
817 {
818 .active_pipes = BIT(PIPE_A),
819 .dbuf_mask = {
820 [PIPE_A] = BIT(DBUF_S1),
821 },
822 },
823 {
824 .active_pipes = BIT(PIPE_B),
825 .dbuf_mask = {
826 [PIPE_B] = BIT(DBUF_S1),
827 },
828 },
829 {
830 .active_pipes = BIT(PIPE_A) | BIT(PIPE_B),
831 .dbuf_mask = {
832 [PIPE_A] = BIT(DBUF_S1),
833 [PIPE_B] = BIT(DBUF_S2),
834 },
835 },
836 {
837 .active_pipes = BIT(PIPE_C),
838 .dbuf_mask = {
839 [PIPE_C] = BIT(DBUF_S2),
840 },
841 },
842 {
843 .active_pipes = BIT(PIPE_A) | BIT(PIPE_C),
844 .dbuf_mask = {
845 [PIPE_A] = BIT(DBUF_S1),
846 [PIPE_C] = BIT(DBUF_S2),
847 },
848 },
849 {
850 .active_pipes = BIT(PIPE_B) | BIT(PIPE_C),
851 .dbuf_mask = {
852 [PIPE_B] = BIT(DBUF_S1),
853 [PIPE_C] = BIT(DBUF_S2),
854 },
855 },
856 {
857 .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
858 .dbuf_mask = {
859 [PIPE_A] = BIT(DBUF_S1),
860 [PIPE_B] = BIT(DBUF_S1),
861 [PIPE_C] = BIT(DBUF_S2),
862 },
863 },
864 {}
865 };
866
867 /*
868 * Table taken from Bspec 49255
869 * Pipes do have some preferred DBuf slice affinity,
870 * plus there are some hardcoded requirements on how
871 * those should be distributed for multipipe scenarios.
872 * For more DBuf slices algorithm can get even more messy
873 * and less readable, so decided to use a table almost
874 * as is from BSpec itself - that way it is at least easier
875 * to compare, change and check.
876 */
877 static const struct dbuf_slice_conf_entry tgl_allowed_dbufs[] =
878 /* Autogenerated with igt/tools/intel_dbuf_map tool: */
879 {
880 {
881 .active_pipes = BIT(PIPE_A),
882 .dbuf_mask = {
883 [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
884 },
885 },
886 {
887 .active_pipes = BIT(PIPE_B),
888 .dbuf_mask = {
889 [PIPE_B] = BIT(DBUF_S1) | BIT(DBUF_S2),
890 },
891 },
892 {
893 .active_pipes = BIT(PIPE_A) | BIT(PIPE_B),
894 .dbuf_mask = {
895 [PIPE_A] = BIT(DBUF_S2),
896 [PIPE_B] = BIT(DBUF_S1),
897 },
898 },
899 {
900 .active_pipes = BIT(PIPE_C),
901 .dbuf_mask = {
902 [PIPE_C] = BIT(DBUF_S2) | BIT(DBUF_S1),
903 },
904 },
905 {
906 .active_pipes = BIT(PIPE_A) | BIT(PIPE_C),
907 .dbuf_mask = {
908 [PIPE_A] = BIT(DBUF_S1),
909 [PIPE_C] = BIT(DBUF_S2),
910 },
911 },
912 {
913 .active_pipes = BIT(PIPE_B) | BIT(PIPE_C),
914 .dbuf_mask = {
915 [PIPE_B] = BIT(DBUF_S1),
916 [PIPE_C] = BIT(DBUF_S2),
917 },
918 },
919 {
920 .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
921 .dbuf_mask = {
922 [PIPE_A] = BIT(DBUF_S1),
923 [PIPE_B] = BIT(DBUF_S1),
924 [PIPE_C] = BIT(DBUF_S2),
925 },
926 },
927 {
928 .active_pipes = BIT(PIPE_D),
929 .dbuf_mask = {
930 [PIPE_D] = BIT(DBUF_S2) | BIT(DBUF_S1),
931 },
932 },
933 {
934 .active_pipes = BIT(PIPE_A) | BIT(PIPE_D),
935 .dbuf_mask = {
936 [PIPE_A] = BIT(DBUF_S1),
937 [PIPE_D] = BIT(DBUF_S2),
938 },
939 },
940 {
941 .active_pipes = BIT(PIPE_B) | BIT(PIPE_D),
942 .dbuf_mask = {
943 [PIPE_B] = BIT(DBUF_S1),
944 [PIPE_D] = BIT(DBUF_S2),
945 },
946 },
947 {
948 .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_D),
949 .dbuf_mask = {
950 [PIPE_A] = BIT(DBUF_S1),
951 [PIPE_B] = BIT(DBUF_S1),
952 [PIPE_D] = BIT(DBUF_S2),
953 },
954 },
955 {
956 .active_pipes = BIT(PIPE_C) | BIT(PIPE_D),
957 .dbuf_mask = {
958 [PIPE_C] = BIT(DBUF_S1),
959 [PIPE_D] = BIT(DBUF_S2),
960 },
961 },
962 {
963 .active_pipes = BIT(PIPE_A) | BIT(PIPE_C) | BIT(PIPE_D),
964 .dbuf_mask = {
965 [PIPE_A] = BIT(DBUF_S1),
966 [PIPE_C] = BIT(DBUF_S2),
967 [PIPE_D] = BIT(DBUF_S2),
968 },
969 },
970 {
971 .active_pipes = BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D),
972 .dbuf_mask = {
973 [PIPE_B] = BIT(DBUF_S1),
974 [PIPE_C] = BIT(DBUF_S2),
975 [PIPE_D] = BIT(DBUF_S2),
976 },
977 },
978 {
979 .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D),
980 .dbuf_mask = {
981 [PIPE_A] = BIT(DBUF_S1),
982 [PIPE_B] = BIT(DBUF_S1),
983 [PIPE_C] = BIT(DBUF_S2),
984 [PIPE_D] = BIT(DBUF_S2),
985 },
986 },
987 {}
988 };
989
990 static const struct dbuf_slice_conf_entry dg2_allowed_dbufs[] = {
991 {
992 .active_pipes = BIT(PIPE_A),
993 .dbuf_mask = {
994 [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
995 },
996 },
997 {
998 .active_pipes = BIT(PIPE_B),
999 .dbuf_mask = {
1000 [PIPE_B] = BIT(DBUF_S1) | BIT(DBUF_S2),
1001 },
1002 },
1003 {
1004 .active_pipes = BIT(PIPE_A) | BIT(PIPE_B),
1005 .dbuf_mask = {
1006 [PIPE_A] = BIT(DBUF_S1),
1007 [PIPE_B] = BIT(DBUF_S2),
1008 },
1009 },
1010 {
1011 .active_pipes = BIT(PIPE_C),
1012 .dbuf_mask = {
1013 [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
1014 },
1015 },
1016 {
1017 .active_pipes = BIT(PIPE_A) | BIT(PIPE_C),
1018 .dbuf_mask = {
1019 [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
1020 [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
1021 },
1022 },
1023 {
1024 .active_pipes = BIT(PIPE_B) | BIT(PIPE_C),
1025 .dbuf_mask = {
1026 [PIPE_B] = BIT(DBUF_S1) | BIT(DBUF_S2),
1027 [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
1028 },
1029 },
1030 {
1031 .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
1032 .dbuf_mask = {
1033 [PIPE_A] = BIT(DBUF_S1),
1034 [PIPE_B] = BIT(DBUF_S2),
1035 [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
1036 },
1037 },
1038 {
1039 .active_pipes = BIT(PIPE_D),
1040 .dbuf_mask = {
1041 [PIPE_D] = BIT(DBUF_S3) | BIT(DBUF_S4),
1042 },
1043 },
1044 {
1045 .active_pipes = BIT(PIPE_A) | BIT(PIPE_D),
1046 .dbuf_mask = {
1047 [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
1048 [PIPE_D] = BIT(DBUF_S3) | BIT(DBUF_S4),
1049 },
1050 },
1051 {
1052 .active_pipes = BIT(PIPE_B) | BIT(PIPE_D),
1053 .dbuf_mask = {
1054 [PIPE_B] = BIT(DBUF_S1) | BIT(DBUF_S2),
1055 [PIPE_D] = BIT(DBUF_S3) | BIT(DBUF_S4),
1056 },
1057 },
1058 {
1059 .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_D),
1060 .dbuf_mask = {
1061 [PIPE_A] = BIT(DBUF_S1),
1062 [PIPE_B] = BIT(DBUF_S2),
1063 [PIPE_D] = BIT(DBUF_S3) | BIT(DBUF_S4),
1064 },
1065 },
1066 {
1067 .active_pipes = BIT(PIPE_C) | BIT(PIPE_D),
1068 .dbuf_mask = {
1069 [PIPE_C] = BIT(DBUF_S3),
1070 [PIPE_D] = BIT(DBUF_S4),
1071 },
1072 },
1073 {
1074 .active_pipes = BIT(PIPE_A) | BIT(PIPE_C) | BIT(PIPE_D),
1075 .dbuf_mask = {
1076 [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
1077 [PIPE_C] = BIT(DBUF_S3),
1078 [PIPE_D] = BIT(DBUF_S4),
1079 },
1080 },
1081 {
1082 .active_pipes = BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D),
1083 .dbuf_mask = {
1084 [PIPE_B] = BIT(DBUF_S1) | BIT(DBUF_S2),
1085 [PIPE_C] = BIT(DBUF_S3),
1086 [PIPE_D] = BIT(DBUF_S4),
1087 },
1088 },
1089 {
1090 .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D),
1091 .dbuf_mask = {
1092 [PIPE_A] = BIT(DBUF_S1),
1093 [PIPE_B] = BIT(DBUF_S2),
1094 [PIPE_C] = BIT(DBUF_S3),
1095 [PIPE_D] = BIT(DBUF_S4),
1096 },
1097 },
1098 {}
1099 };
1100
1101 static const struct dbuf_slice_conf_entry adlp_allowed_dbufs[] = {
1102 /*
1103 * Keep the join_mbus cases first so check_mbus_joined()
1104 * will prefer them over the !join_mbus cases.
1105 */
1106 {
1107 .active_pipes = BIT(PIPE_A),
1108 .dbuf_mask = {
1109 [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2) | BIT(DBUF_S3) | BIT(DBUF_S4),
1110 },
1111 .join_mbus = true,
1112 },
1113 {
1114 .active_pipes = BIT(PIPE_B),
1115 .dbuf_mask = {
1116 [PIPE_B] = BIT(DBUF_S1) | BIT(DBUF_S2) | BIT(DBUF_S3) | BIT(DBUF_S4),
1117 },
1118 .join_mbus = true,
1119 },
1120 {
1121 .active_pipes = BIT(PIPE_A),
1122 .dbuf_mask = {
1123 [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
1124 },
1125 .join_mbus = false,
1126 },
1127 {
1128 .active_pipes = BIT(PIPE_B),
1129 .dbuf_mask = {
1130 [PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4),
1131 },
1132 .join_mbus = false,
1133 },
1134 {
1135 .active_pipes = BIT(PIPE_A) | BIT(PIPE_B),
1136 .dbuf_mask = {
1137 [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
1138 [PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4),
1139 },
1140 },
1141 {
1142 .active_pipes = BIT(PIPE_C),
1143 .dbuf_mask = {
1144 [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
1145 },
1146 },
1147 {
1148 .active_pipes = BIT(PIPE_A) | BIT(PIPE_C),
1149 .dbuf_mask = {
1150 [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
1151 [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
1152 },
1153 },
1154 {
1155 .active_pipes = BIT(PIPE_B) | BIT(PIPE_C),
1156 .dbuf_mask = {
1157 [PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4),
1158 [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
1159 },
1160 },
1161 {
1162 .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
1163 .dbuf_mask = {
1164 [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
1165 [PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4),
1166 [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
1167 },
1168 },
1169 {
1170 .active_pipes = BIT(PIPE_D),
1171 .dbuf_mask = {
1172 [PIPE_D] = BIT(DBUF_S1) | BIT(DBUF_S2),
1173 },
1174 },
1175 {
1176 .active_pipes = BIT(PIPE_A) | BIT(PIPE_D),
1177 .dbuf_mask = {
1178 [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
1179 [PIPE_D] = BIT(DBUF_S1) | BIT(DBUF_S2),
1180 },
1181 },
1182 {
1183 .active_pipes = BIT(PIPE_B) | BIT(PIPE_D),
1184 .dbuf_mask = {
1185 [PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4),
1186 [PIPE_D] = BIT(DBUF_S1) | BIT(DBUF_S2),
1187 },
1188 },
1189 {
1190 .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_D),
1191 .dbuf_mask = {
1192 [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
1193 [PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4),
1194 [PIPE_D] = BIT(DBUF_S1) | BIT(DBUF_S2),
1195 },
1196 },
1197 {
1198 .active_pipes = BIT(PIPE_C) | BIT(PIPE_D),
1199 .dbuf_mask = {
1200 [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
1201 [PIPE_D] = BIT(DBUF_S1) | BIT(DBUF_S2),
1202 },
1203 },
1204 {
1205 .active_pipes = BIT(PIPE_A) | BIT(PIPE_C) | BIT(PIPE_D),
1206 .dbuf_mask = {
1207 [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
1208 [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
1209 [PIPE_D] = BIT(DBUF_S1) | BIT(DBUF_S2),
1210 },
1211 },
1212 {
1213 .active_pipes = BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D),
1214 .dbuf_mask = {
1215 [PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4),
1216 [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
1217 [PIPE_D] = BIT(DBUF_S1) | BIT(DBUF_S2),
1218 },
1219 },
1220 {
1221 .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D),
1222 .dbuf_mask = {
1223 [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
1224 [PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4),
1225 [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
1226 [PIPE_D] = BIT(DBUF_S1) | BIT(DBUF_S2),
1227 },
1228 },
1229 {}
1230
1231 };
1232
check_mbus_joined(u8 active_pipes,const struct dbuf_slice_conf_entry * dbuf_slices)1233 static bool check_mbus_joined(u8 active_pipes,
1234 const struct dbuf_slice_conf_entry *dbuf_slices)
1235 {
1236 int i;
1237
1238 for (i = 0; dbuf_slices[i].active_pipes != 0; i++) {
1239 if (dbuf_slices[i].active_pipes == active_pipes)
1240 return dbuf_slices[i].join_mbus;
1241 }
1242 return false;
1243 }
1244
adlp_check_mbus_joined(u8 active_pipes)1245 static bool adlp_check_mbus_joined(u8 active_pipes)
1246 {
1247 return check_mbus_joined(active_pipes, adlp_allowed_dbufs);
1248 }
1249
compute_dbuf_slices(enum pipe pipe,u8 active_pipes,bool join_mbus,const struct dbuf_slice_conf_entry * dbuf_slices)1250 static u8 compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbus,
1251 const struct dbuf_slice_conf_entry *dbuf_slices)
1252 {
1253 int i;
1254
1255 for (i = 0; dbuf_slices[i].active_pipes != 0; i++) {
1256 if (dbuf_slices[i].active_pipes == active_pipes &&
1257 dbuf_slices[i].join_mbus == join_mbus)
1258 return dbuf_slices[i].dbuf_mask[pipe];
1259 }
1260 return 0;
1261 }
1262
1263 /*
1264 * This function finds an entry with same enabled pipe configuration and
1265 * returns correspondent DBuf slice mask as stated in BSpec for particular
1266 * platform.
1267 */
icl_compute_dbuf_slices(enum pipe pipe,u8 active_pipes,bool join_mbus)1268 static u8 icl_compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbus)
1269 {
1270 /*
1271 * FIXME: For ICL this is still a bit unclear as prev BSpec revision
1272 * required calculating "pipe ratio" in order to determine
1273 * if one or two slices can be used for single pipe configurations
1274 * as additional constraint to the existing table.
1275 * However based on recent info, it should be not "pipe ratio"
1276 * but rather ratio between pixel_rate and cdclk with additional
1277 * constants, so for now we are using only table until this is
1278 * clarified. Also this is the reason why crtc_state param is
1279 * still here - we will need it once those additional constraints
1280 * pop up.
1281 */
1282 return compute_dbuf_slices(pipe, active_pipes, join_mbus,
1283 icl_allowed_dbufs);
1284 }
1285
tgl_compute_dbuf_slices(enum pipe pipe,u8 active_pipes,bool join_mbus)1286 static u8 tgl_compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbus)
1287 {
1288 return compute_dbuf_slices(pipe, active_pipes, join_mbus,
1289 tgl_allowed_dbufs);
1290 }
1291
adlp_compute_dbuf_slices(enum pipe pipe,u8 active_pipes,bool join_mbus)1292 static u8 adlp_compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbus)
1293 {
1294 return compute_dbuf_slices(pipe, active_pipes, join_mbus,
1295 adlp_allowed_dbufs);
1296 }
1297
dg2_compute_dbuf_slices(enum pipe pipe,u8 active_pipes,bool join_mbus)1298 static u8 dg2_compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbus)
1299 {
1300 return compute_dbuf_slices(pipe, active_pipes, join_mbus,
1301 dg2_allowed_dbufs);
1302 }
1303
skl_compute_dbuf_slices(struct intel_crtc * crtc,u8 active_pipes,bool join_mbus)1304 static u8 skl_compute_dbuf_slices(struct intel_crtc *crtc, u8 active_pipes, bool join_mbus)
1305 {
1306 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1307 enum pipe pipe = crtc->pipe;
1308
1309 if (IS_DG2(i915))
1310 return dg2_compute_dbuf_slices(pipe, active_pipes, join_mbus);
1311 else if (DISPLAY_VER(i915) >= 13)
1312 return adlp_compute_dbuf_slices(pipe, active_pipes, join_mbus);
1313 else if (DISPLAY_VER(i915) == 12)
1314 return tgl_compute_dbuf_slices(pipe, active_pipes, join_mbus);
1315 else if (DISPLAY_VER(i915) == 11)
1316 return icl_compute_dbuf_slices(pipe, active_pipes, join_mbus);
1317 /*
1318 * For anything else just return one slice yet.
1319 * Should be extended for other platforms.
1320 */
1321 return active_pipes & BIT(pipe) ? BIT(DBUF_S1) : 0;
1322 }
1323
1324 static bool
use_minimal_wm0_only(const struct intel_crtc_state * crtc_state,struct intel_plane * plane)1325 use_minimal_wm0_only(const struct intel_crtc_state *crtc_state,
1326 struct intel_plane *plane)
1327 {
1328 struct drm_i915_private *i915 = to_i915(plane->base.dev);
1329
1330 return DISPLAY_VER(i915) >= 13 &&
1331 crtc_state->uapi.async_flip &&
1332 plane->async_flip;
1333 }
1334
1335 static u64
skl_total_relative_data_rate(const struct intel_crtc_state * crtc_state)1336 skl_total_relative_data_rate(const struct intel_crtc_state *crtc_state)
1337 {
1338 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1339 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1340 enum plane_id plane_id;
1341 u64 data_rate = 0;
1342
1343 for_each_plane_id_on_crtc(crtc, plane_id) {
1344 if (plane_id == PLANE_CURSOR)
1345 continue;
1346
1347 data_rate += crtc_state->rel_data_rate[plane_id];
1348
1349 if (DISPLAY_VER(i915) < 11)
1350 data_rate += crtc_state->rel_data_rate_y[plane_id];
1351 }
1352
1353 return data_rate;
1354 }
1355
1356 static const struct skl_wm_level *
skl_plane_wm_level(const struct skl_pipe_wm * pipe_wm,enum plane_id plane_id,int level)1357 skl_plane_wm_level(const struct skl_pipe_wm *pipe_wm,
1358 enum plane_id plane_id,
1359 int level)
1360 {
1361 const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
1362
1363 if (level == 0 && pipe_wm->use_sagv_wm)
1364 return &wm->sagv.wm0;
1365
1366 return &wm->wm[level];
1367 }
1368
1369 static const struct skl_wm_level *
skl_plane_trans_wm(const struct skl_pipe_wm * pipe_wm,enum plane_id plane_id)1370 skl_plane_trans_wm(const struct skl_pipe_wm *pipe_wm,
1371 enum plane_id plane_id)
1372 {
1373 const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
1374
1375 if (pipe_wm->use_sagv_wm)
1376 return &wm->sagv.trans_wm;
1377
1378 return &wm->trans_wm;
1379 }
1380
1381 /*
1382 * We only disable the watermarks for each plane if
1383 * they exceed the ddb allocation of said plane. This
1384 * is done so that we don't end up touching cursor
1385 * watermarks needlessly when some other plane reduces
1386 * our max possible watermark level.
1387 *
1388 * Bspec has this to say about the PLANE_WM enable bit:
1389 * "All the watermarks at this level for all enabled
1390 * planes must be enabled before the level will be used."
1391 * So this is actually safe to do.
1392 */
1393 static void
skl_check_wm_level(struct skl_wm_level * wm,const struct skl_ddb_entry * ddb)1394 skl_check_wm_level(struct skl_wm_level *wm, const struct skl_ddb_entry *ddb)
1395 {
1396 if (wm->min_ddb_alloc > skl_ddb_entry_size(ddb))
1397 memset(wm, 0, sizeof(*wm));
1398 }
1399
1400 static void
skl_check_nv12_wm_level(struct skl_wm_level * wm,struct skl_wm_level * uv_wm,const struct skl_ddb_entry * ddb_y,const struct skl_ddb_entry * ddb)1401 skl_check_nv12_wm_level(struct skl_wm_level *wm, struct skl_wm_level *uv_wm,
1402 const struct skl_ddb_entry *ddb_y, const struct skl_ddb_entry *ddb)
1403 {
1404 if (wm->min_ddb_alloc > skl_ddb_entry_size(ddb_y) ||
1405 uv_wm->min_ddb_alloc > skl_ddb_entry_size(ddb)) {
1406 memset(wm, 0, sizeof(*wm));
1407 memset(uv_wm, 0, sizeof(*uv_wm));
1408 }
1409 }
1410
icl_need_wm1_wa(struct drm_i915_private * i915,enum plane_id plane_id)1411 static bool icl_need_wm1_wa(struct drm_i915_private *i915,
1412 enum plane_id plane_id)
1413 {
1414 /*
1415 * Wa_1408961008:icl, ehl
1416 * Wa_14012656716:tgl, adl
1417 * Underruns with WM1+ disabled
1418 */
1419 return DISPLAY_VER(i915) == 11 ||
1420 (IS_DISPLAY_VER(i915, 12, 13) && plane_id == PLANE_CURSOR);
1421 }
1422
1423 struct skl_plane_ddb_iter {
1424 u64 data_rate;
1425 u16 start, size;
1426 };
1427
1428 static void
skl_allocate_plane_ddb(struct skl_plane_ddb_iter * iter,struct skl_ddb_entry * ddb,const struct skl_wm_level * wm,u64 data_rate)1429 skl_allocate_plane_ddb(struct skl_plane_ddb_iter *iter,
1430 struct skl_ddb_entry *ddb,
1431 const struct skl_wm_level *wm,
1432 u64 data_rate)
1433 {
1434 u16 size, extra = 0;
1435
1436 if (data_rate) {
1437 extra = min_t(u16, iter->size,
1438 DIV64_U64_ROUND_UP(iter->size * data_rate,
1439 iter->data_rate));
1440 iter->size -= extra;
1441 iter->data_rate -= data_rate;
1442 }
1443
1444 /*
1445 * Keep ddb entry of all disabled planes explicitly zeroed
1446 * to avoid skl_ddb_add_affected_planes() adding them to
1447 * the state when other planes change their allocations.
1448 */
1449 size = wm->min_ddb_alloc + extra;
1450 if (size)
1451 iter->start = skl_ddb_entry_init(ddb, iter->start,
1452 iter->start + size);
1453 }
1454
1455 static int
skl_crtc_allocate_plane_ddb(struct intel_atomic_state * state,struct intel_crtc * crtc)1456 skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state,
1457 struct intel_crtc *crtc)
1458 {
1459 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1460 struct intel_crtc_state *crtc_state =
1461 intel_atomic_get_new_crtc_state(state, crtc);
1462 const struct intel_dbuf_state *dbuf_state =
1463 intel_atomic_get_new_dbuf_state(state);
1464 const struct skl_ddb_entry *alloc = &dbuf_state->ddb[crtc->pipe];
1465 int num_active = hweight8(dbuf_state->active_pipes);
1466 struct skl_plane_ddb_iter iter;
1467 enum plane_id plane_id;
1468 u16 cursor_size;
1469 u32 blocks;
1470 int level;
1471
1472 /* Clear the partitioning for disabled planes. */
1473 memset(crtc_state->wm.skl.plane_ddb, 0, sizeof(crtc_state->wm.skl.plane_ddb));
1474 memset(crtc_state->wm.skl.plane_ddb_y, 0, sizeof(crtc_state->wm.skl.plane_ddb_y));
1475
1476 if (!crtc_state->hw.active)
1477 return 0;
1478
1479 iter.start = alloc->start;
1480 iter.size = skl_ddb_entry_size(alloc);
1481 if (iter.size == 0)
1482 return 0;
1483
1484 /* Allocate fixed number of blocks for cursor. */
1485 cursor_size = skl_cursor_allocation(crtc_state, num_active);
1486 iter.size -= cursor_size;
1487 skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb[PLANE_CURSOR],
1488 alloc->end - cursor_size, alloc->end);
1489
1490 iter.data_rate = skl_total_relative_data_rate(crtc_state);
1491
1492 /*
1493 * Find the highest watermark level for which we can satisfy the block
1494 * requirement of active planes.
1495 */
1496 for (level = ilk_wm_max_level(i915); level >= 0; level--) {
1497 blocks = 0;
1498 for_each_plane_id_on_crtc(crtc, plane_id) {
1499 const struct skl_plane_wm *wm =
1500 &crtc_state->wm.skl.optimal.planes[plane_id];
1501
1502 if (plane_id == PLANE_CURSOR) {
1503 const struct skl_ddb_entry *ddb =
1504 &crtc_state->wm.skl.plane_ddb[plane_id];
1505
1506 if (wm->wm[level].min_ddb_alloc > skl_ddb_entry_size(ddb)) {
1507 drm_WARN_ON(&i915->drm,
1508 wm->wm[level].min_ddb_alloc != U16_MAX);
1509 blocks = U32_MAX;
1510 break;
1511 }
1512 continue;
1513 }
1514
1515 blocks += wm->wm[level].min_ddb_alloc;
1516 blocks += wm->uv_wm[level].min_ddb_alloc;
1517 }
1518
1519 if (blocks <= iter.size) {
1520 iter.size -= blocks;
1521 break;
1522 }
1523 }
1524
1525 if (level < 0) {
1526 drm_dbg_kms(&i915->drm,
1527 "Requested display configuration exceeds system DDB limitations");
1528 drm_dbg_kms(&i915->drm, "minimum required %d/%d\n",
1529 blocks, iter.size);
1530 return -EINVAL;
1531 }
1532
1533 /* avoid the WARN later when we don't allocate any extra DDB */
1534 if (iter.data_rate == 0)
1535 iter.size = 0;
1536
1537 /*
1538 * Grant each plane the blocks it requires at the highest achievable
1539 * watermark level, plus an extra share of the leftover blocks
1540 * proportional to its relative data rate.
1541 */
1542 for_each_plane_id_on_crtc(crtc, plane_id) {
1543 struct skl_ddb_entry *ddb =
1544 &crtc_state->wm.skl.plane_ddb[plane_id];
1545 struct skl_ddb_entry *ddb_y =
1546 &crtc_state->wm.skl.plane_ddb_y[plane_id];
1547 const struct skl_plane_wm *wm =
1548 &crtc_state->wm.skl.optimal.planes[plane_id];
1549
1550 if (plane_id == PLANE_CURSOR)
1551 continue;
1552
1553 if (DISPLAY_VER(i915) < 11 &&
1554 crtc_state->nv12_planes & BIT(plane_id)) {
1555 skl_allocate_plane_ddb(&iter, ddb_y, &wm->wm[level],
1556 crtc_state->rel_data_rate_y[plane_id]);
1557 skl_allocate_plane_ddb(&iter, ddb, &wm->uv_wm[level],
1558 crtc_state->rel_data_rate[plane_id]);
1559 } else {
1560 skl_allocate_plane_ddb(&iter, ddb, &wm->wm[level],
1561 crtc_state->rel_data_rate[plane_id]);
1562 }
1563 }
1564 drm_WARN_ON(&i915->drm, iter.size != 0 || iter.data_rate != 0);
1565
1566 /*
1567 * When we calculated watermark values we didn't know how high
1568 * of a level we'd actually be able to hit, so we just marked
1569 * all levels as "enabled." Go back now and disable the ones
1570 * that aren't actually possible.
1571 */
1572 for (level++; level <= ilk_wm_max_level(i915); level++) {
1573 for_each_plane_id_on_crtc(crtc, plane_id) {
1574 const struct skl_ddb_entry *ddb =
1575 &crtc_state->wm.skl.plane_ddb[plane_id];
1576 const struct skl_ddb_entry *ddb_y =
1577 &crtc_state->wm.skl.plane_ddb_y[plane_id];
1578 struct skl_plane_wm *wm =
1579 &crtc_state->wm.skl.optimal.planes[plane_id];
1580
1581 if (DISPLAY_VER(i915) < 11 &&
1582 crtc_state->nv12_planes & BIT(plane_id))
1583 skl_check_nv12_wm_level(&wm->wm[level],
1584 &wm->uv_wm[level],
1585 ddb_y, ddb);
1586 else
1587 skl_check_wm_level(&wm->wm[level], ddb);
1588
1589 if (icl_need_wm1_wa(i915, plane_id) &&
1590 level == 1 && wm->wm[0].enable) {
1591 wm->wm[level].blocks = wm->wm[0].blocks;
1592 wm->wm[level].lines = wm->wm[0].lines;
1593 wm->wm[level].ignore_lines = wm->wm[0].ignore_lines;
1594 }
1595 }
1596 }
1597
1598 /*
1599 * Go back and disable the transition and SAGV watermarks
1600 * if it turns out we don't have enough DDB blocks for them.
1601 */
1602 for_each_plane_id_on_crtc(crtc, plane_id) {
1603 const struct skl_ddb_entry *ddb =
1604 &crtc_state->wm.skl.plane_ddb[plane_id];
1605 const struct skl_ddb_entry *ddb_y =
1606 &crtc_state->wm.skl.plane_ddb_y[plane_id];
1607 struct skl_plane_wm *wm =
1608 &crtc_state->wm.skl.optimal.planes[plane_id];
1609
1610 if (DISPLAY_VER(i915) < 11 &&
1611 crtc_state->nv12_planes & BIT(plane_id)) {
1612 skl_check_wm_level(&wm->trans_wm, ddb_y);
1613 } else {
1614 WARN_ON(skl_ddb_entry_size(ddb_y));
1615
1616 skl_check_wm_level(&wm->trans_wm, ddb);
1617 }
1618
1619 skl_check_wm_level(&wm->sagv.wm0, ddb);
1620 skl_check_wm_level(&wm->sagv.trans_wm, ddb);
1621 }
1622
1623 return 0;
1624 }
1625
1626 /*
1627 * The max latency should be 257 (max the punit can code is 255 and we add 2us
1628 * for the read latency) and cpp should always be <= 8, so that
1629 * should allow pixel_rate up to ~2 GHz which seems sufficient since max
1630 * 2xcdclk is 1350 MHz and the pixel rate should never exceed that.
1631 */
1632 static uint_fixed_16_16_t
skl_wm_method1(const struct drm_i915_private * i915,u32 pixel_rate,u8 cpp,u32 latency,u32 dbuf_block_size)1633 skl_wm_method1(const struct drm_i915_private *i915, u32 pixel_rate,
1634 u8 cpp, u32 latency, u32 dbuf_block_size)
1635 {
1636 u32 wm_intermediate_val;
1637 uint_fixed_16_16_t ret;
1638
1639 if (latency == 0)
1640 return FP_16_16_MAX;
1641
1642 wm_intermediate_val = latency * pixel_rate * cpp;
1643 ret = div_fixed16(wm_intermediate_val, 1000 * dbuf_block_size);
1644
1645 if (DISPLAY_VER(i915) >= 10)
1646 ret = add_fixed16_u32(ret, 1);
1647
1648 return ret;
1649 }
1650
1651 static uint_fixed_16_16_t
skl_wm_method2(u32 pixel_rate,u32 pipe_htotal,u32 latency,uint_fixed_16_16_t plane_blocks_per_line)1652 skl_wm_method2(u32 pixel_rate, u32 pipe_htotal, u32 latency,
1653 uint_fixed_16_16_t plane_blocks_per_line)
1654 {
1655 u32 wm_intermediate_val;
1656 uint_fixed_16_16_t ret;
1657
1658 if (latency == 0)
1659 return FP_16_16_MAX;
1660
1661 wm_intermediate_val = latency * pixel_rate;
1662 wm_intermediate_val = DIV_ROUND_UP(wm_intermediate_val,
1663 pipe_htotal * 1000);
1664 ret = mul_u32_fixed16(wm_intermediate_val, plane_blocks_per_line);
1665 return ret;
1666 }
1667
1668 static uint_fixed_16_16_t
intel_get_linetime_us(const struct intel_crtc_state * crtc_state)1669 intel_get_linetime_us(const struct intel_crtc_state *crtc_state)
1670 {
1671 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1672 u32 pixel_rate;
1673 u32 crtc_htotal;
1674 uint_fixed_16_16_t linetime_us;
1675
1676 if (!crtc_state->hw.active)
1677 return u32_to_fixed16(0);
1678
1679 pixel_rate = crtc_state->pixel_rate;
1680
1681 if (drm_WARN_ON(&i915->drm, pixel_rate == 0))
1682 return u32_to_fixed16(0);
1683
1684 crtc_htotal = crtc_state->hw.pipe_mode.crtc_htotal;
1685 linetime_us = div_fixed16(crtc_htotal * 1000, pixel_rate);
1686
1687 return linetime_us;
1688 }
1689
1690 static int
skl_compute_wm_params(const struct intel_crtc_state * crtc_state,int width,const struct drm_format_info * format,u64 modifier,unsigned int rotation,u32 plane_pixel_rate,struct skl_wm_params * wp,int color_plane)1691 skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
1692 int width, const struct drm_format_info *format,
1693 u64 modifier, unsigned int rotation,
1694 u32 plane_pixel_rate, struct skl_wm_params *wp,
1695 int color_plane)
1696 {
1697 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1698 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1699 u32 interm_pbpl;
1700
1701 /* only planar format has two planes */
1702 if (color_plane == 1 &&
1703 !intel_format_info_is_yuv_semiplanar(format, modifier)) {
1704 drm_dbg_kms(&i915->drm,
1705 "Non planar format have single plane\n");
1706 return -EINVAL;
1707 }
1708
1709 wp->y_tiled = modifier == I915_FORMAT_MOD_Y_TILED ||
1710 modifier == I915_FORMAT_MOD_4_TILED ||
1711 modifier == I915_FORMAT_MOD_Yf_TILED ||
1712 modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
1713 modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
1714 modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
1715 modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
1716 modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC ||
1717 modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS ||
1718 modifier == I915_FORMAT_MOD_4_TILED_DG2_MC_CCS ||
1719 modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
1720 wp->x_tiled = modifier == I915_FORMAT_MOD_X_TILED;
1721 wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
1722 modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
1723 modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
1724 modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
1725 modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC ||
1726 modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS ||
1727 modifier == I915_FORMAT_MOD_4_TILED_DG2_MC_CCS ||
1728 modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
1729 wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier);
1730
1731 wp->width = width;
1732 if (color_plane == 1 && wp->is_planar)
1733 wp->width /= 2;
1734
1735 wp->cpp = format->cpp[color_plane];
1736 wp->plane_pixel_rate = plane_pixel_rate;
1737
1738 if (DISPLAY_VER(i915) >= 11 &&
1739 modifier == I915_FORMAT_MOD_Yf_TILED && wp->cpp == 1)
1740 wp->dbuf_block_size = 256;
1741 else
1742 wp->dbuf_block_size = 512;
1743
1744 if (drm_rotation_90_or_270(rotation)) {
1745 switch (wp->cpp) {
1746 case 1:
1747 wp->y_min_scanlines = 16;
1748 break;
1749 case 2:
1750 wp->y_min_scanlines = 8;
1751 break;
1752 case 4:
1753 wp->y_min_scanlines = 4;
1754 break;
1755 default:
1756 MISSING_CASE(wp->cpp);
1757 return -EINVAL;
1758 }
1759 } else {
1760 wp->y_min_scanlines = 4;
1761 }
1762
1763 if (skl_needs_memory_bw_wa(i915))
1764 wp->y_min_scanlines *= 2;
1765
1766 wp->plane_bytes_per_line = wp->width * wp->cpp;
1767 if (wp->y_tiled) {
1768 interm_pbpl = DIV_ROUND_UP(wp->plane_bytes_per_line *
1769 wp->y_min_scanlines,
1770 wp->dbuf_block_size);
1771
1772 if (DISPLAY_VER(i915) >= 10)
1773 interm_pbpl++;
1774
1775 wp->plane_blocks_per_line = div_fixed16(interm_pbpl,
1776 wp->y_min_scanlines);
1777 } else {
1778 interm_pbpl = DIV_ROUND_UP(wp->plane_bytes_per_line,
1779 wp->dbuf_block_size);
1780
1781 if (!wp->x_tiled || DISPLAY_VER(i915) >= 10)
1782 interm_pbpl++;
1783
1784 wp->plane_blocks_per_line = u32_to_fixed16(interm_pbpl);
1785 }
1786
1787 wp->y_tile_minimum = mul_u32_fixed16(wp->y_min_scanlines,
1788 wp->plane_blocks_per_line);
1789
1790 wp->linetime_us = fixed16_to_u32_round_up(intel_get_linetime_us(crtc_state));
1791
1792 return 0;
1793 }
1794
1795 static int
skl_compute_plane_wm_params(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state,struct skl_wm_params * wp,int color_plane)1796 skl_compute_plane_wm_params(const struct intel_crtc_state *crtc_state,
1797 const struct intel_plane_state *plane_state,
1798 struct skl_wm_params *wp, int color_plane)
1799 {
1800 const struct drm_framebuffer *fb = plane_state->hw.fb;
1801 int width;
1802
1803 /*
1804 * Src coordinates are already rotated by 270 degrees for
1805 * the 90/270 degree plane rotation cases (to match the
1806 * GTT mapping), hence no need to account for rotation here.
1807 */
1808 width = drm_rect_width(&plane_state->uapi.src) >> 16;
1809
1810 return skl_compute_wm_params(crtc_state, width,
1811 fb->format, fb->modifier,
1812 plane_state->hw.rotation,
1813 intel_plane_pixel_rate(crtc_state, plane_state),
1814 wp, color_plane);
1815 }
1816
skl_wm_has_lines(struct drm_i915_private * i915,int level)1817 static bool skl_wm_has_lines(struct drm_i915_private *i915, int level)
1818 {
1819 if (DISPLAY_VER(i915) >= 10)
1820 return true;
1821
1822 /* The number of lines are ignored for the level 0 watermark. */
1823 return level > 0;
1824 }
1825
skl_wm_max_lines(struct drm_i915_private * i915)1826 static int skl_wm_max_lines(struct drm_i915_private *i915)
1827 {
1828 if (DISPLAY_VER(i915) >= 13)
1829 return 255;
1830 else
1831 return 31;
1832 }
1833
skl_compute_plane_wm(const struct intel_crtc_state * crtc_state,struct intel_plane * plane,int level,unsigned int latency,const struct skl_wm_params * wp,const struct skl_wm_level * result_prev,struct skl_wm_level * result)1834 static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
1835 struct intel_plane *plane,
1836 int level,
1837 unsigned int latency,
1838 const struct skl_wm_params *wp,
1839 const struct skl_wm_level *result_prev,
1840 struct skl_wm_level *result /* out */)
1841 {
1842 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1843 uint_fixed_16_16_t method1, method2;
1844 uint_fixed_16_16_t selected_result;
1845 u32 blocks, lines, min_ddb_alloc = 0;
1846
1847 if (latency == 0 ||
1848 (use_minimal_wm0_only(crtc_state, plane) && level > 0)) {
1849 /* reject it */
1850 result->min_ddb_alloc = U16_MAX;
1851 return;
1852 }
1853
1854 /*
1855 * WaIncreaseLatencyIPCEnabled: kbl,cfl
1856 * Display WA #1141: kbl,cfl
1857 */
1858 if ((IS_KABYLAKE(i915) || IS_COFFEELAKE(i915) || IS_COMETLAKE(i915)) &&
1859 skl_watermark_ipc_enabled(i915))
1860 latency += 4;
1861
1862 if (skl_needs_memory_bw_wa(i915) && wp->x_tiled)
1863 latency += 15;
1864
1865 method1 = skl_wm_method1(i915, wp->plane_pixel_rate,
1866 wp->cpp, latency, wp->dbuf_block_size);
1867 method2 = skl_wm_method2(wp->plane_pixel_rate,
1868 crtc_state->hw.pipe_mode.crtc_htotal,
1869 latency,
1870 wp->plane_blocks_per_line);
1871
1872 if (wp->y_tiled) {
1873 selected_result = max_fixed16(method2, wp->y_tile_minimum);
1874 } else {
1875 if ((wp->cpp * crtc_state->hw.pipe_mode.crtc_htotal /
1876 wp->dbuf_block_size < 1) &&
1877 (wp->plane_bytes_per_line / wp->dbuf_block_size < 1)) {
1878 selected_result = method2;
1879 } else if (latency >= wp->linetime_us) {
1880 if (DISPLAY_VER(i915) == 9)
1881 selected_result = min_fixed16(method1, method2);
1882 else
1883 selected_result = method2;
1884 } else {
1885 selected_result = method1;
1886 }
1887 }
1888
1889 blocks = fixed16_to_u32_round_up(selected_result) + 1;
1890 /*
1891 * Lets have blocks at minimum equivalent to plane_blocks_per_line
1892 * as there will be at minimum one line for lines configuration. This
1893 * is a work around for FIFO underruns observed with resolutions like
1894 * 4k 60 Hz in single channel DRAM configurations.
1895 *
1896 * As per the Bspec 49325, if the ddb allocation can hold at least
1897 * one plane_blocks_per_line, we should have selected method2 in
1898 * the above logic. Assuming that modern versions have enough dbuf
1899 * and method2 guarantees blocks equivalent to at least 1 line,
1900 * select the blocks as plane_blocks_per_line.
1901 *
1902 * TODO: Revisit the logic when we have better understanding on DRAM
1903 * channels' impact on the level 0 memory latency and the relevant
1904 * wm calculations.
1905 */
1906 if (skl_wm_has_lines(i915, level))
1907 blocks = max(blocks,
1908 fixed16_to_u32_round_up(wp->plane_blocks_per_line));
1909 lines = div_round_up_fixed16(selected_result,
1910 wp->plane_blocks_per_line);
1911
1912 if (DISPLAY_VER(i915) == 9) {
1913 /* Display WA #1125: skl,bxt,kbl */
1914 if (level == 0 && wp->rc_surface)
1915 blocks += fixed16_to_u32_round_up(wp->y_tile_minimum);
1916
1917 /* Display WA #1126: skl,bxt,kbl */
1918 if (level >= 1 && level <= 7) {
1919 if (wp->y_tiled) {
1920 blocks += fixed16_to_u32_round_up(wp->y_tile_minimum);
1921 lines += wp->y_min_scanlines;
1922 } else {
1923 blocks++;
1924 }
1925
1926 /*
1927 * Make sure result blocks for higher latency levels are
1928 * at least as high as level below the current level.
1929 * Assumption in DDB algorithm optimization for special
1930 * cases. Also covers Display WA #1125 for RC.
1931 */
1932 if (result_prev->blocks > blocks)
1933 blocks = result_prev->blocks;
1934 }
1935 }
1936
1937 if (DISPLAY_VER(i915) >= 11) {
1938 if (wp->y_tiled) {
1939 int extra_lines;
1940
1941 if (lines % wp->y_min_scanlines == 0)
1942 extra_lines = wp->y_min_scanlines;
1943 else
1944 extra_lines = wp->y_min_scanlines * 2 -
1945 lines % wp->y_min_scanlines;
1946
1947 min_ddb_alloc = mul_round_up_u32_fixed16(lines + extra_lines,
1948 wp->plane_blocks_per_line);
1949 } else {
1950 min_ddb_alloc = blocks + DIV_ROUND_UP(blocks, 10);
1951 }
1952 }
1953
1954 if (!skl_wm_has_lines(i915, level))
1955 lines = 0;
1956
1957 if (lines > skl_wm_max_lines(i915)) {
1958 /* reject it */
1959 result->min_ddb_alloc = U16_MAX;
1960 return;
1961 }
1962
1963 /*
1964 * If lines is valid, assume we can use this watermark level
1965 * for now. We'll come back and disable it after we calculate the
1966 * DDB allocation if it turns out we don't actually have enough
1967 * blocks to satisfy it.
1968 */
1969 result->blocks = blocks;
1970 result->lines = lines;
1971 /* Bspec says: value >= plane ddb allocation -> invalid, hence the +1 here */
1972 result->min_ddb_alloc = max(min_ddb_alloc, blocks) + 1;
1973 result->enable = true;
1974
1975 if (DISPLAY_VER(i915) < 12 && i915->display.sagv.block_time_us)
1976 result->can_sagv = latency >= i915->display.sagv.block_time_us;
1977 }
1978
1979 static void
skl_compute_wm_levels(const struct intel_crtc_state * crtc_state,struct intel_plane * plane,const struct skl_wm_params * wm_params,struct skl_wm_level * levels)1980 skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
1981 struct intel_plane *plane,
1982 const struct skl_wm_params *wm_params,
1983 struct skl_wm_level *levels)
1984 {
1985 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1986 int level, max_level = ilk_wm_max_level(i915);
1987 struct skl_wm_level *result_prev = &levels[0];
1988
1989 for (level = 0; level <= max_level; level++) {
1990 struct skl_wm_level *result = &levels[level];
1991 unsigned int latency = i915->display.wm.skl_latency[level];
1992
1993 skl_compute_plane_wm(crtc_state, plane, level, latency,
1994 wm_params, result_prev, result);
1995
1996 result_prev = result;
1997 }
1998 }
1999
tgl_compute_sagv_wm(const struct intel_crtc_state * crtc_state,struct intel_plane * plane,const struct skl_wm_params * wm_params,struct skl_plane_wm * plane_wm)2000 static void tgl_compute_sagv_wm(const struct intel_crtc_state *crtc_state,
2001 struct intel_plane *plane,
2002 const struct skl_wm_params *wm_params,
2003 struct skl_plane_wm *plane_wm)
2004 {
2005 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2006 struct skl_wm_level *sagv_wm = &plane_wm->sagv.wm0;
2007 struct skl_wm_level *levels = plane_wm->wm;
2008 unsigned int latency = 0;
2009
2010 if (i915->display.sagv.block_time_us)
2011 latency = i915->display.sagv.block_time_us + i915->display.wm.skl_latency[0];
2012
2013 skl_compute_plane_wm(crtc_state, plane, 0, latency,
2014 wm_params, &levels[0],
2015 sagv_wm);
2016 }
2017
skl_compute_transition_wm(struct drm_i915_private * i915,struct skl_wm_level * trans_wm,const struct skl_wm_level * wm0,const struct skl_wm_params * wp)2018 static void skl_compute_transition_wm(struct drm_i915_private *i915,
2019 struct skl_wm_level *trans_wm,
2020 const struct skl_wm_level *wm0,
2021 const struct skl_wm_params *wp)
2022 {
2023 u16 trans_min, trans_amount, trans_y_tile_min;
2024 u16 wm0_blocks, trans_offset, blocks;
2025
2026 /* Transition WM don't make any sense if ipc is disabled */
2027 if (!skl_watermark_ipc_enabled(i915))
2028 return;
2029
2030 /*
2031 * WaDisableTWM:skl,kbl,cfl,bxt
2032 * Transition WM are not recommended by HW team for GEN9
2033 */
2034 if (DISPLAY_VER(i915) == 9)
2035 return;
2036
2037 if (DISPLAY_VER(i915) >= 11)
2038 trans_min = 4;
2039 else
2040 trans_min = 14;
2041
2042 /* Display WA #1140: glk,cnl */
2043 if (DISPLAY_VER(i915) == 10)
2044 trans_amount = 0;
2045 else
2046 trans_amount = 10; /* This is configurable amount */
2047
2048 trans_offset = trans_min + trans_amount;
2049
2050 /*
2051 * The spec asks for Selected Result Blocks for wm0 (the real value),
2052 * not Result Blocks (the integer value). Pay attention to the capital
2053 * letters. The value wm_l0->blocks is actually Result Blocks, but
2054 * since Result Blocks is the ceiling of Selected Result Blocks plus 1,
2055 * and since we later will have to get the ceiling of the sum in the
2056 * transition watermarks calculation, we can just pretend Selected
2057 * Result Blocks is Result Blocks minus 1 and it should work for the
2058 * current platforms.
2059 */
2060 wm0_blocks = wm0->blocks - 1;
2061
2062 if (wp->y_tiled) {
2063 trans_y_tile_min =
2064 (u16)mul_round_up_u32_fixed16(2, wp->y_tile_minimum);
2065 blocks = max(wm0_blocks, trans_y_tile_min) + trans_offset;
2066 } else {
2067 blocks = wm0_blocks + trans_offset;
2068 }
2069 blocks++;
2070
2071 /*
2072 * Just assume we can enable the transition watermark. After
2073 * computing the DDB we'll come back and disable it if that
2074 * assumption turns out to be false.
2075 */
2076 trans_wm->blocks = blocks;
2077 trans_wm->min_ddb_alloc = max_t(u16, wm0->min_ddb_alloc, blocks + 1);
2078 trans_wm->enable = true;
2079 }
2080
skl_build_plane_wm_single(struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state,struct intel_plane * plane,int color_plane)2081 static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state,
2082 const struct intel_plane_state *plane_state,
2083 struct intel_plane *plane, int color_plane)
2084 {
2085 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2086 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
2087 struct skl_plane_wm *wm = &crtc_state->wm.skl.raw.planes[plane->id];
2088 struct skl_wm_params wm_params;
2089 int ret;
2090
2091 ret = skl_compute_plane_wm_params(crtc_state, plane_state,
2092 &wm_params, color_plane);
2093 if (ret)
2094 return ret;
2095
2096 skl_compute_wm_levels(crtc_state, plane, &wm_params, wm->wm);
2097
2098 skl_compute_transition_wm(i915, &wm->trans_wm,
2099 &wm->wm[0], &wm_params);
2100
2101 if (DISPLAY_VER(i915) >= 12) {
2102 tgl_compute_sagv_wm(crtc_state, plane, &wm_params, wm);
2103
2104 skl_compute_transition_wm(i915, &wm->sagv.trans_wm,
2105 &wm->sagv.wm0, &wm_params);
2106 }
2107
2108 return 0;
2109 }
2110
skl_build_plane_wm_uv(struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state,struct intel_plane * plane)2111 static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state,
2112 const struct intel_plane_state *plane_state,
2113 struct intel_plane *plane)
2114 {
2115 struct skl_plane_wm *wm = &crtc_state->wm.skl.raw.planes[plane->id];
2116 struct skl_wm_params wm_params;
2117 int ret;
2118
2119 wm->is_planar = true;
2120
2121 /* uv plane watermarks must also be validated for NV12/Planar */
2122 ret = skl_compute_plane_wm_params(crtc_state, plane_state,
2123 &wm_params, 1);
2124 if (ret)
2125 return ret;
2126
2127 skl_compute_wm_levels(crtc_state, plane, &wm_params, wm->uv_wm);
2128
2129 return 0;
2130 }
2131
skl_build_plane_wm(struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)2132 static int skl_build_plane_wm(struct intel_crtc_state *crtc_state,
2133 const struct intel_plane_state *plane_state)
2134 {
2135 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
2136 enum plane_id plane_id = plane->id;
2137 struct skl_plane_wm *wm = &crtc_state->wm.skl.raw.planes[plane_id];
2138 const struct drm_framebuffer *fb = plane_state->hw.fb;
2139 int ret;
2140
2141 memset(wm, 0, sizeof(*wm));
2142
2143 if (!intel_wm_plane_visible(crtc_state, plane_state))
2144 return 0;
2145
2146 ret = skl_build_plane_wm_single(crtc_state, plane_state,
2147 plane, 0);
2148 if (ret)
2149 return ret;
2150
2151 if (fb->format->is_yuv && fb->format->num_planes > 1) {
2152 ret = skl_build_plane_wm_uv(crtc_state, plane_state,
2153 plane);
2154 if (ret)
2155 return ret;
2156 }
2157
2158 return 0;
2159 }
2160
icl_build_plane_wm(struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)2161 static int icl_build_plane_wm(struct intel_crtc_state *crtc_state,
2162 const struct intel_plane_state *plane_state)
2163 {
2164 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
2165 struct drm_i915_private *i915 = to_i915(plane->base.dev);
2166 enum plane_id plane_id = plane->id;
2167 struct skl_plane_wm *wm = &crtc_state->wm.skl.raw.planes[plane_id];
2168 int ret;
2169
2170 /* Watermarks calculated in master */
2171 if (plane_state->planar_slave)
2172 return 0;
2173
2174 memset(wm, 0, sizeof(*wm));
2175
2176 if (plane_state->planar_linked_plane) {
2177 const struct drm_framebuffer *fb = plane_state->hw.fb;
2178
2179 drm_WARN_ON(&i915->drm,
2180 !intel_wm_plane_visible(crtc_state, plane_state));
2181 drm_WARN_ON(&i915->drm, !fb->format->is_yuv ||
2182 fb->format->num_planes == 1);
2183
2184 ret = skl_build_plane_wm_single(crtc_state, plane_state,
2185 plane_state->planar_linked_plane, 0);
2186 if (ret)
2187 return ret;
2188
2189 ret = skl_build_plane_wm_single(crtc_state, plane_state,
2190 plane, 1);
2191 if (ret)
2192 return ret;
2193 } else if (intel_wm_plane_visible(crtc_state, plane_state)) {
2194 ret = skl_build_plane_wm_single(crtc_state, plane_state,
2195 plane, 0);
2196 if (ret)
2197 return ret;
2198 }
2199
2200 return 0;
2201 }
2202
skl_build_pipe_wm(struct intel_atomic_state * state,struct intel_crtc * crtc)2203 static int skl_build_pipe_wm(struct intel_atomic_state *state,
2204 struct intel_crtc *crtc)
2205 {
2206 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
2207 struct intel_crtc_state *crtc_state =
2208 intel_atomic_get_new_crtc_state(state, crtc);
2209 const struct intel_plane_state *plane_state;
2210 struct intel_plane *plane;
2211 int ret, i;
2212
2213 for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
2214 /*
2215 * FIXME should perhaps check {old,new}_plane_crtc->hw.crtc
2216 * instead but we don't populate that correctly for NV12 Y
2217 * planes so for now hack this.
2218 */
2219 if (plane->pipe != crtc->pipe)
2220 continue;
2221
2222 if (DISPLAY_VER(i915) >= 11)
2223 ret = icl_build_plane_wm(crtc_state, plane_state);
2224 else
2225 ret = skl_build_plane_wm(crtc_state, plane_state);
2226 if (ret)
2227 return ret;
2228 }
2229
2230 crtc_state->wm.skl.optimal = crtc_state->wm.skl.raw;
2231
2232 return 0;
2233 }
2234
skl_ddb_entry_write(struct drm_i915_private * i915,i915_reg_t reg,const struct skl_ddb_entry * entry)2235 static void skl_ddb_entry_write(struct drm_i915_private *i915,
2236 i915_reg_t reg,
2237 const struct skl_ddb_entry *entry)
2238 {
2239 if (entry->end)
2240 intel_de_write_fw(i915, reg,
2241 PLANE_BUF_END(entry->end - 1) |
2242 PLANE_BUF_START(entry->start));
2243 else
2244 intel_de_write_fw(i915, reg, 0);
2245 }
2246
skl_write_wm_level(struct drm_i915_private * i915,i915_reg_t reg,const struct skl_wm_level * level)2247 static void skl_write_wm_level(struct drm_i915_private *i915,
2248 i915_reg_t reg,
2249 const struct skl_wm_level *level)
2250 {
2251 u32 val = 0;
2252
2253 if (level->enable)
2254 val |= PLANE_WM_EN;
2255 if (level->ignore_lines)
2256 val |= PLANE_WM_IGNORE_LINES;
2257 val |= REG_FIELD_PREP(PLANE_WM_BLOCKS_MASK, level->blocks);
2258 val |= REG_FIELD_PREP(PLANE_WM_LINES_MASK, level->lines);
2259
2260 intel_de_write_fw(i915, reg, val);
2261 }
2262
skl_write_plane_wm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state)2263 void skl_write_plane_wm(struct intel_plane *plane,
2264 const struct intel_crtc_state *crtc_state)
2265 {
2266 struct drm_i915_private *i915 = to_i915(plane->base.dev);
2267 int level, max_level = ilk_wm_max_level(i915);
2268 enum plane_id plane_id = plane->id;
2269 enum pipe pipe = plane->pipe;
2270 const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
2271 const struct skl_ddb_entry *ddb =
2272 &crtc_state->wm.skl.plane_ddb[plane_id];
2273 const struct skl_ddb_entry *ddb_y =
2274 &crtc_state->wm.skl.plane_ddb_y[plane_id];
2275
2276 for (level = 0; level <= max_level; level++)
2277 skl_write_wm_level(i915, PLANE_WM(pipe, plane_id, level),
2278 skl_plane_wm_level(pipe_wm, plane_id, level));
2279
2280 skl_write_wm_level(i915, PLANE_WM_TRANS(pipe, plane_id),
2281 skl_plane_trans_wm(pipe_wm, plane_id));
2282
2283 if (HAS_HW_SAGV_WM(i915)) {
2284 const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
2285
2286 skl_write_wm_level(i915, PLANE_WM_SAGV(pipe, plane_id),
2287 &wm->sagv.wm0);
2288 skl_write_wm_level(i915, PLANE_WM_SAGV_TRANS(pipe, plane_id),
2289 &wm->sagv.trans_wm);
2290 }
2291
2292 skl_ddb_entry_write(i915,
2293 PLANE_BUF_CFG(pipe, plane_id), ddb);
2294
2295 if (DISPLAY_VER(i915) < 11)
2296 skl_ddb_entry_write(i915,
2297 PLANE_NV12_BUF_CFG(pipe, plane_id), ddb_y);
2298 }
2299
skl_write_cursor_wm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state)2300 void skl_write_cursor_wm(struct intel_plane *plane,
2301 const struct intel_crtc_state *crtc_state)
2302 {
2303 struct drm_i915_private *i915 = to_i915(plane->base.dev);
2304 int level, max_level = ilk_wm_max_level(i915);
2305 enum plane_id plane_id = plane->id;
2306 enum pipe pipe = plane->pipe;
2307 const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
2308 const struct skl_ddb_entry *ddb =
2309 &crtc_state->wm.skl.plane_ddb[plane_id];
2310
2311 for (level = 0; level <= max_level; level++)
2312 skl_write_wm_level(i915, CUR_WM(pipe, level),
2313 skl_plane_wm_level(pipe_wm, plane_id, level));
2314
2315 skl_write_wm_level(i915, CUR_WM_TRANS(pipe),
2316 skl_plane_trans_wm(pipe_wm, plane_id));
2317
2318 if (HAS_HW_SAGV_WM(i915)) {
2319 const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
2320
2321 skl_write_wm_level(i915, CUR_WM_SAGV(pipe),
2322 &wm->sagv.wm0);
2323 skl_write_wm_level(i915, CUR_WM_SAGV_TRANS(pipe),
2324 &wm->sagv.trans_wm);
2325 }
2326
2327 skl_ddb_entry_write(i915, CUR_BUF_CFG(pipe), ddb);
2328 }
2329
skl_wm_level_equals(const struct skl_wm_level * l1,const struct skl_wm_level * l2)2330 static bool skl_wm_level_equals(const struct skl_wm_level *l1,
2331 const struct skl_wm_level *l2)
2332 {
2333 return l1->enable == l2->enable &&
2334 l1->ignore_lines == l2->ignore_lines &&
2335 l1->lines == l2->lines &&
2336 l1->blocks == l2->blocks;
2337 }
2338
skl_plane_wm_equals(struct drm_i915_private * i915,const struct skl_plane_wm * wm1,const struct skl_plane_wm * wm2)2339 static bool skl_plane_wm_equals(struct drm_i915_private *i915,
2340 const struct skl_plane_wm *wm1,
2341 const struct skl_plane_wm *wm2)
2342 {
2343 int level, max_level = ilk_wm_max_level(i915);
2344
2345 for (level = 0; level <= max_level; level++) {
2346 /*
2347 * We don't check uv_wm as the hardware doesn't actually
2348 * use it. It only gets used for calculating the required
2349 * ddb allocation.
2350 */
2351 if (!skl_wm_level_equals(&wm1->wm[level], &wm2->wm[level]))
2352 return false;
2353 }
2354
2355 return skl_wm_level_equals(&wm1->trans_wm, &wm2->trans_wm) &&
2356 skl_wm_level_equals(&wm1->sagv.wm0, &wm2->sagv.wm0) &&
2357 skl_wm_level_equals(&wm1->sagv.trans_wm, &wm2->sagv.trans_wm);
2358 }
2359
skl_ddb_entries_overlap(const struct skl_ddb_entry * a,const struct skl_ddb_entry * b)2360 static bool skl_ddb_entries_overlap(const struct skl_ddb_entry *a,
2361 const struct skl_ddb_entry *b)
2362 {
2363 return a->start < b->end && b->start < a->end;
2364 }
2365
skl_ddb_entry_union(struct skl_ddb_entry * a,const struct skl_ddb_entry * b)2366 static void skl_ddb_entry_union(struct skl_ddb_entry *a,
2367 const struct skl_ddb_entry *b)
2368 {
2369 if (a->end && b->end) {
2370 a->start = min(a->start, b->start);
2371 a->end = max(a->end, b->end);
2372 } else if (b->end) {
2373 a->start = b->start;
2374 a->end = b->end;
2375 }
2376 }
2377
skl_ddb_allocation_overlaps(const struct skl_ddb_entry * ddb,const struct skl_ddb_entry * entries,int num_entries,int ignore_idx)2378 bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
2379 const struct skl_ddb_entry *entries,
2380 int num_entries, int ignore_idx)
2381 {
2382 int i;
2383
2384 for (i = 0; i < num_entries; i++) {
2385 if (i != ignore_idx &&
2386 skl_ddb_entries_overlap(ddb, &entries[i]))
2387 return true;
2388 }
2389
2390 return false;
2391 }
2392
2393 static int
skl_ddb_add_affected_planes(const struct intel_crtc_state * old_crtc_state,struct intel_crtc_state * new_crtc_state)2394 skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state,
2395 struct intel_crtc_state *new_crtc_state)
2396 {
2397 struct intel_atomic_state *state = to_intel_atomic_state(new_crtc_state->uapi.state);
2398 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
2399 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
2400 struct intel_plane *plane;
2401
2402 for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
2403 struct intel_plane_state *plane_state;
2404 enum plane_id plane_id = plane->id;
2405
2406 if (skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb[plane_id],
2407 &new_crtc_state->wm.skl.plane_ddb[plane_id]) &&
2408 skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_y[plane_id],
2409 &new_crtc_state->wm.skl.plane_ddb_y[plane_id]))
2410 continue;
2411
2412 plane_state = intel_atomic_get_plane_state(state, plane);
2413 if (IS_ERR(plane_state))
2414 return PTR_ERR(plane_state);
2415
2416 new_crtc_state->update_planes |= BIT(plane_id);
2417 }
2418
2419 return 0;
2420 }
2421
intel_dbuf_enabled_slices(const struct intel_dbuf_state * dbuf_state)2422 static u8 intel_dbuf_enabled_slices(const struct intel_dbuf_state *dbuf_state)
2423 {
2424 struct drm_i915_private *i915 = to_i915(dbuf_state->base.state->base.dev);
2425 u8 enabled_slices;
2426 enum pipe pipe;
2427
2428 /*
2429 * FIXME: For now we always enable slice S1 as per
2430 * the Bspec display initialization sequence.
2431 */
2432 enabled_slices = BIT(DBUF_S1);
2433
2434 for_each_pipe(i915, pipe)
2435 enabled_slices |= dbuf_state->slices[pipe];
2436
2437 return enabled_slices;
2438 }
2439
2440 static int
skl_compute_ddb(struct intel_atomic_state * state)2441 skl_compute_ddb(struct intel_atomic_state *state)
2442 {
2443 struct drm_i915_private *i915 = to_i915(state->base.dev);
2444 const struct intel_dbuf_state *old_dbuf_state;
2445 struct intel_dbuf_state *new_dbuf_state = NULL;
2446 const struct intel_crtc_state *old_crtc_state;
2447 struct intel_crtc_state *new_crtc_state;
2448 struct intel_crtc *crtc;
2449 int ret, i;
2450
2451 for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
2452 new_dbuf_state = intel_atomic_get_dbuf_state(state);
2453 if (IS_ERR(new_dbuf_state))
2454 return PTR_ERR(new_dbuf_state);
2455
2456 old_dbuf_state = intel_atomic_get_old_dbuf_state(state);
2457 break;
2458 }
2459
2460 if (!new_dbuf_state)
2461 return 0;
2462
2463 new_dbuf_state->active_pipes =
2464 intel_calc_active_pipes(state, old_dbuf_state->active_pipes);
2465
2466 if (old_dbuf_state->active_pipes != new_dbuf_state->active_pipes) {
2467 ret = intel_atomic_lock_global_state(&new_dbuf_state->base);
2468 if (ret)
2469 return ret;
2470 }
2471
2472 if (HAS_MBUS_JOINING(i915))
2473 new_dbuf_state->joined_mbus =
2474 adlp_check_mbus_joined(new_dbuf_state->active_pipes);
2475
2476 for_each_intel_crtc(&i915->drm, crtc) {
2477 enum pipe pipe = crtc->pipe;
2478
2479 new_dbuf_state->slices[pipe] =
2480 skl_compute_dbuf_slices(crtc, new_dbuf_state->active_pipes,
2481 new_dbuf_state->joined_mbus);
2482
2483 if (old_dbuf_state->slices[pipe] == new_dbuf_state->slices[pipe])
2484 continue;
2485
2486 ret = intel_atomic_lock_global_state(&new_dbuf_state->base);
2487 if (ret)
2488 return ret;
2489 }
2490
2491 new_dbuf_state->enabled_slices = intel_dbuf_enabled_slices(new_dbuf_state);
2492
2493 if (old_dbuf_state->enabled_slices != new_dbuf_state->enabled_slices ||
2494 old_dbuf_state->joined_mbus != new_dbuf_state->joined_mbus) {
2495 ret = intel_atomic_serialize_global_state(&new_dbuf_state->base);
2496 if (ret)
2497 return ret;
2498
2499 if (old_dbuf_state->joined_mbus != new_dbuf_state->joined_mbus) {
2500 /* TODO: Implement vblank synchronized MBUS joining changes */
2501 ret = intel_modeset_all_pipes(state);
2502 if (ret)
2503 return ret;
2504 }
2505
2506 drm_dbg_kms(&i915->drm,
2507 "Enabled dbuf slices 0x%x -> 0x%x (total dbuf slices 0x%x), mbus joined? %s->%s\n",
2508 old_dbuf_state->enabled_slices,
2509 new_dbuf_state->enabled_slices,
2510 INTEL_INFO(i915)->display.dbuf.slice_mask,
2511 str_yes_no(old_dbuf_state->joined_mbus),
2512 str_yes_no(new_dbuf_state->joined_mbus));
2513 }
2514
2515 for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
2516 enum pipe pipe = crtc->pipe;
2517
2518 new_dbuf_state->weight[pipe] = intel_crtc_ddb_weight(new_crtc_state);
2519
2520 if (old_dbuf_state->weight[pipe] == new_dbuf_state->weight[pipe])
2521 continue;
2522
2523 ret = intel_atomic_lock_global_state(&new_dbuf_state->base);
2524 if (ret)
2525 return ret;
2526 }
2527
2528 for_each_intel_crtc(&i915->drm, crtc) {
2529 ret = skl_crtc_allocate_ddb(state, crtc);
2530 if (ret)
2531 return ret;
2532 }
2533
2534 for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
2535 new_crtc_state, i) {
2536 ret = skl_crtc_allocate_plane_ddb(state, crtc);
2537 if (ret)
2538 return ret;
2539
2540 ret = skl_ddb_add_affected_planes(old_crtc_state,
2541 new_crtc_state);
2542 if (ret)
2543 return ret;
2544 }
2545
2546 return 0;
2547 }
2548
enast(bool enable)2549 static char enast(bool enable)
2550 {
2551 return enable ? '*' : ' ';
2552 }
2553
2554 static void
skl_print_wm_changes(struct intel_atomic_state * state)2555 skl_print_wm_changes(struct intel_atomic_state *state)
2556 {
2557 struct drm_i915_private *i915 = to_i915(state->base.dev);
2558 const struct intel_crtc_state *old_crtc_state;
2559 const struct intel_crtc_state *new_crtc_state;
2560 struct intel_plane *plane;
2561 struct intel_crtc *crtc;
2562 int i;
2563
2564 if (!drm_debug_enabled(DRM_UT_KMS))
2565 return;
2566
2567 for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
2568 new_crtc_state, i) {
2569 const struct skl_pipe_wm *old_pipe_wm, *new_pipe_wm;
2570
2571 old_pipe_wm = &old_crtc_state->wm.skl.optimal;
2572 new_pipe_wm = &new_crtc_state->wm.skl.optimal;
2573
2574 for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
2575 enum plane_id plane_id = plane->id;
2576 const struct skl_ddb_entry *old, *new;
2577
2578 old = &old_crtc_state->wm.skl.plane_ddb[plane_id];
2579 new = &new_crtc_state->wm.skl.plane_ddb[plane_id];
2580
2581 if (skl_ddb_entry_equal(old, new))
2582 continue;
2583
2584 drm_dbg_kms(&i915->drm,
2585 "[PLANE:%d:%s] ddb (%4d - %4d) -> (%4d - %4d), size %4d -> %4d\n",
2586 plane->base.base.id, plane->base.name,
2587 old->start, old->end, new->start, new->end,
2588 skl_ddb_entry_size(old), skl_ddb_entry_size(new));
2589 }
2590
2591 for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
2592 enum plane_id plane_id = plane->id;
2593 const struct skl_plane_wm *old_wm, *new_wm;
2594
2595 old_wm = &old_pipe_wm->planes[plane_id];
2596 new_wm = &new_pipe_wm->planes[plane_id];
2597
2598 if (skl_plane_wm_equals(i915, old_wm, new_wm))
2599 continue;
2600
2601 drm_dbg_kms(&i915->drm,
2602 "[PLANE:%d:%s] level %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm,%cstwm"
2603 " -> %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm,%cstwm\n",
2604 plane->base.base.id, plane->base.name,
2605 enast(old_wm->wm[0].enable), enast(old_wm->wm[1].enable),
2606 enast(old_wm->wm[2].enable), enast(old_wm->wm[3].enable),
2607 enast(old_wm->wm[4].enable), enast(old_wm->wm[5].enable),
2608 enast(old_wm->wm[6].enable), enast(old_wm->wm[7].enable),
2609 enast(old_wm->trans_wm.enable),
2610 enast(old_wm->sagv.wm0.enable),
2611 enast(old_wm->sagv.trans_wm.enable),
2612 enast(new_wm->wm[0].enable), enast(new_wm->wm[1].enable),
2613 enast(new_wm->wm[2].enable), enast(new_wm->wm[3].enable),
2614 enast(new_wm->wm[4].enable), enast(new_wm->wm[5].enable),
2615 enast(new_wm->wm[6].enable), enast(new_wm->wm[7].enable),
2616 enast(new_wm->trans_wm.enable),
2617 enast(new_wm->sagv.wm0.enable),
2618 enast(new_wm->sagv.trans_wm.enable));
2619
2620 drm_dbg_kms(&i915->drm,
2621 "[PLANE:%d:%s] lines %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%4d"
2622 " -> %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%4d\n",
2623 plane->base.base.id, plane->base.name,
2624 enast(old_wm->wm[0].ignore_lines), old_wm->wm[0].lines,
2625 enast(old_wm->wm[1].ignore_lines), old_wm->wm[1].lines,
2626 enast(old_wm->wm[2].ignore_lines), old_wm->wm[2].lines,
2627 enast(old_wm->wm[3].ignore_lines), old_wm->wm[3].lines,
2628 enast(old_wm->wm[4].ignore_lines), old_wm->wm[4].lines,
2629 enast(old_wm->wm[5].ignore_lines), old_wm->wm[5].lines,
2630 enast(old_wm->wm[6].ignore_lines), old_wm->wm[6].lines,
2631 enast(old_wm->wm[7].ignore_lines), old_wm->wm[7].lines,
2632 enast(old_wm->trans_wm.ignore_lines), old_wm->trans_wm.lines,
2633 enast(old_wm->sagv.wm0.ignore_lines), old_wm->sagv.wm0.lines,
2634 enast(old_wm->sagv.trans_wm.ignore_lines), old_wm->sagv.trans_wm.lines,
2635 enast(new_wm->wm[0].ignore_lines), new_wm->wm[0].lines,
2636 enast(new_wm->wm[1].ignore_lines), new_wm->wm[1].lines,
2637 enast(new_wm->wm[2].ignore_lines), new_wm->wm[2].lines,
2638 enast(new_wm->wm[3].ignore_lines), new_wm->wm[3].lines,
2639 enast(new_wm->wm[4].ignore_lines), new_wm->wm[4].lines,
2640 enast(new_wm->wm[5].ignore_lines), new_wm->wm[5].lines,
2641 enast(new_wm->wm[6].ignore_lines), new_wm->wm[6].lines,
2642 enast(new_wm->wm[7].ignore_lines), new_wm->wm[7].lines,
2643 enast(new_wm->trans_wm.ignore_lines), new_wm->trans_wm.lines,
2644 enast(new_wm->sagv.wm0.ignore_lines), new_wm->sagv.wm0.lines,
2645 enast(new_wm->sagv.trans_wm.ignore_lines), new_wm->sagv.trans_wm.lines);
2646
2647 drm_dbg_kms(&i915->drm,
2648 "[PLANE:%d:%s] blocks %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d"
2649 " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d\n",
2650 plane->base.base.id, plane->base.name,
2651 old_wm->wm[0].blocks, old_wm->wm[1].blocks,
2652 old_wm->wm[2].blocks, old_wm->wm[3].blocks,
2653 old_wm->wm[4].blocks, old_wm->wm[5].blocks,
2654 old_wm->wm[6].blocks, old_wm->wm[7].blocks,
2655 old_wm->trans_wm.blocks,
2656 old_wm->sagv.wm0.blocks,
2657 old_wm->sagv.trans_wm.blocks,
2658 new_wm->wm[0].blocks, new_wm->wm[1].blocks,
2659 new_wm->wm[2].blocks, new_wm->wm[3].blocks,
2660 new_wm->wm[4].blocks, new_wm->wm[5].blocks,
2661 new_wm->wm[6].blocks, new_wm->wm[7].blocks,
2662 new_wm->trans_wm.blocks,
2663 new_wm->sagv.wm0.blocks,
2664 new_wm->sagv.trans_wm.blocks);
2665
2666 drm_dbg_kms(&i915->drm,
2667 "[PLANE:%d:%s] min_ddb %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d"
2668 " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d\n",
2669 plane->base.base.id, plane->base.name,
2670 old_wm->wm[0].min_ddb_alloc, old_wm->wm[1].min_ddb_alloc,
2671 old_wm->wm[2].min_ddb_alloc, old_wm->wm[3].min_ddb_alloc,
2672 old_wm->wm[4].min_ddb_alloc, old_wm->wm[5].min_ddb_alloc,
2673 old_wm->wm[6].min_ddb_alloc, old_wm->wm[7].min_ddb_alloc,
2674 old_wm->trans_wm.min_ddb_alloc,
2675 old_wm->sagv.wm0.min_ddb_alloc,
2676 old_wm->sagv.trans_wm.min_ddb_alloc,
2677 new_wm->wm[0].min_ddb_alloc, new_wm->wm[1].min_ddb_alloc,
2678 new_wm->wm[2].min_ddb_alloc, new_wm->wm[3].min_ddb_alloc,
2679 new_wm->wm[4].min_ddb_alloc, new_wm->wm[5].min_ddb_alloc,
2680 new_wm->wm[6].min_ddb_alloc, new_wm->wm[7].min_ddb_alloc,
2681 new_wm->trans_wm.min_ddb_alloc,
2682 new_wm->sagv.wm0.min_ddb_alloc,
2683 new_wm->sagv.trans_wm.min_ddb_alloc);
2684 }
2685 }
2686 }
2687
skl_plane_selected_wm_equals(struct intel_plane * plane,const struct skl_pipe_wm * old_pipe_wm,const struct skl_pipe_wm * new_pipe_wm)2688 static bool skl_plane_selected_wm_equals(struct intel_plane *plane,
2689 const struct skl_pipe_wm *old_pipe_wm,
2690 const struct skl_pipe_wm *new_pipe_wm)
2691 {
2692 struct drm_i915_private *i915 = to_i915(plane->base.dev);
2693 int level, max_level = ilk_wm_max_level(i915);
2694
2695 for (level = 0; level <= max_level; level++) {
2696 /*
2697 * We don't check uv_wm as the hardware doesn't actually
2698 * use it. It only gets used for calculating the required
2699 * ddb allocation.
2700 */
2701 if (!skl_wm_level_equals(skl_plane_wm_level(old_pipe_wm, plane->id, level),
2702 skl_plane_wm_level(new_pipe_wm, plane->id, level)))
2703 return false;
2704 }
2705
2706 if (HAS_HW_SAGV_WM(i915)) {
2707 const struct skl_plane_wm *old_wm = &old_pipe_wm->planes[plane->id];
2708 const struct skl_plane_wm *new_wm = &new_pipe_wm->planes[plane->id];
2709
2710 if (!skl_wm_level_equals(&old_wm->sagv.wm0, &new_wm->sagv.wm0) ||
2711 !skl_wm_level_equals(&old_wm->sagv.trans_wm, &new_wm->sagv.trans_wm))
2712 return false;
2713 }
2714
2715 return skl_wm_level_equals(skl_plane_trans_wm(old_pipe_wm, plane->id),
2716 skl_plane_trans_wm(new_pipe_wm, plane->id));
2717 }
2718
2719 /*
2720 * To make sure the cursor watermark registers are always consistent
2721 * with our computed state the following scenario needs special
2722 * treatment:
2723 *
2724 * 1. enable cursor
2725 * 2. move cursor entirely offscreen
2726 * 3. disable cursor
2727 *
2728 * Step 2. does call .disable_plane() but does not zero the watermarks
2729 * (since we consider an offscreen cursor still active for the purposes
2730 * of watermarks). Step 3. would not normally call .disable_plane()
2731 * because the actual plane visibility isn't changing, and we don't
2732 * deallocate the cursor ddb until the pipe gets disabled. So we must
2733 * force step 3. to call .disable_plane() to update the watermark
2734 * registers properly.
2735 *
2736 * Other planes do not suffer from this issues as their watermarks are
2737 * calculated based on the actual plane visibility. The only time this
2738 * can trigger for the other planes is during the initial readout as the
2739 * default value of the watermarks registers is not zero.
2740 */
skl_wm_add_affected_planes(struct intel_atomic_state * state,struct intel_crtc * crtc)2741 static int skl_wm_add_affected_planes(struct intel_atomic_state *state,
2742 struct intel_crtc *crtc)
2743 {
2744 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
2745 const struct intel_crtc_state *old_crtc_state =
2746 intel_atomic_get_old_crtc_state(state, crtc);
2747 struct intel_crtc_state *new_crtc_state =
2748 intel_atomic_get_new_crtc_state(state, crtc);
2749 struct intel_plane *plane;
2750
2751 for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
2752 struct intel_plane_state *plane_state;
2753 enum plane_id plane_id = plane->id;
2754
2755 /*
2756 * Force a full wm update for every plane on modeset.
2757 * Required because the reset value of the wm registers
2758 * is non-zero, whereas we want all disabled planes to
2759 * have zero watermarks. So if we turn off the relevant
2760 * power well the hardware state will go out of sync
2761 * with the software state.
2762 */
2763 if (!drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi) &&
2764 skl_plane_selected_wm_equals(plane,
2765 &old_crtc_state->wm.skl.optimal,
2766 &new_crtc_state->wm.skl.optimal))
2767 continue;
2768
2769 plane_state = intel_atomic_get_plane_state(state, plane);
2770 if (IS_ERR(plane_state))
2771 return PTR_ERR(plane_state);
2772
2773 new_crtc_state->update_planes |= BIT(plane_id);
2774 }
2775
2776 return 0;
2777 }
2778
2779 static int
skl_compute_wm(struct intel_atomic_state * state)2780 skl_compute_wm(struct intel_atomic_state *state)
2781 {
2782 struct intel_crtc *crtc;
2783 struct intel_crtc_state *new_crtc_state;
2784 int ret, i;
2785
2786 for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
2787 ret = skl_build_pipe_wm(state, crtc);
2788 if (ret)
2789 return ret;
2790 }
2791
2792 ret = skl_compute_ddb(state);
2793 if (ret)
2794 return ret;
2795
2796 ret = intel_compute_sagv_mask(state);
2797 if (ret)
2798 return ret;
2799
2800 /*
2801 * skl_compute_ddb() will have adjusted the final watermarks
2802 * based on how much ddb is available. Now we can actually
2803 * check if the final watermarks changed.
2804 */
2805 for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
2806 ret = skl_wm_add_affected_planes(state, crtc);
2807 if (ret)
2808 return ret;
2809 }
2810
2811 skl_print_wm_changes(state);
2812
2813 return 0;
2814 }
2815
skl_wm_level_from_reg_val(u32 val,struct skl_wm_level * level)2816 static void skl_wm_level_from_reg_val(u32 val, struct skl_wm_level *level)
2817 {
2818 level->enable = val & PLANE_WM_EN;
2819 level->ignore_lines = val & PLANE_WM_IGNORE_LINES;
2820 level->blocks = REG_FIELD_GET(PLANE_WM_BLOCKS_MASK, val);
2821 level->lines = REG_FIELD_GET(PLANE_WM_LINES_MASK, val);
2822 }
2823
skl_pipe_wm_get_hw_state(struct intel_crtc * crtc,struct skl_pipe_wm * out)2824 static void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
2825 struct skl_pipe_wm *out)
2826 {
2827 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
2828 enum pipe pipe = crtc->pipe;
2829 int level, max_level;
2830 enum plane_id plane_id;
2831 u32 val;
2832
2833 max_level = ilk_wm_max_level(i915);
2834
2835 for_each_plane_id_on_crtc(crtc, plane_id) {
2836 struct skl_plane_wm *wm = &out->planes[plane_id];
2837
2838 for (level = 0; level <= max_level; level++) {
2839 if (plane_id != PLANE_CURSOR)
2840 val = intel_uncore_read(&i915->uncore, PLANE_WM(pipe, plane_id, level));
2841 else
2842 val = intel_uncore_read(&i915->uncore, CUR_WM(pipe, level));
2843
2844 skl_wm_level_from_reg_val(val, &wm->wm[level]);
2845 }
2846
2847 if (plane_id != PLANE_CURSOR)
2848 val = intel_uncore_read(&i915->uncore, PLANE_WM_TRANS(pipe, plane_id));
2849 else
2850 val = intel_uncore_read(&i915->uncore, CUR_WM_TRANS(pipe));
2851
2852 skl_wm_level_from_reg_val(val, &wm->trans_wm);
2853
2854 if (HAS_HW_SAGV_WM(i915)) {
2855 if (plane_id != PLANE_CURSOR)
2856 val = intel_uncore_read(&i915->uncore,
2857 PLANE_WM_SAGV(pipe, plane_id));
2858 else
2859 val = intel_uncore_read(&i915->uncore,
2860 CUR_WM_SAGV(pipe));
2861
2862 skl_wm_level_from_reg_val(val, &wm->sagv.wm0);
2863
2864 if (plane_id != PLANE_CURSOR)
2865 val = intel_uncore_read(&i915->uncore,
2866 PLANE_WM_SAGV_TRANS(pipe, plane_id));
2867 else
2868 val = intel_uncore_read(&i915->uncore,
2869 CUR_WM_SAGV_TRANS(pipe));
2870
2871 skl_wm_level_from_reg_val(val, &wm->sagv.trans_wm);
2872 } else if (DISPLAY_VER(i915) >= 12) {
2873 wm->sagv.wm0 = wm->wm[0];
2874 wm->sagv.trans_wm = wm->trans_wm;
2875 }
2876 }
2877 }
2878
skl_wm_get_hw_state(struct drm_i915_private * i915)2879 void skl_wm_get_hw_state(struct drm_i915_private *i915)
2880 {
2881 struct intel_dbuf_state *dbuf_state =
2882 to_intel_dbuf_state(i915->display.dbuf.obj.state);
2883 struct intel_crtc *crtc;
2884
2885 if (HAS_MBUS_JOINING(i915))
2886 dbuf_state->joined_mbus = intel_de_read(i915, MBUS_CTL) & MBUS_JOIN;
2887
2888 for_each_intel_crtc(&i915->drm, crtc) {
2889 struct intel_crtc_state *crtc_state =
2890 to_intel_crtc_state(crtc->base.state);
2891 enum pipe pipe = crtc->pipe;
2892 unsigned int mbus_offset;
2893 enum plane_id plane_id;
2894 u8 slices;
2895
2896 memset(&crtc_state->wm.skl.optimal, 0,
2897 sizeof(crtc_state->wm.skl.optimal));
2898 if (crtc_state->hw.active)
2899 skl_pipe_wm_get_hw_state(crtc, &crtc_state->wm.skl.optimal);
2900 crtc_state->wm.skl.raw = crtc_state->wm.skl.optimal;
2901
2902 memset(&dbuf_state->ddb[pipe], 0, sizeof(dbuf_state->ddb[pipe]));
2903
2904 for_each_plane_id_on_crtc(crtc, plane_id) {
2905 struct skl_ddb_entry *ddb =
2906 &crtc_state->wm.skl.plane_ddb[plane_id];
2907 struct skl_ddb_entry *ddb_y =
2908 &crtc_state->wm.skl.plane_ddb_y[plane_id];
2909
2910 if (!crtc_state->hw.active)
2911 continue;
2912
2913 skl_ddb_get_hw_plane_state(i915, crtc->pipe,
2914 plane_id, ddb, ddb_y);
2915
2916 skl_ddb_entry_union(&dbuf_state->ddb[pipe], ddb);
2917 skl_ddb_entry_union(&dbuf_state->ddb[pipe], ddb_y);
2918 }
2919
2920 dbuf_state->weight[pipe] = intel_crtc_ddb_weight(crtc_state);
2921
2922 /*
2923 * Used for checking overlaps, so we need absolute
2924 * offsets instead of MBUS relative offsets.
2925 */
2926 slices = skl_compute_dbuf_slices(crtc, dbuf_state->active_pipes,
2927 dbuf_state->joined_mbus);
2928 mbus_offset = mbus_ddb_offset(i915, slices);
2929 crtc_state->wm.skl.ddb.start = mbus_offset + dbuf_state->ddb[pipe].start;
2930 crtc_state->wm.skl.ddb.end = mbus_offset + dbuf_state->ddb[pipe].end;
2931
2932 /* The slices actually used by the planes on the pipe */
2933 dbuf_state->slices[pipe] =
2934 skl_ddb_dbuf_slice_mask(i915, &crtc_state->wm.skl.ddb);
2935
2936 drm_dbg_kms(&i915->drm,
2937 "[CRTC:%d:%s] dbuf slices 0x%x, ddb (%d - %d), active pipes 0x%x, mbus joined: %s\n",
2938 crtc->base.base.id, crtc->base.name,
2939 dbuf_state->slices[pipe], dbuf_state->ddb[pipe].start,
2940 dbuf_state->ddb[pipe].end, dbuf_state->active_pipes,
2941 str_yes_no(dbuf_state->joined_mbus));
2942 }
2943
2944 dbuf_state->enabled_slices = i915->display.dbuf.enabled_slices;
2945 }
2946
skl_dbuf_is_misconfigured(struct drm_i915_private * i915)2947 static bool skl_dbuf_is_misconfigured(struct drm_i915_private *i915)
2948 {
2949 const struct intel_dbuf_state *dbuf_state =
2950 to_intel_dbuf_state(i915->display.dbuf.obj.state);
2951 struct skl_ddb_entry entries[I915_MAX_PIPES] = {};
2952 struct intel_crtc *crtc;
2953
2954 for_each_intel_crtc(&i915->drm, crtc) {
2955 const struct intel_crtc_state *crtc_state =
2956 to_intel_crtc_state(crtc->base.state);
2957
2958 entries[crtc->pipe] = crtc_state->wm.skl.ddb;
2959 }
2960
2961 for_each_intel_crtc(&i915->drm, crtc) {
2962 const struct intel_crtc_state *crtc_state =
2963 to_intel_crtc_state(crtc->base.state);
2964 u8 slices;
2965
2966 slices = skl_compute_dbuf_slices(crtc, dbuf_state->active_pipes,
2967 dbuf_state->joined_mbus);
2968 if (dbuf_state->slices[crtc->pipe] & ~slices)
2969 return true;
2970
2971 if (skl_ddb_allocation_overlaps(&crtc_state->wm.skl.ddb, entries,
2972 I915_MAX_PIPES, crtc->pipe))
2973 return true;
2974 }
2975
2976 return false;
2977 }
2978
skl_wm_sanitize(struct drm_i915_private * i915)2979 void skl_wm_sanitize(struct drm_i915_private *i915)
2980 {
2981 struct intel_crtc *crtc;
2982
2983 /*
2984 * On TGL/RKL (at least) the BIOS likes to assign the planes
2985 * to the wrong DBUF slices. This will cause an infinite loop
2986 * in skl_commit_modeset_enables() as it can't find a way to
2987 * transition between the old bogus DBUF layout to the new
2988 * proper DBUF layout without DBUF allocation overlaps between
2989 * the planes (which cannot be allowed or else the hardware
2990 * may hang). If we detect a bogus DBUF layout just turn off
2991 * all the planes so that skl_commit_modeset_enables() can
2992 * simply ignore them.
2993 */
2994 if (!skl_dbuf_is_misconfigured(i915))
2995 return;
2996
2997 drm_dbg_kms(&i915->drm, "BIOS has misprogrammed the DBUF, disabling all planes\n");
2998
2999 for_each_intel_crtc(&i915->drm, crtc) {
3000 struct intel_plane *plane = to_intel_plane(crtc->base.primary);
3001 const struct intel_plane_state *plane_state =
3002 to_intel_plane_state(plane->base.state);
3003 struct intel_crtc_state *crtc_state =
3004 to_intel_crtc_state(crtc->base.state);
3005
3006 if (plane_state->uapi.visible)
3007 intel_plane_disable_noatomic(crtc, plane);
3008
3009 drm_WARN_ON(&i915->drm, crtc_state->active_planes != 0);
3010
3011 memset(&crtc_state->wm.skl.ddb, 0, sizeof(crtc_state->wm.skl.ddb));
3012 }
3013 }
3014
intel_wm_state_verify(struct intel_crtc * crtc,struct intel_crtc_state * new_crtc_state)3015 void intel_wm_state_verify(struct intel_crtc *crtc,
3016 struct intel_crtc_state *new_crtc_state)
3017 {
3018 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3019 struct skl_hw_state {
3020 struct skl_ddb_entry ddb[I915_MAX_PLANES];
3021 struct skl_ddb_entry ddb_y[I915_MAX_PLANES];
3022 struct skl_pipe_wm wm;
3023 } *hw;
3024 const struct skl_pipe_wm *sw_wm = &new_crtc_state->wm.skl.optimal;
3025 int level, max_level = ilk_wm_max_level(i915);
3026 struct intel_plane *plane;
3027 u8 hw_enabled_slices;
3028
3029 if (DISPLAY_VER(i915) < 9 || !new_crtc_state->hw.active)
3030 return;
3031
3032 hw = kzalloc(sizeof(*hw), GFP_KERNEL);
3033 if (!hw)
3034 return;
3035
3036 skl_pipe_wm_get_hw_state(crtc, &hw->wm);
3037
3038 skl_pipe_ddb_get_hw_state(crtc, hw->ddb, hw->ddb_y);
3039
3040 hw_enabled_slices = intel_enabled_dbuf_slices_mask(i915);
3041
3042 if (DISPLAY_VER(i915) >= 11 &&
3043 hw_enabled_slices != i915->display.dbuf.enabled_slices)
3044 drm_err(&i915->drm,
3045 "mismatch in DBUF Slices (expected 0x%x, got 0x%x)\n",
3046 i915->display.dbuf.enabled_slices,
3047 hw_enabled_slices);
3048
3049 for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
3050 const struct skl_ddb_entry *hw_ddb_entry, *sw_ddb_entry;
3051 const struct skl_wm_level *hw_wm_level, *sw_wm_level;
3052
3053 /* Watermarks */
3054 for (level = 0; level <= max_level; level++) {
3055 hw_wm_level = &hw->wm.planes[plane->id].wm[level];
3056 sw_wm_level = skl_plane_wm_level(sw_wm, plane->id, level);
3057
3058 if (skl_wm_level_equals(hw_wm_level, sw_wm_level))
3059 continue;
3060
3061 drm_err(&i915->drm,
3062 "[PLANE:%d:%s] mismatch in WM%d (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n",
3063 plane->base.base.id, plane->base.name, level,
3064 sw_wm_level->enable,
3065 sw_wm_level->blocks,
3066 sw_wm_level->lines,
3067 hw_wm_level->enable,
3068 hw_wm_level->blocks,
3069 hw_wm_level->lines);
3070 }
3071
3072 hw_wm_level = &hw->wm.planes[plane->id].trans_wm;
3073 sw_wm_level = skl_plane_trans_wm(sw_wm, plane->id);
3074
3075 if (!skl_wm_level_equals(hw_wm_level, sw_wm_level)) {
3076 drm_err(&i915->drm,
3077 "[PLANE:%d:%s] mismatch in trans WM (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n",
3078 plane->base.base.id, plane->base.name,
3079 sw_wm_level->enable,
3080 sw_wm_level->blocks,
3081 sw_wm_level->lines,
3082 hw_wm_level->enable,
3083 hw_wm_level->blocks,
3084 hw_wm_level->lines);
3085 }
3086
3087 hw_wm_level = &hw->wm.planes[plane->id].sagv.wm0;
3088 sw_wm_level = &sw_wm->planes[plane->id].sagv.wm0;
3089
3090 if (HAS_HW_SAGV_WM(i915) &&
3091 !skl_wm_level_equals(hw_wm_level, sw_wm_level)) {
3092 drm_err(&i915->drm,
3093 "[PLANE:%d:%s] mismatch in SAGV WM (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n",
3094 plane->base.base.id, plane->base.name,
3095 sw_wm_level->enable,
3096 sw_wm_level->blocks,
3097 sw_wm_level->lines,
3098 hw_wm_level->enable,
3099 hw_wm_level->blocks,
3100 hw_wm_level->lines);
3101 }
3102
3103 hw_wm_level = &hw->wm.planes[plane->id].sagv.trans_wm;
3104 sw_wm_level = &sw_wm->planes[plane->id].sagv.trans_wm;
3105
3106 if (HAS_HW_SAGV_WM(i915) &&
3107 !skl_wm_level_equals(hw_wm_level, sw_wm_level)) {
3108 drm_err(&i915->drm,
3109 "[PLANE:%d:%s] mismatch in SAGV trans WM (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n",
3110 plane->base.base.id, plane->base.name,
3111 sw_wm_level->enable,
3112 sw_wm_level->blocks,
3113 sw_wm_level->lines,
3114 hw_wm_level->enable,
3115 hw_wm_level->blocks,
3116 hw_wm_level->lines);
3117 }
3118
3119 /* DDB */
3120 hw_ddb_entry = &hw->ddb[PLANE_CURSOR];
3121 sw_ddb_entry = &new_crtc_state->wm.skl.plane_ddb[PLANE_CURSOR];
3122
3123 if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) {
3124 drm_err(&i915->drm,
3125 "[PLANE:%d:%s] mismatch in DDB (expected (%u,%u), found (%u,%u))\n",
3126 plane->base.base.id, plane->base.name,
3127 sw_ddb_entry->start, sw_ddb_entry->end,
3128 hw_ddb_entry->start, hw_ddb_entry->end);
3129 }
3130 }
3131
3132 kfree(hw);
3133 }
3134
skl_watermark_ipc_enabled(struct drm_i915_private * i915)3135 bool skl_watermark_ipc_enabled(struct drm_i915_private *i915)
3136 {
3137 return i915->display.wm.ipc_enabled;
3138 }
3139
skl_watermark_ipc_update(struct drm_i915_private * i915)3140 void skl_watermark_ipc_update(struct drm_i915_private *i915)
3141 {
3142 if (!HAS_IPC(i915))
3143 return;
3144
3145 intel_uncore_rmw(&i915->uncore, DISP_ARB_CTL2, DISP_IPC_ENABLE,
3146 skl_watermark_ipc_enabled(i915) ? DISP_IPC_ENABLE : 0);
3147 }
3148
skl_watermark_ipc_can_enable(struct drm_i915_private * i915)3149 static bool skl_watermark_ipc_can_enable(struct drm_i915_private *i915)
3150 {
3151 /* Display WA #0477 WaDisableIPC: skl */
3152 if (IS_SKYLAKE(i915))
3153 return false;
3154
3155 /* Display WA #1141: SKL:all KBL:all CFL */
3156 if (IS_KABYLAKE(i915) ||
3157 IS_COFFEELAKE(i915) ||
3158 IS_COMETLAKE(i915))
3159 return i915->dram_info.symmetric_memory;
3160
3161 return true;
3162 }
3163
skl_watermark_ipc_init(struct drm_i915_private * i915)3164 void skl_watermark_ipc_init(struct drm_i915_private *i915)
3165 {
3166 if (!HAS_IPC(i915))
3167 return;
3168
3169 i915->display.wm.ipc_enabled = skl_watermark_ipc_can_enable(i915);
3170
3171 skl_watermark_ipc_update(i915);
3172 }
3173
3174 static void
adjust_wm_latency(struct drm_i915_private * i915,u16 wm[],int max_level,int read_latency)3175 adjust_wm_latency(struct drm_i915_private *i915,
3176 u16 wm[], int max_level, int read_latency)
3177 {
3178 bool wm_lv_0_adjust_needed = i915->dram_info.wm_lv_0_adjust_needed;
3179 int i, level;
3180
3181 /*
3182 * If a level n (n > 1) has a 0us latency, all levels m (m >= n)
3183 * need to be disabled. We make sure to sanitize the values out
3184 * of the punit to satisfy this requirement.
3185 */
3186 for (level = 1; level <= max_level; level++) {
3187 if (wm[level] == 0) {
3188 for (i = level + 1; i <= max_level; i++)
3189 wm[i] = 0;
3190
3191 max_level = level - 1;
3192 break;
3193 }
3194 }
3195
3196 /*
3197 * WaWmMemoryReadLatency
3198 *
3199 * punit doesn't take into account the read latency so we need
3200 * to add proper adjustement to each valid level we retrieve
3201 * from the punit when level 0 response data is 0us.
3202 */
3203 if (wm[0] == 0) {
3204 for (level = 0; level <= max_level; level++)
3205 wm[level] += read_latency;
3206 }
3207
3208 /*
3209 * WA Level-0 adjustment for 16GB DIMMs: SKL+
3210 * If we could not get dimm info enable this WA to prevent from
3211 * any underrun. If not able to get Dimm info assume 16GB dimm
3212 * to avoid any underrun.
3213 */
3214 if (wm_lv_0_adjust_needed)
3215 wm[0] += 1;
3216 }
3217
mtl_read_wm_latency(struct drm_i915_private * i915,u16 wm[])3218 static void mtl_read_wm_latency(struct drm_i915_private *i915, u16 wm[])
3219 {
3220 struct intel_uncore *uncore = &i915->uncore;
3221 int max_level = ilk_wm_max_level(i915);
3222 u32 val;
3223
3224 val = intel_uncore_read(uncore, MTL_LATENCY_LP0_LP1);
3225 wm[0] = REG_FIELD_GET(MTL_LATENCY_LEVEL_EVEN_MASK, val);
3226 wm[1] = REG_FIELD_GET(MTL_LATENCY_LEVEL_ODD_MASK, val);
3227
3228 val = intel_uncore_read(uncore, MTL_LATENCY_LP2_LP3);
3229 wm[2] = REG_FIELD_GET(MTL_LATENCY_LEVEL_EVEN_MASK, val);
3230 wm[3] = REG_FIELD_GET(MTL_LATENCY_LEVEL_ODD_MASK, val);
3231
3232 val = intel_uncore_read(uncore, MTL_LATENCY_LP4_LP5);
3233 wm[4] = REG_FIELD_GET(MTL_LATENCY_LEVEL_EVEN_MASK, val);
3234 wm[5] = REG_FIELD_GET(MTL_LATENCY_LEVEL_ODD_MASK, val);
3235
3236 adjust_wm_latency(i915, wm, max_level, 6);
3237 }
3238
skl_read_wm_latency(struct drm_i915_private * i915,u16 wm[])3239 static void skl_read_wm_latency(struct drm_i915_private *i915, u16 wm[])
3240 {
3241 int max_level = ilk_wm_max_level(i915);
3242 int read_latency = DISPLAY_VER(i915) >= 12 ? 3 : 2;
3243 int mult = IS_DG2(i915) ? 2 : 1;
3244 u32 val;
3245 int ret;
3246
3247 /* read the first set of memory latencies[0:3] */
3248 val = 0; /* data0 to be programmed to 0 for first set */
3249 ret = snb_pcode_read(&i915->uncore, GEN9_PCODE_READ_MEM_LATENCY, &val, NULL);
3250 if (ret) {
3251 drm_err(&i915->drm, "SKL Mailbox read error = %d\n", ret);
3252 return;
3253 }
3254
3255 wm[0] = REG_FIELD_GET(GEN9_MEM_LATENCY_LEVEL_0_4_MASK, val) * mult;
3256 wm[1] = REG_FIELD_GET(GEN9_MEM_LATENCY_LEVEL_1_5_MASK, val) * mult;
3257 wm[2] = REG_FIELD_GET(GEN9_MEM_LATENCY_LEVEL_2_6_MASK, val) * mult;
3258 wm[3] = REG_FIELD_GET(GEN9_MEM_LATENCY_LEVEL_3_7_MASK, val) * mult;
3259
3260 /* read the second set of memory latencies[4:7] */
3261 val = 1; /* data0 to be programmed to 1 for second set */
3262 ret = snb_pcode_read(&i915->uncore, GEN9_PCODE_READ_MEM_LATENCY, &val, NULL);
3263 if (ret) {
3264 drm_err(&i915->drm, "SKL Mailbox read error = %d\n", ret);
3265 return;
3266 }
3267
3268 wm[4] = REG_FIELD_GET(GEN9_MEM_LATENCY_LEVEL_0_4_MASK, val) * mult;
3269 wm[5] = REG_FIELD_GET(GEN9_MEM_LATENCY_LEVEL_1_5_MASK, val) * mult;
3270 wm[6] = REG_FIELD_GET(GEN9_MEM_LATENCY_LEVEL_2_6_MASK, val) * mult;
3271 wm[7] = REG_FIELD_GET(GEN9_MEM_LATENCY_LEVEL_3_7_MASK, val) * mult;
3272
3273 adjust_wm_latency(i915, wm, max_level, read_latency);
3274 }
3275
skl_setup_wm_latency(struct drm_i915_private * i915)3276 static void skl_setup_wm_latency(struct drm_i915_private *i915)
3277 {
3278 if (DISPLAY_VER(i915) >= 14)
3279 mtl_read_wm_latency(i915, i915->display.wm.skl_latency);
3280 else
3281 skl_read_wm_latency(i915, i915->display.wm.skl_latency);
3282
3283 intel_print_wm_latency(i915, "Gen9 Plane", i915->display.wm.skl_latency);
3284 }
3285
3286 static const struct intel_wm_funcs skl_wm_funcs = {
3287 .compute_global_watermarks = skl_compute_wm,
3288 };
3289
skl_wm_init(struct drm_i915_private * i915)3290 void skl_wm_init(struct drm_i915_private *i915)
3291 {
3292 intel_sagv_init(i915);
3293
3294 skl_setup_wm_latency(i915);
3295
3296 i915->display.funcs.wm = &skl_wm_funcs;
3297 }
3298
intel_dbuf_duplicate_state(struct intel_global_obj * obj)3299 static struct intel_global_state *intel_dbuf_duplicate_state(struct intel_global_obj *obj)
3300 {
3301 struct intel_dbuf_state *dbuf_state;
3302
3303 dbuf_state = kmemdup(obj->state, sizeof(*dbuf_state), GFP_KERNEL);
3304 if (!dbuf_state)
3305 return NULL;
3306
3307 return &dbuf_state->base;
3308 }
3309
intel_dbuf_destroy_state(struct intel_global_obj * obj,struct intel_global_state * state)3310 static void intel_dbuf_destroy_state(struct intel_global_obj *obj,
3311 struct intel_global_state *state)
3312 {
3313 kfree(state);
3314 }
3315
3316 static const struct intel_global_state_funcs intel_dbuf_funcs = {
3317 .atomic_duplicate_state = intel_dbuf_duplicate_state,
3318 .atomic_destroy_state = intel_dbuf_destroy_state,
3319 };
3320
3321 struct intel_dbuf_state *
intel_atomic_get_dbuf_state(struct intel_atomic_state * state)3322 intel_atomic_get_dbuf_state(struct intel_atomic_state *state)
3323 {
3324 struct drm_i915_private *i915 = to_i915(state->base.dev);
3325 struct intel_global_state *dbuf_state;
3326
3327 dbuf_state = intel_atomic_get_global_obj_state(state, &i915->display.dbuf.obj);
3328 if (IS_ERR(dbuf_state))
3329 return ERR_CAST(dbuf_state);
3330
3331 return to_intel_dbuf_state(dbuf_state);
3332 }
3333
intel_dbuf_init(struct drm_i915_private * i915)3334 int intel_dbuf_init(struct drm_i915_private *i915)
3335 {
3336 struct intel_dbuf_state *dbuf_state;
3337
3338 dbuf_state = kzalloc(sizeof(*dbuf_state), GFP_KERNEL);
3339 if (!dbuf_state)
3340 return -ENOMEM;
3341
3342 intel_atomic_global_obj_init(i915, &i915->display.dbuf.obj,
3343 &dbuf_state->base, &intel_dbuf_funcs);
3344
3345 return 0;
3346 }
3347
3348 /*
3349 * Configure MBUS_CTL and all DBUF_CTL_S of each slice to join_mbus state before
3350 * update the request state of all DBUS slices.
3351 */
update_mbus_pre_enable(struct intel_atomic_state * state)3352 static void update_mbus_pre_enable(struct intel_atomic_state *state)
3353 {
3354 struct drm_i915_private *i915 = to_i915(state->base.dev);
3355 u32 mbus_ctl, dbuf_min_tracker_val;
3356 enum dbuf_slice slice;
3357 const struct intel_dbuf_state *dbuf_state =
3358 intel_atomic_get_new_dbuf_state(state);
3359
3360 if (!HAS_MBUS_JOINING(i915))
3361 return;
3362
3363 /*
3364 * TODO: Implement vblank synchronized MBUS joining changes.
3365 * Must be properly coordinated with dbuf reprogramming.
3366 */
3367 if (dbuf_state->joined_mbus) {
3368 mbus_ctl = MBUS_HASHING_MODE_1x4 | MBUS_JOIN |
3369 MBUS_JOIN_PIPE_SELECT_NONE;
3370 dbuf_min_tracker_val = DBUF_MIN_TRACKER_STATE_SERVICE(3);
3371 } else {
3372 mbus_ctl = MBUS_HASHING_MODE_2x2 |
3373 MBUS_JOIN_PIPE_SELECT_NONE;
3374 dbuf_min_tracker_val = DBUF_MIN_TRACKER_STATE_SERVICE(1);
3375 }
3376
3377 intel_de_rmw(i915, MBUS_CTL,
3378 MBUS_HASHING_MODE_MASK | MBUS_JOIN |
3379 MBUS_JOIN_PIPE_SELECT_MASK, mbus_ctl);
3380
3381 for_each_dbuf_slice(i915, slice)
3382 intel_de_rmw(i915, DBUF_CTL_S(slice),
3383 DBUF_MIN_TRACKER_STATE_SERVICE_MASK,
3384 dbuf_min_tracker_val);
3385 }
3386
intel_dbuf_pre_plane_update(struct intel_atomic_state * state)3387 void intel_dbuf_pre_plane_update(struct intel_atomic_state *state)
3388 {
3389 struct drm_i915_private *i915 = to_i915(state->base.dev);
3390 const struct intel_dbuf_state *new_dbuf_state =
3391 intel_atomic_get_new_dbuf_state(state);
3392 const struct intel_dbuf_state *old_dbuf_state =
3393 intel_atomic_get_old_dbuf_state(state);
3394
3395 if (!new_dbuf_state ||
3396 (new_dbuf_state->enabled_slices == old_dbuf_state->enabled_slices &&
3397 new_dbuf_state->joined_mbus == old_dbuf_state->joined_mbus))
3398 return;
3399
3400 WARN_ON(!new_dbuf_state->base.changed);
3401
3402 update_mbus_pre_enable(state);
3403 gen9_dbuf_slices_update(i915,
3404 old_dbuf_state->enabled_slices |
3405 new_dbuf_state->enabled_slices);
3406 }
3407
intel_dbuf_post_plane_update(struct intel_atomic_state * state)3408 void intel_dbuf_post_plane_update(struct intel_atomic_state *state)
3409 {
3410 struct drm_i915_private *i915 = to_i915(state->base.dev);
3411 const struct intel_dbuf_state *new_dbuf_state =
3412 intel_atomic_get_new_dbuf_state(state);
3413 const struct intel_dbuf_state *old_dbuf_state =
3414 intel_atomic_get_old_dbuf_state(state);
3415
3416 if (!new_dbuf_state ||
3417 (new_dbuf_state->enabled_slices == old_dbuf_state->enabled_slices &&
3418 new_dbuf_state->joined_mbus == old_dbuf_state->joined_mbus))
3419 return;
3420
3421 WARN_ON(!new_dbuf_state->base.changed);
3422
3423 gen9_dbuf_slices_update(i915,
3424 new_dbuf_state->enabled_slices);
3425 }
3426
xelpdp_is_only_pipe_per_dbuf_bank(enum pipe pipe,u8 active_pipes)3427 static bool xelpdp_is_only_pipe_per_dbuf_bank(enum pipe pipe, u8 active_pipes)
3428 {
3429 switch (pipe) {
3430 case PIPE_A:
3431 return !(active_pipes & BIT(PIPE_D));
3432 case PIPE_D:
3433 return !(active_pipes & BIT(PIPE_A));
3434 case PIPE_B:
3435 return !(active_pipes & BIT(PIPE_C));
3436 case PIPE_C:
3437 return !(active_pipes & BIT(PIPE_B));
3438 default: /* to suppress compiler warning */
3439 MISSING_CASE(pipe);
3440 break;
3441 }
3442
3443 return false;
3444 }
3445
intel_mbus_dbox_update(struct intel_atomic_state * state)3446 void intel_mbus_dbox_update(struct intel_atomic_state *state)
3447 {
3448 struct drm_i915_private *i915 = to_i915(state->base.dev);
3449 const struct intel_dbuf_state *new_dbuf_state, *old_dbuf_state;
3450 const struct intel_crtc_state *new_crtc_state;
3451 const struct intel_crtc *crtc;
3452 u32 val = 0;
3453 int i;
3454
3455 if (DISPLAY_VER(i915) < 11)
3456 return;
3457
3458 new_dbuf_state = intel_atomic_get_new_dbuf_state(state);
3459 old_dbuf_state = intel_atomic_get_old_dbuf_state(state);
3460 if (!new_dbuf_state ||
3461 (new_dbuf_state->joined_mbus == old_dbuf_state->joined_mbus &&
3462 new_dbuf_state->active_pipes == old_dbuf_state->active_pipes))
3463 return;
3464
3465 if (DISPLAY_VER(i915) >= 14)
3466 val |= MBUS_DBOX_I_CREDIT(2);
3467
3468 if (DISPLAY_VER(i915) >= 12) {
3469 val |= MBUS_DBOX_B2B_TRANSACTIONS_MAX(16);
3470 val |= MBUS_DBOX_B2B_TRANSACTIONS_DELAY(1);
3471 val |= MBUS_DBOX_REGULATE_B2B_TRANSACTIONS_EN;
3472 }
3473
3474 if (DISPLAY_VER(i915) >= 14)
3475 val |= new_dbuf_state->joined_mbus ? MBUS_DBOX_A_CREDIT(12) :
3476 MBUS_DBOX_A_CREDIT(8);
3477 else if (IS_ALDERLAKE_P(i915))
3478 /* Wa_22010947358:adl-p */
3479 val |= new_dbuf_state->joined_mbus ? MBUS_DBOX_A_CREDIT(6) :
3480 MBUS_DBOX_A_CREDIT(4);
3481 else
3482 val |= MBUS_DBOX_A_CREDIT(2);
3483
3484 if (DISPLAY_VER(i915) >= 14) {
3485 val |= MBUS_DBOX_B_CREDIT(0xA);
3486 } else if (IS_ALDERLAKE_P(i915)) {
3487 val |= MBUS_DBOX_BW_CREDIT(2);
3488 val |= MBUS_DBOX_B_CREDIT(8);
3489 } else if (DISPLAY_VER(i915) >= 12) {
3490 val |= MBUS_DBOX_BW_CREDIT(2);
3491 val |= MBUS_DBOX_B_CREDIT(12);
3492 } else {
3493 val |= MBUS_DBOX_BW_CREDIT(1);
3494 val |= MBUS_DBOX_B_CREDIT(8);
3495 }
3496
3497 for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
3498 u32 pipe_val = val;
3499
3500 if (!new_crtc_state->hw.active)
3501 continue;
3502
3503 if (DISPLAY_VER(i915) >= 14) {
3504 if (xelpdp_is_only_pipe_per_dbuf_bank(crtc->pipe,
3505 new_dbuf_state->active_pipes))
3506 pipe_val |= MBUS_DBOX_BW_8CREDITS_MTL;
3507 else
3508 pipe_val |= MBUS_DBOX_BW_4CREDITS_MTL;
3509 }
3510
3511 intel_de_write(i915, PIPE_MBUS_DBOX_CTL(crtc->pipe), pipe_val);
3512 }
3513 }
3514
skl_watermark_ipc_status_show(struct seq_file * m,void * data)3515 static int skl_watermark_ipc_status_show(struct seq_file *m, void *data)
3516 {
3517 struct drm_i915_private *i915 = m->private;
3518
3519 seq_printf(m, "Isochronous Priority Control: %s\n",
3520 str_yes_no(skl_watermark_ipc_enabled(i915)));
3521 return 0;
3522 }
3523
skl_watermark_ipc_status_open(struct inode * inode,struct file * file)3524 static int skl_watermark_ipc_status_open(struct inode *inode, struct file *file)
3525 {
3526 struct drm_i915_private *i915 = inode->i_private;
3527
3528 return single_open(file, skl_watermark_ipc_status_show, i915);
3529 }
3530
skl_watermark_ipc_status_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)3531 static ssize_t skl_watermark_ipc_status_write(struct file *file,
3532 const char __user *ubuf,
3533 size_t len, loff_t *offp)
3534 {
3535 struct seq_file *m = file->private_data;
3536 struct drm_i915_private *i915 = m->private;
3537 intel_wakeref_t wakeref;
3538 bool enable;
3539 int ret;
3540
3541 ret = kstrtobool_from_user(ubuf, len, &enable);
3542 if (ret < 0)
3543 return ret;
3544
3545 with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
3546 if (!skl_watermark_ipc_enabled(i915) && enable)
3547 drm_info(&i915->drm,
3548 "Enabling IPC: WM will be proper only after next commit\n");
3549 i915->display.wm.ipc_enabled = enable;
3550 skl_watermark_ipc_update(i915);
3551 }
3552
3553 return len;
3554 }
3555
3556 static const struct file_operations skl_watermark_ipc_status_fops = {
3557 .owner = THIS_MODULE,
3558 .open = skl_watermark_ipc_status_open,
3559 .read = seq_read,
3560 .llseek = seq_lseek,
3561 .release = single_release,
3562 .write = skl_watermark_ipc_status_write
3563 };
3564
skl_watermark_ipc_debugfs_register(struct drm_i915_private * i915)3565 void skl_watermark_ipc_debugfs_register(struct drm_i915_private *i915)
3566 {
3567 struct drm_minor *minor = i915->drm.primary;
3568
3569 if (!HAS_IPC(i915))
3570 return;
3571
3572 debugfs_create_file("i915_ipc_status", 0644, minor->debugfs_root, i915,
3573 &skl_watermark_ipc_status_fops);
3574 }
3575