1f005ef32Sjsg // SPDX-License-Identifier: MIT
2f005ef32Sjsg /*
3f005ef32Sjsg * Copyright © 2023 Intel Corporation
4f005ef32Sjsg */
5f005ef32Sjsg
6f005ef32Sjsg #include <drm/i915_pciids.h>
7f005ef32Sjsg #include <drm/drm_color_mgmt.h>
8f005ef32Sjsg #include <linux/pci.h>
9f005ef32Sjsg
10f005ef32Sjsg #include "i915_drv.h"
11f005ef32Sjsg #include "i915_reg.h"
12f005ef32Sjsg #include "intel_de.h"
13f005ef32Sjsg #include "intel_display.h"
14f005ef32Sjsg #include "intel_display_device.h"
15f005ef32Sjsg #include "intel_display_power.h"
16f005ef32Sjsg #include "intel_display_reg_defs.h"
17f005ef32Sjsg #include "intel_fbc.h"
18f005ef32Sjsg
19f005ef32Sjsg static const struct intel_display_device_info no_display = {};
20f005ef32Sjsg
21f005ef32Sjsg #define PIPE_A_OFFSET 0x70000
22f005ef32Sjsg #define PIPE_B_OFFSET 0x71000
23f005ef32Sjsg #define PIPE_C_OFFSET 0x72000
24f005ef32Sjsg #define PIPE_D_OFFSET 0x73000
25f005ef32Sjsg #define CHV_PIPE_C_OFFSET 0x74000
26f005ef32Sjsg /*
27f005ef32Sjsg * There's actually no pipe EDP. Some pipe registers have
28f005ef32Sjsg * simply shifted from the pipe to the transcoder, while
29f005ef32Sjsg * keeping their original offset. Thus we need PIPE_EDP_OFFSET
30f005ef32Sjsg * to access such registers in transcoder EDP.
31f005ef32Sjsg */
32f005ef32Sjsg #define PIPE_EDP_OFFSET 0x7f000
33f005ef32Sjsg
34f005ef32Sjsg /* ICL DSI 0 and 1 */
35f005ef32Sjsg #define PIPE_DSI0_OFFSET 0x7b000
36f005ef32Sjsg #define PIPE_DSI1_OFFSET 0x7b800
37f005ef32Sjsg
38f005ef32Sjsg #define TRANSCODER_A_OFFSET 0x60000
39f005ef32Sjsg #define TRANSCODER_B_OFFSET 0x61000
40f005ef32Sjsg #define TRANSCODER_C_OFFSET 0x62000
41f005ef32Sjsg #define CHV_TRANSCODER_C_OFFSET 0x63000
42f005ef32Sjsg #define TRANSCODER_D_OFFSET 0x63000
43f005ef32Sjsg #define TRANSCODER_EDP_OFFSET 0x6f000
44f005ef32Sjsg #define TRANSCODER_DSI0_OFFSET 0x6b000
45f005ef32Sjsg #define TRANSCODER_DSI1_OFFSET 0x6b800
46f005ef32Sjsg
47f005ef32Sjsg #define CURSOR_A_OFFSET 0x70080
48f005ef32Sjsg #define CURSOR_B_OFFSET 0x700c0
49f005ef32Sjsg #define CHV_CURSOR_C_OFFSET 0x700e0
50f005ef32Sjsg #define IVB_CURSOR_B_OFFSET 0x71080
51f005ef32Sjsg #define IVB_CURSOR_C_OFFSET 0x72080
52f005ef32Sjsg #define TGL_CURSOR_D_OFFSET 0x73080
53f005ef32Sjsg
54f005ef32Sjsg #define I845_PIPE_OFFSETS \
55f005ef32Sjsg .pipe_offsets = { \
56f005ef32Sjsg [TRANSCODER_A] = PIPE_A_OFFSET, \
57f005ef32Sjsg }, \
58f005ef32Sjsg .trans_offsets = { \
59f005ef32Sjsg [TRANSCODER_A] = TRANSCODER_A_OFFSET, \
60f005ef32Sjsg }
61f005ef32Sjsg
62f005ef32Sjsg #define I9XX_PIPE_OFFSETS \
63f005ef32Sjsg .pipe_offsets = { \
64f005ef32Sjsg [TRANSCODER_A] = PIPE_A_OFFSET, \
65f005ef32Sjsg [TRANSCODER_B] = PIPE_B_OFFSET, \
66f005ef32Sjsg }, \
67f005ef32Sjsg .trans_offsets = { \
68f005ef32Sjsg [TRANSCODER_A] = TRANSCODER_A_OFFSET, \
69f005ef32Sjsg [TRANSCODER_B] = TRANSCODER_B_OFFSET, \
70f005ef32Sjsg }
71f005ef32Sjsg
72f005ef32Sjsg #define IVB_PIPE_OFFSETS \
73f005ef32Sjsg .pipe_offsets = { \
74f005ef32Sjsg [TRANSCODER_A] = PIPE_A_OFFSET, \
75f005ef32Sjsg [TRANSCODER_B] = PIPE_B_OFFSET, \
76f005ef32Sjsg [TRANSCODER_C] = PIPE_C_OFFSET, \
77f005ef32Sjsg }, \
78f005ef32Sjsg .trans_offsets = { \
79f005ef32Sjsg [TRANSCODER_A] = TRANSCODER_A_OFFSET, \
80f005ef32Sjsg [TRANSCODER_B] = TRANSCODER_B_OFFSET, \
81f005ef32Sjsg [TRANSCODER_C] = TRANSCODER_C_OFFSET, \
82f005ef32Sjsg }
83f005ef32Sjsg
84f005ef32Sjsg #define HSW_PIPE_OFFSETS \
85f005ef32Sjsg .pipe_offsets = { \
86f005ef32Sjsg [TRANSCODER_A] = PIPE_A_OFFSET, \
87f005ef32Sjsg [TRANSCODER_B] = PIPE_B_OFFSET, \
88f005ef32Sjsg [TRANSCODER_C] = PIPE_C_OFFSET, \
89f005ef32Sjsg [TRANSCODER_EDP] = PIPE_EDP_OFFSET, \
90f005ef32Sjsg }, \
91f005ef32Sjsg .trans_offsets = { \
92f005ef32Sjsg [TRANSCODER_A] = TRANSCODER_A_OFFSET, \
93f005ef32Sjsg [TRANSCODER_B] = TRANSCODER_B_OFFSET, \
94f005ef32Sjsg [TRANSCODER_C] = TRANSCODER_C_OFFSET, \
95f005ef32Sjsg [TRANSCODER_EDP] = TRANSCODER_EDP_OFFSET, \
96f005ef32Sjsg }
97f005ef32Sjsg
98f005ef32Sjsg #define CHV_PIPE_OFFSETS \
99f005ef32Sjsg .pipe_offsets = { \
100f005ef32Sjsg [TRANSCODER_A] = PIPE_A_OFFSET, \
101f005ef32Sjsg [TRANSCODER_B] = PIPE_B_OFFSET, \
102f005ef32Sjsg [TRANSCODER_C] = CHV_PIPE_C_OFFSET, \
103f005ef32Sjsg }, \
104f005ef32Sjsg .trans_offsets = { \
105f005ef32Sjsg [TRANSCODER_A] = TRANSCODER_A_OFFSET, \
106f005ef32Sjsg [TRANSCODER_B] = TRANSCODER_B_OFFSET, \
107f005ef32Sjsg [TRANSCODER_C] = CHV_TRANSCODER_C_OFFSET, \
108f005ef32Sjsg }
109f005ef32Sjsg
110f005ef32Sjsg #define I845_CURSOR_OFFSETS \
111f005ef32Sjsg .cursor_offsets = { \
112f005ef32Sjsg [PIPE_A] = CURSOR_A_OFFSET, \
113f005ef32Sjsg }
114f005ef32Sjsg
115f005ef32Sjsg #define I9XX_CURSOR_OFFSETS \
116f005ef32Sjsg .cursor_offsets = { \
117f005ef32Sjsg [PIPE_A] = CURSOR_A_OFFSET, \
118f005ef32Sjsg [PIPE_B] = CURSOR_B_OFFSET, \
119f005ef32Sjsg }
120f005ef32Sjsg
121f005ef32Sjsg #define CHV_CURSOR_OFFSETS \
122f005ef32Sjsg .cursor_offsets = { \
123f005ef32Sjsg [PIPE_A] = CURSOR_A_OFFSET, \
124f005ef32Sjsg [PIPE_B] = CURSOR_B_OFFSET, \
125f005ef32Sjsg [PIPE_C] = CHV_CURSOR_C_OFFSET, \
126f005ef32Sjsg }
127f005ef32Sjsg
128f005ef32Sjsg #define IVB_CURSOR_OFFSETS \
129f005ef32Sjsg .cursor_offsets = { \
130f005ef32Sjsg [PIPE_A] = CURSOR_A_OFFSET, \
131f005ef32Sjsg [PIPE_B] = IVB_CURSOR_B_OFFSET, \
132f005ef32Sjsg [PIPE_C] = IVB_CURSOR_C_OFFSET, \
133f005ef32Sjsg }
134f005ef32Sjsg
135f005ef32Sjsg #define TGL_CURSOR_OFFSETS \
136f005ef32Sjsg .cursor_offsets = { \
137f005ef32Sjsg [PIPE_A] = CURSOR_A_OFFSET, \
138f005ef32Sjsg [PIPE_B] = IVB_CURSOR_B_OFFSET, \
139f005ef32Sjsg [PIPE_C] = IVB_CURSOR_C_OFFSET, \
140f005ef32Sjsg [PIPE_D] = TGL_CURSOR_D_OFFSET, \
141f005ef32Sjsg }
142f005ef32Sjsg
143f005ef32Sjsg #define I845_COLORS \
144f005ef32Sjsg .color = { .gamma_lut_size = 256 }
145f005ef32Sjsg #define I9XX_COLORS \
146f005ef32Sjsg .color = { .gamma_lut_size = 129, \
147f005ef32Sjsg .gamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \
148f005ef32Sjsg }
149f005ef32Sjsg #define ILK_COLORS \
150f005ef32Sjsg .color = { .gamma_lut_size = 1024 }
151f005ef32Sjsg #define IVB_COLORS \
152f005ef32Sjsg .color = { .degamma_lut_size = 1024, .gamma_lut_size = 1024 }
153f005ef32Sjsg #define CHV_COLORS \
154f005ef32Sjsg .color = { \
155f005ef32Sjsg .degamma_lut_size = 65, .gamma_lut_size = 257, \
156f005ef32Sjsg .degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \
157f005ef32Sjsg .gamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \
158f005ef32Sjsg }
159f005ef32Sjsg #define GLK_COLORS \
160f005ef32Sjsg .color = { \
161f005ef32Sjsg .degamma_lut_size = 33, .gamma_lut_size = 1024, \
162f005ef32Sjsg .degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING | \
163f005ef32Sjsg DRM_COLOR_LUT_EQUAL_CHANNELS, \
164f005ef32Sjsg }
165f005ef32Sjsg #define ICL_COLORS \
166f005ef32Sjsg .color = { \
167f005ef32Sjsg .degamma_lut_size = 33, .gamma_lut_size = 262145, \
168f005ef32Sjsg .degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING | \
169f005ef32Sjsg DRM_COLOR_LUT_EQUAL_CHANNELS, \
170f005ef32Sjsg .gamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \
171f005ef32Sjsg }
172f005ef32Sjsg
173f005ef32Sjsg #define I830_DISPLAY \
174f005ef32Sjsg .has_overlay = 1, \
175f005ef32Sjsg .cursor_needs_physical = 1, \
176f005ef32Sjsg .overlay_needs_physical = 1, \
177f005ef32Sjsg .has_gmch = 1, \
178f005ef32Sjsg I9XX_PIPE_OFFSETS, \
179f005ef32Sjsg I9XX_CURSOR_OFFSETS, \
180f005ef32Sjsg I9XX_COLORS, \
181f005ef32Sjsg \
182f005ef32Sjsg .__runtime_defaults.ip.ver = 2, \
183f005ef32Sjsg .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
184f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask = \
185f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B)
186f005ef32Sjsg
187f005ef32Sjsg #define I845_DISPLAY \
188f005ef32Sjsg .has_overlay = 1, \
189f005ef32Sjsg .overlay_needs_physical = 1, \
190f005ef32Sjsg .has_gmch = 1, \
191f005ef32Sjsg I845_PIPE_OFFSETS, \
192f005ef32Sjsg I845_CURSOR_OFFSETS, \
193f005ef32Sjsg I845_COLORS, \
194f005ef32Sjsg \
195f005ef32Sjsg .__runtime_defaults.ip.ver = 2, \
196f005ef32Sjsg .__runtime_defaults.pipe_mask = BIT(PIPE_A), \
197f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask = BIT(TRANSCODER_A)
198f005ef32Sjsg
199f005ef32Sjsg static const struct intel_display_device_info i830_display = {
200f005ef32Sjsg I830_DISPLAY,
201f005ef32Sjsg
202f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C), /* DVO A/B/C */
203f005ef32Sjsg };
204f005ef32Sjsg
205f005ef32Sjsg static const struct intel_display_device_info i845_display = {
206f005ef32Sjsg I845_DISPLAY,
207f005ef32Sjsg
208f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
209f005ef32Sjsg };
210f005ef32Sjsg
211f005ef32Sjsg static const struct intel_display_device_info i85x_display = {
212f005ef32Sjsg I830_DISPLAY,
213f005ef32Sjsg
214f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
215f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
216f005ef32Sjsg };
217f005ef32Sjsg
218f005ef32Sjsg static const struct intel_display_device_info i865g_display = {
219f005ef32Sjsg I845_DISPLAY,
220f005ef32Sjsg
221f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
222f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
223f005ef32Sjsg };
224f005ef32Sjsg
225f005ef32Sjsg #define GEN3_DISPLAY \
226f005ef32Sjsg .has_gmch = 1, \
227f005ef32Sjsg .has_overlay = 1, \
228f005ef32Sjsg I9XX_PIPE_OFFSETS, \
229f005ef32Sjsg I9XX_CURSOR_OFFSETS, \
230f005ef32Sjsg \
231f005ef32Sjsg .__runtime_defaults.ip.ver = 3, \
232f005ef32Sjsg .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
233f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask = \
234f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
235f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) /* SDVO B/C */
236f005ef32Sjsg
237f005ef32Sjsg static const struct intel_display_device_info i915g_display = {
238f005ef32Sjsg GEN3_DISPLAY,
239f005ef32Sjsg I845_COLORS,
240f005ef32Sjsg .cursor_needs_physical = 1,
241f005ef32Sjsg .overlay_needs_physical = 1,
242f005ef32Sjsg };
243f005ef32Sjsg
244f005ef32Sjsg static const struct intel_display_device_info i915gm_display = {
245f005ef32Sjsg GEN3_DISPLAY,
246f005ef32Sjsg I9XX_COLORS,
247f005ef32Sjsg .cursor_needs_physical = 1,
248f005ef32Sjsg .overlay_needs_physical = 1,
249f005ef32Sjsg .supports_tv = 1,
250f005ef32Sjsg
251f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
252f005ef32Sjsg };
253f005ef32Sjsg
254f005ef32Sjsg static const struct intel_display_device_info i945g_display = {
255f005ef32Sjsg GEN3_DISPLAY,
256f005ef32Sjsg I845_COLORS,
257f005ef32Sjsg .has_hotplug = 1,
258f005ef32Sjsg .cursor_needs_physical = 1,
259f005ef32Sjsg .overlay_needs_physical = 1,
260f005ef32Sjsg };
261f005ef32Sjsg
262f005ef32Sjsg static const struct intel_display_device_info i945gm_display = {
263f005ef32Sjsg GEN3_DISPLAY,
264f005ef32Sjsg I9XX_COLORS,
265f005ef32Sjsg .has_hotplug = 1,
266f005ef32Sjsg .cursor_needs_physical = 1,
267f005ef32Sjsg .overlay_needs_physical = 1,
268f005ef32Sjsg .supports_tv = 1,
269f005ef32Sjsg
270f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
271f005ef32Sjsg };
272f005ef32Sjsg
273f005ef32Sjsg static const struct intel_display_device_info g33_display = {
274f005ef32Sjsg GEN3_DISPLAY,
275f005ef32Sjsg I845_COLORS,
276f005ef32Sjsg .has_hotplug = 1,
277f005ef32Sjsg };
278f005ef32Sjsg
279f005ef32Sjsg static const struct intel_display_device_info pnv_display = {
280f005ef32Sjsg GEN3_DISPLAY,
281f005ef32Sjsg I9XX_COLORS,
282f005ef32Sjsg .has_hotplug = 1,
283f005ef32Sjsg };
284f005ef32Sjsg
285f005ef32Sjsg #define GEN4_DISPLAY \
286f005ef32Sjsg .has_hotplug = 1, \
287f005ef32Sjsg .has_gmch = 1, \
288f005ef32Sjsg I9XX_PIPE_OFFSETS, \
289f005ef32Sjsg I9XX_CURSOR_OFFSETS, \
290f005ef32Sjsg I9XX_COLORS, \
291f005ef32Sjsg \
292f005ef32Sjsg .__runtime_defaults.ip.ver = 4, \
293f005ef32Sjsg .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
294f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask = \
295f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B)
296f005ef32Sjsg
297f005ef32Sjsg static const struct intel_display_device_info i965g_display = {
298f005ef32Sjsg GEN4_DISPLAY,
299f005ef32Sjsg .has_overlay = 1,
300f005ef32Sjsg
301f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* SDVO B/C */
302f005ef32Sjsg };
303f005ef32Sjsg
304f005ef32Sjsg static const struct intel_display_device_info i965gm_display = {
305f005ef32Sjsg GEN4_DISPLAY,
306f005ef32Sjsg .has_overlay = 1,
307f005ef32Sjsg .supports_tv = 1,
308f005ef32Sjsg
309f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* SDVO B/C */
310f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
311f005ef32Sjsg };
312f005ef32Sjsg
313f005ef32Sjsg static const struct intel_display_device_info g45_display = {
314f005ef32Sjsg GEN4_DISPLAY,
315f005ef32Sjsg
316f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* SDVO/HDMI/DP B/C, DP D */
317f005ef32Sjsg };
318f005ef32Sjsg
319f005ef32Sjsg static const struct intel_display_device_info gm45_display = {
320f005ef32Sjsg GEN4_DISPLAY,
321f005ef32Sjsg .supports_tv = 1,
322f005ef32Sjsg
323f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* SDVO/HDMI/DP B/C, DP D */
324f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
325f005ef32Sjsg };
326f005ef32Sjsg
327f005ef32Sjsg #define ILK_DISPLAY \
328f005ef32Sjsg .has_hotplug = 1, \
329f005ef32Sjsg I9XX_PIPE_OFFSETS, \
330f005ef32Sjsg I9XX_CURSOR_OFFSETS, \
331f005ef32Sjsg ILK_COLORS, \
332f005ef32Sjsg \
333f005ef32Sjsg .__runtime_defaults.ip.ver = 5, \
334f005ef32Sjsg .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
335f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask = \
336f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
337f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
338f005ef32Sjsg
339f005ef32Sjsg static const struct intel_display_device_info ilk_d_display = {
340f005ef32Sjsg ILK_DISPLAY,
341f005ef32Sjsg };
342f005ef32Sjsg
343f005ef32Sjsg static const struct intel_display_device_info ilk_m_display = {
344f005ef32Sjsg ILK_DISPLAY,
345f005ef32Sjsg
346f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
347f005ef32Sjsg };
348f005ef32Sjsg
349f005ef32Sjsg static const struct intel_display_device_info snb_display = {
350f005ef32Sjsg .has_hotplug = 1,
351f005ef32Sjsg I9XX_PIPE_OFFSETS,
352f005ef32Sjsg I9XX_CURSOR_OFFSETS,
353f005ef32Sjsg ILK_COLORS,
354f005ef32Sjsg
355f005ef32Sjsg .__runtime_defaults.ip.ver = 6,
356f005ef32Sjsg .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
357f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask =
358f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
359f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
360f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
361f005ef32Sjsg };
362f005ef32Sjsg
363f005ef32Sjsg static const struct intel_display_device_info ivb_display = {
364f005ef32Sjsg .has_hotplug = 1,
365f005ef32Sjsg IVB_PIPE_OFFSETS,
366f005ef32Sjsg IVB_CURSOR_OFFSETS,
367f005ef32Sjsg IVB_COLORS,
368f005ef32Sjsg
369f005ef32Sjsg .__runtime_defaults.ip.ver = 7,
370f005ef32Sjsg .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
371f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask =
372f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
373f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
374f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
375f005ef32Sjsg };
376f005ef32Sjsg
377f005ef32Sjsg static const struct intel_display_device_info vlv_display = {
378f005ef32Sjsg .has_gmch = 1,
379f005ef32Sjsg .has_hotplug = 1,
380f005ef32Sjsg .mmio_offset = VLV_DISPLAY_BASE,
381f005ef32Sjsg I9XX_PIPE_OFFSETS,
382f005ef32Sjsg I9XX_CURSOR_OFFSETS,
383f005ef32Sjsg I9XX_COLORS,
384f005ef32Sjsg
385f005ef32Sjsg .__runtime_defaults.ip.ver = 7,
386f005ef32Sjsg .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
387f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask =
388f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
389f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* HDMI/DP B/C */
390f005ef32Sjsg };
391f005ef32Sjsg
392f005ef32Sjsg static const struct intel_display_device_info hsw_display = {
393f005ef32Sjsg .has_ddi = 1,
394f005ef32Sjsg .has_dp_mst = 1,
395f005ef32Sjsg .has_fpga_dbg = 1,
396f005ef32Sjsg .has_hotplug = 1,
397f005ef32Sjsg .has_psr = 1,
398f005ef32Sjsg .has_psr_hw_tracking = 1,
399f005ef32Sjsg HSW_PIPE_OFFSETS,
400f005ef32Sjsg IVB_CURSOR_OFFSETS,
401f005ef32Sjsg IVB_COLORS,
402f005ef32Sjsg
403f005ef32Sjsg .__runtime_defaults.ip.ver = 7,
404f005ef32Sjsg .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
405f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask =
406f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
407f005ef32Sjsg BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
408f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
409f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
410f005ef32Sjsg };
411f005ef32Sjsg
412f005ef32Sjsg static const struct intel_display_device_info bdw_display = {
413f005ef32Sjsg .has_ddi = 1,
414f005ef32Sjsg .has_dp_mst = 1,
415f005ef32Sjsg .has_fpga_dbg = 1,
416f005ef32Sjsg .has_hotplug = 1,
417f005ef32Sjsg .has_psr = 1,
418f005ef32Sjsg .has_psr_hw_tracking = 1,
419f005ef32Sjsg HSW_PIPE_OFFSETS,
420f005ef32Sjsg IVB_CURSOR_OFFSETS,
421f005ef32Sjsg IVB_COLORS,
422f005ef32Sjsg
423f005ef32Sjsg .__runtime_defaults.ip.ver = 8,
424f005ef32Sjsg .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
425f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask =
426f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
427f005ef32Sjsg BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
428f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
429f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
430f005ef32Sjsg };
431f005ef32Sjsg
432f005ef32Sjsg static const struct intel_display_device_info chv_display = {
433f005ef32Sjsg .has_hotplug = 1,
434f005ef32Sjsg .has_gmch = 1,
435f005ef32Sjsg .mmio_offset = VLV_DISPLAY_BASE,
436f005ef32Sjsg CHV_PIPE_OFFSETS,
437f005ef32Sjsg CHV_CURSOR_OFFSETS,
438f005ef32Sjsg CHV_COLORS,
439f005ef32Sjsg
440f005ef32Sjsg .__runtime_defaults.ip.ver = 8,
441f005ef32Sjsg .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
442f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask =
443f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
444f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* HDMI/DP B/C/D */
445f005ef32Sjsg };
446f005ef32Sjsg
447f005ef32Sjsg static const struct intel_display_device_info skl_display = {
448f005ef32Sjsg .dbuf.size = 896 - 4, /* 4 blocks for bypass path allocation */
449f005ef32Sjsg .dbuf.slice_mask = BIT(DBUF_S1),
450f005ef32Sjsg .has_ddi = 1,
451f005ef32Sjsg .has_dp_mst = 1,
452f005ef32Sjsg .has_fpga_dbg = 1,
453f005ef32Sjsg .has_hotplug = 1,
454f005ef32Sjsg .has_ipc = 1,
455f005ef32Sjsg .has_psr = 1,
456f005ef32Sjsg .has_psr_hw_tracking = 1,
457f005ef32Sjsg HSW_PIPE_OFFSETS,
458f005ef32Sjsg IVB_CURSOR_OFFSETS,
459f005ef32Sjsg IVB_COLORS,
460f005ef32Sjsg
461f005ef32Sjsg .__runtime_defaults.ip.ver = 9,
462f005ef32Sjsg .__runtime_defaults.has_dmc = 1,
463f005ef32Sjsg .__runtime_defaults.has_hdcp = 1,
464f005ef32Sjsg .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
465f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask =
466f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
467f005ef32Sjsg BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
468f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
469f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
470f005ef32Sjsg };
471f005ef32Sjsg
472f005ef32Sjsg #define GEN9_LP_DISPLAY \
473f005ef32Sjsg .dbuf.slice_mask = BIT(DBUF_S1), \
474f005ef32Sjsg .has_dp_mst = 1, \
475f005ef32Sjsg .has_ddi = 1, \
476f005ef32Sjsg .has_fpga_dbg = 1, \
477f005ef32Sjsg .has_hotplug = 1, \
478f005ef32Sjsg .has_ipc = 1, \
479f005ef32Sjsg .has_psr = 1, \
480f005ef32Sjsg .has_psr_hw_tracking = 1, \
481f005ef32Sjsg HSW_PIPE_OFFSETS, \
482f005ef32Sjsg IVB_CURSOR_OFFSETS, \
483f005ef32Sjsg IVB_COLORS, \
484f005ef32Sjsg \
485f005ef32Sjsg .__runtime_defaults.has_dmc = 1, \
486f005ef32Sjsg .__runtime_defaults.has_hdcp = 1, \
487f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A), \
488f005ef32Sjsg .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \
489f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask = \
490f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
491f005ef32Sjsg BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) | \
492f005ef32Sjsg BIT(TRANSCODER_DSI_A) | BIT(TRANSCODER_DSI_C), \
493f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C)
494f005ef32Sjsg
495f005ef32Sjsg static const struct intel_display_device_info bxt_display = {
496f005ef32Sjsg GEN9_LP_DISPLAY,
497f005ef32Sjsg .dbuf.size = 512 - 4, /* 4 blocks for bypass path allocation */
498f005ef32Sjsg
499f005ef32Sjsg .__runtime_defaults.ip.ver = 9,
500f005ef32Sjsg };
501f005ef32Sjsg
502f005ef32Sjsg static const struct intel_display_device_info glk_display = {
503f005ef32Sjsg GEN9_LP_DISPLAY,
504f005ef32Sjsg .dbuf.size = 1024 - 4, /* 4 blocks for bypass path allocation */
505f005ef32Sjsg GLK_COLORS,
506f005ef32Sjsg
507f005ef32Sjsg .__runtime_defaults.ip.ver = 10,
508f005ef32Sjsg };
509f005ef32Sjsg
510f005ef32Sjsg #define ICL_DISPLAY \
511f005ef32Sjsg .abox_mask = BIT(0), \
512f005ef32Sjsg .dbuf.size = 2048, \
513f005ef32Sjsg .dbuf.slice_mask = BIT(DBUF_S1) | BIT(DBUF_S2), \
514f005ef32Sjsg .has_ddi = 1, \
515f005ef32Sjsg .has_dp_mst = 1, \
516f005ef32Sjsg .has_fpga_dbg = 1, \
517f005ef32Sjsg .has_hotplug = 1, \
518f005ef32Sjsg .has_ipc = 1, \
519f005ef32Sjsg .has_psr = 1, \
520f005ef32Sjsg .has_psr_hw_tracking = 1, \
521f005ef32Sjsg .pipe_offsets = { \
522f005ef32Sjsg [TRANSCODER_A] = PIPE_A_OFFSET, \
523f005ef32Sjsg [TRANSCODER_B] = PIPE_B_OFFSET, \
524f005ef32Sjsg [TRANSCODER_C] = PIPE_C_OFFSET, \
525f005ef32Sjsg [TRANSCODER_EDP] = PIPE_EDP_OFFSET, \
526f005ef32Sjsg [TRANSCODER_DSI_0] = PIPE_DSI0_OFFSET, \
527f005ef32Sjsg [TRANSCODER_DSI_1] = PIPE_DSI1_OFFSET, \
528f005ef32Sjsg }, \
529f005ef32Sjsg .trans_offsets = { \
530f005ef32Sjsg [TRANSCODER_A] = TRANSCODER_A_OFFSET, \
531f005ef32Sjsg [TRANSCODER_B] = TRANSCODER_B_OFFSET, \
532f005ef32Sjsg [TRANSCODER_C] = TRANSCODER_C_OFFSET, \
533f005ef32Sjsg [TRANSCODER_EDP] = TRANSCODER_EDP_OFFSET, \
534f005ef32Sjsg [TRANSCODER_DSI_0] = TRANSCODER_DSI0_OFFSET, \
535f005ef32Sjsg [TRANSCODER_DSI_1] = TRANSCODER_DSI1_OFFSET, \
536f005ef32Sjsg }, \
537f005ef32Sjsg IVB_CURSOR_OFFSETS, \
538f005ef32Sjsg ICL_COLORS, \
539f005ef32Sjsg \
540f005ef32Sjsg .__runtime_defaults.ip.ver = 11, \
541f005ef32Sjsg .__runtime_defaults.has_dmc = 1, \
542f005ef32Sjsg .__runtime_defaults.has_dsc = 1, \
543f005ef32Sjsg .__runtime_defaults.has_hdcp = 1, \
544f005ef32Sjsg .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \
545f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask = \
546f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
547f005ef32Sjsg BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) | \
548f005ef32Sjsg BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \
549f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A)
550f005ef32Sjsg
551f005ef32Sjsg static const struct intel_display_device_info icl_display = {
552f005ef32Sjsg ICL_DISPLAY,
553f005ef32Sjsg
554f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
555f005ef32Sjsg };
556f005ef32Sjsg
557f005ef32Sjsg static const struct intel_display_device_info jsl_ehl_display = {
558f005ef32Sjsg ICL_DISPLAY,
559f005ef32Sjsg
560f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D),
561f005ef32Sjsg };
562f005ef32Sjsg
563f005ef32Sjsg #define XE_D_DISPLAY \
564f005ef32Sjsg .abox_mask = GENMASK(2, 1), \
565f005ef32Sjsg .dbuf.size = 2048, \
566f005ef32Sjsg .dbuf.slice_mask = BIT(DBUF_S1) | BIT(DBUF_S2), \
567f005ef32Sjsg .has_ddi = 1, \
568f005ef32Sjsg .has_dp_mst = 1, \
569f005ef32Sjsg .has_dsb = 1, \
570f005ef32Sjsg .has_fpga_dbg = 1, \
571f005ef32Sjsg .has_hotplug = 1, \
572f005ef32Sjsg .has_ipc = 1, \
573f005ef32Sjsg .has_psr = 1, \
574f005ef32Sjsg .has_psr_hw_tracking = 1, \
575f005ef32Sjsg .pipe_offsets = { \
576f005ef32Sjsg [TRANSCODER_A] = PIPE_A_OFFSET, \
577f005ef32Sjsg [TRANSCODER_B] = PIPE_B_OFFSET, \
578f005ef32Sjsg [TRANSCODER_C] = PIPE_C_OFFSET, \
579f005ef32Sjsg [TRANSCODER_D] = PIPE_D_OFFSET, \
580f005ef32Sjsg [TRANSCODER_DSI_0] = PIPE_DSI0_OFFSET, \
581f005ef32Sjsg [TRANSCODER_DSI_1] = PIPE_DSI1_OFFSET, \
582f005ef32Sjsg }, \
583f005ef32Sjsg .trans_offsets = { \
584f005ef32Sjsg [TRANSCODER_A] = TRANSCODER_A_OFFSET, \
585f005ef32Sjsg [TRANSCODER_B] = TRANSCODER_B_OFFSET, \
586f005ef32Sjsg [TRANSCODER_C] = TRANSCODER_C_OFFSET, \
587f005ef32Sjsg [TRANSCODER_D] = TRANSCODER_D_OFFSET, \
588f005ef32Sjsg [TRANSCODER_DSI_0] = TRANSCODER_DSI0_OFFSET, \
589f005ef32Sjsg [TRANSCODER_DSI_1] = TRANSCODER_DSI1_OFFSET, \
590f005ef32Sjsg }, \
591f005ef32Sjsg TGL_CURSOR_OFFSETS, \
592f005ef32Sjsg ICL_COLORS, \
593f005ef32Sjsg \
594f005ef32Sjsg .__runtime_defaults.ip.ver = 12, \
595f005ef32Sjsg .__runtime_defaults.has_dmc = 1, \
596f005ef32Sjsg .__runtime_defaults.has_dsc = 1, \
597f005ef32Sjsg .__runtime_defaults.has_hdcp = 1, \
598f005ef32Sjsg .__runtime_defaults.pipe_mask = \
599f005ef32Sjsg BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), \
600f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask = \
601f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
602f005ef32Sjsg BIT(TRANSCODER_C) | BIT(TRANSCODER_D) | \
603f005ef32Sjsg BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \
604f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A)
605f005ef32Sjsg
606f005ef32Sjsg static const struct intel_display_device_info tgl_display = {
607f005ef32Sjsg XE_D_DISPLAY,
608f005ef32Sjsg
609f005ef32Sjsg /*
610f005ef32Sjsg * FIXME DDI C/combo PHY C missing due to combo PHY
611f005ef32Sjsg * code making a mess on SKUs where the PHY is missing.
612f005ef32Sjsg */
613f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
614f005ef32Sjsg BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4) | BIT(PORT_TC5) | BIT(PORT_TC6),
615f005ef32Sjsg };
616f005ef32Sjsg
617f005ef32Sjsg static const struct intel_display_device_info dg1_display = {
618f005ef32Sjsg XE_D_DISPLAY,
619f005ef32Sjsg
620f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
621f005ef32Sjsg BIT(PORT_TC1) | BIT(PORT_TC2),
622f005ef32Sjsg };
623f005ef32Sjsg
624f005ef32Sjsg static const struct intel_display_device_info rkl_display = {
625f005ef32Sjsg XE_D_DISPLAY,
626f005ef32Sjsg .abox_mask = BIT(0),
627f005ef32Sjsg .has_hti = 1,
628f005ef32Sjsg .has_psr_hw_tracking = 0,
629f005ef32Sjsg
630f005ef32Sjsg .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
631f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask =
632f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
633f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
634f005ef32Sjsg BIT(PORT_TC1) | BIT(PORT_TC2),
635f005ef32Sjsg };
636f005ef32Sjsg
637f005ef32Sjsg static const struct intel_display_device_info adl_s_display = {
638f005ef32Sjsg XE_D_DISPLAY,
639f005ef32Sjsg .has_hti = 1,
640f005ef32Sjsg .has_psr_hw_tracking = 0,
641f005ef32Sjsg
642f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) |
643f005ef32Sjsg BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
644f005ef32Sjsg };
645f005ef32Sjsg
646f005ef32Sjsg #define XE_LPD_FEATURES \
647f005ef32Sjsg .abox_mask = GENMASK(1, 0), \
648f005ef32Sjsg .color = { \
649f005ef32Sjsg .degamma_lut_size = 129, .gamma_lut_size = 1024, \
650f005ef32Sjsg .degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING | \
651f005ef32Sjsg DRM_COLOR_LUT_EQUAL_CHANNELS, \
652f005ef32Sjsg }, \
653f005ef32Sjsg .dbuf.size = 4096, \
654f005ef32Sjsg .dbuf.slice_mask = BIT(DBUF_S1) | BIT(DBUF_S2) | BIT(DBUF_S3) | \
655f005ef32Sjsg BIT(DBUF_S4), \
656f005ef32Sjsg .has_ddi = 1, \
657f005ef32Sjsg .has_dp_mst = 1, \
658f005ef32Sjsg .has_dsb = 1, \
659f005ef32Sjsg .has_fpga_dbg = 1, \
660f005ef32Sjsg .has_hotplug = 1, \
661f005ef32Sjsg .has_ipc = 1, \
662f005ef32Sjsg .has_psr = 1, \
663f005ef32Sjsg .pipe_offsets = { \
664f005ef32Sjsg [TRANSCODER_A] = PIPE_A_OFFSET, \
665f005ef32Sjsg [TRANSCODER_B] = PIPE_B_OFFSET, \
666f005ef32Sjsg [TRANSCODER_C] = PIPE_C_OFFSET, \
667f005ef32Sjsg [TRANSCODER_D] = PIPE_D_OFFSET, \
668f005ef32Sjsg [TRANSCODER_DSI_0] = PIPE_DSI0_OFFSET, \
669f005ef32Sjsg [TRANSCODER_DSI_1] = PIPE_DSI1_OFFSET, \
670f005ef32Sjsg }, \
671f005ef32Sjsg .trans_offsets = { \
672f005ef32Sjsg [TRANSCODER_A] = TRANSCODER_A_OFFSET, \
673f005ef32Sjsg [TRANSCODER_B] = TRANSCODER_B_OFFSET, \
674f005ef32Sjsg [TRANSCODER_C] = TRANSCODER_C_OFFSET, \
675f005ef32Sjsg [TRANSCODER_D] = TRANSCODER_D_OFFSET, \
676f005ef32Sjsg [TRANSCODER_DSI_0] = TRANSCODER_DSI0_OFFSET, \
677f005ef32Sjsg [TRANSCODER_DSI_1] = TRANSCODER_DSI1_OFFSET, \
678f005ef32Sjsg }, \
679f005ef32Sjsg TGL_CURSOR_OFFSETS, \
680f005ef32Sjsg \
681f005ef32Sjsg .__runtime_defaults.ip.ver = 13, \
682f005ef32Sjsg .__runtime_defaults.has_dmc = 1, \
683f005ef32Sjsg .__runtime_defaults.has_dsc = 1, \
684f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A), \
685f005ef32Sjsg .__runtime_defaults.has_hdcp = 1, \
686f005ef32Sjsg .__runtime_defaults.pipe_mask = \
687f005ef32Sjsg BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D)
688f005ef32Sjsg
689f005ef32Sjsg static const struct intel_display_device_info xe_lpd_display = {
690f005ef32Sjsg XE_LPD_FEATURES,
691f005ef32Sjsg .has_cdclk_crawl = 1,
692f005ef32Sjsg .has_psr_hw_tracking = 0,
693f005ef32Sjsg
694f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask =
695f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
696f005ef32Sjsg BIT(TRANSCODER_C) | BIT(TRANSCODER_D) |
697f005ef32Sjsg BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1),
698f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
699f005ef32Sjsg BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
700f005ef32Sjsg };
701f005ef32Sjsg
702f005ef32Sjsg static const struct intel_display_device_info xe_hpd_display = {
703f005ef32Sjsg XE_LPD_FEATURES,
704f005ef32Sjsg .has_cdclk_squash = 1,
705f005ef32Sjsg
706f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask =
707f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
708f005ef32Sjsg BIT(TRANSCODER_C) | BIT(TRANSCODER_D),
709f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D_XELPD) |
710f005ef32Sjsg BIT(PORT_TC1),
711f005ef32Sjsg };
712f005ef32Sjsg
713f005ef32Sjsg static const struct intel_display_device_info xe_lpdp_display = {
714f005ef32Sjsg XE_LPD_FEATURES,
715f005ef32Sjsg .has_cdclk_crawl = 1,
716f005ef32Sjsg .has_cdclk_squash = 1,
717f005ef32Sjsg
718f005ef32Sjsg .__runtime_defaults.ip.ver = 14,
719f005ef32Sjsg .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A) | BIT(INTEL_FBC_B),
720f005ef32Sjsg .__runtime_defaults.cpu_transcoder_mask =
721f005ef32Sjsg BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
722f005ef32Sjsg BIT(TRANSCODER_C) | BIT(TRANSCODER_D),
723f005ef32Sjsg .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
724f005ef32Sjsg BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
725f005ef32Sjsg };
726f005ef32Sjsg
727f005ef32Sjsg /*
728f005ef32Sjsg * Separate detection for no display cases to keep the display id array simple.
729f005ef32Sjsg *
730f005ef32Sjsg * IVB Q requires subvendor and subdevice matching to differentiate from IVB D
731f005ef32Sjsg * GT2 server.
732f005ef32Sjsg */
has_no_display(struct pci_dev * pdev)733f005ef32Sjsg static bool has_no_display(struct pci_dev *pdev)
734f005ef32Sjsg {
735f005ef32Sjsg static const struct pci_device_id ids[] = {
736f005ef32Sjsg INTEL_IVB_Q_IDS(0),
737f005ef32Sjsg {}
738f005ef32Sjsg };
739f005ef32Sjsg
740f005ef32Sjsg return pci_match_id(ids, pdev);
741f005ef32Sjsg }
742f005ef32Sjsg
743f005ef32Sjsg #undef INTEL_VGA_DEVICE
744f005ef32Sjsg #define INTEL_VGA_DEVICE(id, info) { id, info }
745f005ef32Sjsg
746f005ef32Sjsg static const struct {
747f005ef32Sjsg u32 devid;
748f005ef32Sjsg const struct intel_display_device_info *info;
749f005ef32Sjsg } intel_display_ids[] = {
750f005ef32Sjsg INTEL_I830_IDS(&i830_display),
751f005ef32Sjsg INTEL_I845G_IDS(&i845_display),
752f005ef32Sjsg INTEL_I85X_IDS(&i85x_display),
753f005ef32Sjsg INTEL_I865G_IDS(&i865g_display),
754f005ef32Sjsg INTEL_I915G_IDS(&i915g_display),
755f005ef32Sjsg INTEL_I915GM_IDS(&i915gm_display),
756f005ef32Sjsg INTEL_I945G_IDS(&i945g_display),
757f005ef32Sjsg INTEL_I945GM_IDS(&i945gm_display),
758f005ef32Sjsg INTEL_I965G_IDS(&i965g_display),
759f005ef32Sjsg INTEL_G33_IDS(&g33_display),
760f005ef32Sjsg INTEL_I965GM_IDS(&i965gm_display),
761f005ef32Sjsg INTEL_GM45_IDS(&gm45_display),
762f005ef32Sjsg INTEL_G45_IDS(&g45_display),
763f005ef32Sjsg INTEL_PINEVIEW_G_IDS(&pnv_display),
764f005ef32Sjsg INTEL_PINEVIEW_M_IDS(&pnv_display),
765f005ef32Sjsg INTEL_IRONLAKE_D_IDS(&ilk_d_display),
766f005ef32Sjsg INTEL_IRONLAKE_M_IDS(&ilk_m_display),
767f005ef32Sjsg INTEL_SNB_D_IDS(&snb_display),
768f005ef32Sjsg INTEL_SNB_M_IDS(&snb_display),
769f005ef32Sjsg INTEL_IVB_M_IDS(&ivb_display),
770f005ef32Sjsg INTEL_IVB_D_IDS(&ivb_display),
771f005ef32Sjsg INTEL_HSW_IDS(&hsw_display),
772f005ef32Sjsg INTEL_VLV_IDS(&vlv_display),
773f005ef32Sjsg INTEL_BDW_IDS(&bdw_display),
774f005ef32Sjsg INTEL_CHV_IDS(&chv_display),
775f005ef32Sjsg INTEL_SKL_IDS(&skl_display),
776f005ef32Sjsg INTEL_BXT_IDS(&bxt_display),
777f005ef32Sjsg INTEL_GLK_IDS(&glk_display),
778f005ef32Sjsg INTEL_KBL_IDS(&skl_display),
779f005ef32Sjsg INTEL_CFL_IDS(&skl_display),
780f005ef32Sjsg INTEL_ICL_11_IDS(&icl_display),
781f005ef32Sjsg INTEL_EHL_IDS(&jsl_ehl_display),
782f005ef32Sjsg INTEL_JSL_IDS(&jsl_ehl_display),
783f005ef32Sjsg INTEL_TGL_12_IDS(&tgl_display),
784f005ef32Sjsg INTEL_DG1_IDS(&dg1_display),
785f005ef32Sjsg INTEL_RKL_IDS(&rkl_display),
786f005ef32Sjsg INTEL_ADLS_IDS(&adl_s_display),
787f005ef32Sjsg INTEL_RPLS_IDS(&adl_s_display),
788f005ef32Sjsg INTEL_ADLP_IDS(&xe_lpd_display),
789f005ef32Sjsg INTEL_ADLN_IDS(&xe_lpd_display),
790f005ef32Sjsg INTEL_RPLP_IDS(&xe_lpd_display),
791f005ef32Sjsg INTEL_DG2_IDS(&xe_hpd_display),
792f005ef32Sjsg
793f005ef32Sjsg /*
794f005ef32Sjsg * Do not add any GMD_ID-based platforms to this list. They will
795f005ef32Sjsg * be probed automatically based on the IP version reported by
796f005ef32Sjsg * the hardware.
797f005ef32Sjsg */
798f005ef32Sjsg };
799f005ef32Sjsg
800f005ef32Sjsg static const struct {
801f005ef32Sjsg u16 ver;
802f005ef32Sjsg u16 rel;
803f005ef32Sjsg const struct intel_display_device_info *display;
804f005ef32Sjsg } gmdid_display_map[] = {
805f005ef32Sjsg { 14, 0, &xe_lpdp_display },
806f005ef32Sjsg };
807f005ef32Sjsg
808f005ef32Sjsg static const struct intel_display_device_info *
probe_gmdid_display(struct drm_i915_private * i915,u16 * ver,u16 * rel,u16 * step)809f005ef32Sjsg probe_gmdid_display(struct drm_i915_private *i915, u16 *ver, u16 *rel, u16 *step)
810f005ef32Sjsg {
811f005ef32Sjsg struct pci_dev *pdev = i915->drm.pdev;
812f005ef32Sjsg void __iomem *addr;
813f005ef32Sjsg u32 val;
814f005ef32Sjsg int i;
815*e4142e7bSjsg int mmio_bar, mmio_size, mmio_type;
816*e4142e7bSjsg bus_space_tag_t bst;
817*e4142e7bSjsg bus_space_handle_t bsh;
818*e4142e7bSjsg bus_size_t memsize;
819f005ef32Sjsg
820f005ef32Sjsg /* The caller expects to ver, rel and step to be initialized
821f005ef32Sjsg * here, and there's no good way to check when there was a
822f005ef32Sjsg * failure and no_display was returned. So initialize all these
823f005ef32Sjsg * values here zero, to be sure.
824f005ef32Sjsg */
825f005ef32Sjsg *ver = 0;
826f005ef32Sjsg *rel = 0;
827f005ef32Sjsg *step = 0;
828f005ef32Sjsg
829*e4142e7bSjsg #ifdef __linux__
830f005ef32Sjsg addr = pci_iomap_range(pdev, 0, i915_mmio_reg_offset(GMD_ID_DISPLAY), sizeof(u32));
831f005ef32Sjsg if (!addr) {
832f005ef32Sjsg drm_err(&i915->drm, "Cannot map MMIO BAR to read display GMD_ID\n");
833f005ef32Sjsg return &no_display;
834f005ef32Sjsg }
835f005ef32Sjsg
836f005ef32Sjsg val = ioread32(addr);
837f005ef32Sjsg pci_iounmap(pdev, addr);
838*e4142e7bSjsg #else
839*e4142e7bSjsg mmio_bar = 0x10;
840*e4142e7bSjsg mmio_type = pci_mapreg_type(i915->pc, i915->tag, mmio_bar);
841*e4142e7bSjsg if (pci_mapreg_map(i915->pa, mmio_bar, mmio_type, 0,
842*e4142e7bSjsg &bst, &bsh, NULL, &memsize, 0)) {
843*e4142e7bSjsg drm_err(&i915->drm, "Cannot map MMIO BAR to read display GMD_ID\n");
844*e4142e7bSjsg return &no_display;
845*e4142e7bSjsg }
846*e4142e7bSjsg
847*e4142e7bSjsg val = bus_space_read_4(bst, bsh, i915_mmio_reg_offset(GMD_ID_DISPLAY));
848*e4142e7bSjsg
849*e4142e7bSjsg bus_space_unmap(bst, bsh, memsize);
850*e4142e7bSjsg #endif
851f005ef32Sjsg
852f005ef32Sjsg if (val == 0) {
853f005ef32Sjsg drm_dbg_kms(&i915->drm, "Device doesn't have display\n");
854f005ef32Sjsg return &no_display;
855f005ef32Sjsg }
856f005ef32Sjsg
857f005ef32Sjsg *ver = REG_FIELD_GET(GMD_ID_ARCH_MASK, val);
858f005ef32Sjsg *rel = REG_FIELD_GET(GMD_ID_RELEASE_MASK, val);
859f005ef32Sjsg *step = REG_FIELD_GET(GMD_ID_STEP, val);
860f005ef32Sjsg
861f005ef32Sjsg for (i = 0; i < ARRAY_SIZE(gmdid_display_map); i++)
862f005ef32Sjsg if (*ver == gmdid_display_map[i].ver &&
863f005ef32Sjsg *rel == gmdid_display_map[i].rel)
864f005ef32Sjsg return gmdid_display_map[i].display;
865f005ef32Sjsg
866f005ef32Sjsg drm_err(&i915->drm, "Unrecognized display IP version %d.%02d; disabling display.\n",
867f005ef32Sjsg *ver, *rel);
868f005ef32Sjsg return &no_display;
869f005ef32Sjsg }
870f005ef32Sjsg
871f005ef32Sjsg const struct intel_display_device_info *
intel_display_device_probe(struct drm_i915_private * i915,bool has_gmdid,u16 * gmdid_ver,u16 * gmdid_rel,u16 * gmdid_step)872f005ef32Sjsg intel_display_device_probe(struct drm_i915_private *i915, bool has_gmdid,
873f005ef32Sjsg u16 *gmdid_ver, u16 *gmdid_rel, u16 *gmdid_step)
874f005ef32Sjsg {
875f005ef32Sjsg struct pci_dev *pdev = i915->drm.pdev;
876f005ef32Sjsg int i;
877f005ef32Sjsg
878f005ef32Sjsg if (has_gmdid)
879f005ef32Sjsg return probe_gmdid_display(i915, gmdid_ver, gmdid_rel, gmdid_step);
880f005ef32Sjsg
881f005ef32Sjsg if (has_no_display(pdev)) {
882f005ef32Sjsg drm_dbg_kms(&i915->drm, "Device doesn't have display\n");
883f005ef32Sjsg return &no_display;
884f005ef32Sjsg }
885f005ef32Sjsg
886f005ef32Sjsg for (i = 0; i < ARRAY_SIZE(intel_display_ids); i++) {
887f005ef32Sjsg if (intel_display_ids[i].devid == pdev->device)
888f005ef32Sjsg return intel_display_ids[i].info;
889f005ef32Sjsg }
890f005ef32Sjsg
891f005ef32Sjsg drm_dbg(&i915->drm, "No display ID found for device ID %04x; disabling display.\n",
892f005ef32Sjsg pdev->device);
893f005ef32Sjsg
894f005ef32Sjsg return &no_display;
895f005ef32Sjsg }
896f005ef32Sjsg
intel_display_device_info_runtime_init(struct drm_i915_private * i915)897f005ef32Sjsg void intel_display_device_info_runtime_init(struct drm_i915_private *i915)
898f005ef32Sjsg {
899f005ef32Sjsg struct intel_display_runtime_info *display_runtime = DISPLAY_RUNTIME_INFO(i915);
900f005ef32Sjsg enum pipe pipe;
901f005ef32Sjsg
902f005ef32Sjsg BUILD_BUG_ON(BITS_PER_TYPE(display_runtime->pipe_mask) < I915_MAX_PIPES);
903f005ef32Sjsg BUILD_BUG_ON(BITS_PER_TYPE(display_runtime->cpu_transcoder_mask) < I915_MAX_TRANSCODERS);
904f005ef32Sjsg BUILD_BUG_ON(BITS_PER_TYPE(display_runtime->port_mask) < I915_MAX_PORTS);
905f005ef32Sjsg
906f005ef32Sjsg /* Wa_14011765242: adl-s A0,A1 */
907f005ef32Sjsg if (IS_ALDERLAKE_S(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_A2))
908f005ef32Sjsg for_each_pipe(i915, pipe)
909f005ef32Sjsg display_runtime->num_scalers[pipe] = 0;
910f005ef32Sjsg else if (DISPLAY_VER(i915) >= 11) {
911f005ef32Sjsg for_each_pipe(i915, pipe)
912f005ef32Sjsg display_runtime->num_scalers[pipe] = 2;
913f005ef32Sjsg } else if (DISPLAY_VER(i915) >= 9) {
914f005ef32Sjsg display_runtime->num_scalers[PIPE_A] = 2;
915f005ef32Sjsg display_runtime->num_scalers[PIPE_B] = 2;
916f005ef32Sjsg display_runtime->num_scalers[PIPE_C] = 1;
917f005ef32Sjsg }
918f005ef32Sjsg
919f005ef32Sjsg if (DISPLAY_VER(i915) >= 13 || HAS_D12_PLANE_MINIMIZATION(i915))
920f005ef32Sjsg for_each_pipe(i915, pipe)
921f005ef32Sjsg display_runtime->num_sprites[pipe] = 4;
922f005ef32Sjsg else if (DISPLAY_VER(i915) >= 11)
923f005ef32Sjsg for_each_pipe(i915, pipe)
924f005ef32Sjsg display_runtime->num_sprites[pipe] = 6;
925f005ef32Sjsg else if (DISPLAY_VER(i915) == 10)
926f005ef32Sjsg for_each_pipe(i915, pipe)
927f005ef32Sjsg display_runtime->num_sprites[pipe] = 3;
928f005ef32Sjsg else if (IS_BROXTON(i915)) {
929f005ef32Sjsg /*
930f005ef32Sjsg * Skylake and Broxton currently don't expose the topmost plane as its
931f005ef32Sjsg * use is exclusive with the legacy cursor and we only want to expose
932f005ef32Sjsg * one of those, not both. Until we can safely expose the topmost plane
933f005ef32Sjsg * as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported,
934f005ef32Sjsg * we don't expose the topmost plane at all to prevent ABI breakage
935f005ef32Sjsg * down the line.
936f005ef32Sjsg */
937f005ef32Sjsg
938f005ef32Sjsg display_runtime->num_sprites[PIPE_A] = 2;
939f005ef32Sjsg display_runtime->num_sprites[PIPE_B] = 2;
940f005ef32Sjsg display_runtime->num_sprites[PIPE_C] = 1;
941f005ef32Sjsg } else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
942f005ef32Sjsg for_each_pipe(i915, pipe)
943f005ef32Sjsg display_runtime->num_sprites[pipe] = 2;
944f005ef32Sjsg } else if (DISPLAY_VER(i915) >= 5 || IS_G4X(i915)) {
945f005ef32Sjsg for_each_pipe(i915, pipe)
946f005ef32Sjsg display_runtime->num_sprites[pipe] = 1;
947f005ef32Sjsg }
948f005ef32Sjsg
949f005ef32Sjsg if ((IS_DGFX(i915) || DISPLAY_VER(i915) >= 14) &&
950f005ef32Sjsg !(intel_de_read(i915, GU_CNTL_PROTECTED) & DEPRESENT)) {
951f005ef32Sjsg drm_info(&i915->drm, "Display not present, disabling\n");
952f005ef32Sjsg goto display_fused_off;
953f005ef32Sjsg }
954f005ef32Sjsg
955f005ef32Sjsg if (IS_GRAPHICS_VER(i915, 7, 8) && HAS_PCH_SPLIT(i915)) {
956f005ef32Sjsg u32 fuse_strap = intel_de_read(i915, FUSE_STRAP);
957f005ef32Sjsg u32 sfuse_strap = intel_de_read(i915, SFUSE_STRAP);
958f005ef32Sjsg
959f005ef32Sjsg /*
960f005ef32Sjsg * SFUSE_STRAP is supposed to have a bit signalling the display
961f005ef32Sjsg * is fused off. Unfortunately it seems that, at least in
962f005ef32Sjsg * certain cases, fused off display means that PCH display
963f005ef32Sjsg * reads don't land anywhere. In that case, we read 0s.
964f005ef32Sjsg *
965f005ef32Sjsg * On CPT/PPT, we can detect this case as SFUSE_STRAP_FUSE_LOCK
966f005ef32Sjsg * should be set when taking over after the firmware.
967f005ef32Sjsg */
968f005ef32Sjsg if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE ||
969f005ef32Sjsg sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED ||
970f005ef32Sjsg (HAS_PCH_CPT(i915) &&
971f005ef32Sjsg !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) {
972f005ef32Sjsg drm_info(&i915->drm,
973f005ef32Sjsg "Display fused off, disabling\n");
974f005ef32Sjsg goto display_fused_off;
975f005ef32Sjsg } else if (fuse_strap & IVB_PIPE_C_DISABLE) {
976f005ef32Sjsg drm_info(&i915->drm, "PipeC fused off\n");
977f005ef32Sjsg display_runtime->pipe_mask &= ~BIT(PIPE_C);
978f005ef32Sjsg display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_C);
979f005ef32Sjsg }
980f005ef32Sjsg } else if (DISPLAY_VER(i915) >= 9) {
981f005ef32Sjsg u32 dfsm = intel_de_read(i915, SKL_DFSM);
982f005ef32Sjsg
983f005ef32Sjsg if (dfsm & SKL_DFSM_PIPE_A_DISABLE) {
984f005ef32Sjsg display_runtime->pipe_mask &= ~BIT(PIPE_A);
985f005ef32Sjsg display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_A);
986f005ef32Sjsg display_runtime->fbc_mask &= ~BIT(INTEL_FBC_A);
987f005ef32Sjsg }
988f005ef32Sjsg if (dfsm & SKL_DFSM_PIPE_B_DISABLE) {
989f005ef32Sjsg display_runtime->pipe_mask &= ~BIT(PIPE_B);
990f005ef32Sjsg display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_B);
991f005ef32Sjsg }
992f005ef32Sjsg if (dfsm & SKL_DFSM_PIPE_C_DISABLE) {
993f005ef32Sjsg display_runtime->pipe_mask &= ~BIT(PIPE_C);
994f005ef32Sjsg display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_C);
995f005ef32Sjsg }
996f005ef32Sjsg
997f005ef32Sjsg if (DISPLAY_VER(i915) >= 12 &&
998f005ef32Sjsg (dfsm & TGL_DFSM_PIPE_D_DISABLE)) {
999f005ef32Sjsg display_runtime->pipe_mask &= ~BIT(PIPE_D);
1000f005ef32Sjsg display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_D);
1001f005ef32Sjsg }
1002f005ef32Sjsg
1003f005ef32Sjsg if (!display_runtime->pipe_mask)
1004f005ef32Sjsg goto display_fused_off;
1005f005ef32Sjsg
1006f005ef32Sjsg if (dfsm & SKL_DFSM_DISPLAY_HDCP_DISABLE)
1007f005ef32Sjsg display_runtime->has_hdcp = 0;
1008f005ef32Sjsg
1009f005ef32Sjsg if (dfsm & SKL_DFSM_DISPLAY_PM_DISABLE)
1010f005ef32Sjsg display_runtime->fbc_mask = 0;
1011f005ef32Sjsg
1012f005ef32Sjsg if (DISPLAY_VER(i915) >= 11 && (dfsm & ICL_DFSM_DMC_DISABLE))
1013f005ef32Sjsg display_runtime->has_dmc = 0;
1014f005ef32Sjsg
1015f005ef32Sjsg if (IS_DISPLAY_VER(i915, 10, 12) &&
1016f005ef32Sjsg (dfsm & GLK_DFSM_DISPLAY_DSC_DISABLE))
1017f005ef32Sjsg display_runtime->has_dsc = 0;
1018f005ef32Sjsg }
1019f005ef32Sjsg
1020f005ef32Sjsg return;
1021f005ef32Sjsg
1022f005ef32Sjsg display_fused_off:
1023f005ef32Sjsg memset(display_runtime, 0, sizeof(*display_runtime));
1024f005ef32Sjsg }
1025f005ef32Sjsg
intel_display_device_info_print(const struct intel_display_device_info * info,const struct intel_display_runtime_info * runtime,struct drm_printer * p)1026f005ef32Sjsg void intel_display_device_info_print(const struct intel_display_device_info *info,
1027f005ef32Sjsg const struct intel_display_runtime_info *runtime,
1028f005ef32Sjsg struct drm_printer *p)
1029f005ef32Sjsg {
1030f005ef32Sjsg if (runtime->ip.rel)
1031f005ef32Sjsg drm_printf(p, "display version: %u.%02u\n",
1032f005ef32Sjsg runtime->ip.ver,
1033f005ef32Sjsg runtime->ip.rel);
1034f005ef32Sjsg else
1035f005ef32Sjsg drm_printf(p, "display version: %u\n",
1036f005ef32Sjsg runtime->ip.ver);
1037f005ef32Sjsg
1038f005ef32Sjsg #define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, str_yes_no(info->name))
1039f005ef32Sjsg DEV_INFO_DISPLAY_FOR_EACH_FLAG(PRINT_FLAG);
1040f005ef32Sjsg #undef PRINT_FLAG
1041f005ef32Sjsg
1042f005ef32Sjsg drm_printf(p, "has_hdcp: %s\n", str_yes_no(runtime->has_hdcp));
1043f005ef32Sjsg drm_printf(p, "has_dmc: %s\n", str_yes_no(runtime->has_dmc));
1044f005ef32Sjsg drm_printf(p, "has_dsc: %s\n", str_yes_no(runtime->has_dsc));
1045f005ef32Sjsg }
1046