diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-05-08 07:39:59 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-05-08 07:39:59 -0400 |
commit | 5e13a0c5ec05d382b488a691dfb8af015b1dea1e (patch) | |
tree | 7a06dfa1f7661f8908193f2437b32452520221d3 /drivers/gpu/drm/i915 | |
parent | b615b57a124a4af7b68196bc2fb8acc236041fa2 (diff) | |
parent | 4f256e8aa3eda15c11c3cec3ec5336e1fc579cbd (diff) |
Merge remote-tracking branch 'airlied/drm-core-next' into drm-intel-next-queued
Backmerge of drm-next to resolve a few ugly conflicts and to get a few
fixes from 3.4-rc6 (which drm-next has already merged). Note that this
merge also restricts the stencil cache lra evict policy workaround to
snb (as it should) - I had to frob the code anyway because the
CM0_MASK_SHIFT define died in the masked bit cleanups.
We need the backmerge to get Paulo Zanoni's infoframe regression fix
for gm45 - further bugfixes from him touch the same area and would
needlessly conflict.
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_fb.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_panel.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 34 |
11 files changed, 82 insertions, 49 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4ab57fd752dc..44a5f241b1a0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1021,11 +1021,9 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
1021 | if (obj == NULL) | 1021 | if (obj == NULL) |
1022 | return -ENOENT; | 1022 | return -ENOENT; |
1023 | 1023 | ||
1024 | down_write(¤t->mm->mmap_sem); | 1024 | addr = vm_mmap(obj->filp, 0, args->size, |
1025 | addr = do_mmap(obj->filp, 0, args->size, | ||
1026 | PROT_READ | PROT_WRITE, MAP_SHARED, | 1025 | PROT_READ | PROT_WRITE, MAP_SHARED, |
1027 | args->offset); | 1026 | args->offset); |
1028 | up_write(¤t->mm->mmap_sem); | ||
1029 | drm_gem_object_unreference_unlocked(obj); | 1027 | drm_gem_object_unreference_unlocked(obj); |
1030 | if (IS_ERR((void *)addr)) | 1028 | if (IS_ERR((void *)addr)) |
1031 | return addr; | 1029 | return addr; |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index a46ed26464f4..206b9bbe6979 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -1121,6 +1121,12 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1121 | return -EINVAL; | 1121 | return -EINVAL; |
1122 | } | 1122 | } |
1123 | 1123 | ||
1124 | if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) { | ||
1125 | DRM_DEBUG("execbuf with %u cliprects\n", | ||
1126 | args->num_cliprects); | ||
1127 | return -EINVAL; | ||
1128 | } | ||
1129 | |||
1124 | cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects), | 1130 | cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects), |
1125 | GFP_KERNEL); | 1131 | GFP_KERNEL); |
1126 | if (cliprects == NULL) { | 1132 | if (cliprects == NULL) { |
@@ -1393,7 +1399,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, | |||
1393 | struct drm_i915_gem_exec_object2 *exec2_list = NULL; | 1399 | struct drm_i915_gem_exec_object2 *exec2_list = NULL; |
1394 | int ret; | 1400 | int ret; |
1395 | 1401 | ||
1396 | if (args->buffer_count < 1) { | 1402 | if (args->buffer_count < 1 || |
1403 | args->buffer_count > UINT_MAX / sizeof(*exec2_list)) { | ||
1397 | DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count); | 1404 | DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count); |
1398 | return -EINVAL; | 1405 | return -EINVAL; |
1399 | } | 1406 | } |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 0976137ab79a..417ca99e697d 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -449,8 +449,8 @@ intel_crt_detect(struct drm_connector *connector, bool force) | |||
449 | { | 449 | { |
450 | struct drm_device *dev = connector->dev; | 450 | struct drm_device *dev = connector->dev; |
451 | struct intel_crt *crt = intel_attached_crt(connector); | 451 | struct intel_crt *crt = intel_attached_crt(connector); |
452 | struct drm_crtc *crtc; | ||
453 | enum drm_connector_status status; | 452 | enum drm_connector_status status; |
453 | struct intel_load_detect_pipe tmp; | ||
454 | 454 | ||
455 | if (I915_HAS_HOTPLUG(dev)) { | 455 | if (I915_HAS_HOTPLUG(dev)) { |
456 | if (intel_crt_detect_hotplug(connector)) { | 456 | if (intel_crt_detect_hotplug(connector)) { |
@@ -469,23 +469,16 @@ intel_crt_detect(struct drm_connector *connector, bool force) | |||
469 | return connector->status; | 469 | return connector->status; |
470 | 470 | ||
471 | /* for pre-945g platforms use load detect */ | 471 | /* for pre-945g platforms use load detect */ |
472 | crtc = crt->base.base.crtc; | 472 | if (intel_get_load_detect_pipe(&crt->base, connector, NULL, |
473 | if (crtc && crtc->enabled) { | 473 | &tmp)) { |
474 | status = intel_crt_load_detect(crt); | 474 | if (intel_crt_detect_ddc(connector)) |
475 | } else { | 475 | status = connector_status_connected; |
476 | struct intel_load_detect_pipe tmp; | 476 | else |
477 | 477 | status = intel_crt_load_detect(crt); | |
478 | if (intel_get_load_detect_pipe(&crt->base, connector, NULL, | 478 | intel_release_load_detect_pipe(&crt->base, connector, |
479 | &tmp)) { | 479 | &tmp); |
480 | if (intel_crt_detect_ddc(connector)) | 480 | } else |
481 | status = connector_status_connected; | 481 | status = connector_status_unknown; |
482 | else | ||
483 | status = intel_crt_load_detect(crt); | ||
484 | intel_release_load_detect_pipe(&crt->base, connector, | ||
485 | &tmp); | ||
486 | } else | ||
487 | status = connector_status_unknown; | ||
488 | } | ||
489 | 482 | ||
490 | return status; | 483 | return status; |
491 | } | 484 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e20f8042fddd..6b4139064f9c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -3150,8 +3150,11 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, | |||
3150 | return false; | 3150 | return false; |
3151 | } | 3151 | } |
3152 | 3152 | ||
3153 | /* All interlaced capable intel hw wants timings in frames. */ | 3153 | /* All interlaced capable intel hw wants timings in frames. Note though |
3154 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 3154 | * that intel_lvds_mode_fixup does some funny tricks with the crtc |
3155 | * timings, so we need to be careful not to clobber these.*/ | ||
3156 | if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET)) | ||
3157 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
3155 | 3158 | ||
3156 | return true; | 3159 | return true; |
3157 | } | 3160 | } |
@@ -5441,9 +5444,6 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) | |||
5441 | struct drm_device *dev = crtc->dev; | 5444 | struct drm_device *dev = crtc->dev; |
5442 | drm_i915_private_t *dev_priv = dev->dev_private; | 5445 | drm_i915_private_t *dev_priv = dev->dev_private; |
5443 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 5446 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
5444 | int pipe = intel_crtc->pipe; | ||
5445 | int dpll_reg = DPLL(pipe); | ||
5446 | int dpll = I915_READ(dpll_reg); | ||
5447 | 5447 | ||
5448 | if (HAS_PCH_SPLIT(dev)) | 5448 | if (HAS_PCH_SPLIT(dev)) |
5449 | return; | 5449 | return; |
@@ -5456,10 +5456,15 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) | |||
5456 | * the manual case. | 5456 | * the manual case. |
5457 | */ | 5457 | */ |
5458 | if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) { | 5458 | if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) { |
5459 | int pipe = intel_crtc->pipe; | ||
5460 | int dpll_reg = DPLL(pipe); | ||
5461 | int dpll; | ||
5462 | |||
5459 | DRM_DEBUG_DRIVER("downclocking LVDS\n"); | 5463 | DRM_DEBUG_DRIVER("downclocking LVDS\n"); |
5460 | 5464 | ||
5461 | assert_panel_unlocked(dev_priv, pipe); | 5465 | assert_panel_unlocked(dev_priv, pipe); |
5462 | 5466 | ||
5467 | dpll = I915_READ(dpll_reg); | ||
5463 | dpll |= DISPLAY_RATE_SELECT_FPA1; | 5468 | dpll |= DISPLAY_RATE_SELECT_FPA1; |
5464 | I915_WRITE(dpll_reg, dpll); | 5469 | I915_WRITE(dpll_reg, dpll); |
5465 | intel_wait_for_vblank(dev, pipe); | 5470 | intel_wait_for_vblank(dev, pipe); |
@@ -5854,7 +5859,13 @@ static int intel_gen6_queue_flip(struct drm_device *dev, | |||
5854 | intel_ring_emit(ring, fb->pitches[0] | obj->tiling_mode); | 5859 | intel_ring_emit(ring, fb->pitches[0] | obj->tiling_mode); |
5855 | intel_ring_emit(ring, obj->gtt_offset); | 5860 | intel_ring_emit(ring, obj->gtt_offset); |
5856 | 5861 | ||
5857 | pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; | 5862 | /* Contrary to the suggestions in the documentation, |
5863 | * "Enable Panel Fitter" does not seem to be required when page | ||
5864 | * flipping with a non-native mode, and worse causes a normal | ||
5865 | * modeset to fail. | ||
5866 | * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; | ||
5867 | */ | ||
5868 | pf = 0; | ||
5858 | pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; | 5869 | pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; |
5859 | intel_ring_emit(ring, pf | pipesrc); | 5870 | intel_ring_emit(ring, pf | pipesrc); |
5860 | intel_ring_advance(ring); | 5871 | intel_ring_advance(ring); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index cfec4842e0c4..e5ee166e2faf 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -117,6 +117,10 @@ | |||
117 | #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) | 117 | #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) |
118 | #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) | 118 | #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) |
119 | #define INTEL_MODE_DP_FORCE_6BPC (0x10) | 119 | #define INTEL_MODE_DP_FORCE_6BPC (0x10) |
120 | /* This flag must be set by the encoder's mode_fixup if it changes the crtc | ||
121 | * timings in the mode to prevent the crtc fixup from overwriting them. | ||
122 | * Currently only lvds needs that. */ | ||
123 | #define INTEL_MODE_CRTC_TIMINGS_SET (0x20) | ||
120 | 124 | ||
121 | static inline void | 125 | static inline void |
122 | intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, | 126 | intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 71ef2896be96..bf8690720a0c 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -279,6 +279,8 @@ void intel_fb_restore_mode(struct drm_device *dev) | |||
279 | struct drm_mode_config *config = &dev->mode_config; | 279 | struct drm_mode_config *config = &dev->mode_config; |
280 | struct drm_plane *plane; | 280 | struct drm_plane *plane; |
281 | 281 | ||
282 | mutex_lock(&dev->mode_config.mutex); | ||
283 | |||
282 | ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); | 284 | ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); |
283 | if (ret) | 285 | if (ret) |
284 | DRM_DEBUG("failed to restore crtc mode\n"); | 286 | DRM_DEBUG("failed to restore crtc mode\n"); |
@@ -286,4 +288,6 @@ void intel_fb_restore_mode(struct drm_device *dev) | |||
286 | /* Be sure to shut off any planes that may be active */ | 288 | /* Be sure to shut off any planes that may be active */ |
287 | list_for_each_entry(plane, &config->plane_list, head) | 289 | list_for_each_entry(plane, &config->plane_list, head) |
288 | plane->funcs->disable_plane(plane); | 290 | plane->funcs->disable_plane(plane); |
291 | |||
292 | mutex_unlock(&dev->mode_config.mutex); | ||
289 | } | 293 | } |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 8d2501704182..bf218753cbaf 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -136,7 +136,7 @@ static void i9xx_write_infoframe(struct drm_encoder *encoder, | |||
136 | 136 | ||
137 | val &= ~VIDEO_DIP_SELECT_MASK; | 137 | val &= ~VIDEO_DIP_SELECT_MASK; |
138 | 138 | ||
139 | I915_WRITE(VIDEO_DIP_CTL, val | port | flags); | 139 | I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | val | port | flags); |
140 | 140 | ||
141 | for (i = 0; i < len; i += 4) { | 141 | for (i = 0; i < len; i += 4) { |
142 | I915_WRITE(VIDEO_DIP_DATA, *data); | 142 | I915_WRITE(VIDEO_DIP_DATA, *data); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 17a4630cec8a..9dee82350def 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -187,6 +187,8 @@ centre_horizontally(struct drm_display_mode *mode, | |||
187 | 187 | ||
188 | mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; | 188 | mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; |
189 | mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; | 189 | mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; |
190 | |||
191 | mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; | ||
190 | } | 192 | } |
191 | 193 | ||
192 | static void | 194 | static void |
@@ -208,6 +210,8 @@ centre_vertically(struct drm_display_mode *mode, | |||
208 | 210 | ||
209 | mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; | 211 | mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; |
210 | mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; | 212 | mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; |
213 | |||
214 | mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; | ||
211 | } | 215 | } |
212 | 216 | ||
213 | static inline u32 panel_fitter_scaling(u32 source, u32 target) | 217 | static inline u32 panel_fitter_scaling(u32 source, u32 target) |
@@ -283,6 +287,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
283 | for_each_pipe(pipe) | 287 | for_each_pipe(pipe) |
284 | I915_WRITE(BCLRPAT(pipe), 0); | 288 | I915_WRITE(BCLRPAT(pipe), 0); |
285 | 289 | ||
290 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
291 | |||
286 | switch (intel_lvds->fitting_mode) { | 292 | switch (intel_lvds->fitting_mode) { |
287 | case DRM_MODE_SCALE_CENTER: | 293 | case DRM_MODE_SCALE_CENTER: |
288 | /* | 294 | /* |
@@ -744,7 +750,7 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
744 | .ident = "Hewlett-Packard t5745", | 750 | .ident = "Hewlett-Packard t5745", |
745 | .matches = { | 751 | .matches = { |
746 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), | 752 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), |
747 | DMI_MATCH(DMI_BOARD_NAME, "hp t5745"), | 753 | DMI_MATCH(DMI_PRODUCT_NAME, "hp t5745"), |
748 | }, | 754 | }, |
749 | }, | 755 | }, |
750 | { | 756 | { |
@@ -752,7 +758,7 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
752 | .ident = "Hewlett-Packard st5747", | 758 | .ident = "Hewlett-Packard st5747", |
753 | .matches = { | 759 | .matches = { |
754 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), | 760 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), |
755 | DMI_MATCH(DMI_BOARD_NAME, "hp st5747"), | 761 | DMI_MATCH(DMI_PRODUCT_NAME, "hp st5747"), |
756 | }, | 762 | }, |
757 | }, | 763 | }, |
758 | { | 764 | { |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index cad45ff8251b..2b2e011e9055 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -50,8 +50,6 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | |||
50 | adjusted_mode->vtotal = fixed_mode->vtotal; | 50 | adjusted_mode->vtotal = fixed_mode->vtotal; |
51 | 51 | ||
52 | adjusted_mode->clock = fixed_mode->clock; | 52 | adjusted_mode->clock = fixed_mode->clock; |
53 | |||
54 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
55 | } | 53 | } |
56 | 54 | ||
57 | /* adjusted_mode has been preset to be the panel's fixed mode */ | 55 | /* adjusted_mode has been preset to be the panel's fixed mode */ |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 3aabe8dfe5c5..b59b6d5b7583 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -414,6 +414,16 @@ static int init_render_ring(struct intel_ring_buffer *ring) | |||
414 | return ret; | 414 | return ret; |
415 | } | 415 | } |
416 | 416 | ||
417 | if (IS_GEN6(dev)) { | ||
418 | /* From the Sandybridge PRM, volume 1 part 3, page 24: | ||
419 | * "If this bit is set, STCunit will have LRA as replacement | ||
420 | * policy. [...] This bit must be reset. LRA replacement | ||
421 | * policy is not supported." | ||
422 | */ | ||
423 | I915_WRITE(CACHE_MODE_0, | ||
424 | _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB)); | ||
425 | } | ||
426 | |||
417 | if (INTEL_INFO(dev)->gen >= 6) | 427 | if (INTEL_INFO(dev)->gen >= 6) |
418 | I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING)); | 428 | I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING)); |
419 | 429 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 9b3a5f999ad7..7d3f238e8265 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -745,6 +745,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | |||
745 | uint16_t width, height; | 745 | uint16_t width, height; |
746 | uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; | 746 | uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; |
747 | uint16_t h_sync_offset, v_sync_offset; | 747 | uint16_t h_sync_offset, v_sync_offset; |
748 | int mode_clock; | ||
748 | 749 | ||
749 | width = mode->hdisplay; | 750 | width = mode->hdisplay; |
750 | height = mode->vdisplay; | 751 | height = mode->vdisplay; |
@@ -759,7 +760,11 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | |||
759 | h_sync_offset = mode->hsync_start - mode->hdisplay; | 760 | h_sync_offset = mode->hsync_start - mode->hdisplay; |
760 | v_sync_offset = mode->vsync_start - mode->vdisplay; | 761 | v_sync_offset = mode->vsync_start - mode->vdisplay; |
761 | 762 | ||
762 | dtd->part1.clock = mode->clock / 10; | 763 | mode_clock = mode->clock; |
764 | mode_clock /= intel_mode_get_pixel_multiplier(mode) ?: 1; | ||
765 | mode_clock /= 10; | ||
766 | dtd->part1.clock = mode_clock; | ||
767 | |||
763 | dtd->part1.h_active = width & 0xff; | 768 | dtd->part1.h_active = width & 0xff; |
764 | dtd->part1.h_blank = h_blank_len & 0xff; | 769 | dtd->part1.h_blank = h_blank_len & 0xff; |
765 | dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | | 770 | dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | |
@@ -1010,7 +1015,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1010 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); | 1015 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); |
1011 | u32 sdvox; | 1016 | u32 sdvox; |
1012 | struct intel_sdvo_in_out_map in_out; | 1017 | struct intel_sdvo_in_out_map in_out; |
1013 | struct intel_sdvo_dtd input_dtd; | 1018 | struct intel_sdvo_dtd input_dtd, output_dtd; |
1014 | int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); | 1019 | int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); |
1015 | int rate; | 1020 | int rate; |
1016 | 1021 | ||
@@ -1035,20 +1040,13 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1035 | intel_sdvo->attached_output)) | 1040 | intel_sdvo->attached_output)) |
1036 | return; | 1041 | return; |
1037 | 1042 | ||
1038 | /* We have tried to get input timing in mode_fixup, and filled into | 1043 | /* lvds has a special fixed output timing. */ |
1039 | * adjusted_mode. | 1044 | if (intel_sdvo->is_lvds) |
1040 | */ | 1045 | intel_sdvo_get_dtd_from_mode(&output_dtd, |
1041 | if (intel_sdvo->is_tv || intel_sdvo->is_lvds) { | 1046 | intel_sdvo->sdvo_lvds_fixed_mode); |
1042 | input_dtd = intel_sdvo->input_dtd; | 1047 | else |
1043 | } else { | 1048 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); |
1044 | /* Set the output timing to the screen */ | 1049 | (void) intel_sdvo_set_output_timing(intel_sdvo, &output_dtd); |
1045 | if (!intel_sdvo_set_target_output(intel_sdvo, | ||
1046 | intel_sdvo->attached_output)) | ||
1047 | return; | ||
1048 | |||
1049 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | ||
1050 | (void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd); | ||
1051 | } | ||
1052 | 1050 | ||
1053 | /* Set the input timing to the screen. Assume always input 0. */ | 1051 | /* Set the input timing to the screen. Assume always input 0. */ |
1054 | if (!intel_sdvo_set_target_input(intel_sdvo)) | 1052 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
@@ -1066,6 +1064,10 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1066 | !intel_sdvo_set_tv_format(intel_sdvo)) | 1064 | !intel_sdvo_set_tv_format(intel_sdvo)) |
1067 | return; | 1065 | return; |
1068 | 1066 | ||
1067 | /* We have tried to get input timing in mode_fixup, and filled into | ||
1068 | * adjusted_mode. | ||
1069 | */ | ||
1070 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | ||
1069 | (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); | 1071 | (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); |
1070 | 1072 | ||
1071 | switch (pixel_multiplier) { | 1073 | switch (pixel_multiplier) { |