aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2014-11-05 17:26:06 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-11-14 04:29:21 -0500
commit7f27126ea3db6ade886f18fd39caf0ff0cd1d37f (patch)
tree3a712edf12b6865c16f6aa4c5ed74d572865e73b /drivers/gpu/drm
parent260d8f98ef9deb71bee4d88f72cd90afe023b08a (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')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c105
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
10744static struct intel_crtc_config *
10745intel_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
10774out:
10775 return pipe_config;
10776}
10777
10744static int __intel_set_mode(struct drm_crtc *crtc, 10778static 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
10884out:
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
10890static int intel_set_mode(struct drm_crtc *crtc, 10908static 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
10927static 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
10904void intel_crtc_restore_mode(struct drm_crtc *crtc) 10947void 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);