blob: ab48083ffcec4649f8c4b460bc76c093b663e001 [file] [log] [blame]
Eugeni Dodonov45244b82012-05-09 15:37:20 -03001/*
2 * Copyright © 2012 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 * Eugeni Dodonov <eugeni.dodonov@intel.com>
25 *
26 */
27
28#include "i915_drv.h"
29#include "intel_drv.h"
30
31/* HDMI/DVI modes ignore everything but the last 2 items. So we share
32 * them for both DP and FDI transports, allowing those ports to
33 * automatically adapt to HDMI connections as well
34 */
35static const u32 hsw_ddi_translations_dp[] = {
36 0x00FFFFFF, 0x0006000E, /* DP parameters */
37 0x00D75FFF, 0x0005000A,
38 0x00C30FFF, 0x00040006,
39 0x80AAAFFF, 0x000B0000,
40 0x00FFFFFF, 0x0005000A,
41 0x00D75FFF, 0x000C0004,
42 0x80C30FFF, 0x000B0000,
43 0x00FFFFFF, 0x00040006,
44 0x80D75FFF, 0x000B0000,
45 0x00FFFFFF, 0x00040006 /* HDMI parameters */
46};
47
48static const u32 hsw_ddi_translations_fdi[] = {
49 0x00FFFFFF, 0x0007000E, /* FDI parameters */
50 0x00D75FFF, 0x000F000A,
51 0x00C30FFF, 0x00060006,
52 0x00AAAFFF, 0x001E0000,
53 0x00FFFFFF, 0x000F000A,
54 0x00D75FFF, 0x00160004,
55 0x00C30FFF, 0x001E0000,
56 0x00FFFFFF, 0x00060006,
57 0x00D75FFF, 0x001E0000,
58 0x00FFFFFF, 0x00040006 /* HDMI parameters */
59};
60
Paulo Zanonifc914632012-10-05 12:05:54 -030061static enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
62{
63 int type = intel_encoder->type;
64
65 if (type == INTEL_OUTPUT_HDMI) {
66 struct intel_hdmi *intel_hdmi =
67 enc_to_intel_hdmi(&intel_encoder->base);
68 return intel_hdmi->ddi_port;
69 } else if (type == INTEL_OUTPUT_ANALOG) {
70 return PORT_E;
71 } else {
72 DRM_ERROR("Invalid DDI encoder type %d\n", type);
73 BUG();
74 }
75}
76
Eugeni Dodonov45244b82012-05-09 15:37:20 -030077/* On Haswell, DDI port buffers must be programmed with correct values
78 * in advance. The buffer values are different for FDI and DP modes,
79 * but the HDMI/DVI fields are shared among those. So we program the DDI
80 * in either FDI or DP modes only, as HDMI connections will work with both
81 * of those
82 */
83void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, bool use_fdi_mode)
84{
85 struct drm_i915_private *dev_priv = dev->dev_private;
86 u32 reg;
87 int i;
88 const u32 *ddi_translations = ((use_fdi_mode) ?
89 hsw_ddi_translations_fdi :
90 hsw_ddi_translations_dp);
91
92 DRM_DEBUG_DRIVER("Initializing DDI buffers for port %c in %s mode\n",
93 port_name(port),
94 use_fdi_mode ? "FDI" : "DP");
95
96 WARN((use_fdi_mode && (port != PORT_E)),
97 "Programming port %c in FDI mode, this probably will not work.\n",
98 port_name(port));
99
100 for (i=0, reg=DDI_BUF_TRANS(port); i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) {
101 I915_WRITE(reg, ddi_translations[i]);
102 reg += 4;
103 }
104}
105
106/* Program DDI buffers translations for DP. By default, program ports A-D in DP
107 * mode and port E for FDI.
108 */
109void intel_prepare_ddi(struct drm_device *dev)
110{
111 int port;
112
113 if (IS_HASWELL(dev)) {
114 for (port = PORT_A; port < PORT_E; port++)
115 intel_prepare_ddi_buffers(dev, port, false);
116
117 /* DDI E is the suggested one to work in FDI mode, so program is as such by
118 * default. It will have to be re-programmed in case a digital DP output
119 * will be detected on it
120 */
121 intel_prepare_ddi_buffers(dev, PORT_E, true);
122 }
123}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300124
125static const long hsw_ddi_buf_ctl_values[] = {
126 DDI_BUF_EMP_400MV_0DB_HSW,
127 DDI_BUF_EMP_400MV_3_5DB_HSW,
128 DDI_BUF_EMP_400MV_6DB_HSW,
129 DDI_BUF_EMP_400MV_9_5DB_HSW,
130 DDI_BUF_EMP_600MV_0DB_HSW,
131 DDI_BUF_EMP_600MV_3_5DB_HSW,
132 DDI_BUF_EMP_600MV_6DB_HSW,
133 DDI_BUF_EMP_800MV_0DB_HSW,
134 DDI_BUF_EMP_800MV_3_5DB_HSW
135};
136
137
138/* Starting with Haswell, different DDI ports can work in FDI mode for
139 * connection to the PCH-located connectors. For this, it is necessary to train
140 * both the DDI port and PCH receiver for the desired DDI buffer settings.
141 *
142 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
143 * please note that when FDI mode is active on DDI E, it shares 2 lines with
144 * DDI A (which is used for eDP)
145 */
146
147void hsw_fdi_link_train(struct drm_crtc *crtc)
148{
149 struct drm_device *dev = crtc->dev;
150 struct drm_i915_private *dev_priv = dev->dev_private;
151 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
152 int pipe = intel_crtc->pipe;
153 u32 reg, temp, i;
154
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300155 /* Start the training iterating through available voltages and emphasis */
156 for (i=0; i < ARRAY_SIZE(hsw_ddi_buf_ctl_values); i++) {
157 /* Configure DP_TP_CTL with auto-training */
158 I915_WRITE(DP_TP_CTL(PORT_E),
159 DP_TP_CTL_FDI_AUTOTRAIN |
160 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
161 DP_TP_CTL_LINK_TRAIN_PAT1 |
162 DP_TP_CTL_ENABLE);
163
164 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage */
165 temp = I915_READ(DDI_BUF_CTL(PORT_E));
166 temp = (temp & ~DDI_BUF_EMP_MASK);
167 I915_WRITE(DDI_BUF_CTL(PORT_E),
168 temp |
169 DDI_BUF_CTL_ENABLE |
170 DDI_PORT_WIDTH_X2 |
171 hsw_ddi_buf_ctl_values[i]);
172
173 udelay(600);
174
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300175 /* We need to program FDI_RX_MISC with the default TP1 to TP2
176 * values before enabling the receiver, and configure the delay
177 * for the FDI timing generator to 90h. Luckily, all the other
178 * bits are supposed to be zeroed, so we can write those values
179 * directly.
180 */
181 I915_WRITE(FDI_RX_MISC(pipe), FDI_RX_TP1_TO_TP2_48 |
182 FDI_RX_FDI_DELAY_90);
183
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300184 /* Enable CPU FDI Receiver with auto-training */
185 reg = FDI_RX_CTL(pipe);
186 I915_WRITE(reg,
187 I915_READ(reg) |
188 FDI_LINK_TRAIN_AUTO |
189 FDI_RX_ENABLE |
190 FDI_LINK_TRAIN_PATTERN_1_CPT |
191 FDI_RX_ENHANCE_FRAME_ENABLE |
192 FDI_PORT_WIDTH_2X_LPT |
193 FDI_RX_PLL_ENABLE);
194 POSTING_READ(reg);
195 udelay(100);
196
197 temp = I915_READ(DP_TP_STATUS(PORT_E));
198 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
199 DRM_DEBUG_DRIVER("BUF_CTL training done on %d step\n", i);
200
201 /* Enable normal pixel sending for FDI */
202 I915_WRITE(DP_TP_CTL(PORT_E),
203 DP_TP_CTL_FDI_AUTOTRAIN |
204 DP_TP_CTL_LINK_TRAIN_NORMAL |
205 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
206 DP_TP_CTL_ENABLE);
207
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300208 break;
209 } else {
210 DRM_ERROR("Error training BUF_CTL %d\n", i);
211
212 /* Disable DP_TP_CTL and FDI_RX_CTL) and retry */
213 I915_WRITE(DP_TP_CTL(PORT_E),
214 I915_READ(DP_TP_CTL(PORT_E)) &
215 ~DP_TP_CTL_ENABLE);
216 I915_WRITE(FDI_RX_CTL(pipe),
217 I915_READ(FDI_RX_CTL(pipe)) &
218 ~FDI_RX_PLL_ENABLE);
219 continue;
220 }
221 }
222
223 DRM_DEBUG_KMS("FDI train done.\n");
224}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300225
226/* For DDI connections, it is possible to support different outputs over the
227 * same DDI port, such as HDMI or DP or even VGA via FDI. So we don't know by
228 * the time the output is detected what exactly is on the other end of it. This
229 * function aims at providing support for this detection and proper output
230 * configuration.
231 */
232void intel_ddi_init(struct drm_device *dev, enum port port)
233{
234 /* For now, we don't do any proper output detection and assume that we
235 * handle HDMI only */
236
237 switch(port){
238 case PORT_A:
239 /* We don't handle eDP and DP yet */
240 DRM_DEBUG_DRIVER("Found digital output on DDI port A\n");
241 break;
242 /* Assume that the ports B, C and D are working in HDMI mode for now */
243 case PORT_B:
244 case PORT_C:
245 case PORT_D:
Daniel Vetter08d644a2012-07-12 20:19:59 +0200246 intel_hdmi_init(dev, DDI_BUF_CTL(port), port);
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300247 break;
248 default:
249 DRM_DEBUG_DRIVER("No handlers defined for port %d, skipping DDI initialization\n",
250 port);
251 break;
252 }
253}
Eugeni Dodonov12a13a32012-05-09 15:37:29 -0300254
255/* WRPLL clock dividers */
256struct wrpll_tmds_clock {
257 u32 clock;
258 u16 p; /* Post divider */
259 u16 n2; /* Feedback divider */
260 u16 r2; /* Reference divider */
261};
262
Paulo Zanoni126e9be2012-08-10 10:03:03 -0300263/* Table of matching values for WRPLL clocks programming for each frequency.
264 * The code assumes this table is sorted. */
Eugeni Dodonov12a13a32012-05-09 15:37:29 -0300265static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
266 {19750, 38, 25, 18},
267 {20000, 48, 32, 18},
268 {21000, 36, 21, 15},
269 {21912, 42, 29, 17},
270 {22000, 36, 22, 15},
271 {23000, 36, 23, 15},
272 {23500, 40, 40, 23},
273 {23750, 26, 16, 14},
Eugeni Dodonov12a13a32012-05-09 15:37:29 -0300274 {24000, 36, 24, 15},
275 {25000, 36, 25, 15},
276 {25175, 26, 40, 33},
277 {25200, 30, 21, 15},
278 {26000, 36, 26, 15},
279 {27000, 30, 21, 14},
280 {27027, 18, 100, 111},
281 {27500, 30, 29, 19},
282 {28000, 34, 30, 17},
283 {28320, 26, 30, 22},
284 {28322, 32, 42, 25},
285 {28750, 24, 23, 18},
286 {29000, 30, 29, 18},
287 {29750, 32, 30, 17},
288 {30000, 30, 25, 15},
289 {30750, 30, 41, 24},
290 {31000, 30, 31, 18},
291 {31500, 30, 28, 16},
292 {32000, 30, 32, 18},
293 {32500, 28, 32, 19},
294 {33000, 24, 22, 15},
295 {34000, 28, 30, 17},
296 {35000, 26, 32, 19},
297 {35500, 24, 30, 19},
298 {36000, 26, 26, 15},
299 {36750, 26, 46, 26},
300 {37000, 24, 23, 14},
301 {37762, 22, 40, 26},
302 {37800, 20, 21, 15},
303 {38000, 24, 27, 16},
304 {38250, 24, 34, 20},
305 {39000, 24, 26, 15},
306 {40000, 24, 32, 18},
307 {40500, 20, 21, 14},
308 {40541, 22, 147, 89},
309 {40750, 18, 19, 14},
310 {41000, 16, 17, 14},
311 {41500, 22, 44, 26},
312 {41540, 22, 44, 26},
313 {42000, 18, 21, 15},
314 {42500, 22, 45, 26},
315 {43000, 20, 43, 27},
316 {43163, 20, 24, 15},
317 {44000, 18, 22, 15},
318 {44900, 20, 108, 65},
319 {45000, 20, 25, 15},
320 {45250, 20, 52, 31},
321 {46000, 18, 23, 15},
322 {46750, 20, 45, 26},
323 {47000, 20, 40, 23},
324 {48000, 18, 24, 15},
325 {49000, 18, 49, 30},
326 {49500, 16, 22, 15},
327 {50000, 18, 25, 15},
328 {50500, 18, 32, 19},
329 {51000, 18, 34, 20},
330 {52000, 18, 26, 15},
331 {52406, 14, 34, 25},
332 {53000, 16, 22, 14},
333 {54000, 16, 24, 15},
334 {54054, 16, 173, 108},
335 {54500, 14, 24, 17},
336 {55000, 12, 22, 18},
337 {56000, 14, 45, 31},
338 {56250, 16, 25, 15},
339 {56750, 14, 25, 17},
340 {57000, 16, 27, 16},
341 {58000, 16, 43, 25},
342 {58250, 16, 38, 22},
343 {58750, 16, 40, 23},
344 {59000, 14, 26, 17},
345 {59341, 14, 40, 26},
346 {59400, 16, 44, 25},
347 {60000, 16, 32, 18},
348 {60500, 12, 39, 29},
349 {61000, 14, 49, 31},
350 {62000, 14, 37, 23},
351 {62250, 14, 42, 26},
352 {63000, 12, 21, 15},
353 {63500, 14, 28, 17},
354 {64000, 12, 27, 19},
355 {65000, 14, 32, 19},
356 {65250, 12, 29, 20},
357 {65500, 12, 32, 22},
358 {66000, 12, 22, 15},
359 {66667, 14, 38, 22},
360 {66750, 10, 21, 17},
361 {67000, 14, 33, 19},
362 {67750, 14, 58, 33},
363 {68000, 14, 30, 17},
364 {68179, 14, 46, 26},
365 {68250, 14, 46, 26},
366 {69000, 12, 23, 15},
367 {70000, 12, 28, 18},
368 {71000, 12, 30, 19},
369 {72000, 12, 24, 15},
370 {73000, 10, 23, 17},
371 {74000, 12, 23, 14},
372 {74176, 8, 100, 91},
373 {74250, 10, 22, 16},
374 {74481, 12, 43, 26},
375 {74500, 10, 29, 21},
376 {75000, 12, 25, 15},
377 {75250, 10, 39, 28},
378 {76000, 12, 27, 16},
379 {77000, 12, 53, 31},
380 {78000, 12, 26, 15},
381 {78750, 12, 28, 16},
382 {79000, 10, 38, 26},
383 {79500, 10, 28, 19},
384 {80000, 12, 32, 18},
385 {81000, 10, 21, 14},
386 {81081, 6, 100, 111},
387 {81624, 8, 29, 24},
388 {82000, 8, 17, 14},
389 {83000, 10, 40, 26},
390 {83950, 10, 28, 18},
391 {84000, 10, 28, 18},
392 {84750, 6, 16, 17},
393 {85000, 6, 17, 18},
394 {85250, 10, 30, 19},
395 {85750, 10, 27, 17},
396 {86000, 10, 43, 27},
397 {87000, 10, 29, 18},
398 {88000, 10, 44, 27},
399 {88500, 10, 41, 25},
400 {89000, 10, 28, 17},
401 {89012, 6, 90, 91},
402 {89100, 10, 33, 20},
403 {90000, 10, 25, 15},
404 {91000, 10, 32, 19},
405 {92000, 10, 46, 27},
406 {93000, 10, 31, 18},
407 {94000, 10, 40, 23},
408 {94500, 10, 28, 16},
409 {95000, 10, 44, 25},
410 {95654, 10, 39, 22},
411 {95750, 10, 39, 22},
412 {96000, 10, 32, 18},
413 {97000, 8, 23, 16},
414 {97750, 8, 42, 29},
415 {98000, 8, 45, 31},
416 {99000, 8, 22, 15},
417 {99750, 8, 34, 23},
418 {100000, 6, 20, 18},
419 {100500, 6, 19, 17},
420 {101000, 6, 37, 33},
421 {101250, 8, 21, 14},
422 {102000, 6, 17, 15},
423 {102250, 6, 25, 22},
424 {103000, 8, 29, 19},
425 {104000, 8, 37, 24},
426 {105000, 8, 28, 18},
427 {106000, 8, 22, 14},
428 {107000, 8, 46, 29},
429 {107214, 8, 27, 17},
430 {108000, 8, 24, 15},
431 {108108, 8, 173, 108},
432 {109000, 6, 23, 19},
Eugeni Dodonov12a13a32012-05-09 15:37:29 -0300433 {110000, 6, 22, 18},
434 {110013, 6, 22, 18},
435 {110250, 8, 49, 30},
436 {110500, 8, 36, 22},
437 {111000, 8, 23, 14},
438 {111264, 8, 150, 91},
439 {111375, 8, 33, 20},
440 {112000, 8, 63, 38},
441 {112500, 8, 25, 15},
442 {113100, 8, 57, 34},
443 {113309, 8, 42, 25},
444 {114000, 8, 27, 16},
445 {115000, 6, 23, 18},
446 {116000, 8, 43, 25},
447 {117000, 8, 26, 15},
448 {117500, 8, 40, 23},
449 {118000, 6, 38, 29},
450 {119000, 8, 30, 17},
451 {119500, 8, 46, 26},
452 {119651, 8, 39, 22},
453 {120000, 8, 32, 18},
454 {121000, 6, 39, 29},
455 {121250, 6, 31, 23},
456 {121750, 6, 23, 17},
457 {122000, 6, 42, 31},
458 {122614, 6, 30, 22},
459 {123000, 6, 41, 30},
460 {123379, 6, 37, 27},
461 {124000, 6, 51, 37},
462 {125000, 6, 25, 18},
463 {125250, 4, 13, 14},
464 {125750, 4, 27, 29},
465 {126000, 6, 21, 15},
466 {127000, 6, 24, 17},
467 {127250, 6, 41, 29},
468 {128000, 6, 27, 19},
469 {129000, 6, 43, 30},
470 {129859, 4, 25, 26},
471 {130000, 6, 26, 18},
472 {130250, 6, 42, 29},
473 {131000, 6, 32, 22},
474 {131500, 6, 38, 26},
475 {131850, 6, 41, 28},
476 {132000, 6, 22, 15},
477 {132750, 6, 28, 19},
478 {133000, 6, 34, 23},
479 {133330, 6, 37, 25},
480 {134000, 6, 61, 41},
481 {135000, 6, 21, 14},
482 {135250, 6, 167, 111},
483 {136000, 6, 62, 41},
484 {137000, 6, 35, 23},
485 {138000, 6, 23, 15},
486 {138500, 6, 40, 26},
487 {138750, 6, 37, 24},
488 {139000, 6, 34, 22},
489 {139050, 6, 34, 22},
490 {139054, 6, 34, 22},
491 {140000, 6, 28, 18},
492 {141000, 6, 36, 23},
493 {141500, 6, 22, 14},
494 {142000, 6, 30, 19},
495 {143000, 6, 27, 17},
496 {143472, 4, 17, 16},
497 {144000, 6, 24, 15},
498 {145000, 6, 29, 18},
499 {146000, 6, 47, 29},
500 {146250, 6, 26, 16},
501 {147000, 6, 49, 30},
502 {147891, 6, 23, 14},
503 {148000, 6, 23, 14},
504 {148250, 6, 28, 17},
505 {148352, 4, 100, 91},
506 {148500, 6, 33, 20},
507 {149000, 6, 48, 29},
508 {150000, 6, 25, 15},
509 {151000, 4, 19, 17},
510 {152000, 6, 27, 16},
511 {152280, 6, 44, 26},
512 {153000, 6, 34, 20},
513 {154000, 6, 53, 31},
514 {155000, 6, 31, 18},
515 {155250, 6, 50, 29},
516 {155750, 6, 45, 26},
517 {156000, 6, 26, 15},
518 {157000, 6, 61, 35},
519 {157500, 6, 28, 16},
520 {158000, 6, 65, 37},
521 {158250, 6, 44, 25},
522 {159000, 6, 53, 30},
523 {159500, 6, 39, 22},
524 {160000, 6, 32, 18},
525 {161000, 4, 31, 26},
526 {162000, 4, 18, 15},
527 {162162, 4, 131, 109},
528 {162500, 4, 53, 44},
529 {163000, 4, 29, 24},
530 {164000, 4, 17, 14},
531 {165000, 4, 22, 18},
532 {166000, 4, 32, 26},
533 {167000, 4, 26, 21},
534 {168000, 4, 46, 37},
535 {169000, 4, 104, 83},
536 {169128, 4, 64, 51},
537 {169500, 4, 39, 31},
538 {170000, 4, 34, 27},
539 {171000, 4, 19, 15},
540 {172000, 4, 51, 40},
541 {172750, 4, 32, 25},
542 {172800, 4, 32, 25},
543 {173000, 4, 41, 32},
544 {174000, 4, 49, 38},
545 {174787, 4, 22, 17},
546 {175000, 4, 35, 27},
547 {176000, 4, 30, 23},
548 {177000, 4, 38, 29},
549 {178000, 4, 29, 22},
550 {178500, 4, 37, 28},
551 {179000, 4, 53, 40},
552 {179500, 4, 73, 55},
553 {180000, 4, 20, 15},
554 {181000, 4, 55, 41},
555 {182000, 4, 31, 23},
556 {183000, 4, 42, 31},
557 {184000, 4, 30, 22},
558 {184750, 4, 26, 19},
559 {185000, 4, 37, 27},
560 {186000, 4, 51, 37},
561 {187000, 4, 36, 26},
562 {188000, 4, 32, 23},
563 {189000, 4, 21, 15},
564 {190000, 4, 38, 27},
565 {190960, 4, 41, 29},
566 {191000, 4, 41, 29},
567 {192000, 4, 27, 19},
568 {192250, 4, 37, 26},
569 {193000, 4, 20, 14},
570 {193250, 4, 53, 37},
571 {194000, 4, 23, 16},
572 {194208, 4, 23, 16},
573 {195000, 4, 26, 18},
574 {196000, 4, 45, 31},
575 {197000, 4, 35, 24},
576 {197750, 4, 41, 28},
577 {198000, 4, 22, 15},
578 {198500, 4, 25, 17},
579 {199000, 4, 28, 19},
580 {200000, 4, 37, 25},
581 {201000, 4, 61, 41},
582 {202000, 4, 112, 75},
583 {202500, 4, 21, 14},
584 {203000, 4, 146, 97},
585 {204000, 4, 62, 41},
586 {204750, 4, 44, 29},
587 {205000, 4, 38, 25},
588 {206000, 4, 29, 19},
589 {207000, 4, 23, 15},
590 {207500, 4, 40, 26},
591 {208000, 4, 37, 24},
592 {208900, 4, 48, 31},
593 {209000, 4, 48, 31},
594 {209250, 4, 31, 20},
595 {210000, 4, 28, 18},
596 {211000, 4, 25, 16},
597 {212000, 4, 22, 14},
598 {213000, 4, 30, 19},
599 {213750, 4, 38, 24},
600 {214000, 4, 46, 29},
601 {214750, 4, 35, 22},
602 {215000, 4, 43, 27},
603 {216000, 4, 24, 15},
604 {217000, 4, 37, 23},
605 {218000, 4, 42, 26},
606 {218250, 4, 42, 26},
607 {218750, 4, 34, 21},
608 {219000, 4, 47, 29},
Eugeni Dodonov12a13a32012-05-09 15:37:29 -0300609 {220000, 4, 44, 27},
610 {220640, 4, 49, 30},
611 {220750, 4, 36, 22},
612 {221000, 4, 36, 22},
613 {222000, 4, 23, 14},
614 {222525, 4, 28, 17},
615 {222750, 4, 33, 20},
616 {227000, 4, 37, 22},
617 {230250, 4, 29, 17},
618 {233500, 4, 38, 22},
619 {235000, 4, 40, 23},
620 {238000, 4, 30, 17},
621 {241500, 2, 17, 19},
622 {245250, 2, 20, 22},
623 {247750, 2, 22, 24},
624 {253250, 2, 15, 16},
625 {256250, 2, 18, 19},
626 {262500, 2, 31, 32},
627 {267250, 2, 66, 67},
628 {268500, 2, 94, 95},
629 {270000, 2, 14, 14},
630 {272500, 2, 77, 76},
631 {273750, 2, 57, 56},
632 {280750, 2, 24, 23},
633 {281250, 2, 23, 22},
634 {286000, 2, 17, 16},
635 {291750, 2, 26, 24},
636 {296703, 2, 56, 51},
637 {297000, 2, 22, 20},
638 {298000, 2, 21, 19},
639};
Eugeni Dodonov72662e12012-05-09 15:37:31 -0300640
641void intel_ddi_mode_set(struct drm_encoder *encoder,
642 struct drm_display_mode *mode,
643 struct drm_display_mode *adjusted_mode)
644{
Eugeni Dodonov72662e12012-05-09 15:37:31 -0300645 struct drm_crtc *crtc = encoder->crtc;
646 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
647 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
648 int port = intel_hdmi->ddi_port;
649 int pipe = intel_crtc->pipe;
Eugeni Dodonov72662e12012-05-09 15:37:31 -0300650
651 /* On Haswell, we need to enable the clocks and prepare DDI function to
652 * work in HDMI mode for this pipe.
653 */
654 DRM_DEBUG_KMS("Preparing HDMI DDI mode for Haswell on port %c, pipe %c\n", port_name(port), pipe_name(pipe));
655
Eugeni Dodonov72662e12012-05-09 15:37:31 -0300656 if (intel_hdmi->has_audio) {
657 /* Proper support for digital audio needs a new logic and a new set
658 * of registers, so we leave it for future patch bombing.
659 */
Wang Xingchao4f078542012-08-09 16:52:16 +0800660 DRM_DEBUG_DRIVER("HDMI audio on pipe %c on DDI\n",
Eugeni Dodonov72662e12012-05-09 15:37:31 -0300661 pipe_name(intel_crtc->pipe));
Wang Xingchao4f078542012-08-09 16:52:16 +0800662
663 /* write eld */
664 DRM_DEBUG_DRIVER("HDMI audio: write eld information\n");
665 intel_write_eld(encoder, adjusted_mode);
Eugeni Dodonov72662e12012-05-09 15:37:31 -0300666 }
667
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300668 intel_hdmi->set_infoframes(encoder, adjusted_mode);
669}
670
671static struct intel_encoder *
672intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
673{
674 struct drm_device *dev = crtc->dev;
675 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
676 struct intel_encoder *intel_encoder, *ret = NULL;
677 int num_encoders = 0;
678
679 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
680 ret = intel_encoder;
681 num_encoders++;
682 }
683
684 if (num_encoders != 1)
685 WARN(1, "%d encoders on crtc for pipe %d\n", num_encoders,
686 intel_crtc->pipe);
687
688 BUG_ON(ret == NULL);
689 return ret;
690}
691
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300692void intel_ddi_put_crtc_pll(struct drm_crtc *crtc)
693{
694 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
695 struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
696 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
697 uint32_t val;
698
699 switch (intel_crtc->ddi_pll_sel) {
700 case PORT_CLK_SEL_SPLL:
701 plls->spll_refcount--;
702 if (plls->spll_refcount == 0) {
703 DRM_DEBUG_KMS("Disabling SPLL\n");
704 val = I915_READ(SPLL_CTL);
705 WARN_ON(!(val & SPLL_PLL_ENABLE));
706 I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
707 POSTING_READ(SPLL_CTL);
708 }
709 break;
710 case PORT_CLK_SEL_WRPLL1:
711 plls->wrpll1_refcount--;
712 if (plls->wrpll1_refcount == 0) {
713 DRM_DEBUG_KMS("Disabling WRPLL 1\n");
714 val = I915_READ(WRPLL_CTL1);
715 WARN_ON(!(val & WRPLL_PLL_ENABLE));
716 I915_WRITE(WRPLL_CTL1, val & ~WRPLL_PLL_ENABLE);
717 POSTING_READ(WRPLL_CTL1);
718 }
719 break;
720 case PORT_CLK_SEL_WRPLL2:
721 plls->wrpll2_refcount--;
722 if (plls->wrpll2_refcount == 0) {
723 DRM_DEBUG_KMS("Disabling WRPLL 2\n");
724 val = I915_READ(WRPLL_CTL2);
725 WARN_ON(!(val & WRPLL_PLL_ENABLE));
726 I915_WRITE(WRPLL_CTL2, val & ~WRPLL_PLL_ENABLE);
727 POSTING_READ(WRPLL_CTL2);
728 }
729 break;
730 }
731
732 WARN(plls->spll_refcount < 0, "Invalid SPLL refcount\n");
733 WARN(plls->wrpll1_refcount < 0, "Invalid WRPLL1 refcount\n");
734 WARN(plls->wrpll2_refcount < 0, "Invalid WRPLL2 refcount\n");
735
736 intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE;
737}
738
739static void intel_ddi_calculate_wrpll(int clock, int *p, int *n2, int *r2)
740{
741 u32 i;
742
743 for (i = 0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++)
744 if (clock <= wrpll_tmds_clock_table[i].clock)
745 break;
746
747 if (i == ARRAY_SIZE(wrpll_tmds_clock_table))
748 i--;
749
750 *p = wrpll_tmds_clock_table[i].p;
751 *n2 = wrpll_tmds_clock_table[i].n2;
752 *r2 = wrpll_tmds_clock_table[i].r2;
753
754 if (wrpll_tmds_clock_table[i].clock != clock)
755 DRM_INFO("WRPLL: using settings for %dKHz on %dKHz mode\n",
756 wrpll_tmds_clock_table[i].clock, clock);
757
758 DRM_DEBUG_KMS("WRPLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n",
759 clock, *p, *n2, *r2);
760}
761
762bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock)
763{
764 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
765 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
766 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
767 struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
768 int type = intel_encoder->type;
769 enum pipe pipe = intel_crtc->pipe;
770 uint32_t reg, val;
771
772 /* TODO: reuse PLLs when possible (compare values) */
773
774 intel_ddi_put_crtc_pll(crtc);
775
776 if (type == INTEL_OUTPUT_HDMI) {
777 int p, n2, r2;
778
779 if (plls->wrpll1_refcount == 0) {
780 DRM_DEBUG_KMS("Using WRPLL 1 on pipe %c\n",
781 pipe_name(pipe));
782 plls->wrpll1_refcount++;
783 reg = WRPLL_CTL1;
784 intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL1;
785 } else if (plls->wrpll2_refcount == 0) {
786 DRM_DEBUG_KMS("Using WRPLL 2 on pipe %c\n",
787 pipe_name(pipe));
788 plls->wrpll2_refcount++;
789 reg = WRPLL_CTL2;
790 intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL2;
791 } else {
792 DRM_ERROR("No WRPLLs available!\n");
793 return false;
794 }
795
796 WARN(I915_READ(reg) & WRPLL_PLL_ENABLE,
797 "WRPLL already enabled\n");
798
799 intel_ddi_calculate_wrpll(clock, &p, &n2, &r2);
800
801 val = WRPLL_PLL_ENABLE | WRPLL_PLL_SELECT_LCPLL_2700 |
802 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
803 WRPLL_DIVIDER_POST(p);
804
805 } else if (type == INTEL_OUTPUT_ANALOG) {
806 if (plls->spll_refcount == 0) {
807 DRM_DEBUG_KMS("Using SPLL on pipe %c\n",
808 pipe_name(pipe));
809 plls->spll_refcount++;
810 reg = SPLL_CTL;
811 intel_crtc->ddi_pll_sel = PORT_CLK_SEL_SPLL;
812 }
813
814 WARN(I915_READ(reg) & SPLL_PLL_ENABLE,
815 "SPLL already enabled\n");
816
817 val = SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SCC;
818
819 } else {
820 WARN(1, "Invalid DDI encoder type %d\n", type);
821 return false;
822 }
823
824 I915_WRITE(reg, val);
825 udelay(20);
826
827 return true;
828}
829
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300830void intel_ddi_enable_pipe_func(struct drm_crtc *crtc)
831{
832 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
833 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
834 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
835 enum pipe pipe = intel_crtc->pipe;
836 uint32_t temp;
837
Eugeni Dodonov72662e12012-05-09 15:37:31 -0300838 /* Enable PIPE_DDI_FUNC_CTL for the pipe to work in HDMI mode */
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300839 temp = PIPE_DDI_FUNC_ENABLE;
Paulo Zanonidfcef252012-08-08 14:15:29 -0300840
841 switch (intel_crtc->bpp) {
842 case 18:
843 temp |= PIPE_DDI_BPC_6;
844 break;
845 case 24:
846 temp |= PIPE_DDI_BPC_8;
847 break;
848 case 30:
849 temp |= PIPE_DDI_BPC_10;
850 break;
851 case 36:
852 temp |= PIPE_DDI_BPC_12;
853 break;
854 default:
855 WARN(1, "%d bpp unsupported by pipe DDI function\n",
856 intel_crtc->bpp);
857 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -0300858
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300859 if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanonif63eb7c42012-08-08 14:15:28 -0300860 temp |= PIPE_DDI_PVSYNC;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300861 if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanonif63eb7c42012-08-08 14:15:28 -0300862 temp |= PIPE_DDI_PHSYNC;
863
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300864 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
865 struct intel_hdmi *intel_hdmi =
866 enc_to_intel_hdmi(&intel_encoder->base);
Eugeni Dodonov72662e12012-05-09 15:37:31 -0300867
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300868 if (intel_hdmi->has_hdmi_sink)
869 temp |= PIPE_DDI_MODE_SELECT_HDMI;
870 else
871 temp |= PIPE_DDI_MODE_SELECT_DVI;
872
873 temp |= PIPE_DDI_SELECT_PORT(intel_hdmi->ddi_port);
874 } else if (intel_encoder->type == INTEL_OUTPUT_ANALOG) {
875 temp |= PIPE_DDI_MODE_SELECT_FDI;
876 temp |= PIPE_DDI_SELECT_PORT(PORT_E);
877 } else {
878 WARN(1, "Invalid encoder type %d for pipe %d\n",
879 intel_encoder->type, pipe);
880 }
881
882 I915_WRITE(DDI_FUNC_CTL(pipe), temp);
883}
884
885void intel_ddi_disable_pipe_func(struct drm_i915_private *dev_priv,
886 enum pipe pipe)
887{
888 uint32_t reg = DDI_FUNC_CTL(pipe);
889 uint32_t val = I915_READ(reg);
890
891 val &= ~(PIPE_DDI_FUNC_ENABLE | PIPE_DDI_PORT_MASK);
892 val |= PIPE_DDI_PORT_NONE;
893 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -0300894}
895
Daniel Vetter85234cd2012-07-02 13:27:29 +0200896bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
897 enum pipe *pipe)
898{
899 struct drm_device *dev = encoder->base.dev;
900 struct drm_i915_private *dev_priv = dev->dev_private;
901 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
902 u32 tmp;
903 int i;
904
905 tmp = I915_READ(DDI_BUF_CTL(intel_hdmi->ddi_port));
906
907 if (!(tmp & DDI_BUF_CTL_ENABLE))
908 return false;
909
910 for_each_pipe(i) {
911 tmp = I915_READ(DDI_FUNC_CTL(i));
912
913 if ((tmp & PIPE_DDI_PORT_MASK)
914 == PIPE_DDI_SELECT_PORT(intel_hdmi->ddi_port)) {
915 *pipe = i;
916 return true;
917 }
918 }
919
920 DRM_DEBUG_KMS("No pipe for ddi port %i found\n", intel_hdmi->ddi_port);
921
922 return true;
923}
924
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300925static uint32_t intel_ddi_get_crtc_pll(struct drm_i915_private *dev_priv,
926 enum pipe pipe)
927{
928 uint32_t temp, ret;
929 enum port port;
930 int i;
931
932 temp = I915_READ(DDI_FUNC_CTL(pipe));
933 temp &= PIPE_DDI_PORT_MASK;
934 for (i = PORT_A; i <= PORT_E; i++)
935 if (temp == PIPE_DDI_SELECT_PORT(i))
936 port = i;
937
938 ret = I915_READ(PORT_CLK_SEL(port));
939
940 DRM_DEBUG_KMS("Pipe %c connected to port %c using clock 0x%08x\n",
941 pipe_name(pipe), port_name(port), ret);
942
943 return ret;
944}
945
946void intel_ddi_setup_hw_pll_state(struct drm_device *dev)
947{
948 struct drm_i915_private *dev_priv = dev->dev_private;
949 enum pipe pipe;
950 struct intel_crtc *intel_crtc;
951
952 for_each_pipe(pipe) {
953 intel_crtc =
954 to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
955
956 if (!intel_crtc->active)
957 continue;
958
959 intel_crtc->ddi_pll_sel = intel_ddi_get_crtc_pll(dev_priv,
960 pipe);
961
962 switch (intel_crtc->ddi_pll_sel) {
963 case PORT_CLK_SEL_SPLL:
964 dev_priv->ddi_plls.spll_refcount++;
965 break;
966 case PORT_CLK_SEL_WRPLL1:
967 dev_priv->ddi_plls.wrpll1_refcount++;
968 break;
969 case PORT_CLK_SEL_WRPLL2:
970 dev_priv->ddi_plls.wrpll2_refcount++;
971 break;
972 }
973 }
974}
975
Paulo Zanonifc914632012-10-05 12:05:54 -0300976void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
977{
978 struct drm_crtc *crtc = &intel_crtc->base;
979 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
980 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
981 enum port port = intel_ddi_get_encoder_port(intel_encoder);
982
983 I915_WRITE(PIPE_CLK_SEL(intel_crtc->pipe), PIPE_CLK_SEL_PORT(port));
984}
985
986void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
987{
988 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
989
990 I915_WRITE(PIPE_CLK_SEL(intel_crtc->pipe), PIPE_CLK_SEL_DISABLED);
991}
992
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300993void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
994{
995 struct drm_crtc *crtc = intel_encoder->base.crtc;
996 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
997 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
998 enum port port = intel_ddi_get_encoder_port(intel_encoder);
999
1000 WARN_ON(intel_crtc->ddi_pll_sel == PORT_CLK_SEL_NONE);
1001
1002 I915_WRITE(PORT_CLK_SEL(port), intel_crtc->ddi_pll_sel);
1003}
1004
1005void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
1006{
1007 struct drm_encoder *encoder = &intel_encoder->base;
1008 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
1009 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1010
1011 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
1012}
1013
Daniel Vetter5ab432e2012-06-30 08:59:56 +02001014void intel_enable_ddi(struct intel_encoder *encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001015{
Daniel Vetter5ab432e2012-06-30 08:59:56 +02001016 struct drm_device *dev = encoder->base.dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001017 struct drm_i915_private *dev_priv = dev->dev_private;
Daniel Vetter5ab432e2012-06-30 08:59:56 +02001018 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001019 int port = intel_hdmi->ddi_port;
1020 u32 temp;
1021
1022 temp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter5ab432e2012-06-30 08:59:56 +02001023 temp |= DDI_BUF_CTL_ENABLE;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001024
1025 /* Enable DDI_BUF_CTL. In HDMI/DVI mode, the port width,
1026 * and swing/emphasis values are ignored so nothing special needs
1027 * to be done besides enabling the port.
1028 */
Daniel Vetter5ab432e2012-06-30 08:59:56 +02001029 I915_WRITE(DDI_BUF_CTL(port), temp);
1030}
1031
1032void intel_disable_ddi(struct intel_encoder *encoder)
1033{
1034 struct drm_device *dev = encoder->base.dev;
1035 struct drm_i915_private *dev_priv = dev->dev_private;
1036 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
1037 int port = intel_hdmi->ddi_port;
1038 u32 temp;
1039
1040 temp = I915_READ(DDI_BUF_CTL(port));
1041 temp &= ~DDI_BUF_CTL_ENABLE;
1042
1043 I915_WRITE(DDI_BUF_CTL(port), temp);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001044}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03001045
1046static int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
1047{
1048 if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT)
1049 return 450;
1050 else if ((I915_READ(LCPLL_CTL) & LCPLL_CLK_FREQ_MASK) ==
1051 LCPLL_CLK_FREQ_450)
1052 return 450;
1053 else
1054 return 540;
1055}
1056
1057void intel_ddi_pll_init(struct drm_device *dev)
1058{
1059 struct drm_i915_private *dev_priv = dev->dev_private;
1060 uint32_t val = I915_READ(LCPLL_CTL);
1061
1062 /* The LCPLL register should be turned on by the BIOS. For now let's
1063 * just check its state and print errors in case something is wrong.
1064 * Don't even try to turn it on.
1065 */
1066
1067 DRM_DEBUG_KMS("CDCLK running at %dMHz\n",
1068 intel_ddi_get_cdclk_freq(dev_priv));
1069
1070 if (val & LCPLL_CD_SOURCE_FCLK)
1071 DRM_ERROR("CDCLK source is not LCPLL\n");
1072
1073 if (val & LCPLL_PLL_DISABLE)
1074 DRM_ERROR("LCPLL is disabled\n");
1075}