Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Egbert Eich <eich@suse.de>

+97
+97
drivers/gpu/drm/radeon/radeon_legacy_encoders.c
··· 1422 1422 return found; 1423 1423 } 1424 1424 1425 + static bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder, 1426 + struct drm_connector *connector) 1427 + { 1428 + struct drm_device *dev = encoder->dev; 1429 + struct radeon_device *rdev = dev->dev_private; 1430 + uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl; 1431 + uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c; 1432 + uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f; 1433 + uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp; 1434 + uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid; 1435 + bool found = false; 1436 + int i; 1437 + 1438 + /* save the regs we need */ 1439 + gpio_monid = RREG32(RADEON_GPIO_MONID); 1440 + fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); 1441 + disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); 1442 + crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); 1443 + disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A); 1444 + disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B); 1445 + disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C); 1446 + disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D); 1447 + disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E); 1448 + disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F); 1449 + crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP); 1450 + crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP); 1451 + crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID); 1452 + crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID); 1453 + 1454 + tmp = RREG32(RADEON_GPIO_MONID); 1455 + tmp &= ~RADEON_GPIO_A_0; 1456 + WREG32(RADEON_GPIO_MONID, tmp); 1457 + 1458 + WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON | 1459 + RADEON_FP2_PANEL_FORMAT | 1460 + R200_FP2_SOURCE_SEL_TRANS_UNIT | 1461 + RADEON_FP2_DVO_EN | 1462 + R200_FP2_DVO_RATE_SEL_SDR)); 1463 + 1464 + WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX | 1465 + RADEON_DISP_TRANS_MATRIX_GRAPHICS)); 1466 + 1467 + WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN | 1468 + RADEON_CRTC2_DISP_REQ_EN_B)); 1469 + 1470 + WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000); 1471 + WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0); 1472 + WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000); 1473 + WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0); 1474 + WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000); 1475 + WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0); 1476 + 1477 + WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008); 1478 + WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800); 1479 + WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001); 1480 + WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080); 1481 + 1482 + for (i = 0; i < 200; i++) { 1483 + tmp = RREG32(RADEON_GPIO_MONID); 1484 + if (tmp & RADEON_GPIO_Y_0) 1485 + found = true; 1486 + 1487 + if (found) 1488 + break; 1489 + 1490 + if (!drm_can_sleep()) 1491 + mdelay(1); 1492 + else 1493 + msleep(1); 1494 + } 1495 + 1496 + /* restore the regs we used */ 1497 + WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a); 1498 + WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b); 1499 + WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c); 1500 + WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d); 1501 + WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e); 1502 + WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f); 1503 + WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp); 1504 + WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp); 1505 + WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid); 1506 + WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid); 1507 + WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); 1508 + WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); 1509 + WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); 1510 + WREG32(RADEON_GPIO_MONID, gpio_monid); 1511 + 1512 + return found; 1513 + } 1514 + 1425 1515 static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, 1426 1516 struct drm_connector *connector) 1427 1517 { ··· 1554 1464 if (radeon_encoder->active_device && !(radeon_encoder->active_device & ATOM_DEVICE_CRT_SUPPORT)) { 1555 1465 DRM_INFO("not detecting due to %08x\n", radeon_encoder->active_device); 1556 1466 return connector_status_disconnected; 1467 + } 1468 + 1469 + /* R200 uses an external DAC for secondary DAC */ 1470 + if (rdev->family == CHIP_R200) { 1471 + if (radeon_legacy_ext_dac_detect(encoder, connector)) 1472 + found = connector_status_connected; 1473 + return found; 1557 1474 } 1558 1475 1559 1476 /* save the regs we need */