diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2009-10-08 15:09:31 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-10-11 23:42:44 -0400 |
commit | 5a9bcacc0a56f0d9577494e834519480018a6cc3 (patch) | |
tree | f46fe410f8c875cf28d3905d23fdffcea4f374c0 /drivers/gpu/drm/radeon/atombios_crtc.c | |
parent | 2606c88608122339cbd5c6b5c149a2eb74ccfe9e (diff) |
drm/radeon/kms/atom: rework crtc modeset
- clean up tv timing handling
- unify SetCRTC_Timing and SetCRTC_UsingDTDTiming
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/atombios_crtc.c')
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 221 |
1 files changed, 70 insertions, 151 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 | } |