diff options
-rw-r--r-- | drivers/gpu/drm/radeon/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/atombios.h | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 99 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 75 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 215 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_drv.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_encoders.c | 116 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 44 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 339 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_legacy_tv.c | 904 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 50 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_reg.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv515.c | 452 |
15 files changed, 1941 insertions, 388 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 6fb842962490..c5db0c4fe788 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
@@ -47,7 +47,7 @@ radeon-$(CONFIG_DRM_RADEON_KMS) += radeon_device.o radeon_kms.o \ | |||
47 | radeon_clocks.o radeon_fb.o radeon_gem.o radeon_ring.o radeon_irq_kms.o \ | 47 | radeon_clocks.o radeon_fb.o radeon_gem.o radeon_ring.o radeon_irq_kms.o \ |
48 | radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ | 48 | radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ |
49 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rs780.o rv770.o \ | 49 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rs780.o rv770.o \ |
50 | radeon_test.o r200.o | 50 | radeon_test.o r200.o radeon_legacy_tv.o |
51 | 51 | ||
52 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o | 52 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o |
53 | 53 | ||
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index cf67928abbc8..5d402086bc47 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h | |||
@@ -2374,6 +2374,17 @@ typedef struct _ATOM_ANALOG_TV_INFO { | |||
2374 | ATOM_MODE_TIMING aModeTimings[MAX_SUPPORTED_TV_TIMING]; | 2374 | ATOM_MODE_TIMING aModeTimings[MAX_SUPPORTED_TV_TIMING]; |
2375 | } ATOM_ANALOG_TV_INFO; | 2375 | } ATOM_ANALOG_TV_INFO; |
2376 | 2376 | ||
2377 | #define MAX_SUPPORTED_TV_TIMING_V1_2 3 | ||
2378 | |||
2379 | typedef struct _ATOM_ANALOG_TV_INFO_V1_2 { | ||
2380 | ATOM_COMMON_TABLE_HEADER sHeader; | ||
2381 | UCHAR ucTV_SupportedStandard; | ||
2382 | UCHAR ucTV_BootUpDefaultStandard; | ||
2383 | UCHAR ucExt_TV_ASIC_ID; | ||
2384 | UCHAR ucExt_TV_ASIC_SlaveAddr; | ||
2385 | ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_TV_TIMING]; | ||
2386 | } ATOM_ANALOG_TV_INFO_V1_2; | ||
2387 | |||
2377 | /**************************************************************************/ | 2388 | /**************************************************************************/ |
2378 | /* VRAM usage and their defintions */ | 2389 | /* VRAM usage and their defintions */ |
2379 | 2390 | ||
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 */ | ||
35 | bool 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); | ||
34 | static void atombios_overscan_setup(struct drm_crtc *crtc, | 38 | static 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); |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 6c35c3c29191..e47f2fc294ce 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -66,6 +66,7 @@ extern int radeon_gart_size; | |||
66 | extern int radeon_benchmarking; | 66 | extern int radeon_benchmarking; |
67 | extern int radeon_testing; | 67 | extern int radeon_testing; |
68 | extern int radeon_connector_table; | 68 | extern int radeon_connector_table; |
69 | extern int radeon_tv; | ||
69 | 70 | ||
70 | /* | 71 | /* |
71 | * Copy from radeon_drv.h so we don't have to include both and have conflicting | 72 | * Copy from radeon_drv.h so we don't have to include both and have conflicting |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index fcfe5c02d744..bba9b4bd8f5c 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -471,11 +471,6 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
471 | continue; | 471 | continue; |
472 | } | 472 | } |
473 | 473 | ||
474 | if (i == ATOM_DEVICE_TV1_INDEX) { | ||
475 | DRM_DEBUG("Skipping TV Out\n"); | ||
476 | continue; | ||
477 | } | ||
478 | |||
479 | bios_connectors[i].connector_type = | 474 | bios_connectors[i].connector_type = |
480 | supported_devices_connector_convert[ci.sucConnectorInfo. | 475 | supported_devices_connector_convert[ci.sucConnectorInfo. |
481 | sbfAccess. | 476 | sbfAccess. |
@@ -858,6 +853,72 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder) | |||
858 | return p_dac; | 853 | return p_dac; |
859 | } | 854 | } |
860 | 855 | ||
856 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | ||
857 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, | ||
858 | int32_t *pixel_clock) | ||
859 | { | ||
860 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
861 | ATOM_ANALOG_TV_INFO *tv_info; | ||
862 | ATOM_ANALOG_TV_INFO_V1_2 *tv_info_v1_2; | ||
863 | ATOM_DTD_FORMAT *dtd_timings; | ||
864 | int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info); | ||
865 | u8 frev, crev; | ||
866 | uint16_t data_offset; | ||
867 | |||
868 | atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset); | ||
869 | |||
870 | switch (crev) { | ||
871 | case 1: | ||
872 | tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset); | ||
873 | if (index > MAX_SUPPORTED_TV_TIMING) | ||
874 | return false; | ||
875 | |||
876 | crtc_timing->usH_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); | ||
877 | crtc_timing->usH_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp); | ||
878 | crtc_timing->usH_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart); | ||
879 | crtc_timing->usH_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth); | ||
880 | |||
881 | crtc_timing->usV_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total); | ||
882 | crtc_timing->usV_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp); | ||
883 | crtc_timing->usV_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart); | ||
884 | crtc_timing->usV_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth); | ||
885 | |||
886 | crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo; | ||
887 | |||
888 | crtc_timing->ucOverscanRight = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanRight); | ||
889 | crtc_timing->ucOverscanLeft = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanLeft); | ||
890 | crtc_timing->ucOverscanBottom = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanBottom); | ||
891 | crtc_timing->ucOverscanTop = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanTop); | ||
892 | *pixel_clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; | ||
893 | |||
894 | if (index == 1) { | ||
895 | /* PAL timings appear to have wrong values for totals */ | ||
896 | crtc_timing->usH_Total -= 1; | ||
897 | crtc_timing->usV_Total -= 1; | ||
898 | } | ||
899 | break; | ||
900 | case 2: | ||
901 | tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset); | ||
902 | if (index > MAX_SUPPORTED_TV_TIMING_V1_2) | ||
903 | return false; | ||
904 | |||
905 | dtd_timings = &tv_info_v1_2->aModeTimings[index]; | ||
906 | crtc_timing->usH_Total = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHBlanking_Time); | ||
907 | crtc_timing->usH_Disp = le16_to_cpu(dtd_timings->usHActive); | ||
908 | crtc_timing->usH_SyncStart = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHSyncOffset); | ||
909 | crtc_timing->usH_SyncWidth = le16_to_cpu(dtd_timings->usHSyncWidth); | ||
910 | crtc_timing->usV_Total = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVBlanking_Time); | ||
911 | crtc_timing->usV_Disp = le16_to_cpu(dtd_timings->usVActive); | ||
912 | crtc_timing->usV_SyncStart = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVSyncOffset); | ||
913 | crtc_timing->usV_SyncWidth = le16_to_cpu(dtd_timings->usVSyncWidth); | ||
914 | |||
915 | crtc_timing->susModeMiscInfo.usAccess = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess); | ||
916 | *pixel_clock = le16_to_cpu(dtd_timings->usPixClk) * 10; | ||
917 | break; | ||
918 | } | ||
919 | return true; | ||
920 | } | ||
921 | |||
861 | struct radeon_encoder_tv_dac * | 922 | struct radeon_encoder_tv_dac * |
862 | radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) | 923 | radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) |
863 | { | 924 | { |
@@ -948,10 +1009,10 @@ void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) | |||
948 | uint32_t bios_2_scratch, bios_6_scratch; | 1009 | uint32_t bios_2_scratch, bios_6_scratch; |
949 | 1010 | ||
950 | if (rdev->family >= CHIP_R600) { | 1011 | if (rdev->family >= CHIP_R600) { |
951 | bios_2_scratch = RREG32(R600_BIOS_0_SCRATCH); | 1012 | bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH); |
952 | bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH); | 1013 | bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH); |
953 | } else { | 1014 | } else { |
954 | bios_2_scratch = RREG32(RADEON_BIOS_0_SCRATCH); | 1015 | bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH); |
955 | bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); | 1016 | bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); |
956 | } | 1017 | } |
957 | 1018 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 70ede6a52d4e..6a2b0296adff 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -94,6 +94,54 @@ struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) | |||
94 | return NULL; | 94 | return NULL; |
95 | } | 95 | } |
96 | 96 | ||
97 | |||
98 | /* | ||
99 | * radeon_connector_analog_encoder_conflict_solve | ||
100 | * - search for other connectors sharing this encoder | ||
101 | * if priority is true, then set them disconnected if this is connected | ||
102 | * if priority is false, set us disconnected if they are connected | ||
103 | */ | ||
104 | static enum drm_connector_status | ||
105 | radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector, | ||
106 | struct drm_encoder *encoder, | ||
107 | enum drm_connector_status current_status, | ||
108 | bool priority) | ||
109 | { | ||
110 | struct drm_device *dev = connector->dev; | ||
111 | struct drm_connector *conflict; | ||
112 | int i; | ||
113 | |||
114 | list_for_each_entry(conflict, &dev->mode_config.connector_list, head) { | ||
115 | if (conflict == connector) | ||
116 | continue; | ||
117 | |||
118 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { | ||
119 | if (conflict->encoder_ids[i] == 0) | ||
120 | break; | ||
121 | |||
122 | /* if the IDs match */ | ||
123 | if (conflict->encoder_ids[i] == encoder->base.id) { | ||
124 | if (conflict->status != connector_status_connected) | ||
125 | continue; | ||
126 | |||
127 | if (priority == true) { | ||
128 | DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict)); | ||
129 | DRM_INFO("in favor of %s\n", drm_get_connector_name(connector)); | ||
130 | conflict->status = connector_status_disconnected; | ||
131 | radeon_connector_update_scratch_regs(conflict, connector_status_disconnected); | ||
132 | } else { | ||
133 | DRM_INFO("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector)); | ||
134 | DRM_INFO("in favor of %s\n", drm_get_connector_name(conflict)); | ||
135 | current_status = connector_status_disconnected; | ||
136 | } | ||
137 | break; | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | return current_status; | ||
142 | |||
143 | } | ||
144 | |||
97 | static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encoder) | 145 | static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encoder) |
98 | { | 146 | { |
99 | struct drm_device *dev = encoder->dev; | 147 | struct drm_device *dev = encoder->dev; |
@@ -213,7 +261,6 @@ static int radeon_vga_get_modes(struct drm_connector *connector) | |||
213 | static int radeon_vga_mode_valid(struct drm_connector *connector, | 261 | static int radeon_vga_mode_valid(struct drm_connector *connector, |
214 | struct drm_display_mode *mode) | 262 | struct drm_display_mode *mode) |
215 | { | 263 | { |
216 | |||
217 | return MODE_OK; | 264 | return MODE_OK; |
218 | } | 265 | } |
219 | 266 | ||
@@ -225,22 +272,22 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect | |||
225 | bool dret; | 272 | bool dret; |
226 | enum drm_connector_status ret = connector_status_disconnected; | 273 | enum drm_connector_status ret = connector_status_disconnected; |
227 | 274 | ||
275 | encoder = radeon_best_single_encoder(connector); | ||
276 | if (!encoder) | ||
277 | ret = connector_status_disconnected; | ||
278 | |||
228 | radeon_i2c_do_lock(radeon_connector, 1); | 279 | radeon_i2c_do_lock(radeon_connector, 1); |
229 | dret = radeon_ddc_probe(radeon_connector); | 280 | dret = radeon_ddc_probe(radeon_connector); |
230 | radeon_i2c_do_lock(radeon_connector, 0); | 281 | radeon_i2c_do_lock(radeon_connector, 0); |
231 | if (dret) | 282 | if (dret) |
232 | ret = connector_status_connected; | 283 | ret = connector_status_connected; |
233 | else { | 284 | else { |
234 | /* if EDID fails to a load detect */ | 285 | encoder_funcs = encoder->helper_private; |
235 | encoder = radeon_best_single_encoder(connector); | 286 | ret = encoder_funcs->detect(encoder, connector); |
236 | if (!encoder) | ||
237 | ret = connector_status_disconnected; | ||
238 | else { | ||
239 | encoder_funcs = encoder->helper_private; | ||
240 | ret = encoder_funcs->detect(encoder, connector); | ||
241 | } | ||
242 | } | 287 | } |
243 | 288 | ||
289 | if (ret == connector_status_connected) | ||
290 | ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true); | ||
244 | radeon_connector_update_scratch_regs(connector, ret); | 291 | radeon_connector_update_scratch_regs(connector, ret); |
245 | return ret; | 292 | return ret; |
246 | } | 293 | } |
@@ -259,21 +306,87 @@ struct drm_connector_funcs radeon_vga_connector_funcs = { | |||
259 | .set_property = radeon_connector_set_property, | 306 | .set_property = radeon_connector_set_property, |
260 | }; | 307 | }; |
261 | 308 | ||
309 | static struct drm_display_mode tv_fixed_mode = { | ||
310 | DRM_MODE("800x600", DRM_MODE_TYPE_DEFAULT, 38250, 800, 832, | ||
311 | 912, 1024, 0, 600, 603, 607, 624, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC), | ||
312 | }; | ||
313 | |||
314 | static int radeon_tv_get_modes(struct drm_connector *connector) | ||
315 | { | ||
316 | struct drm_device *dev = connector->dev; | ||
317 | struct drm_display_mode *tv_mode; | ||
318 | |||
319 | tv_mode = drm_mode_duplicate(dev, &tv_fixed_mode); | ||
320 | tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; | ||
321 | |||
322 | drm_mode_probed_add(connector, tv_mode); | ||
323 | |||
324 | return 1; | ||
325 | } | ||
326 | |||
327 | static int radeon_tv_mode_valid(struct drm_connector *connector, | ||
328 | struct drm_display_mode *mode) | ||
329 | { | ||
330 | return MODE_OK; | ||
331 | } | ||
332 | |||
333 | static enum drm_connector_status radeon_tv_detect(struct drm_connector *connector) | ||
334 | { | ||
335 | struct drm_encoder *encoder; | ||
336 | struct drm_encoder_helper_funcs *encoder_funcs; | ||
337 | int ret; | ||
338 | |||
339 | encoder = radeon_best_single_encoder(connector); | ||
340 | if (!encoder) | ||
341 | ret = connector_status_disconnected; | ||
342 | else { | ||
343 | encoder_funcs = encoder->helper_private; | ||
344 | ret = encoder_funcs->detect(encoder, connector); | ||
345 | } | ||
346 | if (ret == connector_status_connected) | ||
347 | ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false); | ||
348 | radeon_connector_update_scratch_regs(connector, ret); | ||
349 | return ret; | ||
350 | } | ||
351 | |||
352 | struct drm_connector_helper_funcs radeon_tv_connector_helper_funcs = { | ||
353 | .get_modes = radeon_tv_get_modes, | ||
354 | .mode_valid = radeon_tv_mode_valid, | ||
355 | .best_encoder = radeon_best_single_encoder, | ||
356 | }; | ||
357 | |||
358 | struct drm_connector_funcs radeon_tv_connector_funcs = { | ||
359 | .dpms = drm_helper_connector_dpms, | ||
360 | .detect = radeon_tv_detect, | ||
361 | .fill_modes = drm_helper_probe_single_connector_modes, | ||
362 | .destroy = radeon_connector_destroy, | ||
363 | .set_property = radeon_connector_set_property, | ||
364 | }; | ||
365 | |||
262 | static int radeon_dvi_get_modes(struct drm_connector *connector) | 366 | static int radeon_dvi_get_modes(struct drm_connector *connector) |
263 | { | 367 | { |
264 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 368 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
265 | int ret; | 369 | int ret; |
266 | 370 | ||
267 | ret = radeon_ddc_get_modes(radeon_connector); | 371 | ret = radeon_ddc_get_modes(radeon_connector); |
268 | /* reset scratch regs here since radeon_dvi_detect doesn't check digital bit */ | ||
269 | radeon_connector_update_scratch_regs(connector, connector_status_connected); | ||
270 | return ret; | 372 | return ret; |
271 | } | 373 | } |
272 | 374 | ||
375 | /* | ||
376 | * DVI is complicated | ||
377 | * Do a DDC probe, if DDC probe passes, get the full EDID so | ||
378 | * we can do analog/digital monitor detection at this point. | ||
379 | * If the monitor is an analog monitor or we got no DDC, | ||
380 | * we need to find the DAC encoder object for this connector. | ||
381 | * If we got no DDC, we do load detection on the DAC encoder object. | ||
382 | * If we got analog DDC or load detection passes on the DAC encoder | ||
383 | * we have to check if this analog encoder is shared with anyone else (TV) | ||
384 | * if its shared we have to set the other connector to disconnected. | ||
385 | */ | ||
273 | static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector) | 386 | static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector) |
274 | { | 387 | { |
275 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 388 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
276 | struct drm_encoder *encoder; | 389 | struct drm_encoder *encoder = NULL; |
277 | struct drm_encoder_helper_funcs *encoder_funcs; | 390 | struct drm_encoder_helper_funcs *encoder_funcs; |
278 | struct drm_mode_object *obj; | 391 | struct drm_mode_object *obj; |
279 | int i; | 392 | int i; |
@@ -283,32 +396,58 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect | |||
283 | radeon_i2c_do_lock(radeon_connector, 1); | 396 | radeon_i2c_do_lock(radeon_connector, 1); |
284 | dret = radeon_ddc_probe(radeon_connector); | 397 | dret = radeon_ddc_probe(radeon_connector); |
285 | radeon_i2c_do_lock(radeon_connector, 0); | 398 | radeon_i2c_do_lock(radeon_connector, 0); |
286 | if (dret) | 399 | if (dret) { |
287 | ret = connector_status_connected; | 400 | radeon_i2c_do_lock(radeon_connector, 1); |
288 | else { | 401 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); |
289 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { | 402 | radeon_i2c_do_lock(radeon_connector, 0); |
290 | if (connector->encoder_ids[i] == 0) | 403 | |
291 | break; | 404 | if (!radeon_connector->edid) { |
405 | DRM_ERROR("DDC responded but not EDID found for %s\n", | ||
406 | drm_get_connector_name(connector)); | ||
407 | } else { | ||
408 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); | ||
409 | |||
410 | /* if this isn't a digital monitor | ||
411 | then we need to make sure we don't have any | ||
412 | TV conflicts */ | ||
413 | ret = connector_status_connected; | ||
414 | } | ||
415 | } | ||
416 | |||
417 | if ((ret == connector_status_connected) && (radeon_connector->use_digital == true)) | ||
418 | goto out; | ||
419 | |||
420 | /* find analog encoder */ | ||
421 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { | ||
422 | if (connector->encoder_ids[i] == 0) | ||
423 | break; | ||
292 | 424 | ||
293 | obj = drm_mode_object_find(connector->dev, | 425 | obj = drm_mode_object_find(connector->dev, |
294 | connector->encoder_ids[i], | 426 | connector->encoder_ids[i], |
295 | DRM_MODE_OBJECT_ENCODER); | 427 | DRM_MODE_OBJECT_ENCODER); |
296 | if (!obj) | 428 | if (!obj) |
297 | continue; | 429 | continue; |
298 | 430 | ||
299 | encoder = obj_to_encoder(obj); | 431 | encoder = obj_to_encoder(obj); |
300 | 432 | ||
301 | encoder_funcs = encoder->helper_private; | 433 | encoder_funcs = encoder->helper_private; |
302 | if (encoder_funcs->detect) { | 434 | if (encoder_funcs->detect) { |
435 | if (ret != connector_status_connected) { | ||
303 | ret = encoder_funcs->detect(encoder, connector); | 436 | ret = encoder_funcs->detect(encoder, connector); |
304 | if (ret == connector_status_connected) { | 437 | if (ret == connector_status_connected) { |
305 | radeon_connector->use_digital = 0; | 438 | radeon_connector->use_digital = false; |
306 | break; | ||
307 | } | 439 | } |
308 | } | 440 | } |
441 | break; | ||
309 | } | 442 | } |
310 | } | 443 | } |
311 | 444 | ||
445 | if ((ret == connector_status_connected) && (radeon_connector->use_digital == false) && | ||
446 | encoder) { | ||
447 | ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true); | ||
448 | } | ||
449 | |||
450 | out: | ||
312 | /* updated in get modes as well since we need to know if it's analog or digital */ | 451 | /* updated in get modes as well since we need to know if it's analog or digital */ |
313 | radeon_connector_update_scratch_regs(connector, ret); | 452 | radeon_connector_update_scratch_regs(connector, ret); |
314 | return ret; | 453 | return ret; |
@@ -332,7 +471,7 @@ struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) | |||
332 | 471 | ||
333 | encoder = obj_to_encoder(obj); | 472 | encoder = obj_to_encoder(obj); |
334 | 473 | ||
335 | if (radeon_connector->use_digital) { | 474 | if (radeon_connector->use_digital == true) { |
336 | if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS) | 475 | if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS) |
337 | return encoder; | 476 | return encoder; |
338 | } else { | 477 | } else { |
@@ -385,10 +524,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
385 | uint32_t subpixel_order = SubPixelNone; | 524 | uint32_t subpixel_order = SubPixelNone; |
386 | 525 | ||
387 | /* fixme - tv/cv/din */ | 526 | /* fixme - tv/cv/din */ |
388 | if ((connector_type == DRM_MODE_CONNECTOR_Unknown) || | 527 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) |
389 | (connector_type == DRM_MODE_CONNECTOR_SVIDEO) || | ||
390 | (connector_type == DRM_MODE_CONNECTOR_Composite) || | ||
391 | (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) | ||
392 | return; | 528 | return; |
393 | 529 | ||
394 | /* see if we already added it */ | 530 | /* see if we already added it */ |
@@ -480,6 +616,10 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
480 | case DRM_MODE_CONNECTOR_SVIDEO: | 616 | case DRM_MODE_CONNECTOR_SVIDEO: |
481 | case DRM_MODE_CONNECTOR_Composite: | 617 | case DRM_MODE_CONNECTOR_Composite: |
482 | case DRM_MODE_CONNECTOR_9PinDIN: | 618 | case DRM_MODE_CONNECTOR_9PinDIN: |
619 | if (radeon_tv == 1) { | ||
620 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); | ||
621 | drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); | ||
622 | } | ||
483 | break; | 623 | break; |
484 | case DRM_MODE_CONNECTOR_LVDS: | 624 | case DRM_MODE_CONNECTOR_LVDS: |
485 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 625 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
@@ -522,10 +662,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
522 | uint32_t subpixel_order = SubPixelNone; | 662 | uint32_t subpixel_order = SubPixelNone; |
523 | 663 | ||
524 | /* fixme - tv/cv/din */ | 664 | /* fixme - tv/cv/din */ |
525 | if ((connector_type == DRM_MODE_CONNECTOR_Unknown) || | 665 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) |
526 | (connector_type == DRM_MODE_CONNECTOR_SVIDEO) || | ||
527 | (connector_type == DRM_MODE_CONNECTOR_Composite) || | ||
528 | (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) | ||
529 | return; | 666 | return; |
530 | 667 | ||
531 | /* see if we already added it */ | 668 | /* see if we already added it */ |
@@ -578,6 +715,10 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
578 | case DRM_MODE_CONNECTOR_SVIDEO: | 715 | case DRM_MODE_CONNECTOR_SVIDEO: |
579 | case DRM_MODE_CONNECTOR_Composite: | 716 | case DRM_MODE_CONNECTOR_Composite: |
580 | case DRM_MODE_CONNECTOR_9PinDIN: | 717 | case DRM_MODE_CONNECTOR_9PinDIN: |
718 | if (radeon_tv == 1) { | ||
719 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); | ||
720 | drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); | ||
721 | } | ||
581 | break; | 722 | break; |
582 | case DRM_MODE_CONNECTOR_LVDS: | 723 | case DRM_MODE_CONNECTOR_LVDS: |
583 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); | 724 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index af035605d147..9d817a62e7f1 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -312,7 +312,7 @@ static void radeon_print_display_setup(struct drm_device *dev) | |||
312 | } | 312 | } |
313 | } | 313 | } |
314 | 314 | ||
315 | bool radeon_setup_enc_conn(struct drm_device *dev) | 315 | static bool radeon_setup_enc_conn(struct drm_device *dev) |
316 | { | 316 | { |
317 | struct radeon_device *rdev = dev->dev_private; | 317 | struct radeon_device *rdev = dev->dev_private; |
318 | struct drm_connector *drm_connector; | 318 | struct drm_connector *drm_connector; |
@@ -346,9 +346,13 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | |||
346 | 346 | ||
347 | if (!radeon_connector->ddc_bus) | 347 | if (!radeon_connector->ddc_bus) |
348 | return -1; | 348 | return -1; |
349 | radeon_i2c_do_lock(radeon_connector, 1); | 349 | if (!radeon_connector->edid) { |
350 | edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); | 350 | radeon_i2c_do_lock(radeon_connector, 1); |
351 | radeon_i2c_do_lock(radeon_connector, 0); | 351 | edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); |
352 | radeon_i2c_do_lock(radeon_connector, 0); | ||
353 | } else | ||
354 | edid = radeon_connector->edid; | ||
355 | |||
352 | if (edid) { | 356 | if (edid) { |
353 | /* update digital bits here */ | 357 | /* update digital bits here */ |
354 | if (edid->input & DRM_EDID_INPUT_DIGITAL) | 358 | if (edid->input & DRM_EDID_INPUT_DIGITAL) |
@@ -677,7 +681,6 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
677 | continue; | 681 | continue; |
678 | if (first) { | 682 | if (first) { |
679 | radeon_crtc->rmx_type = radeon_encoder->rmx_type; | 683 | radeon_crtc->rmx_type = radeon_encoder->rmx_type; |
680 | radeon_crtc->devices = radeon_encoder->devices; | ||
681 | memcpy(&radeon_crtc->native_mode, | 684 | memcpy(&radeon_crtc->native_mode, |
682 | &radeon_encoder->native_mode, | 685 | &radeon_encoder->native_mode, |
683 | sizeof(struct radeon_native_mode)); | 686 | sizeof(struct radeon_native_mode)); |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 0bd5879a4957..133e975dbf0c 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -91,6 +91,7 @@ int radeon_gart_size = 512; /* default gart size */ | |||
91 | int radeon_benchmarking = 0; | 91 | int radeon_benchmarking = 0; |
92 | int radeon_testing = 0; | 92 | int radeon_testing = 0; |
93 | int radeon_connector_table = 0; | 93 | int radeon_connector_table = 0; |
94 | int radeon_tv = 1; | ||
94 | #endif | 95 | #endif |
95 | 96 | ||
96 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); | 97 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); |
@@ -123,6 +124,9 @@ module_param_named(test, radeon_testing, int, 0444); | |||
123 | 124 | ||
124 | MODULE_PARM_DESC(connector_table, "Force connector table"); | 125 | MODULE_PARM_DESC(connector_table, "Force connector table"); |
125 | module_param_named(connector_table, radeon_connector_table, int, 0444); | 126 | module_param_named(connector_table, radeon_connector_table, int, 0444); |
127 | |||
128 | MODULE_PARM_DESC(tv, "TV enable (0 = disable)"); | ||
129 | module_param_named(tv, radeon_tv, int, 0444); | ||
126 | #endif | 130 | #endif |
127 | 131 | ||
128 | static int radeon_suspend(struct drm_device *dev, pm_message_t state) | 132 | static int radeon_suspend(struct drm_device *dev, pm_message_t state) |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 0a92706eac19..5c4ede7c9901 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -126,6 +126,23 @@ radeon_link_encoder_connector(struct drm_device *dev) | |||
126 | } | 126 | } |
127 | } | 127 | } |
128 | 128 | ||
129 | void radeon_encoder_set_active_device(struct drm_encoder *encoder) | ||
130 | { | ||
131 | struct drm_device *dev = encoder->dev; | ||
132 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
133 | struct drm_connector *connector; | ||
134 | |||
135 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
136 | if (connector->encoder == encoder) { | ||
137 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
138 | radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices; | ||
139 | DRM_INFO("setting active device to %08x from %08x %08x for encoder %d\n", | ||
140 | radeon_encoder->active_device, radeon_encoder->devices, | ||
141 | radeon_connector->devices, encoder->encoder_type); | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | |||
129 | static struct drm_connector * | 146 | static struct drm_connector * |
130 | radeon_get_connector_for_encoder(struct drm_encoder *encoder) | 147 | radeon_get_connector_for_encoder(struct drm_encoder *encoder) |
131 | { | 148 | { |
@@ -244,9 +261,9 @@ atombios_dac_setup(struct drm_encoder *encoder, int action) | |||
244 | 261 | ||
245 | args.ucAction = action; | 262 | args.ucAction = action; |
246 | 263 | ||
247 | if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) | 264 | if (radeon_encoder->active_device & (ATOM_DEVICE_CRT_SUPPORT)) |
248 | args.ucDacStandard = ATOM_DAC1_PS2; | 265 | args.ucDacStandard = ATOM_DAC1_PS2; |
249 | else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) | 266 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
250 | args.ucDacStandard = ATOM_DAC1_CV; | 267 | args.ucDacStandard = ATOM_DAC1_CV; |
251 | else { | 268 | else { |
252 | switch (tv_std) { | 269 | switch (tv_std) { |
@@ -288,7 +305,7 @@ atombios_tv_setup(struct drm_encoder *encoder, int action) | |||
288 | 305 | ||
289 | args.sTVEncoder.ucAction = action; | 306 | args.sTVEncoder.ucAction = action; |
290 | 307 | ||
291 | if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) | 308 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
292 | args.sTVEncoder.ucTvStandard = ATOM_TV_CV; | 309 | args.sTVEncoder.ucTvStandard = ATOM_TV_CV; |
293 | else { | 310 | else { |
294 | switch (tv_std) { | 311 | switch (tv_std) { |
@@ -825,10 +842,10 @@ atombios_yuv_setup(struct drm_encoder *encoder, bool enable) | |||
825 | 842 | ||
826 | /* XXX: fix up scratch reg handling */ | 843 | /* XXX: fix up scratch reg handling */ |
827 | temp = RREG32(reg); | 844 | temp = RREG32(reg); |
828 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) | 845 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
829 | WREG32(reg, (ATOM_S3_TV1_ACTIVE | | 846 | WREG32(reg, (ATOM_S3_TV1_ACTIVE | |
830 | (radeon_crtc->crtc_id << 18))); | 847 | (radeon_crtc->crtc_id << 18))); |
831 | else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) | 848 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
832 | WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24))); | 849 | WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24))); |
833 | else | 850 | else |
834 | WREG32(reg, 0); | 851 | WREG32(reg, 0); |
@@ -851,9 +868,19 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
851 | DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; | 868 | DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; |
852 | int index = 0; | 869 | int index = 0; |
853 | bool is_dig = false; | 870 | bool is_dig = false; |
871 | int devices; | ||
854 | 872 | ||
855 | memset(&args, 0, sizeof(args)); | 873 | memset(&args, 0, sizeof(args)); |
856 | 874 | ||
875 | /* on DPMS off we have no idea if active device is meaningful */ | ||
876 | if (mode != DRM_MODE_DPMS_ON && !radeon_encoder->active_device) | ||
877 | devices = radeon_encoder->devices; | ||
878 | else | ||
879 | devices = radeon_encoder->active_device; | ||
880 | |||
881 | DRM_INFO("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", | ||
882 | radeon_encoder->encoder_id, mode, radeon_encoder->devices, | ||
883 | radeon_encoder->active_device); | ||
857 | switch (radeon_encoder->encoder_id) { | 884 | switch (radeon_encoder->encoder_id) { |
858 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | 885 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: |
859 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | 886 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: |
@@ -881,18 +908,18 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
881 | break; | 908 | break; |
882 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | 909 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: |
883 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | 910 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
884 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) | 911 | if (devices & (ATOM_DEVICE_TV_SUPPORT)) |
885 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); | 912 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); |
886 | else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) | 913 | else if (devices & (ATOM_DEVICE_CV_SUPPORT)) |
887 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); | 914 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); |
888 | else | 915 | else |
889 | index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); | 916 | index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); |
890 | break; | 917 | break; |
891 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | 918 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: |
892 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | 919 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
893 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) | 920 | if (devices & (ATOM_DEVICE_TV_SUPPORT)) |
894 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); | 921 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); |
895 | else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) | 922 | else if (devices & (ATOM_DEVICE_CV_SUPPORT)) |
896 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); | 923 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); |
897 | else | 924 | else |
898 | index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); | 925 | index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); |
@@ -979,18 +1006,18 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | |||
979 | break; | 1006 | break; |
980 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | 1007 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: |
981 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | 1008 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
982 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) | 1009 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
983 | args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; | 1010 | args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; |
984 | else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) | 1011 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
985 | args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; | 1012 | args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; |
986 | else | 1013 | else |
987 | args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX; | 1014 | args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX; |
988 | break; | 1015 | break; |
989 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | 1016 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: |
990 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | 1017 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
991 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) | 1018 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
992 | args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; | 1019 | args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; |
993 | else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) | 1020 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
994 | args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; | 1021 | args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; |
995 | else | 1022 | else |
996 | args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX; | 1023 | args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX; |
@@ -1019,17 +1046,17 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | |||
1019 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | 1046 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; |
1020 | break; | 1047 | break; |
1021 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | 1048 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
1022 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) | 1049 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
1023 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | 1050 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; |
1024 | else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) | 1051 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
1025 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | 1052 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; |
1026 | else | 1053 | else |
1027 | args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID; | 1054 | args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID; |
1028 | break; | 1055 | break; |
1029 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | 1056 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
1030 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) | 1057 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
1031 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | 1058 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; |
1032 | else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) | 1059 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
1033 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | 1060 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; |
1034 | else | 1061 | else |
1035 | args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID; | 1062 | args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID; |
@@ -1097,7 +1124,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1097 | atombios_set_encoder_crtc_source(encoder); | 1124 | atombios_set_encoder_crtc_source(encoder); |
1098 | 1125 | ||
1099 | if (ASIC_IS_AVIVO(rdev)) { | 1126 | if (ASIC_IS_AVIVO(rdev)) { |
1100 | if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) | 1127 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) |
1101 | atombios_yuv_setup(encoder, true); | 1128 | atombios_yuv_setup(encoder, true); |
1102 | else | 1129 | else |
1103 | atombios_yuv_setup(encoder, false); | 1130 | atombios_yuv_setup(encoder, false); |
@@ -1135,7 +1162,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1135 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | 1162 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: |
1136 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | 1163 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
1137 | atombios_dac_setup(encoder, ATOM_ENABLE); | 1164 | atombios_dac_setup(encoder, ATOM_ENABLE); |
1138 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | 1165 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) |
1139 | atombios_tv_setup(encoder, ATOM_ENABLE); | 1166 | atombios_tv_setup(encoder, ATOM_ENABLE); |
1140 | break; | 1167 | break; |
1141 | } | 1168 | } |
@@ -1143,11 +1170,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1143 | } | 1170 | } |
1144 | 1171 | ||
1145 | static bool | 1172 | static bool |
1146 | atombios_dac_load_detect(struct drm_encoder *encoder) | 1173 | atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *connector) |
1147 | { | 1174 | { |
1148 | struct drm_device *dev = encoder->dev; | 1175 | struct drm_device *dev = encoder->dev; |
1149 | struct radeon_device *rdev = dev->dev_private; | 1176 | struct radeon_device *rdev = dev->dev_private; |
1150 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1177 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1178 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
1151 | 1179 | ||
1152 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | | 1180 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | |
1153 | ATOM_DEVICE_CV_SUPPORT | | 1181 | ATOM_DEVICE_CV_SUPPORT | |
@@ -1168,15 +1196,15 @@ atombios_dac_load_detect(struct drm_encoder *encoder) | |||
1168 | else | 1196 | else |
1169 | args.sDacload.ucDacType = ATOM_DAC_B; | 1197 | args.sDacload.ucDacType = ATOM_DAC_B; |
1170 | 1198 | ||
1171 | if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) | 1199 | if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) |
1172 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT); | 1200 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT); |
1173 | else if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) | 1201 | else if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) |
1174 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT); | 1202 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT); |
1175 | else if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) { | 1203 | else if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { |
1176 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT); | 1204 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT); |
1177 | if (crev >= 3) | 1205 | if (crev >= 3) |
1178 | args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; | 1206 | args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; |
1179 | } else if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { | 1207 | } else if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { |
1180 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT); | 1208 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT); |
1181 | if (crev >= 3) | 1209 | if (crev >= 3) |
1182 | args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; | 1210 | args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; |
@@ -1195,9 +1223,10 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec | |||
1195 | struct drm_device *dev = encoder->dev; | 1223 | struct drm_device *dev = encoder->dev; |
1196 | struct radeon_device *rdev = dev->dev_private; | 1224 | struct radeon_device *rdev = dev->dev_private; |
1197 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1225 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1226 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
1198 | uint32_t bios_0_scratch; | 1227 | uint32_t bios_0_scratch; |
1199 | 1228 | ||
1200 | if (!atombios_dac_load_detect(encoder)) { | 1229 | if (!atombios_dac_load_detect(encoder, connector)) { |
1201 | DRM_DEBUG("detect returned false \n"); | 1230 | DRM_DEBUG("detect returned false \n"); |
1202 | return connector_status_unknown; | 1231 | return connector_status_unknown; |
1203 | } | 1232 | } |
@@ -1207,17 +1236,20 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec | |||
1207 | else | 1236 | else |
1208 | bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH); | 1237 | bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH); |
1209 | 1238 | ||
1210 | DRM_DEBUG("Bios 0 scratch %x\n", bios_0_scratch); | 1239 | DRM_DEBUG("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); |
1211 | if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) { | 1240 | if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) { |
1212 | if (bios_0_scratch & ATOM_S0_CRT1_MASK) | 1241 | if (bios_0_scratch & ATOM_S0_CRT1_MASK) |
1213 | return connector_status_connected; | 1242 | return connector_status_connected; |
1214 | } else if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) { | 1243 | } |
1244 | if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) { | ||
1215 | if (bios_0_scratch & ATOM_S0_CRT2_MASK) | 1245 | if (bios_0_scratch & ATOM_S0_CRT2_MASK) |
1216 | return connector_status_connected; | 1246 | return connector_status_connected; |
1217 | } else if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) { | 1247 | } |
1248 | if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { | ||
1218 | if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A)) | 1249 | if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A)) |
1219 | return connector_status_connected; | 1250 | return connector_status_connected; |
1220 | } else if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { | 1251 | } |
1252 | if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { | ||
1221 | if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) | 1253 | if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) |
1222 | return connector_status_connected; /* CTV */ | 1254 | return connector_status_connected; /* CTV */ |
1223 | else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) | 1255 | else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) |
@@ -1230,6 +1262,8 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | |||
1230 | { | 1262 | { |
1231 | radeon_atom_output_lock(encoder, true); | 1263 | radeon_atom_output_lock(encoder, true); |
1232 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | 1264 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); |
1265 | |||
1266 | radeon_encoder_set_active_device(encoder); | ||
1233 | } | 1267 | } |
1234 | 1268 | ||
1235 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) | 1269 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) |
@@ -1238,12 +1272,21 @@ static void radeon_atom_encoder_commit(struct drm_encoder *encoder) | |||
1238 | radeon_atom_output_lock(encoder, false); | 1272 | radeon_atom_output_lock(encoder, false); |
1239 | } | 1273 | } |
1240 | 1274 | ||
1275 | static void radeon_atom_encoder_disable(struct drm_encoder *encoder) | ||
1276 | { | ||
1277 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1278 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
1279 | DRM_INFO("setting active device to 0 for encoder %d\n", encoder->encoder_type); | ||
1280 | radeon_encoder->active_device = 0; | ||
1281 | } | ||
1282 | |||
1241 | static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = { | 1283 | static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = { |
1242 | .dpms = radeon_atom_encoder_dpms, | 1284 | .dpms = radeon_atom_encoder_dpms, |
1243 | .mode_fixup = radeon_atom_mode_fixup, | 1285 | .mode_fixup = radeon_atom_mode_fixup, |
1244 | .prepare = radeon_atom_encoder_prepare, | 1286 | .prepare = radeon_atom_encoder_prepare, |
1245 | .mode_set = radeon_atom_encoder_mode_set, | 1287 | .mode_set = radeon_atom_encoder_mode_set, |
1246 | .commit = radeon_atom_encoder_commit, | 1288 | .commit = radeon_atom_encoder_commit, |
1289 | .disable = radeon_atom_encoder_disable, | ||
1247 | /* no detect for TMDS/LVDS yet */ | 1290 | /* no detect for TMDS/LVDS yet */ |
1248 | }; | 1291 | }; |
1249 | 1292 | ||
@@ -1268,6 +1311,18 @@ static const struct drm_encoder_funcs radeon_atom_enc_funcs = { | |||
1268 | .destroy = radeon_enc_destroy, | 1311 | .destroy = radeon_enc_destroy, |
1269 | }; | 1312 | }; |
1270 | 1313 | ||
1314 | struct radeon_encoder_atom_dac * | ||
1315 | radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) | ||
1316 | { | ||
1317 | struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL); | ||
1318 | |||
1319 | if (!dac) | ||
1320 | return NULL; | ||
1321 | |||
1322 | dac->tv_std = TV_STD_NTSC; | ||
1323 | return dac; | ||
1324 | } | ||
1325 | |||
1271 | struct radeon_encoder_atom_dig * | 1326 | struct radeon_encoder_atom_dig * |
1272 | radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | 1327 | radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) |
1273 | { | 1328 | { |
@@ -1336,6 +1391,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
1336 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | 1391 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
1337 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | 1392 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
1338 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC); | 1393 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC); |
1394 | radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder); | ||
1339 | drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); | 1395 | drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); |
1340 | break; | 1396 | break; |
1341 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | 1397 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 0da72f18fd3a..0d29d15aa62b 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <drm/radeon_drm.h> | 28 | #include <drm/radeon_drm.h> |
29 | #include "radeon_fixed.h" | 29 | #include "radeon_fixed.h" |
30 | #include "radeon.h" | 30 | #include "radeon.h" |
31 | #include "atom.h" | ||
31 | 32 | ||
32 | static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, | 33 | static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, |
33 | struct drm_display_mode *mode, | 34 | struct drm_display_mode *mode, |
@@ -501,6 +502,7 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod | |||
501 | struct drm_device *dev = crtc->dev; | 502 | struct drm_device *dev = crtc->dev; |
502 | struct radeon_device *rdev = dev->dev_private; | 503 | struct radeon_device *rdev = dev->dev_private; |
503 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 504 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
505 | struct drm_encoder *encoder; | ||
504 | int format; | 506 | int format; |
505 | int hsync_start; | 507 | int hsync_start; |
506 | int hsync_wid; | 508 | int hsync_wid; |
@@ -509,8 +511,19 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod | |||
509 | uint32_t crtc_h_sync_strt_wid; | 511 | uint32_t crtc_h_sync_strt_wid; |
510 | uint32_t crtc_v_total_disp; | 512 | uint32_t crtc_v_total_disp; |
511 | uint32_t crtc_v_sync_strt_wid; | 513 | uint32_t crtc_v_sync_strt_wid; |
514 | bool is_tv = false; | ||
512 | 515 | ||
513 | DRM_DEBUG("\n"); | 516 | DRM_DEBUG("\n"); |
517 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
518 | if (encoder->crtc == crtc) { | ||
519 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
520 | if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { | ||
521 | is_tv = true; | ||
522 | DRM_INFO("crtc %d is connected to a TV\n", radeon_crtc->crtc_id); | ||
523 | break; | ||
524 | } | ||
525 | } | ||
526 | } | ||
514 | 527 | ||
515 | switch (crtc->fb->bits_per_pixel) { | 528 | switch (crtc->fb->bits_per_pixel) { |
516 | case 15: /* 555 */ | 529 | case 15: /* 555 */ |
@@ -642,6 +655,11 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod | |||
642 | WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); | 655 | WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); |
643 | } | 656 | } |
644 | 657 | ||
658 | if (is_tv) | ||
659 | radeon_legacy_tv_adjust_crtc_reg(encoder, &crtc_h_total_disp, | ||
660 | &crtc_h_sync_strt_wid, &crtc_v_total_disp, | ||
661 | &crtc_v_sync_strt_wid); | ||
662 | |||
645 | WREG32(RADEON_CRTC_H_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_h_total_disp); | 663 | WREG32(RADEON_CRTC_H_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_h_total_disp); |
646 | WREG32(RADEON_CRTC_H_SYNC_STRT_WID + radeon_crtc->crtc_offset, crtc_h_sync_strt_wid); | 664 | WREG32(RADEON_CRTC_H_SYNC_STRT_WID + radeon_crtc->crtc_offset, crtc_h_sync_strt_wid); |
647 | WREG32(RADEON_CRTC_V_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_v_total_disp); | 665 | WREG32(RADEON_CRTC_V_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_v_total_disp); |
@@ -668,7 +686,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
668 | uint32_t pll_ref_div = 0; | 686 | uint32_t pll_ref_div = 0; |
669 | uint32_t pll_fb_post_div = 0; | 687 | uint32_t pll_fb_post_div = 0; |
670 | uint32_t htotal_cntl = 0; | 688 | uint32_t htotal_cntl = 0; |
671 | 689 | bool is_tv = false; | |
672 | struct radeon_pll *pll; | 690 | struct radeon_pll *pll; |
673 | 691 | ||
674 | struct { | 692 | struct { |
@@ -703,6 +721,13 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
703 | 721 | ||
704 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 722 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
705 | if (encoder->crtc == crtc) { | 723 | if (encoder->crtc == crtc) { |
724 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
725 | |||
726 | if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { | ||
727 | is_tv = true; | ||
728 | break; | ||
729 | } | ||
730 | |||
706 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) | 731 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) |
707 | pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; | 732 | pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; |
708 | if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { | 733 | if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { |
@@ -766,6 +791,12 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
766 | ~(RADEON_PIX2CLK_SRC_SEL_MASK)) | | 791 | ~(RADEON_PIX2CLK_SRC_SEL_MASK)) | |
767 | RADEON_PIX2CLK_SRC_SEL_P2PLLCLK); | 792 | RADEON_PIX2CLK_SRC_SEL_P2PLLCLK); |
768 | 793 | ||
794 | if (is_tv) { | ||
795 | radeon_legacy_tv_adjust_pll2(encoder, &htotal_cntl, | ||
796 | &pll_ref_div, &pll_fb_post_div, | ||
797 | &pixclks_cntl); | ||
798 | } | ||
799 | |||
769 | WREG32_PLL_P(RADEON_PIXCLKS_CNTL, | 800 | WREG32_PLL_P(RADEON_PIXCLKS_CNTL, |
770 | RADEON_PIX2CLK_SRC_SEL_CPUCLK, | 801 | RADEON_PIX2CLK_SRC_SEL_CPUCLK, |
771 | ~(RADEON_PIX2CLK_SRC_SEL_MASK)); | 802 | ~(RADEON_PIX2CLK_SRC_SEL_MASK)); |
@@ -820,6 +851,15 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
820 | 851 | ||
821 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); | 852 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); |
822 | } else { | 853 | } else { |
854 | uint32_t pixclks_cntl; | ||
855 | |||
856 | |||
857 | if (is_tv) { | ||
858 | pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); | ||
859 | radeon_legacy_tv_adjust_pll1(encoder, &htotal_cntl, &pll_ref_div, | ||
860 | &pll_fb_post_div, &pixclks_cntl); | ||
861 | } | ||
862 | |||
823 | if (rdev->flags & RADEON_IS_MOBILITY) { | 863 | if (rdev->flags & RADEON_IS_MOBILITY) { |
824 | /* A temporal workaround for the occational blanking on certain laptop panels. | 864 | /* A temporal workaround for the occational blanking on certain laptop panels. |
825 | This appears to related to the PLL divider registers (fail to lock?). | 865 | This appears to related to the PLL divider registers (fail to lock?). |
@@ -914,6 +954,8 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
914 | RADEON_VCLK_SRC_SEL_PPLLCLK, | 954 | RADEON_VCLK_SRC_SEL_PPLLCLK, |
915 | ~(RADEON_VCLK_SRC_SEL_MASK)); | 955 | ~(RADEON_VCLK_SRC_SEL_MASK)); |
916 | 956 | ||
957 | if (is_tv) | ||
958 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); | ||
917 | } | 959 | } |
918 | } | 960 | } |
919 | 961 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 9322675ef6d0..0aaafcd2089f 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -29,6 +29,15 @@ | |||
29 | #include "radeon.h" | 29 | #include "radeon.h" |
30 | #include "atom.h" | 30 | #include "atom.h" |
31 | 31 | ||
32 | static void radeon_legacy_encoder_disable(struct drm_encoder *encoder) | ||
33 | { | ||
34 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
35 | struct drm_encoder_helper_funcs *encoder_funcs; | ||
36 | |||
37 | encoder_funcs = encoder->helper_private; | ||
38 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF); | ||
39 | radeon_encoder->active_device = 0; | ||
40 | } | ||
32 | 41 | ||
33 | static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) | 42 | static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) |
34 | { | 43 | { |
@@ -98,6 +107,8 @@ static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder) | |||
98 | else | 107 | else |
99 | radeon_combios_output_lock(encoder, true); | 108 | radeon_combios_output_lock(encoder, true); |
100 | radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF); | 109 | radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF); |
110 | |||
111 | radeon_encoder_set_active_device(encoder); | ||
101 | } | 112 | } |
102 | 113 | ||
103 | static void radeon_legacy_lvds_commit(struct drm_encoder *encoder) | 114 | static void radeon_legacy_lvds_commit(struct drm_encoder *encoder) |
@@ -195,6 +206,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = { | |||
195 | .prepare = radeon_legacy_lvds_prepare, | 206 | .prepare = radeon_legacy_lvds_prepare, |
196 | .mode_set = radeon_legacy_lvds_mode_set, | 207 | .mode_set = radeon_legacy_lvds_mode_set, |
197 | .commit = radeon_legacy_lvds_commit, | 208 | .commit = radeon_legacy_lvds_commit, |
209 | .disable = radeon_legacy_encoder_disable, | ||
198 | }; | 210 | }; |
199 | 211 | ||
200 | 212 | ||
@@ -260,6 +272,7 @@ static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder) | |||
260 | else | 272 | else |
261 | radeon_combios_output_lock(encoder, true); | 273 | radeon_combios_output_lock(encoder, true); |
262 | radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF); | 274 | radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF); |
275 | radeon_encoder_set_active_device(encoder); | ||
263 | } | 276 | } |
264 | 277 | ||
265 | static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder) | 278 | static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder) |
@@ -402,6 +415,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_fu | |||
402 | .mode_set = radeon_legacy_primary_dac_mode_set, | 415 | .mode_set = radeon_legacy_primary_dac_mode_set, |
403 | .commit = radeon_legacy_primary_dac_commit, | 416 | .commit = radeon_legacy_primary_dac_commit, |
404 | .detect = radeon_legacy_primary_dac_detect, | 417 | .detect = radeon_legacy_primary_dac_detect, |
418 | .disable = radeon_legacy_encoder_disable, | ||
405 | }; | 419 | }; |
406 | 420 | ||
407 | 421 | ||
@@ -454,6 +468,7 @@ static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder) | |||
454 | else | 468 | else |
455 | radeon_combios_output_lock(encoder, true); | 469 | radeon_combios_output_lock(encoder, true); |
456 | radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF); | 470 | radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF); |
471 | radeon_encoder_set_active_device(encoder); | ||
457 | } | 472 | } |
458 | 473 | ||
459 | static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder) | 474 | static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder) |
@@ -566,6 +581,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs | |||
566 | .prepare = radeon_legacy_tmds_int_prepare, | 581 | .prepare = radeon_legacy_tmds_int_prepare, |
567 | .mode_set = radeon_legacy_tmds_int_mode_set, | 582 | .mode_set = radeon_legacy_tmds_int_mode_set, |
568 | .commit = radeon_legacy_tmds_int_commit, | 583 | .commit = radeon_legacy_tmds_int_commit, |
584 | .disable = radeon_legacy_encoder_disable, | ||
569 | }; | 585 | }; |
570 | 586 | ||
571 | 587 | ||
@@ -620,6 +636,7 @@ static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder) | |||
620 | else | 636 | else |
621 | radeon_combios_output_lock(encoder, true); | 637 | radeon_combios_output_lock(encoder, true); |
622 | radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF); | 638 | radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF); |
639 | radeon_encoder_set_active_device(encoder); | ||
623 | } | 640 | } |
624 | 641 | ||
625 | static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder) | 642 | static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder) |
@@ -706,6 +723,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs | |||
706 | .prepare = radeon_legacy_tmds_ext_prepare, | 723 | .prepare = radeon_legacy_tmds_ext_prepare, |
707 | .mode_set = radeon_legacy_tmds_ext_mode_set, | 724 | .mode_set = radeon_legacy_tmds_ext_mode_set, |
708 | .commit = radeon_legacy_tmds_ext_commit, | 725 | .commit = radeon_legacy_tmds_ext_commit, |
726 | .disable = radeon_legacy_encoder_disable, | ||
709 | }; | 727 | }; |
710 | 728 | ||
711 | 729 | ||
@@ -727,17 +745,21 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) | |||
727 | { | 745 | { |
728 | struct drm_device *dev = encoder->dev; | 746 | struct drm_device *dev = encoder->dev; |
729 | struct radeon_device *rdev = dev->dev_private; | 747 | struct radeon_device *rdev = dev->dev_private; |
748 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
730 | uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0; | 749 | uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0; |
731 | /* uint32_t tv_master_cntl = 0; */ | 750 | uint32_t tv_master_cntl = 0; |
732 | 751 | bool is_tv; | |
733 | DRM_DEBUG("\n"); | 752 | DRM_DEBUG("\n"); |
734 | 753 | ||
754 | is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false; | ||
755 | |||
735 | if (rdev->family == CHIP_R200) | 756 | if (rdev->family == CHIP_R200) |
736 | fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); | 757 | fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); |
737 | else { | 758 | else { |
738 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | 759 | if (is_tv) |
739 | /* FIXME TV */ | 760 | tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL); |
740 | /* tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL); */ | 761 | else |
762 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | ||
741 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); | 763 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); |
742 | } | 764 | } |
743 | 765 | ||
@@ -746,20 +768,23 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) | |||
746 | if (rdev->family == CHIP_R200) { | 768 | if (rdev->family == CHIP_R200) { |
747 | fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); | 769 | fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); |
748 | } else { | 770 | } else { |
749 | crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON; | 771 | if (is_tv) |
750 | /* tv_master_cntl |= RADEON_TV_ON; */ | 772 | tv_master_cntl |= RADEON_TV_ON; |
773 | else | ||
774 | crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON; | ||
775 | |||
751 | if (rdev->family == CHIP_R420 || | 776 | if (rdev->family == CHIP_R420 || |
752 | rdev->family == CHIP_R423 || | 777 | rdev->family == CHIP_R423 || |
753 | rdev->family == CHIP_RV410) | 778 | rdev->family == CHIP_RV410) |
754 | tv_dac_cntl &= ~(R420_TV_DAC_RDACPD | | 779 | tv_dac_cntl &= ~(R420_TV_DAC_RDACPD | |
755 | R420_TV_DAC_GDACPD | | 780 | R420_TV_DAC_GDACPD | |
756 | R420_TV_DAC_BDACPD | | 781 | R420_TV_DAC_BDACPD | |
757 | RADEON_TV_DAC_BGSLEEP); | 782 | RADEON_TV_DAC_BGSLEEP); |
758 | else | 783 | else |
759 | tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD | | 784 | tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD | |
760 | RADEON_TV_DAC_GDACPD | | 785 | RADEON_TV_DAC_GDACPD | |
761 | RADEON_TV_DAC_BDACPD | | 786 | RADEON_TV_DAC_BDACPD | |
762 | RADEON_TV_DAC_BGSLEEP); | 787 | RADEON_TV_DAC_BGSLEEP); |
763 | } | 788 | } |
764 | break; | 789 | break; |
765 | case DRM_MODE_DPMS_STANDBY: | 790 | case DRM_MODE_DPMS_STANDBY: |
@@ -768,8 +793,11 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) | |||
768 | if (rdev->family == CHIP_R200) | 793 | if (rdev->family == CHIP_R200) |
769 | fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); | 794 | fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); |
770 | else { | 795 | else { |
771 | crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; | 796 | if (is_tv) |
772 | /* tv_master_cntl &= ~RADEON_TV_ON; */ | 797 | tv_master_cntl &= ~RADEON_TV_ON; |
798 | else | ||
799 | crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; | ||
800 | |||
773 | if (rdev->family == CHIP_R420 || | 801 | if (rdev->family == CHIP_R420 || |
774 | rdev->family == CHIP_R423 || | 802 | rdev->family == CHIP_R423 || |
775 | rdev->family == CHIP_RV410) | 803 | rdev->family == CHIP_RV410) |
@@ -789,8 +817,10 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) | |||
789 | if (rdev->family == CHIP_R200) { | 817 | if (rdev->family == CHIP_R200) { |
790 | WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); | 818 | WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); |
791 | } else { | 819 | } else { |
792 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | 820 | if (is_tv) |
793 | /* WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); */ | 821 | WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); |
822 | else | ||
823 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | ||
794 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); | 824 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); |
795 | } | 825 | } |
796 | 826 | ||
@@ -809,6 +839,7 @@ static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder) | |||
809 | else | 839 | else |
810 | radeon_combios_output_lock(encoder, true); | 840 | radeon_combios_output_lock(encoder, true); |
811 | radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF); | 841 | radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF); |
842 | radeon_encoder_set_active_device(encoder); | ||
812 | } | 843 | } |
813 | 844 | ||
814 | static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder) | 845 | static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder) |
@@ -831,11 +862,15 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, | |||
831 | struct radeon_device *rdev = dev->dev_private; | 862 | struct radeon_device *rdev = dev->dev_private; |
832 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | 863 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
833 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 864 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
865 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; | ||
834 | uint32_t tv_dac_cntl, gpiopad_a = 0, dac2_cntl, disp_output_cntl = 0; | 866 | uint32_t tv_dac_cntl, gpiopad_a = 0, dac2_cntl, disp_output_cntl = 0; |
835 | uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0; | 867 | uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0, disp_tv_out_cntl = 0; |
868 | bool is_tv = false; | ||
836 | 869 | ||
837 | DRM_DEBUG("\n"); | 870 | DRM_DEBUG("\n"); |
838 | 871 | ||
872 | is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false; | ||
873 | |||
839 | if (rdev->family != CHIP_R200) { | 874 | if (rdev->family != CHIP_R200) { |
840 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); | 875 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); |
841 | if (rdev->family == CHIP_R420 || | 876 | if (rdev->family == CHIP_R420 || |
@@ -858,7 +893,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, | |||
858 | } | 893 | } |
859 | 894 | ||
860 | /* FIXME TV */ | 895 | /* FIXME TV */ |
861 | if (radeon_encoder->enc_priv) { | 896 | if (tv_dac) { |
862 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; | 897 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; |
863 | tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | | 898 | tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | |
864 | RADEON_TV_DAC_NHOLD | | 899 | RADEON_TV_DAC_NHOLD | |
@@ -875,44 +910,93 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, | |||
875 | if (ASIC_IS_R300(rdev)) { | 910 | if (ASIC_IS_R300(rdev)) { |
876 | gpiopad_a = RREG32(RADEON_GPIOPAD_A) | 1; | 911 | gpiopad_a = RREG32(RADEON_GPIOPAD_A) | 1; |
877 | disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); | 912 | disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); |
878 | } else if (rdev->family == CHIP_R200) | 913 | } |
879 | fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); | 914 | |
915 | if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev)) | ||
916 | disp_tv_out_cntl = RREG32(RADEON_DISP_TV_OUT_CNTL); | ||
880 | else | 917 | else |
881 | disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); | 918 | disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); |
882 | 919 | ||
883 | dac2_cntl = RREG32(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC2_CLK_SEL; | 920 | if (rdev->family == CHIP_R200) |
921 | fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); | ||
884 | 922 | ||
885 | if (radeon_crtc->crtc_id == 0) { | 923 | if (is_tv) { |
886 | if (ASIC_IS_R300(rdev)) { | 924 | uint32_t dac_cntl; |
887 | disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; | 925 | |
888 | disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC; | 926 | dac_cntl = RREG32(RADEON_DAC_CNTL); |
889 | } else if (rdev->family == CHIP_R200) { | 927 | dac_cntl &= ~RADEON_DAC_TVO_EN; |
890 | fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | | 928 | WREG32(RADEON_DAC_CNTL, dac_cntl); |
891 | RADEON_FP2_DVO_RATE_SEL_SDR); | 929 | |
892 | } else | 930 | if (ASIC_IS_R300(rdev)) |
893 | disp_hw_debug |= RADEON_CRT2_DISP1_SEL; | 931 | gpiopad_a = RREG32(RADEON_GPIOPAD_A) & ~1; |
932 | |||
933 | dac2_cntl = RREG32(RADEON_DAC_CNTL2) & ~RADEON_DAC2_DAC2_CLK_SEL; | ||
934 | if (radeon_crtc->crtc_id == 0) { | ||
935 | if (ASIC_IS_R300(rdev)) { | ||
936 | disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; | ||
937 | disp_output_cntl |= (RADEON_DISP_TVDAC_SOURCE_CRTC | | ||
938 | RADEON_DISP_TV_SOURCE_CRTC); | ||
939 | } | ||
940 | if (rdev->family >= CHIP_R200) { | ||
941 | disp_tv_out_cntl &= ~RADEON_DISP_TV_PATH_SRC_CRTC2; | ||
942 | } else { | ||
943 | disp_hw_debug |= RADEON_CRT2_DISP1_SEL; | ||
944 | } | ||
945 | } else { | ||
946 | if (ASIC_IS_R300(rdev)) { | ||
947 | disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; | ||
948 | disp_output_cntl |= RADEON_DISP_TV_SOURCE_CRTC; | ||
949 | } | ||
950 | if (rdev->family >= CHIP_R200) { | ||
951 | disp_tv_out_cntl |= RADEON_DISP_TV_PATH_SRC_CRTC2; | ||
952 | } else { | ||
953 | disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL; | ||
954 | } | ||
955 | } | ||
956 | WREG32(RADEON_DAC_CNTL2, dac2_cntl); | ||
894 | } else { | 957 | } else { |
895 | if (ASIC_IS_R300(rdev)) { | ||
896 | disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; | ||
897 | disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2; | ||
898 | } else if (rdev->family == CHIP_R200) { | ||
899 | fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | | ||
900 | RADEON_FP2_DVO_RATE_SEL_SDR); | ||
901 | fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2; | ||
902 | } else | ||
903 | disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL; | ||
904 | } | ||
905 | 958 | ||
906 | WREG32(RADEON_DAC_CNTL2, dac2_cntl); | 959 | dac2_cntl = RREG32(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC2_CLK_SEL; |
960 | |||
961 | if (radeon_crtc->crtc_id == 0) { | ||
962 | if (ASIC_IS_R300(rdev)) { | ||
963 | disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; | ||
964 | disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC; | ||
965 | } else if (rdev->family == CHIP_R200) { | ||
966 | fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | | ||
967 | RADEON_FP2_DVO_RATE_SEL_SDR); | ||
968 | } else | ||
969 | disp_hw_debug |= RADEON_CRT2_DISP1_SEL; | ||
970 | } else { | ||
971 | if (ASIC_IS_R300(rdev)) { | ||
972 | disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; | ||
973 | disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2; | ||
974 | } else if (rdev->family == CHIP_R200) { | ||
975 | fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | | ||
976 | RADEON_FP2_DVO_RATE_SEL_SDR); | ||
977 | fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2; | ||
978 | } else | ||
979 | disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL; | ||
980 | } | ||
981 | WREG32(RADEON_DAC_CNTL2, dac2_cntl); | ||
982 | } | ||
907 | 983 | ||
908 | if (ASIC_IS_R300(rdev)) { | 984 | if (ASIC_IS_R300(rdev)) { |
909 | WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); | 985 | WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); |
910 | WREG32(RADEON_DISP_TV_OUT_CNTL, disp_output_cntl); | 986 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); |
911 | } else if (rdev->family == CHIP_R200) | 987 | } |
912 | WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); | 988 | |
989 | if (rdev->family >= CHIP_R200) | ||
990 | WREG32(RADEON_DISP_TV_OUT_CNTL, disp_tv_out_cntl); | ||
913 | else | 991 | else |
914 | WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); | 992 | WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); |
915 | 993 | ||
994 | if (rdev->family == CHIP_R200) | ||
995 | WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); | ||
996 | |||
997 | if (is_tv) | ||
998 | radeon_legacy_tv_mode_set(encoder, mode, adjusted_mode); | ||
999 | |||
916 | if (rdev->is_atom_bios) | 1000 | if (rdev->is_atom_bios) |
917 | radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | 1001 | radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); |
918 | else | 1002 | else |
@@ -920,6 +1004,141 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, | |||
920 | 1004 | ||
921 | } | 1005 | } |
922 | 1006 | ||
1007 | static bool r300_legacy_tv_detect(struct drm_encoder *encoder, | ||
1008 | struct drm_connector *connector) | ||
1009 | { | ||
1010 | struct drm_device *dev = encoder->dev; | ||
1011 | struct radeon_device *rdev = dev->dev_private; | ||
1012 | uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; | ||
1013 | uint32_t disp_output_cntl, gpiopad_a, tmp; | ||
1014 | bool found = false; | ||
1015 | |||
1016 | /* save regs needed */ | ||
1017 | gpiopad_a = RREG32(RADEON_GPIOPAD_A); | ||
1018 | dac_cntl2 = RREG32(RADEON_DAC_CNTL2); | ||
1019 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | ||
1020 | dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); | ||
1021 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); | ||
1022 | disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); | ||
1023 | |||
1024 | WREG32_P(RADEON_GPIOPAD_A, 0, ~1); | ||
1025 | |||
1026 | WREG32(RADEON_DAC_CNTL2, RADEON_DAC2_DAC2_CLK_SEL); | ||
1027 | |||
1028 | WREG32(RADEON_CRTC2_GEN_CNTL, | ||
1029 | RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT); | ||
1030 | |||
1031 | tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; | ||
1032 | tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; | ||
1033 | WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); | ||
1034 | |||
1035 | WREG32(RADEON_DAC_EXT_CNTL, | ||
1036 | RADEON_DAC2_FORCE_BLANK_OFF_EN | | ||
1037 | RADEON_DAC2_FORCE_DATA_EN | | ||
1038 | RADEON_DAC_FORCE_DATA_SEL_RGB | | ||
1039 | (0xec << RADEON_DAC_FORCE_DATA_SHIFT)); | ||
1040 | |||
1041 | WREG32(RADEON_TV_DAC_CNTL, | ||
1042 | RADEON_TV_DAC_STD_NTSC | | ||
1043 | (8 << RADEON_TV_DAC_BGADJ_SHIFT) | | ||
1044 | (6 << RADEON_TV_DAC_DACADJ_SHIFT)); | ||
1045 | |||
1046 | RREG32(RADEON_TV_DAC_CNTL); | ||
1047 | mdelay(4); | ||
1048 | |||
1049 | WREG32(RADEON_TV_DAC_CNTL, | ||
1050 | RADEON_TV_DAC_NBLANK | | ||
1051 | RADEON_TV_DAC_NHOLD | | ||
1052 | RADEON_TV_MONITOR_DETECT_EN | | ||
1053 | RADEON_TV_DAC_STD_NTSC | | ||
1054 | (8 << RADEON_TV_DAC_BGADJ_SHIFT) | | ||
1055 | (6 << RADEON_TV_DAC_DACADJ_SHIFT)); | ||
1056 | |||
1057 | RREG32(RADEON_TV_DAC_CNTL); | ||
1058 | mdelay(6); | ||
1059 | |||
1060 | tmp = RREG32(RADEON_TV_DAC_CNTL); | ||
1061 | if ((tmp & RADEON_TV_DAC_GDACDET) != 0) { | ||
1062 | found = true; | ||
1063 | DRM_DEBUG("S-video TV connection detected\n"); | ||
1064 | } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) { | ||
1065 | found = true; | ||
1066 | DRM_DEBUG("Composite TV connection detected\n"); | ||
1067 | } | ||
1068 | |||
1069 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); | ||
1070 | WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); | ||
1071 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | ||
1072 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); | ||
1073 | WREG32(RADEON_DAC_CNTL2, dac_cntl2); | ||
1074 | WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); | ||
1075 | return found; | ||
1076 | } | ||
1077 | |||
1078 | static bool radeon_legacy_tv_detect(struct drm_encoder *encoder, | ||
1079 | struct drm_connector *connector) | ||
1080 | { | ||
1081 | struct drm_device *dev = encoder->dev; | ||
1082 | struct radeon_device *rdev = dev->dev_private; | ||
1083 | uint32_t tv_dac_cntl, dac_cntl2; | ||
1084 | uint32_t config_cntl, tv_pre_dac_mux_cntl, tv_master_cntl, tmp; | ||
1085 | bool found = false; | ||
1086 | |||
1087 | if (ASIC_IS_R300(rdev)) | ||
1088 | return r300_legacy_tv_detect(encoder, connector); | ||
1089 | |||
1090 | dac_cntl2 = RREG32(RADEON_DAC_CNTL2); | ||
1091 | tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL); | ||
1092 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); | ||
1093 | config_cntl = RREG32(RADEON_CONFIG_CNTL); | ||
1094 | tv_pre_dac_mux_cntl = RREG32(RADEON_TV_PRE_DAC_MUX_CNTL); | ||
1095 | |||
1096 | tmp = dac_cntl2 & ~RADEON_DAC2_DAC2_CLK_SEL; | ||
1097 | WREG32(RADEON_DAC_CNTL2, tmp); | ||
1098 | |||
1099 | tmp = tv_master_cntl | RADEON_TV_ON; | ||
1100 | tmp &= ~(RADEON_TV_ASYNC_RST | | ||
1101 | RADEON_RESTART_PHASE_FIX | | ||
1102 | RADEON_CRT_FIFO_CE_EN | | ||
1103 | RADEON_TV_FIFO_CE_EN | | ||
1104 | RADEON_RE_SYNC_NOW_SEL_MASK); | ||
1105 | tmp |= RADEON_TV_FIFO_ASYNC_RST | RADEON_CRT_ASYNC_RST; | ||
1106 | WREG32(RADEON_TV_MASTER_CNTL, tmp); | ||
1107 | |||
1108 | tmp = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD | | ||
1109 | RADEON_TV_MONITOR_DETECT_EN | RADEON_TV_DAC_STD_NTSC | | ||
1110 | (8 << RADEON_TV_DAC_BGADJ_SHIFT); | ||
1111 | |||
1112 | if (config_cntl & RADEON_CFG_ATI_REV_ID_MASK) | ||
1113 | tmp |= (4 << RADEON_TV_DAC_DACADJ_SHIFT); | ||
1114 | else | ||
1115 | tmp |= (8 << RADEON_TV_DAC_DACADJ_SHIFT); | ||
1116 | WREG32(RADEON_TV_DAC_CNTL, tmp); | ||
1117 | |||
1118 | tmp = RADEON_C_GRN_EN | RADEON_CMP_BLU_EN | | ||
1119 | RADEON_RED_MX_FORCE_DAC_DATA | | ||
1120 | RADEON_GRN_MX_FORCE_DAC_DATA | | ||
1121 | RADEON_BLU_MX_FORCE_DAC_DATA | | ||
1122 | (0x109 << RADEON_TV_FORCE_DAC_DATA_SHIFT); | ||
1123 | WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tmp); | ||
1124 | |||
1125 | mdelay(3); | ||
1126 | tmp = RREG32(RADEON_TV_DAC_CNTL); | ||
1127 | if (tmp & RADEON_TV_DAC_GDACDET) { | ||
1128 | found = true; | ||
1129 | DRM_DEBUG("S-video TV connection detected\n"); | ||
1130 | } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) { | ||
1131 | found = true; | ||
1132 | DRM_DEBUG("Composite TV connection detected\n"); | ||
1133 | } | ||
1134 | |||
1135 | WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl); | ||
1136 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); | ||
1137 | WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); | ||
1138 | WREG32(RADEON_DAC_CNTL2, dac_cntl2); | ||
1139 | return found; | ||
1140 | } | ||
1141 | |||
923 | static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, | 1142 | static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, |
924 | struct drm_connector *connector) | 1143 | struct drm_connector *connector) |
925 | { | 1144 | { |
@@ -928,9 +1147,29 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | |||
928 | uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; | 1147 | uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; |
929 | uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp; | 1148 | uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp; |
930 | enum drm_connector_status found = connector_status_disconnected; | 1149 | enum drm_connector_status found = connector_status_disconnected; |
1150 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1151 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; | ||
931 | bool color = true; | 1152 | bool color = true; |
932 | 1153 | ||
933 | /* FIXME tv */ | 1154 | if (connector->connector_type == DRM_MODE_CONNECTOR_SVIDEO || |
1155 | connector->connector_type == DRM_MODE_CONNECTOR_Composite || | ||
1156 | connector->connector_type == DRM_MODE_CONNECTOR_9PinDIN) { | ||
1157 | bool tv_detect; | ||
1158 | |||
1159 | if (radeon_encoder->active_device && !(radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT)) | ||
1160 | return connector_status_disconnected; | ||
1161 | |||
1162 | tv_detect = radeon_legacy_tv_detect(encoder, connector); | ||
1163 | if (tv_detect && tv_dac) | ||
1164 | found = connector_status_connected; | ||
1165 | return found; | ||
1166 | } | ||
1167 | |||
1168 | /* don't probe if the encoder is being used for something else not CRT related */ | ||
1169 | if (radeon_encoder->active_device && !(radeon_encoder->active_device & ATOM_DEVICE_CRT_SUPPORT)) { | ||
1170 | DRM_INFO("not detecting due to %08x\n", radeon_encoder->active_device); | ||
1171 | return connector_status_disconnected; | ||
1172 | } | ||
934 | 1173 | ||
935 | /* save the regs we need */ | 1174 | /* save the regs we need */ |
936 | pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); | 1175 | pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); |
@@ -1013,8 +1252,7 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | |||
1013 | } | 1252 | } |
1014 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); | 1253 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); |
1015 | 1254 | ||
1016 | /* return found; */ | 1255 | return found; |
1017 | return connector_status_disconnected; | ||
1018 | 1256 | ||
1019 | } | 1257 | } |
1020 | 1258 | ||
@@ -1025,6 +1263,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs = | |||
1025 | .mode_set = radeon_legacy_tv_dac_mode_set, | 1263 | .mode_set = radeon_legacy_tv_dac_mode_set, |
1026 | .commit = radeon_legacy_tv_dac_commit, | 1264 | .commit = radeon_legacy_tv_dac_commit, |
1027 | .detect = radeon_legacy_tv_dac_detect, | 1265 | .detect = radeon_legacy_tv_dac_detect, |
1266 | .disable = radeon_legacy_encoder_disable, | ||
1028 | }; | 1267 | }; |
1029 | 1268 | ||
1030 | 1269 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_tv.c b/drivers/gpu/drm/radeon/radeon_legacy_tv.c new file mode 100644 index 000000000000..3a12bb0c0563 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_legacy_tv.c | |||
@@ -0,0 +1,904 @@ | |||
1 | #include "drmP.h" | ||
2 | #include "drm_crtc_helper.h" | ||
3 | #include "radeon.h" | ||
4 | |||
5 | /* | ||
6 | * Integrated TV out support based on the GATOS code by | ||
7 | * Federico Ulivi <fulivi@lycos.com> | ||
8 | */ | ||
9 | |||
10 | |||
11 | /* | ||
12 | * Limits of h/v positions (hPos & vPos) | ||
13 | */ | ||
14 | #define MAX_H_POSITION 5 /* Range: [-5..5], negative is on the left, 0 is default, positive is on the right */ | ||
15 | #define MAX_V_POSITION 5 /* Range: [-5..5], negative is up, 0 is default, positive is down */ | ||
16 | |||
17 | /* | ||
18 | * Unit for hPos (in TV clock periods) | ||
19 | */ | ||
20 | #define H_POS_UNIT 10 | ||
21 | |||
22 | /* | ||
23 | * Indexes in h. code timing table for horizontal line position adjustment | ||
24 | */ | ||
25 | #define H_TABLE_POS1 6 | ||
26 | #define H_TABLE_POS2 8 | ||
27 | |||
28 | /* | ||
29 | * Limits of hor. size (hSize) | ||
30 | */ | ||
31 | #define MAX_H_SIZE 5 /* Range: [-5..5], negative is smaller, positive is larger */ | ||
32 | |||
33 | /* tv standard constants */ | ||
34 | #define NTSC_TV_CLOCK_T 233 | ||
35 | #define NTSC_TV_VFTOTAL 1 | ||
36 | #define NTSC_TV_LINES_PER_FRAME 525 | ||
37 | #define NTSC_TV_ZERO_H_SIZE 479166 | ||
38 | #define NTSC_TV_H_SIZE_UNIT 9478 | ||
39 | |||
40 | #define PAL_TV_CLOCK_T 188 | ||
41 | #define PAL_TV_VFTOTAL 3 | ||
42 | #define PAL_TV_LINES_PER_FRAME 625 | ||
43 | #define PAL_TV_ZERO_H_SIZE 473200 | ||
44 | #define PAL_TV_H_SIZE_UNIT 9360 | ||
45 | |||
46 | /* tv pll setting for 27 mhz ref clk */ | ||
47 | #define NTSC_TV_PLL_M_27 22 | ||
48 | #define NTSC_TV_PLL_N_27 175 | ||
49 | #define NTSC_TV_PLL_P_27 5 | ||
50 | |||
51 | #define PAL_TV_PLL_M_27 113 | ||
52 | #define PAL_TV_PLL_N_27 668 | ||
53 | #define PAL_TV_PLL_P_27 3 | ||
54 | |||
55 | /* tv pll setting for 14 mhz ref clk */ | ||
56 | #define NTSC_TV_PLL_M_14 33 | ||
57 | #define NTSC_TV_PLL_N_14 693 | ||
58 | #define NTSC_TV_PLL_P_14 7 | ||
59 | |||
60 | #define VERT_LEAD_IN_LINES 2 | ||
61 | #define FRAC_BITS 0xe | ||
62 | #define FRAC_MASK 0x3fff | ||
63 | |||
64 | struct radeon_tv_mode_constants { | ||
65 | uint16_t hor_resolution; | ||
66 | uint16_t ver_resolution; | ||
67 | enum radeon_tv_std standard; | ||
68 | uint16_t hor_total; | ||
69 | uint16_t ver_total; | ||
70 | uint16_t hor_start; | ||
71 | uint16_t hor_syncstart; | ||
72 | uint16_t ver_syncstart; | ||
73 | unsigned def_restart; | ||
74 | uint16_t crtcPLL_N; | ||
75 | uint8_t crtcPLL_M; | ||
76 | uint8_t crtcPLL_post_div; | ||
77 | unsigned pix_to_tv; | ||
78 | }; | ||
79 | |||
80 | static const uint16_t hor_timing_NTSC[] = { | ||
81 | 0x0007, | ||
82 | 0x003f, | ||
83 | 0x0263, | ||
84 | 0x0a24, | ||
85 | 0x2a6b, | ||
86 | 0x0a36, | ||
87 | 0x126d, /* H_TABLE_POS1 */ | ||
88 | 0x1bfe, | ||
89 | 0x1a8f, /* H_TABLE_POS2 */ | ||
90 | 0x1ec7, | ||
91 | 0x3863, | ||
92 | 0x1bfe, | ||
93 | 0x1bfe, | ||
94 | 0x1a2a, | ||
95 | 0x1e95, | ||
96 | 0x0e31, | ||
97 | 0x201b, | ||
98 | 0 | ||
99 | }; | ||
100 | |||
101 | static const uint16_t vert_timing_NTSC[] = { | ||
102 | 0x2001, | ||
103 | 0x200d, | ||
104 | 0x1006, | ||
105 | 0x0c06, | ||
106 | 0x1006, | ||
107 | 0x1818, | ||
108 | 0x21e3, | ||
109 | 0x1006, | ||
110 | 0x0c06, | ||
111 | 0x1006, | ||
112 | 0x1817, | ||
113 | 0x21d4, | ||
114 | 0x0002, | ||
115 | 0 | ||
116 | }; | ||
117 | |||
118 | static const uint16_t hor_timing_PAL[] = { | ||
119 | 0x0007, | ||
120 | 0x0058, | ||
121 | 0x027c, | ||
122 | 0x0a31, | ||
123 | 0x2a77, | ||
124 | 0x0a95, | ||
125 | 0x124f, /* H_TABLE_POS1 */ | ||
126 | 0x1bfe, | ||
127 | 0x1b22, /* H_TABLE_POS2 */ | ||
128 | 0x1ef9, | ||
129 | 0x387c, | ||
130 | 0x1bfe, | ||
131 | 0x1bfe, | ||
132 | 0x1b31, | ||
133 | 0x1eb5, | ||
134 | 0x0e43, | ||
135 | 0x201b, | ||
136 | 0 | ||
137 | }; | ||
138 | |||
139 | static const uint16_t vert_timing_PAL[] = { | ||
140 | 0x2001, | ||
141 | 0x200c, | ||
142 | 0x1005, | ||
143 | 0x0c05, | ||
144 | 0x1005, | ||
145 | 0x1401, | ||
146 | 0x1821, | ||
147 | 0x2240, | ||
148 | 0x1005, | ||
149 | 0x0c05, | ||
150 | 0x1005, | ||
151 | 0x1401, | ||
152 | 0x1822, | ||
153 | 0x2230, | ||
154 | 0x0002, | ||
155 | 0 | ||
156 | }; | ||
157 | |||
158 | /********************************************************************** | ||
159 | * | ||
160 | * availableModes | ||
161 | * | ||
162 | * Table of all allowed modes for tv output | ||
163 | * | ||
164 | **********************************************************************/ | ||
165 | static const struct radeon_tv_mode_constants available_tv_modes[] = { | ||
166 | { /* NTSC timing for 27 Mhz ref clk */ | ||
167 | 800, /* horResolution */ | ||
168 | 600, /* verResolution */ | ||
169 | TV_STD_NTSC, /* standard */ | ||
170 | 990, /* horTotal */ | ||
171 | 740, /* verTotal */ | ||
172 | 813, /* horStart */ | ||
173 | 824, /* horSyncStart */ | ||
174 | 632, /* verSyncStart */ | ||
175 | 625592, /* defRestart */ | ||
176 | 592, /* crtcPLL_N */ | ||
177 | 91, /* crtcPLL_M */ | ||
178 | 4, /* crtcPLL_postDiv */ | ||
179 | 1022, /* pixToTV */ | ||
180 | }, | ||
181 | { /* PAL timing for 27 Mhz ref clk */ | ||
182 | 800, /* horResolution */ | ||
183 | 600, /* verResolution */ | ||
184 | TV_STD_PAL, /* standard */ | ||
185 | 1144, /* horTotal */ | ||
186 | 706, /* verTotal */ | ||
187 | 812, /* horStart */ | ||
188 | 824, /* horSyncStart */ | ||
189 | 669, /* verSyncStart */ | ||
190 | 696700, /* defRestart */ | ||
191 | 1382, /* crtcPLL_N */ | ||
192 | 231, /* crtcPLL_M */ | ||
193 | 4, /* crtcPLL_postDiv */ | ||
194 | 759, /* pixToTV */ | ||
195 | }, | ||
196 | { /* NTSC timing for 14 Mhz ref clk */ | ||
197 | 800, /* horResolution */ | ||
198 | 600, /* verResolution */ | ||
199 | TV_STD_NTSC, /* standard */ | ||
200 | 1018, /* horTotal */ | ||
201 | 727, /* verTotal */ | ||
202 | 813, /* horStart */ | ||
203 | 840, /* horSyncStart */ | ||
204 | 633, /* verSyncStart */ | ||
205 | 630627, /* defRestart */ | ||
206 | 347, /* crtcPLL_N */ | ||
207 | 14, /* crtcPLL_M */ | ||
208 | 8, /* crtcPLL_postDiv */ | ||
209 | 1022, /* pixToTV */ | ||
210 | }, | ||
211 | }; | ||
212 | |||
213 | #define N_AVAILABLE_MODES ARRAY_SIZE(available_tv_modes) | ||
214 | |||
215 | static const struct radeon_tv_mode_constants *radeon_legacy_tv_get_std_mode(struct radeon_encoder *radeon_encoder, | ||
216 | uint16_t *pll_ref_freq) | ||
217 | { | ||
218 | struct drm_device *dev = radeon_encoder->base.dev; | ||
219 | struct radeon_device *rdev = dev->dev_private; | ||
220 | struct radeon_crtc *radeon_crtc; | ||
221 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; | ||
222 | const struct radeon_tv_mode_constants *const_ptr; | ||
223 | struct radeon_pll *pll; | ||
224 | |||
225 | radeon_crtc = to_radeon_crtc(radeon_encoder->base.crtc); | ||
226 | if (radeon_crtc->crtc_id == 1) | ||
227 | pll = &rdev->clock.p2pll; | ||
228 | else | ||
229 | pll = &rdev->clock.p1pll; | ||
230 | |||
231 | if (pll_ref_freq) | ||
232 | *pll_ref_freq = pll->reference_freq; | ||
233 | |||
234 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
235 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
236 | tv_dac->tv_std == TV_STD_PAL_M) { | ||
237 | if (pll->reference_freq == 2700) | ||
238 | const_ptr = &available_tv_modes[0]; | ||
239 | else | ||
240 | const_ptr = &available_tv_modes[2]; | ||
241 | } else { | ||
242 | if (pll->reference_freq == 2700) | ||
243 | const_ptr = &available_tv_modes[1]; | ||
244 | else | ||
245 | const_ptr = &available_tv_modes[1]; /* FIX ME */ | ||
246 | } | ||
247 | return const_ptr; | ||
248 | } | ||
249 | |||
250 | static long YCOEF_value[5] = { 2, 2, 0, 4, 0 }; | ||
251 | static long YCOEF_EN_value[5] = { 1, 1, 0, 1, 0 }; | ||
252 | static long SLOPE_value[5] = { 1, 2, 2, 4, 8 }; | ||
253 | static long SLOPE_limit[5] = { 6, 5, 4, 3, 2 }; | ||
254 | |||
255 | static void radeon_wait_pll_lock(struct drm_encoder *encoder, unsigned n_tests, | ||
256 | unsigned n_wait_loops, unsigned cnt_threshold) | ||
257 | { | ||
258 | struct drm_device *dev = encoder->dev; | ||
259 | struct radeon_device *rdev = dev->dev_private; | ||
260 | uint32_t save_pll_test; | ||
261 | unsigned int i, j; | ||
262 | |||
263 | WREG32(RADEON_TEST_DEBUG_MUX, (RREG32(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100); | ||
264 | save_pll_test = RREG32_PLL(RADEON_PLL_TEST_CNTL); | ||
265 | WREG32_PLL(RADEON_PLL_TEST_CNTL, save_pll_test & ~RADEON_PLL_MASK_READ_B); | ||
266 | |||
267 | WREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL); | ||
268 | for (i = 0; i < n_tests; i++) { | ||
269 | WREG8(RADEON_CLOCK_CNTL_DATA + 3, 0); | ||
270 | for (j = 0; j < n_wait_loops; j++) | ||
271 | if (RREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cnt_threshold) | ||
272 | break; | ||
273 | } | ||
274 | WREG32_PLL(RADEON_PLL_TEST_CNTL, save_pll_test); | ||
275 | WREG32(RADEON_TEST_DEBUG_MUX, RREG32(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff); | ||
276 | } | ||
277 | |||
278 | |||
279 | static void radeon_legacy_tv_write_fifo(struct radeon_encoder *radeon_encoder, | ||
280 | uint16_t addr, uint32_t value) | ||
281 | { | ||
282 | struct drm_device *dev = radeon_encoder->base.dev; | ||
283 | struct radeon_device *rdev = dev->dev_private; | ||
284 | uint32_t tmp; | ||
285 | int i = 0; | ||
286 | |||
287 | WREG32(RADEON_TV_HOST_WRITE_DATA, value); | ||
288 | |||
289 | WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr); | ||
290 | WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT); | ||
291 | |||
292 | do { | ||
293 | tmp = RREG32(RADEON_TV_HOST_RD_WT_CNTL); | ||
294 | if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0) | ||
295 | break; | ||
296 | i++; | ||
297 | } while (i < 10000); | ||
298 | WREG32(RADEON_TV_HOST_RD_WT_CNTL, 0); | ||
299 | } | ||
300 | |||
301 | #if 0 /* included for completeness */ | ||
302 | static uint32_t radeon_legacy_tv_read_fifo(struct radeon_encoder *radeon_encoder, uint16_t addr) | ||
303 | { | ||
304 | struct drm_device *dev = radeon_encoder->base.dev; | ||
305 | struct radeon_device *rdev = dev->dev_private; | ||
306 | uint32_t tmp; | ||
307 | int i = 0; | ||
308 | |||
309 | WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr); | ||
310 | WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD); | ||
311 | |||
312 | do { | ||
313 | tmp = RREG32(RADEON_TV_HOST_RD_WT_CNTL); | ||
314 | if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0) | ||
315 | break; | ||
316 | i++; | ||
317 | } while (i < 10000); | ||
318 | WREG32(RADEON_TV_HOST_RD_WT_CNTL, 0); | ||
319 | return RREG32(RADEON_TV_HOST_READ_DATA); | ||
320 | } | ||
321 | #endif | ||
322 | |||
323 | static uint16_t radeon_get_htiming_tables_addr(uint32_t tv_uv_adr) | ||
324 | { | ||
325 | uint16_t h_table; | ||
326 | |||
327 | switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) { | ||
328 | case 0: | ||
329 | h_table = RADEON_TV_MAX_FIFO_ADDR_INTERNAL; | ||
330 | break; | ||
331 | case 1: | ||
332 | h_table = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2; | ||
333 | break; | ||
334 | case 2: | ||
335 | h_table = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2; | ||
336 | break; | ||
337 | default: | ||
338 | h_table = 0; | ||
339 | break; | ||
340 | } | ||
341 | return h_table; | ||
342 | } | ||
343 | |||
344 | static uint16_t radeon_get_vtiming_tables_addr(uint32_t tv_uv_adr) | ||
345 | { | ||
346 | uint16_t v_table; | ||
347 | |||
348 | switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) { | ||
349 | case 0: | ||
350 | v_table = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1; | ||
351 | break; | ||
352 | case 1: | ||
353 | v_table = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1; | ||
354 | break; | ||
355 | case 2: | ||
356 | v_table = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1; | ||
357 | break; | ||
358 | default: | ||
359 | v_table = 0; | ||
360 | break; | ||
361 | } | ||
362 | return v_table; | ||
363 | } | ||
364 | |||
365 | static void radeon_restore_tv_timing_tables(struct radeon_encoder *radeon_encoder) | ||
366 | { | ||
367 | struct drm_device *dev = radeon_encoder->base.dev; | ||
368 | struct radeon_device *rdev = dev->dev_private; | ||
369 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; | ||
370 | uint16_t h_table, v_table; | ||
371 | uint32_t tmp; | ||
372 | int i; | ||
373 | |||
374 | WREG32(RADEON_TV_UV_ADR, tv_dac->tv.tv_uv_adr); | ||
375 | h_table = radeon_get_htiming_tables_addr(tv_dac->tv.tv_uv_adr); | ||
376 | v_table = radeon_get_vtiming_tables_addr(tv_dac->tv.tv_uv_adr); | ||
377 | |||
378 | for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, h_table--) { | ||
379 | tmp = ((uint32_t)tv_dac->tv.h_code_timing[i] << 14) | ((uint32_t)tv_dac->tv.h_code_timing[i+1]); | ||
380 | radeon_legacy_tv_write_fifo(radeon_encoder, h_table, tmp); | ||
381 | if (tv_dac->tv.h_code_timing[i] == 0 || tv_dac->tv.h_code_timing[i + 1] == 0) | ||
382 | break; | ||
383 | } | ||
384 | for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, v_table++) { | ||
385 | tmp = ((uint32_t)tv_dac->tv.v_code_timing[i+1] << 14) | ((uint32_t)tv_dac->tv.v_code_timing[i]); | ||
386 | radeon_legacy_tv_write_fifo(radeon_encoder, v_table, tmp); | ||
387 | if (tv_dac->tv.v_code_timing[i] == 0 || tv_dac->tv.v_code_timing[i + 1] == 0) | ||
388 | break; | ||
389 | } | ||
390 | } | ||
391 | |||
392 | static void radeon_legacy_write_tv_restarts(struct radeon_encoder *radeon_encoder) | ||
393 | { | ||
394 | struct drm_device *dev = radeon_encoder->base.dev; | ||
395 | struct radeon_device *rdev = dev->dev_private; | ||
396 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; | ||
397 | WREG32(RADEON_TV_FRESTART, tv_dac->tv.frestart); | ||
398 | WREG32(RADEON_TV_HRESTART, tv_dac->tv.hrestart); | ||
399 | WREG32(RADEON_TV_VRESTART, tv_dac->tv.vrestart); | ||
400 | } | ||
401 | |||
402 | static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder) | ||
403 | { | ||
404 | struct drm_device *dev = encoder->dev; | ||
405 | struct radeon_device *rdev = dev->dev_private; | ||
406 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
407 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; | ||
408 | struct radeon_crtc *radeon_crtc; | ||
409 | int restart; | ||
410 | unsigned int h_total, v_total, f_total; | ||
411 | int v_offset, h_offset; | ||
412 | u16 p1, p2, h_inc; | ||
413 | bool h_changed; | ||
414 | const struct radeon_tv_mode_constants *const_ptr; | ||
415 | struct radeon_pll *pll; | ||
416 | |||
417 | radeon_crtc = to_radeon_crtc(radeon_encoder->base.crtc); | ||
418 | if (radeon_crtc->crtc_id == 1) | ||
419 | pll = &rdev->clock.p2pll; | ||
420 | else | ||
421 | pll = &rdev->clock.p1pll; | ||
422 | |||
423 | const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL); | ||
424 | if (!const_ptr) | ||
425 | return false; | ||
426 | |||
427 | h_total = const_ptr->hor_total; | ||
428 | v_total = const_ptr->ver_total; | ||
429 | |||
430 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
431 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
432 | tv_dac->tv_std == TV_STD_PAL_M || | ||
433 | tv_dac->tv_std == TV_STD_PAL_60) | ||
434 | f_total = NTSC_TV_VFTOTAL + 1; | ||
435 | else | ||
436 | f_total = PAL_TV_VFTOTAL + 1; | ||
437 | |||
438 | /* adjust positions 1&2 in hor. cod timing table */ | ||
439 | h_offset = tv_dac->h_pos * H_POS_UNIT; | ||
440 | |||
441 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
442 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
443 | tv_dac->tv_std == TV_STD_PAL_M) { | ||
444 | h_offset -= 50; | ||
445 | p1 = hor_timing_NTSC[H_TABLE_POS1]; | ||
446 | p2 = hor_timing_NTSC[H_TABLE_POS2]; | ||
447 | } else { | ||
448 | p1 = hor_timing_PAL[H_TABLE_POS1]; | ||
449 | p2 = hor_timing_PAL[H_TABLE_POS2]; | ||
450 | } | ||
451 | |||
452 | p1 = (u16)((int)p1 + h_offset); | ||
453 | p2 = (u16)((int)p2 - h_offset); | ||
454 | |||
455 | h_changed = (p1 != tv_dac->tv.h_code_timing[H_TABLE_POS1] || | ||
456 | p2 != tv_dac->tv.h_code_timing[H_TABLE_POS2]); | ||
457 | |||
458 | tv_dac->tv.h_code_timing[H_TABLE_POS1] = p1; | ||
459 | tv_dac->tv.h_code_timing[H_TABLE_POS2] = p2; | ||
460 | |||
461 | /* Convert hOffset from n. of TV clock periods to n. of CRTC clock periods (CRTC pixels) */ | ||
462 | h_offset = (h_offset * (int)(const_ptr->pix_to_tv)) / 1000; | ||
463 | |||
464 | /* adjust restart */ | ||
465 | restart = const_ptr->def_restart; | ||
466 | |||
467 | /* | ||
468 | * convert v_pos TV lines to n. of CRTC pixels | ||
469 | */ | ||
470 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
471 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
472 | tv_dac->tv_std == TV_STD_PAL_M || | ||
473 | tv_dac->tv_std == TV_STD_PAL_60) | ||
474 | v_offset = ((int)(v_total * h_total) * 2 * tv_dac->v_pos) / (int)(NTSC_TV_LINES_PER_FRAME); | ||
475 | else | ||
476 | v_offset = ((int)(v_total * h_total) * 2 * tv_dac->v_pos) / (int)(PAL_TV_LINES_PER_FRAME); | ||
477 | |||
478 | restart -= v_offset + h_offset; | ||
479 | |||
480 | DRM_DEBUG("compute_restarts: def = %u h = %d v = %d, p1 = %04x, p2 = %04x, restart = %d\n", | ||
481 | const_ptr->def_restart, tv_dac->h_pos, tv_dac->v_pos, p1, p2, restart); | ||
482 | |||
483 | tv_dac->tv.hrestart = restart % h_total; | ||
484 | restart /= h_total; | ||
485 | tv_dac->tv.vrestart = restart % v_total; | ||
486 | restart /= v_total; | ||
487 | tv_dac->tv.frestart = restart % f_total; | ||
488 | |||
489 | DRM_DEBUG("compute_restart: F/H/V=%u,%u,%u\n", | ||
490 | (unsigned)tv_dac->tv.frestart, | ||
491 | (unsigned)tv_dac->tv.vrestart, | ||
492 | (unsigned)tv_dac->tv.hrestart); | ||
493 | |||
494 | /* compute h_inc from hsize */ | ||
495 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
496 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
497 | tv_dac->tv_std == TV_STD_PAL_M) | ||
498 | h_inc = (u16)((int)(const_ptr->hor_resolution * 4096 * NTSC_TV_CLOCK_T) / | ||
499 | (tv_dac->h_size * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE))); | ||
500 | else | ||
501 | h_inc = (u16)((int)(const_ptr->hor_resolution * 4096 * PAL_TV_CLOCK_T) / | ||
502 | (tv_dac->h_size * (int)(PAL_TV_H_SIZE_UNIT) + (int)(PAL_TV_ZERO_H_SIZE))); | ||
503 | |||
504 | tv_dac->tv.timing_cntl = (tv_dac->tv.timing_cntl & ~RADEON_H_INC_MASK) | | ||
505 | ((u32)h_inc << RADEON_H_INC_SHIFT); | ||
506 | |||
507 | DRM_DEBUG("compute_restart: h_size = %d h_inc = %d\n", tv_dac->h_size, h_inc); | ||
508 | |||
509 | return h_changed; | ||
510 | } | ||
511 | |||
512 | void radeon_legacy_tv_mode_set(struct drm_encoder *encoder, | ||
513 | struct drm_display_mode *mode, | ||
514 | struct drm_display_mode *adjusted_mode) | ||
515 | { | ||
516 | struct drm_device *dev = encoder->dev; | ||
517 | struct radeon_device *rdev = dev->dev_private; | ||
518 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
519 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; | ||
520 | const struct radeon_tv_mode_constants *const_ptr; | ||
521 | struct radeon_crtc *radeon_crtc; | ||
522 | int i; | ||
523 | uint16_t pll_ref_freq; | ||
524 | uint32_t vert_space, flicker_removal, tmp; | ||
525 | uint32_t tv_master_cntl, tv_rgb_cntl, tv_dac_cntl; | ||
526 | uint32_t tv_modulator_cntl1, tv_modulator_cntl2; | ||
527 | uint32_t tv_vscaler_cntl1, tv_vscaler_cntl2; | ||
528 | uint32_t tv_pll_cntl, tv_pll_cntl1, tv_ftotal; | ||
529 | uint32_t tv_y_fall_cntl, tv_y_rise_cntl, tv_y_saw_tooth_cntl; | ||
530 | uint32_t m, n, p; | ||
531 | const uint16_t *hor_timing; | ||
532 | const uint16_t *vert_timing; | ||
533 | |||
534 | const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, &pll_ref_freq); | ||
535 | if (!const_ptr) | ||
536 | return; | ||
537 | |||
538 | radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
539 | |||
540 | tv_master_cntl = (RADEON_VIN_ASYNC_RST | | ||
541 | RADEON_CRT_FIFO_CE_EN | | ||
542 | RADEON_TV_FIFO_CE_EN | | ||
543 | RADEON_TV_ON); | ||
544 | |||
545 | if (!ASIC_IS_R300(rdev)) | ||
546 | tv_master_cntl |= RADEON_TVCLK_ALWAYS_ONb; | ||
547 | |||
548 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
549 | tv_dac->tv_std == TV_STD_NTSC_J) | ||
550 | tv_master_cntl |= RADEON_RESTART_PHASE_FIX; | ||
551 | |||
552 | tv_modulator_cntl1 = (RADEON_SLEW_RATE_LIMIT | | ||
553 | RADEON_SYNC_TIP_LEVEL | | ||
554 | RADEON_YFLT_EN | | ||
555 | RADEON_UVFLT_EN | | ||
556 | (6 << RADEON_CY_FILT_BLEND_SHIFT)); | ||
557 | |||
558 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
559 | tv_dac->tv_std == TV_STD_NTSC_J) { | ||
560 | tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT) | | ||
561 | (0x3b << RADEON_BLANK_LEVEL_SHIFT); | ||
562 | tv_modulator_cntl2 = (-111 & RADEON_TV_U_BURST_LEVEL_MASK) | | ||
563 | ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT); | ||
564 | } else if (tv_dac->tv_std == TV_STD_SCART_PAL) { | ||
565 | tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN; | ||
566 | tv_modulator_cntl2 = (0 & RADEON_TV_U_BURST_LEVEL_MASK) | | ||
567 | ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT); | ||
568 | } else { | ||
569 | tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN | | ||
570 | (0x3b << RADEON_SET_UP_LEVEL_SHIFT) | | ||
571 | (0x3b << RADEON_BLANK_LEVEL_SHIFT); | ||
572 | tv_modulator_cntl2 = (-78 & RADEON_TV_U_BURST_LEVEL_MASK) | | ||
573 | ((62 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT); | ||
574 | } | ||
575 | |||
576 | |||
577 | tv_rgb_cntl = (RADEON_RGB_DITHER_EN | ||
578 | | RADEON_TVOUT_SCALE_EN | ||
579 | | (0x0b << RADEON_UVRAM_READ_MARGIN_SHIFT) | ||
580 | | (0x07 << RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT) | ||
581 | | RADEON_RGB_ATTEN_SEL(0x3) | ||
582 | | RADEON_RGB_ATTEN_VAL(0xc)); | ||
583 | |||
584 | if (radeon_crtc->crtc_id == 1) | ||
585 | tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC2; | ||
586 | else { | ||
587 | if (radeon_crtc->rmx_type != RMX_OFF) | ||
588 | tv_rgb_cntl |= RADEON_RGB_SRC_SEL_RMX; | ||
589 | else | ||
590 | tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC1; | ||
591 | } | ||
592 | |||
593 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
594 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
595 | tv_dac->tv_std == TV_STD_PAL_M || | ||
596 | tv_dac->tv_std == TV_STD_PAL_60) | ||
597 | vert_space = const_ptr->ver_total * 2 * 10000 / NTSC_TV_LINES_PER_FRAME; | ||
598 | else | ||
599 | vert_space = const_ptr->ver_total * 2 * 10000 / PAL_TV_LINES_PER_FRAME; | ||
600 | |||
601 | tmp = RREG32(RADEON_TV_VSCALER_CNTL1); | ||
602 | tmp &= 0xe3ff0000; | ||
603 | tmp |= (vert_space * (1 << FRAC_BITS) / 10000); | ||
604 | tv_vscaler_cntl1 = tmp; | ||
605 | |||
606 | if (pll_ref_freq == 2700) | ||
607 | tv_vscaler_cntl1 |= RADEON_RESTART_FIELD; | ||
608 | |||
609 | if (const_ptr->hor_resolution == 1024) | ||
610 | tv_vscaler_cntl1 |= (4 << RADEON_Y_DEL_W_SIG_SHIFT); | ||
611 | else | ||
612 | tv_vscaler_cntl1 |= (2 << RADEON_Y_DEL_W_SIG_SHIFT); | ||
613 | |||
614 | /* scale up for int divide */ | ||
615 | tmp = const_ptr->ver_total * 2 * 1000; | ||
616 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
617 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
618 | tv_dac->tv_std == TV_STD_PAL_M || | ||
619 | tv_dac->tv_std == TV_STD_PAL_60) { | ||
620 | tmp /= NTSC_TV_LINES_PER_FRAME; | ||
621 | } else { | ||
622 | tmp /= PAL_TV_LINES_PER_FRAME; | ||
623 | } | ||
624 | flicker_removal = (tmp + 500) / 1000; | ||
625 | |||
626 | if (flicker_removal < 3) | ||
627 | flicker_removal = 3; | ||
628 | for (i = 0; i < 6; ++i) { | ||
629 | if (flicker_removal == SLOPE_limit[i]) | ||
630 | break; | ||
631 | } | ||
632 | |||
633 | tv_y_saw_tooth_cntl = (vert_space * SLOPE_value[i] * (1 << (FRAC_BITS - 1)) + | ||
634 | 5001) / 10000 / 8 | ((SLOPE_value[i] * | ||
635 | (1 << (FRAC_BITS - 1)) / 8) << 16); | ||
636 | tv_y_fall_cntl = | ||
637 | (YCOEF_EN_value[i] << 17) | ((YCOEF_value[i] * (1 << 8) / 8) << 24) | | ||
638 | RADEON_Y_FALL_PING_PONG | (272 * SLOPE_value[i] / 8) * (1 << (FRAC_BITS - 1)) / | ||
639 | 1024; | ||
640 | tv_y_rise_cntl = RADEON_Y_RISE_PING_PONG| | ||
641 | (flicker_removal * 1024 - 272) * SLOPE_value[i] / 8 * (1 << (FRAC_BITS - 1)) / 1024; | ||
642 | |||
643 | tv_vscaler_cntl2 = RREG32(RADEON_TV_VSCALER_CNTL2) & 0x00fffff0; | ||
644 | tv_vscaler_cntl2 |= (0x10 << 24) | | ||
645 | RADEON_DITHER_MODE | | ||
646 | RADEON_Y_OUTPUT_DITHER_EN | | ||
647 | RADEON_UV_OUTPUT_DITHER_EN | | ||
648 | RADEON_UV_TO_BUF_DITHER_EN; | ||
649 | |||
650 | tmp = (tv_vscaler_cntl1 >> RADEON_UV_INC_SHIFT) & RADEON_UV_INC_MASK; | ||
651 | tmp = ((16384 * 256 * 10) / tmp + 5) / 10; | ||
652 | tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000; | ||
653 | tv_dac->tv.timing_cntl = tmp; | ||
654 | |||
655 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
656 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
657 | tv_dac->tv_std == TV_STD_PAL_M || | ||
658 | tv_dac->tv_std == TV_STD_PAL_60) | ||
659 | tv_dac_cntl = tv_dac->ntsc_tvdac_adj; | ||
660 | else | ||
661 | tv_dac_cntl = tv_dac->pal_tvdac_adj; | ||
662 | |||
663 | tv_dac_cntl |= RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD; | ||
664 | |||
665 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
666 | tv_dac->tv_std == TV_STD_NTSC_J) | ||
667 | tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC; | ||
668 | else | ||
669 | tv_dac_cntl |= RADEON_TV_DAC_STD_PAL; | ||
670 | |||
671 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
672 | tv_dac->tv_std == TV_STD_NTSC_J) { | ||
673 | if (pll_ref_freq == 2700) { | ||
674 | m = NTSC_TV_PLL_M_27; | ||
675 | n = NTSC_TV_PLL_N_27; | ||
676 | p = NTSC_TV_PLL_P_27; | ||
677 | } else { | ||
678 | m = NTSC_TV_PLL_M_14; | ||
679 | n = NTSC_TV_PLL_N_14; | ||
680 | p = NTSC_TV_PLL_P_14; | ||
681 | } | ||
682 | } else { | ||
683 | if (pll_ref_freq == 2700) { | ||
684 | m = PAL_TV_PLL_M_27; | ||
685 | n = PAL_TV_PLL_N_27; | ||
686 | p = PAL_TV_PLL_P_27; | ||
687 | } else { | ||
688 | m = PAL_TV_PLL_M_27; | ||
689 | n = PAL_TV_PLL_N_27; | ||
690 | p = PAL_TV_PLL_P_27; | ||
691 | } | ||
692 | } | ||
693 | |||
694 | tv_pll_cntl = (m & RADEON_TV_M0LO_MASK) | | ||
695 | (((m >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) | | ||
696 | ((n & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) | | ||
697 | (((n >> 9) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) | | ||
698 | ((p & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT); | ||
699 | |||
700 | tv_pll_cntl1 = (((4 & RADEON_TVPCP_MASK) << RADEON_TVPCP_SHIFT) | | ||
701 | ((4 & RADEON_TVPVG_MASK) << RADEON_TVPVG_SHIFT) | | ||
702 | ((1 & RADEON_TVPDC_MASK) << RADEON_TVPDC_SHIFT) | | ||
703 | RADEON_TVCLK_SRC_SEL_TVPLL | | ||
704 | RADEON_TVPLL_TEST_DIS); | ||
705 | |||
706 | tv_dac->tv.tv_uv_adr = 0xc8; | ||
707 | |||
708 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
709 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
710 | tv_dac->tv_std == TV_STD_PAL_M || | ||
711 | tv_dac->tv_std == TV_STD_PAL_60) { | ||
712 | tv_ftotal = NTSC_TV_VFTOTAL; | ||
713 | hor_timing = hor_timing_NTSC; | ||
714 | vert_timing = vert_timing_NTSC; | ||
715 | } else { | ||
716 | hor_timing = hor_timing_PAL; | ||
717 | vert_timing = vert_timing_PAL; | ||
718 | tv_ftotal = PAL_TV_VFTOTAL; | ||
719 | } | ||
720 | |||
721 | for (i = 0; i < MAX_H_CODE_TIMING_LEN; i++) { | ||
722 | if ((tv_dac->tv.h_code_timing[i] = hor_timing[i]) == 0) | ||
723 | break; | ||
724 | } | ||
725 | |||
726 | for (i = 0; i < MAX_V_CODE_TIMING_LEN; i++) { | ||
727 | if ((tv_dac->tv.v_code_timing[i] = vert_timing[i]) == 0) | ||
728 | break; | ||
729 | } | ||
730 | |||
731 | radeon_legacy_tv_init_restarts(encoder); | ||
732 | |||
733 | /* play with DAC_CNTL */ | ||
734 | /* play with GPIOPAD_A */ | ||
735 | /* DISP_OUTPUT_CNTL */ | ||
736 | /* use reference freq */ | ||
737 | |||
738 | /* program the TV registers */ | ||
739 | WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST | | ||
740 | RADEON_CRT_ASYNC_RST | RADEON_TV_FIFO_ASYNC_RST)); | ||
741 | |||
742 | tmp = RREG32(RADEON_TV_DAC_CNTL); | ||
743 | tmp &= ~RADEON_TV_DAC_NBLANK; | ||
744 | tmp |= RADEON_TV_DAC_BGSLEEP | | ||
745 | RADEON_TV_DAC_RDACPD | | ||
746 | RADEON_TV_DAC_GDACPD | | ||
747 | RADEON_TV_DAC_BDACPD; | ||
748 | WREG32(RADEON_TV_DAC_CNTL, tmp); | ||
749 | |||
750 | /* TV PLL */ | ||
751 | WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL); | ||
752 | WREG32_PLL(RADEON_TV_PLL_CNTL, tv_pll_cntl); | ||
753 | WREG32_PLL_P(RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET); | ||
754 | |||
755 | radeon_wait_pll_lock(encoder, 200, 800, 135); | ||
756 | |||
757 | WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET); | ||
758 | |||
759 | radeon_wait_pll_lock(encoder, 300, 160, 27); | ||
760 | radeon_wait_pll_lock(encoder, 200, 800, 135); | ||
761 | |||
762 | WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~0xf); | ||
763 | WREG32_PLL_P(RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL); | ||
764 | |||
765 | WREG32_PLL_P(RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK); | ||
766 | WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP); | ||
767 | |||
768 | /* TV HV */ | ||
769 | WREG32(RADEON_TV_RGB_CNTL, tv_rgb_cntl); | ||
770 | WREG32(RADEON_TV_HTOTAL, const_ptr->hor_total - 1); | ||
771 | WREG32(RADEON_TV_HDISP, const_ptr->hor_resolution - 1); | ||
772 | WREG32(RADEON_TV_HSTART, const_ptr->hor_start); | ||
773 | |||
774 | WREG32(RADEON_TV_VTOTAL, const_ptr->ver_total - 1); | ||
775 | WREG32(RADEON_TV_VDISP, const_ptr->ver_resolution - 1); | ||
776 | WREG32(RADEON_TV_FTOTAL, tv_ftotal); | ||
777 | WREG32(RADEON_TV_VSCALER_CNTL1, tv_vscaler_cntl1); | ||
778 | WREG32(RADEON_TV_VSCALER_CNTL2, tv_vscaler_cntl2); | ||
779 | |||
780 | WREG32(RADEON_TV_Y_FALL_CNTL, tv_y_fall_cntl); | ||
781 | WREG32(RADEON_TV_Y_RISE_CNTL, tv_y_rise_cntl); | ||
782 | WREG32(RADEON_TV_Y_SAW_TOOTH_CNTL, tv_y_saw_tooth_cntl); | ||
783 | |||
784 | WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST | | ||
785 | RADEON_CRT_ASYNC_RST)); | ||
786 | |||
787 | /* TV restarts */ | ||
788 | radeon_legacy_write_tv_restarts(radeon_encoder); | ||
789 | |||
790 | /* tv timings */ | ||
791 | radeon_restore_tv_timing_tables(radeon_encoder); | ||
792 | |||
793 | WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST)); | ||
794 | |||
795 | /* tv std */ | ||
796 | WREG32(RADEON_TV_SYNC_CNTL, (RADEON_SYNC_PUB | RADEON_TV_SYNC_IO_DRIVE)); | ||
797 | WREG32(RADEON_TV_TIMING_CNTL, tv_dac->tv.timing_cntl); | ||
798 | WREG32(RADEON_TV_MODULATOR_CNTL1, tv_modulator_cntl1); | ||
799 | WREG32(RADEON_TV_MODULATOR_CNTL2, tv_modulator_cntl2); | ||
800 | WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, (RADEON_Y_RED_EN | | ||
801 | RADEON_C_GRN_EN | | ||
802 | RADEON_CMP_BLU_EN | | ||
803 | RADEON_DAC_DITHER_EN)); | ||
804 | |||
805 | WREG32(RADEON_TV_CRC_CNTL, 0); | ||
806 | |||
807 | WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); | ||
808 | |||
809 | WREG32(RADEON_TV_GAIN_LIMIT_SETTINGS, ((0x17f << RADEON_UV_GAIN_LIMIT_SHIFT) | | ||
810 | (0x5ff << RADEON_Y_GAIN_LIMIT_SHIFT))); | ||
811 | WREG32(RADEON_TV_LINEAR_GAIN_SETTINGS, ((0x100 << RADEON_UV_GAIN_SHIFT) | | ||
812 | (0x100 << RADEON_Y_GAIN_SHIFT))); | ||
813 | |||
814 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); | ||
815 | |||
816 | } | ||
817 | |||
818 | void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder, | ||
819 | uint32_t *h_total_disp, uint32_t *h_sync_strt_wid, | ||
820 | uint32_t *v_total_disp, uint32_t *v_sync_strt_wid) | ||
821 | { | ||
822 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
823 | const struct radeon_tv_mode_constants *const_ptr; | ||
824 | uint32_t tmp; | ||
825 | |||
826 | const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL); | ||
827 | if (!const_ptr) | ||
828 | return; | ||
829 | |||
830 | *h_total_disp = (((const_ptr->hor_resolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) | | ||
831 | (((const_ptr->hor_total / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT); | ||
832 | |||
833 | tmp = *h_sync_strt_wid; | ||
834 | tmp &= ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR); | ||
835 | tmp |= (((const_ptr->hor_syncstart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) | | ||
836 | (const_ptr->hor_syncstart & 7); | ||
837 | *h_sync_strt_wid = tmp; | ||
838 | |||
839 | *v_total_disp = ((const_ptr->ver_resolution - 1) << RADEON_CRTC_V_DISP_SHIFT) | | ||
840 | ((const_ptr->ver_total - 1) << RADEON_CRTC_V_TOTAL_SHIFT); | ||
841 | |||
842 | tmp = *v_sync_strt_wid; | ||
843 | tmp &= ~RADEON_CRTC_V_SYNC_STRT; | ||
844 | tmp |= ((const_ptr->ver_syncstart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT); | ||
845 | *v_sync_strt_wid = tmp; | ||
846 | } | ||
847 | |||
848 | static inline int get_post_div(int value) | ||
849 | { | ||
850 | int post_div; | ||
851 | switch (value) { | ||
852 | case 1: post_div = 0; break; | ||
853 | case 2: post_div = 1; break; | ||
854 | case 3: post_div = 4; break; | ||
855 | case 4: post_div = 2; break; | ||
856 | case 6: post_div = 6; break; | ||
857 | case 8: post_div = 3; break; | ||
858 | case 12: post_div = 7; break; | ||
859 | case 16: | ||
860 | default: post_div = 5; break; | ||
861 | } | ||
862 | return post_div; | ||
863 | } | ||
864 | |||
865 | void radeon_legacy_tv_adjust_pll1(struct drm_encoder *encoder, | ||
866 | uint32_t *htotal_cntl, uint32_t *ppll_ref_div, | ||
867 | uint32_t *ppll_div_3, uint32_t *pixclks_cntl) | ||
868 | { | ||
869 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
870 | const struct radeon_tv_mode_constants *const_ptr; | ||
871 | |||
872 | const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL); | ||
873 | if (!const_ptr) | ||
874 | return; | ||
875 | |||
876 | *htotal_cntl = (const_ptr->hor_total & 0x7) | RADEON_HTOT_CNTL_VGA_EN; | ||
877 | |||
878 | *ppll_ref_div = const_ptr->crtcPLL_M; | ||
879 | |||
880 | *ppll_div_3 = (const_ptr->crtcPLL_N & 0x7ff) | (get_post_div(const_ptr->crtcPLL_post_div) << 16); | ||
881 | *pixclks_cntl &= ~(RADEON_PIX2CLK_SRC_SEL_MASK | RADEON_PIXCLK_TV_SRC_SEL); | ||
882 | *pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK; | ||
883 | } | ||
884 | |||
885 | void radeon_legacy_tv_adjust_pll2(struct drm_encoder *encoder, | ||
886 | uint32_t *htotal2_cntl, uint32_t *p2pll_ref_div, | ||
887 | uint32_t *p2pll_div_0, uint32_t *pixclks_cntl) | ||
888 | { | ||
889 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
890 | const struct radeon_tv_mode_constants *const_ptr; | ||
891 | |||
892 | const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL); | ||
893 | if (!const_ptr) | ||
894 | return; | ||
895 | |||
896 | *htotal2_cntl = (const_ptr->hor_total & 0x7); | ||
897 | |||
898 | *p2pll_ref_div = const_ptr->crtcPLL_M; | ||
899 | |||
900 | *p2pll_div_0 = (const_ptr->crtcPLL_N & 0x7ff) | (get_post_div(const_ptr->crtcPLL_post_div) << 16); | ||
901 | *pixclks_cntl &= ~RADEON_PIX2CLK_SRC_SEL_MASK; | ||
902 | *pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK | RADEON_PIXCLK_TV_SRC_SEL; | ||
903 | } | ||
904 | |||
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 20e9509a7130..523d6cbd4f08 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -188,6 +188,21 @@ struct radeon_native_mode { | |||
188 | uint32_t flags; | 188 | uint32_t flags; |
189 | }; | 189 | }; |
190 | 190 | ||
191 | #define MAX_H_CODE_TIMING_LEN 32 | ||
192 | #define MAX_V_CODE_TIMING_LEN 32 | ||
193 | |||
194 | /* need to store these as reading | ||
195 | back code tables is excessive */ | ||
196 | struct radeon_tv_regs { | ||
197 | uint32_t tv_uv_adr; | ||
198 | uint32_t timing_cntl; | ||
199 | uint32_t hrestart; | ||
200 | uint32_t vrestart; | ||
201 | uint32_t frestart; | ||
202 | uint16_t h_code_timing[MAX_H_CODE_TIMING_LEN]; | ||
203 | uint16_t v_code_timing[MAX_V_CODE_TIMING_LEN]; | ||
204 | }; | ||
205 | |||
191 | struct radeon_crtc { | 206 | struct radeon_crtc { |
192 | struct drm_crtc base; | 207 | struct drm_crtc base; |
193 | int crtc_id; | 208 | int crtc_id; |
@@ -202,7 +217,6 @@ struct radeon_crtc { | |||
202 | uint32_t legacy_display_base_addr; | 217 | uint32_t legacy_display_base_addr; |
203 | uint32_t legacy_cursor_offset; | 218 | uint32_t legacy_cursor_offset; |
204 | enum radeon_rmx_type rmx_type; | 219 | enum radeon_rmx_type rmx_type; |
205 | uint32_t devices; | ||
206 | fixed20_12 vsc; | 220 | fixed20_12 vsc; |
207 | fixed20_12 hsc; | 221 | fixed20_12 hsc; |
208 | struct radeon_native_mode native_mode; | 222 | struct radeon_native_mode native_mode; |
@@ -234,7 +248,13 @@ struct radeon_encoder_tv_dac { | |||
234 | uint32_t ntsc_tvdac_adj; | 248 | uint32_t ntsc_tvdac_adj; |
235 | uint32_t pal_tvdac_adj; | 249 | uint32_t pal_tvdac_adj; |
236 | 250 | ||
251 | int h_pos; | ||
252 | int v_pos; | ||
253 | int h_size; | ||
254 | int supported_tv_stds; | ||
255 | bool tv_on; | ||
237 | enum radeon_tv_std tv_std; | 256 | enum radeon_tv_std tv_std; |
257 | struct radeon_tv_regs tv; | ||
238 | }; | 258 | }; |
239 | 259 | ||
240 | struct radeon_encoder_int_tmds { | 260 | struct radeon_encoder_int_tmds { |
@@ -253,10 +273,15 @@ struct radeon_encoder_atom_dig { | |||
253 | struct radeon_native_mode native_mode; | 273 | struct radeon_native_mode native_mode; |
254 | }; | 274 | }; |
255 | 275 | ||
276 | struct radeon_encoder_atom_dac { | ||
277 | enum radeon_tv_std tv_std; | ||
278 | }; | ||
279 | |||
256 | struct radeon_encoder { | 280 | struct radeon_encoder { |
257 | struct drm_encoder base; | 281 | struct drm_encoder base; |
258 | uint32_t encoder_id; | 282 | uint32_t encoder_id; |
259 | uint32_t devices; | 283 | uint32_t devices; |
284 | uint32_t active_device; | ||
260 | uint32_t flags; | 285 | uint32_t flags; |
261 | uint32_t pixel_clock; | 286 | uint32_t pixel_clock; |
262 | enum radeon_rmx_type rmx_type; | 287 | enum radeon_rmx_type rmx_type; |
@@ -274,7 +299,10 @@ struct radeon_connector { | |||
274 | uint32_t connector_id; | 299 | uint32_t connector_id; |
275 | uint32_t devices; | 300 | uint32_t devices; |
276 | struct radeon_i2c_chan *ddc_bus; | 301 | struct radeon_i2c_chan *ddc_bus; |
277 | int use_digital; | 302 | bool use_digital; |
303 | /* we need to mind the EDID between detect | ||
304 | and get modes due to analog/digital/tvencoder */ | ||
305 | struct edid *edid; | ||
278 | void *con_priv; | 306 | void *con_priv; |
279 | }; | 307 | }; |
280 | 308 | ||
@@ -308,6 +336,7 @@ struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, i | |||
308 | struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index); | 336 | struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index); |
309 | extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action); | 337 | extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action); |
310 | extern int atombios_get_encoder_mode(struct drm_encoder *encoder); | 338 | extern int atombios_get_encoder_mode(struct drm_encoder *encoder); |
339 | extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); | ||
311 | 340 | ||
312 | extern void radeon_crtc_load_lut(struct drm_crtc *crtc); | 341 | extern void radeon_crtc_load_lut(struct drm_crtc *crtc); |
313 | extern int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 342 | extern int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, |
@@ -394,6 +423,19 @@ extern int radeon_static_clocks_init(struct drm_device *dev); | |||
394 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | 423 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, |
395 | struct drm_display_mode *mode, | 424 | struct drm_display_mode *mode, |
396 | struct drm_display_mode *adjusted_mode); | 425 | struct drm_display_mode *adjusted_mode); |
397 | void atom_rv515_force_tv_scaler(struct radeon_device *rdev); | 426 | void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc); |
398 | 427 | ||
428 | /* legacy tv */ | ||
429 | void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder, | ||
430 | uint32_t *h_total_disp, uint32_t *h_sync_strt_wid, | ||
431 | uint32_t *v_total_disp, uint32_t *v_sync_strt_wid); | ||
432 | void radeon_legacy_tv_adjust_pll1(struct drm_encoder *encoder, | ||
433 | uint32_t *htotal_cntl, uint32_t *ppll_ref_div, | ||
434 | uint32_t *ppll_div_3, uint32_t *pixclks_cntl); | ||
435 | void radeon_legacy_tv_adjust_pll2(struct drm_encoder *encoder, | ||
436 | uint32_t *htotal2_cntl, uint32_t *p2pll_ref_div, | ||
437 | uint32_t *p2pll_div_0, uint32_t *pixclks_cntl); | ||
438 | void radeon_legacy_tv_mode_set(struct drm_encoder *encoder, | ||
439 | struct drm_display_mode *mode, | ||
440 | struct drm_display_mode *adjusted_mode); | ||
399 | #endif | 441 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index 404b39bf3430..28be2f1165cb 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
@@ -3462,7 +3462,9 @@ | |||
3462 | # define RADEON_RGB_CONVERT_BY_PASS (1 << 10) | 3462 | # define RADEON_RGB_CONVERT_BY_PASS (1 << 10) |
3463 | # define RADEON_UVRAM_READ_MARGIN_SHIFT 16 | 3463 | # define RADEON_UVRAM_READ_MARGIN_SHIFT 16 |
3464 | # define RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT 20 | 3464 | # define RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT 20 |
3465 | # define RADEON_TVOUT_SCALE_EN (1 << 26) | 3465 | # define RADEON_RGB_ATTEN_SEL(x) ((x) << 24) |
3466 | # define RADEON_TVOUT_SCALE_EN (1 << 26) | ||
3467 | # define RADEON_RGB_ATTEN_VAL(x) ((x) << 28) | ||
3466 | #define RADEON_TV_SYNC_CNTL 0x0808 | 3468 | #define RADEON_TV_SYNC_CNTL 0x0808 |
3467 | # define RADEON_SYNC_OE (1 << 0) | 3469 | # define RADEON_SYNC_OE (1 << 0) |
3468 | # define RADEON_SYNC_OUT (1 << 1) | 3470 | # define RADEON_SYNC_OUT (1 << 1) |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 60a194f1d9a8..97965c430c1f 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -475,232 +475,234 @@ int rv515_init(struct radeon_device *rdev) | |||
475 | return 0; | 475 | return 0; |
476 | } | 476 | } |
477 | 477 | ||
478 | void atom_rv515_force_tv_scaler(struct radeon_device *rdev) | 478 | void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *crtc) |
479 | { | 479 | { |
480 | 480 | int index_reg = 0x6578 + crtc->crtc_offset; | |
481 | WREG32(0x659C, 0x0); | 481 | int data_reg = 0x657c + crtc->crtc_offset; |
482 | WREG32(0x6594, 0x705); | 482 | |
483 | WREG32(0x65A4, 0x10001); | 483 | WREG32(0x659C + crtc->crtc_offset, 0x0); |
484 | WREG32(0x65D8, 0x0); | 484 | WREG32(0x6594 + crtc->crtc_offset, 0x705); |
485 | WREG32(0x65B0, 0x0); | 485 | WREG32(0x65A4 + crtc->crtc_offset, 0x10001); |
486 | WREG32(0x65C0, 0x0); | 486 | WREG32(0x65D8 + crtc->crtc_offset, 0x0); |
487 | WREG32(0x65D4, 0x0); | 487 | WREG32(0x65B0 + crtc->crtc_offset, 0x0); |
488 | WREG32(0x6578, 0x0); | 488 | WREG32(0x65C0 + crtc->crtc_offset, 0x0); |
489 | WREG32(0x657C, 0x841880A8); | 489 | WREG32(0x65D4 + crtc->crtc_offset, 0x0); |
490 | WREG32(0x6578, 0x1); | 490 | WREG32(index_reg, 0x0); |
491 | WREG32(0x657C, 0x84208680); | 491 | WREG32(data_reg, 0x841880A8); |
492 | WREG32(0x6578, 0x2); | 492 | WREG32(index_reg, 0x1); |
493 | WREG32(0x657C, 0xBFF880B0); | 493 | WREG32(data_reg, 0x84208680); |
494 | WREG32(0x6578, 0x100); | 494 | WREG32(index_reg, 0x2); |
495 | WREG32(0x657C, 0x83D88088); | 495 | WREG32(data_reg, 0xBFF880B0); |
496 | WREG32(0x6578, 0x101); | 496 | WREG32(index_reg, 0x100); |
497 | WREG32(0x657C, 0x84608680); | 497 | WREG32(data_reg, 0x83D88088); |
498 | WREG32(0x6578, 0x102); | 498 | WREG32(index_reg, 0x101); |
499 | WREG32(0x657C, 0xBFF080D0); | 499 | WREG32(data_reg, 0x84608680); |
500 | WREG32(0x6578, 0x200); | 500 | WREG32(index_reg, 0x102); |
501 | WREG32(0x657C, 0x83988068); | 501 | WREG32(data_reg, 0xBFF080D0); |
502 | WREG32(0x6578, 0x201); | 502 | WREG32(index_reg, 0x200); |
503 | WREG32(0x657C, 0x84A08680); | 503 | WREG32(data_reg, 0x83988068); |
504 | WREG32(0x6578, 0x202); | 504 | WREG32(index_reg, 0x201); |
505 | WREG32(0x657C, 0xBFF080F8); | 505 | WREG32(data_reg, 0x84A08680); |
506 | WREG32(0x6578, 0x300); | 506 | WREG32(index_reg, 0x202); |
507 | WREG32(0x657C, 0x83588058); | 507 | WREG32(data_reg, 0xBFF080F8); |
508 | WREG32(0x6578, 0x301); | 508 | WREG32(index_reg, 0x300); |
509 | WREG32(0x657C, 0x84E08660); | 509 | WREG32(data_reg, 0x83588058); |
510 | WREG32(0x6578, 0x302); | 510 | WREG32(index_reg, 0x301); |
511 | WREG32(0x657C, 0xBFF88120); | 511 | WREG32(data_reg, 0x84E08660); |
512 | WREG32(0x6578, 0x400); | 512 | WREG32(index_reg, 0x302); |
513 | WREG32(0x657C, 0x83188040); | 513 | WREG32(data_reg, 0xBFF88120); |
514 | WREG32(0x6578, 0x401); | 514 | WREG32(index_reg, 0x400); |
515 | WREG32(0x657C, 0x85008660); | 515 | WREG32(data_reg, 0x83188040); |
516 | WREG32(0x6578, 0x402); | 516 | WREG32(index_reg, 0x401); |
517 | WREG32(0x657C, 0xBFF88150); | 517 | WREG32(data_reg, 0x85008660); |
518 | WREG32(0x6578, 0x500); | 518 | WREG32(index_reg, 0x402); |
519 | WREG32(0x657C, 0x82D88030); | 519 | WREG32(data_reg, 0xBFF88150); |
520 | WREG32(0x6578, 0x501); | 520 | WREG32(index_reg, 0x500); |
521 | WREG32(0x657C, 0x85408640); | 521 | WREG32(data_reg, 0x82D88030); |
522 | WREG32(0x6578, 0x502); | 522 | WREG32(index_reg, 0x501); |
523 | WREG32(0x657C, 0xBFF88180); | 523 | WREG32(data_reg, 0x85408640); |
524 | WREG32(0x6578, 0x600); | 524 | WREG32(index_reg, 0x502); |
525 | WREG32(0x657C, 0x82A08018); | 525 | WREG32(data_reg, 0xBFF88180); |
526 | WREG32(0x6578, 0x601); | 526 | WREG32(index_reg, 0x600); |
527 | WREG32(0x657C, 0x85808620); | 527 | WREG32(data_reg, 0x82A08018); |
528 | WREG32(0x6578, 0x602); | 528 | WREG32(index_reg, 0x601); |
529 | WREG32(0x657C, 0xBFF081B8); | 529 | WREG32(data_reg, 0x85808620); |
530 | WREG32(0x6578, 0x700); | 530 | WREG32(index_reg, 0x602); |
531 | WREG32(0x657C, 0x82608010); | 531 | WREG32(data_reg, 0xBFF081B8); |
532 | WREG32(0x6578, 0x701); | 532 | WREG32(index_reg, 0x700); |
533 | WREG32(0x657C, 0x85A08600); | 533 | WREG32(data_reg, 0x82608010); |
534 | WREG32(0x6578, 0x702); | 534 | WREG32(index_reg, 0x701); |
535 | WREG32(0x657C, 0x800081F0); | 535 | WREG32(data_reg, 0x85A08600); |
536 | WREG32(0x6578, 0x800); | 536 | WREG32(index_reg, 0x702); |
537 | WREG32(0x657C, 0x8228BFF8); | 537 | WREG32(data_reg, 0x800081F0); |
538 | WREG32(0x6578, 0x801); | 538 | WREG32(index_reg, 0x800); |
539 | WREG32(0x657C, 0x85E085E0); | 539 | WREG32(data_reg, 0x8228BFF8); |
540 | WREG32(0x6578, 0x802); | 540 | WREG32(index_reg, 0x801); |
541 | WREG32(0x657C, 0xBFF88228); | 541 | WREG32(data_reg, 0x85E085E0); |
542 | WREG32(0x6578, 0x10000); | 542 | WREG32(index_reg, 0x802); |
543 | WREG32(0x657C, 0x82A8BF00); | 543 | WREG32(data_reg, 0xBFF88228); |
544 | WREG32(0x6578, 0x10001); | 544 | WREG32(index_reg, 0x10000); |
545 | WREG32(0x657C, 0x82A08CC0); | 545 | WREG32(data_reg, 0x82A8BF00); |
546 | WREG32(0x6578, 0x10002); | 546 | WREG32(index_reg, 0x10001); |
547 | WREG32(0x657C, 0x8008BEF8); | 547 | WREG32(data_reg, 0x82A08CC0); |
548 | WREG32(0x6578, 0x10100); | 548 | WREG32(index_reg, 0x10002); |
549 | WREG32(0x657C, 0x81F0BF28); | 549 | WREG32(data_reg, 0x8008BEF8); |
550 | WREG32(0x6578, 0x10101); | 550 | WREG32(index_reg, 0x10100); |
551 | WREG32(0x657C, 0x83608CA0); | 551 | WREG32(data_reg, 0x81F0BF28); |
552 | WREG32(0x6578, 0x10102); | 552 | WREG32(index_reg, 0x10101); |
553 | WREG32(0x657C, 0x8018BED0); | 553 | WREG32(data_reg, 0x83608CA0); |
554 | WREG32(0x6578, 0x10200); | 554 | WREG32(index_reg, 0x10102); |
555 | WREG32(0x657C, 0x8148BF38); | 555 | WREG32(data_reg, 0x8018BED0); |
556 | WREG32(0x6578, 0x10201); | 556 | WREG32(index_reg, 0x10200); |
557 | WREG32(0x657C, 0x84408C80); | 557 | WREG32(data_reg, 0x8148BF38); |
558 | WREG32(0x6578, 0x10202); | 558 | WREG32(index_reg, 0x10201); |
559 | WREG32(0x657C, 0x8008BEB8); | 559 | WREG32(data_reg, 0x84408C80); |
560 | WREG32(0x6578, 0x10300); | 560 | WREG32(index_reg, 0x10202); |
561 | WREG32(0x657C, 0x80B0BF78); | 561 | WREG32(data_reg, 0x8008BEB8); |
562 | WREG32(0x6578, 0x10301); | 562 | WREG32(index_reg, 0x10300); |
563 | WREG32(0x657C, 0x85008C20); | 563 | WREG32(data_reg, 0x80B0BF78); |
564 | WREG32(0x6578, 0x10302); | 564 | WREG32(index_reg, 0x10301); |
565 | WREG32(0x657C, 0x8020BEA0); | 565 | WREG32(data_reg, 0x85008C20); |
566 | WREG32(0x6578, 0x10400); | 566 | WREG32(index_reg, 0x10302); |
567 | WREG32(0x657C, 0x8028BF90); | 567 | WREG32(data_reg, 0x8020BEA0); |
568 | WREG32(0x6578, 0x10401); | 568 | WREG32(index_reg, 0x10400); |
569 | WREG32(0x657C, 0x85E08BC0); | 569 | WREG32(data_reg, 0x8028BF90); |
570 | WREG32(0x6578, 0x10402); | 570 | WREG32(index_reg, 0x10401); |
571 | WREG32(0x657C, 0x8018BE90); | 571 | WREG32(data_reg, 0x85E08BC0); |
572 | WREG32(0x6578, 0x10500); | 572 | WREG32(index_reg, 0x10402); |
573 | WREG32(0x657C, 0xBFB8BFB0); | 573 | WREG32(data_reg, 0x8018BE90); |
574 | WREG32(0x6578, 0x10501); | 574 | WREG32(index_reg, 0x10500); |
575 | WREG32(0x657C, 0x86C08B40); | 575 | WREG32(data_reg, 0xBFB8BFB0); |
576 | WREG32(0x6578, 0x10502); | 576 | WREG32(index_reg, 0x10501); |
577 | WREG32(0x657C, 0x8010BE90); | 577 | WREG32(data_reg, 0x86C08B40); |
578 | WREG32(0x6578, 0x10600); | 578 | WREG32(index_reg, 0x10502); |
579 | WREG32(0x657C, 0xBF58BFC8); | 579 | WREG32(data_reg, 0x8010BE90); |
580 | WREG32(0x6578, 0x10601); | 580 | WREG32(index_reg, 0x10600); |
581 | WREG32(0x657C, 0x87A08AA0); | 581 | WREG32(data_reg, 0xBF58BFC8); |
582 | WREG32(0x6578, 0x10602); | 582 | WREG32(index_reg, 0x10601); |
583 | WREG32(0x657C, 0x8010BE98); | 583 | WREG32(data_reg, 0x87A08AA0); |
584 | WREG32(0x6578, 0x10700); | 584 | WREG32(index_reg, 0x10602); |
585 | WREG32(0x657C, 0xBF10BFF0); | 585 | WREG32(data_reg, 0x8010BE98); |
586 | WREG32(0x6578, 0x10701); | 586 | WREG32(index_reg, 0x10700); |
587 | WREG32(0x657C, 0x886089E0); | 587 | WREG32(data_reg, 0xBF10BFF0); |
588 | WREG32(0x6578, 0x10702); | 588 | WREG32(index_reg, 0x10701); |
589 | WREG32(0x657C, 0x8018BEB0); | 589 | WREG32(data_reg, 0x886089E0); |
590 | WREG32(0x6578, 0x10800); | 590 | WREG32(index_reg, 0x10702); |
591 | WREG32(0x657C, 0xBED8BFE8); | 591 | WREG32(data_reg, 0x8018BEB0); |
592 | WREG32(0x6578, 0x10801); | 592 | WREG32(index_reg, 0x10800); |
593 | WREG32(0x657C, 0x89408940); | 593 | WREG32(data_reg, 0xBED8BFE8); |
594 | WREG32(0x6578, 0x10802); | 594 | WREG32(index_reg, 0x10801); |
595 | WREG32(0x657C, 0xBFE8BED8); | 595 | WREG32(data_reg, 0x89408940); |
596 | WREG32(0x6578, 0x20000); | 596 | WREG32(index_reg, 0x10802); |
597 | WREG32(0x657C, 0x80008000); | 597 | WREG32(data_reg, 0xBFE8BED8); |
598 | WREG32(0x6578, 0x20001); | 598 | WREG32(index_reg, 0x20000); |
599 | WREG32(0x657C, 0x90008000); | 599 | WREG32(data_reg, 0x80008000); |
600 | WREG32(0x6578, 0x20002); | 600 | WREG32(index_reg, 0x20001); |
601 | WREG32(0x657C, 0x80008000); | 601 | WREG32(data_reg, 0x90008000); |
602 | WREG32(0x6578, 0x20003); | 602 | WREG32(index_reg, 0x20002); |
603 | WREG32(0x657C, 0x80008000); | 603 | WREG32(data_reg, 0x80008000); |
604 | WREG32(0x6578, 0x20100); | 604 | WREG32(index_reg, 0x20003); |
605 | WREG32(0x657C, 0x80108000); | 605 | WREG32(data_reg, 0x80008000); |
606 | WREG32(0x6578, 0x20101); | 606 | WREG32(index_reg, 0x20100); |
607 | WREG32(0x657C, 0x8FE0BF70); | 607 | WREG32(data_reg, 0x80108000); |
608 | WREG32(0x6578, 0x20102); | 608 | WREG32(index_reg, 0x20101); |
609 | WREG32(0x657C, 0xBFE880C0); | 609 | WREG32(data_reg, 0x8FE0BF70); |
610 | WREG32(0x6578, 0x20103); | 610 | WREG32(index_reg, 0x20102); |
611 | WREG32(0x657C, 0x80008000); | 611 | WREG32(data_reg, 0xBFE880C0); |
612 | WREG32(0x6578, 0x20200); | 612 | WREG32(index_reg, 0x20103); |
613 | WREG32(0x657C, 0x8018BFF8); | 613 | WREG32(data_reg, 0x80008000); |
614 | WREG32(0x6578, 0x20201); | 614 | WREG32(index_reg, 0x20200); |
615 | WREG32(0x657C, 0x8F80BF08); | 615 | WREG32(data_reg, 0x8018BFF8); |
616 | WREG32(0x6578, 0x20202); | 616 | WREG32(index_reg, 0x20201); |
617 | WREG32(0x657C, 0xBFD081A0); | 617 | WREG32(data_reg, 0x8F80BF08); |
618 | WREG32(0x6578, 0x20203); | 618 | WREG32(index_reg, 0x20202); |
619 | WREG32(0x657C, 0xBFF88000); | 619 | WREG32(data_reg, 0xBFD081A0); |
620 | WREG32(0x6578, 0x20300); | 620 | WREG32(index_reg, 0x20203); |
621 | WREG32(0x657C, 0x80188000); | 621 | WREG32(data_reg, 0xBFF88000); |
622 | WREG32(0x6578, 0x20301); | 622 | WREG32(index_reg, 0x20300); |
623 | WREG32(0x657C, 0x8EE0BEC0); | 623 | WREG32(data_reg, 0x80188000); |
624 | WREG32(0x6578, 0x20302); | 624 | WREG32(index_reg, 0x20301); |
625 | WREG32(0x657C, 0xBFB082A0); | 625 | WREG32(data_reg, 0x8EE0BEC0); |
626 | WREG32(0x6578, 0x20303); | 626 | WREG32(index_reg, 0x20302); |
627 | WREG32(0x657C, 0x80008000); | 627 | WREG32(data_reg, 0xBFB082A0); |
628 | WREG32(0x6578, 0x20400); | 628 | WREG32(index_reg, 0x20303); |
629 | WREG32(0x657C, 0x80188000); | 629 | WREG32(data_reg, 0x80008000); |
630 | WREG32(0x6578, 0x20401); | 630 | WREG32(index_reg, 0x20400); |
631 | WREG32(0x657C, 0x8E00BEA0); | 631 | WREG32(data_reg, 0x80188000); |
632 | WREG32(0x6578, 0x20402); | 632 | WREG32(index_reg, 0x20401); |
633 | WREG32(0x657C, 0xBF8883C0); | 633 | WREG32(data_reg, 0x8E00BEA0); |
634 | WREG32(0x6578, 0x20403); | 634 | WREG32(index_reg, 0x20402); |
635 | WREG32(0x657C, 0x80008000); | 635 | WREG32(data_reg, 0xBF8883C0); |
636 | WREG32(0x6578, 0x20500); | 636 | WREG32(index_reg, 0x20403); |
637 | WREG32(0x657C, 0x80188000); | 637 | WREG32(data_reg, 0x80008000); |
638 | WREG32(0x6578, 0x20501); | 638 | WREG32(index_reg, 0x20500); |
639 | WREG32(0x657C, 0x8D00BE90); | 639 | WREG32(data_reg, 0x80188000); |
640 | WREG32(0x6578, 0x20502); | 640 | WREG32(index_reg, 0x20501); |
641 | WREG32(0x657C, 0xBF588500); | 641 | WREG32(data_reg, 0x8D00BE90); |
642 | WREG32(0x6578, 0x20503); | 642 | WREG32(index_reg, 0x20502); |
643 | WREG32(0x657C, 0x80008008); | 643 | WREG32(data_reg, 0xBF588500); |
644 | WREG32(0x6578, 0x20600); | 644 | WREG32(index_reg, 0x20503); |
645 | WREG32(0x657C, 0x80188000); | 645 | WREG32(data_reg, 0x80008008); |
646 | WREG32(0x6578, 0x20601); | 646 | WREG32(index_reg, 0x20600); |
647 | WREG32(0x657C, 0x8BC0BE98); | 647 | WREG32(data_reg, 0x80188000); |
648 | WREG32(0x6578, 0x20602); | 648 | WREG32(index_reg, 0x20601); |
649 | WREG32(0x657C, 0xBF308660); | 649 | WREG32(data_reg, 0x8BC0BE98); |
650 | WREG32(0x6578, 0x20603); | 650 | WREG32(index_reg, 0x20602); |
651 | WREG32(0x657C, 0x80008008); | 651 | WREG32(data_reg, 0xBF308660); |
652 | WREG32(0x6578, 0x20700); | 652 | WREG32(index_reg, 0x20603); |
653 | WREG32(0x657C, 0x80108000); | 653 | WREG32(data_reg, 0x80008008); |
654 | WREG32(0x6578, 0x20701); | 654 | WREG32(index_reg, 0x20700); |
655 | WREG32(0x657C, 0x8A80BEB0); | 655 | WREG32(data_reg, 0x80108000); |
656 | WREG32(0x6578, 0x20702); | 656 | WREG32(index_reg, 0x20701); |
657 | WREG32(0x657C, 0xBF0087C0); | 657 | WREG32(data_reg, 0x8A80BEB0); |
658 | WREG32(0x6578, 0x20703); | 658 | WREG32(index_reg, 0x20702); |
659 | WREG32(0x657C, 0x80008008); | 659 | WREG32(data_reg, 0xBF0087C0); |
660 | WREG32(0x6578, 0x20800); | 660 | WREG32(index_reg, 0x20703); |
661 | WREG32(0x657C, 0x80108000); | 661 | WREG32(data_reg, 0x80008008); |
662 | WREG32(0x6578, 0x20801); | 662 | WREG32(index_reg, 0x20800); |
663 | WREG32(0x657C, 0x8920BED0); | 663 | WREG32(data_reg, 0x80108000); |
664 | WREG32(0x6578, 0x20802); | 664 | WREG32(index_reg, 0x20801); |
665 | WREG32(0x657C, 0xBED08920); | 665 | WREG32(data_reg, 0x8920BED0); |
666 | WREG32(0x6578, 0x20803); | 666 | WREG32(index_reg, 0x20802); |
667 | WREG32(0x657C, 0x80008010); | 667 | WREG32(data_reg, 0xBED08920); |
668 | WREG32(0x6578, 0x30000); | 668 | WREG32(index_reg, 0x20803); |
669 | WREG32(0x657C, 0x90008000); | 669 | WREG32(data_reg, 0x80008010); |
670 | WREG32(0x6578, 0x30001); | 670 | WREG32(index_reg, 0x30000); |
671 | WREG32(0x657C, 0x80008000); | 671 | WREG32(data_reg, 0x90008000); |
672 | WREG32(0x6578, 0x30100); | 672 | WREG32(index_reg, 0x30001); |
673 | WREG32(0x657C, 0x8FE0BF90); | 673 | WREG32(data_reg, 0x80008000); |
674 | WREG32(0x6578, 0x30101); | 674 | WREG32(index_reg, 0x30100); |
675 | WREG32(0x657C, 0xBFF880A0); | 675 | WREG32(data_reg, 0x8FE0BF90); |
676 | WREG32(0x6578, 0x30200); | 676 | WREG32(index_reg, 0x30101); |
677 | WREG32(0x657C, 0x8F60BF40); | 677 | WREG32(data_reg, 0xBFF880A0); |
678 | WREG32(0x6578, 0x30201); | 678 | WREG32(index_reg, 0x30200); |
679 | WREG32(0x657C, 0xBFE88180); | 679 | WREG32(data_reg, 0x8F60BF40); |
680 | WREG32(0x6578, 0x30300); | 680 | WREG32(index_reg, 0x30201); |
681 | WREG32(0x657C, 0x8EC0BF00); | 681 | WREG32(data_reg, 0xBFE88180); |
682 | WREG32(0x6578, 0x30301); | 682 | WREG32(index_reg, 0x30300); |
683 | WREG32(0x657C, 0xBFC88280); | 683 | WREG32(data_reg, 0x8EC0BF00); |
684 | WREG32(0x6578, 0x30400); | 684 | WREG32(index_reg, 0x30301); |
685 | WREG32(0x657C, 0x8DE0BEE0); | 685 | WREG32(data_reg, 0xBFC88280); |
686 | WREG32(0x6578, 0x30401); | 686 | WREG32(index_reg, 0x30400); |
687 | WREG32(0x657C, 0xBFA083A0); | 687 | WREG32(data_reg, 0x8DE0BEE0); |
688 | WREG32(0x6578, 0x30500); | 688 | WREG32(index_reg, 0x30401); |
689 | WREG32(0x657C, 0x8CE0BED0); | 689 | WREG32(data_reg, 0xBFA083A0); |
690 | WREG32(0x6578, 0x30501); | 690 | WREG32(index_reg, 0x30500); |
691 | WREG32(0x657C, 0xBF7884E0); | 691 | WREG32(data_reg, 0x8CE0BED0); |
692 | WREG32(0x6578, 0x30600); | 692 | WREG32(index_reg, 0x30501); |
693 | WREG32(0x657C, 0x8BA0BED8); | 693 | WREG32(data_reg, 0xBF7884E0); |
694 | WREG32(0x6578, 0x30601); | 694 | WREG32(index_reg, 0x30600); |
695 | WREG32(0x657C, 0xBF508640); | 695 | WREG32(data_reg, 0x8BA0BED8); |
696 | WREG32(0x6578, 0x30700); | 696 | WREG32(index_reg, 0x30601); |
697 | WREG32(0x657C, 0x8A60BEE8); | 697 | WREG32(data_reg, 0xBF508640); |
698 | WREG32(0x6578, 0x30701); | 698 | WREG32(index_reg, 0x30700); |
699 | WREG32(0x657C, 0xBF2087A0); | 699 | WREG32(data_reg, 0x8A60BEE8); |
700 | WREG32(0x6578, 0x30800); | 700 | WREG32(index_reg, 0x30701); |
701 | WREG32(0x657C, 0x8900BF00); | 701 | WREG32(data_reg, 0xBF2087A0); |
702 | WREG32(0x6578, 0x30801); | 702 | WREG32(index_reg, 0x30800); |
703 | WREG32(0x657C, 0xBF008900); | 703 | WREG32(data_reg, 0x8900BF00); |
704 | WREG32(index_reg, 0x30801); | ||
705 | WREG32(data_reg, 0xBF008900); | ||
704 | } | 706 | } |
705 | 707 | ||
706 | struct rv515_watermark { | 708 | struct rv515_watermark { |