Rev 6935 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6935 | Rev 6937 | ||
---|---|---|---|
Line 69... | Line 69... | ||
69 | * FIXME: |
69 | * FIXME: |
70 | * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only. |
70 | * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only. |
71 | */ |
71 | */ |
72 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | |
72 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | |
73 | GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); |
73 | GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); |
- | 74 | ||
- | 75 | /* |
|
- | 76 | * Wa: Backlight PWM may stop in the asserted state, causing backlight |
|
- | 77 | * to stay fully on. |
|
- | 78 | */ |
|
- | 79 | if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) |
|
- | 80 | I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) | |
|
- | 81 | PWM1_GATING_DIS | PWM2_GATING_DIS); |
|
74 | } |
82 | } |
Line 75... | Line 83... | ||
75 | 83 | ||
76 | static void i915_pineview_get_mem_freq(struct drm_device *dev) |
84 | static void i915_pineview_get_mem_freq(struct drm_device *dev) |
77 | { |
85 | { |
Line 286... | Line 294... | ||
286 | void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable) |
294 | void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable) |
287 | { |
295 | { |
288 | struct drm_device *dev = dev_priv->dev; |
296 | struct drm_device *dev = dev_priv->dev; |
289 | u32 val; |
297 | u32 val; |
Line 290... | Line 298... | ||
290 | 298 | ||
291 | if (IS_VALLEYVIEW(dev)) { |
299 | if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { |
292 | I915_WRITE(FW_BLC_SELF_VLV, enable ? FW_CSPWRDWNEN : 0); |
300 | I915_WRITE(FW_BLC_SELF_VLV, enable ? FW_CSPWRDWNEN : 0); |
293 | POSTING_READ(FW_BLC_SELF_VLV); |
301 | POSTING_READ(FW_BLC_SELF_VLV); |
294 | dev_priv->wm.vlv.cxsr = enable; |
302 | dev_priv->wm.vlv.cxsr = enable; |
295 | } else if (IS_G4X(dev) || IS_CRESTLINE(dev)) { |
303 | } else if (IS_G4X(dev) || IS_CRESTLINE(dev)) { |
Line 1711... | Line 1719... | ||
1711 | uint8_t bytes_per_pixel) |
1719 | uint8_t bytes_per_pixel) |
1712 | { |
1720 | { |
1713 | return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2; |
1721 | return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2; |
1714 | } |
1722 | } |
Line 1715... | Line -... | ||
1715 | - | ||
1716 | struct skl_pipe_wm_parameters { |
- | |
1717 | bool active; |
- | |
1718 | uint32_t pipe_htotal; |
- | |
1719 | uint32_t pixel_rate; /* in KHz */ |
- | |
1720 | struct intel_plane_wm_parameters plane[I915_MAX_PLANES]; |
- | |
1721 | }; |
- | |
1722 | 1723 | ||
1723 | struct ilk_wm_maximums { |
1724 | struct ilk_wm_maximums { |
1724 | uint16_t pri; |
1725 | uint16_t pri; |
1725 | uint16_t spr; |
1726 | uint16_t spr; |
1726 | uint16_t cur; |
1727 | uint16_t cur; |
1727 | uint16_t fbc; |
1728 | uint16_t fbc; |
Line 1728... | Line -... | ||
1728 | }; |
- | |
1729 | - | ||
1730 | /* used in computing the new watermarks state */ |
- | |
1731 | struct intel_wm_config { |
- | |
1732 | unsigned int num_pipes_active; |
- | |
1733 | bool sprites_enabled; |
- | |
1734 | bool sprites_scaled; |
- | |
1735 | }; |
1729 | }; |
1736 | 1730 | ||
1737 | /* |
1731 | /* |
1738 | * For both WM_PIPE and WM_LP. |
1732 | * For both WM_PIPE and WM_LP. |
1739 | * mem_value must be in 0.1us units. |
1733 | * mem_value must be in 0.1us units. |
Line 1986... | Line 1980... | ||
1986 | 1980 | ||
1987 | static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, |
1981 | static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, |
1988 | const struct intel_crtc *intel_crtc, |
1982 | const struct intel_crtc *intel_crtc, |
1989 | int level, |
1983 | int level, |
- | 1984 | struct intel_crtc_state *cstate, |
|
- | 1985 | struct intel_plane_state *pristate, |
|
- | 1986 | struct intel_plane_state *sprstate, |
|
1990 | struct intel_crtc_state *cstate, |
1987 | struct intel_plane_state *curstate, |
1991 | struct intel_wm_level *result) |
1988 | struct intel_wm_level *result) |
1992 | { |
- | |
1993 | struct intel_plane *intel_plane; |
1989 | { |
1994 | uint16_t pri_latency = dev_priv->wm.pri_latency[level]; |
1990 | uint16_t pri_latency = dev_priv->wm.pri_latency[level]; |
1995 | uint16_t spr_latency = dev_priv->wm.spr_latency[level]; |
1991 | uint16_t spr_latency = dev_priv->wm.spr_latency[level]; |
Line 1996... | Line 1992... | ||
1996 | uint16_t cur_latency = dev_priv->wm.cur_latency[level]; |
1992 | uint16_t cur_latency = dev_priv->wm.cur_latency[level]; |
Line 2000... | Line 1996... | ||
2000 | pri_latency *= 5; |
1996 | pri_latency *= 5; |
2001 | spr_latency *= 5; |
1997 | spr_latency *= 5; |
2002 | cur_latency *= 5; |
1998 | cur_latency *= 5; |
2003 | } |
1999 | } |
Line 2004... | Line -... | ||
2004 | - | ||
2005 | for_each_intel_plane_on_crtc(dev_priv->dev, intel_crtc, intel_plane) { |
- | |
2006 | struct intel_plane_state *pstate = |
- | |
2007 | to_intel_plane_state(intel_plane->base.state); |
- | |
2008 | - | ||
2009 | switch (intel_plane->base.type) { |
- | |
2010 | case DRM_PLANE_TYPE_PRIMARY: |
2000 | |
2011 | result->pri_val = ilk_compute_pri_wm(cstate, pstate, |
2001 | result->pri_val = ilk_compute_pri_wm(cstate, pristate, |
2012 | pri_latency, |
- | |
2013 | level); |
2002 | pri_latency, level); |
2014 | result->fbc_val = ilk_compute_fbc_wm(cstate, pstate, |
- | |
2015 | result->pri_val); |
- | |
2016 | break; |
- | |
2017 | case DRM_PLANE_TYPE_OVERLAY: |
2003 | result->spr_val = ilk_compute_spr_wm(cstate, sprstate, spr_latency); |
2018 | result->spr_val = ilk_compute_spr_wm(cstate, pstate, |
- | |
2019 | spr_latency); |
- | |
2020 | break; |
- | |
2021 | case DRM_PLANE_TYPE_CURSOR: |
2004 | result->cur_val = ilk_compute_cur_wm(cstate, curstate, cur_latency); |
2022 | result->cur_val = ilk_compute_cur_wm(cstate, pstate, |
- | |
2023 | cur_latency); |
- | |
2024 | break; |
- | |
2025 | } |
- | |
2026 | } |
- | |
2027 | 2005 | result->fbc_val = ilk_compute_fbc_wm(cstate, pristate, result->pri_val); |
|
2028 | result->enable = true; |
2006 | result->enable = true; |
Line 2029... | Line 2007... | ||
2029 | } |
2007 | } |
2030 | 2008 | ||
Line 2100... | Line 2078... | ||
2100 | GEN9_MEM_LATENCY_LEVEL_MASK; |
2078 | GEN9_MEM_LATENCY_LEVEL_MASK; |
2101 | wm[7] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) & |
2079 | wm[7] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) & |
2102 | GEN9_MEM_LATENCY_LEVEL_MASK; |
2080 | GEN9_MEM_LATENCY_LEVEL_MASK; |
Line 2103... | Line 2081... | ||
2103 | 2081 | ||
2104 | /* |
- | |
2105 | * If a level n (n > 1) has a 0us latency, all levels m (m >= n) |
- | |
2106 | * need to be disabled. We make sure to sanitize the values out |
- | |
2107 | * of the punit to satisfy this requirement. |
- | |
2108 | */ |
- | |
2109 | for (level = 1; level <= max_level; level++) { |
- | |
2110 | if (wm[level] == 0) { |
- | |
2111 | for (i = level + 1; i <= max_level; i++) |
- | |
2112 | wm[i] = 0; |
- | |
2113 | break; |
- | |
2114 | } |
- | |
2115 | } |
- | |
2116 | - | ||
2117 | /* |
2082 | /* |
2118 | * WaWmMemoryReadLatency:skl |
2083 | * WaWmMemoryReadLatency:skl |
2119 | * |
2084 | * |
2120 | * punit doesn't take into account the read latency so we need |
2085 | * punit doesn't take into account the read latency so we need |
- | 2086 | * to add 2us to the various latency levels we retrieve from |
|
- | 2087 | * the punit. |
|
- | 2088 | * - W0 is a bit special in that it's the only level that |
|
- | 2089 | * can't be disabled if we want to have display working, so |
|
- | 2090 | * we always add 2us there. |
|
- | 2091 | * - For levels >=1, punit returns 0us latency when they are |
|
- | 2092 | * disabled, so we respect that and don't add 2us then |
|
- | 2093 | * |
|
- | 2094 | * Additionally, if a level n (n > 1) has a 0us latency, all |
|
2121 | * to add 2us to the various latency levels we retrieve from the |
2095 | * levels m (m >= n) need to be disabled. We make sure to |
- | 2096 | * sanitize the values out of the punit to satisfy this |
|
2122 | * punit when level 0 response data us 0us. |
2097 | * requirement. |
2123 | */ |
- | |
2124 | if (wm[0] == 0) { |
2098 | */ |
2125 | wm[0] += 2; |
2099 | wm[0] += 2; |
2126 | for (level = 1; level <= max_level; level++) { |
2100 | for (level = 1; level <= max_level; level++) |
2127 | if (wm[level] == 0) |
- | |
2128 | break; |
2101 | if (wm[level] != 0) |
2129 | wm[level] += 2; |
2102 | wm[level] += 2; |
- | 2103 | else { |
|
2130 | } |
2104 | for (i = level + 1; i <= max_level; i++) |
Line -... | Line 2105... | ||
- | 2105 | wm[i] = 0; |
|
- | 2106 | ||
2131 | } |
2107 | break; |
2132 | 2108 | } |
|
Line 2133... | Line 2109... | ||
2133 | } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { |
2109 | } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { |
2134 | uint64_t sskpd = I915_READ64(MCH_SSKPD); |
2110 | uint64_t sskpd = I915_READ64(MCH_SSKPD); |
Line 2283... | Line 2259... | ||
2283 | 2259 | ||
2284 | intel_read_wm_latency(dev, dev_priv->wm.skl_latency); |
2260 | intel_read_wm_latency(dev, dev_priv->wm.skl_latency); |
2285 | intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency); |
2261 | intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency); |
Line 2286... | Line -... | ||
2286 | } |
- | |
2287 | - | ||
2288 | static void ilk_compute_wm_config(struct drm_device *dev, |
- | |
2289 | struct intel_wm_config *config) |
- | |
2290 | { |
- | |
2291 | struct intel_crtc *intel_crtc; |
- | |
2292 | - | ||
2293 | /* Compute the currently _active_ config */ |
- | |
2294 | for_each_intel_crtc(dev, intel_crtc) { |
- | |
2295 | const struct intel_pipe_wm *wm = &intel_crtc->wm.active; |
- | |
2296 | - | ||
2297 | if (!wm->pipe_enabled) |
- | |
2298 | continue; |
- | |
2299 | - | ||
2300 | config->sprites_enabled |= wm->sprites_enabled; |
- | |
2301 | config->sprites_scaled |= wm->sprites_scaled; |
- | |
2302 | config->num_pipes_active++; |
- | |
2303 | } |
- | |
2304 | } |
2262 | } |
2305 | 2263 | ||
2306 | /* Compute new watermarks for the pipe */ |
2264 | /* Compute new watermarks for the pipe */ |
2307 | static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate, |
2265 | static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, |
2308 | struct intel_pipe_wm *pipe_wm) |
2266 | struct drm_atomic_state *state) |
2309 | { |
2267 | { |
2310 | struct drm_crtc *crtc = cstate->base.crtc; |
2268 | struct intel_pipe_wm *pipe_wm; |
2311 | struct drm_device *dev = crtc->dev; |
2269 | struct drm_device *dev = intel_crtc->base.dev; |
2312 | const struct drm_i915_private *dev_priv = dev->dev_private; |
2270 | const struct drm_i915_private *dev_priv = dev->dev_private; |
- | 2271 | struct intel_crtc_state *cstate = NULL; |
|
- | 2272 | struct intel_plane *intel_plane; |
|
2313 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2273 | struct drm_plane_state *ps; |
- | 2274 | struct intel_plane_state *pristate = NULL; |
|
2314 | struct intel_plane *intel_plane; |
2275 | struct intel_plane_state *sprstate = NULL; |
2315 | struct intel_plane_state *sprstate = NULL; |
2276 | struct intel_plane_state *curstate = NULL; |
2316 | int level, max_level = ilk_wm_max_level(dev); |
2277 | int level, max_level = ilk_wm_max_level(dev); |
2317 | /* LP0 watermark maximums depend on this pipe alone */ |
2278 | /* LP0 watermark maximums depend on this pipe alone */ |
2318 | struct intel_wm_config config = { |
2279 | struct intel_wm_config config = { |
2319 | .num_pipes_active = 1, |
2280 | .num_pipes_active = 1, |
Line -... | Line 2281... | ||
- | 2281 | }; |
|
- | 2282 | struct ilk_wm_maximums max; |
|
- | 2283 | ||
- | 2284 | cstate = intel_atomic_get_crtc_state(state, intel_crtc); |
|
- | 2285 | if (IS_ERR(cstate)) |
|
- | 2286 | return PTR_ERR(cstate); |
|
- | 2287 | ||
2320 | }; |
2288 | pipe_wm = &cstate->wm.optimal.ilk; |
- | 2289 | memset(pipe_wm, 0, sizeof(*pipe_wm)); |
|
- | 2290 | ||
- | 2291 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { |
|
- | 2292 | ps = drm_atomic_get_plane_state(state, |
|
- | 2293 | &intel_plane->base); |
|
- | 2294 | if (IS_ERR(ps)) |
|
- | 2295 | return PTR_ERR(ps); |
|
2321 | struct ilk_wm_maximums max; |
2296 | |
2322 | 2297 | if (intel_plane->base.type == DRM_PLANE_TYPE_PRIMARY) |
|
- | 2298 | pristate = to_intel_plane_state(ps); |
|
2323 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { |
2299 | else if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) |
2324 | if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) { |
- | |
2325 | sprstate = to_intel_plane_state(intel_plane->base.state); |
2300 | sprstate = to_intel_plane_state(ps); |
Line 2326... | Line 2301... | ||
2326 | break; |
2301 | else if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR) |
2327 | } |
2302 | curstate = to_intel_plane_state(ps); |
2328 | } |
2303 | } |
2329 | 2304 | ||
Line 2330... | Line 2305... | ||
2330 | config.sprites_enabled = sprstate->visible; |
2305 | config.sprites_enabled = sprstate->visible; |
2331 | config.sprites_scaled = sprstate->visible && |
2306 | config.sprites_scaled = sprstate->visible && |
2332 | (drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 || |
2307 | (drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 || |
Line 2333... | Line 2308... | ||
2333 | drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16); |
2308 | drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16); |
2334 | 2309 | ||
2335 | pipe_wm->pipe_enabled = cstate->base.active; |
2310 | pipe_wm->pipe_enabled = cstate->base.active; |
Line 2336... | Line 2311... | ||
2336 | pipe_wm->sprites_enabled = sprstate->visible; |
2311 | pipe_wm->sprites_enabled = config.sprites_enabled; |
2337 | pipe_wm->sprites_scaled = config.sprites_scaled; |
2312 | pipe_wm->sprites_scaled = config.sprites_scaled; |
2338 | 2313 | ||
Line 2339... | Line 2314... | ||
2339 | /* ILK/SNB: LP2+ watermarks only w/o sprites */ |
2314 | /* ILK/SNB: LP2+ watermarks only w/o sprites */ |
- | 2315 | if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible) |
|
Line 2340... | Line 2316... | ||
2340 | if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible) |
2316 | max_level = 1; |
2341 | max_level = 1; |
2317 | |
- | 2318 | /* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */ |
|
Line 2342... | Line 2319... | ||
2342 | 2319 | if (config.sprites_scaled) |
|
2343 | /* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */ |
2320 | max_level = 0; |
Line 2344... | Line 2321... | ||
2344 | if (config.sprites_scaled) |
2321 | |
2345 | max_level = 0; |
2322 | ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, |
2346 | 2323 | pristate, sprstate, curstate, &pipe_wm->wm[0]); |
|
Line 2347... | Line 2324... | ||
2347 | ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, &pipe_wm->wm[0]); |
2324 | |
Line 2348... | Line 2325... | ||
2348 | 2325 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
|
2349 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
2326 | pipe_wm->linetime = hsw_compute_linetime_wm(dev, |
Line 2350... | Line 2327... | ||
2350 | pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc); |
2327 | &intel_crtc->base); |
- | 2328 | ||
Line 2351... | Line 2329... | ||
2351 | 2329 | /* LP0 watermarks always use 1/2 DDB partitioning */ |
|
2352 | /* LP0 watermarks always use 1/2 DDB partitioning */ |
2330 | ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max); |
2353 | ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max); |
2331 | |
2354 | 2332 | /* At least LP0 must be valid */ |
|
Line 2372... | Line 2350... | ||
2372 | break; |
2350 | break; |
Line 2373... | Line 2351... | ||
2373 | 2351 | ||
2374 | pipe_wm->wm[level] = wm; |
2352 | pipe_wm->wm[level] = wm; |
Line 2375... | Line 2353... | ||
2375 | } |
2353 | } |
2376 | 2354 | ||
Line 2377... | Line 2355... | ||
2377 | return true; |
2355 | return 0; |
2378 | } |
2356 | } |
2379 | 2357 | ||
Line 2387... | Line 2365... | ||
2387 | const struct intel_crtc *intel_crtc; |
2365 | const struct intel_crtc *intel_crtc; |
Line 2388... | Line 2366... | ||
2388 | 2366 | ||
Line 2389... | Line 2367... | ||
2389 | ret_wm->enable = true; |
2367 | ret_wm->enable = true; |
- | 2368 | ||
- | 2369 | for_each_intel_crtc(dev, intel_crtc) { |
|
2390 | 2370 | const struct intel_crtc_state *cstate = |
|
2391 | for_each_intel_crtc(dev, intel_crtc) { |
2371 | to_intel_crtc_state(intel_crtc->base.state); |
Line 2392... | Line 2372... | ||
2392 | const struct intel_pipe_wm *active = &intel_crtc->wm.active; |
2372 | const struct intel_pipe_wm *active = &cstate->wm.optimal.ilk; |
2393 | const struct intel_wm_level *wm = &active->wm[level]; |
2373 | const struct intel_wm_level *wm = &active->wm[level]; |
Line 2458... | Line 2438... | ||
2458 | * FIXME this is racy. FBC might get enabled later. |
2438 | * FIXME this is racy. FBC might get enabled later. |
2459 | * What we should check here is whether FBC can be |
2439 | * What we should check here is whether FBC can be |
2460 | * enabled sometime later. |
2440 | * enabled sometime later. |
2461 | */ |
2441 | */ |
2462 | if (IS_GEN5(dev) && !merged->fbc_wm_enabled && |
2442 | if (IS_GEN5(dev) && !merged->fbc_wm_enabled && |
2463 | intel_fbc_enabled(dev_priv)) { |
2443 | intel_fbc_is_active(dev_priv)) { |
2464 | for (level = 2; level <= max_level; level++) { |
2444 | for (level = 2; level <= max_level; level++) { |
2465 | struct intel_wm_level *wm = &merged->wm[level]; |
2445 | struct intel_wm_level *wm = &merged->wm[level]; |
Line 2466... | Line 2446... | ||
2466 | 2446 | ||
2467 | wm->enable = false; |
2447 | wm->enable = false; |
Line 2535... | Line 2515... | ||
2535 | results->wm_lp_spr[wm_lp - 1] = r->spr_val; |
2515 | results->wm_lp_spr[wm_lp - 1] = r->spr_val; |
2536 | } |
2516 | } |
Line 2537... | Line 2517... | ||
2537 | 2517 | ||
2538 | /* LP0 register values */ |
2518 | /* LP0 register values */ |
- | 2519 | for_each_intel_crtc(dev, intel_crtc) { |
|
- | 2520 | const struct intel_crtc_state *cstate = |
|
2539 | for_each_intel_crtc(dev, intel_crtc) { |
2521 | to_intel_crtc_state(intel_crtc->base.state); |
2540 | enum pipe pipe = intel_crtc->pipe; |
2522 | enum pipe pipe = intel_crtc->pipe; |
2541 | const struct intel_wm_level *r = |
- | |
Line 2542... | Line 2523... | ||
2542 | &intel_crtc->wm.active.wm[0]; |
2523 | const struct intel_wm_level *r = &cstate->wm.optimal.ilk.wm[0]; |
2543 | 2524 | ||
Line 2544... | Line 2525... | ||
2544 | if (WARN_ON(!r->enable)) |
2525 | if (WARN_ON(!r->enable)) |
Line 2545... | Line 2526... | ||
2545 | continue; |
2526 | continue; |
2546 | 2527 | ||
2547 | results->wm_linetime[pipe] = intel_crtc->wm.active.linetime; |
2528 | results->wm_linetime[pipe] = cstate->wm.optimal.ilk.linetime; |
2548 | 2529 | ||
Line 2764... | Line 2745... | ||
2764 | */ |
2745 | */ |
Line 2765... | Line 2746... | ||
2765 | 2746 | ||
2766 | #define SKL_DDB_SIZE 896 /* in blocks */ |
2747 | #define SKL_DDB_SIZE 896 /* in blocks */ |
Line -... | Line 2748... | ||
- | 2748 | #define BXT_DDB_SIZE 512 |
|
- | 2749 | ||
- | 2750 | /* |
|
- | 2751 | * Return the index of a plane in the SKL DDB and wm result arrays. Primary |
|
- | 2752 | * plane is always in slot 0, cursor is always in slot I915_MAX_PLANES-1, and |
|
- | 2753 | * other universal planes are in indices 1..n. Note that this may leave unused |
|
- | 2754 | * indices between the top "sprite" plane and the cursor. |
|
- | 2755 | */ |
|
- | 2756 | static int |
|
- | 2757 | skl_wm_plane_id(const struct intel_plane *plane) |
|
- | 2758 | { |
|
- | 2759 | switch (plane->base.type) { |
|
- | 2760 | case DRM_PLANE_TYPE_PRIMARY: |
|
- | 2761 | return 0; |
|
- | 2762 | case DRM_PLANE_TYPE_CURSOR: |
|
- | 2763 | return PLANE_CURSOR; |
|
- | 2764 | case DRM_PLANE_TYPE_OVERLAY: |
|
- | 2765 | return plane->plane + 1; |
|
- | 2766 | default: |
|
- | 2767 | MISSING_CASE(plane->base.type); |
|
- | 2768 | return plane->plane; |
|
- | 2769 | } |
|
2767 | #define BXT_DDB_SIZE 512 |
2770 | } |
2768 | 2771 | ||
2769 | static void |
2772 | static void |
2770 | skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, |
2773 | skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, |
2771 | struct drm_crtc *for_crtc, |
- | |
2772 | const struct intel_wm_config *config, |
2774 | const struct intel_crtc_state *cstate, |
2773 | const struct skl_pipe_wm_parameters *params, |
2775 | const struct intel_wm_config *config, |
- | 2776 | struct skl_ddb_entry *alloc /* out */) |
|
2774 | struct skl_ddb_entry *alloc /* out */) |
2777 | { |
2775 | { |
2778 | struct drm_crtc *for_crtc = cstate->base.crtc; |
2776 | struct drm_crtc *crtc; |
2779 | struct drm_crtc *crtc; |
Line 2777... | Line 2780... | ||
2777 | unsigned int pipe_size, ddb_size; |
2780 | unsigned int pipe_size, ddb_size; |
2778 | int nth_active_pipe; |
2781 | int nth_active_pipe; |
2779 | 2782 | ||
2780 | if (!params->active) { |
2783 | if (!cstate->base.active) { |
2781 | alloc->start = 0; |
2784 | alloc->start = 0; |
Line 2830... | Line 2833... | ||
2830 | u32 val; |
2833 | u32 val; |
Line 2831... | Line 2834... | ||
2831 | 2834 | ||
Line 2832... | Line 2835... | ||
2832 | memset(ddb, 0, sizeof(*ddb)); |
2835 | memset(ddb, 0, sizeof(*ddb)); |
- | 2836 | ||
- | 2837 | for_each_pipe(dev_priv, pipe) { |
|
- | 2838 | enum intel_display_power_domain power_domain; |
|
2833 | 2839 | ||
2834 | for_each_pipe(dev_priv, pipe) { |
2840 | power_domain = POWER_DOMAIN_PIPE(pipe); |
Line 2835... | Line 2841... | ||
2835 | if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) |
2841 | if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) |
2836 | continue; |
2842 | continue; |
2837 | 2843 | ||
Line 2842... | Line 2848... | ||
2842 | } |
2848 | } |
Line 2843... | Line 2849... | ||
2843 | 2849 | ||
2844 | val = I915_READ(CUR_BUF_CFG(pipe)); |
2850 | val = I915_READ(CUR_BUF_CFG(pipe)); |
2845 | skl_ddb_entry_init_from_hw(&ddb->plane[pipe][PLANE_CURSOR], |
2851 | skl_ddb_entry_init_from_hw(&ddb->plane[pipe][PLANE_CURSOR], |
- | 2852 | val); |
|
- | 2853 | ||
2846 | val); |
2854 | intel_display_power_put(dev_priv, power_domain); |
2847 | } |
2855 | } |
Line 2848... | Line 2856... | ||
2848 | } |
2856 | } |
2849 | 2857 | ||
- | 2858 | static unsigned int |
|
- | 2859 | skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, |
|
2850 | static unsigned int |
2860 | const struct drm_plane_state *pstate, |
- | 2861 | int y) |
|
- | 2862 | { |
|
Line 2851... | Line 2863... | ||
2851 | skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p, int y) |
2863 | struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); |
2852 | { |
2864 | struct drm_framebuffer *fb = pstate->fb; |
2853 | 2865 | ||
2854 | /* for planar format */ |
2866 | /* for planar format */ |
- | 2867 | if (fb->pixel_format == DRM_FORMAT_NV12) { |
|
- | 2868 | if (y) /* y-plane data rate */ |
|
2855 | if (p->y_bytes_per_pixel) { |
2869 | return intel_crtc->config->pipe_src_w * |
2856 | if (y) /* y-plane data rate */ |
2870 | intel_crtc->config->pipe_src_h * |
- | 2871 | drm_format_plane_cpp(fb->pixel_format, 0); |
|
- | 2872 | else /* uv-plane data rate */ |
|
2857 | return p->horiz_pixels * p->vert_pixels * p->y_bytes_per_pixel; |
2873 | return (intel_crtc->config->pipe_src_w/2) * |
Line 2858... | Line 2874... | ||
2858 | else /* uv-plane data rate */ |
2874 | (intel_crtc->config->pipe_src_h/2) * |
2859 | return (p->horiz_pixels/2) * (p->vert_pixels/2) * p->bytes_per_pixel; |
2875 | drm_format_plane_cpp(fb->pixel_format, 1); |
- | 2876 | } |
|
- | 2877 | ||
2860 | } |
2878 | /* for packed formats */ |
Line 2861... | Line 2879... | ||
2861 | 2879 | return intel_crtc->config->pipe_src_w * |
|
2862 | /* for packed formats */ |
2880 | intel_crtc->config->pipe_src_h * |
2863 | return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel; |
2881 | drm_format_plane_cpp(fb->pixel_format, 0); |
2864 | } |
2882 | } |
2865 | 2883 | ||
2866 | /* |
2884 | /* |
2867 | * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching |
2885 | * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching |
2868 | * a 8192x4096@32bpp framebuffer: |
- | |
2869 | * 3 * 4096 * 8192 * 4 < 2^32 |
2886 | * a 8192x4096@32bpp framebuffer: |
- | 2887 | * 3 * 4096 * 8192 * 4 < 2^32 |
|
- | 2888 | */ |
|
- | 2889 | static unsigned int |
|
2870 | */ |
2890 | skl_get_total_relative_data_rate(const struct intel_crtc_state *cstate) |
2871 | static unsigned int |
- | |
Line 2872... | Line 2891... | ||
2872 | skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc, |
2891 | { |
2873 | const struct skl_pipe_wm_parameters *params) |
2892 | struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); |
Line 2874... | Line -... | ||
2874 | { |
- | |
2875 | unsigned int total_data_rate = 0; |
2893 | struct drm_device *dev = intel_crtc->base.dev; |
2876 | int plane; |
2894 | const struct intel_plane *intel_plane; |
Line -... | Line 2895... | ||
- | 2895 | unsigned int total_data_rate = 0; |
|
- | 2896 | ||
- | 2897 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { |
|
- | 2898 | const struct drm_plane_state *pstate = intel_plane->base.state; |
|
2877 | 2899 | ||
- | 2900 | if (pstate->fb == NULL) |
|
- | 2901 | continue; |
|
- | 2902 | ||
2878 | for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { |
2903 | if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR) |
- | 2904 | continue; |
|
2879 | const struct intel_plane_wm_parameters *p; |
2905 | |
- | 2906 | /* packed/uv */ |
|
2880 | 2907 | total_data_rate += skl_plane_relative_data_rate(cstate, |
|
2881 | p = ¶ms->plane[plane]; |
2908 | pstate, |
Line 2882... | Line 2909... | ||
2882 | if (!p->enabled) |
2909 | 0); |
2883 | continue; |
2910 | |
Line 2884... | Line 2911... | ||
2884 | 2911 | if (pstate->fb->pixel_format == DRM_FORMAT_NV12) |
|
2885 | total_data_rate += skl_plane_relative_data_rate(p, 0); /* packed/uv */ |
2912 | /* y-plane */ |
2886 | if (p->y_bytes_per_pixel) { |
- | |
2887 | total_data_rate += skl_plane_relative_data_rate(p, 1); /* y-plane */ |
- | |
2888 | } |
2913 | total_data_rate += skl_plane_relative_data_rate(cstate, |
2889 | } |
2914 | pstate, |
- | 2915 | 1); |
|
2890 | 2916 | } |
|
2891 | return total_data_rate; |
2917 | |
- | 2918 | return total_data_rate; |
|
2892 | } |
2919 | } |
- | 2920 | ||
2893 | 2921 | static void |
|
2894 | static void |
2922 | skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, |
2895 | skl_allocate_pipe_ddb(struct drm_crtc *crtc, |
2923 | struct skl_ddb_allocation *ddb /* out */) |
2896 | const struct intel_wm_config *config, |
2924 | { |
2897 | const struct skl_pipe_wm_parameters *params, |
2925 | struct drm_crtc *crtc = cstate->base.crtc; |
2898 | struct skl_ddb_allocation *ddb /* out */) |
2926 | struct drm_device *dev = crtc->dev; |
2899 | { |
- | |
Line 2900... | Line 2927... | ||
2900 | struct drm_device *dev = crtc->dev; |
2927 | struct drm_i915_private *dev_priv = to_i915(dev); |
2901 | struct drm_i915_private *dev_priv = dev->dev_private; |
2928 | struct intel_wm_config *config = &dev_priv->wm.config; |
2902 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2929 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2903 | enum pipe pipe = intel_crtc->pipe; |
2930 | struct intel_plane *intel_plane; |
2904 | struct skl_ddb_entry *alloc = &ddb->pipe[pipe]; |
2931 | enum pipe pipe = intel_crtc->pipe; |
2905 | uint16_t alloc_size, start, cursor_blocks; |
2932 | struct skl_ddb_entry *alloc = &ddb->pipe[pipe]; |
Line 2923... | Line 2950... | ||
2923 | 2950 | ||
2924 | alloc_size -= cursor_blocks; |
2951 | alloc_size -= cursor_blocks; |
Line 2925... | Line 2952... | ||
2925 | alloc->end -= cursor_blocks; |
2952 | alloc->end -= cursor_blocks; |
2926 | 2953 | ||
- | 2954 | /* 1. Allocate the mininum required blocks for each active plane */ |
|
- | 2955 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { |
|
2927 | /* 1. Allocate the mininum required blocks for each active plane */ |
2956 | struct drm_plane *plane = &intel_plane->base; |
Line 2928... | Line 2957... | ||
2928 | for_each_plane(dev_priv, pipe, plane) { |
2957 | struct drm_framebuffer *fb = plane->state->fb; |
2929 | const struct intel_plane_wm_parameters *p; |
2958 | int id = skl_wm_plane_id(intel_plane); |
- | 2959 | ||
2930 | 2960 | if (fb == NULL) |
|
Line 2931... | Line 2961... | ||
2931 | p = ¶ms->plane[plane]; |
2961 | continue; |
2932 | if (!p->enabled) |
2962 | if (plane->type == DRM_PLANE_TYPE_CURSOR) |
2933 | continue; |
2963 | continue; |
2934 | 2964 | ||
2935 | minimum[plane] = 8; |
2965 | minimum[id] = 8; |
Line 2936... | Line 2966... | ||
2936 | alloc_size -= minimum[plane]; |
2966 | alloc_size -= minimum[id]; |
2937 | y_minimum[plane] = p->y_bytes_per_pixel ? 8 : 0; |
2967 | y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0; |
2938 | alloc_size -= y_minimum[plane]; |
2968 | alloc_size -= y_minimum[id]; |
2939 | } |
2969 | } |
2940 | 2970 | ||
2941 | /* |
2971 | /* |
2942 | * 2. Distribute the remaining space in proportion to the amount of |
2972 | * 2. Distribute the remaining space in proportion to the amount of |
Line 2943... | Line 2973... | ||
2943 | * data each plane needs to fetch from memory. |
2973 | * data each plane needs to fetch from memory. |
2944 | * |
2974 | * |
2945 | * FIXME: we may not allocate every single block here. |
2975 | * FIXME: we may not allocate every single block here. |
- | 2976 | */ |
|
2946 | */ |
2977 | total_data_rate = skl_get_total_relative_data_rate(cstate); |
2947 | total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params); |
2978 | |
- | 2979 | start = alloc->start; |
|
Line 2948... | Line 2980... | ||
2948 | 2980 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { |
|
2949 | start = alloc->start; |
2981 | struct drm_plane *plane = &intel_plane->base; |
- | 2982 | struct drm_plane_state *pstate = intel_plane->base.state; |
|
2950 | for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { |
2983 | unsigned int data_rate, y_data_rate; |
Line 2951... | Line 2984... | ||
2951 | const struct intel_plane_wm_parameters *p; |
2984 | uint16_t plane_blocks, y_plane_blocks = 0; |
Line 2952... | Line 2985... | ||
2952 | unsigned int data_rate, y_data_rate; |
2985 | int id = skl_wm_plane_id(intel_plane); |
2953 | uint16_t plane_blocks, y_plane_blocks = 0; |
2986 | |
2954 | 2987 | if (pstate->fb == NULL) |
|
2955 | p = ¶ms->plane[plane]; |
2988 | continue; |
2956 | if (!p->enabled) |
2989 | if (plane->type == DRM_PLANE_TYPE_CURSOR) |
2957 | continue; |
2990 | continue; |
2958 | 2991 | ||
2959 | data_rate = skl_plane_relative_data_rate(p, 0); |
2992 | data_rate = skl_plane_relative_data_rate(cstate, pstate, 0); |
Line 2960... | Line 2993... | ||
2960 | 2993 | ||
2961 | /* |
2994 | /* |
Line 2962... | Line 2995... | ||
2962 | * allocation for (packed formats) or (uv-plane part of planar format): |
2995 | * allocation for (packed formats) or (uv-plane part of planar format): |
Line 2963... | Line 2996... | ||
2963 | * promote the expression to 64 bits to avoid overflowing, the |
2996 | * promote the expression to 64 bits to avoid overflowing, the |
2964 | * result is < available as data_rate / total_data_rate < 1 |
2997 | * result is < available as data_rate / total_data_rate < 1 |
2965 | */ |
2998 | */ |
2966 | plane_blocks = minimum[plane]; |
2999 | plane_blocks = minimum[id]; |
2967 | plane_blocks += div_u64((uint64_t)alloc_size * data_rate, |
3000 | plane_blocks += div_u64((uint64_t)alloc_size * data_rate, |
- | 3001 | total_data_rate); |
|
- | 3002 | ||
2968 | total_data_rate); |
3003 | ddb->plane[pipe][id].start = start; |
2969 | 3004 | ddb->plane[pipe][id].end = start + plane_blocks; |
|
2970 | ddb->plane[pipe][plane].start = start; |
3005 | |
Line 2971... | Line 3006... | ||
2971 | ddb->plane[pipe][plane].end = start + plane_blocks; |
3006 | start += plane_blocks; |
2972 | 3007 | ||
Line 2973... | Line 3008... | ||
2973 | start += plane_blocks; |
3008 | /* |
2974 | 3009 | * allocation for y_plane part of planar format: |
|
Line 2975... | Line 3010... | ||
2975 | /* |
3010 | */ |
Line 3050... | Line 3085... | ||
3050 | const struct intel_crtc *intel_crtc) |
3085 | const struct intel_crtc *intel_crtc) |
3051 | { |
3086 | { |
3052 | struct drm_device *dev = intel_crtc->base.dev; |
3087 | struct drm_device *dev = intel_crtc->base.dev; |
3053 | struct drm_i915_private *dev_priv = dev->dev_private; |
3088 | struct drm_i915_private *dev_priv = dev->dev_private; |
3054 | const struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb; |
3089 | const struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb; |
3055 | enum pipe pipe = intel_crtc->pipe; |
- | |
Line -... | Line 3090... | ||
- | 3090 | ||
3056 | 3091 | /* |
|
3057 | if (memcmp(new_ddb->plane[pipe], cur_ddb->plane[pipe], |
- | |
3058 | sizeof(new_ddb->plane[pipe]))) |
3092 | * If ddb allocation of pipes changed, it may require recalculation of |
3059 | return true; |
3093 | * watermarks |
3060 | 3094 | */ |
|
3061 | if (memcmp(&new_ddb->plane[pipe][PLANE_CURSOR], &cur_ddb->plane[pipe][PLANE_CURSOR], |
- | |
3062 | sizeof(new_ddb->plane[pipe][PLANE_CURSOR]))) |
3095 | if (memcmp(new_ddb->pipe, cur_ddb->pipe, sizeof(new_ddb->pipe))) |
Line 3063... | Line 3096... | ||
3063 | return true; |
3096 | return true; |
3064 | 3097 | ||
Line 3065... | Line -... | ||
3065 | return false; |
- | |
3066 | } |
- | |
3067 | - | ||
3068 | static void skl_compute_wm_global_parameters(struct drm_device *dev, |
- | |
3069 | struct intel_wm_config *config) |
- | |
3070 | { |
- | |
3071 | struct drm_crtc *crtc; |
- | |
3072 | struct drm_plane *plane; |
- | |
3073 | - | ||
3074 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) |
- | |
3075 | config->num_pipes_active += to_intel_crtc(crtc)->active; |
- | |
3076 | - | ||
3077 | /* FIXME: I don't think we need those two global parameters on SKL */ |
- | |
3078 | list_for_each_entry(plane, &dev->mode_config.plane_list, head) { |
- | |
3079 | struct intel_plane *intel_plane = to_intel_plane(plane); |
- | |
3080 | - | ||
3081 | config->sprites_enabled |= intel_plane->wm.enabled; |
- | |
3082 | config->sprites_scaled |= intel_plane->wm.scaled; |
- | |
3083 | } |
- | |
3084 | } |
- | |
3085 | - | ||
3086 | static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc, |
- | |
3087 | struct skl_pipe_wm_parameters *p) |
- | |
3088 | { |
- | |
3089 | struct drm_device *dev = crtc->dev; |
- | |
3090 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
3091 | enum pipe pipe = intel_crtc->pipe; |
- | |
3092 | struct drm_plane *plane; |
- | |
3093 | struct drm_framebuffer *fb; |
- | |
3094 | int i = 1; /* Index for sprite planes start */ |
- | |
3095 | - | ||
3096 | p->active = intel_crtc->active; |
- | |
3097 | if (p->active) { |
- | |
3098 | p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal; |
- | |
3099 | p->pixel_rate = skl_pipe_pixel_rate(intel_crtc->config); |
- | |
3100 | - | ||
3101 | fb = crtc->primary->state->fb; |
- | |
3102 | /* For planar: Bpp is for uv plane, y_Bpp is for y plane */ |
- | |
3103 | if (fb) { |
- | |
3104 | p->plane[0].enabled = true; |
- | |
3105 | p->plane[0].bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ? |
- | |
3106 | drm_format_plane_cpp(fb->pixel_format, 1) : |
- | |
3107 | drm_format_plane_cpp(fb->pixel_format, 0); |
- | |
3108 | p->plane[0].y_bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ? |
- | |
3109 | drm_format_plane_cpp(fb->pixel_format, 0) : 0; |
- | |
3110 | p->plane[0].tiling = fb->modifier[0]; |
- | |
3111 | } else { |
- | |
3112 | p->plane[0].enabled = false; |
- | |
3113 | p->plane[0].bytes_per_pixel = 0; |
- | |
3114 | p->plane[0].y_bytes_per_pixel = 0; |
- | |
3115 | p->plane[0].tiling = DRM_FORMAT_MOD_NONE; |
- | |
3116 | } |
- | |
3117 | p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w; |
- | |
3118 | p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h; |
- | |
3119 | p->plane[0].rotation = crtc->primary->state->rotation; |
- | |
3120 | - | ||
3121 | fb = crtc->cursor->state->fb; |
- | |
3122 | p->plane[PLANE_CURSOR].y_bytes_per_pixel = 0; |
- | |
3123 | if (fb) { |
- | |
3124 | p->plane[PLANE_CURSOR].enabled = true; |
- | |
3125 | p->plane[PLANE_CURSOR].bytes_per_pixel = fb->bits_per_pixel / 8; |
- | |
3126 | p->plane[PLANE_CURSOR].horiz_pixels = crtc->cursor->state->crtc_w; |
- | |
3127 | p->plane[PLANE_CURSOR].vert_pixels = crtc->cursor->state->crtc_h; |
- | |
3128 | } else { |
- | |
3129 | p->plane[PLANE_CURSOR].enabled = false; |
- | |
3130 | p->plane[PLANE_CURSOR].bytes_per_pixel = 0; |
- | |
3131 | p->plane[PLANE_CURSOR].horiz_pixels = 64; |
- | |
3132 | p->plane[PLANE_CURSOR].vert_pixels = 64; |
- | |
3133 | } |
- | |
3134 | } |
- | |
3135 | - | ||
3136 | list_for_each_entry(plane, &dev->mode_config.plane_list, head) { |
- | |
3137 | struct intel_plane *intel_plane = to_intel_plane(plane); |
- | |
3138 | - | ||
3139 | if (intel_plane->pipe == pipe && |
- | |
3140 | plane->type == DRM_PLANE_TYPE_OVERLAY) |
- | |
3141 | p->plane[i++] = intel_plane->wm; |
- | |
3142 | } |
3098 | return false; |
3143 | } |
3099 | } |
3144 | 3100 | ||
3145 | static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, |
3101 | static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, |
3146 | struct skl_pipe_wm_parameters *p, |
3102 | struct intel_crtc_state *cstate, |
3147 | struct intel_plane_wm_parameters *p_params, |
3103 | struct intel_plane *intel_plane, |
3148 | uint16_t ddb_allocation, |
3104 | uint16_t ddb_allocation, |
3149 | int level, |
3105 | int level, |
- | 3106 | uint16_t *out_blocks, /* out */ |
|
- | 3107 | uint8_t *out_lines /* out */) |
|
3150 | uint16_t *out_blocks, /* out */ |
3108 | { |
3151 | uint8_t *out_lines /* out */) |
3109 | struct drm_plane *plane = &intel_plane->base; |
3152 | { |
3110 | struct drm_framebuffer *fb = plane->state->fb; |
3153 | uint32_t latency = dev_priv->wm.skl_latency[level]; |
3111 | uint32_t latency = dev_priv->wm.skl_latency[level]; |
3154 | uint32_t method1, method2; |
3112 | uint32_t method1, method2; |
3155 | uint32_t plane_bytes_per_line, plane_blocks_per_line; |
3113 | uint32_t plane_bytes_per_line, plane_blocks_per_line; |
Line 3156... | Line 3114... | ||
3156 | uint32_t res_blocks, res_lines; |
3114 | uint32_t res_blocks, res_lines; |
3157 | uint32_t selected_result; |
3115 | uint32_t selected_result; |
Line 3158... | Line 3116... | ||
3158 | uint8_t bytes_per_pixel; |
3116 | uint8_t bytes_per_pixel; |
3159 | - | ||
3160 | if (latency == 0 || !p->active || !p_params->enabled) |
- | |
3161 | return false; |
3117 | |
3162 | 3118 | if (latency == 0 || !cstate->base.active || !fb) |
|
3163 | bytes_per_pixel = p_params->y_bytes_per_pixel ? |
3119 | return false; |
3164 | p_params->y_bytes_per_pixel : |
3120 | |
3165 | p_params->bytes_per_pixel; |
3121 | bytes_per_pixel = drm_format_plane_cpp(fb->pixel_format, 0); |
3166 | method1 = skl_wm_method1(p->pixel_rate, |
3122 | method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate), |
3167 | bytes_per_pixel, |
3123 | bytes_per_pixel, |
3168 | latency); |
3124 | latency); |
3169 | method2 = skl_wm_method2(p->pixel_rate, |
3125 | method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate), |
Line 3170... | Line 3126... | ||
3170 | p->pipe_htotal, |
3126 | cstate->base.adjusted_mode.crtc_htotal, |
3171 | p_params->horiz_pixels, |
3127 | cstate->pipe_src_w, |
Line 3172... | Line 3128... | ||
3172 | bytes_per_pixel, |
3128 | bytes_per_pixel, |
3173 | p_params->tiling, |
3129 | fb->modifier[0], |
3174 | latency); |
3130 | latency); |
3175 | 3131 | ||
3176 | plane_bytes_per_line = p_params->horiz_pixels * bytes_per_pixel; |
3132 | plane_bytes_per_line = cstate->pipe_src_w * bytes_per_pixel; |
- | 3133 | plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); |
|
- | 3134 | ||
- | 3135 | if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || |
|
- | 3136 | fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { |
|
3177 | plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); |
3137 | uint32_t min_scanlines = 4; |
3178 | 3138 | uint32_t y_tile_minimum; |
|
3179 | if (p_params->tiling == I915_FORMAT_MOD_Y_TILED || |
3139 | if (intel_rotation_90_or_270(plane->state->rotation)) { |
3180 | p_params->tiling == I915_FORMAT_MOD_Yf_TILED) { |
3140 | int bpp = (fb->pixel_format == DRM_FORMAT_NV12) ? |
3181 | uint32_t min_scanlines = 4; |
3141 | drm_format_plane_cpp(fb->pixel_format, 1) : |
3182 | uint32_t y_tile_minimum; |
3142 | drm_format_plane_cpp(fb->pixel_format, 0); |
Line 3203... | Line 3163... | ||
3203 | 3163 | ||
3204 | res_blocks = selected_result + 1; |
3164 | res_blocks = selected_result + 1; |
Line 3205... | Line 3165... | ||
3205 | res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line); |
3165 | res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line); |
3206 | 3166 | ||
3207 | if (level >= 1 && level <= 7) { |
3167 | if (level >= 1 && level <= 7) { |
3208 | if (p_params->tiling == I915_FORMAT_MOD_Y_TILED || |
3168 | if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || |
3209 | p_params->tiling == I915_FORMAT_MOD_Yf_TILED) |
3169 | fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) |
3210 | res_lines += 4; |
3170 | res_lines += 4; |
3211 | else |
3171 | else |
Line 3221... | Line 3181... | ||
3221 | return true; |
3181 | return true; |
3222 | } |
3182 | } |
Line 3223... | Line 3183... | ||
3223 | 3183 | ||
3224 | static void skl_compute_wm_level(const struct drm_i915_private *dev_priv, |
3184 | static void skl_compute_wm_level(const struct drm_i915_private *dev_priv, |
3225 | struct skl_ddb_allocation *ddb, |
3185 | struct skl_ddb_allocation *ddb, |
3226 | struct skl_pipe_wm_parameters *p, |
- | |
3227 | enum pipe pipe, |
3186 | struct intel_crtc_state *cstate, |
3228 | int level, |
- | |
3229 | int num_planes, |
3187 | int level, |
3230 | struct skl_wm_level *result) |
3188 | struct skl_wm_level *result) |
- | 3189 | { |
|
- | 3190 | struct drm_device *dev = dev_priv->dev; |
|
- | 3191 | struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); |
|
3231 | { |
3192 | struct intel_plane *intel_plane; |
3232 | uint16_t ddb_blocks; |
3193 | uint16_t ddb_blocks; |
- | 3194 | enum pipe pipe = intel_crtc->pipe; |
|
- | 3195 | ||
- | 3196 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { |
|
Line 3233... | Line -... | ||
3233 | int i; |
- | |
3234 | 3197 | int i = skl_wm_plane_id(intel_plane); |
|
Line 3235... | Line 3198... | ||
3235 | for (i = 0; i < num_planes; i++) { |
3198 | |
- | 3199 | ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]); |
|
3236 | ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]); |
3200 | |
3237 | 3201 | result->plane_en[i] = skl_compute_plane_wm(dev_priv, |
|
3238 | result->plane_en[i] = skl_compute_plane_wm(dev_priv, |
3202 | cstate, |
3239 | p, &p->plane[i], |
3203 | intel_plane, |
3240 | ddb_blocks, |
3204 | ddb_blocks, |
3241 | level, |
3205 | level, |
3242 | &result->plane_res_b[i], |
- | |
3243 | &result->plane_res_l[i]); |
- | |
3244 | } |
- | |
3245 | - | ||
3246 | ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][PLANE_CURSOR]); |
- | |
3247 | result->plane_en[PLANE_CURSOR] = skl_compute_plane_wm(dev_priv, p, |
- | |
3248 | &p->plane[PLANE_CURSOR], |
- | |
3249 | ddb_blocks, level, |
3206 | &result->plane_res_b[i], |
Line 3250... | Line 3207... | ||
3250 | &result->plane_res_b[PLANE_CURSOR], |
3207 | &result->plane_res_l[i]); |
3251 | &result->plane_res_l[PLANE_CURSOR]); |
3208 | } |
3252 | } |
3209 | } |
3253 | 3210 | ||
3254 | static uint32_t |
3211 | static uint32_t |
Line 3255... | Line 3212... | ||
3255 | skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p) |
3212 | skl_compute_linetime_wm(struct intel_crtc_state *cstate) |
3256 | { |
3213 | { |
Line 3257... | Line 3214... | ||
3257 | if (!to_intel_crtc(crtc)->active) |
3214 | if (!cstate->base.active) |
- | 3215 | return 0; |
|
3258 | return 0; |
3216 | |
Line 3259... | Line 3217... | ||
3259 | 3217 | if (WARN_ON(skl_pipe_pixel_rate(cstate) == 0)) |
|
3260 | if (WARN_ON(p->pixel_rate == 0)) |
- | |
3261 | return 0; |
3218 | return 0; |
3262 | 3219 | ||
- | 3220 | return DIV_ROUND_UP(8 * cstate->base.adjusted_mode.crtc_htotal * 1000, |
|
3263 | return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate); |
3221 | skl_pipe_pixel_rate(cstate)); |
3264 | } |
3222 | } |
Line 3265... | Line 3223... | ||
3265 | 3223 | ||
3266 | static void skl_compute_transition_wm(struct drm_crtc *crtc, |
3224 | static void skl_compute_transition_wm(struct intel_crtc_state *cstate, |
Line 3267... | Line 3225... | ||
3267 | struct skl_pipe_wm_parameters *params, |
3225 | struct skl_wm_level *trans_wm /* out */) |
- | 3226 | { |
|
3268 | struct skl_wm_level *trans_wm /* out */) |
3227 | struct drm_crtc *crtc = cstate->base.crtc; |
- | 3228 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
3269 | { |
3229 | struct intel_plane *intel_plane; |
3270 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
- | 3230 | ||
3271 | int i; |
3231 | if (!cstate->base.active) |
Line 3272... | Line 3232... | ||
3272 | 3232 | return; |
|
3273 | if (!params->active) |
3233 | |
3274 | return; |
- | |
3275 | 3234 | /* Until we know more, just disable transition WMs */ |
|
3276 | /* Until we know more, just disable transition WMs */ |
3235 | for_each_intel_plane_on_crtc(crtc->dev, intel_crtc, intel_plane) { |
3277 | for (i = 0; i < intel_num_planes(intel_crtc); i++) |
3236 | int i = skl_wm_plane_id(intel_plane); |
3278 | trans_wm->plane_en[i] = false; |
3237 | |
3279 | trans_wm->plane_en[PLANE_CURSOR] = false; |
- | |
3280 | } |
3238 | trans_wm->plane_en[i] = false; |
Line 3281... | Line 3239... | ||
3281 | 3239 | } |
|
3282 | static void skl_compute_pipe_wm(struct drm_crtc *crtc, |
3240 | } |
3283 | struct skl_ddb_allocation *ddb, |
- | |
3284 | struct skl_pipe_wm_parameters *params, |
3241 | |
3285 | struct skl_pipe_wm *pipe_wm) |
3242 | static void skl_compute_pipe_wm(struct intel_crtc_state *cstate, |
3286 | { |
3243 | struct skl_ddb_allocation *ddb, |
Line 3287... | Line 3244... | ||
3287 | struct drm_device *dev = crtc->dev; |
3244 | struct skl_pipe_wm *pipe_wm) |
3288 | const struct drm_i915_private *dev_priv = dev->dev_private; |
3245 | { |
Line 3289... | Line 3246... | ||
3289 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3246 | struct drm_device *dev = cstate->base.crtc->dev; |
3290 | int level, max_level = ilk_wm_max_level(dev); |
- | |
3291 | 3247 | const struct drm_i915_private *dev_priv = dev->dev_private; |
|
3292 | for (level = 0; level <= max_level; level++) { |
3248 | int level, max_level = ilk_wm_max_level(dev); |
3293 | skl_compute_wm_level(dev_priv, ddb, params, intel_crtc->pipe, |
3249 | |
3294 | level, intel_num_planes(intel_crtc), |
3250 | for (level = 0; level <= max_level; level++) { |
3295 | &pipe_wm->wm[level]); |
3251 | skl_compute_wm_level(dev_priv, ddb, cstate, |
Line 3355... | Line 3311... | ||
3355 | r->plane_trans[pipe][PLANE_CURSOR] = temp; |
3311 | r->plane_trans[pipe][PLANE_CURSOR] = temp; |
Line 3356... | Line 3312... | ||
3356 | 3312 | ||
3357 | r->wm_linetime[pipe] = p_wm->linetime; |
3313 | r->wm_linetime[pipe] = p_wm->linetime; |
Line 3358... | Line 3314... | ||
3358 | } |
3314 | } |
- | 3315 | ||
3359 | 3316 | static void skl_ddb_entry_write(struct drm_i915_private *dev_priv, |
|
3360 | static void skl_ddb_entry_write(struct drm_i915_private *dev_priv, uint32_t reg, |
3317 | i915_reg_t reg, |
3361 | const struct skl_ddb_entry *entry) |
3318 | const struct skl_ddb_entry *entry) |
3362 | { |
3319 | { |
3363 | if (entry->end) |
3320 | if (entry->end) |
Line 3370... | Line 3327... | ||
3370 | const struct skl_wm_values *new) |
3327 | const struct skl_wm_values *new) |
3371 | { |
3328 | { |
3372 | struct drm_device *dev = dev_priv->dev; |
3329 | struct drm_device *dev = dev_priv->dev; |
3373 | struct intel_crtc *crtc; |
3330 | struct intel_crtc *crtc; |
Line 3374... | Line 3331... | ||
3374 | 3331 | ||
3375 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { |
3332 | for_each_intel_crtc(dev, crtc) { |
3376 | int i, level, max_level = ilk_wm_max_level(dev); |
3333 | int i, level, max_level = ilk_wm_max_level(dev); |
Line 3377... | Line 3334... | ||
3377 | enum pipe pipe = crtc->pipe; |
3334 | enum pipe pipe = crtc->pipe; |
3378 | 3335 | ||
Line 3542... | Line 3499... | ||
3542 | skl_wm_flush_pipe(dev_priv, pipe, 3); |
3499 | skl_wm_flush_pipe(dev_priv, pipe, 3); |
3543 | } |
3500 | } |
3544 | } |
3501 | } |
Line 3545... | Line 3502... | ||
3545 | 3502 | ||
3546 | static bool skl_update_pipe_wm(struct drm_crtc *crtc, |
- | |
3547 | struct skl_pipe_wm_parameters *params, |
- | |
3548 | struct intel_wm_config *config, |
3503 | static bool skl_update_pipe_wm(struct drm_crtc *crtc, |
3549 | struct skl_ddb_allocation *ddb, /* out */ |
3504 | struct skl_ddb_allocation *ddb, /* out */ |
3550 | struct skl_pipe_wm *pipe_wm /* out */) |
3505 | struct skl_pipe_wm *pipe_wm /* out */) |
3551 | { |
3506 | { |
- | 3507 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
Line 3552... | Line -... | ||
3552 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
3553 | 3508 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); |
|
3554 | skl_compute_wm_pipe_parameters(crtc, params); |
3509 | |
Line 3555... | Line 3510... | ||
3555 | skl_allocate_pipe_ddb(crtc, config, params, ddb); |
3510 | skl_allocate_pipe_ddb(cstate, ddb); |
3556 | skl_compute_pipe_wm(crtc, ddb, params, pipe_wm); |
3511 | skl_compute_pipe_wm(cstate, ddb, pipe_wm); |
Line 3557... | Line 3512... | ||
3557 | 3512 | ||
Line 3558... | Line 3513... | ||
3558 | if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm))) |
3513 | if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm))) |
3559 | return false; |
3514 | return false; |
Line 3560... | Line 3515... | ||
3560 | 3515 | ||
3561 | intel_crtc->wm.skl_active = *pipe_wm; |
3516 | intel_crtc->wm.active.skl = *pipe_wm; |
3562 | - | ||
3563 | return true; |
3517 | |
3564 | } |
3518 | return true; |
3565 | 3519 | } |
|
3566 | static void skl_update_other_pipe_wm(struct drm_device *dev, |
3520 | |
Line 3582... | Line 3536... | ||
3582 | 3536 | ||
3583 | /* |
3537 | /* |
3584 | * Otherwise, because of this_crtc being freshly enabled/disabled, the |
3538 | * Otherwise, because of this_crtc being freshly enabled/disabled, the |
3585 | * other active pipes need new DDB allocation and WM values. |
3539 | * other active pipes need new DDB allocation and WM values. |
3586 | */ |
3540 | */ |
3587 | list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, |
- | |
3588 | base.head) { |
- | |
3589 | struct skl_pipe_wm_parameters params = {}; |
3541 | for_each_intel_crtc(dev, intel_crtc) { |
3590 | struct skl_pipe_wm pipe_wm = {}; |
3542 | struct skl_pipe_wm pipe_wm = {}; |
Line 3591... | Line 3543... | ||
3591 | bool wm_changed; |
3543 | bool wm_changed; |
3592 | 3544 | ||
Line 3593... | Line 3545... | ||
3593 | if (this_crtc->pipe == intel_crtc->pipe) |
3545 | if (this_crtc->pipe == intel_crtc->pipe) |
3594 | continue; |
3546 | continue; |
Line 3595... | Line 3547... | ||
3595 | 3547 | ||
3596 | if (!intel_crtc->active) |
- | |
3597 | continue; |
3548 | if (!intel_crtc->active) |
Line 3598... | Line 3549... | ||
3598 | 3549 | continue; |
|
3599 | wm_changed = skl_update_pipe_wm(&intel_crtc->base, |
3550 | |
3600 | ¶ms, config, |
3551 | wm_changed = skl_update_pipe_wm(&intel_crtc->base, |
3601 | &r->ddb, &pipe_wm); |
3552 | &r->ddb, &pipe_wm); |
3602 | 3553 | ||
3603 | /* |
3554 | /* |
Line 3604... | Line 3555... | ||
3604 | * If we end up re-computing the other pipe WM values, it's |
3555 | * If we end up re-computing the other pipe WM values, it's |
3605 | * because it was really needed, so we expect the WM values to |
3556 | * because it was really needed, so we expect the WM values to |
3606 | * be different. |
3557 | * be different. |
3607 | */ |
3558 | */ |
Line 3608... | Line 3559... | ||
3608 | WARN_ON(!wm_changed); |
3559 | WARN_ON(!wm_changed); |
Line 3635... | Line 3586... | ||
3635 | static void skl_update_wm(struct drm_crtc *crtc) |
3586 | static void skl_update_wm(struct drm_crtc *crtc) |
3636 | { |
3587 | { |
3637 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3588 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3638 | struct drm_device *dev = crtc->dev; |
3589 | struct drm_device *dev = crtc->dev; |
3639 | struct drm_i915_private *dev_priv = dev->dev_private; |
3590 | struct drm_i915_private *dev_priv = dev->dev_private; |
3640 | struct skl_pipe_wm_parameters params = {}; |
- | |
3641 | struct skl_wm_values *results = &dev_priv->wm.skl_results; |
3591 | struct skl_wm_values *results = &dev_priv->wm.skl_results; |
3642 | struct skl_pipe_wm pipe_wm = {}; |
3592 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); |
3643 | struct intel_wm_config config = {}; |
3593 | struct skl_pipe_wm *pipe_wm = &cstate->wm.optimal.skl; |
Line 3644... | Line 3594... | ||
3644 | 3594 | ||
3645 | 3595 | ||
Line 3646... | Line 3596... | ||
3646 | /* Clear all dirty flags */ |
3596 | /* Clear all dirty flags */ |
Line 3647... | Line -... | ||
3647 | memset(results->dirty, 0, sizeof(bool) * I915_MAX_PIPES); |
- | |
3648 | - | ||
3649 | skl_clear_wm(results, intel_crtc->pipe); |
3597 | memset(results->dirty, 0, sizeof(bool) * I915_MAX_PIPES); |
3650 | - | ||
3651 | skl_compute_wm_global_parameters(dev, &config); |
3598 | |
Line 3652... | Line 3599... | ||
3652 | 3599 | skl_clear_wm(results, intel_crtc->pipe); |
|
3653 | if (!skl_update_pipe_wm(crtc, ¶ms, &config, |
3600 | |
Line 3654... | Line 3601... | ||
3654 | &results->ddb, &pipe_wm)) |
3601 | if (!skl_update_pipe_wm(crtc, &results->ddb, pipe_wm)) |
3655 | return; |
3602 | return; |
3656 | 3603 | ||
Line 3657... | Line 3604... | ||
3657 | skl_compute_wm_results(dev, ¶ms, &pipe_wm, results, intel_crtc); |
3604 | skl_compute_wm_results(dev, pipe_wm, results, intel_crtc); |
3658 | results->dirty[intel_crtc->pipe] = true; |
3605 | results->dirty[intel_crtc->pipe] = true; |
3659 | 3606 | ||
Line 3660... | Line -... | ||
3660 | skl_update_other_pipe_wm(dev, crtc, &config, results); |
- | |
3661 | skl_write_wm_values(dev_priv, results); |
3607 | skl_update_other_pipe_wm(dev, crtc, results); |
3662 | skl_flush_wm_values(dev_priv, results); |
- | |
3663 | 3608 | skl_write_wm_values(dev_priv, results); |
|
3664 | /* store the new configuration */ |
3609 | skl_flush_wm_values(dev_priv, results); |
3665 | dev_priv->wm.skl_hw = *results; |
- | |
3666 | } |
3610 | |
Line 3667... | Line -... | ||
3667 | - | ||
3668 | static void |
- | |
3669 | skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc, |
- | |
3670 | uint32_t sprite_width, uint32_t sprite_height, |
3611 | /* store the new configuration */ |
3671 | int pixel_size, bool enabled, bool scaled) |
- | |
3672 | { |
- | |
3673 | struct intel_plane *intel_plane = to_intel_plane(plane); |
- | |
3674 | struct drm_framebuffer *fb = plane->state->fb; |
3612 | dev_priv->wm.skl_hw = *results; |
3675 | - | ||
3676 | intel_plane->wm.enabled = enabled; |
- | |
3677 | intel_plane->wm.scaled = scaled; |
- | |
3678 | intel_plane->wm.horiz_pixels = sprite_width; |
- | |
3679 | intel_plane->wm.vert_pixels = sprite_height; |
- | |
3680 | intel_plane->wm.tiling = DRM_FORMAT_MOD_NONE; |
- | |
3681 | - | ||
3682 | /* For planar: Bpp is for UV plane, y_Bpp is for Y plane */ |
- | |
3683 | intel_plane->wm.bytes_per_pixel = |
- | |
3684 | (fb && fb->pixel_format == DRM_FORMAT_NV12) ? |
- | |
3685 | drm_format_plane_cpp(plane->state->fb->pixel_format, 1) : pixel_size; |
- | |
3686 | intel_plane->wm.y_bytes_per_pixel = |
3613 | } |
3687 | (fb && fb->pixel_format == DRM_FORMAT_NV12) ? |
- | |
Line 3688... | Line 3614... | ||
3688 | drm_format_plane_cpp(plane->state->fb->pixel_format, 0) : 0; |
3614 | |
- | 3615 | static void ilk_compute_wm_config(struct drm_device *dev, |
|
- | 3616 | struct intel_wm_config *config) |
|
- | 3617 | { |
|
- | 3618 | struct intel_crtc *crtc; |
|
- | 3619 | ||
- | 3620 | /* Compute the currently _active_ config */ |
|
3689 | 3621 | for_each_intel_crtc(dev, crtc) { |
|
Line 3690... | Line 3622... | ||
3690 | /* |
3622 | const struct intel_pipe_wm *wm = &crtc->wm.active.ilk; |
3691 | * Framebuffer can be NULL on plane disable, but it does not |
3623 | |
3692 | * matter for watermarks if we assume no tiling in that case. |
- | |
3693 | */ |
- | |
3694 | if (fb) |
3624 | if (!wm->pipe_enabled) |
3695 | intel_plane->wm.tiling = fb->modifier[0]; |
3625 | continue; |
3696 | intel_plane->wm.rotation = plane->state->rotation; |
3626 | |
- | 3627 | config->sprites_enabled |= wm->sprites_enabled; |
|
3697 | 3628 | config->sprites_scaled |= wm->sprites_scaled; |
|
3698 | skl_update_wm(crtc); |
3629 | config->num_pipes_active++; |
3699 | } |
- | |
3700 | - | ||
3701 | static void ilk_update_wm(struct drm_crtc *crtc) |
- | |
3702 | { |
- | |
3703 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
3704 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); |
- | |
3705 | struct drm_device *dev = crtc->dev; |
- | |
3706 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
3707 | struct ilk_wm_maximums max; |
- | |
3708 | struct ilk_wm_values results = {}; |
- | |
3709 | enum intel_ddb_partitioning partitioning; |
- | |
3710 | struct intel_pipe_wm pipe_wm = {}; |
- | |
Line 3711... | Line 3630... | ||
3711 | struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; |
3630 | } |
Line 3712... | Line 3631... | ||
3712 | struct intel_wm_config config = {}; |
3631 | } |
3713 | 3632 | ||
Line 3742... | Line 3661... | ||
3742 | ilk_compute_wm_results(dev, best_lp_wm, partitioning, &results); |
3661 | ilk_compute_wm_results(dev, best_lp_wm, partitioning, &results); |
Line 3743... | Line 3662... | ||
3743 | 3662 | ||
3744 | ilk_write_wm_values(dev_priv, &results); |
3663 | ilk_write_wm_values(dev_priv, &results); |
Line 3745... | Line -... | ||
3745 | } |
- | |
3746 | 3664 | } |
|
3747 | static void |
- | |
3748 | ilk_update_sprite_wm(struct drm_plane *plane, |
- | |
3749 | struct drm_crtc *crtc, |
- | |
3750 | uint32_t sprite_width, uint32_t sprite_height, |
3665 | |
3751 | int pixel_size, bool enabled, bool scaled) |
3666 | static void ilk_update_wm(struct drm_crtc *crtc) |
3752 | { |
3667 | { |
- | 3668 | struct drm_i915_private *dev_priv = to_i915(crtc->dev); |
|
- | 3669 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 3670 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); |
|
Line 3753... | Line 3671... | ||
3753 | struct drm_device *dev = plane->dev; |
3671 | |
3754 | struct intel_plane *intel_plane = to_intel_plane(plane); |
3672 | WARN_ON(cstate->base.active != intel_crtc->active); |
3755 | 3673 | ||
3756 | /* |
3674 | /* |
3757 | * IVB workaround: must disable low power watermarks for at least |
3675 | * IVB workaround: must disable low power watermarks for at least |
3758 | * one frame before enabling scaling. LP watermarks can be re-enabled |
3676 | * one frame before enabling scaling. LP watermarks can be re-enabled |
3759 | * when scaling is disabled. |
3677 | * when scaling is disabled. |
3760 | * |
3678 | * |
- | 3679 | * WaCxSRDisabledForSpriteScaling:ivb |
|
3761 | * WaCxSRDisabledForSpriteScaling:ivb |
3680 | */ |
- | 3681 | if (cstate->disable_lp_wm) { |
|
Line -... | Line 3682... | ||
- | 3682 | ilk_disable_lp_wm(crtc->dev); |
|
- | 3683 | intel_wait_for_vblank(crtc->dev, intel_crtc->pipe); |
|
3762 | */ |
3684 | } |
3763 | if (IS_IVYBRIDGE(dev) && scaled && ilk_disable_lp_wm(dev)) |
3685 | |
Line 3764... | Line 3686... | ||
3764 | intel_wait_for_vblank(dev, intel_plane->pipe); |
3686 | intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk; |
3765 | 3687 | ||
3766 | ilk_update_wm(crtc); |
3688 | ilk_program_watermarks(dev_priv); |
Line 3814... | Line 3736... | ||
3814 | { |
3736 | { |
3815 | struct drm_device *dev = crtc->dev; |
3737 | struct drm_device *dev = crtc->dev; |
3816 | struct drm_i915_private *dev_priv = dev->dev_private; |
3738 | struct drm_i915_private *dev_priv = dev->dev_private; |
3817 | struct skl_wm_values *hw = &dev_priv->wm.skl_hw; |
3739 | struct skl_wm_values *hw = &dev_priv->wm.skl_hw; |
3818 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3740 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | 3741 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); |
|
3819 | struct skl_pipe_wm *active = &intel_crtc->wm.skl_active; |
3742 | struct skl_pipe_wm *active = &cstate->wm.optimal.skl; |
3820 | enum pipe pipe = intel_crtc->pipe; |
3743 | enum pipe pipe = intel_crtc->pipe; |
3821 | int level, i, max_level; |
3744 | int level, i, max_level; |
3822 | uint32_t temp; |
3745 | uint32_t temp; |
Line 3823... | Line 3746... | ||
3823 | 3746 | ||
Line 3858... | Line 3781... | ||
3858 | skl_pipe_wm_active_state(temp, active, true, false, i, 0); |
3781 | skl_pipe_wm_active_state(temp, active, true, false, i, 0); |
3859 | } |
3782 | } |
Line 3860... | Line 3783... | ||
3860 | 3783 | ||
3861 | temp = hw->plane_trans[pipe][PLANE_CURSOR]; |
3784 | temp = hw->plane_trans[pipe][PLANE_CURSOR]; |
- | 3785 | skl_pipe_wm_active_state(temp, active, true, true, i, 0); |
|
- | 3786 | ||
3862 | skl_pipe_wm_active_state(temp, active, true, true, i, 0); |
3787 | intel_crtc->wm.active.skl = *active; |
Line 3863... | Line 3788... | ||
3863 | } |
3788 | } |
3864 | 3789 | ||
3865 | void skl_wm_get_hw_state(struct drm_device *dev) |
3790 | void skl_wm_get_hw_state(struct drm_device *dev) |
Line 3877... | Line 3802... | ||
3877 | { |
3802 | { |
3878 | struct drm_device *dev = crtc->dev; |
3803 | struct drm_device *dev = crtc->dev; |
3879 | struct drm_i915_private *dev_priv = dev->dev_private; |
3804 | struct drm_i915_private *dev_priv = dev->dev_private; |
3880 | struct ilk_wm_values *hw = &dev_priv->wm.hw; |
3805 | struct ilk_wm_values *hw = &dev_priv->wm.hw; |
3881 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3806 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | 3807 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); |
|
3882 | struct intel_pipe_wm *active = &intel_crtc->wm.active; |
3808 | struct intel_pipe_wm *active = &cstate->wm.optimal.ilk; |
3883 | enum pipe pipe = intel_crtc->pipe; |
3809 | enum pipe pipe = intel_crtc->pipe; |
3884 | static const unsigned int wm0_pipe_reg[] = { |
3810 | static const i915_reg_t wm0_pipe_reg[] = { |
3885 | [PIPE_A] = WM0_PIPEA_ILK, |
3811 | [PIPE_A] = WM0_PIPEA_ILK, |
3886 | [PIPE_B] = WM0_PIPEB_ILK, |
3812 | [PIPE_B] = WM0_PIPEB_ILK, |
3887 | [PIPE_C] = WM0_PIPEC_IVB, |
3813 | [PIPE_C] = WM0_PIPEC_IVB, |
3888 | }; |
3814 | }; |
Line 3918... | Line 3844... | ||
3918 | * which is what we'd compute them to. |
3844 | * which is what we'd compute them to. |
3919 | */ |
3845 | */ |
3920 | for (level = 0; level <= max_level; level++) |
3846 | for (level = 0; level <= max_level; level++) |
3921 | active->wm[level].enable = true; |
3847 | active->wm[level].enable = true; |
3922 | } |
3848 | } |
- | 3849 | ||
- | 3850 | intel_crtc->wm.active.ilk = *active; |
|
3923 | } |
3851 | } |
Line 3924... | Line 3852... | ||
3924 | 3852 | ||
3925 | #define _FW_WM(value, plane) \ |
3853 | #define _FW_WM(value, plane) \ |
3926 | (((value) & DSPFW_ ## plane ## _MASK) >> DSPFW_ ## plane ## _SHIFT) |
3854 | (((value) & DSPFW_ ## plane ## _MASK) >> DSPFW_ ## plane ## _SHIFT) |
Line 4143... | Line 4071... | ||
4143 | 4071 | ||
4144 | if (dev_priv->display.update_wm) |
4072 | if (dev_priv->display.update_wm) |
4145 | dev_priv->display.update_wm(crtc); |
4073 | dev_priv->display.update_wm(crtc); |
Line 4146... | Line -... | ||
4146 | } |
- | |
4147 | - | ||
4148 | void intel_update_sprite_watermarks(struct drm_plane *plane, |
- | |
4149 | struct drm_crtc *crtc, |
- | |
4150 | uint32_t sprite_width, |
- | |
4151 | uint32_t sprite_height, |
- | |
4152 | int pixel_size, |
- | |
4153 | bool enabled, bool scaled) |
- | |
4154 | { |
- | |
4155 | struct drm_i915_private *dev_priv = plane->dev->dev_private; |
- | |
4156 | - | ||
4157 | if (dev_priv->display.update_sprite_wm) |
- | |
4158 | dev_priv->display.update_sprite_wm(plane, crtc, |
- | |
4159 | sprite_width, sprite_height, |
- | |
4160 | pixel_size, enabled, scaled); |
- | |
4161 | } |
4074 | } |
4162 | 4075 | ||
4163 | /** |
4076 | /** |
4164 | * Lock protecting IPS related data structures |
4077 | * Lock protecting IPS related data structures |
Line 4379... | Line 4292... | ||
4379 | ei_down = 32000; |
4292 | ei_down = 32000; |
4380 | threshold_down = 60; |
4293 | threshold_down = 60; |
4381 | break; |
4294 | break; |
4382 | } |
4295 | } |
Line 4383... | Line -... | ||
4383 | - | ||
4384 | /* When byt can survive without system hang with dynamic |
- | |
4385 | * sw freq adjustments, this restriction can be lifted. |
- | |
4386 | */ |
- | |
4387 | if (IS_VALLEYVIEW(dev_priv)) |
- | |
4388 | goto skip_hw_write; |
- | |
4389 | 4296 | ||
4390 | I915_WRITE(GEN6_RP_UP_EI, |
4297 | I915_WRITE(GEN6_RP_UP_EI, |
4391 | GT_INTERVAL_FROM_US(dev_priv, ei_up)); |
4298 | GT_INTERVAL_FROM_US(dev_priv, ei_up)); |
4392 | I915_WRITE(GEN6_RP_UP_THRESHOLD, |
4299 | I915_WRITE(GEN6_RP_UP_THRESHOLD, |
Line 4403... | Line 4310... | ||
4403 | GEN6_RP_MEDIA_IS_GFX | |
4310 | GEN6_RP_MEDIA_IS_GFX | |
4404 | GEN6_RP_ENABLE | |
4311 | GEN6_RP_ENABLE | |
4405 | GEN6_RP_UP_BUSY_AVG | |
4312 | GEN6_RP_UP_BUSY_AVG | |
4406 | GEN6_RP_DOWN_IDLE_AVG); |
4313 | GEN6_RP_DOWN_IDLE_AVG); |
Line 4407... | Line -... | ||
4407 | - | ||
4408 | skip_hw_write: |
4314 | |
4409 | dev_priv->rps.power = new_power; |
4315 | dev_priv->rps.power = new_power; |
4410 | dev_priv->rps.up_threshold = threshold_up; |
4316 | dev_priv->rps.up_threshold = threshold_up; |
4411 | dev_priv->rps.down_threshold = threshold_down; |
4317 | dev_priv->rps.down_threshold = threshold_down; |
4412 | dev_priv->rps.last_adj = 0; |
4318 | dev_priv->rps.last_adj = 0; |
Line 4413... | Line 4319... | ||
4413 | } |
4319 | } |
4414 | 4320 | ||
4415 | static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) |
4321 | static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) |
Line 4416... | Line -... | ||
4416 | { |
- | |
4417 | u32 mask = 0; |
4322 | { |
4418 | 4323 | u32 mask = 0; |
|
4419 | /* We use UP_EI_EXPIRED interupts for both up/down in manual mode */ |
4324 | |
4420 | if (val > dev_priv->rps.min_freq_softlimit) |
4325 | if (val > dev_priv->rps.min_freq_softlimit) |
Line 4421... | Line 4326... | ||
4421 | mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT; |
4326 | mask |= GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT; |
Line 4433... | Line 4338... | ||
4433 | static void gen6_set_rps(struct drm_device *dev, u8 val) |
4338 | static void gen6_set_rps(struct drm_device *dev, u8 val) |
4434 | { |
4339 | { |
4435 | struct drm_i915_private *dev_priv = dev->dev_private; |
4340 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 4436... | Line 4341... | ||
4436 | 4341 | ||
4437 | /* WaGsvDisableTurbo: Workaround to disable turbo on BXT A* */ |
4342 | /* WaGsvDisableTurbo: Workaround to disable turbo on BXT A* */ |
4438 | if (IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) |
4343 | if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) |
Line 4439... | Line 4344... | ||
4439 | return; |
4344 | return; |
4440 | 4345 | ||
4441 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); |
4346 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); |
Line 4520... | Line 4425... | ||
4520 | 4425 | ||
4521 | void gen6_rps_busy(struct drm_i915_private *dev_priv) |
4426 | void gen6_rps_busy(struct drm_i915_private *dev_priv) |
4522 | { |
4427 | { |
4523 | mutex_lock(&dev_priv->rps.hw_lock); |
4428 | mutex_lock(&dev_priv->rps.hw_lock); |
4524 | if (dev_priv->rps.enabled) { |
4429 | if (dev_priv->rps.enabled) { |
4525 | if (dev_priv->pm_rps_events & GEN6_PM_RP_UP_EI_EXPIRED) |
4430 | if (dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED)) |
4526 | gen6_rps_reset_ei(dev_priv); |
4431 | gen6_rps_reset_ei(dev_priv); |
4527 | I915_WRITE(GEN6_PMINTRMSK, |
4432 | I915_WRITE(GEN6_PMINTRMSK, |
4528 | gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq)); |
4433 | gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq)); |
4529 | } |
4434 | } |
Line 4534... | Line 4439... | ||
4534 | { |
4439 | { |
4535 | struct drm_device *dev = dev_priv->dev; |
4440 | struct drm_device *dev = dev_priv->dev; |
Line 4536... | Line 4441... | ||
4536 | 4441 | ||
4537 | mutex_lock(&dev_priv->rps.hw_lock); |
4442 | mutex_lock(&dev_priv->rps.hw_lock); |
4538 | if (dev_priv->rps.enabled) { |
4443 | if (dev_priv->rps.enabled) { |
4539 | if (IS_VALLEYVIEW(dev)) |
4444 | if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) |
4540 | vlv_set_rps_idle(dev_priv); |
4445 | vlv_set_rps_idle(dev_priv); |
4541 | else |
4446 | else |
4542 | gen6_set_rps(dev_priv->dev, dev_priv->rps.idle_freq); |
4447 | gen6_set_rps(dev_priv->dev, dev_priv->rps.idle_freq); |
4543 | dev_priv->rps.last_adj = 0; |
4448 | dev_priv->rps.last_adj = 0; |
4544 | I915_WRITE(GEN6_PMINTRMSK, |
- | |
4545 | gen6_sanitize_rps_pm_mask(dev_priv, ~0)); |
4449 | I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); |
4546 | } |
4450 | } |
Line 4547... | Line 4451... | ||
4547 | mutex_unlock(&dev_priv->rps.hw_lock); |
4451 | mutex_unlock(&dev_priv->rps.hw_lock); |
4548 | 4452 | ||
Line 4588... | Line 4492... | ||
4588 | spin_unlock(&dev_priv->rps.client_lock); |
4492 | spin_unlock(&dev_priv->rps.client_lock); |
4589 | } |
4493 | } |
Line 4590... | Line 4494... | ||
4590 | 4494 | ||
4591 | void intel_set_rps(struct drm_device *dev, u8 val) |
4495 | void intel_set_rps(struct drm_device *dev, u8 val) |
4592 | { |
4496 | { |
4593 | if (IS_VALLEYVIEW(dev)) |
4497 | if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) |
4594 | valleyview_set_rps(dev, val); |
4498 | valleyview_set_rps(dev, val); |
4595 | else |
4499 | else |
4596 | gen6_set_rps(dev, val); |
4500 | gen6_set_rps(dev, val); |
Line 4632... | Line 4536... | ||
4632 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
4536 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
4633 | } |
4537 | } |
Line 4634... | Line 4538... | ||
4634 | 4538 | ||
4635 | static void intel_print_rc6_info(struct drm_device *dev, u32 mode) |
4539 | static void intel_print_rc6_info(struct drm_device *dev, u32 mode) |
4636 | { |
4540 | { |
4637 | if (IS_VALLEYVIEW(dev)) { |
4541 | if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { |
4638 | if (mode & (GEN7_RC_CTL_TO_MODE | GEN6_RC_CTL_EI_MODE(1))) |
4542 | if (mode & (GEN7_RC_CTL_TO_MODE | GEN6_RC_CTL_EI_MODE(1))) |
4639 | mode = GEN6_RC_CTL_RC6_ENABLE; |
4543 | mode = GEN6_RC_CTL_RC6_ENABLE; |
4640 | else |
4544 | else |
4641 | mode = 0; |
4545 | mode = 0; |
Line 4709... | Line 4613... | ||
4709 | 4613 | ||
4710 | /* hw_max = RP0 until we check for overclocking */ |
4614 | /* hw_max = RP0 until we check for overclocking */ |
Line 4711... | Line 4615... | ||
4711 | dev_priv->rps.max_freq = dev_priv->rps.rp0_freq; |
4615 | dev_priv->rps.max_freq = dev_priv->rps.rp0_freq; |
4712 | 4616 | ||
- | 4617 | dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq; |
|
4713 | dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq; |
4618 | if (IS_HASWELL(dev) || IS_BROADWELL(dev) || |
4714 | if (IS_HASWELL(dev) || IS_BROADWELL(dev) || IS_SKYLAKE(dev)) { |
4619 | IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) { |
4715 | ret = sandybridge_pcode_read(dev_priv, |
4620 | ret = sandybridge_pcode_read(dev_priv, |
4716 | HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL, |
4621 | HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL, |
4717 | &ddcc_status); |
4622 | &ddcc_status); |
Line 4721... | Line 4626... | ||
4721 | ((ddcc_status >> 8) & 0xff), |
4626 | ((ddcc_status >> 8) & 0xff), |
4722 | dev_priv->rps.min_freq, |
4627 | dev_priv->rps.min_freq, |
4723 | dev_priv->rps.max_freq); |
4628 | dev_priv->rps.max_freq); |
4724 | } |
4629 | } |
Line 4725... | Line 4630... | ||
4725 | 4630 | ||
4726 | if (IS_SKYLAKE(dev)) { |
4631 | if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) { |
4727 | /* Store the frequency values in 16.66 MHZ units, which is |
4632 | /* Store the frequency values in 16.66 MHZ units, which is |
4728 | the natural hardware unit for SKL */ |
4633 | the natural hardware unit for SKL */ |
4729 | dev_priv->rps.rp0_freq *= GEN9_FREQ_SCALER; |
4634 | dev_priv->rps.rp0_freq *= GEN9_FREQ_SCALER; |
4730 | dev_priv->rps.rp1_freq *= GEN9_FREQ_SCALER; |
4635 | dev_priv->rps.rp1_freq *= GEN9_FREQ_SCALER; |
Line 4758... | Line 4663... | ||
4758 | intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
4663 | intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
Line 4759... | Line 4664... | ||
4759 | 4664 | ||
Line 4760... | Line 4665... | ||
4760 | gen6_init_rps_frequencies(dev); |
4665 | gen6_init_rps_frequencies(dev); |
4761 | 4666 | ||
4762 | /* WaGsvDisableTurbo: Workaround to disable turbo on BXT A* */ |
4667 | /* WaGsvDisableTurbo: Workaround to disable turbo on BXT A* */ |
4763 | if (IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) { |
4668 | if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) { |
4764 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
4669 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
Line 4765... | Line 4670... | ||
4765 | return; |
4670 | return; |
Line 4826... | Line 4731... | ||
4826 | if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE) |
4731 | if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE) |
4827 | rc6_mask = GEN6_RC_CTL_RC6_ENABLE; |
4732 | rc6_mask = GEN6_RC_CTL_RC6_ENABLE; |
4828 | DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? |
4733 | DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? |
4829 | "on" : "off"); |
4734 | "on" : "off"); |
4830 | /* WaRsUseTimeoutMode */ |
4735 | /* WaRsUseTimeoutMode */ |
4831 | if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) <= SKL_REVID_D0) || |
4736 | if (IS_SKL_REVID(dev, 0, SKL_REVID_D0) || |
4832 | (IS_BROXTON(dev) && INTEL_REVID(dev) <= BXT_REVID_A0)) { |
4737 | IS_BXT_REVID(dev, 0, BXT_REVID_A1)) { |
4833 | I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us */ |
4738 | I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us */ |
4834 | I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | |
4739 | I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | |
4835 | GEN7_RC_CTL_TO_MODE | |
4740 | GEN7_RC_CTL_TO_MODE | |
4836 | rc6_mask); |
4741 | rc6_mask); |
4837 | } else { |
4742 | } else { |
Line 5070... | Line 4975... | ||
5070 | 4975 | ||
5071 | min_ring_freq = I915_READ(DCLK) & 0xf; |
4976 | min_ring_freq = I915_READ(DCLK) & 0xf; |
5072 | /* convert DDR frequency from units of 266.6MHz to bandwidth */ |
4977 | /* convert DDR frequency from units of 266.6MHz to bandwidth */ |
Line 5073... | Line 4978... | ||
5073 | min_ring_freq = mult_frac(min_ring_freq, 8, 3); |
4978 | min_ring_freq = mult_frac(min_ring_freq, 8, 3); |
5074 | 4979 | ||
5075 | if (IS_SKYLAKE(dev)) { |
4980 | if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) { |
5076 | /* Convert GT frequency to 50 HZ units */ |
4981 | /* Convert GT frequency to 50 HZ units */ |
5077 | min_gpu_freq = dev_priv->rps.min_freq / GEN9_FREQ_SCALER; |
4982 | min_gpu_freq = dev_priv->rps.min_freq / GEN9_FREQ_SCALER; |
5078 | max_gpu_freq = dev_priv->rps.max_freq / GEN9_FREQ_SCALER; |
4983 | max_gpu_freq = dev_priv->rps.max_freq / GEN9_FREQ_SCALER; |
Line 5088... | Line 4993... | ||
5088 | */ |
4993 | */ |
5089 | for (gpu_freq = max_gpu_freq; gpu_freq >= min_gpu_freq; gpu_freq--) { |
4994 | for (gpu_freq = max_gpu_freq; gpu_freq >= min_gpu_freq; gpu_freq--) { |
5090 | int diff = max_gpu_freq - gpu_freq; |
4995 | int diff = max_gpu_freq - gpu_freq; |
5091 | unsigned int ia_freq = 0, ring_freq = 0; |
4996 | unsigned int ia_freq = 0, ring_freq = 0; |
Line 5092... | Line 4997... | ||
5092 | 4997 | ||
5093 | if (IS_SKYLAKE(dev)) { |
4998 | if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) { |
5094 | /* |
4999 | /* |
5095 | * ring_freq = 2 * GT. ring_freq is in 100MHz units |
5000 | * ring_freq = 2 * GT. ring_freq is in 100MHz units |
5096 | * No floor required for ring frequency on SKL. |
5001 | * No floor required for ring frequency on SKL. |
5097 | */ |
5002 | */ |
Line 5223... | Line 5128... | ||
5223 | return rpe; |
5128 | return rpe; |
5224 | } |
5129 | } |
Line 5225... | Line 5130... | ||
5225 | 5130 | ||
5226 | static int valleyview_rps_min_freq(struct drm_i915_private *dev_priv) |
5131 | static int valleyview_rps_min_freq(struct drm_i915_private *dev_priv) |
- | 5132 | { |
|
- | 5133 | u32 val; |
|
5227 | { |
5134 | |
- | 5135 | val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM) & 0xff; |
|
- | 5136 | /* |
|
- | 5137 | * According to the BYT Punit GPU turbo HAS 1.1.6.3 the minimum value |
|
- | 5138 | * for the minimum frequency in GPLL mode is 0xc1. Contrary to this on |
|
- | 5139 | * a BYT-M B0 the above register contains 0xbf. Moreover when setting |
|
- | 5140 | * a frequency Punit will not allow values below 0xc0. Clamp it 0xc0 |
|
- | 5141 | * to make sure it matches what Punit accepts. |
|
- | 5142 | */ |
|
5228 | return vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM) & 0xff; |
5143 | return max_t(u32, val, 0xc0); |
Line 5229... | Line 5144... | ||
5229 | } |
5144 | } |
5230 | 5145 | ||
5231 | /* Check that the pctx buffer wasn't move under us. */ |
5146 | /* Check that the pctx buffer wasn't move under us. */ |
Line 6128... | Line 6043... | ||
6128 | dev_priv->ips.corr = (lcfuse & LCFUSE_HIV_MASK); |
6043 | dev_priv->ips.corr = (lcfuse & LCFUSE_HIV_MASK); |
6129 | } |
6044 | } |
Line 6130... | Line 6045... | ||
6130 | 6045 | ||
6131 | void intel_init_gt_powersave(struct drm_device *dev) |
6046 | void intel_init_gt_powersave(struct drm_device *dev) |
- | 6047 | { |
|
- | 6048 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
6132 | { |
6049 | |
- | 6050 | i915.enable_rc6 = sanitize_rc6_option(dev, i915.enable_rc6); |
|
- | 6051 | /* |
|
- | 6052 | * RPM depends on RC6 to save restore the GT HW context, so make RC6 a |
|
- | 6053 | * requirement. |
|
- | 6054 | */ |
|
- | 6055 | if (!i915.enable_rc6) { |
|
- | 6056 | DRM_INFO("RC6 disabled, disabling runtime PM support\n"); |
|
- | 6057 | intel_runtime_pm_get(dev_priv); |
|
Line 6133... | Line 6058... | ||
6133 | i915.enable_rc6 = sanitize_rc6_option(dev, i915.enable_rc6); |
6058 | } |
6134 | 6059 | ||
6135 | if (IS_CHERRYVIEW(dev)) |
6060 | if (IS_CHERRYVIEW(dev)) |
6136 | cherryview_init_gt_powersave(dev); |
6061 | cherryview_init_gt_powersave(dev); |
6137 | else if (IS_VALLEYVIEW(dev)) |
6062 | else if (IS_VALLEYVIEW(dev)) |
Line 6138... | Line 6063... | ||
6138 | valleyview_init_gt_powersave(dev); |
6063 | valleyview_init_gt_powersave(dev); |
6139 | } |
6064 | } |
- | 6065 | ||
- | 6066 | void intel_cleanup_gt_powersave(struct drm_device *dev) |
|
6140 | 6067 | { |
|
6141 | void intel_cleanup_gt_powersave(struct drm_device *dev) |
6068 | struct drm_i915_private *dev_priv = dev->dev_private; |
6142 | { |
6069 | |
6143 | if (IS_CHERRYVIEW(dev)) |
6070 | if (IS_CHERRYVIEW(dev)) |
- | 6071 | return; |
|
- | 6072 | else if (IS_VALLEYVIEW(dev)) |
|
- | 6073 | valleyview_cleanup_gt_powersave(dev); |
|
6144 | return; |
6074 | |
Line 6145... | Line 6075... | ||
6145 | else if (IS_VALLEYVIEW(dev)) |
6075 | if (!i915.enable_rc6) |
6146 | valleyview_cleanup_gt_powersave(dev); |
6076 | intel_runtime_pm_put(dev_priv); |
6147 | } |
6077 | } |
Line 6216... | Line 6146... | ||
6216 | } else if (IS_VALLEYVIEW(dev)) { |
6146 | } else if (IS_VALLEYVIEW(dev)) { |
6217 | valleyview_enable_rps(dev); |
6147 | valleyview_enable_rps(dev); |
6218 | } else if (INTEL_INFO(dev)->gen >= 9) { |
6148 | } else if (INTEL_INFO(dev)->gen >= 9) { |
6219 | gen9_enable_rc6(dev); |
6149 | gen9_enable_rc6(dev); |
6220 | gen9_enable_rps(dev); |
6150 | gen9_enable_rps(dev); |
6221 | if (IS_SKYLAKE(dev)) |
6151 | if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) |
6222 | __gen6_update_ring_freq(dev); |
6152 | __gen6_update_ring_freq(dev); |
6223 | } else if (IS_BROADWELL(dev)) { |
6153 | } else if (IS_BROADWELL(dev)) { |
6224 | gen8_enable_rps(dev); |
6154 | gen8_enable_rps(dev); |
6225 | __gen6_update_ring_freq(dev); |
6155 | __gen6_update_ring_freq(dev); |
6226 | } else { |
6156 | } else { |
Line 6809... | Line 6739... | ||
6809 | gen6_check_mch_setup(dev); |
6739 | gen6_check_mch_setup(dev); |
6810 | } |
6740 | } |
Line 6811... | Line 6741... | ||
6811 | 6741 | ||
6812 | static void vlv_init_display_clock_gating(struct drm_i915_private *dev_priv) |
6742 | static void vlv_init_display_clock_gating(struct drm_i915_private *dev_priv) |
6813 | { |
- | |
6814 | u32 val; |
- | |
6815 | - | ||
6816 | /* |
- | |
6817 | * On driver load, a pipe may be active and driving a DSI display. |
- | |
6818 | * Preserve DPOUNIT_CLOCK_GATE_DISABLE to avoid the pipe getting stuck |
- | |
6819 | * (and never recovering) in this case. intel_dsi_post_disable() will |
- | |
6820 | * clear it when we turn off the display. |
- | |
6821 | */ |
- | |
6822 | val = I915_READ(DSPCLK_GATE_D); |
- | |
6823 | val &= DPOUNIT_CLOCK_GATE_DISABLE; |
6743 | { |
6824 | val |= VRHUNIT_CLOCK_GATE_DISABLE; |
- | |
Line 6825... | Line 6744... | ||
6825 | I915_WRITE(DSPCLK_GATE_D, val); |
6744 | I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); |
6826 | 6745 | ||
6827 | /* |
6746 | /* |
6828 | * Disable trickle feed and enable pnd deadline calculation |
6747 | * Disable trickle feed and enable pnd deadline calculation |
Line 7089... | Line 7008... | ||
7089 | 7008 | ||
7090 | if (IS_BROXTON(dev)) |
7009 | if (IS_BROXTON(dev)) |
7091 | dev_priv->display.init_clock_gating = |
7010 | dev_priv->display.init_clock_gating = |
7092 | bxt_init_clock_gating; |
7011 | bxt_init_clock_gating; |
7093 | dev_priv->display.update_wm = skl_update_wm; |
- | |
7094 | dev_priv->display.update_sprite_wm = skl_update_sprite_wm; |
7012 | dev_priv->display.update_wm = skl_update_wm; |
7095 | } else if (HAS_PCH_SPLIT(dev)) { |
7013 | } else if (HAS_PCH_SPLIT(dev)) { |
Line 7096... | Line 7014... | ||
7096 | ilk_setup_wm_latency(dev); |
7014 | ilk_setup_wm_latency(dev); |
7097 | 7015 | ||
7098 | if ((IS_GEN5(dev) && dev_priv->wm.pri_latency[1] && |
7016 | if ((IS_GEN5(dev) && dev_priv->wm.pri_latency[1] && |
7099 | dev_priv->wm.spr_latency[1] && dev_priv->wm.cur_latency[1]) || |
7017 | dev_priv->wm.spr_latency[1] && dev_priv->wm.cur_latency[1]) || |
7100 | (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] && |
7018 | (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] && |
7101 | dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { |
7019 | dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { |
7102 | dev_priv->display.update_wm = ilk_update_wm; |
7020 | dev_priv->display.update_wm = ilk_update_wm; |
7103 | dev_priv->display.update_sprite_wm = ilk_update_sprite_wm; |
7021 | dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm; |
7104 | } else { |
7022 | } else { |
7105 | DRM_DEBUG_KMS("Failed to read display plane latency. " |
7023 | DRM_DEBUG_KMS("Failed to read display plane latency. " |
Line 7363... | Line 7281... | ||
7363 | INIT_LIST_HEAD(&dev_priv->rps.clients); |
7281 | INIT_LIST_HEAD(&dev_priv->rps.clients); |
7364 | INIT_LIST_HEAD(&dev_priv->rps.semaphores.link); |
7282 | INIT_LIST_HEAD(&dev_priv->rps.semaphores.link); |
7365 | INIT_LIST_HEAD(&dev_priv->rps.mmioflips.link); |
7283 | INIT_LIST_HEAD(&dev_priv->rps.mmioflips.link); |
Line 7366... | Line 7284... | ||
7366 | 7284 | ||
- | 7285 | dev_priv->pm.suspended = false; |
|
- | 7286 | atomic_set(&dev_priv->pm.wakeref_count, 0); |
|
7367 | dev_priv->pm.suspended = false; |
7287 | atomic_set(&dev_priv->pm.atomic_seq, 0); |