drm/i915: Move HSW/BDW pll selection logic to intel_dpll_mgr.c
[deliverable/linux.git] / drivers / gpu / drm / i915 / intel_dpll_mgr.c
CommitLineData
7abd4b35
ACO
1/*
2 * Copyright © 2006-2016 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
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#include "intel_drv.h"
25
26struct intel_shared_dpll *
8106ddbd
ACO
27intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
28 enum intel_dpll_id id)
7abd4b35 29{
8106ddbd
ACO
30 return &dev_priv->shared_dplls[id];
31}
7abd4b35 32
8106ddbd
ACO
33enum intel_dpll_id
34intel_get_shared_dpll_id(struct drm_i915_private *dev_priv,
35 struct intel_shared_dpll *pll)
36{
37 if (WARN_ON(pll < dev_priv->shared_dplls||
38 pll > &dev_priv->shared_dplls[dev_priv->num_shared_dpll]))
39 return -1;
40
41 return (enum intel_dpll_id) (pll - dev_priv->shared_dplls);
42}
43
44void
45intel_shared_dpll_config_get(struct intel_shared_dpll_config *config,
46 struct intel_shared_dpll *pll,
47 struct intel_crtc *crtc)
48{
49 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
50 enum intel_dpll_id id = intel_get_shared_dpll_id(dev_priv, pll);
51
52 config[id].crtc_mask |= 1 << crtc->pipe;
53}
54
55void
56intel_shared_dpll_config_put(struct intel_shared_dpll_config *config,
57 struct intel_shared_dpll *pll,
58 struct intel_crtc *crtc)
59{
60 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
61 enum intel_dpll_id id = intel_get_shared_dpll_id(dev_priv, pll);
7abd4b35 62
8106ddbd 63 config[id].crtc_mask &= ~(1 << crtc->pipe);
7abd4b35
ACO
64}
65
66/* For ILK+ */
67void assert_shared_dpll(struct drm_i915_private *dev_priv,
68 struct intel_shared_dpll *pll,
69 bool state)
70{
71 bool cur_state;
72 struct intel_dpll_hw_state hw_state;
73
74 if (WARN(!pll, "asserting DPLL %s with no DPLL\n", onoff(state)))
75 return;
76
2edd6443 77 cur_state = pll->funcs.get_hw_state(dev_priv, pll, &hw_state);
7abd4b35
ACO
78 I915_STATE_WARN(cur_state != state,
79 "%s assertion failure (expected %s, current %s)\n",
80 pll->name, onoff(state), onoff(cur_state));
81}
82
83void intel_prepare_shared_dpll(struct intel_crtc *crtc)
84{
85 struct drm_device *dev = crtc->base.dev;
86 struct drm_i915_private *dev_priv = dev->dev_private;
8106ddbd 87 struct intel_shared_dpll *pll = crtc->config->shared_dpll;
7abd4b35
ACO
88
89 if (WARN_ON(pll == NULL))
90 return;
91
92 WARN_ON(!pll->config.crtc_mask);
93 if (pll->active == 0) {
94 DRM_DEBUG_DRIVER("setting up %s\n", pll->name);
95 WARN_ON(pll->on);
96 assert_shared_dpll_disabled(dev_priv, pll);
97
2edd6443 98 pll->funcs.mode_set(dev_priv, pll);
7abd4b35
ACO
99 }
100}
101
102/**
103 * intel_enable_shared_dpll - enable PCH PLL
104 * @dev_priv: i915 private structure
105 * @pipe: pipe PLL to enable
106 *
107 * The PCH PLL needs to be enabled before the PCH transcoder, since it
108 * drives the transcoder clock.
109 */
110void intel_enable_shared_dpll(struct intel_crtc *crtc)
111{
112 struct drm_device *dev = crtc->base.dev;
113 struct drm_i915_private *dev_priv = dev->dev_private;
8106ddbd 114 struct intel_shared_dpll *pll = crtc->config->shared_dpll;
7abd4b35
ACO
115
116 if (WARN_ON(pll == NULL))
117 return;
118
119 if (WARN_ON(pll->config.crtc_mask == 0))
120 return;
121
122 DRM_DEBUG_KMS("enable %s (active %d, on? %d) for crtc %d\n",
123 pll->name, pll->active, pll->on,
124 crtc->base.base.id);
125
126 if (pll->active++) {
127 WARN_ON(!pll->on);
128 assert_shared_dpll_enabled(dev_priv, pll);
129 return;
130 }
131 WARN_ON(pll->on);
132
133 intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
134
135 DRM_DEBUG_KMS("enabling %s\n", pll->name);
2edd6443 136 pll->funcs.enable(dev_priv, pll);
7abd4b35
ACO
137 pll->on = true;
138}
139
140void intel_disable_shared_dpll(struct intel_crtc *crtc)
141{
142 struct drm_device *dev = crtc->base.dev;
143 struct drm_i915_private *dev_priv = dev->dev_private;
8106ddbd 144 struct intel_shared_dpll *pll = crtc->config->shared_dpll;
7abd4b35
ACO
145
146 /* PCH only available on ILK+ */
147 if (INTEL_INFO(dev)->gen < 5)
148 return;
149
150 if (pll == NULL)
151 return;
152
153 if (WARN_ON(!(pll->config.crtc_mask & (1 << drm_crtc_index(&crtc->base)))))
154 return;
155
156 DRM_DEBUG_KMS("disable %s (active %d, on? %d) for crtc %d\n",
157 pll->name, pll->active, pll->on,
158 crtc->base.base.id);
159
160 if (WARN_ON(pll->active == 0)) {
161 assert_shared_dpll_disabled(dev_priv, pll);
162 return;
163 }
164
165 assert_shared_dpll_enabled(dev_priv, pll);
166 WARN_ON(!pll->on);
167 if (--pll->active)
168 return;
169
170 DRM_DEBUG_KMS("disabling %s\n", pll->name);
2edd6443 171 pll->funcs.disable(dev_priv, pll);
7abd4b35
ACO
172 pll->on = false;
173
174 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
175}
176
f9476a6c 177static struct intel_shared_dpll *
a4780b77 178intel_find_shared_dpll(struct intel_crtc *crtc,
f9476a6c
ACO
179 struct intel_crtc_state *crtc_state,
180 enum intel_dpll_id range_min,
181 enum intel_dpll_id range_max)
a4780b77
ACO
182{
183 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
184 struct intel_shared_dpll *pll;
185 struct intel_shared_dpll_config *shared_dpll;
186 enum intel_dpll_id i;
7abd4b35 187
a4780b77
ACO
188 shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
189
f9476a6c 190 for (i = range_min; i <= range_max; i++) {
7abd4b35
ACO
191 pll = &dev_priv->shared_dplls[i];
192
193 /* Only want to check enabled timings first */
194 if (shared_dpll[i].crtc_mask == 0)
195 continue;
196
197 if (memcmp(&crtc_state->dpll_hw_state,
198 &shared_dpll[i].hw_state,
199 sizeof(crtc_state->dpll_hw_state)) == 0) {
200 DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 0x%08x, ative %d)\n",
201 crtc->base.base.id, pll->name,
202 shared_dpll[i].crtc_mask,
203 pll->active);
f9476a6c 204 return pll;
7abd4b35
ACO
205 }
206 }
207
208 /* Ok no matching timings, maybe there's a free one? */
f9476a6c 209 for (i = range_min; i <= range_max; i++) {
7abd4b35
ACO
210 pll = &dev_priv->shared_dplls[i];
211 if (shared_dpll[i].crtc_mask == 0) {
212 DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
213 crtc->base.base.id, pll->name);
f9476a6c 214 return pll;
7abd4b35
ACO
215 }
216 }
217
f9476a6c 218 return NULL;
a4780b77
ACO
219}
220
f9476a6c
ACO
221static void
222intel_reference_shared_dpll(struct intel_shared_dpll *pll,
223 struct intel_crtc_state *crtc_state)
a4780b77 224{
a4780b77 225 struct intel_shared_dpll_config *shared_dpll;
f9476a6c
ACO
226 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
227 enum intel_dpll_id i = pll->id;
a4780b77
ACO
228
229 shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
230
7abd4b35
ACO
231 if (shared_dpll[i].crtc_mask == 0)
232 shared_dpll[i].hw_state =
233 crtc_state->dpll_hw_state;
234
8106ddbd 235 crtc_state->shared_dpll = pll;
7abd4b35
ACO
236 DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
237 pipe_name(crtc->pipe));
238
8106ddbd 239 intel_shared_dpll_config_get(shared_dpll, pll, crtc);
7abd4b35
ACO
240}
241
242void intel_shared_dpll_commit(struct drm_atomic_state *state)
243{
244 struct drm_i915_private *dev_priv = to_i915(state->dev);
245 struct intel_shared_dpll_config *shared_dpll;
246 struct intel_shared_dpll *pll;
247 enum intel_dpll_id i;
248
249 if (!to_intel_atomic_state(state)->dpll_set)
250 return;
251
252 shared_dpll = to_intel_atomic_state(state)->shared_dpll;
253 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
254 pll = &dev_priv->shared_dplls[i];
255 pll->config = shared_dpll[i];
256 }
257}
258
259static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
260 struct intel_shared_dpll *pll,
261 struct intel_dpll_hw_state *hw_state)
262{
263 uint32_t val;
264
265 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
266 return false;
267
268 val = I915_READ(PCH_DPLL(pll->id));
269 hw_state->dpll = val;
270 hw_state->fp0 = I915_READ(PCH_FP0(pll->id));
271 hw_state->fp1 = I915_READ(PCH_FP1(pll->id));
272
273 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
274
275 return val & DPLL_VCO_ENABLE;
276}
277
278static void ibx_pch_dpll_mode_set(struct drm_i915_private *dev_priv,
279 struct intel_shared_dpll *pll)
280{
281 I915_WRITE(PCH_FP0(pll->id), pll->config.hw_state.fp0);
282 I915_WRITE(PCH_FP1(pll->id), pll->config.hw_state.fp1);
283}
284
285static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv)
286{
287 u32 val;
288 bool enabled;
289
290 I915_STATE_WARN_ON(!(HAS_PCH_IBX(dev_priv->dev) || HAS_PCH_CPT(dev_priv->dev)));
291
292 val = I915_READ(PCH_DREF_CONTROL);
293 enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK |
294 DREF_SUPERSPREAD_SOURCE_MASK));
295 I915_STATE_WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n");
296}
297
298static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv,
299 struct intel_shared_dpll *pll)
300{
301 /* PCH refclock must be enabled first */
302 ibx_assert_pch_refclk_enabled(dev_priv);
303
304 I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll);
305
306 /* Wait for the clocks to stabilize. */
307 POSTING_READ(PCH_DPLL(pll->id));
308 udelay(150);
309
310 /* The pixel multiplier can only be updated once the
311 * DPLL is enabled and the clocks are stable.
312 *
313 * So write it again.
314 */
315 I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll);
316 POSTING_READ(PCH_DPLL(pll->id));
317 udelay(200);
318}
319
320static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
321 struct intel_shared_dpll *pll)
322{
323 struct drm_device *dev = dev_priv->dev;
324 struct intel_crtc *crtc;
325
326 /* Make sure no transcoder isn't still depending on us. */
327 for_each_intel_crtc(dev, crtc) {
8106ddbd 328 if (crtc->config->shared_dpll == pll)
7abd4b35
ACO
329 assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
330 }
331
332 I915_WRITE(PCH_DPLL(pll->id), 0);
333 POSTING_READ(PCH_DPLL(pll->id));
334 udelay(200);
335}
336
f9476a6c 337static struct intel_shared_dpll *
daedf20a
ACO
338ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
339 struct intel_encoder *encoder)
f9476a6c
ACO
340{
341 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
342 struct intel_shared_dpll *pll;
343 enum intel_dpll_id i;
344
345 if (HAS_PCH_IBX(dev_priv)) {
346 /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
347 i = (enum intel_dpll_id) crtc->pipe;
348 pll = &dev_priv->shared_dplls[i];
349
350 DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
351 crtc->base.base.id, pll->name);
352 } else {
353 pll = intel_find_shared_dpll(crtc, crtc_state,
354 DPLL_ID_PCH_PLL_A,
355 DPLL_ID_PCH_PLL_B);
356 }
357
358 /* reference the pll */
359 intel_reference_shared_dpll(pll, crtc_state);
360
361 return pll;
362}
363
2edd6443
ACO
364static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
365 .mode_set = ibx_pch_dpll_mode_set,
366 .enable = ibx_pch_dpll_enable,
367 .disable = ibx_pch_dpll_disable,
368 .get_hw_state = ibx_pch_dpll_get_hw_state,
7abd4b35
ACO
369};
370
55be2f08
ACO
371static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
372 struct intel_shared_dpll *pll)
373{
374 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
375 POSTING_READ(WRPLL_CTL(pll->id));
376 udelay(20);
377}
378
379static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
380 struct intel_shared_dpll *pll)
381{
382 I915_WRITE(SPLL_CTL, pll->config.hw_state.spll);
383 POSTING_READ(SPLL_CTL);
384 udelay(20);
385}
386
387static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
388 struct intel_shared_dpll *pll)
389{
390 uint32_t val;
391
392 val = I915_READ(WRPLL_CTL(pll->id));
393 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
394 POSTING_READ(WRPLL_CTL(pll->id));
395}
396
397static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
398 struct intel_shared_dpll *pll)
399{
400 uint32_t val;
401
402 val = I915_READ(SPLL_CTL);
403 I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
404 POSTING_READ(SPLL_CTL);
405}
406
407static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
408 struct intel_shared_dpll *pll,
409 struct intel_dpll_hw_state *hw_state)
410{
411 uint32_t val;
412
413 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
414 return false;
415
416 val = I915_READ(WRPLL_CTL(pll->id));
417 hw_state->wrpll = val;
418
419 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
420
421 return val & WRPLL_PLL_ENABLE;
422}
423
424static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
425 struct intel_shared_dpll *pll,
426 struct intel_dpll_hw_state *hw_state)
427{
428 uint32_t val;
429
430 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
431 return false;
432
433 val = I915_READ(SPLL_CTL);
434 hw_state->spll = val;
435
436 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
437
438 return val & SPLL_PLL_ENABLE;
439}
440
daedf20a
ACO
441static uint32_t hsw_pll_to_ddi_pll_sel(struct intel_shared_dpll *pll)
442{
443 switch (pll->id) {
444 case DPLL_ID_WRPLL1:
445 return PORT_CLK_SEL_WRPLL1;
446 case DPLL_ID_WRPLL2:
447 return PORT_CLK_SEL_WRPLL2;
448 case DPLL_ID_SPLL:
449 return PORT_CLK_SEL_SPLL;
450 default:
451 return PORT_CLK_SEL_NONE;
452 }
453}
454
455#define LC_FREQ 2700
456#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
457
458#define P_MIN 2
459#define P_MAX 64
460#define P_INC 2
461
462/* Constraints for PLL good behavior */
463#define REF_MIN 48
464#define REF_MAX 400
465#define VCO_MIN 2400
466#define VCO_MAX 4800
467
468struct hsw_wrpll_rnp {
469 unsigned p, n2, r2;
470};
471
472static unsigned hsw_wrpll_get_budget_for_freq(int clock)
473{
474 unsigned budget;
475
476 switch (clock) {
477 case 25175000:
478 case 25200000:
479 case 27000000:
480 case 27027000:
481 case 37762500:
482 case 37800000:
483 case 40500000:
484 case 40541000:
485 case 54000000:
486 case 54054000:
487 case 59341000:
488 case 59400000:
489 case 72000000:
490 case 74176000:
491 case 74250000:
492 case 81000000:
493 case 81081000:
494 case 89012000:
495 case 89100000:
496 case 108000000:
497 case 108108000:
498 case 111264000:
499 case 111375000:
500 case 148352000:
501 case 148500000:
502 case 162000000:
503 case 162162000:
504 case 222525000:
505 case 222750000:
506 case 296703000:
507 case 297000000:
508 budget = 0;
509 break;
510 case 233500000:
511 case 245250000:
512 case 247750000:
513 case 253250000:
514 case 298000000:
515 budget = 1500;
516 break;
517 case 169128000:
518 case 169500000:
519 case 179500000:
520 case 202000000:
521 budget = 2000;
522 break;
523 case 256250000:
524 case 262500000:
525 case 270000000:
526 case 272500000:
527 case 273750000:
528 case 280750000:
529 case 281250000:
530 case 286000000:
531 case 291750000:
532 budget = 4000;
533 break;
534 case 267250000:
535 case 268500000:
536 budget = 5000;
537 break;
538 default:
539 budget = 1000;
540 break;
541 }
542
543 return budget;
544}
545
546static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
547 unsigned r2, unsigned n2, unsigned p,
548 struct hsw_wrpll_rnp *best)
549{
550 uint64_t a, b, c, d, diff, diff_best;
551
552 /* No best (r,n,p) yet */
553 if (best->p == 0) {
554 best->p = p;
555 best->n2 = n2;
556 best->r2 = r2;
557 return;
558 }
559
560 /*
561 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
562 * freq2k.
563 *
564 * delta = 1e6 *
565 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
566 * freq2k;
567 *
568 * and we would like delta <= budget.
569 *
570 * If the discrepancy is above the PPM-based budget, always prefer to
571 * improve upon the previous solution. However, if you're within the
572 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
573 */
574 a = freq2k * budget * p * r2;
575 b = freq2k * budget * best->p * best->r2;
576 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
577 diff_best = abs_diff(freq2k * best->p * best->r2,
578 LC_FREQ_2K * best->n2);
579 c = 1000000 * diff;
580 d = 1000000 * diff_best;
581
582 if (a < c && b < d) {
583 /* If both are above the budget, pick the closer */
584 if (best->p * best->r2 * diff < p * r2 * diff_best) {
585 best->p = p;
586 best->n2 = n2;
587 best->r2 = r2;
588 }
589 } else if (a >= c && b < d) {
590 /* If A is below the threshold but B is above it? Update. */
591 best->p = p;
592 best->n2 = n2;
593 best->r2 = r2;
594 } else if (a >= c && b >= d) {
595 /* Both are below the limit, so pick the higher n2/(r2*r2) */
596 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
597 best->p = p;
598 best->n2 = n2;
599 best->r2 = r2;
600 }
601 }
602 /* Otherwise a < c && b >= d, do nothing */
603}
604
605static void
606hsw_ddi_calculate_wrpll(int clock /* in Hz */,
607 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
608{
609 uint64_t freq2k;
610 unsigned p, n2, r2;
611 struct hsw_wrpll_rnp best = { 0, 0, 0 };
612 unsigned budget;
613
614 freq2k = clock / 100;
615
616 budget = hsw_wrpll_get_budget_for_freq(clock);
617
618 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
619 * and directly pass the LC PLL to it. */
620 if (freq2k == 5400000) {
621 *n2_out = 2;
622 *p_out = 1;
623 *r2_out = 2;
624 return;
625 }
626
627 /*
628 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
629 * the WR PLL.
630 *
631 * We want R so that REF_MIN <= Ref <= REF_MAX.
632 * Injecting R2 = 2 * R gives:
633 * REF_MAX * r2 > LC_FREQ * 2 and
634 * REF_MIN * r2 < LC_FREQ * 2
635 *
636 * Which means the desired boundaries for r2 are:
637 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
638 *
639 */
640 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
641 r2 <= LC_FREQ * 2 / REF_MIN;
642 r2++) {
643
644 /*
645 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
646 *
647 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
648 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
649 * VCO_MAX * r2 > n2 * LC_FREQ and
650 * VCO_MIN * r2 < n2 * LC_FREQ)
651 *
652 * Which means the desired boundaries for n2 are:
653 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
654 */
655 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
656 n2 <= VCO_MAX * r2 / LC_FREQ;
657 n2++) {
658
659 for (p = P_MIN; p <= P_MAX; p += P_INC)
660 hsw_wrpll_update_rnp(freq2k, budget,
661 r2, n2, p, &best);
662 }
663 }
664
665 *n2_out = best.n2;
666 *p_out = best.p;
667 *r2_out = best.r2;
668}
669
f9476a6c 670static struct intel_shared_dpll *
daedf20a
ACO
671hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
672 struct intel_encoder *encoder)
f9476a6c
ACO
673{
674 struct intel_shared_dpll *pll;
daedf20a 675 int clock = crtc_state->port_clock;
f9476a6c 676
daedf20a
ACO
677 if (encoder->type == INTEL_OUTPUT_HDMI) {
678 uint32_t val;
679 unsigned p, n2, r2;
680
681 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
682
683 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
684 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
685 WRPLL_DIVIDER_POST(p);
686
687 memset(&crtc_state->dpll_hw_state, 0,
688 sizeof(crtc_state->dpll_hw_state));
689
690 crtc_state->dpll_hw_state.wrpll = val;
691
692 pll = intel_find_shared_dpll(crtc, crtc_state,
693 DPLL_ID_WRPLL1, DPLL_ID_WRPLL2);
694
695 } else if (encoder->type == INTEL_OUTPUT_ANALOG) {
696 if (WARN_ON(crtc_state->port_clock / 2 != 135000))
697 return NULL;
698
699 memset(&crtc_state->dpll_hw_state, 0,
700 sizeof(crtc_state->dpll_hw_state));
701
702 crtc_state->dpll_hw_state.spll =
703 SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC;
704
705 pll = intel_find_shared_dpll(crtc, crtc_state,
706 DPLL_ID_SPLL, DPLL_ID_SPLL);
707 } else {
708 return NULL;
709 }
710
711 if (!pll)
712 return NULL;
713
714 crtc_state->ddi_pll_sel = hsw_pll_to_ddi_pll_sel(pll);
715
716 intel_reference_shared_dpll(pll, crtc_state);
f9476a6c
ACO
717
718 return pll;
719}
720
55be2f08 721
2edd6443
ACO
722static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
723 .enable = hsw_ddi_wrpll_enable,
724 .disable = hsw_ddi_wrpll_disable,
725 .get_hw_state = hsw_ddi_wrpll_get_hw_state,
55be2f08
ACO
726};
727
2edd6443
ACO
728static const struct intel_shared_dpll_funcs hsw_ddi_spll_funcs = {
729 .enable = hsw_ddi_spll_enable,
730 .disable = hsw_ddi_spll_disable,
731 .get_hw_state = hsw_ddi_spll_get_hw_state,
55be2f08
ACO
732};
733
734struct skl_dpll_regs {
735 i915_reg_t ctl, cfgcr1, cfgcr2;
736};
737
738/* this array is indexed by the *shared* pll id */
739static const struct skl_dpll_regs skl_dpll_regs[3] = {
740 {
741 /* DPLL 1 */
742 .ctl = LCPLL2_CTL,
743 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
744 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
745 },
746 {
747 /* DPLL 2 */
748 .ctl = WRPLL_CTL(0),
749 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
750 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
751 },
752 {
753 /* DPLL 3 */
754 .ctl = WRPLL_CTL(1),
755 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
756 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
757 },
758};
759
760static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
761 struct intel_shared_dpll *pll)
762{
763 uint32_t val;
764 unsigned int dpll;
765 const struct skl_dpll_regs *regs = skl_dpll_regs;
766
767 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
768 dpll = pll->id + 1;
769
770 val = I915_READ(DPLL_CTRL1);
771
772 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
773 DPLL_CTRL1_LINK_RATE_MASK(dpll));
774 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
775
776 I915_WRITE(DPLL_CTRL1, val);
777 POSTING_READ(DPLL_CTRL1);
778
779 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
780 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
781 POSTING_READ(regs[pll->id].cfgcr1);
782 POSTING_READ(regs[pll->id].cfgcr2);
783
784 /* the enable bit is always bit 31 */
785 I915_WRITE(regs[pll->id].ctl,
786 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
787
788 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
789 DRM_ERROR("DPLL %d not locked\n", dpll);
790}
791
792static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
793 struct intel_shared_dpll *pll)
794{
795 const struct skl_dpll_regs *regs = skl_dpll_regs;
796
797 /* the enable bit is always bit 31 */
798 I915_WRITE(regs[pll->id].ctl,
799 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
800 POSTING_READ(regs[pll->id].ctl);
801}
802
803static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
804 struct intel_shared_dpll *pll,
805 struct intel_dpll_hw_state *hw_state)
806{
807 uint32_t val;
808 unsigned int dpll;
809 const struct skl_dpll_regs *regs = skl_dpll_regs;
810 bool ret;
811
812 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
813 return false;
814
815 ret = false;
816
817 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
818 dpll = pll->id + 1;
819
820 val = I915_READ(regs[pll->id].ctl);
821 if (!(val & LCPLL_PLL_ENABLE))
822 goto out;
823
824 val = I915_READ(DPLL_CTRL1);
825 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
826
827 /* avoid reading back stale values if HDMI mode is not enabled */
828 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
829 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
830 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
831 }
832 ret = true;
833
834out:
835 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
836
837 return ret;
838}
839
f9476a6c 840static struct intel_shared_dpll *
daedf20a
ACO
841skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
842 struct intel_encoder *encoder)
f9476a6c
ACO
843{
844 struct intel_shared_dpll *pll;
845
846 pll = intel_find_shared_dpll(crtc, crtc_state,
847 DPLL_ID_SKL_DPLL1, DPLL_ID_SKL_DPLL3);
848 if (pll)
849 intel_reference_shared_dpll(pll, crtc_state);
850
851 return pll;
852}
853
2edd6443
ACO
854static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
855 .enable = skl_ddi_pll_enable,
856 .disable = skl_ddi_pll_disable,
857 .get_hw_state = skl_ddi_pll_get_hw_state,
55be2f08
ACO
858};
859
860static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
861 struct intel_shared_dpll *pll)
862{
863 uint32_t temp;
864 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
865
866 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
867 temp &= ~PORT_PLL_REF_SEL;
868 /* Non-SSC reference */
869 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
870
871 /* Disable 10 bit clock */
872 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
873 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
874 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
875
876 /* Write P1 & P2 */
877 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
878 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
879 temp |= pll->config.hw_state.ebb0;
880 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
881
882 /* Write M2 integer */
883 temp = I915_READ(BXT_PORT_PLL(port, 0));
884 temp &= ~PORT_PLL_M2_MASK;
885 temp |= pll->config.hw_state.pll0;
886 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
887
888 /* Write N */
889 temp = I915_READ(BXT_PORT_PLL(port, 1));
890 temp &= ~PORT_PLL_N_MASK;
891 temp |= pll->config.hw_state.pll1;
892 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
893
894 /* Write M2 fraction */
895 temp = I915_READ(BXT_PORT_PLL(port, 2));
896 temp &= ~PORT_PLL_M2_FRAC_MASK;
897 temp |= pll->config.hw_state.pll2;
898 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
899
900 /* Write M2 fraction enable */
901 temp = I915_READ(BXT_PORT_PLL(port, 3));
902 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
903 temp |= pll->config.hw_state.pll3;
904 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
905
906 /* Write coeff */
907 temp = I915_READ(BXT_PORT_PLL(port, 6));
908 temp &= ~PORT_PLL_PROP_COEFF_MASK;
909 temp &= ~PORT_PLL_INT_COEFF_MASK;
910 temp &= ~PORT_PLL_GAIN_CTL_MASK;
911 temp |= pll->config.hw_state.pll6;
912 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
913
914 /* Write calibration val */
915 temp = I915_READ(BXT_PORT_PLL(port, 8));
916 temp &= ~PORT_PLL_TARGET_CNT_MASK;
917 temp |= pll->config.hw_state.pll8;
918 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
919
920 temp = I915_READ(BXT_PORT_PLL(port, 9));
921 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
922 temp |= pll->config.hw_state.pll9;
923 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
924
925 temp = I915_READ(BXT_PORT_PLL(port, 10));
926 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
927 temp &= ~PORT_PLL_DCO_AMP_MASK;
928 temp |= pll->config.hw_state.pll10;
929 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
930
931 /* Recalibrate with new settings */
932 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
933 temp |= PORT_PLL_RECALIBRATE;
934 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
935 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
936 temp |= pll->config.hw_state.ebb4;
937 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
938
939 /* Enable PLL */
940 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
941 temp |= PORT_PLL_ENABLE;
942 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
943 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
944
945 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
946 PORT_PLL_LOCK), 200))
947 DRM_ERROR("PLL %d not locked\n", port);
948
949 /*
950 * While we write to the group register to program all lanes at once we
951 * can read only lane registers and we pick lanes 0/1 for that.
952 */
953 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
954 temp &= ~LANE_STAGGER_MASK;
955 temp &= ~LANESTAGGER_STRAP_OVRD;
956 temp |= pll->config.hw_state.pcsdw12;
957 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
958}
959
960static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
961 struct intel_shared_dpll *pll)
962{
963 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
964 uint32_t temp;
965
966 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
967 temp &= ~PORT_PLL_ENABLE;
968 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
969 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
970}
971
972static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
973 struct intel_shared_dpll *pll,
974 struct intel_dpll_hw_state *hw_state)
975{
976 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
977 uint32_t val;
978 bool ret;
979
980 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
981 return false;
982
983 ret = false;
984
985 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
986 if (!(val & PORT_PLL_ENABLE))
987 goto out;
988
989 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
990 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
991
992 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
993 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
994
995 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
996 hw_state->pll0 &= PORT_PLL_M2_MASK;
997
998 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
999 hw_state->pll1 &= PORT_PLL_N_MASK;
1000
1001 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
1002 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
1003
1004 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
1005 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
1006
1007 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
1008 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
1009 PORT_PLL_INT_COEFF_MASK |
1010 PORT_PLL_GAIN_CTL_MASK;
1011
1012 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
1013 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
1014
1015 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
1016 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
1017
1018 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
1019 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
1020 PORT_PLL_DCO_AMP_MASK;
1021
1022 /*
1023 * While we write to the group register to program all lanes at once we
1024 * can read only lane registers. We configure all lanes the same way, so
1025 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
1026 */
1027 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
1028 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
1029 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
1030 hw_state->pcsdw12,
1031 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
1032 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
1033
1034 ret = true;
1035
1036out:
1037 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
1038
1039 return ret;
1040}
1041
f9476a6c 1042static struct intel_shared_dpll *
daedf20a
ACO
1043bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
1044 struct intel_encoder *encoder)
f9476a6c
ACO
1045{
1046 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
f9476a6c
ACO
1047 struct intel_digital_port *intel_dig_port;
1048 struct intel_shared_dpll *pll;
1049 enum intel_dpll_id i;
1050
1051 /* PLL is attached to port in bxt */
1052 encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
1053 if (WARN_ON(!encoder))
1054 return NULL;
1055
1056 intel_dig_port = enc_to_dig_port(&encoder->base);
1057 /* 1:1 mapping between ports and PLLs */
1058 i = (enum intel_dpll_id)intel_dig_port->port;
1059 pll = &dev_priv->shared_dplls[i];
1060 DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
1061 crtc->base.base.id, pll->name);
1062
1063 intel_reference_shared_dpll(pll, crtc_state);
1064
1065 return pll;
1066}
1067
2edd6443
ACO
1068static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
1069 .enable = bxt_ddi_pll_enable,
1070 .disable = bxt_ddi_pll_disable,
1071 .get_hw_state = bxt_ddi_pll_get_hw_state,
1072};
55be2f08
ACO
1073
1074static void intel_ddi_pll_init(struct drm_device *dev)
1075{
1076 struct drm_i915_private *dev_priv = dev->dev_private;
1077 uint32_t val = I915_READ(LCPLL_CTL);
1078
55be2f08
ACO
1079 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
1080 int cdclk_freq;
1081
1082 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
1083 dev_priv->skl_boot_cdclk = cdclk_freq;
1084 if (skl_sanitize_cdclk(dev_priv))
1085 DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
1086 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
1087 DRM_ERROR("LCPLL1 is disabled\n");
1088 } else if (IS_BROXTON(dev)) {
1089 broxton_init_cdclk(dev);
1090 broxton_ddi_phy_init(dev);
1091 } else {
1092 /*
1093 * The LCPLL register should be turned on by the BIOS. For now
1094 * let's just check its state and print errors in case
1095 * something is wrong. Don't even try to turn it on.
1096 */
1097
1098 if (val & LCPLL_CD_SOURCE_FCLK)
1099 DRM_ERROR("CDCLK source is not LCPLL\n");
1100
1101 if (val & LCPLL_PLL_DISABLE)
1102 DRM_ERROR("LCPLL is disabled\n");
1103 }
1104}
1105
2edd6443
ACO
1106struct dpll_info {
1107 const char *name;
1108 const int id;
1109 const struct intel_shared_dpll_funcs *funcs;
1110};
1111
f9476a6c
ACO
1112struct intel_dpll_mgr {
1113 const struct dpll_info *dpll_info;
1114
1115 struct intel_shared_dpll *(*get_dpll)(struct intel_crtc *crtc,
daedf20a
ACO
1116 struct intel_crtc_state *crtc_state,
1117 struct intel_encoder *encoder);
f9476a6c
ACO
1118};
1119
2edd6443
ACO
1120static const struct dpll_info pch_plls[] = {
1121 { "PCH DPLL A", DPLL_ID_PCH_PLL_A, &ibx_pch_dpll_funcs },
1122 { "PCH DPLL B", DPLL_ID_PCH_PLL_B, &ibx_pch_dpll_funcs },
1123 { NULL, -1, NULL },
1124};
1125
f9476a6c
ACO
1126static const struct intel_dpll_mgr pch_pll_mgr = {
1127 .dpll_info = pch_plls,
1128 .get_dpll = ibx_get_dpll,
1129};
1130
2edd6443
ACO
1131static const struct dpll_info hsw_plls[] = {
1132 { "WRPLL 1", DPLL_ID_WRPLL1, &hsw_ddi_wrpll_funcs },
1133 { "WRPLL 2", DPLL_ID_WRPLL2, &hsw_ddi_wrpll_funcs },
1134 { "SPLL", DPLL_ID_SPLL, &hsw_ddi_spll_funcs },
1135 { NULL, -1, NULL, },
1136};
1137
f9476a6c
ACO
1138static const struct intel_dpll_mgr hsw_pll_mgr = {
1139 .dpll_info = hsw_plls,
1140 .get_dpll = hsw_get_dpll,
1141};
1142
2edd6443
ACO
1143static const struct dpll_info skl_plls[] = {
1144 { "DPPL 1", DPLL_ID_SKL_DPLL1, &skl_ddi_pll_funcs },
1145 { "DPPL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs },
1146 { "DPPL 3", DPLL_ID_SKL_DPLL3, &skl_ddi_pll_funcs },
1147 { NULL, -1, NULL, },
1148};
1149
f9476a6c
ACO
1150static const struct intel_dpll_mgr skl_pll_mgr = {
1151 .dpll_info = skl_plls,
1152 .get_dpll = skl_get_dpll,
1153};
1154
2edd6443
ACO
1155static const struct dpll_info bxt_plls[] = {
1156 { "PORT PLL A", 0, &bxt_ddi_pll_funcs },
1157 { "PORT PLL B", 1, &bxt_ddi_pll_funcs },
1158 { "PORT PLL C", 2, &bxt_ddi_pll_funcs },
1159 { NULL, -1, NULL, },
1160};
1161
f9476a6c
ACO
1162static const struct intel_dpll_mgr bxt_pll_mgr = {
1163 .dpll_info = bxt_plls,
1164 .get_dpll = bxt_get_dpll,
1165};
1166
7abd4b35
ACO
1167void intel_shared_dpll_init(struct drm_device *dev)
1168{
1169 struct drm_i915_private *dev_priv = dev->dev_private;
f9476a6c
ACO
1170 const struct intel_dpll_mgr *dpll_mgr = NULL;
1171 const struct dpll_info *dpll_info;
2edd6443 1172 int i;
7abd4b35 1173
2edd6443 1174 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
f9476a6c 1175 dpll_mgr = &skl_pll_mgr;
2edd6443 1176 else if IS_BROXTON(dev)
f9476a6c 1177 dpll_mgr = &bxt_pll_mgr;
2edd6443 1178 else if (HAS_DDI(dev))
f9476a6c 1179 dpll_mgr = &hsw_pll_mgr;
7abd4b35 1180 else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
f9476a6c 1181 dpll_mgr = &pch_pll_mgr;
2edd6443 1182
f9476a6c 1183 if (!dpll_mgr) {
7abd4b35 1184 dev_priv->num_shared_dpll = 0;
2edd6443
ACO
1185 return;
1186 }
1187
f9476a6c
ACO
1188 dpll_info = dpll_mgr->dpll_info;
1189
2edd6443
ACO
1190 for (i = 0; dpll_info[i].id >= 0; i++) {
1191 WARN_ON(i != dpll_info[i].id);
1192
1193 dev_priv->shared_dplls[i].id = dpll_info[i].id;
1194 dev_priv->shared_dplls[i].name = dpll_info[i].name;
1195 dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs;
1196 }
1197
f9476a6c 1198 dev_priv->dpll_mgr = dpll_mgr;
2edd6443 1199 dev_priv->num_shared_dpll = i;
7abd4b35
ACO
1200
1201 BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
2edd6443
ACO
1202
1203 /* FIXME: Move this to a more suitable place */
1204 if (HAS_DDI(dev))
1205 intel_ddi_pll_init(dev);
7abd4b35 1206}
f9476a6c
ACO
1207
1208struct intel_shared_dpll *
1209intel_get_shared_dpll(struct intel_crtc *crtc,
daedf20a
ACO
1210 struct intel_crtc_state *crtc_state,
1211 struct intel_encoder *encoder)
f9476a6c
ACO
1212{
1213 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1214 const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll_mgr;
1215
1216 if (WARN_ON(!dpll_mgr))
1217 return NULL;
1218
daedf20a 1219 return dpll_mgr->get_dpll(crtc, crtc_state, encoder);
f9476a6c 1220}
This page took 0.075721 seconds and 5 git commands to generate.