diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 19 |
3 files changed, 26 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1e3090978882..673d91a3e1f2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -3987,7 +3987,7 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc, | |||
3987 | /* All interlaced capable intel hw wants timings in frames. Note though | 3987 | /* All interlaced capable intel hw wants timings in frames. Note though |
3988 | * that intel_lvds_mode_fixup does some funny tricks with the crtc | 3988 | * that intel_lvds_mode_fixup does some funny tricks with the crtc |
3989 | * timings, so we need to be careful not to clobber these.*/ | 3989 | * timings, so we need to be careful not to clobber these.*/ |
3990 | if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET)) | 3990 | if (!pipe_config->timings_set) |
3991 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 3991 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
3992 | 3992 | ||
3993 | /* WaPruneModeWithIncorrectHsyncOffset: Cantiga+ cannot handle modes | 3993 | /* WaPruneModeWithIncorrectHsyncOffset: Cantiga+ cannot handle modes |
@@ -7560,6 +7560,16 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, | |||
7560 | 7560 | ||
7561 | if (&encoder->new_crtc->base != crtc) | 7561 | if (&encoder->new_crtc->base != crtc) |
7562 | continue; | 7562 | continue; |
7563 | |||
7564 | if (encoder->compute_config) { | ||
7565 | if (!(encoder->compute_config(encoder, pipe_config))) { | ||
7566 | DRM_DEBUG_KMS("Encoder config failure\n"); | ||
7567 | goto fail; | ||
7568 | } | ||
7569 | |||
7570 | continue; | ||
7571 | } | ||
7572 | |||
7563 | encoder_funcs = encoder->base.helper_private; | 7573 | encoder_funcs = encoder->base.helper_private; |
7564 | if (!(encoder_funcs->mode_fixup(&encoder->base, | 7574 | if (!(encoder_funcs->mode_fixup(&encoder->base, |
7565 | &pipe_config->requested_mode, | 7575 | &pipe_config->requested_mode, |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4cc66251fd34..054032ae2856 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -105,10 +105,6 @@ | |||
105 | #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) | 105 | #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) |
106 | #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) | 106 | #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) |
107 | #define INTEL_MODE_DP_FORCE_6BPC (0x10) | 107 | #define INTEL_MODE_DP_FORCE_6BPC (0x10) |
108 | /* This flag must be set by the encoder's mode_fixup if it changes the crtc | ||
109 | * timings in the mode to prevent the crtc fixup from overwriting them. | ||
110 | * Currently only lvds needs that. */ | ||
111 | #define INTEL_MODE_CRTC_TIMINGS_SET (0x20) | ||
112 | /* | 108 | /* |
113 | * Set when limited 16-235 (as opposed to full 0-255) RGB color range is | 109 | * Set when limited 16-235 (as opposed to full 0-255) RGB color range is |
114 | * to be used. | 110 | * to be used. |
@@ -158,6 +154,8 @@ struct intel_encoder { | |||
158 | bool cloneable; | 154 | bool cloneable; |
159 | bool connectors_active; | 155 | bool connectors_active; |
160 | void (*hot_plug)(struct intel_encoder *); | 156 | void (*hot_plug)(struct intel_encoder *); |
157 | bool (*compute_config)(struct intel_encoder *, | ||
158 | struct intel_crtc_config *); | ||
161 | void (*pre_pll_enable)(struct intel_encoder *); | 159 | void (*pre_pll_enable)(struct intel_encoder *); |
162 | void (*pre_enable)(struct intel_encoder *); | 160 | void (*pre_enable)(struct intel_encoder *); |
163 | void (*enable)(struct intel_encoder *); | 161 | void (*enable)(struct intel_encoder *); |
@@ -203,6 +201,10 @@ struct intel_connector { | |||
203 | struct intel_crtc_config { | 201 | struct intel_crtc_config { |
204 | struct drm_display_mode requested_mode; | 202 | struct drm_display_mode requested_mode; |
205 | struct drm_display_mode adjusted_mode; | 203 | struct drm_display_mode adjusted_mode; |
204 | /* This flag must be set by the encoder's compute_config callback if it | ||
205 | * changes the crtc timings in the mode to prevent the crtc fixup from | ||
206 | * overwriting them. Currently only lvds needs that. */ | ||
207 | bool timings_set; | ||
206 | }; | 208 | }; |
207 | 209 | ||
208 | struct intel_crtc { | 210 | struct intel_crtc { |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 6ff145f97e90..a2c516c116cb 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -261,8 +261,6 @@ centre_horizontally(struct drm_display_mode *mode, | |||
261 | 261 | ||
262 | mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; | 262 | mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; |
263 | mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; | 263 | mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; |
264 | |||
265 | mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; | ||
266 | } | 264 | } |
267 | 265 | ||
268 | static void | 266 | static void |
@@ -284,8 +282,6 @@ centre_vertically(struct drm_display_mode *mode, | |||
284 | 282 | ||
285 | mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; | 283 | mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; |
286 | mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; | 284 | mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; |
287 | |||
288 | mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; | ||
289 | } | 285 | } |
290 | 286 | ||
291 | static inline u32 panel_fitter_scaling(u32 source, u32 target) | 287 | static inline u32 panel_fitter_scaling(u32 source, u32 target) |
@@ -301,15 +297,17 @@ static inline u32 panel_fitter_scaling(u32 source, u32 target) | |||
301 | return (FACTOR * ratio + FACTOR/2) / FACTOR; | 297 | return (FACTOR * ratio + FACTOR/2) / FACTOR; |
302 | } | 298 | } |
303 | 299 | ||
304 | static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | 300 | static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, |
305 | const struct drm_display_mode *mode, | 301 | struct intel_crtc_config *pipe_config) |
306 | struct drm_display_mode *adjusted_mode) | ||
307 | { | 302 | { |
308 | struct drm_device *dev = encoder->dev; | 303 | struct drm_device *dev = intel_encoder->base.dev; |
309 | struct drm_i915_private *dev_priv = dev->dev_private; | 304 | struct drm_i915_private *dev_priv = dev->dev_private; |
310 | struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder); | 305 | struct intel_lvds_encoder *lvds_encoder = |
306 | to_lvds_encoder(&intel_encoder->base); | ||
311 | struct intel_connector *intel_connector = | 307 | struct intel_connector *intel_connector = |
312 | &lvds_encoder->attached_connector->base; | 308 | &lvds_encoder->attached_connector->base; |
309 | struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; | ||
310 | struct drm_display_mode *mode = &pipe_config->requested_mode; | ||
313 | struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc; | 311 | struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc; |
314 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; | 312 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; |
315 | int pipe; | 313 | int pipe; |
@@ -359,6 +357,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
359 | I915_WRITE(BCLRPAT(pipe), 0); | 357 | I915_WRITE(BCLRPAT(pipe), 0); |
360 | 358 | ||
361 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 359 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
360 | pipe_config->timings_set = true; | ||
362 | 361 | ||
363 | switch (intel_connector->panel.fitting_mode) { | 362 | switch (intel_connector->panel.fitting_mode) { |
364 | case DRM_MODE_SCALE_CENTER: | 363 | case DRM_MODE_SCALE_CENTER: |
@@ -661,7 +660,6 @@ static int intel_lvds_set_property(struct drm_connector *connector, | |||
661 | } | 660 | } |
662 | 661 | ||
663 | static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = { | 662 | static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = { |
664 | .mode_fixup = intel_lvds_mode_fixup, | ||
665 | .mode_set = intel_lvds_mode_set, | 663 | .mode_set = intel_lvds_mode_set, |
666 | }; | 664 | }; |
667 | 665 | ||
@@ -1105,6 +1103,7 @@ bool intel_lvds_init(struct drm_device *dev) | |||
1105 | intel_encoder->enable = intel_enable_lvds; | 1103 | intel_encoder->enable = intel_enable_lvds; |
1106 | intel_encoder->pre_enable = intel_pre_enable_lvds; | 1104 | intel_encoder->pre_enable = intel_pre_enable_lvds; |
1107 | intel_encoder->pre_pll_enable = intel_pre_pll_enable_lvds; | 1105 | intel_encoder->pre_pll_enable = intel_pre_pll_enable_lvds; |
1106 | intel_encoder->compute_config = intel_lvds_compute_config; | ||
1108 | intel_encoder->disable = intel_disable_lvds; | 1107 | intel_encoder->disable = intel_disable_lvds; |
1109 | intel_encoder->get_hw_state = intel_lvds_get_hw_state; | 1108 | intel_encoder->get_hw_state = intel_lvds_get_hw_state; |
1110 | intel_connector->get_hw_state = intel_connector_get_hw_state; | 1109 | intel_connector->get_hw_state = intel_connector_get_hw_state; |