aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_ddi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ddi.c')
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c344
1 files changed, 206 insertions, 138 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 5db0b5552e39..b63d4fa204a3 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -28,87 +28,103 @@
28#include "i915_drv.h" 28#include "i915_drv.h"
29#include "intel_drv.h" 29#include "intel_drv.h"
30 30
31struct ddi_buf_trans {
32 u32 trans1; /* balance leg enable, de-emph level */
33 u32 trans2; /* vref sel, vswing */
34};
35
31/* HDMI/DVI modes ignore everything but the last 2 items. So we share 36/* 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 37 * them for both DP and FDI transports, allowing those ports to
33 * automatically adapt to HDMI connections as well 38 * automatically adapt to HDMI connections as well
34 */ 39 */
35static const u32 hsw_ddi_translations_dp[] = { 40static const struct ddi_buf_trans hsw_ddi_translations_dp[] = {
36 0x00FFFFFF, 0x0006000E, /* DP parameters */ 41 { 0x00FFFFFF, 0x0006000E },
37 0x00D75FFF, 0x0005000A, 42 { 0x00D75FFF, 0x0005000A },
38 0x00C30FFF, 0x00040006, 43 { 0x00C30FFF, 0x00040006 },
39 0x80AAAFFF, 0x000B0000, 44 { 0x80AAAFFF, 0x000B0000 },
40 0x00FFFFFF, 0x0005000A, 45 { 0x00FFFFFF, 0x0005000A },
41 0x00D75FFF, 0x000C0004, 46 { 0x00D75FFF, 0x000C0004 },
42 0x80C30FFF, 0x000B0000, 47 { 0x80C30FFF, 0x000B0000 },
43 0x00FFFFFF, 0x00040006, 48 { 0x00FFFFFF, 0x00040006 },
44 0x80D75FFF, 0x000B0000, 49 { 0x80D75FFF, 0x000B0000 },
45}; 50};
46 51
47static const u32 hsw_ddi_translations_fdi[] = { 52static const struct ddi_buf_trans hsw_ddi_translations_fdi[] = {
48 0x00FFFFFF, 0x0007000E, /* FDI parameters */ 53 { 0x00FFFFFF, 0x0007000E },
49 0x00D75FFF, 0x000F000A, 54 { 0x00D75FFF, 0x000F000A },
50 0x00C30FFF, 0x00060006, 55 { 0x00C30FFF, 0x00060006 },
51 0x00AAAFFF, 0x001E0000, 56 { 0x00AAAFFF, 0x001E0000 },
52 0x00FFFFFF, 0x000F000A, 57 { 0x00FFFFFF, 0x000F000A },
53 0x00D75FFF, 0x00160004, 58 { 0x00D75FFF, 0x00160004 },
54 0x00C30FFF, 0x001E0000, 59 { 0x00C30FFF, 0x001E0000 },
55 0x00FFFFFF, 0x00060006, 60 { 0x00FFFFFF, 0x00060006 },
56 0x00D75FFF, 0x001E0000, 61 { 0x00D75FFF, 0x001E0000 },
57}; 62};
58 63
59static const u32 hsw_ddi_translations_hdmi[] = { 64static const struct ddi_buf_trans hsw_ddi_translations_hdmi[] = {
60 /* Idx NT mV diff T mV diff db */ 65 /* Idx NT mV d T mV d db */
61 0x00FFFFFF, 0x0006000E, /* 0: 400 400 0 */ 66 { 0x00FFFFFF, 0x0006000E }, /* 0: 400 400 0 */
62 0x00E79FFF, 0x000E000C, /* 1: 400 500 2 */ 67 { 0x00E79FFF, 0x000E000C }, /* 1: 400 500 2 */
63 0x00D75FFF, 0x0005000A, /* 2: 400 600 3.5 */ 68 { 0x00D75FFF, 0x0005000A }, /* 2: 400 600 3.5 */
64 0x00FFFFFF, 0x0005000A, /* 3: 600 600 0 */ 69 { 0x00FFFFFF, 0x0005000A }, /* 3: 600 600 0 */
65 0x00E79FFF, 0x001D0007, /* 4: 600 750 2 */ 70 { 0x00E79FFF, 0x001D0007 }, /* 4: 600 750 2 */
66 0x00D75FFF, 0x000C0004, /* 5: 600 900 3.5 */ 71 { 0x00D75FFF, 0x000C0004 }, /* 5: 600 900 3.5 */
67 0x00FFFFFF, 0x00040006, /* 6: 800 800 0 */ 72 { 0x00FFFFFF, 0x00040006 }, /* 6: 800 800 0 */
68 0x80E79FFF, 0x00030002, /* 7: 800 1000 2 */ 73 { 0x80E79FFF, 0x00030002 }, /* 7: 800 1000 2 */
69 0x00FFFFFF, 0x00140005, /* 8: 850 850 0 */ 74 { 0x00FFFFFF, 0x00140005 }, /* 8: 850 850 0 */
70 0x00FFFFFF, 0x000C0004, /* 9: 900 900 0 */ 75 { 0x00FFFFFF, 0x000C0004 }, /* 9: 900 900 0 */
71 0x00FFFFFF, 0x001C0003, /* 10: 950 950 0 */ 76 { 0x00FFFFFF, 0x001C0003 }, /* 10: 950 950 0 */
72 0x80FFFFFF, 0x00030002, /* 11: 1000 1000 0 */ 77 { 0x80FFFFFF, 0x00030002 }, /* 11: 1000 1000 0 */
73}; 78};
74 79
75static const u32 bdw_ddi_translations_edp[] = { 80static const struct ddi_buf_trans bdw_ddi_translations_edp[] = {
76 0x00FFFFFF, 0x00000012, /* eDP parameters */ 81 { 0x00FFFFFF, 0x00000012 },
77 0x00EBAFFF, 0x00020011, 82 { 0x00EBAFFF, 0x00020011 },
78 0x00C71FFF, 0x0006000F, 83 { 0x00C71FFF, 0x0006000F },
79 0x00AAAFFF, 0x000E000A, 84 { 0x00AAAFFF, 0x000E000A },
80 0x00FFFFFF, 0x00020011, 85 { 0x00FFFFFF, 0x00020011 },
81 0x00DB6FFF, 0x0005000F, 86 { 0x00DB6FFF, 0x0005000F },
82 0x00BEEFFF, 0x000A000C, 87 { 0x00BEEFFF, 0x000A000C },
83 0x00FFFFFF, 0x0005000F, 88 { 0x00FFFFFF, 0x0005000F },
84 0x00DB6FFF, 0x000A000C, 89 { 0x00DB6FFF, 0x000A000C },
85 0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/
86}; 90};
87 91
88static const u32 bdw_ddi_translations_dp[] = { 92static const struct ddi_buf_trans bdw_ddi_translations_dp[] = {
89 0x00FFFFFF, 0x0007000E, /* DP parameters */ 93 { 0x00FFFFFF, 0x0007000E },
90 0x00D75FFF, 0x000E000A, 94 { 0x00D75FFF, 0x000E000A },
91 0x00BEFFFF, 0x00140006, 95 { 0x00BEFFFF, 0x00140006 },
92 0x80B2CFFF, 0x001B0002, 96 { 0x80B2CFFF, 0x001B0002 },
93 0x00FFFFFF, 0x000E000A, 97 { 0x00FFFFFF, 0x000E000A },
94 0x00D75FFF, 0x00180004, 98 { 0x00D75FFF, 0x00180004 },
95 0x80CB2FFF, 0x001B0002, 99 { 0x80CB2FFF, 0x001B0002 },
96 0x00F7DFFF, 0x00180004, 100 { 0x00F7DFFF, 0x00180004 },
97 0x80D75FFF, 0x001B0002, 101 { 0x80D75FFF, 0x001B0002 },
98 0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/
99}; 102};
100 103
101static const u32 bdw_ddi_translations_fdi[] = { 104static const struct ddi_buf_trans bdw_ddi_translations_fdi[] = {
102 0x00FFFFFF, 0x0001000E, /* FDI parameters */ 105 { 0x00FFFFFF, 0x0001000E },
103 0x00D75FFF, 0x0004000A, 106 { 0x00D75FFF, 0x0004000A },
104 0x00C30FFF, 0x00070006, 107 { 0x00C30FFF, 0x00070006 },
105 0x00AAAFFF, 0x000C0000, 108 { 0x00AAAFFF, 0x000C0000 },
106 0x00FFFFFF, 0x0004000A, 109 { 0x00FFFFFF, 0x0004000A },
107 0x00D75FFF, 0x00090004, 110 { 0x00D75FFF, 0x00090004 },
108 0x00C30FFF, 0x000C0000, 111 { 0x00C30FFF, 0x000C0000 },
109 0x00FFFFFF, 0x00070006, 112 { 0x00FFFFFF, 0x00070006 },
110 0x00D75FFF, 0x000C0000, 113 { 0x00D75FFF, 0x000C0000 },
111 0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/ 114};
115
116static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
117 /* Idx NT mV d T mV df db */
118 { 0x00FFFFFF, 0x0007000E }, /* 0: 400 400 0 */
119 { 0x00D75FFF, 0x000E000A }, /* 1: 400 600 3.5 */
120 { 0x00BEFFFF, 0x00140006 }, /* 2: 400 800 6 */
121 { 0x00FFFFFF, 0x0009000D }, /* 3: 450 450 0 */
122 { 0x00FFFFFF, 0x000E000A }, /* 4: 600 600 0 */
123 { 0x00D7FFFF, 0x00140006 }, /* 5: 600 800 2.5 */
124 { 0x80CB2FFF, 0x001B0002 }, /* 6: 600 1000 4.5 */
125 { 0x00FFFFFF, 0x00140006 }, /* 7: 800 800 0 */
126 { 0x80E79FFF, 0x001B0002 }, /* 8: 800 1000 2 */
127 { 0x80FFFFFF, 0x001B0002 }, /* 9: 1000 1000 0 */
112}; 128};
113 129
114enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder) 130enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
@@ -145,26 +161,36 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port)
145{ 161{
146 struct drm_i915_private *dev_priv = dev->dev_private; 162 struct drm_i915_private *dev_priv = dev->dev_private;
147 u32 reg; 163 u32 reg;
148 int i; 164 int i, n_hdmi_entries, hdmi_800mV_0dB;
149 int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; 165 int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
150 const u32 *ddi_translations_fdi; 166 const struct ddi_buf_trans *ddi_translations_fdi;
151 const u32 *ddi_translations_dp; 167 const struct ddi_buf_trans *ddi_translations_dp;
152 const u32 *ddi_translations_edp; 168 const struct ddi_buf_trans *ddi_translations_edp;
153 const u32 *ddi_translations; 169 const struct ddi_buf_trans *ddi_translations_hdmi;
170 const struct ddi_buf_trans *ddi_translations;
154 171
155 if (IS_BROADWELL(dev)) { 172 if (IS_BROADWELL(dev)) {
156 ddi_translations_fdi = bdw_ddi_translations_fdi; 173 ddi_translations_fdi = bdw_ddi_translations_fdi;
157 ddi_translations_dp = bdw_ddi_translations_dp; 174 ddi_translations_dp = bdw_ddi_translations_dp;
158 ddi_translations_edp = bdw_ddi_translations_edp; 175 ddi_translations_edp = bdw_ddi_translations_edp;
176 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
177 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
178 hdmi_800mV_0dB = 7;
159 } else if (IS_HASWELL(dev)) { 179 } else if (IS_HASWELL(dev)) {
160 ddi_translations_fdi = hsw_ddi_translations_fdi; 180 ddi_translations_fdi = hsw_ddi_translations_fdi;
161 ddi_translations_dp = hsw_ddi_translations_dp; 181 ddi_translations_dp = hsw_ddi_translations_dp;
162 ddi_translations_edp = hsw_ddi_translations_dp; 182 ddi_translations_edp = hsw_ddi_translations_dp;
183 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
184 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
185 hdmi_800mV_0dB = 6;
163 } else { 186 } else {
164 WARN(1, "ddi translation table missing\n"); 187 WARN(1, "ddi translation table missing\n");
165 ddi_translations_edp = bdw_ddi_translations_dp; 188 ddi_translations_edp = bdw_ddi_translations_dp;
166 ddi_translations_fdi = bdw_ddi_translations_fdi; 189 ddi_translations_fdi = bdw_ddi_translations_fdi;
167 ddi_translations_dp = bdw_ddi_translations_dp; 190 ddi_translations_dp = bdw_ddi_translations_dp;
191 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
192 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
193 hdmi_800mV_0dB = 7;
168 } 194 }
169 195
170 switch (port) { 196 switch (port) {
@@ -190,14 +216,22 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port)
190 216
191 for (i = 0, reg = DDI_BUF_TRANS(port); 217 for (i = 0, reg = DDI_BUF_TRANS(port);
192 i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { 218 i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) {
193 I915_WRITE(reg, ddi_translations[i]); 219 I915_WRITE(reg, ddi_translations[i].trans1);
194 reg += 4; 220 reg += 4;
195 } 221 I915_WRITE(reg, ddi_translations[i].trans2);
196 /* Entry 9 is for HDMI: */
197 for (i = 0; i < 2; i++) {
198 I915_WRITE(reg, hsw_ddi_translations_hdmi[hdmi_level * 2 + i]);
199 reg += 4; 222 reg += 4;
200 } 223 }
224
225 /* Choose a good default if VBT is badly populated */
226 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
227 hdmi_level >= n_hdmi_entries)
228 hdmi_level = hdmi_800mV_0dB;
229
230 /* Entry 9 is for HDMI: */
231 I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans1);
232 reg += 4;
233 I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans2);
234 reg += 4;
201} 235}
202 236
203/* Program DDI buffers translations for DP. By default, program ports A-D in DP 237/* Program DDI buffers translations for DP. By default, program ports A-D in DP
@@ -214,18 +248,6 @@ void intel_prepare_ddi(struct drm_device *dev)
214 intel_prepare_ddi_buffers(dev, port); 248 intel_prepare_ddi_buffers(dev, port);
215} 249}
216 250
217static const long hsw_ddi_buf_ctl_values[] = {
218 DDI_BUF_EMP_400MV_0DB_HSW,
219 DDI_BUF_EMP_400MV_3_5DB_HSW,
220 DDI_BUF_EMP_400MV_6DB_HSW,
221 DDI_BUF_EMP_400MV_9_5DB_HSW,
222 DDI_BUF_EMP_600MV_0DB_HSW,
223 DDI_BUF_EMP_600MV_3_5DB_HSW,
224 DDI_BUF_EMP_600MV_6DB_HSW,
225 DDI_BUF_EMP_800MV_0DB_HSW,
226 DDI_BUF_EMP_800MV_3_5DB_HSW
227};
228
229static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, 251static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
230 enum port port) 252 enum port port)
231{ 253{
@@ -285,7 +307,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
285 307
286 /* Start the training iterating through available voltages and emphasis, 308 /* Start the training iterating through available voltages and emphasis,
287 * testing each value twice. */ 309 * testing each value twice. */
288 for (i = 0; i < ARRAY_SIZE(hsw_ddi_buf_ctl_values) * 2; i++) { 310 for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
289 /* Configure DP_TP_CTL with auto-training */ 311 /* Configure DP_TP_CTL with auto-training */
290 I915_WRITE(DP_TP_CTL(PORT_E), 312 I915_WRITE(DP_TP_CTL(PORT_E),
291 DP_TP_CTL_FDI_AUTOTRAIN | 313 DP_TP_CTL_FDI_AUTOTRAIN |
@@ -300,7 +322,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
300 I915_WRITE(DDI_BUF_CTL(PORT_E), 322 I915_WRITE(DDI_BUF_CTL(PORT_E),
301 DDI_BUF_CTL_ENABLE | 323 DDI_BUF_CTL_ENABLE |
302 ((intel_crtc->config.fdi_lanes - 1) << 1) | 324 ((intel_crtc->config.fdi_lanes - 1) << 1) |
303 hsw_ddi_buf_ctl_values[i / 2]); 325 DDI_BUF_TRANS_SELECT(i / 2));
304 POSTING_READ(DDI_BUF_CTL(PORT_E)); 326 POSTING_READ(DDI_BUF_CTL(PORT_E));
305 327
306 udelay(600); 328 udelay(600);
@@ -375,7 +397,7 @@ void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
375 enc_to_dig_port(&encoder->base); 397 enc_to_dig_port(&encoder->base);
376 398
377 intel_dp->DP = intel_dig_port->saved_port_bits | 399 intel_dp->DP = intel_dig_port->saved_port_bits |
378 DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW; 400 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
379 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count); 401 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
380 402
381} 403}
@@ -402,7 +424,7 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
402} 424}
403 425
404#define LC_FREQ 2700 426#define LC_FREQ 2700
405#define LC_FREQ_2K (LC_FREQ * 2000) 427#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
406 428
407#define P_MIN 2 429#define P_MIN 2
408#define P_MAX 64 430#define P_MAX 64
@@ -414,7 +436,11 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
414#define VCO_MIN 2400 436#define VCO_MIN 2400
415#define VCO_MAX 4800 437#define VCO_MAX 4800
416 438
417#define ABS_DIFF(a, b) ((a > b) ? (a - b) : (b - a)) 439#define abs_diff(a, b) ({ \
440 typeof(a) __a = (a); \
441 typeof(b) __b = (b); \
442 (void) (&__a == &__b); \
443 __a > __b ? (__a - __b) : (__b - __a); })
418 444
419struct wrpll_rnp { 445struct wrpll_rnp {
420 unsigned p, n2, r2; 446 unsigned p, n2, r2;
@@ -524,9 +550,9 @@ static void wrpll_update_rnp(uint64_t freq2k, unsigned budget,
524 */ 550 */
525 a = freq2k * budget * p * r2; 551 a = freq2k * budget * p * r2;
526 b = freq2k * budget * best->p * best->r2; 552 b = freq2k * budget * best->p * best->r2;
527 diff = ABS_DIFF((freq2k * p * r2), (LC_FREQ_2K * n2)); 553 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
528 diff_best = ABS_DIFF((freq2k * best->p * best->r2), 554 diff_best = abs_diff(freq2k * best->p * best->r2,
529 (LC_FREQ_2K * best->n2)); 555 LC_FREQ_2K * best->n2);
530 c = 1000000 * diff; 556 c = 1000000 * diff;
531 d = 1000000 * diff_best; 557 d = 1000000 * diff_best;
532 558
@@ -587,8 +613,8 @@ static int intel_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
587 return (refclk * n * 100) / (p * r); 613 return (refclk * n * 100) / (p * r);
588} 614}
589 615
590void intel_ddi_clock_get(struct intel_encoder *encoder, 616static void hsw_ddi_clock_get(struct intel_encoder *encoder,
591 struct intel_crtc_config *pipe_config) 617 struct intel_crtc_config *pipe_config)
592{ 618{
593 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; 619 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
594 int link_clock = 0; 620 int link_clock = 0;
@@ -643,9 +669,15 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
643 pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock; 669 pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock;
644} 670}
645 671
672void intel_ddi_clock_get(struct intel_encoder *encoder,
673 struct intel_crtc_config *pipe_config)
674{
675 hsw_ddi_clock_get(encoder, pipe_config);
676}
677
646static void 678static void
647intel_ddi_calculate_wrpll(int clock /* in Hz */, 679hsw_ddi_calculate_wrpll(int clock /* in Hz */,
648 unsigned *r2_out, unsigned *n2_out, unsigned *p_out) 680 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
649{ 681{
650 uint64_t freq2k; 682 uint64_t freq2k;
651 unsigned p, n2, r2; 683 unsigned p, n2, r2;
@@ -708,27 +740,17 @@ intel_ddi_calculate_wrpll(int clock /* in Hz */,
708 *r2_out = best.r2; 740 *r2_out = best.r2;
709} 741}
710 742
711/* 743static bool
712 * Tries to find a PLL for the CRTC. If it finds, it increases the refcount and 744hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
713 * stores it in intel_crtc->ddi_pll_sel, so other mode sets won't be able to 745 struct intel_encoder *intel_encoder,
714 * steal the selected PLL. You need to call intel_ddi_pll_enable to actually 746 int clock)
715 * enable the PLL.
716 */
717bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
718{ 747{
719 struct drm_crtc *crtc = &intel_crtc->base; 748 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
720 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
721 int type = intel_encoder->type;
722 int clock = intel_crtc->config.port_clock;
723
724 intel_put_shared_dpll(intel_crtc);
725
726 if (type == INTEL_OUTPUT_HDMI) {
727 struct intel_shared_dpll *pll; 749 struct intel_shared_dpll *pll;
728 uint32_t val; 750 uint32_t val;
729 unsigned p, n2, r2; 751 unsigned p, n2, r2;
730 752
731 intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p); 753 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
732 754
733 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL | 755 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
734 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | 756 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
@@ -749,6 +771,25 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
749 return true; 771 return true;
750} 772}
751 773
774
775/*
776 * Tries to find a *shared* PLL for the CRTC and store it in
777 * intel_crtc->ddi_pll_sel.
778 *
779 * For private DPLLs, compute_config() should do the selection for us. This
780 * function should be folded into compute_config() eventually.
781 */
782bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
783{
784 struct drm_crtc *crtc = &intel_crtc->base;
785 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
786 int clock = intel_crtc->config.port_clock;
787
788 intel_put_shared_dpll(intel_crtc);
789
790 return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock);
791}
792
752void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) 793void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
753{ 794{
754 struct drm_i915_private *dev_priv = crtc->dev->dev_private; 795 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
@@ -1183,31 +1224,52 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
1183 } 1224 }
1184} 1225}
1185 1226
1186int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) 1227static int bdw_get_cdclk_freq(struct drm_i915_private *dev_priv)
1228{
1229 uint32_t lcpll = I915_READ(LCPLL_CTL);
1230 uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;
1231
1232 if (lcpll & LCPLL_CD_SOURCE_FCLK)
1233 return 800000;
1234 else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
1235 return 450000;
1236 else if (freq == LCPLL_CLK_FREQ_450)
1237 return 450000;
1238 else if (freq == LCPLL_CLK_FREQ_54O_BDW)
1239 return 540000;
1240 else if (freq == LCPLL_CLK_FREQ_337_5_BDW)
1241 return 337500;
1242 else
1243 return 675000;
1244}
1245
1246static int hsw_get_cdclk_freq(struct drm_i915_private *dev_priv)
1187{ 1247{
1188 struct drm_device *dev = dev_priv->dev; 1248 struct drm_device *dev = dev_priv->dev;
1189 uint32_t lcpll = I915_READ(LCPLL_CTL); 1249 uint32_t lcpll = I915_READ(LCPLL_CTL);
1190 uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK; 1250 uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;
1191 1251
1192 if (lcpll & LCPLL_CD_SOURCE_FCLK) { 1252 if (lcpll & LCPLL_CD_SOURCE_FCLK)
1193 return 800000; 1253 return 800000;
1194 } else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT) { 1254 else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
1195 return 450000; 1255 return 450000;
1196 } else if (freq == LCPLL_CLK_FREQ_450) { 1256 else if (freq == LCPLL_CLK_FREQ_450)
1197 return 450000; 1257 return 450000;
1198 } else if (IS_HASWELL(dev)) { 1258 else if (IS_ULT(dev))
1199 if (IS_ULT(dev)) 1259 return 337500;
1200 return 337500; 1260 else
1201 else 1261 return 540000;
1202 return 540000; 1262}
1203 } else { 1263
1204 if (freq == LCPLL_CLK_FREQ_54O_BDW) 1264int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
1205 return 540000; 1265{
1206 else if (freq == LCPLL_CLK_FREQ_337_5_BDW) 1266 struct drm_device *dev = dev_priv->dev;
1207 return 337500; 1267
1208 else 1268 if (IS_BROADWELL(dev))
1209 return 675000; 1269 return bdw_get_cdclk_freq(dev_priv);
1210 } 1270
1271 /* Haswell */
1272 return hsw_get_cdclk_freq(dev_priv);
1211} 1273}
1212 1274
1213static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv, 1275static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
@@ -1248,10 +1310,8 @@ static const char * const hsw_ddi_pll_names[] = {
1248 "WRPLL 2", 1310 "WRPLL 2",
1249}; 1311};
1250 1312
1251void intel_ddi_pll_init(struct drm_device *dev) 1313static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
1252{ 1314{
1253 struct drm_i915_private *dev_priv = dev->dev_private;
1254 uint32_t val = I915_READ(LCPLL_CTL);
1255 int i; 1315 int i;
1256 1316
1257 dev_priv->num_shared_dpll = 2; 1317 dev_priv->num_shared_dpll = 2;
@@ -1264,6 +1324,14 @@ void intel_ddi_pll_init(struct drm_device *dev)
1264 dev_priv->shared_dplls[i].get_hw_state = 1324 dev_priv->shared_dplls[i].get_hw_state =
1265 hsw_ddi_pll_get_hw_state; 1325 hsw_ddi_pll_get_hw_state;
1266 } 1326 }
1327}
1328
1329void intel_ddi_pll_init(struct drm_device *dev)
1330{
1331 struct drm_i915_private *dev_priv = dev->dev_private;
1332 uint32_t val = I915_READ(LCPLL_CTL);
1333
1334 hsw_shared_dplls_init(dev_priv);
1267 1335
1268 /* The LCPLL register should be turned on by the BIOS. For now let's 1336 /* The LCPLL register should be turned on by the BIOS. For now let's
1269 * just check its state and print errors in case something is wrong. 1337 * just check its state and print errors in case something is wrong.
@@ -1444,7 +1512,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
1444 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp; 1512 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
1445 } 1513 }
1446 1514
1447 intel_ddi_clock_get(encoder, pipe_config); 1515 hsw_ddi_clock_get(encoder, pipe_config);
1448} 1516}
1449 1517
1450static void intel_ddi_destroy(struct drm_encoder *encoder) 1518static void intel_ddi_destroy(struct drm_encoder *encoder)