diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-07-08 16:08:04 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-09-06 02:21:26 -0400 |
commit | 25c5b2665fe4cc5a93edd29b62e7c05c15dddd26 (patch) | |
tree | eaea57c899fa1dbf88ce1465c2f1e8f8282ac2ff | |
parent | e2e1ed41ed6e3012464e8a8e7cf7bbcb6d3f7412 (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.c | 99 |
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 | |||
6801 | bool intel_set_mode(struct drm_crtc *crtc, | 6807 | bool 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 */ |
6874 | done: | 6899 | done: |
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 | |||
6884 | static void intel_set_config_free(struct intel_set_config *config) | 6911 | static void intel_set_config_free(struct intel_set_config *config) |
6885 | { | 6912 | { |
6886 | if (!config) | 6913 | if (!config) |