提交 6d9cdfc2 编写于 作者: A Alex Deucher

drm/radeon: add load detection support for ext DAC on R200 (v2)

The R200 asics use an external DAC for the secondary DAC.
The current KMS code tries to use code for the integrated
TV DAC for R200 which leads to unpredictable results since
R200 does not have an integrated TV DAC. This patch ports
the external DAC load detection support from the UMS
driver to KMS.

v2: fix typo in loop break logic
Signed-off-by: NAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: NEgbert Eich <eich@suse.de>
上级 f8c4d701
......@@ -1422,6 +1422,96 @@ 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)
{
......@@ -1466,6 +1556,13 @@ 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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册