blob: 763132d1b63f3c7b70763c06f3a6b6c4d848b034 [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
Maarten Lankhorstfbf6d872016-03-23 14:51:12 +010092 mutex_lock(&dev_priv->dpll_lock);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +020093 WARN_ON(!pll->config.crtc_mask);
Maarten Lankhorstfbf6d872016-03-23 14:51:12 +010094 if (!pll->active_mask) {
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +020095 DRM_DEBUG_DRIVER("setting up %s\n", pll->name);
96 WARN_ON(pll->on);
97 assert_shared_dpll_disabled(dev_priv, pll);
98
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +020099 pll->funcs.mode_set(dev_priv, pll);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200100 }
Maarten Lankhorstfbf6d872016-03-23 14:51:12 +0100101 mutex_unlock(&dev_priv->dpll_lock);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200102}
103
104/**
105 * intel_enable_shared_dpll - enable PCH PLL
106 * @dev_priv: i915 private structure
107 * @pipe: pipe PLL to enable
108 *
109 * The PCH PLL needs to be enabled before the PCH transcoder, since it
110 * drives the transcoder clock.
111 */
112void intel_enable_shared_dpll(struct intel_crtc *crtc)
113{
114 struct drm_device *dev = crtc->base.dev;
115 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +0200116 struct intel_shared_dpll *pll = crtc->config->shared_dpll;
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100117 unsigned crtc_mask = 1 << drm_crtc_index(&crtc->base);
Maarten Lankhorstfbf6d872016-03-23 14:51:12 +0100118 unsigned old_mask;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200119
120 if (WARN_ON(pll == NULL))
121 return;
122
Maarten Lankhorstfbf6d872016-03-23 14:51:12 +0100123 mutex_lock(&dev_priv->dpll_lock);
124 old_mask = pll->active_mask;
125
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100126 if (WARN_ON(!(pll->config.crtc_mask & crtc_mask)) ||
127 WARN_ON(pll->active_mask & crtc_mask))
Maarten Lankhorstfbf6d872016-03-23 14:51:12 +0100128 goto out;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200129
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100130 pll->active_mask |= crtc_mask;
131
132 DRM_DEBUG_KMS("enable %s (active %x, on? %d) for crtc %d\n",
133 pll->name, pll->active_mask, pll->on,
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200134 crtc->base.base.id);
135
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100136 if (old_mask) {
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200137 WARN_ON(!pll->on);
138 assert_shared_dpll_enabled(dev_priv, pll);
Maarten Lankhorstfbf6d872016-03-23 14:51:12 +0100139 goto out;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200140 }
141 WARN_ON(pll->on);
142
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200143 DRM_DEBUG_KMS("enabling %s\n", pll->name);
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +0200144 pll->funcs.enable(dev_priv, pll);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200145 pll->on = true;
Maarten Lankhorstfbf6d872016-03-23 14:51:12 +0100146
147out:
148 mutex_unlock(&dev_priv->dpll_lock);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200149}
150
151void intel_disable_shared_dpll(struct intel_crtc *crtc)
152{
153 struct drm_device *dev = crtc->base.dev;
154 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +0200155 struct intel_shared_dpll *pll = crtc->config->shared_dpll;
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100156 unsigned crtc_mask = 1 << drm_crtc_index(&crtc->base);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200157
158 /* PCH only available on ILK+ */
159 if (INTEL_INFO(dev)->gen < 5)
160 return;
161
162 if (pll == NULL)
163 return;
164
Maarten Lankhorstfbf6d872016-03-23 14:51:12 +0100165 mutex_lock(&dev_priv->dpll_lock);
Maarten Lankhorsta1475e72016-03-14 09:27:53 +0100166 if (WARN_ON(!(pll->active_mask & crtc_mask)))
Maarten Lankhorstfbf6d872016-03-23 14:51:12 +0100167 goto out;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200168
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100169 DRM_DEBUG_KMS("disable %s (active %x, on? %d) for crtc %d\n",
170 pll->name, pll->active_mask, pll->on,
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200171 crtc->base.base.id);
172
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200173 assert_shared_dpll_enabled(dev_priv, pll);
174 WARN_ON(!pll->on);
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100175
176 pll->active_mask &= ~crtc_mask;
177 if (pll->active_mask)
Maarten Lankhorstfbf6d872016-03-23 14:51:12 +0100178 goto out;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200179
180 DRM_DEBUG_KMS("disabling %s\n", pll->name);
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +0200181 pll->funcs.disable(dev_priv, pll);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200182 pll->on = false;
Maarten Lankhorstfbf6d872016-03-23 14:51:12 +0100183
184out:
185 mutex_unlock(&dev_priv->dpll_lock);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200186}
187
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200188static struct intel_shared_dpll *
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200189intel_find_shared_dpll(struct intel_crtc *crtc,
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200190 struct intel_crtc_state *crtc_state,
191 enum intel_dpll_id range_min,
192 enum intel_dpll_id range_max)
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200193{
194 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
195 struct intel_shared_dpll *pll;
196 struct intel_shared_dpll_config *shared_dpll;
197 enum intel_dpll_id i;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200198
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200199 shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
200
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200201 for (i = range_min; i <= range_max; i++) {
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200202 pll = &dev_priv->shared_dplls[i];
203
204 /* Only want to check enabled timings first */
205 if (shared_dpll[i].crtc_mask == 0)
206 continue;
207
208 if (memcmp(&crtc_state->dpll_hw_state,
209 &shared_dpll[i].hw_state,
210 sizeof(crtc_state->dpll_hw_state)) == 0) {
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100211 DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 0x%08x, active %x)\n",
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200212 crtc->base.base.id, pll->name,
213 shared_dpll[i].crtc_mask,
Maarten Lankhorst2dd66ebd2016-03-14 09:27:52 +0100214 pll->active_mask);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200215 return pll;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200216 }
217 }
218
219 /* Ok no matching timings, maybe there's a free one? */
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200220 for (i = range_min; i <= range_max; i++) {
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200221 pll = &dev_priv->shared_dplls[i];
222 if (shared_dpll[i].crtc_mask == 0) {
223 DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
224 crtc->base.base.id, pll->name);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200225 return pll;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200226 }
227 }
228
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200229 return NULL;
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200230}
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200231
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200232static void
233intel_reference_shared_dpll(struct intel_shared_dpll *pll,
234 struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200235{
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200236 struct intel_shared_dpll_config *shared_dpll;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200237 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
238 enum intel_dpll_id i = pll->id;
Ander Conselvan de Oliveiraa4780b72016-03-08 17:46:17 +0200239
240 shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
241
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200242 if (shared_dpll[i].crtc_mask == 0)
243 shared_dpll[i].hw_state =
244 crtc_state->dpll_hw_state;
245
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +0200246 crtc_state->shared_dpll = pll;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200247 DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
248 pipe_name(crtc->pipe));
249
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +0200250 intel_shared_dpll_config_get(shared_dpll, pll, crtc);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200251}
252
253void intel_shared_dpll_commit(struct drm_atomic_state *state)
254{
255 struct drm_i915_private *dev_priv = to_i915(state->dev);
256 struct intel_shared_dpll_config *shared_dpll;
257 struct intel_shared_dpll *pll;
258 enum intel_dpll_id i;
259
260 if (!to_intel_atomic_state(state)->dpll_set)
261 return;
262
263 shared_dpll = to_intel_atomic_state(state)->shared_dpll;
264 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
265 pll = &dev_priv->shared_dplls[i];
266 pll->config = shared_dpll[i];
267 }
268}
269
270static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
271 struct intel_shared_dpll *pll,
272 struct intel_dpll_hw_state *hw_state)
273{
274 uint32_t val;
275
276 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
277 return false;
278
279 val = I915_READ(PCH_DPLL(pll->id));
280 hw_state->dpll = val;
281 hw_state->fp0 = I915_READ(PCH_FP0(pll->id));
282 hw_state->fp1 = I915_READ(PCH_FP1(pll->id));
283
284 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
285
286 return val & DPLL_VCO_ENABLE;
287}
288
289static void ibx_pch_dpll_mode_set(struct drm_i915_private *dev_priv,
290 struct intel_shared_dpll *pll)
291{
292 I915_WRITE(PCH_FP0(pll->id), pll->config.hw_state.fp0);
293 I915_WRITE(PCH_FP1(pll->id), pll->config.hw_state.fp1);
294}
295
296static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv)
297{
298 u32 val;
299 bool enabled;
300
Joonas Lahtinen2d1fe072016-04-07 11:08:05 +0300301 I915_STATE_WARN_ON(!(HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)));
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200302
303 val = I915_READ(PCH_DREF_CONTROL);
304 enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK |
305 DREF_SUPERSPREAD_SOURCE_MASK));
306 I915_STATE_WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n");
307}
308
309static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv,
310 struct intel_shared_dpll *pll)
311{
312 /* PCH refclock must be enabled first */
313 ibx_assert_pch_refclk_enabled(dev_priv);
314
315 I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll);
316
317 /* Wait for the clocks to stabilize. */
318 POSTING_READ(PCH_DPLL(pll->id));
319 udelay(150);
320
321 /* The pixel multiplier can only be updated once the
322 * DPLL is enabled and the clocks are stable.
323 *
324 * So write it again.
325 */
326 I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll);
327 POSTING_READ(PCH_DPLL(pll->id));
328 udelay(200);
329}
330
331static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
332 struct intel_shared_dpll *pll)
333{
334 struct drm_device *dev = dev_priv->dev;
335 struct intel_crtc *crtc;
336
337 /* Make sure no transcoder isn't still depending on us. */
338 for_each_intel_crtc(dev, crtc) {
Ander Conselvan de Oliveira8106ddb2016-03-08 17:46:18 +0200339 if (crtc->config->shared_dpll == pll)
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200340 assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
341 }
342
343 I915_WRITE(PCH_DPLL(pll->id), 0);
344 POSTING_READ(PCH_DPLL(pll->id));
345 udelay(200);
346}
347
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200348static struct intel_shared_dpll *
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200349ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
350 struct intel_encoder *encoder)
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200351{
352 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
353 struct intel_shared_dpll *pll;
354 enum intel_dpll_id i;
355
356 if (HAS_PCH_IBX(dev_priv)) {
357 /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
358 i = (enum intel_dpll_id) crtc->pipe;
359 pll = &dev_priv->shared_dplls[i];
360
361 DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
362 crtc->base.base.id, pll->name);
363 } else {
364 pll = intel_find_shared_dpll(crtc, crtc_state,
365 DPLL_ID_PCH_PLL_A,
366 DPLL_ID_PCH_PLL_B);
367 }
368
369 /* reference the pll */
370 intel_reference_shared_dpll(pll, crtc_state);
371
372 return pll;
373}
374
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +0200375static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
376 .mode_set = ibx_pch_dpll_mode_set,
377 .enable = ibx_pch_dpll_enable,
378 .disable = ibx_pch_dpll_disable,
379 .get_hw_state = ibx_pch_dpll_get_hw_state,
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +0200380};
381
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200382static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
383 struct intel_shared_dpll *pll)
384{
385 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
386 POSTING_READ(WRPLL_CTL(pll->id));
387 udelay(20);
388}
389
390static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
391 struct intel_shared_dpll *pll)
392{
393 I915_WRITE(SPLL_CTL, pll->config.hw_state.spll);
394 POSTING_READ(SPLL_CTL);
395 udelay(20);
396}
397
398static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
399 struct intel_shared_dpll *pll)
400{
401 uint32_t val;
402
403 val = I915_READ(WRPLL_CTL(pll->id));
404 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
405 POSTING_READ(WRPLL_CTL(pll->id));
406}
407
408static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
409 struct intel_shared_dpll *pll)
410{
411 uint32_t val;
412
413 val = I915_READ(SPLL_CTL);
414 I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
415 POSTING_READ(SPLL_CTL);
416}
417
418static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
419 struct intel_shared_dpll *pll,
420 struct intel_dpll_hw_state *hw_state)
421{
422 uint32_t val;
423
424 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
425 return false;
426
427 val = I915_READ(WRPLL_CTL(pll->id));
428 hw_state->wrpll = val;
429
430 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
431
432 return val & WRPLL_PLL_ENABLE;
433}
434
435static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
436 struct intel_shared_dpll *pll,
437 struct intel_dpll_hw_state *hw_state)
438{
439 uint32_t val;
440
441 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
442 return false;
443
444 val = I915_READ(SPLL_CTL);
445 hw_state->spll = val;
446
447 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
448
449 return val & SPLL_PLL_ENABLE;
450}
451
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200452static uint32_t hsw_pll_to_ddi_pll_sel(struct intel_shared_dpll *pll)
453{
454 switch (pll->id) {
455 case DPLL_ID_WRPLL1:
456 return PORT_CLK_SEL_WRPLL1;
457 case DPLL_ID_WRPLL2:
458 return PORT_CLK_SEL_WRPLL2;
459 case DPLL_ID_SPLL:
460 return PORT_CLK_SEL_SPLL;
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +0200461 case DPLL_ID_LCPLL_810:
462 return PORT_CLK_SEL_LCPLL_810;
463 case DPLL_ID_LCPLL_1350:
464 return PORT_CLK_SEL_LCPLL_1350;
465 case DPLL_ID_LCPLL_2700:
466 return PORT_CLK_SEL_LCPLL_2700;
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200467 default:
468 return PORT_CLK_SEL_NONE;
469 }
470}
471
472#define LC_FREQ 2700
473#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
474
475#define P_MIN 2
476#define P_MAX 64
477#define P_INC 2
478
479/* Constraints for PLL good behavior */
480#define REF_MIN 48
481#define REF_MAX 400
482#define VCO_MIN 2400
483#define VCO_MAX 4800
484
485struct hsw_wrpll_rnp {
486 unsigned p, n2, r2;
487};
488
489static unsigned hsw_wrpll_get_budget_for_freq(int clock)
490{
491 unsigned budget;
492
493 switch (clock) {
494 case 25175000:
495 case 25200000:
496 case 27000000:
497 case 27027000:
498 case 37762500:
499 case 37800000:
500 case 40500000:
501 case 40541000:
502 case 54000000:
503 case 54054000:
504 case 59341000:
505 case 59400000:
506 case 72000000:
507 case 74176000:
508 case 74250000:
509 case 81000000:
510 case 81081000:
511 case 89012000:
512 case 89100000:
513 case 108000000:
514 case 108108000:
515 case 111264000:
516 case 111375000:
517 case 148352000:
518 case 148500000:
519 case 162000000:
520 case 162162000:
521 case 222525000:
522 case 222750000:
523 case 296703000:
524 case 297000000:
525 budget = 0;
526 break;
527 case 233500000:
528 case 245250000:
529 case 247750000:
530 case 253250000:
531 case 298000000:
532 budget = 1500;
533 break;
534 case 169128000:
535 case 169500000:
536 case 179500000:
537 case 202000000:
538 budget = 2000;
539 break;
540 case 256250000:
541 case 262500000:
542 case 270000000:
543 case 272500000:
544 case 273750000:
545 case 280750000:
546 case 281250000:
547 case 286000000:
548 case 291750000:
549 budget = 4000;
550 break;
551 case 267250000:
552 case 268500000:
553 budget = 5000;
554 break;
555 default:
556 budget = 1000;
557 break;
558 }
559
560 return budget;
561}
562
563static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
564 unsigned r2, unsigned n2, unsigned p,
565 struct hsw_wrpll_rnp *best)
566{
567 uint64_t a, b, c, d, diff, diff_best;
568
569 /* No best (r,n,p) yet */
570 if (best->p == 0) {
571 best->p = p;
572 best->n2 = n2;
573 best->r2 = r2;
574 return;
575 }
576
577 /*
578 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
579 * freq2k.
580 *
581 * delta = 1e6 *
582 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
583 * freq2k;
584 *
585 * and we would like delta <= budget.
586 *
587 * If the discrepancy is above the PPM-based budget, always prefer to
588 * improve upon the previous solution. However, if you're within the
589 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
590 */
591 a = freq2k * budget * p * r2;
592 b = freq2k * budget * best->p * best->r2;
593 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
594 diff_best = abs_diff(freq2k * best->p * best->r2,
595 LC_FREQ_2K * best->n2);
596 c = 1000000 * diff;
597 d = 1000000 * diff_best;
598
599 if (a < c && b < d) {
600 /* If both are above the budget, pick the closer */
601 if (best->p * best->r2 * diff < p * r2 * diff_best) {
602 best->p = p;
603 best->n2 = n2;
604 best->r2 = r2;
605 }
606 } else if (a >= c && b < d) {
607 /* If A is below the threshold but B is above it? Update. */
608 best->p = p;
609 best->n2 = n2;
610 best->r2 = r2;
611 } else if (a >= c && b >= d) {
612 /* Both are below the limit, so pick the higher n2/(r2*r2) */
613 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
614 best->p = p;
615 best->n2 = n2;
616 best->r2 = r2;
617 }
618 }
619 /* Otherwise a < c && b >= d, do nothing */
620}
621
622static void
623hsw_ddi_calculate_wrpll(int clock /* in Hz */,
624 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
625{
626 uint64_t freq2k;
627 unsigned p, n2, r2;
628 struct hsw_wrpll_rnp best = { 0, 0, 0 };
629 unsigned budget;
630
631 freq2k = clock / 100;
632
633 budget = hsw_wrpll_get_budget_for_freq(clock);
634
635 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
636 * and directly pass the LC PLL to it. */
637 if (freq2k == 5400000) {
638 *n2_out = 2;
639 *p_out = 1;
640 *r2_out = 2;
641 return;
642 }
643
644 /*
645 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
646 * the WR PLL.
647 *
648 * We want R so that REF_MIN <= Ref <= REF_MAX.
649 * Injecting R2 = 2 * R gives:
650 * REF_MAX * r2 > LC_FREQ * 2 and
651 * REF_MIN * r2 < LC_FREQ * 2
652 *
653 * Which means the desired boundaries for r2 are:
654 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
655 *
656 */
657 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
658 r2 <= LC_FREQ * 2 / REF_MIN;
659 r2++) {
660
661 /*
662 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
663 *
664 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
665 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
666 * VCO_MAX * r2 > n2 * LC_FREQ and
667 * VCO_MIN * r2 < n2 * LC_FREQ)
668 *
669 * Which means the desired boundaries for n2 are:
670 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
671 */
672 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
673 n2 <= VCO_MAX * r2 / LC_FREQ;
674 n2++) {
675
676 for (p = P_MIN; p <= P_MAX; p += P_INC)
677 hsw_wrpll_update_rnp(freq2k, budget,
678 r2, n2, p, &best);
679 }
680 }
681
682 *n2_out = best.n2;
683 *p_out = best.p;
684 *r2_out = best.r2;
685}
686
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200687static struct intel_shared_dpll *
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200688hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
689 struct intel_encoder *encoder)
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200690{
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +0200691 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200692 struct intel_shared_dpll *pll;
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200693 int clock = crtc_state->port_clock;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200694
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +0200695 memset(&crtc_state->dpll_hw_state, 0,
696 sizeof(crtc_state->dpll_hw_state));
697
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200698 if (encoder->type == INTEL_OUTPUT_HDMI) {
699 uint32_t val;
700 unsigned p, n2, r2;
701
702 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
703
704 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
705 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
706 WRPLL_DIVIDER_POST(p);
707
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200708 crtc_state->dpll_hw_state.wrpll = val;
709
710 pll = intel_find_shared_dpll(crtc, crtc_state,
711 DPLL_ID_WRPLL1, DPLL_ID_WRPLL2);
712
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +0200713 } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
714 encoder->type == INTEL_OUTPUT_DP_MST ||
715 encoder->type == INTEL_OUTPUT_EDP) {
716 enum intel_dpll_id pll_id;
717
718 switch (clock / 2) {
719 case 81000:
720 pll_id = DPLL_ID_LCPLL_810;
721 break;
722 case 135000:
723 pll_id = DPLL_ID_LCPLL_1350;
724 break;
725 case 270000:
726 pll_id = DPLL_ID_LCPLL_2700;
727 break;
728 default:
729 DRM_DEBUG_KMS("Invalid clock for DP: %d\n", clock);
730 return NULL;
731 }
732
733 pll = intel_get_shared_dpll_by_id(dev_priv, pll_id);
734
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200735 } else if (encoder->type == INTEL_OUTPUT_ANALOG) {
736 if (WARN_ON(crtc_state->port_clock / 2 != 135000))
737 return NULL;
738
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +0200739 crtc_state->dpll_hw_state.spll =
740 SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC;
741
742 pll = intel_find_shared_dpll(crtc, crtc_state,
743 DPLL_ID_SPLL, DPLL_ID_SPLL);
744 } else {
745 return NULL;
746 }
747
748 if (!pll)
749 return NULL;
750
751 crtc_state->ddi_pll_sel = hsw_pll_to_ddi_pll_sel(pll);
752
753 intel_reference_shared_dpll(pll, crtc_state);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +0200754
755 return pll;
756}
757
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200758
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +0200759static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
760 .enable = hsw_ddi_wrpll_enable,
761 .disable = hsw_ddi_wrpll_disable,
762 .get_hw_state = hsw_ddi_wrpll_get_hw_state,
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200763};
764
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +0200765static const struct intel_shared_dpll_funcs hsw_ddi_spll_funcs = {
766 .enable = hsw_ddi_spll_enable,
767 .disable = hsw_ddi_spll_disable,
768 .get_hw_state = hsw_ddi_spll_get_hw_state,
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200769};
770
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +0200771static void hsw_ddi_lcpll_enable(struct drm_i915_private *dev_priv,
772 struct intel_shared_dpll *pll)
773{
774}
775
776static void hsw_ddi_lcpll_disable(struct drm_i915_private *dev_priv,
777 struct intel_shared_dpll *pll)
778{
779}
780
781static bool hsw_ddi_lcpll_get_hw_state(struct drm_i915_private *dev_priv,
782 struct intel_shared_dpll *pll,
783 struct intel_dpll_hw_state *hw_state)
784{
785 return true;
786}
787
788static const struct intel_shared_dpll_funcs hsw_ddi_lcpll_funcs = {
789 .enable = hsw_ddi_lcpll_enable,
790 .disable = hsw_ddi_lcpll_disable,
791 .get_hw_state = hsw_ddi_lcpll_get_hw_state,
792};
793
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200794struct skl_dpll_regs {
795 i915_reg_t ctl, cfgcr1, cfgcr2;
796};
797
798/* this array is indexed by the *shared* pll id */
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200799static const struct skl_dpll_regs skl_dpll_regs[4] = {
800 {
801 /* DPLL 0 */
802 .ctl = LCPLL1_CTL,
803 /* DPLL 0 doesn't support HDMI mode */
804 },
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200805 {
806 /* DPLL 1 */
807 .ctl = LCPLL2_CTL,
808 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
809 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
810 },
811 {
812 /* DPLL 2 */
813 .ctl = WRPLL_CTL(0),
814 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
815 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
816 },
817 {
818 /* DPLL 3 */
819 .ctl = WRPLL_CTL(1),
820 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
821 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
822 },
823};
824
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200825static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *dev_priv,
826 struct intel_shared_dpll *pll)
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200827{
828 uint32_t val;
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200829
830 val = I915_READ(DPLL_CTRL1);
831
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200832 val &= ~(DPLL_CTRL1_HDMI_MODE(pll->id) | DPLL_CTRL1_SSC(pll->id) |
833 DPLL_CTRL1_LINK_RATE_MASK(pll->id));
834 val |= pll->config.hw_state.ctrl1 << (pll->id * 6);
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200835
836 I915_WRITE(DPLL_CTRL1, val);
837 POSTING_READ(DPLL_CTRL1);
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200838}
839
840static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
841 struct intel_shared_dpll *pll)
842{
843 const struct skl_dpll_regs *regs = skl_dpll_regs;
844
845 skl_ddi_pll_write_ctrl1(dev_priv, pll);
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200846
847 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
848 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
849 POSTING_READ(regs[pll->id].cfgcr1);
850 POSTING_READ(regs[pll->id].cfgcr2);
851
852 /* the enable bit is always bit 31 */
853 I915_WRITE(regs[pll->id].ctl,
854 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
855
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200856 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(pll->id), 5))
857 DRM_ERROR("DPLL %d not locked\n", pll->id);
858}
859
860static void skl_ddi_dpll0_enable(struct drm_i915_private *dev_priv,
861 struct intel_shared_dpll *pll)
862{
863 skl_ddi_pll_write_ctrl1(dev_priv, pll);
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200864}
865
866static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
867 struct intel_shared_dpll *pll)
868{
869 const struct skl_dpll_regs *regs = skl_dpll_regs;
870
871 /* the enable bit is always bit 31 */
872 I915_WRITE(regs[pll->id].ctl,
873 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
874 POSTING_READ(regs[pll->id].ctl);
875}
876
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200877static void skl_ddi_dpll0_disable(struct drm_i915_private *dev_priv,
878 struct intel_shared_dpll *pll)
879{
880}
881
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200882static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
883 struct intel_shared_dpll *pll,
884 struct intel_dpll_hw_state *hw_state)
885{
886 uint32_t val;
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200887 const struct skl_dpll_regs *regs = skl_dpll_regs;
888 bool ret;
889
890 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
891 return false;
892
893 ret = false;
894
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200895 val = I915_READ(regs[pll->id].ctl);
896 if (!(val & LCPLL_PLL_ENABLE))
897 goto out;
898
899 val = I915_READ(DPLL_CTRL1);
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200900 hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200901
902 /* avoid reading back stale values if HDMI mode is not enabled */
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200903 if (val & DPLL_CTRL1_HDMI_MODE(pll->id)) {
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +0200904 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
905 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
906 }
907 ret = true;
908
909out:
910 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
911
912 return ret;
913}
914
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +0200915static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv,
916 struct intel_shared_dpll *pll,
917 struct intel_dpll_hw_state *hw_state)
918{
919 uint32_t val;
920 const struct skl_dpll_regs *regs = skl_dpll_regs;
921 bool ret;
922
923 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
924 return false;
925
926 ret = false;
927
928 /* DPLL0 is always enabled since it drives CDCLK */
929 val = I915_READ(regs[pll->id].ctl);
930 if (WARN_ON(!(val & LCPLL_PLL_ENABLE)))
931 goto out;
932
933 val = I915_READ(DPLL_CTRL1);
934 hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
935
936 ret = true;
937
938out:
939 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
940
941 return ret;
942}
943
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +0200944struct skl_wrpll_context {
945 uint64_t min_deviation; /* current minimal deviation */
946 uint64_t central_freq; /* chosen central freq */
947 uint64_t dco_freq; /* chosen dco freq */
948 unsigned int p; /* chosen divider */
949};
950
951static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
952{
953 memset(ctx, 0, sizeof(*ctx));
954
955 ctx->min_deviation = U64_MAX;
956}
957
958/* DCO freq must be within +1%/-6% of the DCO central freq */
959#define SKL_DCO_MAX_PDEVIATION 100
960#define SKL_DCO_MAX_NDEVIATION 600
961
962static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
963 uint64_t central_freq,
964 uint64_t dco_freq,
965 unsigned int divider)
966{
967 uint64_t deviation;
968
969 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
970 central_freq);
971
972 /* positive deviation */
973 if (dco_freq >= central_freq) {
974 if (deviation < SKL_DCO_MAX_PDEVIATION &&
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 /* negative deviation */
982 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
983 deviation < ctx->min_deviation) {
984 ctx->min_deviation = deviation;
985 ctx->central_freq = central_freq;
986 ctx->dco_freq = dco_freq;
987 ctx->p = divider;
988 }
989}
990
991static void skl_wrpll_get_multipliers(unsigned int p,
992 unsigned int *p0 /* out */,
993 unsigned int *p1 /* out */,
994 unsigned int *p2 /* out */)
995{
996 /* even dividers */
997 if (p % 2 == 0) {
998 unsigned int half = p / 2;
999
1000 if (half == 1 || half == 2 || half == 3 || half == 5) {
1001 *p0 = 2;
1002 *p1 = 1;
1003 *p2 = half;
1004 } else if (half % 2 == 0) {
1005 *p0 = 2;
1006 *p1 = half / 2;
1007 *p2 = 2;
1008 } else if (half % 3 == 0) {
1009 *p0 = 3;
1010 *p1 = half / 3;
1011 *p2 = 2;
1012 } else if (half % 7 == 0) {
1013 *p0 = 7;
1014 *p1 = half / 7;
1015 *p2 = 2;
1016 }
1017 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1018 *p0 = 3;
1019 *p1 = 1;
1020 *p2 = p / 3;
1021 } else if (p == 5 || p == 7) {
1022 *p0 = p;
1023 *p1 = 1;
1024 *p2 = 1;
1025 } else if (p == 15) {
1026 *p0 = 3;
1027 *p1 = 1;
1028 *p2 = 5;
1029 } else if (p == 21) {
1030 *p0 = 7;
1031 *p1 = 1;
1032 *p2 = 3;
1033 } else if (p == 35) {
1034 *p0 = 7;
1035 *p1 = 1;
1036 *p2 = 5;
1037 }
1038}
1039
1040struct skl_wrpll_params {
1041 uint32_t dco_fraction;
1042 uint32_t dco_integer;
1043 uint32_t qdiv_ratio;
1044 uint32_t qdiv_mode;
1045 uint32_t kdiv;
1046 uint32_t pdiv;
1047 uint32_t central_freq;
1048};
1049
1050static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1051 uint64_t afe_clock,
1052 uint64_t central_freq,
1053 uint32_t p0, uint32_t p1, uint32_t p2)
1054{
1055 uint64_t dco_freq;
1056
1057 switch (central_freq) {
1058 case 9600000000ULL:
1059 params->central_freq = 0;
1060 break;
1061 case 9000000000ULL:
1062 params->central_freq = 1;
1063 break;
1064 case 8400000000ULL:
1065 params->central_freq = 3;
1066 }
1067
1068 switch (p0) {
1069 case 1:
1070 params->pdiv = 0;
1071 break;
1072 case 2:
1073 params->pdiv = 1;
1074 break;
1075 case 3:
1076 params->pdiv = 2;
1077 break;
1078 case 7:
1079 params->pdiv = 4;
1080 break;
1081 default:
1082 WARN(1, "Incorrect PDiv\n");
1083 }
1084
1085 switch (p2) {
1086 case 5:
1087 params->kdiv = 0;
1088 break;
1089 case 2:
1090 params->kdiv = 1;
1091 break;
1092 case 3:
1093 params->kdiv = 2;
1094 break;
1095 case 1:
1096 params->kdiv = 3;
1097 break;
1098 default:
1099 WARN(1, "Incorrect KDiv\n");
1100 }
1101
1102 params->qdiv_ratio = p1;
1103 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1104
1105 dco_freq = p0 * p1 * p2 * afe_clock;
1106
1107 /*
1108 * Intermediate values are in Hz.
1109 * Divide by MHz to match bsepc
1110 */
1111 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
1112 params->dco_fraction =
1113 div_u64((div_u64(dco_freq, 24) -
1114 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
1115}
1116
1117static bool
1118skl_ddi_calculate_wrpll(int clock /* in Hz */,
1119 struct skl_wrpll_params *wrpll_params)
1120{
1121 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
1122 uint64_t dco_central_freq[3] = {8400000000ULL,
1123 9000000000ULL,
1124 9600000000ULL};
1125 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1126 24, 28, 30, 32, 36, 40, 42, 44,
1127 48, 52, 54, 56, 60, 64, 66, 68,
1128 70, 72, 76, 78, 80, 84, 88, 90,
1129 92, 96, 98 };
1130 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1131 static const struct {
1132 const int *list;
1133 int n_dividers;
1134 } dividers[] = {
1135 { even_dividers, ARRAY_SIZE(even_dividers) },
1136 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1137 };
1138 struct skl_wrpll_context ctx;
1139 unsigned int dco, d, i;
1140 unsigned int p0, p1, p2;
1141
1142 skl_wrpll_context_init(&ctx);
1143
1144 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1145 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1146 for (i = 0; i < dividers[d].n_dividers; i++) {
1147 unsigned int p = dividers[d].list[i];
1148 uint64_t dco_freq = p * afe_clock;
1149
1150 skl_wrpll_try_divider(&ctx,
1151 dco_central_freq[dco],
1152 dco_freq,
1153 p);
1154 /*
1155 * Skip the remaining dividers if we're sure to
1156 * have found the definitive divider, we can't
1157 * improve a 0 deviation.
1158 */
1159 if (ctx.min_deviation == 0)
1160 goto skip_remaining_dividers;
1161 }
1162 }
1163
1164skip_remaining_dividers:
1165 /*
1166 * If a solution is found with an even divider, prefer
1167 * this one.
1168 */
1169 if (d == 0 && ctx.p)
1170 break;
1171 }
1172
1173 if (!ctx.p) {
1174 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
1175 return false;
1176 }
1177
1178 /*
1179 * gcc incorrectly analyses that these can be used without being
1180 * initialized. To be fair, it's hard to guess.
1181 */
1182 p0 = p1 = p2 = 0;
1183 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1184 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1185 p0, p1, p2);
1186
1187 return true;
1188}
1189
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001190static struct intel_shared_dpll *
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +02001191skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
1192 struct intel_encoder *encoder)
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001193{
1194 struct intel_shared_dpll *pll;
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +02001195 uint32_t ctrl1, cfgcr1, cfgcr2;
1196 int clock = crtc_state->port_clock;
1197
1198 /*
1199 * See comment in intel_dpll_hw_state to understand why we always use 0
1200 * as the DPLL id in this function.
1201 */
1202
1203 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1204
1205 if (encoder->type == INTEL_OUTPUT_HDMI) {
1206 struct skl_wrpll_params wrpll_params = { 0, };
1207
1208 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1209
1210 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
Jani Nikula52e2abb2016-03-16 18:06:58 +02001211 return NULL;
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +02001212
1213 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1214 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1215 wrpll_params.dco_integer;
1216
1217 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1218 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1219 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1220 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1221 wrpll_params.central_freq;
1222 } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001223 encoder->type == INTEL_OUTPUT_DP_MST ||
1224 encoder->type == INTEL_OUTPUT_EDP) {
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +02001225 switch (crtc_state->port_clock / 2) {
1226 case 81000:
1227 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
1228 break;
1229 case 135000:
1230 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
1231 break;
1232 case 270000:
1233 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
1234 break;
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001235 /* eDP 1.4 rates */
1236 case 162000:
1237 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
1238 break;
1239 /* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is 8640 which
1240 results in CDCLK change. Need to handle the change of CDCLK by
1241 disabling pipes and re-enabling them */
1242 case 108000:
1243 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, 0);
1244 break;
1245 case 216000:
1246 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, 0);
1247 break;
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +02001248 }
1249
1250 cfgcr1 = cfgcr2 = 0;
1251 } else {
1252 return NULL;
1253 }
1254
1255 memset(&crtc_state->dpll_hw_state, 0,
1256 sizeof(crtc_state->dpll_hw_state));
1257
1258 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1259 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1260 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001261
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001262 if (encoder->type == INTEL_OUTPUT_EDP)
1263 pll = intel_find_shared_dpll(crtc, crtc_state,
1264 DPLL_ID_SKL_DPLL0,
1265 DPLL_ID_SKL_DPLL0);
1266 else
1267 pll = intel_find_shared_dpll(crtc, crtc_state,
1268 DPLL_ID_SKL_DPLL1,
1269 DPLL_ID_SKL_DPLL3);
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +02001270 if (!pll)
1271 return NULL;
1272
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001273 crtc_state->ddi_pll_sel = pll->id;
Ander Conselvan de Oliveira304b65c2016-03-08 17:46:24 +02001274
1275 intel_reference_shared_dpll(pll, crtc_state);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001276
1277 return pll;
1278}
1279
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001280static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
1281 .enable = skl_ddi_pll_enable,
1282 .disable = skl_ddi_pll_disable,
1283 .get_hw_state = skl_ddi_pll_get_hw_state,
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +02001284};
1285
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001286static const struct intel_shared_dpll_funcs skl_ddi_dpll0_funcs = {
1287 .enable = skl_ddi_dpll0_enable,
1288 .disable = skl_ddi_dpll0_disable,
1289 .get_hw_state = skl_ddi_dpll0_get_hw_state,
1290};
1291
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +02001292static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
1293 struct intel_shared_dpll *pll)
1294{
1295 uint32_t temp;
1296 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
1297
1298 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
Dongwon Kim25a56702016-03-16 18:06:13 -07001299 /*
1300 * Definition of each bit polarity has been changed
1301 * after A1 stepping
1302 */
1303 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
1304 temp &= ~PORT_PLL_REF_SEL;
1305 else
1306 temp |= PORT_PLL_REF_SEL;
1307
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +02001308 /* Non-SSC reference */
1309 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
1310
1311 /* Disable 10 bit clock */
1312 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
1313 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
1314 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
1315
1316 /* Write P1 & P2 */
1317 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
1318 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
1319 temp |= pll->config.hw_state.ebb0;
1320 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
1321
1322 /* Write M2 integer */
1323 temp = I915_READ(BXT_PORT_PLL(port, 0));
1324 temp &= ~PORT_PLL_M2_MASK;
1325 temp |= pll->config.hw_state.pll0;
1326 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
1327
1328 /* Write N */
1329 temp = I915_READ(BXT_PORT_PLL(port, 1));
1330 temp &= ~PORT_PLL_N_MASK;
1331 temp |= pll->config.hw_state.pll1;
1332 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
1333
1334 /* Write M2 fraction */
1335 temp = I915_READ(BXT_PORT_PLL(port, 2));
1336 temp &= ~PORT_PLL_M2_FRAC_MASK;
1337 temp |= pll->config.hw_state.pll2;
1338 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
1339
1340 /* Write M2 fraction enable */
1341 temp = I915_READ(BXT_PORT_PLL(port, 3));
1342 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
1343 temp |= pll->config.hw_state.pll3;
1344 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
1345
1346 /* Write coeff */
1347 temp = I915_READ(BXT_PORT_PLL(port, 6));
1348 temp &= ~PORT_PLL_PROP_COEFF_MASK;
1349 temp &= ~PORT_PLL_INT_COEFF_MASK;
1350 temp &= ~PORT_PLL_GAIN_CTL_MASK;
1351 temp |= pll->config.hw_state.pll6;
1352 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
1353
1354 /* Write calibration val */
1355 temp = I915_READ(BXT_PORT_PLL(port, 8));
1356 temp &= ~PORT_PLL_TARGET_CNT_MASK;
1357 temp |= pll->config.hw_state.pll8;
1358 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
1359
1360 temp = I915_READ(BXT_PORT_PLL(port, 9));
1361 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
1362 temp |= pll->config.hw_state.pll9;
1363 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
1364
1365 temp = I915_READ(BXT_PORT_PLL(port, 10));
1366 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
1367 temp &= ~PORT_PLL_DCO_AMP_MASK;
1368 temp |= pll->config.hw_state.pll10;
1369 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
1370
1371 /* Recalibrate with new settings */
1372 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
1373 temp |= PORT_PLL_RECALIBRATE;
1374 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
1375 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
1376 temp |= pll->config.hw_state.ebb4;
1377 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
1378
1379 /* Enable PLL */
1380 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
1381 temp |= PORT_PLL_ENABLE;
1382 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
1383 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
1384
1385 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
1386 PORT_PLL_LOCK), 200))
1387 DRM_ERROR("PLL %d not locked\n", port);
1388
1389 /*
1390 * While we write to the group register to program all lanes at once we
1391 * can read only lane registers and we pick lanes 0/1 for that.
1392 */
1393 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
1394 temp &= ~LANE_STAGGER_MASK;
1395 temp &= ~LANESTAGGER_STRAP_OVRD;
1396 temp |= pll->config.hw_state.pcsdw12;
1397 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
1398}
1399
1400static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
1401 struct intel_shared_dpll *pll)
1402{
1403 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
1404 uint32_t temp;
1405
1406 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
1407 temp &= ~PORT_PLL_ENABLE;
1408 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
1409 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
1410}
1411
1412static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
1413 struct intel_shared_dpll *pll,
1414 struct intel_dpll_hw_state *hw_state)
1415{
1416 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
1417 uint32_t val;
1418 bool ret;
1419
1420 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
1421 return false;
1422
1423 ret = false;
1424
1425 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
1426 if (!(val & PORT_PLL_ENABLE))
1427 goto out;
1428
1429 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
1430 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
1431
1432 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
1433 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
1434
1435 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
1436 hw_state->pll0 &= PORT_PLL_M2_MASK;
1437
1438 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
1439 hw_state->pll1 &= PORT_PLL_N_MASK;
1440
1441 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
1442 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
1443
1444 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
1445 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
1446
1447 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
1448 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
1449 PORT_PLL_INT_COEFF_MASK |
1450 PORT_PLL_GAIN_CTL_MASK;
1451
1452 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
1453 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
1454
1455 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
1456 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
1457
1458 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
1459 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
1460 PORT_PLL_DCO_AMP_MASK;
1461
1462 /*
1463 * While we write to the group register to program all lanes at once we
1464 * can read only lane registers. We configure all lanes the same way, so
1465 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
1466 */
1467 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
1468 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
1469 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
1470 hw_state->pcsdw12,
1471 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
1472 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
1473
1474 ret = true;
1475
1476out:
1477 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
1478
1479 return ret;
1480}
1481
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001482/* bxt clock parameters */
1483struct bxt_clk_div {
1484 int clock;
1485 uint32_t p1;
1486 uint32_t p2;
1487 uint32_t m2_int;
1488 uint32_t m2_frac;
1489 bool m2_frac_en;
1490 uint32_t n;
1491};
1492
1493/* pre-calculated values for DP linkrates */
1494static const struct bxt_clk_div bxt_dp_clk_val[] = {
1495 {162000, 4, 2, 32, 1677722, 1, 1},
1496 {270000, 4, 1, 27, 0, 0, 1},
1497 {540000, 2, 1, 27, 0, 0, 1},
1498 {216000, 3, 2, 32, 1677722, 1, 1},
1499 {243000, 4, 1, 24, 1258291, 1, 1},
1500 {324000, 4, 1, 32, 1677722, 1, 1},
1501 {432000, 3, 1, 32, 1677722, 1, 1}
1502};
1503
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001504static struct intel_shared_dpll *
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +02001505bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
1506 struct intel_encoder *encoder)
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001507{
1508 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001509 struct intel_shared_dpll *pll;
1510 enum intel_dpll_id i;
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001511 struct intel_digital_port *intel_dig_port;
1512 struct bxt_clk_div clk_div = {0};
1513 int vco = 0;
1514 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
1515 uint32_t lanestagger;
1516 int clock = crtc_state->port_clock;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001517
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001518 if (encoder->type == INTEL_OUTPUT_HDMI) {
1519 intel_clock_t best_clock;
1520
1521 /* Calculate HDMI div */
1522 /*
1523 * FIXME: tie the following calculation into
1524 * i9xx_crtc_compute_clock
1525 */
1526 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1527 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1528 clock, pipe_name(crtc->pipe));
1529 return NULL;
1530 }
1531
1532 clk_div.p1 = best_clock.p1;
1533 clk_div.p2 = best_clock.p2;
1534 WARN_ON(best_clock.m1 != 2);
1535 clk_div.n = best_clock.n;
1536 clk_div.m2_int = best_clock.m2 >> 22;
1537 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1538 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1539
1540 vco = best_clock.vco;
1541 } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1542 encoder->type == INTEL_OUTPUT_EDP) {
1543 int i;
1544
1545 clk_div = bxt_dp_clk_val[0];
1546 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1547 if (bxt_dp_clk_val[i].clock == clock) {
1548 clk_div = bxt_dp_clk_val[i];
1549 break;
1550 }
1551 }
1552 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1553 }
1554
1555 if (vco >= 6200000 && vco <= 6700000) {
1556 prop_coef = 4;
1557 int_coef = 9;
1558 gain_ctl = 3;
1559 targ_cnt = 8;
1560 } else if ((vco > 5400000 && vco < 6200000) ||
1561 (vco >= 4800000 && vco < 5400000)) {
1562 prop_coef = 5;
1563 int_coef = 11;
1564 gain_ctl = 3;
1565 targ_cnt = 9;
1566 } else if (vco == 5400000) {
1567 prop_coef = 3;
1568 int_coef = 8;
1569 gain_ctl = 1;
1570 targ_cnt = 9;
1571 } else {
1572 DRM_ERROR("Invalid VCO\n");
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001573 return NULL;
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001574 }
1575
1576 memset(&crtc_state->dpll_hw_state, 0,
1577 sizeof(crtc_state->dpll_hw_state));
1578
1579 if (clock > 270000)
1580 lanestagger = 0x18;
1581 else if (clock > 135000)
1582 lanestagger = 0x0d;
1583 else if (clock > 67000)
1584 lanestagger = 0x07;
1585 else if (clock > 33000)
1586 lanestagger = 0x04;
1587 else
1588 lanestagger = 0x02;
1589
1590 crtc_state->dpll_hw_state.ebb0 =
1591 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1592 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1593 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1594 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1595
1596 if (clk_div.m2_frac_en)
1597 crtc_state->dpll_hw_state.pll3 =
1598 PORT_PLL_M2_FRAC_ENABLE;
1599
1600 crtc_state->dpll_hw_state.pll6 =
1601 prop_coef | PORT_PLL_INT_COEFF(int_coef);
1602 crtc_state->dpll_hw_state.pll6 |=
1603 PORT_PLL_GAIN_CTL(gain_ctl);
1604
1605 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1606
1607 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1608
1609 crtc_state->dpll_hw_state.pll10 =
1610 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1611 | PORT_PLL_DCO_AMP_OVR_EN_H;
1612
1613 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1614
1615 crtc_state->dpll_hw_state.pcsdw12 =
1616 LANESTAGGER_STRAP_OVRD | lanestagger;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001617
1618 intel_dig_port = enc_to_dig_port(&encoder->base);
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001619
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001620 /* 1:1 mapping between ports and PLLs */
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001621 i = (enum intel_dpll_id) intel_dig_port->port;
1622 pll = intel_get_shared_dpll_by_id(dev_priv, i);
1623
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001624 DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
1625 crtc->base.base.id, pll->name);
1626
1627 intel_reference_shared_dpll(pll, crtc_state);
1628
Ander Conselvan de Oliveira34177c22016-03-08 17:46:25 +02001629 /* shared DPLL id 0 is DPLL A */
1630 crtc_state->ddi_pll_sel = pll->id;
1631
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001632 return pll;
1633}
1634
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001635static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
1636 .enable = bxt_ddi_pll_enable,
1637 .disable = bxt_ddi_pll_disable,
1638 .get_hw_state = bxt_ddi_pll_get_hw_state,
1639};
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +02001640
1641static void intel_ddi_pll_init(struct drm_device *dev)
1642{
1643 struct drm_i915_private *dev_priv = dev->dev_private;
1644 uint32_t val = I915_READ(LCPLL_CTL);
1645
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +02001646 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
1647 int cdclk_freq;
1648
1649 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
1650 dev_priv->skl_boot_cdclk = cdclk_freq;
1651 if (skl_sanitize_cdclk(dev_priv))
1652 DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
1653 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
1654 DRM_ERROR("LCPLL1 is disabled\n");
Imre Deakd7d7c9e2016-04-01 16:02:42 +03001655 } else if (!IS_BROXTON(dev_priv)) {
Ander Conselvan de Oliveira55be2f02016-03-08 17:46:16 +02001656 /*
1657 * The LCPLL register should be turned on by the BIOS. For now
1658 * let's just check its state and print errors in case
1659 * something is wrong. Don't even try to turn it on.
1660 */
1661
1662 if (val & LCPLL_CD_SOURCE_FCLK)
1663 DRM_ERROR("CDCLK source is not LCPLL\n");
1664
1665 if (val & LCPLL_PLL_DISABLE)
1666 DRM_ERROR("LCPLL is disabled\n");
1667 }
1668}
1669
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001670struct dpll_info {
1671 const char *name;
1672 const int id;
1673 const struct intel_shared_dpll_funcs *funcs;
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +02001674 uint32_t flags;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001675};
1676
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001677struct intel_dpll_mgr {
1678 const struct dpll_info *dpll_info;
1679
1680 struct intel_shared_dpll *(*get_dpll)(struct intel_crtc *crtc,
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +02001681 struct intel_crtc_state *crtc_state,
1682 struct intel_encoder *encoder);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001683};
1684
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001685static const struct dpll_info pch_plls[] = {
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +02001686 { "PCH DPLL A", DPLL_ID_PCH_PLL_A, &ibx_pch_dpll_funcs, 0 },
1687 { "PCH DPLL B", DPLL_ID_PCH_PLL_B, &ibx_pch_dpll_funcs, 0 },
1688 { NULL, -1, NULL, 0 },
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001689};
1690
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001691static const struct intel_dpll_mgr pch_pll_mgr = {
1692 .dpll_info = pch_plls,
1693 .get_dpll = ibx_get_dpll,
1694};
1695
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001696static const struct dpll_info hsw_plls[] = {
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +02001697 { "WRPLL 1", DPLL_ID_WRPLL1, &hsw_ddi_wrpll_funcs, 0 },
1698 { "WRPLL 2", DPLL_ID_WRPLL2, &hsw_ddi_wrpll_funcs, 0 },
1699 { "SPLL", DPLL_ID_SPLL, &hsw_ddi_spll_funcs, 0 },
1700 { "LCPLL 810", DPLL_ID_LCPLL_810, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON },
1701 { "LCPLL 1350", DPLL_ID_LCPLL_1350, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON },
1702 { "LCPLL 2700", DPLL_ID_LCPLL_2700, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON },
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 hsw_pll_mgr = {
1707 .dpll_info = hsw_plls,
1708 .get_dpll = hsw_get_dpll,
1709};
1710
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001711static const struct dpll_info skl_plls[] = {
Ander Conselvan de Oliveiraa3c988e2016-03-08 17:46:27 +02001712 { "DPLL 0", DPLL_ID_SKL_DPLL0, &skl_ddi_dpll0_funcs, INTEL_DPLL_ALWAYS_ON },
1713 { "DPPL 1", DPLL_ID_SKL_DPLL1, &skl_ddi_pll_funcs, 0 },
1714 { "DPPL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs, 0 },
1715 { "DPPL 3", DPLL_ID_SKL_DPLL3, &skl_ddi_pll_funcs, 0 },
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001716 { NULL, -1, NULL, },
1717};
1718
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001719static const struct intel_dpll_mgr skl_pll_mgr = {
1720 .dpll_info = skl_plls,
1721 .get_dpll = skl_get_dpll,
1722};
1723
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001724static const struct dpll_info bxt_plls[] = {
Imre Deak08250c42016-03-14 19:55:34 +02001725 { "PORT PLL A", DPLL_ID_SKL_DPLL0, &bxt_ddi_pll_funcs, 0 },
1726 { "PORT PLL B", DPLL_ID_SKL_DPLL1, &bxt_ddi_pll_funcs, 0 },
1727 { "PORT PLL C", DPLL_ID_SKL_DPLL2, &bxt_ddi_pll_funcs, 0 },
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001728 { NULL, -1, NULL, },
1729};
1730
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001731static const struct intel_dpll_mgr bxt_pll_mgr = {
1732 .dpll_info = bxt_plls,
1733 .get_dpll = bxt_get_dpll,
1734};
1735
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001736void intel_shared_dpll_init(struct drm_device *dev)
1737{
1738 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001739 const struct intel_dpll_mgr *dpll_mgr = NULL;
1740 const struct dpll_info *dpll_info;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001741 int i;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001742
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001743 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001744 dpll_mgr = &skl_pll_mgr;
Imre Deak08250c42016-03-14 19:55:34 +02001745 else if (IS_BROXTON(dev))
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001746 dpll_mgr = &bxt_pll_mgr;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001747 else if (HAS_DDI(dev))
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001748 dpll_mgr = &hsw_pll_mgr;
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001749 else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001750 dpll_mgr = &pch_pll_mgr;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001751
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001752 if (!dpll_mgr) {
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001753 dev_priv->num_shared_dpll = 0;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001754 return;
1755 }
1756
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001757 dpll_info = dpll_mgr->dpll_info;
1758
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001759 for (i = 0; dpll_info[i].id >= 0; i++) {
1760 WARN_ON(i != dpll_info[i].id);
1761
1762 dev_priv->shared_dplls[i].id = dpll_info[i].id;
1763 dev_priv->shared_dplls[i].name = dpll_info[i].name;
1764 dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs;
Ander Conselvan de Oliveira9d16da62016-03-08 17:46:26 +02001765 dev_priv->shared_dplls[i].flags = dpll_info[i].flags;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001766 }
1767
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001768 dev_priv->dpll_mgr = dpll_mgr;
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001769 dev_priv->num_shared_dpll = i;
Maarten Lankhorstfbf6d872016-03-23 14:51:12 +01001770 mutex_init(&dev_priv->dpll_lock);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001771
1772 BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
Ander Conselvan de Oliveira2edd6442016-03-08 17:46:21 +02001773
1774 /* FIXME: Move this to a more suitable place */
1775 if (HAS_DDI(dev))
1776 intel_ddi_pll_init(dev);
Ander Conselvan de Oliveira7abd4b32016-03-08 17:46:15 +02001777}
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001778
1779struct intel_shared_dpll *
1780intel_get_shared_dpll(struct intel_crtc *crtc,
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +02001781 struct intel_crtc_state *crtc_state,
1782 struct intel_encoder *encoder)
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001783{
1784 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1785 const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll_mgr;
1786
1787 if (WARN_ON(!dpll_mgr))
1788 return NULL;
1789
Ander Conselvan de Oliveiradaedf202016-03-08 17:46:23 +02001790 return dpll_mgr->get_dpll(crtc, crtc_state, encoder);
Ander Conselvan de Oliveiraf9476a62016-03-08 17:46:22 +02001791}