blob: 9bf2c3914625953b4d51b4965afb2c5ad6ced0a7 [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);
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +010093 if (pll->active_mask == 0) {
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +020094 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;
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100115 unsigned crtc_mask = 1 << drm_crtc_index(&crtc->base);
116 unsigned old_mask = pll->active_mask;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200117
118 if (WARN_ON(pll == NULL))
119 return;
120
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100121 if (WARN_ON(!(pll->config.crtc_mask & crtc_mask)) ||
122 WARN_ON(pll->active_mask & crtc_mask))
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200123 return;
124
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100125 pll->active_mask |= crtc_mask;
126
127 DRM_DEBUG_KMS("enable %s (active %x, on? %d) for crtc %d\n",
128 pll->name, pll->active_mask, pll->on,
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200129 crtc->base.base.id);
130
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100131 if (old_mask) {
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200132 WARN_ON(!pll->on);
133 assert_shared_dpll_enabled(dev_priv, pll);
134 return;
135 }
136 WARN_ON(pll->on);
137
138 intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
139
140 DRM_DEBUG_KMS("enabling %s\n", pll->name);
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +0200141 pll->funcs.enable(dev_priv, pll);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200142 pll->on = true;
143}
144
145void intel_disable_shared_dpll(struct intel_crtc *crtc)
146{
147 struct drm_device *dev = crtc->base.dev;
148 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +0200149 struct intel_shared_dpll *pll = crtc->config->shared_dpll;
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100150 unsigned crtc_mask = 1 << drm_crtc_index(&crtc->base);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200151
152 /* PCH only available on ILK+ */
153 if (INTEL_INFO(dev)->gen < 5)
154 return;
155
156 if (pll == NULL)
157 return;
158
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100159 if (WARN_ON(!(pll->config.crtc_mask & crtc_mask)))
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200160 return;
161
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100162 DRM_DEBUG_KMS("disable %s (active %x, on? %d) for crtc %d\n",
163 pll->name, pll->active_mask, pll->on,
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200164 crtc->base.base.id);
165
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200166 assert_shared_dpll_enabled(dev_priv, pll);
167 WARN_ON(!pll->on);
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100168
169 pll->active_mask &= ~crtc_mask;
170 if (pll->active_mask)
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200171 return;
172
173 DRM_DEBUG_KMS("disabling %s\n", pll->name);
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +0200174 pll->funcs.disable(dev_priv, pll);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200175 pll->on = false;
176
177 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
178}
179
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200180static struct intel_shared_dpll *
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200181intel_find_shared_dpll(struct intel_crtc *crtc,
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200182 struct intel_crtc_state *crtc_state,
183 enum intel_dpll_id range_min,
184 enum intel_dpll_id range_max)
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200185{
186 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
187 struct intel_shared_dpll *pll;
188 struct intel_shared_dpll_config *shared_dpll;
189 enum intel_dpll_id i;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200190
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200191 shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
192
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200193 for (i = range_min; i <= range_max; i++) {
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200194 pll = &dev_priv->shared_dplls[i];
195
196 /* Only want to check enabled timings first */
197 if (shared_dpll[i].crtc_mask == 0)
198 continue;
199
200 if (memcmp(&crtc_state->dpll_hw_state,
201 &shared_dpll[i].hw_state,
202 sizeof(crtc_state->dpll_hw_state)) == 0) {
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100203 DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 0x%08x, active %x)\n",
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200204 crtc->base.base.id, pll->name,
205 shared_dpll[i].crtc_mask,
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100206 pll->active_mask);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200207 return pll;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200208 }
209 }
210
211 /* Ok no matching timings, maybe there's a free one? */
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200212 for (i = range_min; i <= range_max; i++) {
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200213 pll = &dev_priv->shared_dplls[i];
214 if (shared_dpll[i].crtc_mask == 0) {
215 DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
216 crtc->base.base.id, pll->name);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200217 return pll;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200218 }
219 }
220
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200221 return NULL;
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200222}
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200223
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200224static void
225intel_reference_shared_dpll(struct intel_shared_dpll *pll,
226 struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200227{
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200228 struct intel_shared_dpll_config *shared_dpll;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200229 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
230 enum intel_dpll_id i = pll->id;
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200231
232 shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
233
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200234 if (shared_dpll[i].crtc_mask == 0)
235 shared_dpll[i].hw_state =
236 crtc_state->dpll_hw_state;
237
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +0200238 crtc_state->shared_dpll = pll;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200239 DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
240 pipe_name(crtc->pipe));
241
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +0200242 intel_shared_dpll_config_get(shared_dpll, pll, crtc);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200243}
244
245void intel_shared_dpll_commit(struct drm_atomic_state *state)
246{
247 struct drm_i915_private *dev_priv = to_i915(state->dev);
248 struct intel_shared_dpll_config *shared_dpll;
249 struct intel_shared_dpll *pll;
250 enum intel_dpll_id i;
251
252 if (!to_intel_atomic_state(state)->dpll_set)
253 return;
254
255 shared_dpll = to_intel_atomic_state(state)->shared_dpll;
256 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
257 pll = &dev_priv->shared_dplls[i];
258 pll->config = shared_dpll[i];
259 }
260}
261
262static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
263 struct intel_shared_dpll *pll,
264 struct intel_dpll_hw_state *hw_state)
265{
266 uint32_t val;
267
268 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
269 return false;
270
271 val = I915_READ(PCH_DPLL(pll->id));
272 hw_state->dpll = val;
273 hw_state->fp0 = I915_READ(PCH_FP0(pll->id));
274 hw_state->fp1 = I915_READ(PCH_FP1(pll->id));
275
276 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
277
278 return val & DPLL_VCO_ENABLE;
279}
280
281static void ibx_pch_dpll_mode_set(struct drm_i915_private *dev_priv,
282 struct intel_shared_dpll *pll)
283{
284 I915_WRITE(PCH_FP0(pll->id), pll->config.hw_state.fp0);
285 I915_WRITE(PCH_FP1(pll->id), pll->config.hw_state.fp1);
286}
287
288static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv)
289{
290 u32 val;
291 bool enabled;
292
293 I915_STATE_WARN_ON(!(HAS_PCH_IBX(dev_priv->dev) || HAS_PCH_CPT(dev_priv->dev)));
294
295 val = I915_READ(PCH_DREF_CONTROL);
296 enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK |
297 DREF_SUPERSPREAD_SOURCE_MASK));
298 I915_STATE_WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n");
299}
300
301static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv,
302 struct intel_shared_dpll *pll)
303{
304 /* PCH refclock must be enabled first */
305 ibx_assert_pch_refclk_enabled(dev_priv);
306
307 I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll);
308
309 /* Wait for the clocks to stabilize. */
310 POSTING_READ(PCH_DPLL(pll->id));
311 udelay(150);
312
313 /* The pixel multiplier can only be updated once the
314 * DPLL is enabled and the clocks are stable.
315 *
316 * So write it again.
317 */
318 I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll);
319 POSTING_READ(PCH_DPLL(pll->id));
320 udelay(200);
321}
322
323static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
324 struct intel_shared_dpll *pll)
325{
326 struct drm_device *dev = dev_priv->dev;
327 struct intel_crtc *crtc;
328
329 /* Make sure no transcoder isn't still depending on us. */
330 for_each_intel_crtc(dev, crtc) {
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +0200331 if (crtc->config->shared_dpll == pll)
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200332 assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
333 }
334
335 I915_WRITE(PCH_DPLL(pll->id), 0);
336 POSTING_READ(PCH_DPLL(pll->id));
337 udelay(200);
338}
339
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200340static struct intel_shared_dpll *
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200341ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
342 struct intel_encoder *encoder)
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200343{
344 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
345 struct intel_shared_dpll *pll;
346 enum intel_dpll_id i;
347
348 if (HAS_PCH_IBX(dev_priv)) {
349 /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
350 i = (enum intel_dpll_id) crtc->pipe;
351 pll = &dev_priv->shared_dplls[i];
352
353 DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
354 crtc->base.base.id, pll->name);
355 } else {
356 pll = intel_find_shared_dpll(crtc, crtc_state,
357 DPLL_ID_PCH_PLL_A,
358 DPLL_ID_PCH_PLL_B);
359 }
360
361 /* reference the pll */
362 intel_reference_shared_dpll(pll, crtc_state);
363
364 return pll;
365}
366
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +0200367static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
368 .mode_set = ibx_pch_dpll_mode_set,
369 .enable = ibx_pch_dpll_enable,
370 .disable = ibx_pch_dpll_disable,
371 .get_hw_state = ibx_pch_dpll_get_hw_state,
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200372};
373
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200374static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
375 struct intel_shared_dpll *pll)
376{
377 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
378 POSTING_READ(WRPLL_CTL(pll->id));
379 udelay(20);
380}
381
382static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
383 struct intel_shared_dpll *pll)
384{
385 I915_WRITE(SPLL_CTL, pll->config.hw_state.spll);
386 POSTING_READ(SPLL_CTL);
387 udelay(20);
388}
389
390static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
391 struct intel_shared_dpll *pll)
392{
393 uint32_t val;
394
395 val = I915_READ(WRPLL_CTL(pll->id));
396 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
397 POSTING_READ(WRPLL_CTL(pll->id));
398}
399
400static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
401 struct intel_shared_dpll *pll)
402{
403 uint32_t val;
404
405 val = I915_READ(SPLL_CTL);
406 I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
407 POSTING_READ(SPLL_CTL);
408}
409
410static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
411 struct intel_shared_dpll *pll,
412 struct intel_dpll_hw_state *hw_state)
413{
414 uint32_t val;
415
416 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
417 return false;
418
419 val = I915_READ(WRPLL_CTL(pll->id));
420 hw_state->wrpll = val;
421
422 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
423
424 return val & WRPLL_PLL_ENABLE;
425}
426
427static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
428 struct intel_shared_dpll *pll,
429 struct intel_dpll_hw_state *hw_state)
430{
431 uint32_t val;
432
433 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
434 return false;
435
436 val = I915_READ(SPLL_CTL);
437 hw_state->spll = val;
438
439 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
440
441 return val & SPLL_PLL_ENABLE;
442}
443
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200444static uint32_t hsw_pll_to_ddi_pll_sel(struct intel_shared_dpll *pll)
445{
446 switch (pll->id) {
447 case DPLL_ID_WRPLL1:
448 return PORT_CLK_SEL_WRPLL1;
449 case DPLL_ID_WRPLL2:
450 return PORT_CLK_SEL_WRPLL2;
451 case DPLL_ID_SPLL:
452 return PORT_CLK_SEL_SPLL;
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +0200453 case DPLL_ID_LCPLL_810:
454 return PORT_CLK_SEL_LCPLL_810;
455 case DPLL_ID_LCPLL_1350:
456 return PORT_CLK_SEL_LCPLL_1350;
457 case DPLL_ID_LCPLL_2700:
458 return PORT_CLK_SEL_LCPLL_2700;
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200459 default:
460 return PORT_CLK_SEL_NONE;
461 }
462}
463
464#define LC_FREQ 2700
465#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
466
467#define P_MIN 2
468#define P_MAX 64
469#define P_INC 2
470
471/* Constraints for PLL good behavior */
472#define REF_MIN 48
473#define REF_MAX 400
474#define VCO_MIN 2400
475#define VCO_MAX 4800
476
477struct hsw_wrpll_rnp {
478 unsigned p, n2, r2;
479};
480
481static unsigned hsw_wrpll_get_budget_for_freq(int clock)
482{
483 unsigned budget;
484
485 switch (clock) {
486 case 25175000:
487 case 25200000:
488 case 27000000:
489 case 27027000:
490 case 37762500:
491 case 37800000:
492 case 40500000:
493 case 40541000:
494 case 54000000:
495 case 54054000:
496 case 59341000:
497 case 59400000:
498 case 72000000:
499 case 74176000:
500 case 74250000:
501 case 81000000:
502 case 81081000:
503 case 89012000:
504 case 89100000:
505 case 108000000:
506 case 108108000:
507 case 111264000:
508 case 111375000:
509 case 148352000:
510 case 148500000:
511 case 162000000:
512 case 162162000:
513 case 222525000:
514 case 222750000:
515 case 296703000:
516 case 297000000:
517 budget = 0;
518 break;
519 case 233500000:
520 case 245250000:
521 case 247750000:
522 case 253250000:
523 case 298000000:
524 budget = 1500;
525 break;
526 case 169128000:
527 case 169500000:
528 case 179500000:
529 case 202000000:
530 budget = 2000;
531 break;
532 case 256250000:
533 case 262500000:
534 case 270000000:
535 case 272500000:
536 case 273750000:
537 case 280750000:
538 case 281250000:
539 case 286000000:
540 case 291750000:
541 budget = 4000;
542 break;
543 case 267250000:
544 case 268500000:
545 budget = 5000;
546 break;
547 default:
548 budget = 1000;
549 break;
550 }
551
552 return budget;
553}
554
555static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
556 unsigned r2, unsigned n2, unsigned p,
557 struct hsw_wrpll_rnp *best)
558{
559 uint64_t a, b, c, d, diff, diff_best;
560
561 /* No best (r,n,p) yet */
562 if (best->p == 0) {
563 best->p = p;
564 best->n2 = n2;
565 best->r2 = r2;
566 return;
567 }
568
569 /*
570 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
571 * freq2k.
572 *
573 * delta = 1e6 *
574 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
575 * freq2k;
576 *
577 * and we would like delta <= budget.
578 *
579 * If the discrepancy is above the PPM-based budget, always prefer to
580 * improve upon the previous solution. However, if you're within the
581 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
582 */
583 a = freq2k * budget * p * r2;
584 b = freq2k * budget * best->p * best->r2;
585 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
586 diff_best = abs_diff(freq2k * best->p * best->r2,
587 LC_FREQ_2K * best->n2);
588 c = 1000000 * diff;
589 d = 1000000 * diff_best;
590
591 if (a < c && b < d) {
592 /* If both are above the budget, pick the closer */
593 if (best->p * best->r2 * diff < p * r2 * diff_best) {
594 best->p = p;
595 best->n2 = n2;
596 best->r2 = r2;
597 }
598 } else if (a >= c && b < d) {
599 /* If A is below the threshold but B is above it? Update. */
600 best->p = p;
601 best->n2 = n2;
602 best->r2 = r2;
603 } else if (a >= c && b >= d) {
604 /* Both are below the limit, so pick the higher n2/(r2*r2) */
605 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
606 best->p = p;
607 best->n2 = n2;
608 best->r2 = r2;
609 }
610 }
611 /* Otherwise a < c && b >= d, do nothing */
612}
613
614static void
615hsw_ddi_calculate_wrpll(int clock /* in Hz */,
616 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
617{
618 uint64_t freq2k;
619 unsigned p, n2, r2;
620 struct hsw_wrpll_rnp best = { 0, 0, 0 };
621 unsigned budget;
622
623 freq2k = clock / 100;
624
625 budget = hsw_wrpll_get_budget_for_freq(clock);
626
627 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
628 * and directly pass the LC PLL to it. */
629 if (freq2k == 5400000) {
630 *n2_out = 2;
631 *p_out = 1;
632 *r2_out = 2;
633 return;
634 }
635
636 /*
637 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
638 * the WR PLL.
639 *
640 * We want R so that REF_MIN <= Ref <= REF_MAX.
641 * Injecting R2 = 2 * R gives:
642 * REF_MAX * r2 > LC_FREQ * 2 and
643 * REF_MIN * r2 < LC_FREQ * 2
644 *
645 * Which means the desired boundaries for r2 are:
646 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
647 *
648 */
649 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
650 r2 <= LC_FREQ * 2 / REF_MIN;
651 r2++) {
652
653 /*
654 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
655 *
656 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
657 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
658 * VCO_MAX * r2 > n2 * LC_FREQ and
659 * VCO_MIN * r2 < n2 * LC_FREQ)
660 *
661 * Which means the desired boundaries for n2 are:
662 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
663 */
664 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
665 n2 <= VCO_MAX * r2 / LC_FREQ;
666 n2++) {
667
668 for (p = P_MIN; p <= P_MAX; p += P_INC)
669 hsw_wrpll_update_rnp(freq2k, budget,
670 r2, n2, p, &best);
671 }
672 }
673
674 *n2_out = best.n2;
675 *p_out = best.p;
676 *r2_out = best.r2;
677}
678
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200679static struct intel_shared_dpll *
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200680hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
681 struct intel_encoder *encoder)
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200682{
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +0200683 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200684 struct intel_shared_dpll *pll;
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200685 int clock = crtc_state->port_clock;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200686
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +0200687 memset(&crtc_state->dpll_hw_state, 0,
688 sizeof(crtc_state->dpll_hw_state));
689
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200690 if (encoder->type == INTEL_OUTPUT_HDMI) {
691 uint32_t val;
692 unsigned p, n2, r2;
693
694 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
695
696 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
697 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
698 WRPLL_DIVIDER_POST(p);
699
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200700 crtc_state->dpll_hw_state.wrpll = val;
701
702 pll = intel_find_shared_dpll(crtc, crtc_state,
703 DPLL_ID_WRPLL1, DPLL_ID_WRPLL2);
704
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +0200705 } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
706 encoder->type == INTEL_OUTPUT_DP_MST ||
707 encoder->type == INTEL_OUTPUT_EDP) {
708 enum intel_dpll_id pll_id;
709
710 switch (clock / 2) {
711 case 81000:
712 pll_id = DPLL_ID_LCPLL_810;
713 break;
714 case 135000:
715 pll_id = DPLL_ID_LCPLL_1350;
716 break;
717 case 270000:
718 pll_id = DPLL_ID_LCPLL_2700;
719 break;
720 default:
721 DRM_DEBUG_KMS("Invalid clock for DP: %d\n", clock);
722 return NULL;
723 }
724
725 pll = intel_get_shared_dpll_by_id(dev_priv, pll_id);
726
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200727 } else if (encoder->type == INTEL_OUTPUT_ANALOG) {
728 if (WARN_ON(crtc_state->port_clock / 2 != 135000))
729 return NULL;
730
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200731 crtc_state->dpll_hw_state.spll =
732 SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC;
733
734 pll = intel_find_shared_dpll(crtc, crtc_state,
735 DPLL_ID_SPLL, DPLL_ID_SPLL);
736 } else {
737 return NULL;
738 }
739
740 if (!pll)
741 return NULL;
742
743 crtc_state->ddi_pll_sel = hsw_pll_to_ddi_pll_sel(pll);
744
745 intel_reference_shared_dpll(pll, crtc_state);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200746
747 return pll;
748}
749
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200750
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +0200751static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
752 .enable = hsw_ddi_wrpll_enable,
753 .disable = hsw_ddi_wrpll_disable,
754 .get_hw_state = hsw_ddi_wrpll_get_hw_state,
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200755};
756
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +0200757static const struct intel_shared_dpll_funcs hsw_ddi_spll_funcs = {
758 .enable = hsw_ddi_spll_enable,
759 .disable = hsw_ddi_spll_disable,
760 .get_hw_state = hsw_ddi_spll_get_hw_state,
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200761};
762
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +0200763static void hsw_ddi_lcpll_enable(struct drm_i915_private *dev_priv,
764 struct intel_shared_dpll *pll)
765{
766}
767
768static void hsw_ddi_lcpll_disable(struct drm_i915_private *dev_priv,
769 struct intel_shared_dpll *pll)
770{
771}
772
773static bool hsw_ddi_lcpll_get_hw_state(struct drm_i915_private *dev_priv,
774 struct intel_shared_dpll *pll,
775 struct intel_dpll_hw_state *hw_state)
776{
777 return true;
778}
779
780static const struct intel_shared_dpll_funcs hsw_ddi_lcpll_funcs = {
781 .enable = hsw_ddi_lcpll_enable,
782 .disable = hsw_ddi_lcpll_disable,
783 .get_hw_state = hsw_ddi_lcpll_get_hw_state,
784};
785
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200786struct skl_dpll_regs {
787 i915_reg_t ctl, cfgcr1, cfgcr2;
788};
789
790/* this array is indexed by the *shared* pll id */
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200791static const struct skl_dpll_regs skl_dpll_regs[4] = {
792 {
793 /* DPLL 0 */
794 .ctl = LCPLL1_CTL,
795 /* DPLL 0 doesn't support HDMI mode */
796 },
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200797 {
798 /* DPLL 1 */
799 .ctl = LCPLL2_CTL,
800 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
801 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
802 },
803 {
804 /* DPLL 2 */
805 .ctl = WRPLL_CTL(0),
806 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
807 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
808 },
809 {
810 /* DPLL 3 */
811 .ctl = WRPLL_CTL(1),
812 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
813 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
814 },
815};
816
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200817static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *dev_priv,
818 struct intel_shared_dpll *pll)
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200819{
820 uint32_t val;
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200821
822 val = I915_READ(DPLL_CTRL1);
823
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200824 val &= ~(DPLL_CTRL1_HDMI_MODE(pll->id) | DPLL_CTRL1_SSC(pll->id) |
825 DPLL_CTRL1_LINK_RATE_MASK(pll->id));
826 val |= pll->config.hw_state.ctrl1 << (pll->id * 6);
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200827
828 I915_WRITE(DPLL_CTRL1, val);
829 POSTING_READ(DPLL_CTRL1);
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200830}
831
832static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
833 struct intel_shared_dpll *pll)
834{
835 const struct skl_dpll_regs *regs = skl_dpll_regs;
836
837 skl_ddi_pll_write_ctrl1(dev_priv, pll);
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200838
839 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
840 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
841 POSTING_READ(regs[pll->id].cfgcr1);
842 POSTING_READ(regs[pll->id].cfgcr2);
843
844 /* the enable bit is always bit 31 */
845 I915_WRITE(regs[pll->id].ctl,
846 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
847
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200848 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(pll->id), 5))
849 DRM_ERROR("DPLL %d not locked\n", pll->id);
850}
851
852static void skl_ddi_dpll0_enable(struct drm_i915_private *dev_priv,
853 struct intel_shared_dpll *pll)
854{
855 skl_ddi_pll_write_ctrl1(dev_priv, pll);
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200856}
857
858static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
859 struct intel_shared_dpll *pll)
860{
861 const struct skl_dpll_regs *regs = skl_dpll_regs;
862
863 /* the enable bit is always bit 31 */
864 I915_WRITE(regs[pll->id].ctl,
865 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
866 POSTING_READ(regs[pll->id].ctl);
867}
868
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200869static void skl_ddi_dpll0_disable(struct drm_i915_private *dev_priv,
870 struct intel_shared_dpll *pll)
871{
872}
873
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200874static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
875 struct intel_shared_dpll *pll,
876 struct intel_dpll_hw_state *hw_state)
877{
878 uint32_t val;
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200879 const struct skl_dpll_regs *regs = skl_dpll_regs;
880 bool ret;
881
882 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
883 return false;
884
885 ret = false;
886
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200887 val = I915_READ(regs[pll->id].ctl);
888 if (!(val & LCPLL_PLL_ENABLE))
889 goto out;
890
891 val = I915_READ(DPLL_CTRL1);
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200892 hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200893
894 /* avoid reading back stale values if HDMI mode is not enabled */
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200895 if (val & DPLL_CTRL1_HDMI_MODE(pll->id)) {
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200896 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
897 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
898 }
899 ret = true;
900
901out:
902 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
903
904 return ret;
905}
906
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200907static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv,
908 struct intel_shared_dpll *pll,
909 struct intel_dpll_hw_state *hw_state)
910{
911 uint32_t val;
912 const struct skl_dpll_regs *regs = skl_dpll_regs;
913 bool ret;
914
915 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
916 return false;
917
918 ret = false;
919
920 /* DPLL0 is always enabled since it drives CDCLK */
921 val = I915_READ(regs[pll->id].ctl);
922 if (WARN_ON(!(val & LCPLL_PLL_ENABLE)))
923 goto out;
924
925 val = I915_READ(DPLL_CTRL1);
926 hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
927
928 ret = true;
929
930out:
931 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
932
933 return ret;
934}
935
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +0200936struct skl_wrpll_context {
937 uint64_t min_deviation; /* current minimal deviation */
938 uint64_t central_freq; /* chosen central freq */
939 uint64_t dco_freq; /* chosen dco freq */
940 unsigned int p; /* chosen divider */
941};
942
943static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
944{
945 memset(ctx, 0, sizeof(*ctx));
946
947 ctx->min_deviation = U64_MAX;
948}
949
950/* DCO freq must be within +1%/-6% of the DCO central freq */
951#define SKL_DCO_MAX_PDEVIATION 100
952#define SKL_DCO_MAX_NDEVIATION 600
953
954static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
955 uint64_t central_freq,
956 uint64_t dco_freq,
957 unsigned int divider)
958{
959 uint64_t deviation;
960
961 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
962 central_freq);
963
964 /* positive deviation */
965 if (dco_freq >= central_freq) {
966 if (deviation < SKL_DCO_MAX_PDEVIATION &&
967 deviation < ctx->min_deviation) {
968 ctx->min_deviation = deviation;
969 ctx->central_freq = central_freq;
970 ctx->dco_freq = dco_freq;
971 ctx->p = divider;
972 }
973 /* negative deviation */
974 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
975 deviation < ctx->min_deviation) {
976 ctx->min_deviation = deviation;
977 ctx->central_freq = central_freq;
978 ctx->dco_freq = dco_freq;
979 ctx->p = divider;
980 }
981}
982
983static void skl_wrpll_get_multipliers(unsigned int p,
984 unsigned int *p0 /* out */,
985 unsigned int *p1 /* out */,
986 unsigned int *p2 /* out */)
987{
988 /* even dividers */
989 if (p % 2 == 0) {
990 unsigned int half = p / 2;
991
992 if (half == 1 || half == 2 || half == 3 || half == 5) {
993 *p0 = 2;
994 *p1 = 1;
995 *p2 = half;
996 } else if (half % 2 == 0) {
997 *p0 = 2;
998 *p1 = half / 2;
999 *p2 = 2;
1000 } else if (half % 3 == 0) {
1001 *p0 = 3;
1002 *p1 = half / 3;
1003 *p2 = 2;
1004 } else if (half % 7 == 0) {
1005 *p0 = 7;
1006 *p1 = half / 7;
1007 *p2 = 2;
1008 }
1009 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1010 *p0 = 3;
1011 *p1 = 1;
1012 *p2 = p / 3;
1013 } else if (p == 5 || p == 7) {
1014 *p0 = p;
1015 *p1 = 1;
1016 *p2 = 1;
1017 } else if (p == 15) {
1018 *p0 = 3;
1019 *p1 = 1;
1020 *p2 = 5;
1021 } else if (p == 21) {
1022 *p0 = 7;
1023 *p1 = 1;
1024 *p2 = 3;
1025 } else if (p == 35) {
1026 *p0 = 7;
1027 *p1 = 1;
1028 *p2 = 5;
1029 }
1030}
1031
1032struct skl_wrpll_params {
1033 uint32_t dco_fraction;
1034 uint32_t dco_integer;
1035 uint32_t qdiv_ratio;
1036 uint32_t qdiv_mode;
1037 uint32_t kdiv;
1038 uint32_t pdiv;
1039 uint32_t central_freq;
1040};
1041
1042static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1043 uint64_t afe_clock,
1044 uint64_t central_freq,
1045 uint32_t p0, uint32_t p1, uint32_t p2)
1046{
1047 uint64_t dco_freq;
1048
1049 switch (central_freq) {
1050 case 9600000000ULL:
1051 params->central_freq = 0;
1052 break;
1053 case 9000000000ULL:
1054 params->central_freq = 1;
1055 break;
1056 case 8400000000ULL:
1057 params->central_freq = 3;
1058 }
1059
1060 switch (p0) {
1061 case 1:
1062 params->pdiv = 0;
1063 break;
1064 case 2:
1065 params->pdiv = 1;
1066 break;
1067 case 3:
1068 params->pdiv = 2;
1069 break;
1070 case 7:
1071 params->pdiv = 4;
1072 break;
1073 default:
1074 WARN(1, "Incorrect PDiv\n");
1075 }
1076
1077 switch (p2) {
1078 case 5:
1079 params->kdiv = 0;
1080 break;
1081 case 2:
1082 params->kdiv = 1;
1083 break;
1084 case 3:
1085 params->kdiv = 2;
1086 break;
1087 case 1:
1088 params->kdiv = 3;
1089 break;
1090 default:
1091 WARN(1, "Incorrect KDiv\n");
1092 }
1093
1094 params->qdiv_ratio = p1;
1095 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1096
1097 dco_freq = p0 * p1 * p2 * afe_clock;
1098
1099 /*
1100 * Intermediate values are in Hz.
1101 * Divide by MHz to match bsepc
1102 */
1103 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
1104 params->dco_fraction =
1105 div_u64((div_u64(dco_freq, 24) -
1106 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
1107}
1108
1109static bool
1110skl_ddi_calculate_wrpll(int clock /* in Hz */,
1111 struct skl_wrpll_params *wrpll_params)
1112{
1113 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
1114 uint64_t dco_central_freq[3] = {8400000000ULL,
1115 9000000000ULL,
1116 9600000000ULL};
1117 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1118 24, 28, 30, 32, 36, 40, 42, 44,
1119 48, 52, 54, 56, 60, 64, 66, 68,
1120 70, 72, 76, 78, 80, 84, 88, 90,
1121 92, 96, 98 };
1122 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1123 static const struct {
1124 const int *list;
1125 int n_dividers;
1126 } dividers[] = {
1127 { even_dividers, ARRAY_SIZE(even_dividers) },
1128 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1129 };
1130 struct skl_wrpll_context ctx;
1131 unsigned int dco, d, i;
1132 unsigned int p0, p1, p2;
1133
1134 skl_wrpll_context_init(&ctx);
1135
1136 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1137 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1138 for (i = 0; i < dividers[d].n_dividers; i++) {
1139 unsigned int p = dividers[d].list[i];
1140 uint64_t dco_freq = p * afe_clock;
1141
1142 skl_wrpll_try_divider(&ctx,
1143 dco_central_freq[dco],
1144 dco_freq,
1145 p);
1146 /*
1147 * Skip the remaining dividers if we're sure to
1148 * have found the definitive divider, we can't
1149 * improve a 0 deviation.
1150 */
1151 if (ctx.min_deviation == 0)
1152 goto skip_remaining_dividers;
1153 }
1154 }
1155
1156skip_remaining_dividers:
1157 /*
1158 * If a solution is found with an even divider, prefer
1159 * this one.
1160 */
1161 if (d == 0 && ctx.p)
1162 break;
1163 }
1164
1165 if (!ctx.p) {
1166 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
1167 return false;
1168 }
1169
1170 /*
1171 * gcc incorrectly analyses that these can be used without being
1172 * initialized. To be fair, it's hard to guess.
1173 */
1174 p0 = p1 = p2 = 0;
1175 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1176 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1177 p0, p1, p2);
1178
1179 return true;
1180}
1181
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001182static struct intel_shared_dpll *
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +02001183skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
1184 struct intel_encoder *encoder)
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001185{
1186 struct intel_shared_dpll *pll;
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +02001187 uint32_t ctrl1, cfgcr1, cfgcr2;
1188 int clock = crtc_state->port_clock;
1189
1190 /*
1191 * See comment in intel_dpll_hw_state to understand why we always use 0
1192 * as the DPLL id in this function.
1193 */
1194
1195 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1196
1197 if (encoder->type == INTEL_OUTPUT_HDMI) {
1198 struct skl_wrpll_params wrpll_params = { 0, };
1199
1200 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1201
1202 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1203 return false;
1204
1205 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1206 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1207 wrpll_params.dco_integer;
1208
1209 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1210 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1211 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1212 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1213 wrpll_params.central_freq;
1214 } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001215 encoder->type == INTEL_OUTPUT_DP_MST ||
1216 encoder->type == INTEL_OUTPUT_EDP) {
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +02001217 switch (crtc_state->port_clock / 2) {
1218 case 81000:
1219 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
1220 break;
1221 case 135000:
1222 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
1223 break;
1224 case 270000:
1225 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
1226 break;
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001227 /* eDP 1.4 rates */
1228 case 162000:
1229 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
1230 break;
1231 /* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is 8640 which
1232 results in CDCLK change. Need to handle the change of CDCLK by
1233 disabling pipes and re-enabling them */
1234 case 108000:
1235 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, 0);
1236 break;
1237 case 216000:
1238 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, 0);
1239 break;
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +02001240 }
1241
1242 cfgcr1 = cfgcr2 = 0;
1243 } else {
1244 return NULL;
1245 }
1246
1247 memset(&crtc_state->dpll_hw_state, 0,
1248 sizeof(crtc_state->dpll_hw_state));
1249
1250 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1251 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1252 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001253
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001254 if (encoder->type == INTEL_OUTPUT_EDP)
1255 pll = intel_find_shared_dpll(crtc, crtc_state,
1256 DPLL_ID_SKL_DPLL0,
1257 DPLL_ID_SKL_DPLL0);
1258 else
1259 pll = intel_find_shared_dpll(crtc, crtc_state,
1260 DPLL_ID_SKL_DPLL1,
1261 DPLL_ID_SKL_DPLL3);
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +02001262 if (!pll)
1263 return NULL;
1264
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001265 crtc_state->ddi_pll_sel = pll->id;
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +02001266
1267 intel_reference_shared_dpll(pll, crtc_state);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001268
1269 return pll;
1270}
1271
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001272static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
1273 .enable = skl_ddi_pll_enable,
1274 .disable = skl_ddi_pll_disable,
1275 .get_hw_state = skl_ddi_pll_get_hw_state,
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +02001276};
1277
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001278static const struct intel_shared_dpll_funcs skl_ddi_dpll0_funcs = {
1279 .enable = skl_ddi_dpll0_enable,
1280 .disable = skl_ddi_dpll0_disable,
1281 .get_hw_state = skl_ddi_dpll0_get_hw_state,
1282};
1283
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +02001284static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
1285 struct intel_shared_dpll *pll)
1286{
1287 uint32_t temp;
1288 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
1289
1290 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
1291 temp &= ~PORT_PLL_REF_SEL;
1292 /* Non-SSC reference */
1293 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
1294
1295 /* Disable 10 bit clock */
1296 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
1297 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
1298 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
1299
1300 /* Write P1 & P2 */
1301 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
1302 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
1303 temp |= pll->config.hw_state.ebb0;
1304 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
1305
1306 /* Write M2 integer */
1307 temp = I915_READ(BXT_PORT_PLL(port, 0));
1308 temp &= ~PORT_PLL_M2_MASK;
1309 temp |= pll->config.hw_state.pll0;
1310 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
1311
1312 /* Write N */
1313 temp = I915_READ(BXT_PORT_PLL(port, 1));
1314 temp &= ~PORT_PLL_N_MASK;
1315 temp |= pll->config.hw_state.pll1;
1316 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
1317
1318 /* Write M2 fraction */
1319 temp = I915_READ(BXT_PORT_PLL(port, 2));
1320 temp &= ~PORT_PLL_M2_FRAC_MASK;
1321 temp |= pll->config.hw_state.pll2;
1322 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
1323
1324 /* Write M2 fraction enable */
1325 temp = I915_READ(BXT_PORT_PLL(port, 3));
1326 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
1327 temp |= pll->config.hw_state.pll3;
1328 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
1329
1330 /* Write coeff */
1331 temp = I915_READ(BXT_PORT_PLL(port, 6));
1332 temp &= ~PORT_PLL_PROP_COEFF_MASK;
1333 temp &= ~PORT_PLL_INT_COEFF_MASK;
1334 temp &= ~PORT_PLL_GAIN_CTL_MASK;
1335 temp |= pll->config.hw_state.pll6;
1336 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
1337
1338 /* Write calibration val */
1339 temp = I915_READ(BXT_PORT_PLL(port, 8));
1340 temp &= ~PORT_PLL_TARGET_CNT_MASK;
1341 temp |= pll->config.hw_state.pll8;
1342 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
1343
1344 temp = I915_READ(BXT_PORT_PLL(port, 9));
1345 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
1346 temp |= pll->config.hw_state.pll9;
1347 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
1348
1349 temp = I915_READ(BXT_PORT_PLL(port, 10));
1350 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
1351 temp &= ~PORT_PLL_DCO_AMP_MASK;
1352 temp |= pll->config.hw_state.pll10;
1353 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
1354
1355 /* Recalibrate with new settings */
1356 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
1357 temp |= PORT_PLL_RECALIBRATE;
1358 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
1359 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
1360 temp |= pll->config.hw_state.ebb4;
1361 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
1362
1363 /* Enable PLL */
1364 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
1365 temp |= PORT_PLL_ENABLE;
1366 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
1367 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
1368
1369 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
1370 PORT_PLL_LOCK), 200))
1371 DRM_ERROR("PLL %d not locked\n", port);
1372
1373 /*
1374 * While we write to the group register to program all lanes at once we
1375 * can read only lane registers and we pick lanes 0/1 for that.
1376 */
1377 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
1378 temp &= ~LANE_STAGGER_MASK;
1379 temp &= ~LANESTAGGER_STRAP_OVRD;
1380 temp |= pll->config.hw_state.pcsdw12;
1381 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
1382}
1383
1384static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
1385 struct intel_shared_dpll *pll)
1386{
1387 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
1388 uint32_t temp;
1389
1390 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
1391 temp &= ~PORT_PLL_ENABLE;
1392 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
1393 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
1394}
1395
1396static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
1397 struct intel_shared_dpll *pll,
1398 struct intel_dpll_hw_state *hw_state)
1399{
1400 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
1401 uint32_t val;
1402 bool ret;
1403
1404 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
1405 return false;
1406
1407 ret = false;
1408
1409 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
1410 if (!(val & PORT_PLL_ENABLE))
1411 goto out;
1412
1413 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
1414 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
1415
1416 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
1417 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
1418
1419 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
1420 hw_state->pll0 &= PORT_PLL_M2_MASK;
1421
1422 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
1423 hw_state->pll1 &= PORT_PLL_N_MASK;
1424
1425 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
1426 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
1427
1428 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
1429 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
1430
1431 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
1432 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
1433 PORT_PLL_INT_COEFF_MASK |
1434 PORT_PLL_GAIN_CTL_MASK;
1435
1436 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
1437 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
1438
1439 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
1440 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
1441
1442 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
1443 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
1444 PORT_PLL_DCO_AMP_MASK;
1445
1446 /*
1447 * While we write to the group register to program all lanes at once we
1448 * can read only lane registers. We configure all lanes the same way, so
1449 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
1450 */
1451 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
1452 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
1453 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
1454 hw_state->pcsdw12,
1455 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
1456 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
1457
1458 ret = true;
1459
1460out:
1461 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
1462
1463 return ret;
1464}
1465
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001466/* bxt clock parameters */
1467struct bxt_clk_div {
1468 int clock;
1469 uint32_t p1;
1470 uint32_t p2;
1471 uint32_t m2_int;
1472 uint32_t m2_frac;
1473 bool m2_frac_en;
1474 uint32_t n;
1475};
1476
1477/* pre-calculated values for DP linkrates */
1478static const struct bxt_clk_div bxt_dp_clk_val[] = {
1479 {162000, 4, 2, 32, 1677722, 1, 1},
1480 {270000, 4, 1, 27, 0, 0, 1},
1481 {540000, 2, 1, 27, 0, 0, 1},
1482 {216000, 3, 2, 32, 1677722, 1, 1},
1483 {243000, 4, 1, 24, 1258291, 1, 1},
1484 {324000, 4, 1, 32, 1677722, 1, 1},
1485 {432000, 3, 1, 32, 1677722, 1, 1}
1486};
1487
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001488static struct intel_shared_dpll *
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +02001489bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
1490 struct intel_encoder *encoder)
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001491{
1492 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001493 struct intel_shared_dpll *pll;
1494 enum intel_dpll_id i;
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001495 struct intel_digital_port *intel_dig_port;
1496 struct bxt_clk_div clk_div = {0};
1497 int vco = 0;
1498 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
1499 uint32_t lanestagger;
1500 int clock = crtc_state->port_clock;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001501
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001502 if (encoder->type == INTEL_OUTPUT_HDMI) {
1503 intel_clock_t best_clock;
1504
1505 /* Calculate HDMI div */
1506 /*
1507 * FIXME: tie the following calculation into
1508 * i9xx_crtc_compute_clock
1509 */
1510 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1511 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1512 clock, pipe_name(crtc->pipe));
1513 return NULL;
1514 }
1515
1516 clk_div.p1 = best_clock.p1;
1517 clk_div.p2 = best_clock.p2;
1518 WARN_ON(best_clock.m1 != 2);
1519 clk_div.n = best_clock.n;
1520 clk_div.m2_int = best_clock.m2 >> 22;
1521 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1522 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1523
1524 vco = best_clock.vco;
1525 } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1526 encoder->type == INTEL_OUTPUT_EDP) {
1527 int i;
1528
1529 clk_div = bxt_dp_clk_val[0];
1530 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1531 if (bxt_dp_clk_val[i].clock == clock) {
1532 clk_div = bxt_dp_clk_val[i];
1533 break;
1534 }
1535 }
1536 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1537 }
1538
1539 if (vco >= 6200000 && vco <= 6700000) {
1540 prop_coef = 4;
1541 int_coef = 9;
1542 gain_ctl = 3;
1543 targ_cnt = 8;
1544 } else if ((vco > 5400000 && vco < 6200000) ||
1545 (vco >= 4800000 && vco < 5400000)) {
1546 prop_coef = 5;
1547 int_coef = 11;
1548 gain_ctl = 3;
1549 targ_cnt = 9;
1550 } else if (vco == 5400000) {
1551 prop_coef = 3;
1552 int_coef = 8;
1553 gain_ctl = 1;
1554 targ_cnt = 9;
1555 } else {
1556 DRM_ERROR("Invalid VCO\n");
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001557 return NULL;
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001558 }
1559
1560 memset(&crtc_state->dpll_hw_state, 0,
1561 sizeof(crtc_state->dpll_hw_state));
1562
1563 if (clock > 270000)
1564 lanestagger = 0x18;
1565 else if (clock > 135000)
1566 lanestagger = 0x0d;
1567 else if (clock > 67000)
1568 lanestagger = 0x07;
1569 else if (clock > 33000)
1570 lanestagger = 0x04;
1571 else
1572 lanestagger = 0x02;
1573
1574 crtc_state->dpll_hw_state.ebb0 =
1575 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1576 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1577 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1578 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1579
1580 if (clk_div.m2_frac_en)
1581 crtc_state->dpll_hw_state.pll3 =
1582 PORT_PLL_M2_FRAC_ENABLE;
1583
1584 crtc_state->dpll_hw_state.pll6 =
1585 prop_coef | PORT_PLL_INT_COEFF(int_coef);
1586 crtc_state->dpll_hw_state.pll6 |=
1587 PORT_PLL_GAIN_CTL(gain_ctl);
1588
1589 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1590
1591 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1592
1593 crtc_state->dpll_hw_state.pll10 =
1594 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1595 | PORT_PLL_DCO_AMP_OVR_EN_H;
1596
1597 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1598
1599 crtc_state->dpll_hw_state.pcsdw12 =
1600 LANESTAGGER_STRAP_OVRD | lanestagger;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001601
1602 intel_dig_port = enc_to_dig_port(&encoder->base);
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001603
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001604 /* 1:1 mapping between ports and PLLs */
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001605 i = (enum intel_dpll_id) intel_dig_port->port;
1606 pll = intel_get_shared_dpll_by_id(dev_priv, i);
1607
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001608 DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
1609 crtc->base.base.id, pll->name);
1610
1611 intel_reference_shared_dpll(pll, crtc_state);
1612
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001613 /* shared DPLL id 0 is DPLL A */
1614 crtc_state->ddi_pll_sel = pll->id;
1615
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001616 return pll;
1617}
1618
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001619static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
1620 .enable = bxt_ddi_pll_enable,
1621 .disable = bxt_ddi_pll_disable,
1622 .get_hw_state = bxt_ddi_pll_get_hw_state,
1623};
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +02001624
1625static void intel_ddi_pll_init(struct drm_device *dev)
1626{
1627 struct drm_i915_private *dev_priv = dev->dev_private;
1628 uint32_t val = I915_READ(LCPLL_CTL);
1629
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +02001630 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
1631 int cdclk_freq;
1632
1633 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
1634 dev_priv->skl_boot_cdclk = cdclk_freq;
1635 if (skl_sanitize_cdclk(dev_priv))
1636 DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
1637 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
1638 DRM_ERROR("LCPLL1 is disabled\n");
1639 } else if (IS_BROXTON(dev)) {
1640 broxton_init_cdclk(dev);
1641 broxton_ddi_phy_init(dev);
1642 } else {
1643 /*
1644 * The LCPLL register should be turned on by the BIOS. For now
1645 * let's just check its state and print errors in case
1646 * something is wrong. Don't even try to turn it on.
1647 */
1648
1649 if (val & LCPLL_CD_SOURCE_FCLK)
1650 DRM_ERROR("CDCLK source is not LCPLL\n");
1651
1652 if (val & LCPLL_PLL_DISABLE)
1653 DRM_ERROR("LCPLL is disabled\n");
1654 }
1655}
1656
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001657struct dpll_info {
1658 const char *name;
1659 const int id;
1660 const struct intel_shared_dpll_funcs *funcs;
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +02001661 uint32_t flags;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001662};
1663
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001664struct intel_dpll_mgr {
1665 const struct dpll_info *dpll_info;
1666
1667 struct intel_shared_dpll *(*get_dpll)(struct intel_crtc *crtc,
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +02001668 struct intel_crtc_state *crtc_state,
1669 struct intel_encoder *encoder);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001670};
1671
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001672static const struct dpll_info pch_plls[] = {
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +02001673 { "PCH DPLL A", DPLL_ID_PCH_PLL_A, &ibx_pch_dpll_funcs, 0 },
1674 { "PCH DPLL B", DPLL_ID_PCH_PLL_B, &ibx_pch_dpll_funcs, 0 },
1675 { NULL, -1, NULL, 0 },
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001676};
1677
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001678static const struct intel_dpll_mgr pch_pll_mgr = {
1679 .dpll_info = pch_plls,
1680 .get_dpll = ibx_get_dpll,
1681};
1682
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001683static const struct dpll_info hsw_plls[] = {
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +02001684 { "WRPLL 1", DPLL_ID_WRPLL1, &hsw_ddi_wrpll_funcs, 0 },
1685 { "WRPLL 2", DPLL_ID_WRPLL2, &hsw_ddi_wrpll_funcs, 0 },
1686 { "SPLL", DPLL_ID_SPLL, &hsw_ddi_spll_funcs, 0 },
1687 { "LCPLL 810", DPLL_ID_LCPLL_810, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON },
1688 { "LCPLL 1350", DPLL_ID_LCPLL_1350, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON },
1689 { "LCPLL 2700", DPLL_ID_LCPLL_2700, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON },
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001690 { NULL, -1, NULL, },
1691};
1692
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001693static const struct intel_dpll_mgr hsw_pll_mgr = {
1694 .dpll_info = hsw_plls,
1695 .get_dpll = hsw_get_dpll,
1696};
1697
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001698static const struct dpll_info skl_plls[] = {
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001699 { "DPLL 0", DPLL_ID_SKL_DPLL0, &skl_ddi_dpll0_funcs, INTEL_DPLL_ALWAYS_ON },
1700 { "DPPL 1", DPLL_ID_SKL_DPLL1, &skl_ddi_pll_funcs, 0 },
1701 { "DPPL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs, 0 },
1702 { "DPPL 3", DPLL_ID_SKL_DPLL3, &skl_ddi_pll_funcs, 0 },
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001703 { NULL, -1, NULL, },
1704};
1705
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001706static const struct intel_dpll_mgr skl_pll_mgr = {
1707 .dpll_info = skl_plls,
1708 .get_dpll = skl_get_dpll,
1709};
1710
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001711static const struct dpll_info bxt_plls[] = {
Imre Deak08250c42016-03-14 19:55:34 +02001712 { "PORT PLL A", DPLL_ID_SKL_DPLL0, &bxt_ddi_pll_funcs, 0 },
1713 { "PORT PLL B", DPLL_ID_SKL_DPLL1, &bxt_ddi_pll_funcs, 0 },
1714 { "PORT PLL C", DPLL_ID_SKL_DPLL2, &bxt_ddi_pll_funcs, 0 },
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001715 { NULL, -1, NULL, },
1716};
1717
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001718static const struct intel_dpll_mgr bxt_pll_mgr = {
1719 .dpll_info = bxt_plls,
1720 .get_dpll = bxt_get_dpll,
1721};
1722
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001723void intel_shared_dpll_init(struct drm_device *dev)
1724{
1725 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001726 const struct intel_dpll_mgr *dpll_mgr = NULL;
1727 const struct dpll_info *dpll_info;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001728 int i;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001729
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001730 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001731 dpll_mgr = &skl_pll_mgr;
Imre Deak08250c42016-03-14 19:55:34 +02001732 else if (IS_BROXTON(dev))
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001733 dpll_mgr = &bxt_pll_mgr;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001734 else if (HAS_DDI(dev))
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001735 dpll_mgr = &hsw_pll_mgr;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001736 else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001737 dpll_mgr = &pch_pll_mgr;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001738
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001739 if (!dpll_mgr) {
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001740 dev_priv->num_shared_dpll = 0;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001741 return;
1742 }
1743
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001744 dpll_info = dpll_mgr->dpll_info;
1745
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001746 for (i = 0; dpll_info[i].id >= 0; i++) {
1747 WARN_ON(i != dpll_info[i].id);
1748
1749 dev_priv->shared_dplls[i].id = dpll_info[i].id;
1750 dev_priv->shared_dplls[i].name = dpll_info[i].name;
1751 dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs;
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +02001752 dev_priv->shared_dplls[i].flags = dpll_info[i].flags;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001753 }
1754
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001755 dev_priv->dpll_mgr = dpll_mgr;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001756 dev_priv->num_shared_dpll = i;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001757
1758 BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001759
1760 /* FIXME: Move this to a more suitable place */
1761 if (HAS_DDI(dev))
1762 intel_ddi_pll_init(dev);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001763}
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001764
1765struct intel_shared_dpll *
1766intel_get_shared_dpll(struct intel_crtc *crtc,
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +02001767 struct intel_crtc_state *crtc_state,
1768 struct intel_encoder *encoder)
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001769{
1770 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1771 const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll_mgr;
1772
1773 if (WARN_ON(!dpll_mgr))
1774 return NULL;
1775
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +02001776 return dpll_mgr->get_dpll(crtc, crtc_state, encoder);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001777}