aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/atombios_crtc.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-08-13 02:32:14 -0400
committerDave Airlie <airlied@redhat.com>2009-09-07 19:24:37 -0400
commit4ce001abafafe77e5dd943d1480fc9f87894e96f (patch)
tree4a22b42c58a80450992fcf5d7625b19fe045855b /drivers/gpu/drm/radeon/atombios_crtc.c
parent551ebd837c75fc75df81811a18b7136c39cab487 (diff)
drm/radeon/kms: add initial radeon tv-out support.
This ports the tv-out code from the DDX to KMS. adds a radeon.tv module option, radeon.tv=0 to disable tv 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.c99
1 files changed, 72 insertions, 27 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 74d034f77c6b..8e31e992ec53 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -31,6 +31,10 @@
31#include "atom.h" 31#include "atom.h"
32#include "atom-bits.h" 32#include "atom-bits.h"
33 33
34/* evil but including atombios.h is much worse */
35bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
36 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing,
37 int32_t *pixel_clock);
34static void atombios_overscan_setup(struct drm_crtc *crtc, 38static void atombios_overscan_setup(struct drm_crtc *crtc,
35 struct drm_display_mode *mode, 39 struct drm_display_mode *mode,
36 struct drm_display_mode *adjusted_mode) 40 struct drm_display_mode *adjusted_mode)
@@ -89,17 +93,32 @@ static void atombios_scaler_setup(struct drm_crtc *crtc)
89 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 93 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
90 ENABLE_SCALER_PS_ALLOCATION args; 94 ENABLE_SCALER_PS_ALLOCATION args;
91 int index = GetIndexIntoMasterTable(COMMAND, EnableScaler); 95 int index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
96
92 /* fixme - fill in enc_priv for atom dac */ 97 /* fixme - fill in enc_priv for atom dac */
93 enum radeon_tv_std tv_std = TV_STD_NTSC; 98 enum radeon_tv_std tv_std = TV_STD_NTSC;
99 bool is_tv = false, is_cv = false;
100 struct drm_encoder *encoder;
94 101
95 if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id) 102 if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id)
96 return; 103 return;
97 104
105 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
106 /* find tv std */
107 if (encoder->crtc == crtc) {
108 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
109 if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
110 struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
111 tv_std = tv_dac->tv_std;
112 is_tv = true;
113 }
114 }
115 }
116
98 memset(&args, 0, sizeof(args)); 117 memset(&args, 0, sizeof(args));
99 118
100 args.ucScaler = radeon_crtc->crtc_id; 119 args.ucScaler = radeon_crtc->crtc_id;
101 120
102 if (radeon_crtc->devices & (ATOM_DEVICE_TV_SUPPORT)) { 121 if (is_tv) {
103 switch (tv_std) { 122 switch (tv_std) {
104 case TV_STD_NTSC: 123 case TV_STD_NTSC:
105 default: 124 default:
@@ -128,7 +147,7 @@ static void atombios_scaler_setup(struct drm_crtc *crtc)
128 break; 147 break;
129 } 148 }
130 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE; 149 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
131 } else if (radeon_crtc->devices & (ATOM_DEVICE_CV_SUPPORT)) { 150 } else if (is_cv) {
132 args.ucTVStandard = ATOM_TV_CV; 151 args.ucTVStandard = ATOM_TV_CV;
133 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE; 152 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
134 } else { 153 } else {
@@ -151,9 +170,9 @@ static void atombios_scaler_setup(struct drm_crtc *crtc)
151 } 170 }
152 } 171 }
153 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 172 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
154 if (radeon_crtc->devices & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT) 173 if ((is_tv || is_cv)
155 && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_RV570) { 174 && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_R580) {
156 atom_rv515_force_tv_scaler(rdev); 175 atom_rv515_force_tv_scaler(rdev, radeon_crtc);
157 } 176 }
158} 177}
159 178
@@ -551,42 +570,68 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
551 struct radeon_device *rdev = dev->dev_private; 570 struct radeon_device *rdev = dev->dev_private;
552 struct drm_encoder *encoder; 571 struct drm_encoder *encoder;
553 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing; 572 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing;
573 int need_tv_timings = 0;
574 bool ret;
554 575
555 /* TODO color tiling */ 576 /* TODO color tiling */
556 memset(&crtc_timing, 0, sizeof(crtc_timing)); 577 memset(&crtc_timing, 0, sizeof(crtc_timing));
557 578
558 /* TODO tv */
559 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 579 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
560 580 /* find tv std */
581 if (encoder->crtc == crtc) {
582 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
583
584 if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
585 struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
586 if (tv_dac) {
587 if (tv_dac->tv_std == TV_STD_NTSC ||
588 tv_dac->tv_std == TV_STD_NTSC_J ||
589 tv_dac->tv_std == TV_STD_PAL_M)
590 need_tv_timings = 1;
591 else
592 need_tv_timings = 2;
593 break;
594 }
595 }
596 }
561 } 597 }
562 598
563 crtc_timing.ucCRTC = radeon_crtc->crtc_id; 599 crtc_timing.ucCRTC = radeon_crtc->crtc_id;
564 crtc_timing.usH_Total = adjusted_mode->crtc_htotal; 600 if (need_tv_timings) {
565 crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay; 601 ret = radeon_atom_get_tv_timings(rdev, need_tv_timings - 1,
566 crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start; 602 &crtc_timing, &adjusted_mode->clock);
567 crtc_timing.usH_SyncWidth = 603 if (ret == false)
568 adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; 604 need_tv_timings = 0;
605 }
606
607 if (!need_tv_timings) {
608 crtc_timing.usH_Total = adjusted_mode->crtc_htotal;
609 crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay;
610 crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start;
611 crtc_timing.usH_SyncWidth =
612 adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
569 613
570 crtc_timing.usV_Total = adjusted_mode->crtc_vtotal; 614 crtc_timing.usV_Total = adjusted_mode->crtc_vtotal;
571 crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay; 615 crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay;
572 crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start; 616 crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start;
573 crtc_timing.usV_SyncWidth = 617 crtc_timing.usV_SyncWidth =
574 adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start; 618 adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
575 619
576 if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) 620 if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
577 crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY; 621 crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY;
578 622
579 if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) 623 if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
580 crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY; 624 crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY;
581 625
582 if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) 626 if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC)
583 crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC; 627 crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC;
584 628
585 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) 629 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
586 crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE; 630 crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE;
587 631
588 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) 632 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
589 crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE; 633 crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE;
634 }
590 635
591 atombios_crtc_set_pll(crtc, adjusted_mode); 636 atombios_crtc_set_pll(crtc, adjusted_mode);
592 atombios_crtc_set_timing(crtc, &crtc_timing); 637 atombios_crtc_set_timing(crtc, &crtc_timing);