aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_dpll_mgr.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-12-03 18:40:35 -0500
committerDave Airlie <airlied@redhat.com>2017-12-03 19:56:53 -0500
commitca797d29cd63e7b71b4eea29aff3b1cefd1ecb59 (patch)
treedb1ada69f713da68b43c828bd15f90e250f86ab7 /drivers/gpu/drm/i915/intel_dpll_mgr.c
parent2c1c55cb75a9c72f9726fabb8c3607947711a8df (diff)
parent010d118c20617021025a930bc8e90f371ab99da5 (diff)
Merge tag 'drm-intel-next-2017-11-17-1' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
More change sets for 4.16: - Many improvements for selftests and other igt tests (Chris) - Forcewake with PUNIT->PMIC bus fixes and robustness (Hans) - Define an engine class for uABI (Tvrtko) - Context switch fixes and improvements (Chris) - GT powersavings and power gating simplification and fixes (Chris) - Other general driver clean-ups (Chris, Lucas, Ville) - Removing old, useless and/or bad workarounds (Chris, Oscar, Radhakrishna) - IPS, pipe config, etc in preparation for another Fast Boot attempt (Maarten) - OA perf fixes and support to Coffee Lake and Cannonlake (Lionel) - Fixes around GPU fault registers (Michel) - GEM Proxy (Tina) - Refactor of Geminilake and Cannonlake plane color handling (James) - Generalize transcoder loop (Mika Kahola) - New HW Workaround for Cannonlake and Geminilake (Rodrigo) - Resume GuC before using GEM (Chris) - Stolen Memory handling improvements (Ville) - Initialize entry in PPAT for older compilers (Chris) - Other fixes and robustness improvements on execbuf (Chris) - Improve logs of GEM_BUG_ON (Mika Kuoppala) - Rework with massive rename of GuC functions and files (Sagar) - Don't sanitize frame start delay if pipe is off (Ville) - Cannonlake clock fixes (Rodrigo) - Cannonlake HDMI 2.0 support (Rodrigo) - Add a GuC doorbells selftest (Michel) - Add might_sleep() check to our wait_for() (Chris) Many GVT changes for 4.16: - CSB HWSP update support (Weinan) - GVT debug helpers, dyndbg and debugfs (Chuanxiao, Shuo) - full virtualized opregion (Xiaolin) - VM health check for sane fallback (Fred) - workload submission code refactor for future enabling (Zhi) - Updated repo URL in MAINTAINERS (Zhenyu) - other many misc fixes * tag 'drm-intel-next-2017-11-17-1' of git://anongit.freedesktop.org/drm/drm-intel: (260 commits) drm/i915: Update DRIVER_DATE to 20171117 drm/i915: Add a policy note for removing workarounds drm/i915/selftests: Report ENOMEM clearly for an allocation failure Revert "drm/i915: Display WA #1133 WaFbcSkipSegments:cnl, glk" drm/i915: Calculate g4x intermediate watermarks correctly drm/i915: Calculate vlv/chv intermediate watermarks correctly, v3. drm/i915: Pass crtc_state to ips toggle functions, v2 drm/i915: Pass idle crtc_state to intel_dp_sink_crc drm/i915: Enable FIFO underrun reporting after initial fastset, v4. drm/i915: Mark the userptr invalidate workqueue as WQ_MEM_RECLAIM drm/i915: Add might_sleep() check to wait_for() drm/i915/selftests: Add a GuC doorbells selftest drm/i915/cnl: Extend HDMI 2.0 support to CNL. drm/i915/cnl: Simplify dco_fraction calculation. drm/i915/cnl: Don't blindly replace qdiv. drm/i915/cnl: Fix wrpll math for higher freqs. drm/i915/cnl: Fix, simplify and unify wrpll variable sizes. drm/i915/cnl: Remove useless conversion. drm/i915/cnl: Remove spurious central_freq. drm/i915/selftests: exercise_ggtt may have nothing to do ...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dpll_mgr.c')
-rw-r--r--drivers/gpu/drm/i915/intel_dpll_mgr.c107
1 files changed, 42 insertions, 65 deletions
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index df808a94c511..51c5ae4e9116 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -813,15 +813,11 @@ hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
813 memset(&crtc_state->dpll_hw_state, 0, 813 memset(&crtc_state->dpll_hw_state, 0,
814 sizeof(crtc_state->dpll_hw_state)); 814 sizeof(crtc_state->dpll_hw_state));
815 815
816 if (encoder->type == INTEL_OUTPUT_HDMI) { 816 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
817 pll = hsw_ddi_hdmi_get_dpll(clock, crtc, crtc_state); 817 pll = hsw_ddi_hdmi_get_dpll(clock, crtc, crtc_state);
818 818 } else if (intel_crtc_has_dp_encoder(crtc_state)) {
819 } else if (encoder->type == INTEL_OUTPUT_DP ||
820 encoder->type == INTEL_OUTPUT_DP_MST ||
821 encoder->type == INTEL_OUTPUT_EDP) {
822 pll = hsw_ddi_dp_get_dpll(encoder, clock); 819 pll = hsw_ddi_dp_get_dpll(encoder, clock);
823 820 } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) {
824 } else if (encoder->type == INTEL_OUTPUT_ANALOG) {
825 if (WARN_ON(crtc_state->port_clock / 2 != 135000)) 821 if (WARN_ON(crtc_state->port_clock / 2 != 135000))
826 return NULL; 822 return NULL;
827 823
@@ -1369,15 +1365,13 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
1369 1365
1370 memset(&dpll_hw_state, 0, sizeof(dpll_hw_state)); 1366 memset(&dpll_hw_state, 0, sizeof(dpll_hw_state));
1371 1367
1372 if (encoder->type == INTEL_OUTPUT_HDMI) { 1368 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
1373 bret = skl_ddi_hdmi_pll_dividers(crtc, crtc_state, clock); 1369 bret = skl_ddi_hdmi_pll_dividers(crtc, crtc_state, clock);
1374 if (!bret) { 1370 if (!bret) {
1375 DRM_DEBUG_KMS("Could not get HDMI pll dividers.\n"); 1371 DRM_DEBUG_KMS("Could not get HDMI pll dividers.\n");
1376 return NULL; 1372 return NULL;
1377 } 1373 }
1378 } else if (encoder->type == INTEL_OUTPUT_DP || 1374 } else if (intel_crtc_has_dp_encoder(crtc_state)) {
1379 encoder->type == INTEL_OUTPUT_DP_MST ||
1380 encoder->type == INTEL_OUTPUT_EDP) {
1381 bret = skl_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state); 1375 bret = skl_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state);
1382 if (!bret) { 1376 if (!bret) {
1383 DRM_DEBUG_KMS("Could not set DP dpll HW state.\n"); 1377 DRM_DEBUG_KMS("Could not set DP dpll HW state.\n");
@@ -1388,7 +1382,7 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
1388 return NULL; 1382 return NULL;
1389 } 1383 }
1390 1384
1391 if (encoder->type == INTEL_OUTPUT_EDP) 1385 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
1392 pll = intel_find_shared_dpll(crtc, crtc_state, 1386 pll = intel_find_shared_dpll(crtc, crtc_state,
1393 DPLL_ID_SKL_DPLL0, 1387 DPLL_ID_SKL_DPLL0,
1394 DPLL_ID_SKL_DPLL0); 1388 DPLL_ID_SKL_DPLL0);
@@ -1808,18 +1802,15 @@ bxt_get_dpll(struct intel_crtc *crtc,
1808{ 1802{
1809 struct intel_dpll_hw_state dpll_hw_state = { }; 1803 struct intel_dpll_hw_state dpll_hw_state = { };
1810 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 1804 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1811 struct intel_digital_port *intel_dig_port;
1812 struct intel_shared_dpll *pll; 1805 struct intel_shared_dpll *pll;
1813 int i, clock = crtc_state->port_clock; 1806 int i, clock = crtc_state->port_clock;
1814 1807
1815 if (encoder->type == INTEL_OUTPUT_HDMI && 1808 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
1816 !bxt_ddi_hdmi_set_dpll_hw_state(crtc, crtc_state, clock, 1809 !bxt_ddi_hdmi_set_dpll_hw_state(crtc, crtc_state, clock,
1817 &dpll_hw_state)) 1810 &dpll_hw_state))
1818 return NULL; 1811 return NULL;
1819 1812
1820 if ((encoder->type == INTEL_OUTPUT_DP || 1813 if (intel_crtc_has_dp_encoder(crtc_state) &&
1821 encoder->type == INTEL_OUTPUT_EDP ||
1822 encoder->type == INTEL_OUTPUT_DP_MST) &&
1823 !bxt_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state)) 1814 !bxt_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state))
1824 return NULL; 1815 return NULL;
1825 1816
@@ -1828,15 +1819,8 @@ bxt_get_dpll(struct intel_crtc *crtc,
1828 1819
1829 crtc_state->dpll_hw_state = dpll_hw_state; 1820 crtc_state->dpll_hw_state = dpll_hw_state;
1830 1821
1831 if (encoder->type == INTEL_OUTPUT_DP_MST) {
1832 struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
1833
1834 intel_dig_port = intel_mst->primary;
1835 } else
1836 intel_dig_port = enc_to_dig_port(&encoder->base);
1837
1838 /* 1:1 mapping between ports and PLLs */ 1822 /* 1:1 mapping between ports and PLLs */
1839 i = (enum intel_dpll_id) intel_dig_port->port; 1823 i = (enum intel_dpll_id) encoder->port;
1840 pll = intel_get_shared_dpll_by_id(dev_priv, i); 1824 pll = intel_get_shared_dpll_by_id(dev_priv, i);
1841 1825
1842 DRM_DEBUG_KMS("[CRTC:%d:%s] using pre-allocated %s\n", 1826 DRM_DEBUG_KMS("[CRTC:%d:%s] using pre-allocated %s\n",
@@ -2008,8 +1992,8 @@ static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2008 * requirement, follow the Display Voltage Frequency Switching 1992 * requirement, follow the Display Voltage Frequency Switching
2009 * Sequence Before Frequency Change 1993 * Sequence Before Frequency Change
2010 * 1994 *
2011 * FIXME: (DVFS) is used to adjust the display voltage to match the 1995 * Note: DVFS is actually handled via the cdclk code paths,
2012 * display clock frequencies 1996 * hence we do nothing here.
2013 */ 1997 */
2014 1998
2015 /* 6. Enable DPLL in DPLL_ENABLE. */ 1999 /* 6. Enable DPLL in DPLL_ENABLE. */
@@ -2030,8 +2014,8 @@ static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2030 * requirement, follow the Display Voltage Frequency Switching 2014 * requirement, follow the Display Voltage Frequency Switching
2031 * Sequence After Frequency Change 2015 * Sequence After Frequency Change
2032 * 2016 *
2033 * FIXME: (DVFS) is used to adjust the display voltage to match the 2017 * Note: DVFS is actually handled via the cdclk code paths,
2034 * display clock frequencies 2018 * hence we do nothing here.
2035 */ 2019 */
2036 2020
2037 /* 2021 /*
@@ -2055,8 +2039,8 @@ static void cnl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2055 * requirement, follow the Display Voltage Frequency Switching 2039 * requirement, follow the Display Voltage Frequency Switching
2056 * Sequence Before Frequency Change 2040 * Sequence Before Frequency Change
2057 * 2041 *
2058 * FIXME: (DVFS) is used to adjust the display voltage to match the 2042 * Note: DVFS is actually handled via the cdclk code paths,
2059 * display clock frequencies 2043 * hence we do nothing here.
2060 */ 2044 */
2061 2045
2062 /* 3. Disable DPLL through DPLL_ENABLE. */ 2046 /* 3. Disable DPLL through DPLL_ENABLE. */
@@ -2077,8 +2061,8 @@ static void cnl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2077 * requirement, follow the Display Voltage Frequency Switching 2061 * requirement, follow the Display Voltage Frequency Switching
2078 * Sequence After Frequency Change 2062 * Sequence After Frequency Change
2079 * 2063 *
2080 * FIXME: (DVFS) is used to adjust the display voltage to match the 2064 * Note: DVFS is actually handled via the cdclk code paths,
2081 * display clock frequencies 2065 * hence we do nothing here.
2082 */ 2066 */
2083 2067
2084 /* 6. Disable DPLL power in DPLL_ENABLE. */ 2068 /* 6. Disable DPLL power in DPLL_ENABLE. */
@@ -2126,10 +2110,8 @@ out:
2126 return ret; 2110 return ret;
2127} 2111}
2128 2112
2129static void cnl_wrpll_get_multipliers(unsigned int bestdiv, 2113static void cnl_wrpll_get_multipliers(int bestdiv, int *pdiv,
2130 unsigned int *pdiv, 2114 int *qdiv, int *kdiv)
2131 unsigned int *qdiv,
2132 unsigned int *kdiv)
2133{ 2115{
2134 /* even dividers */ 2116 /* even dividers */
2135 if (bestdiv % 2 == 0) { 2117 if (bestdiv % 2 == 0) {
@@ -2167,10 +2149,12 @@ static void cnl_wrpll_get_multipliers(unsigned int bestdiv,
2167 } 2149 }
2168} 2150}
2169 2151
2170static void cnl_wrpll_params_populate(struct skl_wrpll_params *params, uint32_t dco_freq, 2152static void cnl_wrpll_params_populate(struct skl_wrpll_params *params,
2171 uint32_t ref_freq, uint32_t pdiv, uint32_t qdiv, 2153 u32 dco_freq, u32 ref_freq,
2172 uint32_t kdiv) 2154 int pdiv, int qdiv, int kdiv)
2173{ 2155{
2156 u32 dco;
2157
2174 switch (kdiv) { 2158 switch (kdiv) {
2175 case 1: 2159 case 1:
2176 params->kdiv = 1; 2160 params->kdiv = 1;
@@ -2202,39 +2186,35 @@ static void cnl_wrpll_params_populate(struct skl_wrpll_params *params, uint32_t
2202 WARN(1, "Incorrect PDiv\n"); 2186 WARN(1, "Incorrect PDiv\n");
2203 } 2187 }
2204 2188
2205 if (kdiv != 2) 2189 WARN_ON(kdiv != 2 && qdiv != 1);
2206 qdiv = 1;
2207 2190
2208 params->qdiv_ratio = qdiv; 2191 params->qdiv_ratio = qdiv;
2209 params->qdiv_mode = (qdiv == 1) ? 0 : 1; 2192 params->qdiv_mode = (qdiv == 1) ? 0 : 1;
2210 2193
2211 params->dco_integer = div_u64(dco_freq, ref_freq); 2194 dco = div_u64((u64)dco_freq << 15, ref_freq);
2212 params->dco_fraction = div_u64((div_u64((uint64_t)dco_freq<<15, (uint64_t)ref_freq) - 2195
2213 ((uint64_t)params->dco_integer<<15)) * 0x8000, 0x8000); 2196 params->dco_integer = dco >> 15;
2197 params->dco_fraction = dco & 0x7fff;
2214} 2198}
2215 2199
2216static bool 2200static bool
2217cnl_ddi_calculate_wrpll(int clock /* in Hz */, 2201cnl_ddi_calculate_wrpll(int clock,
2218 struct drm_i915_private *dev_priv, 2202 struct drm_i915_private *dev_priv,
2219 struct skl_wrpll_params *wrpll_params) 2203 struct skl_wrpll_params *wrpll_params)
2220{ 2204{
2221 uint64_t afe_clock = clock * 5 / KHz(1); /* clocks in kHz */ 2205 u32 afe_clock = clock * 5;
2222 unsigned int dco_min = 7998 * KHz(1); 2206 u32 dco_min = 7998000;
2223 unsigned int dco_max = 10000 * KHz(1); 2207 u32 dco_max = 10000000;
2224 unsigned int dco_mid = (dco_min + dco_max) / 2; 2208 u32 dco_mid = (dco_min + dco_max) / 2;
2225
2226 static const int dividers[] = { 2, 4, 6, 8, 10, 12, 14, 16, 2209 static const int dividers[] = { 2, 4, 6, 8, 10, 12, 14, 16,
2227 18, 20, 24, 28, 30, 32, 36, 40, 2210 18, 20, 24, 28, 30, 32, 36, 40,
2228 42, 44, 48, 50, 52, 54, 56, 60, 2211 42, 44, 48, 50, 52, 54, 56, 60,
2229 64, 66, 68, 70, 72, 76, 78, 80, 2212 64, 66, 68, 70, 72, 76, 78, 80,
2230 84, 88, 90, 92, 96, 98, 100, 102, 2213 84, 88, 90, 92, 96, 98, 100, 102,
2231 3, 5, 7, 9, 15, 21 }; 2214 3, 5, 7, 9, 15, 21 };
2232 unsigned int d, dco; 2215 u32 dco, best_dco = 0, dco_centrality = 0;
2233 unsigned int dco_centrality = 0; 2216 u32 best_dco_centrality = U32_MAX; /* Spec meaning of 999999 MHz */
2234 unsigned int best_dco_centrality = 999999; 2217 int d, best_div = 0, pdiv = 0, qdiv = 0, kdiv = 0;
2235 unsigned int best_div = 0;
2236 unsigned int best_dco = 0;
2237 unsigned int pdiv = 0, qdiv = 0, kdiv = 0;
2238 2218
2239 for (d = 0; d < ARRAY_SIZE(dividers); d++) { 2219 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
2240 dco = afe_clock * dividers[d]; 2220 dco = afe_clock * dividers[d];
@@ -2271,7 +2251,7 @@ static bool cnl_ddi_hdmi_pll_dividers(struct intel_crtc *crtc,
2271 2251
2272 cfgcr0 = DPLL_CFGCR0_HDMI_MODE; 2252 cfgcr0 = DPLL_CFGCR0_HDMI_MODE;
2273 2253
2274 if (!cnl_ddi_calculate_wrpll(clock * 1000, dev_priv, &wrpll_params)) 2254 if (!cnl_ddi_calculate_wrpll(clock, dev_priv, &wrpll_params))
2275 return false; 2255 return false;
2276 2256
2277 cfgcr0 |= DPLL_CFGCR0_DCO_FRACTION(wrpll_params.dco_fraction) | 2257 cfgcr0 |= DPLL_CFGCR0_DCO_FRACTION(wrpll_params.dco_fraction) |
@@ -2281,7 +2261,6 @@ static bool cnl_ddi_hdmi_pll_dividers(struct intel_crtc *crtc,
2281 DPLL_CFGCR1_QDIV_MODE(wrpll_params.qdiv_mode) | 2261 DPLL_CFGCR1_QDIV_MODE(wrpll_params.qdiv_mode) |
2282 DPLL_CFGCR1_KDIV(wrpll_params.kdiv) | 2262 DPLL_CFGCR1_KDIV(wrpll_params.kdiv) |
2283 DPLL_CFGCR1_PDIV(wrpll_params.pdiv) | 2263 DPLL_CFGCR1_PDIV(wrpll_params.pdiv) |
2284 wrpll_params.central_freq |
2285 DPLL_CFGCR1_CENTRAL_FREQ; 2264 DPLL_CFGCR1_CENTRAL_FREQ;
2286 2265
2287 memset(&crtc_state->dpll_hw_state, 0, 2266 memset(&crtc_state->dpll_hw_state, 0,
@@ -2345,15 +2324,13 @@ cnl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
2345 2324
2346 memset(&dpll_hw_state, 0, sizeof(dpll_hw_state)); 2325 memset(&dpll_hw_state, 0, sizeof(dpll_hw_state));
2347 2326
2348 if (encoder->type == INTEL_OUTPUT_HDMI) { 2327 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
2349 bret = cnl_ddi_hdmi_pll_dividers(crtc, crtc_state, clock); 2328 bret = cnl_ddi_hdmi_pll_dividers(crtc, crtc_state, clock);
2350 if (!bret) { 2329 if (!bret) {
2351 DRM_DEBUG_KMS("Could not get HDMI pll dividers.\n"); 2330 DRM_DEBUG_KMS("Could not get HDMI pll dividers.\n");
2352 return NULL; 2331 return NULL;
2353 } 2332 }
2354 } else if (encoder->type == INTEL_OUTPUT_DP || 2333 } else if (intel_crtc_has_dp_encoder(crtc_state)) {
2355 encoder->type == INTEL_OUTPUT_DP_MST ||
2356 encoder->type == INTEL_OUTPUT_EDP) {
2357 bret = cnl_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state); 2334 bret = cnl_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state);
2358 if (!bret) { 2335 if (!bret) {
2359 DRM_DEBUG_KMS("Could not set DP dpll HW state.\n"); 2336 DRM_DEBUG_KMS("Could not set DP dpll HW state.\n");
@@ -2361,8 +2338,8 @@ cnl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
2361 } 2338 }
2362 crtc_state->dpll_hw_state = dpll_hw_state; 2339 crtc_state->dpll_hw_state = dpll_hw_state;
2363 } else { 2340 } else {
2364 DRM_DEBUG_KMS("Skip DPLL setup for encoder %d\n", 2341 DRM_DEBUG_KMS("Skip DPLL setup for output_types 0x%x\n",
2365 encoder->type); 2342 crtc_state->output_types);
2366 return NULL; 2343 return NULL;
2367 } 2344 }
2368 2345