diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-03-26 19:44:53 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-03-27 19:50:06 -0400 |
commit | 6cc5f341b5830541a1b6945435ca90c69b1b8b21 (patch) | |
tree | 74e1cfaa03efaa293c3ef11acd37567361923f6d /drivers/gpu | |
parent | 7ae892337e3357e40c8252f4226083d2e6211847 (diff) |
drm/i915: add pipe_config->pixel_multiplier
Used by SDVO (and hopefully, eventually HDMI, if we ever get around
to fixing up the low dotclock CEA modes ...).
This required adding a new encoder->mode_set callback to be able to
pass around the intel_crtc_config.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 80 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 39 |
3 files changed, 66 insertions, 72 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 673d91a3e1f2..7335ec2733de 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -4337,14 +4337,15 @@ static void i9xx_update_pll_dividers(struct drm_crtc *crtc, | |||
4337 | } | 4337 | } |
4338 | 4338 | ||
4339 | static void vlv_update_pll(struct drm_crtc *crtc, | 4339 | static void vlv_update_pll(struct drm_crtc *crtc, |
4340 | struct drm_display_mode *mode, | ||
4341 | struct drm_display_mode *adjusted_mode, | ||
4342 | intel_clock_t *clock, intel_clock_t *reduced_clock, | 4340 | intel_clock_t *clock, intel_clock_t *reduced_clock, |
4343 | int num_connectors) | 4341 | int num_connectors) |
4344 | { | 4342 | { |
4345 | struct drm_device *dev = crtc->dev; | 4343 | struct drm_device *dev = crtc->dev; |
4346 | struct drm_i915_private *dev_priv = dev->dev_private; | 4344 | struct drm_i915_private *dev_priv = dev->dev_private; |
4347 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 4345 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
4346 | struct drm_display_mode *adjusted_mode = | ||
4347 | &intel_crtc->config.adjusted_mode; | ||
4348 | struct drm_display_mode *mode = &intel_crtc->config.requested_mode; | ||
4348 | int pipe = intel_crtc->pipe; | 4349 | int pipe = intel_crtc->pipe; |
4349 | u32 dpll, mdiv, pdiv; | 4350 | u32 dpll, mdiv, pdiv; |
4350 | u32 bestn, bestm1, bestm2, bestp1, bestp2; | 4351 | u32 bestn, bestm1, bestm2, bestp1, bestp2; |
@@ -4411,11 +4412,11 @@ static void vlv_update_pll(struct drm_crtc *crtc, | |||
4411 | 4412 | ||
4412 | temp = 0; | 4413 | temp = 0; |
4413 | if (is_sdvo) { | 4414 | if (is_sdvo) { |
4414 | temp = intel_mode_get_pixel_multiplier(adjusted_mode); | 4415 | temp = 0; |
4415 | if (temp > 1) | 4416 | if (intel_crtc->config.pixel_multiplier > 1) { |
4416 | temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; | 4417 | temp = (intel_crtc->config.pixel_multiplier - 1) |
4417 | else | 4418 | << DPLL_MD_UDI_MULTIPLIER_SHIFT; |
4418 | temp = 0; | 4419 | } |
4419 | } | 4420 | } |
4420 | I915_WRITE(DPLL_MD(pipe), temp); | 4421 | I915_WRITE(DPLL_MD(pipe), temp); |
4421 | POSTING_READ(DPLL_MD(pipe)); | 4422 | POSTING_READ(DPLL_MD(pipe)); |
@@ -4441,14 +4442,15 @@ static void vlv_update_pll(struct drm_crtc *crtc, | |||
4441 | } | 4442 | } |
4442 | 4443 | ||
4443 | static void i9xx_update_pll(struct drm_crtc *crtc, | 4444 | static void i9xx_update_pll(struct drm_crtc *crtc, |
4444 | struct drm_display_mode *mode, | ||
4445 | struct drm_display_mode *adjusted_mode, | ||
4446 | intel_clock_t *clock, intel_clock_t *reduced_clock, | 4445 | intel_clock_t *clock, intel_clock_t *reduced_clock, |
4447 | int num_connectors) | 4446 | int num_connectors) |
4448 | { | 4447 | { |
4449 | struct drm_device *dev = crtc->dev; | 4448 | struct drm_device *dev = crtc->dev; |
4450 | struct drm_i915_private *dev_priv = dev->dev_private; | 4449 | struct drm_i915_private *dev_priv = dev->dev_private; |
4451 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 4450 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
4451 | struct drm_display_mode *adjusted_mode = | ||
4452 | &intel_crtc->config.adjusted_mode; | ||
4453 | struct drm_display_mode *mode = &intel_crtc->config.requested_mode; | ||
4452 | struct intel_encoder *encoder; | 4454 | struct intel_encoder *encoder; |
4453 | int pipe = intel_crtc->pipe; | 4455 | int pipe = intel_crtc->pipe; |
4454 | u32 dpll; | 4456 | u32 dpll; |
@@ -4465,11 +4467,12 @@ static void i9xx_update_pll(struct drm_crtc *crtc, | |||
4465 | dpll |= DPLLB_MODE_LVDS; | 4467 | dpll |= DPLLB_MODE_LVDS; |
4466 | else | 4468 | else |
4467 | dpll |= DPLLB_MODE_DAC_SERIAL; | 4469 | dpll |= DPLLB_MODE_DAC_SERIAL; |
4470 | |||
4468 | if (is_sdvo) { | 4471 | if (is_sdvo) { |
4469 | int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); | 4472 | if ((intel_crtc->config.pixel_multiplier > 1) && |
4470 | if (pixel_multiplier > 1) { | 4473 | (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))) { |
4471 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | 4474 | dpll |= (intel_crtc->config.pixel_multiplier - 1) |
4472 | dpll |= (pixel_multiplier - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; | 4475 | << SDVO_MULTIPLIER_SHIFT_HIRES; |
4473 | } | 4476 | } |
4474 | dpll |= DPLL_DVO_HIGH_SPEED; | 4477 | dpll |= DPLL_DVO_HIGH_SPEED; |
4475 | } | 4478 | } |
@@ -4534,11 +4537,11 @@ static void i9xx_update_pll(struct drm_crtc *crtc, | |||
4534 | if (INTEL_INFO(dev)->gen >= 4) { | 4537 | if (INTEL_INFO(dev)->gen >= 4) { |
4535 | u32 temp = 0; | 4538 | u32 temp = 0; |
4536 | if (is_sdvo) { | 4539 | if (is_sdvo) { |
4537 | temp = intel_mode_get_pixel_multiplier(adjusted_mode); | 4540 | temp = 0; |
4538 | if (temp > 1) | 4541 | if (intel_crtc->config.pixel_multiplier > 1) { |
4539 | temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; | 4542 | temp = (intel_crtc->config.pixel_multiplier - 1) |
4540 | else | 4543 | << DPLL_MD_UDI_MULTIPLIER_SHIFT; |
4541 | temp = 0; | 4544 | } |
4542 | } | 4545 | } |
4543 | I915_WRITE(DPLL_MD(pipe), temp); | 4546 | I915_WRITE(DPLL_MD(pipe), temp); |
4544 | } else { | 4547 | } else { |
@@ -4748,11 +4751,11 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
4748 | has_reduced_clock ? &reduced_clock : NULL, | 4751 | has_reduced_clock ? &reduced_clock : NULL, |
4749 | num_connectors); | 4752 | num_connectors); |
4750 | else if (IS_VALLEYVIEW(dev)) | 4753 | else if (IS_VALLEYVIEW(dev)) |
4751 | vlv_update_pll(crtc, mode, adjusted_mode, &clock, | 4754 | vlv_update_pll(crtc, &clock, |
4752 | has_reduced_clock ? &reduced_clock : NULL, | 4755 | has_reduced_clock ? &reduced_clock : NULL, |
4753 | num_connectors); | 4756 | num_connectors); |
4754 | else | 4757 | else |
4755 | i9xx_update_pll(crtc, mode, adjusted_mode, &clock, | 4758 | i9xx_update_pll(crtc, &clock, |
4756 | has_reduced_clock ? &reduced_clock : NULL, | 4759 | has_reduced_clock ? &reduced_clock : NULL, |
4757 | num_connectors); | 4760 | num_connectors); |
4758 | 4761 | ||
@@ -5466,17 +5469,18 @@ int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp) | |||
5466 | return bps / (link_bw * 8) + 1; | 5469 | return bps / (link_bw * 8) + 1; |
5467 | } | 5470 | } |
5468 | 5471 | ||
5469 | static void ironlake_set_m_n(struct drm_crtc *crtc, | 5472 | static void ironlake_set_m_n(struct drm_crtc *crtc) |
5470 | struct drm_display_mode *mode, | ||
5471 | struct drm_display_mode *adjusted_mode) | ||
5472 | { | 5473 | { |
5473 | struct drm_device *dev = crtc->dev; | 5474 | struct drm_device *dev = crtc->dev; |
5474 | struct drm_i915_private *dev_priv = dev->dev_private; | 5475 | struct drm_i915_private *dev_priv = dev->dev_private; |
5475 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 5476 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
5477 | struct drm_display_mode *adjusted_mode = | ||
5478 | &intel_crtc->config.adjusted_mode; | ||
5479 | struct drm_display_mode *mode = &intel_crtc->config.requested_mode; | ||
5476 | enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder; | 5480 | enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder; |
5477 | struct intel_encoder *intel_encoder, *edp_encoder = NULL; | 5481 | struct intel_encoder *intel_encoder, *edp_encoder = NULL; |
5478 | struct intel_link_m_n m_n = {0}; | 5482 | struct intel_link_m_n m_n = {0}; |
5479 | int target_clock, pixel_multiplier, lane, link_bw; | 5483 | int target_clock, lane, link_bw; |
5480 | bool is_dp = false, is_cpu_edp = false; | 5484 | bool is_dp = false, is_cpu_edp = false; |
5481 | 5485 | ||
5482 | for_each_encoder_on_crtc(dev, crtc, intel_encoder) { | 5486 | for_each_encoder_on_crtc(dev, crtc, intel_encoder) { |
@@ -5494,7 +5498,6 @@ static void ironlake_set_m_n(struct drm_crtc *crtc, | |||
5494 | } | 5498 | } |
5495 | 5499 | ||
5496 | /* FDI link */ | 5500 | /* FDI link */ |
5497 | pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); | ||
5498 | lane = 0; | 5501 | lane = 0; |
5499 | /* CPU eDP doesn't require FDI link, so just set DP M/N | 5502 | /* CPU eDP doesn't require FDI link, so just set DP M/N |
5500 | according to current link config */ | 5503 | according to current link config */ |
@@ -5525,8 +5528,8 @@ static void ironlake_set_m_n(struct drm_crtc *crtc, | |||
5525 | 5528 | ||
5526 | intel_crtc->fdi_lanes = lane; | 5529 | intel_crtc->fdi_lanes = lane; |
5527 | 5530 | ||
5528 | if (pixel_multiplier > 1) | 5531 | if (intel_crtc->config.pixel_multiplier > 1) |
5529 | link_bw *= pixel_multiplier; | 5532 | link_bw *= intel_crtc->config.pixel_multiplier; |
5530 | intel_link_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw, &m_n); | 5533 | intel_link_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw, &m_n); |
5531 | 5534 | ||
5532 | I915_WRITE(PIPE_DATA_M1(cpu_transcoder), TU_SIZE(m_n.tu) | m_n.gmch_m); | 5535 | I915_WRITE(PIPE_DATA_M1(cpu_transcoder), TU_SIZE(m_n.tu) | m_n.gmch_m); |
@@ -5536,7 +5539,6 @@ static void ironlake_set_m_n(struct drm_crtc *crtc, | |||
5536 | } | 5539 | } |
5537 | 5540 | ||
5538 | static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, | 5541 | static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, |
5539 | struct drm_display_mode *adjusted_mode, | ||
5540 | intel_clock_t *clock, u32 fp) | 5542 | intel_clock_t *clock, u32 fp) |
5541 | { | 5543 | { |
5542 | struct drm_crtc *crtc = &intel_crtc->base; | 5544 | struct drm_crtc *crtc = &intel_crtc->base; |
@@ -5544,7 +5546,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, | |||
5544 | struct drm_i915_private *dev_priv = dev->dev_private; | 5546 | struct drm_i915_private *dev_priv = dev->dev_private; |
5545 | struct intel_encoder *intel_encoder; | 5547 | struct intel_encoder *intel_encoder; |
5546 | uint32_t dpll; | 5548 | uint32_t dpll; |
5547 | int factor, pixel_multiplier, num_connectors = 0; | 5549 | int factor, num_connectors = 0; |
5548 | bool is_lvds = false, is_sdvo = false, is_tv = false; | 5550 | bool is_lvds = false, is_sdvo = false, is_tv = false; |
5549 | bool is_dp = false, is_cpu_edp = false; | 5551 | bool is_dp = false, is_cpu_edp = false; |
5550 | 5552 | ||
@@ -5595,9 +5597,9 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, | |||
5595 | else | 5597 | else |
5596 | dpll |= DPLLB_MODE_DAC_SERIAL; | 5598 | dpll |= DPLLB_MODE_DAC_SERIAL; |
5597 | if (is_sdvo) { | 5599 | if (is_sdvo) { |
5598 | pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); | 5600 | if (intel_crtc->config.pixel_multiplier > 1) { |
5599 | if (pixel_multiplier > 1) { | 5601 | dpll |= (intel_crtc->config.pixel_multiplier - 1) |
5600 | dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; | 5602 | << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; |
5601 | } | 5603 | } |
5602 | dpll |= DPLL_DVO_HIGH_SPEED; | 5604 | dpll |= DPLL_DVO_HIGH_SPEED; |
5603 | } | 5605 | } |
@@ -5701,7 +5703,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
5701 | fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | | 5703 | fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | |
5702 | reduced_clock.m2; | 5704 | reduced_clock.m2; |
5703 | 5705 | ||
5704 | dpll = ironlake_compute_dpll(intel_crtc, adjusted_mode, &clock, fp); | 5706 | dpll = ironlake_compute_dpll(intel_crtc, &clock, fp); |
5705 | 5707 | ||
5706 | DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe); | 5708 | DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe); |
5707 | drm_mode_debug_printmodeline(mode); | 5709 | drm_mode_debug_printmodeline(mode); |
@@ -5755,7 +5757,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
5755 | 5757 | ||
5756 | /* Note, this also computes intel_crtc->fdi_lanes which is used below in | 5758 | /* Note, this also computes intel_crtc->fdi_lanes which is used below in |
5757 | * ironlake_check_fdi_lanes. */ | 5759 | * ironlake_check_fdi_lanes. */ |
5758 | ironlake_set_m_n(crtc, mode, adjusted_mode); | 5760 | ironlake_set_m_n(crtc); |
5759 | 5761 | ||
5760 | fdi_config_ok = ironlake_check_fdi_lanes(intel_crtc); | 5762 | fdi_config_ok = ironlake_check_fdi_lanes(intel_crtc); |
5761 | 5763 | ||
@@ -5871,7 +5873,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, | |||
5871 | intel_set_pipe_timings(intel_crtc, mode, adjusted_mode); | 5873 | intel_set_pipe_timings(intel_crtc, mode, adjusted_mode); |
5872 | 5874 | ||
5873 | if (!is_dp || is_cpu_edp) | 5875 | if (!is_dp || is_cpu_edp) |
5874 | ironlake_set_m_n(crtc, mode, adjusted_mode); | 5876 | ironlake_set_m_n(crtc); |
5875 | 5877 | ||
5876 | haswell_set_pipeconf(crtc, adjusted_mode, dither); | 5878 | haswell_set_pipeconf(crtc, adjusted_mode, dither); |
5877 | 5879 | ||
@@ -5924,8 +5926,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
5924 | encoder->base.base.id, | 5926 | encoder->base.base.id, |
5925 | drm_get_encoder_name(&encoder->base), | 5927 | drm_get_encoder_name(&encoder->base), |
5926 | mode->base.id, mode->name); | 5928 | mode->base.id, mode->name); |
5927 | encoder_funcs = encoder->base.helper_private; | 5929 | if (encoder->mode_set) { |
5928 | encoder_funcs->mode_set(&encoder->base, mode, adjusted_mode); | 5930 | encoder->mode_set(encoder); |
5931 | } else { | ||
5932 | encoder_funcs = encoder->base.helper_private; | ||
5933 | encoder_funcs->mode_set(&encoder->base, mode, adjusted_mode); | ||
5934 | } | ||
5929 | } | 5935 | } |
5930 | 5936 | ||
5931 | return 0; | 5937 | return 0; |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 054032ae2856..f0e5462c665b 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -102,8 +102,6 @@ | |||
102 | #define INTEL_DVO_CHIP_TVOUT 4 | 102 | #define INTEL_DVO_CHIP_TVOUT 4 |
103 | 103 | ||
104 | /* drm_display_mode->private_flags */ | 104 | /* drm_display_mode->private_flags */ |
105 | #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) | ||
106 | #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) | ||
107 | #define INTEL_MODE_DP_FORCE_6BPC (0x10) | 105 | #define INTEL_MODE_DP_FORCE_6BPC (0x10) |
108 | /* | 106 | /* |
109 | * Set when limited 16-235 (as opposed to full 0-255) RGB color range is | 107 | * Set when limited 16-235 (as opposed to full 0-255) RGB color range is |
@@ -111,20 +109,6 @@ | |||
111 | */ | 109 | */ |
112 | #define INTEL_MODE_LIMITED_COLOR_RANGE (0x40) | 110 | #define INTEL_MODE_LIMITED_COLOR_RANGE (0x40) |
113 | 111 | ||
114 | static inline void | ||
115 | intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, | ||
116 | int multiplier) | ||
117 | { | ||
118 | mode->clock *= multiplier; | ||
119 | mode->private_flags |= multiplier; | ||
120 | } | ||
121 | |||
122 | static inline int | ||
123 | intel_mode_get_pixel_multiplier(const struct drm_display_mode *mode) | ||
124 | { | ||
125 | return (mode->private_flags & INTEL_MODE_PIXEL_MULTIPLIER_MASK) >> INTEL_MODE_PIXEL_MULTIPLIER_SHIFT; | ||
126 | } | ||
127 | |||
128 | struct intel_framebuffer { | 112 | struct intel_framebuffer { |
129 | struct drm_framebuffer base; | 113 | struct drm_framebuffer base; |
130 | struct drm_i915_gem_object *obj; | 114 | struct drm_i915_gem_object *obj; |
@@ -159,6 +143,7 @@ struct intel_encoder { | |||
159 | void (*pre_pll_enable)(struct intel_encoder *); | 143 | void (*pre_pll_enable)(struct intel_encoder *); |
160 | void (*pre_enable)(struct intel_encoder *); | 144 | void (*pre_enable)(struct intel_encoder *); |
161 | void (*enable)(struct intel_encoder *); | 145 | void (*enable)(struct intel_encoder *); |
146 | void (*mode_set)(struct intel_encoder *intel_encoder); | ||
162 | void (*disable)(struct intel_encoder *); | 147 | void (*disable)(struct intel_encoder *); |
163 | void (*post_disable)(struct intel_encoder *); | 148 | void (*post_disable)(struct intel_encoder *); |
164 | /* Read out the current hw state of this connector, returning true if | 149 | /* Read out the current hw state of this connector, returning true if |
@@ -205,6 +190,8 @@ struct intel_crtc_config { | |||
205 | * changes the crtc timings in the mode to prevent the crtc fixup from | 190 | * changes the crtc timings in the mode to prevent the crtc fixup from |
206 | * overwriting them. Currently only lvds needs that. */ | 191 | * overwriting them. Currently only lvds needs that. */ |
207 | bool timings_set; | 192 | bool timings_set; |
193 | /* Used by SDVO (and if we ever fix it, HDMI). */ | ||
194 | unsigned pixel_multiplier; | ||
208 | }; | 195 | }; |
209 | 196 | ||
210 | struct intel_crtc { | 197 | struct intel_crtc { |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 8fdd8f82f09d..4d9fedec530a 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -788,7 +788,6 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | |||
788 | v_sync_offset = mode->vsync_start - mode->vdisplay; | 788 | v_sync_offset = mode->vsync_start - mode->vdisplay; |
789 | 789 | ||
790 | mode_clock = mode->clock; | 790 | mode_clock = mode->clock; |
791 | mode_clock /= intel_mode_get_pixel_multiplier(mode) ?: 1; | ||
792 | mode_clock /= 10; | 791 | mode_clock /= 10; |
793 | dtd->part1.clock = mode_clock; | 792 | dtd->part1.clock = mode_clock; |
794 | 793 | ||
@@ -1041,12 +1040,12 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo, | |||
1041 | return true; | 1040 | return true; |
1042 | } | 1041 | } |
1043 | 1042 | ||
1044 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | 1043 | static bool intel_sdvo_compute_config(struct intel_encoder *encoder, |
1045 | const struct drm_display_mode *mode, | 1044 | struct intel_crtc_config *pipe_config) |
1046 | struct drm_display_mode *adjusted_mode) | ||
1047 | { | 1045 | { |
1048 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); | 1046 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); |
1049 | int multiplier; | 1047 | struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; |
1048 | struct drm_display_mode *mode = &pipe_config->requested_mode; | ||
1050 | 1049 | ||
1051 | /* We need to construct preferred input timings based on our | 1050 | /* We need to construct preferred input timings based on our |
1052 | * output timings. To do that, we have to set the output | 1051 | * output timings. To do that, we have to set the output |
@@ -1073,8 +1072,9 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1073 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | 1072 | /* Make the CRTC code factor in the SDVO pixel multiplier. The |
1074 | * SDVO device will factor out the multiplier during mode_set. | 1073 | * SDVO device will factor out the multiplier during mode_set. |
1075 | */ | 1074 | */ |
1076 | multiplier = intel_sdvo_get_pixel_multiplier(adjusted_mode); | 1075 | pipe_config->pixel_multiplier = |
1077 | intel_mode_set_pixel_multiplier(adjusted_mode, multiplier); | 1076 | intel_sdvo_get_pixel_multiplier(adjusted_mode); |
1077 | adjusted_mode->clock *= pipe_config->pixel_multiplier; | ||
1078 | 1078 | ||
1079 | if (intel_sdvo->color_range_auto) { | 1079 | if (intel_sdvo->color_range_auto) { |
1080 | /* See CEA-861-E - 5.1 Default Encoding Parameters */ | 1080 | /* See CEA-861-E - 5.1 Default Encoding Parameters */ |
@@ -1093,19 +1093,19 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1093 | return true; | 1093 | return true; |
1094 | } | 1094 | } |
1095 | 1095 | ||
1096 | static void intel_sdvo_mode_set(struct drm_encoder *encoder, | 1096 | static void intel_sdvo_mode_set(struct intel_encoder *intel_encoder) |
1097 | struct drm_display_mode *mode, | ||
1098 | struct drm_display_mode *adjusted_mode) | ||
1099 | { | 1097 | { |
1100 | struct drm_device *dev = encoder->dev; | 1098 | struct drm_device *dev = intel_encoder->base.dev; |
1101 | struct drm_i915_private *dev_priv = dev->dev_private; | 1099 | struct drm_i915_private *dev_priv = dev->dev_private; |
1102 | struct drm_crtc *crtc = encoder->crtc; | 1100 | struct drm_crtc *crtc = intel_encoder->base.crtc; |
1103 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1101 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1104 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); | 1102 | struct drm_display_mode *adjusted_mode = |
1103 | &intel_crtc->config.adjusted_mode; | ||
1104 | struct drm_display_mode *mode = &intel_crtc->config.requested_mode; | ||
1105 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&intel_encoder->base); | ||
1105 | u32 sdvox; | 1106 | u32 sdvox; |
1106 | struct intel_sdvo_in_out_map in_out; | 1107 | struct intel_sdvo_in_out_map in_out; |
1107 | struct intel_sdvo_dtd input_dtd, output_dtd; | 1108 | struct intel_sdvo_dtd input_dtd, output_dtd; |
1108 | int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); | ||
1109 | int rate; | 1109 | int rate; |
1110 | 1110 | ||
1111 | if (!mode) | 1111 | if (!mode) |
@@ -1165,7 +1165,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1165 | DRM_INFO("Setting input timings on %s failed\n", | 1165 | DRM_INFO("Setting input timings on %s failed\n", |
1166 | SDVO_NAME(intel_sdvo)); | 1166 | SDVO_NAME(intel_sdvo)); |
1167 | 1167 | ||
1168 | switch (pixel_multiplier) { | 1168 | switch (intel_crtc->config.pixel_multiplier) { |
1169 | default: | 1169 | default: |
1170 | case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; | 1170 | case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; |
1171 | case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break; | 1171 | case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break; |
@@ -1209,7 +1209,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1209 | } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { | 1209 | } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { |
1210 | /* done in crtc_mode_set as it lives inside the dpll register */ | 1210 | /* done in crtc_mode_set as it lives inside the dpll register */ |
1211 | } else { | 1211 | } else { |
1212 | sdvox |= (pixel_multiplier - 1) << SDVO_PORT_MULTIPLY_SHIFT; | 1212 | sdvox |= (intel_crtc->config.pixel_multiplier - 1) |
1213 | << SDVO_PORT_MULTIPLY_SHIFT; | ||
1213 | } | 1214 | } |
1214 | 1215 | ||
1215 | if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL && | 1216 | if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL && |
@@ -2041,8 +2042,6 @@ done: | |||
2041 | } | 2042 | } |
2042 | 2043 | ||
2043 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { | 2044 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { |
2044 | .mode_fixup = intel_sdvo_mode_fixup, | ||
2045 | .mode_set = intel_sdvo_mode_set, | ||
2046 | }; | 2045 | }; |
2047 | 2046 | ||
2048 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { | 2047 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { |
@@ -2787,7 +2786,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2787 | 2786 | ||
2788 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); | 2787 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); |
2789 | 2788 | ||
2789 | intel_encoder->compute_config = intel_sdvo_compute_config; | ||
2790 | intel_encoder->disable = intel_disable_sdvo; | 2790 | intel_encoder->disable = intel_disable_sdvo; |
2791 | intel_encoder->mode_set = intel_sdvo_mode_set; | ||
2791 | intel_encoder->enable = intel_enable_sdvo; | 2792 | intel_encoder->enable = intel_enable_sdvo; |
2792 | intel_encoder->get_hw_state = intel_sdvo_get_hw_state; | 2793 | intel_encoder->get_hw_state = intel_sdvo_get_hw_state; |
2793 | 2794 | ||