summaryrefslogtreecommitdiff
path: root/src/atombios_crtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/atombios_crtc.c')
-rw-r--r--src/atombios_crtc.c89
1 files changed, 79 insertions, 10 deletions
diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c
index f7d9c37..8f76e30 100644
--- a/src/atombios_crtc.c
+++ b/src/atombios_crtc.c
@@ -155,12 +155,19 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
{
RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
RADEONInfoPtr info = RADEONPTR(crtc->scrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
unsigned char *RADEONMMIO = info->MMIO;
int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
CARD32 sclock = mode->Clock;
CARD32 ref_div = 0, fb_div = 0, post_div = 0;
- int major, minor;
+ int major, minor, i;
SET_PIXEL_CLOCK_PS_ALLOCATION spc_param;
+ PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr;
+ PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr;
+
+ xf86OutputPtr output;
+ RADEONOutputPrivatePtr radeon_output = NULL;
+
void *ptr;
AtomBiosArgRec data;
unsigned char *space;
@@ -193,6 +200,20 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
"crtc(%d) PLL : refdiv %u, fbdiv 0x%X(%u), pdiv %u\n",
radeon_crtc->crtc_id, (unsigned int)ref_div, (unsigned int)fb_div, (unsigned int)fb_div, (unsigned int)post_div);
+ /* Can't really do cloning easily on DCE3 cards */
+ for (i = 0; i < xf86_config->num_output; i++) {
+ output = xf86_config->output[i];
+ if (output->crtc == crtc) {
+ radeon_output = output->driver_private;
+ break;
+ }
+ }
+
+ if (radeon_output == NULL) {
+ xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "No output assigned to crtc!\n");
+ return;
+ }
+
atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
ErrorF("table is %d %d\n", major, minor);
@@ -200,18 +221,66 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
case 1:
switch(minor) {
case 1:
- case 2: {
- spc_param.sPCLKInput.usPixelClock = sclock;
- spc_param.sPCLKInput.usRefDiv = ref_div;
- spc_param.sPCLKInput.usFbDiv = fb_div;
- spc_param.sPCLKInput.ucPostDiv = post_div;
- spc_param.sPCLKInput.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
- spc_param.sPCLKInput.ucCRTC = radeon_crtc->crtc_id;
- spc_param.sPCLKInput.ucRefDivSrc = 1;
+ case 2:
+ spc2_ptr = &spc_param.sPCLKInput;
+ spc2_ptr->usPixelClock = sclock;
+ spc2_ptr->usRefDiv = ref_div;
+ spc2_ptr->usFbDiv = fb_div;
+ spc2_ptr->ucPostDiv = post_div;
+ spc2_ptr->ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
+ spc2_ptr->ucCRTC = radeon_crtc->crtc_id;
+ spc2_ptr->ucRefDivSrc = 1;
+ ptr = &spc_param;
+ break;
+ case 3:
+ spc3_ptr = &spc_param.sPCLKInput;
+
+ spc3_ptr->usPixelClock = sclock;
+ spc3_ptr->usRefDiv = ref_div;
+ spc3_ptr->usFbDiv = fb_div;
+ spc3_ptr->ucPostDiv = post_div;
+ spc3_ptr->ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
+ spc3_ptr->ucMiscInfo = (radeon_crtc->crtc_id << 2);
+
+ if (radeon_output->MonType == MT_CRT) {
+ if (radeon_output->DACType == DAC_PRIMARY)
+ spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
+ else if (radeon_output->DACType == DAC_TVDAC)
+ spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
+ spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_CRT;
+ } else if (radeon_output->MonType == MT_DFP) {
+ if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
+ spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_UNIPHY;
+ else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
+ spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1;
+ else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
+ spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA;
+ if (OUTPUT_IS_DVI)
+ spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_DVI;
+ else if (radeon_output->type == OUTPUT_HDMI)
+ spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_HDMI;
+ else if (radeon_output->type == OUTPUT_DP)
+ spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_DP;
+ } else if (radeon_output->MonType == MT_LCD) {
+ if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
+ spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA;
+ spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_LVDS;
+ } else if (OUTPUT_IS_TV) {
+ if (radeon_output->DACType == DAC_PRIMARY)
+ spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
+ else if (radeon_output->DACType == DAC_TVDAC)
+ spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
+ spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_TV;
+ } else if (radeon_output->MonType == MT_CV) {
+ if (radeon_output->DACType == DAC_PRIMARY)
+ spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
+ else if (radeon_output->DACType == DAC_TVDAC)
+ spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
+ spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_CV;
+ }
ptr = &spc_param;
break;
- }
default:
ErrorF("Unknown table version\n");
exit(-1);