aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2015-06-15 06:33:51 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2015-06-22 08:27:20 -0400
commitd032ffa04cf7c6f7187e53125e860597bf64b11c (patch)
tree066a2a76c2e6995dad5c0d8bcde232bffacf3ddb /drivers/gpu/drm/i915/intel_display.c
parent61333b6075bf3b48a31fb5623a4101ed6bf393bc (diff)
drm/i915: Handle disabling planes better, v2.
Read out the initial state, and add a quirk to force add all planes to crtc_state->plane_mask during initial commit. This will disable all planes during the initial modeset. The initial plane quirk is temporary, and will go away when hardware readout is fully atomic, and the watermark updates in intel_sprite.c are removed. Changes since v1: - Unset state->visible on !primary planes. - Do not rely on the plane->crtc pointer in intel_atomic_plane, instead assume planes are invisible until modeset. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Tested-by(IVB): Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c120
1 files changed, 98 insertions, 22 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 57bc49039991..827c5a513f86 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -109,8 +109,6 @@ static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_cr
109 struct intel_crtc_state *crtc_state); 109 struct intel_crtc_state *crtc_state);
110static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state, 110static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
111 int num_connectors); 111 int num_connectors);
112static void intel_crtc_enable_planes(struct drm_crtc *crtc);
113static void intel_crtc_disable_planes(struct drm_crtc *crtc);
114 112
115static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe) 113static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
116{ 114{
@@ -4850,11 +4848,11 @@ static void intel_crtc_enable_planes(struct drm_crtc *crtc)
4850 intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_ALL_MASK(pipe)); 4848 intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_ALL_MASK(pipe));
4851} 4849}
4852 4850
4853static void intel_crtc_disable_planes(struct drm_crtc *crtc) 4851static void intel_crtc_disable_planes(struct drm_crtc *crtc, unsigned plane_mask)
4854{ 4852{
4855 struct drm_device *dev = crtc->dev; 4853 struct drm_device *dev = crtc->dev;
4856 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 4854 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
4857 struct intel_plane *intel_plane; 4855 struct drm_plane *p;
4858 int pipe = intel_crtc->pipe; 4856 int pipe = intel_crtc->pipe;
4859 4857
4860 intel_crtc_wait_for_pending_flips(crtc); 4858 intel_crtc_wait_for_pending_flips(crtc);
@@ -4862,14 +4860,9 @@ static void intel_crtc_disable_planes(struct drm_crtc *crtc)
4862 intel_pre_disable_primary(crtc); 4860 intel_pre_disable_primary(crtc);
4863 4861
4864 intel_crtc_dpms_overlay_disable(intel_crtc); 4862 intel_crtc_dpms_overlay_disable(intel_crtc);
4865 for_each_intel_plane(dev, intel_plane) {
4866 if (intel_plane->pipe == pipe) {
4867 struct drm_crtc *from = intel_plane->base.crtc;
4868 4863
4869 intel_plane->disable_plane(&intel_plane->base, 4864 drm_for_each_plane_mask(p, dev, plane_mask)
4870 from ?: crtc); 4865 to_intel_plane(p)->disable_plane(p, crtc);
4871 }
4872 }
4873 4866
4874 /* 4867 /*
4875 * FIXME: Once we grow proper nuclear flip support out of this we need 4868 * FIXME: Once we grow proper nuclear flip support out of this we need
@@ -6289,7 +6282,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
6289 if (!intel_crtc->active) 6282 if (!intel_crtc->active)
6290 return; 6283 return;
6291 6284
6292 intel_crtc_disable_planes(crtc); 6285 intel_crtc_disable_planes(crtc, crtc->state->plane_mask);
6293 dev_priv->display.crtc_disable(crtc); 6286 dev_priv->display.crtc_disable(crtc);
6294 6287
6295 domains = intel_crtc->enabled_power_domains; 6288 domains = intel_crtc->enabled_power_domains;
@@ -11885,7 +11878,7 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
11885 intel_crtc->atomic.fb_bits |= 11878 intel_crtc->atomic.fb_bits |=
11886 INTEL_FRONTBUFFER_SPRITE(intel_crtc->pipe); 11879 INTEL_FRONTBUFFER_SPRITE(intel_crtc->pipe);
11887 11880
11888 if (turn_off && is_crtc_enabled) { 11881 if (turn_off && !mode_changed) {
11889 intel_crtc->atomic.wait_vblank = true; 11882 intel_crtc->atomic.wait_vblank = true;
11890 intel_crtc->atomic.update_sprite_watermarks |= 11883 intel_crtc->atomic.update_sprite_watermarks |=
11891 1 << i; 11884 1 << i;
@@ -11945,6 +11938,34 @@ static bool check_encoder_cloning(struct drm_atomic_state *state,
11945 return true; 11938 return true;
11946} 11939}
11947 11940
11941static void intel_crtc_check_initial_planes(struct drm_crtc *crtc,
11942 struct drm_crtc_state *crtc_state)
11943{
11944 struct intel_crtc_state *pipe_config =
11945 to_intel_crtc_state(crtc_state);
11946 struct drm_plane *p;
11947 unsigned visible_mask = 0;
11948
11949 drm_for_each_plane_mask(p, crtc->dev, crtc_state->plane_mask) {
11950 struct drm_plane_state *plane_state =
11951 drm_atomic_get_existing_plane_state(crtc_state->state, p);
11952
11953 if (WARN_ON(!plane_state))
11954 continue;
11955
11956 if (!plane_state->fb)
11957 crtc_state->plane_mask &=
11958 ~(1 << drm_plane_index(p));
11959 else if (to_intel_plane_state(plane_state)->visible)
11960 visible_mask |= 1 << drm_plane_index(p);
11961 }
11962
11963 if (!visible_mask)
11964 return;
11965
11966 pipe_config->quirks &= ~PIPE_CONFIG_QUIRK_INITIAL_PLANES;
11967}
11968
11948static int intel_crtc_atomic_check(struct drm_crtc *crtc, 11969static int intel_crtc_atomic_check(struct drm_crtc *crtc,
11949 struct drm_crtc_state *crtc_state) 11970 struct drm_crtc_state *crtc_state)
11950{ 11971{
@@ -11966,6 +11987,10 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
11966 "[CRTC:%i] mismatch between state->active(%i) and crtc->active(%i)\n", 11987 "[CRTC:%i] mismatch between state->active(%i) and crtc->active(%i)\n",
11967 idx, crtc->state->active, intel_crtc->active); 11988 idx, crtc->state->active, intel_crtc->active);
11968 11989
11990 /* plane mask is fixed up after all initial planes are calculated */
11991 if (pipe_config->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES)
11992 intel_crtc_check_initial_planes(crtc, crtc_state);
11993
11969 if (mode_changed && crtc_state->enable && 11994 if (mode_changed && crtc_state->enable &&
11970 dev_priv->display.crtc_compute_clock && 11995 dev_priv->display.crtc_compute_clock &&
11971 !WARN_ON(pipe_config->shared_dpll != DPLL_ID_PRIVATE)) { 11996 !WARN_ON(pipe_config->shared_dpll != DPLL_ID_PRIVATE)) {
@@ -13182,6 +13207,20 @@ intel_modeset_compute_config(struct drm_atomic_state *state)
13182 continue; 13207 continue;
13183 } 13208 }
13184 13209
13210 if (to_intel_crtc_state(crtc_state)->quirks &
13211 PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
13212 ret = drm_atomic_add_affected_planes(state, crtc);
13213 if (ret)
13214 return ret;
13215
13216 /*
13217 * We ought to handle i915.fastboot here.
13218 * If no modeset is required and the primary plane has
13219 * a fb, update the members of crtc_state as needed,
13220 * and run the necessary updates during vblank evasion.
13221 */
13222 }
13223
13185 if (!needs_modeset(crtc_state)) { 13224 if (!needs_modeset(crtc_state)) {
13186 ret = drm_atomic_add_affected_connectors(state, crtc); 13225 ret = drm_atomic_add_affected_connectors(state, crtc);
13187 if (ret) 13226 if (ret)
@@ -13235,7 +13274,7 @@ static int __intel_set_mode(struct drm_atomic_state *state)
13235 if (!crtc_state->active) 13274 if (!crtc_state->active)
13236 continue; 13275 continue;
13237 13276
13238 intel_crtc_disable_planes(crtc); 13277 intel_crtc_disable_planes(crtc, crtc_state->plane_mask);
13239 dev_priv->display.crtc_disable(crtc); 13278 dev_priv->display.crtc_disable(crtc);
13240 } 13279 }
13241 13280
@@ -15403,10 +15442,51 @@ static bool primary_get_hw_state(struct intel_crtc *crtc)
15403{ 15442{
15404 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 15443 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
15405 15444
15406 if (!crtc->active) 15445 return !!(I915_READ(DSPCNTR(crtc->plane)) & DISPLAY_PLANE_ENABLE);
15407 return false; 15446}
15447
15448static void readout_plane_state(struct intel_crtc *crtc,
15449 struct intel_crtc_state *crtc_state)
15450{
15451 struct intel_plane *p;
15452 struct drm_plane_state *drm_plane_state;
15453 bool active = crtc_state->base.active;
15454
15455 if (active) {
15456 crtc_state->quirks |= PIPE_CONFIG_QUIRK_INITIAL_PLANES;
15457
15458 /* apply to previous sw state too */
15459 to_intel_crtc_state(crtc->base.state)->quirks |=
15460 PIPE_CONFIG_QUIRK_INITIAL_PLANES;
15461 }
15408 15462
15409 return I915_READ(DSPCNTR(crtc->plane)) & DISPLAY_PLANE_ENABLE; 15463 for_each_intel_plane(crtc->base.dev, p) {
15464 bool visible = active;
15465
15466 if (crtc->pipe != p->pipe)
15467 continue;
15468
15469 drm_plane_state = p->base.state;
15470 if (active && p->base.type == DRM_PLANE_TYPE_PRIMARY) {
15471 visible = primary_get_hw_state(crtc);
15472 to_intel_plane_state(drm_plane_state)->visible = visible;
15473 } else {
15474 /*
15475 * unknown state, assume it's off to force a transition
15476 * to on when calculating state changes.
15477 */
15478 to_intel_plane_state(drm_plane_state)->visible = false;
15479 }
15480
15481 if (visible) {
15482 crtc_state->base.plane_mask |=
15483 1 << drm_plane_index(&p->base);
15484 } else if (crtc_state->base.state) {
15485 /* Make this unconditional for atomic hw readout. */
15486 crtc_state->base.plane_mask &=
15487 ~(1 << drm_plane_index(&p->base));
15488 }
15489 }
15410} 15490}
15411 15491
15412static void intel_modeset_readout_hw_state(struct drm_device *dev) 15492static void intel_modeset_readout_hw_state(struct drm_device *dev)
@@ -15419,9 +15499,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
15419 int i; 15499 int i;
15420 15500
15421 for_each_intel_crtc(dev, crtc) { 15501 for_each_intel_crtc(dev, crtc) {
15422 struct drm_plane *primary = crtc->base.primary;
15423 struct intel_plane_state *plane_state;
15424
15425 memset(crtc->config, 0, sizeof(*crtc->config)); 15502 memset(crtc->config, 0, sizeof(*crtc->config));
15426 crtc->config->base.crtc = &crtc->base; 15503 crtc->config->base.crtc = &crtc->base;
15427 15504
@@ -15435,8 +15512,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
15435 crtc->base.enabled = crtc->active; 15512 crtc->base.enabled = crtc->active;
15436 crtc->base.hwmode = crtc->config->base.adjusted_mode; 15513 crtc->base.hwmode = crtc->config->base.adjusted_mode;
15437 15514
15438 plane_state = to_intel_plane_state(primary->state); 15515 readout_plane_state(crtc, to_intel_crtc_state(crtc->base.state));
15439 plane_state->visible = primary_get_hw_state(crtc);
15440 15516
15441 DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n", 15517 DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
15442 crtc->base.base.id, 15518 crtc->base.base.id,