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