|
@@ -537,7 +537,9 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
|
|
|
+ /* handled in radeon_crtc_dpms() */
|
|
|
+ if (!(rdev->flags & RADEON_SINGLE_CRTC))
|
|
|
+ WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
|
|
|
WREG32(RADEON_DAC_CNTL, dac_cntl);
|
|
|
WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
|
|
|
|
|
@@ -662,6 +664,8 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc
|
|
|
|
|
|
if (ASIC_IS_R300(rdev))
|
|
|
tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
|
|
|
+ else if (ASIC_IS_RV100(rdev))
|
|
|
+ tmp |= (0x1ac << RADEON_DAC_FORCE_DATA_SHIFT);
|
|
|
else
|
|
|
tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
|
|
|
|
|
@@ -671,6 +675,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc
|
|
|
tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;
|
|
|
WREG32(RADEON_DAC_CNTL, tmp);
|
|
|
|
|
|
+ tmp = dac_macro_cntl;
|
|
|
tmp &= ~(RADEON_DAC_PDWN_R |
|
|
|
RADEON_DAC_PDWN_G |
|
|
|
RADEON_DAC_PDWN_B);
|
|
@@ -1092,7 +1097,8 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
|
|
|
} else {
|
|
|
if (is_tv)
|
|
|
WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl);
|
|
|
- else
|
|
|
+ /* handled in radeon_crtc_dpms() */
|
|
|
+ else if (!(rdev->flags & RADEON_SINGLE_CRTC))
|
|
|
WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
|
|
|
WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
|
|
|
}
|
|
@@ -1416,13 +1422,104 @@ static bool radeon_legacy_tv_detect(struct drm_encoder *encoder,
|
|
|
return found;
|
|
|
}
|
|
|
|
|
|
+static bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder,
|
|
|
+ struct drm_connector *connector)
|
|
|
+{
|
|
|
+ struct drm_device *dev = encoder->dev;
|
|
|
+ struct radeon_device *rdev = dev->dev_private;
|
|
|
+ uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl;
|
|
|
+ uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c;
|
|
|
+ uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f;
|
|
|
+ uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp;
|
|
|
+ uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid;
|
|
|
+ bool found = false;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ /* save the regs we need */
|
|
|
+ gpio_monid = RREG32(RADEON_GPIO_MONID);
|
|
|
+ fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
|
|
|
+ disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
|
|
|
+ crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
|
|
|
+ disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A);
|
|
|
+ disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B);
|
|
|
+ disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C);
|
|
|
+ disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D);
|
|
|
+ disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E);
|
|
|
+ disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F);
|
|
|
+ crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP);
|
|
|
+ crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP);
|
|
|
+ crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID);
|
|
|
+ crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID);
|
|
|
+
|
|
|
+ tmp = RREG32(RADEON_GPIO_MONID);
|
|
|
+ tmp &= ~RADEON_GPIO_A_0;
|
|
|
+ WREG32(RADEON_GPIO_MONID, tmp);
|
|
|
+
|
|
|
+ WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON |
|
|
|
+ RADEON_FP2_PANEL_FORMAT |
|
|
|
+ R200_FP2_SOURCE_SEL_TRANS_UNIT |
|
|
|
+ RADEON_FP2_DVO_EN |
|
|
|
+ R200_FP2_DVO_RATE_SEL_SDR));
|
|
|
+
|
|
|
+ WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX |
|
|
|
+ RADEON_DISP_TRANS_MATRIX_GRAPHICS));
|
|
|
+
|
|
|
+ WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN |
|
|
|
+ RADEON_CRTC2_DISP_REQ_EN_B));
|
|
|
+
|
|
|
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
|
|
|
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
|
|
|
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
|
|
|
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
|
|
|
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
|
|
|
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
|
|
|
+
|
|
|
+ WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
|
|
|
+ WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
|
|
|
+ WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
|
|
|
+ WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
|
|
|
+
|
|
|
+ for (i = 0; i < 200; i++) {
|
|
|
+ tmp = RREG32(RADEON_GPIO_MONID);
|
|
|
+ if (tmp & RADEON_GPIO_Y_0)
|
|
|
+ found = true;
|
|
|
+
|
|
|
+ if (found)
|
|
|
+ break;
|
|
|
+
|
|
|
+ if (!drm_can_sleep())
|
|
|
+ mdelay(1);
|
|
|
+ else
|
|
|
+ msleep(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* restore the regs we used */
|
|
|
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a);
|
|
|
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b);
|
|
|
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c);
|
|
|
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d);
|
|
|
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e);
|
|
|
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f);
|
|
|
+ WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp);
|
|
|
+ WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp);
|
|
|
+ WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid);
|
|
|
+ WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid);
|
|
|
+ WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
|
|
|
+ WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
|
|
|
+ WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
|
|
|
+ WREG32(RADEON_GPIO_MONID, gpio_monid);
|
|
|
+
|
|
|
+ return found;
|
|
|
+}
|
|
|
+
|
|
|
static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder,
|
|
|
struct drm_connector *connector)
|
|
|
{
|
|
|
struct drm_device *dev = encoder->dev;
|
|
|
struct radeon_device *rdev = dev->dev_private;
|
|
|
- uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
|
|
|
- uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp;
|
|
|
+ uint32_t crtc2_gen_cntl = 0, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
|
|
|
+ uint32_t gpiopad_a = 0, pixclks_cntl, tmp;
|
|
|
+ uint32_t disp_output_cntl = 0, disp_hw_debug = 0, crtc_ext_cntl = 0;
|
|
|
enum drm_connector_status found = connector_status_disconnected;
|
|
|
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
|
|
struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
|
|
@@ -1459,12 +1556,27 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
|
|
|
return connector_status_disconnected;
|
|
|
}
|
|
|
|
|
|
+ /* R200 uses an external DAC for secondary DAC */
|
|
|
+ if (rdev->family == CHIP_R200) {
|
|
|
+ if (radeon_legacy_ext_dac_detect(encoder, connector))
|
|
|
+ found = connector_status_connected;
|
|
|
+ return found;
|
|
|
+ }
|
|
|
+
|
|
|
/* save the regs we need */
|
|
|
pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL);
|
|
|
- gpiopad_a = ASIC_IS_R300(rdev) ? RREG32(RADEON_GPIOPAD_A) : 0;
|
|
|
- disp_output_cntl = ASIC_IS_R300(rdev) ? RREG32(RADEON_DISP_OUTPUT_CNTL) : 0;
|
|
|
- disp_hw_debug = ASIC_IS_R300(rdev) ? 0 : RREG32(RADEON_DISP_HW_DEBUG);
|
|
|
- crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
|
|
|
+
|
|
|
+ if (rdev->flags & RADEON_SINGLE_CRTC) {
|
|
|
+ crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
|
|
|
+ } else {
|
|
|
+ if (ASIC_IS_R300(rdev)) {
|
|
|
+ gpiopad_a = RREG32(RADEON_GPIOPAD_A);
|
|
|
+ disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
|
|
|
+ } else {
|
|
|
+ disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG);
|
|
|
+ }
|
|
|
+ crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
|
|
|
+ }
|
|
|
tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
|
|
|
dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL);
|
|
|
dac_cntl2 = RREG32(RADEON_DAC_CNTL2);
|
|
@@ -1473,22 +1585,24 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
|
|
|
| RADEON_PIX2CLK_DAC_ALWAYS_ONb);
|
|
|
WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
|
|
|
|
|
|
- if (ASIC_IS_R300(rdev))
|
|
|
- WREG32_P(RADEON_GPIOPAD_A, 1, ~1);
|
|
|
-
|
|
|
- tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
|
|
|
- tmp |= RADEON_CRTC2_CRT2_ON |
|
|
|
- (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
|
|
|
-
|
|
|
- WREG32(RADEON_CRTC2_GEN_CNTL, tmp);
|
|
|
-
|
|
|
- if (ASIC_IS_R300(rdev)) {
|
|
|
- tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
|
|
|
- tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
|
|
|
- WREG32(RADEON_DISP_OUTPUT_CNTL, tmp);
|
|
|
+ if (rdev->flags & RADEON_SINGLE_CRTC) {
|
|
|
+ tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON;
|
|
|
+ WREG32(RADEON_CRTC_EXT_CNTL, tmp);
|
|
|
} else {
|
|
|
- tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL;
|
|
|
- WREG32(RADEON_DISP_HW_DEBUG, tmp);
|
|
|
+ tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
|
|
|
+ tmp |= RADEON_CRTC2_CRT2_ON |
|
|
|
+ (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
|
|
|
+ WREG32(RADEON_CRTC2_GEN_CNTL, tmp);
|
|
|
+
|
|
|
+ if (ASIC_IS_R300(rdev)) {
|
|
|
+ WREG32_P(RADEON_GPIOPAD_A, 1, ~1);
|
|
|
+ tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
|
|
|
+ tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
|
|
|
+ WREG32(RADEON_DISP_OUTPUT_CNTL, tmp);
|
|
|
+ } else {
|
|
|
+ tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL;
|
|
|
+ WREG32(RADEON_DISP_HW_DEBUG, tmp);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
tmp = RADEON_TV_DAC_NBLANK |
|
|
@@ -1530,14 +1644,19 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
|
|
|
WREG32(RADEON_DAC_CNTL2, dac_cntl2);
|
|
|
WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
|
|
|
WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
|
|
|
- WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
|
|
|
|
|
|
- if (ASIC_IS_R300(rdev)) {
|
|
|
- WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
|
|
|
- WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1);
|
|
|
+ if (rdev->flags & RADEON_SINGLE_CRTC) {
|
|
|
+ WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
|
|
|
} else {
|
|
|
- WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
|
|
|
+ WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
|
|
|
+ if (ASIC_IS_R300(rdev)) {
|
|
|
+ WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
|
|
|
+ WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1);
|
|
|
+ } else {
|
|
|
+ WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
|
|
|
|
|
|
return found;
|