aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-03-26 19:44:50 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-03-27 19:50:04 -0400
commitb8cecdf5a8cb847b8234fa3f5b61e89aea53032f (patch)
tree23392113cad8923a3d238464c126ac6521a19a5c /drivers
parent7c23396b40ed1e1d4751b0cadb8d1c8183a4e020 (diff)
drm/i915: introduce struct intel_crtc_config
Currently only containing the requested and the adjusted mode. And only crtc callbacks are converted somewhat to it, encoders will be done on a as-needed basis (simply too much churn in one patch otherwise). Future patches will add tons more useful stuff to this struct, starting with the very simple. v2: Store the pipe_config in the intel_crtc, so that the ->mode-set, ->enable and also ->disable have easy access to it. v3: Store the pipe config in the right crtc ... v4: Rebased. v5: Fixup an OOPS when trying to kfree an ERR_PTR. v6: Used drm_moode_copy and some other small cleanups as suggested by Ville Syrjälä. v7: drm_mode_copy preserves the mode id of the destination, so no need to clear it again (Ville). v8: Break a long line spotted by Paulo. Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h4
-rw-r--r--drivers/gpu/drm/i915/intel_display.c82
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h7
3 files changed, 57 insertions, 36 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f69538508d8c..2962a9ab44d5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -284,6 +284,8 @@ struct drm_i915_error_state {
284 struct intel_display_error_state *display; 284 struct intel_display_error_state *display;
285}; 285};
286 286
287struct intel_crtc_config;
288
287struct drm_i915_display_funcs { 289struct drm_i915_display_funcs {
288 bool (*fbc_enabled)(struct drm_device *dev); 290 bool (*fbc_enabled)(struct drm_device *dev);
289 void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval); 291 void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval);
@@ -297,8 +299,6 @@ struct drm_i915_display_funcs {
297 struct drm_display_mode *mode); 299 struct drm_display_mode *mode);
298 void (*modeset_global_resources)(struct drm_device *dev); 300 void (*modeset_global_resources)(struct drm_device *dev);
299 int (*crtc_mode_set)(struct drm_crtc *crtc, 301 int (*crtc_mode_set)(struct drm_crtc *crtc,
300 struct drm_display_mode *mode,
301 struct drm_display_mode *adjusted_mode,
302 int x, int y, 302 int x, int y,
303 struct drm_framebuffer *old_fb); 303 struct drm_framebuffer *old_fb);
304 void (*crtc_enable)(struct drm_crtc *crtc); 304 void (*crtc_enable)(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 2db50e234c2c..e22be581ed9b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3971,15 +3971,16 @@ bool intel_connector_get_hw_state(struct intel_connector *connector)
3971 return encoder->get_hw_state(encoder, &pipe); 3971 return encoder->get_hw_state(encoder, &pipe);
3972} 3972}
3973 3973
3974static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, 3974static bool intel_crtc_compute_config(struct drm_crtc *crtc,
3975 const struct drm_display_mode *mode, 3975 struct intel_crtc_config *pipe_config)
3976 struct drm_display_mode *adjusted_mode)
3977{ 3976{
3978 struct drm_device *dev = crtc->dev; 3977 struct drm_device *dev = crtc->dev;
3978 struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
3979 3979
3980 if (HAS_PCH_SPLIT(dev)) { 3980 if (HAS_PCH_SPLIT(dev)) {
3981 /* FDI link clock is fixed at 2.7G */ 3981 /* FDI link clock is fixed at 2.7G */
3982 if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4) 3982 if (pipe_config->requested_mode.clock * 3
3983 > IRONLAKE_FDI_FREQ * 4)
3983 return false; 3984 return false;
3984 } 3985 }
3985 3986
@@ -4665,14 +4666,15 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc,
4665} 4666}
4666 4667
4667static int i9xx_crtc_mode_set(struct drm_crtc *crtc, 4668static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
4668 struct drm_display_mode *mode,
4669 struct drm_display_mode *adjusted_mode,
4670 int x, int y, 4669 int x, int y,
4671 struct drm_framebuffer *fb) 4670 struct drm_framebuffer *fb)
4672{ 4671{
4673 struct drm_device *dev = crtc->dev; 4672 struct drm_device *dev = crtc->dev;
4674 struct drm_i915_private *dev_priv = dev->dev_private; 4673 struct drm_i915_private *dev_priv = dev->dev_private;
4675 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 4674 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
4675 struct drm_display_mode *adjusted_mode =
4676 &intel_crtc->config.adjusted_mode;
4677 struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
4676 int pipe = intel_crtc->pipe; 4678 int pipe = intel_crtc->pipe;
4677 int plane = intel_crtc->plane; 4679 int plane = intel_crtc->plane;
4678 int refclk, num_connectors = 0; 4680 int refclk, num_connectors = 0;
@@ -5637,14 +5639,15 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
5637} 5639}
5638 5640
5639static int ironlake_crtc_mode_set(struct drm_crtc *crtc, 5641static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
5640 struct drm_display_mode *mode,
5641 struct drm_display_mode *adjusted_mode,
5642 int x, int y, 5642 int x, int y,
5643 struct drm_framebuffer *fb) 5643 struct drm_framebuffer *fb)
5644{ 5644{
5645 struct drm_device *dev = crtc->dev; 5645 struct drm_device *dev = crtc->dev;
5646 struct drm_i915_private *dev_priv = dev->dev_private; 5646 struct drm_i915_private *dev_priv = dev->dev_private;
5647 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 5647 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
5648 struct drm_display_mode *adjusted_mode =
5649 &intel_crtc->config.adjusted_mode;
5650 struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
5648 int pipe = intel_crtc->pipe; 5651 int pipe = intel_crtc->pipe;
5649 int plane = intel_crtc->plane; 5652 int plane = intel_crtc->plane;
5650 int num_connectors = 0; 5653 int num_connectors = 0;
@@ -5803,14 +5806,15 @@ static void haswell_modeset_global_resources(struct drm_device *dev)
5803} 5806}
5804 5807
5805static int haswell_crtc_mode_set(struct drm_crtc *crtc, 5808static int haswell_crtc_mode_set(struct drm_crtc *crtc,
5806 struct drm_display_mode *mode,
5807 struct drm_display_mode *adjusted_mode,
5808 int x, int y, 5809 int x, int y,
5809 struct drm_framebuffer *fb) 5810 struct drm_framebuffer *fb)
5810{ 5811{
5811 struct drm_device *dev = crtc->dev; 5812 struct drm_device *dev = crtc->dev;
5812 struct drm_i915_private *dev_priv = dev->dev_private; 5813 struct drm_i915_private *dev_priv = dev->dev_private;
5813 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 5814 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
5815 struct drm_display_mode *adjusted_mode =
5816 &intel_crtc->config.adjusted_mode;
5817 struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
5814 int pipe = intel_crtc->pipe; 5818 int pipe = intel_crtc->pipe;
5815 int plane = intel_crtc->plane; 5819 int plane = intel_crtc->plane;
5816 int num_connectors = 0; 5820 int num_connectors = 0;
@@ -5887,8 +5891,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
5887} 5891}
5888 5892
5889static int intel_crtc_mode_set(struct drm_crtc *crtc, 5893static int intel_crtc_mode_set(struct drm_crtc *crtc,
5890 struct drm_display_mode *mode,
5891 struct drm_display_mode *adjusted_mode,
5892 int x, int y, 5894 int x, int y,
5893 struct drm_framebuffer *fb) 5895 struct drm_framebuffer *fb)
5894{ 5896{
@@ -5897,6 +5899,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
5897 struct drm_encoder_helper_funcs *encoder_funcs; 5899 struct drm_encoder_helper_funcs *encoder_funcs;
5898 struct intel_encoder *encoder; 5900 struct intel_encoder *encoder;
5899 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 5901 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
5902 struct drm_display_mode *adjusted_mode =
5903 &intel_crtc->config.adjusted_mode;
5904 struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
5900 int pipe = intel_crtc->pipe; 5905 int pipe = intel_crtc->pipe;
5901 int ret; 5906 int ret;
5902 5907
@@ -5907,8 +5912,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
5907 5912
5908 drm_vblank_pre_modeset(dev, pipe); 5913 drm_vblank_pre_modeset(dev, pipe);
5909 5914
5910 ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode, 5915 ret = dev_priv->display.crtc_mode_set(crtc, x, y, fb);
5911 x, y, fb); 5916
5912 drm_vblank_post_modeset(dev, pipe); 5917 drm_vblank_post_modeset(dev, pipe);
5913 5918
5914 if (ret != 0) 5919 if (ret != 0)
@@ -7530,19 +7535,22 @@ static void intel_modeset_commit_output_state(struct drm_device *dev)
7530 } 7535 }
7531} 7536}
7532 7537
7533static struct drm_display_mode * 7538static struct intel_crtc_config *
7534intel_modeset_adjusted_mode(struct drm_crtc *crtc, 7539intel_modeset_pipe_config(struct drm_crtc *crtc,
7535 struct drm_display_mode *mode) 7540 struct drm_display_mode *mode)
7536{ 7541{
7537 struct drm_device *dev = crtc->dev; 7542 struct drm_device *dev = crtc->dev;
7538 struct drm_display_mode *adjusted_mode;
7539 struct drm_encoder_helper_funcs *encoder_funcs; 7543 struct drm_encoder_helper_funcs *encoder_funcs;
7540 struct intel_encoder *encoder; 7544 struct intel_encoder *encoder;
7545 struct intel_crtc_config *pipe_config;
7541 7546
7542 adjusted_mode = drm_mode_duplicate(dev, mode); 7547 pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
7543 if (!adjusted_mode) 7548 if (!pipe_config)
7544 return ERR_PTR(-ENOMEM); 7549 return ERR_PTR(-ENOMEM);
7545 7550
7551 drm_mode_copy(&pipe_config->adjusted_mode, mode);
7552 drm_mode_copy(&pipe_config->requested_mode, mode);
7553
7546 /* Pass our mode to the connectors and the CRTC to give them a chance to 7554 /* Pass our mode to the connectors and the CRTC to give them a chance to
7547 * adjust it according to limitations or connector properties, and also 7555 * adjust it according to limitations or connector properties, and also
7548 * a chance to reject the mode entirely. 7556 * a chance to reject the mode entirely.
@@ -7553,22 +7561,23 @@ intel_modeset_adjusted_mode(struct drm_crtc *crtc,
7553 if (&encoder->new_crtc->base != crtc) 7561 if (&encoder->new_crtc->base != crtc)
7554 continue; 7562 continue;
7555 encoder_funcs = encoder->base.helper_private; 7563 encoder_funcs = encoder->base.helper_private;
7556 if (!(encoder_funcs->mode_fixup(&encoder->base, mode, 7564 if (!(encoder_funcs->mode_fixup(&encoder->base,
7557 adjusted_mode))) { 7565 &pipe_config->requested_mode,
7566 &pipe_config->adjusted_mode))) {
7558 DRM_DEBUG_KMS("Encoder fixup failed\n"); 7567 DRM_DEBUG_KMS("Encoder fixup failed\n");
7559 goto fail; 7568 goto fail;
7560 } 7569 }
7561 } 7570 }
7562 7571
7563 if (!(intel_crtc_mode_fixup(crtc, mode, adjusted_mode))) { 7572 if (!(intel_crtc_compute_config(crtc, pipe_config))) {
7564 DRM_DEBUG_KMS("CRTC fixup failed\n"); 7573 DRM_DEBUG_KMS("CRTC fixup failed\n");
7565 goto fail; 7574 goto fail;
7566 } 7575 }
7567 DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); 7576 DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
7568 7577
7569 return adjusted_mode; 7578 return pipe_config;
7570fail: 7579fail:
7571 drm_mode_destroy(dev, adjusted_mode); 7580 kfree(pipe_config);
7572 return ERR_PTR(-EINVAL); 7581 return ERR_PTR(-EINVAL);
7573} 7582}
7574 7583
@@ -7834,7 +7843,8 @@ int intel_set_mode(struct drm_crtc *crtc,
7834{ 7843{
7835 struct drm_device *dev = crtc->dev; 7844 struct drm_device *dev = crtc->dev;
7836 drm_i915_private_t *dev_priv = dev->dev_private; 7845 drm_i915_private_t *dev_priv = dev->dev_private;
7837 struct drm_display_mode *adjusted_mode, *saved_mode, *saved_hwmode; 7846 struct drm_display_mode *saved_mode, *saved_hwmode;
7847 struct intel_crtc_config *pipe_config = NULL;
7838 struct intel_crtc *intel_crtc; 7848 struct intel_crtc *intel_crtc;
7839 unsigned disable_pipes, prepare_pipes, modeset_pipes; 7849 unsigned disable_pipes, prepare_pipes, modeset_pipes;
7840 int ret = 0; 7850 int ret = 0;
@@ -7861,11 +7871,12 @@ int intel_set_mode(struct drm_crtc *crtc,
7861 * Hence simply check whether any bit is set in modeset_pipes in all the 7871 * Hence simply check whether any bit is set in modeset_pipes in all the
7862 * pieces of code that are not yet converted to deal with mutliple crtcs 7872 * pieces of code that are not yet converted to deal with mutliple crtcs
7863 * changing their mode at the same time. */ 7873 * changing their mode at the same time. */
7864 adjusted_mode = NULL;
7865 if (modeset_pipes) { 7874 if (modeset_pipes) {
7866 adjusted_mode = intel_modeset_adjusted_mode(crtc, mode); 7875 pipe_config = intel_modeset_pipe_config(crtc, mode);
7867 if (IS_ERR(adjusted_mode)) { 7876 if (IS_ERR(pipe_config)) {
7868 ret = PTR_ERR(adjusted_mode); 7877 ret = PTR_ERR(pipe_config);
7878 pipe_config = NULL;
7879
7869 goto out; 7880 goto out;
7870 } 7881 }
7871 } 7882 }
@@ -7878,8 +7889,12 @@ int intel_set_mode(struct drm_crtc *crtc,
7878 /* crtc->mode is already used by the ->mode_set callbacks, hence we need 7889 /* crtc->mode is already used by the ->mode_set callbacks, hence we need
7879 * to set it here already despite that we pass it down the callchain. 7890 * to set it here already despite that we pass it down the callchain.
7880 */ 7891 */
7881 if (modeset_pipes) 7892 if (modeset_pipes) {
7882 crtc->mode = *mode; 7893 crtc->mode = *mode;
7894 /* mode_set/enable/disable functions rely on a correct pipe
7895 * config. */
7896 to_intel_crtc(crtc)->config = *pipe_config;
7897 }
7883 7898
7884 /* Only after disabling all output pipelines that will be changed can we 7899 /* Only after disabling all output pipelines that will be changed can we
7885 * update the the output configuration. */ 7900 * update the the output configuration. */
@@ -7893,7 +7908,6 @@ int intel_set_mode(struct drm_crtc *crtc,
7893 */ 7908 */
7894 for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) { 7909 for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
7895 ret = intel_crtc_mode_set(&intel_crtc->base, 7910 ret = intel_crtc_mode_set(&intel_crtc->base,
7896 mode, adjusted_mode,
7897 x, y, fb); 7911 x, y, fb);
7898 if (ret) 7912 if (ret)
7899 goto done; 7913 goto done;
@@ -7905,7 +7919,7 @@ int intel_set_mode(struct drm_crtc *crtc,
7905 7919
7906 if (modeset_pipes) { 7920 if (modeset_pipes) {
7907 /* Store real post-adjustment hardware mode. */ 7921 /* Store real post-adjustment hardware mode. */
7908 crtc->hwmode = *adjusted_mode; 7922 crtc->hwmode = pipe_config->adjusted_mode;
7909 7923
7910 /* Calculate and store various constants which 7924 /* Calculate and store various constants which
7911 * are later needed by vblank and swap-completion 7925 * are later needed by vblank and swap-completion
@@ -7916,7 +7930,6 @@ int intel_set_mode(struct drm_crtc *crtc,
7916 7930
7917 /* FIXME: add subpixel order */ 7931 /* FIXME: add subpixel order */
7918done: 7932done:
7919 drm_mode_destroy(dev, adjusted_mode);
7920 if (ret && crtc->enabled) { 7933 if (ret && crtc->enabled) {
7921 crtc->hwmode = *saved_hwmode; 7934 crtc->hwmode = *saved_hwmode;
7922 crtc->mode = *saved_mode; 7935 crtc->mode = *saved_mode;
@@ -7925,6 +7938,7 @@ done:
7925 } 7938 }
7926 7939
7927out: 7940out:
7941 kfree(pipe_config);
7928 kfree(saved_mode); 7942 kfree(saved_mode);
7929 return ret; 7943 return ret;
7930} 7944}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 54bc2ea61fa9..4cc66251fd34 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -200,6 +200,11 @@ struct intel_connector {
200 struct edid *edid; 200 struct edid *edid;
201}; 201};
202 202
203struct intel_crtc_config {
204 struct drm_display_mode requested_mode;
205 struct drm_display_mode adjusted_mode;
206};
207
203struct intel_crtc { 208struct intel_crtc {
204 struct drm_crtc base; 209 struct drm_crtc base;
205 enum pipe pipe; 210 enum pipe pipe;
@@ -233,6 +238,8 @@ struct intel_crtc {
233 bool cursor_visible; 238 bool cursor_visible;
234 unsigned int bpp; 239 unsigned int bpp;
235 240
241 struct intel_crtc_config config;
242
236 /* We can share PLLs across outputs if the timings match */ 243 /* We can share PLLs across outputs if the timings match */
237 struct intel_pch_pll *pch_pll; 244 struct intel_pch_pll *pch_pll;
238 uint32_t ddi_pll_sel; 245 uint32_t ddi_pll_sel;