Blame view

drivers/gpu/drm/i915/intel_hdmi.c 37.6 KB
7d57382e6   Eric Anholt   drm/i915: Add sup...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  /*
   * Copyright 2006 Dave Airlie <airlied@linux.ie>
   * Copyright © 2006-2009 Intel Corporation
   *
   * Permission is hereby granted, free of charge, to any person obtaining a
   * copy of this software and associated documentation files (the "Software"),
   * to deal in the Software without restriction, including without limitation
   * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   * and/or sell copies of the Software, and to permit persons to whom the
   * Software is furnished to do so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice (including the next
   * paragraph) shall be included in all copies or substantial portions of the
   * Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   * DEALINGS IN THE SOFTWARE.
   *
   * Authors:
   *	Eric Anholt <eric@anholt.net>
   *	Jesse Barnes <jesse.barnes@intel.com>
   */
  
  #include <linux/i2c.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
30
  #include <linux/slab.h>
7d57382e6   Eric Anholt   drm/i915: Add sup...
31
  #include <linux/delay.h>
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
32
  #include <linux/hdmi.h>
760285e7e   David Howells   UAPI: (Scripted) ...
33
34
35
  #include <drm/drmP.h>
  #include <drm/drm_crtc.h>
  #include <drm/drm_edid.h>
7d57382e6   Eric Anholt   drm/i915: Add sup...
36
  #include "intel_drv.h"
760285e7e   David Howells   UAPI: (Scripted) ...
37
  #include <drm/i915_drm.h>
7d57382e6   Eric Anholt   drm/i915: Add sup...
38
  #include "i915_drv.h"
30add22d8   Paulo Zanoni   drm/i915: add int...
39
40
  static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi)
  {
da63a9f2e   Paulo Zanoni   drm/i915: create ...
41
  	return hdmi_to_dig_port(intel_hdmi)->base.base.dev;
30add22d8   Paulo Zanoni   drm/i915: add int...
42
  }
afba01889   Daniel Vetter   drm/i915: ensure ...
43
44
45
  static void
  assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi)
  {
30add22d8   Paulo Zanoni   drm/i915: add int...
46
  	struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi);
afba01889   Daniel Vetter   drm/i915: ensure ...
47
48
  	struct drm_i915_private *dev_priv = dev->dev_private;
  	uint32_t enabled_bits;
affa93544   Paulo Zanoni   drm/i915: add HAS...
49
  	enabled_bits = HAS_DDI(dev) ? DDI_BUF_CTL_ENABLE : SDVO_ENABLE;
afba01889   Daniel Vetter   drm/i915: ensure ...
50

b242b7f74   Paulo Zanoni   drm/i915: rename ...
51
  	WARN(I915_READ(intel_hdmi->hdmi_reg) & enabled_bits,
afba01889   Daniel Vetter   drm/i915: ensure ...
52
53
54
  	     "HDMI port enabled, expecting disabled
  ");
  }
f5bbfca3e   Eugeni Dodonov   drm/i915: move HD...
55
  struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder)
ea5b213ad   Chris Wilson   drm/i915: Subclas...
56
  {
da63a9f2e   Paulo Zanoni   drm/i915: create ...
57
58
59
  	struct intel_digital_port *intel_dig_port =
  		container_of(encoder, struct intel_digital_port, base.base);
  	return &intel_dig_port->hdmi;
ea5b213ad   Chris Wilson   drm/i915: Subclas...
60
  }
df0e92488   Chris Wilson   drm/i915: Make th...
61
62
  static struct intel_hdmi *intel_attached_hdmi(struct drm_connector *connector)
  {
da63a9f2e   Paulo Zanoni   drm/i915: create ...
63
  	return enc_to_intel_hdmi(&intel_attached_encoder(connector)->base);
df0e92488   Chris Wilson   drm/i915: Make th...
64
  }
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
65
  static u32 g4x_infoframe_index(enum hdmi_infoframe_type type)
3c17fe4b8   David Härdeman   i915: enable AVI ...
66
  {
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
67
68
  	switch (type) {
  	case HDMI_INFOFRAME_TYPE_AVI:
ed517fbbb   Paulo Zanoni   drm/i915: small h...
69
  		return VIDEO_DIP_SELECT_AVI;
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
70
  	case HDMI_INFOFRAME_TYPE_SPD:
ed517fbbb   Paulo Zanoni   drm/i915: small h...
71
  		return VIDEO_DIP_SELECT_SPD;
c8bb75aff   Lespiau, Damien   drm/i915/hdmi: Wr...
72
73
  	case HDMI_INFOFRAME_TYPE_VENDOR:
  		return VIDEO_DIP_SELECT_VENDOR;
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
74
  	default:
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
75
76
  		DRM_DEBUG_DRIVER("unknown info frame type %d
  ", type);
ed517fbbb   Paulo Zanoni   drm/i915: small h...
77
  		return 0;
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
78
  	}
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
79
  }
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
80
  static u32 g4x_infoframe_enable(enum hdmi_infoframe_type type)
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
81
  {
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
82
83
  	switch (type) {
  	case HDMI_INFOFRAME_TYPE_AVI:
ed517fbbb   Paulo Zanoni   drm/i915: small h...
84
  		return VIDEO_DIP_ENABLE_AVI;
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
85
  	case HDMI_INFOFRAME_TYPE_SPD:
ed517fbbb   Paulo Zanoni   drm/i915: small h...
86
  		return VIDEO_DIP_ENABLE_SPD;
c8bb75aff   Lespiau, Damien   drm/i915/hdmi: Wr...
87
88
  	case HDMI_INFOFRAME_TYPE_VENDOR:
  		return VIDEO_DIP_ENABLE_VENDOR;
fa193ff79   Paulo Zanoni   drm/i915: break i...
89
  	default:
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
90
91
  		DRM_DEBUG_DRIVER("unknown info frame type %d
  ", type);
ed517fbbb   Paulo Zanoni   drm/i915: small h...
92
  		return 0;
fa193ff79   Paulo Zanoni   drm/i915: break i...
93
  	}
fa193ff79   Paulo Zanoni   drm/i915: break i...
94
  }
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
95
  static u32 hsw_infoframe_enable(enum hdmi_infoframe_type type)
2da8af540   Paulo Zanoni   drm/i915: impleme...
96
  {
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
97
98
  	switch (type) {
  	case HDMI_INFOFRAME_TYPE_AVI:
2da8af540   Paulo Zanoni   drm/i915: impleme...
99
  		return VIDEO_DIP_ENABLE_AVI_HSW;
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
100
  	case HDMI_INFOFRAME_TYPE_SPD:
2da8af540   Paulo Zanoni   drm/i915: impleme...
101
  		return VIDEO_DIP_ENABLE_SPD_HSW;
c8bb75aff   Lespiau, Damien   drm/i915/hdmi: Wr...
102
103
  	case HDMI_INFOFRAME_TYPE_VENDOR:
  		return VIDEO_DIP_ENABLE_VS_HSW;
2da8af540   Paulo Zanoni   drm/i915: impleme...
104
  	default:
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
105
106
  		DRM_DEBUG_DRIVER("unknown info frame type %d
  ", type);
2da8af540   Paulo Zanoni   drm/i915: impleme...
107
108
109
  		return 0;
  	}
  }
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
110
  static u32 hsw_infoframe_data_reg(enum hdmi_infoframe_type type,
7d9bcebe1   Rodrigo Vivi   drm/i915: Use cpu...
111
  				  enum transcoder cpu_transcoder)
2da8af540   Paulo Zanoni   drm/i915: impleme...
112
  {
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
113
114
  	switch (type) {
  	case HDMI_INFOFRAME_TYPE_AVI:
7d9bcebe1   Rodrigo Vivi   drm/i915: Use cpu...
115
  		return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder);
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
116
  	case HDMI_INFOFRAME_TYPE_SPD:
7d9bcebe1   Rodrigo Vivi   drm/i915: Use cpu...
117
  		return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder);
c8bb75aff   Lespiau, Damien   drm/i915/hdmi: Wr...
118
119
  	case HDMI_INFOFRAME_TYPE_VENDOR:
  		return HSW_TVIDEO_DIP_VS_DATA(cpu_transcoder);
2da8af540   Paulo Zanoni   drm/i915: impleme...
120
  	default:
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
121
122
  		DRM_DEBUG_DRIVER("unknown info frame type %d
  ", type);
2da8af540   Paulo Zanoni   drm/i915: impleme...
123
124
125
  		return 0;
  	}
  }
a3da1df7b   Daniel Vetter   drm/i915: s/i9xx_...
126
  static void g4x_write_infoframe(struct drm_encoder *encoder,
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
127
128
  				enum hdmi_infoframe_type type,
  				const uint8_t *frame, ssize_t len)
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
129
130
  {
  	uint32_t *data = (uint32_t *)frame;
3c17fe4b8   David Härdeman   i915: enable AVI ...
131
132
  	struct drm_device *dev = encoder->dev;
  	struct drm_i915_private *dev_priv = dev->dev_private;
22509ec86   Paulo Zanoni   drm/i915: change ...
133
  	u32 val = I915_READ(VIDEO_DIP_CTL);
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
134
  	int i;
3c17fe4b8   David Härdeman   i915: enable AVI ...
135

822974aea   Paulo Zanoni   drm/i915: enable ...
136
137
  	WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled
  ");
1d4f85ac2   Paulo Zanoni   drm/i915: start w...
138
  	val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
139
  	val |= g4x_infoframe_index(type);
22509ec86   Paulo Zanoni   drm/i915: change ...
140

178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
141
  	val &= ~g4x_infoframe_enable(type);
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
142

22509ec86   Paulo Zanoni   drm/i915: change ...
143
  	I915_WRITE(VIDEO_DIP_CTL, val);
3c17fe4b8   David Härdeman   i915: enable AVI ...
144

9d9740f09   Paulo Zanoni   drm/i915: add som...
145
  	mmiowb();
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
146
  	for (i = 0; i < len; i += 4) {
3c17fe4b8   David Härdeman   i915: enable AVI ...
147
148
149
  		I915_WRITE(VIDEO_DIP_DATA, *data);
  		data++;
  	}
adf00b26d   Paulo Zanoni   drm/i915: make su...
150
151
152
  	/* Write every possible data byte to force correct ECC calculation. */
  	for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
  		I915_WRITE(VIDEO_DIP_DATA, 0);
9d9740f09   Paulo Zanoni   drm/i915: add som...
153
  	mmiowb();
3c17fe4b8   David Härdeman   i915: enable AVI ...
154

178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
155
  	val |= g4x_infoframe_enable(type);
60c5ea2dd   Paulo Zanoni   drm/i915: mask th...
156
  	val &= ~VIDEO_DIP_FREQ_MASK;
4b24c9331   Daniel Vetter   drm/i915: replace...
157
  	val |= VIDEO_DIP_FREQ_VSYNC;
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
158

22509ec86   Paulo Zanoni   drm/i915: change ...
159
  	I915_WRITE(VIDEO_DIP_CTL, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
160
  	POSTING_READ(VIDEO_DIP_CTL);
3c17fe4b8   David Härdeman   i915: enable AVI ...
161
  }
fdf1250aa   Paulo Zanoni   drm/i915: split i...
162
  static void ibx_write_infoframe(struct drm_encoder *encoder,
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
163
164
  				enum hdmi_infoframe_type type,
  				const uint8_t *frame, ssize_t len)
fdf1250aa   Paulo Zanoni   drm/i915: split i...
165
166
167
168
  {
  	uint32_t *data = (uint32_t *)frame;
  	struct drm_device *dev = encoder->dev;
  	struct drm_i915_private *dev_priv = dev->dev_private;
ed517fbbb   Paulo Zanoni   drm/i915: small h...
169
  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
170
  	int i, reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
fdf1250aa   Paulo Zanoni   drm/i915: split i...
171
  	u32 val = I915_READ(reg);
822974aea   Paulo Zanoni   drm/i915: enable ...
172
173
  	WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled
  ");
fdf1250aa   Paulo Zanoni   drm/i915: split i...
174
  	val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
175
  	val |= g4x_infoframe_index(type);
fdf1250aa   Paulo Zanoni   drm/i915: split i...
176

178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
177
  	val &= ~g4x_infoframe_enable(type);
fdf1250aa   Paulo Zanoni   drm/i915: split i...
178
179
  
  	I915_WRITE(reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
180
  	mmiowb();
fdf1250aa   Paulo Zanoni   drm/i915: split i...
181
182
183
184
  	for (i = 0; i < len; i += 4) {
  		I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
  		data++;
  	}
adf00b26d   Paulo Zanoni   drm/i915: make su...
185
186
187
  	/* Write every possible data byte to force correct ECC calculation. */
  	for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
  		I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
9d9740f09   Paulo Zanoni   drm/i915: add som...
188
  	mmiowb();
fdf1250aa   Paulo Zanoni   drm/i915: split i...
189

178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
190
  	val |= g4x_infoframe_enable(type);
fdf1250aa   Paulo Zanoni   drm/i915: split i...
191
  	val &= ~VIDEO_DIP_FREQ_MASK;
4b24c9331   Daniel Vetter   drm/i915: replace...
192
  	val |= VIDEO_DIP_FREQ_VSYNC;
fdf1250aa   Paulo Zanoni   drm/i915: split i...
193
194
  
  	I915_WRITE(reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
195
  	POSTING_READ(reg);
fdf1250aa   Paulo Zanoni   drm/i915: split i...
196
197
198
  }
  
  static void cpt_write_infoframe(struct drm_encoder *encoder,
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
199
200
  				enum hdmi_infoframe_type type,
  				const uint8_t *frame, ssize_t len)
b055c8f3e   Jesse Barnes   drm/i915/hdmi: se...
201
  {
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
202
  	uint32_t *data = (uint32_t *)frame;
b055c8f3e   Jesse Barnes   drm/i915/hdmi: se...
203
204
  	struct drm_device *dev = encoder->dev;
  	struct drm_i915_private *dev_priv = dev->dev_private;
ed517fbbb   Paulo Zanoni   drm/i915: small h...
205
  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
206
  	int i, reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
22509ec86   Paulo Zanoni   drm/i915: change ...
207
  	u32 val = I915_READ(reg);
b055c8f3e   Jesse Barnes   drm/i915/hdmi: se...
208

822974aea   Paulo Zanoni   drm/i915: enable ...
209
210
  	WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled
  ");
64a8fc014   Jesse Barnes   drm/i915: fix ILK...
211
  	val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
212
  	val |= g4x_infoframe_index(type);
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
213

ecb978515   Paulo Zanoni   drm/i915: disable...
214
215
  	/* The DIP control register spec says that we need to update the AVI
  	 * infoframe without clearing its enable bit */
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
216
217
  	if (type != HDMI_INFOFRAME_TYPE_AVI)
  		val &= ~g4x_infoframe_enable(type);
ecb978515   Paulo Zanoni   drm/i915: disable...
218

22509ec86   Paulo Zanoni   drm/i915: change ...
219
  	I915_WRITE(reg, val);
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
220

9d9740f09   Paulo Zanoni   drm/i915: add som...
221
  	mmiowb();
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
222
  	for (i = 0; i < len; i += 4) {
b055c8f3e   Jesse Barnes   drm/i915/hdmi: se...
223
224
225
  		I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
  		data++;
  	}
adf00b26d   Paulo Zanoni   drm/i915: make su...
226
227
228
  	/* Write every possible data byte to force correct ECC calculation. */
  	for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
  		I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
9d9740f09   Paulo Zanoni   drm/i915: add som...
229
  	mmiowb();
b055c8f3e   Jesse Barnes   drm/i915/hdmi: se...
230

178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
231
  	val |= g4x_infoframe_enable(type);
60c5ea2dd   Paulo Zanoni   drm/i915: mask th...
232
  	val &= ~VIDEO_DIP_FREQ_MASK;
4b24c9331   Daniel Vetter   drm/i915: replace...
233
  	val |= VIDEO_DIP_FREQ_VSYNC;
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
234

22509ec86   Paulo Zanoni   drm/i915: change ...
235
  	I915_WRITE(reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
236
  	POSTING_READ(reg);
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
237
  }
90b107c8f   Shobhit Kumar   drm/i915: Enable ...
238
239
  
  static void vlv_write_infoframe(struct drm_encoder *encoder,
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
240
241
  				enum hdmi_infoframe_type type,
  				const uint8_t *frame, ssize_t len)
90b107c8f   Shobhit Kumar   drm/i915: Enable ...
242
243
244
245
  {
  	uint32_t *data = (uint32_t *)frame;
  	struct drm_device *dev = encoder->dev;
  	struct drm_i915_private *dev_priv = dev->dev_private;
ed517fbbb   Paulo Zanoni   drm/i915: small h...
246
  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
247
  	int i, reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
22509ec86   Paulo Zanoni   drm/i915: change ...
248
  	u32 val = I915_READ(reg);
90b107c8f   Shobhit Kumar   drm/i915: Enable ...
249

822974aea   Paulo Zanoni   drm/i915: enable ...
250
251
  	WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled
  ");
90b107c8f   Shobhit Kumar   drm/i915: Enable ...
252
  	val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
253
  	val |= g4x_infoframe_index(type);
22509ec86   Paulo Zanoni   drm/i915: change ...
254

178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
255
  	val &= ~g4x_infoframe_enable(type);
90b107c8f   Shobhit Kumar   drm/i915: Enable ...
256

22509ec86   Paulo Zanoni   drm/i915: change ...
257
  	I915_WRITE(reg, val);
90b107c8f   Shobhit Kumar   drm/i915: Enable ...
258

9d9740f09   Paulo Zanoni   drm/i915: add som...
259
  	mmiowb();
90b107c8f   Shobhit Kumar   drm/i915: Enable ...
260
261
262
263
  	for (i = 0; i < len; i += 4) {
  		I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
  		data++;
  	}
adf00b26d   Paulo Zanoni   drm/i915: make su...
264
265
266
  	/* Write every possible data byte to force correct ECC calculation. */
  	for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
  		I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
9d9740f09   Paulo Zanoni   drm/i915: add som...
267
  	mmiowb();
90b107c8f   Shobhit Kumar   drm/i915: Enable ...
268

178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
269
  	val |= g4x_infoframe_enable(type);
60c5ea2dd   Paulo Zanoni   drm/i915: mask th...
270
  	val &= ~VIDEO_DIP_FREQ_MASK;
4b24c9331   Daniel Vetter   drm/i915: replace...
271
  	val |= VIDEO_DIP_FREQ_VSYNC;
90b107c8f   Shobhit Kumar   drm/i915: Enable ...
272

22509ec86   Paulo Zanoni   drm/i915: change ...
273
  	I915_WRITE(reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
274
  	POSTING_READ(reg);
90b107c8f   Shobhit Kumar   drm/i915: Enable ...
275
  }
8c5f5f7c4   Eugeni Dodonov   drm/i915: add new...
276
  static void hsw_write_infoframe(struct drm_encoder *encoder,
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
277
278
  				enum hdmi_infoframe_type type,
  				const uint8_t *frame, ssize_t len)
8c5f5f7c4   Eugeni Dodonov   drm/i915: add new...
279
  {
2da8af540   Paulo Zanoni   drm/i915: impleme...
280
281
282
283
  	uint32_t *data = (uint32_t *)frame;
  	struct drm_device *dev = encoder->dev;
  	struct drm_i915_private *dev_priv = dev->dev_private;
  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
3b117c8f2   Daniel Vetter   drm/i915: move cp...
284
  	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config.cpu_transcoder);
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
285
286
  	u32 data_reg;
  	int i;
2da8af540   Paulo Zanoni   drm/i915: impleme...
287
  	u32 val = I915_READ(ctl_reg);
8c5f5f7c4   Eugeni Dodonov   drm/i915: add new...
288

178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
289
290
  	data_reg = hsw_infoframe_data_reg(type,
  					  intel_crtc->config.cpu_transcoder);
2da8af540   Paulo Zanoni   drm/i915: impleme...
291
292
  	if (data_reg == 0)
  		return;
178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
293
  	val &= ~hsw_infoframe_enable(type);
2da8af540   Paulo Zanoni   drm/i915: impleme...
294
  	I915_WRITE(ctl_reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
295
  	mmiowb();
2da8af540   Paulo Zanoni   drm/i915: impleme...
296
297
298
299
  	for (i = 0; i < len; i += 4) {
  		I915_WRITE(data_reg + i, *data);
  		data++;
  	}
adf00b26d   Paulo Zanoni   drm/i915: make su...
300
301
302
  	/* Write every possible data byte to force correct ECC calculation. */
  	for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
  		I915_WRITE(data_reg + i, 0);
9d9740f09   Paulo Zanoni   drm/i915: add som...
303
  	mmiowb();
8c5f5f7c4   Eugeni Dodonov   drm/i915: add new...
304

178f736ab   Damien Lespiau   drm/i915/hdmi: Ch...
305
  	val |= hsw_infoframe_enable(type);
2da8af540   Paulo Zanoni   drm/i915: impleme...
306
  	I915_WRITE(ctl_reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
307
  	POSTING_READ(ctl_reg);
8c5f5f7c4   Eugeni Dodonov   drm/i915: add new...
308
  }
5adaea799   Damien Lespiau   drm/i915/hdmi: Po...
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
  /*
   * The data we write to the DIP data buffer registers is 1 byte bigger than the
   * HDMI infoframe size because of an ECC/reserved byte at position 3 (starting
   * at 0). It's also a byte used by DisplayPort so the same DIP registers can be
   * used for both technologies.
   *
   * DW0: Reserved/ECC/DP | HB2 | HB1 | HB0
   * DW1:       DB3       | DB2 | DB1 | DB0
   * DW2:       DB7       | DB6 | DB5 | DB4
   * DW3: ...
   *
   * (HB is Header Byte, DB is Data Byte)
   *
   * The hdmi pack() functions don't know about that hardware specific hole so we
   * trick them by giving an offset into the buffer and moving back the header
   * bytes by one.
   */
9198ee5b9   Damien Lespiau   drm/i915/hmdi: Re...
326
327
  static void intel_write_infoframe(struct drm_encoder *encoder,
  				  union hdmi_infoframe *frame)
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
328
329
  {
  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
5adaea799   Damien Lespiau   drm/i915/hdmi: Po...
330
331
  	uint8_t buffer[VIDEO_DIP_DATA_SIZE];
  	ssize_t len;
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
332

5adaea799   Damien Lespiau   drm/i915/hdmi: Po...
333
334
335
336
337
338
339
340
341
342
343
  	/* see comment above for the reason for this offset */
  	len = hdmi_infoframe_pack(frame, buffer + 1, sizeof(buffer) - 1);
  	if (len < 0)
  		return;
  
  	/* Insert the 'hole' (see big comment above) at position 3 */
  	buffer[0] = buffer[1];
  	buffer[1] = buffer[2];
  	buffer[2] = buffer[3];
  	buffer[3] = 0;
  	len++;
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
344

5adaea799   Damien Lespiau   drm/i915/hdmi: Po...
345
  	intel_hdmi->write_infoframe(encoder, frame->any.type, buffer, len);
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
346
  }
687f4d06d   Paulo Zanoni   drm/i915: add set...
347
  static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
c846b6194   Paulo Zanoni   drm/i915: make DB...
348
  					 struct drm_display_mode *adjusted_mode)
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
349
  {
abedc077b   Ville Syrjälä   drm/i915: Provide...
350
  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
50f3b016b   Daniel Vetter   drm/i915: add pip...
351
  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
5adaea799   Damien Lespiau   drm/i915/hdmi: Po...
352
353
  	union hdmi_infoframe frame;
  	int ret;
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
354

5adaea799   Damien Lespiau   drm/i915/hdmi: Po...
355
356
357
358
359
360
361
  	ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
  						       adjusted_mode);
  	if (ret < 0) {
  		DRM_ERROR("couldn't fill AVI infoframe
  ");
  		return;
  	}
c846b6194   Paulo Zanoni   drm/i915: make DB...
362

abedc077b   Ville Syrjälä   drm/i915: Provide...
363
  	if (intel_hdmi->rgb_quant_range_selectable) {
50f3b016b   Daniel Vetter   drm/i915: add pip...
364
  		if (intel_crtc->config.limited_color_range)
5adaea799   Damien Lespiau   drm/i915/hdmi: Po...
365
366
  			frame.avi.quantization_range =
  				HDMI_QUANTIZATION_RANGE_LIMITED;
abedc077b   Ville Syrjälä   drm/i915: Provide...
367
  		else
5adaea799   Damien Lespiau   drm/i915/hdmi: Po...
368
369
  			frame.avi.quantization_range =
  				HDMI_QUANTIZATION_RANGE_FULL;
abedc077b   Ville Syrjälä   drm/i915: Provide...
370
  	}
9198ee5b9   Damien Lespiau   drm/i915/hmdi: Re...
371
  	intel_write_infoframe(encoder, &frame);
b055c8f3e   Jesse Barnes   drm/i915/hdmi: se...
372
  }
687f4d06d   Paulo Zanoni   drm/i915: add set...
373
  static void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder)
c0864cb39   Jesse Barnes   drm/i915/hdmi: HD...
374
  {
5adaea799   Damien Lespiau   drm/i915/hdmi: Po...
375
376
377
378
379
380
381
382
383
  	union hdmi_infoframe frame;
  	int ret;
  
  	ret = hdmi_spd_infoframe_init(&frame.spd, "Intel", "Integrated gfx");
  	if (ret < 0) {
  		DRM_ERROR("couldn't fill SPD infoframe
  ");
  		return;
  	}
c0864cb39   Jesse Barnes   drm/i915/hdmi: HD...
384

5adaea799   Damien Lespiau   drm/i915/hdmi: Po...
385
  	frame.spd.sdi = HDMI_SPD_SDI_PC;
c0864cb39   Jesse Barnes   drm/i915/hdmi: HD...
386

9198ee5b9   Damien Lespiau   drm/i915/hmdi: Re...
387
  	intel_write_infoframe(encoder, &frame);
c0864cb39   Jesse Barnes   drm/i915/hdmi: HD...
388
  }
c8bb75aff   Lespiau, Damien   drm/i915/hdmi: Wr...
389
390
391
392
393
394
395
396
397
398
399
400
401
402
  static void
  intel_hdmi_set_hdmi_infoframe(struct drm_encoder *encoder,
  			      struct drm_display_mode *adjusted_mode)
  {
  	union hdmi_infoframe frame;
  	int ret;
  
  	ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi,
  							  adjusted_mode);
  	if (ret < 0)
  		return;
  
  	intel_write_infoframe(encoder, &frame);
  }
687f4d06d   Paulo Zanoni   drm/i915: add set...
403
404
405
  static void g4x_set_infoframes(struct drm_encoder *encoder,
  			       struct drm_display_mode *adjusted_mode)
  {
0c14c7f95   Paulo Zanoni   drm/i915: properl...
406
  	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
69fde0a61   Ville Syrjälä   drm/i915: Convert...
407
408
  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
  	struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
0c14c7f95   Paulo Zanoni   drm/i915: properl...
409
410
  	u32 reg = VIDEO_DIP_CTL;
  	u32 val = I915_READ(reg);
72b78c9d1   Paulo Zanoni   drm/i915: disable...
411
  	u32 port;
0c14c7f95   Paulo Zanoni   drm/i915: properl...
412

afba01889   Daniel Vetter   drm/i915: ensure ...
413
  	assert_hdmi_port_disabled(intel_hdmi);
0c14c7f95   Paulo Zanoni   drm/i915: properl...
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
  	/* If the registers were not initialized yet, they might be zeroes,
  	 * which means we're selecting the AVI DIP and we're setting its
  	 * frequency to once. This seems to really confuse the HW and make
  	 * things stop working (the register spec says the AVI always needs to
  	 * be sent every VSync). So here we avoid writing to the register more
  	 * than we need and also explicitly select the AVI DIP and explicitly
  	 * set its frequency to every VSync. Avoiding to write it twice seems to
  	 * be enough to solve the problem, but being defensive shouldn't hurt us
  	 * either. */
  	val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;
  
  	if (!intel_hdmi->has_hdmi_sink) {
  		if (!(val & VIDEO_DIP_ENABLE))
  			return;
  		val &= ~VIDEO_DIP_ENABLE;
  		I915_WRITE(reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
430
  		POSTING_READ(reg);
0c14c7f95   Paulo Zanoni   drm/i915: properl...
431
432
  		return;
  	}
69fde0a61   Ville Syrjälä   drm/i915: Convert...
433
434
  	switch (intel_dig_port->port) {
  	case PORT_B:
72b78c9d1   Paulo Zanoni   drm/i915: disable...
435
  		port = VIDEO_DIP_PORT_B;
f278d9721   Paulo Zanoni   drm/i915: only se...
436
  		break;
69fde0a61   Ville Syrjälä   drm/i915: Convert...
437
  	case PORT_C:
72b78c9d1   Paulo Zanoni   drm/i915: disable...
438
  		port = VIDEO_DIP_PORT_C;
f278d9721   Paulo Zanoni   drm/i915: only se...
439
440
  		break;
  	default:
57df2ae9d   Paulo Zanoni   drm/i915: BUG() o...
441
  		BUG();
f278d9721   Paulo Zanoni   drm/i915: only se...
442
443
  		return;
  	}
72b78c9d1   Paulo Zanoni   drm/i915: disable...
444
445
446
447
  	if (port != (val & VIDEO_DIP_PORT_MASK)) {
  		if (val & VIDEO_DIP_ENABLE) {
  			val &= ~VIDEO_DIP_ENABLE;
  			I915_WRITE(reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
448
  			POSTING_READ(reg);
72b78c9d1   Paulo Zanoni   drm/i915: disable...
449
450
451
452
  		}
  		val &= ~VIDEO_DIP_PORT_MASK;
  		val |= port;
  	}
822974aea   Paulo Zanoni   drm/i915: enable ...
453
  	val |= VIDEO_DIP_ENABLE;
0dd87d208   Paulo Zanoni   drm/i915: explici...
454
  	val &= ~VIDEO_DIP_ENABLE_VENDOR;
822974aea   Paulo Zanoni   drm/i915: enable ...
455

f278d9721   Paulo Zanoni   drm/i915: only se...
456
  	I915_WRITE(reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
457
  	POSTING_READ(reg);
f278d9721   Paulo Zanoni   drm/i915: only se...
458

687f4d06d   Paulo Zanoni   drm/i915: add set...
459
460
  	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
  	intel_hdmi_set_spd_infoframe(encoder);
c8bb75aff   Lespiau, Damien   drm/i915/hdmi: Wr...
461
  	intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
687f4d06d   Paulo Zanoni   drm/i915: add set...
462
463
464
465
466
  }
  
  static void ibx_set_infoframes(struct drm_encoder *encoder,
  			       struct drm_display_mode *adjusted_mode)
  {
0c14c7f95   Paulo Zanoni   drm/i915: properl...
467
468
  	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
69fde0a61   Ville Syrjälä   drm/i915: Convert...
469
470
  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
  	struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
0c14c7f95   Paulo Zanoni   drm/i915: properl...
471
472
  	u32 reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
  	u32 val = I915_READ(reg);
72b78c9d1   Paulo Zanoni   drm/i915: disable...
473
  	u32 port;
0c14c7f95   Paulo Zanoni   drm/i915: properl...
474

afba01889   Daniel Vetter   drm/i915: ensure ...
475
  	assert_hdmi_port_disabled(intel_hdmi);
0c14c7f95   Paulo Zanoni   drm/i915: properl...
476
477
478
479
480
481
482
483
  	/* See the big comment in g4x_set_infoframes() */
  	val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;
  
  	if (!intel_hdmi->has_hdmi_sink) {
  		if (!(val & VIDEO_DIP_ENABLE))
  			return;
  		val &= ~VIDEO_DIP_ENABLE;
  		I915_WRITE(reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
484
  		POSTING_READ(reg);
0c14c7f95   Paulo Zanoni   drm/i915: properl...
485
486
  		return;
  	}
69fde0a61   Ville Syrjälä   drm/i915: Convert...
487
488
  	switch (intel_dig_port->port) {
  	case PORT_B:
72b78c9d1   Paulo Zanoni   drm/i915: disable...
489
  		port = VIDEO_DIP_PORT_B;
f278d9721   Paulo Zanoni   drm/i915: only se...
490
  		break;
69fde0a61   Ville Syrjälä   drm/i915: Convert...
491
  	case PORT_C:
72b78c9d1   Paulo Zanoni   drm/i915: disable...
492
  		port = VIDEO_DIP_PORT_C;
f278d9721   Paulo Zanoni   drm/i915: only se...
493
  		break;
69fde0a61   Ville Syrjälä   drm/i915: Convert...
494
  	case PORT_D:
72b78c9d1   Paulo Zanoni   drm/i915: disable...
495
  		port = VIDEO_DIP_PORT_D;
f278d9721   Paulo Zanoni   drm/i915: only se...
496
497
  		break;
  	default:
57df2ae9d   Paulo Zanoni   drm/i915: BUG() o...
498
  		BUG();
f278d9721   Paulo Zanoni   drm/i915: only se...
499
500
  		return;
  	}
72b78c9d1   Paulo Zanoni   drm/i915: disable...
501
502
503
504
  	if (port != (val & VIDEO_DIP_PORT_MASK)) {
  		if (val & VIDEO_DIP_ENABLE) {
  			val &= ~VIDEO_DIP_ENABLE;
  			I915_WRITE(reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
505
  			POSTING_READ(reg);
72b78c9d1   Paulo Zanoni   drm/i915: disable...
506
507
508
509
  		}
  		val &= ~VIDEO_DIP_PORT_MASK;
  		val |= port;
  	}
822974aea   Paulo Zanoni   drm/i915: enable ...
510
  	val |= VIDEO_DIP_ENABLE;
0dd87d208   Paulo Zanoni   drm/i915: explici...
511
512
  	val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
  		 VIDEO_DIP_ENABLE_GCP);
822974aea   Paulo Zanoni   drm/i915: enable ...
513

f278d9721   Paulo Zanoni   drm/i915: only se...
514
  	I915_WRITE(reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
515
  	POSTING_READ(reg);
f278d9721   Paulo Zanoni   drm/i915: only se...
516

687f4d06d   Paulo Zanoni   drm/i915: add set...
517
518
  	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
  	intel_hdmi_set_spd_infoframe(encoder);
c8bb75aff   Lespiau, Damien   drm/i915/hdmi: Wr...
519
  	intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
687f4d06d   Paulo Zanoni   drm/i915: add set...
520
521
522
523
524
  }
  
  static void cpt_set_infoframes(struct drm_encoder *encoder,
  			       struct drm_display_mode *adjusted_mode)
  {
0c14c7f95   Paulo Zanoni   drm/i915: properl...
525
526
527
528
529
  	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
  	u32 reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
  	u32 val = I915_READ(reg);
afba01889   Daniel Vetter   drm/i915: ensure ...
530
  	assert_hdmi_port_disabled(intel_hdmi);
0c14c7f95   Paulo Zanoni   drm/i915: properl...
531
532
533
534
535
536
537
538
  	/* See the big comment in g4x_set_infoframes() */
  	val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;
  
  	if (!intel_hdmi->has_hdmi_sink) {
  		if (!(val & VIDEO_DIP_ENABLE))
  			return;
  		val &= ~(VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI);
  		I915_WRITE(reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
539
  		POSTING_READ(reg);
0c14c7f95   Paulo Zanoni   drm/i915: properl...
540
541
  		return;
  	}
822974aea   Paulo Zanoni   drm/i915: enable ...
542
543
  	/* Set both together, unset both together: see the spec. */
  	val |= VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI;
0dd87d208   Paulo Zanoni   drm/i915: explici...
544
545
  	val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
  		 VIDEO_DIP_ENABLE_GCP);
822974aea   Paulo Zanoni   drm/i915: enable ...
546
547
  
  	I915_WRITE(reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
548
  	POSTING_READ(reg);
822974aea   Paulo Zanoni   drm/i915: enable ...
549

687f4d06d   Paulo Zanoni   drm/i915: add set...
550
551
  	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
  	intel_hdmi_set_spd_infoframe(encoder);
c8bb75aff   Lespiau, Damien   drm/i915/hdmi: Wr...
552
  	intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
687f4d06d   Paulo Zanoni   drm/i915: add set...
553
554
555
556
557
  }
  
  static void vlv_set_infoframes(struct drm_encoder *encoder,
  			       struct drm_display_mode *adjusted_mode)
  {
0c14c7f95   Paulo Zanoni   drm/i915: properl...
558
559
560
561
562
  	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
  	u32 reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
  	u32 val = I915_READ(reg);
afba01889   Daniel Vetter   drm/i915: ensure ...
563
  	assert_hdmi_port_disabled(intel_hdmi);
0c14c7f95   Paulo Zanoni   drm/i915: properl...
564
565
566
567
568
569
570
571
  	/* See the big comment in g4x_set_infoframes() */
  	val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;
  
  	if (!intel_hdmi->has_hdmi_sink) {
  		if (!(val & VIDEO_DIP_ENABLE))
  			return;
  		val &= ~VIDEO_DIP_ENABLE;
  		I915_WRITE(reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
572
  		POSTING_READ(reg);
0c14c7f95   Paulo Zanoni   drm/i915: properl...
573
574
  		return;
  	}
822974aea   Paulo Zanoni   drm/i915: enable ...
575
  	val |= VIDEO_DIP_ENABLE;
0dd87d208   Paulo Zanoni   drm/i915: explici...
576
577
  	val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
  		 VIDEO_DIP_ENABLE_GCP);
822974aea   Paulo Zanoni   drm/i915: enable ...
578
579
  
  	I915_WRITE(reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
580
  	POSTING_READ(reg);
822974aea   Paulo Zanoni   drm/i915: enable ...
581

687f4d06d   Paulo Zanoni   drm/i915: add set...
582
583
  	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
  	intel_hdmi_set_spd_infoframe(encoder);
c8bb75aff   Lespiau, Damien   drm/i915/hdmi: Wr...
584
  	intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
687f4d06d   Paulo Zanoni   drm/i915: add set...
585
586
587
588
589
  }
  
  static void hsw_set_infoframes(struct drm_encoder *encoder,
  			       struct drm_display_mode *adjusted_mode)
  {
0c14c7f95   Paulo Zanoni   drm/i915: properl...
590
591
592
  	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
3b117c8f2   Daniel Vetter   drm/i915: move cp...
593
  	u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config.cpu_transcoder);
0dd87d208   Paulo Zanoni   drm/i915: explici...
594
  	u32 val = I915_READ(reg);
0c14c7f95   Paulo Zanoni   drm/i915: properl...
595

afba01889   Daniel Vetter   drm/i915: ensure ...
596
  	assert_hdmi_port_disabled(intel_hdmi);
0c14c7f95   Paulo Zanoni   drm/i915: properl...
597
598
  	if (!intel_hdmi->has_hdmi_sink) {
  		I915_WRITE(reg, 0);
9d9740f09   Paulo Zanoni   drm/i915: add som...
599
  		POSTING_READ(reg);
0c14c7f95   Paulo Zanoni   drm/i915: properl...
600
601
  		return;
  	}
0dd87d208   Paulo Zanoni   drm/i915: explici...
602
603
604
605
  	val &= ~(VIDEO_DIP_ENABLE_VSC_HSW | VIDEO_DIP_ENABLE_GCP_HSW |
  		 VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW);
  
  	I915_WRITE(reg, val);
9d9740f09   Paulo Zanoni   drm/i915: add som...
606
  	POSTING_READ(reg);
0dd87d208   Paulo Zanoni   drm/i915: explici...
607

687f4d06d   Paulo Zanoni   drm/i915: add set...
608
609
  	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
  	intel_hdmi_set_spd_infoframe(encoder);
c8bb75aff   Lespiau, Damien   drm/i915/hdmi: Wr...
610
  	intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
687f4d06d   Paulo Zanoni   drm/i915: add set...
611
  }
c59423a3d   Daniel Vetter   drm/i915/hdmi: us...
612
  static void intel_hdmi_mode_set(struct intel_encoder *encoder)
7d57382e6   Eric Anholt   drm/i915: Add sup...
613
  {
c59423a3d   Daniel Vetter   drm/i915/hdmi: us...
614
  	struct drm_device *dev = encoder->base.dev;
7d57382e6   Eric Anholt   drm/i915: Add sup...
615
  	struct drm_i915_private *dev_priv = dev->dev_private;
c59423a3d   Daniel Vetter   drm/i915/hdmi: us...
616
617
618
  	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
  	struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode;
b242b7f74   Paulo Zanoni   drm/i915: rename ...
619
  	u32 hdmi_val;
7d57382e6   Eric Anholt   drm/i915: Add sup...
620

b242b7f74   Paulo Zanoni   drm/i915: rename ...
621
  	hdmi_val = SDVO_ENCODING_HDMI;
2af2c4909   Ville Syrjälä   Revert "drm/i915:...
622
  	if (!HAS_PCH_SPLIT(dev))
b242b7f74   Paulo Zanoni   drm/i915: rename ...
623
  		hdmi_val |= intel_hdmi->color_range;
b599c0bca   Adam Jackson   drm/i915/hdmi: Se...
624
  	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
b242b7f74   Paulo Zanoni   drm/i915: rename ...
625
  		hdmi_val |= SDVO_VSYNC_ACTIVE_HIGH;
b599c0bca   Adam Jackson   drm/i915/hdmi: Se...
626
  	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
b242b7f74   Paulo Zanoni   drm/i915: rename ...
627
  		hdmi_val |= SDVO_HSYNC_ACTIVE_HIGH;
7d57382e6   Eric Anholt   drm/i915: Add sup...
628

c59423a3d   Daniel Vetter   drm/i915/hdmi: us...
629
  	if (crtc->config.pipe_bpp > 24)
4f3a8bc7b   Paulo Zanoni   drm/i915: rename ...
630
  		hdmi_val |= HDMI_COLOR_FORMAT_12bpc;
020f6704b   Jesse Barnes   drm/i915: use pip...
631
  	else
4f3a8bc7b   Paulo Zanoni   drm/i915: rename ...
632
  		hdmi_val |= SDVO_COLOR_FORMAT_8bpc;
020f6704b   Jesse Barnes   drm/i915: use pip...
633

2e3d6006a   Zhenyu Wang   drm/i915: Enable ...
634
635
  	/* Required on CPT */
  	if (intel_hdmi->has_hdmi_sink && HAS_PCH_CPT(dev))
dc0fa7181   Paulo Zanoni   drm/i915: remove ...
636
  		hdmi_val |= HDMI_MODE_SELECT_HDMI;
2e3d6006a   Zhenyu Wang   drm/i915: Enable ...
637

3c17fe4b8   David Härdeman   i915: enable AVI ...
638
  	if (intel_hdmi->has_audio) {
e0dac65ed   Wu Fengguang   drm/i915: pass EL...
639
640
  		DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c
  ",
c59423a3d   Daniel Vetter   drm/i915/hdmi: us...
641
  				 pipe_name(crtc->pipe));
b242b7f74   Paulo Zanoni   drm/i915: rename ...
642
  		hdmi_val |= SDVO_AUDIO_ENABLE;
dc0fa7181   Paulo Zanoni   drm/i915: remove ...
643
  		hdmi_val |= HDMI_MODE_SELECT_HDMI;
c59423a3d   Daniel Vetter   drm/i915/hdmi: us...
644
  		intel_write_eld(&encoder->base, adjusted_mode);
3c17fe4b8   David Härdeman   i915: enable AVI ...
645
  	}
7d57382e6   Eric Anholt   drm/i915: Add sup...
646

75770564c   Jesse Barnes   drm/i915: use tra...
647
  	if (HAS_PCH_CPT(dev))
c59423a3d   Daniel Vetter   drm/i915/hdmi: us...
648
  		hdmi_val |= SDVO_PIPE_SEL_CPT(crtc->pipe);
dc0fa7181   Paulo Zanoni   drm/i915: remove ...
649
  	else
c59423a3d   Daniel Vetter   drm/i915/hdmi: us...
650
  		hdmi_val |= SDVO_PIPE_SEL(crtc->pipe);
7d57382e6   Eric Anholt   drm/i915: Add sup...
651

b242b7f74   Paulo Zanoni   drm/i915: rename ...
652
653
  	I915_WRITE(intel_hdmi->hdmi_reg, hdmi_val);
  	POSTING_READ(intel_hdmi->hdmi_reg);
3c17fe4b8   David Härdeman   i915: enable AVI ...
654

c59423a3d   Daniel Vetter   drm/i915/hdmi: us...
655
  	intel_hdmi->set_infoframes(&encoder->base, adjusted_mode);
7d57382e6   Eric Anholt   drm/i915: Add sup...
656
  }
85234cdc2   Daniel Vetter   drm/i915/hdmi: im...
657
658
  static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
  				    enum pipe *pipe)
7d57382e6   Eric Anholt   drm/i915: Add sup...
659
  {
85234cdc2   Daniel Vetter   drm/i915/hdmi: im...
660
  	struct drm_device *dev = encoder->base.dev;
7d57382e6   Eric Anholt   drm/i915: Add sup...
661
  	struct drm_i915_private *dev_priv = dev->dev_private;
85234cdc2   Daniel Vetter   drm/i915/hdmi: im...
662
663
  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
  	u32 tmp;
b242b7f74   Paulo Zanoni   drm/i915: rename ...
664
  	tmp = I915_READ(intel_hdmi->hdmi_reg);
85234cdc2   Daniel Vetter   drm/i915/hdmi: im...
665
666
667
668
669
670
671
672
673
674
675
  
  	if (!(tmp & SDVO_ENABLE))
  		return false;
  
  	if (HAS_PCH_CPT(dev))
  		*pipe = PORT_TO_PIPE_CPT(tmp);
  	else
  		*pipe = PORT_TO_PIPE(tmp);
  
  	return true;
  }
045ac3b56   Jesse Barnes   drm/i915: add enc...
676
677
678
679
680
681
  static void intel_hdmi_get_config(struct intel_encoder *encoder,
  				  struct intel_crtc_config *pipe_config)
  {
  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
  	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
  	u32 tmp, flags = 0;
18442d087   Ville Syrjälä   drm/i915: Fix por...
682
  	int dotclock;
045ac3b56   Jesse Barnes   drm/i915: add enc...
683
684
685
686
687
688
689
690
691
692
693
694
695
696
  
  	tmp = I915_READ(intel_hdmi->hdmi_reg);
  
  	if (tmp & SDVO_HSYNC_ACTIVE_HIGH)
  		flags |= DRM_MODE_FLAG_PHSYNC;
  	else
  		flags |= DRM_MODE_FLAG_NHSYNC;
  
  	if (tmp & SDVO_VSYNC_ACTIVE_HIGH)
  		flags |= DRM_MODE_FLAG_PVSYNC;
  	else
  		flags |= DRM_MODE_FLAG_NVSYNC;
  
  	pipe_config->adjusted_mode.flags |= flags;
18442d087   Ville Syrjälä   drm/i915: Fix por...
697
698
699
700
701
702
703
704
  
  	if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc)
  		dotclock = pipe_config->port_clock * 2 / 3;
  	else
  		dotclock = pipe_config->port_clock;
  
  	if (HAS_PCH_SPLIT(dev_priv->dev))
  		ironlake_check_encoder_dotclock(pipe_config, dotclock);
241bfc389   Damien Lespiau   drm/i915: Use crt...
705
  	pipe_config->adjusted_mode.crtc_clock = dotclock;
045ac3b56   Jesse Barnes   drm/i915: add enc...
706
  }
5ab432ef4   Daniel Vetter   drm/i915/hdmi: co...
707
  static void intel_enable_hdmi(struct intel_encoder *encoder)
7d57382e6   Eric Anholt   drm/i915: Add sup...
708
  {
5ab432ef4   Daniel Vetter   drm/i915/hdmi: co...
709
  	struct drm_device *dev = encoder->base.dev;
7d57382e6   Eric Anholt   drm/i915: Add sup...
710
  	struct drm_i915_private *dev_priv = dev->dev_private;
dc0fa7181   Paulo Zanoni   drm/i915: remove ...
711
  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
5ab432ef4   Daniel Vetter   drm/i915/hdmi: co...
712
  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
7d57382e6   Eric Anholt   drm/i915: Add sup...
713
  	u32 temp;
2deed7611   Wu Fengguang   drm/i915: HDMI ho...
714
715
716
717
  	u32 enable_bits = SDVO_ENABLE;
  
  	if (intel_hdmi->has_audio)
  		enable_bits |= SDVO_AUDIO_ENABLE;
7d57382e6   Eric Anholt   drm/i915: Add sup...
718

b242b7f74   Paulo Zanoni   drm/i915: rename ...
719
  	temp = I915_READ(intel_hdmi->hdmi_reg);
d8a2d0e00   Zhenyu Wang   drm/i915: HDMI ha...
720

7a87c2897   Daniel Vetter   drm/i915: impleme...
721
  	/* HW workaround for IBX, we need to move the port to transcoder A
dc0fa7181   Paulo Zanoni   drm/i915: remove ...
722
723
724
  	 * before disabling it, so restore the transcoder select bit here. */
  	if (HAS_PCH_IBX(dev))
  		enable_bits |= SDVO_PIPE_SEL(intel_crtc->pipe);
7a87c2897   Daniel Vetter   drm/i915: impleme...
725

d8a2d0e00   Zhenyu Wang   drm/i915: HDMI ha...
726
727
728
  	/* HW workaround, need to toggle enable bit off and on for 12bpc, but
  	 * we do this anyway which shows more stable in testing.
  	 */
c619eed4b   Eric Anholt   drm/i915: More s/...
729
  	if (HAS_PCH_SPLIT(dev)) {
b242b7f74   Paulo Zanoni   drm/i915: rename ...
730
731
  		I915_WRITE(intel_hdmi->hdmi_reg, temp & ~SDVO_ENABLE);
  		POSTING_READ(intel_hdmi->hdmi_reg);
d8a2d0e00   Zhenyu Wang   drm/i915: HDMI ha...
732
  	}
5ab432ef4   Daniel Vetter   drm/i915/hdmi: co...
733
  	temp |= enable_bits;
b242b7f74   Paulo Zanoni   drm/i915: rename ...
734
735
  	I915_WRITE(intel_hdmi->hdmi_reg, temp);
  	POSTING_READ(intel_hdmi->hdmi_reg);
5ab432ef4   Daniel Vetter   drm/i915/hdmi: co...
736
737
738
739
740
  
  	/* HW workaround, need to write this twice for issue that may result
  	 * in first write getting masked.
  	 */
  	if (HAS_PCH_SPLIT(dev)) {
b242b7f74   Paulo Zanoni   drm/i915: rename ...
741
742
  		I915_WRITE(intel_hdmi->hdmi_reg, temp);
  		POSTING_READ(intel_hdmi->hdmi_reg);
7d57382e6   Eric Anholt   drm/i915: Add sup...
743
  	}
b76cf76bf   Jani Nikula   drm/i915: rearran...
744
  }
89b667f86   Jesse Barnes   drm/i915: update ...
745

b76cf76bf   Jani Nikula   drm/i915: rearran...
746
747
  static void vlv_enable_hdmi(struct intel_encoder *encoder)
  {
5ab432ef4   Daniel Vetter   drm/i915/hdmi: co...
748
749
750
751
752
753
754
755
  }
  
  static void intel_disable_hdmi(struct intel_encoder *encoder)
  {
  	struct drm_device *dev = encoder->base.dev;
  	struct drm_i915_private *dev_priv = dev->dev_private;
  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
  	u32 temp;
3cce574f0   Wang Xingchao   drm/i915: HDMI - ...
756
  	u32 enable_bits = SDVO_ENABLE | SDVO_AUDIO_ENABLE;
5ab432ef4   Daniel Vetter   drm/i915/hdmi: co...
757

b242b7f74   Paulo Zanoni   drm/i915: rename ...
758
  	temp = I915_READ(intel_hdmi->hdmi_reg);
5ab432ef4   Daniel Vetter   drm/i915/hdmi: co...
759
760
761
762
763
764
765
766
767
  
  	/* HW workaround for IBX, we need to move the port to transcoder A
  	 * before disabling it. */
  	if (HAS_PCH_IBX(dev)) {
  		struct drm_crtc *crtc = encoder->base.crtc;
  		int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1;
  
  		if (temp & SDVO_PIPE_B_SELECT) {
  			temp &= ~SDVO_PIPE_B_SELECT;
b242b7f74   Paulo Zanoni   drm/i915: rename ...
768
769
  			I915_WRITE(intel_hdmi->hdmi_reg, temp);
  			POSTING_READ(intel_hdmi->hdmi_reg);
5ab432ef4   Daniel Vetter   drm/i915/hdmi: co...
770
771
  
  			/* Again we need to write this twice. */
b242b7f74   Paulo Zanoni   drm/i915: rename ...
772
773
  			I915_WRITE(intel_hdmi->hdmi_reg, temp);
  			POSTING_READ(intel_hdmi->hdmi_reg);
5ab432ef4   Daniel Vetter   drm/i915/hdmi: co...
774
775
776
777
778
779
780
781
  
  			/* Transcoder selection bits only update
  			 * effectively on vblank. */
  			if (crtc)
  				intel_wait_for_vblank(dev, pipe);
  			else
  				msleep(50);
  		}
7d57382e6   Eric Anholt   drm/i915: Add sup...
782
  	}
d8a2d0e00   Zhenyu Wang   drm/i915: HDMI ha...
783

5ab432ef4   Daniel Vetter   drm/i915/hdmi: co...
784
785
786
787
  	/* HW workaround, need to toggle enable bit off and on for 12bpc, but
  	 * we do this anyway which shows more stable in testing.
  	 */
  	if (HAS_PCH_SPLIT(dev)) {
b242b7f74   Paulo Zanoni   drm/i915: rename ...
788
789
  		I915_WRITE(intel_hdmi->hdmi_reg, temp & ~SDVO_ENABLE);
  		POSTING_READ(intel_hdmi->hdmi_reg);
5ab432ef4   Daniel Vetter   drm/i915/hdmi: co...
790
791
792
  	}
  
  	temp &= ~enable_bits;
d8a2d0e00   Zhenyu Wang   drm/i915: HDMI ha...
793

b242b7f74   Paulo Zanoni   drm/i915: rename ...
794
795
  	I915_WRITE(intel_hdmi->hdmi_reg, temp);
  	POSTING_READ(intel_hdmi->hdmi_reg);
d8a2d0e00   Zhenyu Wang   drm/i915: HDMI ha...
796
797
798
799
  
  	/* HW workaround, need to write this twice for issue that may result
  	 * in first write getting masked.
  	 */
c619eed4b   Eric Anholt   drm/i915: More s/...
800
  	if (HAS_PCH_SPLIT(dev)) {
b242b7f74   Paulo Zanoni   drm/i915: rename ...
801
802
  		I915_WRITE(intel_hdmi->hdmi_reg, temp);
  		POSTING_READ(intel_hdmi->hdmi_reg);
d8a2d0e00   Zhenyu Wang   drm/i915: HDMI ha...
803
  	}
7d57382e6   Eric Anholt   drm/i915: Add sup...
804
  }
7d148ef51   Daniel Vetter   drm/i915: fix hdm...
805
806
807
808
809
810
  static int hdmi_portclock_limit(struct intel_hdmi *hdmi)
  {
  	struct drm_device *dev = intel_hdmi_to_dev(hdmi);
  
  	if (IS_G4X(dev))
  		return 165000;
e3c335786   Damien Lespiau   drm/i915/bdw: Bro...
811
  	else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8)
7d148ef51   Daniel Vetter   drm/i915: fix hdm...
812
813
814
815
  		return 300000;
  	else
  		return 225000;
  }
7d57382e6   Eric Anholt   drm/i915: Add sup...
816
817
818
  static int intel_hdmi_mode_valid(struct drm_connector *connector,
  				 struct drm_display_mode *mode)
  {
7d148ef51   Daniel Vetter   drm/i915: fix hdm...
819
  	if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector)))
7d57382e6   Eric Anholt   drm/i915: Add sup...
820
821
  		return MODE_CLOCK_HIGH;
  	if (mode->clock < 20000)
5cbba41d2   Nicolas Kaiser   drm: i915: correc...
822
  		return MODE_CLOCK_LOW;
7d57382e6   Eric Anholt   drm/i915: Add sup...
823
824
825
826
827
828
  
  	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
  		return MODE_NO_DBLESCAN;
  
  	return MODE_OK;
  }
5bfe2ac00   Daniel Vetter   drm/i915: add pip...
829
830
  bool intel_hdmi_compute_config(struct intel_encoder *encoder,
  			       struct intel_crtc_config *pipe_config)
7d57382e6   Eric Anholt   drm/i915: Add sup...
831
  {
5bfe2ac00   Daniel Vetter   drm/i915: add pip...
832
833
834
  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
  	struct drm_device *dev = encoder->base.dev;
  	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
241bfc389   Damien Lespiau   drm/i915: Use crt...
835
  	int clock_12bpc = pipe_config->adjusted_mode.crtc_clock * 3 / 2;
7d148ef51   Daniel Vetter   drm/i915: fix hdm...
836
  	int portclock_limit = hdmi_portclock_limit(intel_hdmi);
e29c22c0c   Daniel Vetter   drm/i915: impleme...
837
  	int desired_bpp;
3685a8f38   Ville Syrjälä   drm/i915: Fix RGB...
838

55bc60db5   Ville Syrjälä   drm/i915: Add "Au...
839
840
841
  	if (intel_hdmi->color_range_auto) {
  		/* See CEA-861-E - 5.1 Default Encoding Parameters */
  		if (intel_hdmi->has_hdmi_sink &&
18316c8c3   Thierry Reding   drm: Remove dupli...
842
  		    drm_match_cea_mode(adjusted_mode) > 1)
4f3a8bc7b   Paulo Zanoni   drm/i915: rename ...
843
  			intel_hdmi->color_range = HDMI_COLOR_RANGE_16_235;
55bc60db5   Ville Syrjälä   drm/i915: Add "Au...
844
845
846
  		else
  			intel_hdmi->color_range = 0;
  	}
3685a8f38   Ville Syrjälä   drm/i915: Fix RGB...
847
  	if (intel_hdmi->color_range)
50f3b016b   Daniel Vetter   drm/i915: add pip...
848
  		pipe_config->limited_color_range = true;
3685a8f38   Ville Syrjälä   drm/i915: Fix RGB...
849

5bfe2ac00   Daniel Vetter   drm/i915: add pip...
850
851
  	if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev))
  		pipe_config->has_pch_encoder = true;
4e53c2e01   Daniel Vetter   drm/i915: precomp...
852
853
854
  	/*
  	 * HDMI is either 12 or 8, so if the display lets 10bpc sneak
  	 * through, clamp it down. Note that g4x/vlv don't support 12bpc hdmi
325b9d048   Daniel Vetter   drm/i915: fixup 1...
855
856
  	 * outputs. We also need to check that the higher clock still fits
  	 * within limits.
4e53c2e01   Daniel Vetter   drm/i915: precomp...
857
  	 */
7d148ef51   Daniel Vetter   drm/i915: fix hdm...
858
  	if (pipe_config->pipe_bpp > 8*3 && clock_12bpc <= portclock_limit
325b9d048   Daniel Vetter   drm/i915: fixup 1...
859
  	    && HAS_PCH_SPLIT(dev)) {
e29c22c0c   Daniel Vetter   drm/i915: impleme...
860
861
862
  		DRM_DEBUG_KMS("picking bpc to 12 for HDMI output
  ");
  		desired_bpp = 12*3;
325b9d048   Daniel Vetter   drm/i915: fixup 1...
863
864
  
  		/* Need to adjust the port link by 1.5x for 12bpc. */
ff9a6750a   Daniel Vetter   drm/i915: store a...
865
  		pipe_config->port_clock = clock_12bpc;
4e53c2e01   Daniel Vetter   drm/i915: precomp...
866
  	} else {
e29c22c0c   Daniel Vetter   drm/i915: impleme...
867
868
869
870
871
872
873
874
875
  		DRM_DEBUG_KMS("picking bpc to 8 for HDMI output
  ");
  		desired_bpp = 8*3;
  	}
  
  	if (!pipe_config->bw_constrained) {
  		DRM_DEBUG_KMS("forcing pipe bpc to %i for HDMI
  ", desired_bpp);
  		pipe_config->pipe_bpp = desired_bpp;
4e53c2e01   Daniel Vetter   drm/i915: precomp...
876
  	}
241bfc389   Damien Lespiau   drm/i915: Use crt...
877
  	if (adjusted_mode->crtc_clock > portclock_limit) {
325b9d048   Daniel Vetter   drm/i915: fixup 1...
878
879
880
881
  		DRM_DEBUG_KMS("too high HDMI clock, rejecting mode
  ");
  		return false;
  	}
7d57382e6   Eric Anholt   drm/i915: Add sup...
882
883
  	return true;
  }
aa93d632c   Keith Packard   drm/i915: Require...
884
  static enum drm_connector_status
930a9e283   Chris Wilson   drm: Use a nondes...
885
  intel_hdmi_detect(struct drm_connector *connector, bool force)
9dff6af86   Ma Ling   drm/i915: sync hd...
886
  {
b0ea7d37a   Damien Lespiau   drm/i915/hdmi: Re...
887
  	struct drm_device *dev = connector->dev;
df0e92488   Chris Wilson   drm/i915: Make th...
888
  	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
d63885da9   Paulo Zanoni   drm/i915: reset i...
889
890
891
  	struct intel_digital_port *intel_dig_port =
  		hdmi_to_dig_port(intel_hdmi);
  	struct intel_encoder *intel_encoder = &intel_dig_port->base;
b0ea7d37a   Damien Lespiau   drm/i915/hdmi: Re...
892
  	struct drm_i915_private *dev_priv = dev->dev_private;
f899fc64c   Chris Wilson   drm/i915: use GMB...
893
  	struct edid *edid;
aa93d632c   Keith Packard   drm/i915: Require...
894
  	enum drm_connector_status status = connector_status_disconnected;
9dff6af86   Ma Ling   drm/i915: sync hd...
895

164c85984   Chris Wilson   drm/i915: Add som...
896
897
898
  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]
  ",
  		      connector->base.id, drm_get_connector_name(connector));
ea5b213ad   Chris Wilson   drm/i915: Subclas...
899
  	intel_hdmi->has_hdmi_sink = false;
2e3d6006a   Zhenyu Wang   drm/i915: Enable ...
900
  	intel_hdmi->has_audio = false;
abedc077b   Ville Syrjälä   drm/i915: Provide...
901
  	intel_hdmi->rgb_quant_range_selectable = false;
f899fc64c   Chris Wilson   drm/i915: use GMB...
902
  	edid = drm_get_edid(connector,
3bd7d9093   Daniel Kurtz   drm/i915/intel_i2...
903
904
  			    intel_gmbus_get_adapter(dev_priv,
  						    intel_hdmi->ddc_bus));
2ded9e274   ling.ma@intel.com   drm/i915: hdmi de...
905

aa93d632c   Keith Packard   drm/i915: Require...
906
  	if (edid) {
be9f1c4f7   Eric Anholt   Merge commit 'kei...
907
  		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
aa93d632c   Keith Packard   drm/i915: Require...
908
  			status = connector_status_connected;
b1d7e4b41   Wu Fengguang   drm/i915: add a "...
909
910
911
  			if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI)
  				intel_hdmi->has_hdmi_sink =
  						drm_detect_hdmi_monitor(edid);
2e3d6006a   Zhenyu Wang   drm/i915: Enable ...
912
  			intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
abedc077b   Ville Syrjälä   drm/i915: Provide...
913
914
  			intel_hdmi->rgb_quant_range_selectable =
  				drm_rgb_quant_range_selectable(edid);
aa93d632c   Keith Packard   drm/i915: Require...
915
  		}
aa93d632c   Keith Packard   drm/i915: Require...
916
  		kfree(edid);
9dff6af86   Ma Ling   drm/i915: sync hd...
917
  	}
30ad48b73   Zhenyu Wang   drm/i915: Add HDM...
918

55b7d6e8c   Chris Wilson   drm/i915/hdmi: Ad...
919
  	if (status == connector_status_connected) {
b1d7e4b41   Wu Fengguang   drm/i915: add a "...
920
921
922
  		if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO)
  			intel_hdmi->has_audio =
  				(intel_hdmi->force_audio == HDMI_AUDIO_ON);
d63885da9   Paulo Zanoni   drm/i915: reset i...
923
  		intel_encoder->type = INTEL_OUTPUT_HDMI;
55b7d6e8c   Chris Wilson   drm/i915/hdmi: Ad...
924
  	}
2ded9e274   ling.ma@intel.com   drm/i915: hdmi de...
925
  	return status;
7d57382e6   Eric Anholt   drm/i915: Add sup...
926
927
928
929
  }
  
  static int intel_hdmi_get_modes(struct drm_connector *connector)
  {
df0e92488   Chris Wilson   drm/i915: Make th...
930
  	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
f899fc64c   Chris Wilson   drm/i915: use GMB...
931
  	struct drm_i915_private *dev_priv = connector->dev->dev_private;
7d57382e6   Eric Anholt   drm/i915: Add sup...
932
933
934
935
  
  	/* We should parse the EDID data and find out if it's an HDMI sink so
  	 * we can send audio to it.
  	 */
f899fc64c   Chris Wilson   drm/i915: use GMB...
936
  	return intel_ddc_get_modes(connector,
3bd7d9093   Daniel Kurtz   drm/i915/intel_i2...
937
938
  				   intel_gmbus_get_adapter(dev_priv,
  							   intel_hdmi->ddc_bus));
7d57382e6   Eric Anholt   drm/i915: Add sup...
939
  }
1aad7ac04   Chris Wilson   drm/i915: Trigger...
940
941
942
943
944
945
946
947
948
  static bool
  intel_hdmi_detect_audio(struct drm_connector *connector)
  {
  	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
  	struct drm_i915_private *dev_priv = connector->dev->dev_private;
  	struct edid *edid;
  	bool has_audio = false;
  
  	edid = drm_get_edid(connector,
3bd7d9093   Daniel Kurtz   drm/i915/intel_i2...
949
950
  			    intel_gmbus_get_adapter(dev_priv,
  						    intel_hdmi->ddc_bus));
1aad7ac04   Chris Wilson   drm/i915: Trigger...
951
952
953
  	if (edid) {
  		if (edid->input & DRM_EDID_INPUT_DIGITAL)
  			has_audio = drm_detect_monitor_audio(edid);
1aad7ac04   Chris Wilson   drm/i915: Trigger...
954
955
956
957
958
  		kfree(edid);
  	}
  
  	return has_audio;
  }
55b7d6e8c   Chris Wilson   drm/i915/hdmi: Ad...
959
960
  static int
  intel_hdmi_set_property(struct drm_connector *connector,
ed517fbbb   Paulo Zanoni   drm/i915: small h...
961
962
  			struct drm_property *property,
  			uint64_t val)
55b7d6e8c   Chris Wilson   drm/i915/hdmi: Ad...
963
964
  {
  	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
da63a9f2e   Paulo Zanoni   drm/i915: create ...
965
966
  	struct intel_digital_port *intel_dig_port =
  		hdmi_to_dig_port(intel_hdmi);
e953fd7bb   Chris Wilson   drm/i915: Add sup...
967
  	struct drm_i915_private *dev_priv = connector->dev->dev_private;
55b7d6e8c   Chris Wilson   drm/i915/hdmi: Ad...
968
  	int ret;
662595df9   Rob Clark   drm/i915: drm_con...
969
  	ret = drm_object_property_set_value(&connector->base, property, val);
55b7d6e8c   Chris Wilson   drm/i915/hdmi: Ad...
970
971
  	if (ret)
  		return ret;
3f43c48d3   Chris Wilson   drm/i915: Share t...
972
  	if (property == dev_priv->force_audio_property) {
b1d7e4b41   Wu Fengguang   drm/i915: add a "...
973
  		enum hdmi_force_audio i = val;
1aad7ac04   Chris Wilson   drm/i915: Trigger...
974
975
976
  		bool has_audio;
  
  		if (i == intel_hdmi->force_audio)
55b7d6e8c   Chris Wilson   drm/i915/hdmi: Ad...
977
  			return 0;
1aad7ac04   Chris Wilson   drm/i915: Trigger...
978
  		intel_hdmi->force_audio = i;
55b7d6e8c   Chris Wilson   drm/i915/hdmi: Ad...
979

b1d7e4b41   Wu Fengguang   drm/i915: add a "...
980
  		if (i == HDMI_AUDIO_AUTO)
1aad7ac04   Chris Wilson   drm/i915: Trigger...
981
982
  			has_audio = intel_hdmi_detect_audio(connector);
  		else
b1d7e4b41   Wu Fengguang   drm/i915: add a "...
983
  			has_audio = (i == HDMI_AUDIO_ON);
1aad7ac04   Chris Wilson   drm/i915: Trigger...
984

b1d7e4b41   Wu Fengguang   drm/i915: add a "...
985
986
  		if (i == HDMI_AUDIO_OFF_DVI)
  			intel_hdmi->has_hdmi_sink = 0;
55b7d6e8c   Chris Wilson   drm/i915/hdmi: Ad...
987

1aad7ac04   Chris Wilson   drm/i915: Trigger...
988
  		intel_hdmi->has_audio = has_audio;
55b7d6e8c   Chris Wilson   drm/i915/hdmi: Ad...
989
990
  		goto done;
  	}
e953fd7bb   Chris Wilson   drm/i915: Add sup...
991
  	if (property == dev_priv->broadcast_rgb_property) {
ae4edb808   Daniel Vetter   drm/i915: avoid f...
992
993
  		bool old_auto = intel_hdmi->color_range_auto;
  		uint32_t old_range = intel_hdmi->color_range;
55bc60db5   Ville Syrjälä   drm/i915: Add "Au...
994
995
996
997
998
999
1000
1001
1002
1003
  		switch (val) {
  		case INTEL_BROADCAST_RGB_AUTO:
  			intel_hdmi->color_range_auto = true;
  			break;
  		case INTEL_BROADCAST_RGB_FULL:
  			intel_hdmi->color_range_auto = false;
  			intel_hdmi->color_range = 0;
  			break;
  		case INTEL_BROADCAST_RGB_LIMITED:
  			intel_hdmi->color_range_auto = false;
4f3a8bc7b   Paulo Zanoni   drm/i915: rename ...
1004
  			intel_hdmi->color_range = HDMI_COLOR_RANGE_16_235;
55bc60db5   Ville Syrjälä   drm/i915: Add "Au...
1005
1006
1007
1008
  			break;
  		default:
  			return -EINVAL;
  		}
ae4edb808   Daniel Vetter   drm/i915: avoid f...
1009
1010
1011
1012
  
  		if (old_auto == intel_hdmi->color_range_auto &&
  		    old_range == intel_hdmi->color_range)
  			return 0;
e953fd7bb   Chris Wilson   drm/i915: Add sup...
1013
1014
  		goto done;
  	}
55b7d6e8c   Chris Wilson   drm/i915/hdmi: Ad...
1015
1016
1017
  	return -EINVAL;
  
  done:
c0c36b941   Chris Wilson   drm/i915: Return ...
1018
1019
  	if (intel_dig_port->base.base.crtc)
  		intel_crtc_restore_mode(intel_dig_port->base.base.crtc);
55b7d6e8c   Chris Wilson   drm/i915/hdmi: Ad...
1020
1021
1022
  
  	return 0;
  }
9514ac6e7   Chon Ming Lee   drm/i915: Move so...
1023
  static void vlv_hdmi_pre_enable(struct intel_encoder *encoder)
89b667f86   Jesse Barnes   drm/i915: update ...
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
  {
  	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
  	struct drm_device *dev = encoder->base.dev;
  	struct drm_i915_private *dev_priv = dev->dev_private;
  	struct intel_crtc *intel_crtc =
  		to_intel_crtc(encoder->base.crtc);
  	int port = vlv_dport_to_channel(dport);
  	int pipe = intel_crtc->pipe;
  	u32 val;
  
  	if (!IS_VALLEYVIEW(dev))
  		return;
89b667f86   Jesse Barnes   drm/i915: update ...
1036
  	/* Enable clock channels for this port */
0980a60fb   Chris Wilson   drm/i915: Acquire...
1037
  	mutex_lock(&dev_priv->dpio_lock);
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1038
  	val = vlv_dpio_read(dev_priv, pipe, DPIO_DATA_LANE_A(port));
89b667f86   Jesse Barnes   drm/i915: update ...
1039
1040
1041
1042
1043
1044
  	val = 0;
  	if (pipe)
  		val |= (1<<21);
  	else
  		val &= ~(1<<21);
  	val |= 0x001000c4;
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1045
  	vlv_dpio_write(dev_priv, pipe, DPIO_DATA_CHANNEL(port), val);
89b667f86   Jesse Barnes   drm/i915: update ...
1046
1047
  
  	/* HDMI 1.0V-2dB */
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1048
1049
  	vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port), 0);
  	vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL4(port),
89b667f86   Jesse Barnes   drm/i915: update ...
1050
  			 0x2b245f5f);
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1051
  	vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL2(port),
89b667f86   Jesse Barnes   drm/i915: update ...
1052
  			 0x5578b83a);
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1053
  	vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL3(port),
89b667f86   Jesse Barnes   drm/i915: update ...
1054
  			 0x0c782040);
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1055
  	vlv_dpio_write(dev_priv, pipe, DPIO_TX3_SWING_CTL4(port),
89b667f86   Jesse Barnes   drm/i915: update ...
1056
  			 0x2b247878);
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1057
1058
  	vlv_dpio_write(dev_priv, pipe, DPIO_PCS_STAGGER0(port), 0x00030000);
  	vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CTL_OVER1(port),
89b667f86   Jesse Barnes   drm/i915: update ...
1059
  			 0x00002000);
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1060
  	vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port),
89b667f86   Jesse Barnes   drm/i915: update ...
1061
1062
1063
  			 DPIO_TX_OCALINIT_EN);
  
  	/* Program lane clock */
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1064
  	vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLOCKBUF0(port),
89b667f86   Jesse Barnes   drm/i915: update ...
1065
  			 0x00760018);
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1066
  	vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLOCKBUF8(port),
89b667f86   Jesse Barnes   drm/i915: update ...
1067
  			 0x00400888);
0980a60fb   Chris Wilson   drm/i915: Acquire...
1068
  	mutex_unlock(&dev_priv->dpio_lock);
b76cf76bf   Jani Nikula   drm/i915: rearran...
1069
1070
1071
1072
  
  	intel_enable_hdmi(encoder);
  
  	vlv_wait_port_ready(dev_priv, port);
89b667f86   Jesse Barnes   drm/i915: update ...
1073
  }
9514ac6e7   Chon Ming Lee   drm/i915: Move so...
1074
  static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
89b667f86   Jesse Barnes   drm/i915: update ...
1075
1076
1077
1078
  {
  	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
  	struct drm_device *dev = encoder->base.dev;
  	struct drm_i915_private *dev_priv = dev->dev_private;
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1079
1080
  	struct intel_crtc *intel_crtc =
  		to_intel_crtc(encoder->base.crtc);
89b667f86   Jesse Barnes   drm/i915: update ...
1081
  	int port = vlv_dport_to_channel(dport);
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1082
  	int pipe = intel_crtc->pipe;
89b667f86   Jesse Barnes   drm/i915: update ...
1083
1084
1085
  
  	if (!IS_VALLEYVIEW(dev))
  		return;
89b667f86   Jesse Barnes   drm/i915: update ...
1086
  	/* Program Tx lane resets to default */
0980a60fb   Chris Wilson   drm/i915: Acquire...
1087
  	mutex_lock(&dev_priv->dpio_lock);
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1088
  	vlv_dpio_write(dev_priv, pipe, DPIO_PCS_TX(port),
89b667f86   Jesse Barnes   drm/i915: update ...
1089
1090
  			 DPIO_PCS_TX_LANE2_RESET |
  			 DPIO_PCS_TX_LANE1_RESET);
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1091
  	vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLK(port),
89b667f86   Jesse Barnes   drm/i915: update ...
1092
1093
1094
1095
1096
1097
  			 DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
  			 DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
  			 (1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) |
  			 DPIO_PCS_CLK_SOFT_RESET);
  
  	/* Fix up inter-pair skew failure */
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1098
1099
1100
  	vlv_dpio_write(dev_priv, pipe, DPIO_PCS_STAGGER1(port), 0x00750f00);
  	vlv_dpio_write(dev_priv, pipe, DPIO_TX_CTL(port), 0x00001500);
  	vlv_dpio_write(dev_priv, pipe, DPIO_TX_LANE(port), 0x40400000);
89b667f86   Jesse Barnes   drm/i915: update ...
1101

5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1102
  	vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CTL_OVER1(port),
89b667f86   Jesse Barnes   drm/i915: update ...
1103
  			 0x00002000);
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1104
  	vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port),
89b667f86   Jesse Barnes   drm/i915: update ...
1105
  			 DPIO_TX_OCALINIT_EN);
0980a60fb   Chris Wilson   drm/i915: Acquire...
1106
  	mutex_unlock(&dev_priv->dpio_lock);
89b667f86   Jesse Barnes   drm/i915: update ...
1107
  }
9514ac6e7   Chon Ming Lee   drm/i915: Move so...
1108
  static void vlv_hdmi_post_disable(struct intel_encoder *encoder)
89b667f86   Jesse Barnes   drm/i915: update ...
1109
1110
1111
  {
  	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
  	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1112
1113
  	struct intel_crtc *intel_crtc =
  		to_intel_crtc(encoder->base.crtc);
89b667f86   Jesse Barnes   drm/i915: update ...
1114
  	int port = vlv_dport_to_channel(dport);
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1115
  	int pipe = intel_crtc->pipe;
89b667f86   Jesse Barnes   drm/i915: update ...
1116
1117
1118
  
  	/* Reset lanes to avoid HDMI flicker (VLV w/a) */
  	mutex_lock(&dev_priv->dpio_lock);
5e69f97fb   Chon Ming Lee   drm/i915: Add add...
1119
1120
  	vlv_dpio_write(dev_priv, pipe, DPIO_PCS_TX(port), 0x00000000);
  	vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLK(port), 0x00e00060);
89b667f86   Jesse Barnes   drm/i915: update ...
1121
1122
  	mutex_unlock(&dev_priv->dpio_lock);
  }
7d57382e6   Eric Anholt   drm/i915: Add sup...
1123
1124
  static void intel_hdmi_destroy(struct drm_connector *connector)
  {
7d57382e6   Eric Anholt   drm/i915: Add sup...
1125
  	drm_connector_cleanup(connector);
674e2d088   Zhenyu Wang   drm/i915: convert...
1126
  	kfree(connector);
7d57382e6   Eric Anholt   drm/i915: Add sup...
1127
  }
7d57382e6   Eric Anholt   drm/i915: Add sup...
1128
  static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
5ab432ef4   Daniel Vetter   drm/i915/hdmi: co...
1129
  	.dpms = intel_connector_dpms,
7d57382e6   Eric Anholt   drm/i915: Add sup...
1130
1131
  	.detect = intel_hdmi_detect,
  	.fill_modes = drm_helper_probe_single_connector_modes,
55b7d6e8c   Chris Wilson   drm/i915/hdmi: Ad...
1132
  	.set_property = intel_hdmi_set_property,
7d57382e6   Eric Anholt   drm/i915: Add sup...
1133
1134
1135
1136
1137
1138
  	.destroy = intel_hdmi_destroy,
  };
  
  static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = {
  	.get_modes = intel_hdmi_get_modes,
  	.mode_valid = intel_hdmi_mode_valid,
df0e92488   Chris Wilson   drm/i915: Make th...
1139
  	.best_encoder = intel_best_encoder,
7d57382e6   Eric Anholt   drm/i915: Add sup...
1140
  };
7d57382e6   Eric Anholt   drm/i915: Add sup...
1141
  static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
ea5b213ad   Chris Wilson   drm/i915: Subclas...
1142
  	.destroy = intel_encoder_destroy,
7d57382e6   Eric Anholt   drm/i915: Add sup...
1143
  };
55b7d6e8c   Chris Wilson   drm/i915/hdmi: Ad...
1144
1145
1146
  static void
  intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector)
  {
3f43c48d3   Chris Wilson   drm/i915: Share t...
1147
  	intel_attach_force_audio_property(connector);
e953fd7bb   Chris Wilson   drm/i915: Add sup...
1148
  	intel_attach_broadcast_rgb_property(connector);
55bc60db5   Ville Syrjälä   drm/i915: Add "Au...
1149
  	intel_hdmi->color_range_auto = true;
55b7d6e8c   Chris Wilson   drm/i915/hdmi: Ad...
1150
  }
00c09d70d   Paulo Zanoni   drm/i915: create ...
1151
1152
  void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
  			       struct intel_connector *intel_connector)
7d57382e6   Eric Anholt   drm/i915: Add sup...
1153
  {
b9cb234cb   Paulo Zanoni   drm/i915: split i...
1154
1155
1156
1157
  	struct drm_connector *connector = &intel_connector->base;
  	struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
  	struct intel_encoder *intel_encoder = &intel_dig_port->base;
  	struct drm_device *dev = intel_encoder->base.dev;
7d57382e6   Eric Anholt   drm/i915: Add sup...
1158
  	struct drm_i915_private *dev_priv = dev->dev_private;
174edf1f8   Paulo Zanoni   drm/i915: add por...
1159
  	enum port port = intel_dig_port->port;
373a3cf74   Chris Wilson   drm/i915: call dr...
1160

7d57382e6   Eric Anholt   drm/i915: Add sup...
1161
  	drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
8d91104aa   Adam Jackson   drm/i915: Initial...
1162
  			   DRM_MODE_CONNECTOR_HDMIA);
7d57382e6   Eric Anholt   drm/i915: Add sup...
1163
  	drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
c3febcc43   Peter Ross   drm/i915: allow i...
1164
  	connector->interlace_allowed = 1;
7d57382e6   Eric Anholt   drm/i915: Add sup...
1165
  	connector->doublescan_allowed = 0;
573e74adb   Damien Lespiau   drm/i915: Allow s...
1166
  	connector->stereo_allowed = 1;
66a9278ee   Daniel Vetter   drm/i915: simplif...
1167

08d644add   Daniel Vetter   drm/i915: add por...
1168
1169
  	switch (port) {
  	case PORT_B:
f899fc64c   Chris Wilson   drm/i915: use GMB...
1170
  		intel_hdmi->ddc_bus = GMBUS_PORT_DPB;
1d843f9de   Egbert Eich   DRM/I915: Add enu...
1171
  		intel_encoder->hpd_pin = HPD_PORT_B;
08d644add   Daniel Vetter   drm/i915: add por...
1172
1173
  		break;
  	case PORT_C:
7ceae0a55   Eugeni Dodonov   drm/i915: add sup...
1174
  		intel_hdmi->ddc_bus = GMBUS_PORT_DPC;
1d843f9de   Egbert Eich   DRM/I915: Add enu...
1175
  		intel_encoder->hpd_pin = HPD_PORT_C;
08d644add   Daniel Vetter   drm/i915: add por...
1176
1177
  		break;
  	case PORT_D:
7ceae0a55   Eugeni Dodonov   drm/i915: add sup...
1178
  		intel_hdmi->ddc_bus = GMBUS_PORT_DPD;
1d843f9de   Egbert Eich   DRM/I915: Add enu...
1179
  		intel_encoder->hpd_pin = HPD_PORT_D;
08d644add   Daniel Vetter   drm/i915: add por...
1180
1181
  		break;
  	case PORT_A:
1d843f9de   Egbert Eich   DRM/I915: Add enu...
1182
  		intel_encoder->hpd_pin = HPD_PORT_A;
08d644add   Daniel Vetter   drm/i915: add por...
1183
1184
  		/* Internal port only for eDP. */
  	default:
6e4c1677f   Eugeni Dodonov   drm/i915: show un...
1185
  		BUG();
f8aed700c   Ma Ling   drm/i915: Set crt...
1186
  	}
7d57382e6   Eric Anholt   drm/i915: Add sup...
1187

7637bfdb5   Jesse Barnes   drm/i915: use VLV...
1188
  	if (IS_VALLEYVIEW(dev)) {
90b107c8f   Shobhit Kumar   drm/i915: Enable ...
1189
  		intel_hdmi->write_infoframe = vlv_write_infoframe;
687f4d06d   Paulo Zanoni   drm/i915: add set...
1190
  		intel_hdmi->set_infoframes = vlv_set_infoframes;
7637bfdb5   Jesse Barnes   drm/i915: use VLV...
1191
1192
1193
  	} else if (!HAS_PCH_SPLIT(dev)) {
  		intel_hdmi->write_infoframe = g4x_write_infoframe;
  		intel_hdmi->set_infoframes = g4x_set_infoframes;
22b8bf17c   Paulo Zanoni   drm/i915: use HAS...
1194
  	} else if (HAS_DDI(dev)) {
8c5f5f7c4   Eugeni Dodonov   drm/i915: add new...
1195
  		intel_hdmi->write_infoframe = hsw_write_infoframe;
687f4d06d   Paulo Zanoni   drm/i915: add set...
1196
  		intel_hdmi->set_infoframes = hsw_set_infoframes;
fdf1250aa   Paulo Zanoni   drm/i915: split i...
1197
1198
  	} else if (HAS_PCH_IBX(dev)) {
  		intel_hdmi->write_infoframe = ibx_write_infoframe;
687f4d06d   Paulo Zanoni   drm/i915: add set...
1199
  		intel_hdmi->set_infoframes = ibx_set_infoframes;
fdf1250aa   Paulo Zanoni   drm/i915: split i...
1200
1201
  	} else {
  		intel_hdmi->write_infoframe = cpt_write_infoframe;
687f4d06d   Paulo Zanoni   drm/i915: add set...
1202
  		intel_hdmi->set_infoframes = cpt_set_infoframes;
64a8fc014   Jesse Barnes   drm/i915: fix ILK...
1203
  	}
45187ace9   Jesse Barnes   drm/i915/hdmi: sp...
1204

affa93544   Paulo Zanoni   drm/i915: add HAS...
1205
  	if (HAS_DDI(dev))
bcbc889bc   Paulo Zanoni   drm/i915: add int...
1206
1207
1208
  		intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
  	else
  		intel_connector->get_hw_state = intel_connector_get_hw_state;
b9cb234cb   Paulo Zanoni   drm/i915: split i...
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
  
  	intel_hdmi_add_properties(intel_hdmi, connector);
  
  	intel_connector_attach_encoder(intel_connector, intel_encoder);
  	drm_sysfs_connector_add(connector);
  
  	/* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
  	 * 0xd.  Failure to do so will result in spurious interrupts being
  	 * generated on the port when a cable is not attached.
  	 */
  	if (IS_G4X(dev) && !IS_GM45(dev)) {
  		u32 temp = I915_READ(PEG_BAND_GAP_DATA);
  		I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
  	}
  }
b242b7f74   Paulo Zanoni   drm/i915: rename ...
1224
  void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
b9cb234cb   Paulo Zanoni   drm/i915: split i...
1225
1226
1227
  {
  	struct intel_digital_port *intel_dig_port;
  	struct intel_encoder *intel_encoder;
b9cb234cb   Paulo Zanoni   drm/i915: split i...
1228
  	struct intel_connector *intel_connector;
b14c5679d   Daniel Vetter   drm/i915: use poi...
1229
  	intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
b9cb234cb   Paulo Zanoni   drm/i915: split i...
1230
1231
  	if (!intel_dig_port)
  		return;
b14c5679d   Daniel Vetter   drm/i915: use poi...
1232
  	intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
b9cb234cb   Paulo Zanoni   drm/i915: split i...
1233
1234
1235
1236
1237
1238
  	if (!intel_connector) {
  		kfree(intel_dig_port);
  		return;
  	}
  
  	intel_encoder = &intel_dig_port->base;
b9cb234cb   Paulo Zanoni   drm/i915: split i...
1239
1240
1241
  
  	drm_encoder_init(dev, &intel_encoder->base, &intel_hdmi_enc_funcs,
  			 DRM_MODE_ENCODER_TMDS);
00c09d70d   Paulo Zanoni   drm/i915: create ...
1242

5bfe2ac00   Daniel Vetter   drm/i915: add pip...
1243
  	intel_encoder->compute_config = intel_hdmi_compute_config;
c59423a3d   Daniel Vetter   drm/i915/hdmi: us...
1244
  	intel_encoder->mode_set = intel_hdmi_mode_set;
00c09d70d   Paulo Zanoni   drm/i915: create ...
1245
1246
  	intel_encoder->disable = intel_disable_hdmi;
  	intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
045ac3b56   Jesse Barnes   drm/i915: add enc...
1247
  	intel_encoder->get_config = intel_hdmi_get_config;
89b667f86   Jesse Barnes   drm/i915: update ...
1248
  	if (IS_VALLEYVIEW(dev)) {
9514ac6e7   Chon Ming Lee   drm/i915: Move so...
1249
1250
  		intel_encoder->pre_pll_enable = vlv_hdmi_pre_pll_enable;
  		intel_encoder->pre_enable = vlv_hdmi_pre_enable;
b76cf76bf   Jani Nikula   drm/i915: rearran...
1251
  		intel_encoder->enable = vlv_enable_hdmi;
9514ac6e7   Chon Ming Lee   drm/i915: Move so...
1252
  		intel_encoder->post_disable = vlv_hdmi_post_disable;
b76cf76bf   Jani Nikula   drm/i915: rearran...
1253
1254
  	} else {
  		intel_encoder->enable = intel_enable_hdmi;
89b667f86   Jesse Barnes   drm/i915: update ...
1255
  	}
5ab432ef4   Daniel Vetter   drm/i915/hdmi: co...
1256

b9cb234cb   Paulo Zanoni   drm/i915: split i...
1257
1258
1259
  	intel_encoder->type = INTEL_OUTPUT_HDMI;
  	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
  	intel_encoder->cloneable = false;
7d57382e6   Eric Anholt   drm/i915: Add sup...
1260

174edf1f8   Paulo Zanoni   drm/i915: add por...
1261
  	intel_dig_port->port = port;
b242b7f74   Paulo Zanoni   drm/i915: rename ...
1262
  	intel_dig_port->hdmi.hdmi_reg = hdmi_reg;
b9cb234cb   Paulo Zanoni   drm/i915: split i...
1263
  	intel_dig_port->dp.output_reg = 0;
55b7d6e8c   Chris Wilson   drm/i915/hdmi: Ad...
1264

b9cb234cb   Paulo Zanoni   drm/i915: split i...
1265
  	intel_hdmi_init_connector(intel_dig_port, intel_connector);
7d57382e6   Eric Anholt   drm/i915: Add sup...
1266
  }