Rev 3746 | Rev 4280 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3746 | Rev 4104 | ||
---|---|---|---|
Line 82... | Line 82... | ||
82 | * in advance. The buffer values are different for FDI and DP modes, |
82 | * in advance. The buffer values are different for FDI and DP modes, |
83 | * but the HDMI/DVI fields are shared among those. So we program the DDI |
83 | * but the HDMI/DVI fields are shared among those. So we program the DDI |
84 | * in either FDI or DP modes only, as HDMI connections will work with both |
84 | * in either FDI or DP modes only, as HDMI connections will work with both |
85 | * of those |
85 | * of those |
86 | */ |
86 | */ |
87 | static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, |
87 | static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) |
88 | bool use_fdi_mode) |
- | |
89 | { |
88 | { |
90 | struct drm_i915_private *dev_priv = dev->dev_private; |
89 | struct drm_i915_private *dev_priv = dev->dev_private; |
91 | u32 reg; |
90 | u32 reg; |
92 | int i; |
91 | int i; |
93 | const u32 *ddi_translations = ((use_fdi_mode) ? |
92 | const u32 *ddi_translations = (port == PORT_E) ? |
94 | hsw_ddi_translations_fdi : |
93 | hsw_ddi_translations_fdi : |
95 | hsw_ddi_translations_dp); |
94 | hsw_ddi_translations_dp; |
Line 96... | Line -... | ||
96 | - | ||
97 | DRM_DEBUG_DRIVER("Initializing DDI buffers for port %c in %s mode\n", |
- | |
98 | port_name(port), |
95 | |
99 | use_fdi_mode ? "FDI" : "DP"); |
- | |
100 | - | ||
101 | WARN((use_fdi_mode && (port != PORT_E)), |
- | |
102 | "Programming port %c in FDI mode, this probably will not work.\n", |
- | |
103 | port_name(port)); |
- | |
104 | 96 | for (i = 0, reg = DDI_BUF_TRANS(port); |
|
105 | for (i=0, reg=DDI_BUF_TRANS(port); i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { |
97 | i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { |
106 | I915_WRITE(reg, ddi_translations[i]); |
98 | I915_WRITE(reg, ddi_translations[i]); |
107 | reg += 4; |
99 | reg += 4; |
108 | } |
100 | } |
Line 116... | Line 108... | ||
116 | int port; |
108 | int port; |
Line 117... | Line 109... | ||
117 | 109 | ||
118 | if (!HAS_DDI(dev)) |
110 | if (!HAS_DDI(dev)) |
Line 119... | Line 111... | ||
119 | return; |
111 | return; |
120 | 112 | ||
121 | for (port = PORT_A; port < PORT_E; port++) |
- | |
122 | intel_prepare_ddi_buffers(dev, port, false); |
- | |
123 | - | ||
124 | /* DDI E is the suggested one to work in FDI mode, so program is as such |
- | |
125 | * by default. It will have to be re-programmed in case a digital DP |
- | |
126 | * output will be detected on it |
- | |
127 | */ |
113 | for (port = PORT_A; port <= PORT_E; port++) |
Line 128... | Line 114... | ||
128 | intel_prepare_ddi_buffers(dev, PORT_E, true); |
114 | intel_prepare_ddi_buffers(dev, port); |
129 | } |
115 | } |
130 | 116 | ||
Line 172... | Line 158... | ||
172 | 158 | ||
173 | /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the |
159 | /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the |
174 | * mode set "sequence for CRT port" document: |
160 | * mode set "sequence for CRT port" document: |
175 | * - TP1 to TP2 time with the default value |
161 | * - TP1 to TP2 time with the default value |
- | 162 | * - FDI delay to 90h |
|
- | 163 | * |
|
176 | * - FDI delay to 90h |
164 | * WaFDIAutoLinkSetTimingOverrride:hsw |
177 | */ |
165 | */ |
178 | I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) | |
166 | I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) | |
179 | FDI_RX_PWRDN_LANE0_VAL(2) | |
167 | FDI_RX_PWRDN_LANE0_VAL(2) | |
Line 180... | Line 168... | ||
180 | FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); |
168 | FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); |
181 | 169 | ||
- | 170 | /* Enable the PCH Receiver FDI PLL */ |
|
182 | /* Enable the PCH Receiver FDI PLL */ |
171 | rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE | |
183 | rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE | |
172 | FDI_RX_PLL_ENABLE | |
184 | FDI_RX_PLL_ENABLE | ((intel_crtc->fdi_lanes - 1) << 19); |
173 | FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes); |
185 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
174 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
Line 186... | Line 175... | ||
186 | POSTING_READ(_FDI_RXA_CTL); |
175 | POSTING_READ(_FDI_RXA_CTL); |
Line 207... | Line 196... | ||
207 | * DDI E does not support port reversal, the functionality is |
196 | * DDI E does not support port reversal, the functionality is |
208 | * achieved on the PCH side in FDI_RX_CTL, so no need to set the |
197 | * achieved on the PCH side in FDI_RX_CTL, so no need to set the |
209 | * port reversal bit */ |
198 | * port reversal bit */ |
210 | I915_WRITE(DDI_BUF_CTL(PORT_E), |
199 | I915_WRITE(DDI_BUF_CTL(PORT_E), |
211 | DDI_BUF_CTL_ENABLE | |
200 | DDI_BUF_CTL_ENABLE | |
212 | ((intel_crtc->fdi_lanes - 1) << 1) | |
201 | ((intel_crtc->config.fdi_lanes - 1) << 1) | |
213 | hsw_ddi_buf_ctl_values[i / 2]); |
202 | hsw_ddi_buf_ctl_values[i / 2]); |
214 | POSTING_READ(DDI_BUF_CTL(PORT_E)); |
203 | POSTING_READ(DDI_BUF_CTL(PORT_E)); |
Line 215... | Line 204... | ||
215 | 204 | ||
Line 276... | Line 265... | ||
276 | } |
265 | } |
Line 277... | Line 266... | ||
277 | 266 | ||
278 | DRM_ERROR("FDI link training failed!\n"); |
267 | DRM_ERROR("FDI link training failed!\n"); |
Line 279... | Line -... | ||
279 | } |
- | |
280 | - | ||
281 | /* WRPLL clock dividers */ |
- | |
282 | struct wrpll_tmds_clock { |
- | |
283 | u32 clock; |
- | |
284 | u16 p; /* Post divider */ |
- | |
285 | u16 n2; /* Feedback divider */ |
- | |
286 | u16 r2; /* Reference divider */ |
- | |
287 | }; |
- | |
288 | - | ||
289 | /* Table of matching values for WRPLL clocks programming for each frequency. |
- | |
290 | * The code assumes this table is sorted. */ |
- | |
291 | static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = { |
- | |
292 | {19750, 38, 25, 18}, |
- | |
293 | {20000, 48, 32, 18}, |
- | |
294 | {21000, 36, 21, 15}, |
- | |
295 | {21912, 42, 29, 17}, |
- | |
296 | {22000, 36, 22, 15}, |
- | |
297 | {23000, 36, 23, 15}, |
- | |
298 | {23500, 40, 40, 23}, |
- | |
299 | {23750, 26, 16, 14}, |
- | |
300 | {24000, 36, 24, 15}, |
- | |
301 | {25000, 36, 25, 15}, |
- | |
302 | {25175, 26, 40, 33}, |
- | |
303 | {25200, 30, 21, 15}, |
- | |
304 | {26000, 36, 26, 15}, |
- | |
305 | {27000, 30, 21, 14}, |
- | |
306 | {27027, 18, 100, 111}, |
- | |
307 | {27500, 30, 29, 19}, |
- | |
308 | {28000, 34, 30, 17}, |
- | |
309 | {28320, 26, 30, 22}, |
- | |
310 | {28322, 32, 42, 25}, |
- | |
311 | {28750, 24, 23, 18}, |
- | |
312 | {29000, 30, 29, 18}, |
- | |
313 | {29750, 32, 30, 17}, |
- | |
314 | {30000, 30, 25, 15}, |
- | |
315 | {30750, 30, 41, 24}, |
- | |
316 | {31000, 30, 31, 18}, |
- | |
317 | {31500, 30, 28, 16}, |
- | |
318 | {32000, 30, 32, 18}, |
- | |
319 | {32500, 28, 32, 19}, |
- | |
320 | {33000, 24, 22, 15}, |
- | |
321 | {34000, 28, 30, 17}, |
- | |
322 | {35000, 26, 32, 19}, |
- | |
323 | {35500, 24, 30, 19}, |
- | |
324 | {36000, 26, 26, 15}, |
- | |
325 | {36750, 26, 46, 26}, |
- | |
326 | {37000, 24, 23, 14}, |
- | |
327 | {37762, 22, 40, 26}, |
- | |
328 | {37800, 20, 21, 15}, |
- | |
329 | {38000, 24, 27, 16}, |
- | |
330 | {38250, 24, 34, 20}, |
- | |
331 | {39000, 24, 26, 15}, |
- | |
332 | {40000, 24, 32, 18}, |
- | |
333 | {40500, 20, 21, 14}, |
- | |
334 | {40541, 22, 147, 89}, |
- | |
335 | {40750, 18, 19, 14}, |
- | |
336 | {41000, 16, 17, 14}, |
- | |
337 | {41500, 22, 44, 26}, |
- | |
338 | {41540, 22, 44, 26}, |
- | |
339 | {42000, 18, 21, 15}, |
- | |
340 | {42500, 22, 45, 26}, |
- | |
341 | {43000, 20, 43, 27}, |
- | |
342 | {43163, 20, 24, 15}, |
- | |
343 | {44000, 18, 22, 15}, |
- | |
344 | {44900, 20, 108, 65}, |
- | |
345 | {45000, 20, 25, 15}, |
- | |
346 | {45250, 20, 52, 31}, |
- | |
347 | {46000, 18, 23, 15}, |
- | |
348 | {46750, 20, 45, 26}, |
- | |
349 | {47000, 20, 40, 23}, |
- | |
350 | {48000, 18, 24, 15}, |
- | |
351 | {49000, 18, 49, 30}, |
- | |
352 | {49500, 16, 22, 15}, |
- | |
353 | {50000, 18, 25, 15}, |
- | |
354 | {50500, 18, 32, 19}, |
- | |
355 | {51000, 18, 34, 20}, |
- | |
356 | {52000, 18, 26, 15}, |
- | |
357 | {52406, 14, 34, 25}, |
- | |
358 | {53000, 16, 22, 14}, |
- | |
359 | {54000, 16, 24, 15}, |
- | |
360 | {54054, 16, 173, 108}, |
- | |
361 | {54500, 14, 24, 17}, |
- | |
362 | {55000, 12, 22, 18}, |
- | |
363 | {56000, 14, 45, 31}, |
- | |
364 | {56250, 16, 25, 15}, |
- | |
365 | {56750, 14, 25, 17}, |
- | |
366 | {57000, 16, 27, 16}, |
- | |
367 | {58000, 16, 43, 25}, |
- | |
368 | {58250, 16, 38, 22}, |
- | |
369 | {58750, 16, 40, 23}, |
- | |
370 | {59000, 14, 26, 17}, |
- | |
371 | {59341, 14, 40, 26}, |
- | |
372 | {59400, 16, 44, 25}, |
- | |
373 | {60000, 16, 32, 18}, |
- | |
374 | {60500, 12, 39, 29}, |
- | |
375 | {61000, 14, 49, 31}, |
- | |
376 | {62000, 14, 37, 23}, |
- | |
377 | {62250, 14, 42, 26}, |
- | |
378 | {63000, 12, 21, 15}, |
- | |
379 | {63500, 14, 28, 17}, |
- | |
380 | {64000, 12, 27, 19}, |
- | |
381 | {65000, 14, 32, 19}, |
- | |
382 | {65250, 12, 29, 20}, |
- | |
383 | {65500, 12, 32, 22}, |
- | |
384 | {66000, 12, 22, 15}, |
- | |
385 | {66667, 14, 38, 22}, |
- | |
386 | {66750, 10, 21, 17}, |
- | |
387 | {67000, 14, 33, 19}, |
- | |
388 | {67750, 14, 58, 33}, |
- | |
389 | {68000, 14, 30, 17}, |
- | |
390 | {68179, 14, 46, 26}, |
- | |
391 | {68250, 14, 46, 26}, |
- | |
392 | {69000, 12, 23, 15}, |
- | |
393 | {70000, 12, 28, 18}, |
- | |
394 | {71000, 12, 30, 19}, |
- | |
395 | {72000, 12, 24, 15}, |
- | |
396 | {73000, 10, 23, 17}, |
- | |
397 | {74000, 12, 23, 14}, |
- | |
398 | {74176, 8, 100, 91}, |
- | |
399 | {74250, 10, 22, 16}, |
- | |
400 | {74481, 12, 43, 26}, |
- | |
401 | {74500, 10, 29, 21}, |
- | |
402 | {75000, 12, 25, 15}, |
- | |
403 | {75250, 10, 39, 28}, |
- | |
404 | {76000, 12, 27, 16}, |
- | |
405 | {77000, 12, 53, 31}, |
- | |
406 | {78000, 12, 26, 15}, |
- | |
407 | {78750, 12, 28, 16}, |
- | |
408 | {79000, 10, 38, 26}, |
- | |
409 | {79500, 10, 28, 19}, |
- | |
410 | {80000, 12, 32, 18}, |
- | |
411 | {81000, 10, 21, 14}, |
- | |
412 | {81081, 6, 100, 111}, |
- | |
413 | {81624, 8, 29, 24}, |
- | |
414 | {82000, 8, 17, 14}, |
- | |
415 | {83000, 10, 40, 26}, |
- | |
416 | {83950, 10, 28, 18}, |
- | |
417 | {84000, 10, 28, 18}, |
- | |
418 | {84750, 6, 16, 17}, |
- | |
419 | {85000, 6, 17, 18}, |
- | |
420 | {85250, 10, 30, 19}, |
- | |
421 | {85750, 10, 27, 17}, |
- | |
422 | {86000, 10, 43, 27}, |
- | |
423 | {87000, 10, 29, 18}, |
- | |
424 | {88000, 10, 44, 27}, |
- | |
425 | {88500, 10, 41, 25}, |
- | |
426 | {89000, 10, 28, 17}, |
- | |
427 | {89012, 6, 90, 91}, |
- | |
428 | {89100, 10, 33, 20}, |
- | |
429 | {90000, 10, 25, 15}, |
- | |
430 | {91000, 10, 32, 19}, |
- | |
431 | {92000, 10, 46, 27}, |
- | |
432 | {93000, 10, 31, 18}, |
- | |
433 | {94000, 10, 40, 23}, |
- | |
434 | {94500, 10, 28, 16}, |
- | |
435 | {95000, 10, 44, 25}, |
- | |
436 | {95654, 10, 39, 22}, |
- | |
437 | {95750, 10, 39, 22}, |
- | |
438 | {96000, 10, 32, 18}, |
- | |
439 | {97000, 8, 23, 16}, |
- | |
440 | {97750, 8, 42, 29}, |
- | |
441 | {98000, 8, 45, 31}, |
- | |
442 | {99000, 8, 22, 15}, |
- | |
443 | {99750, 8, 34, 23}, |
- | |
444 | {100000, 6, 20, 18}, |
- | |
445 | {100500, 6, 19, 17}, |
- | |
446 | {101000, 6, 37, 33}, |
- | |
447 | {101250, 8, 21, 14}, |
- | |
448 | {102000, 6, 17, 15}, |
- | |
449 | {102250, 6, 25, 22}, |
- | |
450 | {103000, 8, 29, 19}, |
- | |
451 | {104000, 8, 37, 24}, |
- | |
452 | {105000, 8, 28, 18}, |
- | |
453 | {106000, 8, 22, 14}, |
- | |
454 | {107000, 8, 46, 29}, |
- | |
455 | {107214, 8, 27, 17}, |
- | |
456 | {108000, 8, 24, 15}, |
- | |
457 | {108108, 8, 173, 108}, |
- | |
458 | {109000, 6, 23, 19}, |
- | |
459 | {110000, 6, 22, 18}, |
- | |
460 | {110013, 6, 22, 18}, |
- | |
461 | {110250, 8, 49, 30}, |
- | |
462 | {110500, 8, 36, 22}, |
- | |
463 | {111000, 8, 23, 14}, |
- | |
464 | {111264, 8, 150, 91}, |
- | |
465 | {111375, 8, 33, 20}, |
- | |
466 | {112000, 8, 63, 38}, |
- | |
467 | {112500, 8, 25, 15}, |
- | |
468 | {113100, 8, 57, 34}, |
- | |
469 | {113309, 8, 42, 25}, |
- | |
470 | {114000, 8, 27, 16}, |
- | |
471 | {115000, 6, 23, 18}, |
- | |
472 | {116000, 8, 43, 25}, |
- | |
473 | {117000, 8, 26, 15}, |
- | |
474 | {117500, 8, 40, 23}, |
- | |
475 | {118000, 6, 38, 29}, |
- | |
476 | {119000, 8, 30, 17}, |
- | |
477 | {119500, 8, 46, 26}, |
- | |
478 | {119651, 8, 39, 22}, |
- | |
479 | {120000, 8, 32, 18}, |
- | |
480 | {121000, 6, 39, 29}, |
- | |
481 | {121250, 6, 31, 23}, |
- | |
482 | {121750, 6, 23, 17}, |
- | |
483 | {122000, 6, 42, 31}, |
- | |
484 | {122614, 6, 30, 22}, |
- | |
485 | {123000, 6, 41, 30}, |
- | |
486 | {123379, 6, 37, 27}, |
- | |
487 | {124000, 6, 51, 37}, |
- | |
488 | {125000, 6, 25, 18}, |
- | |
489 | {125250, 4, 13, 14}, |
- | |
490 | {125750, 4, 27, 29}, |
- | |
491 | {126000, 6, 21, 15}, |
- | |
492 | {127000, 6, 24, 17}, |
- | |
493 | {127250, 6, 41, 29}, |
- | |
494 | {128000, 6, 27, 19}, |
- | |
495 | {129000, 6, 43, 30}, |
- | |
496 | {129859, 4, 25, 26}, |
- | |
497 | {130000, 6, 26, 18}, |
- | |
498 | {130250, 6, 42, 29}, |
- | |
499 | {131000, 6, 32, 22}, |
- | |
500 | {131500, 6, 38, 26}, |
- | |
501 | {131850, 6, 41, 28}, |
- | |
502 | {132000, 6, 22, 15}, |
- | |
503 | {132750, 6, 28, 19}, |
- | |
504 | {133000, 6, 34, 23}, |
- | |
505 | {133330, 6, 37, 25}, |
- | |
506 | {134000, 6, 61, 41}, |
- | |
507 | {135000, 6, 21, 14}, |
- | |
508 | {135250, 6, 167, 111}, |
- | |
509 | {136000, 6, 62, 41}, |
- | |
510 | {137000, 6, 35, 23}, |
- | |
511 | {138000, 6, 23, 15}, |
- | |
512 | {138500, 6, 40, 26}, |
- | |
513 | {138750, 6, 37, 24}, |
- | |
514 | {139000, 6, 34, 22}, |
- | |
515 | {139050, 6, 34, 22}, |
- | |
516 | {139054, 6, 34, 22}, |
- | |
517 | {140000, 6, 28, 18}, |
- | |
518 | {141000, 6, 36, 23}, |
- | |
519 | {141500, 6, 22, 14}, |
- | |
520 | {142000, 6, 30, 19}, |
- | |
521 | {143000, 6, 27, 17}, |
- | |
522 | {143472, 4, 17, 16}, |
- | |
523 | {144000, 6, 24, 15}, |
- | |
524 | {145000, 6, 29, 18}, |
- | |
525 | {146000, 6, 47, 29}, |
- | |
526 | {146250, 6, 26, 16}, |
- | |
527 | {147000, 6, 49, 30}, |
- | |
528 | {147891, 6, 23, 14}, |
- | |
529 | {148000, 6, 23, 14}, |
- | |
530 | {148250, 6, 28, 17}, |
- | |
531 | {148352, 4, 100, 91}, |
- | |
532 | {148500, 6, 33, 20}, |
- | |
533 | {149000, 6, 48, 29}, |
- | |
534 | {150000, 6, 25, 15}, |
- | |
535 | {151000, 4, 19, 17}, |
- | |
536 | {152000, 6, 27, 16}, |
- | |
537 | {152280, 6, 44, 26}, |
- | |
538 | {153000, 6, 34, 20}, |
- | |
539 | {154000, 6, 53, 31}, |
- | |
540 | {155000, 6, 31, 18}, |
- | |
541 | {155250, 6, 50, 29}, |
- | |
542 | {155750, 6, 45, 26}, |
- | |
543 | {156000, 6, 26, 15}, |
- | |
544 | {157000, 6, 61, 35}, |
- | |
545 | {157500, 6, 28, 16}, |
- | |
546 | {158000, 6, 65, 37}, |
- | |
547 | {158250, 6, 44, 25}, |
- | |
548 | {159000, 6, 53, 30}, |
- | |
549 | {159500, 6, 39, 22}, |
- | |
550 | {160000, 6, 32, 18}, |
- | |
551 | {161000, 4, 31, 26}, |
- | |
552 | {162000, 4, 18, 15}, |
- | |
553 | {162162, 4, 131, 109}, |
- | |
554 | {162500, 4, 53, 44}, |
- | |
555 | {163000, 4, 29, 24}, |
- | |
556 | {164000, 4, 17, 14}, |
- | |
557 | {165000, 4, 22, 18}, |
- | |
558 | {166000, 4, 32, 26}, |
- | |
559 | {167000, 4, 26, 21}, |
- | |
560 | {168000, 4, 46, 37}, |
- | |
561 | {169000, 4, 104, 83}, |
- | |
562 | {169128, 4, 64, 51}, |
- | |
563 | {169500, 4, 39, 31}, |
- | |
564 | {170000, 4, 34, 27}, |
- | |
565 | {171000, 4, 19, 15}, |
- | |
566 | {172000, 4, 51, 40}, |
- | |
567 | {172750, 4, 32, 25}, |
- | |
568 | {172800, 4, 32, 25}, |
- | |
569 | {173000, 4, 41, 32}, |
- | |
570 | {174000, 4, 49, 38}, |
- | |
571 | {174787, 4, 22, 17}, |
- | |
572 | {175000, 4, 35, 27}, |
- | |
573 | {176000, 4, 30, 23}, |
- | |
574 | {177000, 4, 38, 29}, |
- | |
575 | {178000, 4, 29, 22}, |
- | |
576 | {178500, 4, 37, 28}, |
- | |
577 | {179000, 4, 53, 40}, |
- | |
578 | {179500, 4, 73, 55}, |
- | |
579 | {180000, 4, 20, 15}, |
- | |
580 | {181000, 4, 55, 41}, |
- | |
581 | {182000, 4, 31, 23}, |
- | |
582 | {183000, 4, 42, 31}, |
- | |
583 | {184000, 4, 30, 22}, |
- | |
584 | {184750, 4, 26, 19}, |
- | |
585 | {185000, 4, 37, 27}, |
- | |
586 | {186000, 4, 51, 37}, |
- | |
587 | {187000, 4, 36, 26}, |
- | |
588 | {188000, 4, 32, 23}, |
- | |
589 | {189000, 4, 21, 15}, |
- | |
590 | {190000, 4, 38, 27}, |
- | |
591 | {190960, 4, 41, 29}, |
- | |
592 | {191000, 4, 41, 29}, |
- | |
593 | {192000, 4, 27, 19}, |
- | |
594 | {192250, 4, 37, 26}, |
- | |
595 | {193000, 4, 20, 14}, |
- | |
596 | {193250, 4, 53, 37}, |
- | |
597 | {194000, 4, 23, 16}, |
- | |
598 | {194208, 4, 23, 16}, |
- | |
599 | {195000, 4, 26, 18}, |
- | |
600 | {196000, 4, 45, 31}, |
- | |
601 | {197000, 4, 35, 24}, |
- | |
602 | {197750, 4, 41, 28}, |
- | |
603 | {198000, 4, 22, 15}, |
- | |
604 | {198500, 4, 25, 17}, |
- | |
605 | {199000, 4, 28, 19}, |
- | |
606 | {200000, 4, 37, 25}, |
- | |
607 | {201000, 4, 61, 41}, |
- | |
608 | {202000, 4, 112, 75}, |
- | |
609 | {202500, 4, 21, 14}, |
- | |
610 | {203000, 4, 146, 97}, |
- | |
611 | {204000, 4, 62, 41}, |
- | |
612 | {204750, 4, 44, 29}, |
- | |
613 | {205000, 4, 38, 25}, |
- | |
614 | {206000, 4, 29, 19}, |
- | |
615 | {207000, 4, 23, 15}, |
- | |
616 | {207500, 4, 40, 26}, |
- | |
617 | {208000, 4, 37, 24}, |
- | |
618 | {208900, 4, 48, 31}, |
- | |
619 | {209000, 4, 48, 31}, |
- | |
620 | {209250, 4, 31, 20}, |
- | |
621 | {210000, 4, 28, 18}, |
- | |
622 | {211000, 4, 25, 16}, |
- | |
623 | {212000, 4, 22, 14}, |
- | |
624 | {213000, 4, 30, 19}, |
- | |
625 | {213750, 4, 38, 24}, |
- | |
626 | {214000, 4, 46, 29}, |
- | |
627 | {214750, 4, 35, 22}, |
- | |
628 | {215000, 4, 43, 27}, |
- | |
629 | {216000, 4, 24, 15}, |
- | |
630 | {217000, 4, 37, 23}, |
- | |
631 | {218000, 4, 42, 26}, |
- | |
632 | {218250, 4, 42, 26}, |
- | |
633 | {218750, 4, 34, 21}, |
- | |
634 | {219000, 4, 47, 29}, |
- | |
635 | {220000, 4, 44, 27}, |
- | |
636 | {220640, 4, 49, 30}, |
- | |
637 | {220750, 4, 36, 22}, |
- | |
638 | {221000, 4, 36, 22}, |
- | |
639 | {222000, 4, 23, 14}, |
- | |
640 | {222525, 4, 28, 17}, |
- | |
641 | {222750, 4, 33, 20}, |
- | |
642 | {227000, 4, 37, 22}, |
- | |
643 | {230250, 4, 29, 17}, |
- | |
644 | {233500, 4, 38, 22}, |
- | |
645 | {235000, 4, 40, 23}, |
- | |
646 | {238000, 4, 30, 17}, |
- | |
647 | {241500, 2, 17, 19}, |
- | |
648 | {245250, 2, 20, 22}, |
- | |
649 | {247750, 2, 22, 24}, |
- | |
650 | {253250, 2, 15, 16}, |
- | |
651 | {256250, 2, 18, 19}, |
- | |
652 | {262500, 2, 31, 32}, |
- | |
653 | {267250, 2, 66, 67}, |
- | |
654 | {268500, 2, 94, 95}, |
- | |
655 | {270000, 2, 14, 14}, |
- | |
656 | {272500, 2, 77, 76}, |
- | |
657 | {273750, 2, 57, 56}, |
- | |
658 | {280750, 2, 24, 23}, |
- | |
659 | {281250, 2, 23, 22}, |
- | |
660 | {286000, 2, 17, 16}, |
- | |
661 | {291750, 2, 26, 24}, |
- | |
662 | {296703, 2, 56, 51}, |
- | |
663 | {297000, 2, 22, 20}, |
- | |
664 | {298000, 2, 21, 19}, |
- | |
665 | }; |
268 | } |
666 | - | ||
667 | static void intel_ddi_mode_set(struct drm_encoder *encoder, |
- | |
668 | struct drm_display_mode *mode, |
269 | |
669 | struct drm_display_mode *adjusted_mode) |
- | |
670 | { |
270 | static void intel_ddi_mode_set(struct intel_encoder *encoder) |
671 | struct drm_crtc *crtc = encoder->crtc; |
- | |
672 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
271 | { |
673 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); |
272 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); |
674 | int port = intel_ddi_get_encoder_port(intel_encoder); |
273 | int port = intel_ddi_get_encoder_port(encoder); |
- | 274 | int pipe = crtc->pipe; |
|
Line 675... | Line 275... | ||
675 | int pipe = intel_crtc->pipe; |
275 | int type = encoder->type; |
676 | int type = intel_encoder->type; |
276 | struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode; |
Line 677... | Line 277... | ||
677 | 277 | ||
678 | DRM_DEBUG_KMS("Preparing DDI mode for Haswell on port %c, pipe %c\n", |
278 | DRM_DEBUG_KMS("Preparing DDI mode on port %c, pipe %c\n", |
679 | port_name(port), pipe_name(pipe)); |
279 | port_name(port), pipe_name(pipe)); |
680 | 280 | ||
681 | intel_crtc->eld_vld = false; |
281 | crtc->eld_vld = false; |
Line 682... | Line 282... | ||
682 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
282 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
683 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
283 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
684 | struct intel_digital_port *intel_dig_port = |
- | |
685 | enc_to_dig_port(encoder); |
- | |
686 | 284 | struct intel_digital_port *intel_dig_port = |
|
687 | intel_dp->DP = intel_dig_port->port_reversal | |
- | |
688 | DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW; |
- | |
689 | switch (intel_dp->lane_count) { |
- | |
690 | case 1: |
- | |
691 | intel_dp->DP |= DDI_PORT_WIDTH_X1; |
- | |
692 | break; |
- | |
693 | case 2: |
- | |
694 | intel_dp->DP |= DDI_PORT_WIDTH_X2; |
- | |
695 | break; |
- | |
696 | case 4: |
- | |
697 | intel_dp->DP |= DDI_PORT_WIDTH_X4; |
- | |
698 | break; |
- | |
699 | default: |
- | |
Line 700... | Line 285... | ||
700 | intel_dp->DP |= DDI_PORT_WIDTH_X4; |
285 | enc_to_dig_port(&encoder->base); |
701 | WARN(1, "Unexpected DP lane count %d\n", |
286 | |
702 | intel_dp->lane_count); |
287 | intel_dp->DP = intel_dig_port->saved_port_bits | |
Line 703... | Line 288... | ||
703 | break; |
288 | DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW; |
704 | } |
289 | intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count); |
705 | 290 | ||
706 | if (intel_dp->has_audio) { |
291 | if (intel_dp->has_audio) { |
Line 707... | Line 292... | ||
707 | DRM_DEBUG_DRIVER("DP audio on pipe %c on DDI\n", |
292 | DRM_DEBUG_DRIVER("DP audio on pipe %c on DDI\n", |
Line 708... | Line 293... | ||
708 | pipe_name(intel_crtc->pipe)); |
293 | pipe_name(crtc->pipe)); |
709 | 294 | ||
Line 710... | Line 295... | ||
710 | /* write eld */ |
295 | /* write eld */ |
711 | DRM_DEBUG_DRIVER("DP audio: write eld information\n"); |
296 | DRM_DEBUG_DRIVER("DP audio: write eld information\n"); |
712 | intel_write_eld(encoder, adjusted_mode); |
297 | intel_write_eld(&encoder->base, adjusted_mode); |
713 | } |
298 | } |
714 | 299 | ||
715 | intel_dp_init_link_config(intel_dp); |
300 | intel_dp_init_link_config(intel_dp); |
716 | 301 | ||
Line 717... | Line 302... | ||
717 | } else if (type == INTEL_OUTPUT_HDMI) { |
302 | } else if (type == INTEL_OUTPUT_HDMI) { |
718 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
303 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); |
719 | 304 | ||
720 | if (intel_hdmi->has_audio) { |
305 | if (intel_hdmi->has_audio) { |
Line 721... | Line 306... | ||
721 | /* Proper support for digital audio needs a new logic |
306 | /* Proper support for digital audio needs a new logic |
722 | * and a new set of registers, so we leave it for future |
307 | * and a new set of registers, so we leave it for future |
723 | * patch bombing. |
308 | * patch bombing. |
Line 724... | Line 309... | ||
724 | */ |
309 | */ |
725 | DRM_DEBUG_DRIVER("HDMI audio on pipe %c on DDI\n", |
310 | DRM_DEBUG_DRIVER("HDMI audio on pipe %c on DDI\n", |
Line 746... | Line 331... | ||
746 | ret = intel_encoder; |
331 | ret = intel_encoder; |
747 | num_encoders++; |
332 | num_encoders++; |
748 | } |
333 | } |
Line 749... | Line 334... | ||
749 | 334 | ||
750 | if (num_encoders != 1) |
335 | if (num_encoders != 1) |
751 | WARN(1, "%d encoders on crtc for pipe %d\n", num_encoders, |
336 | WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders, |
Line 752... | Line 337... | ||
752 | intel_crtc->pipe); |
337 | pipe_name(intel_crtc->pipe)); |
753 | 338 | ||
754 | BUG_ON(ret == NULL); |
339 | BUG_ON(ret == NULL); |
Line 800... | Line 385... | ||
800 | WARN(plls->wrpll2_refcount < 0, "Invalid WRPLL2 refcount\n"); |
385 | WARN(plls->wrpll2_refcount < 0, "Invalid WRPLL2 refcount\n"); |
Line 801... | Line 386... | ||
801 | 386 | ||
802 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE; |
387 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE; |
Line -... | Line 388... | ||
- | 388 | } |
|
- | 389 | ||
- | 390 | #define LC_FREQ 2700 |
|
- | 391 | #define LC_FREQ_2K (LC_FREQ * 2000) |
|
- | 392 | ||
- | 393 | #define P_MIN 2 |
|
- | 394 | #define P_MAX 64 |
|
- | 395 | #define P_INC 2 |
|
- | 396 | ||
- | 397 | /* Constraints for PLL good behavior */ |
|
- | 398 | #define REF_MIN 48 |
|
- | 399 | #define REF_MAX 400 |
|
- | 400 | #define VCO_MIN 2400 |
|
- | 401 | #define VCO_MAX 4800 |
|
- | 402 | ||
- | 403 | #define ABS_DIFF(a, b) ((a > b) ? (a - b) : (b - a)) |
|
- | 404 | ||
- | 405 | struct wrpll_rnp { |
|
- | 406 | unsigned p, n2, r2; |
|
803 | } |
407 | }; |
804 | 408 | ||
805 | static void intel_ddi_calculate_wrpll(int clock, int *p, int *n2, int *r2) |
409 | static unsigned wrpll_get_budget_for_freq(int clock) |
Line 806... | Line 410... | ||
806 | { |
410 | { |
- | 411 | unsigned budget; |
|
- | 412 | ||
- | 413 | switch (clock) { |
|
- | 414 | case 25175000: |
|
- | 415 | case 25200000: |
|
- | 416 | case 27000000: |
|
- | 417 | case 27027000: |
|
- | 418 | case 37762500: |
|
- | 419 | case 37800000: |
|
- | 420 | case 40500000: |
|
- | 421 | case 40541000: |
|
- | 422 | case 54000000: |
|
- | 423 | case 54054000: |
|
- | 424 | case 59341000: |
|
- | 425 | case 59400000: |
|
- | 426 | case 72000000: |
|
- | 427 | case 74176000: |
|
- | 428 | case 74250000: |
|
- | 429 | case 81000000: |
|
- | 430 | case 81081000: |
|
- | 431 | case 89012000: |
|
- | 432 | case 89100000: |
|
- | 433 | case 108000000: |
|
- | 434 | case 108108000: |
|
- | 435 | case 111264000: |
|
- | 436 | case 111375000: |
|
- | 437 | case 148352000: |
|
- | 438 | case 148500000: |
|
- | 439 | case 162000000: |
|
- | 440 | case 162162000: |
|
- | 441 | case 222525000: |
|
- | 442 | case 222750000: |
|
- | 443 | case 296703000: |
|
- | 444 | case 297000000: |
|
- | 445 | budget = 0; |
|
- | 446 | break; |
|
- | 447 | case 233500000: |
|
- | 448 | case 245250000: |
|
- | 449 | case 247750000: |
|
- | 450 | case 253250000: |
|
- | 451 | case 298000000: |
|
- | 452 | budget = 1500; |
|
- | 453 | break; |
|
- | 454 | case 169128000: |
|
- | 455 | case 169500000: |
|
- | 456 | case 179500000: |
|
- | 457 | case 202000000: |
|
- | 458 | budget = 2000; |
|
- | 459 | break; |
|
- | 460 | case 256250000: |
|
- | 461 | case 262500000: |
|
- | 462 | case 270000000: |
|
- | 463 | case 272500000: |
|
- | 464 | case 273750000: |
|
- | 465 | case 280750000: |
|
- | 466 | case 281250000: |
|
- | 467 | case 286000000: |
|
- | 468 | case 291750000: |
|
- | 469 | budget = 4000; |
|
- | 470 | break; |
|
- | 471 | case 267250000: |
|
- | 472 | case 268500000: |
|
807 | u32 i; |
473 | budget = 5000; |
808 | 474 | break; |
|
- | 475 | default: |
|
Line 809... | Line 476... | ||
809 | for (i = 0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++) |
476 | budget = 1000; |
810 | if (clock <= wrpll_tmds_clock_table[i].clock) |
477 | break; |
Line -... | Line 478... | ||
- | 478 | } |
|
811 | break; |
479 | |
812 | 480 | return budget; |
|
- | 481 | } |
|
813 | if (i == ARRAY_SIZE(wrpll_tmds_clock_table)) |
482 | |
Line 814... | Line 483... | ||
814 | i--; |
483 | static void wrpll_update_rnp(uint64_t freq2k, unsigned budget, |
815 | 484 | unsigned r2, unsigned n2, unsigned p, |
|
- | 485 | struct wrpll_rnp *best) |
|
- | 486 | { |
|
816 | *p = wrpll_tmds_clock_table[i].p; |
487 | uint64_t a, b, c, d, diff, diff_best; |
- | 488 | ||
- | 489 | /* No best (r,n,p) yet */ |
|
Line -... | Line 490... | ||
- | 490 | if (best->p == 0) { |
|
- | 491 | best->p = p; |
|
- | 492 | best->n2 = n2; |
|
- | 493 | best->r2 = r2; |
|
- | 494 | return; |
|
- | 495 | } |
|
- | 496 | ||
- | 497 | /* |
|
- | 498 | * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to |
|
- | 499 | * freq2k. |
|
- | 500 | * |
|
- | 501 | * delta = 1e6 * |
|
- | 502 | * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) / |
|
- | 503 | * freq2k; |
|
- | 504 | * |
|
- | 505 | * and we would like delta <= budget. |
|
- | 506 | * |
|
- | 507 | * If the discrepancy is above the PPM-based budget, always prefer to |
|
- | 508 | * improve upon the previous solution. However, if you're within the |
|
- | 509 | * budget, try to maximize Ref * VCO, that is N / (P * R^2). |
|
- | 510 | */ |
|
- | 511 | a = freq2k * budget * p * r2; |
|
- | 512 | b = freq2k * budget * best->p * best->r2; |
|
- | 513 | diff = ABS_DIFF((freq2k * p * r2), (LC_FREQ_2K * n2)); |
|
- | 514 | diff_best = ABS_DIFF((freq2k * best->p * best->r2), |
|
- | 515 | (LC_FREQ_2K * best->n2)); |
|
- | 516 | c = 1000000 * diff; |
|
- | 517 | d = 1000000 * diff_best; |
|
- | 518 | ||
- | 519 | if (a < c && b < d) { |
|
- | 520 | /* If both are above the budget, pick the closer */ |
|
- | 521 | if (best->p * best->r2 * diff < p * r2 * diff_best) { |
|
- | 522 | best->p = p; |
|
- | 523 | best->n2 = n2; |
|
- | 524 | best->r2 = r2; |
|
817 | *n2 = wrpll_tmds_clock_table[i].n2; |
525 | } |
- | 526 | } else if (a >= c && b < d) { |
|
- | 527 | /* If A is below the threshold but B is above it? Update. */ |
|
- | 528 | best->p = p; |
|
- | 529 | best->n2 = n2; |
|
- | 530 | best->r2 = r2; |
|
- | 531 | } else if (a >= c && b >= d) { |
|
- | 532 | /* Both are below the limit, so pick the higher n2/(r2*r2) */ |
|
- | 533 | if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) { |
|
- | 534 | best->p = p; |
|
- | 535 | best->n2 = n2; |
|
- | 536 | best->r2 = r2; |
|
- | 537 | } |
|
- | 538 | } |
|
- | 539 | /* Otherwise a < c && b >= d, do nothing */ |
|
818 | *r2 = wrpll_tmds_clock_table[i].r2; |
540 | } |
- | 541 | ||
- | 542 | static void |
|
- | 543 | intel_ddi_calculate_wrpll(int clock /* in Hz */, |
|
- | 544 | unsigned *r2_out, unsigned *n2_out, unsigned *p_out) |
|
- | 545 | { |
|
- | 546 | uint64_t freq2k; |
|
- | 547 | unsigned p, n2, r2; |
|
- | 548 | struct wrpll_rnp best = { 0, 0, 0 }; |
|
- | 549 | unsigned budget; |
|
- | 550 | ||
- | 551 | freq2k = clock / 100; |
|
- | 552 | ||
- | 553 | budget = wrpll_get_budget_for_freq(clock); |
|
- | 554 | ||
819 | 555 | /* Special case handling for 540 pixel clock: bypass WR PLL entirely |
|
Line -... | Line 556... | ||
- | 556 | * and directly pass the LC PLL to it. */ |
|
- | 557 | if (freq2k == 5400000) { |
|
- | 558 | *n2_out = 2; |
|
- | 559 | *p_out = 1; |
|
- | 560 | *r2_out = 2; |
|
- | 561 | return; |
|
- | 562 | } |
|
- | 563 | ||
- | 564 | /* |
|
- | 565 | * Ref = LC_FREQ / R, where Ref is the actual reference input seen by |
|
- | 566 | * the WR PLL. |
|
- | 567 | * |
|
- | 568 | * We want R so that REF_MIN <= Ref <= REF_MAX. |
|
- | 569 | * Injecting R2 = 2 * R gives: |
|
- | 570 | * REF_MAX * r2 > LC_FREQ * 2 and |
|
- | 571 | * REF_MIN * r2 < LC_FREQ * 2 |
|
- | 572 | * |
|
- | 573 | * Which means the desired boundaries for r2 are: |
|
- | 574 | * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN |
|
- | 575 | * |
|
- | 576 | */ |
|
- | 577 | for (r2 = LC_FREQ * 2 / REF_MAX + 1; |
|
- | 578 | r2 <= LC_FREQ * 2 / REF_MIN; |
|
- | 579 | r2++) { |
|
- | 580 | ||
- | 581 | /* |
|
- | 582 | * VCO = N * Ref, that is: VCO = N * LC_FREQ / R |
|
- | 583 | * |
|
- | 584 | * Once again we want VCO_MIN <= VCO <= VCO_MAX. |
|
- | 585 | * Injecting R2 = 2 * R and N2 = 2 * N, we get: |
|
- | 586 | * VCO_MAX * r2 > n2 * LC_FREQ and |
|
- | 587 | * VCO_MIN * r2 < n2 * LC_FREQ) |
|
- | 588 | * |
|
- | 589 | * Which means the desired boundaries for n2 are: |
|
- | 590 | * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ |
|
- | 591 | */ |
|
- | 592 | for (n2 = VCO_MIN * r2 / LC_FREQ + 1; |
|
- | 593 | n2 <= VCO_MAX * r2 / LC_FREQ; |
|
- | 594 | n2++) { |
|
- | 595 | ||
- | 596 | for (p = P_MIN; p <= P_MAX; p += P_INC) |
|
- | 597 | wrpll_update_rnp(freq2k, budget, |
|
- | 598 | r2, n2, p, &best); |
|
- | 599 | } |
|
- | 600 | } |
|
- | 601 | ||
820 | if (wrpll_tmds_clock_table[i].clock != clock) |
602 | *n2_out = best.n2; |
821 | DRM_INFO("WRPLL: using settings for %dKHz on %dKHz mode\n", |
603 | *p_out = best.p; |
822 | wrpll_tmds_clock_table[i].clock, clock); |
604 | *r2_out = best.r2; |
823 | 605 | ||
824 | DRM_DEBUG_KMS("WRPLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n", |
606 | DRM_DEBUG_KMS("WRPLL: %dHz refresh rate with p=%d, n2=%d r2=%d\n", |
825 | clock, *p, *n2, *r2); |
607 | clock, *p_out, *n2_out, *r2_out); |
826 | } |
608 | } |
827 | 609 | ||
828 | bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock) |
610 | bool intel_ddi_pll_mode_set(struct drm_crtc *crtc) |
829 | { |
611 | { |
- | 612 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
Line 830... | Line 613... | ||
830 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
613 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
Line 831... | Line 614... | ||
831 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
614 | struct drm_encoder *encoder = &intel_encoder->base; |
Line 861... | Line 644... | ||
861 | 644 | ||
862 | /* We don't need to turn any PLL on because we'll use LCPLL. */ |
645 | /* We don't need to turn any PLL on because we'll use LCPLL. */ |
Line 863... | Line 646... | ||
863 | return true; |
646 | return true; |
864 | 647 | ||
Line 865... | Line 648... | ||
865 | } else if (type == INTEL_OUTPUT_HDMI) { |
648 | } else if (type == INTEL_OUTPUT_HDMI) { |
866 | int p, n2, r2; |
649 | unsigned p, n2, r2; |
867 | 650 | ||
868 | if (plls->wrpll1_refcount == 0) { |
651 | if (plls->wrpll1_refcount == 0) { |
Line 883... | Line 666... | ||
883 | } |
666 | } |
Line 884... | Line 667... | ||
884 | 667 | ||
885 | WARN(I915_READ(reg) & WRPLL_PLL_ENABLE, |
668 | WARN(I915_READ(reg) & WRPLL_PLL_ENABLE, |
Line 886... | Line 669... | ||
886 | "WRPLL already enabled\n"); |
669 | "WRPLL already enabled\n"); |
Line 887... | Line 670... | ||
887 | 670 | ||
888 | intel_ddi_calculate_wrpll(clock, &p, &n2, &r2); |
671 | intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p); |
889 | 672 | ||
Line 993... | Line 776... | ||
993 | switch (pipe) { |
776 | switch (pipe) { |
994 | case PIPE_A: |
777 | case PIPE_A: |
995 | /* Can only use the always-on power well for eDP when |
778 | /* Can only use the always-on power well for eDP when |
996 | * not using the panel fitter, and when not using motion |
779 | * not using the panel fitter, and when not using motion |
997 | * blur mitigation (which we don't support). */ |
780 | * blur mitigation (which we don't support). */ |
998 | if (dev_priv->pch_pf_size) |
781 | if (intel_crtc->config.pch_pfit.enabled) |
999 | temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; |
782 | temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; |
1000 | else |
783 | else |
1001 | temp |= TRANS_DDI_EDP_INPUT_A_ON; |
784 | temp |= TRANS_DDI_EDP_INPUT_A_ON; |
1002 | break; |
785 | break; |
1003 | case PIPE_B: |
786 | case PIPE_B: |
Line 1020... | Line 803... | ||
1020 | else |
803 | else |
1021 | temp |= TRANS_DDI_MODE_SELECT_DVI; |
804 | temp |= TRANS_DDI_MODE_SELECT_DVI; |
Line 1022... | Line 805... | ||
1022 | 805 | ||
1023 | } else if (type == INTEL_OUTPUT_ANALOG) { |
806 | } else if (type == INTEL_OUTPUT_ANALOG) { |
1024 | temp |= TRANS_DDI_MODE_SELECT_FDI; |
807 | temp |= TRANS_DDI_MODE_SELECT_FDI; |
Line 1025... | Line 808... | ||
1025 | temp |= (intel_crtc->fdi_lanes - 1) << 1; |
808 | temp |= (intel_crtc->config.fdi_lanes - 1) << 1; |
1026 | 809 | ||
1027 | } else if (type == INTEL_OUTPUT_DISPLAYPORT || |
810 | } else if (type == INTEL_OUTPUT_DISPLAYPORT || |
Line 1028... | Line 811... | ||
1028 | type == INTEL_OUTPUT_EDP) { |
811 | type == INTEL_OUTPUT_EDP) { |
Line 1029... | Line -... | ||
1029 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
- | |
1030 | - | ||
1031 | temp |= TRANS_DDI_MODE_SELECT_DP_SST; |
- | |
1032 | - | ||
1033 | switch (intel_dp->lane_count) { |
- | |
1034 | case 1: |
- | |
1035 | temp |= TRANS_DDI_PORT_WIDTH_X1; |
- | |
1036 | break; |
- | |
1037 | case 2: |
- | |
1038 | temp |= TRANS_DDI_PORT_WIDTH_X2; |
- | |
1039 | break; |
- | |
1040 | case 4: |
- | |
1041 | temp |= TRANS_DDI_PORT_WIDTH_X4; |
- | |
1042 | break; |
812 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1043 | default: |
- | |
1044 | temp |= TRANS_DDI_PORT_WIDTH_X4; |
- | |
1045 | WARN(1, "Unsupported lane count %d\n", |
813 | |
1046 | intel_dp->lane_count); |
814 | temp |= TRANS_DDI_MODE_SELECT_DP_SST; |
1047 | } |
815 | |
1048 | 816 | temp |= DDI_PORT_WIDTH(intel_dp->lane_count); |
|
Line 1049... | Line 817... | ||
1049 | } else { |
817 | } else { |
1050 | WARN(1, "Invalid encoder type %d for pipe %d\n", |
818 | WARN(1, "Invalid encoder type %d for pipe %c\n", |
Line 1146... | Line 914... | ||
1146 | return true; |
914 | return true; |
1147 | } |
915 | } |
1148 | } |
916 | } |
1149 | } |
917 | } |
Line 1150... | Line 918... | ||
1150 | 918 | ||
Line 1151... | Line 919... | ||
1151 | DRM_DEBUG_KMS("No pipe for ddi port %i found\n", port); |
919 | DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port)); |
1152 | 920 | ||
Line 1153... | Line 921... | ||
1153 | return false; |
921 | return false; |
Line 1322... | Line 1090... | ||
1322 | /* In HDMI/DVI mode, the port width, and swing/emphasis values |
1090 | /* In HDMI/DVI mode, the port width, and swing/emphasis values |
1323 | * are ignored so nothing special needs to be done besides |
1091 | * are ignored so nothing special needs to be done besides |
1324 | * enabling the port. |
1092 | * enabling the port. |
1325 | */ |
1093 | */ |
1326 | I915_WRITE(DDI_BUF_CTL(port), |
1094 | I915_WRITE(DDI_BUF_CTL(port), |
1327 | intel_dig_port->port_reversal | DDI_BUF_CTL_ENABLE); |
1095 | intel_dig_port->saved_port_bits | |
- | 1096 | DDI_BUF_CTL_ENABLE); |
|
1328 | } else if (type == INTEL_OUTPUT_EDP) { |
1097 | } else if (type == INTEL_OUTPUT_EDP) { |
1329 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1098 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
Line 1330... | Line 1099... | ||
1330 | 1099 | ||
1331 | if (port == PORT_A) |
1100 | if (port == PORT_A) |
Line 1332... | Line 1101... | ||
1332 | intel_dp_stop_link_train(intel_dp); |
1101 | intel_dp_stop_link_train(intel_dp); |
- | 1102 | ||
1333 | 1103 | ironlake_edp_backlight_on(intel_dp); |
|
Line 1334... | Line 1104... | ||
1334 | ironlake_edp_backlight_on(intel_dp); |
1104 | intel_edp_psr_enable(intel_dp); |
1335 | } |
1105 | } |
1336 | 1106 | ||
1337 | if (intel_crtc->eld_vld) { |
1107 | if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) { |
1338 | tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); |
1108 | tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); |
1339 | tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); |
1109 | tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); |
Line 1350... | Line 1120... | ||
1350 | int type = intel_encoder->type; |
1120 | int type = intel_encoder->type; |
1351 | struct drm_device *dev = encoder->dev; |
1121 | struct drm_device *dev = encoder->dev; |
1352 | struct drm_i915_private *dev_priv = dev->dev_private; |
1122 | struct drm_i915_private *dev_priv = dev->dev_private; |
1353 | uint32_t tmp; |
1123 | uint32_t tmp; |
Line -... | Line 1124... | ||
- | 1124 | ||
1354 | 1125 | if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) { |
|
1355 | tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); |
1126 | tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); |
- | 1127 | tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << |
|
1356 | tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); |
1128 | (pipe * 4)); |
- | 1129 | I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); |
|
Line 1357... | Line 1130... | ||
1357 | I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); |
1130 | } |
1358 | 1131 | ||
Line -... | Line 1132... | ||
- | 1132 | if (type == INTEL_OUTPUT_EDP) { |
|
1359 | if (type == INTEL_OUTPUT_EDP) { |
1133 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1360 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1134 | |
1361 | 1135 | intel_edp_psr_disable(intel_dp); |
|
Line 1362... | Line 1136... | ||
1362 | ironlake_edp_backlight_off(intel_dp); |
1136 | ironlake_edp_backlight_off(intel_dp); |
1363 | } |
1137 | } |
- | 1138 | } |
|
- | 1139 | ||
- | 1140 | int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) |
|
- | 1141 | { |
|
1364 | } |
1142 | uint32_t lcpll = I915_READ(LCPLL_CTL); |
1365 | 1143 | ||
1366 | int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) |
1144 | if (lcpll & LCPLL_CD_SOURCE_FCLK) |
1367 | { |
- | |
1368 | if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) |
1145 | return 800000; |
1369 | return 450; |
1146 | else if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) |
1370 | else if ((I915_READ(LCPLL_CTL) & LCPLL_CLK_FREQ_MASK) == |
1147 | return 450000; |
1371 | LCPLL_CLK_FREQ_450) |
1148 | else if ((lcpll & LCPLL_CLK_FREQ_MASK) == LCPLL_CLK_FREQ_450) |
1372 | return 450; |
1149 | return 450000; |
1373 | else if (IS_ULT(dev_priv->dev)) |
1150 | else if (IS_ULT(dev_priv->dev)) |
Line 1374... | Line 1151... | ||
1374 | return 338; |
1151 | return 337500; |
1375 | else |
1152 | else |
1376 | return 540; |
1153 | return 540000; |
Line 1384... | Line 1161... | ||
1384 | /* The LCPLL register should be turned on by the BIOS. For now let's |
1161 | /* The LCPLL register should be turned on by the BIOS. For now let's |
1385 | * just check its state and print errors in case something is wrong. |
1162 | * just check its state and print errors in case something is wrong. |
1386 | * Don't even try to turn it on. |
1163 | * Don't even try to turn it on. |
1387 | */ |
1164 | */ |
Line 1388... | Line 1165... | ||
1388 | 1165 | ||
1389 | DRM_DEBUG_KMS("CDCLK running at %dMHz\n", |
1166 | DRM_DEBUG_KMS("CDCLK running at %dKHz\n", |
Line 1390... | Line 1167... | ||
1390 | intel_ddi_get_cdclk_freq(dev_priv)); |
1167 | intel_ddi_get_cdclk_freq(dev_priv)); |
1391 | 1168 | ||
Line 1470... | Line 1247... | ||
1470 | 1247 | ||
1471 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) |
1248 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) |
1472 | intel_dp_check_link_status(intel_dp); |
1249 | intel_dp_check_link_status(intel_dp); |
Line -... | Line 1250... | ||
- | 1250 | } |
|
- | 1251 | ||
- | 1252 | static void intel_ddi_get_config(struct intel_encoder *encoder, |
|
- | 1253 | struct intel_crtc_config *pipe_config) |
|
- | 1254 | { |
|
- | 1255 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
|
- | 1256 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
|
- | 1257 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
|
- | 1258 | u32 temp, flags = 0; |
|
- | 1259 | ||
- | 1260 | temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); |
|
- | 1261 | if (temp & TRANS_DDI_PHSYNC) |
|
- | 1262 | flags |= DRM_MODE_FLAG_PHSYNC; |
|
- | 1263 | else |
|
- | 1264 | flags |= DRM_MODE_FLAG_NHSYNC; |
|
- | 1265 | if (temp & TRANS_DDI_PVSYNC) |
|
- | 1266 | flags |= DRM_MODE_FLAG_PVSYNC; |
|
- | 1267 | else |
|
- | 1268 | flags |= DRM_MODE_FLAG_NVSYNC; |
|
- | 1269 | ||
- | 1270 | pipe_config->adjusted_mode.flags |= flags; |
|
1473 | } |
1271 | } |
1474 | 1272 | ||
1475 | static void intel_ddi_destroy(struct drm_encoder *encoder) |
1273 | static void intel_ddi_destroy(struct drm_encoder *encoder) |
1476 | { |
1274 | { |
1477 | /* HDMI has nothing special to destroy, so we can go with this. */ |
1275 | /* HDMI has nothing special to destroy, so we can go with this. */ |
Line 1478... | Line 1276... | ||
1478 | intel_dp_encoder_destroy(encoder); |
1276 | intel_dp_encoder_destroy(encoder); |
1479 | } |
1277 | } |
1480 | 1278 | ||
1481 | static bool intel_ddi_compute_config(struct intel_encoder *encoder, |
1279 | static bool intel_ddi_compute_config(struct intel_encoder *encoder, |
- | 1280 | struct intel_crtc_config *pipe_config) |
|
Line 1482... | Line 1281... | ||
1482 | struct intel_crtc_config *pipe_config) |
1281 | { |
Line -... | Line 1282... | ||
- | 1282 | int type = encoder->type; |
|
- | 1283 | int port = intel_ddi_get_encoder_port(encoder); |
|
- | 1284 | ||
1483 | { |
1285 | WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); |
1484 | int type = encoder->type; |
1286 | |
1485 | 1287 | if (port == PORT_A) |
|
1486 | WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); |
1288 | pipe_config->cpu_transcoder = TRANSCODER_EDP; |
1487 | 1289 | ||
Line 1488... | Line 1290... | ||
1488 | if (type == INTEL_OUTPUT_HDMI) |
1290 | if (type == INTEL_OUTPUT_HDMI) |
1489 | return intel_hdmi_compute_config(encoder, pipe_config); |
1291 | return intel_hdmi_compute_config(encoder, pipe_config); |
1490 | else |
1292 | else |
Line 1491... | Line -... | ||
1491 | return intel_dp_compute_config(encoder, pipe_config); |
- | |
1492 | } |
- | |
1493 | - | ||
1494 | static const struct drm_encoder_funcs intel_ddi_funcs = { |
- | |
1495 | .destroy = intel_ddi_destroy, |
1293 | return intel_dp_compute_config(encoder, pipe_config); |
1496 | }; |
1294 | } |
1497 | 1295 | ||
1498 | static const struct drm_encoder_helper_funcs intel_ddi_helper_funcs = { |
1296 | static const struct drm_encoder_funcs intel_ddi_funcs = { |
1499 | .mode_set = intel_ddi_mode_set, |
1297 | .destroy = intel_ddi_destroy, |
Line 1516... | Line 1314... | ||
1516 | if (!dp_connector) { |
1314 | if (!dp_connector) { |
1517 | kfree(intel_dig_port); |
1315 | kfree(intel_dig_port); |
1518 | return; |
1316 | return; |
1519 | } |
1317 | } |
Line 1520... | Line -... | ||
1520 | - | ||
1521 | if (port != PORT_A) { |
- | |
1522 | hdmi_connector = kzalloc(sizeof(struct intel_connector), |
- | |
1523 | GFP_KERNEL); |
- | |
1524 | if (!hdmi_connector) { |
- | |
1525 | kfree(dp_connector); |
- | |
1526 | kfree(intel_dig_port); |
- | |
1527 | return; |
- | |
1528 | } |
- | |
1529 | } |
- | |
1530 | 1318 | ||
1531 | intel_encoder = &intel_dig_port->base; |
1319 | intel_encoder = &intel_dig_port->base; |
Line 1532... | Line 1320... | ||
1532 | encoder = &intel_encoder->base; |
1320 | encoder = &intel_encoder->base; |
1533 | 1321 | ||
1534 | drm_encoder_init(dev, encoder, &intel_ddi_funcs, |
- | |
Line 1535... | Line 1322... | ||
1535 | DRM_MODE_ENCODER_TMDS); |
1322 | drm_encoder_init(dev, encoder, &intel_ddi_funcs, |
- | 1323 | DRM_MODE_ENCODER_TMDS); |
|
1536 | drm_encoder_helper_add(encoder, &intel_ddi_helper_funcs); |
1324 | |
1537 | 1325 | intel_encoder->compute_config = intel_ddi_compute_config; |
|
1538 | intel_encoder->compute_config = intel_ddi_compute_config; |
1326 | intel_encoder->mode_set = intel_ddi_mode_set; |
1539 | intel_encoder->enable = intel_enable_ddi; |
1327 | intel_encoder->enable = intel_enable_ddi; |
1540 | intel_encoder->pre_enable = intel_ddi_pre_enable; |
1328 | intel_encoder->pre_enable = intel_ddi_pre_enable; |
- | 1329 | intel_encoder->disable = intel_disable_ddi; |
|
Line 1541... | Line 1330... | ||
1541 | intel_encoder->disable = intel_disable_ddi; |
1330 | intel_encoder->post_disable = intel_ddi_post_disable; |
1542 | intel_encoder->post_disable = intel_ddi_post_disable; |
1331 | intel_encoder->get_hw_state = intel_ddi_get_hw_state; |
1543 | intel_encoder->get_hw_state = intel_ddi_get_hw_state; |
1332 | intel_encoder->get_config = intel_ddi_get_config; |
1544 | 1333 | ||
1545 | intel_dig_port->port = port; |
- | |
1546 | intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) & |
1334 | intel_dig_port->port = port; |
Line 1547... | Line 1335... | ||
1547 | DDI_BUF_PORT_REVERSAL; |
1335 | intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & |
1548 | if (hdmi_connector) |
1336 | (DDI_BUF_PORT_REVERSAL | |
1549 | intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port); |
1337 | DDI_A_4_LANES); |
1550 | intel_dig_port->dp.output_reg = DDI_BUF_CTL(port); |
1338 | intel_dig_port->dp.output_reg = DDI_BUF_CTL(port); |
Line -... | Line 1339... | ||
- | 1339 | ||
- | 1340 | intel_encoder->type = INTEL_OUTPUT_UNKNOWN; |
|
- | 1341 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
|
- | 1342 | intel_encoder->cloneable = false; |
|
- | 1343 | intel_encoder->hot_plug = intel_ddi_hot_plug; |
|
- | 1344 | ||
- | 1345 | if (!intel_dp_init_connector(intel_dig_port, dp_connector)) { |
|
- | 1346 | drm_encoder_cleanup(encoder); |
|
- | 1347 | kfree(intel_dig_port); |
|
- | 1348 | kfree(dp_connector); |
|
1551 | 1349 | return; |
|
- | 1350 | } |
|
- | 1351 | ||
- | 1352 | if (intel_encoder->type != INTEL_OUTPUT_EDP) { |
|
- | 1353 | hdmi_connector = kzalloc(sizeof(struct intel_connector), |
|
1552 | intel_encoder->type = INTEL_OUTPUT_UNKNOWN; |
1354 | GFP_KERNEL); |
1553 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
- | |
- | 1355 | if (!hdmi_connector) { |
|
1554 | intel_encoder->cloneable = false; |
1356 | return; |