diff options
Diffstat (limited to 'src/atombios_crtc.c')
-rw-r--r-- | src/atombios_crtc.c | 89 |
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); |