aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-07-08 16:08:04 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-09-06 02:21:26 -0400
commit25c5b2665fe4cc5a93edd29b62e7c05c15dddd26 (patch)
treeeaea57c899fa1dbf88ce1465c2f1e8f8282ac2ff
parente2e1ed41ed6e3012464e8a8e7cf7bbcb6d3f7412 (diff)
drm/i915: implement new set_mode code flow
... using the pipe masks from the previous patch. Well, not quite: - We still need to call the disable_unused_functions helper, until we've moved the call to commit_output_state further down and adjusted intel_crtc_disable a bit. The next patch will do that. - Because we don't support (yet) mode changes on more than one crtc at a time, some of the modeset_pipes checks are a bit hackish - but that only needs fixing once we incorporate global modeset support. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/intel_display.c99
1 files changed, 63 insertions, 36 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index d354aa0b8eed..16cbf9554216 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6798,6 +6798,12 @@ intel_modeset_affected_pipes(struct drm_crtc *crtc, unsigned *modeset_pipes,
6798 *prepare_pipes &= ~(*disable_pipes); 6798 *prepare_pipes &= ~(*disable_pipes);
6799} 6799}
6800 6800
6801#define for_each_intel_crtc_masked(dev, mask, intel_crtc) \
6802 list_for_each_entry((intel_crtc), \
6803 &(dev)->mode_config.crtc_list, \
6804 base.head) \
6805 if (mask & (1 <<(intel_crtc)->pipe)) \
6806
6801bool intel_set_mode(struct drm_crtc *crtc, 6807bool intel_set_mode(struct drm_crtc *crtc,
6802 struct drm_display_mode *mode, 6808 struct drm_display_mode *mode,
6803 int x, int y, struct drm_framebuffer *fb) 6809 int x, int y, struct drm_framebuffer *fb)
@@ -6807,73 +6813,92 @@ bool intel_set_mode(struct drm_crtc *crtc,
6807 struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode; 6813 struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
6808 struct drm_encoder_helper_funcs *encoder_funcs; 6814 struct drm_encoder_helper_funcs *encoder_funcs;
6809 struct drm_encoder *encoder; 6815 struct drm_encoder *encoder;
6810 unsigned disable_pipe, prepare_pipes, modeset_pipes; 6816 struct intel_crtc *intel_crtc;
6817 unsigned disable_pipes, prepare_pipes, modeset_pipes;
6811 bool ret = true; 6818 bool ret = true;
6812 6819
6813 intel_modeset_affected_pipes(crtc, &modeset_pipes, 6820 intel_modeset_affected_pipes(crtc, &modeset_pipes,
6814 &prepare_pipes, &disable_pipe); 6821 &prepare_pipes, &disable_pipes);
6822
6823 DRM_DEBUG_KMS("set mode pipe masks: modeset: %x, prepare: %x, disable: %x\n",
6824 modeset_pipes, prepare_pipes, disable_pipes);
6815 6825
6816 intel_modeset_commit_output_state(dev); 6826 intel_modeset_commit_output_state(dev);
6817 6827
6818 crtc->enabled = drm_helper_crtc_in_use(crtc); 6828 crtc->enabled = drm_helper_crtc_in_use(crtc);
6819 if (!crtc->enabled) {
6820 drm_helper_disable_unused_functions(dev);
6821 return true;
6822 }
6823 6829
6830 for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc)
6831 drm_helper_disable_unused_functions(dev);
6824 6832
6825 saved_hwmode = crtc->hwmode; 6833 saved_hwmode = crtc->hwmode;
6826 saved_mode = crtc->mode; 6834 saved_mode = crtc->mode;
6827 6835
6828 adjusted_mode = intel_modeset_adjusted_mode(crtc, mode); 6836 /* Hack: Because we don't (yet) support global modeset on multiple
6829 if (IS_ERR(adjusted_mode)) { 6837 * crtcs, we don't keep track of the new mode for more than one crtc.
6830 return false; 6838 * Hence simply check whether any bit is set in modeset_pipes in all the
6831 } 6839 * pieces of code that are not yet converted to deal with mutliple crtcs
6840 * changing their mode at the same time. */
6841 adjusted_mode = NULL;
6842 if (modeset_pipes) {
6843 adjusted_mode = intel_modeset_adjusted_mode(crtc, mode);
6844 if (IS_ERR(adjusted_mode)) {
6845 return false;
6846 }
6832 6847
6833 intel_crtc_prepare_encoders(dev); 6848 intel_crtc_prepare_encoders(dev);
6849 }
6834 6850
6835 dev_priv->display.crtc_disable(crtc); 6851 for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc)
6852 dev_priv->display.crtc_disable(&intel_crtc->base);
6836 6853
6837 crtc->mode = *mode; 6854 if (modeset_pipes) {
6855 crtc->mode = *mode;
6856 crtc->x = x;
6857 crtc->y = y;
6858 }
6838 6859
6839 /* Set up the DPLL and any encoders state that needs to adjust or depend 6860 /* Set up the DPLL and any encoders state that needs to adjust or depend
6840 * on the DPLL. 6861 * on the DPLL.
6841 */ 6862 */
6842 ret = !intel_crtc_mode_set(crtc, mode, adjusted_mode, x, y, fb); 6863 for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
6843 if (!ret) 6864 ret = !intel_crtc_mode_set(&intel_crtc->base,
6844 goto done; 6865 mode, adjusted_mode,
6866 x, y, fb);
6867 if (!ret)
6868 goto done;
6845 6869
6846 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 6870 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
6847 6871
6848 if (encoder->crtc != crtc) 6872 if (encoder->crtc != &intel_crtc->base)
6849 continue; 6873 continue;
6850 6874
6851 DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n", 6875 DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n",
6852 encoder->base.id, drm_get_encoder_name(encoder), 6876 encoder->base.id, drm_get_encoder_name(encoder),
6853 mode->base.id, mode->name); 6877 mode->base.id, mode->name);
6854 encoder_funcs = encoder->helper_private; 6878 encoder_funcs = encoder->helper_private;
6855 encoder_funcs->mode_set(encoder, mode, adjusted_mode); 6879 encoder_funcs->mode_set(encoder, mode, adjusted_mode);
6880 }
6856 } 6881 }
6857 6882
6858 crtc->x = x;
6859 crtc->y = y;
6860
6861 /* Now enable the clocks, plane, pipe, and connectors that we set up. */ 6883 /* Now enable the clocks, plane, pipe, and connectors that we set up. */
6862 dev_priv->display.crtc_enable(crtc); 6884 for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc)
6885 dev_priv->display.crtc_enable(&intel_crtc->base);
6863 6886
6864 /* Store real post-adjustment hardware mode. */ 6887 if (modeset_pipes) {
6865 crtc->hwmode = *adjusted_mode; 6888 /* Store real post-adjustment hardware mode. */
6889 crtc->hwmode = *adjusted_mode;
6866 6890
6867 /* Calculate and store various constants which 6891 /* Calculate and store various constants which
6868 * are later needed by vblank and swap-completion 6892 * are later needed by vblank and swap-completion
6869 * timestamping. They are derived from true hwmode. 6893 * timestamping. They are derived from true hwmode.
6870 */ 6894 */
6871 drm_calc_timestamping_constants(crtc); 6895 drm_calc_timestamping_constants(crtc);
6896 }
6872 6897
6873 /* FIXME: add subpixel order */ 6898 /* FIXME: add subpixel order */
6874done: 6899done:
6875 drm_mode_destroy(dev, adjusted_mode); 6900 drm_mode_destroy(dev, adjusted_mode);
6876 if (!ret) { 6901 if (!ret && crtc->enabled) {
6877 crtc->hwmode = saved_hwmode; 6902 crtc->hwmode = saved_hwmode;
6878 crtc->mode = saved_mode; 6903 crtc->mode = saved_mode;
6879 } 6904 }
@@ -6881,6 +6906,8 @@ done:
6881 return ret; 6906 return ret;
6882} 6907}
6883 6908
6909#undef for_each_intel_crtc_masked
6910
6884static void intel_set_config_free(struct intel_set_config *config) 6911static void intel_set_config_free(struct intel_set_config *config)
6885{ 6912{
6886 if (!config) 6913 if (!config)