aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c174
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h16
2 files changed, 146 insertions, 44 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a2ce117aa794..5031e0c4a02e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6619,6 +6619,51 @@ intel_crtc_prepare_encoders(struct drm_device *dev)
6619 } 6619 }
6620} 6620}
6621 6621
6622/**
6623 * intel_modeset_update_staged_output_state
6624 *
6625 * Updates the staged output configuration state, e.g. after we've read out the
6626 * current hw state.
6627 */
6628static void intel_modeset_update_staged_output_state(struct drm_device *dev)
6629{
6630 struct intel_encoder *encoder;
6631 struct intel_connector *connector;
6632
6633 list_for_each_entry(connector, &dev->mode_config.connector_list,
6634 base.head) {
6635 connector->new_encoder =
6636 to_intel_encoder(connector->base.encoder);
6637 }
6638
6639 list_for_each_entry(encoder, &dev->mode_config.encoder_list,
6640 base.head) {
6641 encoder->new_crtc =
6642 to_intel_crtc(encoder->base.crtc);
6643 }
6644}
6645
6646/**
6647 * intel_modeset_commit_output_state
6648 *
6649 * This function copies the stage display pipe configuration to the real one.
6650 */
6651static void intel_modeset_commit_output_state(struct drm_device *dev)
6652{
6653 struct intel_encoder *encoder;
6654 struct intel_connector *connector;
6655
6656 list_for_each_entry(connector, &dev->mode_config.connector_list,
6657 base.head) {
6658 connector->base.encoder = &connector->new_encoder->base;
6659 }
6660
6661 list_for_each_entry(encoder, &dev->mode_config.encoder_list,
6662 base.head) {
6663 encoder->base.crtc = &encoder->new_crtc->base;
6664 }
6665}
6666
6622bool intel_set_mode(struct drm_crtc *crtc, 6667bool intel_set_mode(struct drm_crtc *crtc,
6623 struct drm_display_mode *mode, 6668 struct drm_display_mode *mode,
6624 int x, int y, struct drm_framebuffer *old_fb) 6669 int x, int y, struct drm_framebuffer *old_fb)
@@ -6785,8 +6830,8 @@ static void intel_set_config_restore_state(struct drm_device *dev,
6785 struct intel_set_config *config) 6830 struct intel_set_config *config)
6786{ 6831{
6787 struct drm_crtc *crtc; 6832 struct drm_crtc *crtc;
6788 struct drm_encoder *encoder; 6833 struct intel_encoder *encoder;
6789 struct drm_connector *connector; 6834 struct intel_connector *connector;
6790 int count; 6835 int count;
6791 6836
6792 count = 0; 6837 count = 0;
@@ -6795,13 +6840,15 @@ static void intel_set_config_restore_state(struct drm_device *dev,
6795 } 6840 }
6796 6841
6797 count = 0; 6842 count = 0;
6798 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 6843 list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) {
6799 encoder->crtc = config->save_encoder_crtcs[count++]; 6844 encoder->new_crtc =
6845 to_intel_crtc(config->save_encoder_crtcs[count++]);
6800 } 6846 }
6801 6847
6802 count = 0; 6848 count = 0;
6803 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 6849 list_for_each_entry(connector, &dev->mode_config.connector_list, base.head) {
6804 connector->encoder = config->save_connector_encoders[count++]; 6850 connector->new_encoder =
6851 to_intel_encoder(config->save_connector_encoders[count++]);
6805 } 6852 }
6806} 6853}
6807 6854
@@ -6840,73 +6887,106 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set,
6840} 6887}
6841 6888
6842static int 6889static int
6843intel_set_config_update_output_state(struct drm_device *dev, 6890intel_modeset_stage_output_state(struct drm_device *dev,
6844 struct drm_mode_set *set, 6891 struct drm_mode_set *set,
6845 struct intel_set_config *config) 6892 struct intel_set_config *config)
6846{ 6893{
6847 struct drm_crtc *new_crtc; 6894 struct drm_crtc *new_crtc;
6848 struct drm_encoder *new_encoder; 6895 struct intel_connector *connector;
6849 struct drm_connector *connector; 6896 struct intel_encoder *encoder;
6850 int count, ro; 6897 int count, ro;
6851 6898
6852 /* a) traverse passed in connector list and get encoders for them */ 6899 /* The upper layers ensure that we either disabl a crtc or have a list
6900 * of connectors. For paranoia, double-check this. */
6901 WARN_ON(!set->fb && (set->num_connectors != 0));
6902 WARN_ON(set->fb && (set->num_connectors == 0));
6903
6853 count = 0; 6904 count = 0;
6854 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 6905 list_for_each_entry(connector, &dev->mode_config.connector_list,
6855 new_encoder = connector->encoder; 6906 base.head) {
6907 /* Otherwise traverse passed in connector list and get encoders
6908 * for them. */
6856 for (ro = 0; ro < set->num_connectors; ro++) { 6909 for (ro = 0; ro < set->num_connectors; ro++) {
6857 if (set->connectors[ro] == connector) { 6910 if (set->connectors[ro] == &connector->base) {
6858 new_encoder = 6911 connector->new_encoder = connector->encoder;
6859 &intel_attached_encoder(connector)->base;
6860 break; 6912 break;
6861 } 6913 }
6862 } 6914 }
6863 6915
6864 if (new_encoder != connector->encoder) { 6916 /* If we disable the crtc, disable all its connectors. Also, if
6917 * the connector is on the changing crtc but not on the new
6918 * connector list, disable it. */
6919 if ((!set->fb || ro == set->num_connectors) &&
6920 connector->base.encoder &&
6921 connector->base.encoder->crtc == set->crtc) {
6922 connector->new_encoder = NULL;
6923
6924 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
6925 connector->base.base.id,
6926 drm_get_connector_name(&connector->base));
6927 }
6928
6929
6930 if (&connector->new_encoder->base != connector->base.encoder) {
6865 DRM_DEBUG_KMS("encoder changed, full mode switch\n"); 6931 DRM_DEBUG_KMS("encoder changed, full mode switch\n");
6866 config->mode_changed = true; 6932 config->mode_changed = true;
6867 /* If the encoder is reused for another connector, then
6868 * the appropriate crtc will be set later.
6869 */
6870 if (connector->encoder)
6871 connector->encoder->crtc = NULL;
6872 connector->encoder = new_encoder;
6873 } 6933 }
6934
6935 /* Disable all disconnected encoders. */
6936 if (connector->base.status == connector_status_disconnected)
6937 connector->new_encoder = NULL;
6874 } 6938 }
6939 /* connector->new_encoder is now updated for all connectors. */
6875 6940
6941 /* Update crtc of enabled connectors. */
6876 count = 0; 6942 count = 0;
6877 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 6943 list_for_each_entry(connector, &dev->mode_config.connector_list,
6878 if (!connector->encoder) 6944 base.head) {
6945 if (!connector->new_encoder)
6879 continue; 6946 continue;
6880 6947
6881 if (connector->encoder->crtc == set->crtc) 6948 new_crtc = connector->new_encoder->base.crtc;
6882 new_crtc = NULL;
6883 else
6884 new_crtc = connector->encoder->crtc;
6885 6949
6886 for (ro = 0; ro < set->num_connectors; ro++) { 6950 for (ro = 0; ro < set->num_connectors; ro++) {
6887 if (set->connectors[ro] == connector) 6951 if (set->connectors[ro] == &connector->base)
6888 new_crtc = set->crtc; 6952 new_crtc = set->crtc;
6889 } 6953 }
6890 6954
6891 /* Make sure the new CRTC will work with the encoder */ 6955 /* Make sure the new CRTC will work with the encoder */
6892 if (new_crtc && 6956 if (!intel_encoder_crtc_ok(&connector->new_encoder->base,
6893 !intel_encoder_crtc_ok(connector->encoder, new_crtc)) { 6957 new_crtc)) {
6894 return -EINVAL; 6958 return -EINVAL;
6895 } 6959 }
6896 if (new_crtc != connector->encoder->crtc) { 6960 connector->encoder->new_crtc = to_intel_crtc(new_crtc);
6961
6962 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
6963 connector->base.base.id,
6964 drm_get_connector_name(&connector->base),
6965 new_crtc->base.id);
6966 }
6967
6968 /* Check for any encoders that needs to be disabled. */
6969 list_for_each_entry(encoder, &dev->mode_config.encoder_list,
6970 base.head) {
6971 list_for_each_entry(connector,
6972 &dev->mode_config.connector_list,
6973 base.head) {
6974 if (connector->new_encoder == encoder) {
6975 WARN_ON(!connector->new_encoder->new_crtc);
6976
6977 goto next_encoder;
6978 }
6979 }
6980 encoder->new_crtc = NULL;
6981next_encoder:
6982 /* Only now check for crtc changes so we don't miss encoders
6983 * that will be disabled. */
6984 if (&encoder->new_crtc->base != encoder->base.crtc) {
6897 DRM_DEBUG_KMS("crtc changed, full mode switch\n"); 6985 DRM_DEBUG_KMS("crtc changed, full mode switch\n");
6898 config->mode_changed = true; 6986 config->mode_changed = true;
6899 connector->encoder->crtc = new_crtc;
6900 }
6901 if (new_crtc) {
6902 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
6903 connector->base.id, drm_get_connector_name(connector),
6904 new_crtc->base.id);
6905 } else {
6906 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
6907 connector->base.id, drm_get_connector_name(connector));
6908 } 6987 }
6909 } 6988 }
6989 /* Now we've also updated encoder->new_crtc for all encoders. */
6910 6990
6911 return 0; 6991 return 0;
6912} 6992}
@@ -6965,11 +7045,13 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
6965 * such cases. */ 7045 * such cases. */
6966 intel_set_config_compute_mode_changes(set, config); 7046 intel_set_config_compute_mode_changes(set, config);
6967 7047
6968 ret = intel_set_config_update_output_state(dev, set, config); 7048 ret = intel_modeset_stage_output_state(dev, set, config);
6969 if (ret) 7049 if (ret)
6970 goto fail; 7050 goto fail;
6971 7051
6972 if (config->mode_changed) { 7052 if (config->mode_changed) {
7053 intel_modeset_commit_output_state(dev);
7054
6973 set->crtc->enabled = drm_helper_crtc_in_use(set->crtc); 7055 set->crtc->enabled = drm_helper_crtc_in_use(set->crtc);
6974 if (set->crtc->enabled) { 7056 if (set->crtc->enabled) {
6975 DRM_DEBUG_KMS("attempting to set mode from" 7057 DRM_DEBUG_KMS("attempting to set mode from"
@@ -7015,6 +7097,8 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
7015fail: 7097fail:
7016 intel_set_config_restore_state(dev, config); 7098 intel_set_config_restore_state(dev, config);
7017 7099
7100 intel_modeset_commit_output_state(dev);
7101
7018 /* Try to restore the config */ 7102 /* Try to restore the config */
7019 if (config->mode_changed && 7103 if (config->mode_changed &&
7020 !intel_set_mode(save_set.crtc, save_set.mode, 7104 !intel_set_mode(save_set.crtc, save_set.mode,
@@ -7888,6 +7972,8 @@ void intel_modeset_setup_hw_state(struct drm_device *dev)
7888 crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); 7972 crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
7889 intel_sanitize_crtc(crtc); 7973 intel_sanitize_crtc(crtc);
7890 } 7974 }
7975
7976 intel_modeset_update_staged_output_state(dev);
7891} 7977}
7892 7978
7893void intel_modeset_gem_init(struct drm_device *dev) 7979void intel_modeset_gem_init(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4946282bd324..ae807afc5fbf 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -133,6 +133,12 @@ struct intel_fbdev {
133 133
134struct intel_encoder { 134struct intel_encoder {
135 struct drm_encoder base; 135 struct drm_encoder base;
136 /*
137 * The new crtc this encoder will be driven from. Only differs from
138 * base->crtc while a modeset is in progress.
139 */
140 struct intel_crtc *new_crtc;
141
136 int type; 142 int type;
137 bool needs_tv_clock; 143 bool needs_tv_clock;
138 /* 144 /*
@@ -153,7 +159,17 @@ struct intel_encoder {
153 159
154struct intel_connector { 160struct intel_connector {
155 struct drm_connector base; 161 struct drm_connector base;
162 /*
163 * The fixed encoder this connector is connected to.
164 */
156 struct intel_encoder *encoder; 165 struct intel_encoder *encoder;
166
167 /*
168 * The new encoder this connector will be driven. Only differs from
169 * encoder while a modeset is in progress.
170 */
171 struct intel_encoder *new_encoder;
172
157 /* Reads out the current hw, returning true if the connector is enabled 173 /* Reads out the current hw, returning true if the connector is enabled
158 * and active (i.e. dpms ON state). */ 174 * and active (i.e. dpms ON state). */
159 bool (*get_hw_state)(struct intel_connector *); 175 bool (*get_hw_state)(struct intel_connector *);