blob: 3cb180e38ca13bdc1cba6d0eec17dceda72c540d [file] [log] [blame]
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001/*
2 * Copyright © 2008 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Keith Packard <keithp@keithp.com>
25 *
26 */
27
28#include <linux/i2c.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090029#include <linux/slab.h>
Paul Gortmaker2d1a8a42011-08-30 18:16:33 -040030#include <linux/export.h>
David Howells760285e2012-10-02 18:01:07 +010031#include <drm/drmP.h>
32#include <drm/drm_crtc.h>
33#include <drm/drm_crtc_helper.h>
34#include <drm/drm_edid.h>
Keith Packarda4fc5ed2009-04-07 16:16:42 -070035#include "intel_drv.h"
David Howells760285e2012-10-02 18:01:07 +010036#include <drm/i915_drm.h>
Keith Packarda4fc5ed2009-04-07 16:16:42 -070037#include "i915_drv.h"
Keith Packarda4fc5ed2009-04-07 16:16:42 -070038
Keith Packarda4fc5ed2009-04-07 16:16:42 -070039#define DP_LINK_CHECK_TIMEOUT (10 * 1000)
40
Jesse Barnescfcb0fc2010-10-07 16:01:06 -070041/**
42 * is_edp - is the given port attached to an eDP panel (either CPU or PCH)
43 * @intel_dp: DP struct
44 *
45 * If a CPU or PCH DP output is attached to an eDP panel, this function
46 * will return true, and false otherwise.
47 */
48static bool is_edp(struct intel_dp *intel_dp)
49{
50 return intel_dp->base.type == INTEL_OUTPUT_EDP;
51}
52
53/**
54 * is_pch_edp - is the port on the PCH and attached to an eDP panel?
55 * @intel_dp: DP struct
56 *
57 * Returns true if the given DP struct corresponds to a PCH DP port attached
58 * to an eDP panel, false otherwise. Helpful for determining whether we
59 * may need FDI resources for a given DP output or not.
60 */
61static bool is_pch_edp(struct intel_dp *intel_dp)
62{
63 return intel_dp->is_pch_edp;
64}
65
Adam Jackson1c958222011-10-14 17:22:25 -040066/**
67 * is_cpu_edp - is the port on the CPU and attached to an eDP panel?
68 * @intel_dp: DP struct
69 *
70 * Returns true if the given DP struct corresponds to a CPU eDP port.
71 */
72static bool is_cpu_edp(struct intel_dp *intel_dp)
73{
74 return is_edp(intel_dp) && !is_pch_edp(intel_dp);
75}
76
Chris Wilsondf0e9242010-09-09 16:20:55 +010077static struct intel_dp *intel_attached_dp(struct drm_connector *connector)
78{
79 return container_of(intel_attached_encoder(connector),
80 struct intel_dp, base);
81}
82
Jesse Barnes814948a2010-10-07 16:01:09 -070083/**
84 * intel_encoder_is_pch_edp - is the given encoder a PCH attached eDP?
85 * @encoder: DRM encoder
86 *
87 * Return true if @encoder corresponds to a PCH attached eDP panel. Needed
88 * by intel_display.c.
89 */
90bool intel_encoder_is_pch_edp(struct drm_encoder *encoder)
91{
92 struct intel_dp *intel_dp;
93
94 if (!encoder)
95 return false;
96
97 intel_dp = enc_to_intel_dp(encoder);
98
99 return is_pch_edp(intel_dp);
100}
101
Chris Wilsonea5b2132010-08-04 13:50:23 +0100102static void intel_dp_link_down(struct intel_dp *intel_dp);
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700103
Zhenyu Wang32f9d652009-07-24 01:00:32 +0800104void
Akshay Joshi0206e352011-08-16 15:34:10 -0400105intel_edp_link_config(struct intel_encoder *intel_encoder,
Chris Wilsonea5b2132010-08-04 13:50:23 +0100106 int *lane_num, int *link_bw)
Zhenyu Wang32f9d652009-07-24 01:00:32 +0800107{
Chris Wilsonea5b2132010-08-04 13:50:23 +0100108 struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base);
Zhenyu Wang32f9d652009-07-24 01:00:32 +0800109
Chris Wilsonea5b2132010-08-04 13:50:23 +0100110 *lane_num = intel_dp->lane_count;
111 if (intel_dp->link_bw == DP_LINK_BW_1_62)
Zhenyu Wang32f9d652009-07-24 01:00:32 +0800112 *link_bw = 162000;
Chris Wilsonea5b2132010-08-04 13:50:23 +0100113 else if (intel_dp->link_bw == DP_LINK_BW_2_7)
Zhenyu Wang32f9d652009-07-24 01:00:32 +0800114 *link_bw = 270000;
115}
116
Daniel Vetter94bf2ce2012-06-04 18:39:19 +0200117int
118intel_edp_target_clock(struct intel_encoder *intel_encoder,
119 struct drm_display_mode *mode)
120{
121 struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base);
Jani Nikuladd06f902012-10-19 14:51:50 +0300122 struct intel_connector *intel_connector = intel_dp->attached_connector;
Daniel Vetter94bf2ce2012-06-04 18:39:19 +0200123
Jani Nikuladd06f902012-10-19 14:51:50 +0300124 if (intel_connector->panel.fixed_mode)
125 return intel_connector->panel.fixed_mode->clock;
Daniel Vetter94bf2ce2012-06-04 18:39:19 +0200126 else
127 return mode->clock;
128}
129
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700130static int
Chris Wilsonea5b2132010-08-04 13:50:23 +0100131intel_dp_max_lane_count(struct intel_dp *intel_dp)
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700132{
Keith Packard9a10f402011-11-02 13:03:47 -0700133 int max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f;
134 switch (max_lane_count) {
135 case 1: case 2: case 4:
136 break;
137 default:
138 max_lane_count = 4;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700139 }
140 return max_lane_count;
141}
142
143static int
Chris Wilsonea5b2132010-08-04 13:50:23 +0100144intel_dp_max_link_bw(struct intel_dp *intel_dp)
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700145{
Jesse Barnes7183dc22011-07-07 11:10:58 -0700146 int max_link_bw = intel_dp->dpcd[DP_MAX_LINK_RATE];
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700147
148 switch (max_link_bw) {
149 case DP_LINK_BW_1_62:
150 case DP_LINK_BW_2_7:
151 break;
152 default:
153 max_link_bw = DP_LINK_BW_1_62;
154 break;
155 }
156 return max_link_bw;
157}
158
159static int
160intel_dp_link_clock(uint8_t link_bw)
161{
162 if (link_bw == DP_LINK_BW_2_7)
163 return 270000;
164 else
165 return 162000;
166}
167
Adam Jacksoncd9dde42011-10-14 12:43:49 -0400168/*
169 * The units on the numbers in the next two are... bizarre. Examples will
170 * make it clearer; this one parallels an example in the eDP spec.
171 *
172 * intel_dp_max_data_rate for one lane of 2.7GHz evaluates as:
173 *
174 * 270000 * 1 * 8 / 10 == 216000
175 *
176 * The actual data capacity of that configuration is 2.16Gbit/s, so the
177 * units are decakilobits. ->clock in a drm_display_mode is in kilohertz -
178 * or equivalently, kilopixels per second - so for 1680x1050R it'd be
179 * 119000. At 18bpp that's 2142000 kilobits per second.
180 *
181 * Thus the strange-looking division by 10 in intel_dp_link_required, to
182 * get the result in decakilobits instead of kilobits.
183 */
184
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700185static int
Keith Packardc8982612012-01-25 08:16:25 -0800186intel_dp_link_required(int pixel_clock, int bpp)
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700187{
Adam Jacksoncd9dde42011-10-14 12:43:49 -0400188 return (pixel_clock * bpp + 9) / 10;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700189}
190
191static int
Dave Airliefe27d532010-06-30 11:46:17 +1000192intel_dp_max_data_rate(int max_link_clock, int max_lanes)
193{
194 return (max_link_clock * max_lanes * 8) / 10;
195}
196
Daniel Vetterc4867932012-04-10 10:42:36 +0200197static bool
198intel_dp_adjust_dithering(struct intel_dp *intel_dp,
199 struct drm_display_mode *mode,
Daniel Vettercb1793c2012-06-04 18:39:21 +0200200 bool adjust_mode)
Daniel Vetterc4867932012-04-10 10:42:36 +0200201{
202 int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
203 int max_lanes = intel_dp_max_lane_count(intel_dp);
204 int max_rate, mode_rate;
205
206 mode_rate = intel_dp_link_required(mode->clock, 24);
207 max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
208
209 if (mode_rate > max_rate) {
210 mode_rate = intel_dp_link_required(mode->clock, 18);
211 if (mode_rate > max_rate)
212 return false;
213
Daniel Vettercb1793c2012-06-04 18:39:21 +0200214 if (adjust_mode)
215 mode->private_flags
Daniel Vetterc4867932012-04-10 10:42:36 +0200216 |= INTEL_MODE_DP_FORCE_6BPC;
217
218 return true;
219 }
220
221 return true;
222}
223
Dave Airliefe27d532010-06-30 11:46:17 +1000224static int
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700225intel_dp_mode_valid(struct drm_connector *connector,
226 struct drm_display_mode *mode)
227{
Chris Wilsondf0e9242010-09-09 16:20:55 +0100228 struct intel_dp *intel_dp = intel_attached_dp(connector);
Jani Nikuladd06f902012-10-19 14:51:50 +0300229 struct intel_connector *intel_connector = to_intel_connector(connector);
230 struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700231
Jani Nikuladd06f902012-10-19 14:51:50 +0300232 if (is_edp(intel_dp) && fixed_mode) {
233 if (mode->hdisplay > fixed_mode->hdisplay)
Zhao Yakui7de56f42010-07-19 09:43:14 +0100234 return MODE_PANEL;
235
Jani Nikuladd06f902012-10-19 14:51:50 +0300236 if (mode->vdisplay > fixed_mode->vdisplay)
Zhao Yakui7de56f42010-07-19 09:43:14 +0100237 return MODE_PANEL;
238 }
239
Daniel Vettercb1793c2012-06-04 18:39:21 +0200240 if (!intel_dp_adjust_dithering(intel_dp, mode, false))
Daniel Vetterc4867932012-04-10 10:42:36 +0200241 return MODE_CLOCK_HIGH;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700242
243 if (mode->clock < 10000)
244 return MODE_CLOCK_LOW;
245
Daniel Vetter0af78a22012-05-23 11:30:55 +0200246 if (mode->flags & DRM_MODE_FLAG_DBLCLK)
247 return MODE_H_ILLEGAL;
248
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700249 return MODE_OK;
250}
251
252static uint32_t
253pack_aux(uint8_t *src, int src_bytes)
254{
255 int i;
256 uint32_t v = 0;
257
258 if (src_bytes > 4)
259 src_bytes = 4;
260 for (i = 0; i < src_bytes; i++)
261 v |= ((uint32_t) src[i]) << ((3-i) * 8);
262 return v;
263}
264
265static void
266unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes)
267{
268 int i;
269 if (dst_bytes > 4)
270 dst_bytes = 4;
271 for (i = 0; i < dst_bytes; i++)
272 dst[i] = src >> ((3-i) * 8);
273}
274
Keith Packardfb0f8fb2009-06-11 22:31:31 -0700275/* hrawclock is 1/4 the FSB frequency */
276static int
277intel_hrawclk(struct drm_device *dev)
278{
279 struct drm_i915_private *dev_priv = dev->dev_private;
280 uint32_t clkcfg;
281
Vijay Purushothaman9473c8f2012-09-27 19:13:01 +0530282 /* There is no CLKCFG reg in Valleyview. VLV hrawclk is 200 MHz */
283 if (IS_VALLEYVIEW(dev))
284 return 200;
285
Keith Packardfb0f8fb2009-06-11 22:31:31 -0700286 clkcfg = I915_READ(CLKCFG);
287 switch (clkcfg & CLKCFG_FSB_MASK) {
288 case CLKCFG_FSB_400:
289 return 100;
290 case CLKCFG_FSB_533:
291 return 133;
292 case CLKCFG_FSB_667:
293 return 166;
294 case CLKCFG_FSB_800:
295 return 200;
296 case CLKCFG_FSB_1067:
297 return 266;
298 case CLKCFG_FSB_1333:
299 return 333;
300 /* these two are just a guess; one of them might be right */
301 case CLKCFG_FSB_1600:
302 case CLKCFG_FSB_1600_ALT:
303 return 400;
304 default:
305 return 133;
306 }
307}
308
Keith Packardebf33b12011-09-29 15:53:27 -0700309static bool ironlake_edp_have_panel_power(struct intel_dp *intel_dp)
310{
311 struct drm_device *dev = intel_dp->base.base.dev;
312 struct drm_i915_private *dev_priv = dev->dev_private;
313
314 return (I915_READ(PCH_PP_STATUS) & PP_ON) != 0;
315}
316
317static bool ironlake_edp_have_panel_vdd(struct intel_dp *intel_dp)
318{
319 struct drm_device *dev = intel_dp->base.base.dev;
320 struct drm_i915_private *dev_priv = dev->dev_private;
321
322 return (I915_READ(PCH_PP_CONTROL) & EDP_FORCE_VDD) != 0;
323}
324
Keith Packard9b984da2011-09-19 13:54:47 -0700325static void
326intel_dp_check_edp(struct intel_dp *intel_dp)
327{
328 struct drm_device *dev = intel_dp->base.base.dev;
329 struct drm_i915_private *dev_priv = dev->dev_private;
Keith Packardebf33b12011-09-29 15:53:27 -0700330
Keith Packard9b984da2011-09-19 13:54:47 -0700331 if (!is_edp(intel_dp))
332 return;
Keith Packardebf33b12011-09-29 15:53:27 -0700333 if (!ironlake_edp_have_panel_power(intel_dp) && !ironlake_edp_have_panel_vdd(intel_dp)) {
Keith Packard9b984da2011-09-19 13:54:47 -0700334 WARN(1, "eDP powered off while attempting aux channel communication.\n");
335 DRM_DEBUG_KMS("Status 0x%08x Control 0x%08x\n",
Keith Packardebf33b12011-09-29 15:53:27 -0700336 I915_READ(PCH_PP_STATUS),
Keith Packard9b984da2011-09-19 13:54:47 -0700337 I915_READ(PCH_PP_CONTROL));
338 }
339}
340
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700341static int
Chris Wilsonea5b2132010-08-04 13:50:23 +0100342intel_dp_aux_ch(struct intel_dp *intel_dp,
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700343 uint8_t *send, int send_bytes,
344 uint8_t *recv, int recv_size)
345{
Chris Wilsonea5b2132010-08-04 13:50:23 +0100346 uint32_t output_reg = intel_dp->output_reg;
Chris Wilson4ef69c72010-09-09 15:14:28 +0100347 struct drm_device *dev = intel_dp->base.base.dev;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700348 struct drm_i915_private *dev_priv = dev->dev_private;
349 uint32_t ch_ctl = output_reg + 0x10;
350 uint32_t ch_data = ch_ctl + 4;
351 int i;
352 int recv_bytes;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700353 uint32_t status;
Keith Packardfb0f8fb2009-06-11 22:31:31 -0700354 uint32_t aux_clock_divider;
Daniel Vetter6b4e0a92012-06-14 22:15:00 +0200355 int try, precharge;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700356
Paulo Zanoni750eb992012-10-18 16:25:08 +0200357 if (IS_HASWELL(dev)) {
358 switch (intel_dp->port) {
359 case PORT_A:
360 ch_ctl = DPA_AUX_CH_CTL;
361 ch_data = DPA_AUX_CH_DATA1;
362 break;
363 case PORT_B:
364 ch_ctl = PCH_DPB_AUX_CH_CTL;
365 ch_data = PCH_DPB_AUX_CH_DATA1;
366 break;
367 case PORT_C:
368 ch_ctl = PCH_DPC_AUX_CH_CTL;
369 ch_data = PCH_DPC_AUX_CH_DATA1;
370 break;
371 case PORT_D:
372 ch_ctl = PCH_DPD_AUX_CH_CTL;
373 ch_data = PCH_DPD_AUX_CH_DATA1;
374 break;
375 default:
376 BUG();
377 }
378 }
379
Keith Packard9b984da2011-09-19 13:54:47 -0700380 intel_dp_check_edp(intel_dp);
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700381 /* The clock divider is based off the hrawclk,
Keith Packardfb0f8fb2009-06-11 22:31:31 -0700382 * and would like to run at 2MHz. So, take the
383 * hrawclk value and divide by 2 and use that
Jesse Barnes6176b8f2010-09-08 12:42:00 -0700384 *
385 * Note that PCH attached eDP panels should use a 125MHz input
386 * clock divider.
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700387 */
Adam Jackson1c958222011-10-14 17:22:25 -0400388 if (is_cpu_edp(intel_dp)) {
Vijay Purushothaman9473c8f2012-09-27 19:13:01 +0530389 if (IS_VALLEYVIEW(dev))
390 aux_clock_divider = 100;
391 else if (IS_GEN6(dev) || IS_GEN7(dev))
Keith Packard1a2eb462011-11-16 16:26:07 -0800392 aux_clock_divider = 200; /* SNB & IVB eDP input clock at 400Mhz */
Zhenyu Wange3421a12010-04-08 09:43:27 +0800393 else
394 aux_clock_divider = 225; /* eDP input clock at 450Mhz */
395 } else if (HAS_PCH_SPLIT(dev))
Adam Jackson69191322011-07-26 15:39:44 -0400396 aux_clock_divider = 63; /* IRL input clock fixed at 125Mhz */
Zhenyu Wang5eb08b62009-07-24 01:00:31 +0800397 else
398 aux_clock_divider = intel_hrawclk(dev) / 2;
399
Daniel Vetter6b4e0a92012-06-14 22:15:00 +0200400 if (IS_GEN6(dev))
401 precharge = 3;
402 else
403 precharge = 5;
404
Jesse Barnes11bee432011-08-01 15:02:20 -0700405 /* Try to wait for any previous AUX channel activity */
406 for (try = 0; try < 3; try++) {
407 status = I915_READ(ch_ctl);
408 if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0)
409 break;
410 msleep(1);
411 }
412
413 if (try == 3) {
414 WARN(1, "dp_aux_ch not started status 0x%08x\n",
415 I915_READ(ch_ctl));
Chris Wilson4f7f7b72010-08-18 18:12:56 +0100416 return -EBUSY;
417 }
418
Keith Packardfb0f8fb2009-06-11 22:31:31 -0700419 /* Must try at least 3 times according to DP spec */
420 for (try = 0; try < 5; try++) {
421 /* Load the send data into the aux channel data registers */
Chris Wilson4f7f7b72010-08-18 18:12:56 +0100422 for (i = 0; i < send_bytes; i += 4)
423 I915_WRITE(ch_data + i,
424 pack_aux(send + i, send_bytes - i));
Akshay Joshi0206e352011-08-16 15:34:10 -0400425
Keith Packardfb0f8fb2009-06-11 22:31:31 -0700426 /* Send the command and wait for it to complete */
Chris Wilson4f7f7b72010-08-18 18:12:56 +0100427 I915_WRITE(ch_ctl,
428 DP_AUX_CH_CTL_SEND_BUSY |
429 DP_AUX_CH_CTL_TIME_OUT_400us |
430 (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
431 (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
432 (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) |
433 DP_AUX_CH_CTL_DONE |
434 DP_AUX_CH_CTL_TIME_OUT_ERROR |
435 DP_AUX_CH_CTL_RECEIVE_ERROR);
Keith Packardfb0f8fb2009-06-11 22:31:31 -0700436 for (;;) {
Keith Packardfb0f8fb2009-06-11 22:31:31 -0700437 status = I915_READ(ch_ctl);
438 if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0)
439 break;
Chris Wilson4f7f7b72010-08-18 18:12:56 +0100440 udelay(100);
Keith Packardfb0f8fb2009-06-11 22:31:31 -0700441 }
Akshay Joshi0206e352011-08-16 15:34:10 -0400442
Keith Packardfb0f8fb2009-06-11 22:31:31 -0700443 /* Clear done status and any errors */
Chris Wilson4f7f7b72010-08-18 18:12:56 +0100444 I915_WRITE(ch_ctl,
445 status |
446 DP_AUX_CH_CTL_DONE |
447 DP_AUX_CH_CTL_TIME_OUT_ERROR |
448 DP_AUX_CH_CTL_RECEIVE_ERROR);
Adam Jacksond7e96fe2011-07-26 15:39:46 -0400449
450 if (status & (DP_AUX_CH_CTL_TIME_OUT_ERROR |
451 DP_AUX_CH_CTL_RECEIVE_ERROR))
452 continue;
Chris Wilson4f7f7b72010-08-18 18:12:56 +0100453 if (status & DP_AUX_CH_CTL_DONE)
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700454 break;
455 }
456
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700457 if ((status & DP_AUX_CH_CTL_DONE) == 0) {
Keith Packard1ae8c0a2009-06-28 15:42:17 -0700458 DRM_ERROR("dp_aux_ch not done status 0x%08x\n", status);
Keith Packarda5b3da52009-06-11 22:30:32 -0700459 return -EBUSY;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700460 }
461
462 /* Check for timeout or receive error.
463 * Timeouts occur when the sink is not connected
464 */
Keith Packarda5b3da52009-06-11 22:30:32 -0700465 if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) {
Keith Packard1ae8c0a2009-06-28 15:42:17 -0700466 DRM_ERROR("dp_aux_ch receive error status 0x%08x\n", status);
Keith Packarda5b3da52009-06-11 22:30:32 -0700467 return -EIO;
468 }
Keith Packard1ae8c0a2009-06-28 15:42:17 -0700469
470 /* Timeouts occur when the device isn't connected, so they're
471 * "normal" -- don't fill the kernel log with these */
Keith Packarda5b3da52009-06-11 22:30:32 -0700472 if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) {
Zhao Yakui28c97732009-10-09 11:39:41 +0800473 DRM_DEBUG_KMS("dp_aux_ch timeout status 0x%08x\n", status);
Keith Packarda5b3da52009-06-11 22:30:32 -0700474 return -ETIMEDOUT;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700475 }
476
477 /* Unload any bytes sent back from the other side */
478 recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >>
479 DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT);
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700480 if (recv_bytes > recv_size)
481 recv_bytes = recv_size;
Akshay Joshi0206e352011-08-16 15:34:10 -0400482
Chris Wilson4f7f7b72010-08-18 18:12:56 +0100483 for (i = 0; i < recv_bytes; i += 4)
484 unpack_aux(I915_READ(ch_data + i),
485 recv + i, recv_bytes - i);
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700486
487 return recv_bytes;
488}
489
490/* Write data to the aux channel in native mode */
491static int
Chris Wilsonea5b2132010-08-04 13:50:23 +0100492intel_dp_aux_native_write(struct intel_dp *intel_dp,
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700493 uint16_t address, uint8_t *send, int send_bytes)
494{
495 int ret;
496 uint8_t msg[20];
497 int msg_bytes;
498 uint8_t ack;
499
Keith Packard9b984da2011-09-19 13:54:47 -0700500 intel_dp_check_edp(intel_dp);
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700501 if (send_bytes > 16)
502 return -1;
503 msg[0] = AUX_NATIVE_WRITE << 4;
504 msg[1] = address >> 8;
Zhenyu Wangeebc8632009-07-24 01:00:30 +0800505 msg[2] = address & 0xff;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700506 msg[3] = send_bytes - 1;
507 memcpy(&msg[4], send, send_bytes);
508 msg_bytes = send_bytes + 4;
509 for (;;) {
Chris Wilsonea5b2132010-08-04 13:50:23 +0100510 ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1);
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700511 if (ret < 0)
512 return ret;
513 if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
514 break;
515 else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)
516 udelay(100);
517 else
Keith Packarda5b3da52009-06-11 22:30:32 -0700518 return -EIO;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700519 }
520 return send_bytes;
521}
522
523/* Write a single byte to the aux channel in native mode */
524static int
Chris Wilsonea5b2132010-08-04 13:50:23 +0100525intel_dp_aux_native_write_1(struct intel_dp *intel_dp,
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700526 uint16_t address, uint8_t byte)
527{
Chris Wilsonea5b2132010-08-04 13:50:23 +0100528 return intel_dp_aux_native_write(intel_dp, address, &byte, 1);
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700529}
530
531/* read bytes from a native aux channel */
532static int
Chris Wilsonea5b2132010-08-04 13:50:23 +0100533intel_dp_aux_native_read(struct intel_dp *intel_dp,
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700534 uint16_t address, uint8_t *recv, int recv_bytes)
535{
536 uint8_t msg[4];
537 int msg_bytes;
538 uint8_t reply[20];
539 int reply_bytes;
540 uint8_t ack;
541 int ret;
542
Keith Packard9b984da2011-09-19 13:54:47 -0700543 intel_dp_check_edp(intel_dp);
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700544 msg[0] = AUX_NATIVE_READ << 4;
545 msg[1] = address >> 8;
546 msg[2] = address & 0xff;
547 msg[3] = recv_bytes - 1;
548
549 msg_bytes = 4;
550 reply_bytes = recv_bytes + 1;
551
552 for (;;) {
Chris Wilsonea5b2132010-08-04 13:50:23 +0100553 ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes,
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700554 reply, reply_bytes);
Keith Packarda5b3da52009-06-11 22:30:32 -0700555 if (ret == 0)
556 return -EPROTO;
557 if (ret < 0)
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700558 return ret;
559 ack = reply[0];
560 if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) {
561 memcpy(recv, reply + 1, ret - 1);
562 return ret - 1;
563 }
564 else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)
565 udelay(100);
566 else
Keith Packarda5b3da52009-06-11 22:30:32 -0700567 return -EIO;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700568 }
569}
570
571static int
Dave Airlieab2c0672009-12-04 10:55:24 +1000572intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
573 uint8_t write_byte, uint8_t *read_byte)
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700574{
Dave Airlieab2c0672009-12-04 10:55:24 +1000575 struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
Chris Wilsonea5b2132010-08-04 13:50:23 +0100576 struct intel_dp *intel_dp = container_of(adapter,
577 struct intel_dp,
578 adapter);
Dave Airlieab2c0672009-12-04 10:55:24 +1000579 uint16_t address = algo_data->address;
580 uint8_t msg[5];
581 uint8_t reply[2];
David Flynn8316f332010-12-08 16:10:21 +0000582 unsigned retry;
Dave Airlieab2c0672009-12-04 10:55:24 +1000583 int msg_bytes;
584 int reply_bytes;
585 int ret;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700586
Keith Packard9b984da2011-09-19 13:54:47 -0700587 intel_dp_check_edp(intel_dp);
Dave Airlieab2c0672009-12-04 10:55:24 +1000588 /* Set up the command byte */
589 if (mode & MODE_I2C_READ)
590 msg[0] = AUX_I2C_READ << 4;
591 else
592 msg[0] = AUX_I2C_WRITE << 4;
593
594 if (!(mode & MODE_I2C_STOP))
595 msg[0] |= AUX_I2C_MOT << 4;
596
597 msg[1] = address >> 8;
598 msg[2] = address;
599
600 switch (mode) {
601 case MODE_I2C_WRITE:
602 msg[3] = 0;
603 msg[4] = write_byte;
604 msg_bytes = 5;
605 reply_bytes = 1;
606 break;
607 case MODE_I2C_READ:
608 msg[3] = 0;
609 msg_bytes = 4;
610 reply_bytes = 2;
611 break;
612 default:
613 msg_bytes = 3;
614 reply_bytes = 1;
615 break;
616 }
617
David Flynn8316f332010-12-08 16:10:21 +0000618 for (retry = 0; retry < 5; retry++) {
619 ret = intel_dp_aux_ch(intel_dp,
620 msg, msg_bytes,
621 reply, reply_bytes);
Dave Airlieab2c0672009-12-04 10:55:24 +1000622 if (ret < 0) {
Dave Airlie3ff99162009-12-08 14:03:47 +1000623 DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
Dave Airlieab2c0672009-12-04 10:55:24 +1000624 return ret;
625 }
David Flynn8316f332010-12-08 16:10:21 +0000626
627 switch (reply[0] & AUX_NATIVE_REPLY_MASK) {
628 case AUX_NATIVE_REPLY_ACK:
629 /* I2C-over-AUX Reply field is only valid
630 * when paired with AUX ACK.
631 */
632 break;
633 case AUX_NATIVE_REPLY_NACK:
634 DRM_DEBUG_KMS("aux_ch native nack\n");
635 return -EREMOTEIO;
636 case AUX_NATIVE_REPLY_DEFER:
637 udelay(100);
638 continue;
639 default:
640 DRM_ERROR("aux_ch invalid native reply 0x%02x\n",
641 reply[0]);
642 return -EREMOTEIO;
643 }
644
Dave Airlieab2c0672009-12-04 10:55:24 +1000645 switch (reply[0] & AUX_I2C_REPLY_MASK) {
646 case AUX_I2C_REPLY_ACK:
647 if (mode == MODE_I2C_READ) {
648 *read_byte = reply[1];
649 }
650 return reply_bytes - 1;
651 case AUX_I2C_REPLY_NACK:
David Flynn8316f332010-12-08 16:10:21 +0000652 DRM_DEBUG_KMS("aux_i2c nack\n");
Dave Airlieab2c0672009-12-04 10:55:24 +1000653 return -EREMOTEIO;
654 case AUX_I2C_REPLY_DEFER:
David Flynn8316f332010-12-08 16:10:21 +0000655 DRM_DEBUG_KMS("aux_i2c defer\n");
Dave Airlieab2c0672009-12-04 10:55:24 +1000656 udelay(100);
657 break;
658 default:
David Flynn8316f332010-12-08 16:10:21 +0000659 DRM_ERROR("aux_i2c invalid reply 0x%02x\n", reply[0]);
Dave Airlieab2c0672009-12-04 10:55:24 +1000660 return -EREMOTEIO;
661 }
662 }
David Flynn8316f332010-12-08 16:10:21 +0000663
664 DRM_ERROR("too many retries, giving up\n");
665 return -EREMOTEIO;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700666}
667
Keith Packard0b5c5412011-09-28 16:41:05 -0700668static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp);
Keith Packardbd943152011-09-18 23:09:52 -0700669static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync);
Keith Packard0b5c5412011-09-28 16:41:05 -0700670
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700671static int
Chris Wilsonea5b2132010-08-04 13:50:23 +0100672intel_dp_i2c_init(struct intel_dp *intel_dp,
Zhenyu Wang55f78c42010-03-29 16:13:57 +0800673 struct intel_connector *intel_connector, const char *name)
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700674{
Keith Packard0b5c5412011-09-28 16:41:05 -0700675 int ret;
676
Zhenyu Wangd54e9d22009-10-19 15:43:51 +0800677 DRM_DEBUG_KMS("i2c_init %s\n", name);
Chris Wilsonea5b2132010-08-04 13:50:23 +0100678 intel_dp->algo.running = false;
679 intel_dp->algo.address = 0;
680 intel_dp->algo.aux_ch = intel_dp_i2c_aux_ch;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700681
Akshay Joshi0206e352011-08-16 15:34:10 -0400682 memset(&intel_dp->adapter, '\0', sizeof(intel_dp->adapter));
Chris Wilsonea5b2132010-08-04 13:50:23 +0100683 intel_dp->adapter.owner = THIS_MODULE;
684 intel_dp->adapter.class = I2C_CLASS_DDC;
Akshay Joshi0206e352011-08-16 15:34:10 -0400685 strncpy(intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1);
Chris Wilsonea5b2132010-08-04 13:50:23 +0100686 intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0';
687 intel_dp->adapter.algo_data = &intel_dp->algo;
688 intel_dp->adapter.dev.parent = &intel_connector->base.kdev;
689
Keith Packard0b5c5412011-09-28 16:41:05 -0700690 ironlake_edp_panel_vdd_on(intel_dp);
691 ret = i2c_dp_aux_add_bus(&intel_dp->adapter);
Keith Packardbd943152011-09-18 23:09:52 -0700692 ironlake_edp_panel_vdd_off(intel_dp, false);
Keith Packard0b5c5412011-09-28 16:41:05 -0700693 return ret;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700694}
695
696static bool
Laurent Pincharte811f5a2012-07-17 17:56:50 +0200697intel_dp_mode_fixup(struct drm_encoder *encoder,
698 const struct drm_display_mode *mode,
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700699 struct drm_display_mode *adjusted_mode)
700{
Zhao Yakui0d3a1bee2010-07-19 09:43:13 +0100701 struct drm_device *dev = encoder->dev;
Chris Wilsonea5b2132010-08-04 13:50:23 +0100702 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikuladd06f902012-10-19 14:51:50 +0300703 struct intel_connector *intel_connector = intel_dp->attached_connector;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700704 int lane_count, clock;
Chris Wilsonea5b2132010-08-04 13:50:23 +0100705 int max_lane_count = intel_dp_max_lane_count(intel_dp);
706 int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
Daniel Vetter083f9562012-04-20 20:23:49 +0200707 int bpp, mode_rate;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700708 static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
709
Jani Nikuladd06f902012-10-19 14:51:50 +0300710 if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
711 intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
712 adjusted_mode);
Chris Wilson1d8e1c72010-08-07 11:01:28 +0100713 intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN,
714 mode, adjusted_mode);
Zhao Yakui0d3a1bee2010-07-19 09:43:13 +0100715 }
716
Daniel Vettercb1793c2012-06-04 18:39:21 +0200717 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
Daniel Vetter0af78a22012-05-23 11:30:55 +0200718 return false;
719
Daniel Vetter083f9562012-04-20 20:23:49 +0200720 DRM_DEBUG_KMS("DP link computation with max lane count %i "
721 "max bw %02x pixel clock %iKHz\n",
Daniel Vetter71244652012-06-04 18:39:20 +0200722 max_lane_count, bws[max_clock], adjusted_mode->clock);
Daniel Vetter083f9562012-04-20 20:23:49 +0200723
Daniel Vettercb1793c2012-06-04 18:39:21 +0200724 if (!intel_dp_adjust_dithering(intel_dp, adjusted_mode, true))
Daniel Vetterc4867932012-04-10 10:42:36 +0200725 return false;
726
727 bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
Daniel Vetter71244652012-06-04 18:39:20 +0200728 mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp);
Daniel Vetterc4867932012-04-10 10:42:36 +0200729
Jesse Barnes2514bc52012-06-21 15:13:50 -0700730 for (clock = 0; clock <= max_clock; clock++) {
731 for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
Dave Airliefe27d532010-06-30 11:46:17 +1000732 int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700733
Daniel Vetter083f9562012-04-20 20:23:49 +0200734 if (mode_rate <= link_avail) {
Chris Wilsonea5b2132010-08-04 13:50:23 +0100735 intel_dp->link_bw = bws[clock];
736 intel_dp->lane_count = lane_count;
737 adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw);
Daniel Vetter083f9562012-04-20 20:23:49 +0200738 DRM_DEBUG_KMS("DP link bw %02x lane "
739 "count %d clock %d bpp %d\n",
Chris Wilsonea5b2132010-08-04 13:50:23 +0100740 intel_dp->link_bw, intel_dp->lane_count,
Daniel Vetter083f9562012-04-20 20:23:49 +0200741 adjusted_mode->clock, bpp);
742 DRM_DEBUG_KMS("DP link bw required %i available %i\n",
743 mode_rate, link_avail);
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700744 return true;
745 }
746 }
747 }
Dave Airliefe27d532010-06-30 11:46:17 +1000748
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700749 return false;
750}
751
752struct intel_dp_m_n {
753 uint32_t tu;
754 uint32_t gmch_m;
755 uint32_t gmch_n;
756 uint32_t link_m;
757 uint32_t link_n;
758};
759
760static void
761intel_reduce_ratio(uint32_t *num, uint32_t *den)
762{
763 while (*num > 0xffffff || *den > 0xffffff) {
764 *num >>= 1;
765 *den >>= 1;
766 }
767}
768
769static void
Zhao Yakui36e83a12010-06-12 14:32:21 +0800770intel_dp_compute_m_n(int bpp,
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700771 int nlanes,
772 int pixel_clock,
773 int link_clock,
774 struct intel_dp_m_n *m_n)
775{
776 m_n->tu = 64;
Zhao Yakui36e83a12010-06-12 14:32:21 +0800777 m_n->gmch_m = (pixel_clock * bpp) >> 3;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700778 m_n->gmch_n = link_clock * nlanes;
779 intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
780 m_n->link_m = pixel_clock;
781 m_n->link_n = link_clock;
782 intel_reduce_ratio(&m_n->link_m, &m_n->link_n);
783}
784
785void
786intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
787 struct drm_display_mode *adjusted_mode)
788{
789 struct drm_device *dev = crtc->dev;
Daniel Vetter6c2b7c12012-07-05 09:50:24 +0200790 struct intel_encoder *encoder;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700791 struct drm_i915_private *dev_priv = dev->dev_private;
792 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Jesse Barnes858fa0352011-06-24 12:19:24 -0700793 int lane_count = 4;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700794 struct intel_dp_m_n m_n;
Jesse Barnes9db4a9c2011-02-07 12:26:52 -0800795 int pipe = intel_crtc->pipe;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700796
797 /*
Eric Anholt21d40d32010-03-25 11:11:14 -0700798 * Find the lane count in the intel_encoder private
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700799 */
Daniel Vetter6c2b7c12012-07-05 09:50:24 +0200800 for_each_encoder_on_crtc(dev, crtc, encoder) {
801 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700802
Keith Packard9a10f402011-11-02 13:03:47 -0700803 if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT ||
804 intel_dp->base.type == INTEL_OUTPUT_EDP)
805 {
Chris Wilsonea5b2132010-08-04 13:50:23 +0100806 lane_count = intel_dp->lane_count;
Jesse Barnes51190662010-10-07 16:01:08 -0700807 break;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700808 }
809 }
810
811 /*
812 * Compute the GMCH and Link ratios. The '3' here is
813 * the number of bytes_per_pixel post-LUT, which we always
814 * set up for 8-bits of R/G/B, or 3 bytes total.
815 */
Jesse Barnes858fa0352011-06-24 12:19:24 -0700816 intel_dp_compute_m_n(intel_crtc->bpp, lane_count,
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700817 mode->clock, adjusted_mode->clock, &m_n);
818
Paulo Zanoni1eb8dfe2012-10-18 12:42:10 -0300819 if (IS_HASWELL(dev)) {
820 I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
821 I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n);
822 I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m);
823 I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n);
824 } else if (HAS_PCH_SPLIT(dev)) {
Paulo Zanoni7346bfa2012-10-15 15:51:35 -0300825 I915_WRITE(TRANSDATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
Jesse Barnes9db4a9c2011-02-07 12:26:52 -0800826 I915_WRITE(TRANSDATA_N1(pipe), m_n.gmch_n);
827 I915_WRITE(TRANSDPLINK_M1(pipe), m_n.link_m);
828 I915_WRITE(TRANSDPLINK_N1(pipe), m_n.link_n);
Vijay Purushothaman74a4dd22012-09-27 19:13:04 +0530829 } else if (IS_VALLEYVIEW(dev)) {
830 I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
831 I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n);
832 I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m);
833 I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n);
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700834 } else {
Jesse Barnes9db4a9c2011-02-07 12:26:52 -0800835 I915_WRITE(PIPE_GMCH_DATA_M(pipe),
Paulo Zanoni7346bfa2012-10-15 15:51:35 -0300836 TU_SIZE(m_n.tu) | m_n.gmch_m);
Jesse Barnes9db4a9c2011-02-07 12:26:52 -0800837 I915_WRITE(PIPE_GMCH_DATA_N(pipe), m_n.gmch_n);
838 I915_WRITE(PIPE_DP_LINK_M(pipe), m_n.link_m);
839 I915_WRITE(PIPE_DP_LINK_N(pipe), m_n.link_n);
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700840 }
841}
842
Paulo Zanoni247d89f2012-10-15 15:51:33 -0300843void intel_dp_init_link_config(struct intel_dp *intel_dp)
844{
845 memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
846 intel_dp->link_configuration[0] = intel_dp->link_bw;
847 intel_dp->link_configuration[1] = intel_dp->lane_count;
848 intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B;
849 /*
850 * Check for DPCD version > 1.1 and enhanced framing support
851 */
852 if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
853 (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) {
854 intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
855 }
856}
857
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700858static void
859intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
860 struct drm_display_mode *adjusted_mode)
861{
Zhenyu Wange3421a12010-04-08 09:43:27 +0800862 struct drm_device *dev = encoder->dev;
Keith Packard417e8222011-11-01 19:54:11 -0700863 struct drm_i915_private *dev_priv = dev->dev_private;
Chris Wilsonea5b2132010-08-04 13:50:23 +0100864 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Chris Wilson4ef69c72010-09-09 15:14:28 +0100865 struct drm_crtc *crtc = intel_dp->base.base.crtc;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700866 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
867
Keith Packard417e8222011-11-01 19:54:11 -0700868 /*
Keith Packard1a2eb462011-11-16 16:26:07 -0800869 * There are four kinds of DP registers:
Keith Packard417e8222011-11-01 19:54:11 -0700870 *
871 * IBX PCH
Keith Packard1a2eb462011-11-16 16:26:07 -0800872 * SNB CPU
873 * IVB CPU
Keith Packard417e8222011-11-01 19:54:11 -0700874 * CPT PCH
875 *
876 * IBX PCH and CPU are the same for almost everything,
877 * except that the CPU DP PLL is configured in this
878 * register
879 *
880 * CPT PCH is quite different, having many bits moved
881 * to the TRANS_DP_CTL register instead. That
882 * configuration happens (oddly) in ironlake_pch_enable
883 */
Adam Jackson9c9e7922010-04-05 17:57:59 -0400884
Keith Packard417e8222011-11-01 19:54:11 -0700885 /* Preserve the BIOS-computed detected bit. This is
886 * supposed to be read-only.
887 */
888 intel_dp->DP = I915_READ(intel_dp->output_reg) & DP_DETECTED;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700889
Keith Packard417e8222011-11-01 19:54:11 -0700890 /* Handle DP bits in common between all three register formats */
Keith Packard417e8222011-11-01 19:54:11 -0700891 intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700892
Chris Wilsonea5b2132010-08-04 13:50:23 +0100893 switch (intel_dp->lane_count) {
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700894 case 1:
Chris Wilsonea5b2132010-08-04 13:50:23 +0100895 intel_dp->DP |= DP_PORT_WIDTH_1;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700896 break;
897 case 2:
Chris Wilsonea5b2132010-08-04 13:50:23 +0100898 intel_dp->DP |= DP_PORT_WIDTH_2;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700899 break;
900 case 4:
Chris Wilsonea5b2132010-08-04 13:50:23 +0100901 intel_dp->DP |= DP_PORT_WIDTH_4;
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700902 break;
903 }
Wu Fengguange0dac652011-09-05 14:25:34 +0800904 if (intel_dp->has_audio) {
905 DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n",
906 pipe_name(intel_crtc->pipe));
Chris Wilsonea5b2132010-08-04 13:50:23 +0100907 intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
Wu Fengguange0dac652011-09-05 14:25:34 +0800908 intel_write_eld(encoder, adjusted_mode);
909 }
Paulo Zanoni247d89f2012-10-15 15:51:33 -0300910
911 intel_dp_init_link_config(intel_dp);
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700912
Keith Packard417e8222011-11-01 19:54:11 -0700913 /* Split out the IBX/CPU vs CPT settings */
Zhenyu Wang32f9d652009-07-24 01:00:32 +0800914
Gajanan Bhat19c03922012-09-27 19:13:07 +0530915 if (is_cpu_edp(intel_dp) && IS_GEN7(dev) && !IS_VALLEYVIEW(dev)) {
Keith Packard1a2eb462011-11-16 16:26:07 -0800916 if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
917 intel_dp->DP |= DP_SYNC_HS_HIGH;
918 if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
919 intel_dp->DP |= DP_SYNC_VS_HIGH;
920 intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
921
922 if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN)
923 intel_dp->DP |= DP_ENHANCED_FRAMING;
924
925 intel_dp->DP |= intel_crtc->pipe << 29;
926
927 /* don't miss out required setting for eDP */
Keith Packard1a2eb462011-11-16 16:26:07 -0800928 if (adjusted_mode->clock < 200000)
929 intel_dp->DP |= DP_PLL_FREQ_160MHZ;
930 else
931 intel_dp->DP |= DP_PLL_FREQ_270MHZ;
932 } else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) {
Keith Packard417e8222011-11-01 19:54:11 -0700933 intel_dp->DP |= intel_dp->color_range;
934
935 if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
936 intel_dp->DP |= DP_SYNC_HS_HIGH;
937 if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
938 intel_dp->DP |= DP_SYNC_VS_HIGH;
939 intel_dp->DP |= DP_LINK_TRAIN_OFF;
940
941 if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN)
942 intel_dp->DP |= DP_ENHANCED_FRAMING;
943
944 if (intel_crtc->pipe == 1)
945 intel_dp->DP |= DP_PIPEB_SELECT;
946
947 if (is_cpu_edp(intel_dp)) {
948 /* don't miss out required setting for eDP */
Keith Packard417e8222011-11-01 19:54:11 -0700949 if (adjusted_mode->clock < 200000)
950 intel_dp->DP |= DP_PLL_FREQ_160MHZ;
951 else
952 intel_dp->DP |= DP_PLL_FREQ_270MHZ;
953 }
954 } else {
955 intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
Zhenyu Wang32f9d652009-07-24 01:00:32 +0800956 }
Keith Packarda4fc5ed2009-04-07 16:16:42 -0700957}
958
Keith Packard99ea7122011-11-01 19:57:50 -0700959#define IDLE_ON_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | 0 | PP_SEQUENCE_STATE_MASK)
960#define IDLE_ON_VALUE (PP_ON | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_ON_IDLE)
961
962#define IDLE_OFF_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | 0 | PP_SEQUENCE_STATE_MASK)
963#define IDLE_OFF_VALUE (0 | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_OFF_IDLE)
964
965#define IDLE_CYCLE_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK)
966#define IDLE_CYCLE_VALUE (0 | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_OFF_IDLE)
967
968static void ironlake_wait_panel_status(struct intel_dp *intel_dp,
969 u32 mask,
970 u32 value)
971{
972 struct drm_device *dev = intel_dp->base.base.dev;
973 struct drm_i915_private *dev_priv = dev->dev_private;
974
975 DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n",
976 mask, value,
977 I915_READ(PCH_PP_STATUS),
978 I915_READ(PCH_PP_CONTROL));
979
980 if (_wait_for((I915_READ(PCH_PP_STATUS) & mask) == value, 5000, 10)) {
981 DRM_ERROR("Panel status timeout: status %08x control %08x\n",
982 I915_READ(PCH_PP_STATUS),
983 I915_READ(PCH_PP_CONTROL));
984 }
985}
986
987static void ironlake_wait_panel_on(struct intel_dp *intel_dp)
988{
989 DRM_DEBUG_KMS("Wait for panel power on\n");
990 ironlake_wait_panel_status(intel_dp, IDLE_ON_MASK, IDLE_ON_VALUE);
991}
992
Keith Packardbd943152011-09-18 23:09:52 -0700993static void ironlake_wait_panel_off(struct intel_dp *intel_dp)
994{
Keith Packardbd943152011-09-18 23:09:52 -0700995 DRM_DEBUG_KMS("Wait for panel power off time\n");
Keith Packard99ea7122011-11-01 19:57:50 -0700996 ironlake_wait_panel_status(intel_dp, IDLE_OFF_MASK, IDLE_OFF_VALUE);
Keith Packardbd943152011-09-18 23:09:52 -0700997}
Keith Packardbd943152011-09-18 23:09:52 -0700998
Keith Packard99ea7122011-11-01 19:57:50 -0700999static void ironlake_wait_panel_power_cycle(struct intel_dp *intel_dp)
1000{
1001 DRM_DEBUG_KMS("Wait for panel power cycle\n");
1002 ironlake_wait_panel_status(intel_dp, IDLE_CYCLE_MASK, IDLE_CYCLE_VALUE);
1003}
Keith Packardbd943152011-09-18 23:09:52 -07001004
Keith Packard99ea7122011-11-01 19:57:50 -07001005
Keith Packard832dd3c2011-11-01 19:34:06 -07001006/* Read the current pp_control value, unlocking the register if it
1007 * is locked
1008 */
1009
1010static u32 ironlake_get_pp_control(struct drm_i915_private *dev_priv)
1011{
1012 u32 control = I915_READ(PCH_PP_CONTROL);
1013
1014 control &= ~PANEL_UNLOCK_MASK;
1015 control |= PANEL_UNLOCK_REGS;
1016 return control;
Keith Packardbd943152011-09-18 23:09:52 -07001017}
1018
Jesse Barnes5d613502011-01-24 17:10:54 -08001019static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
1020{
1021 struct drm_device *dev = intel_dp->base.base.dev;
1022 struct drm_i915_private *dev_priv = dev->dev_private;
1023 u32 pp;
1024
Keith Packard97af61f572011-09-28 16:23:51 -07001025 if (!is_edp(intel_dp))
1026 return;
Keith Packardf01eca22011-09-28 16:48:10 -07001027 DRM_DEBUG_KMS("Turn eDP VDD on\n");
Jesse Barnes5d613502011-01-24 17:10:54 -08001028
Keith Packardbd943152011-09-18 23:09:52 -07001029 WARN(intel_dp->want_panel_vdd,
1030 "eDP VDD already requested on\n");
1031
1032 intel_dp->want_panel_vdd = true;
Keith Packard99ea7122011-11-01 19:57:50 -07001033
Keith Packardbd943152011-09-18 23:09:52 -07001034 if (ironlake_edp_have_panel_vdd(intel_dp)) {
1035 DRM_DEBUG_KMS("eDP VDD already on\n");
1036 return;
1037 }
1038
Keith Packard99ea7122011-11-01 19:57:50 -07001039 if (!ironlake_edp_have_panel_power(intel_dp))
1040 ironlake_wait_panel_power_cycle(intel_dp);
1041
Keith Packard832dd3c2011-11-01 19:34:06 -07001042 pp = ironlake_get_pp_control(dev_priv);
Jesse Barnes5d613502011-01-24 17:10:54 -08001043 pp |= EDP_FORCE_VDD;
1044 I915_WRITE(PCH_PP_CONTROL, pp);
1045 POSTING_READ(PCH_PP_CONTROL);
Keith Packardf01eca22011-09-28 16:48:10 -07001046 DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n",
1047 I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL));
Keith Packardebf33b12011-09-29 15:53:27 -07001048
1049 /*
1050 * If the panel wasn't on, delay before accessing aux channel
1051 */
1052 if (!ironlake_edp_have_panel_power(intel_dp)) {
Keith Packardbd943152011-09-18 23:09:52 -07001053 DRM_DEBUG_KMS("eDP was not running\n");
Keith Packardf01eca22011-09-28 16:48:10 -07001054 msleep(intel_dp->panel_power_up_delay);
Keith Packardf01eca22011-09-28 16:48:10 -07001055 }
Jesse Barnes5d613502011-01-24 17:10:54 -08001056}
1057
Keith Packardbd943152011-09-18 23:09:52 -07001058static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp)
Jesse Barnes5d613502011-01-24 17:10:54 -08001059{
1060 struct drm_device *dev = intel_dp->base.base.dev;
1061 struct drm_i915_private *dev_priv = dev->dev_private;
1062 u32 pp;
1063
Keith Packardbd943152011-09-18 23:09:52 -07001064 if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) {
Keith Packard832dd3c2011-11-01 19:34:06 -07001065 pp = ironlake_get_pp_control(dev_priv);
Keith Packardbd943152011-09-18 23:09:52 -07001066 pp &= ~EDP_FORCE_VDD;
1067 I915_WRITE(PCH_PP_CONTROL, pp);
1068 POSTING_READ(PCH_PP_CONTROL);
Jesse Barnes5d613502011-01-24 17:10:54 -08001069
Keith Packardbd943152011-09-18 23:09:52 -07001070 /* Make sure sequencer is idle before allowing subsequent activity */
1071 DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n",
1072 I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL));
Keith Packard99ea7122011-11-01 19:57:50 -07001073
1074 msleep(intel_dp->panel_power_down_delay);
Keith Packardbd943152011-09-18 23:09:52 -07001075 }
1076}
1077
1078static void ironlake_panel_vdd_work(struct work_struct *__work)
1079{
1080 struct intel_dp *intel_dp = container_of(to_delayed_work(__work),
1081 struct intel_dp, panel_vdd_work);
1082 struct drm_device *dev = intel_dp->base.base.dev;
1083
Keith Packard627f7672011-10-31 11:30:10 -07001084 mutex_lock(&dev->mode_config.mutex);
Keith Packardbd943152011-09-18 23:09:52 -07001085 ironlake_panel_vdd_off_sync(intel_dp);
Keith Packard627f7672011-10-31 11:30:10 -07001086 mutex_unlock(&dev->mode_config.mutex);
Keith Packardbd943152011-09-18 23:09:52 -07001087}
1088
1089static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
1090{
Keith Packard97af61f572011-09-28 16:23:51 -07001091 if (!is_edp(intel_dp))
1092 return;
Jesse Barnes5d613502011-01-24 17:10:54 -08001093
Keith Packardbd943152011-09-18 23:09:52 -07001094 DRM_DEBUG_KMS("Turn eDP VDD off %d\n", intel_dp->want_panel_vdd);
1095 WARN(!intel_dp->want_panel_vdd, "eDP VDD not forced on");
Keith Packardf2e8b182011-11-01 20:01:35 -07001096
Keith Packardbd943152011-09-18 23:09:52 -07001097 intel_dp->want_panel_vdd = false;
1098
1099 if (sync) {
1100 ironlake_panel_vdd_off_sync(intel_dp);
1101 } else {
1102 /*
1103 * Queue the timer to fire a long
1104 * time from now (relative to the power down delay)
1105 * to keep the panel power up across a sequence of operations
1106 */
1107 schedule_delayed_work(&intel_dp->panel_vdd_work,
1108 msecs_to_jiffies(intel_dp->panel_power_cycle_delay * 5));
1109 }
Jesse Barnes5d613502011-01-24 17:10:54 -08001110}
1111
Keith Packard86a30732011-10-20 13:40:33 -07001112static void ironlake_edp_panel_on(struct intel_dp *intel_dp)
Jesse Barnes9934c132010-07-22 13:18:19 -07001113{
Jesse Barnes01cb9ea2010-10-07 16:01:12 -07001114 struct drm_device *dev = intel_dp->base.base.dev;
Jesse Barnes9934c132010-07-22 13:18:19 -07001115 struct drm_i915_private *dev_priv = dev->dev_private;
Keith Packard99ea7122011-11-01 19:57:50 -07001116 u32 pp;
Jesse Barnes9934c132010-07-22 13:18:19 -07001117
Keith Packard97af61f572011-09-28 16:23:51 -07001118 if (!is_edp(intel_dp))
Keith Packardbd943152011-09-18 23:09:52 -07001119 return;
Keith Packard99ea7122011-11-01 19:57:50 -07001120
1121 DRM_DEBUG_KMS("Turn eDP power on\n");
1122
1123 if (ironlake_edp_have_panel_power(intel_dp)) {
1124 DRM_DEBUG_KMS("eDP power already on\n");
Keith Packard7d639f32011-09-29 16:05:34 -07001125 return;
Keith Packard99ea7122011-11-01 19:57:50 -07001126 }
Jesse Barnes9934c132010-07-22 13:18:19 -07001127
Keith Packard99ea7122011-11-01 19:57:50 -07001128 ironlake_wait_panel_power_cycle(intel_dp);
Jesse Barnes37c6c9b2010-08-11 10:04:43 -07001129
Keith Packard832dd3c2011-11-01 19:34:06 -07001130 pp = ironlake_get_pp_control(dev_priv);
Keith Packard05ce1a42011-09-29 16:33:01 -07001131 if (IS_GEN5(dev)) {
1132 /* ILK workaround: disable reset around power sequence */
1133 pp &= ~PANEL_POWER_RESET;
1134 I915_WRITE(PCH_PP_CONTROL, pp);
1135 POSTING_READ(PCH_PP_CONTROL);
1136 }
Jesse Barnes37c6c9b2010-08-11 10:04:43 -07001137
Keith Packard1c0ae802011-09-19 13:59:29 -07001138 pp |= POWER_TARGET_ON;
Keith Packard99ea7122011-11-01 19:57:50 -07001139 if (!IS_GEN5(dev))
1140 pp |= PANEL_POWER_RESET;
1141
Jesse Barnes9934c132010-07-22 13:18:19 -07001142 I915_WRITE(PCH_PP_CONTROL, pp);
Jesse Barnes01cb9ea2010-10-07 16:01:12 -07001143 POSTING_READ(PCH_PP_CONTROL);
Jesse Barnes9934c132010-07-22 13:18:19 -07001144
Keith Packard99ea7122011-11-01 19:57:50 -07001145 ironlake_wait_panel_on(intel_dp);
Jesse Barnes9934c132010-07-22 13:18:19 -07001146
Keith Packard05ce1a42011-09-29 16:33:01 -07001147 if (IS_GEN5(dev)) {
1148 pp |= PANEL_POWER_RESET; /* restore panel reset bit */
1149 I915_WRITE(PCH_PP_CONTROL, pp);
1150 POSTING_READ(PCH_PP_CONTROL);
1151 }
Jesse Barnes9934c132010-07-22 13:18:19 -07001152}
1153
Keith Packard99ea7122011-11-01 19:57:50 -07001154static void ironlake_edp_panel_off(struct intel_dp *intel_dp)
Jesse Barnes9934c132010-07-22 13:18:19 -07001155{
Keith Packard99ea7122011-11-01 19:57:50 -07001156 struct drm_device *dev = intel_dp->base.base.dev;
Jesse Barnes9934c132010-07-22 13:18:19 -07001157 struct drm_i915_private *dev_priv = dev->dev_private;
Keith Packard99ea7122011-11-01 19:57:50 -07001158 u32 pp;
Jesse Barnes9934c132010-07-22 13:18:19 -07001159
Keith Packard97af61f572011-09-28 16:23:51 -07001160 if (!is_edp(intel_dp))
1161 return;
Jesse Barnes37c6c9b2010-08-11 10:04:43 -07001162
Keith Packard99ea7122011-11-01 19:57:50 -07001163 DRM_DEBUG_KMS("Turn eDP power off\n");
Jesse Barnes37c6c9b2010-08-11 10:04:43 -07001164
Daniel Vetter6cb49832012-05-20 17:14:50 +02001165 WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");
Jesse Barnes9934c132010-07-22 13:18:19 -07001166
Keith Packard832dd3c2011-11-01 19:34:06 -07001167 pp = ironlake_get_pp_control(dev_priv);
Daniel Vetter35a38552012-08-12 22:17:14 +02001168 /* We need to switch off panel power _and_ force vdd, for otherwise some
1169 * panels get very unhappy and cease to work. */
1170 pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
Keith Packard99ea7122011-11-01 19:57:50 -07001171 I915_WRITE(PCH_PP_CONTROL, pp);
1172 POSTING_READ(PCH_PP_CONTROL);
Jesse Barnes9934c132010-07-22 13:18:19 -07001173
Daniel Vetter35a38552012-08-12 22:17:14 +02001174 intel_dp->want_panel_vdd = false;
1175
Keith Packard99ea7122011-11-01 19:57:50 -07001176 ironlake_wait_panel_off(intel_dp);
Jesse Barnes9934c132010-07-22 13:18:19 -07001177}
1178
Keith Packard86a30732011-10-20 13:40:33 -07001179static void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
Zhenyu Wang32f9d652009-07-24 01:00:32 +08001180{
Keith Packardf01eca22011-09-28 16:48:10 -07001181 struct drm_device *dev = intel_dp->base.base.dev;
Zhenyu Wang32f9d652009-07-24 01:00:32 +08001182 struct drm_i915_private *dev_priv = dev->dev_private;
1183 u32 pp;
1184
Keith Packardf01eca22011-09-28 16:48:10 -07001185 if (!is_edp(intel_dp))
1186 return;
1187
Zhao Yakui28c97732009-10-09 11:39:41 +08001188 DRM_DEBUG_KMS("\n");
Jesse Barnes01cb9ea2010-10-07 16:01:12 -07001189 /*
1190 * If we enable the backlight right away following a panel power
1191 * on, we may see slight flicker as the panel syncs with the eDP
1192 * link. So delay a bit to make sure the image is solid before
1193 * allowing it to appear.
1194 */
Keith Packardf01eca22011-09-28 16:48:10 -07001195 msleep(intel_dp->backlight_on_delay);
Keith Packard832dd3c2011-11-01 19:34:06 -07001196 pp = ironlake_get_pp_control(dev_priv);
Zhenyu Wang32f9d652009-07-24 01:00:32 +08001197 pp |= EDP_BLC_ENABLE;
1198 I915_WRITE(PCH_PP_CONTROL, pp);
Keith Packardf01eca22011-09-28 16:48:10 -07001199 POSTING_READ(PCH_PP_CONTROL);
Zhenyu Wang32f9d652009-07-24 01:00:32 +08001200}
1201
Keith Packard86a30732011-10-20 13:40:33 -07001202static void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
Zhenyu Wang32f9d652009-07-24 01:00:32 +08001203{
Keith Packardf01eca22011-09-28 16:48:10 -07001204 struct drm_device *dev = intel_dp->base.base.dev;
Zhenyu Wang32f9d652009-07-24 01:00:32 +08001205 struct drm_i915_private *dev_priv = dev->dev_private;
1206 u32 pp;
1207
Keith Packardf01eca22011-09-28 16:48:10 -07001208 if (!is_edp(intel_dp))
1209 return;
1210
Zhao Yakui28c97732009-10-09 11:39:41 +08001211 DRM_DEBUG_KMS("\n");
Keith Packard832dd3c2011-11-01 19:34:06 -07001212 pp = ironlake_get_pp_control(dev_priv);
Zhenyu Wang32f9d652009-07-24 01:00:32 +08001213 pp &= ~EDP_BLC_ENABLE;
1214 I915_WRITE(PCH_PP_CONTROL, pp);
Keith Packardf01eca22011-09-28 16:48:10 -07001215 POSTING_READ(PCH_PP_CONTROL);
1216 msleep(intel_dp->backlight_off_delay);
Zhenyu Wang32f9d652009-07-24 01:00:32 +08001217}
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001218
Daniel Vetter2bd2ad62012-09-06 22:15:41 +02001219static void ironlake_edp_pll_on(struct intel_dp *intel_dp)
Jesse Barnesd240f202010-08-13 15:43:26 -07001220{
Daniel Vetter2bd2ad62012-09-06 22:15:41 +02001221 struct drm_device *dev = intel_dp->base.base.dev;
1222 struct drm_crtc *crtc = intel_dp->base.base.crtc;
Jesse Barnesd240f202010-08-13 15:43:26 -07001223 struct drm_i915_private *dev_priv = dev->dev_private;
1224 u32 dpa_ctl;
1225
Daniel Vetter2bd2ad62012-09-06 22:15:41 +02001226 assert_pipe_disabled(dev_priv,
1227 to_intel_crtc(crtc)->pipe);
1228
Jesse Barnesd240f202010-08-13 15:43:26 -07001229 DRM_DEBUG_KMS("\n");
1230 dpa_ctl = I915_READ(DP_A);
Daniel Vetter07679352012-09-06 22:15:42 +02001231 WARN(dpa_ctl & DP_PLL_ENABLE, "dp pll on, should be off\n");
1232 WARN(dpa_ctl & DP_PORT_EN, "dp port still on, should be off\n");
1233
1234 /* We don't adjust intel_dp->DP while tearing down the link, to
1235 * facilitate link retraining (e.g. after hotplug). Hence clear all
1236 * enable bits here to ensure that we don't enable too much. */
1237 intel_dp->DP &= ~(DP_PORT_EN | DP_AUDIO_OUTPUT_ENABLE);
1238 intel_dp->DP |= DP_PLL_ENABLE;
1239 I915_WRITE(DP_A, intel_dp->DP);
Jesse Barnes298b0b32010-10-07 16:01:24 -07001240 POSTING_READ(DP_A);
1241 udelay(200);
Jesse Barnesd240f202010-08-13 15:43:26 -07001242}
1243
Daniel Vetter2bd2ad62012-09-06 22:15:41 +02001244static void ironlake_edp_pll_off(struct intel_dp *intel_dp)
Jesse Barnesd240f202010-08-13 15:43:26 -07001245{
Daniel Vetter2bd2ad62012-09-06 22:15:41 +02001246 struct drm_device *dev = intel_dp->base.base.dev;
1247 struct drm_crtc *crtc = intel_dp->base.base.crtc;
Jesse Barnesd240f202010-08-13 15:43:26 -07001248 struct drm_i915_private *dev_priv = dev->dev_private;
1249 u32 dpa_ctl;
1250
Daniel Vetter2bd2ad62012-09-06 22:15:41 +02001251 assert_pipe_disabled(dev_priv,
1252 to_intel_crtc(crtc)->pipe);
1253
Jesse Barnesd240f202010-08-13 15:43:26 -07001254 dpa_ctl = I915_READ(DP_A);
Daniel Vetter07679352012-09-06 22:15:42 +02001255 WARN((dpa_ctl & DP_PLL_ENABLE) == 0,
1256 "dp pll off, should be on\n");
1257 WARN(dpa_ctl & DP_PORT_EN, "dp port still on, should be off\n");
1258
1259 /* We can't rely on the value tracked for the DP register in
1260 * intel_dp->DP because link_down must not change that (otherwise link
1261 * re-training will fail. */
Jesse Barnes298b0b32010-10-07 16:01:24 -07001262 dpa_ctl &= ~DP_PLL_ENABLE;
Jesse Barnesd240f202010-08-13 15:43:26 -07001263 I915_WRITE(DP_A, dpa_ctl);
Chris Wilson1af5fa12010-09-08 21:07:28 +01001264 POSTING_READ(DP_A);
Jesse Barnesd240f202010-08-13 15:43:26 -07001265 udelay(200);
1266}
1267
Jesse Barnesc7ad3812011-07-07 11:11:03 -07001268/* If the sink supports it, try to set the power state appropriately */
Paulo Zanonic19b0662012-10-15 15:51:41 -03001269void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
Jesse Barnesc7ad3812011-07-07 11:11:03 -07001270{
1271 int ret, i;
1272
1273 /* Should have a valid DPCD by this point */
1274 if (intel_dp->dpcd[DP_DPCD_REV] < 0x11)
1275 return;
1276
1277 if (mode != DRM_MODE_DPMS_ON) {
1278 ret = intel_dp_aux_native_write_1(intel_dp, DP_SET_POWER,
1279 DP_SET_POWER_D3);
1280 if (ret != 1)
1281 DRM_DEBUG_DRIVER("failed to write sink power state\n");
1282 } else {
1283 /*
1284 * When turning on, we need to retry for 1ms to give the sink
1285 * time to wake up.
1286 */
1287 for (i = 0; i < 3; i++) {
1288 ret = intel_dp_aux_native_write_1(intel_dp,
1289 DP_SET_POWER,
1290 DP_SET_POWER_D0);
1291 if (ret == 1)
1292 break;
1293 msleep(1);
1294 }
1295 }
1296}
1297
Daniel Vetter19d8fe12012-07-02 13:26:27 +02001298static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
1299 enum pipe *pipe)
Jesse Barnesd240f202010-08-13 15:43:26 -07001300{
Daniel Vetter19d8fe12012-07-02 13:26:27 +02001301 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
1302 struct drm_device *dev = encoder->base.dev;
1303 struct drm_i915_private *dev_priv = dev->dev_private;
1304 u32 tmp = I915_READ(intel_dp->output_reg);
Jesse Barnesd240f202010-08-13 15:43:26 -07001305
Daniel Vetter19d8fe12012-07-02 13:26:27 +02001306 if (!(tmp & DP_PORT_EN))
1307 return false;
1308
1309 if (is_cpu_edp(intel_dp) && IS_GEN7(dev)) {
1310 *pipe = PORT_TO_PIPE_CPT(tmp);
1311 } else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) {
1312 *pipe = PORT_TO_PIPE(tmp);
1313 } else {
1314 u32 trans_sel;
1315 u32 trans_dp;
1316 int i;
1317
1318 switch (intel_dp->output_reg) {
1319 case PCH_DP_B:
1320 trans_sel = TRANS_DP_PORT_SEL_B;
1321 break;
1322 case PCH_DP_C:
1323 trans_sel = TRANS_DP_PORT_SEL_C;
1324 break;
1325 case PCH_DP_D:
1326 trans_sel = TRANS_DP_PORT_SEL_D;
1327 break;
1328 default:
1329 return true;
1330 }
1331
1332 for_each_pipe(i) {
1333 trans_dp = I915_READ(TRANS_DP_CTL(i));
1334 if ((trans_dp & TRANS_DP_PORT_SEL_MASK) == trans_sel) {
1335 *pipe = i;
1336 return true;
1337 }
1338 }
1339 }
1340
1341 DRM_DEBUG_KMS("No pipe for dp port 0x%x found\n", intel_dp->output_reg);
1342
1343 return true;
1344}
1345
Daniel Vettere8cb4552012-07-01 13:05:48 +02001346static void intel_disable_dp(struct intel_encoder *encoder)
Jesse Barnesd240f202010-08-13 15:43:26 -07001347{
Daniel Vettere8cb4552012-07-01 13:05:48 +02001348 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
Daniel Vetter6cb49832012-05-20 17:14:50 +02001349
1350 /* Make sure the panel is off before trying to change the mode. But also
1351 * ensure that we have vdd while we switch off the panel. */
1352 ironlake_edp_panel_vdd_on(intel_dp);
Keith Packard21264c62011-11-01 20:25:21 -07001353 ironlake_edp_backlight_off(intel_dp);
Jesse Barnesc7ad3812011-07-07 11:11:03 -07001354 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
Daniel Vetter35a38552012-08-12 22:17:14 +02001355 ironlake_edp_panel_off(intel_dp);
Daniel Vetter37398502012-09-06 22:15:44 +02001356
1357 /* cpu edp my only be disable _after_ the cpu pipe/plane is disabled. */
1358 if (!is_cpu_edp(intel_dp))
1359 intel_dp_link_down(intel_dp);
Jesse Barnesd240f202010-08-13 15:43:26 -07001360}
1361
Daniel Vetter2bd2ad62012-09-06 22:15:41 +02001362static void intel_post_disable_dp(struct intel_encoder *encoder)
1363{
1364 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
1365
Daniel Vetter37398502012-09-06 22:15:44 +02001366 if (is_cpu_edp(intel_dp)) {
1367 intel_dp_link_down(intel_dp);
Daniel Vetter2bd2ad62012-09-06 22:15:41 +02001368 ironlake_edp_pll_off(intel_dp);
Daniel Vetter37398502012-09-06 22:15:44 +02001369 }
Daniel Vetter2bd2ad62012-09-06 22:15:41 +02001370}
1371
Daniel Vettere8cb4552012-07-01 13:05:48 +02001372static void intel_enable_dp(struct intel_encoder *encoder)
Jesse Barnesd240f202010-08-13 15:43:26 -07001373{
Daniel Vettere8cb4552012-07-01 13:05:48 +02001374 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
1375 struct drm_device *dev = encoder->base.dev;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001376 struct drm_i915_private *dev_priv = dev->dev_private;
Chris Wilsonea5b2132010-08-04 13:50:23 +01001377 uint32_t dp_reg = I915_READ(intel_dp->output_reg);
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001378
Daniel Vetter0c33d8d2012-09-06 22:15:43 +02001379 if (WARN_ON(dp_reg & DP_PORT_EN))
1380 return;
1381
Daniel Vettere8cb4552012-07-01 13:05:48 +02001382 ironlake_edp_panel_vdd_on(intel_dp);
1383 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
Daniel Vetter0c33d8d2012-09-06 22:15:43 +02001384 intel_dp_start_link_train(intel_dp);
1385 ironlake_edp_panel_on(intel_dp);
1386 ironlake_edp_panel_vdd_off(intel_dp, true);
1387 intel_dp_complete_link_train(intel_dp);
Daniel Vettere8cb4552012-07-01 13:05:48 +02001388 ironlake_edp_backlight_on(intel_dp);
Daniel Vettere8cb4552012-07-01 13:05:48 +02001389}
1390
Daniel Vetter2bd2ad62012-09-06 22:15:41 +02001391static void intel_pre_enable_dp(struct intel_encoder *encoder)
Daniel Vettere8cb4552012-07-01 13:05:48 +02001392{
Daniel Vetter2bd2ad62012-09-06 22:15:41 +02001393 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
Daniel Vettere8cb4552012-07-01 13:05:48 +02001394
Daniel Vetter2bd2ad62012-09-06 22:15:41 +02001395 if (is_cpu_edp(intel_dp))
1396 ironlake_edp_pll_on(intel_dp);
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001397}
1398
1399/*
Jesse Barnesdf0c2372011-07-07 11:11:02 -07001400 * Native read with retry for link status and receiver capability reads for
1401 * cases where the sink may still be asleep.
1402 */
1403static bool
1404intel_dp_aux_native_read_retry(struct intel_dp *intel_dp, uint16_t address,
1405 uint8_t *recv, int recv_bytes)
1406{
1407 int ret, i;
1408
1409 /*
1410 * Sinks are *supposed* to come up within 1ms from an off state,
1411 * but we're also supposed to retry 3 times per the spec.
1412 */
1413 for (i = 0; i < 3; i++) {
1414 ret = intel_dp_aux_native_read(intel_dp, address, recv,
1415 recv_bytes);
1416 if (ret == recv_bytes)
1417 return true;
1418 msleep(1);
1419 }
1420
1421 return false;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001422}
1423
1424/*
1425 * Fetch AUX CH registers 0x202 - 0x207 which contain
1426 * link status information
1427 */
1428static bool
Keith Packard93f62da2011-11-01 19:45:03 -07001429intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001430{
Jesse Barnesdf0c2372011-07-07 11:11:02 -07001431 return intel_dp_aux_native_read_retry(intel_dp,
1432 DP_LANE0_1_STATUS,
Keith Packard93f62da2011-11-01 19:45:03 -07001433 link_status,
Jesse Barnesdf0c2372011-07-07 11:11:02 -07001434 DP_LINK_STATUS_SIZE);
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001435}
1436
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001437#if 0
1438static char *voltage_names[] = {
1439 "0.4V", "0.6V", "0.8V", "1.2V"
1440};
1441static char *pre_emph_names[] = {
1442 "0dB", "3.5dB", "6dB", "9.5dB"
1443};
1444static char *link_train_names[] = {
1445 "pattern 1", "pattern 2", "idle", "off"
1446};
1447#endif
1448
1449/*
1450 * These are source-specific values; current Intel hardware supports
1451 * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB
1452 */
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001453
1454static uint8_t
Keith Packard1a2eb462011-11-16 16:26:07 -08001455intel_dp_voltage_max(struct intel_dp *intel_dp)
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001456{
Keith Packard1a2eb462011-11-16 16:26:07 -08001457 struct drm_device *dev = intel_dp->base.base.dev;
1458
1459 if (IS_GEN7(dev) && is_cpu_edp(intel_dp))
1460 return DP_TRAIN_VOLTAGE_SWING_800;
1461 else if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
1462 return DP_TRAIN_VOLTAGE_SWING_1200;
1463 else
1464 return DP_TRAIN_VOLTAGE_SWING_800;
1465}
1466
1467static uint8_t
1468intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
1469{
1470 struct drm_device *dev = intel_dp->base.base.dev;
1471
Paulo Zanonid6c0d722012-10-15 15:51:34 -03001472 if (IS_HASWELL(dev)) {
1473 switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
1474 case DP_TRAIN_VOLTAGE_SWING_400:
1475 return DP_TRAIN_PRE_EMPHASIS_9_5;
1476 case DP_TRAIN_VOLTAGE_SWING_600:
1477 return DP_TRAIN_PRE_EMPHASIS_6;
1478 case DP_TRAIN_VOLTAGE_SWING_800:
1479 return DP_TRAIN_PRE_EMPHASIS_3_5;
1480 case DP_TRAIN_VOLTAGE_SWING_1200:
1481 default:
1482 return DP_TRAIN_PRE_EMPHASIS_0;
1483 }
1484 } else if (IS_GEN7(dev) && is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) {
Keith Packard1a2eb462011-11-16 16:26:07 -08001485 switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
1486 case DP_TRAIN_VOLTAGE_SWING_400:
1487 return DP_TRAIN_PRE_EMPHASIS_6;
1488 case DP_TRAIN_VOLTAGE_SWING_600:
1489 case DP_TRAIN_VOLTAGE_SWING_800:
1490 return DP_TRAIN_PRE_EMPHASIS_3_5;
1491 default:
1492 return DP_TRAIN_PRE_EMPHASIS_0;
1493 }
1494 } else {
1495 switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
1496 case DP_TRAIN_VOLTAGE_SWING_400:
1497 return DP_TRAIN_PRE_EMPHASIS_6;
1498 case DP_TRAIN_VOLTAGE_SWING_600:
1499 return DP_TRAIN_PRE_EMPHASIS_6;
1500 case DP_TRAIN_VOLTAGE_SWING_800:
1501 return DP_TRAIN_PRE_EMPHASIS_3_5;
1502 case DP_TRAIN_VOLTAGE_SWING_1200:
1503 default:
1504 return DP_TRAIN_PRE_EMPHASIS_0;
1505 }
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001506 }
1507}
1508
1509static void
Keith Packard93f62da2011-11-01 19:45:03 -07001510intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001511{
1512 uint8_t v = 0;
1513 uint8_t p = 0;
1514 int lane;
Keith Packard1a2eb462011-11-16 16:26:07 -08001515 uint8_t voltage_max;
1516 uint8_t preemph_max;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001517
Jesse Barnes33a34e42010-09-08 12:42:02 -07001518 for (lane = 0; lane < intel_dp->lane_count; lane++) {
Daniel Vetter0f037bd2012-10-18 10:15:27 +02001519 uint8_t this_v = drm_dp_get_adjust_request_voltage(link_status, lane);
1520 uint8_t this_p = drm_dp_get_adjust_request_pre_emphasis(link_status, lane);
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001521
1522 if (this_v > v)
1523 v = this_v;
1524 if (this_p > p)
1525 p = this_p;
1526 }
1527
Keith Packard1a2eb462011-11-16 16:26:07 -08001528 voltage_max = intel_dp_voltage_max(intel_dp);
Keith Packard417e8222011-11-01 19:54:11 -07001529 if (v >= voltage_max)
1530 v = voltage_max | DP_TRAIN_MAX_SWING_REACHED;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001531
Keith Packard1a2eb462011-11-16 16:26:07 -08001532 preemph_max = intel_dp_pre_emphasis_max(intel_dp, v);
1533 if (p >= preemph_max)
1534 p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001535
1536 for (lane = 0; lane < 4; lane++)
Jesse Barnes33a34e42010-09-08 12:42:02 -07001537 intel_dp->train_set[lane] = v | p;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001538}
1539
1540static uint32_t
Keith Packard93f62da2011-11-01 19:45:03 -07001541intel_dp_signal_levels(uint8_t train_set)
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001542{
Chris Wilson3cf2efb2010-11-29 10:09:55 +00001543 uint32_t signal_levels = 0;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001544
Chris Wilson3cf2efb2010-11-29 10:09:55 +00001545 switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001546 case DP_TRAIN_VOLTAGE_SWING_400:
1547 default:
1548 signal_levels |= DP_VOLTAGE_0_4;
1549 break;
1550 case DP_TRAIN_VOLTAGE_SWING_600:
1551 signal_levels |= DP_VOLTAGE_0_6;
1552 break;
1553 case DP_TRAIN_VOLTAGE_SWING_800:
1554 signal_levels |= DP_VOLTAGE_0_8;
1555 break;
1556 case DP_TRAIN_VOLTAGE_SWING_1200:
1557 signal_levels |= DP_VOLTAGE_1_2;
1558 break;
1559 }
Chris Wilson3cf2efb2010-11-29 10:09:55 +00001560 switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001561 case DP_TRAIN_PRE_EMPHASIS_0:
1562 default:
1563 signal_levels |= DP_PRE_EMPHASIS_0;
1564 break;
1565 case DP_TRAIN_PRE_EMPHASIS_3_5:
1566 signal_levels |= DP_PRE_EMPHASIS_3_5;
1567 break;
1568 case DP_TRAIN_PRE_EMPHASIS_6:
1569 signal_levels |= DP_PRE_EMPHASIS_6;
1570 break;
1571 case DP_TRAIN_PRE_EMPHASIS_9_5:
1572 signal_levels |= DP_PRE_EMPHASIS_9_5;
1573 break;
1574 }
1575 return signal_levels;
1576}
1577
Zhenyu Wange3421a12010-04-08 09:43:27 +08001578/* Gen6's DP voltage swing and pre-emphasis control */
1579static uint32_t
1580intel_gen6_edp_signal_levels(uint8_t train_set)
1581{
Yuanhan Liu3c5a62b2011-01-06 18:26:08 +08001582 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
1583 DP_TRAIN_PRE_EMPHASIS_MASK);
1584 switch (signal_levels) {
Zhenyu Wange3421a12010-04-08 09:43:27 +08001585 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0:
Yuanhan Liu3c5a62b2011-01-06 18:26:08 +08001586 case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_0:
1587 return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
1588 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_3_5:
1589 return EDP_LINK_TRAIN_400MV_3_5DB_SNB_B;
Zhenyu Wange3421a12010-04-08 09:43:27 +08001590 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6:
Yuanhan Liu3c5a62b2011-01-06 18:26:08 +08001591 case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_6:
1592 return EDP_LINK_TRAIN_400_600MV_6DB_SNB_B;
Zhenyu Wange3421a12010-04-08 09:43:27 +08001593 case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5:
Yuanhan Liu3c5a62b2011-01-06 18:26:08 +08001594 case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_3_5:
1595 return EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B;
Zhenyu Wange3421a12010-04-08 09:43:27 +08001596 case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0:
Yuanhan Liu3c5a62b2011-01-06 18:26:08 +08001597 case DP_TRAIN_VOLTAGE_SWING_1200 | DP_TRAIN_PRE_EMPHASIS_0:
1598 return EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B;
Zhenyu Wange3421a12010-04-08 09:43:27 +08001599 default:
Yuanhan Liu3c5a62b2011-01-06 18:26:08 +08001600 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
1601 "0x%x\n", signal_levels);
1602 return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
Zhenyu Wange3421a12010-04-08 09:43:27 +08001603 }
1604}
1605
Keith Packard1a2eb462011-11-16 16:26:07 -08001606/* Gen7's DP voltage swing and pre-emphasis control */
1607static uint32_t
1608intel_gen7_edp_signal_levels(uint8_t train_set)
1609{
1610 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
1611 DP_TRAIN_PRE_EMPHASIS_MASK);
1612 switch (signal_levels) {
1613 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0:
1614 return EDP_LINK_TRAIN_400MV_0DB_IVB;
1615 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_3_5:
1616 return EDP_LINK_TRAIN_400MV_3_5DB_IVB;
1617 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6:
1618 return EDP_LINK_TRAIN_400MV_6DB_IVB;
1619
1620 case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_0:
1621 return EDP_LINK_TRAIN_600MV_0DB_IVB;
1622 case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5:
1623 return EDP_LINK_TRAIN_600MV_3_5DB_IVB;
1624
1625 case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0:
1626 return EDP_LINK_TRAIN_800MV_0DB_IVB;
1627 case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_3_5:
1628 return EDP_LINK_TRAIN_800MV_3_5DB_IVB;
1629
1630 default:
1631 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
1632 "0x%x\n", signal_levels);
1633 return EDP_LINK_TRAIN_500MV_0DB_IVB;
1634 }
1635}
1636
Paulo Zanonid6c0d722012-10-15 15:51:34 -03001637/* Gen7.5's (HSW) DP voltage swing and pre-emphasis control */
1638static uint32_t
1639intel_dp_signal_levels_hsw(uint8_t train_set)
1640{
1641 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
1642 DP_TRAIN_PRE_EMPHASIS_MASK);
1643 switch (signal_levels) {
1644 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0:
1645 return DDI_BUF_EMP_400MV_0DB_HSW;
1646 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_3_5:
1647 return DDI_BUF_EMP_400MV_3_5DB_HSW;
1648 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6:
1649 return DDI_BUF_EMP_400MV_6DB_HSW;
1650 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_9_5:
1651 return DDI_BUF_EMP_400MV_9_5DB_HSW;
1652
1653 case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_0:
1654 return DDI_BUF_EMP_600MV_0DB_HSW;
1655 case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5:
1656 return DDI_BUF_EMP_600MV_3_5DB_HSW;
1657 case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_6:
1658 return DDI_BUF_EMP_600MV_6DB_HSW;
1659
1660 case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0:
1661 return DDI_BUF_EMP_800MV_0DB_HSW;
1662 case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_3_5:
1663 return DDI_BUF_EMP_800MV_3_5DB_HSW;
1664 default:
1665 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
1666 "0x%x\n", signal_levels);
1667 return DDI_BUF_EMP_400MV_0DB_HSW;
1668 }
1669}
1670
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001671static bool
Chris Wilsonea5b2132010-08-04 13:50:23 +01001672intel_dp_set_link_train(struct intel_dp *intel_dp,
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001673 uint32_t dp_reg_value,
Chris Wilson58e10eb2010-10-03 10:56:11 +01001674 uint8_t dp_train_pat)
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001675{
Chris Wilson4ef69c72010-09-09 15:14:28 +01001676 struct drm_device *dev = intel_dp->base.base.dev;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001677 struct drm_i915_private *dev_priv = dev->dev_private;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001678 int ret;
Paulo Zanonid6c0d722012-10-15 15:51:34 -03001679 uint32_t temp;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001680
Paulo Zanonid6c0d722012-10-15 15:51:34 -03001681 if (IS_HASWELL(dev)) {
1682 temp = I915_READ(DP_TP_CTL(intel_dp->port));
1683
1684 if (dp_train_pat & DP_LINK_SCRAMBLING_DISABLE)
1685 temp |= DP_TP_CTL_SCRAMBLE_DISABLE;
1686 else
1687 temp &= ~DP_TP_CTL_SCRAMBLE_DISABLE;
1688
1689 temp &= ~DP_TP_CTL_LINK_TRAIN_MASK;
1690 switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
1691 case DP_TRAINING_PATTERN_DISABLE:
1692 temp |= DP_TP_CTL_LINK_TRAIN_IDLE;
1693 I915_WRITE(DP_TP_CTL(intel_dp->port), temp);
1694
1695 if (wait_for((I915_READ(DP_TP_STATUS(intel_dp->port)) &
1696 DP_TP_STATUS_IDLE_DONE), 1))
1697 DRM_ERROR("Timed out waiting for DP idle patterns\n");
1698
1699 temp &= ~DP_TP_CTL_LINK_TRAIN_MASK;
1700 temp |= DP_TP_CTL_LINK_TRAIN_NORMAL;
1701
1702 break;
1703 case DP_TRAINING_PATTERN_1:
1704 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
1705 break;
1706 case DP_TRAINING_PATTERN_2:
1707 temp |= DP_TP_CTL_LINK_TRAIN_PAT2;
1708 break;
1709 case DP_TRAINING_PATTERN_3:
1710 temp |= DP_TP_CTL_LINK_TRAIN_PAT3;
1711 break;
1712 }
1713 I915_WRITE(DP_TP_CTL(intel_dp->port), temp);
1714
1715 } else if (HAS_PCH_CPT(dev) &&
1716 (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) {
Paulo Zanoni47ea7542012-07-17 16:55:16 -03001717 dp_reg_value &= ~DP_LINK_TRAIN_MASK_CPT;
1718
1719 switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
1720 case DP_TRAINING_PATTERN_DISABLE:
1721 dp_reg_value |= DP_LINK_TRAIN_OFF_CPT;
1722 break;
1723 case DP_TRAINING_PATTERN_1:
1724 dp_reg_value |= DP_LINK_TRAIN_PAT_1_CPT;
1725 break;
1726 case DP_TRAINING_PATTERN_2:
1727 dp_reg_value |= DP_LINK_TRAIN_PAT_2_CPT;
1728 break;
1729 case DP_TRAINING_PATTERN_3:
1730 DRM_ERROR("DP training pattern 3 not supported\n");
1731 dp_reg_value |= DP_LINK_TRAIN_PAT_2_CPT;
1732 break;
1733 }
1734
1735 } else {
1736 dp_reg_value &= ~DP_LINK_TRAIN_MASK;
1737
1738 switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
1739 case DP_TRAINING_PATTERN_DISABLE:
1740 dp_reg_value |= DP_LINK_TRAIN_OFF;
1741 break;
1742 case DP_TRAINING_PATTERN_1:
1743 dp_reg_value |= DP_LINK_TRAIN_PAT_1;
1744 break;
1745 case DP_TRAINING_PATTERN_2:
1746 dp_reg_value |= DP_LINK_TRAIN_PAT_2;
1747 break;
1748 case DP_TRAINING_PATTERN_3:
1749 DRM_ERROR("DP training pattern 3 not supported\n");
1750 dp_reg_value |= DP_LINK_TRAIN_PAT_2;
1751 break;
1752 }
1753 }
1754
Chris Wilsonea5b2132010-08-04 13:50:23 +01001755 I915_WRITE(intel_dp->output_reg, dp_reg_value);
1756 POSTING_READ(intel_dp->output_reg);
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001757
Chris Wilsonea5b2132010-08-04 13:50:23 +01001758 intel_dp_aux_native_write_1(intel_dp,
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001759 DP_TRAINING_PATTERN_SET,
1760 dp_train_pat);
1761
Paulo Zanoni47ea7542012-07-17 16:55:16 -03001762 if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) !=
1763 DP_TRAINING_PATTERN_DISABLE) {
1764 ret = intel_dp_aux_native_write(intel_dp,
1765 DP_TRAINING_LANE0_SET,
1766 intel_dp->train_set,
1767 intel_dp->lane_count);
1768 if (ret != intel_dp->lane_count)
1769 return false;
1770 }
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001771
1772 return true;
1773}
1774
Jesse Barnes33a34e42010-09-08 12:42:02 -07001775/* Enable corresponding port and start training pattern 1 */
Paulo Zanonic19b0662012-10-15 15:51:41 -03001776void
Jesse Barnes33a34e42010-09-08 12:42:02 -07001777intel_dp_start_link_train(struct intel_dp *intel_dp)
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001778{
Paulo Zanonic19b0662012-10-15 15:51:41 -03001779 struct drm_encoder *encoder = &intel_dp->base.base;
1780 struct drm_device *dev = encoder->dev;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001781 int i;
1782 uint8_t voltage;
1783 bool clock_recovery = false;
Keith Packardcdb0e952011-11-01 20:00:06 -07001784 int voltage_tries, loop_tries;
Chris Wilsonea5b2132010-08-04 13:50:23 +01001785 uint32_t DP = intel_dp->DP;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001786
Paulo Zanonic19b0662012-10-15 15:51:41 -03001787 if (IS_HASWELL(dev))
1788 intel_ddi_prepare_link_retrain(encoder);
1789
Chris Wilson3cf2efb2010-11-29 10:09:55 +00001790 /* Write the link configuration data */
1791 intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
1792 intel_dp->link_configuration,
1793 DP_LINK_CONFIGURATION_SIZE);
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001794
1795 DP |= DP_PORT_EN;
Keith Packard1a2eb462011-11-16 16:26:07 -08001796
Jesse Barnes33a34e42010-09-08 12:42:02 -07001797 memset(intel_dp->train_set, 0, 4);
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001798 voltage = 0xff;
Keith Packardcdb0e952011-11-01 20:00:06 -07001799 voltage_tries = 0;
1800 loop_tries = 0;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001801 clock_recovery = false;
1802 for (;;) {
Jesse Barnes33a34e42010-09-08 12:42:02 -07001803 /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
Keith Packard93f62da2011-11-01 19:45:03 -07001804 uint8_t link_status[DP_LINK_STATUS_SIZE];
Zhenyu Wange3421a12010-04-08 09:43:27 +08001805 uint32_t signal_levels;
Keith Packard417e8222011-11-01 19:54:11 -07001806
Paulo Zanonid6c0d722012-10-15 15:51:34 -03001807 if (IS_HASWELL(dev)) {
1808 signal_levels = intel_dp_signal_levels_hsw(
1809 intel_dp->train_set[0]);
1810 DP = (DP & ~DDI_BUF_EMP_MASK) | signal_levels;
1811 } else if (IS_GEN7(dev) && is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) {
Keith Packard1a2eb462011-11-16 16:26:07 -08001812 signal_levels = intel_gen7_edp_signal_levels(intel_dp->train_set[0]);
1813 DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB) | signal_levels;
1814 } else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) {
Jesse Barnes33a34e42010-09-08 12:42:02 -07001815 signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
Zhenyu Wange3421a12010-04-08 09:43:27 +08001816 DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
1817 } else {
Keith Packard93f62da2011-11-01 19:45:03 -07001818 signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]);
Zhenyu Wange3421a12010-04-08 09:43:27 +08001819 DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
1820 }
Paulo Zanonid6c0d722012-10-15 15:51:34 -03001821 DRM_DEBUG_KMS("training pattern 1 signal levels %08x\n",
1822 signal_levels);
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001823
Daniel Vettera7c96552012-10-18 10:15:30 +02001824 /* Set training pattern 1 */
Paulo Zanoni47ea7542012-07-17 16:55:16 -03001825 if (!intel_dp_set_link_train(intel_dp, DP,
Adam Jackson81055852011-07-21 17:48:37 -04001826 DP_TRAINING_PATTERN_1 |
1827 DP_LINK_SCRAMBLING_DISABLE))
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001828 break;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001829
Daniel Vettera7c96552012-10-18 10:15:30 +02001830 drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
Keith Packard93f62da2011-11-01 19:45:03 -07001831 if (!intel_dp_get_link_status(intel_dp, link_status)) {
1832 DRM_ERROR("failed to get link status\n");
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001833 break;
Keith Packard93f62da2011-11-01 19:45:03 -07001834 }
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001835
Daniel Vetter01916272012-10-18 10:15:25 +02001836 if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
Keith Packard93f62da2011-11-01 19:45:03 -07001837 DRM_DEBUG_KMS("clock recovery OK\n");
Chris Wilson3cf2efb2010-11-29 10:09:55 +00001838 clock_recovery = true;
1839 break;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001840 }
Chris Wilson3cf2efb2010-11-29 10:09:55 +00001841
1842 /* Check to see if we've tried the max voltage */
1843 for (i = 0; i < intel_dp->lane_count; i++)
1844 if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
1845 break;
Paulo Zanoni0d710682012-06-29 16:03:34 -03001846 if (i == intel_dp->lane_count && voltage_tries == 5) {
Chris Wilson24773672012-09-26 16:48:30 +01001847 if (++loop_tries == 5) {
Keith Packardcdb0e952011-11-01 20:00:06 -07001848 DRM_DEBUG_KMS("too many full retries, give up\n");
1849 break;
1850 }
1851 memset(intel_dp->train_set, 0, 4);
1852 voltage_tries = 0;
1853 continue;
1854 }
Chris Wilson3cf2efb2010-11-29 10:09:55 +00001855
1856 /* Check to see if we've tried the same voltage 5 times */
Chris Wilson24773672012-09-26 16:48:30 +01001857 if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) != voltage) {
1858 voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
Keith Packardcdb0e952011-11-01 20:00:06 -07001859 voltage_tries = 0;
Chris Wilson24773672012-09-26 16:48:30 +01001860 } else
1861 ++voltage_tries;
Chris Wilson3cf2efb2010-11-29 10:09:55 +00001862
1863 /* Compute new intel_dp->train_set as requested by target */
Keith Packard93f62da2011-11-01 19:45:03 -07001864 intel_get_adjust_train(intel_dp, link_status);
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001865 }
1866
Jesse Barnes33a34e42010-09-08 12:42:02 -07001867 intel_dp->DP = DP;
1868}
1869
Paulo Zanonic19b0662012-10-15 15:51:41 -03001870void
Jesse Barnes33a34e42010-09-08 12:42:02 -07001871intel_dp_complete_link_train(struct intel_dp *intel_dp)
1872{
Chris Wilson4ef69c72010-09-09 15:14:28 +01001873 struct drm_device *dev = intel_dp->base.base.dev;
Jesse Barnes33a34e42010-09-08 12:42:02 -07001874 bool channel_eq = false;
Jesse Barnes37f80972011-01-05 14:45:24 -08001875 int tries, cr_tries;
Jesse Barnes33a34e42010-09-08 12:42:02 -07001876 uint32_t DP = intel_dp->DP;
1877
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001878 /* channel equalization */
1879 tries = 0;
Jesse Barnes37f80972011-01-05 14:45:24 -08001880 cr_tries = 0;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001881 channel_eq = false;
1882 for (;;) {
Jesse Barnes33a34e42010-09-08 12:42:02 -07001883 /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
Zhenyu Wange3421a12010-04-08 09:43:27 +08001884 uint32_t signal_levels;
Keith Packard93f62da2011-11-01 19:45:03 -07001885 uint8_t link_status[DP_LINK_STATUS_SIZE];
Zhenyu Wange3421a12010-04-08 09:43:27 +08001886
Jesse Barnes37f80972011-01-05 14:45:24 -08001887 if (cr_tries > 5) {
1888 DRM_ERROR("failed to train DP, aborting\n");
1889 intel_dp_link_down(intel_dp);
1890 break;
1891 }
1892
Paulo Zanonid6c0d722012-10-15 15:51:34 -03001893 if (IS_HASWELL(dev)) {
1894 signal_levels = intel_dp_signal_levels_hsw(intel_dp->train_set[0]);
1895 DP = (DP & ~DDI_BUF_EMP_MASK) | signal_levels;
1896 } else if (IS_GEN7(dev) && is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) {
Keith Packard1a2eb462011-11-16 16:26:07 -08001897 signal_levels = intel_gen7_edp_signal_levels(intel_dp->train_set[0]);
1898 DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB) | signal_levels;
1899 } else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) {
Jesse Barnes33a34e42010-09-08 12:42:02 -07001900 signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
Zhenyu Wange3421a12010-04-08 09:43:27 +08001901 DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
1902 } else {
Keith Packard93f62da2011-11-01 19:45:03 -07001903 signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]);
Zhenyu Wange3421a12010-04-08 09:43:27 +08001904 DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
1905 }
1906
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001907 /* channel eq pattern */
Paulo Zanoni47ea7542012-07-17 16:55:16 -03001908 if (!intel_dp_set_link_train(intel_dp, DP,
Adam Jackson81055852011-07-21 17:48:37 -04001909 DP_TRAINING_PATTERN_2 |
1910 DP_LINK_SCRAMBLING_DISABLE))
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001911 break;
1912
Daniel Vettera7c96552012-10-18 10:15:30 +02001913 drm_dp_link_train_channel_eq_delay(intel_dp->dpcd);
Keith Packard93f62da2011-11-01 19:45:03 -07001914 if (!intel_dp_get_link_status(intel_dp, link_status))
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001915 break;
Jesse Barnes869184a2010-10-07 16:01:22 -07001916
Jesse Barnes37f80972011-01-05 14:45:24 -08001917 /* Make sure clock is still ok */
Daniel Vetter01916272012-10-18 10:15:25 +02001918 if (!drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
Jesse Barnes37f80972011-01-05 14:45:24 -08001919 intel_dp_start_link_train(intel_dp);
1920 cr_tries++;
1921 continue;
1922 }
1923
Daniel Vetter1ffdff12012-10-18 10:15:24 +02001924 if (drm_dp_channel_eq_ok(link_status, intel_dp->lane_count)) {
Chris Wilson3cf2efb2010-11-29 10:09:55 +00001925 channel_eq = true;
1926 break;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001927 }
Chris Wilson3cf2efb2010-11-29 10:09:55 +00001928
Jesse Barnes37f80972011-01-05 14:45:24 -08001929 /* Try 5 times, then try clock recovery if that fails */
1930 if (tries > 5) {
1931 intel_dp_link_down(intel_dp);
1932 intel_dp_start_link_train(intel_dp);
1933 tries = 0;
1934 cr_tries++;
1935 continue;
1936 }
Chris Wilson3cf2efb2010-11-29 10:09:55 +00001937
1938 /* Compute new intel_dp->train_set as requested by target */
Keith Packard93f62da2011-11-01 19:45:03 -07001939 intel_get_adjust_train(intel_dp, link_status);
Chris Wilson3cf2efb2010-11-29 10:09:55 +00001940 ++tries;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001941 }
Chris Wilson3cf2efb2010-11-29 10:09:55 +00001942
Paulo Zanonid6c0d722012-10-15 15:51:34 -03001943 if (channel_eq)
1944 DRM_DEBUG_KMS("Channel EQ done. DP Training successfull\n");
1945
Paulo Zanoni47ea7542012-07-17 16:55:16 -03001946 intel_dp_set_link_train(intel_dp, DP, DP_TRAINING_PATTERN_DISABLE);
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001947}
1948
1949static void
Chris Wilsonea5b2132010-08-04 13:50:23 +01001950intel_dp_link_down(struct intel_dp *intel_dp)
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001951{
Chris Wilson4ef69c72010-09-09 15:14:28 +01001952 struct drm_device *dev = intel_dp->base.base.dev;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001953 struct drm_i915_private *dev_priv = dev->dev_private;
Chris Wilsonea5b2132010-08-04 13:50:23 +01001954 uint32_t DP = intel_dp->DP;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07001955
Paulo Zanonic19b0662012-10-15 15:51:41 -03001956 /*
1957 * DDI code has a strict mode set sequence and we should try to respect
1958 * it, otherwise we might hang the machine in many different ways. So we
1959 * really should be disabling the port only on a complete crtc_disable
1960 * sequence. This function is just called under two conditions on DDI
1961 * code:
1962 * - Link train failed while doing crtc_enable, and on this case we
1963 * really should respect the mode set sequence and wait for a
1964 * crtc_disable.
1965 * - Someone turned the monitor off and intel_dp_check_link_status
1966 * called us. We don't need to disable the whole port on this case, so
1967 * when someone turns the monitor on again,
1968 * intel_ddi_prepare_link_retrain will take care of redoing the link
1969 * train.
1970 */
1971 if (IS_HASWELL(dev))
1972 return;
1973
Daniel Vetter0c33d8d2012-09-06 22:15:43 +02001974 if (WARN_ON((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0))
Chris Wilson1b39d6f2010-12-06 11:20:45 +00001975 return;
1976
Zhao Yakui28c97732009-10-09 11:39:41 +08001977 DRM_DEBUG_KMS("\n");
Zhenyu Wang32f9d652009-07-24 01:00:32 +08001978
Keith Packard1a2eb462011-11-16 16:26:07 -08001979 if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) {
Zhenyu Wange3421a12010-04-08 09:43:27 +08001980 DP &= ~DP_LINK_TRAIN_MASK_CPT;
Chris Wilsonea5b2132010-08-04 13:50:23 +01001981 I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT);
Zhenyu Wange3421a12010-04-08 09:43:27 +08001982 } else {
1983 DP &= ~DP_LINK_TRAIN_MASK;
Chris Wilsonea5b2132010-08-04 13:50:23 +01001984 I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE);
Zhenyu Wange3421a12010-04-08 09:43:27 +08001985 }
Chris Wilsonfe255d02010-09-11 21:37:48 +01001986 POSTING_READ(intel_dp->output_reg);
Zhenyu Wang5eb08b62009-07-24 01:00:31 +08001987
Chris Wilsonfe255d02010-09-11 21:37:48 +01001988 msleep(17);
Zhenyu Wang5eb08b62009-07-24 01:00:31 +08001989
Daniel Vetter493a7082012-05-30 12:31:56 +02001990 if (HAS_PCH_IBX(dev) &&
Chris Wilson1b39d6f2010-12-06 11:20:45 +00001991 I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
Chris Wilson31acbcc2011-04-17 06:38:35 +01001992 struct drm_crtc *crtc = intel_dp->base.base.crtc;
1993
Eric Anholt5bddd172010-11-18 09:32:59 +08001994 /* Hardware workaround: leaving our transcoder select
1995 * set to transcoder B while it's off will prevent the
1996 * corresponding HDMI output on transcoder A.
1997 *
1998 * Combine this with another hardware workaround:
1999 * transcoder select bit can only be cleared while the
2000 * port is enabled.
2001 */
2002 DP &= ~DP_PIPEB_SELECT;
2003 I915_WRITE(intel_dp->output_reg, DP);
2004
2005 /* Changes to enable or select take place the vblank
2006 * after being written.
2007 */
Chris Wilson31acbcc2011-04-17 06:38:35 +01002008 if (crtc == NULL) {
2009 /* We can arrive here never having been attached
2010 * to a CRTC, for instance, due to inheriting
2011 * random state from the BIOS.
2012 *
2013 * If the pipe is not running, play safe and
2014 * wait for the clocks to stabilise before
2015 * continuing.
2016 */
2017 POSTING_READ(intel_dp->output_reg);
2018 msleep(50);
2019 } else
2020 intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
Eric Anholt5bddd172010-11-18 09:32:59 +08002021 }
2022
Wu Fengguang832afda2011-12-09 20:42:21 +08002023 DP &= ~DP_AUDIO_OUTPUT_ENABLE;
Chris Wilsonea5b2132010-08-04 13:50:23 +01002024 I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
2025 POSTING_READ(intel_dp->output_reg);
Keith Packardf01eca22011-09-28 16:48:10 -07002026 msleep(intel_dp->panel_power_down_delay);
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002027}
2028
Keith Packard26d61aa2011-07-25 20:01:09 -07002029static bool
2030intel_dp_get_dpcd(struct intel_dp *intel_dp)
Keith Packard92fd8fd2011-07-25 19:50:10 -07002031{
Keith Packard92fd8fd2011-07-25 19:50:10 -07002032 if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd,
Adam Jacksonb091cd92012-09-18 10:58:49 -04002033 sizeof(intel_dp->dpcd)) == 0)
2034 return false; /* aux transfer failed */
Keith Packard92fd8fd2011-07-25 19:50:10 -07002035
Adam Jacksonb091cd92012-09-18 10:58:49 -04002036 if (intel_dp->dpcd[DP_DPCD_REV] == 0)
2037 return false; /* DPCD not present */
2038
2039 if (!(intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
2040 DP_DWN_STRM_PORT_PRESENT))
2041 return true; /* native DP sink */
2042
2043 if (intel_dp->dpcd[DP_DPCD_REV] == 0x10)
2044 return true; /* no per-port downstream info */
2045
2046 if (intel_dp_aux_native_read_retry(intel_dp, DP_DOWNSTREAM_PORT_0,
2047 intel_dp->downstream_ports,
2048 DP_MAX_DOWNSTREAM_PORTS) == 0)
2049 return false; /* downstream port status fetch failed */
2050
2051 return true;
Keith Packard92fd8fd2011-07-25 19:50:10 -07002052}
2053
Adam Jackson0d198322012-05-14 16:05:47 -04002054static void
2055intel_dp_probe_oui(struct intel_dp *intel_dp)
2056{
2057 u8 buf[3];
2058
2059 if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
2060 return;
2061
Daniel Vetter351cfc32012-06-12 13:20:47 +02002062 ironlake_edp_panel_vdd_on(intel_dp);
2063
Adam Jackson0d198322012-05-14 16:05:47 -04002064 if (intel_dp_aux_native_read_retry(intel_dp, DP_SINK_OUI, buf, 3))
2065 DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
2066 buf[0], buf[1], buf[2]);
2067
2068 if (intel_dp_aux_native_read_retry(intel_dp, DP_BRANCH_OUI, buf, 3))
2069 DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
2070 buf[0], buf[1], buf[2]);
Daniel Vetter351cfc32012-06-12 13:20:47 +02002071
2072 ironlake_edp_panel_vdd_off(intel_dp, false);
Adam Jackson0d198322012-05-14 16:05:47 -04002073}
2074
Jesse Barnesa60f0e32011-10-20 15:09:17 -07002075static bool
2076intel_dp_get_sink_irq(struct intel_dp *intel_dp, u8 *sink_irq_vector)
2077{
2078 int ret;
2079
2080 ret = intel_dp_aux_native_read_retry(intel_dp,
2081 DP_DEVICE_SERVICE_IRQ_VECTOR,
2082 sink_irq_vector, 1);
2083 if (!ret)
2084 return false;
2085
2086 return true;
2087}
2088
2089static void
2090intel_dp_handle_test_request(struct intel_dp *intel_dp)
2091{
2092 /* NAK by default */
2093 intel_dp_aux_native_write_1(intel_dp, DP_TEST_RESPONSE, DP_TEST_ACK);
2094}
2095
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002096/*
2097 * According to DP spec
2098 * 5.1.2:
2099 * 1. Read DPCD
2100 * 2. Configure link according to Receiver Capabilities
2101 * 3. Use Link Training from 2.5.3.3 and 3.5.1.3
2102 * 4. Check link status on receipt of hot-plug interrupt
2103 */
2104
2105static void
Chris Wilsonea5b2132010-08-04 13:50:23 +01002106intel_dp_check_link_status(struct intel_dp *intel_dp)
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002107{
Jesse Barnesa60f0e32011-10-20 15:09:17 -07002108 u8 sink_irq_vector;
Keith Packard93f62da2011-11-01 19:45:03 -07002109 u8 link_status[DP_LINK_STATUS_SIZE];
Jesse Barnesa60f0e32011-10-20 15:09:17 -07002110
Daniel Vetter24e804b2012-07-26 19:25:46 +02002111 if (!intel_dp->base.connectors_active)
Keith Packardd2b996a2011-07-25 22:37:51 -07002112 return;
Jesse Barnes59cd09e2011-07-07 11:10:59 -07002113
Daniel Vetter24e804b2012-07-26 19:25:46 +02002114 if (WARN_ON(!intel_dp->base.base.crtc))
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002115 return;
2116
Keith Packard92fd8fd2011-07-25 19:50:10 -07002117 /* Try to read receiver status if the link appears to be up */
Keith Packard93f62da2011-11-01 19:45:03 -07002118 if (!intel_dp_get_link_status(intel_dp, link_status)) {
Chris Wilsonea5b2132010-08-04 13:50:23 +01002119 intel_dp_link_down(intel_dp);
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002120 return;
2121 }
2122
Keith Packard92fd8fd2011-07-25 19:50:10 -07002123 /* Now read the DPCD to see if it's actually running */
Keith Packard26d61aa2011-07-25 20:01:09 -07002124 if (!intel_dp_get_dpcd(intel_dp)) {
Jesse Barnes59cd09e2011-07-07 11:10:59 -07002125 intel_dp_link_down(intel_dp);
2126 return;
2127 }
2128
Jesse Barnesa60f0e32011-10-20 15:09:17 -07002129 /* Try to read the source of the interrupt */
2130 if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
2131 intel_dp_get_sink_irq(intel_dp, &sink_irq_vector)) {
2132 /* Clear interrupt source */
2133 intel_dp_aux_native_write_1(intel_dp,
2134 DP_DEVICE_SERVICE_IRQ_VECTOR,
2135 sink_irq_vector);
2136
2137 if (sink_irq_vector & DP_AUTOMATED_TEST_REQUEST)
2138 intel_dp_handle_test_request(intel_dp);
2139 if (sink_irq_vector & (DP_CP_IRQ | DP_SINK_SPECIFIC_IRQ))
2140 DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n");
2141 }
2142
Daniel Vetter1ffdff12012-10-18 10:15:24 +02002143 if (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count)) {
Keith Packard92fd8fd2011-07-25 19:50:10 -07002144 DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
2145 drm_get_encoder_name(&intel_dp->base.base));
Jesse Barnes33a34e42010-09-08 12:42:02 -07002146 intel_dp_start_link_train(intel_dp);
2147 intel_dp_complete_link_train(intel_dp);
2148 }
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002149}
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002150
Adam Jackson07d3dc12012-09-18 10:58:50 -04002151/* XXX this is probably wrong for multiple downstream ports */
Zhenyu Wang5eb08b62009-07-24 01:00:31 +08002152static enum drm_connector_status
Keith Packard26d61aa2011-07-25 20:01:09 -07002153intel_dp_detect_dpcd(struct intel_dp *intel_dp)
Adam Jackson71ba90002011-07-12 17:38:04 -04002154{
Adam Jackson07d3dc12012-09-18 10:58:50 -04002155 uint8_t *dpcd = intel_dp->dpcd;
2156 bool hpd;
2157 uint8_t type;
2158
2159 if (!intel_dp_get_dpcd(intel_dp))
2160 return connector_status_disconnected;
2161
2162 /* if there's no downstream port, we're done */
2163 if (!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT))
Keith Packard26d61aa2011-07-25 20:01:09 -07002164 return connector_status_connected;
Adam Jackson07d3dc12012-09-18 10:58:50 -04002165
2166 /* If we're HPD-aware, SINK_COUNT changes dynamically */
2167 hpd = !!(intel_dp->downstream_ports[0] & DP_DS_PORT_HPD);
2168 if (hpd) {
Adam Jacksonda131a42012-09-20 16:42:45 -04002169 uint8_t reg;
Adam Jackson07d3dc12012-09-18 10:58:50 -04002170 if (!intel_dp_aux_native_read_retry(intel_dp, DP_SINK_COUNT,
Adam Jacksonda131a42012-09-20 16:42:45 -04002171 &reg, 1))
Adam Jackson07d3dc12012-09-18 10:58:50 -04002172 return connector_status_unknown;
Adam Jacksonda131a42012-09-20 16:42:45 -04002173 return DP_GET_SINK_COUNT(reg) ? connector_status_connected
2174 : connector_status_disconnected;
Adam Jackson07d3dc12012-09-18 10:58:50 -04002175 }
2176
2177 /* If no HPD, poke DDC gently */
2178 if (drm_probe_ddc(&intel_dp->adapter))
2179 return connector_status_connected;
2180
2181 /* Well we tried, say unknown for unreliable port types */
2182 type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
2183 if (type == DP_DS_PORT_TYPE_VGA || type == DP_DS_PORT_TYPE_NON_EDID)
2184 return connector_status_unknown;
2185
2186 /* Anything else is out of spec, warn and ignore */
2187 DRM_DEBUG_KMS("Broken DP branch device, ignoring\n");
Keith Packard26d61aa2011-07-25 20:01:09 -07002188 return connector_status_disconnected;
Adam Jackson71ba90002011-07-12 17:38:04 -04002189}
2190
2191static enum drm_connector_status
Zhenyu Wanga9756bb2010-09-19 13:09:06 +08002192ironlake_dp_detect(struct intel_dp *intel_dp)
Zhenyu Wang5eb08b62009-07-24 01:00:31 +08002193{
Zhenyu Wang5eb08b62009-07-24 01:00:31 +08002194 enum drm_connector_status status;
2195
Chris Wilsonfe16d942011-02-12 10:29:38 +00002196 /* Can't disconnect eDP, but you can close the lid... */
2197 if (is_edp(intel_dp)) {
2198 status = intel_panel_detect(intel_dp->base.base.dev);
2199 if (status == connector_status_unknown)
2200 status = connector_status_connected;
2201 return status;
2202 }
Jesse Barnes01cb9ea2010-10-07 16:01:12 -07002203
Keith Packard26d61aa2011-07-25 20:01:09 -07002204 return intel_dp_detect_dpcd(intel_dp);
Zhenyu Wang5eb08b62009-07-24 01:00:31 +08002205}
2206
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002207static enum drm_connector_status
Zhenyu Wanga9756bb2010-09-19 13:09:06 +08002208g4x_dp_detect(struct intel_dp *intel_dp)
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002209{
Chris Wilson4ef69c72010-09-09 15:14:28 +01002210 struct drm_device *dev = intel_dp->base.base.dev;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002211 struct drm_i915_private *dev_priv = dev->dev_private;
Chris Wilson10f76a32012-05-11 18:01:32 +01002212 uint32_t bit;
Zhenyu Wang5eb08b62009-07-24 01:00:31 +08002213
Chris Wilsonea5b2132010-08-04 13:50:23 +01002214 switch (intel_dp->output_reg) {
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002215 case DP_B:
Chris Wilson10f76a32012-05-11 18:01:32 +01002216 bit = DPB_HOTPLUG_LIVE_STATUS;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002217 break;
2218 case DP_C:
Chris Wilson10f76a32012-05-11 18:01:32 +01002219 bit = DPC_HOTPLUG_LIVE_STATUS;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002220 break;
2221 case DP_D:
Chris Wilson10f76a32012-05-11 18:01:32 +01002222 bit = DPD_HOTPLUG_LIVE_STATUS;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002223 break;
2224 default:
2225 return connector_status_unknown;
2226 }
2227
Chris Wilson10f76a32012-05-11 18:01:32 +01002228 if ((I915_READ(PORT_HOTPLUG_STAT) & bit) == 0)
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002229 return connector_status_disconnected;
2230
Keith Packard26d61aa2011-07-25 20:01:09 -07002231 return intel_dp_detect_dpcd(intel_dp);
Zhenyu Wanga9756bb2010-09-19 13:09:06 +08002232}
2233
Keith Packard8c241fe2011-09-28 16:38:44 -07002234static struct edid *
2235intel_dp_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
2236{
Jani Nikula9cd300e2012-10-19 14:51:52 +03002237 struct intel_connector *intel_connector = to_intel_connector(connector);
Keith Packard8c241fe2011-09-28 16:38:44 -07002238
Jani Nikula9cd300e2012-10-19 14:51:52 +03002239 /* use cached edid if we have one */
2240 if (intel_connector->edid) {
2241 struct edid *edid;
2242 int size;
2243
2244 /* invalid edid */
2245 if (IS_ERR(intel_connector->edid))
Jesse Barnesd6f24d02012-06-14 15:28:33 -04002246 return NULL;
2247
Jani Nikula9cd300e2012-10-19 14:51:52 +03002248 size = (intel_connector->edid->extensions + 1) * EDID_LENGTH;
Jesse Barnesd6f24d02012-06-14 15:28:33 -04002249 edid = kmalloc(size, GFP_KERNEL);
2250 if (!edid)
2251 return NULL;
2252
Jani Nikula9cd300e2012-10-19 14:51:52 +03002253 memcpy(edid, intel_connector->edid, size);
Jesse Barnesd6f24d02012-06-14 15:28:33 -04002254 return edid;
2255 }
2256
Jani Nikula9cd300e2012-10-19 14:51:52 +03002257 return drm_get_edid(connector, adapter);
Keith Packard8c241fe2011-09-28 16:38:44 -07002258}
2259
2260static int
2261intel_dp_get_edid_modes(struct drm_connector *connector, struct i2c_adapter *adapter)
2262{
Jani Nikula9cd300e2012-10-19 14:51:52 +03002263 struct intel_connector *intel_connector = to_intel_connector(connector);
Keith Packard8c241fe2011-09-28 16:38:44 -07002264
Jani Nikula9cd300e2012-10-19 14:51:52 +03002265 /* use cached edid if we have one */
2266 if (intel_connector->edid) {
2267 /* invalid edid */
2268 if (IS_ERR(intel_connector->edid))
2269 return 0;
2270
2271 return intel_connector_update_modes(connector,
2272 intel_connector->edid);
Jesse Barnesd6f24d02012-06-14 15:28:33 -04002273 }
2274
Jani Nikula9cd300e2012-10-19 14:51:52 +03002275 return intel_ddc_get_modes(connector, adapter);
Keith Packard8c241fe2011-09-28 16:38:44 -07002276}
2277
2278
Zhenyu Wanga9756bb2010-09-19 13:09:06 +08002279/**
2280 * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection.
2281 *
2282 * \return true if DP port is connected.
2283 * \return false if DP port is disconnected.
2284 */
2285static enum drm_connector_status
2286intel_dp_detect(struct drm_connector *connector, bool force)
2287{
2288 struct intel_dp *intel_dp = intel_attached_dp(connector);
2289 struct drm_device *dev = intel_dp->base.base.dev;
2290 enum drm_connector_status status;
2291 struct edid *edid = NULL;
2292
2293 intel_dp->has_audio = false;
2294
2295 if (HAS_PCH_SPLIT(dev))
2296 status = ironlake_dp_detect(intel_dp);
2297 else
2298 status = g4x_dp_detect(intel_dp);
Adam Jackson1b9be9d2011-07-12 17:38:01 -04002299
Adam Jacksonac66ae82011-07-12 17:38:03 -04002300 DRM_DEBUG_KMS("DPCD: %02hx%02hx%02hx%02hx%02hx%02hx%02hx%02hx\n",
2301 intel_dp->dpcd[0], intel_dp->dpcd[1], intel_dp->dpcd[2],
2302 intel_dp->dpcd[3], intel_dp->dpcd[4], intel_dp->dpcd[5],
2303 intel_dp->dpcd[6], intel_dp->dpcd[7]);
Adam Jackson1b9be9d2011-07-12 17:38:01 -04002304
Zhenyu Wanga9756bb2010-09-19 13:09:06 +08002305 if (status != connector_status_connected)
2306 return status;
2307
Adam Jackson0d198322012-05-14 16:05:47 -04002308 intel_dp_probe_oui(intel_dp);
2309
Daniel Vetterc3e5f672012-02-23 17:14:47 +01002310 if (intel_dp->force_audio != HDMI_AUDIO_AUTO) {
2311 intel_dp->has_audio = (intel_dp->force_audio == HDMI_AUDIO_ON);
Chris Wilsonf6849602010-09-19 09:29:33 +01002312 } else {
Keith Packard8c241fe2011-09-28 16:38:44 -07002313 edid = intel_dp_get_edid(connector, &intel_dp->adapter);
Chris Wilsonf6849602010-09-19 09:29:33 +01002314 if (edid) {
2315 intel_dp->has_audio = drm_detect_monitor_audio(edid);
Chris Wilsonf6849602010-09-19 09:29:33 +01002316 kfree(edid);
2317 }
Zhenyu Wanga9756bb2010-09-19 13:09:06 +08002318 }
2319
2320 return connector_status_connected;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002321}
2322
2323static int intel_dp_get_modes(struct drm_connector *connector)
2324{
Chris Wilsondf0e9242010-09-09 16:20:55 +01002325 struct intel_dp *intel_dp = intel_attached_dp(connector);
Jani Nikuladd06f902012-10-19 14:51:50 +03002326 struct intel_connector *intel_connector = to_intel_connector(connector);
Chris Wilson4ef69c72010-09-09 15:14:28 +01002327 struct drm_device *dev = intel_dp->base.base.dev;
Zhenyu Wang32f9d652009-07-24 01:00:32 +08002328 int ret;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002329
2330 /* We should parse the EDID data and find out if it has an audio sink
2331 */
2332
Keith Packard8c241fe2011-09-28 16:38:44 -07002333 ret = intel_dp_get_edid_modes(connector, &intel_dp->adapter);
Jani Nikulaf8779fd2012-10-19 14:51:48 +03002334 if (ret)
Zhenyu Wang32f9d652009-07-24 01:00:32 +08002335 return ret;
2336
Jani Nikulaf8779fd2012-10-19 14:51:48 +03002337 /* if eDP has no EDID, fall back to fixed mode */
Jani Nikuladd06f902012-10-19 14:51:50 +03002338 if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
Jani Nikulaf8779fd2012-10-19 14:51:48 +03002339 struct drm_display_mode *mode;
Jani Nikuladd06f902012-10-19 14:51:50 +03002340 mode = drm_mode_duplicate(dev,
2341 intel_connector->panel.fixed_mode);
Jani Nikulaf8779fd2012-10-19 14:51:48 +03002342 if (mode) {
Zhenyu Wang32f9d652009-07-24 01:00:32 +08002343 drm_mode_probed_add(connector, mode);
2344 return 1;
2345 }
2346 }
2347 return 0;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002348}
2349
Chris Wilson1aad7ac2011-02-09 18:46:58 +00002350static bool
2351intel_dp_detect_audio(struct drm_connector *connector)
2352{
2353 struct intel_dp *intel_dp = intel_attached_dp(connector);
2354 struct edid *edid;
2355 bool has_audio = false;
2356
Keith Packard8c241fe2011-09-28 16:38:44 -07002357 edid = intel_dp_get_edid(connector, &intel_dp->adapter);
Chris Wilson1aad7ac2011-02-09 18:46:58 +00002358 if (edid) {
2359 has_audio = drm_detect_monitor_audio(edid);
Chris Wilson1aad7ac2011-02-09 18:46:58 +00002360 kfree(edid);
2361 }
2362
2363 return has_audio;
2364}
2365
Chris Wilsonf6849602010-09-19 09:29:33 +01002366static int
2367intel_dp_set_property(struct drm_connector *connector,
2368 struct drm_property *property,
2369 uint64_t val)
2370{
Chris Wilsone953fd72011-02-21 22:23:52 +00002371 struct drm_i915_private *dev_priv = connector->dev->dev_private;
Chris Wilsonf6849602010-09-19 09:29:33 +01002372 struct intel_dp *intel_dp = intel_attached_dp(connector);
2373 int ret;
2374
2375 ret = drm_connector_property_set_value(connector, property, val);
2376 if (ret)
2377 return ret;
2378
Chris Wilson3f43c482011-05-12 22:17:24 +01002379 if (property == dev_priv->force_audio_property) {
Chris Wilson1aad7ac2011-02-09 18:46:58 +00002380 int i = val;
2381 bool has_audio;
2382
2383 if (i == intel_dp->force_audio)
Chris Wilsonf6849602010-09-19 09:29:33 +01002384 return 0;
2385
Chris Wilson1aad7ac2011-02-09 18:46:58 +00002386 intel_dp->force_audio = i;
Chris Wilsonf6849602010-09-19 09:29:33 +01002387
Daniel Vetterc3e5f672012-02-23 17:14:47 +01002388 if (i == HDMI_AUDIO_AUTO)
Chris Wilson1aad7ac2011-02-09 18:46:58 +00002389 has_audio = intel_dp_detect_audio(connector);
2390 else
Daniel Vetterc3e5f672012-02-23 17:14:47 +01002391 has_audio = (i == HDMI_AUDIO_ON);
Chris Wilson1aad7ac2011-02-09 18:46:58 +00002392
2393 if (has_audio == intel_dp->has_audio)
Chris Wilsonf6849602010-09-19 09:29:33 +01002394 return 0;
2395
Chris Wilson1aad7ac2011-02-09 18:46:58 +00002396 intel_dp->has_audio = has_audio;
Chris Wilsonf6849602010-09-19 09:29:33 +01002397 goto done;
2398 }
2399
Chris Wilsone953fd72011-02-21 22:23:52 +00002400 if (property == dev_priv->broadcast_rgb_property) {
2401 if (val == !!intel_dp->color_range)
2402 return 0;
2403
2404 intel_dp->color_range = val ? DP_COLOR_RANGE_16_235 : 0;
2405 goto done;
2406 }
2407
Chris Wilsonf6849602010-09-19 09:29:33 +01002408 return -EINVAL;
2409
2410done:
2411 if (intel_dp->base.base.crtc) {
2412 struct drm_crtc *crtc = intel_dp->base.base.crtc;
Daniel Vettera6778b32012-07-02 09:56:42 +02002413 intel_set_mode(crtc, &crtc->mode,
2414 crtc->x, crtc->y, crtc->fb);
Chris Wilsonf6849602010-09-19 09:29:33 +01002415 }
2416
2417 return 0;
2418}
2419
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002420static void
Akshay Joshi0206e352011-08-16 15:34:10 -04002421intel_dp_destroy(struct drm_connector *connector)
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002422{
Matthew Garrettaaa6fd22011-08-12 12:11:33 +02002423 struct drm_device *dev = connector->dev;
Jani Nikulabe3cd5e2012-10-12 10:33:05 +03002424 struct intel_dp *intel_dp = intel_attached_dp(connector);
Jani Nikula1d508702012-10-19 14:51:49 +03002425 struct intel_connector *intel_connector = to_intel_connector(connector);
Matthew Garrettaaa6fd22011-08-12 12:11:33 +02002426
Jani Nikula9cd300e2012-10-19 14:51:52 +03002427 if (!IS_ERR_OR_NULL(intel_connector->edid))
2428 kfree(intel_connector->edid);
2429
Jani Nikula1d508702012-10-19 14:51:49 +03002430 if (is_edp(intel_dp)) {
Matthew Garrettaaa6fd22011-08-12 12:11:33 +02002431 intel_panel_destroy_backlight(dev);
Jani Nikula1d508702012-10-19 14:51:49 +03002432 intel_panel_fini(&intel_connector->panel);
2433 }
Matthew Garrettaaa6fd22011-08-12 12:11:33 +02002434
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002435 drm_sysfs_connector_remove(connector);
2436 drm_connector_cleanup(connector);
Zhenyu Wang55f78c42010-03-29 16:13:57 +08002437 kfree(connector);
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002438}
2439
Daniel Vetter24d05922010-08-20 18:08:28 +02002440static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
2441{
2442 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2443
2444 i2c_del_adapter(&intel_dp->adapter);
2445 drm_encoder_cleanup(encoder);
Keith Packardbd943152011-09-18 23:09:52 -07002446 if (is_edp(intel_dp)) {
2447 cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
2448 ironlake_panel_vdd_off_sync(intel_dp);
2449 }
Daniel Vetter24d05922010-08-20 18:08:28 +02002450 kfree(intel_dp);
2451}
2452
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002453static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002454 .mode_fixup = intel_dp_mode_fixup,
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002455 .mode_set = intel_dp_mode_set,
Daniel Vetter1f703852012-07-11 16:51:39 +02002456 .disable = intel_encoder_noop,
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002457};
2458
Paulo Zanonia7902ac52012-10-15 15:51:42 -03002459static const struct drm_encoder_helper_funcs intel_dp_helper_funcs_hsw = {
2460 .mode_fixup = intel_dp_mode_fixup,
2461 .mode_set = intel_ddi_mode_set,
2462 .disable = intel_encoder_noop,
2463};
2464
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002465static const struct drm_connector_funcs intel_dp_connector_funcs = {
Daniel Vetter2bd2ad62012-09-06 22:15:41 +02002466 .dpms = intel_connector_dpms,
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002467 .detect = intel_dp_detect,
2468 .fill_modes = drm_helper_probe_single_connector_modes,
Chris Wilsonf6849602010-09-19 09:29:33 +01002469 .set_property = intel_dp_set_property,
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002470 .destroy = intel_dp_destroy,
2471};
2472
2473static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = {
2474 .get_modes = intel_dp_get_modes,
2475 .mode_valid = intel_dp_mode_valid,
Chris Wilsondf0e9242010-09-09 16:20:55 +01002476 .best_encoder = intel_best_encoder,
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002477};
2478
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002479static const struct drm_encoder_funcs intel_dp_enc_funcs = {
Daniel Vetter24d05922010-08-20 18:08:28 +02002480 .destroy = intel_dp_encoder_destroy,
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002481};
2482
Chris Wilson995b6762010-08-20 13:23:26 +01002483static void
Eric Anholt21d40d32010-03-25 11:11:14 -07002484intel_dp_hot_plug(struct intel_encoder *intel_encoder)
Keith Packardc8110e52009-05-06 11:51:10 -07002485{
Chris Wilsonea5b2132010-08-04 13:50:23 +01002486 struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base);
Keith Packardc8110e52009-05-06 11:51:10 -07002487
Jesse Barnes885a5012011-07-07 11:11:01 -07002488 intel_dp_check_link_status(intel_dp);
Keith Packardc8110e52009-05-06 11:51:10 -07002489}
2490
Zhenyu Wange3421a12010-04-08 09:43:27 +08002491/* Return which DP Port should be selected for Transcoder DP control */
2492int
Akshay Joshi0206e352011-08-16 15:34:10 -04002493intel_trans_dp_port_sel(struct drm_crtc *crtc)
Zhenyu Wange3421a12010-04-08 09:43:27 +08002494{
2495 struct drm_device *dev = crtc->dev;
Daniel Vetter6c2b7c12012-07-05 09:50:24 +02002496 struct intel_encoder *encoder;
Zhenyu Wange3421a12010-04-08 09:43:27 +08002497
Daniel Vetter6c2b7c12012-07-05 09:50:24 +02002498 for_each_encoder_on_crtc(dev, crtc, encoder) {
2499 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
Chris Wilsonea5b2132010-08-04 13:50:23 +01002500
Keith Packard417e8222011-11-01 19:54:11 -07002501 if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT ||
2502 intel_dp->base.type == INTEL_OUTPUT_EDP)
Chris Wilsonea5b2132010-08-04 13:50:23 +01002503 return intel_dp->output_reg;
Zhenyu Wange3421a12010-04-08 09:43:27 +08002504 }
Chris Wilsonea5b2132010-08-04 13:50:23 +01002505
Zhenyu Wange3421a12010-04-08 09:43:27 +08002506 return -1;
2507}
2508
Zhao Yakui36e83a12010-06-12 14:32:21 +08002509/* check the VBT to see whether the eDP is on DP-D port */
Adam Jacksoncb0953d2010-07-16 14:46:29 -04002510bool intel_dpd_is_edp(struct drm_device *dev)
Zhao Yakui36e83a12010-06-12 14:32:21 +08002511{
2512 struct drm_i915_private *dev_priv = dev->dev_private;
2513 struct child_device_config *p_child;
2514 int i;
2515
2516 if (!dev_priv->child_dev_num)
2517 return false;
2518
2519 for (i = 0; i < dev_priv->child_dev_num; i++) {
2520 p_child = dev_priv->child_dev + i;
2521
2522 if (p_child->dvo_port == PORT_IDPD &&
2523 p_child->device_type == DEVICE_TYPE_eDP)
2524 return true;
2525 }
2526 return false;
2527}
2528
Chris Wilsonf6849602010-09-19 09:29:33 +01002529static void
2530intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector)
2531{
Chris Wilson3f43c482011-05-12 22:17:24 +01002532 intel_attach_force_audio_property(connector);
Chris Wilsone953fd72011-02-21 22:23:52 +00002533 intel_attach_broadcast_rgb_property(connector);
Chris Wilsonf6849602010-09-19 09:29:33 +01002534}
2535
Keith Packardc8110e52009-05-06 11:51:10 -07002536void
Paulo Zanoniab9d7c32012-07-17 17:53:45 -03002537intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002538{
2539 struct drm_i915_private *dev_priv = dev->dev_private;
2540 struct drm_connector *connector;
Chris Wilsonea5b2132010-08-04 13:50:23 +01002541 struct intel_dp *intel_dp;
Eric Anholt21d40d32010-03-25 11:11:14 -07002542 struct intel_encoder *intel_encoder;
Zhenyu Wang55f78c42010-03-29 16:13:57 +08002543 struct intel_connector *intel_connector;
Jani Nikulaf8779fd2012-10-19 14:51:48 +03002544 struct drm_display_mode *fixed_mode = NULL;
Zhenyu Wang5eb08b62009-07-24 01:00:31 +08002545 const char *name = NULL;
Adam Jacksonb3295302010-07-16 14:46:28 -04002546 int type;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002547
Chris Wilsonea5b2132010-08-04 13:50:23 +01002548 intel_dp = kzalloc(sizeof(struct intel_dp), GFP_KERNEL);
2549 if (!intel_dp)
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002550 return;
2551
Chris Wilson3d3dc142011-02-12 10:33:12 +00002552 intel_dp->output_reg = output_reg;
Paulo Zanoniab9d7c32012-07-17 17:53:45 -03002553 intel_dp->port = port;
Daniel Vetter07679352012-09-06 22:15:42 +02002554 /* Preserve the current hw state. */
2555 intel_dp->DP = I915_READ(intel_dp->output_reg);
Chris Wilson3d3dc142011-02-12 10:33:12 +00002556
Zhenyu Wang55f78c42010-03-29 16:13:57 +08002557 intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
2558 if (!intel_connector) {
Chris Wilsonea5b2132010-08-04 13:50:23 +01002559 kfree(intel_dp);
Zhenyu Wang55f78c42010-03-29 16:13:57 +08002560 return;
2561 }
Chris Wilsonea5b2132010-08-04 13:50:23 +01002562 intel_encoder = &intel_dp->base;
Jani Nikuladd06f902012-10-19 14:51:50 +03002563 intel_dp->attached_connector = intel_connector;
Zhenyu Wang55f78c42010-03-29 16:13:57 +08002564
Chris Wilsonea5b2132010-08-04 13:50:23 +01002565 if (HAS_PCH_SPLIT(dev) && output_reg == PCH_DP_D)
Adam Jacksonb3295302010-07-16 14:46:28 -04002566 if (intel_dpd_is_edp(dev))
Chris Wilsonea5b2132010-08-04 13:50:23 +01002567 intel_dp->is_pch_edp = true;
Adam Jacksonb3295302010-07-16 14:46:28 -04002568
Gajanan Bhat19c03922012-09-27 19:13:07 +05302569 /*
2570 * FIXME : We need to initialize built-in panels before external panels.
2571 * For X0, DP_C is fixed as eDP. Revisit this as part of VLV eDP cleanup
2572 */
2573 if (IS_VALLEYVIEW(dev) && output_reg == DP_C) {
2574 type = DRM_MODE_CONNECTOR_eDP;
2575 intel_encoder->type = INTEL_OUTPUT_EDP;
2576 } else if (output_reg == DP_A || is_pch_edp(intel_dp)) {
Adam Jacksonb3295302010-07-16 14:46:28 -04002577 type = DRM_MODE_CONNECTOR_eDP;
2578 intel_encoder->type = INTEL_OUTPUT_EDP;
2579 } else {
2580 type = DRM_MODE_CONNECTOR_DisplayPort;
2581 intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
2582 }
2583
Zhenyu Wang55f78c42010-03-29 16:13:57 +08002584 connector = &intel_connector->base;
Adam Jacksonb3295302010-07-16 14:46:28 -04002585 drm_connector_init(dev, connector, &intel_dp_connector_funcs, type);
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002586 drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
2587
Dave Airlieeb1f8e42010-05-07 06:42:51 +00002588 connector->polled = DRM_CONNECTOR_POLL_HPD;
2589
Daniel Vetter66a92782012-07-12 20:08:18 +02002590 intel_encoder->cloneable = false;
Ma Lingf8aed702009-08-24 13:50:24 +08002591
Daniel Vetter66a92782012-07-12 20:08:18 +02002592 INIT_DELAYED_WORK(&intel_dp->panel_vdd_work,
2593 ironlake_panel_vdd_work);
Zhenyu Wang6251ec02010-01-12 05:38:32 +08002594
Jesse Barnes27f82272011-09-02 12:54:37 -07002595 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Jesse Barnesee7b9f92012-04-20 17:11:53 +01002596
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002597 connector->interlace_allowed = true;
2598 connector->doublescan_allowed = 0;
2599
Chris Wilson4ef69c72010-09-09 15:14:28 +01002600 drm_encoder_init(dev, &intel_encoder->base, &intel_dp_enc_funcs,
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002601 DRM_MODE_ENCODER_TMDS);
Paulo Zanonia7902ac52012-10-15 15:51:42 -03002602
2603 if (IS_HASWELL(dev))
2604 drm_encoder_helper_add(&intel_encoder->base,
2605 &intel_dp_helper_funcs_hsw);
2606 else
2607 drm_encoder_helper_add(&intel_encoder->base,
2608 &intel_dp_helper_funcs);
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002609
Chris Wilsondf0e9242010-09-09 16:20:55 +01002610 intel_connector_attach_encoder(intel_connector, intel_encoder);
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002611 drm_sysfs_connector_add(connector);
2612
Paulo Zanonia7902ac52012-10-15 15:51:42 -03002613 if (IS_HASWELL(dev)) {
2614 intel_encoder->enable = intel_enable_ddi;
2615 intel_encoder->pre_enable = intel_ddi_pre_enable;
2616 intel_encoder->disable = intel_disable_ddi;
2617 intel_encoder->post_disable = intel_ddi_post_disable;
2618 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
2619 } else {
2620 intel_encoder->enable = intel_enable_dp;
2621 intel_encoder->pre_enable = intel_pre_enable_dp;
2622 intel_encoder->disable = intel_disable_dp;
2623 intel_encoder->post_disable = intel_post_disable_dp;
2624 intel_encoder->get_hw_state = intel_dp_get_hw_state;
2625 }
Daniel Vetter19d8fe12012-07-02 13:26:27 +02002626 intel_connector->get_hw_state = intel_connector_get_hw_state;
Daniel Vettere8cb4552012-07-01 13:05:48 +02002627
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002628 /* Set up the DDC bus. */
Paulo Zanoniab9d7c32012-07-17 17:53:45 -03002629 switch (port) {
2630 case PORT_A:
2631 name = "DPDDC-A";
2632 break;
2633 case PORT_B:
2634 dev_priv->hotplug_supported_mask |= DPB_HOTPLUG_INT_STATUS;
2635 name = "DPDDC-B";
2636 break;
2637 case PORT_C:
2638 dev_priv->hotplug_supported_mask |= DPC_HOTPLUG_INT_STATUS;
2639 name = "DPDDC-C";
2640 break;
2641 case PORT_D:
2642 dev_priv->hotplug_supported_mask |= DPD_HOTPLUG_INT_STATUS;
2643 name = "DPDDC-D";
2644 break;
2645 default:
2646 WARN(1, "Invalid port %c\n", port_name(port));
2647 break;
Zhenyu Wang5eb08b62009-07-24 01:00:31 +08002648 }
2649
Jesse Barnes89667382010-10-07 16:01:21 -07002650 /* Cache some DPCD data in the eDP case */
2651 if (is_edp(intel_dp)) {
Keith Packardf01eca22011-09-28 16:48:10 -07002652 struct edp_power_seq cur, vbt;
2653 u32 pp_on, pp_off, pp_div;
Jesse Barnes89667382010-10-07 16:01:21 -07002654
Jesse Barnes5d613502011-01-24 17:10:54 -08002655 pp_on = I915_READ(PCH_PP_ON_DELAYS);
Keith Packardf01eca22011-09-28 16:48:10 -07002656 pp_off = I915_READ(PCH_PP_OFF_DELAYS);
Jesse Barnes5d613502011-01-24 17:10:54 -08002657 pp_div = I915_READ(PCH_PP_DIVISOR);
2658
Jesse Barnesbfa33842012-04-10 11:58:04 -07002659 if (!pp_on || !pp_off || !pp_div) {
2660 DRM_INFO("bad panel power sequencing delays, disabling panel\n");
2661 intel_dp_encoder_destroy(&intel_dp->base.base);
2662 intel_dp_destroy(&intel_connector->base);
2663 return;
2664 }
2665
Keith Packardf01eca22011-09-28 16:48:10 -07002666 /* Pull timing values out of registers */
2667 cur.t1_t3 = (pp_on & PANEL_POWER_UP_DELAY_MASK) >>
2668 PANEL_POWER_UP_DELAY_SHIFT;
2669
2670 cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >>
2671 PANEL_LIGHT_ON_DELAY_SHIFT;
Keith Packardf2e8b182011-11-01 20:01:35 -07002672
Keith Packardf01eca22011-09-28 16:48:10 -07002673 cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >>
2674 PANEL_LIGHT_OFF_DELAY_SHIFT;
2675
2676 cur.t10 = (pp_off & PANEL_POWER_DOWN_DELAY_MASK) >>
2677 PANEL_POWER_DOWN_DELAY_SHIFT;
2678
2679 cur.t11_t12 = ((pp_div & PANEL_POWER_CYCLE_DELAY_MASK) >>
2680 PANEL_POWER_CYCLE_DELAY_SHIFT) * 1000;
2681
2682 DRM_DEBUG_KMS("cur t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
2683 cur.t1_t3, cur.t8, cur.t9, cur.t10, cur.t11_t12);
2684
2685 vbt = dev_priv->edp.pps;
2686
2687 DRM_DEBUG_KMS("vbt t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
2688 vbt.t1_t3, vbt.t8, vbt.t9, vbt.t10, vbt.t11_t12);
2689
2690#define get_delay(field) ((max(cur.field, vbt.field) + 9) / 10)
2691
2692 intel_dp->panel_power_up_delay = get_delay(t1_t3);
2693 intel_dp->backlight_on_delay = get_delay(t8);
2694 intel_dp->backlight_off_delay = get_delay(t9);
2695 intel_dp->panel_power_down_delay = get_delay(t10);
2696 intel_dp->panel_power_cycle_delay = get_delay(t11_t12);
2697
2698 DRM_DEBUG_KMS("panel power up delay %d, power down delay %d, power cycle delay %d\n",
2699 intel_dp->panel_power_up_delay, intel_dp->panel_power_down_delay,
2700 intel_dp->panel_power_cycle_delay);
2701
2702 DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n",
2703 intel_dp->backlight_on_delay, intel_dp->backlight_off_delay);
Dave Airliec1f05262012-08-30 11:06:18 +10002704 }
2705
2706 intel_dp_i2c_init(intel_dp, intel_connector, name);
2707
2708 if (is_edp(intel_dp)) {
2709 bool ret;
Jani Nikulaf8779fd2012-10-19 14:51:48 +03002710 struct drm_display_mode *scan;
Dave Airliec1f05262012-08-30 11:06:18 +10002711 struct edid *edid;
Jesse Barnes5d613502011-01-24 17:10:54 -08002712
2713 ironlake_edp_panel_vdd_on(intel_dp);
Keith Packard59f3e272011-07-25 20:01:56 -07002714 ret = intel_dp_get_dpcd(intel_dp);
Keith Packardbd943152011-09-18 23:09:52 -07002715 ironlake_edp_panel_vdd_off(intel_dp, false);
Keith Packard99ea7122011-11-01 19:57:50 -07002716
Keith Packard59f3e272011-07-25 20:01:56 -07002717 if (ret) {
Jesse Barnes7183dc22011-07-07 11:10:58 -07002718 if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11)
2719 dev_priv->no_aux_handshake =
2720 intel_dp->dpcd[DP_MAX_DOWNSPREAD] &
Jesse Barnes89667382010-10-07 16:01:21 -07002721 DP_NO_AUX_HANDSHAKE_LINK_TRAINING;
2722 } else {
Chris Wilson3d3dc142011-02-12 10:33:12 +00002723 /* if this fails, presume the device is a ghost */
Takashi Iwai48898b02011-03-18 09:06:49 +00002724 DRM_INFO("failed to retrieve link info, disabling eDP\n");
Chris Wilson3d3dc142011-02-12 10:33:12 +00002725 intel_dp_encoder_destroy(&intel_dp->base.base);
Takashi Iwai48898b02011-03-18 09:06:49 +00002726 intel_dp_destroy(&intel_connector->base);
Chris Wilson3d3dc142011-02-12 10:33:12 +00002727 return;
Jesse Barnes89667382010-10-07 16:01:21 -07002728 }
Jesse Barnes89667382010-10-07 16:01:21 -07002729
Jesse Barnesd6f24d02012-06-14 15:28:33 -04002730 ironlake_edp_panel_vdd_on(intel_dp);
2731 edid = drm_get_edid(connector, &intel_dp->adapter);
2732 if (edid) {
Jani Nikula9cd300e2012-10-19 14:51:52 +03002733 if (drm_add_edid_modes(connector, edid)) {
2734 drm_mode_connector_update_edid_property(connector, edid);
2735 drm_edid_to_eld(connector, edid);
2736 } else {
2737 kfree(edid);
2738 edid = ERR_PTR(-EINVAL);
2739 }
2740 } else {
2741 edid = ERR_PTR(-ENOENT);
Jesse Barnesd6f24d02012-06-14 15:28:33 -04002742 }
Jani Nikula9cd300e2012-10-19 14:51:52 +03002743 intel_connector->edid = edid;
Jani Nikulaf8779fd2012-10-19 14:51:48 +03002744
2745 /* prefer fixed mode from EDID if available */
2746 list_for_each_entry(scan, &connector->probed_modes, head) {
2747 if ((scan->type & DRM_MODE_TYPE_PREFERRED)) {
2748 fixed_mode = drm_mode_duplicate(dev, scan);
2749 break;
2750 }
2751 }
2752
2753 /* fallback to VBT if available for eDP */
2754 if (!fixed_mode && dev_priv->lfp_lvds_vbt_mode) {
2755 fixed_mode = drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
2756 if (fixed_mode)
2757 fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
2758 }
Jani Nikulaf8779fd2012-10-19 14:51:48 +03002759
Jesse Barnesd6f24d02012-06-14 15:28:33 -04002760 ironlake_edp_panel_vdd_off(intel_dp, false);
2761 }
Keith Packard552fb0b2011-09-28 16:31:53 -07002762
Eric Anholt21d40d32010-03-25 11:11:14 -07002763 intel_encoder->hot_plug = intel_dp_hot_plug;
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002764
Jani Nikula1d508702012-10-19 14:51:49 +03002765 if (is_edp(intel_dp)) {
Jani Nikuladd06f902012-10-19 14:51:50 +03002766 intel_panel_init(&intel_connector->panel, fixed_mode);
Jani Nikula0657b6b2012-10-19 14:51:46 +03002767 intel_panel_setup_backlight(connector);
Jani Nikula1d508702012-10-19 14:51:49 +03002768 }
Zhenyu Wang32f9d652009-07-24 01:00:32 +08002769
Chris Wilsonf6849602010-09-19 09:29:33 +01002770 intel_dp_add_properties(intel_dp, connector);
2771
Keith Packarda4fc5ed2009-04-07 16:16:42 -07002772 /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
2773 * 0xd. Failure to do so will result in spurious interrupts being
2774 * generated on the port when a cable is not attached.
2775 */
2776 if (IS_G4X(dev) && !IS_GM45(dev)) {
2777 u32 temp = I915_READ(PEG_BAND_GAP_DATA);
2778 I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
2779 }
2780}