blob: 4b636c47e8e3c1466b9b5671cae7a106d712e478 [file] [log] [blame]
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001/*
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 *
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +020027intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
28 enum intel_dpll_id id)
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +020029{
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +020030 return &dev_priv->shared_dplls[id];
31}
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +020032
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +020033enum 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;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +020040
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +020041 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);
62
63 config[id].crtc_mask &= ~(1 << crtc->pipe);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +020064}
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
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +020077 cur_state = pll->funcs.get_hw_state(dev_priv, pll, &hw_state);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +020078 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;
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +020087 struct intel_shared_dpll *pll = crtc->config->shared_dpll;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +020088
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
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +020098 pll->funcs.mode_set(dev_priv, pll);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +020099 }
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;
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +0200114 struct intel_shared_dpll *pll = crtc->config->shared_dpll;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200115
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);
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +0200136 pll->funcs.enable(dev_priv, pll);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200137 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;
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +0200144 struct intel_shared_dpll *pll = crtc->config->shared_dpll;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200145
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);
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +0200171 pll->funcs.disable(dev_priv, pll);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200172 pll->on = false;
173
174 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
175}
176
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200177static struct intel_shared_dpll *
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200178intel_find_shared_dpll(struct intel_crtc *crtc,
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200179 struct intel_crtc_state *crtc_state,
180 enum intel_dpll_id range_min,
181 enum intel_dpll_id range_max)
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200182{
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;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200187
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200188 shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
189
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200190 for (i = range_min; i <= range_max; i++) {
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200191 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);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200204 return pll;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200205 }
206 }
207
208 /* Ok no matching timings, maybe there's a free one? */
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200209 for (i = range_min; i <= range_max; i++) {
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200210 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);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200214 return pll;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200215 }
216 }
217
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200218 return NULL;
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200219}
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200220
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200221static void
222intel_reference_shared_dpll(struct intel_shared_dpll *pll,
223 struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200224{
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200225 struct intel_shared_dpll_config *shared_dpll;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200226 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
227 enum intel_dpll_id i = pll->id;
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200228
229 shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
230
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200231 if (shared_dpll[i].crtc_mask == 0)
232 shared_dpll[i].hw_state =
233 crtc_state->dpll_hw_state;
234
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +0200235 crtc_state->shared_dpll = pll;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200236 DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
237 pipe_name(crtc->pipe));
238
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +0200239 intel_shared_dpll_config_get(shared_dpll, pll, crtc);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200240}
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) {
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +0200328 if (crtc->config->shared_dpll == pll)
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200329 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
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200337static struct intel_shared_dpll *
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200338ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
339 struct intel_encoder *encoder)
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200340{
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
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +0200364static 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,
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200369};
370
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200371static 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
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200441static 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;
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +0200450 case DPLL_ID_LCPLL_810:
451 return PORT_CLK_SEL_LCPLL_810;
452 case DPLL_ID_LCPLL_1350:
453 return PORT_CLK_SEL_LCPLL_1350;
454 case DPLL_ID_LCPLL_2700:
455 return PORT_CLK_SEL_LCPLL_2700;
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200456 default:
457 return PORT_CLK_SEL_NONE;
458 }
459}
460
461#define LC_FREQ 2700
462#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
463
464#define P_MIN 2
465#define P_MAX 64
466#define P_INC 2
467
468/* Constraints for PLL good behavior */
469#define REF_MIN 48
470#define REF_MAX 400
471#define VCO_MIN 2400
472#define VCO_MAX 4800
473
474struct hsw_wrpll_rnp {
475 unsigned p, n2, r2;
476};
477
478static unsigned hsw_wrpll_get_budget_for_freq(int clock)
479{
480 unsigned budget;
481
482 switch (clock) {
483 case 25175000:
484 case 25200000:
485 case 27000000:
486 case 27027000:
487 case 37762500:
488 case 37800000:
489 case 40500000:
490 case 40541000:
491 case 54000000:
492 case 54054000:
493 case 59341000:
494 case 59400000:
495 case 72000000:
496 case 74176000:
497 case 74250000:
498 case 81000000:
499 case 81081000:
500 case 89012000:
501 case 89100000:
502 case 108000000:
503 case 108108000:
504 case 111264000:
505 case 111375000:
506 case 148352000:
507 case 148500000:
508 case 162000000:
509 case 162162000:
510 case 222525000:
511 case 222750000:
512 case 296703000:
513 case 297000000:
514 budget = 0;
515 break;
516 case 233500000:
517 case 245250000:
518 case 247750000:
519 case 253250000:
520 case 298000000:
521 budget = 1500;
522 break;
523 case 169128000:
524 case 169500000:
525 case 179500000:
526 case 202000000:
527 budget = 2000;
528 break;
529 case 256250000:
530 case 262500000:
531 case 270000000:
532 case 272500000:
533 case 273750000:
534 case 280750000:
535 case 281250000:
536 case 286000000:
537 case 291750000:
538 budget = 4000;
539 break;
540 case 267250000:
541 case 268500000:
542 budget = 5000;
543 break;
544 default:
545 budget = 1000;
546 break;
547 }
548
549 return budget;
550}
551
552static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
553 unsigned r2, unsigned n2, unsigned p,
554 struct hsw_wrpll_rnp *best)
555{
556 uint64_t a, b, c, d, diff, diff_best;
557
558 /* No best (r,n,p) yet */
559 if (best->p == 0) {
560 best->p = p;
561 best->n2 = n2;
562 best->r2 = r2;
563 return;
564 }
565
566 /*
567 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
568 * freq2k.
569 *
570 * delta = 1e6 *
571 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
572 * freq2k;
573 *
574 * and we would like delta <= budget.
575 *
576 * If the discrepancy is above the PPM-based budget, always prefer to
577 * improve upon the previous solution. However, if you're within the
578 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
579 */
580 a = freq2k * budget * p * r2;
581 b = freq2k * budget * best->p * best->r2;
582 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
583 diff_best = abs_diff(freq2k * best->p * best->r2,
584 LC_FREQ_2K * best->n2);
585 c = 1000000 * diff;
586 d = 1000000 * diff_best;
587
588 if (a < c && b < d) {
589 /* If both are above the budget, pick the closer */
590 if (best->p * best->r2 * diff < p * r2 * diff_best) {
591 best->p = p;
592 best->n2 = n2;
593 best->r2 = r2;
594 }
595 } else if (a >= c && b < d) {
596 /* If A is below the threshold but B is above it? Update. */
597 best->p = p;
598 best->n2 = n2;
599 best->r2 = r2;
600 } else if (a >= c && b >= d) {
601 /* Both are below the limit, so pick the higher n2/(r2*r2) */
602 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
603 best->p = p;
604 best->n2 = n2;
605 best->r2 = r2;
606 }
607 }
608 /* Otherwise a < c && b >= d, do nothing */
609}
610
611static void
612hsw_ddi_calculate_wrpll(int clock /* in Hz */,
613 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
614{
615 uint64_t freq2k;
616 unsigned p, n2, r2;
617 struct hsw_wrpll_rnp best = { 0, 0, 0 };
618 unsigned budget;
619
620 freq2k = clock / 100;
621
622 budget = hsw_wrpll_get_budget_for_freq(clock);
623
624 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
625 * and directly pass the LC PLL to it. */
626 if (freq2k == 5400000) {
627 *n2_out = 2;
628 *p_out = 1;
629 *r2_out = 2;
630 return;
631 }
632
633 /*
634 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
635 * the WR PLL.
636 *
637 * We want R so that REF_MIN <= Ref <= REF_MAX.
638 * Injecting R2 = 2 * R gives:
639 * REF_MAX * r2 > LC_FREQ * 2 and
640 * REF_MIN * r2 < LC_FREQ * 2
641 *
642 * Which means the desired boundaries for r2 are:
643 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
644 *
645 */
646 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
647 r2 <= LC_FREQ * 2 / REF_MIN;
648 r2++) {
649
650 /*
651 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
652 *
653 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
654 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
655 * VCO_MAX * r2 > n2 * LC_FREQ and
656 * VCO_MIN * r2 < n2 * LC_FREQ)
657 *
658 * Which means the desired boundaries for n2 are:
659 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
660 */
661 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
662 n2 <= VCO_MAX * r2 / LC_FREQ;
663 n2++) {
664
665 for (p = P_MIN; p <= P_MAX; p += P_INC)
666 hsw_wrpll_update_rnp(freq2k, budget,
667 r2, n2, p, &best);
668 }
669 }
670
671 *n2_out = best.n2;
672 *p_out = best.p;
673 *r2_out = best.r2;
674}
675
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200676static struct intel_shared_dpll *
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200677hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
678 struct intel_encoder *encoder)
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200679{
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +0200680 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200681 struct intel_shared_dpll *pll;
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200682 int clock = crtc_state->port_clock;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200683
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +0200684 memset(&crtc_state->dpll_hw_state, 0,
685 sizeof(crtc_state->dpll_hw_state));
686
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200687 if (encoder->type == INTEL_OUTPUT_HDMI) {
688 uint32_t val;
689 unsigned p, n2, r2;
690
691 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
692
693 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
694 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
695 WRPLL_DIVIDER_POST(p);
696
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200697 crtc_state->dpll_hw_state.wrpll = val;
698
699 pll = intel_find_shared_dpll(crtc, crtc_state,
700 DPLL_ID_WRPLL1, DPLL_ID_WRPLL2);
701
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +0200702 } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
703 encoder->type == INTEL_OUTPUT_DP_MST ||
704 encoder->type == INTEL_OUTPUT_EDP) {
705 enum intel_dpll_id pll_id;
706
707 switch (clock / 2) {
708 case 81000:
709 pll_id = DPLL_ID_LCPLL_810;
710 break;
711 case 135000:
712 pll_id = DPLL_ID_LCPLL_1350;
713 break;
714 case 270000:
715 pll_id = DPLL_ID_LCPLL_2700;
716 break;
717 default:
718 DRM_DEBUG_KMS("Invalid clock for DP: %d\n", clock);
719 return NULL;
720 }
721
722 pll = intel_get_shared_dpll_by_id(dev_priv, pll_id);
723
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200724 } else if (encoder->type == INTEL_OUTPUT_ANALOG) {
725 if (WARN_ON(crtc_state->port_clock / 2 != 135000))
726 return NULL;
727
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200728 crtc_state->dpll_hw_state.spll =
729 SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC;
730
731 pll = intel_find_shared_dpll(crtc, crtc_state,
732 DPLL_ID_SPLL, DPLL_ID_SPLL);
733 } else {
734 return NULL;
735 }
736
737 if (!pll)
738 return NULL;
739
740 crtc_state->ddi_pll_sel = hsw_pll_to_ddi_pll_sel(pll);
741
742 intel_reference_shared_dpll(pll, crtc_state);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200743
744 return pll;
745}
746
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200747
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +0200748static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
749 .enable = hsw_ddi_wrpll_enable,
750 .disable = hsw_ddi_wrpll_disable,
751 .get_hw_state = hsw_ddi_wrpll_get_hw_state,
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200752};
753
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +0200754static const struct intel_shared_dpll_funcs hsw_ddi_spll_funcs = {
755 .enable = hsw_ddi_spll_enable,
756 .disable = hsw_ddi_spll_disable,
757 .get_hw_state = hsw_ddi_spll_get_hw_state,
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200758};
759
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +0200760static void hsw_ddi_lcpll_enable(struct drm_i915_private *dev_priv,
761 struct intel_shared_dpll *pll)
762{
763}
764
765static void hsw_ddi_lcpll_disable(struct drm_i915_private *dev_priv,
766 struct intel_shared_dpll *pll)
767{
768}
769
770static bool hsw_ddi_lcpll_get_hw_state(struct drm_i915_private *dev_priv,
771 struct intel_shared_dpll *pll,
772 struct intel_dpll_hw_state *hw_state)
773{
774 return true;
775}
776
777static const struct intel_shared_dpll_funcs hsw_ddi_lcpll_funcs = {
778 .enable = hsw_ddi_lcpll_enable,
779 .disable = hsw_ddi_lcpll_disable,
780 .get_hw_state = hsw_ddi_lcpll_get_hw_state,
781};
782
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200783struct skl_dpll_regs {
784 i915_reg_t ctl, cfgcr1, cfgcr2;
785};
786
787/* this array is indexed by the *shared* pll id */
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200788static const struct skl_dpll_regs skl_dpll_regs[4] = {
789 {
790 /* DPLL 0 */
791 .ctl = LCPLL1_CTL,
792 /* DPLL 0 doesn't support HDMI mode */
793 },
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200794 {
795 /* DPLL 1 */
796 .ctl = LCPLL2_CTL,
797 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
798 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
799 },
800 {
801 /* DPLL 2 */
802 .ctl = WRPLL_CTL(0),
803 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
804 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
805 },
806 {
807 /* DPLL 3 */
808 .ctl = WRPLL_CTL(1),
809 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
810 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
811 },
812};
813
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200814static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *dev_priv,
815 struct intel_shared_dpll *pll)
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200816{
817 uint32_t val;
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200818
819 val = I915_READ(DPLL_CTRL1);
820
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200821 val &= ~(DPLL_CTRL1_HDMI_MODE(pll->id) | DPLL_CTRL1_SSC(pll->id) |
822 DPLL_CTRL1_LINK_RATE_MASK(pll->id));
823 val |= pll->config.hw_state.ctrl1 << (pll->id * 6);
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200824
825 I915_WRITE(DPLL_CTRL1, val);
826 POSTING_READ(DPLL_CTRL1);
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200827}
828
829static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
830 struct intel_shared_dpll *pll)
831{
832 const struct skl_dpll_regs *regs = skl_dpll_regs;
833
834 skl_ddi_pll_write_ctrl1(dev_priv, pll);
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200835
836 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
837 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
838 POSTING_READ(regs[pll->id].cfgcr1);
839 POSTING_READ(regs[pll->id].cfgcr2);
840
841 /* the enable bit is always bit 31 */
842 I915_WRITE(regs[pll->id].ctl,
843 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
844
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200845 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(pll->id), 5))
846 DRM_ERROR("DPLL %d not locked\n", pll->id);
847}
848
849static void skl_ddi_dpll0_enable(struct drm_i915_private *dev_priv,
850 struct intel_shared_dpll *pll)
851{
852 skl_ddi_pll_write_ctrl1(dev_priv, pll);
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200853}
854
855static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
856 struct intel_shared_dpll *pll)
857{
858 const struct skl_dpll_regs *regs = skl_dpll_regs;
859
860 /* the enable bit is always bit 31 */
861 I915_WRITE(regs[pll->id].ctl,
862 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
863 POSTING_READ(regs[pll->id].ctl);
864}
865
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200866static void skl_ddi_dpll0_disable(struct drm_i915_private *dev_priv,
867 struct intel_shared_dpll *pll)
868{
869}
870
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200871static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
872 struct intel_shared_dpll *pll,
873 struct intel_dpll_hw_state *hw_state)
874{
875 uint32_t val;
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200876 const struct skl_dpll_regs *regs = skl_dpll_regs;
877 bool ret;
878
879 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
880 return false;
881
882 ret = false;
883
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200884 val = I915_READ(regs[pll->id].ctl);
885 if (!(val & LCPLL_PLL_ENABLE))
886 goto out;
887
888 val = I915_READ(DPLL_CTRL1);
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200889 hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200890
891 /* avoid reading back stale values if HDMI mode is not enabled */
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200892 if (val & DPLL_CTRL1_HDMI_MODE(pll->id)) {
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200893 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
894 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
895 }
896 ret = true;
897
898out:
899 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
900
901 return ret;
902}
903
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200904static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv,
905 struct intel_shared_dpll *pll,
906 struct intel_dpll_hw_state *hw_state)
907{
908 uint32_t val;
909 const struct skl_dpll_regs *regs = skl_dpll_regs;
910 bool ret;
911
912 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
913 return false;
914
915 ret = false;
916
917 /* DPLL0 is always enabled since it drives CDCLK */
918 val = I915_READ(regs[pll->id].ctl);
919 if (WARN_ON(!(val & LCPLL_PLL_ENABLE)))
920 goto out;
921
922 val = I915_READ(DPLL_CTRL1);
923 hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
924
925 ret = true;
926
927out:
928 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
929
930 return ret;
931}
932
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +0200933struct skl_wrpll_context {
934 uint64_t min_deviation; /* current minimal deviation */
935 uint64_t central_freq; /* chosen central freq */
936 uint64_t dco_freq; /* chosen dco freq */
937 unsigned int p; /* chosen divider */
938};
939
940static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
941{
942 memset(ctx, 0, sizeof(*ctx));
943
944 ctx->min_deviation = U64_MAX;
945}
946
947/* DCO freq must be within +1%/-6% of the DCO central freq */
948#define SKL_DCO_MAX_PDEVIATION 100
949#define SKL_DCO_MAX_NDEVIATION 600
950
951static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
952 uint64_t central_freq,
953 uint64_t dco_freq,
954 unsigned int divider)
955{
956 uint64_t deviation;
957
958 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
959 central_freq);
960
961 /* positive deviation */
962 if (dco_freq >= central_freq) {
963 if (deviation < SKL_DCO_MAX_PDEVIATION &&
964 deviation < ctx->min_deviation) {
965 ctx->min_deviation = deviation;
966 ctx->central_freq = central_freq;
967 ctx->dco_freq = dco_freq;
968 ctx->p = divider;
969 }
970 /* negative deviation */
971 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
972 deviation < ctx->min_deviation) {
973 ctx->min_deviation = deviation;
974 ctx->central_freq = central_freq;
975 ctx->dco_freq = dco_freq;
976 ctx->p = divider;
977 }
978}
979
980static void skl_wrpll_get_multipliers(unsigned int p,
981 unsigned int *p0 /* out */,
982 unsigned int *p1 /* out */,
983 unsigned int *p2 /* out */)
984{
985 /* even dividers */
986 if (p % 2 == 0) {
987 unsigned int half = p / 2;
988
989 if (half == 1 || half == 2 || half == 3 || half == 5) {
990 *p0 = 2;
991 *p1 = 1;
992 *p2 = half;
993 } else if (half % 2 == 0) {
994 *p0 = 2;
995 *p1 = half / 2;
996 *p2 = 2;
997 } else if (half % 3 == 0) {
998 *p0 = 3;
999 *p1 = half / 3;
1000 *p2 = 2;
1001 } else if (half % 7 == 0) {
1002 *p0 = 7;
1003 *p1 = half / 7;
1004 *p2 = 2;
1005 }
1006 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1007 *p0 = 3;
1008 *p1 = 1;
1009 *p2 = p / 3;
1010 } else if (p == 5 || p == 7) {
1011 *p0 = p;
1012 *p1 = 1;
1013 *p2 = 1;
1014 } else if (p == 15) {
1015 *p0 = 3;
1016 *p1 = 1;
1017 *p2 = 5;
1018 } else if (p == 21) {
1019 *p0 = 7;
1020 *p1 = 1;
1021 *p2 = 3;
1022 } else if (p == 35) {
1023 *p0 = 7;
1024 *p1 = 1;
1025 *p2 = 5;
1026 }
1027}
1028
1029struct skl_wrpll_params {
1030 uint32_t dco_fraction;
1031 uint32_t dco_integer;
1032 uint32_t qdiv_ratio;
1033 uint32_t qdiv_mode;
1034 uint32_t kdiv;
1035 uint32_t pdiv;
1036 uint32_t central_freq;
1037};
1038
1039static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1040 uint64_t afe_clock,
1041 uint64_t central_freq,
1042 uint32_t p0, uint32_t p1, uint32_t p2)
1043{
1044 uint64_t dco_freq;
1045
1046 switch (central_freq) {
1047 case 9600000000ULL:
1048 params->central_freq = 0;
1049 break;
1050 case 9000000000ULL:
1051 params->central_freq = 1;
1052 break;
1053 case 8400000000ULL:
1054 params->central_freq = 3;
1055 }
1056
1057 switch (p0) {
1058 case 1:
1059 params->pdiv = 0;
1060 break;
1061 case 2:
1062 params->pdiv = 1;
1063 break;
1064 case 3:
1065 params->pdiv = 2;
1066 break;
1067 case 7:
1068 params->pdiv = 4;
1069 break;
1070 default:
1071 WARN(1, "Incorrect PDiv\n");
1072 }
1073
1074 switch (p2) {
1075 case 5:
1076 params->kdiv = 0;
1077 break;
1078 case 2:
1079 params->kdiv = 1;
1080 break;
1081 case 3:
1082 params->kdiv = 2;
1083 break;
1084 case 1:
1085 params->kdiv = 3;
1086 break;
1087 default:
1088 WARN(1, "Incorrect KDiv\n");
1089 }
1090
1091 params->qdiv_ratio = p1;
1092 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1093
1094 dco_freq = p0 * p1 * p2 * afe_clock;
1095
1096 /*
1097 * Intermediate values are in Hz.
1098 * Divide by MHz to match bsepc
1099 */
1100 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
1101 params->dco_fraction =
1102 div_u64((div_u64(dco_freq, 24) -
1103 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
1104}
1105
1106static bool
1107skl_ddi_calculate_wrpll(int clock /* in Hz */,
1108 struct skl_wrpll_params *wrpll_params)
1109{
1110 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
1111 uint64_t dco_central_freq[3] = {8400000000ULL,
1112 9000000000ULL,
1113 9600000000ULL};
1114 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1115 24, 28, 30, 32, 36, 40, 42, 44,
1116 48, 52, 54, 56, 60, 64, 66, 68,
1117 70, 72, 76, 78, 80, 84, 88, 90,
1118 92, 96, 98 };
1119 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1120 static const struct {
1121 const int *list;
1122 int n_dividers;
1123 } dividers[] = {
1124 { even_dividers, ARRAY_SIZE(even_dividers) },
1125 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1126 };
1127 struct skl_wrpll_context ctx;
1128 unsigned int dco, d, i;
1129 unsigned int p0, p1, p2;
1130
1131 skl_wrpll_context_init(&ctx);
1132
1133 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1134 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1135 for (i = 0; i < dividers[d].n_dividers; i++) {
1136 unsigned int p = dividers[d].list[i];
1137 uint64_t dco_freq = p * afe_clock;
1138
1139 skl_wrpll_try_divider(&ctx,
1140 dco_central_freq[dco],
1141 dco_freq,
1142 p);
1143 /*
1144 * Skip the remaining dividers if we're sure to
1145 * have found the definitive divider, we can't
1146 * improve a 0 deviation.
1147 */
1148 if (ctx.min_deviation == 0)
1149 goto skip_remaining_dividers;
1150 }
1151 }
1152
1153skip_remaining_dividers:
1154 /*
1155 * If a solution is found with an even divider, prefer
1156 * this one.
1157 */
1158 if (d == 0 && ctx.p)
1159 break;
1160 }
1161
1162 if (!ctx.p) {
1163 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
1164 return false;
1165 }
1166
1167 /*
1168 * gcc incorrectly analyses that these can be used without being
1169 * initialized. To be fair, it's hard to guess.
1170 */
1171 p0 = p1 = p2 = 0;
1172 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1173 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1174 p0, p1, p2);
1175
1176 return true;
1177}
1178
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001179static struct intel_shared_dpll *
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +02001180skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
1181 struct intel_encoder *encoder)
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001182{
1183 struct intel_shared_dpll *pll;
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +02001184 uint32_t ctrl1, cfgcr1, cfgcr2;
1185 int clock = crtc_state->port_clock;
1186
1187 /*
1188 * See comment in intel_dpll_hw_state to understand why we always use 0
1189 * as the DPLL id in this function.
1190 */
1191
1192 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1193
1194 if (encoder->type == INTEL_OUTPUT_HDMI) {
1195 struct skl_wrpll_params wrpll_params = { 0, };
1196
1197 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1198
1199 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1200 return false;
1201
1202 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1203 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1204 wrpll_params.dco_integer;
1205
1206 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1207 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1208 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1209 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1210 wrpll_params.central_freq;
1211 } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001212 encoder->type == INTEL_OUTPUT_DP_MST ||
1213 encoder->type == INTEL_OUTPUT_EDP) {
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +02001214 switch (crtc_state->port_clock / 2) {
1215 case 81000:
1216 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
1217 break;
1218 case 135000:
1219 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
1220 break;
1221 case 270000:
1222 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
1223 break;
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001224 /* eDP 1.4 rates */
1225 case 162000:
1226 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
1227 break;
1228 /* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is 8640 which
1229 results in CDCLK change. Need to handle the change of CDCLK by
1230 disabling pipes and re-enabling them */
1231 case 108000:
1232 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, 0);
1233 break;
1234 case 216000:
1235 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, 0);
1236 break;
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +02001237 }
1238
1239 cfgcr1 = cfgcr2 = 0;
1240 } else {
1241 return NULL;
1242 }
1243
1244 memset(&crtc_state->dpll_hw_state, 0,
1245 sizeof(crtc_state->dpll_hw_state));
1246
1247 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1248 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1249 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001250
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001251 if (encoder->type == INTEL_OUTPUT_EDP)
1252 pll = intel_find_shared_dpll(crtc, crtc_state,
1253 DPLL_ID_SKL_DPLL0,
1254 DPLL_ID_SKL_DPLL0);
1255 else
1256 pll = intel_find_shared_dpll(crtc, crtc_state,
1257 DPLL_ID_SKL_DPLL1,
1258 DPLL_ID_SKL_DPLL3);
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +02001259 if (!pll)
1260 return NULL;
1261
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001262 crtc_state->ddi_pll_sel = pll->id;
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +02001263
1264 intel_reference_shared_dpll(pll, crtc_state);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001265
1266 return pll;
1267}
1268
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001269static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
1270 .enable = skl_ddi_pll_enable,
1271 .disable = skl_ddi_pll_disable,
1272 .get_hw_state = skl_ddi_pll_get_hw_state,
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +02001273};
1274
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001275static const struct intel_shared_dpll_funcs skl_ddi_dpll0_funcs = {
1276 .enable = skl_ddi_dpll0_enable,
1277 .disable = skl_ddi_dpll0_disable,
1278 .get_hw_state = skl_ddi_dpll0_get_hw_state,
1279};
1280
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +02001281static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
1282 struct intel_shared_dpll *pll)
1283{
1284 uint32_t temp;
1285 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
1286
1287 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
1288 temp &= ~PORT_PLL_REF_SEL;
1289 /* Non-SSC reference */
1290 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
1291
1292 /* Disable 10 bit clock */
1293 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
1294 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
1295 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
1296
1297 /* Write P1 & P2 */
1298 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
1299 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
1300 temp |= pll->config.hw_state.ebb0;
1301 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
1302
1303 /* Write M2 integer */
1304 temp = I915_READ(BXT_PORT_PLL(port, 0));
1305 temp &= ~PORT_PLL_M2_MASK;
1306 temp |= pll->config.hw_state.pll0;
1307 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
1308
1309 /* Write N */
1310 temp = I915_READ(BXT_PORT_PLL(port, 1));
1311 temp &= ~PORT_PLL_N_MASK;
1312 temp |= pll->config.hw_state.pll1;
1313 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
1314
1315 /* Write M2 fraction */
1316 temp = I915_READ(BXT_PORT_PLL(port, 2));
1317 temp &= ~PORT_PLL_M2_FRAC_MASK;
1318 temp |= pll->config.hw_state.pll2;
1319 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
1320
1321 /* Write M2 fraction enable */
1322 temp = I915_READ(BXT_PORT_PLL(port, 3));
1323 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
1324 temp |= pll->config.hw_state.pll3;
1325 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
1326
1327 /* Write coeff */
1328 temp = I915_READ(BXT_PORT_PLL(port, 6));
1329 temp &= ~PORT_PLL_PROP_COEFF_MASK;
1330 temp &= ~PORT_PLL_INT_COEFF_MASK;
1331 temp &= ~PORT_PLL_GAIN_CTL_MASK;
1332 temp |= pll->config.hw_state.pll6;
1333 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
1334
1335 /* Write calibration val */
1336 temp = I915_READ(BXT_PORT_PLL(port, 8));
1337 temp &= ~PORT_PLL_TARGET_CNT_MASK;
1338 temp |= pll->config.hw_state.pll8;
1339 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
1340
1341 temp = I915_READ(BXT_PORT_PLL(port, 9));
1342 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
1343 temp |= pll->config.hw_state.pll9;
1344 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
1345
1346 temp = I915_READ(BXT_PORT_PLL(port, 10));
1347 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
1348 temp &= ~PORT_PLL_DCO_AMP_MASK;
1349 temp |= pll->config.hw_state.pll10;
1350 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
1351
1352 /* Recalibrate with new settings */
1353 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
1354 temp |= PORT_PLL_RECALIBRATE;
1355 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
1356 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
1357 temp |= pll->config.hw_state.ebb4;
1358 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
1359
1360 /* Enable PLL */
1361 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
1362 temp |= PORT_PLL_ENABLE;
1363 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
1364 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
1365
1366 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
1367 PORT_PLL_LOCK), 200))
1368 DRM_ERROR("PLL %d not locked\n", port);
1369
1370 /*
1371 * While we write to the group register to program all lanes at once we
1372 * can read only lane registers and we pick lanes 0/1 for that.
1373 */
1374 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
1375 temp &= ~LANE_STAGGER_MASK;
1376 temp &= ~LANESTAGGER_STRAP_OVRD;
1377 temp |= pll->config.hw_state.pcsdw12;
1378 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
1379}
1380
1381static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
1382 struct intel_shared_dpll *pll)
1383{
1384 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
1385 uint32_t temp;
1386
1387 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
1388 temp &= ~PORT_PLL_ENABLE;
1389 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
1390 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
1391}
1392
1393static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
1394 struct intel_shared_dpll *pll,
1395 struct intel_dpll_hw_state *hw_state)
1396{
1397 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
1398 uint32_t val;
1399 bool ret;
1400
1401 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
1402 return false;
1403
1404 ret = false;
1405
1406 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
1407 if (!(val & PORT_PLL_ENABLE))
1408 goto out;
1409
1410 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
1411 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
1412
1413 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
1414 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
1415
1416 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
1417 hw_state->pll0 &= PORT_PLL_M2_MASK;
1418
1419 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
1420 hw_state->pll1 &= PORT_PLL_N_MASK;
1421
1422 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
1423 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
1424
1425 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
1426 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
1427
1428 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
1429 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
1430 PORT_PLL_INT_COEFF_MASK |
1431 PORT_PLL_GAIN_CTL_MASK;
1432
1433 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
1434 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
1435
1436 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
1437 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
1438
1439 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
1440 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
1441 PORT_PLL_DCO_AMP_MASK;
1442
1443 /*
1444 * While we write to the group register to program all lanes at once we
1445 * can read only lane registers. We configure all lanes the same way, so
1446 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
1447 */
1448 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
1449 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
1450 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
1451 hw_state->pcsdw12,
1452 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
1453 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
1454
1455 ret = true;
1456
1457out:
1458 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
1459
1460 return ret;
1461}
1462
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001463/* bxt clock parameters */
1464struct bxt_clk_div {
1465 int clock;
1466 uint32_t p1;
1467 uint32_t p2;
1468 uint32_t m2_int;
1469 uint32_t m2_frac;
1470 bool m2_frac_en;
1471 uint32_t n;
1472};
1473
1474/* pre-calculated values for DP linkrates */
1475static const struct bxt_clk_div bxt_dp_clk_val[] = {
1476 {162000, 4, 2, 32, 1677722, 1, 1},
1477 {270000, 4, 1, 27, 0, 0, 1},
1478 {540000, 2, 1, 27, 0, 0, 1},
1479 {216000, 3, 2, 32, 1677722, 1, 1},
1480 {243000, 4, 1, 24, 1258291, 1, 1},
1481 {324000, 4, 1, 32, 1677722, 1, 1},
1482 {432000, 3, 1, 32, 1677722, 1, 1}
1483};
1484
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001485static struct intel_shared_dpll *
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +02001486bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
1487 struct intel_encoder *encoder)
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001488{
1489 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001490 struct intel_shared_dpll *pll;
1491 enum intel_dpll_id i;
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001492 struct intel_digital_port *intel_dig_port;
1493 struct bxt_clk_div clk_div = {0};
1494 int vco = 0;
1495 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
1496 uint32_t lanestagger;
1497 int clock = crtc_state->port_clock;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001498
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001499 if (encoder->type == INTEL_OUTPUT_HDMI) {
1500 intel_clock_t best_clock;
1501
1502 /* Calculate HDMI div */
1503 /*
1504 * FIXME: tie the following calculation into
1505 * i9xx_crtc_compute_clock
1506 */
1507 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1508 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1509 clock, pipe_name(crtc->pipe));
1510 return NULL;
1511 }
1512
1513 clk_div.p1 = best_clock.p1;
1514 clk_div.p2 = best_clock.p2;
1515 WARN_ON(best_clock.m1 != 2);
1516 clk_div.n = best_clock.n;
1517 clk_div.m2_int = best_clock.m2 >> 22;
1518 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1519 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1520
1521 vco = best_clock.vco;
1522 } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1523 encoder->type == INTEL_OUTPUT_EDP) {
1524 int i;
1525
1526 clk_div = bxt_dp_clk_val[0];
1527 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1528 if (bxt_dp_clk_val[i].clock == clock) {
1529 clk_div = bxt_dp_clk_val[i];
1530 break;
1531 }
1532 }
1533 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1534 }
1535
1536 if (vco >= 6200000 && vco <= 6700000) {
1537 prop_coef = 4;
1538 int_coef = 9;
1539 gain_ctl = 3;
1540 targ_cnt = 8;
1541 } else if ((vco > 5400000 && vco < 6200000) ||
1542 (vco >= 4800000 && vco < 5400000)) {
1543 prop_coef = 5;
1544 int_coef = 11;
1545 gain_ctl = 3;
1546 targ_cnt = 9;
1547 } else if (vco == 5400000) {
1548 prop_coef = 3;
1549 int_coef = 8;
1550 gain_ctl = 1;
1551 targ_cnt = 9;
1552 } else {
1553 DRM_ERROR("Invalid VCO\n");
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001554 return NULL;
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001555 }
1556
1557 memset(&crtc_state->dpll_hw_state, 0,
1558 sizeof(crtc_state->dpll_hw_state));
1559
1560 if (clock > 270000)
1561 lanestagger = 0x18;
1562 else if (clock > 135000)
1563 lanestagger = 0x0d;
1564 else if (clock > 67000)
1565 lanestagger = 0x07;
1566 else if (clock > 33000)
1567 lanestagger = 0x04;
1568 else
1569 lanestagger = 0x02;
1570
1571 crtc_state->dpll_hw_state.ebb0 =
1572 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1573 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1574 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1575 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1576
1577 if (clk_div.m2_frac_en)
1578 crtc_state->dpll_hw_state.pll3 =
1579 PORT_PLL_M2_FRAC_ENABLE;
1580
1581 crtc_state->dpll_hw_state.pll6 =
1582 prop_coef | PORT_PLL_INT_COEFF(int_coef);
1583 crtc_state->dpll_hw_state.pll6 |=
1584 PORT_PLL_GAIN_CTL(gain_ctl);
1585
1586 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1587
1588 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1589
1590 crtc_state->dpll_hw_state.pll10 =
1591 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1592 | PORT_PLL_DCO_AMP_OVR_EN_H;
1593
1594 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1595
1596 crtc_state->dpll_hw_state.pcsdw12 =
1597 LANESTAGGER_STRAP_OVRD | lanestagger;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001598
1599 intel_dig_port = enc_to_dig_port(&encoder->base);
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001600
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001601 /* 1:1 mapping between ports and PLLs */
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001602 i = (enum intel_dpll_id) intel_dig_port->port;
1603 pll = intel_get_shared_dpll_by_id(dev_priv, i);
1604
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001605 DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
1606 crtc->base.base.id, pll->name);
1607
1608 intel_reference_shared_dpll(pll, crtc_state);
1609
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001610 /* shared DPLL id 0 is DPLL A */
1611 crtc_state->ddi_pll_sel = pll->id;
1612
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001613 return pll;
1614}
1615
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001616static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
1617 .enable = bxt_ddi_pll_enable,
1618 .disable = bxt_ddi_pll_disable,
1619 .get_hw_state = bxt_ddi_pll_get_hw_state,
1620};
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +02001621
1622static void intel_ddi_pll_init(struct drm_device *dev)
1623{
1624 struct drm_i915_private *dev_priv = dev->dev_private;
1625 uint32_t val = I915_READ(LCPLL_CTL);
1626
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +02001627 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
1628 int cdclk_freq;
1629
1630 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
1631 dev_priv->skl_boot_cdclk = cdclk_freq;
1632 if (skl_sanitize_cdclk(dev_priv))
1633 DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
1634 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
1635 DRM_ERROR("LCPLL1 is disabled\n");
1636 } else if (IS_BROXTON(dev)) {
1637 broxton_init_cdclk(dev);
1638 broxton_ddi_phy_init(dev);
1639 } else {
1640 /*
1641 * The LCPLL register should be turned on by the BIOS. For now
1642 * let's just check its state and print errors in case
1643 * something is wrong. Don't even try to turn it on.
1644 */
1645
1646 if (val & LCPLL_CD_SOURCE_FCLK)
1647 DRM_ERROR("CDCLK source is not LCPLL\n");
1648
1649 if (val & LCPLL_PLL_DISABLE)
1650 DRM_ERROR("LCPLL is disabled\n");
1651 }
1652}
1653
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001654struct dpll_info {
1655 const char *name;
1656 const int id;
1657 const struct intel_shared_dpll_funcs *funcs;
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +02001658 uint32_t flags;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001659};
1660
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001661struct intel_dpll_mgr {
1662 const struct dpll_info *dpll_info;
1663
1664 struct intel_shared_dpll *(*get_dpll)(struct intel_crtc *crtc,
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +02001665 struct intel_crtc_state *crtc_state,
1666 struct intel_encoder *encoder);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001667};
1668
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001669static const struct dpll_info pch_plls[] = {
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +02001670 { "PCH DPLL A", DPLL_ID_PCH_PLL_A, &ibx_pch_dpll_funcs, 0 },
1671 { "PCH DPLL B", DPLL_ID_PCH_PLL_B, &ibx_pch_dpll_funcs, 0 },
1672 { NULL, -1, NULL, 0 },
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001673};
1674
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001675static const struct intel_dpll_mgr pch_pll_mgr = {
1676 .dpll_info = pch_plls,
1677 .get_dpll = ibx_get_dpll,
1678};
1679
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001680static const struct dpll_info hsw_plls[] = {
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +02001681 { "WRPLL 1", DPLL_ID_WRPLL1, &hsw_ddi_wrpll_funcs, 0 },
1682 { "WRPLL 2", DPLL_ID_WRPLL2, &hsw_ddi_wrpll_funcs, 0 },
1683 { "SPLL", DPLL_ID_SPLL, &hsw_ddi_spll_funcs, 0 },
1684 { "LCPLL 810", DPLL_ID_LCPLL_810, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON },
1685 { "LCPLL 1350", DPLL_ID_LCPLL_1350, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON },
1686 { "LCPLL 2700", DPLL_ID_LCPLL_2700, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON },
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001687 { NULL, -1, NULL, },
1688};
1689
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001690static const struct intel_dpll_mgr hsw_pll_mgr = {
1691 .dpll_info = hsw_plls,
1692 .get_dpll = hsw_get_dpll,
1693};
1694
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001695static const struct dpll_info skl_plls[] = {
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001696 { "DPLL 0", DPLL_ID_SKL_DPLL0, &skl_ddi_dpll0_funcs, INTEL_DPLL_ALWAYS_ON },
1697 { "DPPL 1", DPLL_ID_SKL_DPLL1, &skl_ddi_pll_funcs, 0 },
1698 { "DPPL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs, 0 },
1699 { "DPPL 3", DPLL_ID_SKL_DPLL3, &skl_ddi_pll_funcs, 0 },
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001700 { NULL, -1, NULL, },
1701};
1702
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001703static const struct intel_dpll_mgr skl_pll_mgr = {
1704 .dpll_info = skl_plls,
1705 .get_dpll = skl_get_dpll,
1706};
1707
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001708static const struct dpll_info bxt_plls[] = {
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +02001709 { "PORT PLL A", 0, &bxt_ddi_pll_funcs, 0 },
1710 { "PORT PLL B", 1, &bxt_ddi_pll_funcs, 0 },
1711 { "PORT PLL C", 2, &bxt_ddi_pll_funcs, 0 },
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001712 { NULL, -1, NULL, },
1713};
1714
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001715static const struct intel_dpll_mgr bxt_pll_mgr = {
1716 .dpll_info = bxt_plls,
1717 .get_dpll = bxt_get_dpll,
1718};
1719
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001720void intel_shared_dpll_init(struct drm_device *dev)
1721{
1722 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001723 const struct intel_dpll_mgr *dpll_mgr = NULL;
1724 const struct dpll_info *dpll_info;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001725 int i;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001726
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001727 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001728 dpll_mgr = &skl_pll_mgr;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001729 else if IS_BROXTON(dev)
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001730 dpll_mgr = &bxt_pll_mgr;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001731 else if (HAS_DDI(dev))
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001732 dpll_mgr = &hsw_pll_mgr;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001733 else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001734 dpll_mgr = &pch_pll_mgr;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001735
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001736 if (!dpll_mgr) {
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001737 dev_priv->num_shared_dpll = 0;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001738 return;
1739 }
1740
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001741 dpll_info = dpll_mgr->dpll_info;
1742
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001743 for (i = 0; dpll_info[i].id >= 0; i++) {
1744 WARN_ON(i != dpll_info[i].id);
1745
1746 dev_priv->shared_dplls[i].id = dpll_info[i].id;
1747 dev_priv->shared_dplls[i].name = dpll_info[i].name;
1748 dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs;
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +02001749 dev_priv->shared_dplls[i].flags = dpll_info[i].flags;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001750 }
1751
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001752 dev_priv->dpll_mgr = dpll_mgr;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001753 dev_priv->num_shared_dpll = i;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001754
1755 BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001756
1757 /* FIXME: Move this to a more suitable place */
1758 if (HAS_DDI(dev))
1759 intel_ddi_pll_init(dev);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001760}
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001761
1762struct intel_shared_dpll *
1763intel_get_shared_dpll(struct intel_crtc *crtc,
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +02001764 struct intel_crtc_state *crtc_state,
1765 struct intel_encoder *encoder)
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001766{
1767 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1768 const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll_mgr;
1769
1770 if (WARN_ON(!dpll_mgr))
1771 return NULL;
1772
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +02001773 return dpll_mgr->get_dpll(crtc, crtc_state, encoder);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001774}