diff options
| -rw-r--r-- | drivers/gpu/drm/drm_dp_mst_topology.c | 19 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_atomic.c | 45 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 59 | ||||
| -rw-r--r-- | include/drm/drm_crtc.h | 2 |
4 files changed, 36 insertions, 89 deletions
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index b0487c9f018c..eb603f1defc2 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c | |||
| @@ -873,9 +873,10 @@ static void drm_dp_destroy_port(struct kref *kref) | |||
| 873 | from an EDID retrieval */ | 873 | from an EDID retrieval */ |
| 874 | if (port->connector) { | 874 | if (port->connector) { |
| 875 | mutex_lock(&mgr->destroy_connector_lock); | 875 | mutex_lock(&mgr->destroy_connector_lock); |
| 876 | list_add(&port->connector->destroy_list, &mgr->destroy_connector_list); | 876 | list_add(&port->next, &mgr->destroy_connector_list); |
| 877 | mutex_unlock(&mgr->destroy_connector_lock); | 877 | mutex_unlock(&mgr->destroy_connector_lock); |
| 878 | schedule_work(&mgr->destroy_connector_work); | 878 | schedule_work(&mgr->destroy_connector_work); |
| 879 | return; | ||
| 879 | } | 880 | } |
| 880 | drm_dp_port_teardown_pdt(port, port->pdt); | 881 | drm_dp_port_teardown_pdt(port, port->pdt); |
| 881 | 882 | ||
| @@ -2659,7 +2660,7 @@ static void drm_dp_tx_work(struct work_struct *work) | |||
| 2659 | static void drm_dp_destroy_connector_work(struct work_struct *work) | 2660 | static void drm_dp_destroy_connector_work(struct work_struct *work) |
| 2660 | { | 2661 | { |
| 2661 | struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, destroy_connector_work); | 2662 | struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, destroy_connector_work); |
| 2662 | struct drm_connector *connector; | 2663 | struct drm_dp_mst_port *port; |
| 2663 | 2664 | ||
| 2664 | /* | 2665 | /* |
| 2665 | * Not a regular list traverse as we have to drop the destroy | 2666 | * Not a regular list traverse as we have to drop the destroy |
| @@ -2668,15 +2669,21 @@ static void drm_dp_destroy_connector_work(struct work_struct *work) | |||
| 2668 | */ | 2669 | */ |
| 2669 | for (;;) { | 2670 | for (;;) { |
| 2670 | mutex_lock(&mgr->destroy_connector_lock); | 2671 | mutex_lock(&mgr->destroy_connector_lock); |
| 2671 | connector = list_first_entry_or_null(&mgr->destroy_connector_list, struct drm_connector, destroy_list); | 2672 | port = list_first_entry_or_null(&mgr->destroy_connector_list, struct drm_dp_mst_port, next); |
| 2672 | if (!connector) { | 2673 | if (!port) { |
| 2673 | mutex_unlock(&mgr->destroy_connector_lock); | 2674 | mutex_unlock(&mgr->destroy_connector_lock); |
| 2674 | break; | 2675 | break; |
| 2675 | } | 2676 | } |
| 2676 | list_del(&connector->destroy_list); | 2677 | list_del(&port->next); |
| 2677 | mutex_unlock(&mgr->destroy_connector_lock); | 2678 | mutex_unlock(&mgr->destroy_connector_lock); |
| 2678 | 2679 | ||
| 2679 | mgr->cbs->destroy_connector(mgr, connector); | 2680 | mgr->cbs->destroy_connector(mgr, port->connector); |
| 2681 | |||
| 2682 | drm_dp_port_teardown_pdt(port, port->pdt); | ||
| 2683 | |||
| 2684 | if (!port->input && port->vcpi.vcpi > 0) | ||
| 2685 | drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi); | ||
| 2686 | kfree(port); | ||
| 2680 | } | 2687 | } |
| 2681 | } | 2688 | } |
| 2682 | 2689 | ||
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 | ||
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 57ca8cc383a6..3b4d8a4a23fb 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
| @@ -743,8 +743,6 @@ struct drm_connector { | |||
| 743 | uint8_t num_h_tile, num_v_tile; | 743 | uint8_t num_h_tile, num_v_tile; |
| 744 | uint8_t tile_h_loc, tile_v_loc; | 744 | uint8_t tile_h_loc, tile_v_loc; |
| 745 | uint16_t tile_h_size, tile_v_size; | 745 | uint16_t tile_h_size, tile_v_size; |
| 746 | |||
| 747 | struct list_head destroy_list; | ||
| 748 | }; | 746 | }; |
| 749 | 747 | ||
| 750 | /** | 748 | /** |
