diff options
author | Dave Airlie <airlied@gmail.com> | 2015-08-15 00:51:31 -0400 |
---|---|---|
committer | Dave Airlie <airlied@gmail.com> | 2015-08-15 00:51:31 -0400 |
commit | 3acceca904b7f0b860cb21942dea24fac459b700 (patch) | |
tree | 48fda135d3d160db46dfa696449f74e9a688d3fa | |
parent | 45e38cff4fce8d6871b5fa5e734e4dc9814d6056 (diff) | |
parent | d2944cf21305c754fa8b2d6c1eea05ad5dad7944 (diff) |
Merge tag 'drm-intel-fixes-2015-08-14' of git://anongit.freedesktop.org/drm-intel into drm-next
three display fixes for Intel.
* tag 'drm-intel-fixes-2015-08-14' of git://anongit.freedesktop.org/drm-intel:
drm/i915: Commit planes on each crtc separately.
drm/i915: calculate primary visibility changes instead of calling from set_config
drm/i915: Only dither on 6bpc panels
-rw-r--r-- | drivers/gpu/drm/i915/intel_atomic.c | 45 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 59 |
2 files changed, 23 insertions, 81 deletions
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 7ed8033aae60..8e35e0d013df 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c | |||
@@ -129,8 +129,9 @@ int intel_atomic_commit(struct drm_device *dev, | |||
129 | struct drm_atomic_state *state, | 129 | struct drm_atomic_state *state, |
130 | bool async) | 130 | bool async) |
131 | { | 131 | { |
132 | int ret; | 132 | struct drm_crtc_state *crtc_state; |
133 | int i; | 133 | struct drm_crtc *crtc; |
134 | int ret, i; | ||
134 | 135 | ||
135 | if (async) { | 136 | if (async) { |
136 | DRM_DEBUG_KMS("i915 does not yet support async commit\n"); | 137 | DRM_DEBUG_KMS("i915 does not yet support async commit\n"); |
@@ -142,48 +143,18 @@ int intel_atomic_commit(struct drm_device *dev, | |||
142 | return ret; | 143 | return ret; |
143 | 144 | ||
144 | /* Point of no return */ | 145 | /* Point of no return */ |
145 | 146 | drm_atomic_helper_swap_state(dev, state); | |
146 | /* | ||
147 | * FIXME: The proper sequence here will eventually be: | ||
148 | * | ||
149 | * drm_atomic_helper_swap_state(dev, state) | ||
150 | * drm_atomic_helper_commit_modeset_disables(dev, state); | ||
151 | * drm_atomic_helper_commit_planes(dev, state); | ||
152 | * drm_atomic_helper_commit_modeset_enables(dev, state); | ||
153 | * drm_atomic_helper_wait_for_vblanks(dev, state); | ||
154 | * drm_atomic_helper_cleanup_planes(dev, state); | ||
155 | * drm_atomic_state_free(state); | ||
156 | * | ||
157 | * once we have full atomic modeset. For now, just manually update | ||
158 | * plane states to avoid clobbering good states with dummy states | ||
159 | * while nuclear pageflipping. | ||
160 | */ | ||
161 | for (i = 0; i < dev->mode_config.num_total_plane; i++) { | ||
162 | struct drm_plane *plane = state->planes[i]; | ||
163 | |||
164 | if (!plane) | ||
165 | continue; | ||
166 | |||
167 | plane->state->state = state; | ||
168 | swap(state->plane_states[i], plane->state); | ||
169 | plane->state->state = NULL; | ||
170 | } | ||
171 | 147 | ||
172 | /* swap crtc_scaler_state */ | 148 | /* swap crtc_scaler_state */ |
173 | for (i = 0; i < dev->mode_config.num_crtc; i++) { | 149 | for_each_crtc_in_state(state, crtc, crtc_state, i) { |
174 | struct drm_crtc *crtc = state->crtcs[i]; | 150 | to_intel_crtc(crtc)->config = to_intel_crtc_state(crtc->state); |
175 | if (!crtc) { | ||
176 | continue; | ||
177 | } | ||
178 | |||
179 | to_intel_crtc(crtc)->config->scaler_state = | ||
180 | to_intel_crtc_state(state->crtc_states[i])->scaler_state; | ||
181 | 151 | ||
182 | if (INTEL_INFO(dev)->gen >= 9) | 152 | if (INTEL_INFO(dev)->gen >= 9) |
183 | skl_detach_scalers(to_intel_crtc(crtc)); | 153 | skl_detach_scalers(to_intel_crtc(crtc)); |
154 | |||
155 | drm_atomic_helper_commit_planes_on_crtc(crtc_state); | ||
184 | } | 156 | } |
185 | 157 | ||
186 | drm_atomic_helper_commit_planes(dev, state); | ||
187 | drm_atomic_helper_wait_for_vblanks(dev, state); | 158 | drm_atomic_helper_wait_for_vblanks(dev, state); |
188 | drm_atomic_helper_cleanup_planes(dev, state); | 159 | drm_atomic_helper_cleanup_planes(dev, state); |
189 | drm_atomic_state_free(state); | 160 | drm_atomic_state_free(state); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 30e0f54ba19d..87476ff181dd 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -11826,7 +11826,9 @@ encoder_retry: | |||
11826 | goto encoder_retry; | 11826 | goto encoder_retry; |
11827 | } | 11827 | } |
11828 | 11828 | ||
11829 | pipe_config->dither = pipe_config->pipe_bpp != base_bpp; | 11829 | /* Dithering seems to not pass-through bits correctly when it should, so |
11830 | * only enable it on 6bpc panels. */ | ||
11831 | pipe_config->dither = pipe_config->pipe_bpp == 6*3; | ||
11830 | DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n", | 11832 | DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n", |
11831 | base_bpp, pipe_config->pipe_bpp, pipe_config->dither); | 11833 | base_bpp, pipe_config->pipe_bpp, pipe_config->dither); |
11832 | 11834 | ||
@@ -12624,17 +12626,17 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc, | |||
12624 | 12626 | ||
12625 | modeset_update_crtc_power_domains(state); | 12627 | modeset_update_crtc_power_domains(state); |
12626 | 12628 | ||
12627 | drm_atomic_helper_commit_planes(dev, state); | ||
12628 | |||
12629 | /* Now enable the clocks, plane, pipe, and connectors that we set up. */ | 12629 | /* Now enable the clocks, plane, pipe, and connectors that we set up. */ |
12630 | for_each_crtc_in_state(state, crtc, crtc_state, i) { | 12630 | for_each_crtc_in_state(state, crtc, crtc_state, i) { |
12631 | if (!needs_modeset(crtc->state) || !crtc->state->enable) | 12631 | if (!needs_modeset(crtc->state) || !crtc->state->enable) { |
12632 | drm_atomic_helper_commit_planes_on_crtc(crtc_state); | ||
12632 | continue; | 12633 | continue; |
12634 | } | ||
12633 | 12635 | ||
12634 | update_scanline_offset(to_intel_crtc(crtc)); | 12636 | update_scanline_offset(to_intel_crtc(crtc)); |
12635 | 12637 | ||
12636 | dev_priv->display.crtc_enable(crtc); | 12638 | dev_priv->display.crtc_enable(crtc); |
12637 | intel_crtc_enable_planes(crtc); | 12639 | drm_atomic_helper_commit_planes_on_crtc(crtc_state); |
12638 | } | 12640 | } |
12639 | 12641 | ||
12640 | /* FIXME: add subpixel order */ | 12642 | /* FIXME: add subpixel order */ |
@@ -12891,20 +12893,11 @@ intel_modeset_stage_output_state(struct drm_device *dev, | |||
12891 | return 0; | 12893 | return 0; |
12892 | } | 12894 | } |
12893 | 12895 | ||
12894 | static bool primary_plane_visible(struct drm_crtc *crtc) | ||
12895 | { | ||
12896 | struct intel_plane_state *plane_state = | ||
12897 | to_intel_plane_state(crtc->primary->state); | ||
12898 | |||
12899 | return plane_state->visible; | ||
12900 | } | ||
12901 | |||
12902 | static int intel_crtc_set_config(struct drm_mode_set *set) | 12896 | static int intel_crtc_set_config(struct drm_mode_set *set) |
12903 | { | 12897 | { |
12904 | struct drm_device *dev; | 12898 | struct drm_device *dev; |
12905 | struct drm_atomic_state *state = NULL; | 12899 | struct drm_atomic_state *state = NULL; |
12906 | struct intel_crtc_state *pipe_config; | 12900 | struct intel_crtc_state *pipe_config; |
12907 | bool primary_plane_was_visible; | ||
12908 | int ret; | 12901 | int ret; |
12909 | 12902 | ||
12910 | BUG_ON(!set); | 12903 | BUG_ON(!set); |
@@ -12943,38 +12936,8 @@ static int intel_crtc_set_config(struct drm_mode_set *set) | |||
12943 | 12936 | ||
12944 | intel_update_pipe_size(to_intel_crtc(set->crtc)); | 12937 | intel_update_pipe_size(to_intel_crtc(set->crtc)); |
12945 | 12938 | ||
12946 | primary_plane_was_visible = primary_plane_visible(set->crtc); | ||
12947 | |||
12948 | ret = intel_set_mode_with_config(set->crtc, pipe_config, true); | 12939 | ret = intel_set_mode_with_config(set->crtc, pipe_config, true); |
12949 | 12940 | ||
12950 | if (ret == 0 && | ||
12951 | pipe_config->base.enable && | ||
12952 | pipe_config->base.planes_changed && | ||
12953 | !needs_modeset(&pipe_config->base)) { | ||
12954 | struct intel_crtc *intel_crtc = to_intel_crtc(set->crtc); | ||
12955 | |||
12956 | /* | ||
12957 | * We need to make sure the primary plane is re-enabled if it | ||
12958 | * has previously been turned off. | ||
12959 | */ | ||
12960 | if (ret == 0 && !primary_plane_was_visible && | ||
12961 | primary_plane_visible(set->crtc)) { | ||
12962 | WARN_ON(!intel_crtc->active); | ||
12963 | intel_post_enable_primary(set->crtc); | ||
12964 | } | ||
12965 | |||
12966 | /* | ||
12967 | * In the fastboot case this may be our only check of the | ||
12968 | * state after boot. It would be better to only do it on | ||
12969 | * the first update, but we don't have a nice way of doing that | ||
12970 | * (and really, set_config isn't used much for high freq page | ||
12971 | * flipping, so increasing its cost here shouldn't be a big | ||
12972 | * deal). | ||
12973 | */ | ||
12974 | if (i915.fastboot && ret == 0) | ||
12975 | intel_modeset_check_state(set->crtc->dev); | ||
12976 | } | ||
12977 | |||
12978 | if (ret) { | 12941 | if (ret) { |
12979 | DRM_DEBUG_KMS("failed to set mode on [CRTC:%d], err = %d\n", | 12942 | DRM_DEBUG_KMS("failed to set mode on [CRTC:%d], err = %d\n", |
12980 | set->crtc->base.id, ret); | 12943 | set->crtc->base.id, ret); |
@@ -13305,6 +13268,9 @@ intel_check_primary_plane(struct drm_plane *plane, | |||
13305 | */ | 13268 | */ |
13306 | if (IS_BROADWELL(dev)) | 13269 | if (IS_BROADWELL(dev)) |
13307 | intel_crtc->atomic.wait_vblank = true; | 13270 | intel_crtc->atomic.wait_vblank = true; |
13271 | |||
13272 | if (crtc_state) | ||
13273 | intel_crtc->atomic.post_enable_primary = true; | ||
13308 | } | 13274 | } |
13309 | 13275 | ||
13310 | /* | 13276 | /* |
@@ -13317,6 +13283,10 @@ intel_check_primary_plane(struct drm_plane *plane, | |||
13317 | if (!state->visible || !fb) | 13283 | if (!state->visible || !fb) |
13318 | intel_crtc->atomic.disable_ips = true; | 13284 | intel_crtc->atomic.disable_ips = true; |
13319 | 13285 | ||
13286 | if (!state->visible && old_state->visible && | ||
13287 | crtc_state && !needs_modeset(&crtc_state->base)) | ||
13288 | intel_crtc->atomic.pre_disable_primary = true; | ||
13289 | |||
13320 | intel_crtc->atomic.fb_bits |= | 13290 | intel_crtc->atomic.fb_bits |= |
13321 | INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe); | 13291 | INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe); |
13322 | 13292 | ||
@@ -15034,6 +15004,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) | |||
15034 | struct intel_plane_state *plane_state; | 15004 | struct intel_plane_state *plane_state; |
15035 | 15005 | ||
15036 | memset(crtc->config, 0, sizeof(*crtc->config)); | 15006 | memset(crtc->config, 0, sizeof(*crtc->config)); |
15007 | crtc->config->base.crtc = &crtc->base; | ||
15037 | 15008 | ||
15038 | crtc->config->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE; | 15009 | crtc->config->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE; |
15039 | 15010 | ||