diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2014-11-05 17:26:06 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-11-14 04:29:21 -0500 |
commit | 7f27126ea3db6ade886f18fd39caf0ff0cd1d37f (patch) | |
tree | 3a712edf12b6865c16f6aa4c5ed74d572865e73b /drivers/gpu/drm/i915/intel_display.c | |
parent | 260d8f98ef9deb71bee4d88f72cd90afe023b08a (diff) |
drm/i915: factor out compute_config from __intel_set_mode v3
This allows us to calculate the full pipe config before we do any mode
setting work.
v2:
- clarify comments about global vs. per-crtc mode set (Ander)
- clean up unnecessary pipe_config = NULL setting (Ander)
v3:
- fix pipe_config handling (alloc in compute_config, free in set_mode) (Jesse)
- fix arg order in set_mode (Jesse)
- fix failure path of set_config (Ander)
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Reviewed-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 105 |
1 files changed, 74 insertions, 31 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 983091224f11..6e8f9e295d01 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -10741,45 +10741,60 @@ static void update_scanline_offset(struct intel_crtc *crtc) | |||
10741 | crtc->scanline_offset = 1; | 10741 | crtc->scanline_offset = 1; |
10742 | } | 10742 | } |
10743 | 10743 | ||
10744 | static struct intel_crtc_config * | ||
10745 | intel_modeset_compute_config(struct drm_crtc *crtc, | ||
10746 | struct drm_display_mode *mode, | ||
10747 | struct drm_framebuffer *fb, | ||
10748 | unsigned *modeset_pipes, | ||
10749 | unsigned *prepare_pipes, | ||
10750 | unsigned *disable_pipes) | ||
10751 | { | ||
10752 | struct intel_crtc_config *pipe_config = NULL; | ||
10753 | |||
10754 | intel_modeset_affected_pipes(crtc, modeset_pipes, | ||
10755 | prepare_pipes, disable_pipes); | ||
10756 | |||
10757 | if ((*modeset_pipes) == 0) | ||
10758 | goto out; | ||
10759 | |||
10760 | /* | ||
10761 | * Note this needs changes when we start tracking multiple modes | ||
10762 | * and crtcs. At that point we'll need to compute the whole config | ||
10763 | * (i.e. one pipe_config for each crtc) rather than just the one | ||
10764 | * for this crtc. | ||
10765 | */ | ||
10766 | pipe_config = intel_modeset_pipe_config(crtc, fb, mode); | ||
10767 | if (IS_ERR(pipe_config)) { | ||
10768 | goto out; | ||
10769 | } | ||
10770 | intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config, | ||
10771 | "[modeset]"); | ||
10772 | to_intel_crtc(crtc)->new_config = pipe_config; | ||
10773 | |||
10774 | out: | ||
10775 | return pipe_config; | ||
10776 | } | ||
10777 | |||
10744 | static int __intel_set_mode(struct drm_crtc *crtc, | 10778 | static int __intel_set_mode(struct drm_crtc *crtc, |
10745 | struct drm_display_mode *mode, | 10779 | struct drm_display_mode *mode, |
10746 | int x, int y, struct drm_framebuffer *fb) | 10780 | int x, int y, struct drm_framebuffer *fb, |
10781 | struct intel_crtc_config *pipe_config, | ||
10782 | unsigned modeset_pipes, | ||
10783 | unsigned prepare_pipes, | ||
10784 | unsigned disable_pipes) | ||
10747 | { | 10785 | { |
10748 | struct drm_device *dev = crtc->dev; | 10786 | struct drm_device *dev = crtc->dev; |
10749 | struct drm_i915_private *dev_priv = dev->dev_private; | 10787 | struct drm_i915_private *dev_priv = dev->dev_private; |
10750 | struct drm_display_mode *saved_mode; | 10788 | struct drm_display_mode *saved_mode; |
10751 | struct intel_crtc_config *pipe_config = NULL; | ||
10752 | struct intel_crtc *intel_crtc; | 10789 | struct intel_crtc *intel_crtc; |
10753 | unsigned disable_pipes, prepare_pipes, modeset_pipes; | ||
10754 | int ret = 0; | 10790 | int ret = 0; |
10755 | 10791 | ||
10756 | saved_mode = kmalloc(sizeof(*saved_mode), GFP_KERNEL); | 10792 | saved_mode = kmalloc(sizeof(*saved_mode), GFP_KERNEL); |
10757 | if (!saved_mode) | 10793 | if (!saved_mode) |
10758 | return -ENOMEM; | 10794 | return -ENOMEM; |
10759 | 10795 | ||
10760 | intel_modeset_affected_pipes(crtc, &modeset_pipes, | ||
10761 | &prepare_pipes, &disable_pipes); | ||
10762 | |||
10763 | *saved_mode = crtc->mode; | 10796 | *saved_mode = crtc->mode; |
10764 | 10797 | ||
10765 | /* Hack: Because we don't (yet) support global modeset on multiple | ||
10766 | * crtcs, we don't keep track of the new mode for more than one crtc. | ||
10767 | * Hence simply check whether any bit is set in modeset_pipes in all the | ||
10768 | * pieces of code that are not yet converted to deal with mutliple crtcs | ||
10769 | * changing their mode at the same time. */ | ||
10770 | if (modeset_pipes) { | ||
10771 | pipe_config = intel_modeset_pipe_config(crtc, fb, mode); | ||
10772 | if (IS_ERR(pipe_config)) { | ||
10773 | ret = PTR_ERR(pipe_config); | ||
10774 | pipe_config = NULL; | ||
10775 | |||
10776 | goto out; | ||
10777 | } | ||
10778 | intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config, | ||
10779 | "[modeset]"); | ||
10780 | to_intel_crtc(crtc)->new_config = pipe_config; | ||
10781 | } | ||
10782 | |||
10783 | /* | 10798 | /* |
10784 | * See if the config requires any additional preparation, e.g. | 10799 | * See if the config requires any additional preparation, e.g. |
10785 | * to adjust global state with pipes off. We need to do this | 10800 | * to adjust global state with pipes off. We need to do this |
@@ -10820,6 +10835,10 @@ static int __intel_set_mode(struct drm_crtc *crtc, | |||
10820 | 10835 | ||
10821 | /* crtc->mode is already used by the ->mode_set callbacks, hence we need | 10836 | /* crtc->mode is already used by the ->mode_set callbacks, hence we need |
10822 | * to set it here already despite that we pass it down the callchain. | 10837 | * to set it here already despite that we pass it down the callchain. |
10838 | * | ||
10839 | * Note we'll need to fix this up when we start tracking multiple | ||
10840 | * pipes; here we assume a single modeset_pipe and only track the | ||
10841 | * single crtc and mode. | ||
10823 | */ | 10842 | */ |
10824 | if (modeset_pipes) { | 10843 | if (modeset_pipes) { |
10825 | crtc->mode = *mode; | 10844 | crtc->mode = *mode; |
@@ -10881,19 +10900,23 @@ done: | |||
10881 | if (ret && crtc->enabled) | 10900 | if (ret && crtc->enabled) |
10882 | crtc->mode = *saved_mode; | 10901 | crtc->mode = *saved_mode; |
10883 | 10902 | ||
10884 | out: | ||
10885 | kfree(pipe_config); | 10903 | kfree(pipe_config); |
10886 | kfree(saved_mode); | 10904 | kfree(saved_mode); |
10887 | return ret; | 10905 | return ret; |
10888 | } | 10906 | } |
10889 | 10907 | ||
10890 | static int intel_set_mode(struct drm_crtc *crtc, | 10908 | static int intel_set_mode_pipes(struct drm_crtc *crtc, |
10891 | struct drm_display_mode *mode, | 10909 | struct drm_display_mode *mode, |
10892 | int x, int y, struct drm_framebuffer *fb) | 10910 | int x, int y, struct drm_framebuffer *fb, |
10911 | struct intel_crtc_config *pipe_config, | ||
10912 | unsigned modeset_pipes, | ||
10913 | unsigned prepare_pipes, | ||
10914 | unsigned disable_pipes) | ||
10893 | { | 10915 | { |
10894 | int ret; | 10916 | int ret; |
10895 | 10917 | ||
10896 | ret = __intel_set_mode(crtc, mode, x, y, fb); | 10918 | ret = __intel_set_mode(crtc, mode, x, y, fb, pipe_config, modeset_pipes, |
10919 | prepare_pipes, disable_pipes); | ||
10897 | 10920 | ||
10898 | if (ret == 0) | 10921 | if (ret == 0) |
10899 | intel_modeset_check_state(crtc->dev); | 10922 | intel_modeset_check_state(crtc->dev); |
@@ -10901,6 +10924,26 @@ static int intel_set_mode(struct drm_crtc *crtc, | |||
10901 | return ret; | 10924 | return ret; |
10902 | } | 10925 | } |
10903 | 10926 | ||
10927 | static int intel_set_mode(struct drm_crtc *crtc, | ||
10928 | struct drm_display_mode *mode, | ||
10929 | int x, int y, struct drm_framebuffer *fb) | ||
10930 | { | ||
10931 | struct intel_crtc_config *pipe_config; | ||
10932 | unsigned modeset_pipes, prepare_pipes, disable_pipes; | ||
10933 | |||
10934 | pipe_config = intel_modeset_compute_config(crtc, mode, fb, | ||
10935 | &modeset_pipes, | ||
10936 | &prepare_pipes, | ||
10937 | &disable_pipes); | ||
10938 | |||
10939 | if (IS_ERR(pipe_config)) | ||
10940 | return PTR_ERR(pipe_config); | ||
10941 | |||
10942 | return intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config, | ||
10943 | modeset_pipes, prepare_pipes, | ||
10944 | disable_pipes); | ||
10945 | } | ||
10946 | |||
10904 | void intel_crtc_restore_mode(struct drm_crtc *crtc) | 10947 | void intel_crtc_restore_mode(struct drm_crtc *crtc) |
10905 | { | 10948 | { |
10906 | intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb); | 10949 | intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb); |
@@ -13249,8 +13292,8 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, | |||
13249 | struct drm_crtc *crtc = | 13292 | struct drm_crtc *crtc = |
13250 | dev_priv->pipe_to_crtc_mapping[pipe]; | 13293 | dev_priv->pipe_to_crtc_mapping[pipe]; |
13251 | 13294 | ||
13252 | __intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, | 13295 | intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, |
13253 | crtc->primary->fb); | 13296 | crtc->primary->fb); |
13254 | } | 13297 | } |
13255 | } else { | 13298 | } else { |
13256 | intel_modeset_update_staged_output_state(dev); | 13299 | intel_modeset_update_staged_output_state(dev); |