diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2014-03-07 11:32:09 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-04-09 08:42:03 -0400 |
commit | 2a44b76bb5a1f520371432825c91fa46c63bde84 (patch) | |
tree | 75fa476cca0faf03cd4264c4ff77fc3b2bcd5639 | |
parent | 17d36749a559905f7d9a640239a9fc74fc3bb445 (diff) |
drm/i915: Add some more tracked state to intel_pipe_wm
intel_pipe_wm will be used to track the state in different stages
of the watermark update process. For that we need to keep a bit
more state in intel_pipe_wm.
We also need to separate the multi-pipe intel_wm_config computation
from ilk_compute_wm_parameters() as that one deals with the future
state, and we need the intel_wm_config to match the current hardware
state at the time we do the watermark merging for multiple pipes.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
[danvet: Frob conflict.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 64 |
2 files changed, 46 insertions, 21 deletions
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 42762b798cb0..6b512607b2f5 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -342,6 +342,9 @@ struct intel_pipe_wm { | |||
342 | struct intel_wm_level wm[5]; | 342 | struct intel_wm_level wm[5]; |
343 | uint32_t linetime; | 343 | uint32_t linetime; |
344 | bool fbc_wm_enabled; | 344 | bool fbc_wm_enabled; |
345 | bool pipe_enabled; | ||
346 | bool sprites_enabled; | ||
347 | bool sprites_scaled; | ||
345 | }; | 348 | }; |
346 | 349 | ||
347 | struct intel_crtc { | 350 | struct intel_crtc { |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 2091a9ce1375..855c01b2b0c1 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -2105,38 +2105,52 @@ static void ilk_setup_wm_latency(struct drm_device *dev) | |||
2105 | } | 2105 | } |
2106 | 2106 | ||
2107 | static void ilk_compute_wm_parameters(struct drm_crtc *crtc, | 2107 | static void ilk_compute_wm_parameters(struct drm_crtc *crtc, |
2108 | struct ilk_pipe_wm_parameters *p, | 2108 | struct ilk_pipe_wm_parameters *p) |
2109 | struct intel_wm_config *config) | ||
2110 | { | 2109 | { |
2111 | struct drm_device *dev = crtc->dev; | 2110 | struct drm_device *dev = crtc->dev; |
2112 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 2111 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2113 | enum pipe pipe = intel_crtc->pipe; | 2112 | enum pipe pipe = intel_crtc->pipe; |
2114 | struct drm_plane *plane; | 2113 | struct drm_plane *plane; |
2115 | 2114 | ||
2116 | p->active = intel_crtc_active(crtc); | 2115 | if (!intel_crtc_active(crtc)) |
2117 | if (p->active) { | 2116 | return; |
2118 | p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal; | ||
2119 | p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc); | ||
2120 | p->pri.bytes_per_pixel = crtc->primary->fb->bits_per_pixel / 8; | ||
2121 | p->cur.bytes_per_pixel = 4; | ||
2122 | p->pri.horiz_pixels = intel_crtc->config.pipe_src_w; | ||
2123 | p->cur.horiz_pixels = intel_crtc->cursor_width; | ||
2124 | /* TODO: for now, assume primary and cursor planes are always enabled. */ | ||
2125 | p->pri.enabled = true; | ||
2126 | p->cur.enabled = true; | ||
2127 | } | ||
2128 | 2117 | ||
2129 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | 2118 | p->active = true; |
2130 | config->num_pipes_active += intel_crtc_active(crtc); | 2119 | p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal; |
2120 | p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc); | ||
2121 | p->pri.bytes_per_pixel = crtc->primary->fb->bits_per_pixel / 8; | ||
2122 | p->cur.bytes_per_pixel = 4; | ||
2123 | p->pri.horiz_pixels = intel_crtc->config.pipe_src_w; | ||
2124 | p->cur.horiz_pixels = intel_crtc->cursor_width; | ||
2125 | /* TODO: for now, assume primary and cursor planes are always enabled. */ | ||
2126 | p->pri.enabled = true; | ||
2127 | p->cur.enabled = true; | ||
2131 | 2128 | ||
2132 | drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { | 2129 | drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { |
2133 | struct intel_plane *intel_plane = to_intel_plane(plane); | 2130 | struct intel_plane *intel_plane = to_intel_plane(plane); |
2134 | 2131 | ||
2135 | if (intel_plane->pipe == pipe) | 2132 | if (intel_plane->pipe == pipe) { |
2136 | p->spr = intel_plane->wm; | 2133 | p->spr = intel_plane->wm; |
2134 | break; | ||
2135 | } | ||
2136 | } | ||
2137 | } | ||
2137 | 2138 | ||
2138 | config->sprites_enabled |= intel_plane->wm.enabled; | 2139 | static void ilk_compute_wm_config(struct drm_device *dev, |
2139 | config->sprites_scaled |= intel_plane->wm.scaled; | 2140 | struct intel_wm_config *config) |
2141 | { | ||
2142 | struct intel_crtc *intel_crtc; | ||
2143 | |||
2144 | /* Compute the currently _active_ config */ | ||
2145 | list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head) { | ||
2146 | const struct intel_pipe_wm *wm = &intel_crtc->wm.active; | ||
2147 | |||
2148 | if (!wm->pipe_enabled) | ||
2149 | continue; | ||
2150 | |||
2151 | config->sprites_enabled |= wm->sprites_enabled; | ||
2152 | config->sprites_scaled |= wm->sprites_scaled; | ||
2153 | config->num_pipes_active++; | ||
2140 | } | 2154 | } |
2141 | } | 2155 | } |
2142 | 2156 | ||
@@ -2159,6 +2173,10 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc, | |||
2159 | /* LP0 watermarks always use 1/2 DDB partitioning */ | 2173 | /* LP0 watermarks always use 1/2 DDB partitioning */ |
2160 | ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max); | 2174 | ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max); |
2161 | 2175 | ||
2176 | pipe_wm->pipe_enabled = params->active; | ||
2177 | pipe_wm->sprites_enabled = params->spr.enabled; | ||
2178 | pipe_wm->sprites_scaled = params->spr.scaled; | ||
2179 | |||
2162 | /* ILK/SNB: LP2+ watermarks only w/o sprites */ | 2180 | /* ILK/SNB: LP2+ watermarks only w/o sprites */ |
2163 | if (INTEL_INFO(dev)->gen <= 6 && params->spr.enabled) | 2181 | if (INTEL_INFO(dev)->gen <= 6 && params->spr.enabled) |
2164 | max_level = 1; | 2182 | max_level = 1; |
@@ -2548,7 +2566,7 @@ static void ilk_update_wm(struct drm_crtc *crtc) | |||
2548 | struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; | 2566 | struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; |
2549 | struct intel_wm_config config = {}; | 2567 | struct intel_wm_config config = {}; |
2550 | 2568 | ||
2551 | ilk_compute_wm_parameters(crtc, ¶ms, &config); | 2569 | ilk_compute_wm_parameters(crtc, ¶ms); |
2552 | 2570 | ||
2553 | intel_compute_pipe_wm(crtc, ¶ms, &pipe_wm); | 2571 | intel_compute_pipe_wm(crtc, ¶ms, &pipe_wm); |
2554 | 2572 | ||
@@ -2557,6 +2575,8 @@ static void ilk_update_wm(struct drm_crtc *crtc) | |||
2557 | 2575 | ||
2558 | intel_crtc->wm.active = pipe_wm; | 2576 | intel_crtc->wm.active = pipe_wm; |
2559 | 2577 | ||
2578 | ilk_compute_wm_config(dev, &config); | ||
2579 | |||
2560 | ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_1_2, &max); | 2580 | ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_1_2, &max); |
2561 | ilk_wm_merge(dev, &config, &max, &lp_wm_1_2); | 2581 | ilk_wm_merge(dev, &config, &max, &lp_wm_1_2); |
2562 | 2582 | ||
@@ -2623,7 +2643,9 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc) | |||
2623 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) | 2643 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
2624 | hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe)); | 2644 | hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe)); |
2625 | 2645 | ||
2626 | if (intel_crtc_active(crtc)) { | 2646 | active->pipe_enabled = intel_crtc_active(crtc); |
2647 | |||
2648 | if (active->pipe_enabled) { | ||
2627 | u32 tmp = hw->wm_pipe[pipe]; | 2649 | u32 tmp = hw->wm_pipe[pipe]; |
2628 | 2650 | ||
2629 | /* | 2651 | /* |