drm/i915: add aux_ch_ctl_reg to struct intel_dp
[linux-2.6-block.git] / drivers / gpu / drm / i915 / intel_hdmi.c
CommitLineData
7d57382e
EA
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/i2c.h>
5a0e3ad6 30#include <linux/slab.h>
7d57382e 31#include <linux/delay.h>
760285e7
DH
32#include <drm/drmP.h>
33#include <drm/drm_crtc.h>
34#include <drm/drm_edid.h>
7d57382e 35#include "intel_drv.h"
760285e7 36#include <drm/i915_drm.h>
7d57382e
EA
37#include "i915_drv.h"
38
30add22d
PZ
39static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi)
40{
da63a9f2 41 return hdmi_to_dig_port(intel_hdmi)->base.base.dev;
30add22d
PZ
42}
43
afba0188
DV
44static void
45assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi)
46{
30add22d 47 struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi);
afba0188
DV
48 struct drm_i915_private *dev_priv = dev->dev_private;
49 uint32_t enabled_bits;
50
affa9354 51 enabled_bits = HAS_DDI(dev) ? DDI_BUF_CTL_ENABLE : SDVO_ENABLE;
afba0188
DV
52
53 WARN(I915_READ(intel_hdmi->sdvox_reg) & enabled_bits,
54 "HDMI port enabled, expecting disabled\n");
55}
56
f5bbfca3 57struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder)
ea5b213a 58{
da63a9f2
PZ
59 struct intel_digital_port *intel_dig_port =
60 container_of(encoder, struct intel_digital_port, base.base);
61 return &intel_dig_port->hdmi;
ea5b213a
CW
62}
63
df0e9248
CW
64static struct intel_hdmi *intel_attached_hdmi(struct drm_connector *connector)
65{
da63a9f2 66 return enc_to_intel_hdmi(&intel_attached_encoder(connector)->base);
df0e9248
CW
67}
68
45187ace 69void intel_dip_infoframe_csum(struct dip_infoframe *frame)
3c17fe4b 70{
45187ace 71 uint8_t *data = (uint8_t *)frame;
3c17fe4b
DH
72 uint8_t sum = 0;
73 unsigned i;
74
45187ace
JB
75 frame->checksum = 0;
76 frame->ecc = 0;
3c17fe4b 77
64a8fc01 78 for (i = 0; i < frame->len + DIP_HEADER_SIZE; i++)
3c17fe4b
DH
79 sum += data[i];
80
45187ace 81 frame->checksum = 0x100 - sum;
3c17fe4b
DH
82}
83
bc2481f3 84static u32 g4x_infoframe_index(struct dip_infoframe *frame)
3c17fe4b 85{
45187ace
JB
86 switch (frame->type) {
87 case DIP_TYPE_AVI:
ed517fbb 88 return VIDEO_DIP_SELECT_AVI;
45187ace 89 case DIP_TYPE_SPD:
ed517fbb 90 return VIDEO_DIP_SELECT_SPD;
45187ace
JB
91 default:
92 DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type);
ed517fbb 93 return 0;
45187ace 94 }
45187ace
JB
95}
96
bc2481f3 97static u32 g4x_infoframe_enable(struct dip_infoframe *frame)
45187ace 98{
45187ace
JB
99 switch (frame->type) {
100 case DIP_TYPE_AVI:
ed517fbb 101 return VIDEO_DIP_ENABLE_AVI;
45187ace 102 case DIP_TYPE_SPD:
ed517fbb 103 return VIDEO_DIP_ENABLE_SPD;
fa193ff7
PZ
104 default:
105 DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type);
ed517fbb 106 return 0;
fa193ff7 107 }
fa193ff7
PZ
108}
109
2da8af54
PZ
110static u32 hsw_infoframe_enable(struct dip_infoframe *frame)
111{
112 switch (frame->type) {
113 case DIP_TYPE_AVI:
114 return VIDEO_DIP_ENABLE_AVI_HSW;
115 case DIP_TYPE_SPD:
116 return VIDEO_DIP_ENABLE_SPD_HSW;
117 default:
118 DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type);
119 return 0;
120 }
121}
122
123static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame, enum pipe pipe)
124{
125 switch (frame->type) {
126 case DIP_TYPE_AVI:
127 return HSW_TVIDEO_DIP_AVI_DATA(pipe);
128 case DIP_TYPE_SPD:
129 return HSW_TVIDEO_DIP_SPD_DATA(pipe);
130 default:
131 DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type);
132 return 0;
133 }
134}
135
a3da1df7
DV
136static void g4x_write_infoframe(struct drm_encoder *encoder,
137 struct dip_infoframe *frame)
45187ace
JB
138{
139 uint32_t *data = (uint32_t *)frame;
3c17fe4b
DH
140 struct drm_device *dev = encoder->dev;
141 struct drm_i915_private *dev_priv = dev->dev_private;
22509ec8 142 u32 val = I915_READ(VIDEO_DIP_CTL);
45187ace 143 unsigned i, len = DIP_HEADER_SIZE + frame->len;
3c17fe4b 144
822974ae
PZ
145 WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n");
146
1d4f85ac 147 val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
bc2481f3 148 val |= g4x_infoframe_index(frame);
22509ec8 149
bc2481f3 150 val &= ~g4x_infoframe_enable(frame);
45187ace 151
22509ec8 152 I915_WRITE(VIDEO_DIP_CTL, val);
3c17fe4b 153
9d9740f0 154 mmiowb();
45187ace 155 for (i = 0; i < len; i += 4) {
3c17fe4b
DH
156 I915_WRITE(VIDEO_DIP_DATA, *data);
157 data++;
158 }
adf00b26
PZ
159 /* Write every possible data byte to force correct ECC calculation. */
160 for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
161 I915_WRITE(VIDEO_DIP_DATA, 0);
9d9740f0 162 mmiowb();
3c17fe4b 163
bc2481f3 164 val |= g4x_infoframe_enable(frame);
60c5ea2d 165 val &= ~VIDEO_DIP_FREQ_MASK;
4b24c933 166 val |= VIDEO_DIP_FREQ_VSYNC;
45187ace 167
22509ec8 168 I915_WRITE(VIDEO_DIP_CTL, val);
9d9740f0 169 POSTING_READ(VIDEO_DIP_CTL);
3c17fe4b
DH
170}
171
fdf1250a
PZ
172static void ibx_write_infoframe(struct drm_encoder *encoder,
173 struct dip_infoframe *frame)
174{
175 uint32_t *data = (uint32_t *)frame;
176 struct drm_device *dev = encoder->dev;
177 struct drm_i915_private *dev_priv = dev->dev_private;
ed517fbb 178 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
fdf1250a
PZ
179 int reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
180 unsigned i, len = DIP_HEADER_SIZE + frame->len;
181 u32 val = I915_READ(reg);
182
822974ae
PZ
183 WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n");
184
fdf1250a 185 val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
bc2481f3 186 val |= g4x_infoframe_index(frame);
fdf1250a 187
bc2481f3 188 val &= ~g4x_infoframe_enable(frame);
fdf1250a
PZ
189
190 I915_WRITE(reg, val);
191
9d9740f0 192 mmiowb();
fdf1250a
PZ
193 for (i = 0; i < len; i += 4) {
194 I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
195 data++;
196 }
adf00b26
PZ
197 /* Write every possible data byte to force correct ECC calculation. */
198 for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
199 I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
9d9740f0 200 mmiowb();
fdf1250a 201
bc2481f3 202 val |= g4x_infoframe_enable(frame);
fdf1250a 203 val &= ~VIDEO_DIP_FREQ_MASK;
4b24c933 204 val |= VIDEO_DIP_FREQ_VSYNC;
fdf1250a
PZ
205
206 I915_WRITE(reg, val);
9d9740f0 207 POSTING_READ(reg);
fdf1250a
PZ
208}
209
210static void cpt_write_infoframe(struct drm_encoder *encoder,
211 struct dip_infoframe *frame)
b055c8f3 212{
45187ace 213 uint32_t *data = (uint32_t *)frame;
b055c8f3
JB
214 struct drm_device *dev = encoder->dev;
215 struct drm_i915_private *dev_priv = dev->dev_private;
ed517fbb 216 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
b055c8f3 217 int reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
45187ace 218 unsigned i, len = DIP_HEADER_SIZE + frame->len;
22509ec8 219 u32 val = I915_READ(reg);
b055c8f3 220
822974ae
PZ
221 WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n");
222
64a8fc01 223 val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
bc2481f3 224 val |= g4x_infoframe_index(frame);
45187ace 225
ecb97851
PZ
226 /* The DIP control register spec says that we need to update the AVI
227 * infoframe without clearing its enable bit */
822974ae 228 if (frame->type != DIP_TYPE_AVI)
bc2481f3 229 val &= ~g4x_infoframe_enable(frame);
ecb97851 230
22509ec8 231 I915_WRITE(reg, val);
45187ace 232
9d9740f0 233 mmiowb();
45187ace 234 for (i = 0; i < len; i += 4) {
b055c8f3
JB
235 I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
236 data++;
237 }
adf00b26
PZ
238 /* Write every possible data byte to force correct ECC calculation. */
239 for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
240 I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
9d9740f0 241 mmiowb();
b055c8f3 242
bc2481f3 243 val |= g4x_infoframe_enable(frame);
60c5ea2d 244 val &= ~VIDEO_DIP_FREQ_MASK;
4b24c933 245 val |= VIDEO_DIP_FREQ_VSYNC;
45187ace 246
22509ec8 247 I915_WRITE(reg, val);
9d9740f0 248 POSTING_READ(reg);
45187ace 249}
90b107c8
SK
250
251static void vlv_write_infoframe(struct drm_encoder *encoder,
252 struct dip_infoframe *frame)
253{
254 uint32_t *data = (uint32_t *)frame;
255 struct drm_device *dev = encoder->dev;
256 struct drm_i915_private *dev_priv = dev->dev_private;
ed517fbb 257 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
90b107c8
SK
258 int reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
259 unsigned i, len = DIP_HEADER_SIZE + frame->len;
22509ec8 260 u32 val = I915_READ(reg);
90b107c8 261
822974ae
PZ
262 WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n");
263
90b107c8 264 val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
bc2481f3 265 val |= g4x_infoframe_index(frame);
22509ec8 266
bc2481f3 267 val &= ~g4x_infoframe_enable(frame);
90b107c8 268
22509ec8 269 I915_WRITE(reg, val);
90b107c8 270
9d9740f0 271 mmiowb();
90b107c8
SK
272 for (i = 0; i < len; i += 4) {
273 I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
274 data++;
275 }
adf00b26
PZ
276 /* Write every possible data byte to force correct ECC calculation. */
277 for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
278 I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
9d9740f0 279 mmiowb();
90b107c8 280
bc2481f3 281 val |= g4x_infoframe_enable(frame);
60c5ea2d 282 val &= ~VIDEO_DIP_FREQ_MASK;
4b24c933 283 val |= VIDEO_DIP_FREQ_VSYNC;
90b107c8 284
22509ec8 285 I915_WRITE(reg, val);
9d9740f0 286 POSTING_READ(reg);
90b107c8
SK
287}
288
8c5f5f7c 289static void hsw_write_infoframe(struct drm_encoder *encoder,
ed517fbb 290 struct dip_infoframe *frame)
8c5f5f7c 291{
2da8af54
PZ
292 uint32_t *data = (uint32_t *)frame;
293 struct drm_device *dev = encoder->dev;
294 struct drm_i915_private *dev_priv = dev->dev_private;
295 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
296 u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->pipe);
297 u32 data_reg = hsw_infoframe_data_reg(frame, intel_crtc->pipe);
298 unsigned int i, len = DIP_HEADER_SIZE + frame->len;
299 u32 val = I915_READ(ctl_reg);
8c5f5f7c 300
2da8af54
PZ
301 if (data_reg == 0)
302 return;
303
2da8af54
PZ
304 val &= ~hsw_infoframe_enable(frame);
305 I915_WRITE(ctl_reg, val);
306
9d9740f0 307 mmiowb();
2da8af54
PZ
308 for (i = 0; i < len; i += 4) {
309 I915_WRITE(data_reg + i, *data);
310 data++;
311 }
adf00b26
PZ
312 /* Write every possible data byte to force correct ECC calculation. */
313 for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
314 I915_WRITE(data_reg + i, 0);
9d9740f0 315 mmiowb();
8c5f5f7c 316
2da8af54
PZ
317 val |= hsw_infoframe_enable(frame);
318 I915_WRITE(ctl_reg, val);
9d9740f0 319 POSTING_READ(ctl_reg);
8c5f5f7c
ED
320}
321
45187ace
JB
322static void intel_set_infoframe(struct drm_encoder *encoder,
323 struct dip_infoframe *frame)
324{
325 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
326
45187ace
JB
327 intel_dip_infoframe_csum(frame);
328 intel_hdmi->write_infoframe(encoder, frame);
329}
330
687f4d06 331static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
c846b619 332 struct drm_display_mode *adjusted_mode)
45187ace 333{
abedc077 334 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
45187ace
JB
335 struct dip_infoframe avi_if = {
336 .type = DIP_TYPE_AVI,
337 .ver = DIP_VERSION_AVI,
338 .len = DIP_LEN_AVI,
339 };
340
c846b619
PZ
341 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
342 avi_if.body.avi.YQ_CN_PR |= DIP_AVI_PR_2;
343
abedc077
VS
344 if (intel_hdmi->rgb_quant_range_selectable) {
345 if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
346 avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED;
347 else
348 avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL;
349 }
350
9a69b885
PZ
351 avi_if.body.avi.VIC = drm_mode_cea_vic(adjusted_mode);
352
45187ace 353 intel_set_infoframe(encoder, &avi_if);
b055c8f3
JB
354}
355
687f4d06 356static void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder)
c0864cb3
JB
357{
358 struct dip_infoframe spd_if;
359
360 memset(&spd_if, 0, sizeof(spd_if));
361 spd_if.type = DIP_TYPE_SPD;
362 spd_if.ver = DIP_VERSION_SPD;
363 spd_if.len = DIP_LEN_SPD;
364 strcpy(spd_if.body.spd.vn, "Intel");
365 strcpy(spd_if.body.spd.pd, "Integrated gfx");
366 spd_if.body.spd.sdi = DIP_SPD_PC;
367
368 intel_set_infoframe(encoder, &spd_if);
369}
370
687f4d06
PZ
371static void g4x_set_infoframes(struct drm_encoder *encoder,
372 struct drm_display_mode *adjusted_mode)
373{
0c14c7f9 374 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
69fde0a6
VS
375 struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
376 struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
0c14c7f9
PZ
377 u32 reg = VIDEO_DIP_CTL;
378 u32 val = I915_READ(reg);
72b78c9d 379 u32 port;
0c14c7f9 380
afba0188
DV
381 assert_hdmi_port_disabled(intel_hdmi);
382
0c14c7f9
PZ
383 /* If the registers were not initialized yet, they might be zeroes,
384 * which means we're selecting the AVI DIP and we're setting its
385 * frequency to once. This seems to really confuse the HW and make
386 * things stop working (the register spec says the AVI always needs to
387 * be sent every VSync). So here we avoid writing to the register more
388 * than we need and also explicitly select the AVI DIP and explicitly
389 * set its frequency to every VSync. Avoiding to write it twice seems to
390 * be enough to solve the problem, but being defensive shouldn't hurt us
391 * either. */
392 val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;
393
394 if (!intel_hdmi->has_hdmi_sink) {
395 if (!(val & VIDEO_DIP_ENABLE))
396 return;
397 val &= ~VIDEO_DIP_ENABLE;
398 I915_WRITE(reg, val);
9d9740f0 399 POSTING_READ(reg);
0c14c7f9
PZ
400 return;
401 }
402
69fde0a6
VS
403 switch (intel_dig_port->port) {
404 case PORT_B:
72b78c9d 405 port = VIDEO_DIP_PORT_B;
f278d972 406 break;
69fde0a6 407 case PORT_C:
72b78c9d 408 port = VIDEO_DIP_PORT_C;
f278d972
PZ
409 break;
410 default:
57df2ae9 411 BUG();
f278d972
PZ
412 return;
413 }
414
72b78c9d
PZ
415 if (port != (val & VIDEO_DIP_PORT_MASK)) {
416 if (val & VIDEO_DIP_ENABLE) {
417 val &= ~VIDEO_DIP_ENABLE;
418 I915_WRITE(reg, val);
9d9740f0 419 POSTING_READ(reg);
72b78c9d
PZ
420 }
421 val &= ~VIDEO_DIP_PORT_MASK;
422 val |= port;
423 }
424
822974ae 425 val |= VIDEO_DIP_ENABLE;
0dd87d20 426 val &= ~VIDEO_DIP_ENABLE_VENDOR;
822974ae 427
f278d972 428 I915_WRITE(reg, val);
9d9740f0 429 POSTING_READ(reg);
f278d972 430
687f4d06
PZ
431 intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
432 intel_hdmi_set_spd_infoframe(encoder);
433}
434
435static void ibx_set_infoframes(struct drm_encoder *encoder,
436 struct drm_display_mode *adjusted_mode)
437{
0c14c7f9
PZ
438 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
439 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
69fde0a6
VS
440 struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
441 struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
0c14c7f9
PZ
442 u32 reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
443 u32 val = I915_READ(reg);
72b78c9d 444 u32 port;
0c14c7f9 445
afba0188
DV
446 assert_hdmi_port_disabled(intel_hdmi);
447
0c14c7f9
PZ
448 /* See the big comment in g4x_set_infoframes() */
449 val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;
450
451 if (!intel_hdmi->has_hdmi_sink) {
452 if (!(val & VIDEO_DIP_ENABLE))
453 return;
454 val &= ~VIDEO_DIP_ENABLE;
455 I915_WRITE(reg, val);
9d9740f0 456 POSTING_READ(reg);
0c14c7f9
PZ
457 return;
458 }
459
69fde0a6
VS
460 switch (intel_dig_port->port) {
461 case PORT_B:
72b78c9d 462 port = VIDEO_DIP_PORT_B;
f278d972 463 break;
69fde0a6 464 case PORT_C:
72b78c9d 465 port = VIDEO_DIP_PORT_C;
f278d972 466 break;
69fde0a6 467 case PORT_D:
72b78c9d 468 port = VIDEO_DIP_PORT_D;
f278d972
PZ
469 break;
470 default:
57df2ae9 471 BUG();
f278d972
PZ
472 return;
473 }
474
72b78c9d
PZ
475 if (port != (val & VIDEO_DIP_PORT_MASK)) {
476 if (val & VIDEO_DIP_ENABLE) {
477 val &= ~VIDEO_DIP_ENABLE;
478 I915_WRITE(reg, val);
9d9740f0 479 POSTING_READ(reg);
72b78c9d
PZ
480 }
481 val &= ~VIDEO_DIP_PORT_MASK;
482 val |= port;
483 }
484
822974ae 485 val |= VIDEO_DIP_ENABLE;
0dd87d20
PZ
486 val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
487 VIDEO_DIP_ENABLE_GCP);
822974ae 488
f278d972 489 I915_WRITE(reg, val);
9d9740f0 490 POSTING_READ(reg);
f278d972 491
687f4d06
PZ
492 intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
493 intel_hdmi_set_spd_infoframe(encoder);
494}
495
496static void cpt_set_infoframes(struct drm_encoder *encoder,
497 struct drm_display_mode *adjusted_mode)
498{
0c14c7f9
PZ
499 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
500 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
501 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
502 u32 reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
503 u32 val = I915_READ(reg);
504
afba0188
DV
505 assert_hdmi_port_disabled(intel_hdmi);
506
0c14c7f9
PZ
507 /* See the big comment in g4x_set_infoframes() */
508 val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;
509
510 if (!intel_hdmi->has_hdmi_sink) {
511 if (!(val & VIDEO_DIP_ENABLE))
512 return;
513 val &= ~(VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI);
514 I915_WRITE(reg, val);
9d9740f0 515 POSTING_READ(reg);
0c14c7f9
PZ
516 return;
517 }
518
822974ae
PZ
519 /* Set both together, unset both together: see the spec. */
520 val |= VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI;
0dd87d20
PZ
521 val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
522 VIDEO_DIP_ENABLE_GCP);
822974ae
PZ
523
524 I915_WRITE(reg, val);
9d9740f0 525 POSTING_READ(reg);
822974ae 526
687f4d06
PZ
527 intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
528 intel_hdmi_set_spd_infoframe(encoder);
529}
530
531static void vlv_set_infoframes(struct drm_encoder *encoder,
532 struct drm_display_mode *adjusted_mode)
533{
0c14c7f9
PZ
534 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
535 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
536 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
537 u32 reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
538 u32 val = I915_READ(reg);
539
afba0188
DV
540 assert_hdmi_port_disabled(intel_hdmi);
541
0c14c7f9
PZ
542 /* See the big comment in g4x_set_infoframes() */
543 val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;
544
545 if (!intel_hdmi->has_hdmi_sink) {
546 if (!(val & VIDEO_DIP_ENABLE))
547 return;
548 val &= ~VIDEO_DIP_ENABLE;
549 I915_WRITE(reg, val);
9d9740f0 550 POSTING_READ(reg);
0c14c7f9
PZ
551 return;
552 }
553
822974ae 554 val |= VIDEO_DIP_ENABLE;
0dd87d20
PZ
555 val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
556 VIDEO_DIP_ENABLE_GCP);
822974ae
PZ
557
558 I915_WRITE(reg, val);
9d9740f0 559 POSTING_READ(reg);
822974ae 560
687f4d06
PZ
561 intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
562 intel_hdmi_set_spd_infoframe(encoder);
563}
564
565static void hsw_set_infoframes(struct drm_encoder *encoder,
566 struct drm_display_mode *adjusted_mode)
567{
0c14c7f9
PZ
568 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
569 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
570 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
571 u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->pipe);
0dd87d20 572 u32 val = I915_READ(reg);
0c14c7f9 573
afba0188
DV
574 assert_hdmi_port_disabled(intel_hdmi);
575
0c14c7f9
PZ
576 if (!intel_hdmi->has_hdmi_sink) {
577 I915_WRITE(reg, 0);
9d9740f0 578 POSTING_READ(reg);
0c14c7f9
PZ
579 return;
580 }
581
0dd87d20
PZ
582 val &= ~(VIDEO_DIP_ENABLE_VSC_HSW | VIDEO_DIP_ENABLE_GCP_HSW |
583 VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW);
584
585 I915_WRITE(reg, val);
9d9740f0 586 POSTING_READ(reg);
0dd87d20 587
687f4d06
PZ
588 intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
589 intel_hdmi_set_spd_infoframe(encoder);
590}
591
7d57382e
EA
592static void intel_hdmi_mode_set(struct drm_encoder *encoder,
593 struct drm_display_mode *mode,
594 struct drm_display_mode *adjusted_mode)
595{
596 struct drm_device *dev = encoder->dev;
597 struct drm_i915_private *dev_priv = dev->dev_private;
ed517fbb 598 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
ea5b213a 599 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
7d57382e
EA
600 u32 sdvox;
601
b659c3db 602 sdvox = SDVO_ENCODING_HDMI;
5d4fac97
JB
603 if (!HAS_PCH_SPLIT(dev))
604 sdvox |= intel_hdmi->color_range;
b599c0bc
AJ
605 if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
606 sdvox |= SDVO_VSYNC_ACTIVE_HIGH;
607 if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
608 sdvox |= SDVO_HSYNC_ACTIVE_HIGH;
7d57382e 609
020f6704
JB
610 if (intel_crtc->bpp > 24)
611 sdvox |= COLOR_FORMAT_12bpc;
612 else
613 sdvox |= COLOR_FORMAT_8bpc;
614
2e3d6006
ZW
615 /* Required on CPT */
616 if (intel_hdmi->has_hdmi_sink && HAS_PCH_CPT(dev))
617 sdvox |= HDMI_MODE_SELECT;
618
3c17fe4b 619 if (intel_hdmi->has_audio) {
e0dac65e
WF
620 DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n",
621 pipe_name(intel_crtc->pipe));
7d57382e 622 sdvox |= SDVO_AUDIO_ENABLE;
3c17fe4b 623 sdvox |= SDVO_NULL_PACKETS_DURING_VSYNC;
e0dac65e 624 intel_write_eld(encoder, adjusted_mode);
3c17fe4b 625 }
7d57382e 626
75770564
JB
627 if (HAS_PCH_CPT(dev))
628 sdvox |= PORT_TRANS_SEL_CPT(intel_crtc->pipe);
7a87c289 629 else if (intel_crtc->pipe == PIPE_B)
75770564 630 sdvox |= SDVO_PIPE_B_SELECT;
7d57382e 631
ea5b213a
CW
632 I915_WRITE(intel_hdmi->sdvox_reg, sdvox);
633 POSTING_READ(intel_hdmi->sdvox_reg);
3c17fe4b 634
687f4d06 635 intel_hdmi->set_infoframes(encoder, adjusted_mode);
7d57382e
EA
636}
637
85234cdc
DV
638static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
639 enum pipe *pipe)
7d57382e 640{
85234cdc 641 struct drm_device *dev = encoder->base.dev;
7d57382e 642 struct drm_i915_private *dev_priv = dev->dev_private;
85234cdc
DV
643 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
644 u32 tmp;
645
646 tmp = I915_READ(intel_hdmi->sdvox_reg);
647
648 if (!(tmp & SDVO_ENABLE))
649 return false;
650
651 if (HAS_PCH_CPT(dev))
652 *pipe = PORT_TO_PIPE_CPT(tmp);
653 else
654 *pipe = PORT_TO_PIPE(tmp);
655
656 return true;
657}
658
5ab432ef 659static void intel_enable_hdmi(struct intel_encoder *encoder)
7d57382e 660{
5ab432ef 661 struct drm_device *dev = encoder->base.dev;
7d57382e 662 struct drm_i915_private *dev_priv = dev->dev_private;
5ab432ef 663 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
7d57382e 664 u32 temp;
2deed761
WF
665 u32 enable_bits = SDVO_ENABLE;
666
667 if (intel_hdmi->has_audio)
668 enable_bits |= SDVO_AUDIO_ENABLE;
7d57382e 669
ea5b213a 670 temp = I915_READ(intel_hdmi->sdvox_reg);
d8a2d0e0 671
7a87c289
DV
672 /* HW workaround for IBX, we need to move the port to transcoder A
673 * before disabling it. */
674 if (HAS_PCH_IBX(dev)) {
5ab432ef 675 struct drm_crtc *crtc = encoder->base.crtc;
7a87c289
DV
676 int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1;
677
5ab432ef
DV
678 /* Restore the transcoder select bit. */
679 if (pipe == PIPE_B)
680 enable_bits |= SDVO_PIPE_B_SELECT;
7a87c289
DV
681 }
682
d8a2d0e0
ZW
683 /* HW workaround, need to toggle enable bit off and on for 12bpc, but
684 * we do this anyway which shows more stable in testing.
685 */
c619eed4 686 if (HAS_PCH_SPLIT(dev)) {
ea5b213a
CW
687 I915_WRITE(intel_hdmi->sdvox_reg, temp & ~SDVO_ENABLE);
688 POSTING_READ(intel_hdmi->sdvox_reg);
d8a2d0e0
ZW
689 }
690
5ab432ef
DV
691 temp |= enable_bits;
692
693 I915_WRITE(intel_hdmi->sdvox_reg, temp);
694 POSTING_READ(intel_hdmi->sdvox_reg);
695
696 /* HW workaround, need to write this twice for issue that may result
697 * in first write getting masked.
698 */
699 if (HAS_PCH_SPLIT(dev)) {
700 I915_WRITE(intel_hdmi->sdvox_reg, temp);
701 POSTING_READ(intel_hdmi->sdvox_reg);
7d57382e 702 }
5ab432ef
DV
703}
704
705static void intel_disable_hdmi(struct intel_encoder *encoder)
706{
707 struct drm_device *dev = encoder->base.dev;
708 struct drm_i915_private *dev_priv = dev->dev_private;
709 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
710 u32 temp;
3cce574f 711 u32 enable_bits = SDVO_ENABLE | SDVO_AUDIO_ENABLE;
5ab432ef
DV
712
713 temp = I915_READ(intel_hdmi->sdvox_reg);
714
715 /* HW workaround for IBX, we need to move the port to transcoder A
716 * before disabling it. */
717 if (HAS_PCH_IBX(dev)) {
718 struct drm_crtc *crtc = encoder->base.crtc;
719 int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1;
720
721 if (temp & SDVO_PIPE_B_SELECT) {
722 temp &= ~SDVO_PIPE_B_SELECT;
723 I915_WRITE(intel_hdmi->sdvox_reg, temp);
724 POSTING_READ(intel_hdmi->sdvox_reg);
725
726 /* Again we need to write this twice. */
727 I915_WRITE(intel_hdmi->sdvox_reg, temp);
728 POSTING_READ(intel_hdmi->sdvox_reg);
729
730 /* Transcoder selection bits only update
731 * effectively on vblank. */
732 if (crtc)
733 intel_wait_for_vblank(dev, pipe);
734 else
735 msleep(50);
736 }
7d57382e 737 }
d8a2d0e0 738
5ab432ef
DV
739 /* HW workaround, need to toggle enable bit off and on for 12bpc, but
740 * we do this anyway which shows more stable in testing.
741 */
742 if (HAS_PCH_SPLIT(dev)) {
743 I915_WRITE(intel_hdmi->sdvox_reg, temp & ~SDVO_ENABLE);
744 POSTING_READ(intel_hdmi->sdvox_reg);
745 }
746
747 temp &= ~enable_bits;
d8a2d0e0 748
ea5b213a
CW
749 I915_WRITE(intel_hdmi->sdvox_reg, temp);
750 POSTING_READ(intel_hdmi->sdvox_reg);
d8a2d0e0
ZW
751
752 /* HW workaround, need to write this twice for issue that may result
753 * in first write getting masked.
754 */
c619eed4 755 if (HAS_PCH_SPLIT(dev)) {
ea5b213a
CW
756 I915_WRITE(intel_hdmi->sdvox_reg, temp);
757 POSTING_READ(intel_hdmi->sdvox_reg);
d8a2d0e0 758 }
7d57382e
EA
759}
760
7d57382e
EA
761static int intel_hdmi_mode_valid(struct drm_connector *connector,
762 struct drm_display_mode *mode)
763{
764 if (mode->clock > 165000)
765 return MODE_CLOCK_HIGH;
766 if (mode->clock < 20000)
5cbba41d 767 return MODE_CLOCK_LOW;
7d57382e
EA
768
769 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
770 return MODE_NO_DBLESCAN;
771
772 return MODE_OK;
773}
774
00c09d70
PZ
775bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
776 const struct drm_display_mode *mode,
777 struct drm_display_mode *adjusted_mode)
7d57382e 778{
3685a8f3
VS
779 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
780
55bc60db
VS
781 if (intel_hdmi->color_range_auto) {
782 /* See CEA-861-E - 5.1 Default Encoding Parameters */
783 if (intel_hdmi->has_hdmi_sink &&
784 drm_mode_cea_vic(adjusted_mode) > 1)
785 intel_hdmi->color_range = SDVO_COLOR_RANGE_16_235;
786 else
787 intel_hdmi->color_range = 0;
788 }
789
3685a8f3
VS
790 if (intel_hdmi->color_range)
791 adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
792
7d57382e
EA
793 return true;
794}
795
8ec22b21
CW
796static bool g4x_hdmi_connected(struct intel_hdmi *intel_hdmi)
797{
30add22d 798 struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi);
8ec22b21 799 struct drm_i915_private *dev_priv = dev->dev_private;
69fde0a6 800 struct intel_digital_port *intel_dig_port = hdmi_to_dig_port(intel_hdmi);
8ec22b21
CW
801 uint32_t bit;
802
69fde0a6
VS
803 switch (intel_dig_port->port) {
804 case PORT_B:
26739f12 805 bit = PORTB_HOTPLUG_LIVE_STATUS;
8ec22b21 806 break;
69fde0a6 807 case PORT_C:
26739f12 808 bit = PORTC_HOTPLUG_LIVE_STATUS;
8ec22b21 809 break;
8ec22b21
CW
810 default:
811 bit = 0;
812 break;
813 }
814
815 return I915_READ(PORT_HOTPLUG_STAT) & bit;
816}
817
aa93d632 818static enum drm_connector_status
930a9e28 819intel_hdmi_detect(struct drm_connector *connector, bool force)
9dff6af8 820{
b0ea7d37 821 struct drm_device *dev = connector->dev;
df0e9248 822 struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
d63885da
PZ
823 struct intel_digital_port *intel_dig_port =
824 hdmi_to_dig_port(intel_hdmi);
825 struct intel_encoder *intel_encoder = &intel_dig_port->base;
b0ea7d37 826 struct drm_i915_private *dev_priv = dev->dev_private;
f899fc64 827 struct edid *edid;
aa93d632 828 enum drm_connector_status status = connector_status_disconnected;
9dff6af8 829
b0ea7d37
DL
830
831 if (IS_G4X(dev) && !g4x_hdmi_connected(intel_hdmi))
8ec22b21 832 return status;
b0ea7d37
DL
833 else if (HAS_PCH_SPLIT(dev) &&
834 !ibx_digital_port_connected(dev_priv, intel_dig_port))
835 return status;
8ec22b21 836
ea5b213a 837 intel_hdmi->has_hdmi_sink = false;
2e3d6006 838 intel_hdmi->has_audio = false;
abedc077 839 intel_hdmi->rgb_quant_range_selectable = false;
f899fc64 840 edid = drm_get_edid(connector,
3bd7d909
DK
841 intel_gmbus_get_adapter(dev_priv,
842 intel_hdmi->ddc_bus));
2ded9e27 843
aa93d632 844 if (edid) {
be9f1c4f 845 if (edid->input & DRM_EDID_INPUT_DIGITAL) {
aa93d632 846 status = connector_status_connected;
b1d7e4b4
WF
847 if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI)
848 intel_hdmi->has_hdmi_sink =
849 drm_detect_hdmi_monitor(edid);
2e3d6006 850 intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
abedc077
VS
851 intel_hdmi->rgb_quant_range_selectable =
852 drm_rgb_quant_range_selectable(edid);
aa93d632 853 }
aa93d632 854 kfree(edid);
9dff6af8 855 }
30ad48b7 856
55b7d6e8 857 if (status == connector_status_connected) {
b1d7e4b4
WF
858 if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO)
859 intel_hdmi->has_audio =
860 (intel_hdmi->force_audio == HDMI_AUDIO_ON);
d63885da 861 intel_encoder->type = INTEL_OUTPUT_HDMI;
55b7d6e8
CW
862 }
863
2ded9e27 864 return status;
7d57382e
EA
865}
866
867static int intel_hdmi_get_modes(struct drm_connector *connector)
868{
df0e9248 869 struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
f899fc64 870 struct drm_i915_private *dev_priv = connector->dev->dev_private;
7d57382e
EA
871
872 /* We should parse the EDID data and find out if it's an HDMI sink so
873 * we can send audio to it.
874 */
875
f899fc64 876 return intel_ddc_get_modes(connector,
3bd7d909
DK
877 intel_gmbus_get_adapter(dev_priv,
878 intel_hdmi->ddc_bus));
7d57382e
EA
879}
880
1aad7ac0
CW
881static bool
882intel_hdmi_detect_audio(struct drm_connector *connector)
883{
884 struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
885 struct drm_i915_private *dev_priv = connector->dev->dev_private;
886 struct edid *edid;
887 bool has_audio = false;
888
889 edid = drm_get_edid(connector,
3bd7d909
DK
890 intel_gmbus_get_adapter(dev_priv,
891 intel_hdmi->ddc_bus));
1aad7ac0
CW
892 if (edid) {
893 if (edid->input & DRM_EDID_INPUT_DIGITAL)
894 has_audio = drm_detect_monitor_audio(edid);
1aad7ac0
CW
895 kfree(edid);
896 }
897
898 return has_audio;
899}
900
55b7d6e8
CW
901static int
902intel_hdmi_set_property(struct drm_connector *connector,
ed517fbb
PZ
903 struct drm_property *property,
904 uint64_t val)
55b7d6e8
CW
905{
906 struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
da63a9f2
PZ
907 struct intel_digital_port *intel_dig_port =
908 hdmi_to_dig_port(intel_hdmi);
e953fd7b 909 struct drm_i915_private *dev_priv = connector->dev->dev_private;
55b7d6e8
CW
910 int ret;
911
662595df 912 ret = drm_object_property_set_value(&connector->base, property, val);
55b7d6e8
CW
913 if (ret)
914 return ret;
915
3f43c48d 916 if (property == dev_priv->force_audio_property) {
b1d7e4b4 917 enum hdmi_force_audio i = val;
1aad7ac0
CW
918 bool has_audio;
919
920 if (i == intel_hdmi->force_audio)
55b7d6e8
CW
921 return 0;
922
1aad7ac0 923 intel_hdmi->force_audio = i;
55b7d6e8 924
b1d7e4b4 925 if (i == HDMI_AUDIO_AUTO)
1aad7ac0
CW
926 has_audio = intel_hdmi_detect_audio(connector);
927 else
b1d7e4b4 928 has_audio = (i == HDMI_AUDIO_ON);
1aad7ac0 929
b1d7e4b4
WF
930 if (i == HDMI_AUDIO_OFF_DVI)
931 intel_hdmi->has_hdmi_sink = 0;
55b7d6e8 932
1aad7ac0 933 intel_hdmi->has_audio = has_audio;
55b7d6e8
CW
934 goto done;
935 }
936
e953fd7b 937 if (property == dev_priv->broadcast_rgb_property) {
55bc60db
VS
938 switch (val) {
939 case INTEL_BROADCAST_RGB_AUTO:
940 intel_hdmi->color_range_auto = true;
941 break;
942 case INTEL_BROADCAST_RGB_FULL:
943 intel_hdmi->color_range_auto = false;
944 intel_hdmi->color_range = 0;
945 break;
946 case INTEL_BROADCAST_RGB_LIMITED:
947 intel_hdmi->color_range_auto = false;
948 intel_hdmi->color_range = SDVO_COLOR_RANGE_16_235;
949 break;
950 default:
951 return -EINVAL;
952 }
e953fd7b
CW
953 goto done;
954 }
955
55b7d6e8
CW
956 return -EINVAL;
957
958done:
c0c36b94
CW
959 if (intel_dig_port->base.base.crtc)
960 intel_crtc_restore_mode(intel_dig_port->base.base.crtc);
55b7d6e8
CW
961
962 return 0;
963}
964
7d57382e
EA
965static void intel_hdmi_destroy(struct drm_connector *connector)
966{
7d57382e
EA
967 drm_sysfs_connector_remove(connector);
968 drm_connector_cleanup(connector);
674e2d08 969 kfree(connector);
7d57382e
EA
970}
971
972static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
7d57382e 973 .mode_fixup = intel_hdmi_mode_fixup,
7d57382e 974 .mode_set = intel_hdmi_mode_set,
1f703855 975 .disable = intel_encoder_noop,
7d57382e
EA
976};
977
978static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
5ab432ef 979 .dpms = intel_connector_dpms,
7d57382e
EA
980 .detect = intel_hdmi_detect,
981 .fill_modes = drm_helper_probe_single_connector_modes,
55b7d6e8 982 .set_property = intel_hdmi_set_property,
7d57382e
EA
983 .destroy = intel_hdmi_destroy,
984};
985
986static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = {
987 .get_modes = intel_hdmi_get_modes,
988 .mode_valid = intel_hdmi_mode_valid,
df0e9248 989 .best_encoder = intel_best_encoder,
7d57382e
EA
990};
991
7d57382e 992static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
ea5b213a 993 .destroy = intel_encoder_destroy,
7d57382e
EA
994};
995
55b7d6e8
CW
996static void
997intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector)
998{
3f43c48d 999 intel_attach_force_audio_property(connector);
e953fd7b 1000 intel_attach_broadcast_rgb_property(connector);
55bc60db 1001 intel_hdmi->color_range_auto = true;
55b7d6e8
CW
1002}
1003
00c09d70
PZ
1004void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
1005 struct intel_connector *intel_connector)
7d57382e 1006{
b9cb234c
PZ
1007 struct drm_connector *connector = &intel_connector->base;
1008 struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
1009 struct intel_encoder *intel_encoder = &intel_dig_port->base;
1010 struct drm_device *dev = intel_encoder->base.dev;
7d57382e 1011 struct drm_i915_private *dev_priv = dev->dev_private;
174edf1f 1012 enum port port = intel_dig_port->port;
373a3cf7 1013
7d57382e 1014 drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
8d91104a 1015 DRM_MODE_CONNECTOR_HDMIA);
7d57382e
EA
1016 drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
1017
eb1f8e4f 1018 connector->polled = DRM_CONNECTOR_POLL_HPD;
c3febcc4 1019 connector->interlace_allowed = 1;
7d57382e 1020 connector->doublescan_allowed = 0;
66a9278e 1021
08d644ad
DV
1022 switch (port) {
1023 case PORT_B:
f899fc64 1024 intel_hdmi->ddc_bus = GMBUS_PORT_DPB;
26739f12 1025 dev_priv->hotplug_supported_mask |= PORTB_HOTPLUG_INT_STATUS;
08d644ad
DV
1026 break;
1027 case PORT_C:
7ceae0a5 1028 intel_hdmi->ddc_bus = GMBUS_PORT_DPC;
26739f12 1029 dev_priv->hotplug_supported_mask |= PORTC_HOTPLUG_INT_STATUS;
08d644ad
DV
1030 break;
1031 case PORT_D:
7ceae0a5 1032 intel_hdmi->ddc_bus = GMBUS_PORT_DPD;
26739f12 1033 dev_priv->hotplug_supported_mask |= PORTD_HOTPLUG_INT_STATUS;
08d644ad
DV
1034 break;
1035 case PORT_A:
1036 /* Internal port only for eDP. */
1037 default:
6e4c1677 1038 BUG();
f8aed700 1039 }
7d57382e 1040
64a8fc01 1041 if (!HAS_PCH_SPLIT(dev)) {
a3da1df7 1042 intel_hdmi->write_infoframe = g4x_write_infoframe;
687f4d06 1043 intel_hdmi->set_infoframes = g4x_set_infoframes;
90b107c8
SK
1044 } else if (IS_VALLEYVIEW(dev)) {
1045 intel_hdmi->write_infoframe = vlv_write_infoframe;
687f4d06 1046 intel_hdmi->set_infoframes = vlv_set_infoframes;
22b8bf17 1047 } else if (HAS_DDI(dev)) {
8c5f5f7c 1048 intel_hdmi->write_infoframe = hsw_write_infoframe;
687f4d06 1049 intel_hdmi->set_infoframes = hsw_set_infoframes;
fdf1250a
PZ
1050 } else if (HAS_PCH_IBX(dev)) {
1051 intel_hdmi->write_infoframe = ibx_write_infoframe;
687f4d06 1052 intel_hdmi->set_infoframes = ibx_set_infoframes;
fdf1250a
PZ
1053 } else {
1054 intel_hdmi->write_infoframe = cpt_write_infoframe;
687f4d06 1055 intel_hdmi->set_infoframes = cpt_set_infoframes;
64a8fc01 1056 }
45187ace 1057
affa9354 1058 if (HAS_DDI(dev))
bcbc889b
PZ
1059 intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
1060 else
1061 intel_connector->get_hw_state = intel_connector_get_hw_state;
b9cb234c
PZ
1062
1063 intel_hdmi_add_properties(intel_hdmi, connector);
1064
1065 intel_connector_attach_encoder(intel_connector, intel_encoder);
1066 drm_sysfs_connector_add(connector);
1067
1068 /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
1069 * 0xd. Failure to do so will result in spurious interrupts being
1070 * generated on the port when a cable is not attached.
1071 */
1072 if (IS_G4X(dev) && !IS_GM45(dev)) {
1073 u32 temp = I915_READ(PEG_BAND_GAP_DATA);
1074 I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
1075 }
1076}
1077
1078void intel_hdmi_init(struct drm_device *dev, int sdvox_reg, enum port port)
1079{
1080 struct intel_digital_port *intel_dig_port;
1081 struct intel_encoder *intel_encoder;
1082 struct drm_encoder *encoder;
1083 struct intel_connector *intel_connector;
1084
1085 intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL);
1086 if (!intel_dig_port)
1087 return;
1088
1089 intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
1090 if (!intel_connector) {
1091 kfree(intel_dig_port);
1092 return;
1093 }
1094
1095 intel_encoder = &intel_dig_port->base;
1096 encoder = &intel_encoder->base;
1097
1098 drm_encoder_init(dev, &intel_encoder->base, &intel_hdmi_enc_funcs,
1099 DRM_MODE_ENCODER_TMDS);
00c09d70
PZ
1100 drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs);
1101
1102 intel_encoder->enable = intel_enable_hdmi;
1103 intel_encoder->disable = intel_disable_hdmi;
1104 intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
5ab432ef 1105
b9cb234c
PZ
1106 intel_encoder->type = INTEL_OUTPUT_HDMI;
1107 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
1108 intel_encoder->cloneable = false;
7d57382e 1109
174edf1f 1110 intel_dig_port->port = port;
b9cb234c
PZ
1111 intel_dig_port->hdmi.sdvox_reg = sdvox_reg;
1112 intel_dig_port->dp.output_reg = 0;
55b7d6e8 1113
b9cb234c 1114 intel_hdmi_init_connector(intel_dig_port, intel_connector);
7d57382e 1115}