File: | dev/pci/drm/i915/display/intel_hdmi.c |
Warning: | line 568, column 2 Value stored to 'val' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright 2006 Dave Airlie <airlied@linux.ie> |
3 | * Copyright © 2006-2009 Intel Corporation |
4 | * |
5 | * Permission is hereby granted, free of charge, to any person obtaining a |
6 | * copy of this software and associated documentation files (the "Software"), |
7 | * to deal in the Software without restriction, including without limitation |
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
9 | * and/or sell copies of the Software, and to permit persons to whom the |
10 | * Software is furnished to do so, subject to the following conditions: |
11 | * |
12 | * The above copyright notice and this permission notice (including the next |
13 | * paragraph) shall be included in all copies or substantial portions of the |
14 | * Software. |
15 | * |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
22 | * DEALINGS IN THE SOFTWARE. |
23 | * |
24 | * Authors: |
25 | * Eric Anholt <eric@anholt.net> |
26 | * Jesse Barnes <jesse.barnes@intel.com> |
27 | */ |
28 | |
29 | #include <linux/delay.h> |
30 | #include <linux/hdmi.h> |
31 | #include <linux/i2c.h> |
32 | #include <linux/slab.h> |
33 | |
34 | #include <drm/drm_atomic_helper.h> |
35 | #include <drm/drm_crtc.h> |
36 | #include <drm/drm_edid.h> |
37 | #include <drm/drm_hdcp.h> |
38 | #include <drm/drm_scdc_helper.h> |
39 | #include <drm/intel_lpe_audio.h> |
40 | |
41 | #include "i915_debugfs.h" |
42 | #include "i915_drv.h" |
43 | #include "intel_atomic.h" |
44 | #include "intel_audio.h" |
45 | #include "intel_connector.h" |
46 | #include "intel_ddi.h" |
47 | #include "intel_display_types.h" |
48 | #include "intel_dp.h" |
49 | #include "intel_dpio_phy.h" |
50 | #include "intel_fifo_underrun.h" |
51 | #include "intel_gmbus.h" |
52 | #include "intel_hdcp.h" |
53 | #include "intel_hdmi.h" |
54 | #include "intel_hotplug.h" |
55 | #include "intel_lspcon.h" |
56 | #include "intel_panel.h" |
57 | #include "intel_sdvo.h" |
58 | #include "intel_sideband.h" |
59 | |
60 | static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi) |
61 | { |
62 | return hdmi_to_dig_port(intel_hdmi)->base.base.dev; |
63 | } |
64 | |
65 | static void |
66 | assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi) |
67 | { |
68 | struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi); |
69 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev); |
70 | u32 enabled_bits; |
71 | |
72 | enabled_bits = HAS_DDI(dev_priv)((&(dev_priv)->__info)->display.has_ddi) ? DDI_BUF_CTL_ENABLE(1 << 31) : SDVO_ENABLE(1 << 31); |
73 | |
74 | drm_WARN(dev,({ int __ret = !!(intel_de_read(dev_priv, intel_hdmi->hdmi_reg ) & enabled_bits); if (__ret) printf("%s %s: " "HDMI port enabled, expecting disabled\n" , dev_driver_string((dev)->dev), ""); __builtin_expect(!!( __ret), 0); }) |
75 | intel_de_read(dev_priv, intel_hdmi->hdmi_reg) & enabled_bits,({ int __ret = !!(intel_de_read(dev_priv, intel_hdmi->hdmi_reg ) & enabled_bits); if (__ret) printf("%s %s: " "HDMI port enabled, expecting disabled\n" , dev_driver_string((dev)->dev), ""); __builtin_expect(!!( __ret), 0); }) |
76 | "HDMI port enabled, expecting disabled\n")({ int __ret = !!(intel_de_read(dev_priv, intel_hdmi->hdmi_reg ) & enabled_bits); if (__ret) printf("%s %s: " "HDMI port enabled, expecting disabled\n" , dev_driver_string((dev)->dev), ""); __builtin_expect(!!( __ret), 0); }); |
77 | } |
78 | |
79 | static void |
80 | assert_hdmi_transcoder_func_disabled(struct drm_i915_privateinteldrm_softc *dev_priv, |
81 | enum transcoder cpu_transcoder) |
82 | { |
83 | drm_WARN(&dev_priv->drm,({ int __ret = !!(intel_de_read(dev_priv, ((const i915_reg_t) { .reg = (((&(dev_priv)->__info)->trans_offsets[(cpu_transcoder )] - (&(dev_priv)->__info)->trans_offsets[TRANSCODER_A ] + (0x60400) + ((&(dev_priv)->__info)->display_mmio_offset ))) })) & (1 << 31)); if (__ret) printf("%s %s: " "HDMI transcoder function enabled, expecting disabled\n" , dev_driver_string((&dev_priv->drm)->dev), ""); __builtin_expect (!!(__ret), 0); }) |
84 | intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)) &({ int __ret = !!(intel_de_read(dev_priv, ((const i915_reg_t) { .reg = (((&(dev_priv)->__info)->trans_offsets[(cpu_transcoder )] - (&(dev_priv)->__info)->trans_offsets[TRANSCODER_A ] + (0x60400) + ((&(dev_priv)->__info)->display_mmio_offset ))) })) & (1 << 31)); if (__ret) printf("%s %s: " "HDMI transcoder function enabled, expecting disabled\n" , dev_driver_string((&dev_priv->drm)->dev), ""); __builtin_expect (!!(__ret), 0); }) |
85 | TRANS_DDI_FUNC_ENABLE,({ int __ret = !!(intel_de_read(dev_priv, ((const i915_reg_t) { .reg = (((&(dev_priv)->__info)->trans_offsets[(cpu_transcoder )] - (&(dev_priv)->__info)->trans_offsets[TRANSCODER_A ] + (0x60400) + ((&(dev_priv)->__info)->display_mmio_offset ))) })) & (1 << 31)); if (__ret) printf("%s %s: " "HDMI transcoder function enabled, expecting disabled\n" , dev_driver_string((&dev_priv->drm)->dev), ""); __builtin_expect (!!(__ret), 0); }) |
86 | "HDMI transcoder function enabled, expecting disabled\n")({ int __ret = !!(intel_de_read(dev_priv, ((const i915_reg_t) { .reg = (((&(dev_priv)->__info)->trans_offsets[(cpu_transcoder )] - (&(dev_priv)->__info)->trans_offsets[TRANSCODER_A ] + (0x60400) + ((&(dev_priv)->__info)->display_mmio_offset ))) })) & (1 << 31)); if (__ret) printf("%s %s: " "HDMI transcoder function enabled, expecting disabled\n" , dev_driver_string((&dev_priv->drm)->dev), ""); __builtin_expect (!!(__ret), 0); }); |
87 | } |
88 | |
89 | struct intel_hdmi *enc_to_intel_hdmi(struct intel_encoder *encoder) |
90 | { |
91 | struct intel_digital_port *dig_port = |
92 | container_of(&encoder->base, struct intel_digital_port,({ const __typeof( ((struct intel_digital_port *)0)->base. base ) *__mptr = (&encoder->base); (struct intel_digital_port *)( (char *)__mptr - __builtin_offsetof(struct intel_digital_port , base.base) );}) |
93 | base.base)({ const __typeof( ((struct intel_digital_port *)0)->base. base ) *__mptr = (&encoder->base); (struct intel_digital_port *)( (char *)__mptr - __builtin_offsetof(struct intel_digital_port , base.base) );}); |
94 | return &dig_port->hdmi; |
95 | } |
96 | |
97 | static struct intel_hdmi *intel_attached_hdmi(struct intel_connector *connector) |
98 | { |
99 | return enc_to_intel_hdmi(intel_attached_encoder(connector)); |
100 | } |
101 | |
102 | static u32 g4x_infoframe_index(unsigned int type) |
103 | { |
104 | switch (type) { |
105 | case HDMI_PACKET_TYPE_GAMUT_METADATA: |
106 | return VIDEO_DIP_SELECT_GAMUT(2 << 19); |
107 | case HDMI_INFOFRAME_TYPE_AVI: |
108 | return VIDEO_DIP_SELECT_AVI(0 << 19); |
109 | case HDMI_INFOFRAME_TYPE_SPD: |
110 | return VIDEO_DIP_SELECT_SPD(3 << 19); |
111 | case HDMI_INFOFRAME_TYPE_VENDOR: |
112 | return VIDEO_DIP_SELECT_VENDOR(1 << 19); |
113 | default: |
114 | MISSING_CASE(type)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "type", (long)(type)); __builtin_expect(!!(__ret), 0); }); |
115 | return 0; |
116 | } |
117 | } |
118 | |
119 | static u32 g4x_infoframe_enable(unsigned int type) |
120 | { |
121 | switch (type) { |
122 | case HDMI_PACKET_TYPE_GENERAL_CONTROL: |
123 | return VIDEO_DIP_ENABLE_GCP(1 << 25); |
124 | case HDMI_PACKET_TYPE_GAMUT_METADATA: |
125 | return VIDEO_DIP_ENABLE_GAMUT(4 << 21); |
126 | case DP_SDP_VSC0x07: |
127 | return 0; |
128 | case HDMI_INFOFRAME_TYPE_AVI: |
129 | return VIDEO_DIP_ENABLE_AVI(1 << 21); |
130 | case HDMI_INFOFRAME_TYPE_SPD: |
131 | return VIDEO_DIP_ENABLE_SPD(8 << 21); |
132 | case HDMI_INFOFRAME_TYPE_VENDOR: |
133 | return VIDEO_DIP_ENABLE_VENDOR(2 << 21); |
134 | case HDMI_INFOFRAME_TYPE_DRM: |
135 | return 0; |
136 | default: |
137 | MISSING_CASE(type)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "type", (long)(type)); __builtin_expect(!!(__ret), 0); }); |
138 | return 0; |
139 | } |
140 | } |
141 | |
142 | static u32 hsw_infoframe_enable(unsigned int type) |
143 | { |
144 | switch (type) { |
145 | case HDMI_PACKET_TYPE_GENERAL_CONTROL: |
146 | return VIDEO_DIP_ENABLE_GCP_HSW(1 << 16); |
147 | case HDMI_PACKET_TYPE_GAMUT_METADATA: |
148 | return VIDEO_DIP_ENABLE_GMP_HSW(1 << 4); |
149 | case DP_SDP_VSC0x07: |
150 | return VIDEO_DIP_ENABLE_VSC_HSW(1 << 20); |
151 | case DP_SDP_PPS0x10: |
152 | return VDIP_ENABLE_PPS(1 << 24); |
153 | case HDMI_INFOFRAME_TYPE_AVI: |
154 | return VIDEO_DIP_ENABLE_AVI_HSW(1 << 12); |
155 | case HDMI_INFOFRAME_TYPE_SPD: |
156 | return VIDEO_DIP_ENABLE_SPD_HSW(1 << 0); |
157 | case HDMI_INFOFRAME_TYPE_VENDOR: |
158 | return VIDEO_DIP_ENABLE_VS_HSW(1 << 8); |
159 | case HDMI_INFOFRAME_TYPE_DRM: |
160 | return VIDEO_DIP_ENABLE_DRM_GLK(1 << 28); |
161 | default: |
162 | MISSING_CASE(type)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "type", (long)(type)); __builtin_expect(!!(__ret), 0); }); |
163 | return 0; |
164 | } |
165 | } |
166 | |
167 | static i915_reg_t |
168 | hsw_dip_data_reg(struct drm_i915_privateinteldrm_softc *dev_priv, |
169 | enum transcoder cpu_transcoder, |
170 | unsigned int type, |
171 | int i) |
172 | { |
173 | switch (type) { |
174 | case HDMI_PACKET_TYPE_GAMUT_METADATA: |
175 | return HSW_TVIDEO_DIP_GMP_DATA(cpu_transcoder, i)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(cpu_transcoder)] - (&(dev_priv)->__info )->trans_offsets[TRANSCODER_A] + (0x602E0 + (i) * 4) + ((& (dev_priv)->__info)->display_mmio_offset))) }); |
176 | case DP_SDP_VSC0x07: |
177 | return HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder, i)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(cpu_transcoder)] - (&(dev_priv)->__info )->trans_offsets[TRANSCODER_A] + (0x60320 + (i) * 4) + ((& (dev_priv)->__info)->display_mmio_offset))) }); |
178 | case DP_SDP_PPS0x10: |
179 | return ICL_VIDEO_DIP_PPS_DATA(cpu_transcoder, i)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(cpu_transcoder)] - (&(dev_priv)->__info )->trans_offsets[TRANSCODER_A] + (0x60350 + (i) * 4) + ((& (dev_priv)->__info)->display_mmio_offset))) }); |
180 | case HDMI_INFOFRAME_TYPE_AVI: |
181 | return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder, i)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(cpu_transcoder)] - (&(dev_priv)->__info )->trans_offsets[TRANSCODER_A] + (0x60220 + (i) * 4) + ((& (dev_priv)->__info)->display_mmio_offset))) }); |
182 | case HDMI_INFOFRAME_TYPE_SPD: |
183 | return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder, i)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(cpu_transcoder)] - (&(dev_priv)->__info )->trans_offsets[TRANSCODER_A] + (0x602A0 + (i) * 4) + ((& (dev_priv)->__info)->display_mmio_offset))) }); |
184 | case HDMI_INFOFRAME_TYPE_VENDOR: |
185 | return HSW_TVIDEO_DIP_VS_DATA(cpu_transcoder, i)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(cpu_transcoder)] - (&(dev_priv)->__info )->trans_offsets[TRANSCODER_A] + (0x60260 + (i) * 4) + ((& (dev_priv)->__info)->display_mmio_offset))) }); |
186 | case HDMI_INFOFRAME_TYPE_DRM: |
187 | return GLK_TVIDEO_DIP_DRM_DATA(cpu_transcoder, i)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(cpu_transcoder)] - (&(dev_priv)->__info )->trans_offsets[TRANSCODER_A] + (0x60440 + (i) * 4) + ((& (dev_priv)->__info)->display_mmio_offset))) }); |
188 | default: |
189 | MISSING_CASE(type)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "type", (long)(type)); __builtin_expect(!!(__ret), 0); }); |
190 | return INVALID_MMIO_REG((const i915_reg_t){ .reg = (0) }); |
191 | } |
192 | } |
193 | |
194 | static int hsw_dip_data_size(struct drm_i915_privateinteldrm_softc *dev_priv, |
195 | unsigned int type) |
196 | { |
197 | switch (type) { |
198 | case DP_SDP_VSC0x07: |
199 | return VIDEO_DIP_VSC_DATA_SIZE36; |
200 | case DP_SDP_PPS0x10: |
201 | return VIDEO_DIP_PPS_DATA_SIZE132; |
202 | case HDMI_PACKET_TYPE_GAMUT_METADATA: |
203 | if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 11) |
204 | return VIDEO_DIP_GMP_DATA_SIZE36; |
205 | else |
206 | return VIDEO_DIP_DATA_SIZE32; |
207 | default: |
208 | return VIDEO_DIP_DATA_SIZE32; |
209 | } |
210 | } |
211 | |
212 | static void g4x_write_infoframe(struct intel_encoder *encoder, |
213 | const struct intel_crtc_state *crtc_state, |
214 | unsigned int type, |
215 | const void *frame, ssize_t len) |
216 | { |
217 | const u32 *data = frame; |
218 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
219 | u32 val = intel_de_read(dev_priv, VIDEO_DIP_CTL((const i915_reg_t){ .reg = (0x61170) })); |
220 | int i; |
221 | |
222 | drm_WARN(&dev_priv->drm, !(val & VIDEO_DIP_ENABLE),({ int __ret = !!(!(val & (1 << 31))); if (__ret) printf ("%s %s: " "Writing DIP with CTL reg disabled\n", dev_driver_string ((&dev_priv->drm)->dev), ""); __builtin_expect(!!(__ret ), 0); }) |
223 | "Writing DIP with CTL reg disabled\n")({ int __ret = !!(!(val & (1 << 31))); if (__ret) printf ("%s %s: " "Writing DIP with CTL reg disabled\n", dev_driver_string ((&dev_priv->drm)->dev), ""); __builtin_expect(!!(__ret ), 0); }); |
224 | |
225 | val &= ~(VIDEO_DIP_SELECT_MASK(3 << 19) | 0xf); /* clear DIP data offset */ |
226 | val |= g4x_infoframe_index(type); |
227 | |
228 | val &= ~g4x_infoframe_enable(type); |
229 | |
230 | intel_de_write(dev_priv, VIDEO_DIP_CTL((const i915_reg_t){ .reg = (0x61170) }), val); |
231 | |
232 | for (i = 0; i < len; i += 4) { |
233 | intel_de_write(dev_priv, VIDEO_DIP_DATA((const i915_reg_t){ .reg = (0x61178) }), *data); |
234 | data++; |
235 | } |
236 | /* Write every possible data byte to force correct ECC calculation. */ |
237 | for (; i < VIDEO_DIP_DATA_SIZE32; i += 4) |
238 | intel_de_write(dev_priv, VIDEO_DIP_DATA((const i915_reg_t){ .reg = (0x61178) }), 0); |
239 | |
240 | val |= g4x_infoframe_enable(type); |
241 | val &= ~VIDEO_DIP_FREQ_MASK(3 << 16); |
242 | val |= VIDEO_DIP_FREQ_VSYNC(1 << 16); |
243 | |
244 | intel_de_write(dev_priv, VIDEO_DIP_CTL((const i915_reg_t){ .reg = (0x61170) }), val); |
245 | intel_de_posting_read(dev_priv, VIDEO_DIP_CTL((const i915_reg_t){ .reg = (0x61170) })); |
246 | } |
247 | |
248 | static void g4x_read_infoframe(struct intel_encoder *encoder, |
249 | const struct intel_crtc_state *crtc_state, |
250 | unsigned int type, |
251 | void *frame, ssize_t len) |
252 | { |
253 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
254 | u32 val, *data = frame; |
255 | int i; |
256 | |
257 | val = intel_de_read(dev_priv, VIDEO_DIP_CTL((const i915_reg_t){ .reg = (0x61170) })); |
258 | |
259 | val &= ~(VIDEO_DIP_SELECT_MASK(3 << 19) | 0xf); /* clear DIP data offset */ |
260 | val |= g4x_infoframe_index(type); |
261 | |
262 | intel_de_write(dev_priv, VIDEO_DIP_CTL((const i915_reg_t){ .reg = (0x61170) }), val); |
263 | |
264 | for (i = 0; i < len; i += 4) |
265 | *data++ = intel_de_read(dev_priv, VIDEO_DIP_DATA((const i915_reg_t){ .reg = (0x61178) })); |
266 | } |
267 | |
268 | static u32 g4x_infoframes_enabled(struct intel_encoder *encoder, |
269 | const struct intel_crtc_state *pipe_config) |
270 | { |
271 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
272 | u32 val = intel_de_read(dev_priv, VIDEO_DIP_CTL((const i915_reg_t){ .reg = (0x61170) })); |
273 | |
274 | if ((val & VIDEO_DIP_ENABLE(1 << 31)) == 0) |
275 | return 0; |
276 | |
277 | if ((val & VIDEO_DIP_PORT_MASK(3 << 29)) != VIDEO_DIP_PORT(encoder->port)((encoder->port) << 29)) |
278 | return 0; |
279 | |
280 | return val & (VIDEO_DIP_ENABLE_AVI(1 << 21) | |
281 | VIDEO_DIP_ENABLE_VENDOR(2 << 21) | VIDEO_DIP_ENABLE_SPD(8 << 21)); |
282 | } |
283 | |
284 | static void ibx_write_infoframe(struct intel_encoder *encoder, |
285 | const struct intel_crtc_state *crtc_state, |
286 | unsigned int type, |
287 | const void *frame, ssize_t len) |
288 | { |
289 | const u32 *data = frame; |
290 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
291 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
292 | i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe)((const i915_reg_t){ .reg = (((0xe0200) + (intel_crtc->pipe ) * ((0xe1200) - (0xe0200)))) }); |
293 | u32 val = intel_de_read(dev_priv, reg); |
294 | int i; |
295 | |
296 | drm_WARN(&dev_priv->drm, !(val & VIDEO_DIP_ENABLE),({ int __ret = !!(!(val & (1 << 31))); if (__ret) printf ("%s %s: " "Writing DIP with CTL reg disabled\n", dev_driver_string ((&dev_priv->drm)->dev), ""); __builtin_expect(!!(__ret ), 0); }) |
297 | "Writing DIP with CTL reg disabled\n")({ int __ret = !!(!(val & (1 << 31))); if (__ret) printf ("%s %s: " "Writing DIP with CTL reg disabled\n", dev_driver_string ((&dev_priv->drm)->dev), ""); __builtin_expect(!!(__ret ), 0); }); |
298 | |
299 | val &= ~(VIDEO_DIP_SELECT_MASK(3 << 19) | 0xf); /* clear DIP data offset */ |
300 | val |= g4x_infoframe_index(type); |
301 | |
302 | val &= ~g4x_infoframe_enable(type); |
303 | |
304 | intel_de_write(dev_priv, reg, val); |
305 | |
306 | for (i = 0; i < len; i += 4) { |
307 | intel_de_write(dev_priv, TVIDEO_DIP_DATA(intel_crtc->pipe)((const i915_reg_t){ .reg = (((0xe0208) + (intel_crtc->pipe ) * ((0xe1208) - (0xe0208)))) }), |
308 | *data); |
309 | data++; |
310 | } |
311 | /* Write every possible data byte to force correct ECC calculation. */ |
312 | for (; i < VIDEO_DIP_DATA_SIZE32; i += 4) |
313 | intel_de_write(dev_priv, TVIDEO_DIP_DATA(intel_crtc->pipe)((const i915_reg_t){ .reg = (((0xe0208) + (intel_crtc->pipe ) * ((0xe1208) - (0xe0208)))) }), 0); |
314 | |
315 | val |= g4x_infoframe_enable(type); |
316 | val &= ~VIDEO_DIP_FREQ_MASK(3 << 16); |
317 | val |= VIDEO_DIP_FREQ_VSYNC(1 << 16); |
318 | |
319 | intel_de_write(dev_priv, reg, val); |
320 | intel_de_posting_read(dev_priv, reg); |
321 | } |
322 | |
323 | static void ibx_read_infoframe(struct intel_encoder *encoder, |
324 | const struct intel_crtc_state *crtc_state, |
325 | unsigned int type, |
326 | void *frame, ssize_t len) |
327 | { |
328 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
329 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
330 | u32 val, *data = frame; |
331 | int i; |
332 | |
333 | val = intel_de_read(dev_priv, TVIDEO_DIP_CTL(crtc->pipe)((const i915_reg_t){ .reg = (((0xe0200) + (crtc->pipe) * ( (0xe1200) - (0xe0200)))) })); |
334 | |
335 | val &= ~(VIDEO_DIP_SELECT_MASK(3 << 19) | 0xf); /* clear DIP data offset */ |
336 | val |= g4x_infoframe_index(type); |
337 | |
338 | intel_de_write(dev_priv, TVIDEO_DIP_CTL(crtc->pipe)((const i915_reg_t){ .reg = (((0xe0200) + (crtc->pipe) * ( (0xe1200) - (0xe0200)))) }), val); |
339 | |
340 | for (i = 0; i < len; i += 4) |
341 | *data++ = intel_de_read(dev_priv, TVIDEO_DIP_DATA(crtc->pipe)((const i915_reg_t){ .reg = (((0xe0208) + (crtc->pipe) * ( (0xe1208) - (0xe0208)))) })); |
342 | } |
343 | |
344 | static u32 ibx_infoframes_enabled(struct intel_encoder *encoder, |
345 | const struct intel_crtc_state *pipe_config) |
346 | { |
347 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
348 | enum pipe pipe = to_intel_crtc(pipe_config->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (pipe_config->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );})->pipe; |
349 | i915_reg_t reg = TVIDEO_DIP_CTL(pipe)((const i915_reg_t){ .reg = (((0xe0200) + (pipe) * ((0xe1200) - (0xe0200)))) }); |
350 | u32 val = intel_de_read(dev_priv, reg); |
351 | |
352 | if ((val & VIDEO_DIP_ENABLE(1 << 31)) == 0) |
353 | return 0; |
354 | |
355 | if ((val & VIDEO_DIP_PORT_MASK(3 << 29)) != VIDEO_DIP_PORT(encoder->port)((encoder->port) << 29)) |
356 | return 0; |
357 | |
358 | return val & (VIDEO_DIP_ENABLE_AVI(1 << 21) | |
359 | VIDEO_DIP_ENABLE_VENDOR(2 << 21) | VIDEO_DIP_ENABLE_GAMUT(4 << 21) | |
360 | VIDEO_DIP_ENABLE_SPD(8 << 21) | VIDEO_DIP_ENABLE_GCP(1 << 25)); |
361 | } |
362 | |
363 | static void cpt_write_infoframe(struct intel_encoder *encoder, |
364 | const struct intel_crtc_state *crtc_state, |
365 | unsigned int type, |
366 | const void *frame, ssize_t len) |
367 | { |
368 | const u32 *data = frame; |
369 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
370 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
371 | i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe)((const i915_reg_t){ .reg = (((0xe0200) + (intel_crtc->pipe ) * ((0xe1200) - (0xe0200)))) }); |
372 | u32 val = intel_de_read(dev_priv, reg); |
373 | int i; |
374 | |
375 | drm_WARN(&dev_priv->drm, !(val & VIDEO_DIP_ENABLE),({ int __ret = !!(!(val & (1 << 31))); if (__ret) printf ("%s %s: " "Writing DIP with CTL reg disabled\n", dev_driver_string ((&dev_priv->drm)->dev), ""); __builtin_expect(!!(__ret ), 0); }) |
376 | "Writing DIP with CTL reg disabled\n")({ int __ret = !!(!(val & (1 << 31))); if (__ret) printf ("%s %s: " "Writing DIP with CTL reg disabled\n", dev_driver_string ((&dev_priv->drm)->dev), ""); __builtin_expect(!!(__ret ), 0); }); |
377 | |
378 | val &= ~(VIDEO_DIP_SELECT_MASK(3 << 19) | 0xf); /* clear DIP data offset */ |
379 | val |= g4x_infoframe_index(type); |
380 | |
381 | /* The DIP control register spec says that we need to update the AVI |
382 | * infoframe without clearing its enable bit */ |
383 | if (type != HDMI_INFOFRAME_TYPE_AVI) |
384 | val &= ~g4x_infoframe_enable(type); |
385 | |
386 | intel_de_write(dev_priv, reg, val); |
387 | |
388 | for (i = 0; i < len; i += 4) { |
389 | intel_de_write(dev_priv, TVIDEO_DIP_DATA(intel_crtc->pipe)((const i915_reg_t){ .reg = (((0xe0208) + (intel_crtc->pipe ) * ((0xe1208) - (0xe0208)))) }), |
390 | *data); |
391 | data++; |
392 | } |
393 | /* Write every possible data byte to force correct ECC calculation. */ |
394 | for (; i < VIDEO_DIP_DATA_SIZE32; i += 4) |
395 | intel_de_write(dev_priv, TVIDEO_DIP_DATA(intel_crtc->pipe)((const i915_reg_t){ .reg = (((0xe0208) + (intel_crtc->pipe ) * ((0xe1208) - (0xe0208)))) }), 0); |
396 | |
397 | val |= g4x_infoframe_enable(type); |
398 | val &= ~VIDEO_DIP_FREQ_MASK(3 << 16); |
399 | val |= VIDEO_DIP_FREQ_VSYNC(1 << 16); |
400 | |
401 | intel_de_write(dev_priv, reg, val); |
402 | intel_de_posting_read(dev_priv, reg); |
403 | } |
404 | |
405 | static void cpt_read_infoframe(struct intel_encoder *encoder, |
406 | const struct intel_crtc_state *crtc_state, |
407 | unsigned int type, |
408 | void *frame, ssize_t len) |
409 | { |
410 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
411 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
412 | u32 val, *data = frame; |
413 | int i; |
414 | |
415 | val = intel_de_read(dev_priv, TVIDEO_DIP_CTL(crtc->pipe)((const i915_reg_t){ .reg = (((0xe0200) + (crtc->pipe) * ( (0xe1200) - (0xe0200)))) })); |
416 | |
417 | val &= ~(VIDEO_DIP_SELECT_MASK(3 << 19) | 0xf); /* clear DIP data offset */ |
418 | val |= g4x_infoframe_index(type); |
419 | |
420 | intel_de_write(dev_priv, TVIDEO_DIP_CTL(crtc->pipe)((const i915_reg_t){ .reg = (((0xe0200) + (crtc->pipe) * ( (0xe1200) - (0xe0200)))) }), val); |
421 | |
422 | for (i = 0; i < len; i += 4) |
423 | *data++ = intel_de_read(dev_priv, TVIDEO_DIP_DATA(crtc->pipe)((const i915_reg_t){ .reg = (((0xe0208) + (crtc->pipe) * ( (0xe1208) - (0xe0208)))) })); |
424 | } |
425 | |
426 | static u32 cpt_infoframes_enabled(struct intel_encoder *encoder, |
427 | const struct intel_crtc_state *pipe_config) |
428 | { |
429 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
430 | enum pipe pipe = to_intel_crtc(pipe_config->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (pipe_config->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );})->pipe; |
431 | u32 val = intel_de_read(dev_priv, TVIDEO_DIP_CTL(pipe)((const i915_reg_t){ .reg = (((0xe0200) + (pipe) * ((0xe1200) - (0xe0200)))) })); |
432 | |
433 | if ((val & VIDEO_DIP_ENABLE(1 << 31)) == 0) |
434 | return 0; |
435 | |
436 | return val & (VIDEO_DIP_ENABLE_AVI(1 << 21) | |
437 | VIDEO_DIP_ENABLE_VENDOR(2 << 21) | VIDEO_DIP_ENABLE_GAMUT(4 << 21) | |
438 | VIDEO_DIP_ENABLE_SPD(8 << 21) | VIDEO_DIP_ENABLE_GCP(1 << 25)); |
439 | } |
440 | |
441 | static void vlv_write_infoframe(struct intel_encoder *encoder, |
442 | const struct intel_crtc_state *crtc_state, |
443 | unsigned int type, |
444 | const void *frame, ssize_t len) |
445 | { |
446 | const u32 *data = frame; |
447 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
448 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
449 | i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe)((const i915_reg_t){ .reg = ((((const u32 []){ (0x180000 + 0x60200 ), (0x180000 + 0x61170), (0x180000 + 0x611f0) })[(intel_crtc-> pipe)])) }); |
450 | u32 val = intel_de_read(dev_priv, reg); |
451 | int i; |
452 | |
453 | drm_WARN(&dev_priv->drm, !(val & VIDEO_DIP_ENABLE),({ int __ret = !!(!(val & (1 << 31))); if (__ret) printf ("%s %s: " "Writing DIP with CTL reg disabled\n", dev_driver_string ((&dev_priv->drm)->dev), ""); __builtin_expect(!!(__ret ), 0); }) |
454 | "Writing DIP with CTL reg disabled\n")({ int __ret = !!(!(val & (1 << 31))); if (__ret) printf ("%s %s: " "Writing DIP with CTL reg disabled\n", dev_driver_string ((&dev_priv->drm)->dev), ""); __builtin_expect(!!(__ret ), 0); }); |
455 | |
456 | val &= ~(VIDEO_DIP_SELECT_MASK(3 << 19) | 0xf); /* clear DIP data offset */ |
457 | val |= g4x_infoframe_index(type); |
458 | |
459 | val &= ~g4x_infoframe_enable(type); |
460 | |
461 | intel_de_write(dev_priv, reg, val); |
462 | |
463 | for (i = 0; i < len; i += 4) { |
464 | intel_de_write(dev_priv, |
465 | VLV_TVIDEO_DIP_DATA(intel_crtc->pipe)((const i915_reg_t){ .reg = ((((const u32 []){ (0x180000 + 0x60208 ), (0x180000 + 0x61174), (0x180000 + 0x611f4) })[(intel_crtc-> pipe)])) }), *data); |
466 | data++; |
467 | } |
468 | /* Write every possible data byte to force correct ECC calculation. */ |
469 | for (; i < VIDEO_DIP_DATA_SIZE32; i += 4) |
470 | intel_de_write(dev_priv, |
471 | VLV_TVIDEO_DIP_DATA(intel_crtc->pipe)((const i915_reg_t){ .reg = ((((const u32 []){ (0x180000 + 0x60208 ), (0x180000 + 0x61174), (0x180000 + 0x611f4) })[(intel_crtc-> pipe)])) }), 0); |
472 | |
473 | val |= g4x_infoframe_enable(type); |
474 | val &= ~VIDEO_DIP_FREQ_MASK(3 << 16); |
475 | val |= VIDEO_DIP_FREQ_VSYNC(1 << 16); |
476 | |
477 | intel_de_write(dev_priv, reg, val); |
478 | intel_de_posting_read(dev_priv, reg); |
479 | } |
480 | |
481 | static void vlv_read_infoframe(struct intel_encoder *encoder, |
482 | const struct intel_crtc_state *crtc_state, |
483 | unsigned int type, |
484 | void *frame, ssize_t len) |
485 | { |
486 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
487 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
488 | u32 val, *data = frame; |
489 | int i; |
490 | |
491 | val = intel_de_read(dev_priv, VLV_TVIDEO_DIP_CTL(crtc->pipe)((const i915_reg_t){ .reg = ((((const u32 []){ (0x180000 + 0x60200 ), (0x180000 + 0x61170), (0x180000 + 0x611f0) })[(crtc->pipe )])) })); |
492 | |
493 | val &= ~(VIDEO_DIP_SELECT_MASK(3 << 19) | 0xf); /* clear DIP data offset */ |
494 | val |= g4x_infoframe_index(type); |
495 | |
496 | intel_de_write(dev_priv, VLV_TVIDEO_DIP_CTL(crtc->pipe)((const i915_reg_t){ .reg = ((((const u32 []){ (0x180000 + 0x60200 ), (0x180000 + 0x61170), (0x180000 + 0x611f0) })[(crtc->pipe )])) }), val); |
497 | |
498 | for (i = 0; i < len; i += 4) |
499 | *data++ = intel_de_read(dev_priv, |
500 | VLV_TVIDEO_DIP_DATA(crtc->pipe)((const i915_reg_t){ .reg = ((((const u32 []){ (0x180000 + 0x60208 ), (0x180000 + 0x61174), (0x180000 + 0x611f4) })[(crtc->pipe )])) })); |
501 | } |
502 | |
503 | static u32 vlv_infoframes_enabled(struct intel_encoder *encoder, |
504 | const struct intel_crtc_state *pipe_config) |
505 | { |
506 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
507 | enum pipe pipe = to_intel_crtc(pipe_config->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (pipe_config->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );})->pipe; |
508 | u32 val = intel_de_read(dev_priv, VLV_TVIDEO_DIP_CTL(pipe)((const i915_reg_t){ .reg = ((((const u32 []){ (0x180000 + 0x60200 ), (0x180000 + 0x61170), (0x180000 + 0x611f0) })[(pipe)])) })); |
509 | |
510 | if ((val & VIDEO_DIP_ENABLE(1 << 31)) == 0) |
511 | return 0; |
512 | |
513 | if ((val & VIDEO_DIP_PORT_MASK(3 << 29)) != VIDEO_DIP_PORT(encoder->port)((encoder->port) << 29)) |
514 | return 0; |
515 | |
516 | return val & (VIDEO_DIP_ENABLE_AVI(1 << 21) | |
517 | VIDEO_DIP_ENABLE_VENDOR(2 << 21) | VIDEO_DIP_ENABLE_GAMUT(4 << 21) | |
518 | VIDEO_DIP_ENABLE_SPD(8 << 21) | VIDEO_DIP_ENABLE_GCP(1 << 25)); |
519 | } |
520 | |
521 | static void hsw_write_infoframe(struct intel_encoder *encoder, |
522 | const struct intel_crtc_state *crtc_state, |
523 | unsigned int type, |
524 | const void *frame, ssize_t len) |
525 | { |
526 | const u32 *data = frame; |
527 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
528 | enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; |
529 | i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(cpu_transcoder)] - (&(dev_priv)->__info )->trans_offsets[TRANSCODER_A] + (0x60200) + ((&(dev_priv )->__info)->display_mmio_offset))) }); |
530 | int data_size; |
531 | int i; |
532 | u32 val = intel_de_read(dev_priv, ctl_reg); |
533 | |
534 | data_size = hsw_dip_data_size(dev_priv, type); |
535 | |
536 | drm_WARN_ON(&dev_priv->drm, len > data_size)({ int __ret = !!((len > data_size)); if (__ret) printf("%s %s: " "%s", dev_driver_string(((&dev_priv->drm))->dev), "" , "drm_WARN_ON(" "len > data_size" ")"); __builtin_expect( !!(__ret), 0); }); |
537 | |
538 | val &= ~hsw_infoframe_enable(type); |
539 | intel_de_write(dev_priv, ctl_reg, val); |
540 | |
541 | for (i = 0; i < len; i += 4) { |
542 | intel_de_write(dev_priv, |
543 | hsw_dip_data_reg(dev_priv, cpu_transcoder, type, i >> 2), |
544 | *data); |
545 | data++; |
546 | } |
547 | /* Write every possible data byte to force correct ECC calculation. */ |
548 | for (; i < data_size; i += 4) |
549 | intel_de_write(dev_priv, |
550 | hsw_dip_data_reg(dev_priv, cpu_transcoder, type, i >> 2), |
551 | 0); |
552 | |
553 | val |= hsw_infoframe_enable(type); |
554 | intel_de_write(dev_priv, ctl_reg, val); |
555 | intel_de_posting_read(dev_priv, ctl_reg); |
556 | } |
557 | |
558 | static void hsw_read_infoframe(struct intel_encoder *encoder, |
559 | const struct intel_crtc_state *crtc_state, |
560 | unsigned int type, |
561 | void *frame, ssize_t len) |
562 | { |
563 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
564 | enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; |
565 | u32 val, *data = frame; |
566 | int i; |
567 | |
568 | val = intel_de_read(dev_priv, HSW_TVIDEO_DIP_CTL(cpu_transcoder)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(cpu_transcoder)] - (&(dev_priv)->__info )->trans_offsets[TRANSCODER_A] + (0x60200) + ((&(dev_priv )->__info)->display_mmio_offset))) })); |
Value stored to 'val' is never read | |
569 | |
570 | for (i = 0; i < len; i += 4) |
571 | *data++ = intel_de_read(dev_priv, |
572 | hsw_dip_data_reg(dev_priv, cpu_transcoder, type, i >> 2)); |
573 | } |
574 | |
575 | static u32 hsw_infoframes_enabled(struct intel_encoder *encoder, |
576 | const struct intel_crtc_state *pipe_config) |
577 | { |
578 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
579 | u32 val = intel_de_read(dev_priv, |
580 | HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(pipe_config->cpu_transcoder)] - (&(dev_priv )->__info)->trans_offsets[TRANSCODER_A] + (0x60200) + ( (&(dev_priv)->__info)->display_mmio_offset))) })); |
581 | u32 mask; |
582 | |
583 | mask = (VIDEO_DIP_ENABLE_VSC_HSW(1 << 20) | VIDEO_DIP_ENABLE_AVI_HSW(1 << 12) | |
584 | VIDEO_DIP_ENABLE_GCP_HSW(1 << 16) | VIDEO_DIP_ENABLE_VS_HSW(1 << 8) | |
585 | VIDEO_DIP_ENABLE_GMP_HSW(1 << 4) | VIDEO_DIP_ENABLE_SPD_HSW(1 << 0)); |
586 | |
587 | if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 10 || IS_GEMINILAKE(dev_priv)IS_PLATFORM(dev_priv, INTEL_GEMINILAKE)) |
588 | mask |= VIDEO_DIP_ENABLE_DRM_GLK(1 << 28); |
589 | |
590 | return val & mask; |
591 | } |
592 | |
593 | static const u8 infoframe_type_to_idx[] = { |
594 | HDMI_PACKET_TYPE_GENERAL_CONTROL, |
595 | HDMI_PACKET_TYPE_GAMUT_METADATA, |
596 | DP_SDP_VSC0x07, |
597 | HDMI_INFOFRAME_TYPE_AVI, |
598 | HDMI_INFOFRAME_TYPE_SPD, |
599 | HDMI_INFOFRAME_TYPE_VENDOR, |
600 | HDMI_INFOFRAME_TYPE_DRM, |
601 | }; |
602 | |
603 | u32 intel_hdmi_infoframe_enable(unsigned int type) |
604 | { |
605 | int i; |
606 | |
607 | for (i = 0; i < ARRAY_SIZE(infoframe_type_to_idx)(sizeof((infoframe_type_to_idx)) / sizeof((infoframe_type_to_idx )[0])); i++) { |
608 | if (infoframe_type_to_idx[i] == type) |
609 | return BIT(i)(1UL << (i)); |
610 | } |
611 | |
612 | return 0; |
613 | } |
614 | |
615 | u32 intel_hdmi_infoframes_enabled(struct intel_encoder *encoder, |
616 | const struct intel_crtc_state *crtc_state) |
617 | { |
618 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
619 | struct intel_digital_port *dig_port = enc_to_dig_port(encoder); |
620 | u32 val, ret = 0; |
621 | int i; |
622 | |
623 | val = dig_port->infoframes_enabled(encoder, crtc_state); |
624 | |
625 | /* map from hardware bits to dip idx */ |
626 | for (i = 0; i < ARRAY_SIZE(infoframe_type_to_idx)(sizeof((infoframe_type_to_idx)) / sizeof((infoframe_type_to_idx )[0])); i++) { |
627 | unsigned int type = infoframe_type_to_idx[i]; |
628 | |
629 | if (HAS_DDI(dev_priv)((&(dev_priv)->__info)->display.has_ddi)) { |
630 | if (val & hsw_infoframe_enable(type)) |
631 | ret |= BIT(i)(1UL << (i)); |
632 | } else { |
633 | if (val & g4x_infoframe_enable(type)) |
634 | ret |= BIT(i)(1UL << (i)); |
635 | } |
636 | } |
637 | |
638 | return ret; |
639 | } |
640 | |
641 | /* |
642 | * The data we write to the DIP data buffer registers is 1 byte bigger than the |
643 | * HDMI infoframe size because of an ECC/reserved byte at position 3 (starting |
644 | * at 0). It's also a byte used by DisplayPort so the same DIP registers can be |
645 | * used for both technologies. |
646 | * |
647 | * DW0: Reserved/ECC/DP | HB2 | HB1 | HB0 |
648 | * DW1: DB3 | DB2 | DB1 | DB0 |
649 | * DW2: DB7 | DB6 | DB5 | DB4 |
650 | * DW3: ... |
651 | * |
652 | * (HB is Header Byte, DB is Data Byte) |
653 | * |
654 | * The hdmi pack() functions don't know about that hardware specific hole so we |
655 | * trick them by giving an offset into the buffer and moving back the header |
656 | * bytes by one. |
657 | */ |
658 | static void intel_write_infoframe(struct intel_encoder *encoder, |
659 | const struct intel_crtc_state *crtc_state, |
660 | enum hdmi_infoframe_type type, |
661 | const union hdmi_infoframe *frame) |
662 | { |
663 | struct intel_digital_port *dig_port = enc_to_dig_port(encoder); |
664 | u8 buffer[VIDEO_DIP_DATA_SIZE32]; |
665 | ssize_t len; |
666 | |
667 | if ((crtc_state->infoframes.enable & |
668 | intel_hdmi_infoframe_enable(type)) == 0) |
669 | return; |
670 | |
671 | if (drm_WARN_ON(encoder->base.dev, frame->any.type != type)({ int __ret = !!((frame->any.type != type)); if (__ret) printf ("%s %s: " "%s", dev_driver_string(((encoder->base.dev))-> dev), "", "drm_WARN_ON(" "frame->any.type != type" ")"); __builtin_expect (!!(__ret), 0); })) |
672 | return; |
673 | |
674 | /* see comment above for the reason for this offset */ |
675 | len = hdmi_infoframe_pack_only(frame, buffer + 1, sizeof(buffer) - 1); |
676 | if (drm_WARN_ON(encoder->base.dev, len < 0)({ int __ret = !!((len < 0)); if (__ret) printf("%s %s: " "%s" , dev_driver_string(((encoder->base.dev))->dev), "", "drm_WARN_ON(" "len < 0" ")"); __builtin_expect(!!(__ret), 0); })) |
677 | return; |
678 | |
679 | /* Insert the 'hole' (see big comment above) at position 3 */ |
680 | memmove(&buffer[0], &buffer[1], 3)__builtin_memmove((&buffer[0]), (&buffer[1]), (3)); |
681 | buffer[3] = 0; |
682 | len++; |
683 | |
684 | dig_port->write_infoframe(encoder, crtc_state, type, buffer, len); |
685 | } |
686 | |
687 | void intel_read_infoframe(struct intel_encoder *encoder, |
688 | const struct intel_crtc_state *crtc_state, |
689 | enum hdmi_infoframe_type type, |
690 | union hdmi_infoframe *frame) |
691 | { |
692 | struct intel_digital_port *dig_port = enc_to_dig_port(encoder); |
693 | u8 buffer[VIDEO_DIP_DATA_SIZE32]; |
694 | int ret; |
695 | |
696 | if ((crtc_state->infoframes.enable & |
697 | intel_hdmi_infoframe_enable(type)) == 0) |
698 | return; |
699 | |
700 | dig_port->read_infoframe(encoder, crtc_state, |
701 | type, buffer, sizeof(buffer)); |
702 | |
703 | /* Fill the 'hole' (see big comment above) at position 3 */ |
704 | memmove(&buffer[1], &buffer[0], 3)__builtin_memmove((&buffer[1]), (&buffer[0]), (3)); |
705 | |
706 | /* see comment above for the reason for this offset */ |
707 | ret = hdmi_infoframe_unpack(frame, buffer + 1, sizeof(buffer) - 1); |
708 | if (ret) { |
709 | drm_dbg_kms(encoder->base.dev,drm_dev_dbg((encoder->base.dev)->dev, DRM_UT_KMS, "Failed to unpack infoframe type 0x%02x\n" , type) |
710 | "Failed to unpack infoframe type 0x%02x\n", type)drm_dev_dbg((encoder->base.dev)->dev, DRM_UT_KMS, "Failed to unpack infoframe type 0x%02x\n" , type); |
711 | return; |
712 | } |
713 | |
714 | if (frame->any.type != type) |
715 | drm_dbg_kms(encoder->base.dev,drm_dev_dbg((encoder->base.dev)->dev, DRM_UT_KMS, "Found the wrong infoframe type 0x%x (expected 0x%02x)\n" , frame->any.type, type) |
716 | "Found the wrong infoframe type 0x%x (expected 0x%02x)\n",drm_dev_dbg((encoder->base.dev)->dev, DRM_UT_KMS, "Found the wrong infoframe type 0x%x (expected 0x%02x)\n" , frame->any.type, type) |
717 | frame->any.type, type)drm_dev_dbg((encoder->base.dev)->dev, DRM_UT_KMS, "Found the wrong infoframe type 0x%x (expected 0x%02x)\n" , frame->any.type, type); |
718 | } |
719 | |
720 | static bool_Bool |
721 | intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder, |
722 | struct intel_crtc_state *crtc_state, |
723 | struct drm_connector_state *conn_state) |
724 | { |
725 | struct hdmi_avi_infoframe *frame = &crtc_state->infoframes.avi.avi; |
726 | const struct drm_display_mode *adjusted_mode = |
727 | &crtc_state->hw.adjusted_mode; |
728 | struct drm_connector *connector = conn_state->connector; |
729 | int ret; |
730 | |
731 | if (!crtc_state->has_infoframe) |
732 | return true1; |
733 | |
734 | crtc_state->infoframes.enable |= |
735 | intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_AVI); |
736 | |
737 | ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector, |
738 | adjusted_mode); |
739 | if (ret) |
740 | return false0; |
741 | |
742 | if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) |
743 | frame->colorspace = HDMI_COLORSPACE_YUV420; |
744 | else if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444) |
745 | frame->colorspace = HDMI_COLORSPACE_YUV444; |
746 | else |
747 | frame->colorspace = HDMI_COLORSPACE_RGB; |
748 | |
749 | drm_hdmi_avi_infoframe_colorspace(frame, conn_state); |
750 | |
751 | /* nonsense combination */ |
752 | drm_WARN_ON(encoder->base.dev, crtc_state->limited_color_range &&({ int __ret = !!((crtc_state->limited_color_range && crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)); if (__ret) printf("%s %s: " "%s", dev_driver_string(((encoder-> base.dev))->dev), "", "drm_WARN_ON(" "crtc_state->limited_color_range && crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB" ")"); __builtin_expect(!!(__ret), 0); }) |
753 | crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)({ int __ret = !!((crtc_state->limited_color_range && crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)); if (__ret) printf("%s %s: " "%s", dev_driver_string(((encoder-> base.dev))->dev), "", "drm_WARN_ON(" "crtc_state->limited_color_range && crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB" ")"); __builtin_expect(!!(__ret), 0); }); |
754 | |
755 | if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_RGB) { |
756 | drm_hdmi_avi_infoframe_quant_range(frame, connector, |
757 | adjusted_mode, |
758 | crtc_state->limited_color_range ? |
759 | HDMI_QUANTIZATION_RANGE_LIMITED : |
760 | HDMI_QUANTIZATION_RANGE_FULL); |
761 | } else { |
762 | frame->quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT; |
763 | frame->ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED; |
764 | } |
765 | |
766 | drm_hdmi_avi_infoframe_content_type(frame, conn_state); |
767 | |
768 | /* TODO: handle pixel repetition for YCBCR420 outputs */ |
769 | |
770 | ret = hdmi_avi_infoframe_check(frame); |
771 | if (drm_WARN_ON(encoder->base.dev, ret)({ int __ret = !!((ret)); if (__ret) printf("%s %s: " "%s", dev_driver_string (((encoder->base.dev))->dev), "", "drm_WARN_ON(" "ret" ")" ); __builtin_expect(!!(__ret), 0); })) |
772 | return false0; |
773 | |
774 | return true1; |
775 | } |
776 | |
777 | static bool_Bool |
778 | intel_hdmi_compute_spd_infoframe(struct intel_encoder *encoder, |
779 | struct intel_crtc_state *crtc_state, |
780 | struct drm_connector_state *conn_state) |
781 | { |
782 | struct hdmi_spd_infoframe *frame = &crtc_state->infoframes.spd.spd; |
783 | int ret; |
784 | |
785 | if (!crtc_state->has_infoframe) |
786 | return true1; |
787 | |
788 | crtc_state->infoframes.enable |= |
789 | intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_SPD); |
790 | |
791 | ret = hdmi_spd_infoframe_init(frame, "Intel", "Integrated gfx"); |
792 | if (drm_WARN_ON(encoder->base.dev, ret)({ int __ret = !!((ret)); if (__ret) printf("%s %s: " "%s", dev_driver_string (((encoder->base.dev))->dev), "", "drm_WARN_ON(" "ret" ")" ); __builtin_expect(!!(__ret), 0); })) |
793 | return false0; |
794 | |
795 | frame->sdi = HDMI_SPD_SDI_PC; |
796 | |
797 | ret = hdmi_spd_infoframe_check(frame); |
798 | if (drm_WARN_ON(encoder->base.dev, ret)({ int __ret = !!((ret)); if (__ret) printf("%s %s: " "%s", dev_driver_string (((encoder->base.dev))->dev), "", "drm_WARN_ON(" "ret" ")" ); __builtin_expect(!!(__ret), 0); })) |
799 | return false0; |
800 | |
801 | return true1; |
802 | } |
803 | |
804 | static bool_Bool |
805 | intel_hdmi_compute_hdmi_infoframe(struct intel_encoder *encoder, |
806 | struct intel_crtc_state *crtc_state, |
807 | struct drm_connector_state *conn_state) |
808 | { |
809 | struct hdmi_vendor_infoframe *frame = |
810 | &crtc_state->infoframes.hdmi.vendor.hdmi; |
811 | const struct drm_display_info *info = |
812 | &conn_state->connector->display_info; |
813 | int ret; |
814 | |
815 | if (!crtc_state->has_infoframe || !info->has_hdmi_infoframe) |
816 | return true1; |
817 | |
818 | crtc_state->infoframes.enable |= |
819 | intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_VENDOR); |
820 | |
821 | ret = drm_hdmi_vendor_infoframe_from_display_mode(frame, |
822 | conn_state->connector, |
823 | &crtc_state->hw.adjusted_mode); |
824 | if (drm_WARN_ON(encoder->base.dev, ret)({ int __ret = !!((ret)); if (__ret) printf("%s %s: " "%s", dev_driver_string (((encoder->base.dev))->dev), "", "drm_WARN_ON(" "ret" ")" ); __builtin_expect(!!(__ret), 0); })) |
825 | return false0; |
826 | |
827 | ret = hdmi_vendor_infoframe_check(frame); |
828 | if (drm_WARN_ON(encoder->base.dev, ret)({ int __ret = !!((ret)); if (__ret) printf("%s %s: " "%s", dev_driver_string (((encoder->base.dev))->dev), "", "drm_WARN_ON(" "ret" ")" ); __builtin_expect(!!(__ret), 0); })) |
829 | return false0; |
830 | |
831 | return true1; |
832 | } |
833 | |
834 | static bool_Bool |
835 | intel_hdmi_compute_drm_infoframe(struct intel_encoder *encoder, |
836 | struct intel_crtc_state *crtc_state, |
837 | struct drm_connector_state *conn_state) |
838 | { |
839 | struct hdmi_drm_infoframe *frame = &crtc_state->infoframes.drm.drm; |
840 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
841 | int ret; |
842 | |
843 | if (!(INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 10 || IS_GEMINILAKE(dev_priv)IS_PLATFORM(dev_priv, INTEL_GEMINILAKE))) |
844 | return true1; |
845 | |
846 | if (!crtc_state->has_infoframe) |
847 | return true1; |
848 | |
849 | if (!conn_state->hdr_output_metadata) |
850 | return true1; |
851 | |
852 | crtc_state->infoframes.enable |= |
853 | intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_DRM); |
854 | |
855 | ret = drm_hdmi_infoframe_set_hdr_metadata(frame, conn_state); |
856 | if (ret < 0) { |
857 | drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "couldn't set HDR metadata in infoframe\n" ) |
858 | "couldn't set HDR metadata in infoframe\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "couldn't set HDR metadata in infoframe\n" ); |
859 | return false0; |
860 | } |
861 | |
862 | ret = hdmi_drm_infoframe_check(frame); |
863 | if (drm_WARN_ON(&dev_priv->drm, ret)({ int __ret = !!((ret)); if (__ret) printf("%s %s: " "%s", dev_driver_string (((&dev_priv->drm))->dev), "", "drm_WARN_ON(" "ret" ")"); __builtin_expect(!!(__ret), 0); })) |
864 | return false0; |
865 | |
866 | return true1; |
867 | } |
868 | |
869 | static void g4x_set_infoframes(struct intel_encoder *encoder, |
870 | bool_Bool enable, |
871 | const struct intel_crtc_state *crtc_state, |
872 | const struct drm_connector_state *conn_state) |
873 | { |
874 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
875 | struct intel_digital_port *dig_port = enc_to_dig_port(encoder); |
876 | struct intel_hdmi *intel_hdmi = &dig_port->hdmi; |
877 | i915_reg_t reg = VIDEO_DIP_CTL((const i915_reg_t){ .reg = (0x61170) }); |
878 | u32 val = intel_de_read(dev_priv, reg); |
879 | u32 port = VIDEO_DIP_PORT(encoder->port)((encoder->port) << 29); |
880 | |
881 | assert_hdmi_port_disabled(intel_hdmi); |
882 | |
883 | /* If the registers were not initialized yet, they might be zeroes, |
884 | * which means we're selecting the AVI DIP and we're setting its |
885 | * frequency to once. This seems to really confuse the HW and make |
886 | * things stop working (the register spec says the AVI always needs to |
887 | * be sent every VSync). So here we avoid writing to the register more |
888 | * than we need and also explicitly select the AVI DIP and explicitly |
889 | * set its frequency to every VSync. Avoiding to write it twice seems to |
890 | * be enough to solve the problem, but being defensive shouldn't hurt us |
891 | * either. */ |
892 | val |= VIDEO_DIP_SELECT_AVI(0 << 19) | VIDEO_DIP_FREQ_VSYNC(1 << 16); |
893 | |
894 | if (!enable) { |
895 | if (!(val & VIDEO_DIP_ENABLE(1 << 31))) |
896 | return; |
897 | if (port != (val & VIDEO_DIP_PORT_MASK(3 << 29))) { |
898 | drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "video DIP still enabled on port %c\n" , (val & (3 << 29)) >> 29) |
899 | "video DIP still enabled on port %c\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "video DIP still enabled on port %c\n" , (val & (3 << 29)) >> 29) |
900 | (val & VIDEO_DIP_PORT_MASK) >> 29)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "video DIP still enabled on port %c\n" , (val & (3 << 29)) >> 29); |
901 | return; |
902 | } |
903 | val &= ~(VIDEO_DIP_ENABLE(1 << 31) | VIDEO_DIP_ENABLE_AVI(1 << 21) | |
904 | VIDEO_DIP_ENABLE_VENDOR(2 << 21) | VIDEO_DIP_ENABLE_SPD(8 << 21)); |
905 | intel_de_write(dev_priv, reg, val); |
906 | intel_de_posting_read(dev_priv, reg); |
907 | return; |
908 | } |
909 | |
910 | if (port != (val & VIDEO_DIP_PORT_MASK(3 << 29))) { |
911 | if (val & VIDEO_DIP_ENABLE(1 << 31)) { |
912 | drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "video DIP already enabled on port %c\n" , (val & (3 << 29)) >> 29) |
913 | "video DIP already enabled on port %c\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "video DIP already enabled on port %c\n" , (val & (3 << 29)) >> 29) |
914 | (val & VIDEO_DIP_PORT_MASK) >> 29)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "video DIP already enabled on port %c\n" , (val & (3 << 29)) >> 29); |
915 | return; |
916 | } |
917 | val &= ~VIDEO_DIP_PORT_MASK(3 << 29); |
918 | val |= port; |
919 | } |
920 | |
921 | val |= VIDEO_DIP_ENABLE(1 << 31); |
922 | val &= ~(VIDEO_DIP_ENABLE_AVI(1 << 21) | |
923 | VIDEO_DIP_ENABLE_VENDOR(2 << 21) | VIDEO_DIP_ENABLE_SPD(8 << 21)); |
924 | |
925 | intel_de_write(dev_priv, reg, val); |
926 | intel_de_posting_read(dev_priv, reg); |
927 | |
928 | intel_write_infoframe(encoder, crtc_state, |
929 | HDMI_INFOFRAME_TYPE_AVI, |
930 | &crtc_state->infoframes.avi); |
931 | intel_write_infoframe(encoder, crtc_state, |
932 | HDMI_INFOFRAME_TYPE_SPD, |
933 | &crtc_state->infoframes.spd); |
934 | intel_write_infoframe(encoder, crtc_state, |
935 | HDMI_INFOFRAME_TYPE_VENDOR, |
936 | &crtc_state->infoframes.hdmi); |
937 | } |
938 | |
939 | /* |
940 | * Determine if default_phase=1 can be indicated in the GCP infoframe. |
941 | * |
942 | * From HDMI specification 1.4a: |
943 | * - The first pixel of each Video Data Period shall always have a pixel packing phase of 0 |
944 | * - The first pixel following each Video Data Period shall have a pixel packing phase of 0 |
945 | * - The PP bits shall be constant for all GCPs and will be equal to the last packing phase |
946 | * - The first pixel following every transition of HSYNC or VSYNC shall have a pixel packing |
947 | * phase of 0 |
948 | */ |
949 | static bool_Bool gcp_default_phase_possible(int pipe_bpp, |
950 | const struct drm_display_mode *mode) |
951 | { |
952 | unsigned int pixels_per_group; |
953 | |
954 | switch (pipe_bpp) { |
955 | case 30: |
956 | /* 4 pixels in 5 clocks */ |
957 | pixels_per_group = 4; |
958 | break; |
959 | case 36: |
960 | /* 2 pixels in 3 clocks */ |
961 | pixels_per_group = 2; |
962 | break; |
963 | case 48: |
964 | /* 1 pixel in 2 clocks */ |
965 | pixels_per_group = 1; |
966 | break; |
967 | default: |
968 | /* phase information not relevant for 8bpc */ |
969 | return false0; |
970 | } |
971 | |
972 | return mode->crtc_hdisplay % pixels_per_group == 0 && |
973 | mode->crtc_htotal % pixels_per_group == 0 && |
974 | mode->crtc_hblank_start % pixels_per_group == 0 && |
975 | mode->crtc_hblank_end % pixels_per_group == 0 && |
976 | mode->crtc_hsync_start % pixels_per_group == 0 && |
977 | mode->crtc_hsync_end % pixels_per_group == 0 && |
978 | ((mode->flags & DRM_MODE_FLAG_INTERLACE(1<<4)) == 0 || |
979 | mode->crtc_htotal/2 % pixels_per_group == 0); |
980 | } |
981 | |
982 | static bool_Bool intel_hdmi_set_gcp_infoframe(struct intel_encoder *encoder, |
983 | const struct intel_crtc_state *crtc_state, |
984 | const struct drm_connector_state *conn_state) |
985 | { |
986 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
987 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
988 | i915_reg_t reg; |
989 | |
990 | if ((crtc_state->infoframes.enable & |
991 | intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GENERAL_CONTROL)) == 0) |
992 | return false0; |
993 | |
994 | if (HAS_DDI(dev_priv)((&(dev_priv)->__info)->display.has_ddi)) |
995 | reg = HSW_TVIDEO_DIP_GCP(crtc_state->cpu_transcoder)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(crtc_state->cpu_transcoder)] - (&(dev_priv )->__info)->trans_offsets[TRANSCODER_A] + (0x60210) + ( (&(dev_priv)->__info)->display_mmio_offset))) }); |
996 | else if (IS_VALLEYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW) || IS_CHERRYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) |
997 | reg = VLV_TVIDEO_DIP_GCP(crtc->pipe)((const i915_reg_t){ .reg = ((((const u32 []){ (0x180000 + 0x60210 ), (0x180000 + 0x61178), (0x180000 + 0x611f8) })[(crtc->pipe )])) }); |
998 | else if (HAS_PCH_SPLIT(dev_priv)(((dev_priv)->pch_type) != PCH_NONE)) |
999 | reg = TVIDEO_DIP_GCP(crtc->pipe)((const i915_reg_t){ .reg = (((0xe0210) + (crtc->pipe) * ( (0xe1210) - (0xe0210)))) }); |
1000 | else |
1001 | return false0; |
1002 | |
1003 | intel_de_write(dev_priv, reg, crtc_state->infoframes.gcp); |
1004 | |
1005 | return true1; |
1006 | } |
1007 | |
1008 | void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder, |
1009 | struct intel_crtc_state *crtc_state) |
1010 | { |
1011 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1012 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
1013 | i915_reg_t reg; |
1014 | |
1015 | if ((crtc_state->infoframes.enable & |
1016 | intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GENERAL_CONTROL)) == 0) |
1017 | return; |
1018 | |
1019 | if (HAS_DDI(dev_priv)((&(dev_priv)->__info)->display.has_ddi)) |
1020 | reg = HSW_TVIDEO_DIP_GCP(crtc_state->cpu_transcoder)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(crtc_state->cpu_transcoder)] - (&(dev_priv )->__info)->trans_offsets[TRANSCODER_A] + (0x60210) + ( (&(dev_priv)->__info)->display_mmio_offset))) }); |
1021 | else if (IS_VALLEYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW) || IS_CHERRYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) |
1022 | reg = VLV_TVIDEO_DIP_GCP(crtc->pipe)((const i915_reg_t){ .reg = ((((const u32 []){ (0x180000 + 0x60210 ), (0x180000 + 0x61178), (0x180000 + 0x611f8) })[(crtc->pipe )])) }); |
1023 | else if (HAS_PCH_SPLIT(dev_priv)(((dev_priv)->pch_type) != PCH_NONE)) |
1024 | reg = TVIDEO_DIP_GCP(crtc->pipe)((const i915_reg_t){ .reg = (((0xe0210) + (crtc->pipe) * ( (0xe1210) - (0xe0210)))) }); |
1025 | else |
1026 | return; |
1027 | |
1028 | crtc_state->infoframes.gcp = intel_de_read(dev_priv, reg); |
1029 | } |
1030 | |
1031 | static void intel_hdmi_compute_gcp_infoframe(struct intel_encoder *encoder, |
1032 | struct intel_crtc_state *crtc_state, |
1033 | struct drm_connector_state *conn_state) |
1034 | { |
1035 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1036 | |
1037 | if (IS_G4X(dev_priv)(IS_PLATFORM(dev_priv, INTEL_G45) || IS_PLATFORM(dev_priv, INTEL_GM45 )) || !crtc_state->has_infoframe) |
1038 | return; |
1039 | |
1040 | crtc_state->infoframes.enable |= |
1041 | intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GENERAL_CONTROL); |
1042 | |
1043 | /* Indicate color indication for deep color mode */ |
1044 | if (crtc_state->pipe_bpp > 24) |
1045 | crtc_state->infoframes.gcp |= GCP_COLOR_INDICATION(1 << 2); |
1046 | |
1047 | /* Enable default_phase whenever the display mode is suitably aligned */ |
1048 | if (gcp_default_phase_possible(crtc_state->pipe_bpp, |
1049 | &crtc_state->hw.adjusted_mode)) |
1050 | crtc_state->infoframes.gcp |= GCP_DEFAULT_PHASE_ENABLE(1 << 1); |
1051 | } |
1052 | |
1053 | static void ibx_set_infoframes(struct intel_encoder *encoder, |
1054 | bool_Bool enable, |
1055 | const struct intel_crtc_state *crtc_state, |
1056 | const struct drm_connector_state *conn_state) |
1057 | { |
1058 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1059 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
1060 | struct intel_digital_port *dig_port = enc_to_dig_port(encoder); |
1061 | struct intel_hdmi *intel_hdmi = &dig_port->hdmi; |
1062 | i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe)((const i915_reg_t){ .reg = (((0xe0200) + (intel_crtc->pipe ) * ((0xe1200) - (0xe0200)))) }); |
1063 | u32 val = intel_de_read(dev_priv, reg); |
1064 | u32 port = VIDEO_DIP_PORT(encoder->port)((encoder->port) << 29); |
1065 | |
1066 | assert_hdmi_port_disabled(intel_hdmi); |
1067 | |
1068 | /* See the big comment in g4x_set_infoframes() */ |
1069 | val |= VIDEO_DIP_SELECT_AVI(0 << 19) | VIDEO_DIP_FREQ_VSYNC(1 << 16); |
1070 | |
1071 | if (!enable) { |
1072 | if (!(val & VIDEO_DIP_ENABLE(1 << 31))) |
1073 | return; |
1074 | val &= ~(VIDEO_DIP_ENABLE(1 << 31) | VIDEO_DIP_ENABLE_AVI(1 << 21) | |
1075 | VIDEO_DIP_ENABLE_VENDOR(2 << 21) | VIDEO_DIP_ENABLE_GAMUT(4 << 21) | |
1076 | VIDEO_DIP_ENABLE_SPD(8 << 21) | VIDEO_DIP_ENABLE_GCP(1 << 25)); |
1077 | intel_de_write(dev_priv, reg, val); |
1078 | intel_de_posting_read(dev_priv, reg); |
1079 | return; |
1080 | } |
1081 | |
1082 | if (port != (val & VIDEO_DIP_PORT_MASK(3 << 29))) { |
1083 | drm_WARN(&dev_priv->drm, val & VIDEO_DIP_ENABLE,({ int __ret = !!(val & (1 << 31)); if (__ret) printf ("%s %s: " "DIP already enabled on port %c\n", dev_driver_string ((&dev_priv->drm)->dev), "", (val & (3 << 29)) >> 29); __builtin_expect(!!(__ret), 0); }) |
1084 | "DIP already enabled on port %c\n",({ int __ret = !!(val & (1 << 31)); if (__ret) printf ("%s %s: " "DIP already enabled on port %c\n", dev_driver_string ((&dev_priv->drm)->dev), "", (val & (3 << 29)) >> 29); __builtin_expect(!!(__ret), 0); }) |
1085 | (val & VIDEO_DIP_PORT_MASK) >> 29)({ int __ret = !!(val & (1 << 31)); if (__ret) printf ("%s %s: " "DIP already enabled on port %c\n", dev_driver_string ((&dev_priv->drm)->dev), "", (val & (3 << 29)) >> 29); __builtin_expect(!!(__ret), 0); }); |
1086 | val &= ~VIDEO_DIP_PORT_MASK(3 << 29); |
1087 | val |= port; |
1088 | } |
1089 | |
1090 | val |= VIDEO_DIP_ENABLE(1 << 31); |
1091 | val &= ~(VIDEO_DIP_ENABLE_AVI(1 << 21) | |
1092 | VIDEO_DIP_ENABLE_VENDOR(2 << 21) | VIDEO_DIP_ENABLE_GAMUT(4 << 21) | |
1093 | VIDEO_DIP_ENABLE_SPD(8 << 21) | VIDEO_DIP_ENABLE_GCP(1 << 25)); |
1094 | |
1095 | if (intel_hdmi_set_gcp_infoframe(encoder, crtc_state, conn_state)) |
1096 | val |= VIDEO_DIP_ENABLE_GCP(1 << 25); |
1097 | |
1098 | intel_de_write(dev_priv, reg, val); |
1099 | intel_de_posting_read(dev_priv, reg); |
1100 | |
1101 | intel_write_infoframe(encoder, crtc_state, |
1102 | HDMI_INFOFRAME_TYPE_AVI, |
1103 | &crtc_state->infoframes.avi); |
1104 | intel_write_infoframe(encoder, crtc_state, |
1105 | HDMI_INFOFRAME_TYPE_SPD, |
1106 | &crtc_state->infoframes.spd); |
1107 | intel_write_infoframe(encoder, crtc_state, |
1108 | HDMI_INFOFRAME_TYPE_VENDOR, |
1109 | &crtc_state->infoframes.hdmi); |
1110 | } |
1111 | |
1112 | static void cpt_set_infoframes(struct intel_encoder *encoder, |
1113 | bool_Bool enable, |
1114 | const struct intel_crtc_state *crtc_state, |
1115 | const struct drm_connector_state *conn_state) |
1116 | { |
1117 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1118 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
1119 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
1120 | i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe)((const i915_reg_t){ .reg = (((0xe0200) + (intel_crtc->pipe ) * ((0xe1200) - (0xe0200)))) }); |
1121 | u32 val = intel_de_read(dev_priv, reg); |
1122 | |
1123 | assert_hdmi_port_disabled(intel_hdmi); |
1124 | |
1125 | /* See the big comment in g4x_set_infoframes() */ |
1126 | val |= VIDEO_DIP_SELECT_AVI(0 << 19) | VIDEO_DIP_FREQ_VSYNC(1 << 16); |
1127 | |
1128 | if (!enable) { |
1129 | if (!(val & VIDEO_DIP_ENABLE(1 << 31))) |
1130 | return; |
1131 | val &= ~(VIDEO_DIP_ENABLE(1 << 31) | VIDEO_DIP_ENABLE_AVI(1 << 21) | |
1132 | VIDEO_DIP_ENABLE_VENDOR(2 << 21) | VIDEO_DIP_ENABLE_GAMUT(4 << 21) | |
1133 | VIDEO_DIP_ENABLE_SPD(8 << 21) | VIDEO_DIP_ENABLE_GCP(1 << 25)); |
1134 | intel_de_write(dev_priv, reg, val); |
1135 | intel_de_posting_read(dev_priv, reg); |
1136 | return; |
1137 | } |
1138 | |
1139 | /* Set both together, unset both together: see the spec. */ |
1140 | val |= VIDEO_DIP_ENABLE(1 << 31) | VIDEO_DIP_ENABLE_AVI(1 << 21); |
1141 | val &= ~(VIDEO_DIP_ENABLE_VENDOR(2 << 21) | VIDEO_DIP_ENABLE_GAMUT(4 << 21) | |
1142 | VIDEO_DIP_ENABLE_SPD(8 << 21) | VIDEO_DIP_ENABLE_GCP(1 << 25)); |
1143 | |
1144 | if (intel_hdmi_set_gcp_infoframe(encoder, crtc_state, conn_state)) |
1145 | val |= VIDEO_DIP_ENABLE_GCP(1 << 25); |
1146 | |
1147 | intel_de_write(dev_priv, reg, val); |
1148 | intel_de_posting_read(dev_priv, reg); |
1149 | |
1150 | intel_write_infoframe(encoder, crtc_state, |
1151 | HDMI_INFOFRAME_TYPE_AVI, |
1152 | &crtc_state->infoframes.avi); |
1153 | intel_write_infoframe(encoder, crtc_state, |
1154 | HDMI_INFOFRAME_TYPE_SPD, |
1155 | &crtc_state->infoframes.spd); |
1156 | intel_write_infoframe(encoder, crtc_state, |
1157 | HDMI_INFOFRAME_TYPE_VENDOR, |
1158 | &crtc_state->infoframes.hdmi); |
1159 | } |
1160 | |
1161 | static void vlv_set_infoframes(struct intel_encoder *encoder, |
1162 | bool_Bool enable, |
1163 | const struct intel_crtc_state *crtc_state, |
1164 | const struct drm_connector_state *conn_state) |
1165 | { |
1166 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1167 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
1168 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
1169 | i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe)((const i915_reg_t){ .reg = ((((const u32 []){ (0x180000 + 0x60200 ), (0x180000 + 0x61170), (0x180000 + 0x611f0) })[(intel_crtc-> pipe)])) }); |
1170 | u32 val = intel_de_read(dev_priv, reg); |
1171 | u32 port = VIDEO_DIP_PORT(encoder->port)((encoder->port) << 29); |
1172 | |
1173 | assert_hdmi_port_disabled(intel_hdmi); |
1174 | |
1175 | /* See the big comment in g4x_set_infoframes() */ |
1176 | val |= VIDEO_DIP_SELECT_AVI(0 << 19) | VIDEO_DIP_FREQ_VSYNC(1 << 16); |
1177 | |
1178 | if (!enable) { |
1179 | if (!(val & VIDEO_DIP_ENABLE(1 << 31))) |
1180 | return; |
1181 | val &= ~(VIDEO_DIP_ENABLE(1 << 31) | VIDEO_DIP_ENABLE_AVI(1 << 21) | |
1182 | VIDEO_DIP_ENABLE_VENDOR(2 << 21) | VIDEO_DIP_ENABLE_GAMUT(4 << 21) | |
1183 | VIDEO_DIP_ENABLE_SPD(8 << 21) | VIDEO_DIP_ENABLE_GCP(1 << 25)); |
1184 | intel_de_write(dev_priv, reg, val); |
1185 | intel_de_posting_read(dev_priv, reg); |
1186 | return; |
1187 | } |
1188 | |
1189 | if (port != (val & VIDEO_DIP_PORT_MASK(3 << 29))) { |
1190 | drm_WARN(&dev_priv->drm, val & VIDEO_DIP_ENABLE,({ int __ret = !!(val & (1 << 31)); if (__ret) printf ("%s %s: " "DIP already enabled on port %c\n", dev_driver_string ((&dev_priv->drm)->dev), "", (val & (3 << 29)) >> 29); __builtin_expect(!!(__ret), 0); }) |
1191 | "DIP already enabled on port %c\n",({ int __ret = !!(val & (1 << 31)); if (__ret) printf ("%s %s: " "DIP already enabled on port %c\n", dev_driver_string ((&dev_priv->drm)->dev), "", (val & (3 << 29)) >> 29); __builtin_expect(!!(__ret), 0); }) |
1192 | (val & VIDEO_DIP_PORT_MASK) >> 29)({ int __ret = !!(val & (1 << 31)); if (__ret) printf ("%s %s: " "DIP already enabled on port %c\n", dev_driver_string ((&dev_priv->drm)->dev), "", (val & (3 << 29)) >> 29); __builtin_expect(!!(__ret), 0); }); |
1193 | val &= ~VIDEO_DIP_PORT_MASK(3 << 29); |
1194 | val |= port; |
1195 | } |
1196 | |
1197 | val |= VIDEO_DIP_ENABLE(1 << 31); |
1198 | val &= ~(VIDEO_DIP_ENABLE_AVI(1 << 21) | |
1199 | VIDEO_DIP_ENABLE_VENDOR(2 << 21) | VIDEO_DIP_ENABLE_GAMUT(4 << 21) | |
1200 | VIDEO_DIP_ENABLE_SPD(8 << 21) | VIDEO_DIP_ENABLE_GCP(1 << 25)); |
1201 | |
1202 | if (intel_hdmi_set_gcp_infoframe(encoder, crtc_state, conn_state)) |
1203 | val |= VIDEO_DIP_ENABLE_GCP(1 << 25); |
1204 | |
1205 | intel_de_write(dev_priv, reg, val); |
1206 | intel_de_posting_read(dev_priv, reg); |
1207 | |
1208 | intel_write_infoframe(encoder, crtc_state, |
1209 | HDMI_INFOFRAME_TYPE_AVI, |
1210 | &crtc_state->infoframes.avi); |
1211 | intel_write_infoframe(encoder, crtc_state, |
1212 | HDMI_INFOFRAME_TYPE_SPD, |
1213 | &crtc_state->infoframes.spd); |
1214 | intel_write_infoframe(encoder, crtc_state, |
1215 | HDMI_INFOFRAME_TYPE_VENDOR, |
1216 | &crtc_state->infoframes.hdmi); |
1217 | } |
1218 | |
1219 | static void hsw_set_infoframes(struct intel_encoder *encoder, |
1220 | bool_Bool enable, |
1221 | const struct intel_crtc_state *crtc_state, |
1222 | const struct drm_connector_state *conn_state) |
1223 | { |
1224 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1225 | i915_reg_t reg = HSW_TVIDEO_DIP_CTL(crtc_state->cpu_transcoder)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(crtc_state->cpu_transcoder)] - (&(dev_priv )->__info)->trans_offsets[TRANSCODER_A] + (0x60200) + ( (&(dev_priv)->__info)->display_mmio_offset))) }); |
1226 | u32 val = intel_de_read(dev_priv, reg); |
1227 | |
1228 | assert_hdmi_transcoder_func_disabled(dev_priv, |
1229 | crtc_state->cpu_transcoder); |
1230 | |
1231 | val &= ~(VIDEO_DIP_ENABLE_VSC_HSW(1 << 20) | VIDEO_DIP_ENABLE_AVI_HSW(1 << 12) | |
1232 | VIDEO_DIP_ENABLE_GCP_HSW(1 << 16) | VIDEO_DIP_ENABLE_VS_HSW(1 << 8) | |
1233 | VIDEO_DIP_ENABLE_GMP_HSW(1 << 4) | VIDEO_DIP_ENABLE_SPD_HSW(1 << 0) | |
1234 | VIDEO_DIP_ENABLE_DRM_GLK(1 << 28)); |
1235 | |
1236 | if (!enable) { |
1237 | intel_de_write(dev_priv, reg, val); |
1238 | intel_de_posting_read(dev_priv, reg); |
1239 | return; |
1240 | } |
1241 | |
1242 | if (intel_hdmi_set_gcp_infoframe(encoder, crtc_state, conn_state)) |
1243 | val |= VIDEO_DIP_ENABLE_GCP_HSW(1 << 16); |
1244 | |
1245 | intel_de_write(dev_priv, reg, val); |
1246 | intel_de_posting_read(dev_priv, reg); |
1247 | |
1248 | intel_write_infoframe(encoder, crtc_state, |
1249 | HDMI_INFOFRAME_TYPE_AVI, |
1250 | &crtc_state->infoframes.avi); |
1251 | intel_write_infoframe(encoder, crtc_state, |
1252 | HDMI_INFOFRAME_TYPE_SPD, |
1253 | &crtc_state->infoframes.spd); |
1254 | intel_write_infoframe(encoder, crtc_state, |
1255 | HDMI_INFOFRAME_TYPE_VENDOR, |
1256 | &crtc_state->infoframes.hdmi); |
1257 | intel_write_infoframe(encoder, crtc_state, |
1258 | HDMI_INFOFRAME_TYPE_DRM, |
1259 | &crtc_state->infoframes.drm); |
1260 | } |
1261 | |
1262 | void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool_Bool enable) |
1263 | { |
1264 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(intel_hdmi_to_dev(hdmi)); |
1265 | struct i2c_adapter *adapter = |
1266 | intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); |
1267 | |
1268 | if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI) |
1269 | return; |
1270 | |
1271 | drm_dbg_kms(&dev_priv->drm, "%s DP dual mode adaptor TMDS output\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "%s DP dual mode adaptor TMDS output\n" , enable ? "Enabling" : "Disabling") |
1272 | enable ? "Enabling" : "Disabling")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "%s DP dual mode adaptor TMDS output\n" , enable ? "Enabling" : "Disabling"); |
1273 | |
1274 | drm_dp_dual_mode_set_tmds_output(hdmi->dp_dual_mode.type, |
1275 | adapter, enable); |
1276 | } |
1277 | |
1278 | static int intel_hdmi_hdcp_read(struct intel_digital_port *dig_port, |
1279 | unsigned int offset, void *buffer, size_t size) |
1280 | { |
1281 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(dig_port->base.base.dev); |
1282 | struct intel_hdmi *hdmi = &dig_port->hdmi; |
1283 | struct i2c_adapter *adapter = intel_gmbus_get_adapter(i915, |
1284 | hdmi->ddc_bus); |
1285 | int ret; |
1286 | u8 start = offset & 0xff; |
1287 | struct i2c_msg msgs[] = { |
1288 | { |
1289 | .addr = DRM_HDCP_DDC_ADDR0x3A, |
1290 | .flags = 0, |
1291 | .len = 1, |
1292 | .buf = &start, |
1293 | }, |
1294 | { |
1295 | .addr = DRM_HDCP_DDC_ADDR0x3A, |
1296 | .flags = I2C_M_RD0x0001, |
1297 | .len = size, |
1298 | .buf = buffer |
1299 | } |
1300 | }; |
1301 | ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs)(sizeof((msgs)) / sizeof((msgs)[0]))); |
1302 | if (ret == ARRAY_SIZE(msgs)(sizeof((msgs)) / sizeof((msgs)[0]))) |
1303 | return 0; |
1304 | return ret >= 0 ? -EIO5 : ret; |
1305 | } |
1306 | |
1307 | static int intel_hdmi_hdcp_write(struct intel_digital_port *dig_port, |
1308 | unsigned int offset, void *buffer, size_t size) |
1309 | { |
1310 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(dig_port->base.base.dev); |
1311 | struct intel_hdmi *hdmi = &dig_port->hdmi; |
1312 | struct i2c_adapter *adapter = intel_gmbus_get_adapter(i915, |
1313 | hdmi->ddc_bus); |
1314 | int ret; |
1315 | u8 *write_buf; |
1316 | struct i2c_msg msg; |
1317 | |
1318 | write_buf = kzalloc(size + 1, GFP_KERNEL(0x0001 | 0x0004)); |
1319 | if (!write_buf) |
1320 | return -ENOMEM12; |
1321 | |
1322 | write_buf[0] = offset & 0xff; |
1323 | memcpy(&write_buf[1], buffer, size)__builtin_memcpy((&write_buf[1]), (buffer), (size)); |
1324 | |
1325 | msg.addr = DRM_HDCP_DDC_ADDR0x3A; |
1326 | msg.flags = 0, |
1327 | msg.len = size + 1, |
1328 | msg.buf = write_buf; |
1329 | |
1330 | ret = i2c_transfer(adapter, &msg, 1); |
1331 | if (ret == 1) |
1332 | ret = 0; |
1333 | else if (ret >= 0) |
1334 | ret = -EIO5; |
1335 | |
1336 | kfree(write_buf); |
1337 | return ret; |
1338 | } |
1339 | |
1340 | static |
1341 | int intel_hdmi_hdcp_write_an_aksv(struct intel_digital_port *dig_port, |
1342 | u8 *an) |
1343 | { |
1344 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(dig_port->base.base.dev); |
1345 | struct intel_hdmi *hdmi = &dig_port->hdmi; |
1346 | struct i2c_adapter *adapter = intel_gmbus_get_adapter(i915, |
1347 | hdmi->ddc_bus); |
1348 | int ret; |
1349 | |
1350 | ret = intel_hdmi_hdcp_write(dig_port, DRM_HDCP_DDC_AN0x18, an, |
1351 | DRM_HDCP_AN_LEN8); |
1352 | if (ret) { |
1353 | drm_dbg_kms(&i915->drm, "Write An over DDC failed (%d)\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Write An over DDC failed (%d)\n" , ret) |
1354 | ret)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Write An over DDC failed (%d)\n" , ret); |
1355 | return ret; |
1356 | } |
1357 | |
1358 | ret = intel_gmbus_output_aksv(adapter); |
1359 | if (ret < 0) { |
1360 | drm_dbg_kms(&i915->drm, "Failed to output aksv (%d)\n", ret)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Failed to output aksv (%d)\n" , ret); |
1361 | return ret; |
1362 | } |
1363 | return 0; |
1364 | } |
1365 | |
1366 | static int intel_hdmi_hdcp_read_bksv(struct intel_digital_port *dig_port, |
1367 | u8 *bksv) |
1368 | { |
1369 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(dig_port->base.base.dev); |
1370 | |
1371 | int ret; |
1372 | ret = intel_hdmi_hdcp_read(dig_port, DRM_HDCP_DDC_BKSV0x00, bksv, |
1373 | DRM_HDCP_KSV_LEN5); |
1374 | if (ret) |
1375 | drm_dbg_kms(&i915->drm, "Read Bksv over DDC failed (%d)\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Read Bksv over DDC failed (%d)\n" , ret) |
1376 | ret)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Read Bksv over DDC failed (%d)\n" , ret); |
1377 | return ret; |
1378 | } |
1379 | |
1380 | static |
1381 | int intel_hdmi_hdcp_read_bstatus(struct intel_digital_port *dig_port, |
1382 | u8 *bstatus) |
1383 | { |
1384 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(dig_port->base.base.dev); |
1385 | |
1386 | int ret; |
1387 | ret = intel_hdmi_hdcp_read(dig_port, DRM_HDCP_DDC_BSTATUS0x41, |
1388 | bstatus, DRM_HDCP_BSTATUS_LEN2); |
1389 | if (ret) |
1390 | drm_dbg_kms(&i915->drm, "Read bstatus over DDC failed (%d)\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Read bstatus over DDC failed (%d)\n" , ret) |
1391 | ret)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Read bstatus over DDC failed (%d)\n" , ret); |
1392 | return ret; |
1393 | } |
1394 | |
1395 | static |
1396 | int intel_hdmi_hdcp_repeater_present(struct intel_digital_port *dig_port, |
1397 | bool_Bool *repeater_present) |
1398 | { |
1399 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(dig_port->base.base.dev); |
1400 | int ret; |
1401 | u8 val; |
1402 | |
1403 | ret = intel_hdmi_hdcp_read(dig_port, DRM_HDCP_DDC_BCAPS0x40, &val, 1); |
1404 | if (ret) { |
1405 | drm_dbg_kms(&i915->drm, "Read bcaps over DDC failed (%d)\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Read bcaps over DDC failed (%d)\n" , ret) |
1406 | ret)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Read bcaps over DDC failed (%d)\n" , ret); |
1407 | return ret; |
1408 | } |
1409 | *repeater_present = val & DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT(1UL << (6)); |
1410 | return 0; |
1411 | } |
1412 | |
1413 | static |
1414 | int intel_hdmi_hdcp_read_ri_prime(struct intel_digital_port *dig_port, |
1415 | u8 *ri_prime) |
1416 | { |
1417 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(dig_port->base.base.dev); |
1418 | |
1419 | int ret; |
1420 | ret = intel_hdmi_hdcp_read(dig_port, DRM_HDCP_DDC_RI_PRIME0x08, |
1421 | ri_prime, DRM_HDCP_RI_LEN2); |
1422 | if (ret) |
1423 | drm_dbg_kms(&i915->drm, "Read Ri' over DDC failed (%d)\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Read Ri' over DDC failed (%d)\n" , ret) |
1424 | ret)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Read Ri' over DDC failed (%d)\n" , ret); |
1425 | return ret; |
1426 | } |
1427 | |
1428 | static |
1429 | int intel_hdmi_hdcp_read_ksv_ready(struct intel_digital_port *dig_port, |
1430 | bool_Bool *ksv_ready) |
1431 | { |
1432 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(dig_port->base.base.dev); |
1433 | int ret; |
1434 | u8 val; |
1435 | |
1436 | ret = intel_hdmi_hdcp_read(dig_port, DRM_HDCP_DDC_BCAPS0x40, &val, 1); |
1437 | if (ret) { |
1438 | drm_dbg_kms(&i915->drm, "Read bcaps over DDC failed (%d)\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Read bcaps over DDC failed (%d)\n" , ret) |
1439 | ret)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Read bcaps over DDC failed (%d)\n" , ret); |
1440 | return ret; |
1441 | } |
1442 | *ksv_ready = val & DRM_HDCP_DDC_BCAPS_KSV_FIFO_READY(1UL << (5)); |
1443 | return 0; |
1444 | } |
1445 | |
1446 | static |
1447 | int intel_hdmi_hdcp_read_ksv_fifo(struct intel_digital_port *dig_port, |
1448 | int num_downstream, u8 *ksv_fifo) |
1449 | { |
1450 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(dig_port->base.base.dev); |
1451 | int ret; |
1452 | ret = intel_hdmi_hdcp_read(dig_port, DRM_HDCP_DDC_KSV_FIFO0x43, |
1453 | ksv_fifo, num_downstream * DRM_HDCP_KSV_LEN5); |
1454 | if (ret) { |
1455 | drm_dbg_kms(&i915->drm,drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Read ksv fifo over DDC failed (%d)\n" , ret) |
1456 | "Read ksv fifo over DDC failed (%d)\n", ret)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Read ksv fifo over DDC failed (%d)\n" , ret); |
1457 | return ret; |
1458 | } |
1459 | return 0; |
1460 | } |
1461 | |
1462 | static |
1463 | int intel_hdmi_hdcp_read_v_prime_part(struct intel_digital_port *dig_port, |
1464 | int i, u32 *part) |
1465 | { |
1466 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(dig_port->base.base.dev); |
1467 | int ret; |
1468 | |
1469 | if (i >= DRM_HDCP_V_PRIME_NUM_PARTS5) |
1470 | return -EINVAL22; |
1471 | |
1472 | ret = intel_hdmi_hdcp_read(dig_port, DRM_HDCP_DDC_V_PRIME(i)(0x20 + i * 4), |
1473 | part, DRM_HDCP_V_PRIME_PART_LEN4); |
1474 | if (ret) |
1475 | drm_dbg_kms(&i915->drm, "Read V'[%d] over DDC failed (%d)\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Read V'[%d] over DDC failed (%d)\n" , i, ret) |
1476 | i, ret)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Read V'[%d] over DDC failed (%d)\n" , i, ret); |
1477 | return ret; |
1478 | } |
1479 | |
1480 | static int kbl_repositioning_enc_en_signal(struct intel_connector *connector, |
1481 | enum transcoder cpu_transcoder) |
1482 | { |
1483 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); |
1484 | struct intel_digital_port *dig_port = intel_attached_dig_port(connector); |
1485 | struct drm_crtc *crtc = connector->base.state->crtc; |
1486 | struct intel_crtc *intel_crtc = container_of(crtc,({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc); (struct intel_crtc *)( (char *)__mptr - __builtin_offsetof (struct intel_crtc, base) );}) |
1487 | struct intel_crtc, base)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc); (struct intel_crtc *)( (char *)__mptr - __builtin_offsetof (struct intel_crtc, base) );}); |
1488 | u32 scanline; |
1489 | int ret; |
1490 | |
1491 | for (;;) { |
1492 | scanline = intel_de_read(dev_priv, PIPEDSL(intel_crtc->pipe)((const i915_reg_t){ .reg = ((&(dev_priv)->__info)-> pipe_offsets[intel_crtc->pipe] - (&(dev_priv)->__info )->pipe_offsets[PIPE_A] + (0x70000) + ((&(dev_priv)-> __info)->display_mmio_offset)) })); |
1493 | if (scanline > 100 && scanline < 200) |
1494 | break; |
1495 | usleep_range(25, 50); |
1496 | } |
1497 | |
1498 | ret = intel_ddi_toggle_hdcp_signalling(&dig_port->base, cpu_transcoder, |
1499 | false0); |
1500 | if (ret) { |
1501 | drm_err(&dev_priv->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Disable HDCP signalling failed (%d)\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , ret) |
1502 | "Disable HDCP signalling failed (%d)\n", ret)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Disable HDCP signalling failed (%d)\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , ret); |
1503 | return ret; |
1504 | } |
1505 | ret = intel_ddi_toggle_hdcp_signalling(&dig_port->base, cpu_transcoder, |
1506 | true1); |
1507 | if (ret) { |
1508 | drm_err(&dev_priv->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Enable HDCP signalling failed (%d)\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , ret) |
1509 | "Enable HDCP signalling failed (%d)\n", ret)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Enable HDCP signalling failed (%d)\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , ret); |
1510 | return ret; |
1511 | } |
1512 | |
1513 | return 0; |
1514 | } |
1515 | |
1516 | static |
1517 | int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *dig_port, |
1518 | enum transcoder cpu_transcoder, |
1519 | bool_Bool enable) |
1520 | { |
1521 | struct intel_hdmi *hdmi = &dig_port->hdmi; |
1522 | struct intel_connector *connector = hdmi->attached_connector; |
1523 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); |
1524 | int ret; |
1525 | |
1526 | if (!enable) |
1527 | usleep_range(6, 60); /* Bspec says >= 6us */ |
1528 | |
1529 | ret = intel_ddi_toggle_hdcp_signalling(&dig_port->base, cpu_transcoder, |
1530 | enable); |
1531 | if (ret) { |
1532 | drm_err(&dev_priv->drm, "%s HDCP signalling failed (%d)\n",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "%s HDCP signalling failed (%d)\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , enable ? "Enable" : "Disable", ret) |
1533 | enable ? "Enable" : "Disable", ret)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "%s HDCP signalling failed (%d)\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , enable ? "Enable" : "Disable", ret); |
1534 | return ret; |
1535 | } |
1536 | |
1537 | /* |
1538 | * WA: To fix incorrect positioning of the window of |
1539 | * opportunity and enc_en signalling in KABYLAKE. |
1540 | */ |
1541 | if (IS_KABYLAKE(dev_priv)IS_PLATFORM(dev_priv, INTEL_KABYLAKE) && enable) |
1542 | return kbl_repositioning_enc_en_signal(connector, |
1543 | cpu_transcoder); |
1544 | |
1545 | return 0; |
1546 | } |
1547 | |
1548 | static |
1549 | bool_Bool intel_hdmi_hdcp_check_link_once(struct intel_digital_port *dig_port, |
1550 | struct intel_connector *connector) |
1551 | { |
1552 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(dig_port->base.base.dev); |
1553 | enum port port = dig_port->base.port; |
1554 | enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder; |
1555 | int ret; |
1556 | union { |
1557 | u32 reg; |
1558 | u8 shim[DRM_HDCP_RI_LEN2]; |
1559 | } ri; |
1560 | |
1561 | ret = intel_hdmi_hdcp_read_ri_prime(dig_port, ri.shim); |
1562 | if (ret) |
1563 | return false0; |
1564 | |
1565 | intel_de_write(i915, HDCP_RPRIME(i915, cpu_transcoder, port)(((&(i915)->__info)->gen) >= 12 ? ((const i915_reg_t ){ .reg = (((0x66418) + (cpu_transcoder) * ((0x66518) - (0x66418 )))) }) : ((const i915_reg_t){ .reg = ((((const u32 []){ 0x66800 , 0x66500, 0x66600, 0x66700, 0x66A00, 0x66900 })[port]) + (0x18 )) })), ri.reg); |
1566 | |
1567 | /* Wait for Ri prime match */ |
1568 | if (wait_for((intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)) &({ const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (((1) * 1000))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if ((((intel_de_read (i915, (((&(i915)->__info)->gen) >= 12 ? ((const i915_reg_t){ .reg = (((0x6641C) + (cpu_transcoder) * ((0x6651C ) - (0x6641C)))) }) : ((const i915_reg_t){ .reg = ((((const u32 []){ 0x66800, 0x66500, 0x66600, 0x66700, 0x66A00, 0x66900 }) [port]) + (0x1C)) }))) & ((1UL << (19)) | (1UL << (20)))) == ((1UL << (19)) | (1UL << (20)))))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range (wait__, wait__ * 2); if (wait__ < ((1000))) wait__ <<= 1; } ret__; }) |
1569 | (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC)) ==({ const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (((1) * 1000))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if ((((intel_de_read (i915, (((&(i915)->__info)->gen) >= 12 ? ((const i915_reg_t){ .reg = (((0x6641C) + (cpu_transcoder) * ((0x6651C ) - (0x6641C)))) }) : ((const i915_reg_t){ .reg = ((((const u32 []){ 0x66800, 0x66500, 0x66600, 0x66700, 0x66A00, 0x66900 }) [port]) + (0x1C)) }))) & ((1UL << (19)) | (1UL << (20)))) == ((1UL << (19)) | (1UL << (20)))))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range (wait__, wait__ * 2); if (wait__ < ((1000))) wait__ <<= 1; } ret__; }) |
1570 | (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1)({ const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (((1) * 1000))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if ((((intel_de_read (i915, (((&(i915)->__info)->gen) >= 12 ? ((const i915_reg_t){ .reg = (((0x6641C) + (cpu_transcoder) * ((0x6651C ) - (0x6641C)))) }) : ((const i915_reg_t){ .reg = ((((const u32 []){ 0x66800, 0x66500, 0x66600, 0x66700, 0x66A00, 0x66900 }) [port]) + (0x1C)) }))) & ((1UL << (19)) | (1UL << (20)))) == ((1UL << (19)) | (1UL << (20)))))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range (wait__, wait__ * 2); if (wait__ < ((1000))) wait__ <<= 1; } ret__; })) { |
1571 | drm_dbg_kms(&i915->drm, "Ri' mismatch detected (%x)\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Ri' mismatch detected (%x)\n" , intel_de_read(i915, (((&(i915)->__info)->gen) >= 12 ? ((const i915_reg_t){ .reg = (((0x6641C) + (cpu_transcoder ) * ((0x6651C) - (0x6641C)))) }) : ((const i915_reg_t){ .reg = ((((const u32 []){ 0x66800, 0x66500, 0x66600, 0x66700, 0x66A00 , 0x66900 })[port]) + (0x1C)) })))) |
1572 | intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder,drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Ri' mismatch detected (%x)\n" , intel_de_read(i915, (((&(i915)->__info)->gen) >= 12 ? ((const i915_reg_t){ .reg = (((0x6641C) + (cpu_transcoder ) * ((0x6651C) - (0x6641C)))) }) : ((const i915_reg_t){ .reg = ((((const u32 []){ 0x66800, 0x66500, 0x66600, 0x66700, 0x66A00 , 0x66900 })[port]) + (0x1C)) })))) |
1573 | port)))drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Ri' mismatch detected (%x)\n" , intel_de_read(i915, (((&(i915)->__info)->gen) >= 12 ? ((const i915_reg_t){ .reg = (((0x6641C) + (cpu_transcoder ) * ((0x6651C) - (0x6641C)))) }) : ((const i915_reg_t){ .reg = ((((const u32 []){ 0x66800, 0x66500, 0x66600, 0x66700, 0x66A00 , 0x66900 })[port]) + (0x1C)) })))); |
1574 | return false0; |
1575 | } |
1576 | return true1; |
1577 | } |
1578 | |
1579 | static |
1580 | bool_Bool intel_hdmi_hdcp_check_link(struct intel_digital_port *dig_port, |
1581 | struct intel_connector *connector) |
1582 | { |
1583 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(dig_port->base.base.dev); |
1584 | int retry; |
1585 | |
1586 | for (retry = 0; retry < 3; retry++) |
1587 | if (intel_hdmi_hdcp_check_link_once(dig_port, connector)) |
1588 | return true1; |
1589 | |
1590 | drm_err(&i915->drm, "Link check failed\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Link check failed\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
1591 | return false0; |
1592 | } |
1593 | |
1594 | struct hdcp2_hdmi_msg_timeout { |
1595 | u8 msg_id; |
1596 | u16 timeout; |
1597 | }; |
1598 | |
1599 | static const struct hdcp2_hdmi_msg_timeout hdcp2_msg_timeout[] = { |
1600 | { HDCP_2_2_AKE_SEND_CERT3, HDCP_2_2_CERT_TIMEOUT_MS100, }, |
1601 | { HDCP_2_2_AKE_SEND_PAIRING_INFO8, HDCP_2_2_PAIRING_TIMEOUT_MS200, }, |
1602 | { HDCP_2_2_LC_SEND_LPRIME10, HDCP_2_2_HDMI_LPRIME_TIMEOUT_MS20, }, |
1603 | { HDCP_2_2_REP_SEND_RECVID_LIST12, HDCP_2_2_RECVID_LIST_TIMEOUT_MS3000, }, |
1604 | { HDCP_2_2_REP_STREAM_READY17, HDCP_2_2_STREAM_READY_TIMEOUT_MS100, }, |
1605 | }; |
1606 | |
1607 | static |
1608 | int intel_hdmi_hdcp2_read_rx_status(struct intel_digital_port *dig_port, |
1609 | u8 *rx_status) |
1610 | { |
1611 | return intel_hdmi_hdcp_read(dig_port, |
1612 | HDCP_2_2_HDMI_REG_RXSTATUS_OFFSET0x70, |
1613 | rx_status, |
1614 | HDCP_2_2_HDMI_RXSTATUS_LEN2); |
1615 | } |
1616 | |
1617 | static int get_hdcp2_msg_timeout(u8 msg_id, bool_Bool is_paired) |
1618 | { |
1619 | int i; |
1620 | |
1621 | if (msg_id == HDCP_2_2_AKE_SEND_HPRIME7) { |
1622 | if (is_paired) |
1623 | return HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS200; |
1624 | else |
1625 | return HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS1000; |
1626 | } |
1627 | |
1628 | for (i = 0; i < ARRAY_SIZE(hdcp2_msg_timeout)(sizeof((hdcp2_msg_timeout)) / sizeof((hdcp2_msg_timeout)[0]) ); i++) { |
1629 | if (hdcp2_msg_timeout[i].msg_id == msg_id) |
1630 | return hdcp2_msg_timeout[i].timeout; |
1631 | } |
1632 | |
1633 | return -EINVAL22; |
1634 | } |
1635 | |
1636 | static int |
1637 | hdcp2_detect_msg_availability(struct intel_digital_port *dig_port, |
1638 | u8 msg_id, bool_Bool *msg_ready, |
1639 | ssize_t *msg_sz) |
1640 | { |
1641 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(dig_port->base.base.dev); |
1642 | u8 rx_status[HDCP_2_2_HDMI_RXSTATUS_LEN2]; |
1643 | int ret; |
1644 | |
1645 | ret = intel_hdmi_hdcp2_read_rx_status(dig_port, rx_status); |
1646 | if (ret < 0) { |
1647 | drm_dbg_kms(&i915->drm, "rx_status read failed. Err %d\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "rx_status read failed. Err %d\n" , ret) |
1648 | ret)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "rx_status read failed. Err %d\n" , ret); |
1649 | return ret; |
1650 | } |
1651 | |
1652 | *msg_sz = ((HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(rx_status[1])((rx_status[1]) & 0x3) << 8) | |
1653 | rx_status[0]); |
1654 | |
1655 | if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST12) |
1656 | *msg_ready = (HDCP_2_2_HDMI_RXSTATUS_READY(rx_status[1])((rx_status[1]) & (1UL << (2))) && |
1657 | *msg_sz); |
1658 | else |
1659 | *msg_ready = *msg_sz; |
1660 | |
1661 | return 0; |
1662 | } |
1663 | |
1664 | static ssize_t |
1665 | intel_hdmi_hdcp2_wait_for_msg(struct intel_digital_port *dig_port, |
1666 | u8 msg_id, bool_Bool paired) |
1667 | { |
1668 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(dig_port->base.base.dev); |
1669 | bool_Bool msg_ready = false0; |
1670 | int timeout, ret; |
1671 | ssize_t msg_sz = 0; |
1672 | |
1673 | timeout = get_hdcp2_msg_timeout(msg_id, paired); |
1674 | if (timeout < 0) |
1675 | return timeout; |
1676 | |
1677 | ret = __wait_for(ret = hdcp2_detect_msg_availability(dig_port,({ const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (timeout * 1000)); long wait__ = (1000); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ret = hdcp2_detect_msg_availability(dig_port, msg_id , &msg_ready, &msg_sz); __asm volatile("" : : : "memory" ); if (!ret && msg_ready && msg_sz) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range (wait__, wait__ * 2); if (wait__ < (5 * 1000)) wait__ <<= 1; } ret__; }) |
1678 | msg_id, &msg_ready,({ const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (timeout * 1000)); long wait__ = (1000); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ret = hdcp2_detect_msg_availability(dig_port, msg_id , &msg_ready, &msg_sz); __asm volatile("" : : : "memory" ); if (!ret && msg_ready && msg_sz) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range (wait__, wait__ * 2); if (wait__ < (5 * 1000)) wait__ <<= 1; } ret__; }) |
1679 | &msg_sz),({ const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (timeout * 1000)); long wait__ = (1000); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ret = hdcp2_detect_msg_availability(dig_port, msg_id , &msg_ready, &msg_sz); __asm volatile("" : : : "memory" ); if (!ret && msg_ready && msg_sz) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range (wait__, wait__ * 2); if (wait__ < (5 * 1000)) wait__ <<= 1; } ret__; }) |
1680 | !ret && msg_ready && msg_sz, timeout * 1000,({ const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (timeout * 1000)); long wait__ = (1000); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ret = hdcp2_detect_msg_availability(dig_port, msg_id , &msg_ready, &msg_sz); __asm volatile("" : : : "memory" ); if (!ret && msg_ready && msg_sz) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range (wait__, wait__ * 2); if (wait__ < (5 * 1000)) wait__ <<= 1; } ret__; }) |
1681 | 1000, 5 * 1000)({ const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (timeout * 1000)); long wait__ = (1000); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ret = hdcp2_detect_msg_availability(dig_port, msg_id , &msg_ready, &msg_sz); __asm volatile("" : : : "memory" ); if (!ret && msg_ready && msg_sz) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range (wait__, wait__ * 2); if (wait__ < (5 * 1000)) wait__ <<= 1; } ret__; }); |
1682 | if (ret) |
1683 | drm_dbg_kms(&i915->drm, "msg_id: %d, ret: %d, timeout: %d\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "msg_id: %d, ret: %d, timeout: %d\n" , msg_id, ret, timeout) |
1684 | msg_id, ret, timeout)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "msg_id: %d, ret: %d, timeout: %d\n" , msg_id, ret, timeout); |
1685 | |
1686 | return ret ? ret : msg_sz; |
1687 | } |
1688 | |
1689 | static |
1690 | int intel_hdmi_hdcp2_write_msg(struct intel_digital_port *dig_port, |
1691 | void *buf, size_t size) |
1692 | { |
1693 | unsigned int offset; |
1694 | |
1695 | offset = HDCP_2_2_HDMI_REG_WR_MSG_OFFSET0x60; |
1696 | return intel_hdmi_hdcp_write(dig_port, offset, buf, size); |
1697 | } |
1698 | |
1699 | static |
1700 | int intel_hdmi_hdcp2_read_msg(struct intel_digital_port *dig_port, |
1701 | u8 msg_id, void *buf, size_t size) |
1702 | { |
1703 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(dig_port->base.base.dev); |
1704 | struct intel_hdmi *hdmi = &dig_port->hdmi; |
1705 | struct intel_hdcp *hdcp = &hdmi->attached_connector->hdcp; |
1706 | unsigned int offset; |
1707 | ssize_t ret; |
1708 | |
1709 | ret = intel_hdmi_hdcp2_wait_for_msg(dig_port, msg_id, |
1710 | hdcp->is_paired); |
1711 | if (ret < 0) |
1712 | return ret; |
1713 | |
1714 | /* |
1715 | * Available msg size should be equal to or lesser than the |
1716 | * available buffer. |
1717 | */ |
1718 | if (ret > size) { |
1719 | drm_dbg_kms(&i915->drm,drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "msg_sz(%zd) is more than exp size(%zu)\n" , ret, size) |
1720 | "msg_sz(%zd) is more than exp size(%zu)\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "msg_sz(%zd) is more than exp size(%zu)\n" , ret, size) |
1721 | ret, size)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "msg_sz(%zd) is more than exp size(%zu)\n" , ret, size); |
1722 | return -1; |
1723 | } |
1724 | |
1725 | offset = HDCP_2_2_HDMI_REG_RD_MSG_OFFSET0x80; |
1726 | ret = intel_hdmi_hdcp_read(dig_port, offset, buf, ret); |
1727 | if (ret) |
1728 | drm_dbg_kms(&i915->drm, "Failed to read msg_id: %d(%zd)\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Failed to read msg_id: %d(%zd)\n" , msg_id, ret) |
1729 | msg_id, ret)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Failed to read msg_id: %d(%zd)\n" , msg_id, ret); |
1730 | |
1731 | return ret; |
1732 | } |
1733 | |
1734 | static |
1735 | int intel_hdmi_hdcp2_check_link(struct intel_digital_port *dig_port) |
1736 | { |
1737 | u8 rx_status[HDCP_2_2_HDMI_RXSTATUS_LEN2]; |
1738 | int ret; |
1739 | |
1740 | ret = intel_hdmi_hdcp2_read_rx_status(dig_port, rx_status); |
1741 | if (ret) |
1742 | return ret; |
1743 | |
1744 | /* |
1745 | * Re-auth request and Link Integrity Failures are represented by |
1746 | * same bit. i.e reauth_req. |
1747 | */ |
1748 | if (HDCP_2_2_HDMI_RXSTATUS_REAUTH_REQ(rx_status[1])((rx_status[1]) & (1UL << (3)))) |
1749 | ret = HDCP_REAUTH_REQUEST; |
1750 | else if (HDCP_2_2_HDMI_RXSTATUS_READY(rx_status[1])((rx_status[1]) & (1UL << (2)))) |
1751 | ret = HDCP_TOPOLOGY_CHANGE; |
1752 | |
1753 | return ret; |
1754 | } |
1755 | |
1756 | static |
1757 | int intel_hdmi_hdcp2_capable(struct intel_digital_port *dig_port, |
1758 | bool_Bool *capable) |
1759 | { |
1760 | u8 hdcp2_version; |
1761 | int ret; |
1762 | |
1763 | *capable = false0; |
1764 | ret = intel_hdmi_hdcp_read(dig_port, HDCP_2_2_HDMI_REG_VER_OFFSET0x50, |
1765 | &hdcp2_version, sizeof(hdcp2_version)); |
1766 | if (!ret && hdcp2_version & HDCP_2_2_HDMI_SUPPORT_MASK(1UL << (2))) |
1767 | *capable = true1; |
1768 | |
1769 | return ret; |
1770 | } |
1771 | |
1772 | static const struct intel_hdcp_shim intel_hdmi_hdcp_shim = { |
1773 | .write_an_aksv = intel_hdmi_hdcp_write_an_aksv, |
1774 | .read_bksv = intel_hdmi_hdcp_read_bksv, |
1775 | .read_bstatus = intel_hdmi_hdcp_read_bstatus, |
1776 | .repeater_present = intel_hdmi_hdcp_repeater_present, |
1777 | .read_ri_prime = intel_hdmi_hdcp_read_ri_prime, |
1778 | .read_ksv_ready = intel_hdmi_hdcp_read_ksv_ready, |
1779 | .read_ksv_fifo = intel_hdmi_hdcp_read_ksv_fifo, |
1780 | .read_v_prime_part = intel_hdmi_hdcp_read_v_prime_part, |
1781 | .toggle_signalling = intel_hdmi_hdcp_toggle_signalling, |
1782 | .check_link = intel_hdmi_hdcp_check_link, |
1783 | .write_2_2_msg = intel_hdmi_hdcp2_write_msg, |
1784 | .read_2_2_msg = intel_hdmi_hdcp2_read_msg, |
1785 | .check_2_2_link = intel_hdmi_hdcp2_check_link, |
1786 | .hdcp_2_2_capable = intel_hdmi_hdcp2_capable, |
1787 | .protocol = HDCP_PROTOCOL_HDMI, |
1788 | }; |
1789 | |
1790 | static void intel_hdmi_prepare(struct intel_encoder *encoder, |
1791 | const struct intel_crtc_state *crtc_state) |
1792 | { |
1793 | struct drm_device *dev = encoder->base.dev; |
1794 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev); |
1795 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
1796 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
1797 | const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; |
1798 | u32 hdmi_val; |
1799 | |
1800 | intel_dp_dual_mode_set_tmds_output(intel_hdmi, true1); |
1801 | |
1802 | hdmi_val = SDVO_ENCODING_HDMI(2 << 10); |
1803 | if (!HAS_PCH_SPLIT(dev_priv)(((dev_priv)->pch_type) != PCH_NONE) && crtc_state->limited_color_range) |
1804 | hdmi_val |= HDMI_COLOR_RANGE_16_235(1 << 8); |
1805 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC(1<<2)) |
1806 | hdmi_val |= SDVO_VSYNC_ACTIVE_HIGH(1 << 4); |
1807 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC(1<<0)) |
1808 | hdmi_val |= SDVO_HSYNC_ACTIVE_HIGH(1 << 3); |
1809 | |
1810 | if (crtc_state->pipe_bpp > 24) |
1811 | hdmi_val |= HDMI_COLOR_FORMAT_12bpc(3 << 26); |
1812 | else |
1813 | hdmi_val |= SDVO_COLOR_FORMAT_8bpc(0 << 26); |
1814 | |
1815 | if (crtc_state->has_hdmi_sink) |
1816 | hdmi_val |= HDMI_MODE_SELECT_HDMI(1 << 9); |
1817 | |
1818 | if (HAS_PCH_CPT(dev_priv)(((dev_priv)->pch_type) == PCH_CPT)) |
1819 | hdmi_val |= SDVO_PIPE_SEL_CPT(crtc->pipe)((crtc->pipe) << 29); |
1820 | else if (IS_CHERRYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) |
1821 | hdmi_val |= SDVO_PIPE_SEL_CHV(crtc->pipe)((crtc->pipe) << 24); |
1822 | else |
1823 | hdmi_val |= SDVO_PIPE_SEL(crtc->pipe)((crtc->pipe) << 30); |
1824 | |
1825 | intel_de_write(dev_priv, intel_hdmi->hdmi_reg, hdmi_val); |
1826 | intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); |
1827 | } |
1828 | |
1829 | static bool_Bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, |
1830 | enum pipe *pipe) |
1831 | { |
1832 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1833 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
1834 | intel_wakeref_t wakeref; |
1835 | bool_Bool ret; |
1836 | |
1837 | wakeref = intel_display_power_get_if_enabled(dev_priv, |
1838 | encoder->power_domain); |
1839 | if (!wakeref) |
1840 | return false0; |
1841 | |
1842 | ret = intel_sdvo_port_enabled(dev_priv, intel_hdmi->hdmi_reg, pipe); |
1843 | |
1844 | intel_display_power_put(dev_priv, encoder->power_domain, wakeref); |
1845 | |
1846 | return ret; |
1847 | } |
1848 | |
1849 | static void intel_hdmi_get_config(struct intel_encoder *encoder, |
1850 | struct intel_crtc_state *pipe_config) |
1851 | { |
1852 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
1853 | struct drm_device *dev = encoder->base.dev; |
1854 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev); |
1855 | u32 tmp, flags = 0; |
1856 | int dotclock; |
1857 | |
1858 | pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI)(1UL << (INTEL_OUTPUT_HDMI)); |
1859 | |
1860 | tmp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg); |
1861 | |
1862 | if (tmp & SDVO_HSYNC_ACTIVE_HIGH(1 << 3)) |
1863 | flags |= DRM_MODE_FLAG_PHSYNC(1<<0); |
1864 | else |
1865 | flags |= DRM_MODE_FLAG_NHSYNC(1<<1); |
1866 | |
1867 | if (tmp & SDVO_VSYNC_ACTIVE_HIGH(1 << 4)) |
1868 | flags |= DRM_MODE_FLAG_PVSYNC(1<<2); |
1869 | else |
1870 | flags |= DRM_MODE_FLAG_NVSYNC(1<<3); |
1871 | |
1872 | if (tmp & HDMI_MODE_SELECT_HDMI(1 << 9)) |
1873 | pipe_config->has_hdmi_sink = true1; |
1874 | |
1875 | pipe_config->infoframes.enable |= |
1876 | intel_hdmi_infoframes_enabled(encoder, pipe_config); |
1877 | |
1878 | if (pipe_config->infoframes.enable) |
1879 | pipe_config->has_infoframe = true1; |
1880 | |
1881 | if (tmp & HDMI_AUDIO_ENABLE(1 << 6)) |
1882 | pipe_config->has_audio = true1; |
1883 | |
1884 | if (!HAS_PCH_SPLIT(dev_priv)(((dev_priv)->pch_type) != PCH_NONE) && |
1885 | tmp & HDMI_COLOR_RANGE_16_235(1 << 8)) |
1886 | pipe_config->limited_color_range = true1; |
1887 | |
1888 | pipe_config->hw.adjusted_mode.flags |= flags; |
1889 | |
1890 | if ((tmp & SDVO_COLOR_FORMAT_MASK(7 << 26)) == HDMI_COLOR_FORMAT_12bpc(3 << 26)) |
1891 | dotclock = pipe_config->port_clock * 2 / 3; |
1892 | else |
1893 | dotclock = pipe_config->port_clock; |
1894 | |
1895 | if (pipe_config->pixel_multiplier) |
1896 | dotclock /= pipe_config->pixel_multiplier; |
1897 | |
1898 | pipe_config->hw.adjusted_mode.crtc_clock = dotclock; |
1899 | |
1900 | pipe_config->lane_count = 4; |
1901 | |
1902 | intel_hdmi_read_gcp_infoframe(encoder, pipe_config); |
1903 | |
1904 | intel_read_infoframe(encoder, pipe_config, |
1905 | HDMI_INFOFRAME_TYPE_AVI, |
1906 | &pipe_config->infoframes.avi); |
1907 | intel_read_infoframe(encoder, pipe_config, |
1908 | HDMI_INFOFRAME_TYPE_SPD, |
1909 | &pipe_config->infoframes.spd); |
1910 | intel_read_infoframe(encoder, pipe_config, |
1911 | HDMI_INFOFRAME_TYPE_VENDOR, |
1912 | &pipe_config->infoframes.hdmi); |
1913 | } |
1914 | |
1915 | static void intel_enable_hdmi_audio(struct intel_encoder *encoder, |
1916 | const struct intel_crtc_state *pipe_config, |
1917 | const struct drm_connector_state *conn_state) |
1918 | { |
1919 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(encoder->base.dev); |
1920 | struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (pipe_config->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
1921 | |
1922 | drm_WARN_ON(&i915->drm, !pipe_config->has_hdmi_sink)({ int __ret = !!((!pipe_config->has_hdmi_sink)); if (__ret ) printf("%s %s: " "%s", dev_driver_string(((&i915->drm ))->dev), "", "drm_WARN_ON(" "!pipe_config->has_hdmi_sink" ")"); __builtin_expect(!!(__ret), 0); }); |
1923 | drm_dbg_kms(&i915->drm, "Enabling HDMI audio on pipe %c\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Enabling HDMI audio on pipe %c\n" , ((crtc->pipe) + 'A')) |
1924 | pipe_name(crtc->pipe))drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Enabling HDMI audio on pipe %c\n" , ((crtc->pipe) + 'A')); |
1925 | intel_audio_codec_enable(encoder, pipe_config, conn_state); |
1926 | } |
1927 | |
1928 | static void g4x_enable_hdmi(struct intel_atomic_state *state, |
1929 | struct intel_encoder *encoder, |
1930 | const struct intel_crtc_state *pipe_config, |
1931 | const struct drm_connector_state *conn_state) |
1932 | { |
1933 | struct drm_device *dev = encoder->base.dev; |
1934 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev); |
1935 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
1936 | u32 temp; |
1937 | |
1938 | temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg); |
1939 | |
1940 | temp |= SDVO_ENABLE(1 << 31); |
1941 | if (pipe_config->has_audio) |
1942 | temp |= HDMI_AUDIO_ENABLE(1 << 6); |
1943 | |
1944 | intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); |
1945 | intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); |
1946 | |
1947 | if (pipe_config->has_audio) |
1948 | intel_enable_hdmi_audio(encoder, pipe_config, conn_state); |
1949 | } |
1950 | |
1951 | static void ibx_enable_hdmi(struct intel_atomic_state *state, |
1952 | struct intel_encoder *encoder, |
1953 | const struct intel_crtc_state *pipe_config, |
1954 | const struct drm_connector_state *conn_state) |
1955 | { |
1956 | struct drm_device *dev = encoder->base.dev; |
1957 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev); |
1958 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
1959 | u32 temp; |
1960 | |
1961 | temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg); |
1962 | |
1963 | temp |= SDVO_ENABLE(1 << 31); |
1964 | if (pipe_config->has_audio) |
1965 | temp |= HDMI_AUDIO_ENABLE(1 << 6); |
1966 | |
1967 | /* |
1968 | * HW workaround, need to write this twice for issue |
1969 | * that may result in first write getting masked. |
1970 | */ |
1971 | intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); |
1972 | intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); |
1973 | intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); |
1974 | intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); |
1975 | |
1976 | /* |
1977 | * HW workaround, need to toggle enable bit off and on |
1978 | * for 12bpc with pixel repeat. |
1979 | * |
1980 | * FIXME: BSpec says this should be done at the end of |
1981 | * of the modeset sequence, so not sure if this isn't too soon. |
1982 | */ |
1983 | if (pipe_config->pipe_bpp > 24 && |
1984 | pipe_config->pixel_multiplier > 1) { |
1985 | intel_de_write(dev_priv, intel_hdmi->hdmi_reg, |
1986 | temp & ~SDVO_ENABLE(1 << 31)); |
1987 | intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); |
1988 | |
1989 | /* |
1990 | * HW workaround, need to write this twice for issue |
1991 | * that may result in first write getting masked. |
1992 | */ |
1993 | intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); |
1994 | intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); |
1995 | intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); |
1996 | intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); |
1997 | } |
1998 | |
1999 | if (pipe_config->has_audio) |
2000 | intel_enable_hdmi_audio(encoder, pipe_config, conn_state); |
2001 | } |
2002 | |
2003 | static void cpt_enable_hdmi(struct intel_atomic_state *state, |
2004 | struct intel_encoder *encoder, |
2005 | const struct intel_crtc_state *pipe_config, |
2006 | const struct drm_connector_state *conn_state) |
2007 | { |
2008 | struct drm_device *dev = encoder->base.dev; |
2009 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev); |
2010 | struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (pipe_config->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
2011 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
2012 | enum pipe pipe = crtc->pipe; |
2013 | u32 temp; |
2014 | |
2015 | temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg); |
2016 | |
2017 | temp |= SDVO_ENABLE(1 << 31); |
2018 | if (pipe_config->has_audio) |
2019 | temp |= HDMI_AUDIO_ENABLE(1 << 6); |
2020 | |
2021 | /* |
2022 | * WaEnableHDMI8bpcBefore12bpc:snb,ivb |
2023 | * |
2024 | * The procedure for 12bpc is as follows: |
2025 | * 1. disable HDMI clock gating |
2026 | * 2. enable HDMI with 8bpc |
2027 | * 3. enable HDMI with 12bpc |
2028 | * 4. enable HDMI clock gating |
2029 | */ |
2030 | |
2031 | if (pipe_config->pipe_bpp > 24) { |
2032 | intel_de_write(dev_priv, TRANS_CHICKEN1(pipe)((const i915_reg_t){ .reg = (((0xf0060) + (pipe) * ((0xf1060) - (0xf0060)))) }), |
2033 | intel_de_read(dev_priv, TRANS_CHICKEN1(pipe)((const i915_reg_t){ .reg = (((0xf0060) + (pipe) * ((0xf1060) - (0xf0060)))) })) | TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE(1 << 10)); |
2034 | |
2035 | temp &= ~SDVO_COLOR_FORMAT_MASK(7 << 26); |
2036 | temp |= SDVO_COLOR_FORMAT_8bpc(0 << 26); |
2037 | } |
2038 | |
2039 | intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); |
2040 | intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); |
2041 | |
2042 | if (pipe_config->pipe_bpp > 24) { |
2043 | temp &= ~SDVO_COLOR_FORMAT_MASK(7 << 26); |
2044 | temp |= HDMI_COLOR_FORMAT_12bpc(3 << 26); |
2045 | |
2046 | intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); |
2047 | intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); |
2048 | |
2049 | intel_de_write(dev_priv, TRANS_CHICKEN1(pipe)((const i915_reg_t){ .reg = (((0xf0060) + (pipe) * ((0xf1060) - (0xf0060)))) }), |
2050 | intel_de_read(dev_priv, TRANS_CHICKEN1(pipe)((const i915_reg_t){ .reg = (((0xf0060) + (pipe) * ((0xf1060) - (0xf0060)))) })) & ~TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE(1 << 10)); |
2051 | } |
2052 | |
2053 | if (pipe_config->has_audio) |
2054 | intel_enable_hdmi_audio(encoder, pipe_config, conn_state); |
2055 | } |
2056 | |
2057 | static void vlv_enable_hdmi(struct intel_atomic_state *state, |
2058 | struct intel_encoder *encoder, |
2059 | const struct intel_crtc_state *pipe_config, |
2060 | const struct drm_connector_state *conn_state) |
2061 | { |
2062 | } |
2063 | |
2064 | static void intel_disable_hdmi(struct intel_atomic_state *state, |
2065 | struct intel_encoder *encoder, |
2066 | const struct intel_crtc_state *old_crtc_state, |
2067 | const struct drm_connector_state *old_conn_state) |
2068 | { |
2069 | struct drm_device *dev = encoder->base.dev; |
2070 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev); |
2071 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
2072 | struct intel_digital_port *dig_port = |
2073 | hdmi_to_dig_port(intel_hdmi); |
2074 | struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (old_crtc_state->uapi.crtc); (struct intel_crtc *)( (char *)__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
2075 | u32 temp; |
2076 | |
2077 | temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg); |
2078 | |
2079 | temp &= ~(SDVO_ENABLE(1 << 31) | HDMI_AUDIO_ENABLE(1 << 6)); |
2080 | intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); |
2081 | intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); |
2082 | |
2083 | /* |
2084 | * HW workaround for IBX, we need to move the port |
2085 | * to transcoder A after disabling it to allow the |
2086 | * matching DP port to be enabled on transcoder A. |
2087 | */ |
2088 | if (HAS_PCH_IBX(dev_priv)(((dev_priv)->pch_type) == PCH_IBX) && crtc->pipe == PIPE_B) { |
2089 | /* |
2090 | * We get CPU/PCH FIFO underruns on the other pipe when |
2091 | * doing the workaround. Sweep them under the rug. |
2092 | */ |
2093 | intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false0); |
2094 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false0); |
2095 | |
2096 | temp &= ~SDVO_PIPE_SEL_MASK(1 << 30); |
2097 | temp |= SDVO_ENABLE(1 << 31) | SDVO_PIPE_SEL(PIPE_A)((PIPE_A) << 30); |
2098 | /* |
2099 | * HW workaround, need to write this twice for issue |
2100 | * that may result in first write getting masked. |
2101 | */ |
2102 | intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); |
2103 | intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); |
2104 | intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); |
2105 | intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); |
2106 | |
2107 | temp &= ~SDVO_ENABLE(1 << 31); |
2108 | intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp); |
2109 | intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg); |
2110 | |
2111 | intel_wait_for_vblank_if_active(dev_priv, PIPE_A); |
2112 | intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true1); |
2113 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true1); |
2114 | } |
2115 | |
2116 | dig_port->set_infoframes(encoder, |
2117 | false0, |
2118 | old_crtc_state, old_conn_state); |
2119 | |
2120 | intel_dp_dual_mode_set_tmds_output(intel_hdmi, false0); |
2121 | } |
2122 | |
2123 | static void g4x_disable_hdmi(struct intel_atomic_state *state, |
2124 | struct intel_encoder *encoder, |
2125 | const struct intel_crtc_state *old_crtc_state, |
2126 | const struct drm_connector_state *old_conn_state) |
2127 | { |
2128 | if (old_crtc_state->has_audio) |
2129 | intel_audio_codec_disable(encoder, |
2130 | old_crtc_state, old_conn_state); |
2131 | |
2132 | intel_disable_hdmi(state, encoder, old_crtc_state, old_conn_state); |
2133 | } |
2134 | |
2135 | static void pch_disable_hdmi(struct intel_atomic_state *state, |
2136 | struct intel_encoder *encoder, |
2137 | const struct intel_crtc_state *old_crtc_state, |
2138 | const struct drm_connector_state *old_conn_state) |
2139 | { |
2140 | if (old_crtc_state->has_audio) |
2141 | intel_audio_codec_disable(encoder, |
2142 | old_crtc_state, old_conn_state); |
2143 | } |
2144 | |
2145 | static void pch_post_disable_hdmi(struct intel_atomic_state *state, |
2146 | struct intel_encoder *encoder, |
2147 | const struct intel_crtc_state *old_crtc_state, |
2148 | const struct drm_connector_state *old_conn_state) |
2149 | { |
2150 | intel_disable_hdmi(state, encoder, old_crtc_state, old_conn_state); |
2151 | } |
2152 | |
2153 | static int intel_hdmi_source_max_tmds_clock(struct intel_encoder *encoder) |
2154 | { |
2155 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
2156 | int max_tmds_clock, vbt_max_tmds_clock; |
2157 | |
2158 | if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 10 || IS_GEMINILAKE(dev_priv)IS_PLATFORM(dev_priv, INTEL_GEMINILAKE)) |
2159 | max_tmds_clock = 594000; |
2160 | else if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 8 || IS_HASWELL(dev_priv)IS_PLATFORM(dev_priv, INTEL_HASWELL)) |
2161 | max_tmds_clock = 300000; |
2162 | else if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 5) |
2163 | max_tmds_clock = 225000; |
2164 | else |
2165 | max_tmds_clock = 165000; |
2166 | |
2167 | vbt_max_tmds_clock = intel_bios_max_tmds_clock(encoder); |
2168 | if (vbt_max_tmds_clock) |
2169 | max_tmds_clock = min(max_tmds_clock, vbt_max_tmds_clock)(((max_tmds_clock)<(vbt_max_tmds_clock))?(max_tmds_clock): (vbt_max_tmds_clock)); |
2170 | |
2171 | return max_tmds_clock; |
2172 | } |
2173 | |
2174 | static bool_Bool intel_has_hdmi_sink(struct intel_hdmi *hdmi, |
2175 | const struct drm_connector_state *conn_state) |
2176 | { |
2177 | return hdmi->has_hdmi_sink && |
2178 | READ_ONCE(to_intel_digital_connector_state(conn_state)->force_audio)({ typeof(({ const __typeof( ((struct intel_digital_connector_state *)0)->base ) *__mptr = (conn_state); (struct intel_digital_connector_state *)( (char *)__mptr - __builtin_offsetof(struct intel_digital_connector_state , base) );})->force_audio) __tmp = *(volatile typeof(({ const __typeof( ((struct intel_digital_connector_state *)0)->base ) *__mptr = (conn_state); (struct intel_digital_connector_state *)( (char *)__mptr - __builtin_offsetof(struct intel_digital_connector_state , base) );})->force_audio) *)&(({ const __typeof( ((struct intel_digital_connector_state *)0)->base ) *__mptr = (conn_state ); (struct intel_digital_connector_state *)( (char *)__mptr - __builtin_offsetof(struct intel_digital_connector_state, base ) );})->force_audio); membar_datadep_consumer(); __tmp; }) != HDMI_AUDIO_OFF_DVI; |
2179 | } |
2180 | |
2181 | static int hdmi_port_clock_limit(struct intel_hdmi *hdmi, |
2182 | bool_Bool respect_downstream_limits, |
2183 | bool_Bool has_hdmi_sink) |
2184 | { |
2185 | struct intel_encoder *encoder = &hdmi_to_dig_port(hdmi)->base; |
2186 | int max_tmds_clock = intel_hdmi_source_max_tmds_clock(encoder); |
2187 | |
2188 | if (respect_downstream_limits) { |
2189 | struct intel_connector *connector = hdmi->attached_connector; |
2190 | const struct drm_display_info *info = &connector->base.display_info; |
2191 | |
2192 | if (hdmi->dp_dual_mode.max_tmds_clock) |
2193 | max_tmds_clock = min(max_tmds_clock,(((max_tmds_clock)<(hdmi->dp_dual_mode.max_tmds_clock)) ?(max_tmds_clock):(hdmi->dp_dual_mode.max_tmds_clock)) |
2194 | hdmi->dp_dual_mode.max_tmds_clock)(((max_tmds_clock)<(hdmi->dp_dual_mode.max_tmds_clock)) ?(max_tmds_clock):(hdmi->dp_dual_mode.max_tmds_clock)); |
2195 | |
2196 | if (info->max_tmds_clock) |
2197 | max_tmds_clock = min(max_tmds_clock,(((max_tmds_clock)<(info->max_tmds_clock))?(max_tmds_clock ):(info->max_tmds_clock)) |
2198 | info->max_tmds_clock)(((max_tmds_clock)<(info->max_tmds_clock))?(max_tmds_clock ):(info->max_tmds_clock)); |
2199 | else if (!has_hdmi_sink) |
2200 | max_tmds_clock = min(max_tmds_clock, 165000)(((max_tmds_clock)<(165000))?(max_tmds_clock):(165000)); |
2201 | } |
2202 | |
2203 | return max_tmds_clock; |
2204 | } |
2205 | |
2206 | static enum drm_mode_status |
2207 | hdmi_port_clock_valid(struct intel_hdmi *hdmi, |
2208 | int clock, bool_Bool respect_downstream_limits, |
2209 | bool_Bool has_hdmi_sink) |
2210 | { |
2211 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(intel_hdmi_to_dev(hdmi)); |
2212 | |
2213 | if (clock < 25000) |
2214 | return MODE_CLOCK_LOW; |
2215 | if (clock > hdmi_port_clock_limit(hdmi, respect_downstream_limits, |
2216 | has_hdmi_sink)) |
2217 | return MODE_CLOCK_HIGH; |
2218 | |
2219 | /* GLK DPLL can't generate 446-480 MHz */ |
2220 | if (IS_GEMINILAKE(dev_priv)IS_PLATFORM(dev_priv, INTEL_GEMINILAKE) && clock > 446666 && clock < 480000) |
2221 | return MODE_CLOCK_RANGE; |
2222 | |
2223 | /* BXT/GLK DPLL can't generate 223-240 MHz */ |
2224 | if (IS_GEN9_LP(dev_priv)((0 + (&(dev_priv)->__info)->gen == (9)) && ((&(dev_priv)->__info)->is_lp)) && clock > 223333 && clock < 240000) |
2225 | return MODE_CLOCK_RANGE; |
2226 | |
2227 | /* CHV DPLL can't generate 216-240 MHz */ |
2228 | if (IS_CHERRYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW) && clock > 216000 && clock < 240000) |
2229 | return MODE_CLOCK_RANGE; |
2230 | |
2231 | return MODE_OK; |
2232 | } |
2233 | |
2234 | static enum drm_mode_status |
2235 | intel_hdmi_mode_valid(struct drm_connector *connector, |
2236 | struct drm_display_mode *mode) |
2237 | { |
2238 | struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );})); |
2239 | struct drm_device *dev = intel_hdmi_to_dev(hdmi); |
2240 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev); |
2241 | enum drm_mode_status status; |
2242 | int clock = mode->clock; |
2243 | int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; |
2244 | bool_Bool has_hdmi_sink = intel_has_hdmi_sink(hdmi, connector->state); |
2245 | |
2246 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN(1<<5)) |
2247 | return MODE_NO_DBLESCAN; |
2248 | |
2249 | if ((mode->flags & DRM_MODE_FLAG_3D_MASK(0x1f<<14)) == DRM_MODE_FLAG_3D_FRAME_PACKING(1<<14)) |
2250 | clock *= 2; |
2251 | |
2252 | if (clock > max_dotclk) |
2253 | return MODE_CLOCK_HIGH; |
2254 | |
2255 | if (mode->flags & DRM_MODE_FLAG_DBLCLK(1<<12)) { |
2256 | if (!has_hdmi_sink) |
2257 | return MODE_CLOCK_LOW; |
2258 | clock *= 2; |
2259 | } |
2260 | |
2261 | if (drm_mode_is_420_only(&connector->display_info, mode)) |
2262 | clock /= 2; |
2263 | |
2264 | /* check if we can do 8bpc */ |
2265 | status = hdmi_port_clock_valid(hdmi, clock, true1, has_hdmi_sink); |
2266 | |
2267 | if (has_hdmi_sink) { |
2268 | /* if we can't do 8bpc we may still be able to do 12bpc */ |
2269 | if (status != MODE_OK && !HAS_GMCH(dev_priv)((&(dev_priv)->__info)->display.has_gmch)) |
2270 | status = hdmi_port_clock_valid(hdmi, clock * 3 / 2, |
2271 | true1, has_hdmi_sink); |
2272 | |
2273 | /* if we can't do 8,12bpc we may still be able to do 10bpc */ |
2274 | if (status != MODE_OK && INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 11) |
2275 | status = hdmi_port_clock_valid(hdmi, clock * 5 / 4, |
2276 | true1, has_hdmi_sink); |
2277 | } |
2278 | if (status != MODE_OK) |
2279 | return status; |
2280 | |
2281 | return intel_mode_valid_max_plane_size(dev_priv, mode); |
2282 | } |
2283 | |
2284 | bool_Bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state, |
2285 | int bpc, bool_Bool has_hdmi_sink, bool_Bool ycbcr420_output) |
2286 | { |
2287 | struct drm_atomic_state *state = crtc_state->uapi.state; |
2288 | struct drm_connector_state *connector_state; |
2289 | struct drm_connector *connector; |
2290 | int i; |
2291 | |
2292 | if (crtc_state->pipe_bpp < bpc * 3) |
2293 | return false0; |
2294 | |
2295 | if (!has_hdmi_sink) |
2296 | return false0; |
2297 | |
2298 | for_each_new_connector_in_state(state, connector, connector_state, i)for ((i) = 0; (i) < (state)->num_connector; (i)++) if ( !((state)->connectors[i].ptr && ((connector) = (state )->connectors[i].ptr, (void)(connector) , (connector_state ) = (state)->connectors[i].new_state, (void)(connector_state ) , 1))) {} else { |
2299 | const struct drm_display_info *info = &connector->display_info; |
2300 | |
2301 | if (connector_state->crtc != crtc_state->uapi.crtc) |
2302 | continue; |
2303 | |
2304 | if (ycbcr420_output) { |
2305 | const struct drm_hdmi_info *hdmi = &info->hdmi; |
2306 | |
2307 | if (bpc == 12 && !(hdmi->y420_dc_modes & |
2308 | DRM_EDID_YCBCR420_DC_36(1 << 1))) |
2309 | return false0; |
2310 | else if (bpc == 10 && !(hdmi->y420_dc_modes & |
2311 | DRM_EDID_YCBCR420_DC_30(1 << 0))) |
2312 | return false0; |
2313 | } else { |
2314 | if (bpc == 12 && !(info->edid_hdmi_dc_modes & |
2315 | DRM_EDID_HDMI_DC_36(1 << 5))) |
2316 | return false0; |
2317 | else if (bpc == 10 && !(info->edid_hdmi_dc_modes & |
2318 | DRM_EDID_HDMI_DC_30(1 << 4))) |
2319 | return false0; |
2320 | } |
2321 | } |
2322 | |
2323 | return true1; |
2324 | } |
2325 | |
2326 | static bool_Bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state, |
2327 | int bpc) |
2328 | { |
2329 | struct drm_i915_privateinteldrm_softc *dev_priv = |
2330 | to_i915(crtc_state->uapi.crtc->dev); |
2331 | const struct drm_display_mode *adjusted_mode = |
2332 | &crtc_state->hw.adjusted_mode; |
2333 | |
2334 | if (HAS_GMCH(dev_priv)((&(dev_priv)->__info)->display.has_gmch)) |
2335 | return false0; |
2336 | |
2337 | if (bpc == 10 && INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) < 11) |
2338 | return false0; |
2339 | |
2340 | /* |
2341 | * HDMI deep color affects the clocks, so it's only possible |
2342 | * when not cloning with other encoder types. |
2343 | */ |
2344 | if (crtc_state->output_types != BIT(INTEL_OUTPUT_HDMI)(1UL << (INTEL_OUTPUT_HDMI))) |
2345 | return false0; |
2346 | |
2347 | /* Display Wa_1405510057:icl,ehl */ |
2348 | if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 && |
2349 | bpc == 10 && IS_GEN(dev_priv, 11)(0 + (&(dev_priv)->__info)->gen == (11)) && |
2350 | (adjusted_mode->crtc_hblank_end - |
2351 | adjusted_mode->crtc_hblank_start) % 8 == 2) |
2352 | return false0; |
2353 | |
2354 | return intel_hdmi_deep_color_possible(crtc_state, bpc, |
2355 | crtc_state->has_hdmi_sink, |
2356 | crtc_state->output_format == |
2357 | INTEL_OUTPUT_FORMAT_YCBCR420); |
2358 | } |
2359 | |
2360 | static int |
2361 | intel_hdmi_ycbcr420_config(struct intel_crtc_state *crtc_state, |
2362 | const struct drm_connector_state *conn_state) |
2363 | { |
2364 | struct drm_connector *connector = conn_state->connector; |
2365 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->dev); |
2366 | const struct drm_display_mode *adjusted_mode = |
2367 | &crtc_state->hw.adjusted_mode; |
2368 | |
2369 | if (!drm_mode_is_420_only(&connector->display_info, adjusted_mode)) |
2370 | return 0; |
2371 | |
2372 | if (!connector->ycbcr_420_allowed) { |
2373 | drm_err(&i915->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Platform doesn't support YCBCR420 output\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__) |
2374 | "Platform doesn't support YCBCR420 output\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Platform doesn't support YCBCR420 output\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
2375 | return -EINVAL22; |
2376 | } |
2377 | |
2378 | crtc_state->output_format = INTEL_OUTPUT_FORMAT_YCBCR420; |
2379 | |
2380 | return intel_pch_panel_fitting(crtc_state, conn_state); |
2381 | } |
2382 | |
2383 | static int intel_hdmi_port_clock(int clock, int bpc) |
2384 | { |
2385 | /* |
2386 | * Need to adjust the port link by: |
2387 | * 1.5x for 12bpc |
2388 | * 1.25x for 10bpc |
2389 | */ |
2390 | return clock * bpc / 8; |
2391 | } |
2392 | |
2393 | static int intel_hdmi_compute_bpc(struct intel_encoder *encoder, |
2394 | struct intel_crtc_state *crtc_state, |
2395 | int clock) |
2396 | { |
2397 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
2398 | int bpc; |
2399 | |
2400 | for (bpc = 12; bpc >= 10; bpc -= 2) { |
2401 | if (hdmi_deep_color_possible(crtc_state, bpc) && |
2402 | hdmi_port_clock_valid(intel_hdmi, |
2403 | intel_hdmi_port_clock(clock, bpc), |
2404 | true1, crtc_state->has_hdmi_sink) == MODE_OK) |
2405 | return bpc; |
2406 | } |
2407 | |
2408 | return 8; |
2409 | } |
2410 | |
2411 | static int intel_hdmi_compute_clock(struct intel_encoder *encoder, |
2412 | struct intel_crtc_state *crtc_state) |
2413 | { |
2414 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(encoder->base.dev); |
2415 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
2416 | const struct drm_display_mode *adjusted_mode = |
2417 | &crtc_state->hw.adjusted_mode; |
2418 | int bpc, clock = adjusted_mode->crtc_clock; |
2419 | |
2420 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK(1<<12)) |
2421 | clock *= 2; |
2422 | |
2423 | /* YCBCR420 TMDS rate requirement is half the pixel clock */ |
2424 | if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) |
2425 | clock /= 2; |
2426 | |
2427 | bpc = intel_hdmi_compute_bpc(encoder, crtc_state, clock); |
2428 | |
2429 | crtc_state->port_clock = intel_hdmi_port_clock(clock, bpc); |
2430 | |
2431 | /* |
2432 | * pipe_bpp could already be below 8bpc due to |
2433 | * FDI bandwidth constraints. We shouldn't bump it |
2434 | * back up to 8bpc in that case. |
2435 | */ |
2436 | if (crtc_state->pipe_bpp > bpc * 3) |
2437 | crtc_state->pipe_bpp = bpc * 3; |
2438 | |
2439 | drm_dbg_kms(&i915->drm,drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "picking %d bpc for HDMI output (pipe bpp: %d)\n" , bpc, crtc_state->pipe_bpp) |
2440 | "picking %d bpc for HDMI output (pipe bpp: %d)\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "picking %d bpc for HDMI output (pipe bpp: %d)\n" , bpc, crtc_state->pipe_bpp) |
2441 | bpc, crtc_state->pipe_bpp)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "picking %d bpc for HDMI output (pipe bpp: %d)\n" , bpc, crtc_state->pipe_bpp); |
2442 | |
2443 | if (hdmi_port_clock_valid(intel_hdmi, crtc_state->port_clock, |
2444 | false0, crtc_state->has_hdmi_sink) != MODE_OK) { |
2445 | drm_dbg_kms(&i915->drm,drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "unsupported HDMI clock (%d kHz), rejecting mode\n" , crtc_state->port_clock) |
2446 | "unsupported HDMI clock (%d kHz), rejecting mode\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "unsupported HDMI clock (%d kHz), rejecting mode\n" , crtc_state->port_clock) |
2447 | crtc_state->port_clock)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "unsupported HDMI clock (%d kHz), rejecting mode\n" , crtc_state->port_clock); |
2448 | return -EINVAL22; |
2449 | } |
2450 | |
2451 | return 0; |
2452 | } |
2453 | |
2454 | bool_Bool intel_hdmi_limited_color_range(const struct intel_crtc_state *crtc_state, |
2455 | const struct drm_connector_state *conn_state) |
2456 | { |
2457 | const struct intel_digital_connector_state *intel_conn_state = |
2458 | to_intel_digital_connector_state(conn_state)({ const __typeof( ((struct intel_digital_connector_state *)0 )->base ) *__mptr = (conn_state); (struct intel_digital_connector_state *)( (char *)__mptr - __builtin_offsetof(struct intel_digital_connector_state , base) );}); |
2459 | const struct drm_display_mode *adjusted_mode = |
2460 | &crtc_state->hw.adjusted_mode; |
2461 | |
2462 | /* |
2463 | * Our YCbCr output is always limited range. |
2464 | * crtc_state->limited_color_range only applies to RGB, |
2465 | * and it must never be set for YCbCr or we risk setting |
2466 | * some conflicting bits in PIPECONF which will mess up |
2467 | * the colors on the monitor. |
2468 | */ |
2469 | if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) |
2470 | return false0; |
2471 | |
2472 | if (intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_AUTO) { |
2473 | /* See CEA-861-E - 5.1 Default Encoding Parameters */ |
2474 | return crtc_state->has_hdmi_sink && |
2475 | drm_default_rgb_quant_range(adjusted_mode) == |
2476 | HDMI_QUANTIZATION_RANGE_LIMITED; |
2477 | } else { |
2478 | return intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_LIMITED; |
2479 | } |
2480 | } |
2481 | |
2482 | static bool_Bool intel_hdmi_has_audio(struct intel_encoder *encoder, |
2483 | const struct intel_crtc_state *crtc_state, |
2484 | const struct drm_connector_state *conn_state) |
2485 | { |
2486 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
2487 | const struct intel_digital_connector_state *intel_conn_state = |
2488 | to_intel_digital_connector_state(conn_state)({ const __typeof( ((struct intel_digital_connector_state *)0 )->base ) *__mptr = (conn_state); (struct intel_digital_connector_state *)( (char *)__mptr - __builtin_offsetof(struct intel_digital_connector_state , base) );}); |
2489 | |
2490 | if (!crtc_state->has_hdmi_sink) |
2491 | return false0; |
2492 | |
2493 | if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO) |
2494 | return intel_hdmi->has_audio; |
2495 | else |
2496 | return intel_conn_state->force_audio == HDMI_AUDIO_ON; |
2497 | } |
2498 | |
2499 | int intel_hdmi_compute_config(struct intel_encoder *encoder, |
2500 | struct intel_crtc_state *pipe_config, |
2501 | struct drm_connector_state *conn_state) |
2502 | { |
2503 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
2504 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
2505 | struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; |
2506 | struct drm_connector *connector = conn_state->connector; |
2507 | struct drm_scdc *scdc = &connector->display_info.hdmi.scdc; |
2508 | int ret; |
2509 | |
2510 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN(1<<5)) |
2511 | return -EINVAL22; |
2512 | |
2513 | pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; |
2514 | pipe_config->has_hdmi_sink = intel_has_hdmi_sink(intel_hdmi, |
2515 | conn_state); |
2516 | |
2517 | if (pipe_config->has_hdmi_sink) |
2518 | pipe_config->has_infoframe = true1; |
2519 | |
2520 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK(1<<12)) |
2521 | pipe_config->pixel_multiplier = 2; |
2522 | |
2523 | ret = intel_hdmi_ycbcr420_config(pipe_config, conn_state); |
2524 | if (ret) |
2525 | return ret; |
2526 | |
2527 | pipe_config->limited_color_range = |
2528 | intel_hdmi_limited_color_range(pipe_config, conn_state); |
2529 | |
2530 | if (HAS_PCH_SPLIT(dev_priv)(((dev_priv)->pch_type) != PCH_NONE) && !HAS_DDI(dev_priv)((&(dev_priv)->__info)->display.has_ddi)) |
2531 | pipe_config->has_pch_encoder = true1; |
2532 | |
2533 | pipe_config->has_audio = |
2534 | intel_hdmi_has_audio(encoder, pipe_config, conn_state); |
2535 | |
2536 | ret = intel_hdmi_compute_clock(encoder, pipe_config); |
2537 | if (ret) |
2538 | return ret; |
2539 | |
2540 | if (conn_state->picture_aspect_ratio) |
2541 | adjusted_mode->picture_aspect_ratio = |
2542 | conn_state->picture_aspect_ratio; |
2543 | |
2544 | pipe_config->lane_count = 4; |
2545 | |
2546 | if (scdc->scrambling.supported && (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 10 || |
2547 | IS_GEMINILAKE(dev_priv)IS_PLATFORM(dev_priv, INTEL_GEMINILAKE))) { |
2548 | if (scdc->scrambling.low_rates) |
2549 | pipe_config->hdmi_scrambling = true1; |
2550 | |
2551 | if (pipe_config->port_clock > 340000) { |
2552 | pipe_config->hdmi_scrambling = true1; |
2553 | pipe_config->hdmi_high_tmds_clock_ratio = true1; |
2554 | } |
2555 | } |
2556 | |
2557 | intel_hdmi_compute_gcp_infoframe(encoder, pipe_config, |
2558 | conn_state); |
2559 | |
2560 | if (!intel_hdmi_compute_avi_infoframe(encoder, pipe_config, conn_state)) { |
2561 | drm_dbg_kms(&dev_priv->drm, "bad AVI infoframe\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "bad AVI infoframe\n" ); |
2562 | return -EINVAL22; |
2563 | } |
2564 | |
2565 | if (!intel_hdmi_compute_spd_infoframe(encoder, pipe_config, conn_state)) { |
2566 | drm_dbg_kms(&dev_priv->drm, "bad SPD infoframe\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "bad SPD infoframe\n" ); |
2567 | return -EINVAL22; |
2568 | } |
2569 | |
2570 | if (!intel_hdmi_compute_hdmi_infoframe(encoder, pipe_config, conn_state)) { |
2571 | drm_dbg_kms(&dev_priv->drm, "bad HDMI infoframe\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "bad HDMI infoframe\n" ); |
2572 | return -EINVAL22; |
2573 | } |
2574 | |
2575 | if (!intel_hdmi_compute_drm_infoframe(encoder, pipe_config, conn_state)) { |
2576 | drm_dbg_kms(&dev_priv->drm, "bad DRM infoframe\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "bad DRM infoframe\n" ); |
2577 | return -EINVAL22; |
2578 | } |
2579 | |
2580 | return 0; |
2581 | } |
2582 | |
2583 | static void |
2584 | intel_hdmi_unset_edid(struct drm_connector *connector) |
2585 | { |
2586 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );})); |
2587 | |
2588 | intel_hdmi->has_hdmi_sink = false0; |
2589 | intel_hdmi->has_audio = false0; |
2590 | |
2591 | intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE; |
2592 | intel_hdmi->dp_dual_mode.max_tmds_clock = 0; |
2593 | |
2594 | kfree(to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );})->detect_edid); |
2595 | to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );})->detect_edid = NULL((void *)0); |
2596 | } |
2597 | |
2598 | static void |
2599 | intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool_Bool has_edid) |
2600 | { |
2601 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->dev); |
2602 | struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );})); |
2603 | enum port port = hdmi_to_dig_port(hdmi)->base.port; |
2604 | struct i2c_adapter *adapter = |
2605 | intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); |
2606 | enum drm_dp_dual_mode_type type = drm_dp_dual_mode_detect(adapter); |
2607 | |
2608 | /* |
2609 | * Type 1 DVI adaptors are not required to implement any |
2610 | * registers, so we can't always detect their presence. |
2611 | * Ideally we should be able to check the state of the |
2612 | * CONFIG1 pin, but no such luck on our hardware. |
2613 | * |
2614 | * The only method left to us is to check the VBT to see |
2615 | * if the port is a dual mode capable DP port. But let's |
2616 | * only do that when we sucesfully read the EDID, to avoid |
2617 | * confusing log messages about DP dual mode adaptors when |
2618 | * there's nothing connected to the port. |
2619 | */ |
2620 | if (type == DRM_DP_DUAL_MODE_UNKNOWN) { |
2621 | /* An overridden EDID imply that we want this port for testing. |
2622 | * Make sure not to set limits for that port. |
2623 | */ |
2624 | if (has_edid && !connector->override_edid && |
2625 | intel_bios_is_port_dp_dual_mode(dev_priv, port)) { |
2626 | drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Assuming DP dual mode adaptor presence based on VBT\n" ) |
2627 | "Assuming DP dual mode adaptor presence based on VBT\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Assuming DP dual mode adaptor presence based on VBT\n" ); |
2628 | type = DRM_DP_DUAL_MODE_TYPE1_DVI; |
2629 | } else { |
2630 | type = DRM_DP_DUAL_MODE_NONE; |
2631 | } |
2632 | } |
2633 | |
2634 | if (type == DRM_DP_DUAL_MODE_NONE) |
2635 | return; |
2636 | |
2637 | hdmi->dp_dual_mode.type = type; |
2638 | hdmi->dp_dual_mode.max_tmds_clock = |
2639 | drm_dp_dual_mode_max_tmds_clock(type, adapter); |
2640 | |
2641 | drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n" , drm_dp_get_dual_mode_type_name(type), hdmi->dp_dual_mode .max_tmds_clock) |
2642 | "DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n" , drm_dp_get_dual_mode_type_name(type), hdmi->dp_dual_mode .max_tmds_clock) |
2643 | drm_dp_get_dual_mode_type_name(type),drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n" , drm_dp_get_dual_mode_type_name(type), hdmi->dp_dual_mode .max_tmds_clock) |
2644 | hdmi->dp_dual_mode.max_tmds_clock)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n" , drm_dp_get_dual_mode_type_name(type), hdmi->dp_dual_mode .max_tmds_clock); |
2645 | } |
2646 | |
2647 | static bool_Bool |
2648 | intel_hdmi_set_edid(struct drm_connector *connector) |
2649 | { |
2650 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->dev); |
2651 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );})); |
2652 | intel_wakeref_t wakeref; |
2653 | struct edid *edid; |
2654 | bool_Bool connected = false0; |
2655 | struct i2c_adapter *i2c; |
2656 | |
2657 | wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); |
2658 | |
2659 | i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus); |
2660 | |
2661 | edid = drm_get_edid(connector, i2c); |
2662 | |
2663 | if (!edid && !intel_gmbus_is_forced_bit(i2c)) { |
2664 | drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n" ) |
2665 | "HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n" ); |
2666 | intel_gmbus_force_bit(i2c, true1); |
2667 | edid = drm_get_edid(connector, i2c); |
2668 | intel_gmbus_force_bit(i2c, false0); |
2669 | } |
2670 | |
2671 | intel_hdmi_dp_dual_mode_detect(connector, edid != NULL((void *)0)); |
2672 | |
2673 | intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref); |
2674 | |
2675 | to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );})->detect_edid = edid; |
2676 | if (edid && edid->input & DRM_EDID_INPUT_DIGITAL(1 << 7)) { |
2677 | intel_hdmi->has_audio = drm_detect_monitor_audio(edid); |
2678 | intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid); |
2679 | |
2680 | connected = true1; |
2681 | } |
2682 | |
2683 | cec_notifier_set_phys_addr_from_edid(intel_hdmi->cec_notifier, edid); |
2684 | |
2685 | return connected; |
2686 | } |
2687 | |
2688 | static enum drm_connector_status |
2689 | intel_hdmi_detect(struct drm_connector *connector, bool_Bool force) |
2690 | { |
2691 | enum drm_connector_status status = connector_status_disconnected; |
2692 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->dev); |
2693 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );})); |
2694 | struct intel_encoder *encoder = &hdmi_to_dig_port(intel_hdmi)->base; |
2695 | intel_wakeref_t wakeref; |
2696 | |
2697 | drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s]\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s]\n" , connector->base.id, connector->name) |
2698 | connector->base.id, connector->name)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s]\n" , connector->base.id, connector->name); |
2699 | |
2700 | if (!INTEL_DISPLAY_ENABLED(dev_priv)(({ int __ret = !!((!((&(dev_priv)->__info)->pipe_mask != 0))); if (__ret) printf("%s %s: " "%s", dev_driver_string (((&(dev_priv)->drm))->dev), "", "drm_WARN_ON(" "!((&(dev_priv)->__info)->pipe_mask != 0)" ")"); __builtin_expect(!!(__ret), 0); }), !(dev_priv)->params .disable_display)) |
2701 | return connector_status_disconnected; |
2702 | |
2703 | wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); |
2704 | |
2705 | if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 11 && |
2706 | !intel_digital_port_connected(encoder)) |
2707 | goto out; |
2708 | |
2709 | intel_hdmi_unset_edid(connector); |
2710 | |
2711 | if (intel_hdmi_set_edid(connector)) |
2712 | status = connector_status_connected; |
2713 | |
2714 | out: |
2715 | intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref); |
2716 | |
2717 | if (status != connector_status_connected) |
2718 | cec_notifier_phys_addr_invalidate(intel_hdmi->cec_notifier); |
2719 | |
2720 | /* |
2721 | * Make sure the refs for power wells enabled during detect are |
2722 | * dropped to avoid a new detect cycle triggered by HPD polling. |
2723 | */ |
2724 | intel_display_power_flush_work(dev_priv); |
2725 | |
2726 | return status; |
2727 | } |
2728 | |
2729 | static void |
2730 | intel_hdmi_force(struct drm_connector *connector) |
2731 | { |
2732 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->dev); |
2733 | |
2734 | drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s]\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s]\n" , connector->base.id, connector->name) |
2735 | connector->base.id, connector->name)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s]\n" , connector->base.id, connector->name); |
2736 | |
2737 | intel_hdmi_unset_edid(connector); |
2738 | |
2739 | if (connector->status != connector_status_connected) |
2740 | return; |
2741 | |
2742 | intel_hdmi_set_edid(connector); |
2743 | } |
2744 | |
2745 | static int intel_hdmi_get_modes(struct drm_connector *connector) |
2746 | { |
2747 | struct edid *edid; |
2748 | |
2749 | edid = to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );})->detect_edid; |
2750 | if (edid == NULL((void *)0)) |
2751 | return 0; |
2752 | |
2753 | return intel_connector_update_modes(connector, edid); |
2754 | } |
2755 | |
2756 | static void intel_hdmi_pre_enable(struct intel_atomic_state *state, |
2757 | struct intel_encoder *encoder, |
2758 | const struct intel_crtc_state *pipe_config, |
2759 | const struct drm_connector_state *conn_state) |
2760 | { |
2761 | struct intel_digital_port *dig_port = |
2762 | enc_to_dig_port(encoder); |
2763 | |
2764 | intel_hdmi_prepare(encoder, pipe_config); |
2765 | |
2766 | dig_port->set_infoframes(encoder, |
2767 | pipe_config->has_infoframe, |
2768 | pipe_config, conn_state); |
2769 | } |
2770 | |
2771 | static void vlv_hdmi_pre_enable(struct intel_atomic_state *state, |
2772 | struct intel_encoder *encoder, |
2773 | const struct intel_crtc_state *pipe_config, |
2774 | const struct drm_connector_state *conn_state) |
2775 | { |
2776 | struct intel_digital_port *dig_port = enc_to_dig_port(encoder); |
2777 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
2778 | |
2779 | vlv_phy_pre_encoder_enable(encoder, pipe_config); |
2780 | |
2781 | /* HDMI 1.0V-2dB */ |
2782 | vlv_set_phy_signal_level(encoder, 0x2b245f5f, 0x00002000, 0x5578b83a, |
2783 | 0x2b247878); |
2784 | |
2785 | dig_port->set_infoframes(encoder, |
2786 | pipe_config->has_infoframe, |
2787 | pipe_config, conn_state); |
2788 | |
2789 | g4x_enable_hdmi(state, encoder, pipe_config, conn_state); |
2790 | |
2791 | vlv_wait_port_ready(dev_priv, dig_port, 0x0); |
2792 | } |
2793 | |
2794 | static void vlv_hdmi_pre_pll_enable(struct intel_atomic_state *state, |
2795 | struct intel_encoder *encoder, |
2796 | const struct intel_crtc_state *pipe_config, |
2797 | const struct drm_connector_state *conn_state) |
2798 | { |
2799 | intel_hdmi_prepare(encoder, pipe_config); |
2800 | |
2801 | vlv_phy_pre_pll_enable(encoder, pipe_config); |
2802 | } |
2803 | |
2804 | static void chv_hdmi_pre_pll_enable(struct intel_atomic_state *state, |
2805 | struct intel_encoder *encoder, |
2806 | const struct intel_crtc_state *pipe_config, |
2807 | const struct drm_connector_state *conn_state) |
2808 | { |
2809 | intel_hdmi_prepare(encoder, pipe_config); |
2810 | |
2811 | chv_phy_pre_pll_enable(encoder, pipe_config); |
2812 | } |
2813 | |
2814 | static void chv_hdmi_post_pll_disable(struct intel_atomic_state *state, |
2815 | struct intel_encoder *encoder, |
2816 | const struct intel_crtc_state *old_crtc_state, |
2817 | const struct drm_connector_state *old_conn_state) |
2818 | { |
2819 | chv_phy_post_pll_disable(encoder, old_crtc_state); |
2820 | } |
2821 | |
2822 | static void vlv_hdmi_post_disable(struct intel_atomic_state *state, |
2823 | struct intel_encoder *encoder, |
2824 | const struct intel_crtc_state *old_crtc_state, |
2825 | const struct drm_connector_state *old_conn_state) |
2826 | { |
2827 | /* Reset lanes to avoid HDMI flicker (VLV w/a) */ |
2828 | vlv_phy_reset_lanes(encoder, old_crtc_state); |
2829 | } |
2830 | |
2831 | static void chv_hdmi_post_disable(struct intel_atomic_state *state, |
2832 | struct intel_encoder *encoder, |
2833 | const struct intel_crtc_state *old_crtc_state, |
2834 | const struct drm_connector_state *old_conn_state) |
2835 | { |
2836 | struct drm_device *dev = encoder->base.dev; |
2837 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev); |
2838 | |
2839 | vlv_dpio_get(dev_priv); |
2840 | |
2841 | /* Assert data lane reset */ |
2842 | chv_data_lane_soft_reset(encoder, old_crtc_state, true1); |
2843 | |
2844 | vlv_dpio_put(dev_priv); |
2845 | } |
2846 | |
2847 | static void chv_hdmi_pre_enable(struct intel_atomic_state *state, |
2848 | struct intel_encoder *encoder, |
2849 | const struct intel_crtc_state *pipe_config, |
2850 | const struct drm_connector_state *conn_state) |
2851 | { |
2852 | struct intel_digital_port *dig_port = enc_to_dig_port(encoder); |
2853 | struct drm_device *dev = encoder->base.dev; |
2854 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev); |
2855 | |
2856 | chv_phy_pre_encoder_enable(encoder, pipe_config); |
2857 | |
2858 | /* FIXME: Program the support xxx V-dB */ |
2859 | /* Use 800mV-0dB */ |
2860 | chv_set_phy_signal_level(encoder, 128, 102, false0); |
2861 | |
2862 | dig_port->set_infoframes(encoder, |
2863 | pipe_config->has_infoframe, |
2864 | pipe_config, conn_state); |
2865 | |
2866 | g4x_enable_hdmi(state, encoder, pipe_config, conn_state); |
2867 | |
2868 | vlv_wait_port_ready(dev_priv, dig_port, 0x0); |
2869 | |
2870 | /* Second common lane will stay alive on its own now */ |
2871 | chv_phy_release_cl2_override(encoder); |
2872 | } |
2873 | |
2874 | static struct i2c_adapter * |
2875 | intel_hdmi_get_i2c_adapter(struct drm_connector *connector) |
2876 | { |
2877 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->dev); |
2878 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );})); |
2879 | |
2880 | return intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus); |
2881 | } |
2882 | |
2883 | static void intel_hdmi_create_i2c_symlink(struct drm_connector *connector) |
2884 | { |
2885 | #ifdef __linux__ |
2886 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->dev); |
2887 | struct i2c_adapter *adapter = intel_hdmi_get_i2c_adapter(connector); |
2888 | struct kobject *i2c_kobj = &adapter->dev.kobj; |
2889 | struct kobject *connector_kobj = &connector->kdev->kobj; |
2890 | int ret; |
2891 | |
2892 | ret = sysfs_create_link(connector_kobj, i2c_kobj, i2c_kobj->name)0; |
2893 | if (ret) |
2894 | drm_err(&i915->drm, "Failed to create i2c symlink (%d)\n", ret)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to create i2c symlink (%d)\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , ret); |
2895 | #endif |
2896 | } |
2897 | |
2898 | static void intel_hdmi_remove_i2c_symlink(struct drm_connector *connector) |
2899 | { |
2900 | #ifdef __linux__ |
2901 | struct i2c_adapter *adapter = intel_hdmi_get_i2c_adapter(connector); |
2902 | struct kobject *i2c_kobj = &adapter->dev.kobj; |
2903 | struct kobject *connector_kobj = &connector->kdev->kobj; |
2904 | |
2905 | sysfs_remove_link(connector_kobj, i2c_kobj->name); |
2906 | #endif |
2907 | } |
2908 | |
2909 | static int |
2910 | intel_hdmi_connector_register(struct drm_connector *connector) |
2911 | { |
2912 | int ret; |
2913 | |
2914 | ret = intel_connector_register(connector); |
2915 | if (ret) |
2916 | return ret; |
2917 | |
2918 | intel_hdmi_create_i2c_symlink(connector); |
2919 | |
2920 | return ret; |
2921 | } |
2922 | |
2923 | static void intel_hdmi_connector_unregister(struct drm_connector *connector) |
2924 | { |
2925 | struct cec_notifier *n = intel_attached_hdmi(to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );}))->cec_notifier; |
2926 | |
2927 | cec_notifier_conn_unregister(n); |
2928 | |
2929 | intel_hdmi_remove_i2c_symlink(connector); |
2930 | intel_connector_unregister(connector); |
2931 | } |
2932 | |
2933 | static const struct drm_connector_funcs intel_hdmi_connector_funcs = { |
2934 | .detect = intel_hdmi_detect, |
2935 | .force = intel_hdmi_force, |
2936 | .fill_modes = drm_helper_probe_single_connector_modes, |
2937 | .atomic_get_property = intel_digital_connector_atomic_get_property, |
2938 | .atomic_set_property = intel_digital_connector_atomic_set_property, |
2939 | .late_register = intel_hdmi_connector_register, |
2940 | .early_unregister = intel_hdmi_connector_unregister, |
2941 | .destroy = intel_connector_destroy, |
2942 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
2943 | .atomic_duplicate_state = intel_digital_connector_duplicate_state, |
2944 | }; |
2945 | |
2946 | static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = { |
2947 | .get_modes = intel_hdmi_get_modes, |
2948 | .mode_valid = intel_hdmi_mode_valid, |
2949 | .atomic_check = intel_digital_connector_atomic_check, |
2950 | }; |
2951 | |
2952 | static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { |
2953 | .destroy = intel_encoder_destroy, |
2954 | }; |
2955 | |
2956 | static void |
2957 | intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector) |
2958 | { |
2959 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->dev); |
2960 | struct intel_digital_port *dig_port = |
2961 | hdmi_to_dig_port(intel_hdmi); |
2962 | |
2963 | intel_attach_force_audio_property(connector); |
2964 | intel_attach_broadcast_rgb_property(connector); |
2965 | intel_attach_aspect_ratio_property(connector); |
2966 | |
2967 | /* |
2968 | * Attach Colorspace property for Non LSPCON based device |
2969 | * ToDo: This needs to be extended for LSPCON implementation |
2970 | * as well. Will be implemented separately. |
2971 | */ |
2972 | if (!dig_port->lspcon.active) |
2973 | intel_attach_colorspace_property(connector); |
2974 | |
2975 | drm_connector_attach_content_type_property(connector); |
2976 | |
2977 | if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 10 || IS_GEMINILAKE(dev_priv)IS_PLATFORM(dev_priv, INTEL_GEMINILAKE)) |
2978 | drm_object_attach_property(&connector->base, |
2979 | connector->dev->mode_config.hdr_output_metadata_property, 0); |
2980 | |
2981 | if (!HAS_GMCH(dev_priv)((&(dev_priv)->__info)->display.has_gmch)) |
2982 | drm_connector_attach_max_bpc_property(connector, 8, 12); |
2983 | } |
2984 | |
2985 | /* |
2986 | * intel_hdmi_handle_sink_scrambling: handle sink scrambling/clock ratio setup |
2987 | * @encoder: intel_encoder |
2988 | * @connector: drm_connector |
2989 | * @high_tmds_clock_ratio = bool to indicate if the function needs to set |
2990 | * or reset the high tmds clock ratio for scrambling |
2991 | * @scrambling: bool to Indicate if the function needs to set or reset |
2992 | * sink scrambling |
2993 | * |
2994 | * This function handles scrambling on HDMI 2.0 capable sinks. |
2995 | * If required clock rate is > 340 Mhz && scrambling is supported by sink |
2996 | * it enables scrambling. This should be called before enabling the HDMI |
2997 | * 2.0 port, as the sink can choose to disable the scrambling if it doesn't |
2998 | * detect a scrambled clock within 100 ms. |
2999 | * |
3000 | * Returns: |
3001 | * True on success, false on failure. |
3002 | */ |
3003 | bool_Bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder, |
3004 | struct drm_connector *connector, |
3005 | bool_Bool high_tmds_clock_ratio, |
3006 | bool_Bool scrambling) |
3007 | { |
3008 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
3009 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
3010 | struct drm_scrambling *sink_scrambling = |
3011 | &connector->display_info.hdmi.scdc.scrambling; |
3012 | struct i2c_adapter *adapter = |
3013 | intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus); |
3014 | |
3015 | if (!sink_scrambling->supported) |
3016 | return true1; |
3017 | |
3018 | drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s] scrambling=%s, TMDS bit clock ratio=1/%d\n" , connector->base.id, connector->name, yesno(scrambling ), high_tmds_clock_ratio ? 40 : 10) |
3019 | "[CONNECTOR:%d:%s] scrambling=%s, TMDS bit clock ratio=1/%d\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s] scrambling=%s, TMDS bit clock ratio=1/%d\n" , connector->base.id, connector->name, yesno(scrambling ), high_tmds_clock_ratio ? 40 : 10) |
3020 | connector->base.id, connector->name,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s] scrambling=%s, TMDS bit clock ratio=1/%d\n" , connector->base.id, connector->name, yesno(scrambling ), high_tmds_clock_ratio ? 40 : 10) |
3021 | yesno(scrambling), high_tmds_clock_ratio ? 40 : 10)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s] scrambling=%s, TMDS bit clock ratio=1/%d\n" , connector->base.id, connector->name, yesno(scrambling ), high_tmds_clock_ratio ? 40 : 10); |
3022 | |
3023 | /* Set TMDS bit clock ratio to 1/40 or 1/10, and enable/disable scrambling */ |
3024 | return drm_scdc_set_high_tmds_clock_ratio(adapter, |
3025 | high_tmds_clock_ratio) && |
3026 | drm_scdc_set_scrambling(adapter, scrambling); |
3027 | } |
3028 | |
3029 | static u8 chv_port_to_ddc_pin(struct drm_i915_privateinteldrm_softc *dev_priv, enum port port) |
3030 | { |
3031 | u8 ddc_pin; |
3032 | |
3033 | switch (port) { |
3034 | case PORT_B: |
3035 | ddc_pin = GMBUS_PIN_DPB5; |
3036 | break; |
3037 | case PORT_C: |
3038 | ddc_pin = GMBUS_PIN_DPC4; |
3039 | break; |
3040 | case PORT_D: |
3041 | ddc_pin = GMBUS_PIN_DPD_CHV3; |
3042 | break; |
3043 | default: |
3044 | MISSING_CASE(port)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "port", (long)(port)); __builtin_expect(!!(__ret), 0); }); |
3045 | ddc_pin = GMBUS_PIN_DPB5; |
3046 | break; |
3047 | } |
3048 | return ddc_pin; |
3049 | } |
3050 | |
3051 | static u8 bxt_port_to_ddc_pin(struct drm_i915_privateinteldrm_softc *dev_priv, enum port port) |
3052 | { |
3053 | u8 ddc_pin; |
3054 | |
3055 | switch (port) { |
3056 | case PORT_B: |
3057 | ddc_pin = GMBUS_PIN_1_BXT1; |
3058 | break; |
3059 | case PORT_C: |
3060 | ddc_pin = GMBUS_PIN_2_BXT2; |
3061 | break; |
3062 | default: |
3063 | MISSING_CASE(port)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "port", (long)(port)); __builtin_expect(!!(__ret), 0); }); |
3064 | ddc_pin = GMBUS_PIN_1_BXT1; |
3065 | break; |
3066 | } |
3067 | return ddc_pin; |
3068 | } |
3069 | |
3070 | static u8 cnp_port_to_ddc_pin(struct drm_i915_privateinteldrm_softc *dev_priv, |
3071 | enum port port) |
3072 | { |
3073 | u8 ddc_pin; |
3074 | |
3075 | switch (port) { |
3076 | case PORT_B: |
3077 | ddc_pin = GMBUS_PIN_1_BXT1; |
3078 | break; |
3079 | case PORT_C: |
3080 | ddc_pin = GMBUS_PIN_2_BXT2; |
3081 | break; |
3082 | case PORT_D: |
3083 | ddc_pin = GMBUS_PIN_4_CNP4; |
3084 | break; |
3085 | case PORT_F: |
3086 | ddc_pin = GMBUS_PIN_3_BXT3; |
3087 | break; |
3088 | default: |
3089 | MISSING_CASE(port)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "port", (long)(port)); __builtin_expect(!!(__ret), 0); }); |
3090 | ddc_pin = GMBUS_PIN_1_BXT1; |
3091 | break; |
3092 | } |
3093 | return ddc_pin; |
3094 | } |
3095 | |
3096 | static u8 icl_port_to_ddc_pin(struct drm_i915_privateinteldrm_softc *dev_priv, enum port port) |
3097 | { |
3098 | enum phy phy = intel_port_to_phy(dev_priv, port); |
3099 | |
3100 | if (intel_phy_is_combo(dev_priv, phy)) |
3101 | return GMBUS_PIN_1_BXT1 + port; |
3102 | else if (intel_phy_is_tc(dev_priv, phy)) |
3103 | return GMBUS_PIN_9_TC1_ICP9 + intel_port_to_tc(dev_priv, port); |
3104 | |
3105 | drm_WARN(&dev_priv->drm, 1, "Unknown port:%c\n", port_name(port))({ int __ret = !!(1); if (__ret) printf("%s %s: " "Unknown port:%c\n" , dev_driver_string((&dev_priv->drm)->dev), "", ((port ) + 'A')); __builtin_expect(!!(__ret), 0); }); |
3106 | return GMBUS_PIN_2_BXT2; |
3107 | } |
3108 | |
3109 | static u8 mcc_port_to_ddc_pin(struct drm_i915_privateinteldrm_softc *dev_priv, enum port port) |
3110 | { |
3111 | enum phy phy = intel_port_to_phy(dev_priv, port); |
3112 | u8 ddc_pin; |
3113 | |
3114 | switch (phy) { |
3115 | case PHY_A: |
3116 | ddc_pin = GMBUS_PIN_1_BXT1; |
3117 | break; |
3118 | case PHY_B: |
3119 | ddc_pin = GMBUS_PIN_2_BXT2; |
3120 | break; |
3121 | case PHY_C: |
3122 | ddc_pin = GMBUS_PIN_9_TC1_ICP9; |
3123 | break; |
3124 | default: |
3125 | MISSING_CASE(phy)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "phy", (long)(phy)); __builtin_expect(!!(__ret), 0); }); |
3126 | ddc_pin = GMBUS_PIN_1_BXT1; |
3127 | break; |
3128 | } |
3129 | return ddc_pin; |
3130 | } |
3131 | |
3132 | static u8 rkl_port_to_ddc_pin(struct drm_i915_privateinteldrm_softc *dev_priv, enum port port) |
3133 | { |
3134 | enum phy phy = intel_port_to_phy(dev_priv, port); |
3135 | |
3136 | WARN_ON(port == PORT_C)({ int __ret = !!((port == PORT_C)); if (__ret) printf("%s", "WARN_ON(" "port == PORT_C" ")"); __builtin_expect(!!(__ret), 0); }); |
3137 | |
3138 | /* |
3139 | * Pin mapping for RKL depends on which PCH is present. With TGP, the |
3140 | * final two outputs use type-c pins, even though they're actually |
3141 | * combo outputs. With CMP, the traditional DDI A-D pins are used for |
3142 | * all outputs. |
3143 | */ |
3144 | if (INTEL_PCH_TYPE(dev_priv)((dev_priv)->pch_type) >= PCH_TGP && phy >= PHY_C) |
3145 | return GMBUS_PIN_9_TC1_ICP9 + phy - PHY_C; |
3146 | |
3147 | return GMBUS_PIN_1_BXT1 + phy; |
3148 | } |
3149 | |
3150 | static u8 g4x_port_to_ddc_pin(struct drm_i915_privateinteldrm_softc *dev_priv, |
3151 | enum port port) |
3152 | { |
3153 | u8 ddc_pin; |
3154 | |
3155 | switch (port) { |
3156 | case PORT_B: |
3157 | ddc_pin = GMBUS_PIN_DPB5; |
3158 | break; |
3159 | case PORT_C: |
3160 | ddc_pin = GMBUS_PIN_DPC4; |
3161 | break; |
3162 | case PORT_D: |
3163 | ddc_pin = GMBUS_PIN_DPD6; |
3164 | break; |
3165 | default: |
3166 | MISSING_CASE(port)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "port", (long)(port)); __builtin_expect(!!(__ret), 0); }); |
3167 | ddc_pin = GMBUS_PIN_DPB5; |
3168 | break; |
3169 | } |
3170 | return ddc_pin; |
3171 | } |
3172 | |
3173 | static u8 intel_hdmi_ddc_pin(struct intel_encoder *encoder) |
3174 | { |
3175 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
3176 | enum port port = encoder->port; |
3177 | u8 ddc_pin; |
3178 | |
3179 | ddc_pin = intel_bios_alternate_ddc_pin(encoder); |
3180 | if (ddc_pin) { |
3181 | drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Using DDC pin 0x%x for port %c (VBT)\n" , ddc_pin, ((port) + 'A')) |
3182 | "Using DDC pin 0x%x for port %c (VBT)\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Using DDC pin 0x%x for port %c (VBT)\n" , ddc_pin, ((port) + 'A')) |
3183 | ddc_pin, port_name(port))drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Using DDC pin 0x%x for port %c (VBT)\n" , ddc_pin, ((port) + 'A')); |
3184 | return ddc_pin; |
3185 | } |
3186 | |
3187 | if (IS_ROCKETLAKE(dev_priv)IS_PLATFORM(dev_priv, INTEL_ROCKETLAKE)) |
3188 | ddc_pin = rkl_port_to_ddc_pin(dev_priv, port); |
3189 | else if (HAS_PCH_MCC(dev_priv)(((dev_priv)->pch_type) == PCH_MCC)) |
3190 | ddc_pin = mcc_port_to_ddc_pin(dev_priv, port); |
3191 | else if (INTEL_PCH_TYPE(dev_priv)((dev_priv)->pch_type) >= PCH_ICP) |
3192 | ddc_pin = icl_port_to_ddc_pin(dev_priv, port); |
3193 | else if (HAS_PCH_CNP(dev_priv)(((dev_priv)->pch_type) == PCH_CNP)) |
3194 | ddc_pin = cnp_port_to_ddc_pin(dev_priv, port); |
3195 | else if (IS_GEN9_LP(dev_priv)((0 + (&(dev_priv)->__info)->gen == (9)) && ((&(dev_priv)->__info)->is_lp))) |
3196 | ddc_pin = bxt_port_to_ddc_pin(dev_priv, port); |
3197 | else if (IS_CHERRYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) |
3198 | ddc_pin = chv_port_to_ddc_pin(dev_priv, port); |
3199 | else |
3200 | ddc_pin = g4x_port_to_ddc_pin(dev_priv, port); |
3201 | |
3202 | drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Using DDC pin 0x%x for port %c (platform default)\n" , ddc_pin, ((port) + 'A')) |
3203 | "Using DDC pin 0x%x for port %c (platform default)\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Using DDC pin 0x%x for port %c (platform default)\n" , ddc_pin, ((port) + 'A')) |
3204 | ddc_pin, port_name(port))drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Using DDC pin 0x%x for port %c (platform default)\n" , ddc_pin, ((port) + 'A')); |
3205 | |
3206 | return ddc_pin; |
3207 | } |
3208 | |
3209 | void intel_infoframe_init(struct intel_digital_port *dig_port) |
3210 | { |
3211 | struct drm_i915_privateinteldrm_softc *dev_priv = |
3212 | to_i915(dig_port->base.base.dev); |
3213 | |
3214 | if (IS_VALLEYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW) || IS_CHERRYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) { |
3215 | dig_port->write_infoframe = vlv_write_infoframe; |
3216 | dig_port->read_infoframe = vlv_read_infoframe; |
3217 | dig_port->set_infoframes = vlv_set_infoframes; |
3218 | dig_port->infoframes_enabled = vlv_infoframes_enabled; |
3219 | } else if (IS_G4X(dev_priv)(IS_PLATFORM(dev_priv, INTEL_G45) || IS_PLATFORM(dev_priv, INTEL_GM45 ))) { |
3220 | dig_port->write_infoframe = g4x_write_infoframe; |
3221 | dig_port->read_infoframe = g4x_read_infoframe; |
3222 | dig_port->set_infoframes = g4x_set_infoframes; |
3223 | dig_port->infoframes_enabled = g4x_infoframes_enabled; |
3224 | } else if (HAS_DDI(dev_priv)((&(dev_priv)->__info)->display.has_ddi)) { |
3225 | if (dig_port->lspcon.active) { |
3226 | dig_port->write_infoframe = lspcon_write_infoframe; |
3227 | dig_port->read_infoframe = lspcon_read_infoframe; |
3228 | dig_port->set_infoframes = lspcon_set_infoframes; |
3229 | dig_port->infoframes_enabled = lspcon_infoframes_enabled; |
3230 | } else { |
3231 | dig_port->write_infoframe = hsw_write_infoframe; |
3232 | dig_port->read_infoframe = hsw_read_infoframe; |
3233 | dig_port->set_infoframes = hsw_set_infoframes; |
3234 | dig_port->infoframes_enabled = hsw_infoframes_enabled; |
3235 | } |
3236 | } else if (HAS_PCH_IBX(dev_priv)(((dev_priv)->pch_type) == PCH_IBX)) { |
3237 | dig_port->write_infoframe = ibx_write_infoframe; |
3238 | dig_port->read_infoframe = ibx_read_infoframe; |
3239 | dig_port->set_infoframes = ibx_set_infoframes; |
3240 | dig_port->infoframes_enabled = ibx_infoframes_enabled; |
3241 | } else { |
3242 | dig_port->write_infoframe = cpt_write_infoframe; |
3243 | dig_port->read_infoframe = cpt_read_infoframe; |
3244 | dig_port->set_infoframes = cpt_set_infoframes; |
3245 | dig_port->infoframes_enabled = cpt_infoframes_enabled; |
3246 | } |
3247 | } |
3248 | |
3249 | void intel_hdmi_init_connector(struct intel_digital_port *dig_port, |
3250 | struct intel_connector *intel_connector) |
3251 | { |
3252 | struct drm_connector *connector = &intel_connector->base; |
3253 | struct intel_hdmi *intel_hdmi = &dig_port->hdmi; |
3254 | struct intel_encoder *intel_encoder = &dig_port->base; |
3255 | struct drm_device *dev = intel_encoder->base.dev; |
3256 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev); |
3257 | struct i2c_adapter *ddc; |
3258 | enum port port = intel_encoder->port; |
3259 | struct cec_connector_info conn_info; |
3260 | |
3261 | drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Adding HDMI connector on [ENCODER:%d:%s]\n" , intel_encoder->base.base.id, intel_encoder->base.name ) |
3262 | "Adding HDMI connector on [ENCODER:%d:%s]\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Adding HDMI connector on [ENCODER:%d:%s]\n" , intel_encoder->base.base.id, intel_encoder->base.name ) |
3263 | intel_encoder->base.base.id, intel_encoder->base.name)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Adding HDMI connector on [ENCODER:%d:%s]\n" , intel_encoder->base.base.id, intel_encoder->base.name ); |
3264 | |
3265 | if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) < 12 && drm_WARN_ON(dev, port == PORT_A)({ int __ret = !!((port == PORT_A)); if (__ret) printf("%s %s: " "%s", dev_driver_string(((dev))->dev), "", "drm_WARN_ON(" "port == PORT_A" ")"); __builtin_expect(!!(__ret), 0); })) |
3266 | return; |
3267 | |
3268 | if (drm_WARN(dev, dig_port->max_lanes < 4,({ int __ret = !!(dig_port->max_lanes < 4); if (__ret) printf ("%s %s: " "Not enough lanes (%d) for HDMI on [ENCODER:%d:%s]\n" , dev_driver_string((dev)->dev), "", dig_port->max_lanes , intel_encoder->base.base.id, intel_encoder->base.name ); __builtin_expect(!!(__ret), 0); }) |
3269 | "Not enough lanes (%d) for HDMI on [ENCODER:%d:%s]\n",({ int __ret = !!(dig_port->max_lanes < 4); if (__ret) printf ("%s %s: " "Not enough lanes (%d) for HDMI on [ENCODER:%d:%s]\n" , dev_driver_string((dev)->dev), "", dig_port->max_lanes , intel_encoder->base.base.id, intel_encoder->base.name ); __builtin_expect(!!(__ret), 0); }) |
3270 | dig_port->max_lanes, intel_encoder->base.base.id,({ int __ret = !!(dig_port->max_lanes < 4); if (__ret) printf ("%s %s: " "Not enough lanes (%d) for HDMI on [ENCODER:%d:%s]\n" , dev_driver_string((dev)->dev), "", dig_port->max_lanes , intel_encoder->base.base.id, intel_encoder->base.name ); __builtin_expect(!!(__ret), 0); }) |
3271 | intel_encoder->base.name)({ int __ret = !!(dig_port->max_lanes < 4); if (__ret) printf ("%s %s: " "Not enough lanes (%d) for HDMI on [ENCODER:%d:%s]\n" , dev_driver_string((dev)->dev), "", dig_port->max_lanes , intel_encoder->base.base.id, intel_encoder->base.name ); __builtin_expect(!!(__ret), 0); })) |
3272 | return; |
3273 | |
3274 | intel_hdmi->ddc_bus = intel_hdmi_ddc_pin(intel_encoder); |
3275 | ddc = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus); |
3276 | |
3277 | drm_connector_init_with_ddc(dev, connector, |
3278 | &intel_hdmi_connector_funcs, |
3279 | DRM_MODE_CONNECTOR_HDMIA11, |
3280 | ddc); |
3281 | drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); |
3282 | |
3283 | connector->interlace_allowed = 1; |
3284 | connector->doublescan_allowed = 0; |
3285 | connector->stereo_allowed = 1; |
3286 | |
3287 | if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 10 || IS_GEMINILAKE(dev_priv)IS_PLATFORM(dev_priv, INTEL_GEMINILAKE)) |
3288 | connector->ycbcr_420_allowed = true1; |
3289 | |
3290 | intel_connector->polled = DRM_CONNECTOR_POLL_HPD(1 << 0); |
3291 | |
3292 | if (HAS_DDI(dev_priv)((&(dev_priv)->__info)->display.has_ddi)) |
3293 | intel_connector->get_hw_state = intel_ddi_connector_get_hw_state; |
3294 | else |
3295 | intel_connector->get_hw_state = intel_connector_get_hw_state; |
3296 | |
3297 | intel_hdmi_add_properties(intel_hdmi, connector); |
3298 | |
3299 | intel_connector_attach_encoder(intel_connector, intel_encoder); |
3300 | intel_hdmi->attached_connector = intel_connector; |
3301 | |
3302 | if (is_hdcp_supported(dev_priv, port)) { |
3303 | int ret = intel_hdcp_init(intel_connector, port, |
3304 | &intel_hdmi_hdcp_shim); |
3305 | if (ret) |
3306 | drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "HDCP init failed, skipping.\n" ) |
3307 | "HDCP init failed, skipping.\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "HDCP init failed, skipping.\n" ); |
3308 | } |
3309 | |
3310 | /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written |
3311 | * 0xd. Failure to do so will result in spurious interrupts being |
3312 | * generated on the port when a cable is not attached. |
3313 | */ |
3314 | if (IS_G45(dev_priv)IS_PLATFORM(dev_priv, INTEL_G45)) { |
3315 | u32 temp = intel_de_read(dev_priv, PEG_BAND_GAP_DATA((const i915_reg_t){ .reg = (0x14d68) })); |
3316 | intel_de_write(dev_priv, PEG_BAND_GAP_DATA((const i915_reg_t){ .reg = (0x14d68) }), |
3317 | (temp & ~0xf) | 0xd); |
3318 | } |
3319 | |
3320 | cec_fill_conn_info_from_drm(&conn_info, connector); |
3321 | |
3322 | intel_hdmi->cec_notifier = |
3323 | cec_notifier_conn_register(dev->dev, port_identifier(port),(void *)1 |
3324 | &conn_info)(void *)1; |
3325 | if (!intel_hdmi->cec_notifier) |
3326 | drm_dbg_kms(&dev_priv->drm, "CEC notifier get failed\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "CEC notifier get failed\n" ); |
3327 | } |
3328 | |
3329 | static enum intel_hotplug_state |
3330 | intel_hdmi_hotplug(struct intel_encoder *encoder, |
3331 | struct intel_connector *connector) |
3332 | { |
3333 | enum intel_hotplug_state state; |
3334 | |
3335 | state = intel_encoder_hotplug(encoder, connector); |
3336 | |
3337 | /* |
3338 | * On many platforms the HDMI live state signal is known to be |
3339 | * unreliable, so we can't use it to detect if a sink is connected or |
3340 | * not. Instead we detect if it's connected based on whether we can |
3341 | * read the EDID or not. That in turn has a problem during disconnect, |
3342 | * since the HPD interrupt may be raised before the DDC lines get |
3343 | * disconnected (due to how the required length of DDC vs. HPD |
3344 | * connector pins are specified) and so we'll still be able to get a |
3345 | * valid EDID. To solve this schedule another detection cycle if this |
3346 | * time around we didn't detect any change in the sink's connection |
3347 | * status. |
3348 | */ |
3349 | if (state == INTEL_HOTPLUG_UNCHANGED && !connector->hotplug_retries) |
3350 | state = INTEL_HOTPLUG_RETRY; |
3351 | |
3352 | return state; |
3353 | } |
3354 | |
3355 | void intel_hdmi_init(struct drm_i915_privateinteldrm_softc *dev_priv, |
3356 | i915_reg_t hdmi_reg, enum port port) |
3357 | { |
3358 | struct intel_digital_port *dig_port; |
3359 | struct intel_encoder *intel_encoder; |
3360 | struct intel_connector *intel_connector; |
3361 | |
3362 | dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL(0x0001 | 0x0004)); |
3363 | if (!dig_port) |
3364 | return; |
3365 | |
3366 | intel_connector = intel_connector_alloc(); |
3367 | if (!intel_connector) { |
3368 | kfree(dig_port); |
3369 | return; |
3370 | } |
3371 | |
3372 | intel_encoder = &dig_port->base; |
3373 | |
3374 | rw_init(&dig_port->hdcp_mutex, "hhdcp")_rw_init_flags(&dig_port->hdcp_mutex, "hhdcp", 0, ((void *)0)); |
3375 | |
3376 | drm_encoder_init(&dev_priv->drm, &intel_encoder->base, |
3377 | &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS2, |
3378 | "HDMI %c", port_name(port)((port) + 'A')); |
3379 | |
3380 | intel_encoder->hotplug = intel_hdmi_hotplug; |
3381 | intel_encoder->compute_config = intel_hdmi_compute_config; |
3382 | if (HAS_PCH_SPLIT(dev_priv)(((dev_priv)->pch_type) != PCH_NONE)) { |
3383 | intel_encoder->disable = pch_disable_hdmi; |
3384 | intel_encoder->post_disable = pch_post_disable_hdmi; |
3385 | } else { |
3386 | intel_encoder->disable = g4x_disable_hdmi; |
3387 | } |
3388 | intel_encoder->get_hw_state = intel_hdmi_get_hw_state; |
3389 | intel_encoder->get_config = intel_hdmi_get_config; |
3390 | if (IS_CHERRYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) { |
3391 | intel_encoder->pre_pll_enable = chv_hdmi_pre_pll_enable; |
3392 | intel_encoder->pre_enable = chv_hdmi_pre_enable; |
3393 | intel_encoder->enable = vlv_enable_hdmi; |
3394 | intel_encoder->post_disable = chv_hdmi_post_disable; |
3395 | intel_encoder->post_pll_disable = chv_hdmi_post_pll_disable; |
3396 | } else if (IS_VALLEYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW)) { |
3397 | intel_encoder->pre_pll_enable = vlv_hdmi_pre_pll_enable; |
3398 | intel_encoder->pre_enable = vlv_hdmi_pre_enable; |
3399 | intel_encoder->enable = vlv_enable_hdmi; |
3400 | intel_encoder->post_disable = vlv_hdmi_post_disable; |
3401 | } else { |
3402 | intel_encoder->pre_enable = intel_hdmi_pre_enable; |
3403 | if (HAS_PCH_CPT(dev_priv)(((dev_priv)->pch_type) == PCH_CPT)) |
3404 | intel_encoder->enable = cpt_enable_hdmi; |
3405 | else if (HAS_PCH_IBX(dev_priv)(((dev_priv)->pch_type) == PCH_IBX)) |
3406 | intel_encoder->enable = ibx_enable_hdmi; |
3407 | else |
3408 | intel_encoder->enable = g4x_enable_hdmi; |
3409 | } |
3410 | |
3411 | intel_encoder->type = INTEL_OUTPUT_HDMI; |
3412 | intel_encoder->power_domain = intel_port_to_power_domain(port); |
3413 | intel_encoder->port = port; |
3414 | if (IS_CHERRYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) { |
3415 | if (port == PORT_D) |
3416 | intel_encoder->pipe_mask = BIT(PIPE_C)(1UL << (PIPE_C)); |
3417 | else |
3418 | intel_encoder->pipe_mask = BIT(PIPE_A)(1UL << (PIPE_A)) | BIT(PIPE_B)(1UL << (PIPE_B)); |
3419 | } else { |
3420 | intel_encoder->pipe_mask = ~0; |
3421 | } |
3422 | intel_encoder->cloneable = 1 << INTEL_OUTPUT_ANALOG; |
3423 | intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port); |
3424 | /* |
3425 | * BSpec is unclear about HDMI+HDMI cloning on g4x, but it seems |
3426 | * to work on real hardware. And since g4x can send infoframes to |
3427 | * only one port anyway, nothing is lost by allowing it. |
3428 | */ |
3429 | if (IS_G4X(dev_priv)(IS_PLATFORM(dev_priv, INTEL_G45) || IS_PLATFORM(dev_priv, INTEL_GM45 ))) |
3430 | intel_encoder->cloneable |= 1 << INTEL_OUTPUT_HDMI; |
3431 | |
3432 | dig_port->hdmi.hdmi_reg = hdmi_reg; |
3433 | dig_port->dp.output_reg = INVALID_MMIO_REG((const i915_reg_t){ .reg = (0) }); |
3434 | dig_port->max_lanes = 4; |
3435 | |
3436 | intel_infoframe_init(dig_port); |
3437 | |
3438 | dig_port->aux_ch = intel_bios_port_aux_ch(dev_priv, port); |
3439 | intel_hdmi_init_connector(dig_port, intel_connector); |
3440 | } |