diff options
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 221 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 93 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_encoders.c | 18 |
3 files changed, 148 insertions, 184 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index d5e6f3da116c..7522af1b9e46 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -270,59 +270,89 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
270 | 270 | ||
271 | static void | 271 | static void |
272 | atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, | 272 | atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, |
273 | SET_CRTC_USING_DTD_TIMING_PARAMETERS * crtc_param) | 273 | struct drm_display_mode *mode) |
274 | { | 274 | { |
275 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
275 | struct drm_device *dev = crtc->dev; | 276 | struct drm_device *dev = crtc->dev; |
276 | struct radeon_device *rdev = dev->dev_private; | 277 | struct radeon_device *rdev = dev->dev_private; |
277 | SET_CRTC_USING_DTD_TIMING_PARAMETERS conv_param; | 278 | SET_CRTC_USING_DTD_TIMING_PARAMETERS args; |
278 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming); | 279 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming); |
280 | u16 misc = 0; | ||
279 | 281 | ||
280 | conv_param.usH_Size = cpu_to_le16(crtc_param->usH_Size); | 282 | memset(&args, 0, sizeof(args)); |
281 | conv_param.usH_Blanking_Time = | 283 | args.usH_Size = cpu_to_le16(mode->crtc_hdisplay); |
282 | cpu_to_le16(crtc_param->usH_Blanking_Time); | 284 | args.usH_Blanking_Time = |
283 | conv_param.usV_Size = cpu_to_le16(crtc_param->usV_Size); | 285 | cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay); |
284 | conv_param.usV_Blanking_Time = | 286 | args.usV_Size = cpu_to_le16(mode->crtc_vdisplay); |
285 | cpu_to_le16(crtc_param->usV_Blanking_Time); | 287 | args.usV_Blanking_Time = |
286 | conv_param.usH_SyncOffset = cpu_to_le16(crtc_param->usH_SyncOffset); | 288 | cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay); |
287 | conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth); | 289 | args.usH_SyncOffset = |
288 | conv_param.usV_SyncOffset = cpu_to_le16(crtc_param->usV_SyncOffset); | 290 | cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay); |
289 | conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth); | 291 | args.usH_SyncWidth = |
290 | conv_param.susModeMiscInfo.usAccess = | 292 | cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); |
291 | cpu_to_le16(crtc_param->susModeMiscInfo.usAccess); | 293 | args.usV_SyncOffset = |
292 | conv_param.ucCRTC = crtc_param->ucCRTC; | 294 | cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay); |
295 | args.usV_SyncWidth = | ||
296 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); | ||
297 | /*args.ucH_Border = mode->hborder;*/ | ||
298 | /*args.ucV_Border = mode->vborder;*/ | ||
299 | |||
300 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) | ||
301 | misc |= ATOM_VSYNC_POLARITY; | ||
302 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) | ||
303 | misc |= ATOM_HSYNC_POLARITY; | ||
304 | if (mode->flags & DRM_MODE_FLAG_CSYNC) | ||
305 | misc |= ATOM_COMPOSITESYNC; | ||
306 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
307 | misc |= ATOM_INTERLACE; | ||
308 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | ||
309 | misc |= ATOM_DOUBLE_CLOCK_MODE; | ||
310 | |||
311 | args.susModeMiscInfo.usAccess = cpu_to_le16(misc); | ||
312 | args.ucCRTC = radeon_crtc->crtc_id; | ||
293 | 313 | ||
294 | printk("executing set crtc dtd timing\n"); | 314 | printk("executing set crtc dtd timing\n"); |
295 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param); | 315 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
296 | } | 316 | } |
297 | 317 | ||
298 | void atombios_crtc_set_timing(struct drm_crtc *crtc, | 318 | static void atombios_crtc_set_timing(struct drm_crtc *crtc, |
299 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION * | 319 | struct drm_display_mode *mode) |
300 | crtc_param) | ||
301 | { | 320 | { |
321 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
302 | struct drm_device *dev = crtc->dev; | 322 | struct drm_device *dev = crtc->dev; |
303 | struct radeon_device *rdev = dev->dev_private; | 323 | struct radeon_device *rdev = dev->dev_private; |
304 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION conv_param; | 324 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION args; |
305 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing); | 325 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing); |
326 | u16 misc = 0; | ||
306 | 327 | ||
307 | conv_param.usH_Total = cpu_to_le16(crtc_param->usH_Total); | 328 | memset(&args, 0, sizeof(args)); |
308 | conv_param.usH_Disp = cpu_to_le16(crtc_param->usH_Disp); | 329 | args.usH_Total = cpu_to_le16(mode->crtc_htotal); |
309 | conv_param.usH_SyncStart = cpu_to_le16(crtc_param->usH_SyncStart); | 330 | args.usH_Disp = cpu_to_le16(mode->crtc_hdisplay); |
310 | conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth); | 331 | args.usH_SyncStart = cpu_to_le16(mode->crtc_hsync_start); |
311 | conv_param.usV_Total = cpu_to_le16(crtc_param->usV_Total); | 332 | args.usH_SyncWidth = |
312 | conv_param.usV_Disp = cpu_to_le16(crtc_param->usV_Disp); | 333 | cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); |
313 | conv_param.usV_SyncStart = cpu_to_le16(crtc_param->usV_SyncStart); | 334 | args.usV_Total = cpu_to_le16(mode->crtc_vtotal); |
314 | conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth); | 335 | args.usV_Disp = cpu_to_le16(mode->crtc_vdisplay); |
315 | conv_param.susModeMiscInfo.usAccess = | 336 | args.usV_SyncStart = cpu_to_le16(mode->crtc_vsync_start); |
316 | cpu_to_le16(crtc_param->susModeMiscInfo.usAccess); | 337 | args.usV_SyncWidth = |
317 | conv_param.ucCRTC = crtc_param->ucCRTC; | 338 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); |
318 | conv_param.ucOverscanRight = crtc_param->ucOverscanRight; | 339 | |
319 | conv_param.ucOverscanLeft = crtc_param->ucOverscanLeft; | 340 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) |
320 | conv_param.ucOverscanBottom = crtc_param->ucOverscanBottom; | 341 | misc |= ATOM_VSYNC_POLARITY; |
321 | conv_param.ucOverscanTop = crtc_param->ucOverscanTop; | 342 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) |
322 | conv_param.ucReserved = crtc_param->ucReserved; | 343 | misc |= ATOM_HSYNC_POLARITY; |
344 | if (mode->flags & DRM_MODE_FLAG_CSYNC) | ||
345 | misc |= ATOM_COMPOSITESYNC; | ||
346 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
347 | misc |= ATOM_INTERLACE; | ||
348 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | ||
349 | misc |= ATOM_DOUBLE_CLOCK_MODE; | ||
350 | |||
351 | args.susModeMiscInfo.usAccess = cpu_to_le16(misc); | ||
352 | args.ucCRTC = radeon_crtc->crtc_id; | ||
323 | 353 | ||
324 | printk("executing set crtc timing\n"); | 354 | printk("executing set crtc timing\n"); |
325 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param); | 355 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
326 | } | 356 | } |
327 | 357 | ||
328 | void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | 358 | void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) |
@@ -602,128 +632,17 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
602 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 632 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
603 | struct drm_device *dev = crtc->dev; | 633 | struct drm_device *dev = crtc->dev; |
604 | struct radeon_device *rdev = dev->dev_private; | 634 | struct radeon_device *rdev = dev->dev_private; |
605 | struct drm_encoder *encoder; | ||
606 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing; | ||
607 | int need_tv_timings = 0; | ||
608 | bool ret; | ||
609 | 635 | ||
610 | /* TODO color tiling */ | 636 | /* TODO color tiling */ |
611 | memset(&crtc_timing, 0, sizeof(crtc_timing)); | ||
612 | |||
613 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
614 | /* find tv std */ | ||
615 | if (encoder->crtc == crtc) { | ||
616 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
617 | |||
618 | if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { | ||
619 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; | ||
620 | if (tv_dac) { | ||
621 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
622 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
623 | tv_dac->tv_std == TV_STD_PAL_M) | ||
624 | need_tv_timings = 1; | ||
625 | else | ||
626 | need_tv_timings = 2; | ||
627 | break; | ||
628 | } | ||
629 | } | ||
630 | } | ||
631 | } | ||
632 | |||
633 | crtc_timing.ucCRTC = radeon_crtc->crtc_id; | ||
634 | if (need_tv_timings) { | ||
635 | ret = radeon_atom_get_tv_timings(rdev, need_tv_timings - 1, | ||
636 | &crtc_timing, &adjusted_mode->clock); | ||
637 | if (ret == false) | ||
638 | need_tv_timings = 0; | ||
639 | } | ||
640 | |||
641 | if (!need_tv_timings) { | ||
642 | crtc_timing.usH_Total = adjusted_mode->crtc_htotal; | ||
643 | crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay; | ||
644 | crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start; | ||
645 | crtc_timing.usH_SyncWidth = | ||
646 | adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; | ||
647 | |||
648 | crtc_timing.usV_Total = adjusted_mode->crtc_vtotal; | ||
649 | crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay; | ||
650 | crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start; | ||
651 | crtc_timing.usV_SyncWidth = | ||
652 | adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start; | ||
653 | |||
654 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) | ||
655 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY; | ||
656 | |||
657 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) | ||
658 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY; | ||
659 | |||
660 | if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) | ||
661 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC; | ||
662 | |||
663 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
664 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE; | ||
665 | |||
666 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) | ||
667 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE; | ||
668 | } | ||
669 | 637 | ||
670 | atombios_crtc_set_pll(crtc, adjusted_mode); | 638 | atombios_crtc_set_pll(crtc, adjusted_mode); |
671 | atombios_crtc_set_timing(crtc, &crtc_timing); | 639 | atombios_crtc_set_timing(crtc, adjusted_mode); |
672 | 640 | ||
673 | if (ASIC_IS_AVIVO(rdev)) | 641 | if (ASIC_IS_AVIVO(rdev)) |
674 | atombios_crtc_set_base(crtc, x, y, old_fb); | 642 | atombios_crtc_set_base(crtc, x, y, old_fb); |
675 | else { | 643 | else { |
676 | if (radeon_crtc->crtc_id == 0) { | 644 | if (radeon_crtc->crtc_id == 0) |
677 | SET_CRTC_USING_DTD_TIMING_PARAMETERS crtc_dtd_timing; | 645 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |
678 | memset(&crtc_dtd_timing, 0, sizeof(crtc_dtd_timing)); | ||
679 | |||
680 | /* setup FP shadow regs on R4xx */ | ||
681 | crtc_dtd_timing.ucCRTC = radeon_crtc->crtc_id; | ||
682 | crtc_dtd_timing.usH_Size = adjusted_mode->crtc_hdisplay; | ||
683 | crtc_dtd_timing.usV_Size = adjusted_mode->crtc_vdisplay; | ||
684 | crtc_dtd_timing.usH_Blanking_Time = | ||
685 | adjusted_mode->crtc_hblank_end - | ||
686 | adjusted_mode->crtc_hdisplay; | ||
687 | crtc_dtd_timing.usV_Blanking_Time = | ||
688 | adjusted_mode->crtc_vblank_end - | ||
689 | adjusted_mode->crtc_vdisplay; | ||
690 | crtc_dtd_timing.usH_SyncOffset = | ||
691 | adjusted_mode->crtc_hsync_start - | ||
692 | adjusted_mode->crtc_hdisplay; | ||
693 | crtc_dtd_timing.usV_SyncOffset = | ||
694 | adjusted_mode->crtc_vsync_start - | ||
695 | adjusted_mode->crtc_vdisplay; | ||
696 | crtc_dtd_timing.usH_SyncWidth = | ||
697 | adjusted_mode->crtc_hsync_end - | ||
698 | adjusted_mode->crtc_hsync_start; | ||
699 | crtc_dtd_timing.usV_SyncWidth = | ||
700 | adjusted_mode->crtc_vsync_end - | ||
701 | adjusted_mode->crtc_vsync_start; | ||
702 | /* crtc_dtd_timing.ucH_Border = adjusted_mode->crtc_hborder; */ | ||
703 | /* crtc_dtd_timing.ucV_Border = adjusted_mode->crtc_vborder; */ | ||
704 | |||
705 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) | ||
706 | crtc_dtd_timing.susModeMiscInfo.usAccess |= | ||
707 | ATOM_VSYNC_POLARITY; | ||
708 | |||
709 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) | ||
710 | crtc_dtd_timing.susModeMiscInfo.usAccess |= | ||
711 | ATOM_HSYNC_POLARITY; | ||
712 | |||
713 | if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) | ||
714 | crtc_dtd_timing.susModeMiscInfo.usAccess |= | ||
715 | ATOM_COMPOSITESYNC; | ||
716 | |||
717 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
718 | crtc_dtd_timing.susModeMiscInfo.usAccess |= | ||
719 | ATOM_INTERLACE; | ||
720 | |||
721 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) | ||
722 | crtc_dtd_timing.susModeMiscInfo.usAccess |= | ||
723 | ATOM_DOUBLE_CLOCK_MODE; | ||
724 | |||
725 | atombios_set_crtc_dtd_timing(crtc, &crtc_dtd_timing); | ||
726 | } | ||
727 | radeon_crtc_set_base(crtc, x, y, old_fb); | 646 | radeon_crtc_set_base(crtc, x, y, old_fb); |
728 | radeon_legacy_atom_set_surface(crtc); | 647 | radeon_legacy_atom_set_surface(crtc); |
729 | } | 648 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 5b6c08cee40e..979ddfdf209c 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -857,8 +857,7 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder) | |||
857 | } | 857 | } |
858 | 858 | ||
859 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | 859 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, |
860 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, | 860 | struct drm_display_mode *mode) |
861 | int32_t *pixel_clock) | ||
862 | { | 861 | { |
863 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 862 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
864 | ATOM_ANALOG_TV_INFO *tv_info; | 863 | ATOM_ANALOG_TV_INFO *tv_info; |
@@ -866,7 +865,7 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | |||
866 | ATOM_DTD_FORMAT *dtd_timings; | 865 | ATOM_DTD_FORMAT *dtd_timings; |
867 | int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info); | 866 | int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info); |
868 | u8 frev, crev; | 867 | u8 frev, crev; |
869 | uint16_t data_offset; | 868 | u16 data_offset, misc; |
870 | 869 | ||
871 | atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset); | 870 | atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset); |
872 | 871 | ||
@@ -876,28 +875,37 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | |||
876 | if (index > MAX_SUPPORTED_TV_TIMING) | 875 | if (index > MAX_SUPPORTED_TV_TIMING) |
877 | return false; | 876 | return false; |
878 | 877 | ||
879 | crtc_timing->usH_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); | 878 | mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); |
880 | crtc_timing->usH_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp); | 879 | mode->crtc_hdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp); |
881 | crtc_timing->usH_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart); | 880 | mode->crtc_hsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart); |
882 | crtc_timing->usH_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth); | 881 | mode->crtc_hsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart) + |
883 | 882 | le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth); | |
884 | crtc_timing->usV_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total); | 883 | |
885 | crtc_timing->usV_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp); | 884 | mode->crtc_vtotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total); |
886 | crtc_timing->usV_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart); | 885 | mode->crtc_vdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp); |
887 | crtc_timing->usV_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth); | 886 | mode->crtc_vsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart); |
888 | 887 | mode->crtc_vsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart) + | |
889 | crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo; | 888 | le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth); |
890 | 889 | ||
891 | crtc_timing->ucOverscanRight = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanRight); | 890 | mode->flags = 0; |
892 | crtc_timing->ucOverscanLeft = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanLeft); | 891 | misc = le16_to_cpu(tv_info->aModeTimings[index].susModeMiscInfo.usAccess); |
893 | crtc_timing->ucOverscanBottom = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanBottom); | 892 | if (misc & ATOM_VSYNC_POLARITY) |
894 | crtc_timing->ucOverscanTop = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanTop); | 893 | mode->flags |= DRM_MODE_FLAG_NVSYNC; |
895 | *pixel_clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; | 894 | if (misc & ATOM_HSYNC_POLARITY) |
895 | mode->flags |= DRM_MODE_FLAG_NHSYNC; | ||
896 | if (misc & ATOM_COMPOSITESYNC) | ||
897 | mode->flags |= DRM_MODE_FLAG_CSYNC; | ||
898 | if (misc & ATOM_INTERLACE) | ||
899 | mode->flags |= DRM_MODE_FLAG_INTERLACE; | ||
900 | if (misc & ATOM_DOUBLE_CLOCK_MODE) | ||
901 | mode->flags |= DRM_MODE_FLAG_DBLSCAN; | ||
902 | |||
903 | mode->clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; | ||
896 | 904 | ||
897 | if (index == 1) { | 905 | if (index == 1) { |
898 | /* PAL timings appear to have wrong values for totals */ | 906 | /* PAL timings appear to have wrong values for totals */ |
899 | crtc_timing->usH_Total -= 1; | 907 | mode->crtc_htotal -= 1; |
900 | crtc_timing->usV_Total -= 1; | 908 | mode->crtc_vtotal -= 1; |
901 | } | 909 | } |
902 | break; | 910 | break; |
903 | case 2: | 911 | case 2: |
@@ -906,17 +914,36 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | |||
906 | return false; | 914 | return false; |
907 | 915 | ||
908 | dtd_timings = &tv_info_v1_2->aModeTimings[index]; | 916 | dtd_timings = &tv_info_v1_2->aModeTimings[index]; |
909 | crtc_timing->usH_Total = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHBlanking_Time); | 917 | mode->crtc_htotal = le16_to_cpu(dtd_timings->usHActive) + |
910 | crtc_timing->usH_Disp = le16_to_cpu(dtd_timings->usHActive); | 918 | le16_to_cpu(dtd_timings->usHBlanking_Time); |
911 | crtc_timing->usH_SyncStart = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHSyncOffset); | 919 | mode->crtc_hdisplay = le16_to_cpu(dtd_timings->usHActive); |
912 | crtc_timing->usH_SyncWidth = le16_to_cpu(dtd_timings->usHSyncWidth); | 920 | mode->crtc_hsync_start = le16_to_cpu(dtd_timings->usHActive) + |
913 | crtc_timing->usV_Total = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVBlanking_Time); | 921 | le16_to_cpu(dtd_timings->usHSyncOffset); |
914 | crtc_timing->usV_Disp = le16_to_cpu(dtd_timings->usVActive); | 922 | mode->crtc_hsync_end = mode->crtc_hsync_start + |
915 | crtc_timing->usV_SyncStart = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVSyncOffset); | 923 | le16_to_cpu(dtd_timings->usHSyncWidth); |
916 | crtc_timing->usV_SyncWidth = le16_to_cpu(dtd_timings->usVSyncWidth); | 924 | |
917 | 925 | mode->crtc_vtotal = le16_to_cpu(dtd_timings->usVActive) + | |
918 | crtc_timing->susModeMiscInfo.usAccess = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess); | 926 | le16_to_cpu(dtd_timings->usVBlanking_Time); |
919 | *pixel_clock = le16_to_cpu(dtd_timings->usPixClk) * 10; | 927 | mode->crtc_vdisplay = le16_to_cpu(dtd_timings->usVActive); |
928 | mode->crtc_vsync_start = le16_to_cpu(dtd_timings->usVActive) + | ||
929 | le16_to_cpu(dtd_timings->usVSyncOffset); | ||
930 | mode->crtc_vsync_end = mode->crtc_vsync_start + | ||
931 | le16_to_cpu(dtd_timings->usVSyncWidth); | ||
932 | |||
933 | mode->flags = 0; | ||
934 | misc = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess); | ||
935 | if (misc & ATOM_VSYNC_POLARITY) | ||
936 | mode->flags |= DRM_MODE_FLAG_NVSYNC; | ||
937 | if (misc & ATOM_HSYNC_POLARITY) | ||
938 | mode->flags |= DRM_MODE_FLAG_NHSYNC; | ||
939 | if (misc & ATOM_COMPOSITESYNC) | ||
940 | mode->flags |= DRM_MODE_FLAG_CSYNC; | ||
941 | if (misc & ATOM_INTERLACE) | ||
942 | mode->flags |= DRM_MODE_FLAG_INTERLACE; | ||
943 | if (misc & ATOM_DOUBLE_CLOCK_MODE) | ||
944 | mode->flags |= DRM_MODE_FLAG_DBLSCAN; | ||
945 | |||
946 | mode->clock = le16_to_cpu(dtd_timings->usPixClk) * 10; | ||
920 | break; | 947 | break; |
921 | } | 948 | } |
922 | return true; | 949 | return true; |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index a65ab1a0dad2..3e58c6eccea5 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -31,6 +31,10 @@ | |||
31 | 31 | ||
32 | extern int atom_debug; | 32 | extern int atom_debug; |
33 | 33 | ||
34 | /* evil but including atombios.h is much worse */ | ||
35 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | ||
36 | struct drm_display_mode *mode); | ||
37 | |||
34 | uint32_t | 38 | uint32_t |
35 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac) | 39 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac) |
36 | { | 40 | { |
@@ -219,6 +223,8 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | |||
219 | struct drm_display_mode *adjusted_mode) | 223 | struct drm_display_mode *adjusted_mode) |
220 | { | 224 | { |
221 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 225 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
226 | struct drm_device *dev = encoder->dev; | ||
227 | struct radeon_device *rdev = dev->dev_private; | ||
222 | 228 | ||
223 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 229 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
224 | 230 | ||
@@ -230,6 +236,18 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | |||
230 | && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) | 236 | && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) |
231 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; | 237 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; |
232 | 238 | ||
239 | if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { | ||
240 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; | ||
241 | if (tv_dac) { | ||
242 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
243 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
244 | tv_dac->tv_std == TV_STD_PAL_M) | ||
245 | radeon_atom_get_tv_timings(rdev, 0, adjusted_mode); | ||
246 | else | ||
247 | radeon_atom_get_tv_timings(rdev, 1, adjusted_mode); | ||
248 | } | ||
249 | } | ||
250 | |||
233 | return true; | 251 | return true; |
234 | } | 252 | } |
235 | 253 | ||