1/*
2 * Copyright © 2006-2016 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#include <linux/math.h>
25#include <linux/string_helpers.h>
26
27#include <drm/drm_print.h>
28
29#include "bxt_dpio_phy_regs.h"
30#include "intel_cx0_phy.h"
31#include "intel_de.h"
32#include "intel_display_regs.h"
33#include "intel_display_types.h"
34#include "intel_display_utils.h"
35#include "intel_dkl_phy.h"
36#include "intel_dkl_phy_regs.h"
37#include "intel_dpio_phy.h"
38#include "intel_dpll.h"
39#include "intel_dpll_mgr.h"
40#include "intel_hti.h"
41#include "intel_mg_phy_regs.h"
42#include "intel_pch_refclk.h"
43#include "intel_step.h"
44#include "intel_tc.h"
45
46/**
47 * DOC: Display PLLs
48 *
49 * Display PLLs used for driving outputs vary by platform. While some have
50 * per-pipe or per-encoder dedicated PLLs, others allow the use of any PLL
51 * from a pool. In the latter scenario, it is possible that multiple pipes
52 * share a PLL if their configurations match.
53 *
54 * This file provides an abstraction over display PLLs. The function
55 * intel_dpll_init() initializes the PLLs for the given platform. The
56 * users of a PLL are tracked and that tracking is integrated with the atomic
57 * modset interface. During an atomic operation, required PLLs can be reserved
58 * for a given CRTC and encoder configuration by calling
59 * intel_dpll_reserve() and previously reserved PLLs can be released
60 * with intel_dpll_release().
61 * Changes to the users are first staged in the atomic state, and then made
62 * effective by calling intel_dpll_swap_state() during the atomic
63 * commit phase.
64 */
65
66/* platform specific hooks for managing DPLLs */
67struct intel_dpll_funcs {
68 /*
69 * Hook for enabling the pll, called from intel_enable_dpll() if
70 * the pll is not already enabled.
71 */
72 void (*enable)(struct intel_display *display,
73 struct intel_dpll *pll,
74 const struct intel_dpll_hw_state *dpll_hw_state);
75
76 /*
77 * Hook for disabling the pll, called from intel_disable_dpll()
78 * only when it is safe to disable the pll, i.e., there are no more
79 * tracked users for it.
80 */
81 void (*disable)(struct intel_display *display,
82 struct intel_dpll *pll);
83
84 /*
85 * Hook for reading the values currently programmed to the DPLL
86 * registers. This is used for initial hw state readout and state
87 * verification after a mode set.
88 */
89 bool (*get_hw_state)(struct intel_display *display,
90 struct intel_dpll *pll,
91 struct intel_dpll_hw_state *dpll_hw_state);
92
93 /*
94 * Hook for calculating the pll's output frequency based on its passed
95 * in state.
96 */
97 int (*get_freq)(struct intel_display *i915,
98 const struct intel_dpll *pll,
99 const struct intel_dpll_hw_state *dpll_hw_state);
100};
101
102struct intel_dpll_mgr {
103 const struct dpll_info *dpll_info;
104
105 int (*compute_dplls)(struct intel_atomic_state *state,
106 struct intel_crtc *crtc,
107 struct intel_encoder *encoder);
108 int (*get_dplls)(struct intel_atomic_state *state,
109 struct intel_crtc *crtc,
110 struct intel_encoder *encoder);
111 void (*put_dplls)(struct intel_atomic_state *state,
112 struct intel_crtc *crtc);
113 void (*update_active_dpll)(struct intel_atomic_state *state,
114 struct intel_crtc *crtc,
115 struct intel_encoder *encoder);
116 void (*update_ref_clks)(struct intel_display *display);
117 void (*dump_hw_state)(struct drm_printer *p,
118 const struct intel_dpll_hw_state *dpll_hw_state);
119 bool (*compare_hw_state)(const struct intel_dpll_hw_state *a,
120 const struct intel_dpll_hw_state *b);
121};
122
123static void
124intel_atomic_duplicate_dpll_state(struct intel_display *display,
125 struct intel_dpll_state *dpll_state)
126{
127 struct intel_dpll *pll;
128 int i;
129
130 /* Copy dpll state */
131 for_each_dpll(display, pll, i)
132 dpll_state[pll->index] = pll->state;
133}
134
135static struct intel_dpll_state *
136intel_atomic_get_dpll_state(struct drm_atomic_state *s)
137{
138 struct intel_atomic_state *state = to_intel_atomic_state(s);
139 struct intel_display *display = to_intel_display(state);
140
141 drm_WARN_ON(s->dev, !drm_modeset_is_locked(&s->dev->mode_config.connection_mutex));
142
143 if (!state->dpll_set) {
144 state->dpll_set = true;
145
146 intel_atomic_duplicate_dpll_state(display,
147 dpll_state: state->dpll_state);
148 }
149
150 return state->dpll_state;
151}
152
153/**
154 * intel_get_dpll_by_id - get a DPLL given its id
155 * @display: intel_display device instance
156 * @id: pll id
157 *
158 * Returns:
159 * A pointer to the DPLL with @id
160 */
161struct intel_dpll *
162intel_get_dpll_by_id(struct intel_display *display,
163 enum intel_dpll_id id)
164{
165 struct intel_dpll *pll;
166 int i;
167
168 for_each_dpll(display, pll, i) {
169 if (pll->info->id == id)
170 return pll;
171 }
172
173 MISSING_CASE(id);
174 return NULL;
175}
176
177/* For ILK+ */
178void assert_dpll(struct intel_display *display,
179 struct intel_dpll *pll,
180 bool state)
181{
182 bool cur_state;
183 struct intel_dpll_hw_state hw_state;
184
185 if (drm_WARN(display->drm, !pll,
186 "asserting DPLL %s with no DPLL\n", str_on_off(state)))
187 return;
188
189 cur_state = intel_dpll_get_hw_state(display, pll, dpll_hw_state: &hw_state);
190 INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
191 "%s assertion failure (expected %s, current %s)\n",
192 pll->info->name, str_on_off(state),
193 str_on_off(cur_state));
194}
195
196static enum tc_port icl_pll_id_to_tc_port(enum intel_dpll_id id)
197{
198 return TC_PORT_1 + id - DPLL_ID_ICL_MGPLL1;
199}
200
201enum intel_dpll_id icl_tc_port_to_pll_id(enum tc_port tc_port)
202{
203 return tc_port - TC_PORT_1 + DPLL_ID_ICL_MGPLL1;
204}
205
206static i915_reg_t
207intel_combo_pll_enable_reg(struct intel_display *display,
208 struct intel_dpll *pll)
209{
210 if (display->platform.dg1)
211 return DG1_DPLL_ENABLE(pll->info->id);
212 else if ((display->platform.jasperlake || display->platform.elkhartlake) &&
213 (pll->info->id == DPLL_ID_EHL_DPLL4))
214 return MG_PLL_ENABLE(0);
215
216 return ICL_DPLL_ENABLE(pll->info->id);
217}
218
219static i915_reg_t
220intel_tc_pll_enable_reg(struct intel_display *display,
221 struct intel_dpll *pll)
222{
223 const enum intel_dpll_id id = pll->info->id;
224 enum tc_port tc_port = icl_pll_id_to_tc_port(id);
225
226 if (display->platform.alderlake_p)
227 return ADLP_PORTTC_PLL_ENABLE(tc_port);
228
229 return MG_PLL_ENABLE(tc_port);
230}
231
232static void _intel_enable_shared_dpll(struct intel_display *display,
233 struct intel_dpll *pll)
234{
235 if (pll->info->power_domain)
236 pll->wakeref = intel_display_power_get(display, domain: pll->info->power_domain);
237
238 pll->info->funcs->enable(display, pll, &pll->state.hw_state);
239 pll->on = true;
240}
241
242static void _intel_disable_shared_dpll(struct intel_display *display,
243 struct intel_dpll *pll)
244{
245 pll->info->funcs->disable(display, pll);
246 pll->on = false;
247
248 if (pll->info->power_domain)
249 intel_display_power_put(display, domain: pll->info->power_domain, wakeref: pll->wakeref);
250}
251
252/**
253 * intel_dpll_enable - enable a CRTC's DPLL
254 * @crtc_state: CRTC, and its state, which has a DPLL
255 *
256 * Enable DPLL used by @crtc.
257 */
258void intel_dpll_enable(const struct intel_crtc_state *crtc_state)
259{
260 struct intel_display *display = to_intel_display(crtc_state);
261 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
262 struct intel_dpll *pll = crtc_state->intel_dpll;
263 unsigned int pipe_mask = intel_crtc_joined_pipe_mask(crtc_state);
264 unsigned int old_mask;
265
266 if (drm_WARN_ON(display->drm, !pll))
267 return;
268
269 mutex_lock(&display->dpll.lock);
270 old_mask = pll->active_mask;
271
272 if (drm_WARN_ON(display->drm, !(pll->state.pipe_mask & pipe_mask)) ||
273 drm_WARN_ON(display->drm, pll->active_mask & pipe_mask))
274 goto out;
275
276 pll->active_mask |= pipe_mask;
277
278 drm_dbg_kms(display->drm,
279 "enable %s (active 0x%x, on? %d) for [CRTC:%d:%s]\n",
280 pll->info->name, pll->active_mask, pll->on,
281 crtc->base.base.id, crtc->base.name);
282
283 if (old_mask) {
284 drm_WARN_ON(display->drm, !pll->on);
285 assert_dpll_enabled(display, pll);
286 goto out;
287 }
288 drm_WARN_ON(display->drm, pll->on);
289
290 drm_dbg_kms(display->drm, "enabling %s\n", pll->info->name);
291
292 _intel_enable_shared_dpll(display, pll);
293
294out:
295 mutex_unlock(lock: &display->dpll.lock);
296}
297
298/**
299 * intel_dpll_disable - disable a CRTC's shared DPLL
300 * @crtc_state: CRTC, and its state, which has a shared DPLL
301 *
302 * Disable DPLL used by @crtc.
303 */
304void intel_dpll_disable(const struct intel_crtc_state *crtc_state)
305{
306 struct intel_display *display = to_intel_display(crtc_state);
307 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
308 struct intel_dpll *pll = crtc_state->intel_dpll;
309 unsigned int pipe_mask = intel_crtc_joined_pipe_mask(crtc_state);
310
311 /* PCH only available on ILK+ */
312 if (DISPLAY_VER(display) < 5)
313 return;
314
315 if (pll == NULL)
316 return;
317
318 mutex_lock(&display->dpll.lock);
319 if (drm_WARN(display->drm, !(pll->active_mask & pipe_mask),
320 "%s not used by [CRTC:%d:%s]\n", pll->info->name,
321 crtc->base.base.id, crtc->base.name))
322 goto out;
323
324 drm_dbg_kms(display->drm,
325 "disable %s (active 0x%x, on? %d) for [CRTC:%d:%s]\n",
326 pll->info->name, pll->active_mask, pll->on,
327 crtc->base.base.id, crtc->base.name);
328
329 assert_dpll_enabled(display, pll);
330 drm_WARN_ON(display->drm, !pll->on);
331
332 pll->active_mask &= ~pipe_mask;
333 if (pll->active_mask)
334 goto out;
335
336 drm_dbg_kms(display->drm, "disabling %s\n", pll->info->name);
337
338 _intel_disable_shared_dpll(display, pll);
339
340out:
341 mutex_unlock(lock: &display->dpll.lock);
342}
343
344static unsigned long
345intel_dpll_mask_all(struct intel_display *display)
346{
347 struct intel_dpll *pll;
348 unsigned long dpll_mask = 0;
349 int i;
350
351 for_each_dpll(display, pll, i) {
352 drm_WARN_ON(display->drm, dpll_mask & BIT(pll->info->id));
353
354 dpll_mask |= BIT(pll->info->id);
355 }
356
357 return dpll_mask;
358}
359
360static struct intel_dpll *
361intel_find_dpll(struct intel_atomic_state *state,
362 const struct intel_crtc *crtc,
363 const struct intel_dpll_hw_state *dpll_hw_state,
364 unsigned long dpll_mask)
365{
366 struct intel_display *display = to_intel_display(crtc);
367 unsigned long dpll_mask_all = intel_dpll_mask_all(display);
368 struct intel_dpll_state *dpll_state;
369 struct intel_dpll *unused_pll = NULL;
370 enum intel_dpll_id id;
371
372 dpll_state = intel_atomic_get_dpll_state(s: &state->base);
373
374 drm_WARN_ON(display->drm, dpll_mask & ~dpll_mask_all);
375
376 for_each_set_bit(id, &dpll_mask, fls(dpll_mask_all)) {
377 struct intel_dpll *pll;
378
379 pll = intel_get_dpll_by_id(display, id);
380 if (!pll)
381 continue;
382
383 /* Only want to check enabled timings first */
384 if (dpll_state[pll->index].pipe_mask == 0) {
385 if (!unused_pll)
386 unused_pll = pll;
387 continue;
388 }
389
390 if (memcmp(p: dpll_hw_state,
391 q: &dpll_state[pll->index].hw_state,
392 size: sizeof(*dpll_hw_state)) == 0) {
393 drm_dbg_kms(display->drm,
394 "[CRTC:%d:%s] sharing existing %s (pipe mask 0x%x, active 0x%x)\n",
395 crtc->base.base.id, crtc->base.name,
396 pll->info->name,
397 dpll_state[pll->index].pipe_mask,
398 pll->active_mask);
399 return pll;
400 }
401 }
402
403 /* Ok no matching timings, maybe there's a free one? */
404 if (unused_pll) {
405 drm_dbg_kms(display->drm, "[CRTC:%d:%s] allocated %s\n",
406 crtc->base.base.id, crtc->base.name,
407 unused_pll->info->name);
408 return unused_pll;
409 }
410
411 return NULL;
412}
413
414/**
415 * intel_dpll_crtc_get - Get a DPLL reference for a CRTC
416 * @crtc: CRTC on which behalf the reference is taken
417 * @pll: DPLL for which the reference is taken
418 * @dpll_state: the DPLL atomic state in which the reference is tracked
419 *
420 * Take a reference for @pll tracking the use of it by @crtc.
421 */
422static void
423intel_dpll_crtc_get(const struct intel_crtc *crtc,
424 const struct intel_dpll *pll,
425 struct intel_dpll_state *dpll_state)
426{
427 struct intel_display *display = to_intel_display(crtc);
428
429 drm_WARN_ON(display->drm, (dpll_state->pipe_mask & BIT(crtc->pipe)) != 0);
430
431 dpll_state->pipe_mask |= BIT(crtc->pipe);
432
433 drm_dbg_kms(display->drm, "[CRTC:%d:%s] reserving %s\n",
434 crtc->base.base.id, crtc->base.name, pll->info->name);
435}
436
437static void
438intel_reference_dpll(struct intel_atomic_state *state,
439 const struct intel_crtc *crtc,
440 const struct intel_dpll *pll,
441 const struct intel_dpll_hw_state *dpll_hw_state)
442{
443 struct intel_dpll_state *dpll_state;
444
445 dpll_state = intel_atomic_get_dpll_state(s: &state->base);
446
447 if (dpll_state[pll->index].pipe_mask == 0)
448 dpll_state[pll->index].hw_state = *dpll_hw_state;
449
450 intel_dpll_crtc_get(crtc, pll, dpll_state: &dpll_state[pll->index]);
451}
452
453/**
454 * intel_dpll_crtc_put - Drop a DPLL reference for a CRTC
455 * @crtc: CRTC on which behalf the reference is dropped
456 * @pll: DPLL for which the reference is dropped
457 * @dpll_state: the DPLL atomic state in which the reference is tracked
458 *
459 * Drop a reference for @pll tracking the end of use of it by @crtc.
460 */
461void
462intel_dpll_crtc_put(const struct intel_crtc *crtc,
463 const struct intel_dpll *pll,
464 struct intel_dpll_state *dpll_state)
465{
466 struct intel_display *display = to_intel_display(crtc);
467
468 drm_WARN_ON(display->drm, (dpll_state->pipe_mask & BIT(crtc->pipe)) == 0);
469
470 dpll_state->pipe_mask &= ~BIT(crtc->pipe);
471
472 drm_dbg_kms(display->drm, "[CRTC:%d:%s] releasing %s\n",
473 crtc->base.base.id, crtc->base.name, pll->info->name);
474}
475
476static void intel_unreference_dpll(struct intel_atomic_state *state,
477 const struct intel_crtc *crtc,
478 const struct intel_dpll *pll)
479{
480 struct intel_dpll_state *dpll_state;
481
482 dpll_state = intel_atomic_get_dpll_state(s: &state->base);
483
484 intel_dpll_crtc_put(crtc, pll, dpll_state: &dpll_state[pll->index]);
485}
486
487static void intel_put_dpll(struct intel_atomic_state *state,
488 struct intel_crtc *crtc)
489{
490 const struct intel_crtc_state *old_crtc_state =
491 intel_atomic_get_old_crtc_state(state, crtc);
492 struct intel_crtc_state *new_crtc_state =
493 intel_atomic_get_new_crtc_state(state, crtc);
494
495 new_crtc_state->intel_dpll = NULL;
496
497 if (!old_crtc_state->intel_dpll)
498 return;
499
500 intel_unreference_dpll(state, crtc, pll: old_crtc_state->intel_dpll);
501}
502
503/**
504 * intel_dpll_swap_state - make atomic DPLL configuration effective
505 * @state: atomic state
506 *
507 * This is the dpll version of drm_atomic_helper_swap_state() since the
508 * helper does not handle driver-specific global state.
509 *
510 * For consistency with atomic helpers this function does a complete swap,
511 * i.e. it also puts the current state into @state, even though there is no
512 * need for that at this moment.
513 */
514void intel_dpll_swap_state(struct intel_atomic_state *state)
515{
516 struct intel_display *display = to_intel_display(state);
517 struct intel_dpll_state *dpll_state = state->dpll_state;
518 struct intel_dpll *pll;
519 int i;
520
521 if (!state->dpll_set)
522 return;
523
524 for_each_dpll(display, pll, i)
525 swap(pll->state, dpll_state[pll->index]);
526}
527
528static bool ibx_pch_dpll_get_hw_state(struct intel_display *display,
529 struct intel_dpll *pll,
530 struct intel_dpll_hw_state *dpll_hw_state)
531{
532 struct i9xx_dpll_hw_state *hw_state = &dpll_hw_state->i9xx;
533 const enum intel_dpll_id id = pll->info->id;
534 intel_wakeref_t wakeref;
535 u32 val;
536
537 wakeref = intel_display_power_get_if_enabled(display,
538 domain: POWER_DOMAIN_DISPLAY_CORE);
539 if (!wakeref)
540 return false;
541
542 val = intel_de_read(display, PCH_DPLL(id));
543 hw_state->dpll = val;
544 hw_state->fp0 = intel_de_read(display, PCH_FP0(id));
545 hw_state->fp1 = intel_de_read(display, PCH_FP1(id));
546
547 intel_display_power_put(display, domain: POWER_DOMAIN_DISPLAY_CORE, wakeref);
548
549 return val & DPLL_VCO_ENABLE;
550}
551
552static void ibx_assert_pch_refclk_enabled(struct intel_display *display)
553{
554 u32 val;
555 bool enabled;
556
557 val = intel_de_read(display, PCH_DREF_CONTROL);
558 enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK |
559 DREF_SUPERSPREAD_SOURCE_MASK));
560 INTEL_DISPLAY_STATE_WARN(display, !enabled,
561 "PCH refclk assertion failure, should be active but is disabled\n");
562}
563
564static void ibx_pch_dpll_enable(struct intel_display *display,
565 struct intel_dpll *pll,
566 const struct intel_dpll_hw_state *dpll_hw_state)
567{
568 const struct i9xx_dpll_hw_state *hw_state = &dpll_hw_state->i9xx;
569 const enum intel_dpll_id id = pll->info->id;
570
571 /* PCH refclock must be enabled first */
572 ibx_assert_pch_refclk_enabled(display);
573
574 intel_de_write(display, PCH_FP0(id), val: hw_state->fp0);
575 intel_de_write(display, PCH_FP1(id), val: hw_state->fp1);
576
577 intel_de_write(display, PCH_DPLL(id), val: hw_state->dpll);
578
579 /* Wait for the clocks to stabilize. */
580 intel_de_posting_read(display, PCH_DPLL(id));
581 udelay(usec: 150);
582
583 /* The pixel multiplier can only be updated once the
584 * DPLL is enabled and the clocks are stable.
585 *
586 * So write it again.
587 */
588 intel_de_write(display, PCH_DPLL(id), val: hw_state->dpll);
589 intel_de_posting_read(display, PCH_DPLL(id));
590 udelay(usec: 200);
591}
592
593static void ibx_pch_dpll_disable(struct intel_display *display,
594 struct intel_dpll *pll)
595{
596 const enum intel_dpll_id id = pll->info->id;
597
598 intel_de_write(display, PCH_DPLL(id), val: 0);
599 intel_de_posting_read(display, PCH_DPLL(id));
600 udelay(usec: 200);
601}
602
603static int ibx_compute_dpll(struct intel_atomic_state *state,
604 struct intel_crtc *crtc,
605 struct intel_encoder *encoder)
606{
607 return 0;
608}
609
610static int ibx_get_dpll(struct intel_atomic_state *state,
611 struct intel_crtc *crtc,
612 struct intel_encoder *encoder)
613{
614 struct intel_display *display = to_intel_display(state);
615 struct intel_crtc_state *crtc_state =
616 intel_atomic_get_new_crtc_state(state, crtc);
617 struct intel_dpll *pll;
618 enum intel_dpll_id id;
619
620 if (HAS_PCH_IBX(display)) {
621 /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
622 id = (enum intel_dpll_id) crtc->pipe;
623 pll = intel_get_dpll_by_id(display, id);
624
625 drm_dbg_kms(display->drm,
626 "[CRTC:%d:%s] using pre-allocated %s\n",
627 crtc->base.base.id, crtc->base.name,
628 pll->info->name);
629 } else {
630 pll = intel_find_dpll(state, crtc,
631 dpll_hw_state: &crtc_state->dpll_hw_state,
632 BIT(DPLL_ID_PCH_PLL_B) |
633 BIT(DPLL_ID_PCH_PLL_A));
634 }
635
636 if (!pll)
637 return -EINVAL;
638
639 /* reference the pll */
640 intel_reference_dpll(state, crtc,
641 pll, dpll_hw_state: &crtc_state->dpll_hw_state);
642
643 crtc_state->intel_dpll = pll;
644
645 return 0;
646}
647
648static void ibx_dump_hw_state(struct drm_printer *p,
649 const struct intel_dpll_hw_state *dpll_hw_state)
650{
651 const struct i9xx_dpll_hw_state *hw_state = &dpll_hw_state->i9xx;
652
653 drm_printf(p, f: "dpll_hw_state: dpll: 0x%x, dpll_md: 0x%x, "
654 "fp0: 0x%x, fp1: 0x%x\n",
655 hw_state->dpll,
656 hw_state->dpll_md,
657 hw_state->fp0,
658 hw_state->fp1);
659}
660
661static bool ibx_compare_hw_state(const struct intel_dpll_hw_state *_a,
662 const struct intel_dpll_hw_state *_b)
663{
664 const struct i9xx_dpll_hw_state *a = &_a->i9xx;
665 const struct i9xx_dpll_hw_state *b = &_b->i9xx;
666
667 return a->dpll == b->dpll &&
668 a->dpll_md == b->dpll_md &&
669 a->fp0 == b->fp0 &&
670 a->fp1 == b->fp1;
671}
672
673static const struct intel_dpll_funcs ibx_pch_dpll_funcs = {
674 .enable = ibx_pch_dpll_enable,
675 .disable = ibx_pch_dpll_disable,
676 .get_hw_state = ibx_pch_dpll_get_hw_state,
677};
678
679static const struct dpll_info pch_plls[] = {
680 { .name = "PCH DPLL A", .funcs = &ibx_pch_dpll_funcs, .id = DPLL_ID_PCH_PLL_A, },
681 { .name = "PCH DPLL B", .funcs = &ibx_pch_dpll_funcs, .id = DPLL_ID_PCH_PLL_B, },
682 {}
683};
684
685static const struct intel_dpll_mgr pch_pll_mgr = {
686 .dpll_info = pch_plls,
687 .compute_dplls = ibx_compute_dpll,
688 .get_dplls = ibx_get_dpll,
689 .put_dplls = intel_put_dpll,
690 .dump_hw_state = ibx_dump_hw_state,
691 .compare_hw_state = ibx_compare_hw_state,
692};
693
694static void hsw_ddi_wrpll_enable(struct intel_display *display,
695 struct intel_dpll *pll,
696 const struct intel_dpll_hw_state *dpll_hw_state)
697{
698 const struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw;
699 const enum intel_dpll_id id = pll->info->id;
700
701 intel_de_write(display, WRPLL_CTL(id), val: hw_state->wrpll);
702 intel_de_posting_read(display, WRPLL_CTL(id));
703 udelay(usec: 20);
704}
705
706static void hsw_ddi_spll_enable(struct intel_display *display,
707 struct intel_dpll *pll,
708 const struct intel_dpll_hw_state *dpll_hw_state)
709{
710 const struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw;
711
712 intel_de_write(display, SPLL_CTL, val: hw_state->spll);
713 intel_de_posting_read(display, SPLL_CTL);
714 udelay(usec: 20);
715}
716
717static void hsw_ddi_wrpll_disable(struct intel_display *display,
718 struct intel_dpll *pll)
719{
720 const enum intel_dpll_id id = pll->info->id;
721
722 intel_de_rmw(display, WRPLL_CTL(id), WRPLL_PLL_ENABLE, set: 0);
723 intel_de_posting_read(display, WRPLL_CTL(id));
724
725 /*
726 * Try to set up the PCH reference clock once all DPLLs
727 * that depend on it have been shut down.
728 */
729 if (display->dpll.pch_ssc_use & BIT(id))
730 intel_init_pch_refclk(display);
731}
732
733static void hsw_ddi_spll_disable(struct intel_display *display,
734 struct intel_dpll *pll)
735{
736 enum intel_dpll_id id = pll->info->id;
737
738 intel_de_rmw(display, SPLL_CTL, SPLL_PLL_ENABLE, set: 0);
739 intel_de_posting_read(display, SPLL_CTL);
740
741 /*
742 * Try to set up the PCH reference clock once all DPLLs
743 * that depend on it have been shut down.
744 */
745 if (display->dpll.pch_ssc_use & BIT(id))
746 intel_init_pch_refclk(display);
747}
748
749static bool hsw_ddi_wrpll_get_hw_state(struct intel_display *display,
750 struct intel_dpll *pll,
751 struct intel_dpll_hw_state *dpll_hw_state)
752{
753 struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw;
754 const enum intel_dpll_id id = pll->info->id;
755 intel_wakeref_t wakeref;
756 u32 val;
757
758 wakeref = intel_display_power_get_if_enabled(display,
759 domain: POWER_DOMAIN_DISPLAY_CORE);
760 if (!wakeref)
761 return false;
762
763 val = intel_de_read(display, WRPLL_CTL(id));
764 hw_state->wrpll = val;
765
766 intel_display_power_put(display, domain: POWER_DOMAIN_DISPLAY_CORE, wakeref);
767
768 return val & WRPLL_PLL_ENABLE;
769}
770
771static bool hsw_ddi_spll_get_hw_state(struct intel_display *display,
772 struct intel_dpll *pll,
773 struct intel_dpll_hw_state *dpll_hw_state)
774{
775 struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw;
776 intel_wakeref_t wakeref;
777 u32 val;
778
779 wakeref = intel_display_power_get_if_enabled(display,
780 domain: POWER_DOMAIN_DISPLAY_CORE);
781 if (!wakeref)
782 return false;
783
784 val = intel_de_read(display, SPLL_CTL);
785 hw_state->spll = val;
786
787 intel_display_power_put(display, domain: POWER_DOMAIN_DISPLAY_CORE, wakeref);
788
789 return val & SPLL_PLL_ENABLE;
790}
791
792#define LC_FREQ 2700
793#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
794
795#define P_MIN 2
796#define P_MAX 64
797#define P_INC 2
798
799/* Constraints for PLL good behavior */
800#define REF_MIN 48
801#define REF_MAX 400
802#define VCO_MIN 2400
803#define VCO_MAX 4800
804
805struct hsw_wrpll_rnp {
806 unsigned p, n2, r2;
807};
808
809static unsigned hsw_wrpll_get_budget_for_freq(int clock)
810{
811 switch (clock) {
812 case 25175000:
813 case 25200000:
814 case 27000000:
815 case 27027000:
816 case 37762500:
817 case 37800000:
818 case 40500000:
819 case 40541000:
820 case 54000000:
821 case 54054000:
822 case 59341000:
823 case 59400000:
824 case 72000000:
825 case 74176000:
826 case 74250000:
827 case 81000000:
828 case 81081000:
829 case 89012000:
830 case 89100000:
831 case 108000000:
832 case 108108000:
833 case 111264000:
834 case 111375000:
835 case 148352000:
836 case 148500000:
837 case 162000000:
838 case 162162000:
839 case 222525000:
840 case 222750000:
841 case 296703000:
842 case 297000000:
843 return 0;
844 case 233500000:
845 case 245250000:
846 case 247750000:
847 case 253250000:
848 case 298000000:
849 return 1500;
850 case 169128000:
851 case 169500000:
852 case 179500000:
853 case 202000000:
854 return 2000;
855 case 256250000:
856 case 262500000:
857 case 270000000:
858 case 272500000:
859 case 273750000:
860 case 280750000:
861 case 281250000:
862 case 286000000:
863 case 291750000:
864 return 4000;
865 case 267250000:
866 case 268500000:
867 return 5000;
868 default:
869 return 1000;
870 }
871}
872
873static void hsw_wrpll_update_rnp(u64 freq2k, unsigned int budget,
874 unsigned int r2, unsigned int n2,
875 unsigned int p,
876 struct hsw_wrpll_rnp *best)
877{
878 u64 a, b, c, d, diff, diff_best;
879
880 /* No best (r,n,p) yet */
881 if (best->p == 0) {
882 best->p = p;
883 best->n2 = n2;
884 best->r2 = r2;
885 return;
886 }
887
888 /*
889 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
890 * freq2k.
891 *
892 * delta = 1e6 *
893 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
894 * freq2k;
895 *
896 * and we would like delta <= budget.
897 *
898 * If the discrepancy is above the PPM-based budget, always prefer to
899 * improve upon the previous solution. However, if you're within the
900 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
901 */
902 a = freq2k * budget * p * r2;
903 b = freq2k * budget * best->p * best->r2;
904 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
905 diff_best = abs_diff(freq2k * best->p * best->r2,
906 LC_FREQ_2K * best->n2);
907 c = 1000000 * diff;
908 d = 1000000 * diff_best;
909
910 if (a < c && b < d) {
911 /* If both are above the budget, pick the closer */
912 if (best->p * best->r2 * diff < p * r2 * diff_best) {
913 best->p = p;
914 best->n2 = n2;
915 best->r2 = r2;
916 }
917 } else if (a >= c && b < d) {
918 /* If A is below the threshold but B is above it? Update. */
919 best->p = p;
920 best->n2 = n2;
921 best->r2 = r2;
922 } else if (a >= c && b >= d) {
923 /* Both are below the limit, so pick the higher n2/(r2*r2) */
924 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
925 best->p = p;
926 best->n2 = n2;
927 best->r2 = r2;
928 }
929 }
930 /* Otherwise a < c && b >= d, do nothing */
931}
932
933static void
934hsw_ddi_calculate_wrpll(int clock /* in Hz */,
935 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
936{
937 u64 freq2k;
938 unsigned p, n2, r2;
939 struct hsw_wrpll_rnp best = {};
940 unsigned budget;
941
942 freq2k = clock / 100;
943
944 budget = hsw_wrpll_get_budget_for_freq(clock);
945
946 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
947 * and directly pass the LC PLL to it. */
948 if (freq2k == 5400000) {
949 *n2_out = 2;
950 *p_out = 1;
951 *r2_out = 2;
952 return;
953 }
954
955 /*
956 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
957 * the WR PLL.
958 *
959 * We want R so that REF_MIN <= Ref <= REF_MAX.
960 * Injecting R2 = 2 * R gives:
961 * REF_MAX * r2 > LC_FREQ * 2 and
962 * REF_MIN * r2 < LC_FREQ * 2
963 *
964 * Which means the desired boundaries for r2 are:
965 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
966 *
967 */
968 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
969 r2 <= LC_FREQ * 2 / REF_MIN;
970 r2++) {
971
972 /*
973 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
974 *
975 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
976 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
977 * VCO_MAX * r2 > n2 * LC_FREQ and
978 * VCO_MIN * r2 < n2 * LC_FREQ)
979 *
980 * Which means the desired boundaries for n2 are:
981 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
982 */
983 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
984 n2 <= VCO_MAX * r2 / LC_FREQ;
985 n2++) {
986
987 for (p = P_MIN; p <= P_MAX; p += P_INC)
988 hsw_wrpll_update_rnp(freq2k, budget,
989 r2, n2, p, best: &best);
990 }
991 }
992
993 *n2_out = best.n2;
994 *p_out = best.p;
995 *r2_out = best.r2;
996}
997
998static int hsw_ddi_wrpll_get_freq(struct intel_display *display,
999 const struct intel_dpll *pll,
1000 const struct intel_dpll_hw_state *dpll_hw_state)
1001{
1002 const struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw;
1003 int refclk;
1004 int n, p, r;
1005 u32 wrpll = hw_state->wrpll;
1006
1007 switch (wrpll & WRPLL_REF_MASK) {
1008 case WRPLL_REF_SPECIAL_HSW:
1009 /* Muxed-SSC for BDW, non-SSC for non-ULT HSW. */
1010 if (display->platform.haswell && !display->platform.haswell_ult) {
1011 refclk = display->dpll.ref_clks.nssc;
1012 break;
1013 }
1014 fallthrough;
1015 case WRPLL_REF_PCH_SSC:
1016 /*
1017 * We could calculate spread here, but our checking
1018 * code only cares about 5% accuracy, and spread is a max of
1019 * 0.5% downspread.
1020 */
1021 refclk = display->dpll.ref_clks.ssc;
1022 break;
1023 case WRPLL_REF_LCPLL:
1024 refclk = 2700000;
1025 break;
1026 default:
1027 MISSING_CASE(wrpll);
1028 return 0;
1029 }
1030
1031 r = wrpll & WRPLL_DIVIDER_REF_MASK;
1032 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
1033 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
1034
1035 /* Convert to KHz, p & r have a fixed point portion */
1036 return (refclk * n / 10) / (p * r) * 2;
1037}
1038
1039static int
1040hsw_ddi_wrpll_compute_dpll(struct intel_atomic_state *state,
1041 struct intel_crtc *crtc)
1042{
1043 struct intel_display *display = to_intel_display(state);
1044 struct intel_crtc_state *crtc_state =
1045 intel_atomic_get_new_crtc_state(state, crtc);
1046 struct hsw_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.hsw;
1047 unsigned int p, n2, r2;
1048
1049 hsw_ddi_calculate_wrpll(clock: crtc_state->port_clock * 1000, r2_out: &r2, n2_out: &n2, p_out: &p);
1050
1051 hw_state->wrpll =
1052 WRPLL_PLL_ENABLE | WRPLL_REF_LCPLL |
1053 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1054 WRPLL_DIVIDER_POST(p);
1055
1056 crtc_state->port_clock = hsw_ddi_wrpll_get_freq(display, NULL,
1057 dpll_hw_state: &crtc_state->dpll_hw_state);
1058
1059 return 0;
1060}
1061
1062static struct intel_dpll *
1063hsw_ddi_wrpll_get_dpll(struct intel_atomic_state *state,
1064 struct intel_crtc *crtc)
1065{
1066 struct intel_crtc_state *crtc_state =
1067 intel_atomic_get_new_crtc_state(state, crtc);
1068
1069 return intel_find_dpll(state, crtc,
1070 dpll_hw_state: &crtc_state->dpll_hw_state,
1071 BIT(DPLL_ID_WRPLL2) |
1072 BIT(DPLL_ID_WRPLL1));
1073}
1074
1075static int
1076hsw_ddi_lcpll_compute_dpll(struct intel_crtc_state *crtc_state)
1077{
1078 struct intel_display *display = to_intel_display(crtc_state);
1079 int clock = crtc_state->port_clock;
1080
1081 switch (clock / 2) {
1082 case 81000:
1083 case 135000:
1084 case 270000:
1085 return 0;
1086 default:
1087 drm_dbg_kms(display->drm, "Invalid clock for DP: %d\n",
1088 clock);
1089 return -EINVAL;
1090 }
1091}
1092
1093static struct intel_dpll *
1094hsw_ddi_lcpll_get_dpll(struct intel_crtc_state *crtc_state)
1095{
1096 struct intel_display *display = to_intel_display(crtc_state);
1097 struct intel_dpll *pll;
1098 enum intel_dpll_id pll_id;
1099 int clock = crtc_state->port_clock;
1100
1101 switch (clock / 2) {
1102 case 81000:
1103 pll_id = DPLL_ID_LCPLL_810;
1104 break;
1105 case 135000:
1106 pll_id = DPLL_ID_LCPLL_1350;
1107 break;
1108 case 270000:
1109 pll_id = DPLL_ID_LCPLL_2700;
1110 break;
1111 default:
1112 MISSING_CASE(clock / 2);
1113 return NULL;
1114 }
1115
1116 pll = intel_get_dpll_by_id(display, id: pll_id);
1117
1118 if (!pll)
1119 return NULL;
1120
1121 return pll;
1122}
1123
1124static int hsw_ddi_lcpll_get_freq(struct intel_display *display,
1125 const struct intel_dpll *pll,
1126 const struct intel_dpll_hw_state *dpll_hw_state)
1127{
1128 int link_clock = 0;
1129
1130 switch (pll->info->id) {
1131 case DPLL_ID_LCPLL_810:
1132 link_clock = 81000;
1133 break;
1134 case DPLL_ID_LCPLL_1350:
1135 link_clock = 135000;
1136 break;
1137 case DPLL_ID_LCPLL_2700:
1138 link_clock = 270000;
1139 break;
1140 default:
1141 drm_WARN(display->drm, 1, "bad port clock sel\n");
1142 break;
1143 }
1144
1145 return link_clock * 2;
1146}
1147
1148static int
1149hsw_ddi_spll_compute_dpll(struct intel_atomic_state *state,
1150 struct intel_crtc *crtc)
1151{
1152 struct intel_crtc_state *crtc_state =
1153 intel_atomic_get_new_crtc_state(state, crtc);
1154 struct hsw_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.hsw;
1155
1156 if (drm_WARN_ON(crtc->base.dev, crtc_state->port_clock / 2 != 135000))
1157 return -EINVAL;
1158
1159 hw_state->spll =
1160 SPLL_PLL_ENABLE | SPLL_FREQ_1350MHz | SPLL_REF_MUXED_SSC;
1161
1162 return 0;
1163}
1164
1165static struct intel_dpll *
1166hsw_ddi_spll_get_dpll(struct intel_atomic_state *state,
1167 struct intel_crtc *crtc)
1168{
1169 struct intel_crtc_state *crtc_state =
1170 intel_atomic_get_new_crtc_state(state, crtc);
1171
1172 return intel_find_dpll(state, crtc, dpll_hw_state: &crtc_state->dpll_hw_state,
1173 BIT(DPLL_ID_SPLL));
1174}
1175
1176static int hsw_ddi_spll_get_freq(struct intel_display *display,
1177 const struct intel_dpll *pll,
1178 const struct intel_dpll_hw_state *dpll_hw_state)
1179{
1180 const struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw;
1181 int link_clock = 0;
1182
1183 switch (hw_state->spll & SPLL_FREQ_MASK) {
1184 case SPLL_FREQ_810MHz:
1185 link_clock = 81000;
1186 break;
1187 case SPLL_FREQ_1350MHz:
1188 link_clock = 135000;
1189 break;
1190 case SPLL_FREQ_2700MHz:
1191 link_clock = 270000;
1192 break;
1193 default:
1194 drm_WARN(display->drm, 1, "bad spll freq\n");
1195 break;
1196 }
1197
1198 return link_clock * 2;
1199}
1200
1201static int hsw_compute_dpll(struct intel_atomic_state *state,
1202 struct intel_crtc *crtc,
1203 struct intel_encoder *encoder)
1204{
1205 struct intel_crtc_state *crtc_state =
1206 intel_atomic_get_new_crtc_state(state, crtc);
1207
1208 if (intel_crtc_has_type(crtc_state, type: INTEL_OUTPUT_HDMI))
1209 return hsw_ddi_wrpll_compute_dpll(state, crtc);
1210 else if (intel_crtc_has_dp_encoder(crtc_state))
1211 return hsw_ddi_lcpll_compute_dpll(crtc_state);
1212 else if (intel_crtc_has_type(crtc_state, type: INTEL_OUTPUT_ANALOG))
1213 return hsw_ddi_spll_compute_dpll(state, crtc);
1214 else
1215 return -EINVAL;
1216}
1217
1218static int hsw_get_dpll(struct intel_atomic_state *state,
1219 struct intel_crtc *crtc,
1220 struct intel_encoder *encoder)
1221{
1222 struct intel_crtc_state *crtc_state =
1223 intel_atomic_get_new_crtc_state(state, crtc);
1224 struct intel_dpll *pll = NULL;
1225
1226 if (intel_crtc_has_type(crtc_state, type: INTEL_OUTPUT_HDMI))
1227 pll = hsw_ddi_wrpll_get_dpll(state, crtc);
1228 else if (intel_crtc_has_dp_encoder(crtc_state))
1229 pll = hsw_ddi_lcpll_get_dpll(crtc_state);
1230 else if (intel_crtc_has_type(crtc_state, type: INTEL_OUTPUT_ANALOG))
1231 pll = hsw_ddi_spll_get_dpll(state, crtc);
1232
1233 if (!pll)
1234 return -EINVAL;
1235
1236 intel_reference_dpll(state, crtc,
1237 pll, dpll_hw_state: &crtc_state->dpll_hw_state);
1238
1239 crtc_state->intel_dpll = pll;
1240
1241 return 0;
1242}
1243
1244static void hsw_update_dpll_ref_clks(struct intel_display *display)
1245{
1246 display->dpll.ref_clks.ssc = 135000;
1247 /* Non-SSC is only used on non-ULT HSW. */
1248 if (intel_de_read(display, FUSE_STRAP3) & HSW_REF_CLK_SELECT)
1249 display->dpll.ref_clks.nssc = 24000;
1250 else
1251 display->dpll.ref_clks.nssc = 135000;
1252}
1253
1254static void hsw_dump_hw_state(struct drm_printer *p,
1255 const struct intel_dpll_hw_state *dpll_hw_state)
1256{
1257 const struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw;
1258
1259 drm_printf(p, f: "dpll_hw_state: wrpll: 0x%x spll: 0x%x\n",
1260 hw_state->wrpll, hw_state->spll);
1261}
1262
1263static bool hsw_compare_hw_state(const struct intel_dpll_hw_state *_a,
1264 const struct intel_dpll_hw_state *_b)
1265{
1266 const struct hsw_dpll_hw_state *a = &_a->hsw;
1267 const struct hsw_dpll_hw_state *b = &_b->hsw;
1268
1269 return a->wrpll == b->wrpll &&
1270 a->spll == b->spll;
1271}
1272
1273static const struct intel_dpll_funcs hsw_ddi_wrpll_funcs = {
1274 .enable = hsw_ddi_wrpll_enable,
1275 .disable = hsw_ddi_wrpll_disable,
1276 .get_hw_state = hsw_ddi_wrpll_get_hw_state,
1277 .get_freq = hsw_ddi_wrpll_get_freq,
1278};
1279
1280static const struct intel_dpll_funcs hsw_ddi_spll_funcs = {
1281 .enable = hsw_ddi_spll_enable,
1282 .disable = hsw_ddi_spll_disable,
1283 .get_hw_state = hsw_ddi_spll_get_hw_state,
1284 .get_freq = hsw_ddi_spll_get_freq,
1285};
1286
1287static void hsw_ddi_lcpll_enable(struct intel_display *display,
1288 struct intel_dpll *pll,
1289 const struct intel_dpll_hw_state *hw_state)
1290{
1291}
1292
1293static void hsw_ddi_lcpll_disable(struct intel_display *display,
1294 struct intel_dpll *pll)
1295{
1296}
1297
1298static bool hsw_ddi_lcpll_get_hw_state(struct intel_display *display,
1299 struct intel_dpll *pll,
1300 struct intel_dpll_hw_state *dpll_hw_state)
1301{
1302 return true;
1303}
1304
1305static const struct intel_dpll_funcs hsw_ddi_lcpll_funcs = {
1306 .enable = hsw_ddi_lcpll_enable,
1307 .disable = hsw_ddi_lcpll_disable,
1308 .get_hw_state = hsw_ddi_lcpll_get_hw_state,
1309 .get_freq = hsw_ddi_lcpll_get_freq,
1310};
1311
1312static const struct dpll_info hsw_plls[] = {
1313 { .name = "WRPLL 1", .funcs = &hsw_ddi_wrpll_funcs, .id = DPLL_ID_WRPLL1, },
1314 { .name = "WRPLL 2", .funcs = &hsw_ddi_wrpll_funcs, .id = DPLL_ID_WRPLL2, },
1315 { .name = "SPLL", .funcs = &hsw_ddi_spll_funcs, .id = DPLL_ID_SPLL, },
1316 { .name = "LCPLL 810", .funcs = &hsw_ddi_lcpll_funcs, .id = DPLL_ID_LCPLL_810,
1317 .always_on = true, },
1318 { .name = "LCPLL 1350", .funcs = &hsw_ddi_lcpll_funcs, .id = DPLL_ID_LCPLL_1350,
1319 .always_on = true, },
1320 { .name = "LCPLL 2700", .funcs = &hsw_ddi_lcpll_funcs, .id = DPLL_ID_LCPLL_2700,
1321 .always_on = true, },
1322 {}
1323};
1324
1325static const struct intel_dpll_mgr hsw_pll_mgr = {
1326 .dpll_info = hsw_plls,
1327 .compute_dplls = hsw_compute_dpll,
1328 .get_dplls = hsw_get_dpll,
1329 .put_dplls = intel_put_dpll,
1330 .update_ref_clks = hsw_update_dpll_ref_clks,
1331 .dump_hw_state = hsw_dump_hw_state,
1332 .compare_hw_state = hsw_compare_hw_state,
1333};
1334
1335struct skl_dpll_regs {
1336 i915_reg_t ctl, cfgcr1, cfgcr2;
1337};
1338
1339/* this array is indexed by the *shared* pll id */
1340static const struct skl_dpll_regs skl_dpll_regs[4] = {
1341 {
1342 /* DPLL 0 */
1343 .ctl = LCPLL1_CTL,
1344 /* DPLL 0 doesn't support HDMI mode */
1345 },
1346 {
1347 /* DPLL 1 */
1348 .ctl = LCPLL2_CTL,
1349 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
1350 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
1351 },
1352 {
1353 /* DPLL 2 */
1354 .ctl = WRPLL_CTL(0),
1355 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
1356 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
1357 },
1358 {
1359 /* DPLL 3 */
1360 .ctl = WRPLL_CTL(1),
1361 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
1362 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
1363 },
1364};
1365
1366static void skl_ddi_pll_write_ctrl1(struct intel_display *display,
1367 struct intel_dpll *pll,
1368 const struct skl_dpll_hw_state *hw_state)
1369{
1370 const enum intel_dpll_id id = pll->info->id;
1371
1372 intel_de_rmw(display, DPLL_CTRL1,
1373 DPLL_CTRL1_HDMI_MODE(id) |
1374 DPLL_CTRL1_SSC(id) |
1375 DPLL_CTRL1_LINK_RATE_MASK(id),
1376 set: hw_state->ctrl1 << (id * 6));
1377 intel_de_posting_read(display, DPLL_CTRL1);
1378}
1379
1380static void skl_ddi_pll_enable(struct intel_display *display,
1381 struct intel_dpll *pll,
1382 const struct intel_dpll_hw_state *dpll_hw_state)
1383{
1384 const struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl;
1385 const struct skl_dpll_regs *regs = skl_dpll_regs;
1386 const enum intel_dpll_id id = pll->info->id;
1387
1388 skl_ddi_pll_write_ctrl1(display, pll, hw_state);
1389
1390 intel_de_write(display, reg: regs[id].cfgcr1, val: hw_state->cfgcr1);
1391 intel_de_write(display, reg: regs[id].cfgcr2, val: hw_state->cfgcr2);
1392 intel_de_posting_read(display, reg: regs[id].cfgcr1);
1393 intel_de_posting_read(display, reg: regs[id].cfgcr2);
1394
1395 /* the enable bit is always bit 31 */
1396 intel_de_rmw(display, reg: regs[id].ctl, clear: 0, LCPLL_PLL_ENABLE);
1397
1398 if (intel_de_wait_for_set_ms(display, DPLL_STATUS, DPLL_LOCK(id), timeout_ms: 5))
1399 drm_err(display->drm, "DPLL %d not locked\n", id);
1400}
1401
1402static void skl_ddi_dpll0_enable(struct intel_display *display,
1403 struct intel_dpll *pll,
1404 const struct intel_dpll_hw_state *dpll_hw_state)
1405{
1406 const struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl;
1407
1408 skl_ddi_pll_write_ctrl1(display, pll, hw_state);
1409}
1410
1411static void skl_ddi_pll_disable(struct intel_display *display,
1412 struct intel_dpll *pll)
1413{
1414 const struct skl_dpll_regs *regs = skl_dpll_regs;
1415 const enum intel_dpll_id id = pll->info->id;
1416
1417 /* the enable bit is always bit 31 */
1418 intel_de_rmw(display, reg: regs[id].ctl, LCPLL_PLL_ENABLE, set: 0);
1419 intel_de_posting_read(display, reg: regs[id].ctl);
1420}
1421
1422static void skl_ddi_dpll0_disable(struct intel_display *display,
1423 struct intel_dpll *pll)
1424{
1425}
1426
1427static bool skl_ddi_pll_get_hw_state(struct intel_display *display,
1428 struct intel_dpll *pll,
1429 struct intel_dpll_hw_state *dpll_hw_state)
1430{
1431 struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl;
1432 const struct skl_dpll_regs *regs = skl_dpll_regs;
1433 const enum intel_dpll_id id = pll->info->id;
1434 intel_wakeref_t wakeref;
1435 bool ret;
1436 u32 val;
1437
1438 wakeref = intel_display_power_get_if_enabled(display,
1439 domain: POWER_DOMAIN_DISPLAY_CORE);
1440 if (!wakeref)
1441 return false;
1442
1443 ret = false;
1444
1445 val = intel_de_read(display, reg: regs[id].ctl);
1446 if (!(val & LCPLL_PLL_ENABLE))
1447 goto out;
1448
1449 val = intel_de_read(display, DPLL_CTRL1);
1450 hw_state->ctrl1 = (val >> (id * 6)) & 0x3f;
1451
1452 /* avoid reading back stale values if HDMI mode is not enabled */
1453 if (val & DPLL_CTRL1_HDMI_MODE(id)) {
1454 hw_state->cfgcr1 = intel_de_read(display, reg: regs[id].cfgcr1);
1455 hw_state->cfgcr2 = intel_de_read(display, reg: regs[id].cfgcr2);
1456 }
1457 ret = true;
1458
1459out:
1460 intel_display_power_put(display, domain: POWER_DOMAIN_DISPLAY_CORE, wakeref);
1461
1462 return ret;
1463}
1464
1465static bool skl_ddi_dpll0_get_hw_state(struct intel_display *display,
1466 struct intel_dpll *pll,
1467 struct intel_dpll_hw_state *dpll_hw_state)
1468{
1469 struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl;
1470 const struct skl_dpll_regs *regs = skl_dpll_regs;
1471 const enum intel_dpll_id id = pll->info->id;
1472 intel_wakeref_t wakeref;
1473 u32 val;
1474 bool ret;
1475
1476 wakeref = intel_display_power_get_if_enabled(display,
1477 domain: POWER_DOMAIN_DISPLAY_CORE);
1478 if (!wakeref)
1479 return false;
1480
1481 ret = false;
1482
1483 /* DPLL0 is always enabled since it drives CDCLK */
1484 val = intel_de_read(display, reg: regs[id].ctl);
1485 if (drm_WARN_ON(display->drm, !(val & LCPLL_PLL_ENABLE)))
1486 goto out;
1487
1488 val = intel_de_read(display, DPLL_CTRL1);
1489 hw_state->ctrl1 = (val >> (id * 6)) & 0x3f;
1490
1491 ret = true;
1492
1493out:
1494 intel_display_power_put(display, domain: POWER_DOMAIN_DISPLAY_CORE, wakeref);
1495
1496 return ret;
1497}
1498
1499struct skl_wrpll_context {
1500 u64 min_deviation; /* current minimal deviation */
1501 u64 central_freq; /* chosen central freq */
1502 u64 dco_freq; /* chosen dco freq */
1503 unsigned int p; /* chosen divider */
1504};
1505
1506/* DCO freq must be within +1%/-6% of the DCO central freq */
1507#define SKL_DCO_MAX_PDEVIATION 100
1508#define SKL_DCO_MAX_NDEVIATION 600
1509
1510static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1511 u64 central_freq,
1512 u64 dco_freq,
1513 unsigned int divider)
1514{
1515 u64 deviation;
1516
1517 deviation = div64_u64(dividend: 10000 * abs_diff(dco_freq, central_freq),
1518 divisor: central_freq);
1519
1520 /* positive deviation */
1521 if (dco_freq >= central_freq) {
1522 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1523 deviation < ctx->min_deviation) {
1524 ctx->min_deviation = deviation;
1525 ctx->central_freq = central_freq;
1526 ctx->dco_freq = dco_freq;
1527 ctx->p = divider;
1528 }
1529 /* negative deviation */
1530 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1531 deviation < ctx->min_deviation) {
1532 ctx->min_deviation = deviation;
1533 ctx->central_freq = central_freq;
1534 ctx->dco_freq = dco_freq;
1535 ctx->p = divider;
1536 }
1537}
1538
1539static void skl_wrpll_get_multipliers(unsigned int p,
1540 unsigned int *p0 /* out */,
1541 unsigned int *p1 /* out */,
1542 unsigned int *p2 /* out */)
1543{
1544 /* even dividers */
1545 if (p % 2 == 0) {
1546 unsigned int half = p / 2;
1547
1548 if (half == 1 || half == 2 || half == 3 || half == 5) {
1549 *p0 = 2;
1550 *p1 = 1;
1551 *p2 = half;
1552 } else if (half % 2 == 0) {
1553 *p0 = 2;
1554 *p1 = half / 2;
1555 *p2 = 2;
1556 } else if (half % 3 == 0) {
1557 *p0 = 3;
1558 *p1 = half / 3;
1559 *p2 = 2;
1560 } else if (half % 7 == 0) {
1561 *p0 = 7;
1562 *p1 = half / 7;
1563 *p2 = 2;
1564 }
1565 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1566 *p0 = 3;
1567 *p1 = 1;
1568 *p2 = p / 3;
1569 } else if (p == 5 || p == 7) {
1570 *p0 = p;
1571 *p1 = 1;
1572 *p2 = 1;
1573 } else if (p == 15) {
1574 *p0 = 3;
1575 *p1 = 1;
1576 *p2 = 5;
1577 } else if (p == 21) {
1578 *p0 = 7;
1579 *p1 = 1;
1580 *p2 = 3;
1581 } else if (p == 35) {
1582 *p0 = 7;
1583 *p1 = 1;
1584 *p2 = 5;
1585 }
1586}
1587
1588struct skl_wrpll_params {
1589 u32 dco_fraction;
1590 u32 dco_integer;
1591 u32 qdiv_ratio;
1592 u32 qdiv_mode;
1593 u32 kdiv;
1594 u32 pdiv;
1595 u32 central_freq;
1596};
1597
1598static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1599 u64 afe_clock,
1600 int ref_clock,
1601 u64 central_freq,
1602 u32 p0, u32 p1, u32 p2)
1603{
1604 u64 dco_freq;
1605
1606 switch (central_freq) {
1607 case 9600000000ULL:
1608 params->central_freq = 0;
1609 break;
1610 case 9000000000ULL:
1611 params->central_freq = 1;
1612 break;
1613 case 8400000000ULL:
1614 params->central_freq = 3;
1615 }
1616
1617 switch (p0) {
1618 case 1:
1619 params->pdiv = 0;
1620 break;
1621 case 2:
1622 params->pdiv = 1;
1623 break;
1624 case 3:
1625 params->pdiv = 2;
1626 break;
1627 case 7:
1628 params->pdiv = 4;
1629 break;
1630 default:
1631 WARN(1, "Incorrect PDiv\n");
1632 }
1633
1634 switch (p2) {
1635 case 5:
1636 params->kdiv = 0;
1637 break;
1638 case 2:
1639 params->kdiv = 1;
1640 break;
1641 case 3:
1642 params->kdiv = 2;
1643 break;
1644 case 1:
1645 params->kdiv = 3;
1646 break;
1647 default:
1648 WARN(1, "Incorrect KDiv\n");
1649 }
1650
1651 params->qdiv_ratio = p1;
1652 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1653
1654 dco_freq = p0 * p1 * p2 * afe_clock;
1655
1656 /*
1657 * Intermediate values are in Hz.
1658 * Divide by MHz to match bsepc
1659 */
1660 params->dco_integer = div_u64(dividend: dco_freq, divisor: ref_clock * KHz(1));
1661 params->dco_fraction =
1662 div_u64(dividend: (div_u64(dividend: dco_freq, divisor: ref_clock / KHz(1)) -
1663 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
1664}
1665
1666static int
1667skl_ddi_calculate_wrpll(int clock,
1668 int ref_clock,
1669 struct skl_wrpll_params *wrpll_params)
1670{
1671 static const u64 dco_central_freq[3] = { 8400000000ULL,
1672 9000000000ULL,
1673 9600000000ULL };
1674 static const u8 even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1675 24, 28, 30, 32, 36, 40, 42, 44,
1676 48, 52, 54, 56, 60, 64, 66, 68,
1677 70, 72, 76, 78, 80, 84, 88, 90,
1678 92, 96, 98 };
1679 static const u8 odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1680 static const struct {
1681 const u8 *list;
1682 int n_dividers;
1683 } dividers[] = {
1684 { even_dividers, ARRAY_SIZE(even_dividers) },
1685 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1686 };
1687 struct skl_wrpll_context ctx = {
1688 .min_deviation = U64_MAX,
1689 };
1690 unsigned int dco, d, i;
1691 unsigned int p0, p1, p2;
1692 u64 afe_clock = (u64)clock * 1000 * 5; /* AFE Clock is 5x Pixel clock, in Hz */
1693
1694 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1695 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1696 for (i = 0; i < dividers[d].n_dividers; i++) {
1697 unsigned int p = dividers[d].list[i];
1698 u64 dco_freq = p * afe_clock;
1699
1700 skl_wrpll_try_divider(ctx: &ctx,
1701 central_freq: dco_central_freq[dco],
1702 dco_freq,
1703 divider: p);
1704 /*
1705 * Skip the remaining dividers if we're sure to
1706 * have found the definitive divider, we can't
1707 * improve a 0 deviation.
1708 */
1709 if (ctx.min_deviation == 0)
1710 goto skip_remaining_dividers;
1711 }
1712 }
1713
1714skip_remaining_dividers:
1715 /*
1716 * If a solution is found with an even divider, prefer
1717 * this one.
1718 */
1719 if (d == 0 && ctx.p)
1720 break;
1721 }
1722
1723 if (!ctx.p)
1724 return -EINVAL;
1725
1726 /*
1727 * gcc incorrectly analyses that these can be used without being
1728 * initialized. To be fair, it's hard to guess.
1729 */
1730 p0 = p1 = p2 = 0;
1731 skl_wrpll_get_multipliers(p: ctx.p, p0: &p0, p1: &p1, p2: &p2);
1732 skl_wrpll_params_populate(params: wrpll_params, afe_clock, ref_clock,
1733 central_freq: ctx.central_freq, p0, p1, p2);
1734
1735 return 0;
1736}
1737
1738static int skl_ddi_wrpll_get_freq(struct intel_display *display,
1739 const struct intel_dpll *pll,
1740 const struct intel_dpll_hw_state *dpll_hw_state)
1741{
1742 const struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl;
1743 int ref_clock = display->dpll.ref_clks.nssc;
1744 u32 p0, p1, p2, dco_freq;
1745
1746 p0 = hw_state->cfgcr2 & DPLL_CFGCR2_PDIV_MASK;
1747 p2 = hw_state->cfgcr2 & DPLL_CFGCR2_KDIV_MASK;
1748
1749 if (hw_state->cfgcr2 & DPLL_CFGCR2_QDIV_MODE(1))
1750 p1 = (hw_state->cfgcr2 & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
1751 else
1752 p1 = 1;
1753
1754
1755 switch (p0) {
1756 case DPLL_CFGCR2_PDIV_1:
1757 p0 = 1;
1758 break;
1759 case DPLL_CFGCR2_PDIV_2:
1760 p0 = 2;
1761 break;
1762 case DPLL_CFGCR2_PDIV_3:
1763 p0 = 3;
1764 break;
1765 case DPLL_CFGCR2_PDIV_7_INVALID:
1766 /*
1767 * Incorrect ASUS-Z170M BIOS setting, the HW seems to ignore bit#0,
1768 * handling it the same way as PDIV_7.
1769 */
1770 drm_dbg_kms(display->drm, "Invalid WRPLL PDIV divider value, fixing it.\n");
1771 fallthrough;
1772 case DPLL_CFGCR2_PDIV_7:
1773 p0 = 7;
1774 break;
1775 default:
1776 MISSING_CASE(p0);
1777 return 0;
1778 }
1779
1780 switch (p2) {
1781 case DPLL_CFGCR2_KDIV_5:
1782 p2 = 5;
1783 break;
1784 case DPLL_CFGCR2_KDIV_2:
1785 p2 = 2;
1786 break;
1787 case DPLL_CFGCR2_KDIV_3:
1788 p2 = 3;
1789 break;
1790 case DPLL_CFGCR2_KDIV_1:
1791 p2 = 1;
1792 break;
1793 default:
1794 MISSING_CASE(p2);
1795 return 0;
1796 }
1797
1798 dco_freq = (hw_state->cfgcr1 & DPLL_CFGCR1_DCO_INTEGER_MASK) *
1799 ref_clock;
1800
1801 dco_freq += ((hw_state->cfgcr1 & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) *
1802 ref_clock / 0x8000;
1803
1804 if (drm_WARN_ON(display->drm, p0 == 0 || p1 == 0 || p2 == 0))
1805 return 0;
1806
1807 return dco_freq / (p0 * p1 * p2 * 5);
1808}
1809
1810static int skl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state)
1811{
1812 struct intel_display *display = to_intel_display(crtc_state);
1813 struct skl_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.skl;
1814 struct skl_wrpll_params wrpll_params = {};
1815 int ret;
1816
1817 ret = skl_ddi_calculate_wrpll(clock: crtc_state->port_clock,
1818 ref_clock: display->dpll.ref_clks.nssc, wrpll_params: &wrpll_params);
1819 if (ret)
1820 return ret;
1821
1822 /*
1823 * See comment in intel_dpll_hw_state to understand why we always use 0
1824 * as the DPLL id in this function.
1825 */
1826 hw_state->ctrl1 =
1827 DPLL_CTRL1_OVERRIDE(0) |
1828 DPLL_CTRL1_HDMI_MODE(0);
1829
1830 hw_state->cfgcr1 =
1831 DPLL_CFGCR1_FREQ_ENABLE |
1832 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1833 wrpll_params.dco_integer;
1834
1835 hw_state->cfgcr2 =
1836 DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1837 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1838 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1839 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1840 wrpll_params.central_freq;
1841
1842 crtc_state->port_clock = skl_ddi_wrpll_get_freq(display, NULL,
1843 dpll_hw_state: &crtc_state->dpll_hw_state);
1844
1845 return 0;
1846}
1847
1848static int
1849skl_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
1850{
1851 struct skl_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.skl;
1852 u32 ctrl1;
1853
1854 /*
1855 * See comment in intel_dpll_hw_state to understand why we always use 0
1856 * as the DPLL id in this function.
1857 */
1858 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1859 switch (crtc_state->port_clock / 2) {
1860 case 81000:
1861 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
1862 break;
1863 case 135000:
1864 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
1865 break;
1866 case 270000:
1867 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
1868 break;
1869 /* eDP 1.4 rates */
1870 case 162000:
1871 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
1872 break;
1873 case 108000:
1874 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, 0);
1875 break;
1876 case 216000:
1877 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, 0);
1878 break;
1879 }
1880
1881 hw_state->ctrl1 = ctrl1;
1882
1883 return 0;
1884}
1885
1886static int skl_ddi_lcpll_get_freq(struct intel_display *display,
1887 const struct intel_dpll *pll,
1888 const struct intel_dpll_hw_state *dpll_hw_state)
1889{
1890 const struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl;
1891 int link_clock = 0;
1892
1893 switch ((hw_state->ctrl1 & DPLL_CTRL1_LINK_RATE_MASK(0)) >>
1894 DPLL_CTRL1_LINK_RATE_SHIFT(0)) {
1895 case DPLL_CTRL1_LINK_RATE_810:
1896 link_clock = 81000;
1897 break;
1898 case DPLL_CTRL1_LINK_RATE_1080:
1899 link_clock = 108000;
1900 break;
1901 case DPLL_CTRL1_LINK_RATE_1350:
1902 link_clock = 135000;
1903 break;
1904 case DPLL_CTRL1_LINK_RATE_1620:
1905 link_clock = 162000;
1906 break;
1907 case DPLL_CTRL1_LINK_RATE_2160:
1908 link_clock = 216000;
1909 break;
1910 case DPLL_CTRL1_LINK_RATE_2700:
1911 link_clock = 270000;
1912 break;
1913 default:
1914 drm_WARN(display->drm, 1, "Unsupported link rate\n");
1915 break;
1916 }
1917
1918 return link_clock * 2;
1919}
1920
1921static int skl_compute_dpll(struct intel_atomic_state *state,
1922 struct intel_crtc *crtc,
1923 struct intel_encoder *encoder)
1924{
1925 struct intel_crtc_state *crtc_state =
1926 intel_atomic_get_new_crtc_state(state, crtc);
1927
1928 if (intel_crtc_has_type(crtc_state, type: INTEL_OUTPUT_HDMI))
1929 return skl_ddi_hdmi_pll_dividers(crtc_state);
1930 else if (intel_crtc_has_dp_encoder(crtc_state))
1931 return skl_ddi_dp_set_dpll_hw_state(crtc_state);
1932 else
1933 return -EINVAL;
1934}
1935
1936static int skl_get_dpll(struct intel_atomic_state *state,
1937 struct intel_crtc *crtc,
1938 struct intel_encoder *encoder)
1939{
1940 struct intel_crtc_state *crtc_state =
1941 intel_atomic_get_new_crtc_state(state, crtc);
1942 struct intel_dpll *pll;
1943
1944 if (intel_crtc_has_type(crtc_state, type: INTEL_OUTPUT_EDP))
1945 pll = intel_find_dpll(state, crtc,
1946 dpll_hw_state: &crtc_state->dpll_hw_state,
1947 BIT(DPLL_ID_SKL_DPLL0));
1948 else
1949 pll = intel_find_dpll(state, crtc,
1950 dpll_hw_state: &crtc_state->dpll_hw_state,
1951 BIT(DPLL_ID_SKL_DPLL3) |
1952 BIT(DPLL_ID_SKL_DPLL2) |
1953 BIT(DPLL_ID_SKL_DPLL1));
1954 if (!pll)
1955 return -EINVAL;
1956
1957 intel_reference_dpll(state, crtc,
1958 pll, dpll_hw_state: &crtc_state->dpll_hw_state);
1959
1960 crtc_state->intel_dpll = pll;
1961
1962 return 0;
1963}
1964
1965static int skl_ddi_pll_get_freq(struct intel_display *display,
1966 const struct intel_dpll *pll,
1967 const struct intel_dpll_hw_state *dpll_hw_state)
1968{
1969 const struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl;
1970
1971 /*
1972 * ctrl1 register is already shifted for each pll, just use 0 to get
1973 * the internal shift for each field
1974 */
1975 if (hw_state->ctrl1 & DPLL_CTRL1_HDMI_MODE(0))
1976 return skl_ddi_wrpll_get_freq(display, pll, dpll_hw_state);
1977 else
1978 return skl_ddi_lcpll_get_freq(display, pll, dpll_hw_state);
1979}
1980
1981static void skl_update_dpll_ref_clks(struct intel_display *display)
1982{
1983 /* No SSC ref */
1984 display->dpll.ref_clks.nssc = display->cdclk.hw.ref;
1985}
1986
1987static void skl_dump_hw_state(struct drm_printer *p,
1988 const struct intel_dpll_hw_state *dpll_hw_state)
1989{
1990 const struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl;
1991
1992 drm_printf(p, f: "dpll_hw_state: ctrl1: 0x%x, cfgcr1: 0x%x, cfgcr2: 0x%x\n",
1993 hw_state->ctrl1, hw_state->cfgcr1, hw_state->cfgcr2);
1994}
1995
1996static bool skl_compare_hw_state(const struct intel_dpll_hw_state *_a,
1997 const struct intel_dpll_hw_state *_b)
1998{
1999 const struct skl_dpll_hw_state *a = &_a->skl;
2000 const struct skl_dpll_hw_state *b = &_b->skl;
2001
2002 return a->ctrl1 == b->ctrl1 &&
2003 a->cfgcr1 == b->cfgcr1 &&
2004 a->cfgcr2 == b->cfgcr2;
2005}
2006
2007static const struct intel_dpll_funcs skl_ddi_pll_funcs = {
2008 .enable = skl_ddi_pll_enable,
2009 .disable = skl_ddi_pll_disable,
2010 .get_hw_state = skl_ddi_pll_get_hw_state,
2011 .get_freq = skl_ddi_pll_get_freq,
2012};
2013
2014static const struct intel_dpll_funcs skl_ddi_dpll0_funcs = {
2015 .enable = skl_ddi_dpll0_enable,
2016 .disable = skl_ddi_dpll0_disable,
2017 .get_hw_state = skl_ddi_dpll0_get_hw_state,
2018 .get_freq = skl_ddi_pll_get_freq,
2019};
2020
2021static const struct dpll_info skl_plls[] = {
2022 { .name = "DPLL 0", .funcs = &skl_ddi_dpll0_funcs, .id = DPLL_ID_SKL_DPLL0,
2023 .always_on = true, },
2024 { .name = "DPLL 1", .funcs = &skl_ddi_pll_funcs, .id = DPLL_ID_SKL_DPLL1, },
2025 { .name = "DPLL 2", .funcs = &skl_ddi_pll_funcs, .id = DPLL_ID_SKL_DPLL2, },
2026 { .name = "DPLL 3", .funcs = &skl_ddi_pll_funcs, .id = DPLL_ID_SKL_DPLL3, },
2027 {}
2028};
2029
2030static const struct intel_dpll_mgr skl_pll_mgr = {
2031 .dpll_info = skl_plls,
2032 .compute_dplls = skl_compute_dpll,
2033 .get_dplls = skl_get_dpll,
2034 .put_dplls = intel_put_dpll,
2035 .update_ref_clks = skl_update_dpll_ref_clks,
2036 .dump_hw_state = skl_dump_hw_state,
2037 .compare_hw_state = skl_compare_hw_state,
2038};
2039
2040static void bxt_ddi_pll_enable(struct intel_display *display,
2041 struct intel_dpll *pll,
2042 const struct intel_dpll_hw_state *dpll_hw_state)
2043{
2044 const struct bxt_dpll_hw_state *hw_state = &dpll_hw_state->bxt;
2045 enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */
2046 enum dpio_phy phy = DPIO_PHY0;
2047 enum dpio_channel ch = DPIO_CH0;
2048 u32 temp;
2049 int ret;
2050
2051 bxt_port_to_phy_channel(display, port, phy: &phy, ch: &ch);
2052
2053 /* Non-SSC reference */
2054 intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port), clear: 0, PORT_PLL_REF_SEL);
2055
2056 if (display->platform.geminilake) {
2057 intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port),
2058 clear: 0, PORT_PLL_POWER_ENABLE);
2059
2060 ret = intel_de_wait_for_set_us(display,
2061 BXT_PORT_PLL_ENABLE(port),
2062 PORT_PLL_POWER_STATE, timeout_us: 200);
2063 if (ret)
2064 drm_err(display->drm,
2065 "Power state not set for PLL:%d\n", port);
2066 }
2067
2068 /* Disable 10 bit clock */
2069 intel_de_rmw(display, BXT_PORT_PLL_EBB_4(phy, ch),
2070 PORT_PLL_10BIT_CLK_ENABLE, set: 0);
2071
2072 /* Write P1 & P2 */
2073 intel_de_rmw(display, BXT_PORT_PLL_EBB_0(phy, ch),
2074 PORT_PLL_P1_MASK | PORT_PLL_P2_MASK, set: hw_state->ebb0);
2075
2076 /* Write M2 integer */
2077 intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 0),
2078 PORT_PLL_M2_INT_MASK, set: hw_state->pll0);
2079
2080 /* Write N */
2081 intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 1),
2082 PORT_PLL_N_MASK, set: hw_state->pll1);
2083
2084 /* Write M2 fraction */
2085 intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 2),
2086 PORT_PLL_M2_FRAC_MASK, set: hw_state->pll2);
2087
2088 /* Write M2 fraction enable */
2089 intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 3),
2090 PORT_PLL_M2_FRAC_ENABLE, set: hw_state->pll3);
2091
2092 /* Write coeff */
2093 temp = intel_de_read(display, BXT_PORT_PLL(phy, ch, 6));
2094 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2095 temp &= ~PORT_PLL_INT_COEFF_MASK;
2096 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2097 temp |= hw_state->pll6;
2098 intel_de_write(display, BXT_PORT_PLL(phy, ch, 6), val: temp);
2099
2100 /* Write calibration val */
2101 intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 8),
2102 PORT_PLL_TARGET_CNT_MASK, set: hw_state->pll8);
2103
2104 intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 9),
2105 PORT_PLL_LOCK_THRESHOLD_MASK, set: hw_state->pll9);
2106
2107 temp = intel_de_read(display, BXT_PORT_PLL(phy, ch, 10));
2108 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2109 temp &= ~PORT_PLL_DCO_AMP_MASK;
2110 temp |= hw_state->pll10;
2111 intel_de_write(display, BXT_PORT_PLL(phy, ch, 10), val: temp);
2112
2113 /* Recalibrate with new settings */
2114 temp = intel_de_read(display, BXT_PORT_PLL_EBB_4(phy, ch));
2115 temp |= PORT_PLL_RECALIBRATE;
2116 intel_de_write(display, BXT_PORT_PLL_EBB_4(phy, ch), val: temp);
2117 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2118 temp |= hw_state->ebb4;
2119 intel_de_write(display, BXT_PORT_PLL_EBB_4(phy, ch), val: temp);
2120
2121 /* Enable PLL */
2122 intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port), clear: 0, PORT_PLL_ENABLE);
2123 intel_de_posting_read(display, BXT_PORT_PLL_ENABLE(port));
2124
2125 ret = intel_de_wait_for_set_us(display, BXT_PORT_PLL_ENABLE(port),
2126 PORT_PLL_LOCK, timeout_us: 200);
2127 if (ret)
2128 drm_err(display->drm, "PLL %d not locked\n", port);
2129
2130 if (display->platform.geminilake) {
2131 temp = intel_de_read(display, BXT_PORT_TX_DW5_LN(phy, ch, 0));
2132 temp |= DCC_DELAY_RANGE_2;
2133 intel_de_write(display, BXT_PORT_TX_DW5_GRP(phy, ch), val: temp);
2134 }
2135
2136 /*
2137 * While we write to the group register to program all lanes at once we
2138 * can read only lane registers and we pick lanes 0/1 for that.
2139 */
2140 temp = intel_de_read(display, BXT_PORT_PCS_DW12_LN01(phy, ch));
2141 temp &= ~LANE_STAGGER_MASK;
2142 temp &= ~LANESTAGGER_STRAP_OVRD;
2143 temp |= hw_state->pcsdw12;
2144 intel_de_write(display, BXT_PORT_PCS_DW12_GRP(phy, ch), val: temp);
2145}
2146
2147static void bxt_ddi_pll_disable(struct intel_display *display,
2148 struct intel_dpll *pll)
2149{
2150 enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */
2151 int ret;
2152
2153 intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port), PORT_PLL_ENABLE, set: 0);
2154 intel_de_posting_read(display, BXT_PORT_PLL_ENABLE(port));
2155
2156 if (display->platform.geminilake) {
2157 intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port),
2158 PORT_PLL_POWER_ENABLE, set: 0);
2159
2160 ret = intel_de_wait_for_clear_us(display,
2161 BXT_PORT_PLL_ENABLE(port),
2162 PORT_PLL_POWER_STATE, timeout_us: 200);
2163 if (ret)
2164 drm_err(display->drm,
2165 "Power state not reset for PLL:%d\n", port);
2166 }
2167}
2168
2169static bool bxt_ddi_pll_get_hw_state(struct intel_display *display,
2170 struct intel_dpll *pll,
2171 struct intel_dpll_hw_state *dpll_hw_state)
2172{
2173 struct bxt_dpll_hw_state *hw_state = &dpll_hw_state->bxt;
2174 enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */
2175 intel_wakeref_t wakeref;
2176 enum dpio_phy phy;
2177 enum dpio_channel ch;
2178 u32 val;
2179 bool ret;
2180
2181 bxt_port_to_phy_channel(display, port, phy: &phy, ch: &ch);
2182
2183 wakeref = intel_display_power_get_if_enabled(display,
2184 domain: POWER_DOMAIN_DISPLAY_CORE);
2185 if (!wakeref)
2186 return false;
2187
2188 ret = false;
2189
2190 val = intel_de_read(display, BXT_PORT_PLL_ENABLE(port));
2191 if (!(val & PORT_PLL_ENABLE))
2192 goto out;
2193
2194 hw_state->ebb0 = intel_de_read(display, BXT_PORT_PLL_EBB_0(phy, ch));
2195 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2196
2197 hw_state->ebb4 = intel_de_read(display, BXT_PORT_PLL_EBB_4(phy, ch));
2198 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2199
2200 hw_state->pll0 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 0));
2201 hw_state->pll0 &= PORT_PLL_M2_INT_MASK;
2202
2203 hw_state->pll1 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 1));
2204 hw_state->pll1 &= PORT_PLL_N_MASK;
2205
2206 hw_state->pll2 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 2));
2207 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2208
2209 hw_state->pll3 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 3));
2210 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2211
2212 hw_state->pll6 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 6));
2213 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2214 PORT_PLL_INT_COEFF_MASK |
2215 PORT_PLL_GAIN_CTL_MASK;
2216
2217 hw_state->pll8 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 8));
2218 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2219
2220 hw_state->pll9 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 9));
2221 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2222
2223 hw_state->pll10 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 10));
2224 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2225 PORT_PLL_DCO_AMP_MASK;
2226
2227 /*
2228 * While we write to the group register to program all lanes at once we
2229 * can read only lane registers. We configure all lanes the same way, so
2230 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2231 */
2232 hw_state->pcsdw12 = intel_de_read(display,
2233 BXT_PORT_PCS_DW12_LN01(phy, ch));
2234 if (intel_de_read(display, BXT_PORT_PCS_DW12_LN23(phy, ch)) != hw_state->pcsdw12)
2235 drm_dbg(display->drm,
2236 "lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2237 hw_state->pcsdw12,
2238 intel_de_read(display,
2239 BXT_PORT_PCS_DW12_LN23(phy, ch)));
2240 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
2241
2242 ret = true;
2243
2244out:
2245 intel_display_power_put(display, domain: POWER_DOMAIN_DISPLAY_CORE, wakeref);
2246
2247 return ret;
2248}
2249
2250/* pre-calculated values for DP linkrates */
2251static const struct dpll bxt_dp_clk_val[] = {
2252 /* m2 is .22 binary fixed point */
2253 { .dot = 162000, .p1 = 4, .p2 = 2, .n = 1, .m1 = 2, .m2 = 0x819999a /* 32.4 */ },
2254 { .dot = 270000, .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 /* 27.0 */ },
2255 { .dot = 540000, .p1 = 2, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 /* 27.0 */ },
2256 { .dot = 216000, .p1 = 3, .p2 = 2, .n = 1, .m1 = 2, .m2 = 0x819999a /* 32.4 */ },
2257 { .dot = 243000, .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6133333 /* 24.3 */ },
2258 { .dot = 324000, .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x819999a /* 32.4 */ },
2259 { .dot = 432000, .p1 = 3, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x819999a /* 32.4 */ },
2260};
2261
2262static int
2263bxt_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state,
2264 struct dpll *clk_div)
2265{
2266 struct intel_display *display = to_intel_display(crtc_state);
2267
2268 /* Calculate HDMI div */
2269 /*
2270 * FIXME: tie the following calculation into
2271 * i9xx_crtc_compute_clock
2272 */
2273 if (!bxt_find_best_dpll(crtc_state, best_clock: clk_div))
2274 return -EINVAL;
2275
2276 drm_WARN_ON(display->drm, clk_div->m1 != 2);
2277
2278 return 0;
2279}
2280
2281static void bxt_ddi_dp_pll_dividers(struct intel_crtc_state *crtc_state,
2282 struct dpll *clk_div)
2283{
2284 struct intel_display *display = to_intel_display(crtc_state);
2285 int i;
2286
2287 *clk_div = bxt_dp_clk_val[0];
2288 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
2289 if (crtc_state->port_clock == bxt_dp_clk_val[i].dot) {
2290 *clk_div = bxt_dp_clk_val[i];
2291 break;
2292 }
2293 }
2294
2295 chv_calc_dpll_params(refclk: display->dpll.ref_clks.nssc, pll_clock: clk_div);
2296
2297 drm_WARN_ON(display->drm, clk_div->vco == 0 ||
2298 clk_div->dot != crtc_state->port_clock);
2299}
2300
2301static int bxt_ddi_set_dpll_hw_state(struct intel_crtc_state *crtc_state,
2302 const struct dpll *clk_div)
2303{
2304 struct intel_display *display = to_intel_display(crtc_state);
2305 struct bxt_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.bxt;
2306 int clock = crtc_state->port_clock;
2307 int vco = clk_div->vco;
2308 u32 prop_coef, int_coef, gain_ctl, targ_cnt;
2309 u32 lanestagger;
2310
2311 if (vco >= 6200000 && vco <= 6700000) {
2312 prop_coef = 4;
2313 int_coef = 9;
2314 gain_ctl = 3;
2315 targ_cnt = 8;
2316 } else if ((vco > 5400000 && vco < 6200000) ||
2317 (vco >= 4800000 && vco < 5400000)) {
2318 prop_coef = 5;
2319 int_coef = 11;
2320 gain_ctl = 3;
2321 targ_cnt = 9;
2322 } else if (vco == 5400000) {
2323 prop_coef = 3;
2324 int_coef = 8;
2325 gain_ctl = 1;
2326 targ_cnt = 9;
2327 } else {
2328 drm_err(display->drm, "Invalid VCO\n");
2329 return -EINVAL;
2330 }
2331
2332 if (clock > 270000)
2333 lanestagger = 0x18;
2334 else if (clock > 135000)
2335 lanestagger = 0x0d;
2336 else if (clock > 67000)
2337 lanestagger = 0x07;
2338 else if (clock > 33000)
2339 lanestagger = 0x04;
2340 else
2341 lanestagger = 0x02;
2342
2343 hw_state->ebb0 = PORT_PLL_P1(clk_div->p1) | PORT_PLL_P2(clk_div->p2);
2344 hw_state->pll0 = PORT_PLL_M2_INT(clk_div->m2 >> 22);
2345 hw_state->pll1 = PORT_PLL_N(clk_div->n);
2346 hw_state->pll2 = PORT_PLL_M2_FRAC(clk_div->m2 & 0x3fffff);
2347
2348 if (clk_div->m2 & 0x3fffff)
2349 hw_state->pll3 = PORT_PLL_M2_FRAC_ENABLE;
2350
2351 hw_state->pll6 = PORT_PLL_PROP_COEFF(prop_coef) |
2352 PORT_PLL_INT_COEFF(int_coef) |
2353 PORT_PLL_GAIN_CTL(gain_ctl);
2354
2355 hw_state->pll8 = PORT_PLL_TARGET_CNT(targ_cnt);
2356
2357 hw_state->pll9 = PORT_PLL_LOCK_THRESHOLD(5);
2358
2359 hw_state->pll10 = PORT_PLL_DCO_AMP(15) |
2360 PORT_PLL_DCO_AMP_OVR_EN_H;
2361
2362 hw_state->ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
2363
2364 hw_state->pcsdw12 = LANESTAGGER_STRAP_OVRD | lanestagger;
2365
2366 return 0;
2367}
2368
2369static int bxt_ddi_pll_get_freq(struct intel_display *display,
2370 const struct intel_dpll *pll,
2371 const struct intel_dpll_hw_state *dpll_hw_state)
2372{
2373 const struct bxt_dpll_hw_state *hw_state = &dpll_hw_state->bxt;
2374 struct dpll clock;
2375
2376 clock.m1 = 2;
2377 clock.m2 = REG_FIELD_GET(PORT_PLL_M2_INT_MASK, hw_state->pll0) << 22;
2378 if (hw_state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
2379 clock.m2 |= REG_FIELD_GET(PORT_PLL_M2_FRAC_MASK,
2380 hw_state->pll2);
2381 clock.n = REG_FIELD_GET(PORT_PLL_N_MASK, hw_state->pll1);
2382 clock.p1 = REG_FIELD_GET(PORT_PLL_P1_MASK, hw_state->ebb0);
2383 clock.p2 = REG_FIELD_GET(PORT_PLL_P2_MASK, hw_state->ebb0);
2384
2385 return chv_calc_dpll_params(refclk: display->dpll.ref_clks.nssc, pll_clock: &clock);
2386}
2387
2388static int
2389bxt_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
2390{
2391 struct dpll clk_div = {};
2392
2393 bxt_ddi_dp_pll_dividers(crtc_state, clk_div: &clk_div);
2394
2395 return bxt_ddi_set_dpll_hw_state(crtc_state, clk_div: &clk_div);
2396}
2397
2398static int
2399bxt_ddi_hdmi_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
2400{
2401 struct intel_display *display = to_intel_display(crtc_state);
2402 struct dpll clk_div = {};
2403 int ret;
2404
2405 bxt_ddi_hdmi_pll_dividers(crtc_state, clk_div: &clk_div);
2406
2407 ret = bxt_ddi_set_dpll_hw_state(crtc_state, clk_div: &clk_div);
2408 if (ret)
2409 return ret;
2410
2411 crtc_state->port_clock = bxt_ddi_pll_get_freq(display, NULL,
2412 dpll_hw_state: &crtc_state->dpll_hw_state);
2413
2414 return 0;
2415}
2416
2417static int bxt_compute_dpll(struct intel_atomic_state *state,
2418 struct intel_crtc *crtc,
2419 struct intel_encoder *encoder)
2420{
2421 struct intel_crtc_state *crtc_state =
2422 intel_atomic_get_new_crtc_state(state, crtc);
2423
2424 if (intel_crtc_has_type(crtc_state, type: INTEL_OUTPUT_HDMI))
2425 return bxt_ddi_hdmi_set_dpll_hw_state(crtc_state);
2426 else if (intel_crtc_has_dp_encoder(crtc_state))
2427 return bxt_ddi_dp_set_dpll_hw_state(crtc_state);
2428 else
2429 return -EINVAL;
2430}
2431
2432static int bxt_get_dpll(struct intel_atomic_state *state,
2433 struct intel_crtc *crtc,
2434 struct intel_encoder *encoder)
2435{
2436 struct intel_display *display = to_intel_display(state);
2437 struct intel_crtc_state *crtc_state =
2438 intel_atomic_get_new_crtc_state(state, crtc);
2439 struct intel_dpll *pll;
2440 enum intel_dpll_id id;
2441
2442 /* 1:1 mapping between ports and PLLs */
2443 id = (enum intel_dpll_id) encoder->port;
2444 pll = intel_get_dpll_by_id(display, id);
2445
2446 drm_dbg_kms(display->drm, "[CRTC:%d:%s] using pre-allocated %s\n",
2447 crtc->base.base.id, crtc->base.name, pll->info->name);
2448
2449 intel_reference_dpll(state, crtc,
2450 pll, dpll_hw_state: &crtc_state->dpll_hw_state);
2451
2452 crtc_state->intel_dpll = pll;
2453
2454 return 0;
2455}
2456
2457static void bxt_update_dpll_ref_clks(struct intel_display *display)
2458{
2459 display->dpll.ref_clks.ssc = 100000;
2460 display->dpll.ref_clks.nssc = 100000;
2461 /* DSI non-SSC ref 19.2MHz */
2462}
2463
2464static void bxt_dump_hw_state(struct drm_printer *p,
2465 const struct intel_dpll_hw_state *dpll_hw_state)
2466{
2467 const struct bxt_dpll_hw_state *hw_state = &dpll_hw_state->bxt;
2468
2469 drm_printf(p, f: "dpll_hw_state: ebb0: 0x%x, ebb4: 0x%x,"
2470 "pll0: 0x%x, pll1: 0x%x, pll2: 0x%x, pll3: 0x%x, "
2471 "pll6: 0x%x, pll8: 0x%x, pll9: 0x%x, pll10: 0x%x, pcsdw12: 0x%x\n",
2472 hw_state->ebb0, hw_state->ebb4,
2473 hw_state->pll0, hw_state->pll1, hw_state->pll2, hw_state->pll3,
2474 hw_state->pll6, hw_state->pll8, hw_state->pll9, hw_state->pll10,
2475 hw_state->pcsdw12);
2476}
2477
2478static bool bxt_compare_hw_state(const struct intel_dpll_hw_state *_a,
2479 const struct intel_dpll_hw_state *_b)
2480{
2481 const struct bxt_dpll_hw_state *a = &_a->bxt;
2482 const struct bxt_dpll_hw_state *b = &_b->bxt;
2483
2484 return a->ebb0 == b->ebb0 &&
2485 a->ebb4 == b->ebb4 &&
2486 a->pll0 == b->pll0 &&
2487 a->pll1 == b->pll1 &&
2488 a->pll2 == b->pll2 &&
2489 a->pll3 == b->pll3 &&
2490 a->pll6 == b->pll6 &&
2491 a->pll8 == b->pll8 &&
2492 a->pll10 == b->pll10 &&
2493 a->pcsdw12 == b->pcsdw12;
2494}
2495
2496static const struct intel_dpll_funcs bxt_ddi_pll_funcs = {
2497 .enable = bxt_ddi_pll_enable,
2498 .disable = bxt_ddi_pll_disable,
2499 .get_hw_state = bxt_ddi_pll_get_hw_state,
2500 .get_freq = bxt_ddi_pll_get_freq,
2501};
2502
2503static const struct dpll_info bxt_plls[] = {
2504 { .name = "PORT PLL A", .funcs = &bxt_ddi_pll_funcs, .id = DPLL_ID_SKL_DPLL0, },
2505 { .name = "PORT PLL B", .funcs = &bxt_ddi_pll_funcs, .id = DPLL_ID_SKL_DPLL1, },
2506 { .name = "PORT PLL C", .funcs = &bxt_ddi_pll_funcs, .id = DPLL_ID_SKL_DPLL2, },
2507 {}
2508};
2509
2510static const struct intel_dpll_mgr bxt_pll_mgr = {
2511 .dpll_info = bxt_plls,
2512 .compute_dplls = bxt_compute_dpll,
2513 .get_dplls = bxt_get_dpll,
2514 .put_dplls = intel_put_dpll,
2515 .update_ref_clks = bxt_update_dpll_ref_clks,
2516 .dump_hw_state = bxt_dump_hw_state,
2517 .compare_hw_state = bxt_compare_hw_state,
2518};
2519
2520static void icl_wrpll_get_multipliers(int bestdiv, int *pdiv,
2521 int *qdiv, int *kdiv)
2522{
2523 /* even dividers */
2524 if (bestdiv % 2 == 0) {
2525 if (bestdiv == 2) {
2526 *pdiv = 2;
2527 *qdiv = 1;
2528 *kdiv = 1;
2529 } else if (bestdiv % 4 == 0) {
2530 *pdiv = 2;
2531 *qdiv = bestdiv / 4;
2532 *kdiv = 2;
2533 } else if (bestdiv % 6 == 0) {
2534 *pdiv = 3;
2535 *qdiv = bestdiv / 6;
2536 *kdiv = 2;
2537 } else if (bestdiv % 5 == 0) {
2538 *pdiv = 5;
2539 *qdiv = bestdiv / 10;
2540 *kdiv = 2;
2541 } else if (bestdiv % 14 == 0) {
2542 *pdiv = 7;
2543 *qdiv = bestdiv / 14;
2544 *kdiv = 2;
2545 }
2546 } else {
2547 if (bestdiv == 3 || bestdiv == 5 || bestdiv == 7) {
2548 *pdiv = bestdiv;
2549 *qdiv = 1;
2550 *kdiv = 1;
2551 } else { /* 9, 15, 21 */
2552 *pdiv = bestdiv / 3;
2553 *qdiv = 1;
2554 *kdiv = 3;
2555 }
2556 }
2557}
2558
2559static void icl_wrpll_params_populate(struct skl_wrpll_params *params,
2560 u32 dco_freq, u32 ref_freq,
2561 int pdiv, int qdiv, int kdiv)
2562{
2563 u32 dco;
2564
2565 switch (kdiv) {
2566 case 1:
2567 params->kdiv = 1;
2568 break;
2569 case 2:
2570 params->kdiv = 2;
2571 break;
2572 case 3:
2573 params->kdiv = 4;
2574 break;
2575 default:
2576 WARN(1, "Incorrect KDiv\n");
2577 }
2578
2579 switch (pdiv) {
2580 case 2:
2581 params->pdiv = 1;
2582 break;
2583 case 3:
2584 params->pdiv = 2;
2585 break;
2586 case 5:
2587 params->pdiv = 4;
2588 break;
2589 case 7:
2590 params->pdiv = 8;
2591 break;
2592 default:
2593 WARN(1, "Incorrect PDiv\n");
2594 }
2595
2596 WARN_ON(kdiv != 2 && qdiv != 1);
2597
2598 params->qdiv_ratio = qdiv;
2599 params->qdiv_mode = (qdiv == 1) ? 0 : 1;
2600
2601 dco = div_u64(dividend: (u64)dco_freq << 15, divisor: ref_freq);
2602
2603 params->dco_integer = dco >> 15;
2604 params->dco_fraction = dco & 0x7fff;
2605}
2606
2607/*
2608 * Display WA #22010492432: ehl, tgl, adl-s, adl-p
2609 * Program half of the nominal DCO divider fraction value.
2610 */
2611static bool
2612ehl_combo_pll_div_frac_wa_needed(struct intel_display *display)
2613{
2614 return ((display->platform.elkhartlake &&
2615 IS_DISPLAY_STEP(display, STEP_B0, STEP_FOREVER)) ||
2616 DISPLAY_VER(display) >= 12) &&
2617 display->dpll.ref_clks.nssc == 38400;
2618}
2619
2620struct icl_combo_pll_params {
2621 int clock;
2622 struct skl_wrpll_params wrpll;
2623};
2624
2625/*
2626 * These values alrea already adjusted: they're the bits we write to the
2627 * registers, not the logical values.
2628 */
2629static const struct icl_combo_pll_params icl_dp_combo_pll_24MHz_values[] = {
2630 { 540000,
2631 { .dco_integer = 0x151, .dco_fraction = 0x4000, /* [0]: 5.4 */
2632 .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
2633 { 270000,
2634 { .dco_integer = 0x151, .dco_fraction = 0x4000, /* [1]: 2.7 */
2635 .pdiv = 0x2 /* 3 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
2636 { 162000,
2637 { .dco_integer = 0x151, .dco_fraction = 0x4000, /* [2]: 1.62 */
2638 .pdiv = 0x4 /* 5 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
2639 { 324000,
2640 { .dco_integer = 0x151, .dco_fraction = 0x4000, /* [3]: 3.24 */
2641 .pdiv = 0x4 /* 5 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
2642 { 216000,
2643 { .dco_integer = 0x168, .dco_fraction = 0x0000, /* [4]: 2.16 */
2644 .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 1, .qdiv_ratio = 2, }, },
2645 { 432000,
2646 { .dco_integer = 0x168, .dco_fraction = 0x0000, /* [5]: 4.32 */
2647 .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
2648 { 648000,
2649 { .dco_integer = 0x195, .dco_fraction = 0x0000, /* [6]: 6.48 */
2650 .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
2651 { 810000,
2652 { .dco_integer = 0x151, .dco_fraction = 0x4000, /* [7]: 8.1 */
2653 .pdiv = 0x1 /* 2 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
2654};
2655
2656
2657/* Also used for 38.4 MHz values. */
2658static const struct icl_combo_pll_params icl_dp_combo_pll_19_2MHz_values[] = {
2659 { 540000,
2660 { .dco_integer = 0x1A5, .dco_fraction = 0x7000, /* [0]: 5.4 */
2661 .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
2662 { 270000,
2663 { .dco_integer = 0x1A5, .dco_fraction = 0x7000, /* [1]: 2.7 */
2664 .pdiv = 0x2 /* 3 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
2665 { 162000,
2666 { .dco_integer = 0x1A5, .dco_fraction = 0x7000, /* [2]: 1.62 */
2667 .pdiv = 0x4 /* 5 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
2668 { 324000,
2669 { .dco_integer = 0x1A5, .dco_fraction = 0x7000, /* [3]: 3.24 */
2670 .pdiv = 0x4 /* 5 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
2671 { 216000,
2672 { .dco_integer = 0x1C2, .dco_fraction = 0x0000, /* [4]: 2.16 */
2673 .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 1, .qdiv_ratio = 2, }, },
2674 { 432000,
2675 { .dco_integer = 0x1C2, .dco_fraction = 0x0000, /* [5]: 4.32 */
2676 .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
2677 { 648000,
2678 { .dco_integer = 0x1FA, .dco_fraction = 0x2000, /* [6]: 6.48 */
2679 .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
2680 { 810000,
2681 { .dco_integer = 0x1A5, .dco_fraction = 0x7000, /* [7]: 8.1 */
2682 .pdiv = 0x1 /* 2 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
2683};
2684
2685static const struct skl_wrpll_params icl_tbt_pll_24MHz_values = {
2686 .dco_integer = 0x151, .dco_fraction = 0x4000,
2687 .pdiv = 0x4 /* 5 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0,
2688};
2689
2690static const struct skl_wrpll_params icl_tbt_pll_19_2MHz_values = {
2691 .dco_integer = 0x1A5, .dco_fraction = 0x7000,
2692 .pdiv = 0x4 /* 5 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0,
2693};
2694
2695static const struct skl_wrpll_params tgl_tbt_pll_19_2MHz_values = {
2696 .dco_integer = 0x54, .dco_fraction = 0x3000,
2697 /* the following params are unused */
2698 .pdiv = 0, .kdiv = 0, .qdiv_mode = 0, .qdiv_ratio = 0,
2699};
2700
2701static const struct skl_wrpll_params tgl_tbt_pll_24MHz_values = {
2702 .dco_integer = 0x43, .dco_fraction = 0x4000,
2703 /* the following params are unused */
2704};
2705
2706static int icl_calc_dp_combo_pll(struct intel_crtc_state *crtc_state,
2707 struct skl_wrpll_params *pll_params)
2708{
2709 struct intel_display *display = to_intel_display(crtc_state);
2710 const struct icl_combo_pll_params *params =
2711 display->dpll.ref_clks.nssc == 24000 ?
2712 icl_dp_combo_pll_24MHz_values :
2713 icl_dp_combo_pll_19_2MHz_values;
2714 int clock = crtc_state->port_clock;
2715 int i;
2716
2717 for (i = 0; i < ARRAY_SIZE(icl_dp_combo_pll_24MHz_values); i++) {
2718 if (clock == params[i].clock) {
2719 *pll_params = params[i].wrpll;
2720 return 0;
2721 }
2722 }
2723
2724 MISSING_CASE(clock);
2725 return -EINVAL;
2726}
2727
2728static int icl_calc_tbt_pll(struct intel_crtc_state *crtc_state,
2729 struct skl_wrpll_params *pll_params)
2730{
2731 struct intel_display *display = to_intel_display(crtc_state);
2732
2733 if (DISPLAY_VER(display) >= 12) {
2734 switch (display->dpll.ref_clks.nssc) {
2735 default:
2736 MISSING_CASE(display->dpll.ref_clks.nssc);
2737 fallthrough;
2738 case 19200:
2739 case 38400:
2740 *pll_params = tgl_tbt_pll_19_2MHz_values;
2741 break;
2742 case 24000:
2743 *pll_params = tgl_tbt_pll_24MHz_values;
2744 break;
2745 }
2746 } else {
2747 switch (display->dpll.ref_clks.nssc) {
2748 default:
2749 MISSING_CASE(display->dpll.ref_clks.nssc);
2750 fallthrough;
2751 case 19200:
2752 case 38400:
2753 *pll_params = icl_tbt_pll_19_2MHz_values;
2754 break;
2755 case 24000:
2756 *pll_params = icl_tbt_pll_24MHz_values;
2757 break;
2758 }
2759 }
2760
2761 return 0;
2762}
2763
2764static int icl_ddi_tbt_pll_get_freq(struct intel_display *display,
2765 const struct intel_dpll *pll,
2766 const struct intel_dpll_hw_state *dpll_hw_state)
2767{
2768 /*
2769 * The PLL outputs multiple frequencies at the same time, selection is
2770 * made at DDI clock mux level.
2771 */
2772 drm_WARN_ON(display->drm, 1);
2773
2774 return 0;
2775}
2776
2777static int icl_wrpll_ref_clock(struct intel_display *display)
2778{
2779 int ref_clock = display->dpll.ref_clks.nssc;
2780
2781 /*
2782 * For ICL+, the spec states: if reference frequency is 38.4,
2783 * use 19.2 because the DPLL automatically divides that by 2.
2784 */
2785 if (ref_clock == 38400)
2786 ref_clock = 19200;
2787
2788 return ref_clock;
2789}
2790
2791static int
2792icl_calc_wrpll(struct intel_crtc_state *crtc_state,
2793 struct skl_wrpll_params *wrpll_params)
2794{
2795 struct intel_display *display = to_intel_display(crtc_state);
2796 int ref_clock = icl_wrpll_ref_clock(display);
2797 u32 afe_clock = crtc_state->port_clock * 5;
2798 u32 dco_min = 7998000;
2799 u32 dco_max = 10000000;
2800 u32 dco_mid = (dco_min + dco_max) / 2;
2801 static const int dividers[] = { 2, 4, 6, 8, 10, 12, 14, 16,
2802 18, 20, 24, 28, 30, 32, 36, 40,
2803 42, 44, 48, 50, 52, 54, 56, 60,
2804 64, 66, 68, 70, 72, 76, 78, 80,
2805 84, 88, 90, 92, 96, 98, 100, 102,
2806 3, 5, 7, 9, 15, 21 };
2807 u32 dco, best_dco = 0, dco_centrality = 0;
2808 u32 best_dco_centrality = U32_MAX; /* Spec meaning of 999999 MHz */
2809 int d, best_div = 0, pdiv = 0, qdiv = 0, kdiv = 0;
2810
2811 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
2812 dco = afe_clock * dividers[d];
2813
2814 if (dco <= dco_max && dco >= dco_min) {
2815 dco_centrality = abs(dco - dco_mid);
2816
2817 if (dco_centrality < best_dco_centrality) {
2818 best_dco_centrality = dco_centrality;
2819 best_div = dividers[d];
2820 best_dco = dco;
2821 }
2822 }
2823 }
2824
2825 if (best_div == 0)
2826 return -EINVAL;
2827
2828 icl_wrpll_get_multipliers(bestdiv: best_div, pdiv: &pdiv, qdiv: &qdiv, kdiv: &kdiv);
2829 icl_wrpll_params_populate(params: wrpll_params, dco_freq: best_dco, ref_freq: ref_clock,
2830 pdiv, qdiv, kdiv);
2831
2832 return 0;
2833}
2834
2835static int icl_ddi_combo_pll_get_freq(struct intel_display *display,
2836 const struct intel_dpll *pll,
2837 const struct intel_dpll_hw_state *dpll_hw_state)
2838{
2839 const struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
2840 int ref_clock = icl_wrpll_ref_clock(display);
2841 u32 dco_fraction;
2842 u32 p0, p1, p2, dco_freq;
2843
2844 p0 = hw_state->cfgcr1 & DPLL_CFGCR1_PDIV_MASK;
2845 p2 = hw_state->cfgcr1 & DPLL_CFGCR1_KDIV_MASK;
2846
2847 if (hw_state->cfgcr1 & DPLL_CFGCR1_QDIV_MODE(1))
2848 p1 = (hw_state->cfgcr1 & DPLL_CFGCR1_QDIV_RATIO_MASK) >>
2849 DPLL_CFGCR1_QDIV_RATIO_SHIFT;
2850 else
2851 p1 = 1;
2852
2853 switch (p0) {
2854 case DPLL_CFGCR1_PDIV_2:
2855 p0 = 2;
2856 break;
2857 case DPLL_CFGCR1_PDIV_3:
2858 p0 = 3;
2859 break;
2860 case DPLL_CFGCR1_PDIV_5:
2861 p0 = 5;
2862 break;
2863 case DPLL_CFGCR1_PDIV_7:
2864 p0 = 7;
2865 break;
2866 }
2867
2868 switch (p2) {
2869 case DPLL_CFGCR1_KDIV_1:
2870 p2 = 1;
2871 break;
2872 case DPLL_CFGCR1_KDIV_2:
2873 p2 = 2;
2874 break;
2875 case DPLL_CFGCR1_KDIV_3:
2876 p2 = 3;
2877 break;
2878 }
2879
2880 dco_freq = (hw_state->cfgcr0 & DPLL_CFGCR0_DCO_INTEGER_MASK) *
2881 ref_clock;
2882
2883 dco_fraction = (hw_state->cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK) >>
2884 DPLL_CFGCR0_DCO_FRACTION_SHIFT;
2885
2886 if (ehl_combo_pll_div_frac_wa_needed(display))
2887 dco_fraction *= 2;
2888
2889 dco_freq += (dco_fraction * ref_clock) / 0x8000;
2890
2891 if (drm_WARN_ON(display->drm, p0 == 0 || p1 == 0 || p2 == 0))
2892 return 0;
2893
2894 return dco_freq / (p0 * p1 * p2 * 5);
2895}
2896
2897static void icl_calc_dpll_state(struct intel_display *display,
2898 const struct skl_wrpll_params *pll_params,
2899 struct intel_dpll_hw_state *dpll_hw_state)
2900{
2901 struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
2902 u32 dco_fraction = pll_params->dco_fraction;
2903
2904 if (ehl_combo_pll_div_frac_wa_needed(display))
2905 dco_fraction = DIV_ROUND_CLOSEST(dco_fraction, 2);
2906
2907 hw_state->cfgcr0 = DPLL_CFGCR0_DCO_FRACTION(dco_fraction) |
2908 pll_params->dco_integer;
2909
2910 hw_state->cfgcr1 = DPLL_CFGCR1_QDIV_RATIO(pll_params->qdiv_ratio) |
2911 DPLL_CFGCR1_QDIV_MODE(pll_params->qdiv_mode) |
2912 DPLL_CFGCR1_KDIV(pll_params->kdiv) |
2913 DPLL_CFGCR1_PDIV(pll_params->pdiv);
2914
2915 if (DISPLAY_VER(display) >= 12)
2916 hw_state->cfgcr1 |= TGL_DPLL_CFGCR1_CFSELOVRD_NORMAL_XTAL;
2917 else
2918 hw_state->cfgcr1 |= DPLL_CFGCR1_CENTRAL_FREQ_8400;
2919
2920 if (display->vbt.override_afc_startup)
2921 hw_state->div0 = TGL_DPLL0_DIV0_AFC_STARTUP(display->vbt.override_afc_startup_val);
2922}
2923
2924static int icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
2925 u32 *target_dco_khz,
2926 struct icl_dpll_hw_state *hw_state,
2927 bool is_dkl)
2928{
2929 static const u8 div1_vals[] = { 7, 5, 3, 2 };
2930 u32 dco_min_freq, dco_max_freq;
2931 unsigned int i;
2932 int div2;
2933
2934 dco_min_freq = is_dp ? 8100000 : use_ssc ? 8000000 : 7992000;
2935 dco_max_freq = is_dp ? 8100000 : 10000000;
2936
2937 for (i = 0; i < ARRAY_SIZE(div1_vals); i++) {
2938 int div1 = div1_vals[i];
2939
2940 for (div2 = 10; div2 > 0; div2--) {
2941 int dco = div1 * div2 * clock_khz * 5;
2942 int a_divratio, tlinedrv, inputsel;
2943 u32 hsdiv;
2944
2945 if (dco < dco_min_freq || dco > dco_max_freq)
2946 continue;
2947
2948 if (div2 >= 2) {
2949 /*
2950 * Note: a_divratio not matching TGL BSpec
2951 * algorithm but matching hardcoded values and
2952 * working on HW for DP alt-mode at least
2953 */
2954 a_divratio = is_dp ? 10 : 5;
2955 tlinedrv = is_dkl ? 1 : 2;
2956 } else {
2957 a_divratio = 5;
2958 tlinedrv = 0;
2959 }
2960 inputsel = is_dp ? 0 : 1;
2961
2962 switch (div1) {
2963 default:
2964 MISSING_CASE(div1);
2965 fallthrough;
2966 case 2:
2967 hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_2;
2968 break;
2969 case 3:
2970 hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_3;
2971 break;
2972 case 5:
2973 hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_5;
2974 break;
2975 case 7:
2976 hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_7;
2977 break;
2978 }
2979
2980 *target_dco_khz = dco;
2981
2982 hw_state->mg_refclkin_ctl = MG_REFCLKIN_CTL_OD_2_MUX(1);
2983
2984 hw_state->mg_clktop2_coreclkctl1 =
2985 MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(a_divratio);
2986
2987 hw_state->mg_clktop2_hsclkctl =
2988 MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(tlinedrv) |
2989 MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL(inputsel) |
2990 hsdiv |
2991 MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(div2);
2992
2993 return 0;
2994 }
2995 }
2996
2997 return -EINVAL;
2998}
2999
3000/*
3001 * The specification for this function uses real numbers, so the math had to be
3002 * adapted to integer-only calculation, that's why it looks so different.
3003 */
3004static int icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
3005 struct intel_dpll_hw_state *dpll_hw_state)
3006{
3007 struct intel_display *display = to_intel_display(crtc_state);
3008 struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
3009 int refclk_khz = display->dpll.ref_clks.nssc;
3010 int clock = crtc_state->port_clock;
3011 u32 dco_khz, m1div, m2div_int, m2div_rem, m2div_frac;
3012 u32 iref_ndiv, iref_trim, iref_pulse_w;
3013 u32 prop_coeff, int_coeff;
3014 u32 tdc_targetcnt, feedfwgain;
3015 u64 ssc_stepsize, ssc_steplen, ssc_steplog;
3016 u64 tmp;
3017 bool use_ssc = false;
3018 bool is_dp = !intel_crtc_has_type(crtc_state, type: INTEL_OUTPUT_HDMI);
3019 bool is_dkl = DISPLAY_VER(display) >= 12;
3020 int ret;
3021
3022 ret = icl_mg_pll_find_divisors(clock_khz: clock, is_dp, use_ssc, target_dco_khz: &dco_khz,
3023 hw_state, is_dkl);
3024 if (ret)
3025 return ret;
3026
3027 m1div = 2;
3028 m2div_int = dco_khz / (refclk_khz * m1div);
3029 if (m2div_int > 255) {
3030 if (!is_dkl) {
3031 m1div = 4;
3032 m2div_int = dco_khz / (refclk_khz * m1div);
3033 }
3034
3035 if (m2div_int > 255)
3036 return -EINVAL;
3037 }
3038 m2div_rem = dco_khz % (refclk_khz * m1div);
3039
3040 tmp = (u64)m2div_rem * (1 << 22);
3041 do_div(tmp, refclk_khz * m1div);
3042 m2div_frac = tmp;
3043
3044 switch (refclk_khz) {
3045 case 19200:
3046 iref_ndiv = 1;
3047 iref_trim = 28;
3048 iref_pulse_w = 1;
3049 break;
3050 case 24000:
3051 iref_ndiv = 1;
3052 iref_trim = 25;
3053 iref_pulse_w = 2;
3054 break;
3055 case 38400:
3056 iref_ndiv = 2;
3057 iref_trim = 28;
3058 iref_pulse_w = 1;
3059 break;
3060 default:
3061 MISSING_CASE(refclk_khz);
3062 return -EINVAL;
3063 }
3064
3065 /*
3066 * tdc_res = 0.000003
3067 * tdc_targetcnt = int(2 / (tdc_res * 8 * 50 * 1.1) / refclk_mhz + 0.5)
3068 *
3069 * The multiplication by 1000 is due to refclk MHz to KHz conversion. It
3070 * was supposed to be a division, but we rearranged the operations of
3071 * the formula to avoid early divisions so we don't multiply the
3072 * rounding errors.
3073 *
3074 * 0.000003 * 8 * 50 * 1.1 = 0.00132, also known as 132 / 100000, which
3075 * we also rearrange to work with integers.
3076 *
3077 * The 0.5 transformed to 5 results in a multiplication by 10 and the
3078 * last division by 10.
3079 */
3080 tdc_targetcnt = (2 * 1000 * 100000 * 10 / (132 * refclk_khz) + 5) / 10;
3081
3082 /*
3083 * Here we divide dco_khz by 10 in order to allow the dividend to fit in
3084 * 32 bits. That's not a problem since we round the division down
3085 * anyway.
3086 */
3087 feedfwgain = (use_ssc || m2div_rem > 0) ?
3088 m1div * 1000000 * 100 / (dco_khz * 3 / 10) : 0;
3089
3090 if (dco_khz >= 9000000) {
3091 prop_coeff = 5;
3092 int_coeff = 10;
3093 } else {
3094 prop_coeff = 4;
3095 int_coeff = 8;
3096 }
3097
3098 if (use_ssc) {
3099 tmp = mul_u32_u32(a: dco_khz, b: 47 * 32);
3100 do_div(tmp, refclk_khz * m1div * 10000);
3101 ssc_stepsize = tmp;
3102
3103 tmp = mul_u32_u32(a: dco_khz, b: 1000);
3104 ssc_steplen = DIV_ROUND_UP_ULL(tmp, 32 * 2 * 32);
3105 } else {
3106 ssc_stepsize = 0;
3107 ssc_steplen = 0;
3108 }
3109 ssc_steplog = 4;
3110
3111 /* write pll_state calculations */
3112 if (is_dkl) {
3113 hw_state->mg_pll_div0 = DKL_PLL_DIV0_INTEG_COEFF(int_coeff) |
3114 DKL_PLL_DIV0_PROP_COEFF(prop_coeff) |
3115 DKL_PLL_DIV0_FBPREDIV(m1div) |
3116 DKL_PLL_DIV0_FBDIV_INT(m2div_int);
3117 if (display->vbt.override_afc_startup) {
3118 u8 val = display->vbt.override_afc_startup_val;
3119
3120 hw_state->mg_pll_div0 |= DKL_PLL_DIV0_AFC_STARTUP(val);
3121 }
3122
3123 hw_state->mg_pll_div1 = DKL_PLL_DIV1_IREF_TRIM(iref_trim) |
3124 DKL_PLL_DIV1_TDC_TARGET_CNT(tdc_targetcnt);
3125
3126 hw_state->mg_pll_ssc = DKL_PLL_SSC_IREF_NDIV_RATIO(iref_ndiv) |
3127 DKL_PLL_SSC_STEP_LEN(ssc_steplen) |
3128 DKL_PLL_SSC_STEP_NUM(ssc_steplog) |
3129 (use_ssc ? DKL_PLL_SSC_EN : 0);
3130
3131 hw_state->mg_pll_bias = (m2div_frac ? DKL_PLL_BIAS_FRAC_EN_H : 0) |
3132 DKL_PLL_BIAS_FBDIV_FRAC(m2div_frac);
3133
3134 hw_state->mg_pll_tdc_coldst_bias =
3135 DKL_PLL_TDC_SSC_STEP_SIZE(ssc_stepsize) |
3136 DKL_PLL_TDC_FEED_FWD_GAIN(feedfwgain);
3137
3138 } else {
3139 hw_state->mg_pll_div0 =
3140 (m2div_rem > 0 ? MG_PLL_DIV0_FRACNEN_H : 0) |
3141 MG_PLL_DIV0_FBDIV_FRAC(m2div_frac) |
3142 MG_PLL_DIV0_FBDIV_INT(m2div_int);
3143
3144 hw_state->mg_pll_div1 =
3145 MG_PLL_DIV1_IREF_NDIVRATIO(iref_ndiv) |
3146 MG_PLL_DIV1_DITHER_DIV_2 |
3147 MG_PLL_DIV1_NDIVRATIO(1) |
3148 MG_PLL_DIV1_FBPREDIV(m1div);
3149
3150 hw_state->mg_pll_lf =
3151 MG_PLL_LF_TDCTARGETCNT(tdc_targetcnt) |
3152 MG_PLL_LF_AFCCNTSEL_512 |
3153 MG_PLL_LF_GAINCTRL(1) |
3154 MG_PLL_LF_INT_COEFF(int_coeff) |
3155 MG_PLL_LF_PROP_COEFF(prop_coeff);
3156
3157 hw_state->mg_pll_frac_lock =
3158 MG_PLL_FRAC_LOCK_TRUELOCK_CRIT_32 |
3159 MG_PLL_FRAC_LOCK_EARLYLOCK_CRIT_32 |
3160 MG_PLL_FRAC_LOCK_LOCKTHRESH(10) |
3161 MG_PLL_FRAC_LOCK_DCODITHEREN |
3162 MG_PLL_FRAC_LOCK_FEEDFWRDGAIN(feedfwgain);
3163 if (use_ssc || m2div_rem > 0)
3164 hw_state->mg_pll_frac_lock |=
3165 MG_PLL_FRAC_LOCK_FEEDFWRDCAL_EN;
3166
3167 hw_state->mg_pll_ssc =
3168 (use_ssc ? MG_PLL_SSC_EN : 0) |
3169 MG_PLL_SSC_TYPE(2) |
3170 MG_PLL_SSC_STEPLENGTH(ssc_steplen) |
3171 MG_PLL_SSC_STEPNUM(ssc_steplog) |
3172 MG_PLL_SSC_FLLEN |
3173 MG_PLL_SSC_STEPSIZE(ssc_stepsize);
3174
3175 hw_state->mg_pll_tdc_coldst_bias =
3176 MG_PLL_TDC_COLDST_COLDSTART |
3177 MG_PLL_TDC_COLDST_IREFINT_EN |
3178 MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(iref_pulse_w) |
3179 MG_PLL_TDC_TDCOVCCORR_EN |
3180 MG_PLL_TDC_TDCSEL(3);
3181
3182 hw_state->mg_pll_bias =
3183 MG_PLL_BIAS_BIAS_GB_SEL(3) |
3184 MG_PLL_BIAS_INIT_DCOAMP(0x3F) |
3185 MG_PLL_BIAS_BIAS_BONUS(10) |
3186 MG_PLL_BIAS_BIASCAL_EN |
3187 MG_PLL_BIAS_CTRIM(12) |
3188 MG_PLL_BIAS_VREF_RDAC(4) |
3189 MG_PLL_BIAS_IREFTRIM(iref_trim);
3190
3191 if (refclk_khz == 38400) {
3192 hw_state->mg_pll_tdc_coldst_bias_mask =
3193 MG_PLL_TDC_COLDST_COLDSTART;
3194 hw_state->mg_pll_bias_mask = 0;
3195 } else {
3196 hw_state->mg_pll_tdc_coldst_bias_mask = -1U;
3197 hw_state->mg_pll_bias_mask = -1U;
3198 }
3199
3200 hw_state->mg_pll_tdc_coldst_bias &=
3201 hw_state->mg_pll_tdc_coldst_bias_mask;
3202 hw_state->mg_pll_bias &= hw_state->mg_pll_bias_mask;
3203 }
3204
3205 return 0;
3206}
3207
3208static int icl_ddi_mg_pll_get_freq(struct intel_display *display,
3209 const struct intel_dpll *pll,
3210 const struct intel_dpll_hw_state *dpll_hw_state)
3211{
3212 const struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
3213 u32 m1, m2_int, m2_frac, div1, div2, ref_clock;
3214 u64 tmp;
3215
3216 ref_clock = display->dpll.ref_clks.nssc;
3217
3218 if (DISPLAY_VER(display) >= 12) {
3219 m1 = hw_state->mg_pll_div0 & DKL_PLL_DIV0_FBPREDIV_MASK;
3220 m1 = m1 >> DKL_PLL_DIV0_FBPREDIV_SHIFT;
3221 m2_int = hw_state->mg_pll_div0 & DKL_PLL_DIV0_FBDIV_INT_MASK;
3222
3223 if (hw_state->mg_pll_bias & DKL_PLL_BIAS_FRAC_EN_H) {
3224 m2_frac = hw_state->mg_pll_bias &
3225 DKL_PLL_BIAS_FBDIV_FRAC_MASK;
3226 m2_frac = m2_frac >> DKL_PLL_BIAS_FBDIV_SHIFT;
3227 } else {
3228 m2_frac = 0;
3229 }
3230 } else {
3231 m1 = hw_state->mg_pll_div1 & MG_PLL_DIV1_FBPREDIV_MASK;
3232 m2_int = hw_state->mg_pll_div0 & MG_PLL_DIV0_FBDIV_INT_MASK;
3233
3234 if (hw_state->mg_pll_div0 & MG_PLL_DIV0_FRACNEN_H) {
3235 m2_frac = hw_state->mg_pll_div0 &
3236 MG_PLL_DIV0_FBDIV_FRAC_MASK;
3237 m2_frac = m2_frac >> MG_PLL_DIV0_FBDIV_FRAC_SHIFT;
3238 } else {
3239 m2_frac = 0;
3240 }
3241 }
3242
3243 switch (hw_state->mg_clktop2_hsclkctl &
3244 MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK) {
3245 case MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_2:
3246 div1 = 2;
3247 break;
3248 case MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_3:
3249 div1 = 3;
3250 break;
3251 case MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_5:
3252 div1 = 5;
3253 break;
3254 case MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_7:
3255 div1 = 7;
3256 break;
3257 default:
3258 MISSING_CASE(hw_state->mg_clktop2_hsclkctl);
3259 return 0;
3260 }
3261
3262 div2 = (hw_state->mg_clktop2_hsclkctl &
3263 MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK) >>
3264 MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_SHIFT;
3265
3266 /* div2 value of 0 is same as 1 means no div */
3267 if (div2 == 0)
3268 div2 = 1;
3269
3270 /*
3271 * Adjust the original formula to delay the division by 2^22 in order to
3272 * minimize possible rounding errors.
3273 */
3274 tmp = (u64)m1 * m2_int * ref_clock +
3275 (((u64)m1 * m2_frac * ref_clock) >> 22);
3276 tmp = div_u64(dividend: tmp, divisor: 5 * div1 * div2);
3277
3278 return tmp;
3279}
3280
3281/**
3282 * icl_set_active_port_dpll - select the active port DPLL for a given CRTC
3283 * @crtc_state: state for the CRTC to select the DPLL for
3284 * @port_dpll_id: the active @port_dpll_id to select
3285 *
3286 * Select the given @port_dpll_id instance from the DPLLs reserved for the
3287 * CRTC.
3288 */
3289void icl_set_active_port_dpll(struct intel_crtc_state *crtc_state,
3290 enum icl_port_dpll_id port_dpll_id)
3291{
3292 struct icl_port_dpll *port_dpll =
3293 &crtc_state->icl_port_dplls[port_dpll_id];
3294
3295 crtc_state->intel_dpll = port_dpll->pll;
3296 crtc_state->dpll_hw_state = port_dpll->hw_state;
3297}
3298
3299static void icl_update_active_dpll(struct intel_atomic_state *state,
3300 struct intel_crtc *crtc,
3301 struct intel_encoder *encoder)
3302{
3303 struct intel_crtc_state *crtc_state =
3304 intel_atomic_get_new_crtc_state(state, crtc);
3305 struct intel_digital_port *primary_port;
3306 enum icl_port_dpll_id port_dpll_id = ICL_PORT_DPLL_DEFAULT;
3307
3308 primary_port = encoder->type == INTEL_OUTPUT_DP_MST ?
3309 enc_to_mst(encoder)->primary :
3310 enc_to_dig_port(encoder);
3311
3312 if (primary_port &&
3313 (intel_tc_port_in_dp_alt_mode(dig_port: primary_port) ||
3314 intel_tc_port_in_legacy_mode(dig_port: primary_port)))
3315 port_dpll_id = ICL_PORT_DPLL_MG_PHY;
3316
3317 icl_set_active_port_dpll(crtc_state, port_dpll_id);
3318}
3319
3320static int icl_compute_combo_phy_dpll(struct intel_atomic_state *state,
3321 struct intel_crtc *crtc)
3322{
3323 struct intel_display *display = to_intel_display(state);
3324 struct intel_crtc_state *crtc_state =
3325 intel_atomic_get_new_crtc_state(state, crtc);
3326 struct icl_port_dpll *port_dpll =
3327 &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
3328 struct skl_wrpll_params pll_params = {};
3329 int ret;
3330
3331 if (intel_crtc_has_type(crtc_state, type: INTEL_OUTPUT_HDMI) ||
3332 intel_crtc_has_type(crtc_state, type: INTEL_OUTPUT_DSI))
3333 ret = icl_calc_wrpll(crtc_state, wrpll_params: &pll_params);
3334 else
3335 ret = icl_calc_dp_combo_pll(crtc_state, pll_params: &pll_params);
3336
3337 if (ret)
3338 return ret;
3339
3340 icl_calc_dpll_state(display, pll_params: &pll_params, dpll_hw_state: &port_dpll->hw_state);
3341
3342 /* this is mainly for the fastset check */
3343 icl_set_active_port_dpll(crtc_state, port_dpll_id: ICL_PORT_DPLL_DEFAULT);
3344
3345 crtc_state->port_clock = icl_ddi_combo_pll_get_freq(display, NULL,
3346 dpll_hw_state: &port_dpll->hw_state);
3347
3348 return 0;
3349}
3350
3351static int icl_get_combo_phy_dpll(struct intel_atomic_state *state,
3352 struct intel_crtc *crtc,
3353 struct intel_encoder *encoder)
3354{
3355 struct intel_display *display = to_intel_display(crtc);
3356 struct intel_crtc_state *crtc_state =
3357 intel_atomic_get_new_crtc_state(state, crtc);
3358 struct icl_port_dpll *port_dpll =
3359 &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
3360 enum port port = encoder->port;
3361 unsigned long dpll_mask;
3362
3363 if (display->platform.alderlake_s) {
3364 dpll_mask =
3365 BIT(DPLL_ID_DG1_DPLL3) |
3366 BIT(DPLL_ID_DG1_DPLL2) |
3367 BIT(DPLL_ID_ICL_DPLL1) |
3368 BIT(DPLL_ID_ICL_DPLL0);
3369 } else if (display->platform.dg1) {
3370 if (port == PORT_D || port == PORT_E) {
3371 dpll_mask =
3372 BIT(DPLL_ID_DG1_DPLL2) |
3373 BIT(DPLL_ID_DG1_DPLL3);
3374 } else {
3375 dpll_mask =
3376 BIT(DPLL_ID_DG1_DPLL0) |
3377 BIT(DPLL_ID_DG1_DPLL1);
3378 }
3379 } else if (display->platform.rocketlake) {
3380 dpll_mask =
3381 BIT(DPLL_ID_EHL_DPLL4) |
3382 BIT(DPLL_ID_ICL_DPLL1) |
3383 BIT(DPLL_ID_ICL_DPLL0);
3384 } else if ((display->platform.jasperlake ||
3385 display->platform.elkhartlake) &&
3386 port != PORT_A) {
3387 dpll_mask =
3388 BIT(DPLL_ID_EHL_DPLL4) |
3389 BIT(DPLL_ID_ICL_DPLL1) |
3390 BIT(DPLL_ID_ICL_DPLL0);
3391 } else {
3392 dpll_mask = BIT(DPLL_ID_ICL_DPLL1) | BIT(DPLL_ID_ICL_DPLL0);
3393 }
3394
3395 /* Eliminate DPLLs from consideration if reserved by HTI */
3396 dpll_mask &= ~intel_hti_dpll_mask(display);
3397
3398 port_dpll->pll = intel_find_dpll(state, crtc,
3399 dpll_hw_state: &port_dpll->hw_state,
3400 dpll_mask);
3401 if (!port_dpll->pll)
3402 return -EINVAL;
3403
3404 intel_reference_dpll(state, crtc,
3405 pll: port_dpll->pll, dpll_hw_state: &port_dpll->hw_state);
3406
3407 icl_update_active_dpll(state, crtc, encoder);
3408
3409 return 0;
3410}
3411
3412static int icl_compute_tc_phy_dplls(struct intel_atomic_state *state,
3413 struct intel_crtc *crtc)
3414{
3415 struct intel_display *display = to_intel_display(state);
3416 struct intel_crtc_state *crtc_state =
3417 intel_atomic_get_new_crtc_state(state, crtc);
3418 const struct intel_crtc_state *old_crtc_state =
3419 intel_atomic_get_old_crtc_state(state, crtc);
3420 struct icl_port_dpll *port_dpll =
3421 &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
3422 struct skl_wrpll_params pll_params = {};
3423 int ret;
3424
3425 port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
3426 ret = icl_calc_tbt_pll(crtc_state, pll_params: &pll_params);
3427 if (ret)
3428 return ret;
3429
3430 icl_calc_dpll_state(display, pll_params: &pll_params, dpll_hw_state: &port_dpll->hw_state);
3431
3432 port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_MG_PHY];
3433 ret = icl_calc_mg_pll_state(crtc_state, dpll_hw_state: &port_dpll->hw_state);
3434 if (ret)
3435 return ret;
3436
3437 /* this is mainly for the fastset check */
3438 if (old_crtc_state->intel_dpll &&
3439 old_crtc_state->intel_dpll->info->id == DPLL_ID_ICL_TBTPLL)
3440 icl_set_active_port_dpll(crtc_state, port_dpll_id: ICL_PORT_DPLL_DEFAULT);
3441 else
3442 icl_set_active_port_dpll(crtc_state, port_dpll_id: ICL_PORT_DPLL_MG_PHY);
3443
3444 crtc_state->port_clock = icl_ddi_mg_pll_get_freq(display, NULL,
3445 dpll_hw_state: &port_dpll->hw_state);
3446
3447 return 0;
3448}
3449
3450static int icl_get_tc_phy_dplls(struct intel_atomic_state *state,
3451 struct intel_crtc *crtc,
3452 struct intel_encoder *encoder)
3453{
3454 struct intel_crtc_state *crtc_state =
3455 intel_atomic_get_new_crtc_state(state, crtc);
3456 struct icl_port_dpll *port_dpll =
3457 &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
3458 enum intel_dpll_id dpll_id;
3459 int ret;
3460
3461 port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
3462 port_dpll->pll = intel_find_dpll(state, crtc,
3463 dpll_hw_state: &port_dpll->hw_state,
3464 BIT(DPLL_ID_ICL_TBTPLL));
3465 if (!port_dpll->pll)
3466 return -EINVAL;
3467 intel_reference_dpll(state, crtc,
3468 pll: port_dpll->pll, dpll_hw_state: &port_dpll->hw_state);
3469
3470 port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_MG_PHY];
3471 dpll_id = icl_tc_port_to_pll_id(tc_port: intel_encoder_to_tc(encoder));
3472 port_dpll->pll = intel_find_dpll(state, crtc,
3473 dpll_hw_state: &port_dpll->hw_state,
3474 BIT(dpll_id));
3475 if (!port_dpll->pll) {
3476 ret = -EINVAL;
3477 goto err_unreference_tbt_pll;
3478 }
3479 intel_reference_dpll(state, crtc,
3480 pll: port_dpll->pll, dpll_hw_state: &port_dpll->hw_state);
3481
3482 icl_update_active_dpll(state, crtc, encoder);
3483
3484 return 0;
3485
3486err_unreference_tbt_pll:
3487 port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
3488 intel_unreference_dpll(state, crtc, pll: port_dpll->pll);
3489
3490 return ret;
3491}
3492
3493static int icl_compute_dplls(struct intel_atomic_state *state,
3494 struct intel_crtc *crtc,
3495 struct intel_encoder *encoder)
3496{
3497 if (intel_encoder_is_combo(encoder))
3498 return icl_compute_combo_phy_dpll(state, crtc);
3499 else if (intel_encoder_is_tc(encoder))
3500 return icl_compute_tc_phy_dplls(state, crtc);
3501
3502 MISSING_CASE(encoder->port);
3503
3504 return 0;
3505}
3506
3507static int icl_get_dplls(struct intel_atomic_state *state,
3508 struct intel_crtc *crtc,
3509 struct intel_encoder *encoder)
3510{
3511 if (intel_encoder_is_combo(encoder))
3512 return icl_get_combo_phy_dpll(state, crtc, encoder);
3513 else if (intel_encoder_is_tc(encoder))
3514 return icl_get_tc_phy_dplls(state, crtc, encoder);
3515
3516 MISSING_CASE(encoder->port);
3517
3518 return -EINVAL;
3519}
3520
3521static void icl_put_dplls(struct intel_atomic_state *state,
3522 struct intel_crtc *crtc)
3523{
3524 const struct intel_crtc_state *old_crtc_state =
3525 intel_atomic_get_old_crtc_state(state, crtc);
3526 struct intel_crtc_state *new_crtc_state =
3527 intel_atomic_get_new_crtc_state(state, crtc);
3528 enum icl_port_dpll_id id;
3529
3530 new_crtc_state->intel_dpll = NULL;
3531
3532 for (id = ICL_PORT_DPLL_DEFAULT; id < ICL_PORT_DPLL_COUNT; id++) {
3533 const struct icl_port_dpll *old_port_dpll =
3534 &old_crtc_state->icl_port_dplls[id];
3535 struct icl_port_dpll *new_port_dpll =
3536 &new_crtc_state->icl_port_dplls[id];
3537
3538 new_port_dpll->pll = NULL;
3539
3540 if (!old_port_dpll->pll)
3541 continue;
3542
3543 intel_unreference_dpll(state, crtc, pll: old_port_dpll->pll);
3544 }
3545}
3546
3547static bool mg_pll_get_hw_state(struct intel_display *display,
3548 struct intel_dpll *pll,
3549 struct intel_dpll_hw_state *dpll_hw_state)
3550{
3551 struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
3552 const enum intel_dpll_id id = pll->info->id;
3553 enum tc_port tc_port = icl_pll_id_to_tc_port(id);
3554 intel_wakeref_t wakeref;
3555 bool ret = false;
3556 u32 val;
3557
3558 i915_reg_t enable_reg = intel_tc_pll_enable_reg(display, pll);
3559
3560 wakeref = intel_display_power_get_if_enabled(display,
3561 domain: POWER_DOMAIN_DISPLAY_CORE);
3562 if (!wakeref)
3563 return false;
3564
3565 val = intel_de_read(display, reg: enable_reg);
3566 if (!(val & PLL_ENABLE))
3567 goto out;
3568
3569 hw_state->mg_refclkin_ctl = intel_de_read(display,
3570 MG_REFCLKIN_CTL(tc_port));
3571 hw_state->mg_refclkin_ctl &= MG_REFCLKIN_CTL_OD_2_MUX_MASK;
3572
3573 hw_state->mg_clktop2_coreclkctl1 =
3574 intel_de_read(display, MG_CLKTOP2_CORECLKCTL1(tc_port));
3575 hw_state->mg_clktop2_coreclkctl1 &=
3576 MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
3577
3578 hw_state->mg_clktop2_hsclkctl =
3579 intel_de_read(display, MG_CLKTOP2_HSCLKCTL(tc_port));
3580 hw_state->mg_clktop2_hsclkctl &=
3581 MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
3582 MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
3583 MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
3584 MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK;
3585
3586 hw_state->mg_pll_div0 = intel_de_read(display, MG_PLL_DIV0(tc_port));
3587 hw_state->mg_pll_div1 = intel_de_read(display, MG_PLL_DIV1(tc_port));
3588 hw_state->mg_pll_lf = intel_de_read(display, MG_PLL_LF(tc_port));
3589 hw_state->mg_pll_frac_lock = intel_de_read(display,
3590 MG_PLL_FRAC_LOCK(tc_port));
3591 hw_state->mg_pll_ssc = intel_de_read(display, MG_PLL_SSC(tc_port));
3592
3593 hw_state->mg_pll_bias = intel_de_read(display, MG_PLL_BIAS(tc_port));
3594 hw_state->mg_pll_tdc_coldst_bias =
3595 intel_de_read(display, MG_PLL_TDC_COLDST_BIAS(tc_port));
3596
3597 if (display->dpll.ref_clks.nssc == 38400) {
3598 hw_state->mg_pll_tdc_coldst_bias_mask = MG_PLL_TDC_COLDST_COLDSTART;
3599 hw_state->mg_pll_bias_mask = 0;
3600 } else {
3601 hw_state->mg_pll_tdc_coldst_bias_mask = -1U;
3602 hw_state->mg_pll_bias_mask = -1U;
3603 }
3604
3605 hw_state->mg_pll_tdc_coldst_bias &= hw_state->mg_pll_tdc_coldst_bias_mask;
3606 hw_state->mg_pll_bias &= hw_state->mg_pll_bias_mask;
3607
3608 ret = true;
3609out:
3610 intel_display_power_put(display, domain: POWER_DOMAIN_DISPLAY_CORE, wakeref);
3611 return ret;
3612}
3613
3614static bool dkl_pll_get_hw_state(struct intel_display *display,
3615 struct intel_dpll *pll,
3616 struct intel_dpll_hw_state *dpll_hw_state)
3617{
3618 struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
3619 const enum intel_dpll_id id = pll->info->id;
3620 enum tc_port tc_port = icl_pll_id_to_tc_port(id);
3621 intel_wakeref_t wakeref;
3622 bool ret = false;
3623 u32 val;
3624
3625 wakeref = intel_display_power_get_if_enabled(display,
3626 domain: POWER_DOMAIN_DISPLAY_CORE);
3627 if (!wakeref)
3628 return false;
3629
3630 val = intel_de_read(display, reg: intel_tc_pll_enable_reg(display, pll));
3631 if (!(val & PLL_ENABLE))
3632 goto out;
3633
3634 /*
3635 * All registers read here have the same HIP_INDEX_REG even though
3636 * they are on different building blocks
3637 */
3638 hw_state->mg_refclkin_ctl = intel_dkl_phy_read(display,
3639 DKL_REFCLKIN_CTL(tc_port));
3640 hw_state->mg_refclkin_ctl &= MG_REFCLKIN_CTL_OD_2_MUX_MASK;
3641
3642 hw_state->mg_clktop2_hsclkctl =
3643 intel_dkl_phy_read(display, DKL_CLKTOP2_HSCLKCTL(tc_port));
3644 hw_state->mg_clktop2_hsclkctl &=
3645 MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
3646 MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
3647 MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
3648 MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK;
3649
3650 hw_state->mg_clktop2_coreclkctl1 =
3651 intel_dkl_phy_read(display, DKL_CLKTOP2_CORECLKCTL1(tc_port));
3652 hw_state->mg_clktop2_coreclkctl1 &=
3653 MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
3654
3655 hw_state->mg_pll_div0 = intel_dkl_phy_read(display, DKL_PLL_DIV0(tc_port));
3656 val = DKL_PLL_DIV0_MASK;
3657 if (display->vbt.override_afc_startup)
3658 val |= DKL_PLL_DIV0_AFC_STARTUP_MASK;
3659 hw_state->mg_pll_div0 &= val;
3660
3661 hw_state->mg_pll_div1 = intel_dkl_phy_read(display, DKL_PLL_DIV1(tc_port));
3662 hw_state->mg_pll_div1 &= (DKL_PLL_DIV1_IREF_TRIM_MASK |
3663 DKL_PLL_DIV1_TDC_TARGET_CNT_MASK);
3664
3665 hw_state->mg_pll_ssc = intel_dkl_phy_read(display, DKL_PLL_SSC(tc_port));
3666 hw_state->mg_pll_ssc &= (DKL_PLL_SSC_IREF_NDIV_RATIO_MASK |
3667 DKL_PLL_SSC_STEP_LEN_MASK |
3668 DKL_PLL_SSC_STEP_NUM_MASK |
3669 DKL_PLL_SSC_EN);
3670
3671 hw_state->mg_pll_bias = intel_dkl_phy_read(display, DKL_PLL_BIAS(tc_port));
3672 hw_state->mg_pll_bias &= (DKL_PLL_BIAS_FRAC_EN_H |
3673 DKL_PLL_BIAS_FBDIV_FRAC_MASK);
3674
3675 hw_state->mg_pll_tdc_coldst_bias =
3676 intel_dkl_phy_read(display, DKL_PLL_TDC_COLDST_BIAS(tc_port));
3677 hw_state->mg_pll_tdc_coldst_bias &= (DKL_PLL_TDC_SSC_STEP_SIZE_MASK |
3678 DKL_PLL_TDC_FEED_FWD_GAIN_MASK);
3679
3680 ret = true;
3681out:
3682 intel_display_power_put(display, domain: POWER_DOMAIN_DISPLAY_CORE, wakeref);
3683 return ret;
3684}
3685
3686static bool icl_pll_get_hw_state(struct intel_display *display,
3687 struct intel_dpll *pll,
3688 struct intel_dpll_hw_state *dpll_hw_state,
3689 i915_reg_t enable_reg)
3690{
3691 struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
3692 const enum intel_dpll_id id = pll->info->id;
3693 intel_wakeref_t wakeref;
3694 bool ret = false;
3695 u32 val;
3696
3697 wakeref = intel_display_power_get_if_enabled(display,
3698 domain: POWER_DOMAIN_DISPLAY_CORE);
3699 if (!wakeref)
3700 return false;
3701
3702 val = intel_de_read(display, reg: enable_reg);
3703 if (!(val & PLL_ENABLE))
3704 goto out;
3705
3706 if (display->platform.alderlake_s) {
3707 hw_state->cfgcr0 = intel_de_read(display, ADLS_DPLL_CFGCR0(id));
3708 hw_state->cfgcr1 = intel_de_read(display, ADLS_DPLL_CFGCR1(id));
3709 } else if (display->platform.dg1) {
3710 hw_state->cfgcr0 = intel_de_read(display, DG1_DPLL_CFGCR0(id));
3711 hw_state->cfgcr1 = intel_de_read(display, DG1_DPLL_CFGCR1(id));
3712 } else if (display->platform.rocketlake) {
3713 hw_state->cfgcr0 = intel_de_read(display,
3714 RKL_DPLL_CFGCR0(id));
3715 hw_state->cfgcr1 = intel_de_read(display,
3716 RKL_DPLL_CFGCR1(id));
3717 } else if (DISPLAY_VER(display) >= 12) {
3718 hw_state->cfgcr0 = intel_de_read(display,
3719 TGL_DPLL_CFGCR0(id));
3720 hw_state->cfgcr1 = intel_de_read(display,
3721 TGL_DPLL_CFGCR1(id));
3722 if (display->vbt.override_afc_startup) {
3723 hw_state->div0 = intel_de_read(display, TGL_DPLL0_DIV0(id));
3724 hw_state->div0 &= TGL_DPLL0_DIV0_AFC_STARTUP_MASK;
3725 }
3726 } else {
3727 if ((display->platform.jasperlake || display->platform.elkhartlake) &&
3728 id == DPLL_ID_EHL_DPLL4) {
3729 hw_state->cfgcr0 = intel_de_read(display,
3730 ICL_DPLL_CFGCR0(4));
3731 hw_state->cfgcr1 = intel_de_read(display,
3732 ICL_DPLL_CFGCR1(4));
3733 } else {
3734 hw_state->cfgcr0 = intel_de_read(display,
3735 ICL_DPLL_CFGCR0(id));
3736 hw_state->cfgcr1 = intel_de_read(display,
3737 ICL_DPLL_CFGCR1(id));
3738 }
3739 }
3740
3741 ret = true;
3742out:
3743 intel_display_power_put(display, domain: POWER_DOMAIN_DISPLAY_CORE, wakeref);
3744 return ret;
3745}
3746
3747static bool combo_pll_get_hw_state(struct intel_display *display,
3748 struct intel_dpll *pll,
3749 struct intel_dpll_hw_state *dpll_hw_state)
3750{
3751 i915_reg_t enable_reg = intel_combo_pll_enable_reg(display, pll);
3752
3753 return icl_pll_get_hw_state(display, pll, dpll_hw_state, enable_reg);
3754}
3755
3756static bool tbt_pll_get_hw_state(struct intel_display *display,
3757 struct intel_dpll *pll,
3758 struct intel_dpll_hw_state *dpll_hw_state)
3759{
3760 return icl_pll_get_hw_state(display, pll, dpll_hw_state, TBT_PLL_ENABLE);
3761}
3762
3763static void icl_dpll_write(struct intel_display *display,
3764 struct intel_dpll *pll,
3765 const struct icl_dpll_hw_state *hw_state)
3766{
3767 const enum intel_dpll_id id = pll->info->id;
3768 i915_reg_t cfgcr0_reg, cfgcr1_reg, div0_reg = INVALID_MMIO_REG;
3769
3770 if (display->platform.alderlake_s) {
3771 cfgcr0_reg = ADLS_DPLL_CFGCR0(id);
3772 cfgcr1_reg = ADLS_DPLL_CFGCR1(id);
3773 } else if (display->platform.dg1) {
3774 cfgcr0_reg = DG1_DPLL_CFGCR0(id);
3775 cfgcr1_reg = DG1_DPLL_CFGCR1(id);
3776 } else if (display->platform.rocketlake) {
3777 cfgcr0_reg = RKL_DPLL_CFGCR0(id);
3778 cfgcr1_reg = RKL_DPLL_CFGCR1(id);
3779 } else if (DISPLAY_VER(display) >= 12) {
3780 cfgcr0_reg = TGL_DPLL_CFGCR0(id);
3781 cfgcr1_reg = TGL_DPLL_CFGCR1(id);
3782 div0_reg = TGL_DPLL0_DIV0(id);
3783 } else {
3784 if ((display->platform.jasperlake || display->platform.elkhartlake) &&
3785 id == DPLL_ID_EHL_DPLL4) {
3786 cfgcr0_reg = ICL_DPLL_CFGCR0(4);
3787 cfgcr1_reg = ICL_DPLL_CFGCR1(4);
3788 } else {
3789 cfgcr0_reg = ICL_DPLL_CFGCR0(id);
3790 cfgcr1_reg = ICL_DPLL_CFGCR1(id);
3791 }
3792 }
3793
3794 intel_de_write(display, reg: cfgcr0_reg, val: hw_state->cfgcr0);
3795 intel_de_write(display, reg: cfgcr1_reg, val: hw_state->cfgcr1);
3796 drm_WARN_ON_ONCE(display->drm, display->vbt.override_afc_startup &&
3797 !i915_mmio_reg_valid(div0_reg));
3798 if (display->vbt.override_afc_startup &&
3799 i915_mmio_reg_valid(div0_reg))
3800 intel_de_rmw(display, reg: div0_reg,
3801 TGL_DPLL0_DIV0_AFC_STARTUP_MASK, set: hw_state->div0);
3802 intel_de_posting_read(display, reg: cfgcr1_reg);
3803}
3804
3805static void icl_mg_pll_write(struct intel_display *display,
3806 struct intel_dpll *pll,
3807 const struct icl_dpll_hw_state *hw_state)
3808{
3809 enum tc_port tc_port = icl_pll_id_to_tc_port(id: pll->info->id);
3810
3811 /*
3812 * Some of the following registers have reserved fields, so program
3813 * these with RMW based on a mask. The mask can be fixed or generated
3814 * during the calc/readout phase if the mask depends on some other HW
3815 * state like refclk, see icl_calc_mg_pll_state().
3816 */
3817 intel_de_rmw(display, MG_REFCLKIN_CTL(tc_port),
3818 MG_REFCLKIN_CTL_OD_2_MUX_MASK, set: hw_state->mg_refclkin_ctl);
3819
3820 intel_de_rmw(display, MG_CLKTOP2_CORECLKCTL1(tc_port),
3821 MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK,
3822 set: hw_state->mg_clktop2_coreclkctl1);
3823
3824 intel_de_rmw(display, MG_CLKTOP2_HSCLKCTL(tc_port),
3825 MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
3826 MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
3827 MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
3828 MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK,
3829 set: hw_state->mg_clktop2_hsclkctl);
3830
3831 intel_de_write(display, MG_PLL_DIV0(tc_port), val: hw_state->mg_pll_div0);
3832 intel_de_write(display, MG_PLL_DIV1(tc_port), val: hw_state->mg_pll_div1);
3833 intel_de_write(display, MG_PLL_LF(tc_port), val: hw_state->mg_pll_lf);
3834 intel_de_write(display, MG_PLL_FRAC_LOCK(tc_port),
3835 val: hw_state->mg_pll_frac_lock);
3836 intel_de_write(display, MG_PLL_SSC(tc_port), val: hw_state->mg_pll_ssc);
3837
3838 intel_de_rmw(display, MG_PLL_BIAS(tc_port),
3839 clear: hw_state->mg_pll_bias_mask, set: hw_state->mg_pll_bias);
3840
3841 intel_de_rmw(display, MG_PLL_TDC_COLDST_BIAS(tc_port),
3842 clear: hw_state->mg_pll_tdc_coldst_bias_mask,
3843 set: hw_state->mg_pll_tdc_coldst_bias);
3844
3845 intel_de_posting_read(display, MG_PLL_TDC_COLDST_BIAS(tc_port));
3846}
3847
3848static void dkl_pll_write(struct intel_display *display,
3849 struct intel_dpll *pll,
3850 const struct icl_dpll_hw_state *hw_state)
3851{
3852 enum tc_port tc_port = icl_pll_id_to_tc_port(id: pll->info->id);
3853 u32 val;
3854
3855 /*
3856 * All registers programmed here have the same HIP_INDEX_REG even
3857 * though on different building block
3858 */
3859 /* All the registers are RMW */
3860 val = intel_dkl_phy_read(display, DKL_REFCLKIN_CTL(tc_port));
3861 val &= ~MG_REFCLKIN_CTL_OD_2_MUX_MASK;
3862 val |= hw_state->mg_refclkin_ctl;
3863 intel_dkl_phy_write(display, DKL_REFCLKIN_CTL(tc_port), val);
3864
3865 val = intel_dkl_phy_read(display, DKL_CLKTOP2_CORECLKCTL1(tc_port));
3866 val &= ~MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
3867 val |= hw_state->mg_clktop2_coreclkctl1;
3868 intel_dkl_phy_write(display, DKL_CLKTOP2_CORECLKCTL1(tc_port), val);
3869
3870 val = intel_dkl_phy_read(display, DKL_CLKTOP2_HSCLKCTL(tc_port));
3871 val &= ~(MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
3872 MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
3873 MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
3874 MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK);
3875 val |= hw_state->mg_clktop2_hsclkctl;
3876 intel_dkl_phy_write(display, DKL_CLKTOP2_HSCLKCTL(tc_port), val);
3877
3878 val = DKL_PLL_DIV0_MASK;
3879 if (display->vbt.override_afc_startup)
3880 val |= DKL_PLL_DIV0_AFC_STARTUP_MASK;
3881 intel_dkl_phy_rmw(display, DKL_PLL_DIV0(tc_port), clear: val,
3882 set: hw_state->mg_pll_div0);
3883
3884 val = intel_dkl_phy_read(display, DKL_PLL_DIV1(tc_port));
3885 val &= ~(DKL_PLL_DIV1_IREF_TRIM_MASK |
3886 DKL_PLL_DIV1_TDC_TARGET_CNT_MASK);
3887 val |= hw_state->mg_pll_div1;
3888 intel_dkl_phy_write(display, DKL_PLL_DIV1(tc_port), val);
3889
3890 val = intel_dkl_phy_read(display, DKL_PLL_SSC(tc_port));
3891 val &= ~(DKL_PLL_SSC_IREF_NDIV_RATIO_MASK |
3892 DKL_PLL_SSC_STEP_LEN_MASK |
3893 DKL_PLL_SSC_STEP_NUM_MASK |
3894 DKL_PLL_SSC_EN);
3895 val |= hw_state->mg_pll_ssc;
3896 intel_dkl_phy_write(display, DKL_PLL_SSC(tc_port), val);
3897
3898 val = intel_dkl_phy_read(display, DKL_PLL_BIAS(tc_port));
3899 val &= ~(DKL_PLL_BIAS_FRAC_EN_H |
3900 DKL_PLL_BIAS_FBDIV_FRAC_MASK);
3901 val |= hw_state->mg_pll_bias;
3902 intel_dkl_phy_write(display, DKL_PLL_BIAS(tc_port), val);
3903
3904 val = intel_dkl_phy_read(display, DKL_PLL_TDC_COLDST_BIAS(tc_port));
3905 val &= ~(DKL_PLL_TDC_SSC_STEP_SIZE_MASK |
3906 DKL_PLL_TDC_FEED_FWD_GAIN_MASK);
3907 val |= hw_state->mg_pll_tdc_coldst_bias;
3908 intel_dkl_phy_write(display, DKL_PLL_TDC_COLDST_BIAS(tc_port), val);
3909
3910 intel_dkl_phy_posting_read(display, DKL_PLL_TDC_COLDST_BIAS(tc_port));
3911}
3912
3913static void icl_pll_power_enable(struct intel_display *display,
3914 struct intel_dpll *pll,
3915 i915_reg_t enable_reg)
3916{
3917 intel_de_rmw(display, reg: enable_reg, clear: 0, PLL_POWER_ENABLE);
3918
3919 /*
3920 * The spec says we need to "wait" but it also says it should be
3921 * immediate.
3922 */
3923 if (intel_de_wait_for_set_ms(display, reg: enable_reg, PLL_POWER_STATE, timeout_ms: 1))
3924 drm_err(display->drm, "PLL %d Power not enabled\n",
3925 pll->info->id);
3926}
3927
3928static void icl_pll_enable(struct intel_display *display,
3929 struct intel_dpll *pll,
3930 i915_reg_t enable_reg)
3931{
3932 intel_de_rmw(display, reg: enable_reg, clear: 0, PLL_ENABLE);
3933
3934 /* Timeout is actually 600us. */
3935 if (intel_de_wait_for_set_ms(display, reg: enable_reg, PLL_LOCK, timeout_ms: 1))
3936 drm_err(display->drm, "PLL %d not locked\n", pll->info->id);
3937}
3938
3939static void adlp_cmtg_clock_gating_wa(struct intel_display *display, struct intel_dpll *pll)
3940{
3941 u32 val;
3942
3943 if (!(display->platform.alderlake_p && IS_DISPLAY_STEP(display, STEP_A0, STEP_B0)) ||
3944 pll->info->id != DPLL_ID_ICL_DPLL0)
3945 return;
3946 /*
3947 * Wa_16011069516:adl-p[a0]
3948 *
3949 * All CMTG regs are unreliable until CMTG clock gating is disabled,
3950 * so we can only assume the default TRANS_CMTG_CHICKEN reg value and
3951 * sanity check this assumption with a double read, which presumably
3952 * returns the correct value even with clock gating on.
3953 *
3954 * Instead of the usual place for workarounds we apply this one here,
3955 * since TRANS_CMTG_CHICKEN is only accessible while DPLL0 is enabled.
3956 */
3957 val = intel_de_read(display, TRANS_CMTG_CHICKEN);
3958 val = intel_de_rmw(display, TRANS_CMTG_CHICKEN, clear: ~0, DISABLE_DPT_CLK_GATING);
3959 if (drm_WARN_ON(display->drm, val & ~DISABLE_DPT_CLK_GATING))
3960 drm_dbg_kms(display->drm, "Unexpected flags in TRANS_CMTG_CHICKEN: %08x\n", val);
3961}
3962
3963static void combo_pll_enable(struct intel_display *display,
3964 struct intel_dpll *pll,
3965 const struct intel_dpll_hw_state *dpll_hw_state)
3966{
3967 const struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
3968 i915_reg_t enable_reg = intel_combo_pll_enable_reg(display, pll);
3969
3970 icl_pll_power_enable(display, pll, enable_reg);
3971
3972 icl_dpll_write(display, pll, hw_state);
3973
3974 /*
3975 * DVFS pre sequence would be here, but in our driver the cdclk code
3976 * paths should already be setting the appropriate voltage, hence we do
3977 * nothing here.
3978 */
3979
3980 icl_pll_enable(display, pll, enable_reg);
3981
3982 adlp_cmtg_clock_gating_wa(display, pll);
3983
3984 /* DVFS post sequence would be here. See the comment above. */
3985}
3986
3987static void tbt_pll_enable(struct intel_display *display,
3988 struct intel_dpll *pll,
3989 const struct intel_dpll_hw_state *dpll_hw_state)
3990{
3991 const struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
3992
3993 icl_pll_power_enable(display, pll, TBT_PLL_ENABLE);
3994
3995 icl_dpll_write(display, pll, hw_state);
3996
3997 /*
3998 * DVFS pre sequence would be here, but in our driver the cdclk code
3999 * paths should already be setting the appropriate voltage, hence we do
4000 * nothing here.
4001 */
4002
4003 icl_pll_enable(display, pll, TBT_PLL_ENABLE);
4004
4005 /* DVFS post sequence would be here. See the comment above. */
4006}
4007
4008static void mg_pll_enable(struct intel_display *display,
4009 struct intel_dpll *pll,
4010 const struct intel_dpll_hw_state *dpll_hw_state)
4011{
4012 const struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
4013 i915_reg_t enable_reg = intel_tc_pll_enable_reg(display, pll);
4014
4015 icl_pll_power_enable(display, pll, enable_reg);
4016
4017 if (DISPLAY_VER(display) >= 12)
4018 dkl_pll_write(display, pll, hw_state);
4019 else
4020 icl_mg_pll_write(display, pll, hw_state);
4021
4022 /*
4023 * DVFS pre sequence would be here, but in our driver the cdclk code
4024 * paths should already be setting the appropriate voltage, hence we do
4025 * nothing here.
4026 */
4027
4028 icl_pll_enable(display, pll, enable_reg);
4029
4030 /* DVFS post sequence would be here. See the comment above. */
4031}
4032
4033static void icl_pll_disable(struct intel_display *display,
4034 struct intel_dpll *pll,
4035 i915_reg_t enable_reg)
4036{
4037 /* The first steps are done by intel_ddi_post_disable(). */
4038
4039 /*
4040 * DVFS pre sequence would be here, but in our driver the cdclk code
4041 * paths should already be setting the appropriate voltage, hence we do
4042 * nothing here.
4043 */
4044
4045 intel_de_rmw(display, reg: enable_reg, PLL_ENABLE, set: 0);
4046
4047 /* Timeout is actually 1us. */
4048 if (intel_de_wait_for_clear_ms(display, reg: enable_reg, PLL_LOCK, timeout_ms: 1))
4049 drm_err(display->drm, "PLL %d locked\n", pll->info->id);
4050
4051 /* DVFS post sequence would be here. See the comment above. */
4052
4053 intel_de_rmw(display, reg: enable_reg, PLL_POWER_ENABLE, set: 0);
4054
4055 /*
4056 * The spec says we need to "wait" but it also says it should be
4057 * immediate.
4058 */
4059 if (intel_de_wait_for_clear_ms(display, reg: enable_reg, PLL_POWER_STATE, timeout_ms: 1))
4060 drm_err(display->drm, "PLL %d Power not disabled\n",
4061 pll->info->id);
4062}
4063
4064static void combo_pll_disable(struct intel_display *display,
4065 struct intel_dpll *pll)
4066{
4067 i915_reg_t enable_reg = intel_combo_pll_enable_reg(display, pll);
4068
4069 icl_pll_disable(display, pll, enable_reg);
4070}
4071
4072static void tbt_pll_disable(struct intel_display *display,
4073 struct intel_dpll *pll)
4074{
4075 icl_pll_disable(display, pll, TBT_PLL_ENABLE);
4076}
4077
4078static void mg_pll_disable(struct intel_display *display,
4079 struct intel_dpll *pll)
4080{
4081 i915_reg_t enable_reg = intel_tc_pll_enable_reg(display, pll);
4082
4083 icl_pll_disable(display, pll, enable_reg);
4084}
4085
4086static void icl_update_dpll_ref_clks(struct intel_display *display)
4087{
4088 /* No SSC ref */
4089 display->dpll.ref_clks.nssc = display->cdclk.hw.ref;
4090}
4091
4092static void icl_dump_hw_state(struct drm_printer *p,
4093 const struct intel_dpll_hw_state *dpll_hw_state)
4094{
4095 const struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
4096
4097 drm_printf(p, f: "dpll_hw_state: cfgcr0: 0x%x, cfgcr1: 0x%x, div0: 0x%x, "
4098 "mg_refclkin_ctl: 0x%x, hg_clktop2_coreclkctl1: 0x%x, "
4099 "mg_clktop2_hsclkctl: 0x%x, mg_pll_div0: 0x%x, "
4100 "mg_pll_div2: 0x%x, mg_pll_lf: 0x%x, "
4101 "mg_pll_frac_lock: 0x%x, mg_pll_ssc: 0x%x, "
4102 "mg_pll_bias: 0x%x, mg_pll_tdc_coldst_bias: 0x%x\n",
4103 hw_state->cfgcr0, hw_state->cfgcr1, hw_state->div0,
4104 hw_state->mg_refclkin_ctl,
4105 hw_state->mg_clktop2_coreclkctl1,
4106 hw_state->mg_clktop2_hsclkctl,
4107 hw_state->mg_pll_div0,
4108 hw_state->mg_pll_div1,
4109 hw_state->mg_pll_lf,
4110 hw_state->mg_pll_frac_lock,
4111 hw_state->mg_pll_ssc,
4112 hw_state->mg_pll_bias,
4113 hw_state->mg_pll_tdc_coldst_bias);
4114}
4115
4116static bool icl_compare_hw_state(const struct intel_dpll_hw_state *_a,
4117 const struct intel_dpll_hw_state *_b)
4118{
4119 const struct icl_dpll_hw_state *a = &_a->icl;
4120 const struct icl_dpll_hw_state *b = &_b->icl;
4121
4122 /* FIXME split combo vs. mg more thoroughly */
4123 return a->cfgcr0 == b->cfgcr0 &&
4124 a->cfgcr1 == b->cfgcr1 &&
4125 a->div0 == b->div0 &&
4126 a->mg_refclkin_ctl == b->mg_refclkin_ctl &&
4127 a->mg_clktop2_coreclkctl1 == b->mg_clktop2_coreclkctl1 &&
4128 a->mg_clktop2_hsclkctl == b->mg_clktop2_hsclkctl &&
4129 a->mg_pll_div0 == b->mg_pll_div0 &&
4130 a->mg_pll_div1 == b->mg_pll_div1 &&
4131 a->mg_pll_lf == b->mg_pll_lf &&
4132 a->mg_pll_frac_lock == b->mg_pll_frac_lock &&
4133 a->mg_pll_ssc == b->mg_pll_ssc &&
4134 a->mg_pll_bias == b->mg_pll_bias &&
4135 a->mg_pll_tdc_coldst_bias == b->mg_pll_tdc_coldst_bias;
4136}
4137
4138static const struct intel_dpll_funcs combo_pll_funcs = {
4139 .enable = combo_pll_enable,
4140 .disable = combo_pll_disable,
4141 .get_hw_state = combo_pll_get_hw_state,
4142 .get_freq = icl_ddi_combo_pll_get_freq,
4143};
4144
4145static const struct intel_dpll_funcs tbt_pll_funcs = {
4146 .enable = tbt_pll_enable,
4147 .disable = tbt_pll_disable,
4148 .get_hw_state = tbt_pll_get_hw_state,
4149 .get_freq = icl_ddi_tbt_pll_get_freq,
4150};
4151
4152static const struct intel_dpll_funcs mg_pll_funcs = {
4153 .enable = mg_pll_enable,
4154 .disable = mg_pll_disable,
4155 .get_hw_state = mg_pll_get_hw_state,
4156 .get_freq = icl_ddi_mg_pll_get_freq,
4157};
4158
4159static const struct dpll_info icl_plls[] = {
4160 { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
4161 { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
4162 { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL,
4163 .is_alt_port_dpll = true, },
4164 { .name = "MG PLL 1", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, },
4165 { .name = "MG PLL 2", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, },
4166 { .name = "MG PLL 3", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, },
4167 { .name = "MG PLL 4", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL4, },
4168 {}
4169};
4170
4171static const struct intel_dpll_mgr icl_pll_mgr = {
4172 .dpll_info = icl_plls,
4173 .compute_dplls = icl_compute_dplls,
4174 .get_dplls = icl_get_dplls,
4175 .put_dplls = icl_put_dplls,
4176 .update_active_dpll = icl_update_active_dpll,
4177 .update_ref_clks = icl_update_dpll_ref_clks,
4178 .dump_hw_state = icl_dump_hw_state,
4179 .compare_hw_state = icl_compare_hw_state,
4180};
4181
4182static const struct dpll_info ehl_plls[] = {
4183 { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
4184 { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
4185 { .name = "DPLL 4", .funcs = &combo_pll_funcs, .id = DPLL_ID_EHL_DPLL4,
4186 .power_domain = POWER_DOMAIN_DC_OFF, },
4187 {}
4188};
4189
4190static const struct intel_dpll_mgr ehl_pll_mgr = {
4191 .dpll_info = ehl_plls,
4192 .compute_dplls = icl_compute_dplls,
4193 .get_dplls = icl_get_dplls,
4194 .put_dplls = icl_put_dplls,
4195 .update_ref_clks = icl_update_dpll_ref_clks,
4196 .dump_hw_state = icl_dump_hw_state,
4197 .compare_hw_state = icl_compare_hw_state,
4198};
4199
4200static const struct intel_dpll_funcs dkl_pll_funcs = {
4201 .enable = mg_pll_enable,
4202 .disable = mg_pll_disable,
4203 .get_hw_state = dkl_pll_get_hw_state,
4204 .get_freq = icl_ddi_mg_pll_get_freq,
4205};
4206
4207static const struct dpll_info tgl_plls[] = {
4208 { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
4209 { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
4210 { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL,
4211 .is_alt_port_dpll = true, },
4212 { .name = "TC PLL 1", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, },
4213 { .name = "TC PLL 2", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, },
4214 { .name = "TC PLL 3", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, },
4215 { .name = "TC PLL 4", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL4, },
4216 { .name = "TC PLL 5", .funcs = &dkl_pll_funcs, .id = DPLL_ID_TGL_MGPLL5, },
4217 { .name = "TC PLL 6", .funcs = &dkl_pll_funcs, .id = DPLL_ID_TGL_MGPLL6, },
4218 {}
4219};
4220
4221static const struct intel_dpll_mgr tgl_pll_mgr = {
4222 .dpll_info = tgl_plls,
4223 .compute_dplls = icl_compute_dplls,
4224 .get_dplls = icl_get_dplls,
4225 .put_dplls = icl_put_dplls,
4226 .update_active_dpll = icl_update_active_dpll,
4227 .update_ref_clks = icl_update_dpll_ref_clks,
4228 .dump_hw_state = icl_dump_hw_state,
4229 .compare_hw_state = icl_compare_hw_state,
4230};
4231
4232static const struct dpll_info rkl_plls[] = {
4233 { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
4234 { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
4235 { .name = "DPLL 4", .funcs = &combo_pll_funcs, .id = DPLL_ID_EHL_DPLL4, },
4236 {}
4237};
4238
4239static const struct intel_dpll_mgr rkl_pll_mgr = {
4240 .dpll_info = rkl_plls,
4241 .compute_dplls = icl_compute_dplls,
4242 .get_dplls = icl_get_dplls,
4243 .put_dplls = icl_put_dplls,
4244 .update_ref_clks = icl_update_dpll_ref_clks,
4245 .dump_hw_state = icl_dump_hw_state,
4246 .compare_hw_state = icl_compare_hw_state,
4247};
4248
4249static const struct dpll_info dg1_plls[] = {
4250 { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_DG1_DPLL0, },
4251 { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_DG1_DPLL1, },
4252 { .name = "DPLL 2", .funcs = &combo_pll_funcs, .id = DPLL_ID_DG1_DPLL2, },
4253 { .name = "DPLL 3", .funcs = &combo_pll_funcs, .id = DPLL_ID_DG1_DPLL3, },
4254 {}
4255};
4256
4257static const struct intel_dpll_mgr dg1_pll_mgr = {
4258 .dpll_info = dg1_plls,
4259 .compute_dplls = icl_compute_dplls,
4260 .get_dplls = icl_get_dplls,
4261 .put_dplls = icl_put_dplls,
4262 .update_ref_clks = icl_update_dpll_ref_clks,
4263 .dump_hw_state = icl_dump_hw_state,
4264 .compare_hw_state = icl_compare_hw_state,
4265};
4266
4267static const struct dpll_info adls_plls[] = {
4268 { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
4269 { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
4270 { .name = "DPLL 2", .funcs = &combo_pll_funcs, .id = DPLL_ID_DG1_DPLL2, },
4271 { .name = "DPLL 3", .funcs = &combo_pll_funcs, .id = DPLL_ID_DG1_DPLL3, },
4272 {}
4273};
4274
4275static const struct intel_dpll_mgr adls_pll_mgr = {
4276 .dpll_info = adls_plls,
4277 .compute_dplls = icl_compute_dplls,
4278 .get_dplls = icl_get_dplls,
4279 .put_dplls = icl_put_dplls,
4280 .update_ref_clks = icl_update_dpll_ref_clks,
4281 .dump_hw_state = icl_dump_hw_state,
4282 .compare_hw_state = icl_compare_hw_state,
4283};
4284
4285static const struct dpll_info adlp_plls[] = {
4286 { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
4287 { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
4288 { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL,
4289 .is_alt_port_dpll = true, },
4290 { .name = "TC PLL 1", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, },
4291 { .name = "TC PLL 2", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, },
4292 { .name = "TC PLL 3", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, },
4293 { .name = "TC PLL 4", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL4, },
4294 {}
4295};
4296
4297static const struct intel_dpll_mgr adlp_pll_mgr = {
4298 .dpll_info = adlp_plls,
4299 .compute_dplls = icl_compute_dplls,
4300 .get_dplls = icl_get_dplls,
4301 .put_dplls = icl_put_dplls,
4302 .update_active_dpll = icl_update_active_dpll,
4303 .update_ref_clks = icl_update_dpll_ref_clks,
4304 .dump_hw_state = icl_dump_hw_state,
4305 .compare_hw_state = icl_compare_hw_state,
4306};
4307
4308/**
4309 * intel_dpll_init - Initialize DPLLs
4310 * @display: intel_display device
4311 *
4312 * Initialize DPLLs for @display.
4313 */
4314void intel_dpll_init(struct intel_display *display)
4315{
4316 const struct intel_dpll_mgr *dpll_mgr = NULL;
4317 const struct dpll_info *dpll_info;
4318 int i;
4319
4320 mutex_init(&display->dpll.lock);
4321
4322 if (DISPLAY_VER(display) >= 14 || display->platform.dg2)
4323 /* No shared DPLLs on DG2; port PLLs are part of the PHY */
4324 dpll_mgr = NULL;
4325 else if (display->platform.alderlake_p)
4326 dpll_mgr = &adlp_pll_mgr;
4327 else if (display->platform.alderlake_s)
4328 dpll_mgr = &adls_pll_mgr;
4329 else if (display->platform.dg1)
4330 dpll_mgr = &dg1_pll_mgr;
4331 else if (display->platform.rocketlake)
4332 dpll_mgr = &rkl_pll_mgr;
4333 else if (DISPLAY_VER(display) >= 12)
4334 dpll_mgr = &tgl_pll_mgr;
4335 else if (display->platform.jasperlake || display->platform.elkhartlake)
4336 dpll_mgr = &ehl_pll_mgr;
4337 else if (DISPLAY_VER(display) >= 11)
4338 dpll_mgr = &icl_pll_mgr;
4339 else if (display->platform.geminilake || display->platform.broxton)
4340 dpll_mgr = &bxt_pll_mgr;
4341 else if (DISPLAY_VER(display) == 9)
4342 dpll_mgr = &skl_pll_mgr;
4343 else if (HAS_DDI(display))
4344 dpll_mgr = &hsw_pll_mgr;
4345 else if (HAS_PCH_IBX(display) || HAS_PCH_CPT(display))
4346 dpll_mgr = &pch_pll_mgr;
4347
4348 if (!dpll_mgr)
4349 return;
4350
4351 dpll_info = dpll_mgr->dpll_info;
4352
4353 for (i = 0; dpll_info[i].name; i++) {
4354 if (drm_WARN_ON(display->drm,
4355 i >= ARRAY_SIZE(display->dpll.dplls)))
4356 break;
4357
4358 /* must fit into unsigned long bitmask on 32bit */
4359 if (drm_WARN_ON(display->drm, dpll_info[i].id >= 32))
4360 break;
4361
4362 display->dpll.dplls[i].info = &dpll_info[i];
4363 display->dpll.dplls[i].index = i;
4364 }
4365
4366 display->dpll.mgr = dpll_mgr;
4367 display->dpll.num_dpll = i;
4368}
4369
4370/**
4371 * intel_dpll_compute - compute DPLL state CRTC and encoder combination
4372 * @state: atomic state
4373 * @crtc: CRTC to compute DPLLs for
4374 * @encoder: encoder
4375 *
4376 * This function computes the DPLL state for the given CRTC and encoder.
4377 *
4378 * The new configuration in the atomic commit @state is made effective by
4379 * calling intel_dpll_swap_state().
4380 *
4381 * Returns:
4382 * 0 on success, negative error code on failure.
4383 */
4384int intel_dpll_compute(struct intel_atomic_state *state,
4385 struct intel_crtc *crtc,
4386 struct intel_encoder *encoder)
4387{
4388 struct intel_display *display = to_intel_display(state);
4389 const struct intel_dpll_mgr *dpll_mgr = display->dpll.mgr;
4390
4391 if (drm_WARN_ON(display->drm, !dpll_mgr))
4392 return -EINVAL;
4393
4394 return dpll_mgr->compute_dplls(state, crtc, encoder);
4395}
4396
4397/**
4398 * intel_dpll_reserve - reserve DPLLs for CRTC and encoder combination
4399 * @state: atomic state
4400 * @crtc: CRTC to reserve DPLLs for
4401 * @encoder: encoder
4402 *
4403 * This function reserves all required DPLLs for the given CRTC and encoder
4404 * combination in the current atomic commit @state and the new @crtc atomic
4405 * state.
4406 *
4407 * The new configuration in the atomic commit @state is made effective by
4408 * calling intel_dpll_swap_state().
4409 *
4410 * The reserved DPLLs should be released by calling
4411 * intel_dpll_release().
4412 *
4413 * Returns:
4414 * 0 if all required DPLLs were successfully reserved,
4415 * negative error code otherwise.
4416 */
4417int intel_dpll_reserve(struct intel_atomic_state *state,
4418 struct intel_crtc *crtc,
4419 struct intel_encoder *encoder)
4420{
4421 struct intel_display *display = to_intel_display(state);
4422 const struct intel_dpll_mgr *dpll_mgr = display->dpll.mgr;
4423
4424 if (drm_WARN_ON(display->drm, !dpll_mgr))
4425 return -EINVAL;
4426
4427 return dpll_mgr->get_dplls(state, crtc, encoder);
4428}
4429
4430/**
4431 * intel_dpll_release - end use of DPLLs by CRTC in atomic state
4432 * @state: atomic state
4433 * @crtc: crtc from which the DPLLs are to be released
4434 *
4435 * This function releases all DPLLs reserved by intel_dpll_reserve()
4436 * from the current atomic commit @state and the old @crtc atomic state.
4437 *
4438 * The new configuration in the atomic commit @state is made effective by
4439 * calling intel_dpll_swap_state().
4440 */
4441void intel_dpll_release(struct intel_atomic_state *state,
4442 struct intel_crtc *crtc)
4443{
4444 struct intel_display *display = to_intel_display(state);
4445 const struct intel_dpll_mgr *dpll_mgr = display->dpll.mgr;
4446
4447 /*
4448 * FIXME: this function is called for every platform having a
4449 * compute_clock hook, even though the platform doesn't yet support
4450 * the DPLL framework and intel_dpll_reserve() is not
4451 * called on those.
4452 */
4453 if (!dpll_mgr)
4454 return;
4455
4456 dpll_mgr->put_dplls(state, crtc);
4457}
4458
4459/**
4460 * intel_dpll_update_active - update the active DPLL for a CRTC/encoder
4461 * @state: atomic state
4462 * @crtc: the CRTC for which to update the active DPLL
4463 * @encoder: encoder determining the type of port DPLL
4464 *
4465 * Update the active DPLL for the given @crtc/@encoder in @crtc's atomic state,
4466 * from the port DPLLs reserved previously by intel_dpll_reserve(). The
4467 * DPLL selected will be based on the current mode of the encoder's port.
4468 */
4469void intel_dpll_update_active(struct intel_atomic_state *state,
4470 struct intel_crtc *crtc,
4471 struct intel_encoder *encoder)
4472{
4473 struct intel_display *display = to_intel_display(encoder);
4474 const struct intel_dpll_mgr *dpll_mgr = display->dpll.mgr;
4475
4476 if (drm_WARN_ON(display->drm, !dpll_mgr))
4477 return;
4478
4479 dpll_mgr->update_active_dpll(state, crtc, encoder);
4480}
4481
4482/**
4483 * intel_dpll_get_freq - calculate the DPLL's output frequency
4484 * @display: intel_display device
4485 * @pll: DPLL for which to calculate the output frequency
4486 * @dpll_hw_state: DPLL state from which to calculate the output frequency
4487 *
4488 * Return the output frequency corresponding to @pll's passed in @dpll_hw_state.
4489 */
4490int intel_dpll_get_freq(struct intel_display *display,
4491 const struct intel_dpll *pll,
4492 const struct intel_dpll_hw_state *dpll_hw_state)
4493{
4494 if (drm_WARN_ON(display->drm, !pll->info->funcs->get_freq))
4495 return 0;
4496
4497 return pll->info->funcs->get_freq(display, pll, dpll_hw_state);
4498}
4499
4500/**
4501 * intel_dpll_get_hw_state - readout the DPLL's hardware state
4502 * @display: intel_display device instance
4503 * @pll: DPLL for which to calculate the output frequency
4504 * @dpll_hw_state: DPLL's hardware state
4505 *
4506 * Read out @pll's hardware state into @dpll_hw_state.
4507 */
4508bool intel_dpll_get_hw_state(struct intel_display *display,
4509 struct intel_dpll *pll,
4510 struct intel_dpll_hw_state *dpll_hw_state)
4511{
4512 return pll->info->funcs->get_hw_state(display, pll, dpll_hw_state);
4513}
4514
4515static void readout_dpll_hw_state(struct intel_display *display,
4516 struct intel_dpll *pll)
4517{
4518 struct intel_crtc *crtc;
4519
4520 pll->on = intel_dpll_get_hw_state(display, pll, dpll_hw_state: &pll->state.hw_state);
4521
4522 if (pll->on && pll->info->power_domain)
4523 pll->wakeref = intel_display_power_get(display, domain: pll->info->power_domain);
4524
4525 pll->state.pipe_mask = 0;
4526 for_each_intel_crtc(display->drm, crtc) {
4527 struct intel_crtc_state *crtc_state =
4528 to_intel_crtc_state(crtc->base.state);
4529
4530 if (crtc_state->hw.active && crtc_state->intel_dpll == pll)
4531 intel_dpll_crtc_get(crtc, pll, dpll_state: &pll->state);
4532 }
4533 pll->active_mask = pll->state.pipe_mask;
4534
4535 drm_dbg_kms(display->drm,
4536 "%s hw state readout: pipe_mask 0x%x, on %i\n",
4537 pll->info->name, pll->state.pipe_mask, pll->on);
4538}
4539
4540void intel_dpll_update_ref_clks(struct intel_display *display)
4541{
4542 if (display->dpll.mgr && display->dpll.mgr->update_ref_clks)
4543 display->dpll.mgr->update_ref_clks(display);
4544}
4545
4546void intel_dpll_readout_hw_state(struct intel_display *display)
4547{
4548 struct intel_dpll *pll;
4549 int i;
4550
4551 for_each_dpll(display, pll, i)
4552 readout_dpll_hw_state(display, pll);
4553}
4554
4555static void sanitize_dpll_state(struct intel_display *display,
4556 struct intel_dpll *pll)
4557{
4558 if (!pll->on)
4559 return;
4560
4561 adlp_cmtg_clock_gating_wa(display, pll);
4562
4563 if (pll->active_mask)
4564 return;
4565
4566 drm_dbg_kms(display->drm,
4567 "%s enabled but not in use, disabling\n",
4568 pll->info->name);
4569
4570 _intel_disable_shared_dpll(display, pll);
4571}
4572
4573void intel_dpll_sanitize_state(struct intel_display *display)
4574{
4575 struct intel_dpll *pll;
4576 int i;
4577
4578 intel_cx0_pll_power_save_wa(display);
4579
4580 for_each_dpll(display, pll, i)
4581 sanitize_dpll_state(display, pll);
4582}
4583
4584/**
4585 * intel_dpll_dump_hw_state - dump hw_state
4586 * @display: intel_display structure
4587 * @p: where to print the state to
4588 * @dpll_hw_state: hw state to be dumped
4589 *
4590 * Dumo out the relevant values in @dpll_hw_state.
4591 */
4592void intel_dpll_dump_hw_state(struct intel_display *display,
4593 struct drm_printer *p,
4594 const struct intel_dpll_hw_state *dpll_hw_state)
4595{
4596 if (display->dpll.mgr) {
4597 display->dpll.mgr->dump_hw_state(p, dpll_hw_state);
4598 } else {
4599 /* fallback for platforms that don't use the shared dpll
4600 * infrastructure
4601 */
4602 ibx_dump_hw_state(p, dpll_hw_state);
4603 }
4604}
4605
4606/**
4607 * intel_dpll_compare_hw_state - compare the two states
4608 * @display: intel_display structure
4609 * @a: first DPLL hw state
4610 * @b: second DPLL hw state
4611 *
4612 * Compare DPLL hw states @a and @b.
4613 *
4614 * Returns: true if the states are equal, false if the differ
4615 */
4616bool intel_dpll_compare_hw_state(struct intel_display *display,
4617 const struct intel_dpll_hw_state *a,
4618 const struct intel_dpll_hw_state *b)
4619{
4620 if (display->dpll.mgr) {
4621 return display->dpll.mgr->compare_hw_state(a, b);
4622 } else {
4623 /* fallback for platforms that don't use the shared dpll
4624 * infrastructure
4625 */
4626 return ibx_compare_hw_state(a: a, b: b);
4627 }
4628}
4629
4630static void
4631verify_single_dpll_state(struct intel_display *display,
4632 struct intel_dpll *pll,
4633 struct intel_crtc *crtc,
4634 const struct intel_crtc_state *new_crtc_state)
4635{
4636 struct intel_dpll_hw_state dpll_hw_state = {};
4637 u8 pipe_mask;
4638 bool active;
4639
4640 active = intel_dpll_get_hw_state(display, pll, dpll_hw_state: &dpll_hw_state);
4641
4642 if (!pll->info->always_on) {
4643 INTEL_DISPLAY_STATE_WARN(display, !pll->on && pll->active_mask,
4644 "%s: pll in active use but not on in sw tracking\n",
4645 pll->info->name);
4646 INTEL_DISPLAY_STATE_WARN(display, pll->on && !pll->active_mask,
4647 "%s: pll is on but not used by any active pipe\n",
4648 pll->info->name);
4649 INTEL_DISPLAY_STATE_WARN(display, pll->on != active,
4650 "%s: pll on state mismatch (expected %i, found %i)\n",
4651 pll->info->name, pll->on, active);
4652 }
4653
4654 if (!crtc) {
4655 INTEL_DISPLAY_STATE_WARN(display,
4656 pll->active_mask & ~pll->state.pipe_mask,
4657 "%s: more active pll users than references: 0x%x vs 0x%x\n",
4658 pll->info->name, pll->active_mask, pll->state.pipe_mask);
4659
4660 return;
4661 }
4662
4663 pipe_mask = BIT(crtc->pipe);
4664
4665 if (new_crtc_state->hw.active)
4666 INTEL_DISPLAY_STATE_WARN(display, !(pll->active_mask & pipe_mask),
4667 "%s: pll active mismatch (expected pipe %c in active mask 0x%x)\n",
4668 pll->info->name, pipe_name(crtc->pipe), pll->active_mask);
4669 else
4670 INTEL_DISPLAY_STATE_WARN(display, pll->active_mask & pipe_mask,
4671 "%s: pll active mismatch (didn't expect pipe %c in active mask 0x%x)\n",
4672 pll->info->name, pipe_name(crtc->pipe), pll->active_mask);
4673
4674 INTEL_DISPLAY_STATE_WARN(display, !(pll->state.pipe_mask & pipe_mask),
4675 "%s: pll enabled crtcs mismatch (expected 0x%x in 0x%x)\n",
4676 pll->info->name, pipe_mask, pll->state.pipe_mask);
4677
4678 INTEL_DISPLAY_STATE_WARN(display,
4679 pll->on && memcmp(&pll->state.hw_state, &dpll_hw_state,
4680 sizeof(dpll_hw_state)),
4681 "%s: pll hw state mismatch\n",
4682 pll->info->name);
4683}
4684
4685static bool has_alt_port_dpll(const struct intel_dpll *old_pll,
4686 const struct intel_dpll *new_pll)
4687{
4688 return old_pll && new_pll && old_pll != new_pll &&
4689 (old_pll->info->is_alt_port_dpll || new_pll->info->is_alt_port_dpll);
4690}
4691
4692void intel_dpll_state_verify(struct intel_atomic_state *state,
4693 struct intel_crtc *crtc)
4694{
4695 struct intel_display *display = to_intel_display(state);
4696 const struct intel_crtc_state *old_crtc_state =
4697 intel_atomic_get_old_crtc_state(state, crtc);
4698 const struct intel_crtc_state *new_crtc_state =
4699 intel_atomic_get_new_crtc_state(state, crtc);
4700
4701 if (new_crtc_state->intel_dpll)
4702 verify_single_dpll_state(display, pll: new_crtc_state->intel_dpll,
4703 crtc, new_crtc_state);
4704
4705 if (old_crtc_state->intel_dpll &&
4706 old_crtc_state->intel_dpll != new_crtc_state->intel_dpll) {
4707 u8 pipe_mask = BIT(crtc->pipe);
4708 struct intel_dpll *pll = old_crtc_state->intel_dpll;
4709
4710 INTEL_DISPLAY_STATE_WARN(display, pll->active_mask & pipe_mask,
4711 "%s: pll active mismatch (didn't expect pipe %c in active mask (0x%x))\n",
4712 pll->info->name, pipe_name(crtc->pipe), pll->active_mask);
4713
4714 /* TC ports have both MG/TC and TBT PLL referenced simultaneously */
4715 INTEL_DISPLAY_STATE_WARN(display, !has_alt_port_dpll(old_crtc_state->intel_dpll,
4716 new_crtc_state->intel_dpll) &&
4717 pll->state.pipe_mask & pipe_mask,
4718 "%s: pll enabled crtcs mismatch (found pipe %c in enabled mask (0x%x))\n",
4719 pll->info->name, pipe_name(crtc->pipe), pll->state.pipe_mask);
4720 }
4721}
4722
4723void intel_dpll_verify_disabled(struct intel_atomic_state *state)
4724{
4725 struct intel_display *display = to_intel_display(state);
4726 struct intel_dpll *pll;
4727 int i;
4728
4729 for_each_dpll(display, pll, i)
4730 verify_single_dpll_state(display, pll, NULL, NULL);
4731}
4732

source code of linux/drivers/gpu/drm/i915/display/intel_dpll_mgr.c