xref: /openbsd-src/sys/dev/pci/drm/i915/display/intel_dpll.c (revision f005ef32267c16bdb134f0e9fa4477dbe07c263a)
15ca02815Sjsg // SPDX-License-Identifier: MIT
25ca02815Sjsg /*
35ca02815Sjsg  * Copyright © 2020 Intel Corporation
45ca02815Sjsg  */
51bb76ff1Sjsg 
65ca02815Sjsg #include <linux/kernel.h>
71bb76ff1Sjsg #include <linux/string_helpers.h>
81bb76ff1Sjsg 
9*f005ef32Sjsg #include "i915_reg.h"
105ca02815Sjsg #include "intel_crtc.h"
11*f005ef32Sjsg #include "intel_cx0_phy.h"
125ca02815Sjsg #include "intel_de.h"
135ca02815Sjsg #include "intel_display.h"
141bb76ff1Sjsg #include "intel_display_types.h"
15*f005ef32Sjsg #include "intel_dpio_phy.h"
165ca02815Sjsg #include "intel_dpll.h"
175ca02815Sjsg #include "intel_lvds.h"
185ca02815Sjsg #include "intel_panel.h"
191bb76ff1Sjsg #include "intel_pps.h"
201bb76ff1Sjsg #include "intel_snps_phy.h"
211bb76ff1Sjsg #include "vlv_sideband.h"
221bb76ff1Sjsg 
231bb76ff1Sjsg struct intel_dpll_funcs {
241bb76ff1Sjsg 	int (*crtc_compute_clock)(struct intel_atomic_state *state,
251bb76ff1Sjsg 				  struct intel_crtc *crtc);
261bb76ff1Sjsg 	int (*crtc_get_shared_dpll)(struct intel_atomic_state *state,
271bb76ff1Sjsg 				    struct intel_crtc *crtc);
281bb76ff1Sjsg };
295ca02815Sjsg 
305ca02815Sjsg struct intel_limit {
315ca02815Sjsg 	struct {
325ca02815Sjsg 		int min, max;
335ca02815Sjsg 	} dot, vco, n, m, m1, m2, p, p1;
345ca02815Sjsg 
355ca02815Sjsg 	struct {
365ca02815Sjsg 		int dot_limit;
375ca02815Sjsg 		int p2_slow, p2_fast;
385ca02815Sjsg 	} p2;
395ca02815Sjsg };
405ca02815Sjsg static const struct intel_limit intel_limits_i8xx_dac = {
415ca02815Sjsg 	.dot = { .min = 25000, .max = 350000 },
425ca02815Sjsg 	.vco = { .min = 908000, .max = 1512000 },
435ca02815Sjsg 	.n = { .min = 2, .max = 16 },
445ca02815Sjsg 	.m = { .min = 96, .max = 140 },
455ca02815Sjsg 	.m1 = { .min = 18, .max = 26 },
465ca02815Sjsg 	.m2 = { .min = 6, .max = 16 },
475ca02815Sjsg 	.p = { .min = 4, .max = 128 },
485ca02815Sjsg 	.p1 = { .min = 2, .max = 33 },
495ca02815Sjsg 	.p2 = { .dot_limit = 165000,
505ca02815Sjsg 		.p2_slow = 4, .p2_fast = 2 },
515ca02815Sjsg };
525ca02815Sjsg 
535ca02815Sjsg static const struct intel_limit intel_limits_i8xx_dvo = {
545ca02815Sjsg 	.dot = { .min = 25000, .max = 350000 },
555ca02815Sjsg 	.vco = { .min = 908000, .max = 1512000 },
565ca02815Sjsg 	.n = { .min = 2, .max = 16 },
575ca02815Sjsg 	.m = { .min = 96, .max = 140 },
585ca02815Sjsg 	.m1 = { .min = 18, .max = 26 },
595ca02815Sjsg 	.m2 = { .min = 6, .max = 16 },
605ca02815Sjsg 	.p = { .min = 4, .max = 128 },
615ca02815Sjsg 	.p1 = { .min = 2, .max = 33 },
625ca02815Sjsg 	.p2 = { .dot_limit = 165000,
635ca02815Sjsg 		.p2_slow = 4, .p2_fast = 4 },
645ca02815Sjsg };
655ca02815Sjsg 
665ca02815Sjsg static const struct intel_limit intel_limits_i8xx_lvds = {
675ca02815Sjsg 	.dot = { .min = 25000, .max = 350000 },
685ca02815Sjsg 	.vco = { .min = 908000, .max = 1512000 },
695ca02815Sjsg 	.n = { .min = 2, .max = 16 },
705ca02815Sjsg 	.m = { .min = 96, .max = 140 },
715ca02815Sjsg 	.m1 = { .min = 18, .max = 26 },
725ca02815Sjsg 	.m2 = { .min = 6, .max = 16 },
735ca02815Sjsg 	.p = { .min = 4, .max = 128 },
745ca02815Sjsg 	.p1 = { .min = 1, .max = 6 },
755ca02815Sjsg 	.p2 = { .dot_limit = 165000,
765ca02815Sjsg 		.p2_slow = 14, .p2_fast = 7 },
775ca02815Sjsg };
785ca02815Sjsg 
795ca02815Sjsg static const struct intel_limit intel_limits_i9xx_sdvo = {
805ca02815Sjsg 	.dot = { .min = 20000, .max = 400000 },
815ca02815Sjsg 	.vco = { .min = 1400000, .max = 2800000 },
825ca02815Sjsg 	.n = { .min = 1, .max = 6 },
835ca02815Sjsg 	.m = { .min = 70, .max = 120 },
845ca02815Sjsg 	.m1 = { .min = 8, .max = 18 },
855ca02815Sjsg 	.m2 = { .min = 3, .max = 7 },
865ca02815Sjsg 	.p = { .min = 5, .max = 80 },
875ca02815Sjsg 	.p1 = { .min = 1, .max = 8 },
885ca02815Sjsg 	.p2 = { .dot_limit = 200000,
895ca02815Sjsg 		.p2_slow = 10, .p2_fast = 5 },
905ca02815Sjsg };
915ca02815Sjsg 
925ca02815Sjsg static const struct intel_limit intel_limits_i9xx_lvds = {
935ca02815Sjsg 	.dot = { .min = 20000, .max = 400000 },
945ca02815Sjsg 	.vco = { .min = 1400000, .max = 2800000 },
955ca02815Sjsg 	.n = { .min = 1, .max = 6 },
965ca02815Sjsg 	.m = { .min = 70, .max = 120 },
975ca02815Sjsg 	.m1 = { .min = 8, .max = 18 },
985ca02815Sjsg 	.m2 = { .min = 3, .max = 7 },
995ca02815Sjsg 	.p = { .min = 7, .max = 98 },
1005ca02815Sjsg 	.p1 = { .min = 1, .max = 8 },
1015ca02815Sjsg 	.p2 = { .dot_limit = 112000,
1025ca02815Sjsg 		.p2_slow = 14, .p2_fast = 7 },
1035ca02815Sjsg };
1045ca02815Sjsg 
1055ca02815Sjsg 
1065ca02815Sjsg static const struct intel_limit intel_limits_g4x_sdvo = {
1075ca02815Sjsg 	.dot = { .min = 25000, .max = 270000 },
1085ca02815Sjsg 	.vco = { .min = 1750000, .max = 3500000},
1095ca02815Sjsg 	.n = { .min = 1, .max = 4 },
1105ca02815Sjsg 	.m = { .min = 104, .max = 138 },
1115ca02815Sjsg 	.m1 = { .min = 17, .max = 23 },
1125ca02815Sjsg 	.m2 = { .min = 5, .max = 11 },
1135ca02815Sjsg 	.p = { .min = 10, .max = 30 },
1145ca02815Sjsg 	.p1 = { .min = 1, .max = 3},
1155ca02815Sjsg 	.p2 = { .dot_limit = 270000,
1165ca02815Sjsg 		.p2_slow = 10,
1175ca02815Sjsg 		.p2_fast = 10
1185ca02815Sjsg 	},
1195ca02815Sjsg };
1205ca02815Sjsg 
1215ca02815Sjsg static const struct intel_limit intel_limits_g4x_hdmi = {
1225ca02815Sjsg 	.dot = { .min = 22000, .max = 400000 },
1235ca02815Sjsg 	.vco = { .min = 1750000, .max = 3500000},
1245ca02815Sjsg 	.n = { .min = 1, .max = 4 },
1255ca02815Sjsg 	.m = { .min = 104, .max = 138 },
1265ca02815Sjsg 	.m1 = { .min = 16, .max = 23 },
1275ca02815Sjsg 	.m2 = { .min = 5, .max = 11 },
1285ca02815Sjsg 	.p = { .min = 5, .max = 80 },
1295ca02815Sjsg 	.p1 = { .min = 1, .max = 8},
1305ca02815Sjsg 	.p2 = { .dot_limit = 165000,
1315ca02815Sjsg 		.p2_slow = 10, .p2_fast = 5 },
1325ca02815Sjsg };
1335ca02815Sjsg 
1345ca02815Sjsg static const struct intel_limit intel_limits_g4x_single_channel_lvds = {
1355ca02815Sjsg 	.dot = { .min = 20000, .max = 115000 },
1365ca02815Sjsg 	.vco = { .min = 1750000, .max = 3500000 },
1375ca02815Sjsg 	.n = { .min = 1, .max = 3 },
1385ca02815Sjsg 	.m = { .min = 104, .max = 138 },
1395ca02815Sjsg 	.m1 = { .min = 17, .max = 23 },
1405ca02815Sjsg 	.m2 = { .min = 5, .max = 11 },
1415ca02815Sjsg 	.p = { .min = 28, .max = 112 },
1425ca02815Sjsg 	.p1 = { .min = 2, .max = 8 },
1435ca02815Sjsg 	.p2 = { .dot_limit = 0,
1445ca02815Sjsg 		.p2_slow = 14, .p2_fast = 14
1455ca02815Sjsg 	},
1465ca02815Sjsg };
1475ca02815Sjsg 
1485ca02815Sjsg static const struct intel_limit intel_limits_g4x_dual_channel_lvds = {
1495ca02815Sjsg 	.dot = { .min = 80000, .max = 224000 },
1505ca02815Sjsg 	.vco = { .min = 1750000, .max = 3500000 },
1515ca02815Sjsg 	.n = { .min = 1, .max = 3 },
1525ca02815Sjsg 	.m = { .min = 104, .max = 138 },
1535ca02815Sjsg 	.m1 = { .min = 17, .max = 23 },
1545ca02815Sjsg 	.m2 = { .min = 5, .max = 11 },
1555ca02815Sjsg 	.p = { .min = 14, .max = 42 },
1565ca02815Sjsg 	.p1 = { .min = 2, .max = 6 },
1575ca02815Sjsg 	.p2 = { .dot_limit = 0,
1585ca02815Sjsg 		.p2_slow = 7, .p2_fast = 7
1595ca02815Sjsg 	},
1605ca02815Sjsg };
1615ca02815Sjsg 
1625ca02815Sjsg static const struct intel_limit pnv_limits_sdvo = {
1635ca02815Sjsg 	.dot = { .min = 20000, .max = 400000},
1645ca02815Sjsg 	.vco = { .min = 1700000, .max = 3500000 },
1655ca02815Sjsg 	/* Pineview's Ncounter is a ring counter */
1665ca02815Sjsg 	.n = { .min = 3, .max = 6 },
1675ca02815Sjsg 	.m = { .min = 2, .max = 256 },
1685ca02815Sjsg 	/* Pineview only has one combined m divider, which we treat as m2. */
1695ca02815Sjsg 	.m1 = { .min = 0, .max = 0 },
1705ca02815Sjsg 	.m2 = { .min = 0, .max = 254 },
1715ca02815Sjsg 	.p = { .min = 5, .max = 80 },
1725ca02815Sjsg 	.p1 = { .min = 1, .max = 8 },
1735ca02815Sjsg 	.p2 = { .dot_limit = 200000,
1745ca02815Sjsg 		.p2_slow = 10, .p2_fast = 5 },
1755ca02815Sjsg };
1765ca02815Sjsg 
1775ca02815Sjsg static const struct intel_limit pnv_limits_lvds = {
1785ca02815Sjsg 	.dot = { .min = 20000, .max = 400000 },
1795ca02815Sjsg 	.vco = { .min = 1700000, .max = 3500000 },
1805ca02815Sjsg 	.n = { .min = 3, .max = 6 },
1815ca02815Sjsg 	.m = { .min = 2, .max = 256 },
1825ca02815Sjsg 	.m1 = { .min = 0, .max = 0 },
1835ca02815Sjsg 	.m2 = { .min = 0, .max = 254 },
1845ca02815Sjsg 	.p = { .min = 7, .max = 112 },
1855ca02815Sjsg 	.p1 = { .min = 1, .max = 8 },
1865ca02815Sjsg 	.p2 = { .dot_limit = 112000,
1875ca02815Sjsg 		.p2_slow = 14, .p2_fast = 14 },
1885ca02815Sjsg };
1895ca02815Sjsg 
1905ca02815Sjsg /* Ironlake / Sandybridge
1915ca02815Sjsg  *
1925ca02815Sjsg  * We calculate clock using (register_value + 2) for N/M1/M2, so here
1935ca02815Sjsg  * the range value for them is (actual_value - 2).
1945ca02815Sjsg  */
1955ca02815Sjsg static const struct intel_limit ilk_limits_dac = {
1965ca02815Sjsg 	.dot = { .min = 25000, .max = 350000 },
1975ca02815Sjsg 	.vco = { .min = 1760000, .max = 3510000 },
1985ca02815Sjsg 	.n = { .min = 1, .max = 5 },
1995ca02815Sjsg 	.m = { .min = 79, .max = 127 },
2005ca02815Sjsg 	.m1 = { .min = 12, .max = 22 },
2015ca02815Sjsg 	.m2 = { .min = 5, .max = 9 },
2025ca02815Sjsg 	.p = { .min = 5, .max = 80 },
2035ca02815Sjsg 	.p1 = { .min = 1, .max = 8 },
2045ca02815Sjsg 	.p2 = { .dot_limit = 225000,
2055ca02815Sjsg 		.p2_slow = 10, .p2_fast = 5 },
2065ca02815Sjsg };
2075ca02815Sjsg 
2085ca02815Sjsg static const struct intel_limit ilk_limits_single_lvds = {
2095ca02815Sjsg 	.dot = { .min = 25000, .max = 350000 },
2105ca02815Sjsg 	.vco = { .min = 1760000, .max = 3510000 },
2115ca02815Sjsg 	.n = { .min = 1, .max = 3 },
2125ca02815Sjsg 	.m = { .min = 79, .max = 118 },
2135ca02815Sjsg 	.m1 = { .min = 12, .max = 22 },
2145ca02815Sjsg 	.m2 = { .min = 5, .max = 9 },
2155ca02815Sjsg 	.p = { .min = 28, .max = 112 },
2165ca02815Sjsg 	.p1 = { .min = 2, .max = 8 },
2175ca02815Sjsg 	.p2 = { .dot_limit = 225000,
2185ca02815Sjsg 		.p2_slow = 14, .p2_fast = 14 },
2195ca02815Sjsg };
2205ca02815Sjsg 
2215ca02815Sjsg static const struct intel_limit ilk_limits_dual_lvds = {
2225ca02815Sjsg 	.dot = { .min = 25000, .max = 350000 },
2235ca02815Sjsg 	.vco = { .min = 1760000, .max = 3510000 },
2245ca02815Sjsg 	.n = { .min = 1, .max = 3 },
2255ca02815Sjsg 	.m = { .min = 79, .max = 127 },
2265ca02815Sjsg 	.m1 = { .min = 12, .max = 22 },
2275ca02815Sjsg 	.m2 = { .min = 5, .max = 9 },
2285ca02815Sjsg 	.p = { .min = 14, .max = 56 },
2295ca02815Sjsg 	.p1 = { .min = 2, .max = 8 },
2305ca02815Sjsg 	.p2 = { .dot_limit = 225000,
2315ca02815Sjsg 		.p2_slow = 7, .p2_fast = 7 },
2325ca02815Sjsg };
2335ca02815Sjsg 
2345ca02815Sjsg /* LVDS 100mhz refclk limits. */
2355ca02815Sjsg static const struct intel_limit ilk_limits_single_lvds_100m = {
2365ca02815Sjsg 	.dot = { .min = 25000, .max = 350000 },
2375ca02815Sjsg 	.vco = { .min = 1760000, .max = 3510000 },
2385ca02815Sjsg 	.n = { .min = 1, .max = 2 },
2395ca02815Sjsg 	.m = { .min = 79, .max = 126 },
2405ca02815Sjsg 	.m1 = { .min = 12, .max = 22 },
2415ca02815Sjsg 	.m2 = { .min = 5, .max = 9 },
2425ca02815Sjsg 	.p = { .min = 28, .max = 112 },
2435ca02815Sjsg 	.p1 = { .min = 2, .max = 8 },
2445ca02815Sjsg 	.p2 = { .dot_limit = 225000,
2455ca02815Sjsg 		.p2_slow = 14, .p2_fast = 14 },
2465ca02815Sjsg };
2475ca02815Sjsg 
2485ca02815Sjsg static const struct intel_limit ilk_limits_dual_lvds_100m = {
2495ca02815Sjsg 	.dot = { .min = 25000, .max = 350000 },
2505ca02815Sjsg 	.vco = { .min = 1760000, .max = 3510000 },
2515ca02815Sjsg 	.n = { .min = 1, .max = 3 },
2525ca02815Sjsg 	.m = { .min = 79, .max = 126 },
2535ca02815Sjsg 	.m1 = { .min = 12, .max = 22 },
2545ca02815Sjsg 	.m2 = { .min = 5, .max = 9 },
2555ca02815Sjsg 	.p = { .min = 14, .max = 42 },
2565ca02815Sjsg 	.p1 = { .min = 2, .max = 6 },
2575ca02815Sjsg 	.p2 = { .dot_limit = 225000,
2585ca02815Sjsg 		.p2_slow = 7, .p2_fast = 7 },
2595ca02815Sjsg };
2605ca02815Sjsg 
2615ca02815Sjsg static const struct intel_limit intel_limits_vlv = {
2625ca02815Sjsg 	 /*
2631bb76ff1Sjsg 	  * These are based on the data rate limits (measured in fast clocks)
2645ca02815Sjsg 	  * since those are the strictest limits we have. The fast
2655ca02815Sjsg 	  * clock and actual rate limits are more relaxed, so checking
2665ca02815Sjsg 	  * them would make no difference.
2675ca02815Sjsg 	  */
2681bb76ff1Sjsg 	.dot = { .min = 25000, .max = 270000 },
2695ca02815Sjsg 	.vco = { .min = 4000000, .max = 6000000 },
2705ca02815Sjsg 	.n = { .min = 1, .max = 7 },
2715ca02815Sjsg 	.m1 = { .min = 2, .max = 3 },
2725ca02815Sjsg 	.m2 = { .min = 11, .max = 156 },
2735ca02815Sjsg 	.p1 = { .min = 2, .max = 3 },
2745ca02815Sjsg 	.p2 = { .p2_slow = 2, .p2_fast = 20 }, /* slow=min, fast=max */
2755ca02815Sjsg };
2765ca02815Sjsg 
2775ca02815Sjsg static const struct intel_limit intel_limits_chv = {
2785ca02815Sjsg 	/*
2791bb76ff1Sjsg 	 * These are based on the data rate limits (measured in fast clocks)
2805ca02815Sjsg 	 * since those are the strictest limits we have.  The fast
2815ca02815Sjsg 	 * clock and actual rate limits are more relaxed, so checking
2825ca02815Sjsg 	 * them would make no difference.
2835ca02815Sjsg 	 */
2841bb76ff1Sjsg 	.dot = { .min = 25000, .max = 540000 },
2855ca02815Sjsg 	.vco = { .min = 4800000, .max = 6480000 },
2865ca02815Sjsg 	.n = { .min = 1, .max = 1 },
2875ca02815Sjsg 	.m1 = { .min = 2, .max = 2 },
2885ca02815Sjsg 	.m2 = { .min = 24 << 22, .max = 175 << 22 },
2895ca02815Sjsg 	.p1 = { .min = 2, .max = 4 },
2905ca02815Sjsg 	.p2 = {	.p2_slow = 1, .p2_fast = 14 },
2915ca02815Sjsg };
2925ca02815Sjsg 
2935ca02815Sjsg static const struct intel_limit intel_limits_bxt = {
2941bb76ff1Sjsg 	.dot = { .min = 25000, .max = 594000 },
2955ca02815Sjsg 	.vco = { .min = 4800000, .max = 6700000 },
2965ca02815Sjsg 	.n = { .min = 1, .max = 1 },
2975ca02815Sjsg 	.m1 = { .min = 2, .max = 2 },
2985ca02815Sjsg 	/* FIXME: find real m2 limits */
2995ca02815Sjsg 	.m2 = { .min = 2 << 22, .max = 255 << 22 },
3005ca02815Sjsg 	.p1 = { .min = 2, .max = 4 },
3015ca02815Sjsg 	.p2 = { .p2_slow = 1, .p2_fast = 20 },
3025ca02815Sjsg };
3035ca02815Sjsg 
3045ca02815Sjsg /*
3055ca02815Sjsg  * Platform specific helpers to calculate the port PLL loopback- (clock.m),
3065ca02815Sjsg  * and post-divider (clock.p) values, pre- (clock.vco) and post-divided fast
3075ca02815Sjsg  * (clock.dot) clock rates. This fast dot clock is fed to the port's IO logic.
3085ca02815Sjsg  * The helpers' return value is the rate of the clock that is fed to the
3095ca02815Sjsg  * display engine's pipe which can be the above fast dot clock rate or a
3105ca02815Sjsg  * divided-down version of it.
3115ca02815Sjsg  */
3125ca02815Sjsg /* m1 is reserved as 0 in Pineview, n is a ring counter */
pnv_calc_dpll_params(int refclk,struct dpll * clock)3135ca02815Sjsg int pnv_calc_dpll_params(int refclk, struct dpll *clock)
3145ca02815Sjsg {
3155ca02815Sjsg 	clock->m = clock->m2 + 2;
3165ca02815Sjsg 	clock->p = clock->p1 * clock->p2;
3175ca02815Sjsg 	if (WARN_ON(clock->n == 0 || clock->p == 0))
3185ca02815Sjsg 		return 0;
3195ca02815Sjsg 	clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n);
3205ca02815Sjsg 	clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
3215ca02815Sjsg 
3225ca02815Sjsg 	return clock->dot;
3235ca02815Sjsg }
3245ca02815Sjsg 
i9xx_dpll_compute_m(const struct dpll * dpll)3251bb76ff1Sjsg static u32 i9xx_dpll_compute_m(const struct dpll *dpll)
3265ca02815Sjsg {
3275ca02815Sjsg 	return 5 * (dpll->m1 + 2) + (dpll->m2 + 2);
3285ca02815Sjsg }
3295ca02815Sjsg 
i9xx_calc_dpll_params(int refclk,struct dpll * clock)3305ca02815Sjsg int i9xx_calc_dpll_params(int refclk, struct dpll *clock)
3315ca02815Sjsg {
3325ca02815Sjsg 	clock->m = i9xx_dpll_compute_m(clock);
3335ca02815Sjsg 	clock->p = clock->p1 * clock->p2;
3345ca02815Sjsg 	if (WARN_ON(clock->n + 2 == 0 || clock->p == 0))
3355ca02815Sjsg 		return 0;
3365ca02815Sjsg 	clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n + 2);
3375ca02815Sjsg 	clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
3385ca02815Sjsg 
3395ca02815Sjsg 	return clock->dot;
3405ca02815Sjsg }
3415ca02815Sjsg 
vlv_calc_dpll_params(int refclk,struct dpll * clock)3425ca02815Sjsg int vlv_calc_dpll_params(int refclk, struct dpll *clock)
3435ca02815Sjsg {
3445ca02815Sjsg 	clock->m = clock->m1 * clock->m2;
3451bb76ff1Sjsg 	clock->p = clock->p1 * clock->p2 * 5;
3465ca02815Sjsg 	if (WARN_ON(clock->n == 0 || clock->p == 0))
3475ca02815Sjsg 		return 0;
3485ca02815Sjsg 	clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n);
3495ca02815Sjsg 	clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
3505ca02815Sjsg 
3511bb76ff1Sjsg 	return clock->dot;
3525ca02815Sjsg }
3535ca02815Sjsg 
chv_calc_dpll_params(int refclk,struct dpll * clock)3545ca02815Sjsg int chv_calc_dpll_params(int refclk, struct dpll *clock)
3555ca02815Sjsg {
3565ca02815Sjsg 	clock->m = clock->m1 * clock->m2;
3571bb76ff1Sjsg 	clock->p = clock->p1 * clock->p2 * 5;
3585ca02815Sjsg 	if (WARN_ON(clock->n == 0 || clock->p == 0))
3595ca02815Sjsg 		return 0;
3605ca02815Sjsg 	clock->vco = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(refclk, clock->m),
3615ca02815Sjsg 					   clock->n << 22);
3625ca02815Sjsg 	clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
3635ca02815Sjsg 
3641bb76ff1Sjsg 	return clock->dot;
3655ca02815Sjsg }
3665ca02815Sjsg 
3675ca02815Sjsg /*
3685ca02815Sjsg  * Returns whether the given set of divisors are valid for a given refclk with
3695ca02815Sjsg  * the given connectors.
3705ca02815Sjsg  */
intel_pll_is_valid(struct drm_i915_private * dev_priv,const struct intel_limit * limit,const struct dpll * clock)3715ca02815Sjsg static bool intel_pll_is_valid(struct drm_i915_private *dev_priv,
3725ca02815Sjsg 			       const struct intel_limit *limit,
3735ca02815Sjsg 			       const struct dpll *clock)
3745ca02815Sjsg {
3755ca02815Sjsg 	if (clock->n < limit->n.min || limit->n.max < clock->n)
3765ca02815Sjsg 		return false;
3775ca02815Sjsg 	if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
3785ca02815Sjsg 		return false;
3795ca02815Sjsg 	if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
3805ca02815Sjsg 		return false;
3815ca02815Sjsg 	if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
3825ca02815Sjsg 		return false;
3835ca02815Sjsg 
3845ca02815Sjsg 	if (!IS_PINEVIEW(dev_priv) && !IS_LP(dev_priv))
3855ca02815Sjsg 		if (clock->m1 <= clock->m2)
3865ca02815Sjsg 			return false;
3875ca02815Sjsg 
3885ca02815Sjsg 	if (!IS_LP(dev_priv)) {
3895ca02815Sjsg 		if (clock->p < limit->p.min || limit->p.max < clock->p)
3905ca02815Sjsg 			return false;
3915ca02815Sjsg 		if (clock->m < limit->m.min || limit->m.max < clock->m)
3925ca02815Sjsg 			return false;
3935ca02815Sjsg 	}
3945ca02815Sjsg 
3955ca02815Sjsg 	if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
3965ca02815Sjsg 		return false;
3975ca02815Sjsg 	/* XXX: We may need to be checking "Dot clock" depending on the multiplier,
3985ca02815Sjsg 	 * connector, etc., rather than just a single range.
3995ca02815Sjsg 	 */
4005ca02815Sjsg 	if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
4015ca02815Sjsg 		return false;
4025ca02815Sjsg 
4035ca02815Sjsg 	return true;
4045ca02815Sjsg }
4055ca02815Sjsg 
4065ca02815Sjsg static int
i9xx_select_p2_div(const struct intel_limit * limit,const struct intel_crtc_state * crtc_state,int target)4075ca02815Sjsg i9xx_select_p2_div(const struct intel_limit *limit,
4085ca02815Sjsg 		   const struct intel_crtc_state *crtc_state,
4095ca02815Sjsg 		   int target)
4105ca02815Sjsg {
4115ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
4125ca02815Sjsg 
4135ca02815Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
4145ca02815Sjsg 		/*
4155ca02815Sjsg 		 * For LVDS just rely on its current settings for dual-channel.
4165ca02815Sjsg 		 * We haven't figured out how to reliably set up different
4175ca02815Sjsg 		 * single/dual channel state, if we even can.
4185ca02815Sjsg 		 */
4195ca02815Sjsg 		if (intel_is_dual_link_lvds(dev_priv))
4205ca02815Sjsg 			return limit->p2.p2_fast;
4215ca02815Sjsg 		else
4225ca02815Sjsg 			return limit->p2.p2_slow;
4235ca02815Sjsg 	} else {
4245ca02815Sjsg 		if (target < limit->p2.dot_limit)
4255ca02815Sjsg 			return limit->p2.p2_slow;
4265ca02815Sjsg 		else
4275ca02815Sjsg 			return limit->p2.p2_fast;
4285ca02815Sjsg 	}
4295ca02815Sjsg }
4305ca02815Sjsg 
4315ca02815Sjsg /*
4325ca02815Sjsg  * Returns a set of divisors for the desired target clock with the given
4331bb76ff1Sjsg  * refclk, or FALSE.
4345ca02815Sjsg  *
4355ca02815Sjsg  * Target and reference clocks are specified in kHz.
4365ca02815Sjsg  *
4375ca02815Sjsg  * If match_clock is provided, then best_clock P divider must match the P
4385ca02815Sjsg  * divider from @match_clock used for LVDS downclocking.
4395ca02815Sjsg  */
4405ca02815Sjsg static bool
i9xx_find_best_dpll(const struct intel_limit * limit,struct intel_crtc_state * crtc_state,int target,int refclk,const struct dpll * match_clock,struct dpll * best_clock)4415ca02815Sjsg i9xx_find_best_dpll(const struct intel_limit *limit,
4425ca02815Sjsg 		    struct intel_crtc_state *crtc_state,
4431bb76ff1Sjsg 		    int target, int refclk,
4441bb76ff1Sjsg 		    const struct dpll *match_clock,
4455ca02815Sjsg 		    struct dpll *best_clock)
4465ca02815Sjsg {
4475ca02815Sjsg 	struct drm_device *dev = crtc_state->uapi.crtc->dev;
4485ca02815Sjsg 	struct dpll clock;
4495ca02815Sjsg 	int err = target;
4505ca02815Sjsg 
4515ca02815Sjsg 	memset(best_clock, 0, sizeof(*best_clock));
4525ca02815Sjsg 
4535ca02815Sjsg 	clock.p2 = i9xx_select_p2_div(limit, crtc_state, target);
4545ca02815Sjsg 
4555ca02815Sjsg 	for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
4565ca02815Sjsg 	     clock.m1++) {
4575ca02815Sjsg 		for (clock.m2 = limit->m2.min;
4585ca02815Sjsg 		     clock.m2 <= limit->m2.max; clock.m2++) {
4595ca02815Sjsg 			if (clock.m2 >= clock.m1)
4605ca02815Sjsg 				break;
4615ca02815Sjsg 			for (clock.n = limit->n.min;
4625ca02815Sjsg 			     clock.n <= limit->n.max; clock.n++) {
4635ca02815Sjsg 				for (clock.p1 = limit->p1.min;
4645ca02815Sjsg 					clock.p1 <= limit->p1.max; clock.p1++) {
4655ca02815Sjsg 					int this_err;
4665ca02815Sjsg 
4675ca02815Sjsg 					i9xx_calc_dpll_params(refclk, &clock);
4685ca02815Sjsg 					if (!intel_pll_is_valid(to_i915(dev),
4695ca02815Sjsg 								limit,
4705ca02815Sjsg 								&clock))
4715ca02815Sjsg 						continue;
4725ca02815Sjsg 					if (match_clock &&
4735ca02815Sjsg 					    clock.p != match_clock->p)
4745ca02815Sjsg 						continue;
4755ca02815Sjsg 
4765ca02815Sjsg 					this_err = abs(clock.dot - target);
4775ca02815Sjsg 					if (this_err < err) {
4785ca02815Sjsg 						*best_clock = clock;
4795ca02815Sjsg 						err = this_err;
4805ca02815Sjsg 					}
4815ca02815Sjsg 				}
4825ca02815Sjsg 			}
4835ca02815Sjsg 		}
4845ca02815Sjsg 	}
4855ca02815Sjsg 
4865ca02815Sjsg 	return (err != target);
4875ca02815Sjsg }
4885ca02815Sjsg 
4895ca02815Sjsg /*
4905ca02815Sjsg  * Returns a set of divisors for the desired target clock with the given
4911bb76ff1Sjsg  * refclk, or FALSE.
4925ca02815Sjsg  *
4935ca02815Sjsg  * Target and reference clocks are specified in kHz.
4945ca02815Sjsg  *
4955ca02815Sjsg  * If match_clock is provided, then best_clock P divider must match the P
4965ca02815Sjsg  * divider from @match_clock used for LVDS downclocking.
4975ca02815Sjsg  */
4985ca02815Sjsg static bool
pnv_find_best_dpll(const struct intel_limit * limit,struct intel_crtc_state * crtc_state,int target,int refclk,const struct dpll * match_clock,struct dpll * best_clock)4995ca02815Sjsg pnv_find_best_dpll(const struct intel_limit *limit,
5005ca02815Sjsg 		   struct intel_crtc_state *crtc_state,
5011bb76ff1Sjsg 		   int target, int refclk,
5021bb76ff1Sjsg 		   const struct dpll *match_clock,
5035ca02815Sjsg 		   struct dpll *best_clock)
5045ca02815Sjsg {
5055ca02815Sjsg 	struct drm_device *dev = crtc_state->uapi.crtc->dev;
5065ca02815Sjsg 	struct dpll clock;
5075ca02815Sjsg 	int err = target;
5085ca02815Sjsg 
5095ca02815Sjsg 	memset(best_clock, 0, sizeof(*best_clock));
5105ca02815Sjsg 
5115ca02815Sjsg 	clock.p2 = i9xx_select_p2_div(limit, crtc_state, target);
5125ca02815Sjsg 
5135ca02815Sjsg 	for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
5145ca02815Sjsg 	     clock.m1++) {
5155ca02815Sjsg 		for (clock.m2 = limit->m2.min;
5165ca02815Sjsg 		     clock.m2 <= limit->m2.max; clock.m2++) {
5175ca02815Sjsg 			for (clock.n = limit->n.min;
5185ca02815Sjsg 			     clock.n <= limit->n.max; clock.n++) {
5195ca02815Sjsg 				for (clock.p1 = limit->p1.min;
5205ca02815Sjsg 					clock.p1 <= limit->p1.max; clock.p1++) {
5215ca02815Sjsg 					int this_err;
5225ca02815Sjsg 
5235ca02815Sjsg 					pnv_calc_dpll_params(refclk, &clock);
5245ca02815Sjsg 					if (!intel_pll_is_valid(to_i915(dev),
5255ca02815Sjsg 								limit,
5265ca02815Sjsg 								&clock))
5275ca02815Sjsg 						continue;
5285ca02815Sjsg 					if (match_clock &&
5295ca02815Sjsg 					    clock.p != match_clock->p)
5305ca02815Sjsg 						continue;
5315ca02815Sjsg 
5325ca02815Sjsg 					this_err = abs(clock.dot - target);
5335ca02815Sjsg 					if (this_err < err) {
5345ca02815Sjsg 						*best_clock = clock;
5355ca02815Sjsg 						err = this_err;
5365ca02815Sjsg 					}
5375ca02815Sjsg 				}
5385ca02815Sjsg 			}
5395ca02815Sjsg 		}
5405ca02815Sjsg 	}
5415ca02815Sjsg 
5425ca02815Sjsg 	return (err != target);
5435ca02815Sjsg }
5445ca02815Sjsg 
5455ca02815Sjsg /*
5465ca02815Sjsg  * Returns a set of divisors for the desired target clock with the given
5471bb76ff1Sjsg  * refclk, or FALSE.
5485ca02815Sjsg  *
5495ca02815Sjsg  * Target and reference clocks are specified in kHz.
5505ca02815Sjsg  *
5515ca02815Sjsg  * If match_clock is provided, then best_clock P divider must match the P
5525ca02815Sjsg  * divider from @match_clock used for LVDS downclocking.
5535ca02815Sjsg  */
5545ca02815Sjsg static bool
g4x_find_best_dpll(const struct intel_limit * limit,struct intel_crtc_state * crtc_state,int target,int refclk,const struct dpll * match_clock,struct dpll * best_clock)5555ca02815Sjsg g4x_find_best_dpll(const struct intel_limit *limit,
5565ca02815Sjsg 		   struct intel_crtc_state *crtc_state,
5571bb76ff1Sjsg 		   int target, int refclk,
5581bb76ff1Sjsg 		   const struct dpll *match_clock,
5595ca02815Sjsg 		   struct dpll *best_clock)
5605ca02815Sjsg {
5615ca02815Sjsg 	struct drm_device *dev = crtc_state->uapi.crtc->dev;
5625ca02815Sjsg 	struct dpll clock;
5635ca02815Sjsg 	int max_n;
5645ca02815Sjsg 	bool found = false;
5655ca02815Sjsg 	/* approximately equals target * 0.00585 */
5665ca02815Sjsg 	int err_most = (target >> 8) + (target >> 9);
5675ca02815Sjsg 
5685ca02815Sjsg 	memset(best_clock, 0, sizeof(*best_clock));
5695ca02815Sjsg 
5705ca02815Sjsg 	clock.p2 = i9xx_select_p2_div(limit, crtc_state, target);
5715ca02815Sjsg 
5725ca02815Sjsg 	max_n = limit->n.max;
5735ca02815Sjsg 	/* based on hardware requirement, prefer smaller n to precision */
5745ca02815Sjsg 	for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
5755ca02815Sjsg 		/* based on hardware requirement, prefere larger m1,m2 */
5765ca02815Sjsg 		for (clock.m1 = limit->m1.max;
5775ca02815Sjsg 		     clock.m1 >= limit->m1.min; clock.m1--) {
5785ca02815Sjsg 			for (clock.m2 = limit->m2.max;
5795ca02815Sjsg 			     clock.m2 >= limit->m2.min; clock.m2--) {
5805ca02815Sjsg 				for (clock.p1 = limit->p1.max;
5815ca02815Sjsg 				     clock.p1 >= limit->p1.min; clock.p1--) {
5825ca02815Sjsg 					int this_err;
5835ca02815Sjsg 
5845ca02815Sjsg 					i9xx_calc_dpll_params(refclk, &clock);
5855ca02815Sjsg 					if (!intel_pll_is_valid(to_i915(dev),
5865ca02815Sjsg 								limit,
5875ca02815Sjsg 								&clock))
5885ca02815Sjsg 						continue;
5895ca02815Sjsg 
5905ca02815Sjsg 					this_err = abs(clock.dot - target);
5915ca02815Sjsg 					if (this_err < err_most) {
5925ca02815Sjsg 						*best_clock = clock;
5935ca02815Sjsg 						err_most = this_err;
5945ca02815Sjsg 						max_n = clock.n;
5955ca02815Sjsg 						found = true;
5965ca02815Sjsg 					}
5975ca02815Sjsg 				}
5985ca02815Sjsg 			}
5995ca02815Sjsg 		}
6005ca02815Sjsg 	}
6015ca02815Sjsg 	return found;
6025ca02815Sjsg }
6035ca02815Sjsg 
6045ca02815Sjsg /*
6055ca02815Sjsg  * Check if the calculated PLL configuration is more optimal compared to the
6065ca02815Sjsg  * best configuration and error found so far. Return the calculated error.
6075ca02815Sjsg  */
vlv_PLL_is_optimal(struct drm_device * dev,int target_freq,const struct dpll * calculated_clock,const struct dpll * best_clock,unsigned int best_error_ppm,unsigned int * error_ppm)6085ca02815Sjsg static bool vlv_PLL_is_optimal(struct drm_device *dev, int target_freq,
6095ca02815Sjsg 			       const struct dpll *calculated_clock,
6105ca02815Sjsg 			       const struct dpll *best_clock,
6115ca02815Sjsg 			       unsigned int best_error_ppm,
6125ca02815Sjsg 			       unsigned int *error_ppm)
6135ca02815Sjsg {
6145ca02815Sjsg 	/*
6155ca02815Sjsg 	 * For CHV ignore the error and consider only the P value.
6165ca02815Sjsg 	 * Prefer a bigger P value based on HW requirements.
6175ca02815Sjsg 	 */
6185ca02815Sjsg 	if (IS_CHERRYVIEW(to_i915(dev))) {
6195ca02815Sjsg 		*error_ppm = 0;
6205ca02815Sjsg 
6215ca02815Sjsg 		return calculated_clock->p > best_clock->p;
6225ca02815Sjsg 	}
6235ca02815Sjsg 
6245ca02815Sjsg 	if (drm_WARN_ON_ONCE(dev, !target_freq))
6255ca02815Sjsg 		return false;
6265ca02815Sjsg 
6275ca02815Sjsg 	*error_ppm = div_u64(1000000ULL *
6285ca02815Sjsg 				abs(target_freq - calculated_clock->dot),
6295ca02815Sjsg 			     target_freq);
6305ca02815Sjsg 	/*
6315ca02815Sjsg 	 * Prefer a better P value over a better (smaller) error if the error
6325ca02815Sjsg 	 * is small. Ensure this preference for future configurations too by
6335ca02815Sjsg 	 * setting the error to 0.
6345ca02815Sjsg 	 */
6355ca02815Sjsg 	if (*error_ppm < 100 && calculated_clock->p > best_clock->p) {
6365ca02815Sjsg 		*error_ppm = 0;
6375ca02815Sjsg 
6385ca02815Sjsg 		return true;
6395ca02815Sjsg 	}
6405ca02815Sjsg 
6415ca02815Sjsg 	return *error_ppm + 10 < best_error_ppm;
6425ca02815Sjsg }
6435ca02815Sjsg 
6445ca02815Sjsg /*
6455ca02815Sjsg  * Returns a set of divisors for the desired target clock with the given
6461bb76ff1Sjsg  * refclk, or FALSE.
6475ca02815Sjsg  */
6485ca02815Sjsg static bool
vlv_find_best_dpll(const struct intel_limit * limit,struct intel_crtc_state * crtc_state,int target,int refclk,const struct dpll * match_clock,struct dpll * best_clock)6495ca02815Sjsg vlv_find_best_dpll(const struct intel_limit *limit,
6505ca02815Sjsg 		   struct intel_crtc_state *crtc_state,
6511bb76ff1Sjsg 		   int target, int refclk,
6521bb76ff1Sjsg 		   const struct dpll *match_clock,
6535ca02815Sjsg 		   struct dpll *best_clock)
6545ca02815Sjsg {
6555ca02815Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
6565ca02815Sjsg 	struct drm_device *dev = crtc->base.dev;
6575ca02815Sjsg 	struct dpll clock;
6585ca02815Sjsg 	unsigned int bestppm = 1000000;
6595ca02815Sjsg 	/* min update 19.2 MHz */
6605ca02815Sjsg 	int max_n = min(limit->n.max, refclk / 19200);
6615ca02815Sjsg 	bool found = false;
6625ca02815Sjsg 
6635ca02815Sjsg 	memset(best_clock, 0, sizeof(*best_clock));
6645ca02815Sjsg 
6655ca02815Sjsg 	/* based on hardware requirement, prefer smaller n to precision */
6665ca02815Sjsg 	for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
6675ca02815Sjsg 		for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
6685ca02815Sjsg 			for (clock.p2 = limit->p2.p2_fast; clock.p2 >= limit->p2.p2_slow;
6695ca02815Sjsg 			     clock.p2 -= clock.p2 > 10 ? 2 : 1) {
6701bb76ff1Sjsg 				clock.p = clock.p1 * clock.p2 * 5;
6715ca02815Sjsg 				/* based on hardware requirement, prefer bigger m1,m2 values */
6725ca02815Sjsg 				for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
6735ca02815Sjsg 					unsigned int ppm;
6745ca02815Sjsg 
6755ca02815Sjsg 					clock.m2 = DIV_ROUND_CLOSEST(target * clock.p * clock.n,
6765ca02815Sjsg 								     refclk * clock.m1);
6775ca02815Sjsg 
6785ca02815Sjsg 					vlv_calc_dpll_params(refclk, &clock);
6795ca02815Sjsg 
6805ca02815Sjsg 					if (!intel_pll_is_valid(to_i915(dev),
6815ca02815Sjsg 								limit,
6825ca02815Sjsg 								&clock))
6835ca02815Sjsg 						continue;
6845ca02815Sjsg 
6855ca02815Sjsg 					if (!vlv_PLL_is_optimal(dev, target,
6865ca02815Sjsg 								&clock,
6875ca02815Sjsg 								best_clock,
6885ca02815Sjsg 								bestppm, &ppm))
6895ca02815Sjsg 						continue;
6905ca02815Sjsg 
6915ca02815Sjsg 					*best_clock = clock;
6925ca02815Sjsg 					bestppm = ppm;
6935ca02815Sjsg 					found = true;
6945ca02815Sjsg 				}
6955ca02815Sjsg 			}
6965ca02815Sjsg 		}
6975ca02815Sjsg 	}
6985ca02815Sjsg 
6995ca02815Sjsg 	return found;
7005ca02815Sjsg }
7015ca02815Sjsg 
7025ca02815Sjsg /*
7035ca02815Sjsg  * Returns a set of divisors for the desired target clock with the given
7041bb76ff1Sjsg  * refclk, or FALSE.
7055ca02815Sjsg  */
7065ca02815Sjsg static bool
chv_find_best_dpll(const struct intel_limit * limit,struct intel_crtc_state * crtc_state,int target,int refclk,const struct dpll * match_clock,struct dpll * best_clock)7075ca02815Sjsg chv_find_best_dpll(const struct intel_limit *limit,
7085ca02815Sjsg 		   struct intel_crtc_state *crtc_state,
7091bb76ff1Sjsg 		   int target, int refclk,
7101bb76ff1Sjsg 		   const struct dpll *match_clock,
7115ca02815Sjsg 		   struct dpll *best_clock)
7125ca02815Sjsg {
7135ca02815Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
7145ca02815Sjsg 	struct drm_device *dev = crtc->base.dev;
7155ca02815Sjsg 	unsigned int best_error_ppm;
7165ca02815Sjsg 	struct dpll clock;
7175ca02815Sjsg 	u64 m2;
7185ca02815Sjsg 	int found = false;
7195ca02815Sjsg 
7205ca02815Sjsg 	memset(best_clock, 0, sizeof(*best_clock));
7215ca02815Sjsg 	best_error_ppm = 1000000;
7225ca02815Sjsg 
7235ca02815Sjsg 	/*
7245ca02815Sjsg 	 * Based on hardware doc, the n always set to 1, and m1 always
7255ca02815Sjsg 	 * set to 2.  If requires to support 200Mhz refclk, we need to
7265ca02815Sjsg 	 * revisit this because n may not 1 anymore.
7275ca02815Sjsg 	 */
7285ca02815Sjsg 	clock.n = 1;
7295ca02815Sjsg 	clock.m1 = 2;
7305ca02815Sjsg 
7315ca02815Sjsg 	for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
7325ca02815Sjsg 		for (clock.p2 = limit->p2.p2_fast;
7335ca02815Sjsg 				clock.p2 >= limit->p2.p2_slow;
7345ca02815Sjsg 				clock.p2 -= clock.p2 > 10 ? 2 : 1) {
7355ca02815Sjsg 			unsigned int error_ppm;
7365ca02815Sjsg 
7371bb76ff1Sjsg 			clock.p = clock.p1 * clock.p2 * 5;
7385ca02815Sjsg 
7395ca02815Sjsg 			m2 = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(target, clock.p * clock.n) << 22,
7405ca02815Sjsg 						   refclk * clock.m1);
7415ca02815Sjsg 
7425ca02815Sjsg 			if (m2 > INT_MAX/clock.m1)
7435ca02815Sjsg 				continue;
7445ca02815Sjsg 
7455ca02815Sjsg 			clock.m2 = m2;
7465ca02815Sjsg 
7475ca02815Sjsg 			chv_calc_dpll_params(refclk, &clock);
7485ca02815Sjsg 
7495ca02815Sjsg 			if (!intel_pll_is_valid(to_i915(dev), limit, &clock))
7505ca02815Sjsg 				continue;
7515ca02815Sjsg 
7525ca02815Sjsg 			if (!vlv_PLL_is_optimal(dev, target, &clock, best_clock,
7535ca02815Sjsg 						best_error_ppm, &error_ppm))
7545ca02815Sjsg 				continue;
7555ca02815Sjsg 
7565ca02815Sjsg 			*best_clock = clock;
7575ca02815Sjsg 			best_error_ppm = error_ppm;
7585ca02815Sjsg 			found = true;
7595ca02815Sjsg 		}
7605ca02815Sjsg 	}
7615ca02815Sjsg 
7625ca02815Sjsg 	return found;
7635ca02815Sjsg }
7645ca02815Sjsg 
bxt_find_best_dpll(struct intel_crtc_state * crtc_state,struct dpll * best_clock)7655ca02815Sjsg bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state,
7665ca02815Sjsg 			struct dpll *best_clock)
7675ca02815Sjsg {
7685ca02815Sjsg 	const struct intel_limit *limit = &intel_limits_bxt;
7691bb76ff1Sjsg 	int refclk = 100000;
7705ca02815Sjsg 
7715ca02815Sjsg 	return chv_find_best_dpll(limit, crtc_state,
7725ca02815Sjsg 				  crtc_state->port_clock, refclk,
7735ca02815Sjsg 				  NULL, best_clock);
7745ca02815Sjsg }
7755ca02815Sjsg 
i9xx_dpll_compute_fp(const struct dpll * dpll)7761bb76ff1Sjsg u32 i9xx_dpll_compute_fp(const struct dpll *dpll)
7771bb76ff1Sjsg {
7781bb76ff1Sjsg 	return dpll->n << 16 | dpll->m1 << 8 | dpll->m2;
7791bb76ff1Sjsg }
7801bb76ff1Sjsg 
pnv_dpll_compute_fp(const struct dpll * dpll)7811bb76ff1Sjsg static u32 pnv_dpll_compute_fp(const struct dpll *dpll)
7825ca02815Sjsg {
7835ca02815Sjsg 	return (1 << dpll->n) << 16 | dpll->m2;
7845ca02815Sjsg }
7855ca02815Sjsg 
i9xx_update_pll_dividers(struct intel_crtc_state * crtc_state,const struct dpll * clock,const struct dpll * reduced_clock)7861bb76ff1Sjsg static void i9xx_update_pll_dividers(struct intel_crtc_state *crtc_state,
7871bb76ff1Sjsg 				     const struct dpll *clock,
7881bb76ff1Sjsg 				     const struct dpll *reduced_clock)
7895ca02815Sjsg {
7901bb76ff1Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
7915ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
7921bb76ff1Sjsg 	u32 fp, fp2;
7935ca02815Sjsg 
7945ca02815Sjsg 	if (IS_PINEVIEW(dev_priv)) {
7951bb76ff1Sjsg 		fp = pnv_dpll_compute_fp(clock);
7965ca02815Sjsg 		fp2 = pnv_dpll_compute_fp(reduced_clock);
7975ca02815Sjsg 	} else {
7981bb76ff1Sjsg 		fp = i9xx_dpll_compute_fp(clock);
7995ca02815Sjsg 		fp2 = i9xx_dpll_compute_fp(reduced_clock);
8005ca02815Sjsg 	}
8015ca02815Sjsg 
8025ca02815Sjsg 	crtc_state->dpll_hw_state.fp0 = fp;
8035ca02815Sjsg 	crtc_state->dpll_hw_state.fp1 = fp2;
8045ca02815Sjsg }
8055ca02815Sjsg 
i9xx_compute_dpll(struct intel_crtc_state * crtc_state,const struct dpll * clock,const struct dpll * reduced_clock)8061bb76ff1Sjsg static void i9xx_compute_dpll(struct intel_crtc_state *crtc_state,
8071bb76ff1Sjsg 			      const struct dpll *clock,
8081bb76ff1Sjsg 			      const struct dpll *reduced_clock)
8095ca02815Sjsg {
8101bb76ff1Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
8115ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
8125ca02815Sjsg 	u32 dpll;
8135ca02815Sjsg 
8141bb76ff1Sjsg 	i9xx_update_pll_dividers(crtc_state, clock, reduced_clock);
8155ca02815Sjsg 
8165ca02815Sjsg 	dpll = DPLL_VGA_MODE_DIS;
8175ca02815Sjsg 
8185ca02815Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS))
8195ca02815Sjsg 		dpll |= DPLLB_MODE_LVDS;
8205ca02815Sjsg 	else
8215ca02815Sjsg 		dpll |= DPLLB_MODE_DAC_SERIAL;
8225ca02815Sjsg 
8235ca02815Sjsg 	if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) ||
8245ca02815Sjsg 	    IS_G33(dev_priv) || IS_PINEVIEW(dev_priv)) {
8255ca02815Sjsg 		dpll |= (crtc_state->pixel_multiplier - 1)
8265ca02815Sjsg 			<< SDVO_MULTIPLIER_SHIFT_HIRES;
8275ca02815Sjsg 	}
8285ca02815Sjsg 
8295ca02815Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO) ||
8305ca02815Sjsg 	    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
8315ca02815Sjsg 		dpll |= DPLL_SDVO_HIGH_SPEED;
8325ca02815Sjsg 
8335ca02815Sjsg 	if (intel_crtc_has_dp_encoder(crtc_state))
8345ca02815Sjsg 		dpll |= DPLL_SDVO_HIGH_SPEED;
8355ca02815Sjsg 
8365ca02815Sjsg 	/* compute bitmask from p1 value */
8371bb76ff1Sjsg 	if (IS_G4X(dev_priv)) {
8385ca02815Sjsg 		dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
8395ca02815Sjsg 		dpll |= (1 << (reduced_clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
8401bb76ff1Sjsg 	} else if (IS_PINEVIEW(dev_priv)) {
8411bb76ff1Sjsg 		dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW;
8421bb76ff1Sjsg 		WARN_ON(reduced_clock->p1 != clock->p1);
8431bb76ff1Sjsg 	} else {
8441bb76ff1Sjsg 		dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
8451bb76ff1Sjsg 		WARN_ON(reduced_clock->p1 != clock->p1);
8465ca02815Sjsg 	}
8471bb76ff1Sjsg 
8485ca02815Sjsg 	switch (clock->p2) {
8495ca02815Sjsg 	case 5:
8505ca02815Sjsg 		dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
8515ca02815Sjsg 		break;
8525ca02815Sjsg 	case 7:
8535ca02815Sjsg 		dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
8545ca02815Sjsg 		break;
8555ca02815Sjsg 	case 10:
8565ca02815Sjsg 		dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
8575ca02815Sjsg 		break;
8585ca02815Sjsg 	case 14:
8595ca02815Sjsg 		dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
8605ca02815Sjsg 		break;
8615ca02815Sjsg 	}
8621bb76ff1Sjsg 	WARN_ON(reduced_clock->p2 != clock->p2);
8631bb76ff1Sjsg 
8645ca02815Sjsg 	if (DISPLAY_VER(dev_priv) >= 4)
8655ca02815Sjsg 		dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
8665ca02815Sjsg 
8675ca02815Sjsg 	if (crtc_state->sdvo_tv_clock)
8685ca02815Sjsg 		dpll |= PLL_REF_INPUT_TVCLKINBC;
8695ca02815Sjsg 	else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
8705ca02815Sjsg 		 intel_panel_use_ssc(dev_priv))
8715ca02815Sjsg 		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
8725ca02815Sjsg 	else
8735ca02815Sjsg 		dpll |= PLL_REF_INPUT_DREFCLK;
8745ca02815Sjsg 
8755ca02815Sjsg 	dpll |= DPLL_VCO_ENABLE;
8765ca02815Sjsg 	crtc_state->dpll_hw_state.dpll = dpll;
8775ca02815Sjsg 
8785ca02815Sjsg 	if (DISPLAY_VER(dev_priv) >= 4) {
8795ca02815Sjsg 		u32 dpll_md = (crtc_state->pixel_multiplier - 1)
8805ca02815Sjsg 			<< DPLL_MD_UDI_MULTIPLIER_SHIFT;
8815ca02815Sjsg 		crtc_state->dpll_hw_state.dpll_md = dpll_md;
8825ca02815Sjsg 	}
8835ca02815Sjsg }
8845ca02815Sjsg 
i8xx_compute_dpll(struct intel_crtc_state * crtc_state,const struct dpll * clock,const struct dpll * reduced_clock)8851bb76ff1Sjsg static void i8xx_compute_dpll(struct intel_crtc_state *crtc_state,
8861bb76ff1Sjsg 			      const struct dpll *clock,
8871bb76ff1Sjsg 			      const struct dpll *reduced_clock)
8885ca02815Sjsg {
8891bb76ff1Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
8901bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
8915ca02815Sjsg 	u32 dpll;
8925ca02815Sjsg 
8931bb76ff1Sjsg 	i9xx_update_pll_dividers(crtc_state, clock, reduced_clock);
8945ca02815Sjsg 
8955ca02815Sjsg 	dpll = DPLL_VGA_MODE_DIS;
8965ca02815Sjsg 
8975ca02815Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
8985ca02815Sjsg 		dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
8995ca02815Sjsg 	} else {
9005ca02815Sjsg 		if (clock->p1 == 2)
9015ca02815Sjsg 			dpll |= PLL_P1_DIVIDE_BY_TWO;
9025ca02815Sjsg 		else
9035ca02815Sjsg 			dpll |= (clock->p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT;
9045ca02815Sjsg 		if (clock->p2 == 4)
9055ca02815Sjsg 			dpll |= PLL_P2_DIVIDE_BY_4;
9065ca02815Sjsg 	}
9071bb76ff1Sjsg 	WARN_ON(reduced_clock->p1 != clock->p1);
9081bb76ff1Sjsg 	WARN_ON(reduced_clock->p2 != clock->p2);
9095ca02815Sjsg 
9105ca02815Sjsg 	/*
9115ca02815Sjsg 	 * Bspec:
9125ca02815Sjsg 	 * "[Almador Errata}: For the correct operation of the muxed DVO pins
9135ca02815Sjsg 	 *  (GDEVSELB/I2Cdata, GIRDBY/I2CClk) and (GFRAMEB/DVI_Data,
9145ca02815Sjsg 	 *  GTRDYB/DVI_Clk): Bit 31 (DPLL VCO Enable) and Bit 30 (2X Clock
9155ca02815Sjsg 	 *  Enable) must be set to “1” in both the DPLL A Control Register
9165ca02815Sjsg 	 *  (06014h-06017h) and DPLL B Control Register (06018h-0601Bh)."
9175ca02815Sjsg 	 *
9185ca02815Sjsg 	 * For simplicity We simply keep both bits always enabled in
9195ca02815Sjsg 	 * both DPLLS. The spec says we should disable the DVO 2X clock
9205ca02815Sjsg 	 * when not needed, but this seems to work fine in practice.
9215ca02815Sjsg 	 */
9225ca02815Sjsg 	if (IS_I830(dev_priv) ||
9235ca02815Sjsg 	    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DVO))
9245ca02815Sjsg 		dpll |= DPLL_DVO_2X_MODE;
9255ca02815Sjsg 
9265ca02815Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
9275ca02815Sjsg 	    intel_panel_use_ssc(dev_priv))
9285ca02815Sjsg 		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
9295ca02815Sjsg 	else
9305ca02815Sjsg 		dpll |= PLL_REF_INPUT_DREFCLK;
9315ca02815Sjsg 
9325ca02815Sjsg 	dpll |= DPLL_VCO_ENABLE;
9335ca02815Sjsg 	crtc_state->dpll_hw_state.dpll = dpll;
9345ca02815Sjsg }
9355ca02815Sjsg 
hsw_crtc_compute_clock(struct intel_atomic_state * state,struct intel_crtc * crtc)9361bb76ff1Sjsg static int hsw_crtc_compute_clock(struct intel_atomic_state *state,
9371bb76ff1Sjsg 				  struct intel_crtc *crtc)
9385ca02815Sjsg {
9391bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
9401bb76ff1Sjsg 	struct intel_crtc_state *crtc_state =
9411bb76ff1Sjsg 		intel_atomic_get_new_crtc_state(state, crtc);
9425ca02815Sjsg 	struct intel_encoder *encoder =
9435ca02815Sjsg 		intel_get_crtc_new_encoder(state, crtc_state);
9441bb76ff1Sjsg 	int ret;
9455ca02815Sjsg 
9461bb76ff1Sjsg 	if (DISPLAY_VER(dev_priv) < 11 &&
9471bb76ff1Sjsg 	    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
9481bb76ff1Sjsg 		return 0;
9491bb76ff1Sjsg 
9501bb76ff1Sjsg 	ret = intel_compute_shared_dplls(state, crtc, encoder);
9511bb76ff1Sjsg 	if (ret)
9521bb76ff1Sjsg 		return ret;
9531bb76ff1Sjsg 
9541bb76ff1Sjsg 	/* FIXME this is a mess */
9551bb76ff1Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
9561bb76ff1Sjsg 		return 0;
9571bb76ff1Sjsg 
9581bb76ff1Sjsg 	/* CRT dotclock is determined via other means */
9591bb76ff1Sjsg 	if (!crtc_state->has_pch_encoder)
9601bb76ff1Sjsg 		crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
9615ca02815Sjsg 
9625ca02815Sjsg 	return 0;
9635ca02815Sjsg }
9645ca02815Sjsg 
hsw_crtc_get_shared_dpll(struct intel_atomic_state * state,struct intel_crtc * crtc)9651bb76ff1Sjsg static int hsw_crtc_get_shared_dpll(struct intel_atomic_state *state,
9661bb76ff1Sjsg 				    struct intel_crtc *crtc)
9675ca02815Sjsg {
9681bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
9691bb76ff1Sjsg 	struct intel_crtc_state *crtc_state =
9701bb76ff1Sjsg 		intel_atomic_get_new_crtc_state(state, crtc);
9711bb76ff1Sjsg 	struct intel_encoder *encoder =
9721bb76ff1Sjsg 		intel_get_crtc_new_encoder(state, crtc_state);
9731bb76ff1Sjsg 
9741bb76ff1Sjsg 	if (DISPLAY_VER(dev_priv) < 11 &&
9751bb76ff1Sjsg 	    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
9761bb76ff1Sjsg 		return 0;
9771bb76ff1Sjsg 
9781bb76ff1Sjsg 	return intel_reserve_shared_dplls(state, crtc, encoder);
9795ca02815Sjsg }
9805ca02815Sjsg 
dg2_crtc_compute_clock(struct intel_atomic_state * state,struct intel_crtc * crtc)9811bb76ff1Sjsg static int dg2_crtc_compute_clock(struct intel_atomic_state *state,
9821bb76ff1Sjsg 				  struct intel_crtc *crtc)
9835ca02815Sjsg {
9841bb76ff1Sjsg 	struct intel_crtc_state *crtc_state =
9851bb76ff1Sjsg 		intel_atomic_get_new_crtc_state(state, crtc);
9861bb76ff1Sjsg 	struct intel_encoder *encoder =
9871bb76ff1Sjsg 		intel_get_crtc_new_encoder(state, crtc_state);
9881bb76ff1Sjsg 	int ret;
9891bb76ff1Sjsg 
9901bb76ff1Sjsg 	ret = intel_mpllb_calc_state(crtc_state, encoder);
9911bb76ff1Sjsg 	if (ret)
9921bb76ff1Sjsg 		return ret;
9931bb76ff1Sjsg 
9941bb76ff1Sjsg 	crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
9951bb76ff1Sjsg 
9961bb76ff1Sjsg 	return 0;
9971bb76ff1Sjsg }
9981bb76ff1Sjsg 
mtl_crtc_compute_clock(struct intel_atomic_state * state,struct intel_crtc * crtc)999*f005ef32Sjsg static int mtl_crtc_compute_clock(struct intel_atomic_state *state,
1000*f005ef32Sjsg 				  struct intel_crtc *crtc)
1001*f005ef32Sjsg {
1002*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(state->base.dev);
1003*f005ef32Sjsg 	struct intel_crtc_state *crtc_state =
1004*f005ef32Sjsg 		intel_atomic_get_new_crtc_state(state, crtc);
1005*f005ef32Sjsg 	struct intel_encoder *encoder =
1006*f005ef32Sjsg 		intel_get_crtc_new_encoder(state, crtc_state);
1007*f005ef32Sjsg 	enum phy phy = intel_port_to_phy(i915, encoder->port);
1008*f005ef32Sjsg 	int ret;
1009*f005ef32Sjsg 
1010*f005ef32Sjsg 	ret = intel_cx0pll_calc_state(crtc_state, encoder);
1011*f005ef32Sjsg 	if (ret)
1012*f005ef32Sjsg 		return ret;
1013*f005ef32Sjsg 
1014*f005ef32Sjsg 	/* TODO: Do the readback via intel_compute_shared_dplls() */
1015*f005ef32Sjsg 	if (intel_is_c10phy(i915, phy))
1016*f005ef32Sjsg 		crtc_state->port_clock = intel_c10pll_calc_port_clock(encoder, &crtc_state->cx0pll_state.c10);
1017*f005ef32Sjsg 	else
1018*f005ef32Sjsg 		crtc_state->port_clock = intel_c20pll_calc_port_clock(encoder, &crtc_state->cx0pll_state.c20);
1019*f005ef32Sjsg 
1020*f005ef32Sjsg 	crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
1021*f005ef32Sjsg 
1022*f005ef32Sjsg 	return 0;
1023*f005ef32Sjsg }
1024*f005ef32Sjsg 
ilk_needs_fb_cb_tune(const struct dpll * dpll,int factor)10251bb76ff1Sjsg static bool ilk_needs_fb_cb_tune(const struct dpll *dpll, int factor)
10261bb76ff1Sjsg {
10271bb76ff1Sjsg 	return dpll->m < factor * dpll->n;
10281bb76ff1Sjsg }
10291bb76ff1Sjsg 
ilk_update_pll_dividers(struct intel_crtc_state * crtc_state,const struct dpll * clock,const struct dpll * reduced_clock)10301bb76ff1Sjsg static void ilk_update_pll_dividers(struct intel_crtc_state *crtc_state,
10311bb76ff1Sjsg 				    const struct dpll *clock,
10321bb76ff1Sjsg 				    const struct dpll *reduced_clock)
10331bb76ff1Sjsg {
10341bb76ff1Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
10355ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
10361bb76ff1Sjsg 	u32 fp, fp2;
10375ca02815Sjsg 	int factor;
10385ca02815Sjsg 
10395ca02815Sjsg 	/* Enable autotuning of the PLL clock (if permissible) */
10405ca02815Sjsg 	factor = 21;
10415ca02815Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
10425ca02815Sjsg 		if ((intel_panel_use_ssc(dev_priv) &&
10431bb76ff1Sjsg 		     dev_priv->display.vbt.lvds_ssc_freq == 100000) ||
10445ca02815Sjsg 		    (HAS_PCH_IBX(dev_priv) &&
10455ca02815Sjsg 		     intel_is_dual_link_lvds(dev_priv)))
10465ca02815Sjsg 			factor = 25;
10475ca02815Sjsg 	} else if (crtc_state->sdvo_tv_clock) {
10485ca02815Sjsg 		factor = 20;
10495ca02815Sjsg 	}
10505ca02815Sjsg 
10511bb76ff1Sjsg 	fp = i9xx_dpll_compute_fp(clock);
10521bb76ff1Sjsg 	if (ilk_needs_fb_cb_tune(clock, factor))
10535ca02815Sjsg 		fp |= FP_CB_TUNE;
10545ca02815Sjsg 
10555ca02815Sjsg 	fp2 = i9xx_dpll_compute_fp(reduced_clock);
10561bb76ff1Sjsg 	if (ilk_needs_fb_cb_tune(reduced_clock, factor))
10575ca02815Sjsg 		fp2 |= FP_CB_TUNE;
10581bb76ff1Sjsg 
10591bb76ff1Sjsg 	crtc_state->dpll_hw_state.fp0 = fp;
10601bb76ff1Sjsg 	crtc_state->dpll_hw_state.fp1 = fp2;
10615ca02815Sjsg }
10625ca02815Sjsg 
ilk_compute_dpll(struct intel_crtc_state * crtc_state,const struct dpll * clock,const struct dpll * reduced_clock)10631bb76ff1Sjsg static void ilk_compute_dpll(struct intel_crtc_state *crtc_state,
10641bb76ff1Sjsg 			     const struct dpll *clock,
10651bb76ff1Sjsg 			     const struct dpll *reduced_clock)
10661bb76ff1Sjsg {
10671bb76ff1Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
10681bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
10691bb76ff1Sjsg 	u32 dpll;
10701bb76ff1Sjsg 
10711bb76ff1Sjsg 	ilk_update_pll_dividers(crtc_state, clock, reduced_clock);
10721bb76ff1Sjsg 
10735ca02815Sjsg 	dpll = 0;
10745ca02815Sjsg 
10755ca02815Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS))
10765ca02815Sjsg 		dpll |= DPLLB_MODE_LVDS;
10775ca02815Sjsg 	else
10785ca02815Sjsg 		dpll |= DPLLB_MODE_DAC_SERIAL;
10795ca02815Sjsg 
10805ca02815Sjsg 	dpll |= (crtc_state->pixel_multiplier - 1)
10815ca02815Sjsg 		<< PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
10825ca02815Sjsg 
10835ca02815Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO) ||
10845ca02815Sjsg 	    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
10855ca02815Sjsg 		dpll |= DPLL_SDVO_HIGH_SPEED;
10865ca02815Sjsg 
10875ca02815Sjsg 	if (intel_crtc_has_dp_encoder(crtc_state))
10885ca02815Sjsg 		dpll |= DPLL_SDVO_HIGH_SPEED;
10895ca02815Sjsg 
10905ca02815Sjsg 	/*
10915ca02815Sjsg 	 * The high speed IO clock is only really required for
10925ca02815Sjsg 	 * SDVO/HDMI/DP, but we also enable it for CRT to make it
10935ca02815Sjsg 	 * possible to share the DPLL between CRT and HDMI. Enabling
10945ca02815Sjsg 	 * the clock needlessly does no real harm, except use up a
10955ca02815Sjsg 	 * bit of power potentially.
10965ca02815Sjsg 	 *
10975ca02815Sjsg 	 * We'll limit this to IVB with 3 pipes, since it has only two
10985ca02815Sjsg 	 * DPLLs and so DPLL sharing is the only way to get three pipes
10995ca02815Sjsg 	 * driving PCH ports at the same time. On SNB we could do this,
11005ca02815Sjsg 	 * and potentially avoid enabling the second DPLL, but it's not
11015ca02815Sjsg 	 * clear if it''s a win or loss power wise. No point in doing
11025ca02815Sjsg 	 * this on ILK at all since it has a fixed DPLL<->pipe mapping.
11035ca02815Sjsg 	 */
11045ca02815Sjsg 	if (INTEL_NUM_PIPES(dev_priv) == 3 &&
11055ca02815Sjsg 	    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG))
11065ca02815Sjsg 		dpll |= DPLL_SDVO_HIGH_SPEED;
11075ca02815Sjsg 
11085ca02815Sjsg 	/* compute bitmask from p1 value */
11091bb76ff1Sjsg 	dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
11105ca02815Sjsg 	/* also FPA1 */
11111bb76ff1Sjsg 	dpll |= (1 << (reduced_clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
11125ca02815Sjsg 
11131bb76ff1Sjsg 	switch (clock->p2) {
11145ca02815Sjsg 	case 5:
11155ca02815Sjsg 		dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
11165ca02815Sjsg 		break;
11175ca02815Sjsg 	case 7:
11185ca02815Sjsg 		dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
11195ca02815Sjsg 		break;
11205ca02815Sjsg 	case 10:
11215ca02815Sjsg 		dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
11225ca02815Sjsg 		break;
11235ca02815Sjsg 	case 14:
11245ca02815Sjsg 		dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
11255ca02815Sjsg 		break;
11265ca02815Sjsg 	}
11271bb76ff1Sjsg 	WARN_ON(reduced_clock->p2 != clock->p2);
11285ca02815Sjsg 
11295ca02815Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
11305ca02815Sjsg 	    intel_panel_use_ssc(dev_priv))
11315ca02815Sjsg 		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
11325ca02815Sjsg 	else
11335ca02815Sjsg 		dpll |= PLL_REF_INPUT_DREFCLK;
11345ca02815Sjsg 
11355ca02815Sjsg 	dpll |= DPLL_VCO_ENABLE;
11365ca02815Sjsg 
11375ca02815Sjsg 	crtc_state->dpll_hw_state.dpll = dpll;
11385ca02815Sjsg }
11395ca02815Sjsg 
ilk_crtc_compute_clock(struct intel_atomic_state * state,struct intel_crtc * crtc)11401bb76ff1Sjsg static int ilk_crtc_compute_clock(struct intel_atomic_state *state,
11411bb76ff1Sjsg 				  struct intel_crtc *crtc)
11425ca02815Sjsg {
11431bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
11441bb76ff1Sjsg 	struct intel_crtc_state *crtc_state =
11451bb76ff1Sjsg 		intel_atomic_get_new_crtc_state(state, crtc);
11465ca02815Sjsg 	const struct intel_limit *limit;
11475ca02815Sjsg 	int refclk = 120000;
11481bb76ff1Sjsg 	int ret;
11495ca02815Sjsg 
11505ca02815Sjsg 	/* CPU eDP is the only output that doesn't need a PCH PLL of its own. */
11515ca02815Sjsg 	if (!crtc_state->has_pch_encoder)
11525ca02815Sjsg 		return 0;
11535ca02815Sjsg 
11545ca02815Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
11555ca02815Sjsg 		if (intel_panel_use_ssc(dev_priv)) {
11565ca02815Sjsg 			drm_dbg_kms(&dev_priv->drm,
11575ca02815Sjsg 				    "using SSC reference clock of %d kHz\n",
11581bb76ff1Sjsg 				    dev_priv->display.vbt.lvds_ssc_freq);
11591bb76ff1Sjsg 			refclk = dev_priv->display.vbt.lvds_ssc_freq;
11605ca02815Sjsg 		}
11615ca02815Sjsg 
11625ca02815Sjsg 		if (intel_is_dual_link_lvds(dev_priv)) {
11635ca02815Sjsg 			if (refclk == 100000)
11645ca02815Sjsg 				limit = &ilk_limits_dual_lvds_100m;
11655ca02815Sjsg 			else
11665ca02815Sjsg 				limit = &ilk_limits_dual_lvds;
11675ca02815Sjsg 		} else {
11685ca02815Sjsg 			if (refclk == 100000)
11695ca02815Sjsg 				limit = &ilk_limits_single_lvds_100m;
11705ca02815Sjsg 			else
11715ca02815Sjsg 				limit = &ilk_limits_single_lvds;
11725ca02815Sjsg 		}
11735ca02815Sjsg 	} else {
11745ca02815Sjsg 		limit = &ilk_limits_dac;
11755ca02815Sjsg 	}
11765ca02815Sjsg 
11775ca02815Sjsg 	if (!crtc_state->clock_set &&
11785ca02815Sjsg 	    !g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
11791bb76ff1Sjsg 				refclk, NULL, &crtc_state->dpll))
11805ca02815Sjsg 		return -EINVAL;
11811bb76ff1Sjsg 
11821bb76ff1Sjsg 	ilk_compute_dpll(crtc_state, &crtc_state->dpll,
11831bb76ff1Sjsg 			 &crtc_state->dpll);
11841bb76ff1Sjsg 
11851bb76ff1Sjsg 	ret = intel_compute_shared_dplls(state, crtc, NULL);
11861bb76ff1Sjsg 	if (ret)
11871bb76ff1Sjsg 		return ret;
11881bb76ff1Sjsg 
11891bb76ff1Sjsg 	crtc_state->port_clock = crtc_state->dpll.dot;
11901bb76ff1Sjsg 	crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
11911bb76ff1Sjsg 
11921bb76ff1Sjsg 	return ret;
11935ca02815Sjsg }
11945ca02815Sjsg 
ilk_crtc_get_shared_dpll(struct intel_atomic_state * state,struct intel_crtc * crtc)11951bb76ff1Sjsg static int ilk_crtc_get_shared_dpll(struct intel_atomic_state *state,
11961bb76ff1Sjsg 				    struct intel_crtc *crtc)
11975ca02815Sjsg {
11981bb76ff1Sjsg 	struct intel_crtc_state *crtc_state =
11991bb76ff1Sjsg 		intel_atomic_get_new_crtc_state(state, crtc);
12001bb76ff1Sjsg 
12011bb76ff1Sjsg 	/* CPU eDP is the only output that doesn't need a PCH PLL of its own. */
12021bb76ff1Sjsg 	if (!crtc_state->has_pch_encoder)
12031bb76ff1Sjsg 		return 0;
12041bb76ff1Sjsg 
12051bb76ff1Sjsg 	return intel_reserve_shared_dplls(state, crtc, NULL);
12061bb76ff1Sjsg }
12071bb76ff1Sjsg 
vlv_compute_dpll(struct intel_crtc_state * crtc_state)12081bb76ff1Sjsg void vlv_compute_dpll(struct intel_crtc_state *crtc_state)
12091bb76ff1Sjsg {
12101bb76ff1Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
12111bb76ff1Sjsg 
12121bb76ff1Sjsg 	crtc_state->dpll_hw_state.dpll = DPLL_INTEGRATED_REF_CLK_VLV |
12135ca02815Sjsg 		DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
12145ca02815Sjsg 	if (crtc->pipe != PIPE_A)
12151bb76ff1Sjsg 		crtc_state->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
12165ca02815Sjsg 
12175ca02815Sjsg 	/* DPLL not used with DSI, but still need the rest set up */
12181bb76ff1Sjsg 	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
12191bb76ff1Sjsg 		crtc_state->dpll_hw_state.dpll |= DPLL_VCO_ENABLE |
12205ca02815Sjsg 			DPLL_EXT_BUFFER_ENABLE_VLV;
12215ca02815Sjsg 
12221bb76ff1Sjsg 	crtc_state->dpll_hw_state.dpll_md =
12231bb76ff1Sjsg 		(crtc_state->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
12245ca02815Sjsg }
12255ca02815Sjsg 
chv_compute_dpll(struct intel_crtc_state * crtc_state)12261bb76ff1Sjsg void chv_compute_dpll(struct intel_crtc_state *crtc_state)
12275ca02815Sjsg {
12281bb76ff1Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
12291bb76ff1Sjsg 
12301bb76ff1Sjsg 	crtc_state->dpll_hw_state.dpll = DPLL_SSC_REF_CLK_CHV |
12315ca02815Sjsg 		DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
12325ca02815Sjsg 	if (crtc->pipe != PIPE_A)
12331bb76ff1Sjsg 		crtc_state->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
12345ca02815Sjsg 
12355ca02815Sjsg 	/* DPLL not used with DSI, but still need the rest set up */
12361bb76ff1Sjsg 	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
12371bb76ff1Sjsg 		crtc_state->dpll_hw_state.dpll |= DPLL_VCO_ENABLE;
12385ca02815Sjsg 
12391bb76ff1Sjsg 	crtc_state->dpll_hw_state.dpll_md =
12401bb76ff1Sjsg 		(crtc_state->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
12415ca02815Sjsg }
12425ca02815Sjsg 
chv_crtc_compute_clock(struct intel_atomic_state * state,struct intel_crtc * crtc)12431bb76ff1Sjsg static int chv_crtc_compute_clock(struct intel_atomic_state *state,
12441bb76ff1Sjsg 				  struct intel_crtc *crtc)
12455ca02815Sjsg {
12461bb76ff1Sjsg 	struct intel_crtc_state *crtc_state =
12471bb76ff1Sjsg 		intel_atomic_get_new_crtc_state(state, crtc);
12485ca02815Sjsg 	const struct intel_limit *limit = &intel_limits_chv;
12491bb76ff1Sjsg 	int refclk = 100000;
12505ca02815Sjsg 
12515ca02815Sjsg 	if (!crtc_state->clock_set &&
12525ca02815Sjsg 	    !chv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
12531bb76ff1Sjsg 				refclk, NULL, &crtc_state->dpll))
12545ca02815Sjsg 		return -EINVAL;
12555ca02815Sjsg 
12561bb76ff1Sjsg 	chv_compute_dpll(crtc_state);
12571bb76ff1Sjsg 
12581bb76ff1Sjsg 	/* FIXME this is a mess */
12591bb76ff1Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
12601bb76ff1Sjsg 		return 0;
12611bb76ff1Sjsg 
12621bb76ff1Sjsg 	crtc_state->port_clock = crtc_state->dpll.dot;
12631bb76ff1Sjsg 	crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
12645ca02815Sjsg 
12655ca02815Sjsg 	return 0;
12665ca02815Sjsg }
12675ca02815Sjsg 
vlv_crtc_compute_clock(struct intel_atomic_state * state,struct intel_crtc * crtc)12681bb76ff1Sjsg static int vlv_crtc_compute_clock(struct intel_atomic_state *state,
12691bb76ff1Sjsg 				  struct intel_crtc *crtc)
12705ca02815Sjsg {
12711bb76ff1Sjsg 	struct intel_crtc_state *crtc_state =
12721bb76ff1Sjsg 		intel_atomic_get_new_crtc_state(state, crtc);
12735ca02815Sjsg 	const struct intel_limit *limit = &intel_limits_vlv;
12741bb76ff1Sjsg 	int refclk = 100000;
12755ca02815Sjsg 
12765ca02815Sjsg 	if (!crtc_state->clock_set &&
12775ca02815Sjsg 	    !vlv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
12785ca02815Sjsg 				refclk, NULL, &crtc_state->dpll)) {
12795ca02815Sjsg 		return -EINVAL;
12805ca02815Sjsg 	}
12815ca02815Sjsg 
12821bb76ff1Sjsg 	vlv_compute_dpll(crtc_state);
12831bb76ff1Sjsg 
12841bb76ff1Sjsg 	/* FIXME this is a mess */
12851bb76ff1Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
12861bb76ff1Sjsg 		return 0;
12871bb76ff1Sjsg 
12881bb76ff1Sjsg 	crtc_state->port_clock = crtc_state->dpll.dot;
12891bb76ff1Sjsg 	crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
12905ca02815Sjsg 
12915ca02815Sjsg 	return 0;
12925ca02815Sjsg }
12935ca02815Sjsg 
g4x_crtc_compute_clock(struct intel_atomic_state * state,struct intel_crtc * crtc)12941bb76ff1Sjsg static int g4x_crtc_compute_clock(struct intel_atomic_state *state,
12951bb76ff1Sjsg 				  struct intel_crtc *crtc)
12965ca02815Sjsg {
12971bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
12981bb76ff1Sjsg 	struct intel_crtc_state *crtc_state =
12991bb76ff1Sjsg 		intel_atomic_get_new_crtc_state(state, crtc);
13005ca02815Sjsg 	const struct intel_limit *limit;
13015ca02815Sjsg 	int refclk = 96000;
13025ca02815Sjsg 
13035ca02815Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
13045ca02815Sjsg 		if (intel_panel_use_ssc(dev_priv)) {
13051bb76ff1Sjsg 			refclk = dev_priv->display.vbt.lvds_ssc_freq;
13065ca02815Sjsg 			drm_dbg_kms(&dev_priv->drm,
13075ca02815Sjsg 				    "using SSC reference clock of %d kHz\n",
13085ca02815Sjsg 				    refclk);
13095ca02815Sjsg 		}
13105ca02815Sjsg 
13115ca02815Sjsg 		if (intel_is_dual_link_lvds(dev_priv))
13125ca02815Sjsg 			limit = &intel_limits_g4x_dual_channel_lvds;
13135ca02815Sjsg 		else
13145ca02815Sjsg 			limit = &intel_limits_g4x_single_channel_lvds;
13155ca02815Sjsg 	} else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) ||
13165ca02815Sjsg 		   intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) {
13175ca02815Sjsg 		limit = &intel_limits_g4x_hdmi;
13185ca02815Sjsg 	} else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO)) {
13195ca02815Sjsg 		limit = &intel_limits_g4x_sdvo;
13205ca02815Sjsg 	} else {
13215ca02815Sjsg 		/* The option is for other outputs */
13225ca02815Sjsg 		limit = &intel_limits_i9xx_sdvo;
13235ca02815Sjsg 	}
13245ca02815Sjsg 
13255ca02815Sjsg 	if (!crtc_state->clock_set &&
13265ca02815Sjsg 	    !g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
13271bb76ff1Sjsg 				refclk, NULL, &crtc_state->dpll))
13285ca02815Sjsg 		return -EINVAL;
13295ca02815Sjsg 
13301bb76ff1Sjsg 	i9xx_compute_dpll(crtc_state, &crtc_state->dpll,
13311bb76ff1Sjsg 			  &crtc_state->dpll);
13321bb76ff1Sjsg 
13331bb76ff1Sjsg 	crtc_state->port_clock = crtc_state->dpll.dot;
13341bb76ff1Sjsg 	/* FIXME this is a mess */
13351bb76ff1Sjsg 	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_TVOUT))
13361bb76ff1Sjsg 		crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
13375ca02815Sjsg 
13385ca02815Sjsg 	return 0;
13395ca02815Sjsg }
13405ca02815Sjsg 
pnv_crtc_compute_clock(struct intel_atomic_state * state,struct intel_crtc * crtc)13411bb76ff1Sjsg static int pnv_crtc_compute_clock(struct intel_atomic_state *state,
13421bb76ff1Sjsg 				  struct intel_crtc *crtc)
13435ca02815Sjsg {
13441bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
13451bb76ff1Sjsg 	struct intel_crtc_state *crtc_state =
13461bb76ff1Sjsg 		intel_atomic_get_new_crtc_state(state, crtc);
13475ca02815Sjsg 	const struct intel_limit *limit;
13485ca02815Sjsg 	int refclk = 96000;
13495ca02815Sjsg 
13505ca02815Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
13515ca02815Sjsg 		if (intel_panel_use_ssc(dev_priv)) {
13521bb76ff1Sjsg 			refclk = dev_priv->display.vbt.lvds_ssc_freq;
13535ca02815Sjsg 			drm_dbg_kms(&dev_priv->drm,
13545ca02815Sjsg 				    "using SSC reference clock of %d kHz\n",
13555ca02815Sjsg 				    refclk);
13565ca02815Sjsg 		}
13575ca02815Sjsg 
13585ca02815Sjsg 		limit = &pnv_limits_lvds;
13595ca02815Sjsg 	} else {
13605ca02815Sjsg 		limit = &pnv_limits_sdvo;
13615ca02815Sjsg 	}
13625ca02815Sjsg 
13635ca02815Sjsg 	if (!crtc_state->clock_set &&
13645ca02815Sjsg 	    !pnv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
13651bb76ff1Sjsg 				refclk, NULL, &crtc_state->dpll))
13665ca02815Sjsg 		return -EINVAL;
13675ca02815Sjsg 
13681bb76ff1Sjsg 	i9xx_compute_dpll(crtc_state, &crtc_state->dpll,
13691bb76ff1Sjsg 			  &crtc_state->dpll);
13701bb76ff1Sjsg 
13711bb76ff1Sjsg 	crtc_state->port_clock = crtc_state->dpll.dot;
13721bb76ff1Sjsg 	crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
13735ca02815Sjsg 
13745ca02815Sjsg 	return 0;
13755ca02815Sjsg }
13765ca02815Sjsg 
i9xx_crtc_compute_clock(struct intel_atomic_state * state,struct intel_crtc * crtc)13771bb76ff1Sjsg static int i9xx_crtc_compute_clock(struct intel_atomic_state *state,
13781bb76ff1Sjsg 				   struct intel_crtc *crtc)
13795ca02815Sjsg {
13801bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
13811bb76ff1Sjsg 	struct intel_crtc_state *crtc_state =
13821bb76ff1Sjsg 		intel_atomic_get_new_crtc_state(state, crtc);
13835ca02815Sjsg 	const struct intel_limit *limit;
13845ca02815Sjsg 	int refclk = 96000;
13855ca02815Sjsg 
13865ca02815Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
13875ca02815Sjsg 		if (intel_panel_use_ssc(dev_priv)) {
13881bb76ff1Sjsg 			refclk = dev_priv->display.vbt.lvds_ssc_freq;
13895ca02815Sjsg 			drm_dbg_kms(&dev_priv->drm,
13905ca02815Sjsg 				    "using SSC reference clock of %d kHz\n",
13915ca02815Sjsg 				    refclk);
13925ca02815Sjsg 		}
13935ca02815Sjsg 
13945ca02815Sjsg 		limit = &intel_limits_i9xx_lvds;
13955ca02815Sjsg 	} else {
13965ca02815Sjsg 		limit = &intel_limits_i9xx_sdvo;
13975ca02815Sjsg 	}
13985ca02815Sjsg 
13995ca02815Sjsg 	if (!crtc_state->clock_set &&
14005ca02815Sjsg 	    !i9xx_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
14011bb76ff1Sjsg 				 refclk, NULL, &crtc_state->dpll))
14025ca02815Sjsg 		return -EINVAL;
14035ca02815Sjsg 
14041bb76ff1Sjsg 	i9xx_compute_dpll(crtc_state, &crtc_state->dpll,
14051bb76ff1Sjsg 			  &crtc_state->dpll);
14061bb76ff1Sjsg 
14071bb76ff1Sjsg 	crtc_state->port_clock = crtc_state->dpll.dot;
14081bb76ff1Sjsg 	/* FIXME this is a mess */
14091bb76ff1Sjsg 	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_TVOUT))
14101bb76ff1Sjsg 		crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
14115ca02815Sjsg 
14125ca02815Sjsg 	return 0;
14135ca02815Sjsg }
14145ca02815Sjsg 
i8xx_crtc_compute_clock(struct intel_atomic_state * state,struct intel_crtc * crtc)14151bb76ff1Sjsg static int i8xx_crtc_compute_clock(struct intel_atomic_state *state,
14161bb76ff1Sjsg 				   struct intel_crtc *crtc)
14175ca02815Sjsg {
14181bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
14191bb76ff1Sjsg 	struct intel_crtc_state *crtc_state =
14201bb76ff1Sjsg 		intel_atomic_get_new_crtc_state(state, crtc);
14215ca02815Sjsg 	const struct intel_limit *limit;
14225ca02815Sjsg 	int refclk = 48000;
14235ca02815Sjsg 
14245ca02815Sjsg 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
14255ca02815Sjsg 		if (intel_panel_use_ssc(dev_priv)) {
14261bb76ff1Sjsg 			refclk = dev_priv->display.vbt.lvds_ssc_freq;
14275ca02815Sjsg 			drm_dbg_kms(&dev_priv->drm,
14285ca02815Sjsg 				    "using SSC reference clock of %d kHz\n",
14295ca02815Sjsg 				    refclk);
14305ca02815Sjsg 		}
14315ca02815Sjsg 
14325ca02815Sjsg 		limit = &intel_limits_i8xx_lvds;
14335ca02815Sjsg 	} else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DVO)) {
14345ca02815Sjsg 		limit = &intel_limits_i8xx_dvo;
14355ca02815Sjsg 	} else {
14365ca02815Sjsg 		limit = &intel_limits_i8xx_dac;
14375ca02815Sjsg 	}
14385ca02815Sjsg 
14395ca02815Sjsg 	if (!crtc_state->clock_set &&
14405ca02815Sjsg 	    !i9xx_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
14411bb76ff1Sjsg 				 refclk, NULL, &crtc_state->dpll))
14425ca02815Sjsg 		return -EINVAL;
14431bb76ff1Sjsg 
14441bb76ff1Sjsg 	i8xx_compute_dpll(crtc_state, &crtc_state->dpll,
14451bb76ff1Sjsg 			  &crtc_state->dpll);
14461bb76ff1Sjsg 
14471bb76ff1Sjsg 	crtc_state->port_clock = crtc_state->dpll.dot;
14481bb76ff1Sjsg 	crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
14491bb76ff1Sjsg 
14501bb76ff1Sjsg 	return 0;
14515ca02815Sjsg }
14525ca02815Sjsg 
1453*f005ef32Sjsg static const struct intel_dpll_funcs mtl_dpll_funcs = {
1454*f005ef32Sjsg 	.crtc_compute_clock = mtl_crtc_compute_clock,
1455*f005ef32Sjsg };
1456*f005ef32Sjsg 
14571bb76ff1Sjsg static const struct intel_dpll_funcs dg2_dpll_funcs = {
14581bb76ff1Sjsg 	.crtc_compute_clock = dg2_crtc_compute_clock,
14591bb76ff1Sjsg };
14601bb76ff1Sjsg 
14611bb76ff1Sjsg static const struct intel_dpll_funcs hsw_dpll_funcs = {
14621bb76ff1Sjsg 	.crtc_compute_clock = hsw_crtc_compute_clock,
14631bb76ff1Sjsg 	.crtc_get_shared_dpll = hsw_crtc_get_shared_dpll,
14641bb76ff1Sjsg };
14651bb76ff1Sjsg 
14661bb76ff1Sjsg static const struct intel_dpll_funcs ilk_dpll_funcs = {
14671bb76ff1Sjsg 	.crtc_compute_clock = ilk_crtc_compute_clock,
14681bb76ff1Sjsg 	.crtc_get_shared_dpll = ilk_crtc_get_shared_dpll,
14691bb76ff1Sjsg };
14701bb76ff1Sjsg 
14711bb76ff1Sjsg static const struct intel_dpll_funcs chv_dpll_funcs = {
14721bb76ff1Sjsg 	.crtc_compute_clock = chv_crtc_compute_clock,
14731bb76ff1Sjsg };
14741bb76ff1Sjsg 
14751bb76ff1Sjsg static const struct intel_dpll_funcs vlv_dpll_funcs = {
14761bb76ff1Sjsg 	.crtc_compute_clock = vlv_crtc_compute_clock,
14771bb76ff1Sjsg };
14781bb76ff1Sjsg 
14791bb76ff1Sjsg static const struct intel_dpll_funcs g4x_dpll_funcs = {
14801bb76ff1Sjsg 	.crtc_compute_clock = g4x_crtc_compute_clock,
14811bb76ff1Sjsg };
14821bb76ff1Sjsg 
14831bb76ff1Sjsg static const struct intel_dpll_funcs pnv_dpll_funcs = {
14841bb76ff1Sjsg 	.crtc_compute_clock = pnv_crtc_compute_clock,
14851bb76ff1Sjsg };
14861bb76ff1Sjsg 
14871bb76ff1Sjsg static const struct intel_dpll_funcs i9xx_dpll_funcs = {
14881bb76ff1Sjsg 	.crtc_compute_clock = i9xx_crtc_compute_clock,
14891bb76ff1Sjsg };
14901bb76ff1Sjsg 
14911bb76ff1Sjsg static const struct intel_dpll_funcs i8xx_dpll_funcs = {
14921bb76ff1Sjsg 	.crtc_compute_clock = i8xx_crtc_compute_clock,
14931bb76ff1Sjsg };
14941bb76ff1Sjsg 
intel_dpll_crtc_compute_clock(struct intel_atomic_state * state,struct intel_crtc * crtc)14951bb76ff1Sjsg int intel_dpll_crtc_compute_clock(struct intel_atomic_state *state,
14961bb76ff1Sjsg 				  struct intel_crtc *crtc)
14971bb76ff1Sjsg {
14981bb76ff1Sjsg 	struct drm_i915_private *i915 = to_i915(state->base.dev);
14991bb76ff1Sjsg 	struct intel_crtc_state *crtc_state =
15001bb76ff1Sjsg 		intel_atomic_get_new_crtc_state(state, crtc);
15011bb76ff1Sjsg 	int ret;
15021bb76ff1Sjsg 
15031bb76ff1Sjsg 	drm_WARN_ON(&i915->drm, !intel_crtc_needs_modeset(crtc_state));
15041bb76ff1Sjsg 
15051bb76ff1Sjsg 	memset(&crtc_state->dpll_hw_state, 0,
15061bb76ff1Sjsg 	       sizeof(crtc_state->dpll_hw_state));
15071bb76ff1Sjsg 
15081bb76ff1Sjsg 	if (!crtc_state->hw.enable)
15091bb76ff1Sjsg 		return 0;
15101bb76ff1Sjsg 
15111bb76ff1Sjsg 	ret = i915->display.funcs.dpll->crtc_compute_clock(state, crtc);
15121bb76ff1Sjsg 	if (ret) {
15131bb76ff1Sjsg 		drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] Couldn't calculate DPLL settings\n",
15141bb76ff1Sjsg 			    crtc->base.base.id, crtc->base.name);
15151bb76ff1Sjsg 		return ret;
15161bb76ff1Sjsg 	}
15171bb76ff1Sjsg 
15181bb76ff1Sjsg 	return 0;
15191bb76ff1Sjsg }
15201bb76ff1Sjsg 
intel_dpll_crtc_get_shared_dpll(struct intel_atomic_state * state,struct intel_crtc * crtc)15211bb76ff1Sjsg int intel_dpll_crtc_get_shared_dpll(struct intel_atomic_state *state,
15221bb76ff1Sjsg 				    struct intel_crtc *crtc)
15231bb76ff1Sjsg {
15241bb76ff1Sjsg 	struct drm_i915_private *i915 = to_i915(state->base.dev);
15251bb76ff1Sjsg 	struct intel_crtc_state *crtc_state =
15261bb76ff1Sjsg 		intel_atomic_get_new_crtc_state(state, crtc);
15271bb76ff1Sjsg 	int ret;
15281bb76ff1Sjsg 
15291bb76ff1Sjsg 	drm_WARN_ON(&i915->drm, !intel_crtc_needs_modeset(crtc_state));
15301bb76ff1Sjsg 	drm_WARN_ON(&i915->drm, !crtc_state->hw.enable && crtc_state->shared_dpll);
15311bb76ff1Sjsg 
15321bb76ff1Sjsg 	if (!crtc_state->hw.enable || crtc_state->shared_dpll)
15331bb76ff1Sjsg 		return 0;
15341bb76ff1Sjsg 
15351bb76ff1Sjsg 	if (!i915->display.funcs.dpll->crtc_get_shared_dpll)
15361bb76ff1Sjsg 		return 0;
15371bb76ff1Sjsg 
15381bb76ff1Sjsg 	ret = i915->display.funcs.dpll->crtc_get_shared_dpll(state, crtc);
15391bb76ff1Sjsg 	if (ret) {
15401bb76ff1Sjsg 		drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] Couldn't get a shared DPLL\n",
15411bb76ff1Sjsg 			    crtc->base.base.id, crtc->base.name);
15421bb76ff1Sjsg 		return ret;
15431bb76ff1Sjsg 	}
15445ca02815Sjsg 
15455ca02815Sjsg 	return 0;
15465ca02815Sjsg }
15475ca02815Sjsg 
15485ca02815Sjsg void
intel_dpll_init_clock_hook(struct drm_i915_private * dev_priv)15495ca02815Sjsg intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv)
15505ca02815Sjsg {
1551*f005ef32Sjsg 	if (DISPLAY_VER(dev_priv) >= 14)
1552*f005ef32Sjsg 		dev_priv->display.funcs.dpll = &mtl_dpll_funcs;
1553*f005ef32Sjsg 	else if (IS_DG2(dev_priv))
15541bb76ff1Sjsg 		dev_priv->display.funcs.dpll = &dg2_dpll_funcs;
15551bb76ff1Sjsg 	else if (DISPLAY_VER(dev_priv) >= 9 || HAS_DDI(dev_priv))
15561bb76ff1Sjsg 		dev_priv->display.funcs.dpll = &hsw_dpll_funcs;
15575ca02815Sjsg 	else if (HAS_PCH_SPLIT(dev_priv))
15581bb76ff1Sjsg 		dev_priv->display.funcs.dpll = &ilk_dpll_funcs;
15595ca02815Sjsg 	else if (IS_CHERRYVIEW(dev_priv))
15601bb76ff1Sjsg 		dev_priv->display.funcs.dpll = &chv_dpll_funcs;
15615ca02815Sjsg 	else if (IS_VALLEYVIEW(dev_priv))
15621bb76ff1Sjsg 		dev_priv->display.funcs.dpll = &vlv_dpll_funcs;
15635ca02815Sjsg 	else if (IS_G4X(dev_priv))
15641bb76ff1Sjsg 		dev_priv->display.funcs.dpll = &g4x_dpll_funcs;
15655ca02815Sjsg 	else if (IS_PINEVIEW(dev_priv))
15661bb76ff1Sjsg 		dev_priv->display.funcs.dpll = &pnv_dpll_funcs;
15675ca02815Sjsg 	else if (DISPLAY_VER(dev_priv) != 2)
15681bb76ff1Sjsg 		dev_priv->display.funcs.dpll = &i9xx_dpll_funcs;
15695ca02815Sjsg 	else
15701bb76ff1Sjsg 		dev_priv->display.funcs.dpll = &i8xx_dpll_funcs;
15715ca02815Sjsg }
15725ca02815Sjsg 
i9xx_has_pps(struct drm_i915_private * dev_priv)15735ca02815Sjsg static bool i9xx_has_pps(struct drm_i915_private *dev_priv)
15745ca02815Sjsg {
15755ca02815Sjsg 	if (IS_I830(dev_priv))
15765ca02815Sjsg 		return false;
15775ca02815Sjsg 
15785ca02815Sjsg 	return IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv);
15795ca02815Sjsg }
15805ca02815Sjsg 
i9xx_enable_pll(const struct intel_crtc_state * crtc_state)15811bb76ff1Sjsg void i9xx_enable_pll(const struct intel_crtc_state *crtc_state)
15825ca02815Sjsg {
15831bb76ff1Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
15845ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
15855ca02815Sjsg 	u32 dpll = crtc_state->dpll_hw_state.dpll;
15861bb76ff1Sjsg 	enum pipe pipe = crtc->pipe;
15875ca02815Sjsg 	int i;
15885ca02815Sjsg 
15891bb76ff1Sjsg 	assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder);
15905ca02815Sjsg 
15915ca02815Sjsg 	/* PLL is protected by panel, make sure we can write it */
15925ca02815Sjsg 	if (i9xx_has_pps(dev_priv))
15931bb76ff1Sjsg 		assert_pps_unlocked(dev_priv, pipe);
15941bb76ff1Sjsg 
15951bb76ff1Sjsg 	intel_de_write(dev_priv, FP0(pipe), crtc_state->dpll_hw_state.fp0);
15961bb76ff1Sjsg 	intel_de_write(dev_priv, FP1(pipe), crtc_state->dpll_hw_state.fp1);
15975ca02815Sjsg 
15985ca02815Sjsg 	/*
15995ca02815Sjsg 	 * Apparently we need to have VGA mode enabled prior to changing
16005ca02815Sjsg 	 * the P1/P2 dividers. Otherwise the DPLL will keep using the old
16015ca02815Sjsg 	 * dividers, even though the register value does change.
16025ca02815Sjsg 	 */
16031bb76ff1Sjsg 	intel_de_write(dev_priv, DPLL(pipe), dpll & ~DPLL_VGA_MODE_DIS);
16041bb76ff1Sjsg 	intel_de_write(dev_priv, DPLL(pipe), dpll);
16055ca02815Sjsg 
16065ca02815Sjsg 	/* Wait for the clocks to stabilize. */
16071bb76ff1Sjsg 	intel_de_posting_read(dev_priv, DPLL(pipe));
16085ca02815Sjsg 	udelay(150);
16095ca02815Sjsg 
16105ca02815Sjsg 	if (DISPLAY_VER(dev_priv) >= 4) {
16111bb76ff1Sjsg 		intel_de_write(dev_priv, DPLL_MD(pipe),
16125ca02815Sjsg 			       crtc_state->dpll_hw_state.dpll_md);
16135ca02815Sjsg 	} else {
16145ca02815Sjsg 		/* The pixel multiplier can only be updated once the
16155ca02815Sjsg 		 * DPLL is enabled and the clocks are stable.
16165ca02815Sjsg 		 *
16175ca02815Sjsg 		 * So write it again.
16185ca02815Sjsg 		 */
16191bb76ff1Sjsg 		intel_de_write(dev_priv, DPLL(pipe), dpll);
16205ca02815Sjsg 	}
16215ca02815Sjsg 
16225ca02815Sjsg 	/* We do this three times for luck */
16235ca02815Sjsg 	for (i = 0; i < 3; i++) {
16241bb76ff1Sjsg 		intel_de_write(dev_priv, DPLL(pipe), dpll);
16251bb76ff1Sjsg 		intel_de_posting_read(dev_priv, DPLL(pipe));
16265ca02815Sjsg 		udelay(150); /* wait for warmup */
16275ca02815Sjsg 	}
16285ca02815Sjsg }
16295ca02815Sjsg 
vlv_pllb_recal_opamp(struct drm_i915_private * dev_priv,enum pipe pipe)16305ca02815Sjsg static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv,
16315ca02815Sjsg 				 enum pipe pipe)
16325ca02815Sjsg {
16335ca02815Sjsg 	u32 reg_val;
16345ca02815Sjsg 
16355ca02815Sjsg 	/*
16365ca02815Sjsg 	 * PLLB opamp always calibrates to max value of 0x3f, force enable it
16375ca02815Sjsg 	 * and set it to a reasonable value instead.
16385ca02815Sjsg 	 */
16395ca02815Sjsg 	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW9(1));
16405ca02815Sjsg 	reg_val &= 0xffffff00;
16415ca02815Sjsg 	reg_val |= 0x00000030;
16425ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9(1), reg_val);
16435ca02815Sjsg 
16445ca02815Sjsg 	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_REF_DW13);
16455ca02815Sjsg 	reg_val &= 0x00ffffff;
16465ca02815Sjsg 	reg_val |= 0x8c000000;
16475ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val);
16485ca02815Sjsg 
16495ca02815Sjsg 	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW9(1));
16505ca02815Sjsg 	reg_val &= 0xffffff00;
16515ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9(1), reg_val);
16525ca02815Sjsg 
16535ca02815Sjsg 	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_REF_DW13);
16545ca02815Sjsg 	reg_val &= 0x00ffffff;
16555ca02815Sjsg 	reg_val |= 0xb0000000;
16565ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val);
16575ca02815Sjsg }
16585ca02815Sjsg 
vlv_prepare_pll(const struct intel_crtc_state * crtc_state)16591bb76ff1Sjsg static void vlv_prepare_pll(const struct intel_crtc_state *crtc_state)
16605ca02815Sjsg {
16611bb76ff1Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
16625ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
16635ca02815Sjsg 	enum pipe pipe = crtc->pipe;
16645ca02815Sjsg 	u32 mdiv;
16655ca02815Sjsg 	u32 bestn, bestm1, bestm2, bestp1, bestp2;
16665ca02815Sjsg 	u32 coreclk, reg_val;
16675ca02815Sjsg 
16685ca02815Sjsg 	vlv_dpio_get(dev_priv);
16695ca02815Sjsg 
16701bb76ff1Sjsg 	bestn = crtc_state->dpll.n;
16711bb76ff1Sjsg 	bestm1 = crtc_state->dpll.m1;
16721bb76ff1Sjsg 	bestm2 = crtc_state->dpll.m2;
16731bb76ff1Sjsg 	bestp1 = crtc_state->dpll.p1;
16741bb76ff1Sjsg 	bestp2 = crtc_state->dpll.p2;
16755ca02815Sjsg 
16765ca02815Sjsg 	/* See eDP HDMI DPIO driver vbios notes doc */
16775ca02815Sjsg 
16785ca02815Sjsg 	/* PLL B needs special handling */
16795ca02815Sjsg 	if (pipe == PIPE_B)
16805ca02815Sjsg 		vlv_pllb_recal_opamp(dev_priv, pipe);
16815ca02815Sjsg 
16825ca02815Sjsg 	/* Set up Tx target for periodic Rcomp update */
16835ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9_BCAST, 0x0100000f);
16845ca02815Sjsg 
16855ca02815Sjsg 	/* Disable target IRef on PLL */
16865ca02815Sjsg 	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW8(pipe));
16875ca02815Sjsg 	reg_val &= 0x00ffffff;
16885ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW8(pipe), reg_val);
16895ca02815Sjsg 
16905ca02815Sjsg 	/* Disable fast lock */
16915ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, VLV_CMN_DW0, 0x610);
16925ca02815Sjsg 
16935ca02815Sjsg 	/* Set idtafcrecal before PLL is enabled */
16945ca02815Sjsg 	mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK));
16955ca02815Sjsg 	mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT));
16965ca02815Sjsg 	mdiv |= ((bestn << DPIO_N_SHIFT));
16975ca02815Sjsg 	mdiv |= (1 << DPIO_K_SHIFT);
16985ca02815Sjsg 
16995ca02815Sjsg 	/*
17005ca02815Sjsg 	 * Post divider depends on pixel clock rate, DAC vs digital (and LVDS,
17015ca02815Sjsg 	 * but we don't support that).
17025ca02815Sjsg 	 * Note: don't use the DAC post divider as it seems unstable.
17035ca02815Sjsg 	 */
17045ca02815Sjsg 	mdiv |= (DPIO_POST_DIV_HDMIDP << DPIO_POST_DIV_SHIFT);
17055ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv);
17065ca02815Sjsg 
17075ca02815Sjsg 	mdiv |= DPIO_ENABLE_CALIBRATION;
17085ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv);
17095ca02815Sjsg 
17105ca02815Sjsg 	/* Set HBR and RBR LPF coefficients */
17111bb76ff1Sjsg 	if (crtc_state->port_clock == 162000 ||
17121bb76ff1Sjsg 	    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG) ||
17131bb76ff1Sjsg 	    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
17145ca02815Sjsg 		vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
17155ca02815Sjsg 				 0x009f0003);
17165ca02815Sjsg 	else
17175ca02815Sjsg 		vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
17185ca02815Sjsg 				 0x00d0000f);
17195ca02815Sjsg 
17201bb76ff1Sjsg 	if (intel_crtc_has_dp_encoder(crtc_state)) {
17215ca02815Sjsg 		/* Use SSC source */
17225ca02815Sjsg 		if (pipe == PIPE_A)
17235ca02815Sjsg 			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
17245ca02815Sjsg 					 0x0df40000);
17255ca02815Sjsg 		else
17265ca02815Sjsg 			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
17275ca02815Sjsg 					 0x0df70000);
17285ca02815Sjsg 	} else { /* HDMI or VGA */
17295ca02815Sjsg 		/* Use bend source */
17305ca02815Sjsg 		if (pipe == PIPE_A)
17315ca02815Sjsg 			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
17325ca02815Sjsg 					 0x0df70000);
17335ca02815Sjsg 		else
17345ca02815Sjsg 			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
17355ca02815Sjsg 					 0x0df40000);
17365ca02815Sjsg 	}
17375ca02815Sjsg 
17385ca02815Sjsg 	coreclk = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW7(pipe));
17395ca02815Sjsg 	coreclk = (coreclk & 0x0000ff00) | 0x01c00000;
17401bb76ff1Sjsg 	if (intel_crtc_has_dp_encoder(crtc_state))
17415ca02815Sjsg 		coreclk |= 0x01000000;
17425ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW7(pipe), coreclk);
17435ca02815Sjsg 
17445ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW11(pipe), 0x87871000);
17455ca02815Sjsg 
17465ca02815Sjsg 	vlv_dpio_put(dev_priv);
17475ca02815Sjsg }
17485ca02815Sjsg 
_vlv_enable_pll(const struct intel_crtc_state * crtc_state)17491bb76ff1Sjsg static void _vlv_enable_pll(const struct intel_crtc_state *crtc_state)
17505ca02815Sjsg {
17511bb76ff1Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
17521bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
17531bb76ff1Sjsg 	enum pipe pipe = crtc->pipe;
17541bb76ff1Sjsg 
17551bb76ff1Sjsg 	intel_de_write(dev_priv, DPLL(pipe), crtc_state->dpll_hw_state.dpll);
17561bb76ff1Sjsg 	intel_de_posting_read(dev_priv, DPLL(pipe));
17571bb76ff1Sjsg 	udelay(150);
17581bb76ff1Sjsg 
17591bb76ff1Sjsg 	if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1))
17601bb76ff1Sjsg 		drm_err(&dev_priv->drm, "DPLL %d failed to lock\n", pipe);
17611bb76ff1Sjsg }
17621bb76ff1Sjsg 
vlv_enable_pll(const struct intel_crtc_state * crtc_state)17631bb76ff1Sjsg void vlv_enable_pll(const struct intel_crtc_state *crtc_state)
17641bb76ff1Sjsg {
17651bb76ff1Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
17661bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
17671bb76ff1Sjsg 	enum pipe pipe = crtc->pipe;
17681bb76ff1Sjsg 
17691bb76ff1Sjsg 	assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder);
17701bb76ff1Sjsg 
17711bb76ff1Sjsg 	/* PLL is protected by panel, make sure we can write it */
17721bb76ff1Sjsg 	assert_pps_unlocked(dev_priv, pipe);
17731bb76ff1Sjsg 
17741bb76ff1Sjsg 	/* Enable Refclk */
17751bb76ff1Sjsg 	intel_de_write(dev_priv, DPLL(pipe),
17761bb76ff1Sjsg 		       crtc_state->dpll_hw_state.dpll &
17771bb76ff1Sjsg 		       ~(DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV));
17781bb76ff1Sjsg 
17791bb76ff1Sjsg 	if (crtc_state->dpll_hw_state.dpll & DPLL_VCO_ENABLE) {
17801bb76ff1Sjsg 		vlv_prepare_pll(crtc_state);
17811bb76ff1Sjsg 		_vlv_enable_pll(crtc_state);
17821bb76ff1Sjsg 	}
17831bb76ff1Sjsg 
17841bb76ff1Sjsg 	intel_de_write(dev_priv, DPLL_MD(pipe),
17851bb76ff1Sjsg 		       crtc_state->dpll_hw_state.dpll_md);
17861bb76ff1Sjsg 	intel_de_posting_read(dev_priv, DPLL_MD(pipe));
17871bb76ff1Sjsg }
17881bb76ff1Sjsg 
chv_prepare_pll(const struct intel_crtc_state * crtc_state)17891bb76ff1Sjsg static void chv_prepare_pll(const struct intel_crtc_state *crtc_state)
17901bb76ff1Sjsg {
17911bb76ff1Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
17921bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
17935ca02815Sjsg 	enum pipe pipe = crtc->pipe;
17945ca02815Sjsg 	enum dpio_channel port = vlv_pipe_to_channel(pipe);
17955ca02815Sjsg 	u32 loopfilter, tribuf_calcntr;
1796*f005ef32Sjsg 	u32 bestm2, bestp1, bestp2, bestm2_frac;
17975ca02815Sjsg 	u32 dpio_val;
17985ca02815Sjsg 	int vco;
17995ca02815Sjsg 
18001bb76ff1Sjsg 	bestm2_frac = crtc_state->dpll.m2 & 0x3fffff;
18011bb76ff1Sjsg 	bestm2 = crtc_state->dpll.m2 >> 22;
18021bb76ff1Sjsg 	bestp1 = crtc_state->dpll.p1;
18031bb76ff1Sjsg 	bestp2 = crtc_state->dpll.p2;
18041bb76ff1Sjsg 	vco = crtc_state->dpll.vco;
18055ca02815Sjsg 	dpio_val = 0;
18065ca02815Sjsg 	loopfilter = 0;
18075ca02815Sjsg 
18085ca02815Sjsg 	vlv_dpio_get(dev_priv);
18095ca02815Sjsg 
18105ca02815Sjsg 	/* p1 and p2 divider */
18115ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW13(port),
18125ca02815Sjsg 			5 << DPIO_CHV_S1_DIV_SHIFT |
18135ca02815Sjsg 			bestp1 << DPIO_CHV_P1_DIV_SHIFT |
18145ca02815Sjsg 			bestp2 << DPIO_CHV_P2_DIV_SHIFT |
18155ca02815Sjsg 			1 << DPIO_CHV_K_DIV_SHIFT);
18165ca02815Sjsg 
18175ca02815Sjsg 	/* Feedback post-divider - m2 */
18185ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW0(port), bestm2);
18195ca02815Sjsg 
18205ca02815Sjsg 	/* Feedback refclk divider - n and m1 */
18215ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW1(port),
18225ca02815Sjsg 			DPIO_CHV_M1_DIV_BY_2 |
18235ca02815Sjsg 			1 << DPIO_CHV_N_DIV_SHIFT);
18245ca02815Sjsg 
18255ca02815Sjsg 	/* M2 fraction division */
18265ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW2(port), bestm2_frac);
18275ca02815Sjsg 
18285ca02815Sjsg 	/* M2 fraction division enable */
18295ca02815Sjsg 	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW3(port));
18305ca02815Sjsg 	dpio_val &= ~(DPIO_CHV_FEEDFWD_GAIN_MASK | DPIO_CHV_FRAC_DIV_EN);
18315ca02815Sjsg 	dpio_val |= (2 << DPIO_CHV_FEEDFWD_GAIN_SHIFT);
18325ca02815Sjsg 	if (bestm2_frac)
18335ca02815Sjsg 		dpio_val |= DPIO_CHV_FRAC_DIV_EN;
18345ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW3(port), dpio_val);
18355ca02815Sjsg 
18365ca02815Sjsg 	/* Program digital lock detect threshold */
18375ca02815Sjsg 	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW9(port));
18385ca02815Sjsg 	dpio_val &= ~(DPIO_CHV_INT_LOCK_THRESHOLD_MASK |
18395ca02815Sjsg 					DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE);
18405ca02815Sjsg 	dpio_val |= (0x5 << DPIO_CHV_INT_LOCK_THRESHOLD_SHIFT);
18415ca02815Sjsg 	if (!bestm2_frac)
18425ca02815Sjsg 		dpio_val |= DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE;
18435ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW9(port), dpio_val);
18445ca02815Sjsg 
18455ca02815Sjsg 	/* Loop filter */
18465ca02815Sjsg 	if (vco == 5400000) {
18475ca02815Sjsg 		loopfilter |= (0x3 << DPIO_CHV_PROP_COEFF_SHIFT);
18485ca02815Sjsg 		loopfilter |= (0x8 << DPIO_CHV_INT_COEFF_SHIFT);
18495ca02815Sjsg 		loopfilter |= (0x1 << DPIO_CHV_GAIN_CTRL_SHIFT);
18505ca02815Sjsg 		tribuf_calcntr = 0x9;
18515ca02815Sjsg 	} else if (vco <= 6200000) {
18525ca02815Sjsg 		loopfilter |= (0x5 << DPIO_CHV_PROP_COEFF_SHIFT);
18535ca02815Sjsg 		loopfilter |= (0xB << DPIO_CHV_INT_COEFF_SHIFT);
18545ca02815Sjsg 		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
18555ca02815Sjsg 		tribuf_calcntr = 0x9;
18565ca02815Sjsg 	} else if (vco <= 6480000) {
18575ca02815Sjsg 		loopfilter |= (0x4 << DPIO_CHV_PROP_COEFF_SHIFT);
18585ca02815Sjsg 		loopfilter |= (0x9 << DPIO_CHV_INT_COEFF_SHIFT);
18595ca02815Sjsg 		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
18605ca02815Sjsg 		tribuf_calcntr = 0x8;
18615ca02815Sjsg 	} else {
18625ca02815Sjsg 		/* Not supported. Apply the same limits as in the max case */
18635ca02815Sjsg 		loopfilter |= (0x4 << DPIO_CHV_PROP_COEFF_SHIFT);
18645ca02815Sjsg 		loopfilter |= (0x9 << DPIO_CHV_INT_COEFF_SHIFT);
18655ca02815Sjsg 		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
18665ca02815Sjsg 		tribuf_calcntr = 0;
18675ca02815Sjsg 	}
18685ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW6(port), loopfilter);
18695ca02815Sjsg 
18705ca02815Sjsg 	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW8(port));
18715ca02815Sjsg 	dpio_val &= ~DPIO_CHV_TDC_TARGET_CNT_MASK;
18725ca02815Sjsg 	dpio_val |= (tribuf_calcntr << DPIO_CHV_TDC_TARGET_CNT_SHIFT);
18735ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW8(port), dpio_val);
18745ca02815Sjsg 
18755ca02815Sjsg 	/* AFC Recal */
18765ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port),
18775ca02815Sjsg 			vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port)) |
18785ca02815Sjsg 			DPIO_AFC_RECAL);
18795ca02815Sjsg 
18805ca02815Sjsg 	vlv_dpio_put(dev_priv);
18815ca02815Sjsg }
18825ca02815Sjsg 
_chv_enable_pll(const struct intel_crtc_state * crtc_state)18831bb76ff1Sjsg static void _chv_enable_pll(const struct intel_crtc_state *crtc_state)
18841bb76ff1Sjsg {
18851bb76ff1Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
18861bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
18871bb76ff1Sjsg 	enum pipe pipe = crtc->pipe;
18881bb76ff1Sjsg 	enum dpio_channel port = vlv_pipe_to_channel(pipe);
18891bb76ff1Sjsg 	u32 tmp;
18901bb76ff1Sjsg 
18911bb76ff1Sjsg 	vlv_dpio_get(dev_priv);
18921bb76ff1Sjsg 
18931bb76ff1Sjsg 	/* Enable back the 10bit clock to display controller */
18941bb76ff1Sjsg 	tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
18951bb76ff1Sjsg 	tmp |= DPIO_DCLKP_EN;
18961bb76ff1Sjsg 	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), tmp);
18971bb76ff1Sjsg 
18981bb76ff1Sjsg 	vlv_dpio_put(dev_priv);
18991bb76ff1Sjsg 
19001bb76ff1Sjsg 	/*
19011bb76ff1Sjsg 	 * Need to wait > 100ns between dclkp clock enable bit and PLL enable.
19021bb76ff1Sjsg 	 */
19031bb76ff1Sjsg 	udelay(1);
19041bb76ff1Sjsg 
19051bb76ff1Sjsg 	/* Enable PLL */
19061bb76ff1Sjsg 	intel_de_write(dev_priv, DPLL(pipe), crtc_state->dpll_hw_state.dpll);
19071bb76ff1Sjsg 
19081bb76ff1Sjsg 	/* Check PLL is locked */
19091bb76ff1Sjsg 	if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1))
19101bb76ff1Sjsg 		drm_err(&dev_priv->drm, "PLL %d failed to lock\n", pipe);
19111bb76ff1Sjsg }
19121bb76ff1Sjsg 
chv_enable_pll(const struct intel_crtc_state * crtc_state)19131bb76ff1Sjsg void chv_enable_pll(const struct intel_crtc_state *crtc_state)
19141bb76ff1Sjsg {
19151bb76ff1Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
19161bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
19171bb76ff1Sjsg 	enum pipe pipe = crtc->pipe;
19181bb76ff1Sjsg 
19191bb76ff1Sjsg 	assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder);
19201bb76ff1Sjsg 
19211bb76ff1Sjsg 	/* PLL is protected by panel, make sure we can write it */
19221bb76ff1Sjsg 	assert_pps_unlocked(dev_priv, pipe);
19231bb76ff1Sjsg 
19241bb76ff1Sjsg 	/* Enable Refclk and SSC */
19251bb76ff1Sjsg 	intel_de_write(dev_priv, DPLL(pipe),
19261bb76ff1Sjsg 		       crtc_state->dpll_hw_state.dpll & ~DPLL_VCO_ENABLE);
19271bb76ff1Sjsg 
19281bb76ff1Sjsg 	if (crtc_state->dpll_hw_state.dpll & DPLL_VCO_ENABLE) {
19291bb76ff1Sjsg 		chv_prepare_pll(crtc_state);
19301bb76ff1Sjsg 		_chv_enable_pll(crtc_state);
19311bb76ff1Sjsg 	}
19321bb76ff1Sjsg 
19331bb76ff1Sjsg 	if (pipe != PIPE_A) {
19341bb76ff1Sjsg 		/*
19351bb76ff1Sjsg 		 * WaPixelRepeatModeFixForC0:chv
19361bb76ff1Sjsg 		 *
19371bb76ff1Sjsg 		 * DPLLCMD is AWOL. Use chicken bits to propagate
19381bb76ff1Sjsg 		 * the value from DPLLBMD to either pipe B or C.
19391bb76ff1Sjsg 		 */
19401bb76ff1Sjsg 		intel_de_write(dev_priv, CBR4_VLV, CBR_DPLLBMD_PIPE(pipe));
19411bb76ff1Sjsg 		intel_de_write(dev_priv, DPLL_MD(PIPE_B),
19421bb76ff1Sjsg 			       crtc_state->dpll_hw_state.dpll_md);
19431bb76ff1Sjsg 		intel_de_write(dev_priv, CBR4_VLV, 0);
1944*f005ef32Sjsg 		dev_priv->display.state.chv_dpll_md[pipe] = crtc_state->dpll_hw_state.dpll_md;
19451bb76ff1Sjsg 
19461bb76ff1Sjsg 		/*
19471bb76ff1Sjsg 		 * DPLLB VGA mode also seems to cause problems.
19481bb76ff1Sjsg 		 * We should always have it disabled.
19491bb76ff1Sjsg 		 */
19501bb76ff1Sjsg 		drm_WARN_ON(&dev_priv->drm,
19511bb76ff1Sjsg 			    (intel_de_read(dev_priv, DPLL(PIPE_B)) &
19521bb76ff1Sjsg 			     DPLL_VGA_MODE_DIS) == 0);
19531bb76ff1Sjsg 	} else {
19541bb76ff1Sjsg 		intel_de_write(dev_priv, DPLL_MD(pipe),
19551bb76ff1Sjsg 			       crtc_state->dpll_hw_state.dpll_md);
19561bb76ff1Sjsg 		intel_de_posting_read(dev_priv, DPLL_MD(pipe));
19571bb76ff1Sjsg 	}
19581bb76ff1Sjsg }
19591bb76ff1Sjsg 
19605ca02815Sjsg /**
19615ca02815Sjsg  * vlv_force_pll_on - forcibly enable just the PLL
19625ca02815Sjsg  * @dev_priv: i915 private structure
19635ca02815Sjsg  * @pipe: pipe PLL to enable
19645ca02815Sjsg  * @dpll: PLL configuration
19655ca02815Sjsg  *
19665ca02815Sjsg  * Enable the PLL for @pipe using the supplied @dpll config. To be used
19675ca02815Sjsg  * in cases where we need the PLL enabled even when @pipe is not going to
19685ca02815Sjsg  * be enabled.
19695ca02815Sjsg  */
vlv_force_pll_on(struct drm_i915_private * dev_priv,enum pipe pipe,const struct dpll * dpll)19705ca02815Sjsg int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
19715ca02815Sjsg 		     const struct dpll *dpll)
19725ca02815Sjsg {
19731bb76ff1Sjsg 	struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);
19741bb76ff1Sjsg 	struct intel_crtc_state *crtc_state;
19755ca02815Sjsg 
19761bb76ff1Sjsg 	crtc_state = intel_crtc_state_alloc(crtc);
19771bb76ff1Sjsg 	if (!crtc_state)
19785ca02815Sjsg 		return -ENOMEM;
19795ca02815Sjsg 
19801bb76ff1Sjsg 	crtc_state->cpu_transcoder = (enum transcoder)pipe;
19811bb76ff1Sjsg 	crtc_state->pixel_multiplier = 1;
19821bb76ff1Sjsg 	crtc_state->dpll = *dpll;
19831bb76ff1Sjsg 	crtc_state->output_types = BIT(INTEL_OUTPUT_EDP);
19845ca02815Sjsg 
19855ca02815Sjsg 	if (IS_CHERRYVIEW(dev_priv)) {
19861bb76ff1Sjsg 		chv_compute_dpll(crtc_state);
19871bb76ff1Sjsg 		chv_enable_pll(crtc_state);
19885ca02815Sjsg 	} else {
19891bb76ff1Sjsg 		vlv_compute_dpll(crtc_state);
19901bb76ff1Sjsg 		vlv_enable_pll(crtc_state);
19915ca02815Sjsg 	}
19925ca02815Sjsg 
19931bb76ff1Sjsg 	kfree(crtc_state);
19945ca02815Sjsg 
19955ca02815Sjsg 	return 0;
19965ca02815Sjsg }
19975ca02815Sjsg 
vlv_disable_pll(struct drm_i915_private * dev_priv,enum pipe pipe)19985ca02815Sjsg void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
19995ca02815Sjsg {
20005ca02815Sjsg 	u32 val;
20015ca02815Sjsg 
20025ca02815Sjsg 	/* Make sure the pipe isn't still relying on us */
20031bb76ff1Sjsg 	assert_transcoder_disabled(dev_priv, (enum transcoder)pipe);
20045ca02815Sjsg 
20055ca02815Sjsg 	val = DPLL_INTEGRATED_REF_CLK_VLV |
20065ca02815Sjsg 		DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
20075ca02815Sjsg 	if (pipe != PIPE_A)
20085ca02815Sjsg 		val |= DPLL_INTEGRATED_CRI_CLK_VLV;
20095ca02815Sjsg 
20105ca02815Sjsg 	intel_de_write(dev_priv, DPLL(pipe), val);
20115ca02815Sjsg 	intel_de_posting_read(dev_priv, DPLL(pipe));
20125ca02815Sjsg }
20135ca02815Sjsg 
chv_disable_pll(struct drm_i915_private * dev_priv,enum pipe pipe)20145ca02815Sjsg void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
20155ca02815Sjsg {
20165ca02815Sjsg 	enum dpio_channel port = vlv_pipe_to_channel(pipe);
20175ca02815Sjsg 	u32 val;
20185ca02815Sjsg 
20195ca02815Sjsg 	/* Make sure the pipe isn't still relying on us */
20201bb76ff1Sjsg 	assert_transcoder_disabled(dev_priv, (enum transcoder)pipe);
20215ca02815Sjsg 
20225ca02815Sjsg 	val = DPLL_SSC_REF_CLK_CHV |
20235ca02815Sjsg 		DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
20245ca02815Sjsg 	if (pipe != PIPE_A)
20255ca02815Sjsg 		val |= DPLL_INTEGRATED_CRI_CLK_VLV;
20265ca02815Sjsg 
20275ca02815Sjsg 	intel_de_write(dev_priv, DPLL(pipe), val);
20285ca02815Sjsg 	intel_de_posting_read(dev_priv, DPLL(pipe));
20295ca02815Sjsg 
20305ca02815Sjsg 	vlv_dpio_get(dev_priv);
20315ca02815Sjsg 
20325ca02815Sjsg 	/* Disable 10bit clock to display controller */
20335ca02815Sjsg 	val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
20345ca02815Sjsg 	val &= ~DPIO_DCLKP_EN;
20355ca02815Sjsg 	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), val);
20365ca02815Sjsg 
20375ca02815Sjsg 	vlv_dpio_put(dev_priv);
20385ca02815Sjsg }
20395ca02815Sjsg 
i9xx_disable_pll(const struct intel_crtc_state * crtc_state)20405ca02815Sjsg void i9xx_disable_pll(const struct intel_crtc_state *crtc_state)
20415ca02815Sjsg {
20425ca02815Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
20435ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
20445ca02815Sjsg 	enum pipe pipe = crtc->pipe;
20455ca02815Sjsg 
20465ca02815Sjsg 	/* Don't disable pipe or pipe PLLs if needed */
20475ca02815Sjsg 	if (IS_I830(dev_priv))
20485ca02815Sjsg 		return;
20495ca02815Sjsg 
20505ca02815Sjsg 	/* Make sure the pipe isn't still relying on us */
20511bb76ff1Sjsg 	assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder);
20525ca02815Sjsg 
20535ca02815Sjsg 	intel_de_write(dev_priv, DPLL(pipe), DPLL_VGA_MODE_DIS);
20545ca02815Sjsg 	intel_de_posting_read(dev_priv, DPLL(pipe));
20555ca02815Sjsg }
20565ca02815Sjsg 
20575ca02815Sjsg 
20585ca02815Sjsg /**
20595ca02815Sjsg  * vlv_force_pll_off - forcibly disable just the PLL
20605ca02815Sjsg  * @dev_priv: i915 private structure
20615ca02815Sjsg  * @pipe: pipe PLL to disable
20625ca02815Sjsg  *
20635ca02815Sjsg  * Disable the PLL for @pipe. To be used in cases where we need
20645ca02815Sjsg  * the PLL enabled even when @pipe is not going to be enabled.
20655ca02815Sjsg  */
vlv_force_pll_off(struct drm_i915_private * dev_priv,enum pipe pipe)20665ca02815Sjsg void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe)
20675ca02815Sjsg {
20685ca02815Sjsg 	if (IS_CHERRYVIEW(dev_priv))
20695ca02815Sjsg 		chv_disable_pll(dev_priv, pipe);
20705ca02815Sjsg 	else
20715ca02815Sjsg 		vlv_disable_pll(dev_priv, pipe);
20725ca02815Sjsg }
20731bb76ff1Sjsg 
20741bb76ff1Sjsg /* Only for pre-ILK configs */
assert_pll(struct drm_i915_private * dev_priv,enum pipe pipe,bool state)20751bb76ff1Sjsg static void assert_pll(struct drm_i915_private *dev_priv,
20761bb76ff1Sjsg 		       enum pipe pipe, bool state)
20771bb76ff1Sjsg {
20781bb76ff1Sjsg 	bool cur_state;
20791bb76ff1Sjsg 
20801bb76ff1Sjsg 	cur_state = intel_de_read(dev_priv, DPLL(pipe)) & DPLL_VCO_ENABLE;
2081*f005ef32Sjsg 	I915_STATE_WARN(dev_priv, cur_state != state,
20821bb76ff1Sjsg 			"PLL state assertion failure (expected %s, current %s)\n",
20831bb76ff1Sjsg 			str_on_off(state), str_on_off(cur_state));
20841bb76ff1Sjsg }
20851bb76ff1Sjsg 
assert_pll_enabled(struct drm_i915_private * i915,enum pipe pipe)20861bb76ff1Sjsg void assert_pll_enabled(struct drm_i915_private *i915, enum pipe pipe)
20871bb76ff1Sjsg {
20881bb76ff1Sjsg 	assert_pll(i915, pipe, true);
20891bb76ff1Sjsg }
20901bb76ff1Sjsg 
assert_pll_disabled(struct drm_i915_private * i915,enum pipe pipe)20911bb76ff1Sjsg void assert_pll_disabled(struct drm_i915_private *i915, enum pipe pipe)
20921bb76ff1Sjsg {
20931bb76ff1Sjsg 	assert_pll(i915, pipe, false);
20941bb76ff1Sjsg }
2095