aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2014-01-10 04:28:06 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-01-24 11:22:40 -0500
commit7668851fec5c207d1d62c4c9311e083edf940bcc (patch)
tree89001547195a1875f64efd2940ee3eb2559bbe65 /drivers/gpu
parent85ba7b7d399dd2c4c65bd84b9ae4dfbd707e79e7 (diff)
drm/i915: Pre-compute pipe enabled state
Add 'new_enabled' to intel_crtc and precompute it alongside new_encoder and new_crtc. This will allow making decisions about shared resources that are affected by the set of active pipes, before we've clobbered anything for real. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c78
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
2 files changed, 64 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 40a9338ad54f..204c09c9b63f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8774,6 +8774,7 @@ static bool intel_encoder_crtc_ok(struct drm_encoder *encoder,
8774 */ 8774 */
8775static void intel_modeset_update_staged_output_state(struct drm_device *dev) 8775static void intel_modeset_update_staged_output_state(struct drm_device *dev)
8776{ 8776{
8777 struct intel_crtc *crtc;
8777 struct intel_encoder *encoder; 8778 struct intel_encoder *encoder;
8778 struct intel_connector *connector; 8779 struct intel_connector *connector;
8779 8780
@@ -8788,6 +8789,11 @@ static void intel_modeset_update_staged_output_state(struct drm_device *dev)
8788 encoder->new_crtc = 8789 encoder->new_crtc =
8789 to_intel_crtc(encoder->base.crtc); 8790 to_intel_crtc(encoder->base.crtc);
8790 } 8791 }
8792
8793 list_for_each_entry(crtc, &dev->mode_config.crtc_list,
8794 base.head) {
8795 crtc->new_enabled = crtc->base.enabled;
8796 }
8791} 8797}
8792 8798
8793/** 8799/**
@@ -8797,6 +8803,7 @@ static void intel_modeset_update_staged_output_state(struct drm_device *dev)
8797 */ 8803 */
8798static void intel_modeset_commit_output_state(struct drm_device *dev) 8804static void intel_modeset_commit_output_state(struct drm_device *dev)
8799{ 8805{
8806 struct intel_crtc *crtc;
8800 struct intel_encoder *encoder; 8807 struct intel_encoder *encoder;
8801 struct intel_connector *connector; 8808 struct intel_connector *connector;
8802 8809
@@ -8809,6 +8816,11 @@ static void intel_modeset_commit_output_state(struct drm_device *dev)
8809 base.head) { 8816 base.head) {
8810 encoder->base.crtc = &encoder->new_crtc->base; 8817 encoder->base.crtc = &encoder->new_crtc->base;
8811 } 8818 }
8819
8820 list_for_each_entry(crtc, &dev->mode_config.crtc_list,
8821 base.head) {
8822 crtc->base.enabled = crtc->new_enabled;
8823 }
8812} 8824}
8813 8825
8814static void 8826static void
@@ -9135,29 +9147,22 @@ intel_modeset_affected_pipes(struct drm_crtc *crtc, unsigned *modeset_pipes,
9135 *prepare_pipes |= 1 << encoder->new_crtc->pipe; 9147 *prepare_pipes |= 1 << encoder->new_crtc->pipe;
9136 } 9148 }
9137 9149
9138 /* Check for any pipes that will be fully disabled ... */ 9150 /* Check for pipes that will be enabled/disabled ... */
9139 list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, 9151 list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
9140 base.head) { 9152 base.head) {
9141 bool used = false; 9153 if (intel_crtc->base.enabled == intel_crtc->new_enabled)
9142
9143 /* Don't try to disable disabled crtcs. */
9144 if (!intel_crtc->base.enabled)
9145 continue; 9154 continue;
9146 9155
9147 list_for_each_entry(encoder, &dev->mode_config.encoder_list, 9156 if (!intel_crtc->new_enabled)
9148 base.head) {
9149 if (encoder->new_crtc == intel_crtc)
9150 used = true;
9151 }
9152
9153 if (!used)
9154 *disable_pipes |= 1 << intel_crtc->pipe; 9157 *disable_pipes |= 1 << intel_crtc->pipe;
9158 else
9159 *prepare_pipes |= 1 << intel_crtc->pipe;
9155 } 9160 }
9156 9161
9157 9162
9158 /* set_mode is also used to update properties on life display pipes. */ 9163 /* set_mode is also used to update properties on life display pipes. */
9159 intel_crtc = to_intel_crtc(crtc); 9164 intel_crtc = to_intel_crtc(crtc);
9160 if (crtc->enabled) 9165 if (intel_crtc->new_enabled)
9161 *prepare_pipes |= 1 << intel_crtc->pipe; 9166 *prepare_pipes |= 1 << intel_crtc->pipe;
9162 9167
9163 /* 9168 /*
@@ -9216,10 +9221,10 @@ intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes)
9216 9221
9217 intel_modeset_commit_output_state(dev); 9222 intel_modeset_commit_output_state(dev);
9218 9223
9219 /* Update computed state. */ 9224 /* Double check state. */
9220 list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, 9225 list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
9221 base.head) { 9226 base.head) {
9222 intel_crtc->base.enabled = intel_crtc_in_use(&intel_crtc->base); 9227 WARN_ON(intel_crtc->base.enabled != intel_crtc_in_use(&intel_crtc->base));
9223 } 9228 }
9224 9229
9225 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 9230 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
@@ -9754,16 +9759,24 @@ static void intel_set_config_free(struct intel_set_config *config)
9754 9759
9755 kfree(config->save_connector_encoders); 9760 kfree(config->save_connector_encoders);
9756 kfree(config->save_encoder_crtcs); 9761 kfree(config->save_encoder_crtcs);
9762 kfree(config->save_crtc_enabled);
9757 kfree(config); 9763 kfree(config);
9758} 9764}
9759 9765
9760static int intel_set_config_save_state(struct drm_device *dev, 9766static int intel_set_config_save_state(struct drm_device *dev,
9761 struct intel_set_config *config) 9767 struct intel_set_config *config)
9762{ 9768{
9769 struct drm_crtc *crtc;
9763 struct drm_encoder *encoder; 9770 struct drm_encoder *encoder;
9764 struct drm_connector *connector; 9771 struct drm_connector *connector;
9765 int count; 9772 int count;
9766 9773
9774 config->save_crtc_enabled =
9775 kcalloc(dev->mode_config.num_crtc,
9776 sizeof(bool), GFP_KERNEL);
9777 if (!config->save_crtc_enabled)
9778 return -ENOMEM;
9779
9767 config->save_encoder_crtcs = 9780 config->save_encoder_crtcs =
9768 kcalloc(dev->mode_config.num_encoder, 9781 kcalloc(dev->mode_config.num_encoder,
9769 sizeof(struct drm_crtc *), GFP_KERNEL); 9782 sizeof(struct drm_crtc *), GFP_KERNEL);
@@ -9781,6 +9794,11 @@ static int intel_set_config_save_state(struct drm_device *dev,
9781 * restored, not the drivers personal bookkeeping. 9794 * restored, not the drivers personal bookkeeping.
9782 */ 9795 */
9783 count = 0; 9796 count = 0;
9797 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
9798 config->save_crtc_enabled[count++] = crtc->enabled;
9799 }
9800
9801 count = 0;
9784 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 9802 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
9785 config->save_encoder_crtcs[count++] = encoder->crtc; 9803 config->save_encoder_crtcs[count++] = encoder->crtc;
9786 } 9804 }
@@ -9796,11 +9814,17 @@ static int intel_set_config_save_state(struct drm_device *dev,
9796static void intel_set_config_restore_state(struct drm_device *dev, 9814static void intel_set_config_restore_state(struct drm_device *dev,
9797 struct intel_set_config *config) 9815 struct intel_set_config *config)
9798{ 9816{
9817 struct intel_crtc *crtc;
9799 struct intel_encoder *encoder; 9818 struct intel_encoder *encoder;
9800 struct intel_connector *connector; 9819 struct intel_connector *connector;
9801 int count; 9820 int count;
9802 9821
9803 count = 0; 9822 count = 0;
9823 list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
9824 crtc->new_enabled = config->save_crtc_enabled[count++];
9825 }
9826
9827 count = 0;
9804 list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { 9828 list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) {
9805 encoder->new_crtc = 9829 encoder->new_crtc =
9806 to_intel_crtc(config->save_encoder_crtcs[count++]); 9830 to_intel_crtc(config->save_encoder_crtcs[count++]);
@@ -9884,9 +9908,9 @@ intel_modeset_stage_output_state(struct drm_device *dev,
9884 struct drm_mode_set *set, 9908 struct drm_mode_set *set,
9885 struct intel_set_config *config) 9909 struct intel_set_config *config)
9886{ 9910{
9887 struct drm_crtc *new_crtc;
9888 struct intel_connector *connector; 9911 struct intel_connector *connector;
9889 struct intel_encoder *encoder; 9912 struct intel_encoder *encoder;
9913 struct intel_crtc *crtc;
9890 int ro; 9914 int ro;
9891 9915
9892 /* The upper layers ensure that we either disable a crtc or have a list 9916 /* The upper layers ensure that we either disable a crtc or have a list
@@ -9929,6 +9953,8 @@ intel_modeset_stage_output_state(struct drm_device *dev,
9929 /* Update crtc of enabled connectors. */ 9953 /* Update crtc of enabled connectors. */
9930 list_for_each_entry(connector, &dev->mode_config.connector_list, 9954 list_for_each_entry(connector, &dev->mode_config.connector_list,
9931 base.head) { 9955 base.head) {
9956 struct drm_crtc *new_crtc;
9957
9932 if (!connector->new_encoder) 9958 if (!connector->new_encoder)
9933 continue; 9959 continue;
9934 9960
@@ -9979,6 +10005,26 @@ intel_modeset_stage_output_state(struct drm_device *dev,
9979 } 10005 }
9980 /* Now we've also updated encoder->new_crtc for all encoders. */ 10006 /* Now we've also updated encoder->new_crtc for all encoders. */
9981 10007
10008 list_for_each_entry(crtc, &dev->mode_config.crtc_list,
10009 base.head) {
10010 crtc->new_enabled = false;
10011
10012 list_for_each_entry(encoder,
10013 &dev->mode_config.encoder_list,
10014 base.head) {
10015 if (encoder->new_crtc == crtc) {
10016 crtc->new_enabled = true;
10017 break;
10018 }
10019 }
10020
10021 if (crtc->new_enabled != crtc->base.enabled) {
10022 DRM_DEBUG_KMS("crtc %sabled, full mode switch\n",
10023 crtc->new_enabled ? "en" : "dis");
10024 config->mode_changed = true;
10025 }
10026 }
10027
9982 return 0; 10028 return 0;
9983} 10029}
9984 10030
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index fbfaaba5cc3b..718befff98e8 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -359,6 +359,7 @@ struct intel_crtc {
359 bool cursor_visible; 359 bool cursor_visible;
360 360
361 struct intel_crtc_config config; 361 struct intel_crtc_config config;
362 bool new_enabled;
362 363
363 uint32_t ddi_pll_sel; 364 uint32_t ddi_pll_sel;
364 365
@@ -540,6 +541,7 @@ struct intel_unpin_work {
540struct intel_set_config { 541struct intel_set_config {
541 struct drm_encoder **save_connector_encoders; 542 struct drm_encoder **save_connector_encoders;
542 struct drm_crtc **save_encoder_crtcs; 543 struct drm_crtc **save_encoder_crtcs;
544 bool *save_crtc_enabled;
543 545
544 bool fb_changed; 546 bool fb_changed;
545 bool mode_changed; 547 bool mode_changed;