xref: /openbmc/linux/drivers/gpu/drm/i915/display/intel_display_device.c (revision 901bdf5ea1a836400ee69aa32b04e9c209271ec7)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2023 Intel Corporation
4  */
5 
6 #include <drm/i915_pciids.h>
7 #include <drm/drm_color_mgmt.h>
8 #include <linux/pci.h>
9 
10 #include "i915_drv.h"
11 #include "i915_reg.h"
12 #include "intel_display_device.h"
13 #include "intel_display_power.h"
14 #include "intel_display_reg_defs.h"
15 #include "intel_fbc.h"
16 
17 __diag_push();
18 __diag_ignore_all("-Woverride-init", "Allow overriding inherited members");
19 
20 static const struct intel_display_device_info no_display = {};
21 
22 #define PIPE_A_OFFSET		0x70000
23 #define PIPE_B_OFFSET		0x71000
24 #define PIPE_C_OFFSET		0x72000
25 #define PIPE_D_OFFSET		0x73000
26 #define CHV_PIPE_C_OFFSET	0x74000
27 /*
28  * There's actually no pipe EDP. Some pipe registers have
29  * simply shifted from the pipe to the transcoder, while
30  * keeping their original offset. Thus we need PIPE_EDP_OFFSET
31  * to access such registers in transcoder EDP.
32  */
33 #define PIPE_EDP_OFFSET	0x7f000
34 
35 /* ICL DSI 0 and 1 */
36 #define PIPE_DSI0_OFFSET	0x7b000
37 #define PIPE_DSI1_OFFSET	0x7b800
38 
39 #define TRANSCODER_A_OFFSET 0x60000
40 #define TRANSCODER_B_OFFSET 0x61000
41 #define TRANSCODER_C_OFFSET 0x62000
42 #define CHV_TRANSCODER_C_OFFSET 0x63000
43 #define TRANSCODER_D_OFFSET 0x63000
44 #define TRANSCODER_EDP_OFFSET 0x6f000
45 #define TRANSCODER_DSI0_OFFSET	0x6b000
46 #define TRANSCODER_DSI1_OFFSET	0x6b800
47 
48 #define CURSOR_A_OFFSET 0x70080
49 #define CURSOR_B_OFFSET 0x700c0
50 #define CHV_CURSOR_C_OFFSET 0x700e0
51 #define IVB_CURSOR_B_OFFSET 0x71080
52 #define IVB_CURSOR_C_OFFSET 0x72080
53 #define TGL_CURSOR_D_OFFSET 0x73080
54 
55 #define I845_PIPE_OFFSETS \
56 	.pipe_offsets = { \
57 		[TRANSCODER_A] = PIPE_A_OFFSET,	\
58 	}, \
59 	.trans_offsets = { \
60 		[TRANSCODER_A] = TRANSCODER_A_OFFSET, \
61 	}
62 
63 #define I9XX_PIPE_OFFSETS \
64 	.pipe_offsets = { \
65 		[TRANSCODER_A] = PIPE_A_OFFSET,	\
66 		[TRANSCODER_B] = PIPE_B_OFFSET, \
67 	}, \
68 	.trans_offsets = { \
69 		[TRANSCODER_A] = TRANSCODER_A_OFFSET, \
70 		[TRANSCODER_B] = TRANSCODER_B_OFFSET, \
71 	}
72 
73 #define IVB_PIPE_OFFSETS \
74 	.pipe_offsets = { \
75 		[TRANSCODER_A] = PIPE_A_OFFSET,	\
76 		[TRANSCODER_B] = PIPE_B_OFFSET, \
77 		[TRANSCODER_C] = PIPE_C_OFFSET, \
78 	}, \
79 	.trans_offsets = { \
80 		[TRANSCODER_A] = TRANSCODER_A_OFFSET, \
81 		[TRANSCODER_B] = TRANSCODER_B_OFFSET, \
82 		[TRANSCODER_C] = TRANSCODER_C_OFFSET, \
83 	}
84 
85 #define HSW_PIPE_OFFSETS \
86 	.pipe_offsets = { \
87 		[TRANSCODER_A] = PIPE_A_OFFSET,	\
88 		[TRANSCODER_B] = PIPE_B_OFFSET, \
89 		[TRANSCODER_C] = PIPE_C_OFFSET, \
90 		[TRANSCODER_EDP] = PIPE_EDP_OFFSET, \
91 	}, \
92 	.trans_offsets = { \
93 		[TRANSCODER_A] = TRANSCODER_A_OFFSET, \
94 		[TRANSCODER_B] = TRANSCODER_B_OFFSET, \
95 		[TRANSCODER_C] = TRANSCODER_C_OFFSET, \
96 		[TRANSCODER_EDP] = TRANSCODER_EDP_OFFSET, \
97 	}
98 
99 #define CHV_PIPE_OFFSETS \
100 	.pipe_offsets = { \
101 		[TRANSCODER_A] = PIPE_A_OFFSET, \
102 		[TRANSCODER_B] = PIPE_B_OFFSET, \
103 		[TRANSCODER_C] = CHV_PIPE_C_OFFSET, \
104 	}, \
105 	.trans_offsets = { \
106 		[TRANSCODER_A] = TRANSCODER_A_OFFSET, \
107 		[TRANSCODER_B] = TRANSCODER_B_OFFSET, \
108 		[TRANSCODER_C] = CHV_TRANSCODER_C_OFFSET, \
109 	}
110 
111 #define I845_CURSOR_OFFSETS \
112 	.cursor_offsets = { \
113 		[PIPE_A] = CURSOR_A_OFFSET, \
114 	}
115 
116 #define I9XX_CURSOR_OFFSETS \
117 	.cursor_offsets = { \
118 		[PIPE_A] = CURSOR_A_OFFSET, \
119 		[PIPE_B] = CURSOR_B_OFFSET, \
120 	}
121 
122 #define CHV_CURSOR_OFFSETS \
123 	.cursor_offsets = { \
124 		[PIPE_A] = CURSOR_A_OFFSET, \
125 		[PIPE_B] = CURSOR_B_OFFSET, \
126 		[PIPE_C] = CHV_CURSOR_C_OFFSET, \
127 	}
128 
129 #define IVB_CURSOR_OFFSETS \
130 	.cursor_offsets = { \
131 		[PIPE_A] = CURSOR_A_OFFSET, \
132 		[PIPE_B] = IVB_CURSOR_B_OFFSET, \
133 		[PIPE_C] = IVB_CURSOR_C_OFFSET, \
134 	}
135 
136 #define TGL_CURSOR_OFFSETS \
137 	.cursor_offsets = { \
138 		[PIPE_A] = CURSOR_A_OFFSET, \
139 		[PIPE_B] = IVB_CURSOR_B_OFFSET, \
140 		[PIPE_C] = IVB_CURSOR_C_OFFSET, \
141 		[PIPE_D] = TGL_CURSOR_D_OFFSET, \
142 	}
143 
144 #define I845_COLORS \
145 	.color = { .gamma_lut_size = 256 }
146 #define I9XX_COLORS \
147 	.color = { .gamma_lut_size = 129, \
148 		   .gamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \
149 	}
150 #define ILK_COLORS \
151 	.color = { .gamma_lut_size = 1024 }
152 #define IVB_COLORS \
153 	.color = { .degamma_lut_size = 1024, .gamma_lut_size = 1024 }
154 #define CHV_COLORS \
155 	.color = { \
156 		.degamma_lut_size = 65, .gamma_lut_size = 257, \
157 		.degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \
158 		.gamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \
159 	}
160 #define GLK_COLORS \
161 	.color = { \
162 		.degamma_lut_size = 33, .gamma_lut_size = 1024, \
163 		.degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING | \
164 				     DRM_COLOR_LUT_EQUAL_CHANNELS, \
165 	}
166 #define ICL_COLORS \
167 	.color = { \
168 		.degamma_lut_size = 33, .gamma_lut_size = 262145, \
169 		.degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING | \
170 				     DRM_COLOR_LUT_EQUAL_CHANNELS, \
171 		.gamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \
172 	}
173 
174 #define I830_DISPLAY \
175 	.has_overlay = 1, \
176 	.cursor_needs_physical = 1, \
177 	.overlay_needs_physical = 1, \
178 	.has_gmch = 1, \
179 	I9XX_PIPE_OFFSETS, \
180 	I9XX_CURSOR_OFFSETS, \
181 	I9XX_COLORS, \
182 	\
183 	.__runtime_defaults.ip.ver = 2, \
184 	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
185 	.__runtime_defaults.cpu_transcoder_mask = \
186 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B)
187 
188 static const struct intel_display_device_info i830_display = {
189 	I830_DISPLAY,
190 };
191 
192 #define I845_DISPLAY \
193 	.has_overlay = 1, \
194 	.overlay_needs_physical = 1, \
195 	.has_gmch = 1, \
196 	I845_PIPE_OFFSETS, \
197 	I845_CURSOR_OFFSETS, \
198 	I845_COLORS, \
199 	\
200 	.__runtime_defaults.ip.ver = 2, \
201 	.__runtime_defaults.pipe_mask = BIT(PIPE_A), \
202 	.__runtime_defaults.cpu_transcoder_mask = BIT(TRANSCODER_A)
203 
204 static const struct intel_display_device_info i845_display = {
205 	I845_DISPLAY,
206 };
207 
208 static const struct intel_display_device_info i85x_display = {
209 	I830_DISPLAY,
210 
211 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
212 };
213 
214 static const struct intel_display_device_info i865g_display = {
215 	I845_DISPLAY,
216 
217 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
218 };
219 
220 #define GEN3_DISPLAY \
221 	.has_gmch = 1, \
222 	.has_overlay = 1, \
223 	I9XX_PIPE_OFFSETS, \
224 	I9XX_CURSOR_OFFSETS, \
225 	I9XX_COLORS, \
226 	\
227 	.__runtime_defaults.ip.ver = 3, \
228 	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
229 	.__runtime_defaults.cpu_transcoder_mask = \
230 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B)
231 
232 static const struct intel_display_device_info i915g_display = {
233 	GEN3_DISPLAY,
234 	.cursor_needs_physical = 1,
235 	.overlay_needs_physical = 1,
236 };
237 
238 static const struct intel_display_device_info i915gm_display = {
239 	GEN3_DISPLAY,
240 	.cursor_needs_physical = 1,
241 	.overlay_needs_physical = 1,
242 	.supports_tv = 1,
243 
244 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
245 };
246 
247 static const struct intel_display_device_info i945g_display = {
248 	GEN3_DISPLAY,
249 	.has_hotplug = 1,
250 	.cursor_needs_physical = 1,
251 	.overlay_needs_physical = 1,
252 };
253 
254 static const struct intel_display_device_info i945gm_display = {
255 	GEN3_DISPLAY,
256 	.has_hotplug = 1,
257 	.cursor_needs_physical = 1,
258 	.overlay_needs_physical = 1,
259 	.supports_tv = 1,
260 
261 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
262 };
263 
264 static const struct intel_display_device_info g33_display = {
265 	GEN3_DISPLAY,
266 	.has_hotplug = 1,
267 };
268 
269 #define GEN4_DISPLAY \
270 	.has_hotplug = 1, \
271 	.has_gmch = 1, \
272 	I9XX_PIPE_OFFSETS, \
273 	I9XX_CURSOR_OFFSETS, \
274 	I9XX_COLORS, \
275 	\
276 	.__runtime_defaults.ip.ver = 4, \
277 	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
278 	.__runtime_defaults.cpu_transcoder_mask = \
279 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B)
280 
281 static const struct intel_display_device_info i965g_display = {
282 	GEN4_DISPLAY,
283 	.has_overlay = 1,
284 };
285 
286 static const struct intel_display_device_info i965gm_display = {
287 	GEN4_DISPLAY,
288 	.has_overlay = 1,
289 	.supports_tv = 1,
290 
291 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
292 };
293 
294 static const struct intel_display_device_info g45_display = {
295 	GEN4_DISPLAY,
296 };
297 
298 static const struct intel_display_device_info gm45_display = {
299 	GEN4_DISPLAY,
300 	.supports_tv = 1,
301 
302 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
303 };
304 
305 #define ILK_DISPLAY \
306 	.has_hotplug = 1, \
307 	I9XX_PIPE_OFFSETS, \
308 	I9XX_CURSOR_OFFSETS, \
309 	ILK_COLORS, \
310 	\
311 	.__runtime_defaults.ip.ver = 5, \
312 	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
313 	.__runtime_defaults.cpu_transcoder_mask = \
314 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B)
315 
316 static const struct intel_display_device_info ilk_d_display = {
317 	ILK_DISPLAY,
318 };
319 
320 static const struct intel_display_device_info ilk_m_display = {
321 	ILK_DISPLAY,
322 
323 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
324 };
325 
326 static const struct intel_display_device_info snb_display = {
327 	.has_hotplug = 1,
328 	I9XX_PIPE_OFFSETS,
329 	I9XX_CURSOR_OFFSETS,
330 	ILK_COLORS,
331 
332 	.__runtime_defaults.ip.ver = 6,
333 	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
334 	.__runtime_defaults.cpu_transcoder_mask =
335 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
336 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
337 };
338 
339 static const struct intel_display_device_info ivb_display = {
340 	.has_hotplug = 1,
341 	IVB_PIPE_OFFSETS,
342 	IVB_CURSOR_OFFSETS,
343 	IVB_COLORS,
344 
345 	.__runtime_defaults.ip.ver = 7,
346 	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
347 	.__runtime_defaults.cpu_transcoder_mask =
348 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
349 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
350 };
351 
352 static const struct intel_display_device_info vlv_display = {
353 	.has_gmch = 1,
354 	.has_hotplug = 1,
355 	.mmio_offset = VLV_DISPLAY_BASE,
356 	I9XX_PIPE_OFFSETS,
357 	I9XX_CURSOR_OFFSETS,
358 	I9XX_COLORS,
359 
360 	.__runtime_defaults.ip.ver = 7,
361 	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
362 	.__runtime_defaults.cpu_transcoder_mask =
363 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
364 };
365 
366 static const struct intel_display_device_info hsw_display = {
367 	.has_ddi = 1,
368 	.has_dp_mst = 1,
369 	.has_fpga_dbg = 1,
370 	.has_hotplug = 1,
371 	HSW_PIPE_OFFSETS,
372 	IVB_CURSOR_OFFSETS,
373 	IVB_COLORS,
374 
375 	.__runtime_defaults.ip.ver = 7,
376 	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
377 	.__runtime_defaults.cpu_transcoder_mask =
378 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
379 		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
380 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
381 };
382 
383 static const struct intel_display_device_info bdw_display = {
384 	.has_ddi = 1,
385 	.has_dp_mst = 1,
386 	.has_fpga_dbg = 1,
387 	.has_hotplug = 1,
388 	HSW_PIPE_OFFSETS,
389 	IVB_CURSOR_OFFSETS,
390 	IVB_COLORS,
391 
392 	.__runtime_defaults.ip.ver = 8,
393 	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
394 	.__runtime_defaults.cpu_transcoder_mask =
395 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
396 		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
397 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
398 };
399 
400 static const struct intel_display_device_info chv_display = {
401 	.has_hotplug = 1,
402 	.has_gmch = 1,
403 	.mmio_offset = VLV_DISPLAY_BASE,
404 	CHV_PIPE_OFFSETS,
405 	CHV_CURSOR_OFFSETS,
406 	CHV_COLORS,
407 
408 	.__runtime_defaults.ip.ver = 8,
409 	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
410 	.__runtime_defaults.cpu_transcoder_mask =
411 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
412 };
413 
414 static const struct intel_display_device_info skl_display = {
415 	.dbuf.size = 896 - 4, /* 4 blocks for bypass path allocation */
416 	.dbuf.slice_mask = BIT(DBUF_S1),
417 	.has_ddi = 1,
418 	.has_dp_mst = 1,
419 	.has_fpga_dbg = 1,
420 	.has_hotplug = 1,
421 	.has_ipc = 1,
422 	.has_psr = 1,
423 	.has_psr_hw_tracking = 1,
424 	HSW_PIPE_OFFSETS,
425 	IVB_CURSOR_OFFSETS,
426 	IVB_COLORS,
427 
428 	.__runtime_defaults.ip.ver = 9,
429 	.__runtime_defaults.has_dmc = 1,
430 	.__runtime_defaults.has_hdcp = 1,
431 	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
432 	.__runtime_defaults.cpu_transcoder_mask =
433 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
434 		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
435 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
436 };
437 
438 #define GEN9_LP_DISPLAY \
439 	.dbuf.slice_mask = BIT(DBUF_S1), \
440 	.has_dp_mst = 1, \
441 	.has_ddi = 1, \
442 	.has_fpga_dbg = 1, \
443 	.has_hotplug = 1, \
444 	.has_ipc = 1, \
445 	.has_psr = 1, \
446 	.has_psr_hw_tracking = 1, \
447 	HSW_PIPE_OFFSETS, \
448 	IVB_CURSOR_OFFSETS, \
449 	IVB_COLORS, \
450 	\
451 	.__runtime_defaults.has_dmc = 1, \
452 	.__runtime_defaults.has_hdcp = 1, \
453 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A), \
454 	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \
455 	.__runtime_defaults.cpu_transcoder_mask = \
456 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
457 		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) | \
458 		BIT(TRANSCODER_DSI_A) | BIT(TRANSCODER_DSI_C)
459 
460 static const struct intel_display_device_info bxt_display = {
461 	GEN9_LP_DISPLAY,
462 	.dbuf.size = 512 - 4, /* 4 blocks for bypass path allocation */
463 
464 	.__runtime_defaults.ip.ver = 9,
465 };
466 
467 static const struct intel_display_device_info glk_display = {
468 	GEN9_LP_DISPLAY,
469 	.dbuf.size = 1024 - 4, /* 4 blocks for bypass path allocation */
470 	GLK_COLORS,
471 
472 	.__runtime_defaults.ip.ver = 10,
473 };
474 
475 static const struct intel_display_device_info gen11_display = {
476 	.abox_mask = BIT(0),
477 	.dbuf.size = 2048,
478 	.dbuf.slice_mask = BIT(DBUF_S1) | BIT(DBUF_S2),
479 	.has_ddi = 1,
480 	.has_dp_mst = 1,
481 	.has_fpga_dbg = 1,
482 	.has_hotplug = 1,
483 	.has_ipc = 1,
484 	.has_psr = 1,
485 	.has_psr_hw_tracking = 1,
486 	.pipe_offsets = {
487 		[TRANSCODER_A] = PIPE_A_OFFSET,
488 		[TRANSCODER_B] = PIPE_B_OFFSET,
489 		[TRANSCODER_C] = PIPE_C_OFFSET,
490 		[TRANSCODER_EDP] = PIPE_EDP_OFFSET,
491 		[TRANSCODER_DSI_0] = PIPE_DSI0_OFFSET,
492 		[TRANSCODER_DSI_1] = PIPE_DSI1_OFFSET,
493 	},
494 	.trans_offsets = {
495 		[TRANSCODER_A] = TRANSCODER_A_OFFSET,
496 		[TRANSCODER_B] = TRANSCODER_B_OFFSET,
497 		[TRANSCODER_C] = TRANSCODER_C_OFFSET,
498 		[TRANSCODER_EDP] = TRANSCODER_EDP_OFFSET,
499 		[TRANSCODER_DSI_0] = TRANSCODER_DSI0_OFFSET,
500 		[TRANSCODER_DSI_1] = TRANSCODER_DSI1_OFFSET,
501 	},
502 	IVB_CURSOR_OFFSETS,
503 	ICL_COLORS,
504 
505 	.__runtime_defaults.ip.ver = 11,
506 	.__runtime_defaults.has_dmc = 1,
507 	.__runtime_defaults.has_dsc = 1,
508 	.__runtime_defaults.has_hdcp = 1,
509 	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
510 	.__runtime_defaults.cpu_transcoder_mask =
511 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
512 		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) |
513 		BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1),
514 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
515 };
516 
517 #define XE_D_DISPLAY \
518 	.abox_mask = GENMASK(2, 1), \
519 	.dbuf.size = 2048, \
520 	.dbuf.slice_mask = BIT(DBUF_S1) | BIT(DBUF_S2), \
521 	.has_ddi = 1, \
522 	.has_dp_mst = 1, \
523 	.has_dsb = 1, \
524 	.has_fpga_dbg = 1, \
525 	.has_hotplug = 1, \
526 	.has_ipc = 1, \
527 	.has_psr = 1, \
528 	.has_psr_hw_tracking = 1, \
529 	.pipe_offsets = { \
530 		[TRANSCODER_A] = PIPE_A_OFFSET, \
531 		[TRANSCODER_B] = PIPE_B_OFFSET, \
532 		[TRANSCODER_C] = PIPE_C_OFFSET, \
533 		[TRANSCODER_D] = PIPE_D_OFFSET, \
534 		[TRANSCODER_DSI_0] = PIPE_DSI0_OFFSET, \
535 		[TRANSCODER_DSI_1] = PIPE_DSI1_OFFSET, \
536 	}, \
537 	.trans_offsets = { \
538 		[TRANSCODER_A] = TRANSCODER_A_OFFSET, \
539 		[TRANSCODER_B] = TRANSCODER_B_OFFSET, \
540 		[TRANSCODER_C] = TRANSCODER_C_OFFSET, \
541 		[TRANSCODER_D] = TRANSCODER_D_OFFSET, \
542 		[TRANSCODER_DSI_0] = TRANSCODER_DSI0_OFFSET, \
543 		[TRANSCODER_DSI_1] = TRANSCODER_DSI1_OFFSET, \
544 	}, \
545 	TGL_CURSOR_OFFSETS, \
546 	ICL_COLORS, \
547 	\
548 	.__runtime_defaults.ip.ver = 12, \
549 	.__runtime_defaults.has_dmc = 1, \
550 	.__runtime_defaults.has_dsc = 1, \
551 	.__runtime_defaults.has_hdcp = 1, \
552 	.__runtime_defaults.pipe_mask = \
553 		BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), \
554 	.__runtime_defaults.cpu_transcoder_mask = \
555 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
556 		BIT(TRANSCODER_C) | BIT(TRANSCODER_D) | \
557 		BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \
558 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A)
559 
560 static const struct intel_display_device_info tgl_display = {
561 	XE_D_DISPLAY,
562 };
563 
564 static const struct intel_display_device_info rkl_display = {
565 	XE_D_DISPLAY,
566 	.abox_mask = BIT(0),
567 	.has_hti = 1,
568 	.has_psr_hw_tracking = 0,
569 
570 	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
571 	.__runtime_defaults.cpu_transcoder_mask =
572 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
573 };
574 
575 static const struct intel_display_device_info adl_s_display = {
576 	XE_D_DISPLAY,
577 	.has_hti = 1,
578 	.has_psr_hw_tracking = 0,
579 };
580 
581 #define XE_LPD_FEATURES \
582 	.abox_mask = GENMASK(1, 0),						\
583 	.color = {								\
584 		.degamma_lut_size = 129, .gamma_lut_size = 1024,		\
585 		.degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING |		\
586 		DRM_COLOR_LUT_EQUAL_CHANNELS,					\
587 	},									\
588 	.dbuf.size = 4096,							\
589 	.dbuf.slice_mask = BIT(DBUF_S1) | BIT(DBUF_S2) | BIT(DBUF_S3) |		\
590 		BIT(DBUF_S4),							\
591 	.has_ddi = 1,								\
592 	.has_dp_mst = 1,							\
593 	.has_dsb = 1,								\
594 	.has_fpga_dbg = 1,							\
595 	.has_hotplug = 1,							\
596 	.has_ipc = 1,								\
597 	.has_psr = 1,								\
598 	.pipe_offsets = {							\
599 		[TRANSCODER_A] = PIPE_A_OFFSET,					\
600 		[TRANSCODER_B] = PIPE_B_OFFSET,					\
601 		[TRANSCODER_C] = PIPE_C_OFFSET,					\
602 		[TRANSCODER_D] = PIPE_D_OFFSET,					\
603 		[TRANSCODER_DSI_0] = PIPE_DSI0_OFFSET,				\
604 		[TRANSCODER_DSI_1] = PIPE_DSI1_OFFSET,				\
605 	},									\
606 	.trans_offsets = {							\
607 		[TRANSCODER_A] = TRANSCODER_A_OFFSET,				\
608 		[TRANSCODER_B] = TRANSCODER_B_OFFSET,				\
609 		[TRANSCODER_C] = TRANSCODER_C_OFFSET,				\
610 		[TRANSCODER_D] = TRANSCODER_D_OFFSET,				\
611 		[TRANSCODER_DSI_0] = TRANSCODER_DSI0_OFFSET,			\
612 		[TRANSCODER_DSI_1] = TRANSCODER_DSI1_OFFSET,			\
613 	},									\
614 	TGL_CURSOR_OFFSETS,							\
615 										\
616 	.__runtime_defaults.ip.ver = 13,					\
617 	.__runtime_defaults.has_dmc = 1,					\
618 	.__runtime_defaults.has_dsc = 1,					\
619 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),			\
620 	.__runtime_defaults.has_hdcp = 1,					\
621 	.__runtime_defaults.pipe_mask =						\
622 		BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D)
623 
624 static const struct intel_display_device_info xe_lpd_display = {
625 	XE_LPD_FEATURES,
626 	.has_cdclk_crawl = 1,
627 	.has_psr_hw_tracking = 0,
628 
629 	.__runtime_defaults.cpu_transcoder_mask =
630 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
631 		BIT(TRANSCODER_C) | BIT(TRANSCODER_D) |
632 		BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1),
633 };
634 
635 static const struct intel_display_device_info xe_hpd_display = {
636 	XE_LPD_FEATURES,
637 	.has_cdclk_squash = 1,
638 
639 	.__runtime_defaults.cpu_transcoder_mask =
640 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
641 		BIT(TRANSCODER_C) | BIT(TRANSCODER_D),
642 };
643 
644 static const struct intel_display_device_info xe_lpdp_display = {
645 	XE_LPD_FEATURES,
646 	.has_cdclk_crawl = 1,
647 	.has_cdclk_squash = 1,
648 
649 	.__runtime_defaults.ip.ver = 14,
650 	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A) | BIT(INTEL_FBC_B),
651 	.__runtime_defaults.cpu_transcoder_mask =
652 		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
653 		BIT(TRANSCODER_C) | BIT(TRANSCODER_D),
654 };
655 
656 __diag_pop();
657 
658 #undef INTEL_VGA_DEVICE
659 #undef INTEL_QUANTA_VGA_DEVICE
660 #define INTEL_VGA_DEVICE(id, info) { id, info }
661 #define INTEL_QUANTA_VGA_DEVICE(info) { 0x16a, info }
662 
663 static const struct {
664 	u32 devid;
665 	const struct intel_display_device_info *info;
666 } intel_display_ids[] = {
667 	INTEL_I830_IDS(&i830_display),
668 	INTEL_I845G_IDS(&i845_display),
669 	INTEL_I85X_IDS(&i85x_display),
670 	INTEL_I865G_IDS(&i865g_display),
671 	INTEL_I915G_IDS(&i915g_display),
672 	INTEL_I915GM_IDS(&i915gm_display),
673 	INTEL_I945G_IDS(&i945g_display),
674 	INTEL_I945GM_IDS(&i945gm_display),
675 	INTEL_I965G_IDS(&i965g_display),
676 	INTEL_G33_IDS(&g33_display),
677 	INTEL_I965GM_IDS(&i965gm_display),
678 	INTEL_GM45_IDS(&gm45_display),
679 	INTEL_G45_IDS(&g45_display),
680 	INTEL_PINEVIEW_G_IDS(&g33_display),
681 	INTEL_PINEVIEW_M_IDS(&g33_display),
682 	INTEL_IRONLAKE_D_IDS(&ilk_d_display),
683 	INTEL_IRONLAKE_M_IDS(&ilk_m_display),
684 	INTEL_SNB_D_IDS(&snb_display),
685 	INTEL_SNB_M_IDS(&snb_display),
686 	INTEL_IVB_Q_IDS(NULL),		/* must be first IVB in list */
687 	INTEL_IVB_M_IDS(&ivb_display),
688 	INTEL_IVB_D_IDS(&ivb_display),
689 	INTEL_HSW_IDS(&hsw_display),
690 	INTEL_VLV_IDS(&vlv_display),
691 	INTEL_BDW_IDS(&bdw_display),
692 	INTEL_CHV_IDS(&chv_display),
693 	INTEL_SKL_IDS(&skl_display),
694 	INTEL_BXT_IDS(&bxt_display),
695 	INTEL_GLK_IDS(&glk_display),
696 	INTEL_KBL_IDS(&skl_display),
697 	INTEL_CFL_IDS(&skl_display),
698 	INTEL_ICL_11_IDS(&gen11_display),
699 	INTEL_EHL_IDS(&gen11_display),
700 	INTEL_JSL_IDS(&gen11_display),
701 	INTEL_TGL_12_IDS(&tgl_display),
702 	INTEL_DG1_IDS(&tgl_display),
703 	INTEL_RKL_IDS(&rkl_display),
704 	INTEL_ADLS_IDS(&adl_s_display),
705 	INTEL_RPLS_IDS(&adl_s_display),
706 	INTEL_ADLP_IDS(&xe_lpd_display),
707 	INTEL_ADLN_IDS(&xe_lpd_display),
708 	INTEL_RPLP_IDS(&xe_lpd_display),
709 	INTEL_DG2_IDS(&xe_hpd_display),
710 
711 	/*
712 	 * Do not add any GMD_ID-based platforms to this list.  They will
713 	 * be probed automatically based on the IP version reported by
714 	 * the hardware.
715 	 */
716 };
717 
718 static const struct {
719 	u16 ver;
720 	u16 rel;
721 	const struct intel_display_device_info *display;
722 } gmdid_display_map[] = {
723 	{ 14,  0, &xe_lpdp_display },
724 };
725 
726 static const struct intel_display_device_info *
727 probe_gmdid_display(struct drm_i915_private *i915, u16 *ver, u16 *rel, u16 *step)
728 {
729 	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
730 	void __iomem *addr;
731 	u32 val;
732 	int i;
733 
734 	addr = pci_iomap_range(pdev, 0, i915_mmio_reg_offset(GMD_ID_DISPLAY), sizeof(u32));
735 	if (!addr) {
736 		drm_err(&i915->drm, "Cannot map MMIO BAR to read display GMD_ID\n");
737 		return &no_display;
738 	}
739 
740 	val = ioread32(addr);
741 	pci_iounmap(pdev, addr);
742 
743 	if (val == 0)
744 		/* Platform doesn't have display */
745 		return &no_display;
746 
747 	*ver = REG_FIELD_GET(GMD_ID_ARCH_MASK, val);
748 	*rel = REG_FIELD_GET(GMD_ID_RELEASE_MASK, val);
749 	*step = REG_FIELD_GET(GMD_ID_STEP, val);
750 
751 	for (i = 0; i < ARRAY_SIZE(gmdid_display_map); i++)
752 		if (*ver == gmdid_display_map[i].ver &&
753 		    *rel == gmdid_display_map[i].rel)
754 			return gmdid_display_map[i].display;
755 
756 	drm_err(&i915->drm, "Unrecognized display IP version %d.%02d; disabling display.\n",
757 		*ver, *rel);
758 	return &no_display;
759 }
760 
761 const struct intel_display_device_info *
762 intel_display_device_probe(struct drm_i915_private *i915, bool has_gmdid,
763 			   u16 *gmdid_ver, u16 *gmdid_rel, u16 *gmdid_step)
764 {
765 	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
766 	int i;
767 
768 	if (has_gmdid)
769 		return probe_gmdid_display(i915, gmdid_ver, gmdid_rel, gmdid_step);
770 
771 	for (i = 0; i < ARRAY_SIZE(intel_display_ids); i++) {
772 		if (intel_display_ids[i].devid == pdev->device)
773 			return intel_display_ids[i].info;
774 	}
775 
776 	drm_dbg(&i915->drm, "No display ID found for device ID %04x; disabling display.\n",
777 		pdev->device);
778 
779 	return &no_display;
780 }
781