On Tue, Apr 10, 2012 at 07:13:59PM +0200, Daniel Vetter wrote: > Reported-and-Tested-by: Bernard Blackham <b-linuxgit at largestprime.net> This tested-by is actually a lie, I've mixed up a few bug reports. Bug reporter is currently on vacation and will test this stuff in 2 weeks. -Daniel > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=48157 > Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch> > --- > drivers/gpu/drm/i915/intel_sdvo.c | 34 ++++++++++++++++++---------------- > 1 files changed, 18 insertions(+), 16 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c > index 6898145..ab47c1e 100644 > --- a/drivers/gpu/drm/i915/intel_sdvo.c > +++ b/drivers/gpu/drm/i915/intel_sdvo.c > @@ -733,6 +733,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, > uint16_t width, height; > uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; > uint16_t h_sync_offset, v_sync_offset; > + int mode_clock; > > width = mode->crtc_hdisplay; > height = mode->crtc_vdisplay; > @@ -747,7 +748,11 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, > h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; > v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; > > - dtd->part1.clock = mode->clock / 10; > + mode_clock = mode->clock; > + mode_clock /= intel_mode_get_pixel_multiplier(mode) ?: 1; > + mode_clock /= 10; > + dtd->part1.clock = mode_clock; > + > dtd->part1.h_active = width & 0xff; > dtd->part1.h_blank = h_blank_len & 0xff; > dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | > @@ -998,7 +1003,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, > struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); > u32 sdvox; > struct intel_sdvo_in_out_map in_out; > - struct intel_sdvo_dtd input_dtd; > + struct intel_sdvo_dtd input_dtd, output_dtd; > int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); > int rate; > > @@ -1023,20 +1028,13 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, > intel_sdvo->attached_output)) > return; > > - /* We have tried to get input timing in mode_fixup, and filled into > - * adjusted_mode. > - */ > - if (intel_sdvo->is_tv || intel_sdvo->is_lvds) { > - input_dtd = intel_sdvo->input_dtd; > - } else { > - /* Set the output timing to the screen */ > - if (!intel_sdvo_set_target_output(intel_sdvo, > - intel_sdvo->attached_output)) > - return; > - > - intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); > - (void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd); > - } > + /* lvds has a special fixed output timing. */ > + if (intel_sdvo->is_lvds) > + intel_sdvo_get_dtd_from_mode(&output_dtd, > + intel_sdvo->sdvo_lvds_fixed_mode); > + else > + intel_sdvo_get_dtd_from_mode(&output_dtd, mode); > + (void) intel_sdvo_set_output_timing(intel_sdvo, &output_dtd); > > /* Set the input timing to the screen. Assume always input 0. */ > if (!intel_sdvo_set_target_input(intel_sdvo)) > @@ -1054,6 +1052,10 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, > !intel_sdvo_set_tv_format(intel_sdvo)) > return; > > + /* We have tried to get input timing in mode_fixup, and filled into > + * adjusted_mode. > + */ > + intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); > (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); > > switch (pixel_multiplier) { > -- > 1.7.9.1 > -- Daniel Vetter Mail: daniel at ffwll.ch Mobile: +41 (0)79 365 57 48