diff options
-rw-r--r-- | src/atombios_crtc.c | 58 | ||||
-rw-r--r-- | src/atombios_output.c | 970 | ||||
-rw-r--r-- | src/legacy_crtc.c | 8 | ||||
-rw-r--r-- | src/legacy_output.c | 885 | ||||
-rw-r--r-- | src/radeon.h | 32 | ||||
-rw-r--r-- | src/radeon_atombios.c | 631 | ||||
-rw-r--r-- | src/radeon_atombios.h | 12 | ||||
-rw-r--r-- | src/radeon_bios.c | 409 | ||||
-rw-r--r-- | src/radeon_modes.c | 164 | ||||
-rw-r--r-- | src/radeon_output.c | 2116 | ||||
-rw-r--r-- | src/radeon_probe.h | 186 | ||||
-rw-r--r-- | src/radeon_tv.c | 163 | ||||
-rw-r--r-- | src/radeon_video.c | 2 |
13 files changed, 3038 insertions, 2598 deletions
diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c index a1270f34..32997407 100644 --- a/src/atombios_crtc.c +++ b/src/atombios_crtc.c @@ -47,6 +47,9 @@ #include "sarea.h" #endif +extern int +atombios_get_encoder_mode(xf86OutputPtr output); + AtomBiosResult atombios_lock_crtc(atomBiosHandlePtr atomBIOS, int crtc, int lock) { @@ -215,6 +218,7 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode, int pll_flags) PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr; xf86OutputPtr output; RADEONOutputPrivatePtr radeon_output = NULL; + radeon_encoder_ptr radeon_encoder = NULL; void *ptr; AtomBiosArgRec data; @@ -261,6 +265,7 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode, int pll_flags) output = xf86_config->output[i]; if (output->crtc == crtc) { radeon_output = output->driver_private; + radeon_encoder = radeon_get_encoder(output); break; } } @@ -270,6 +275,11 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode, int pll_flags) return; } + if (radeon_encoder == NULL) { + xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "No encoder assigned to output!\n"); + return; + } + atombios_get_command_table_version(info->atomBIOS, index, &major, &minor); /*ErrorF("table is %d %d\n", major, minor);*/ @@ -296,41 +306,8 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode, int pll_flags) 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; - } 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->ucTransmitterId = radeon_encoder->encoder_id; + spc3_ptr->ucEncoderMode = atombios_get_encoder_mode(output); ptr = &spc_param; break; @@ -349,11 +326,11 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode, int pll_flags) data.exec.pspace = ptr; if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { - ErrorF("Set CRTC PLL success\n"); + ErrorF("Set CRTC %d PLL success\n", radeon_crtc->crtc_id); return; } - ErrorF("Set CRTC PLL failed\n"); + ErrorF("Set CRTC %d PLL failed\n", radeon_crtc->crtc_id); return; } @@ -384,12 +361,13 @@ atombios_crtc_mode_set(xf86CrtcPtr crtc, for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_tvout_ptr tvout = &radeon_output->tvout; if (output->crtc == crtc) { if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) { - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M) + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M) need_tv_timings = 1; else need_tv_timings = 2; diff --git a/src/atombios_output.c b/src/atombios_output.c index 796aaed9..0827d746 100644 --- a/src/atombios_output.c +++ b/src/atombios_output.c @@ -45,23 +45,59 @@ #include "ati_pciids_gen.h" +const char *device_name[12] = { + "CRT1", + "LCD1", + "TV1", + "DFP1", + "CRT2", + "LCD2", + "TV2", + "DFP2", + "CV", + "DFP3", + "DFP4", + "DFP5", +}; + static int -atombios_output_dac1_setup(xf86OutputPtr output, DisplayModePtr mode) +atombios_output_dac_setup(xf86OutputPtr output, DisplayModePtr mode) { RADEONOutputPrivatePtr radeon_output = output->driver_private; RADEONInfoPtr info = RADEONPTR(output->scrn); + radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); + radeon_tvout_ptr tvout = &radeon_output->tvout; DAC_ENCODER_CONTROL_PS_ALLOCATION disp_data; AtomBiosArgRec data; unsigned char *space; + int index, num = 0; + + if (radeon_encoder == NULL) + return ATOM_NOT_IMPLEMENTED; - disp_data.ucAction = 1; + memset(&disp_data,0, sizeof(disp_data)); + + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_DAC1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: + index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl); + num = 1; + break; + case ENCODER_OBJECT_ID_INTERNAL_DAC2: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: + index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl); + num = 2; + break; + } - if (radeon_output->MonType == MT_CRT) + disp_data.ucAction = ATOM_ENABLE; + + if (radeon_output->active_device & (ATOM_DEVICE_CRT_SUPPORT)) disp_data.ucDacStandard = ATOM_DAC1_PS2; - else if (radeon_output->MonType == MT_CV) + else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) disp_data.ucDacStandard = ATOM_DAC1_CV; - else if (OUTPUT_IS_TV) { - switch (radeon_output->tvStd) { + else { + switch (tvout->tvStd) { case TV_STD_PAL: case TV_STD_PAL_M: case TV_STD_SCART_PAL: @@ -77,87 +113,40 @@ atombios_output_dac1_setup(xf86OutputPtr output, DisplayModePtr mode) break; } } - disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10); - data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl); - data.exec.dataSpace = (void *)&space; - data.exec.pspace = &disp_data; - - if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { - ErrorF("Output DAC1 setup success\n"); - return ATOM_SUCCESS; - } - - ErrorF("Output DAC1 setup failed\n"); - return ATOM_NOT_IMPLEMENTED; - -} - -static int -atombios_output_dac2_setup(xf86OutputPtr output, DisplayModePtr mode) -{ - RADEONOutputPrivatePtr radeon_output = output->driver_private; - RADEONInfoPtr info = RADEONPTR(output->scrn); - DAC_ENCODER_CONTROL_PS_ALLOCATION disp_data; - AtomBiosArgRec data; - unsigned char *space; - - disp_data.ucAction = 1; - - if (radeon_output->MonType == MT_CRT) - disp_data.ucDacStandard = ATOM_DAC2_PS2; - else if (radeon_output->MonType == MT_CV) - disp_data.ucDacStandard = ATOM_DAC2_CV; - else if (OUTPUT_IS_TV) { - switch (radeon_output->tvStd) { - case TV_STD_NTSC: - case TV_STD_NTSC_J: - case TV_STD_PAL_60: - disp_data.ucDacStandard = ATOM_DAC2_NTSC; - break; - case TV_STD_PAL: - case TV_STD_PAL_M: - case TV_STD_SCART_PAL: - case TV_STD_SECAM: - case TV_STD_PAL_CN: - disp_data.ucDacStandard = ATOM_DAC2_PAL; - break; - default: - disp_data.ucDacStandard = ATOM_DAC2_NTSC; - break; - } - } - disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10); - data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl); + data.exec.index = index; data.exec.dataSpace = (void *)&space; data.exec.pspace = &disp_data; if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { - ErrorF("Output DAC2 setup success\n"); + ErrorF("Output DAC%d setup success\n", num); return ATOM_SUCCESS; } - ErrorF("Output DAC2 setup failed\n"); + ErrorF("Output DAC%d setup failed\n", num); return ATOM_NOT_IMPLEMENTED; } static int -atombios_output_tv1_setup(xf86OutputPtr output, DisplayModePtr mode) +atombios_output_tv_setup(xf86OutputPtr output, DisplayModePtr mode) { RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_tvout_ptr tvout = &radeon_output->tvout; RADEONInfoPtr info = RADEONPTR(output->scrn); TV_ENCODER_CONTROL_PS_ALLOCATION disp_data; AtomBiosArgRec data; unsigned char *space; - disp_data.sTVEncoder.ucAction = 1; + memset(&disp_data,0, sizeof(disp_data)); - if (radeon_output->MonType == MT_CV) + disp_data.sTVEncoder.ucAction = ATOM_ENABLE; + + if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) disp_data.sTVEncoder.ucTvStandard = ATOM_TV_CV; else { - switch (radeon_output->tvStd) { + switch (tvout->tvStd) { case TV_STD_NTSC: disp_data.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; break; @@ -194,11 +183,11 @@ atombios_output_tv1_setup(xf86OutputPtr output, DisplayModePtr mode) data.exec.pspace = &disp_data; if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { - ErrorF("Output TV1 setup success\n"); + ErrorF("Output TV setup success\n"); return ATOM_SUCCESS; } - ErrorF("Output TV1 setup failed\n"); + ErrorF("Output TV setup failed\n"); return ATOM_NOT_IMPLEMENTED; } @@ -212,12 +201,12 @@ atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode) AtomBiosArgRec data; unsigned char *space; - disp_data.sXTmdsEncoder.ucEnable = 1; + memset(&disp_data,0, sizeof(disp_data)); + + disp_data.sXTmdsEncoder.ucEnable = ATOM_ENABLE; if (mode->Clock > 165000) - disp_data.sXTmdsEncoder.ucMisc = 1; - else - disp_data.sXTmdsEncoder.ucMisc = 0; + disp_data.sXTmdsEncoder.ucMisc = PANEL_ENCODER_MISC_DUAL; if (pScrn->rgbBits == 8) disp_data.sXTmdsEncoder.ucMisc |= (1 << 1); @@ -243,13 +232,13 @@ atombios_output_ddia_setup(xf86OutputPtr output, DisplayModePtr mode) AtomBiosArgRec data; unsigned char *space; + memset(&disp_data,0, sizeof(disp_data)); + disp_data.sDVOEncoder.ucAction = ATOM_ENABLE; disp_data.sDVOEncoder.usPixelClock = cpu_to_le16(mode->Clock / 10); if (mode->Clock > 165000) disp_data.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = PANEL_ENCODER_MISC_DUAL; - else - disp_data.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = 0; data.exec.index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl); data.exec.dataSpace = (void *)&space; @@ -265,30 +254,47 @@ atombios_output_ddia_setup(xf86OutputPtr output, DisplayModePtr mode) } static int -atombios_output_digital_setup(xf86OutputPtr output, int device, DisplayModePtr mode) +atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode) { RADEONOutputPrivatePtr radeon_output = output->driver_private; ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); + radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); LVDS_ENCODER_CONTROL_PS_ALLOCATION disp_data; LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 disp_data2; AtomBiosArgRec data; unsigned char *space; int index; int major, minor; + int lvds_misc = 0; - switch (device) { - case ATOM_DEVICE_DFP1_INDEX: - index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl); - break; - case ATOM_DEVICE_LCD1_INDEX: + if (radeon_encoder == NULL) + return ATOM_NOT_IMPLEMENTED; + + if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { + radeon_lvds_ptr lvds = (radeon_lvds_ptr)radeon_encoder->dev_priv; + if (lvds == NULL) + return ATOM_NOT_IMPLEMENTED; + lvds_misc = lvds->lvds_misc; + } + + memset(&disp_data,0, sizeof(disp_data)); + memset(&disp_data2,0, sizeof(disp_data2)); + + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_LVDS: index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl); break; - case ATOM_DEVICE_DFP3_INDEX: - index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl); + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: + index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl); break; - default: - return ATOM_NOT_IMPLEMENTED; + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) + index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl); + else + index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl); break; } @@ -303,15 +309,18 @@ atombios_output_digital_setup(xf86OutputPtr output, int device, DisplayModePtr m case 1: disp_data.ucMisc = 0; disp_data.ucAction = PANEL_ENCODER_ACTION_ENABLE; - if (radeon_output->type == OUTPUT_HDMI) + if ((radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_A) || + (radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_B)) disp_data.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10); - if (device == ATOM_DEVICE_LCD1_INDEX) { - if (radeon_output->lvds_misc & (1 << 0)) + if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { + if (lvds_misc & (1 << 0)) disp_data.ucMisc |= PANEL_ENCODER_MISC_DUAL; - if (radeon_output->lvds_misc & (1 << 1)) + if (lvds_misc & (1 << 1)) disp_data.ucMisc |= (1 << 1); } else { + if (radeon_output->linkb) + disp_data.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; if (mode->Clock > 165000) disp_data.ucMisc |= PANEL_ENCODER_MISC_DUAL; if (pScrn->rgbBits == 8) @@ -329,29 +338,32 @@ atombios_output_digital_setup(xf86OutputPtr output, int device, DisplayModePtr m xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "Coherent Mode enabled\n"); } } - if (radeon_output->type == OUTPUT_HDMI) + if ((radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_A) || + (radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_B)) disp_data2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; disp_data2.usPixelClock = cpu_to_le16(mode->Clock / 10); disp_data2.ucTruncate = 0; disp_data2.ucSpatial = 0; disp_data2.ucTemporal = 0; disp_data2.ucFRC = 0; - if (device == ATOM_DEVICE_LCD1_INDEX) { - if (radeon_output->lvds_misc & (1 << 0)) + if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { + if (lvds_misc & (1 << 0)) disp_data2.ucMisc |= PANEL_ENCODER_MISC_DUAL; - if (radeon_output->lvds_misc & (1 << 5)) { + if (lvds_misc & (1 << 5)) { disp_data2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN; - if (radeon_output->lvds_misc & (1 << 1)) + if (lvds_misc & (1 << 1)) disp_data2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH; } - if (radeon_output->lvds_misc & (1 << 6)) { + if (lvds_misc & (1 << 6)) { disp_data2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN; - if (radeon_output->lvds_misc & (1 << 1)) + if (lvds_misc & (1 << 1)) disp_data2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH; - if (((radeon_output->lvds_misc >> 2) & 0x3) == 2) + if (((lvds_misc >> 2) & 0x3) == 2) disp_data2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; } } else { + if (radeon_output->linkb) + disp_data2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; if (mode->Clock > 165000) disp_data2.ucMisc |= PANEL_ENCODER_MISC_DUAL; } @@ -393,22 +405,88 @@ atombios_maybe_hdmi_mode(xf86OutputPtr output) #endif } +int +atombios_get_encoder_mode(xf86OutputPtr output) +{ + RADEONOutputPrivatePtr radeon_output = output->driver_private; + + /* DVI should really be atombios_maybe_hdmi_mode() as well */ + switch (radeon_output->ConnectorType) { + case CONNECTOR_DVI_I: + if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT)) + return ATOM_ENCODER_MODE_DVI; + else + return ATOM_ENCODER_MODE_CRT; + break; + case CONNECTOR_DVI_D: + default: + return ATOM_ENCODER_MODE_DVI; + break; + case CONNECTOR_HDMI_TYPE_A: + case CONNECTOR_HDMI_TYPE_B: + return atombios_maybe_hdmi_mode(output); + break; + case CONNECTOR_LVDS: + return ATOM_ENCODER_MODE_LVDS; + break; + case CONNECTOR_DISPLAY_PORT: + return ATOM_ENCODER_MODE_DP; + break; + case CONNECTOR_DVI_A: + case CONNECTOR_VGA: + case CONNECTOR_STV: + case CONNECTOR_CTV: + case CONNECTOR_DIN: + if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) + return ATOM_ENCODER_MODE_TV; + else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) + return ATOM_ENCODER_MODE_CV; + else + return ATOM_ENCODER_MODE_CRT; + break; + } + +} + static int -atombios_output_dig_encoder_setup(xf86OutputPtr output, int device, DisplayModePtr mode) +atombios_output_dig_encoder_setup(xf86OutputPtr output, DisplayModePtr mode) { RADEONOutputPrivatePtr radeon_output = output->driver_private; RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private; RADEONInfoPtr info = RADEONPTR(output->scrn); + radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); DIG_ENCODER_CONTROL_PS_ALLOCATION disp_data; AtomBiosArgRec data; unsigned char *space; - int index; - int major, minor; + int index, major, minor, num = 0; - if (radeon_crtc->crtc_id) - index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); - else - index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); + if (radeon_encoder == NULL) + return ATOM_NOT_IMPLEMENTED; + + memset(&disp_data,0, sizeof(disp_data)); + + if (IS_DCE32_VARIANT) { + if (radeon_crtc->crtc_id) + index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); + else + index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); + num = radeon_crtc->crtc_id + 1; + } else { + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: + index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); + num = 1; + break; + case ENCODER_OBJECT_ID_INTERNAL_LVDS: + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); + num = 2; + break; + } + } atombios_get_command_table_version(info->atomBIOS, index, &major, &minor); @@ -416,24 +494,29 @@ atombios_output_dig_encoder_setup(xf86OutputPtr output, int device, DisplayModeP disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10); if (IS_DCE32_VARIANT) { - if (radeon_output->TMDSType == TMDS_UNIPHY) + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; - if (radeon_output->TMDSType == TMDS_UNIPHY1) + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; - if (radeon_output->TMDSType == TMDS_UNIPHY2) + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; + break; + } } else { - switch (device) { - case ATOM_DEVICE_DFP1_INDEX: + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: disp_data.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1; break; - case ATOM_DEVICE_LCD1_INDEX: - case ATOM_DEVICE_DFP3_INDEX: + case ENCODER_OBJECT_ID_INTERNAL_LVDS: + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: disp_data.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2; break; - default: - return ATOM_NOT_IMPLEMENTED; - break; } } @@ -441,29 +524,25 @@ atombios_output_dig_encoder_setup(xf86OutputPtr output, int device, DisplayModeP disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B; disp_data.ucLaneNum = 8; } else { - disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; + if (radeon_output->linkb) + disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; + else + disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; disp_data.ucLaneNum = 4; } - if (OUTPUT_IS_DVI) - disp_data.ucEncoderMode = ATOM_ENCODER_MODE_DVI; - else if (radeon_output->type == OUTPUT_HDMI) - disp_data.ucEncoderMode = atombios_maybe_hdmi_mode(output); - else if (radeon_output->type == OUTPUT_DP) - disp_data.ucEncoderMode = ATOM_ENCODER_MODE_DP; - else if (radeon_output->type == OUTPUT_LVDS) - disp_data.ucEncoderMode = ATOM_ENCODER_MODE_LVDS; + disp_data.ucEncoderMode = atombios_get_encoder_mode(output); data.exec.index = index; data.exec.dataSpace = (void *)&space; data.exec.pspace = &disp_data; if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { - ErrorF("Output DIG%d encoder setup success\n", radeon_crtc->crtc_id + 1); + ErrorF("Output DIG%d encoder setup success\n", num); return ATOM_SUCCESS; } - ErrorF("Output DIG%d setup failed\n", radeon_crtc->crtc_id + 1); + ErrorF("Output DIG%d setup failed\n", num); return ATOM_NOT_IMPLEMENTED; } @@ -474,33 +553,36 @@ union dig_transmitter_control { }; static int -atombios_output_dig_transmitter_setup(xf86OutputPtr output, int device, DisplayModePtr mode) +atombios_output_dig_transmitter_setup(xf86OutputPtr output, DisplayModePtr mode) { RADEONOutputPrivatePtr radeon_output = output->driver_private; RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private; RADEONInfoPtr info = RADEONPTR(output->scrn); + radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); union dig_transmitter_control disp_data; AtomBiosArgRec data; unsigned char *space; int index, num = 0; int major, minor; + if (radeon_encoder == NULL) + return ATOM_NOT_IMPLEMENTED; + memset(&disp_data,0, sizeof(disp_data)); + if (IS_DCE32_VARIANT) index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); else { - switch (device) { - case ATOM_DEVICE_DFP1_INDEX: + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl); - num = 1; break; - case ATOM_DEVICE_LCD1_INDEX: - case ATOM_DEVICE_DFP3_INDEX: + case ENCODER_OBJECT_ID_INTERNAL_LVDS: + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl); - num = 2; - break; - default: - return ATOM_NOT_IMPLEMENTED; break; } } @@ -518,26 +600,23 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, int device, DisplayM } if (radeon_crtc->crtc_id) disp_data.v2.acConfig.ucEncoderSel = 1; - - switch (radeon_output->TMDSType) { - case TMDS_UNIPHY: + + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: disp_data.v2.acConfig.ucTransmitterSel = 0; num = 0; break; - case TMDS_UNIPHY1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: disp_data.v2.acConfig.ucTransmitterSel = 1; num = 1; break; - case TMDS_UNIPHY2: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: disp_data.v2.acConfig.ucTransmitterSel = 2; num = 2; break; - default: - return ATOM_NOT_IMPLEMENTED; - break; } - - if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) { + + if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT)) { if (radeon_output->coherent_mode) { disp_data.v2.acConfig.fCoherentMode = 1; xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "UNIPHY%d transmitter: Coherent Mode enabled\n",disp_data.v2.acConfig.ucTransmitterSel); @@ -547,52 +626,74 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, int device, DisplayM } else { disp_data.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; disp_data.v1.usPixelClock = cpu_to_le16((mode->Clock) / 10); - - if (radeon_crtc->crtc_id) - disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; - else + + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; - - if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) { + if (info->IsIGP) { + if (mode->Clock > 165000) { + disp_data.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | + ATOM_TRANSMITTER_CONFIG_LINKA_B); + /* guess */ + if (radeon_output->igp_lane_info & 0x3) + disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; + else if (radeon_output->igp_lane_info & 0xc) + disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; + } else { + disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; + if (radeon_output->igp_lane_info & 0x1) + disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; + else if (radeon_output->igp_lane_info & 0x2) + disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; + else if (radeon_output->igp_lane_info & 0x4) + disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; + else if (radeon_output->igp_lane_info & 0x8) + disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; + } + } else { + if (mode->Clock > 165000) + disp_data.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | + ATOM_TRANSMITTER_CONFIG_LINKA_B | + ATOM_TRANSMITTER_CONFIG_LANE_0_7); + else { + /* XXX */ + if (radeon_output->linkb) + disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3; + else + disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3; + } + } + break; + case ENCODER_OBJECT_ID_INTERNAL_LVDS: + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; + if (mode->Clock > 165000) + disp_data.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | + ATOM_TRANSMITTER_CONFIG_LINKA_B | + ATOM_TRANSMITTER_CONFIG_LANE_0_7); + else { + /* XXX */ + if (radeon_output->linkb) + disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3; + else + disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3; + } + break; + } + + if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT)) { if (radeon_output->coherent_mode) { disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG%d transmitter: Coherent Mode enabled\n", num); } else xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG%d transmitter: Coherent Mode disabled\n", num); } - - if (info->IsIGP && (radeon_output->TMDSType == TMDS_UNIPHY)) { - if (mode->Clock > 165000) { - disp_data.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | - ATOM_TRANSMITTER_CONFIG_LINKA_B); - /* guess */ - if (radeon_output->igp_lane_info & 0x3) - disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; - else if (radeon_output->igp_lane_info & 0xc) - disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; - } else { - disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; - if (radeon_output->igp_lane_info & 0x1) - disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; - else if (radeon_output->igp_lane_info & 0x2) - disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; - else if (radeon_output->igp_lane_info & 0x4) - disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; - else if (radeon_output->igp_lane_info & 0x8) - disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; - } - } else { - if (mode->Clock > 165000) - disp_data.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | - ATOM_TRANSMITTER_CONFIG_LINKA_B | - ATOM_TRANSMITTER_CONFIG_LANE_0_7); - else - disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3; - } } - radeon_output->transmitter_config = disp_data.v1.ucConfig; - + data.exec.index = index; data.exec.dataSpace = (void *)&space; data.exec.pspace = &disp_data; @@ -859,11 +960,10 @@ atombios_output_yuv_setup(xf86OutputPtr output, Bool enable) //fix up scratch reg handling temp = INREG(reg); - if ((radeon_output->MonType == MT_CTV) || - (radeon_output->MonType == MT_STV)) + if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) OUTREG(reg, (ATOM_S3_TV1_ACTIVE | (radeon_crtc->crtc_id << 18))); - else if (radeon_output->MonType == MT_CV) + else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) OUTREG(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24))); else @@ -899,6 +999,7 @@ atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode) { RADEONInfoPtr info = RADEONPTR(output->scrn); RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_tvout_ptr tvout = &radeon_output->tvout; RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private; ENABLE_SCALER_PS_ALLOCATION disp_data; AtomBiosArgRec data; @@ -908,8 +1009,8 @@ atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode) disp_data.ucScaler = radeon_crtc->crtc_id; - if (OUTPUT_IS_TV) { - switch (radeon_output->tvStd) { + if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) { + switch (tvout->tvStd) { case TV_STD_NTSC: disp_data.ucTVStandard = ATOM_TV_NTSC; break; @@ -940,7 +1041,10 @@ atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode) } disp_data.ucEnable = SCALER_ENABLE_MULTITAP_MODE; ErrorF("Using TV scaler %x %x\n", disp_data.ucTVStandard, disp_data.ucEnable); - + } else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) { + disp_data.ucTVStandard = ATOM_TV_CV; + disp_data.ucEnable = SCALER_ENABLE_MULTITAP_MODE; + ErrorF("Using CV scaler %x %x\n", disp_data.ucTVStandard, disp_data.ucEnable); } else if (radeon_output->Flags & RADEON_USE_RMX) { ErrorF("Using RMX\n"); if (radeon_output->rmx_type == RMX_FULL) @@ -957,11 +1061,11 @@ atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode) data.exec.pspace = &disp_data; if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { - if (OUTPUT_IS_TV && info->ChipFamily >= CHIP_FAMILY_RV515 && info->ChipFamily <= CHIP_FAMILY_RV570) { + if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT) + && info->ChipFamily >= CHIP_FAMILY_RV515 && info->ChipFamily <= CHIP_FAMILY_RV570) { ErrorF("forcing TV scaler\n"); atom_rv515_force_tv_scaler(output->scrn); } - ErrorF("scaler %d setup success\n", radeon_crtc->crtc_id); return ATOM_SUCCESS; } @@ -971,92 +1075,21 @@ atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode) } -static AtomBiosResult -atombios_display_device_control(atomBiosHandlePtr atomBIOS, int device, Bool state) -{ - DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION disp_data; - AtomBiosArgRec data; - unsigned char *space; - - disp_data.ucAction = state; - data.exec.index = device; - data.exec.dataSpace = (void *)&space; - data.exec.pspace = &disp_data; - - if (RHDAtomBiosFunc(atomBIOS->scrnIndex, atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { - ErrorF("Output %d %s success\n", device, state? "enable":"disable"); - return ATOM_SUCCESS; - } - - ErrorF("Output %d %s failed\n", device, state? "enable":"disable"); - return ATOM_NOT_IMPLEMENTED; -} - -static void -atombios_device_dpms(xf86OutputPtr output, int device, int mode) -{ - RADEONOutputPrivatePtr radeon_output = output->driver_private; - RADEONInfoPtr info = RADEONPTR(output->scrn); - int index = 0; - - switch (device) { - case ATOM_DEVICE_CRT1_SUPPORT: - case ATOM_DEVICE_CRT2_SUPPORT: - if (radeon_output->DACType == DAC_PRIMARY) - index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); - else if (radeon_output->DACType == DAC_TVDAC) - index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); - break; - case ATOM_DEVICE_DFP1_SUPPORT: - index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl); - break; - case ATOM_DEVICE_DFP2_SUPPORT: - index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); - break; - case ATOM_DEVICE_DFP3_SUPPORT: - index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl); - break; - case ATOM_DEVICE_LCD1_SUPPORT: - index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); - break; - case ATOM_DEVICE_TV1_SUPPORT: - if (IS_DCE3_VARIANT) - index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); - else - index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); - break; - case ATOM_DEVICE_CV_SUPPORT: - if (IS_DCE3_VARIANT) - index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); - else - index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); - break; - default: - return; - } - - switch (mode) { - case DPMSModeOn: - atombios_display_device_control(info->atomBIOS, index, ATOM_ENABLE); - break; - case DPMSModeStandby: - case DPMSModeSuspend: - case DPMSModeOff: - atombios_display_device_control(info->atomBIOS, index, ATOM_DISABLE); - break; - } -} - static int -atombios_output_dig_dpms(xf86OutputPtr output, int mode, int block) +atombios_dig_dpms(xf86OutputPtr output, int mode) { RADEONOutputPrivatePtr radeon_output = output->driver_private; RADEONInfoPtr info = RADEONPTR(output->scrn); + radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); DIG_TRANSMITTER_CONTROL_PS_ALLOCATION disp_data; AtomBiosArgRec data; unsigned char *space; + if (radeon_encoder == NULL) + return ATOM_NOT_IMPLEMENTED; + memset(&disp_data, 0, sizeof(disp_data)); + switch (mode) { case DPMSModeOn: disp_data.ucAction = ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT; @@ -1070,24 +1103,31 @@ atombios_output_dig_dpms(xf86OutputPtr output, int mode, int block) disp_data.ucConfig = radeon_output->transmitter_config; - if (IS_DCE32_VARIANT) { + if (IS_DCE32_VARIANT) data.exec.index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); - } else { - if (block == 1) + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl); - else + break; + case ENCODER_OBJECT_ID_INTERNAL_LVDS: + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl); + break; + } } data.exec.dataSpace = (void *)&space; data.exec.pspace = &disp_data; if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { - ErrorF("Output DIG%d dpms success\n", block); + ErrorF("Output DIG dpms success\n"); return ATOM_SUCCESS; } - ErrorF("Output DIG%d dpms failed\n", block); + ErrorF("Output DIG dpms failed\n"); return ATOM_NOT_IMPLEMENTED; } @@ -1096,58 +1136,106 @@ void atombios_output_dpms(xf86OutputPtr output, int mode) { RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); RADEONInfoPtr info = RADEONPTR(output->scrn); + DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION disp_data; + AtomBiosArgRec data; + unsigned char *space; + int index = 0; + Bool is_dig = FALSE; - /*ErrorF("output dpms %d\n", mode);*/ + if (radeon_encoder == NULL) + return; - if (radeon_output->MonType == MT_LCD) { - if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) { - if (IS_DCE3_VARIANT) - atombios_output_dig_dpms(output, mode, 2); + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: + index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl); + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + is_dig = TRUE; + break; + case ENCODER_OBJECT_ID_INTERNAL_DVO1: + case ENCODER_OBJECT_ID_INTERNAL_DDI: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: + index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); + break; + case ENCODER_OBJECT_ID_INTERNAL_LVDS: + index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); + break; + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) + index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); + else + index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl); + break; + case ENCODER_OBJECT_ID_INTERNAL_DAC1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: + if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) + index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); + else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) + index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); + else + index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); + break; + case ENCODER_OBJECT_ID_INTERNAL_DAC2: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: + if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) + index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); + else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) + index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); + else + index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); + break; + } + + switch (mode) { + case DPMSModeOn: + if (is_dig) + (void)atombios_dig_dpms(output, mode); + else { + disp_data.ucAction = ATOM_ENABLE; + data.exec.index = index; + data.exec.dataSpace = (void *)&space; + data.exec.pspace = &disp_data; + + if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) + ErrorF("Output %s enable success\n", + device_name[radeon_get_device_index(radeon_output->active_device)]); else - atombios_device_dpms(output, ATOM_DEVICE_LCD1_SUPPORT, mode); + ErrorF("Output %s enable failed\n", + device_name[radeon_get_device_index(radeon_output->active_device)]); } - } else if (radeon_output->MonType == MT_DFP) { - /*ErrorF("tmds dpms\n");*/ - if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) { - if (IS_DCE3_VARIANT) - atombios_output_dig_dpms(output, mode, 1); - else - atombios_device_dpms(output, ATOM_DEVICE_DFP1_SUPPORT, mode); - } else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) { - if (IS_DCE32_VARIANT) - atombios_output_dig_dpms(output, mode, 2); - else if (IS_DCE3_VARIANT) - return; // fixme - else - atombios_device_dpms(output, ATOM_DEVICE_DFP2_SUPPORT, mode); - } else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) { - if (IS_DCE3_VARIANT) - atombios_output_dig_dpms(output, mode, 0); - else - atombios_device_dpms(output, ATOM_DEVICE_DFP3_SUPPORT, mode); - } else if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT) { - atombios_output_dig_dpms(output, mode, 1); - } else if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT) { - atombios_output_dig_dpms(output, mode, 2); + radeon_encoder->use_count++; + break; + case DPMSModeStandby: + case DPMSModeSuspend: + case DPMSModeOff: + if (radeon_encoder->use_count < 2) { + if (is_dig) + (void)atombios_dig_dpms(output, mode); + else { + disp_data.ucAction = ATOM_DISABLE; + data.exec.index = index; + data.exec.dataSpace = (void *)&space; + data.exec.pspace = &disp_data; + + if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) + == ATOM_SUCCESS) + ErrorF("Output %s disable success\n", + device_name[radeon_get_device_index(radeon_output->active_device)]); + else + ErrorF("Output %s disable failed\n", + device_name[radeon_get_device_index(radeon_output->active_device)]); + } } - } else if (radeon_output->MonType == MT_CRT) { - /*ErrorF("AGD: dac dpms\n");*/ - if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) - atombios_device_dpms(output, ATOM_DEVICE_CRT1_SUPPORT, mode); - else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) - atombios_device_dpms(output, ATOM_DEVICE_CRT2_SUPPORT, mode); - } else if (radeon_output->MonType == MT_CV) { - /*ErrorF("AGD: cv dpms\n");*/ - if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) - atombios_device_dpms(output, ATOM_DEVICE_CV_SUPPORT, mode); - } else if (radeon_output->MonType == MT_STV || - radeon_output->MonType == MT_CTV) { - /*ErrorF("AGD: tv dpms\n");*/ - if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) - atombios_device_dpms(output, ATOM_DEVICE_TV1_SUPPORT, mode); + if (radeon_encoder->use_count > 0) + radeon_encoder->use_count--; + break; } - } static void @@ -1156,6 +1244,7 @@ atombios_set_output_crtc_source(xf86OutputPtr output) RADEONOutputPrivatePtr radeon_output = output->driver_private; RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private; RADEONInfoPtr info = RADEONPTR(output->scrn); + radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); AtomBiosArgRec data; unsigned char *space; SELECT_CRTC_SOURCE_PS_ALLOCATION crtc_src_param; @@ -1163,6 +1252,9 @@ atombios_set_output_crtc_source(xf86OutputPtr output) int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source); int major, minor; + if (radeon_encoder == NULL) + return; + memset(&crtc_src_param, 0, sizeof(crtc_src_param)); memset(&crtc_src_param2, 0, sizeof(crtc_src_param2)); atombios_get_command_table_version(info->atomBIOS, index, &major, &minor); @@ -1176,80 +1268,64 @@ atombios_set_output_crtc_source(xf86OutputPtr output) case 1: default: crtc_src_param.ucCRTC = radeon_crtc->crtc_id; - crtc_src_param.ucDevice = 0; - if (radeon_output->MonType == MT_CRT) { - if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) - crtc_src_param.ucDevice = ATOM_DEVICE_CRT1_INDEX; - else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) - crtc_src_param.ucDevice = ATOM_DEVICE_CRT2_INDEX; - } else if (radeon_output->MonType == MT_DFP) { - if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) - crtc_src_param.ucDevice = ATOM_DEVICE_DFP1_INDEX; - else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) - crtc_src_param.ucDevice = ATOM_DEVICE_DFP2_INDEX; - else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) - crtc_src_param.ucDevice = ATOM_DEVICE_DFP3_INDEX; - else if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT) - crtc_src_param.ucDevice = ATOM_DEVICE_DFP4_INDEX; - else if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT) - crtc_src_param.ucDevice = ATOM_DEVICE_DFP5_INDEX; - } else if (radeon_output->MonType == MT_LCD) { - if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) - crtc_src_param.ucDevice = ATOM_DEVICE_LCD1_INDEX; - } else if (OUTPUT_IS_TV) { - if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) - crtc_src_param.ucDevice = ATOM_DEVICE_TV1_INDEX; - } else if (radeon_output->MonType == MT_CV) { - if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) - crtc_src_param.ucDevice = ATOM_DEVICE_CV_INDEX; - } + crtc_src_param.ucDevice = radeon_get_device_index(radeon_output->active_device); data.exec.pspace = &crtc_src_param; /*ErrorF("device sourced: 0x%x\n", crtc_src_param.ucDevice);*/ break; case 2: crtc_src_param2.ucCRTC = radeon_crtc->crtc_id; - if (radeon_output->MonType == MT_CRT) { - crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CRT; - if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) - crtc_src_param2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID; - else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) - crtc_src_param2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID; - } else if (radeon_output->MonType == MT_DFP) { - if (IS_DCE3_VARIANT) { - /* we route digital encoders using the CRTC ids */ + crtc_src_param2.ucEncodeMode = atombios_get_encoder_mode(output); + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: + if (IS_DCE3_VARIANT) + crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; + else + crtc_src_param2.ucEncoderID = radeon_get_device_index(radeon_output->active_device); + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + if (IS_DCE32_VARIANT) { if (radeon_crtc->crtc_id) crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; else crtc_src_param2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; - } else { - if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) - crtc_src_param2.ucEncoderID = ATOM_DEVICE_DFP1_INDEX; - else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) - crtc_src_param2.ucEncoderID = ATOM_DEVICE_DFP2_INDEX; - else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) - crtc_src_param2.ucEncoderID = ATOM_DEVICE_DFP3_INDEX; - } - if (OUTPUT_IS_DVI) - crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DVI; - else if (radeon_output->type == OUTPUT_HDMI) - crtc_src_param2.ucEncodeMode = - atombios_maybe_hdmi_mode(output); - else if (radeon_output->type == OUTPUT_DP) - crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DP; - } else if (radeon_output->MonType == MT_LCD) { - if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) - crtc_src_param2.ucEncoderID = ATOM_DEVICE_LCD1_INDEX; - crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS; - } else if (OUTPUT_IS_TV) { - if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) + } else + crtc_src_param2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; + break; + case ENCODER_OBJECT_ID_INTERNAL_DVO1: + case ENCODER_OBJECT_ID_INTERNAL_DDI: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: + crtc_src_param2.ucEncoderID = radeon_get_device_index(radeon_output->active_device); + break; + case ENCODER_OBJECT_ID_INTERNAL_LVDS: + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + if (IS_DCE3_VARIANT) + crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; + else + crtc_src_param2.ucEncoderID = radeon_get_device_index(radeon_output->active_device); + break; + case ENCODER_OBJECT_ID_INTERNAL_DAC1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: + if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) + crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; + else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; - crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_TV; - } else if (radeon_output->MonType == MT_CV) { - if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) + else + crtc_src_param2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID; + break; + case ENCODER_OBJECT_ID_INTERNAL_DAC2: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: + if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) + crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; + else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; - crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CV; + else + crtc_src_param2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID; + break; } - data.exec.pspace = &crtc_src_param2; /*ErrorF("device sourced: 0x%x\n", crtc_src_param2.ucEncoderID);*/ break; @@ -1273,9 +1349,10 @@ atombios_set_output_crtc_source(xf86OutputPtr output) } static void -atombios_apply_output_quirks(xf86OutputPtr output) +atombios_apply_output_quirks(xf86OutputPtr output, DisplayModePtr mode) { RADEONOutputPrivatePtr radeon_output = output->driver_private; + RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private; RADEONInfoPtr info = RADEONPTR(output->scrn); unsigned char *RADEONMMIO = info->MMIO; @@ -1294,6 +1371,10 @@ atombios_apply_output_quirks(xf86OutputPtr output) } } } + + /* set scaler clears this on some chips */ + if (mode->Flags & V_INTERLACE) + OUTREG(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, AVIVO_D1MODE_INTERLEAVE_EN); } void @@ -1302,75 +1383,49 @@ atombios_output_mode_set(xf86OutputPtr output, DisplayModePtr adjusted_mode) { RADEONOutputPrivatePtr radeon_output = output->driver_private; - RADEONInfoPtr info = RADEONPTR(output->scrn); + radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); + + if (radeon_encoder == NULL) + return; atombios_output_scaler_setup(output, mode); atombios_set_output_crtc_source(output); - if ((radeon_output->MonType == MT_CTV) || - (radeon_output->MonType == MT_STV) || - (radeon_output->MonType == MT_CV)) + if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) atombios_output_yuv_setup(output, TRUE); else atombios_output_yuv_setup(output, FALSE); - if (radeon_output->MonType == MT_CRT) { - if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT || - radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) { - if (radeon_output->DACType == DAC_PRIMARY) - atombios_output_dac1_setup(output, adjusted_mode); - else if (radeon_output->DACType == DAC_TVDAC) - atombios_output_dac2_setup(output, adjusted_mode); - } - } else if (radeon_output->MonType == MT_DFP) { - if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) { - if (IS_DCE3_VARIANT) { - atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP1_INDEX, adjusted_mode); - atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP1_INDEX, adjusted_mode); - } else - atombios_output_digital_setup(output, ATOM_DEVICE_DFP1_INDEX, adjusted_mode); - } else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) { - if (IS_DCE32_VARIANT) { - atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP2_INDEX, adjusted_mode); - atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP2_INDEX, adjusted_mode); - } else { - if ((info->ChipFamily == CHIP_FAMILY_RS600) || - (info->ChipFamily == CHIP_FAMILY_RS690) || - (info->ChipFamily == CHIP_FAMILY_RS740)) - atombios_output_ddia_setup(output, adjusted_mode); - else - atombios_external_tmds_setup(output, adjusted_mode); - } - } else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) { - if (IS_DCE3_VARIANT) { - atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP3_INDEX, adjusted_mode); - atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP3_INDEX, adjusted_mode); - } else - atombios_output_digital_setup(output, ATOM_DEVICE_DFP3_INDEX, adjusted_mode); - } else if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT) { - atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP4_INDEX, adjusted_mode); - atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP4_INDEX, adjusted_mode); - } else if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT) { - atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP5_INDEX, adjusted_mode); - atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP5_INDEX, adjusted_mode); - } - } else if (radeon_output->MonType == MT_LCD) { - if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) { - if (IS_DCE3_VARIANT) { - atombios_output_dig_encoder_setup(output, ATOM_DEVICE_LCD1_INDEX, adjusted_mode); - atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_LCD1_INDEX, adjusted_mode); - } else - atombios_output_digital_setup(output, ATOM_DEVICE_LCD1_INDEX, adjusted_mode); - } - } else if ((radeon_output->MonType == MT_CTV) || - (radeon_output->MonType == MT_STV) || - (radeon_output->MonType == MT_CV)) { - if (radeon_output->DACType == DAC_PRIMARY) - atombios_output_dac1_setup(output, adjusted_mode); - else if (radeon_output->DACType == DAC_TVDAC) - atombios_output_dac2_setup(output, adjusted_mode); - atombios_output_tv1_setup(output, adjusted_mode); + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_LVDS: + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + atombios_output_digital_setup(output, adjusted_mode); + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + atombios_output_dig_encoder_setup(output, adjusted_mode); + atombios_output_dig_transmitter_setup(output, adjusted_mode); + break; + case ENCODER_OBJECT_ID_INTERNAL_DDI: + atombios_output_ddia_setup(output, adjusted_mode); + break; + case ENCODER_OBJECT_ID_INTERNAL_DVO1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: + atombios_external_tmds_setup(output, adjusted_mode); + break; + case ENCODER_OBJECT_ID_INTERNAL_DAC1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: + case ENCODER_OBJECT_ID_INTERNAL_DAC2: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: + atombios_output_dac_setup(output, adjusted_mode); + if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) + atombios_output_tv_setup(output, adjusted_mode); + break; } - atombios_apply_output_quirks(output); + atombios_apply_output_quirks(output, adjusted_mode); } static AtomBiosResult @@ -1381,44 +1436,50 @@ atom_bios_dac_load_detect(atomBiosHandlePtr atomBIOS, xf86OutputPtr output) DAC_LOAD_DETECTION_PS_ALLOCATION dac_data; AtomBiosArgRec data; unsigned char *space; + int major, minor; + int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection); + + atombios_get_command_table_version(info->atomBIOS, index, &major, &minor); dac_data.sDacload.ucMisc = 0; if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) { dac_data.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT); - if (radeon_output->DACType == DAC_PRIMARY) + if (info->encoders[ATOM_DEVICE_CRT1_INDEX] && + (info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1)) dac_data.sDacload.ucDacType = ATOM_DAC_A; - else if (radeon_output->DACType == DAC_TVDAC) + else dac_data.sDacload.ucDacType = ATOM_DAC_B; } else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) { dac_data.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT); - if (radeon_output->DACType == DAC_PRIMARY) + if (info->encoders[ATOM_DEVICE_CRT2_INDEX] && + (info->encoders[ATOM_DEVICE_CRT2_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1)) dac_data.sDacload.ucDacType = ATOM_DAC_A; - else if (radeon_output->DACType == DAC_TVDAC) + else dac_data.sDacload.ucDacType = ATOM_DAC_B; } else if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) { dac_data.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT); - if (radeon_output->DACType == DAC_PRIMARY) + if (info->encoders[ATOM_DEVICE_CV_INDEX] && + (info->encoders[ATOM_DEVICE_CV_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1)) dac_data.sDacload.ucDacType = ATOM_DAC_A; - else if (radeon_output->DACType == DAC_TVDAC) + else dac_data.sDacload.ucDacType = ATOM_DAC_B; - if (IS_DCE3_VARIANT) - dac_data.sDacload.ucMisc = 1; + if (minor >= 3) + dac_data.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; } else if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) { dac_data.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT); - if (radeon_output->DACType == DAC_PRIMARY) + if (info->encoders[ATOM_DEVICE_TV1_INDEX] && + (info->encoders[ATOM_DEVICE_TV1_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1)) dac_data.sDacload.ucDacType = ATOM_DAC_A; - else if (radeon_output->DACType == DAC_TVDAC) + else dac_data.sDacload.ucDacType = ATOM_DAC_B; - if (IS_DCE3_VARIANT) - dac_data.sDacload.ucMisc = 1; } else { ErrorF("invalid output device for dac detection\n"); return ATOM_NOT_IMPLEMENTED; } - data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection); + data.exec.index = index; data.exec.dataSpace = (void *)&space; data.exec.pspace = &dac_data; @@ -1433,8 +1494,9 @@ atom_bios_dac_load_detect(atomBiosHandlePtr atomBIOS, xf86OutputPtr output) } RADEONMonitorType -atombios_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output) +atombios_dac_detect(xf86OutputPtr output) { + ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; RADEONOutputPrivatePtr radeon_output = output->driver_private; @@ -1442,9 +1504,9 @@ atombios_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output) AtomBiosResult ret; uint32_t bios_0_scratch; - if (OUTPUT_IS_TV) { + if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) { if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_TVOUT, FALSE)) { - if (radeon_output->type == OUTPUT_STV) + if (radeon_output->ConnectorType == CONNECTOR_STV) return MT_STV; else return MT_CTV; diff --git a/src/legacy_crtc.c b/src/legacy_crtc.c index 78ac5b39..cba1b5f3 100644 --- a/src/legacy_crtc.c +++ b/src/legacy_crtc.c @@ -45,6 +45,7 @@ #include "radeon_macros.h" #include "radeon_probe.h" #include "radeon_version.h" +#include "radeon_atombios.h" #ifdef XF86DRI #define _XF86DRI_SERVER_ @@ -1742,9 +1743,10 @@ legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, RADEONOutputPrivatePtr radeon_output = output->driver_private; if (output->crtc == crtc) { - if (radeon_output->MonType != MT_CRT) + if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT | + ATOM_DEVICE_DFP_SUPPORT)) pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; - if (radeon_output->MonType == MT_LCD) + if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) pll_flags |= (RADEON_PLL_USE_BIOS_DIVS | RADEON_PLL_USE_REF_DIV); } } @@ -1789,7 +1791,7 @@ legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, RADEONOutputPrivatePtr radeon_output = output->driver_private; if (output->crtc == crtc) { - if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) { + if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) { switch (radeon_crtc->crtc_id) { case 0: RADEONAdjustCrtcRegistersForTV(pScrn, info->ModeReg, adjusted_mode, output); diff --git a/src/legacy_output.c b/src/legacy_output.c index f9b0dffb..82291e57 100644 --- a/src/legacy_output.c +++ b/src/legacy_output.c @@ -55,6 +55,194 @@ static RADEONMonitorType radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color); static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn); +extern Bool +RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, char *name, RADEONI2CBusPtr pRADEONI2CBus); + +static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] = +{ + {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_UNKNOW*/ + {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_LEGACY*/ + {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RADEON*/ + {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV100*/ + {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS100*/ + {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV200*/ + {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS200*/ + {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R200*/ + {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV250*/ + {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS300*/ + {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, /*CHIP_FAMILY_RV280*/ + {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R300*/ + {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R350*/ + {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV350*/ + {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV380*/ + {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R420*/ + {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV410*/ /* FIXME: just values from r420 used... */ + {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS400*/ /* FIXME: just values from rv380 used... */ + {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS480*/ /* FIXME: just values from rv380 used... */ +}; + +static const uint32_t default_tvdac_adj [CHIP_FAMILY_LAST] = +{ + 0x00000000, /* unknown */ + 0x00000000, /* legacy */ + 0x00000000, /* r100 */ + 0x00280000, /* rv100 */ + 0x00000000, /* rs100 */ + 0x00880000, /* rv200 */ + 0x00000000, /* rs200 */ + 0x00000000, /* r200 */ + 0x00770000, /* rv250 */ + 0x00290000, /* rs300 */ + 0x00560000, /* rv280 */ + 0x00780000, /* r300 */ + 0x00770000, /* r350 */ + 0x00780000, /* rv350 */ + 0x00780000, /* rv380 */ + 0x01080000, /* r420 */ + 0x01080000, /* rv410 */ /* FIXME: just values from r420 used... */ + 0x00780000, /* rs400 */ /* FIXME: just values from rv380 used... */ + 0x00780000, /* rs480 */ /* FIXME: just values from rv380 used... */ +}; + +void +RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn, radeon_tvdac_ptr tvdac) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (!RADEONGetDAC2InfoFromBIOS(pScrn, tvdac)) { + tvdac->ps2_tvdac_adj = default_tvdac_adj[info->ChipFamily]; + if (info->IsMobility) { /* some mobility chips may different */ + if (info->ChipFamily == CHIP_FAMILY_RV250) + tvdac->ps2_tvdac_adj = 0x00880000; + } + tvdac->pal_tvdac_adj = tvdac->ps2_tvdac_adj; + tvdac->ntsc_tvdac_adj = tvdac->ps2_tvdac_adj; + } +} + +void +RADEONGetTMDSInfoFromTable(ScrnInfoPtr pScrn, radeon_tmds_ptr tmds) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + int i; + + for (i = 0; i < 4; i++) { + tmds->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value; + tmds->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq; + } +} + +void +RADEONGetTMDSInfo(ScrnInfoPtr pScrn, radeon_tmds_ptr tmds) +{ + int i; + + for (i = 0; i < 4; i++) { + tmds->tmds_pll[i].value = 0; + tmds->tmds_pll[i].freq = 0; + } + + if (!RADEONGetTMDSInfoFromBIOS(pScrn, tmds)) + RADEONGetTMDSInfoFromTable(pScrn, tmds); +} + +void +RADEONGetExtTMDSInfo(ScrnInfoPtr pScrn, radeon_dvo_ptr dvo) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + I2CBusPtr pDVOBus; + + if (!info->IsAtomBios) { +#if defined(__powerpc__) + dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); + dvo->dvo_i2c_slave_addr = 0x70; +#else + if (!RADEONGetExtTMDSInfoFromBIOS(pScrn, dvo)) { + dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); + dvo->dvo_i2c_slave_addr = 0x70; + } +#endif + if (RADEONI2CInit(pScrn, &pDVOBus, "DVO", &dvo->dvo_i2c)) { + dvo->DVOChip = + RADEONDVODeviceInit(pDVOBus, dvo->dvo_i2c_slave_addr); + if (!dvo->DVOChip) + xfree(pDVOBus); + } + } +} + +static void +RADEONGetPanelInfoFromReg (ScrnInfoPtr pScrn, radeon_lvds_ptr lvds) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + radeon_native_mode_ptr native_mode = &lvds->native_mode; + uint32_t fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH); + uint32_t fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH); + + lvds->PanelPwrDly = 200; + if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) { + native_mode->PanelYRes = ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >> + RADEON_VERT_PANEL_SHIFT) + 1; + } else { + native_mode->PanelYRes = (INREG(RADEON_CRTC_V_TOTAL_DISP)>>16) + 1; + } + if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) { + native_mode->PanelXRes = (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >> + RADEON_HORZ_PANEL_SHIFT) + 1) * 8; + } else { + native_mode->PanelXRes = ((INREG(RADEON_CRTC_H_TOTAL_DISP)>>16) + 1) * 8; + } + + if ((native_mode->PanelXRes < 640) || (native_mode->PanelYRes < 480)) { + native_mode->PanelXRes = 640; + native_mode->PanelYRes = 480; + } + + // move this to crtc function + if (xf86ReturnOptValBool(info->Options, OPTION_LVDS_PROBE_PLL, TRUE)) { + uint32_t ppll_div_sel, ppll_val; + + ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3; + RADEONPllErrataAfterIndex(info); + ppll_val = INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel); + if ((ppll_val & 0x000707ff) == 0x1bb) + goto noprobe; + info->FeedbackDivider = ppll_val & 0x7ff; + info->PostDivider = (ppll_val >> 16) & 0x7; + info->RefDivider = info->pll.reference_div; + info->UseBiosDividers = TRUE; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Existing panel PLL dividers will be used.\n"); + } + noprobe: + + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Panel size %dx%d is derived, this may not be correct.\n" + "If not, use PanelSize option to overwrite this setting\n", + native_mode->PanelXRes, native_mode->PanelYRes); +} + +void +RADEONGetLVDSInfo (ScrnInfoPtr pScrn, radeon_lvds_ptr lvds) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + radeon_native_mode_ptr native_mode = &lvds->native_mode; + char* s; + + if (!RADEONGetLVDSInfoFromBIOS(pScrn, lvds)) + RADEONGetPanelInfoFromReg(pScrn, lvds); + + if ((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) { + lvds->PanelPwrDly = 200; + if (sscanf (s, "%dx%d", &native_mode->PanelXRes, &native_mode->PanelYRes) != 2) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid PanelSize option: %s\n", s); + RADEONGetPanelInfoFromReg(pScrn, lvds); + } + } +} + void RADEONRestoreDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) @@ -279,34 +467,43 @@ static void RADEONRestoreDVOChip(ScrnInfoPtr pScrn, xf86OutputPtr output) { RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); + radeon_dvo_ptr dvo = NULL; - if (!radeon_output->DVOChip) + if (radeon_encoder == NULL) + return; + + dvo = (radeon_dvo_ptr)radeon_encoder->dev_priv; + + if (dvo == NULL) + return; + + if (!dvo->DVOChip) return; RADEONI2CDoLock(output, TRUE); if (!RADEONInitExtTMDSInfoFromBIOS(output)) { - if (radeon_output->DVOChip) { + if (dvo->DVOChip) { switch(info->ext_tmds_chip) { case RADEON_SIL_164: - RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x30); - RADEONDVOWriteByte(radeon_output->DVOChip, 0x09, 0x00); - RADEONDVOWriteByte(radeon_output->DVOChip, 0x0a, 0x90); - RADEONDVOWriteByte(radeon_output->DVOChip, 0x0c, 0x89); - RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x3b); + RADEONDVOWriteByte(dvo->DVOChip, 0x08, 0x30); + RADEONDVOWriteByte(dvo->DVOChip, 0x09, 0x00); + RADEONDVOWriteByte(dvo->DVOChip, 0x0a, 0x90); + RADEONDVOWriteByte(dvo->DVOChip, 0x0c, 0x89); + RADEONDVOWriteByte(dvo->DVOChip, 0x08, 0x3b); break; #if 0 /* needs work see bug 10418 */ case RADEON_SIL_1178: - RADEONDVOWriteByte(radeon_output->DVOChip, 0x0f, 0x44); - RADEONDVOWriteByte(radeon_output->DVOChip, 0x0f, 0x4c); - RADEONDVOWriteByte(radeon_output->DVOChip, 0x0e, 0x01); - RADEONDVOWriteByte(radeon_output->DVOChip, 0x0a, 0x80); - RADEONDVOWriteByte(radeon_output->DVOChip, 0x09, 0x30); - RADEONDVOWriteByte(radeon_output->DVOChip, 0x0c, 0xc9); - RADEONDVOWriteByte(radeon_output->DVOChip, 0x0d, 0x70); - RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x32); - RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x33); + RADEONDVOWriteByte(dvo->DVOChip, 0x0f, 0x44); + RADEONDVOWriteByte(dvo->DVOChip, 0x0f, 0x4c); + RADEONDVOWriteByte(dvo->DVOChip, 0x0e, 0x01); + RADEONDVOWriteByte(dvo->DVOChip, 0x0a, 0x80); + RADEONDVOWriteByte(dvo->DVOChip, 0x09, 0x30); + RADEONDVOWriteByte(dvo->DVOChip, 0x0c, 0xc9); + RADEONDVOWriteByte(dvo->DVOChip, 0x0d, 0x70); + RADEONDVOWriteByte(dvo->DVOChip, 0x08, 0x32); + RADEONDVOWriteByte(dvo->DVOChip, 0x08, 0x33); break; #endif default: @@ -565,38 +762,48 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac) #endif RADEONMonitorType -legacy_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output) +legacy_dac_detect(xf86OutputPtr output) { + ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONOutputPrivatePtr radeon_output = output->driver_private; RADEONMonitorType found = MT_NONE; - if (OUTPUT_IS_TV) { + if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT)) { if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_TVOUT, FALSE)) { - if (radeon_output->type == OUTPUT_STV) + if (radeon_output->ConnectorType == CONNECTOR_STV) found = MT_STV; else found = MT_CTV; } else { - if (info->InternalTVOut) { - if (radeon_output->load_detection) - found = radeon_detect_tv(pScrn); + if (radeon_output->load_detection) + found = radeon_detect_tv(pScrn); + } + } else if (radeon_output->devices & (ATOM_DEVICE_CRT2_SUPPORT)) { + if (info->encoders[ATOM_DEVICE_CRT2_INDEX] && + (info->encoders[ATOM_DEVICE_CRT2_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1)) { + if (radeon_output->load_detection) + found = radeon_detect_primary_dac(pScrn, TRUE); + } else { + if (radeon_output->load_detection) { + if (info->ChipFamily == CHIP_FAMILY_R200) + found = radeon_detect_ext_dac(pScrn); else - found = MT_NONE; + found = radeon_detect_tv_dac(pScrn, TRUE); } } - } else { - if (radeon_output->DACType == DAC_PRIMARY) { + } else if (radeon_output->devices & (ATOM_DEVICE_CRT1_SUPPORT)) { + if (info->encoders[ATOM_DEVICE_CRT1_INDEX] && + (info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1)) { if (radeon_output->load_detection) found = radeon_detect_primary_dac(pScrn, TRUE); - } else if (radeon_output->DACType == DAC_TVDAC) { + } else { if (radeon_output->load_detection) { if (info->ChipFamily == CHIP_FAMILY_R200) found = radeon_detect_ext_dac(pScrn); else found = radeon_detect_tv_dac(pScrn, TRUE); - } else - found = MT_NONE; + } } } @@ -635,8 +842,7 @@ RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC) uint32_t tv_dac_cntl; uint32_t fp2_gen_cntl; - switch(info->ChipFamily) - { + switch(info->ChipFamily) { case CHIP_FAMILY_R420: case CHIP_FAMILY_RV410: tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL); @@ -662,7 +868,6 @@ RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC) } OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); break; - default: tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL); if (IsOn) { @@ -682,38 +887,88 @@ RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC) } } -/* This is to be used enable/disable displays dynamically */ -static void -RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) +void +legacy_output_dpms(xf86OutputPtr output, int mode) { ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONSavePtr save = info->ModeReg; unsigned char * RADEONMMIO = info->MMIO; unsigned long tmp; - RADEONOutputPrivatePtr radeon_output; - int tv_dac_change = 0, o; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); - radeon_output = output->driver_private; - for (o = 0; o < xf86_config->num_output; o++) { - if (output == xf86_config->output[o]) { - break; - } - } + if (radeon_encoder == NULL) + return; - if (bEnable) { - /*ErrorF("enable montype: %d\n", radeon_output->MonType);*/ - if (radeon_output->MonType == MT_CRT) { - if (radeon_output->DACType == DAC_PRIMARY) { - info->output_crt1 |= (1 << o); - tmp = INREG(RADEON_CRTC_EXT_CNTL); - tmp |= RADEON_CRTC_CRT_ON; - OUTREG(RADEON_CRTC_EXT_CNTL, tmp); - save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON; - RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY)); - } else if (radeon_output->DACType == DAC_TVDAC) { - info->output_crt2 |= (1 << o); + switch(mode) { + case DPMSModeOn: + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_LVDS: + { + radeon_lvds_ptr lvds = (radeon_lvds_ptr)radeon_encoder->dev_priv; + if (lvds == NULL) + return; + ErrorF("enable LVDS\n"); + tmp = INREG(RADEON_LVDS_GEN_CNTL); + tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN); + tmp &= ~(RADEON_LVDS_DISPLAY_DIS); + usleep (lvds->PanelPwrDly * 1000); + OUTREG(RADEON_LVDS_GEN_CNTL, tmp); + save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN); + save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS); + } + break; + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + ErrorF("enable FP1\n"); + tmp = INREG(RADEON_FP_GEN_CNTL); + tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); + OUTREG(RADEON_FP_GEN_CNTL, tmp); + save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); + if ((info->ChipFamily == CHIP_FAMILY_RS400) || + (info->ChipFamily == CHIP_FAMILY_RS480)) { + tmp = INREG(RS400_FP_2ND_GEN_CNTL); + tmp |= (RS400_FP_2ND_ON | RS400_TMDS_2ND_EN); + OUTREG(RS400_FP_2ND_GEN_CNTL, tmp); + save->fp_2nd_gen_cntl |= (RS400_FP_2ND_ON | + RS400_TMDS_2ND_EN); + } + break; + case ENCODER_OBJECT_ID_INTERNAL_DVO1: + ErrorF("enable FP2\n"); + tmp = INREG(RADEON_FP2_GEN_CNTL); + tmp &= ~RADEON_FP2_BLANK_EN; + tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); + OUTREG(RADEON_FP2_GEN_CNTL, tmp); + save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); + save->fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN; + if ((info->ChipFamily == CHIP_FAMILY_RS400) || + (info->ChipFamily == CHIP_FAMILY_RS480)) { + tmp = INREG(RS400_FP2_2_GEN_CNTL); + tmp &= ~RS400_FP2_2_BLANK_EN; + tmp |= (RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN); + OUTREG(RS400_FP2_2_GEN_CNTL, tmp); + save->fp2_2_gen_cntl |= (RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN); + save->fp2_2_gen_cntl &= ~RS400_FP2_2_BLANK_EN; + } + break; + case ENCODER_OBJECT_ID_INTERNAL_DAC1: + ErrorF("enable primary dac\n"); + tmp = INREG(RADEON_CRTC_EXT_CNTL); + tmp |= RADEON_CRTC_CRT_ON; + OUTREG(RADEON_CRTC_EXT_CNTL, tmp); + save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON; + RADEONDacPowerSet(pScrn, TRUE, TRUE); + break; + case ENCODER_OBJECT_ID_INTERNAL_DAC2: + if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) { + ErrorF("enable TV\n"); + tmp = INREG(RADEON_TV_MASTER_CNTL); + tmp |= RADEON_TV_ON; + OUTREG(RADEON_TV_MASTER_CNTL, tmp); + radeon_output->tvout.tv_on = TRUE; + } else { + ErrorF("enable TVDAC\n"); if (info->ChipFamily == CHIP_FAMILY_R200) { tmp = INREG(RADEON_FP2_GEN_CNTL); tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); @@ -725,75 +980,94 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) OUTREG(RADEON_CRTC2_GEN_CNTL, tmp); save->crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON; } - tv_dac_change = 1; } - } else if (radeon_output->MonType == MT_DFP) { - if (radeon_output->TMDSType == TMDS_INT) { - info->output_dfp1 |= (1 << o); + RADEONDacPowerSet(pScrn, TRUE, FALSE); + break; + } + radeon_encoder->use_count++; + break; + case DPMSModeOff: + case DPMSModeSuspend: + case DPMSModeStandby: + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_LVDS: + if (radeon_encoder->use_count < 2) { + unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL); + ErrorF("disable LVDS\n"); + if (info->IsMobility || info->IsIGP) { + /* Asic bug, when turning off LVDS_ON, we have to make sure + RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off + */ + OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb); + } + tmp = INREG(RADEON_LVDS_GEN_CNTL); + tmp |= RADEON_LVDS_DISPLAY_DIS; + tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN); + OUTREG(RADEON_LVDS_GEN_CNTL, tmp); + save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; + save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN); + if (info->IsMobility || info->IsIGP) { + OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl); + } + } + break; + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + if (radeon_encoder->use_count < 2) { + ErrorF("disable FP1\n"); tmp = INREG(RADEON_FP_GEN_CNTL); - tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); + tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); OUTREG(RADEON_FP_GEN_CNTL, tmp); - save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); + save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); if ((info->ChipFamily == CHIP_FAMILY_RS400) || (info->ChipFamily == CHIP_FAMILY_RS480)) { tmp = INREG(RS400_FP_2ND_GEN_CNTL); - tmp |= (RS400_FP_2ND_ON | RS400_TMDS_2ND_EN); + tmp &= ~(RS400_FP_2ND_ON | RS400_TMDS_2ND_EN); OUTREG(RS400_FP_2ND_GEN_CNTL, tmp); - save->fp_2nd_gen_cntl |= (RS400_FP_2ND_ON | - RS400_TMDS_2ND_EN); + save->fp_2nd_gen_cntl &= ~(RS400_FP_2ND_ON | + RS400_TMDS_2ND_EN); } - } else if (radeon_output->TMDSType == TMDS_EXT) { - info->output_dfp2 |= (1 << o); + } + break; + case ENCODER_OBJECT_ID_INTERNAL_DVO1: + if (radeon_encoder->use_count < 2) { + ErrorF("disable FP2\n"); tmp = INREG(RADEON_FP2_GEN_CNTL); - tmp &= ~RADEON_FP2_BLANK_EN; - tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); + tmp |= RADEON_FP2_BLANK_EN; + tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); OUTREG(RADEON_FP2_GEN_CNTL, tmp); - save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); - save->fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN; + save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); + save->fp2_gen_cntl |= RADEON_FP2_BLANK_EN; if ((info->ChipFamily == CHIP_FAMILY_RS400) || (info->ChipFamily == CHIP_FAMILY_RS480)) { tmp = INREG(RS400_FP2_2_GEN_CNTL); - tmp &= ~RS400_FP2_2_BLANK_EN; - tmp |= (RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN); + tmp |= RS400_FP2_2_BLANK_EN; + tmp &= ~(RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN); OUTREG(RS400_FP2_2_GEN_CNTL, tmp); - save->fp2_2_gen_cntl |= (RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN); - save->fp2_2_gen_cntl &= ~RS400_FP2_2_BLANK_EN; + save->fp2_2_gen_cntl &= ~(RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN); + save->fp2_2_gen_cntl |= RS400_FP2_2_BLANK_EN; } } - } else if (radeon_output->MonType == MT_LCD) { - info->output_lcd1 |= (1 << o); - tmp = INREG(RADEON_LVDS_GEN_CNTL); - tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN); - tmp &= ~(RADEON_LVDS_DISPLAY_DIS); - usleep (radeon_output->PanelPwrDly * 1000); - OUTREG(RADEON_LVDS_GEN_CNTL, tmp); - save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN); - save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS); - } else if (radeon_output->MonType == MT_STV || - radeon_output->MonType == MT_CTV) { - info->output_tv1 |= (1 << o); - tmp = INREG(RADEON_TV_MASTER_CNTL); - tmp |= RADEON_TV_ON; - OUTREG(RADEON_TV_MASTER_CNTL, tmp); - tv_dac_change = 2; - radeon_output->tv_on = TRUE; - } - } else { - /*ErrorF("disable montype: %d\n", radeon_output->MonType);*/ - if (radeon_output->MonType == MT_CRT) { - if (radeon_output->DACType == DAC_PRIMARY) { - info->output_crt1 &= ~(1 << o); - if (!info->output_crt1) { - tmp = INREG(RADEON_CRTC_EXT_CNTL); - tmp &= ~RADEON_CRTC_CRT_ON; - OUTREG(RADEON_CRTC_EXT_CNTL, tmp); - save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON; - RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY)); - } - } else if (radeon_output->DACType == DAC_TVDAC) { - info->output_crt2 &= ~(1 << o); - tv_dac_change = 1; - if (!info->output_crt2) { + break; + case ENCODER_OBJECT_ID_INTERNAL_DAC1: + if (radeon_encoder->use_count < 2) { + ErrorF("disable primary dac\n"); + tmp = INREG(RADEON_CRTC_EXT_CNTL); + tmp &= ~RADEON_CRTC_CRT_ON; + OUTREG(RADEON_CRTC_EXT_CNTL, tmp); + save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON; + RADEONDacPowerSet(pScrn, FALSE, TRUE); + } + break; + case ENCODER_OBJECT_ID_INTERNAL_DAC2: + if (radeon_encoder->use_count < 2) { + if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) { + ErrorF("disable TV\n"); + tmp = INREG(RADEON_TV_MASTER_CNTL); + tmp &= ~RADEON_TV_ON; + OUTREG(RADEON_TV_MASTER_CNTL, tmp); + radeon_output->tvout.tv_on = FALSE; + } else { + ErrorF("disable TVDAC\n"); if (info->ChipFamily == CHIP_FAMILY_R200) { tmp = INREG(RADEON_FP2_GEN_CNTL); tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); @@ -806,101 +1080,12 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) save->crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; } } + RADEONDacPowerSet(pScrn, FALSE, FALSE); } - } else if (radeon_output->MonType == MT_DFP) { - if (radeon_output->TMDSType == TMDS_INT) { - info->output_dfp1 &= ~(1 << o); - if (!info->output_dfp1) { - tmp = INREG(RADEON_FP_GEN_CNTL); - tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); - OUTREG(RADEON_FP_GEN_CNTL, tmp); - save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); - if ((info->ChipFamily == CHIP_FAMILY_RS400) || - (info->ChipFamily == CHIP_FAMILY_RS480)) { - tmp = INREG(RS400_FP_2ND_GEN_CNTL); - tmp &= ~(RS400_FP_2ND_ON | RS400_TMDS_2ND_EN); - OUTREG(RS400_FP_2ND_GEN_CNTL, tmp); - save->fp_2nd_gen_cntl &= ~(RS400_FP_2ND_ON | - RS400_TMDS_2ND_EN); - } - } - } else if (radeon_output->TMDSType == TMDS_EXT) { - info->output_dfp2 &= ~(1 << o); - if (!info->output_dfp2) { - tmp = INREG(RADEON_FP2_GEN_CNTL); - tmp |= RADEON_FP2_BLANK_EN; - tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); - OUTREG(RADEON_FP2_GEN_CNTL, tmp); - save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); - save->fp2_gen_cntl |= RADEON_FP2_BLANK_EN; - if ((info->ChipFamily == CHIP_FAMILY_RS400) || - (info->ChipFamily == CHIP_FAMILY_RS480)) { - tmp = INREG(RS400_FP2_2_GEN_CNTL); - tmp |= RS400_FP2_2_BLANK_EN; - tmp &= ~(RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN); - OUTREG(RS400_FP2_2_GEN_CNTL, tmp); - save->fp2_2_gen_cntl &= ~(RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN); - save->fp2_2_gen_cntl |= RS400_FP2_2_BLANK_EN; - } - } - } - } else if (radeon_output->MonType == MT_LCD) { - info->output_lcd1 &= ~(1 << o); - if (!info->output_lcd1) { - unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL); - if (info->IsMobility || info->IsIGP) { - /* Asic bug, when turning off LVDS_ON, we have to make sure - RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off - */ - OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb); - } - tmp = INREG(RADEON_LVDS_GEN_CNTL); - tmp |= RADEON_LVDS_DISPLAY_DIS; - tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN); - OUTREG(RADEON_LVDS_GEN_CNTL, tmp); - save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; - save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN); - if (info->IsMobility || info->IsIGP) { - OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl); - } - } - } else if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) { - info->output_tv1 &= ~(1 << o); - tv_dac_change = 2; - if (!info->output_tv1) { - tmp = INREG(RADEON_TV_MASTER_CNTL); - tmp &= ~RADEON_TV_ON; - OUTREG(RADEON_TV_MASTER_CNTL, tmp); - radeon_output->tv_on = FALSE; - } + break; } - } - - if (tv_dac_change) { - if (bEnable) - info->tv_dac_enable_mask |= tv_dac_change; - else - info->tv_dac_enable_mask &= ~tv_dac_change; - - if (bEnable && info->tv_dac_enable_mask) - RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY)); - else if (!bEnable && info->tv_dac_enable_mask == 0) - RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY)); - - } -} - -void -legacy_output_dpms(xf86OutputPtr output, int mode) -{ - switch(mode) { - case DPMSModeOn: - RADEONEnableDisplay(output, TRUE); - break; - case DPMSModeOff: - case DPMSModeSuspend: - case DPMSModeStandby: - RADEONEnableDisplay(output, FALSE); + if (radeon_encoder->use_count > 0) + radeon_encoder->use_count--; break; } } @@ -913,13 +1098,24 @@ RADEONInitFPRegisters(xf86OutputPtr output, RADEONSavePtr save, RADEONInfoPtr info = RADEONPTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); + radeon_tmds_ptr tmds = NULL; int i; uint32_t tmp = info->SavedReg->tmds_pll_cntl & 0xfffff; - for (i=0; i<4; i++) { - if (radeon_output->tmds_pll[i].freq == 0) break; - if ((uint32_t)(mode->Clock/10) < radeon_output->tmds_pll[i].freq) { - tmp = radeon_output->tmds_pll[i].value ; + if (radeon_encoder == NULL) + return; + + tmds = (radeon_tmds_ptr)radeon_encoder->dev_priv; + + if (tmds == NULL) + return; + + for (i = 0; i < 4; i++) { + if (tmds->tmds_pll[i].freq == 0) + break; + if ((uint32_t)(mode->Clock / 10) < tmds->tmds_pll[i].freq) { + tmp = tmds->tmds_pll[i].value ; break; } } @@ -1123,6 +1319,7 @@ RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save, ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_native_mode_ptr native_mode = &radeon_output->native_mode; int xres = mode->HDisplay; int yres = mode->VDisplay; Bool Hscale = TRUE, Vscale = TRUE; @@ -1176,88 +1373,94 @@ RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save, save->fp_horz_vert_active = 0; - if (radeon_output->MonType != MT_LCD && radeon_output->MonType != MT_DFP) - return; - - if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) { - Hscale = FALSE; - Vscale = FALSE; - } else { - if (xres > radeon_output->PanelXRes) xres = radeon_output->PanelXRes; - if (yres > radeon_output->PanelYRes) yres = radeon_output->PanelYRes; + if ((radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) || + (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT))) { - if (xres == radeon_output->PanelXRes) + if (native_mode->PanelXRes == 0 || native_mode->PanelYRes == 0) { Hscale = FALSE; - if (yres == radeon_output->PanelYRes) Vscale = FALSE; - } + } else { + if (xres > native_mode->PanelXRes) + xres = native_mode->PanelXRes; + if (yres > native_mode->PanelYRes) + yres = native_mode->PanelYRes; + + if (xres == native_mode->PanelXRes) + Hscale = FALSE; + if (yres == native_mode->PanelYRes) + Vscale = FALSE; + } - if ((!Hscale) || (!(radeon_output->Flags & RADEON_USE_RMX)) || - (radeon_output->rmx_type == RMX_CENTER)) { - save->fp_horz_stretch |= ((xres/8-1)<<16); - } else { - CARD32 scale, inc; - inc = (save->fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0; - scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX) - / radeon_output->PanelXRes + 1; - save->fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) | - RADEON_HORZ_STRETCH_BLEND | - RADEON_HORZ_STRETCH_ENABLE | - ((radeon_output->PanelXRes/8-1)<<16)); - } + if ((!Hscale) || (!(radeon_output->Flags & RADEON_USE_RMX)) || + (radeon_output->rmx_type == RMX_CENTER)) { + save->fp_horz_stretch |= ((xres/8-1)<<16); + } else { + uint32_t scale, inc; + inc = (save->fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0; + scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX) + / native_mode->PanelXRes + 1; + save->fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) | + RADEON_HORZ_STRETCH_BLEND | + RADEON_HORZ_STRETCH_ENABLE | + ((native_mode->PanelXRes/8-1)<<16)); + } - if ((!Vscale) || (!(radeon_output->Flags & RADEON_USE_RMX)) || - (radeon_output->rmx_type == RMX_CENTER)) { - save->fp_vert_stretch |= ((yres-1)<<12); - } else { - CARD32 scale, inc; - inc = (save->fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0; - scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX) - / radeon_output->PanelYRes + 1; - save->fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) | - RADEON_VERT_STRETCH_ENABLE | - RADEON_VERT_STRETCH_BLEND | - ((radeon_output->PanelYRes-1)<<12)); - } + if ((!Vscale) || (!(radeon_output->Flags & RADEON_USE_RMX)) || + (radeon_output->rmx_type == RMX_CENTER)) { + save->fp_vert_stretch |= ((yres-1)<<12); + } else { + uint32_t scale, inc; + inc = (save->fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0; + scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX) + / native_mode->PanelYRes + 1; + save->fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) | + RADEON_VERT_STRETCH_ENABLE | + RADEON_VERT_STRETCH_BLEND | + ((native_mode->PanelYRes-1)<<12)); + } - if ((radeon_output->rmx_type == RMX_CENTER) && - (radeon_output->Flags & RADEON_USE_RMX)) { - int blank_width; + if ((radeon_output->rmx_type == RMX_CENTER) && + (radeon_output->Flags & RADEON_USE_RMX)) { + int blank_width; - save->crtc_more_cntl |= (RADEON_CRTC_AUTO_HORZ_CENTER_EN | - RADEON_CRTC_AUTO_VERT_CENTER_EN); + save->crtc_more_cntl |= (RADEON_CRTC_AUTO_HORZ_CENTER_EN | + RADEON_CRTC_AUTO_VERT_CENTER_EN); - blank_width = (mode->CrtcHBlankEnd - mode->CrtcHBlankStart) / 8; - if (blank_width > 110) blank_width = 110; + blank_width = (mode->CrtcHBlankEnd - mode->CrtcHBlankStart) / 8; + if (blank_width > 110) + blank_width = 110; - save->fp_crtc_h_total_disp = (((blank_width) & 0x3ff) - | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff) - << 16)); + save->fp_crtc_h_total_disp = (((blank_width) & 0x3ff) + | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff) + << 16)); - hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8; - if (!hsync_wid) hsync_wid = 1; + hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8; + if (!hsync_wid) + hsync_wid = 1; - save->fp_h_sync_strt_wid = ((((mode->CrtcHSyncStart - mode->CrtcHBlankStart) / 8) & 0x1fff) - | ((hsync_wid & 0x3f) << 16) - | ((mode->Flags & V_NHSYNC) - ? RADEON_CRTC_H_SYNC_POL - : 0)); + save->fp_h_sync_strt_wid = ((((mode->CrtcHSyncStart - mode->CrtcHBlankStart) / 8) & 0x1fff) + | ((hsync_wid & 0x3f) << 16) + | ((mode->Flags & V_NHSYNC) + ? RADEON_CRTC_H_SYNC_POL + : 0)); - save->fp_crtc_v_total_disp = (((mode->CrtcVBlankEnd - mode->CrtcVBlankStart) & 0xffff) - | ((mode->CrtcVDisplay - 1) << 16)); + save->fp_crtc_v_total_disp = (((mode->CrtcVBlankEnd - mode->CrtcVBlankStart) & 0xffff) + | ((mode->CrtcVDisplay - 1) << 16)); - vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; - if (!vsync_wid) vsync_wid = 1; + vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; + if (!vsync_wid) + vsync_wid = 1; - save->fp_v_sync_strt_wid = ((((mode->CrtcVSyncStart - mode->CrtcVBlankStart) & 0xfff) - | ((vsync_wid & 0x1f) << 16) - | ((mode->Flags & V_NVSYNC) - ? RADEON_CRTC_V_SYNC_POL - : 0))); + save->fp_v_sync_strt_wid = ((((mode->CrtcVSyncStart - mode->CrtcVBlankStart) & 0xfff) + | ((vsync_wid & 0x1f) << 16) + | ((mode->Flags & V_NVSYNC) + ? RADEON_CRTC_V_SYNC_POL + : 0))); - save->fp_horz_vert_active = (((radeon_output->PanelYRes) & 0xfff) | - (((radeon_output->PanelXRes / 8) & 0x1ff) << 16)); + save->fp_horz_vert_active = (((native_mode->PanelYRes) & 0xfff) | + (((native_mode->PanelXRes / 8) & 0x1ff) << 16)); + } } } @@ -1296,7 +1499,16 @@ RADEONInitTvDacCntl(xf86OutputPtr output, RADEONSavePtr save) { ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); + radeon_tvdac_ptr tvdac = NULL; + + if (radeon_encoder == NULL) + return; + + tvdac = (radeon_tvdac_ptr)radeon_encoder->dev_priv; + + if (tvdac == NULL) + return; if (info->ChipFamily == CHIP_FAMILY_R420 || info->ChipFamily == CHIP_FAMILY_RV410) { @@ -1321,7 +1533,7 @@ RADEONInitTvDacCntl(xf86OutputPtr output, RADEONSavePtr save) save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD | RADEON_TV_DAC_STD_PS2 | - radeon_output->ps2_tvdac_adj); + tvdac->ps2_tvdac_adj); } @@ -1369,96 +1581,79 @@ RADEONInitDAC2Registers(xf86OutputPtr output, RADEONSavePtr save, } } -static void -RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, - DisplayModePtr mode, xf86OutputPtr output, - int crtc_num) -{ - Bool IsPrimary = crtc_num == 0 ? TRUE : FALSE; - RADEONOutputPrivatePtr radeon_output = output->driver_private; - - if (crtc_num == 0) - RADEONInitRMXRegisters(output, save, mode); - - if (radeon_output->MonType == MT_CRT) { - if (radeon_output->DACType == DAC_PRIMARY) { - RADEONInitDACRegisters(output, save, mode, IsPrimary); - } else { - RADEONInitDAC2Registers(output, save, mode, IsPrimary); - } - } else if (radeon_output->MonType == MT_LCD) { - RADEONInitLVDSRegisters(output, save, mode, IsPrimary); - } else if (radeon_output->MonType == MT_DFP) { - if (radeon_output->TMDSType == TMDS_INT) { - RADEONInitFPRegisters(output, save, mode, IsPrimary); - } else { - RADEONInitFP2Registers(output, save, mode, IsPrimary); - } - } else if (radeon_output->MonType == MT_STV || - radeon_output->MonType == MT_CTV) { - RADEONInitTVRegisters(output, save, mode, IsPrimary); - } -} - void legacy_output_mode_set(xf86OutputPtr output, DisplayModePtr mode, - DisplayModePtr adjusted_mode) + DisplayModePtr adjusted_mode) { ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONOutputPrivatePtr radeon_output = output->driver_private; xf86CrtcPtr crtc = output->crtc; RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); + Bool is_primary = FALSE; - RADEONInitOutputRegisters(pScrn, info->ModeReg, adjusted_mode, output, radeon_crtc->crtc_id); + if (radeon_encoder == NULL) + return; - if (radeon_crtc->crtc_id == 0) + if (radeon_crtc->crtc_id == 0) { + ErrorF("set RMX\n"); + is_primary = TRUE; + RADEONInitRMXRegisters(output, info->ModeReg, adjusted_mode); RADEONRestoreRMXRegisters(pScrn, info->ModeReg); + } - switch(radeon_output->MonType) { - case MT_LCD: - ErrorF("restore LVDS\n"); + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_LVDS: + ErrorF("set LVDS\n"); + RADEONInitLVDSRegisters(output, info->ModeReg, adjusted_mode, is_primary); RADEONRestoreLVDSRegisters(pScrn, info->ModeReg); break; - case MT_DFP: - if (radeon_output->TMDSType == TMDS_INT) { - ErrorF("restore FP\n"); - RADEONRestoreFPRegisters(pScrn, info->ModeReg); - } else { - ErrorF("restore FP2\n"); - if (info->IsAtomBios) { - unsigned char *RADEONMMIO = info->MMIO; - uint32_t fp2_gen_cntl; - - atombios_external_tmds_setup(output, mode); - /* r4xx atom has hard coded crtc mappings in the atom code - * Fix it up here. - */ - fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL) & ~R200_FP2_SOURCE_SEL_MASK; - if (radeon_crtc->crtc_id == 1) - fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2; - else { - if (radeon_output->Flags & RADEON_USE_RMX) - fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX; - else - fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC1; - } - OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); - } else { - RADEONRestoreFP2Registers(pScrn, info->ModeReg); - RADEONRestoreDVOChip(pScrn, output); + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + ErrorF("set FP1\n"); + RADEONInitFPRegisters(output, info->ModeReg, adjusted_mode, is_primary); + RADEONRestoreFPRegisters(pScrn, info->ModeReg); + break; + case ENCODER_OBJECT_ID_INTERNAL_DVO1: + ErrorF("set FP2\n"); + RADEONInitFP2Registers(output, info->ModeReg, adjusted_mode, is_primary); + if (info->IsAtomBios) { + unsigned char *RADEONMMIO = info->MMIO; + uint32_t fp2_gen_cntl; + + atombios_external_tmds_setup(output, mode); + fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL) & ~R200_FP2_SOURCE_SEL_MASK; + if (radeon_crtc->crtc_id == 1) + fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2; + else { + if (radeon_output->Flags & RADEON_USE_RMX) + fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX; + else + fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC1; } + OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); + } else { + RADEONRestoreFP2Registers(pScrn, info->ModeReg); + RADEONRestoreDVOChip(pScrn, output); } break; - case MT_STV: - case MT_CTV: - ErrorF("restore tv\n"); + case ENCODER_OBJECT_ID_INTERNAL_DAC1: + ErrorF("set primary dac\n"); + RADEONInitDACRegisters(output, info->ModeReg, adjusted_mode, is_primary); RADEONRestoreDACRegisters(pScrn, info->ModeReg); - RADEONRestoreTVRegisters(pScrn, info->ModeReg); break; - default: - ErrorF("restore dac\n"); - RADEONRestoreDACRegisters(pScrn, info->ModeReg); + case ENCODER_OBJECT_ID_INTERNAL_DAC2: + if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) { + ErrorF("set TV\n"); + RADEONInitTVRegisters(output, info->ModeReg, adjusted_mode, is_primary); + RADEONRestoreDACRegisters(pScrn, info->ModeReg); + RADEONRestoreTVRegisters(pScrn, info->ModeReg); + } else { + ErrorF("set TVDAC\n"); + RADEONInitDAC2Registers(output, info->ModeReg, adjusted_mode, is_primary); + RADEONRestoreDACRegisters(pScrn, info->ModeReg); + } + break; } } diff --git a/src/radeon.h b/src/radeon.h index 2a6f150e..66b23304 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -793,18 +793,16 @@ typedef struct { DisplayModePtr currentMode, savedCurrentMode; /* special handlings for DELL triple-head server */ - Bool IsDellServer; + Bool IsDellServer; Bool VGAAccess; int MaxSurfaceWidth; int MaxLines; - uint32_t tv_dac_adj; - uint32_t tv_dac_enable_mask; - Bool want_vblank_interrupts; RADEONBIOSConnector BiosConnector[RADEON_MAX_BIOS_CONNECTOR]; + radeon_encoder_ptr encoders[RADEON_MAX_BIOS_CONNECTOR]; RADEONBIOSInitTable BiosTable; /* save crtc state for console restore */ @@ -812,7 +810,6 @@ typedef struct { Bool crtc2_on; Bool InternalTVOut; - int tvdac_use_count; #if defined(__powerpc__) RADEONMacModel MacModel; @@ -823,14 +820,6 @@ typedef struct { unsigned long FbFreeStart, FbFreeSize; unsigned char* BIOSCopy; - /* output enable masks for outputs shared across connectors */ - int output_crt1; - int output_crt2; - int output_dfp1; - int output_dfp2; - int output_lcd1; - int output_tv1; - Rotation rotation; void (*PointerMoved)(int, int, int); CreateScreenResourcesProcPtr CreateScreenResources; @@ -877,8 +866,7 @@ extern void RADEONSavePLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save); extern void RADEONSavePLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save); /* legacy_output.c */ -extern RADEONMonitorType legacy_dac_detect(ScrnInfoPtr pScrn, - xf86OutputPtr output); +extern RADEONMonitorType legacy_dac_detect(xf86OutputPtr output); extern void legacy_output_dpms(xf86OutputPtr output, int mode); extern void legacy_output_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode); @@ -893,6 +881,12 @@ extern void RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore); extern void RADEONSaveDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save); extern void RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save); +extern void RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn, radeon_tvdac_ptr tvdac); +extern void RADEONGetTMDSInfoFromTable(ScrnInfoPtr pScrn, radeon_tmds_ptr tmds); +extern void RADEONGetTMDSInfo(ScrnInfoPtr pScrn, radeon_tmds_ptr tmds); +extern void RADEONGetExtTMDSInfo(ScrnInfoPtr pScrn, radeon_dvo_ptr dvo); +extern void RADEONGetLVDSInfo(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds); + /* radeon_accel.c */ extern Bool RADEONAccelInit(ScreenPtr pScreen); extern void RADEONEngineFlush(ScrnInfoPtr pScrn); @@ -935,12 +929,12 @@ extern Bool RADEONSetupMemXAA(int scrnIndex, ScreenPtr pScreen); extern Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10); extern Bool RADEONGetClockInfoFromBIOS(ScrnInfoPtr pScrn); extern Bool RADEONGetConnectorInfoFromBIOS(ScrnInfoPtr pScrn); -extern Bool RADEONGetDAC2InfoFromBIOS(xf86OutputPtr output); -extern Bool RADEONGetExtTMDSInfoFromBIOS(xf86OutputPtr output); +extern Bool RADEONGetDAC2InfoFromBIOS(ScrnInfoPtr pScrn, radeon_tvdac_ptr tvdac); +extern Bool RADEONGetExtTMDSInfoFromBIOS (ScrnInfoPtr pScrn, radeon_dvo_ptr dvo); extern xf86MonPtr RADEONGetHardCodedEDIDFromBIOS(xf86OutputPtr output); extern Bool RADEONGetBIOSInitTableOffsets(ScrnInfoPtr pScrn); -extern Bool RADEONGetLVDSInfoFromBIOS(xf86OutputPtr output); -extern Bool RADEONGetTMDSInfoFromBIOS(xf86OutputPtr output); +extern Bool RADEONGetLVDSInfoFromBIOS(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds); +extern Bool RADEONGetTMDSInfoFromBIOS(ScrnInfoPtr pScrn, radeon_tmds_ptr tmds); extern Bool RADEONGetTVInfoFromBIOS(xf86OutputPtr output); extern Bool RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output); extern Bool RADEONPostCardFromBIOSTables(ScrnInfoPtr pScrn); diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c index 1acb997d..9fe7ec72 100644 --- a/src/radeon_atombios.c +++ b/src/radeon_atombios.c @@ -77,6 +77,10 @@ rhdAtomCompassionateDataQuery(atomBiosHandlePtr handle, AtomBiosRequestID func, AtomBiosArgPtr data); +static void +RADEONGetATOMLVDSInfo(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds); + + enum msgDataFormat { MSG_FORMAT_NONE, MSG_FORMAT_HEX, @@ -1526,7 +1530,7 @@ static void RADEONApplyATOMQuirks(ScrnInfoPtr pScrn, int index) (PCI_SUB_VENDOR_ID(info->PciInfo) == 0x1043) && (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x826d)) { if ((info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_A) && - (info->BiosConnector[index].TMDSType == TMDS_LVTMA)) { + (info->BiosConnector[index].devices & ATOM_DEVICE_DFP3_SUPPORT)) { info->BiosConnector[index].ConnectorType = CONNECTOR_DVI_D; } } @@ -1557,16 +1561,155 @@ static void RADEONApplyATOMQuirks(ScrnInfoPtr pScrn, int index) info->BiosConnector[index].valid = FALSE; if (index == ATOM_DEVICE_DFP1_INDEX) { - info->BiosConnector[index].DACType = DAC_TVDAC; - info->BiosConnector[index].devices |= (1 << ATOM_DEVICE_CRT2_INDEX); + info->BiosConnector[index].devices |= ATOM_DEVICE_CRT2_SUPPORT; } } - /* BIOSes seem to report DAC on HDMI - they hurt me with their lies */ + /* some BIOSes seem to report DAC on HDMI - they hurt me with their lies */ if ((info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_A) || (info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_B)) { - info->BiosConnector[index].DACType = DAC_NONE; + info->BiosConnector[index].devices &= ~(ATOM_DEVICE_CRT_SUPPORT); + } +} + +uint32_t +radeon_get_device_index(uint32_t device_support) +{ + uint32_t device_index = 0; + + if (device_support == 0) + return 0; + + while ((device_support & 1) == 0) { + device_support >>= 1; + device_index++; } + return device_index; +} + +radeon_encoder_ptr +radeon_get_encoder(xf86OutputPtr output) +{ + RADEONOutputPrivatePtr radeon_output = output->driver_private; + RADEONInfoPtr info = RADEONPTR(output->scrn); + + return info->encoders[radeon_get_device_index(radeon_output->active_device)]; + +} + +Bool +radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_support) +{ + RADEONInfoPtr info = RADEONPTR (pScrn); + uint32_t device_index = radeon_get_device_index(device_support); + int i; + + if (device_support == 0) { + ErrorF("device support == 0\n"); + return FALSE; + } + + if (info->encoders[device_index] != NULL) + return TRUE; + else { + /* look for the encoder */ + for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) { + if ((info->encoders[i] != NULL) && (info->encoders[i]->encoder_id == encoder_id)) { + info->encoders[device_index] = info->encoders[i]; + switch (encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + if (device_support & ATOM_DEVICE_LCD1_SUPPORT) { + if (info->encoders[device_index]->dev_priv == NULL) { + info->encoders[device_index]->dev_priv = + (radeon_lvds_ptr)xcalloc(1,sizeof(radeon_lvds_rec)); + if (info->encoders[device_index]->dev_priv == NULL) { + ErrorF("xalloc failed\n"); + return FALSE; + } else + RADEONGetATOMLVDSInfo(pScrn, (radeon_lvds_ptr)info->encoders[device_index]->dev_priv); + } + } + break; + } + return TRUE; + } + } + + info->encoders[device_index] = (radeon_encoder_ptr)xcalloc(1,sizeof(radeon_encoder_rec)); + if (info->encoders[device_index] != NULL) { + info->encoders[device_index]->encoder_id = encoder_id; + info->encoders[device_index]->use_count = 0; + info->encoders[device_index]->dev_priv = NULL; + // add dev_priv stuff + switch (encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_LVDS: + info->encoders[device_index]->dev_priv = (radeon_lvds_ptr)xcalloc(1,sizeof(radeon_lvds_rec)); + if (info->encoders[device_index]->dev_priv == NULL) { + ErrorF("xalloc failed\n"); + return FALSE; + } else { + if (info->IsAtomBios) + RADEONGetATOMLVDSInfo(pScrn, (radeon_lvds_ptr)info->encoders[device_index]->dev_priv); + else + RADEONGetLVDSInfo(pScrn, (radeon_lvds_ptr)info->encoders[device_index]->dev_priv); + } + break; + case ENCODER_OBJECT_ID_INTERNAL_DAC2: + if (!IS_AVIVO_VARIANT) { + info->encoders[device_index]->dev_priv = (radeon_tvdac_ptr)xcalloc(1,sizeof(radeon_tvdac_rec)); + if (info->encoders[device_index]->dev_priv == NULL) { + ErrorF("xalloc failed\n"); + return FALSE; + } else + RADEONGetTVDacAdjInfo(pScrn, (radeon_tvdac_ptr)info->encoders[device_index]->dev_priv); + } + break; + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + if (!IS_AVIVO_VARIANT) { + info->encoders[device_index]->dev_priv = (radeon_tmds_ptr)xcalloc(1,sizeof(radeon_tmds_rec)); + if (info->encoders[device_index]->dev_priv == NULL) { + ErrorF("xalloc failed\n"); + return FALSE; + } else + RADEONGetTMDSInfo(pScrn, (radeon_tmds_ptr)info->encoders[device_index]->dev_priv); + } + break; + case ENCODER_OBJECT_ID_INTERNAL_DVO1: + if (!IS_AVIVO_VARIANT) { + info->encoders[device_index]->dev_priv = (radeon_dvo_ptr)xcalloc(1,sizeof(radeon_dvo_rec)); + if (info->encoders[device_index]->dev_priv == NULL) { + ErrorF("xalloc failed\n"); + return FALSE; + } else + RADEONGetExtTMDSInfo(pScrn, (radeon_dvo_ptr)info->encoders[device_index]->dev_priv); + } + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + if (device_support & ATOM_DEVICE_LCD1_SUPPORT) { + info->encoders[device_index]->dev_priv = (radeon_lvds_ptr)xcalloc(1,sizeof(radeon_lvds_rec)); + if (info->encoders[device_index]->dev_priv == NULL) { + ErrorF("xalloc failed\n"); + return FALSE; + } else + RADEONGetATOMLVDSInfo(pScrn, (radeon_lvds_ptr)info->encoders[device_index]->dev_priv); + } + break; + } + return TRUE; + } else { + ErrorF("xalloc failed\n"); + return FALSE; + } + } + } Bool @@ -1577,8 +1720,9 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn) unsigned short size; atomDataTablesPtr atomDataPtr; ATOM_CONNECTOR_OBJECT_TABLE *con_obj; + ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; ATOM_INTEGRATED_SYSTEM_INFO_V2 *igp_obj = NULL; - int i, j; + int i, j, path_size, device_support; Bool enable_tv = FALSE; if (xf86ReturnOptValBool(info->Options, OPTION_ATOM_TVOUT, FALSE)) @@ -1591,185 +1735,132 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn) if (crev < 2) return FALSE; + path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *) + ((char *)&atomDataPtr->Object_Header->sHeader + + le16_to_cpu(atomDataPtr->Object_Header->usDisplayPathTableOffset)); con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *) ((char *)&atomDataPtr->Object_Header->sHeader + le16_to_cpu(atomDataPtr->Object_Header->usConnectorObjectTableOffset)); - - for (i = 0; i < con_obj->ucNumberOfObjects; i++) { - ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *SrcDstTable; - ATOM_COMMON_RECORD_HEADER *Record; - uint8_t obj_id, num, obj_type; - int record_base; - uint16_t con_obj_id = le16_to_cpu(con_obj->asObjects[i].usObjectID); - - obj_id = (con_obj_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; - num = (con_obj_id & ENUM_ID_MASK) >> ENUM_ID_SHIFT; - obj_type = (con_obj_id & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; - if (obj_type != GRAPH_OBJECT_TYPE_CONNECTOR) - continue; - - SrcDstTable = (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *) - ((char *)&atomDataPtr->Object_Header->sHeader - + le16_to_cpu(con_obj->asObjects[i].usSrcDstTableOffset)); - - ErrorF("object id %04x %02x\n", obj_id, SrcDstTable->ucNumberOfSrc); - - if ((info->ChipFamily == CHIP_FAMILY_RS780) && - (obj_id == CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) { - uint32_t slot_config, ct; - - igp_obj = info->atomBIOS->atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo_v2; - - if (!igp_obj) - info->BiosConnector[i].ConnectorType = object_connector_convert[obj_id]; - else { - if (num == 1) - slot_config = igp_obj->ulDDISlot1Config; - else - slot_config = igp_obj->ulDDISlot2Config; - - ct = (slot_config >> 16) & 0xff; - info->BiosConnector[i].ConnectorType = object_connector_convert[ct]; - info->BiosConnector[i].igp_lane_info = slot_config & 0xffff; + device_support = le16_to_cpu(atomDataPtr->Object_Header->usDeviceSupport); + + path_size = 0; + for (i = 0; i < path_obj->ucNumOfDispPath; i++) { + uint8_t *addr = (uint8_t *)path_obj->asDispPath; + ATOM_DISPLAY_OBJECT_PATH *path; + addr += path_size; + path = (ATOM_DISPLAY_OBJECT_PATH *)addr; + path_size += path->usSize; + + if (device_support & path->usDeviceTag) { + uint8_t con_obj_id, con_obj_num, con_obj_type; + + con_obj_id = (path->usConnObjectId & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; + con_obj_num = (path->usConnObjectId & ENUM_ID_MASK) >> ENUM_ID_SHIFT; + con_obj_type = (path->usConnObjectId & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; + + if ((path->usDeviceTag == ATOM_DEVICE_TV1_SUPPORT) || + (path->usDeviceTag == ATOM_DEVICE_TV2_SUPPORT) || + (path->usDeviceTag == ATOM_DEVICE_CV_SUPPORT)) { + if (!enable_tv) { + info->BiosConnector[i].valid = FALSE; + continue; + } } - } else - info->BiosConnector[i].ConnectorType = object_connector_convert[obj_id]; - if (info->BiosConnector[i].ConnectorType == CONNECTOR_NONE) - info->BiosConnector[i].valid = FALSE; - else - info->BiosConnector[i].valid = TRUE; - info->BiosConnector[i].devices = 0; - - for (j = 0; j < SrcDstTable->ucNumberOfSrc; j++) { - uint8_t sobj_id; + if ((info->ChipFamily == CHIP_FAMILY_RS780) && + (con_obj_id == CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) { + uint32_t slot_config, ct; - sobj_id = (le16_to_cpu(SrcDstTable->usSrcObjectID[j]) & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; - ErrorF("src object id %04x %d\n", le16_to_cpu(SrcDstTable->usSrcObjectID[j]), sobj_id); + igp_obj = info->atomBIOS->atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo_v2; - switch(sobj_id) { - case ENCODER_OBJECT_ID_INTERNAL_LVDS: - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX); - break; - case ENCODER_OBJECT_ID_INTERNAL_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX); + if (!igp_obj) + info->BiosConnector[i].ConnectorType = object_connector_convert[con_obj_id]; else { - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP1_INDEX); - info->BiosConnector[i].TMDSType = TMDS_INT; - } - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX); - else { - if (num == 1) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP1_INDEX); + if (con_obj_num == 1) + slot_config = igp_obj->ulDDISlot1Config; else - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP2_INDEX); - info->BiosConnector[i].TMDSType = TMDS_UNIPHY; + slot_config = igp_obj->ulDDISlot2Config; + + ct = (slot_config >> 16) & 0xff; + info->BiosConnector[i].ConnectorType = object_connector_convert[ct]; + info->BiosConnector[i].igp_lane_info = slot_config & 0xffff; } - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX); - else { - if (num == 1) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP3_INDEX); + } else + info->BiosConnector[i].ConnectorType = object_connector_convert[con_obj_id]; + + if (info->BiosConnector[i].ConnectorType == CONNECTOR_NONE) { + info->BiosConnector[i].valid = FALSE; + continue; + } else + info->BiosConnector[i].valid = TRUE; + info->BiosConnector[i].devices = path->usDeviceTag; + info->BiosConnector[i].connector_object = path->usConnObjectId; + + for (j = 0; j < ((path->usSize - 8) / 2); j++) { + uint8_t enc_obj_id, enc_obj_num, enc_obj_type; + + enc_obj_id = (path->usGraphicObjIds[j] & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; + enc_obj_num = (path->usGraphicObjIds[j] & ENUM_ID_MASK) >> ENUM_ID_SHIFT; + enc_obj_type = (path->usGraphicObjIds[j] & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; + + if (enc_obj_type == GRAPH_OBJECT_TYPE_ENCODER) { + if (enc_obj_num == 2) + info->BiosConnector[i].linkb = TRUE; else - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP4_INDEX); - info->BiosConnector[i].TMDSType = TMDS_UNIPHY1; - } - break; + info->BiosConnector[i].linkb = FALSE; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX); - else { - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP5_INDEX); - info->BiosConnector[i].TMDSType = TMDS_UNIPHY2; - } - break; - case ENCODER_OBJECT_ID_INTERNAL_TMDS2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP2_INDEX); - info->BiosConnector[i].TMDSType = TMDS_EXT; - break; - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX); - else { - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP3_INDEX); - info->BiosConnector[i].TMDSType = TMDS_LVTMA; + if (!radeon_add_encoder(pScrn, enc_obj_id, path->usDeviceTag)) + return FALSE; } - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: - if (info->BiosConnector[i].ConnectorType == CONNECTOR_HDMI_TYPE_A || - info->BiosConnector[i].ConnectorType == CONNECTOR_HDMI_TYPE_B) - break; - if (info->BiosConnector[i].ConnectorType == CONNECTOR_DIN || - info->BiosConnector[i].ConnectorType == CONNECTOR_STV || - info->BiosConnector[i].ConnectorType == CONNECTOR_CTV) - if (enable_tv) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_TV1_INDEX); - else - info->BiosConnector[i].valid = FALSE; - else - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_CRT1_INDEX); - info->BiosConnector[i].DACType = DAC_PRIMARY; - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: - if (info->BiosConnector[i].ConnectorType == CONNECTOR_HDMI_TYPE_A || - info->BiosConnector[i].ConnectorType == CONNECTOR_HDMI_TYPE_B) - break; - if (info->BiosConnector[i].ConnectorType == CONNECTOR_DIN || - info->BiosConnector[i].ConnectorType == CONNECTOR_STV || - info->BiosConnector[i].ConnectorType == CONNECTOR_CTV) - if (enable_tv) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_TV1_INDEX); - else - info->BiosConnector[i].valid = FALSE; - else - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_CRT2_INDEX); - info->BiosConnector[i].DACType = DAC_TVDAC; - break; } - } - - Record = (ATOM_COMMON_RECORD_HEADER *) - ((char *)&atomDataPtr->Object_Header->sHeader - + le16_to_cpu(con_obj->asObjects[i].usRecordOffset)); - record_base = le16_to_cpu(con_obj->asObjects[i].usRecordOffset); - - while (Record->ucRecordType > 0 - && Record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER ) { - - ErrorF("record type %d\n", Record->ucRecordType); - switch (Record->ucRecordType) { - case ATOM_I2C_RECORD_TYPE: - info->BiosConnector[i].ddc_i2c = rhdAtomParseI2CRecord(pScrn, info->atomBIOS, - (ATOM_I2C_RECORD *)Record, i); - break; - case ATOM_HPD_INT_RECORD_TYPE: - break; - case ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE: - break; + /* look up gpio for ddc */ + if ((path->usDeviceTag & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) { + for (j = 0; j < con_obj->ucNumberOfObjects; j++) { + if (path->usConnObjectId == le16_to_cpu(con_obj->asObjects[j].usObjectID)) { + ATOM_COMMON_RECORD_HEADER *Record = (ATOM_COMMON_RECORD_HEADER *) + ((char *)&atomDataPtr->Object_Header->sHeader + + le16_to_cpu(con_obj->asObjects[j].usRecordOffset)); + + while (Record->ucRecordType > 0 + && Record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER ) { + + /*ErrorF("record type %d\n", Record->ucRecordType);*/ + switch (Record->ucRecordType) { + case ATOM_I2C_RECORD_TYPE: + info->BiosConnector[i].ddc_i2c = + rhdAtomParseI2CRecord(pScrn, info->atomBIOS, + (ATOM_I2C_RECORD *)Record, j); + break; + case ATOM_HPD_INT_RECORD_TYPE: + break; + case ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE: + break; + } + + Record = (ATOM_COMMON_RECORD_HEADER*) + ((char *)Record + Record->ucRecordSize); + } + break; + } + } } - - Record = (ATOM_COMMON_RECORD_HEADER*) - ((char *)Record + Record->ucRecordSize); } - RADEONApplyATOMQuirks(pScrn, i); } for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { if (info->BiosConnector[i].valid) { + /* shared connectors */ + for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) { + if (info->BiosConnector[j].valid && (i != j) ) { + if (info->BiosConnector[i].connector_object == info->BiosConnector[j].connector_object) { + info->BiosConnector[i].devices |= info->BiosConnector[j].devices; + info->BiosConnector[j].valid = FALSE; + } + } + } + /* shared ddc */ for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) { if (info->BiosConnector[j].valid && (i != j) ) { if (info->BiosConnector[i].i2c_line_mux == info->BiosConnector[j].i2c_line_mux) { @@ -1784,12 +1875,11 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn) return TRUE; } -Bool -RADEONGetATOMLVDSInfo(xf86OutputPtr output) +static void +RADEONGetATOMLVDSInfo(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds) { - ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_native_mode_ptr native_mode = &lvds->native_mode; atomDataTablesPtr atomDataPtr; uint8_t crev, frev; @@ -1798,55 +1888,52 @@ RADEONGetATOMLVDSInfo(xf86OutputPtr output) if (!rhdAtomGetTableRevisionAndSize( (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->LVDS_Info.base), &frev,&crev,NULL)) { - return FALSE; + return; } switch (crev) { case 1: - radeon_output->PanelXRes = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usHActive); - radeon_output->PanelYRes = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVActive); - radeon_output->DotClock = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usPixClk) * 10; - radeon_output->HBlank = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usHBlanking_Time); - radeon_output->HOverPlus = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usHSyncOffset); - radeon_output->HSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usHSyncWidth); - radeon_output->VBlank = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVBlanking_Time); - radeon_output->VOverPlus = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVSyncOffset); - radeon_output->VSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVSyncWidth); - radeon_output->PanelPwrDly = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->usOffDelayInMs); - radeon_output->lvds_misc = atomDataPtr->LVDS_Info.LVDS_Info->ucLVDS_Misc; - radeon_output->lvds_ss_id = atomDataPtr->LVDS_Info.LVDS_Info->ucSS_Id; + native_mode->PanelXRes = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usHActive); + native_mode->PanelYRes = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVActive); + native_mode->DotClock = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usPixClk) * 10; + native_mode->HBlank = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usHBlanking_Time); + native_mode->HOverPlus = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usHSyncOffset); + native_mode->HSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usHSyncWidth); + native_mode->VBlank = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVBlanking_Time); + native_mode->VOverPlus = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVSyncOffset); + native_mode->VSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVSyncWidth); + lvds->PanelPwrDly = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->usOffDelayInMs); + lvds->lvds_misc = atomDataPtr->LVDS_Info.LVDS_Info->ucLVDS_Misc; + lvds->lvds_ss_id = atomDataPtr->LVDS_Info.LVDS_Info->ucSS_Id; break; case 2: - radeon_output->PanelXRes = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usHActive); - radeon_output->PanelYRes = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVActive); - radeon_output->DotClock = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usPixClk) * 10; - radeon_output->HBlank = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usHBlanking_Time); - radeon_output->HOverPlus = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usHSyncOffset); - radeon_output->HSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usHSyncWidth); - radeon_output->VBlank = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVBlanking_Time); - radeon_output->VOverPlus = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVSyncOffset); - radeon_output->VSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVSyncWidth); - radeon_output->PanelPwrDly = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->usOffDelayInMs); - radeon_output->lvds_misc = atomDataPtr->LVDS_Info.LVDS_Info_v12->ucLVDS_Misc; - radeon_output->lvds_ss_id = atomDataPtr->LVDS_Info.LVDS_Info_v12->ucSS_Id; + native_mode->PanelXRes = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usHActive); + native_mode->PanelYRes = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVActive); + native_mode->DotClock = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usPixClk) * 10; + native_mode->HBlank = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usHBlanking_Time); + native_mode->HOverPlus = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usHSyncOffset); + native_mode->HSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usHSyncWidth); + native_mode->VBlank = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVBlanking_Time); + native_mode->VOverPlus = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVSyncOffset); + native_mode->VSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVSyncWidth); + lvds->PanelPwrDly = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->usOffDelayInMs); + lvds->lvds_misc = atomDataPtr->LVDS_Info.LVDS_Info_v12->ucLVDS_Misc; + lvds->lvds_ss_id = atomDataPtr->LVDS_Info.LVDS_Info_v12->ucSS_Id; break; } + native_mode->Flags = 0; - if (radeon_output->PanelPwrDly > 2000 || radeon_output->PanelPwrDly < 0) - radeon_output->PanelPwrDly = 2000; - - radeon_output->Flags = 0; + if (lvds->PanelPwrDly > 2000 || lvds->PanelPwrDly < 0) + lvds->PanelPwrDly = 2000; xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "LVDS Info:\n" "XRes: %d, YRes: %d, DotClock: %d\n" "HBlank: %d, HOverPlus: %d, HSyncWidth: %d\n" "VBlank: %d, VOverPlus: %d, VSyncWidth: %d\n", - radeon_output->PanelXRes, radeon_output->PanelYRes, radeon_output->DotClock, - radeon_output->HBlank, radeon_output->HOverPlus, radeon_output->HSyncWidth, - radeon_output->VBlank, radeon_output->VOverPlus, radeon_output->VSyncWidth); - - return TRUE; + native_mode->PanelXRes, native_mode->PanelYRes, native_mode->DotClock, + native_mode->HBlank, native_mode->HOverPlus, native_mode->HSyncWidth, + native_mode->VBlank, native_mode->VOverPlus, native_mode->VSyncWidth); } Bool @@ -1855,6 +1942,7 @@ RADEONGetATOMTVInfo(xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_tvout_ptr tvout = &radeon_output->tvout; ATOM_ANALOG_TV_INFO *tv_info; tv_info = info->atomBIOS->atomDataPtr->AnalogTV_Info.AnalogTV_Info; @@ -1864,51 +1952,51 @@ RADEONGetATOMTVInfo(xf86OutputPtr output) switch(tv_info->ucTV_BootUpDefaultStandard) { case NTSCJ_SUPPORT: - radeon_output->default_tvStd = TV_STD_NTSC_J; + tvout->default_tvStd = TV_STD_NTSC_J; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC-J\n"); break; case PAL_SUPPORT: - radeon_output->default_tvStd = TV_STD_PAL; + tvout->default_tvStd = TV_STD_PAL; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL\n"); break; case PALM_SUPPORT: - radeon_output->default_tvStd = TV_STD_PAL_M; + tvout->default_tvStd = TV_STD_PAL_M; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-M\n"); break; case PAL60_SUPPORT: - radeon_output->default_tvStd = TV_STD_PAL_60; + tvout->default_tvStd = TV_STD_PAL_60; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-60\n"); break; default: case NTSC_SUPPORT: - radeon_output->default_tvStd = TV_STD_NTSC; + tvout->default_tvStd = TV_STD_NTSC; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC\n"); break; } - radeon_output->tvStd = radeon_output->default_tvStd; + tvout->tvStd = tvout->default_tvStd; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standards supported by chip: "); - radeon_output->SupportedTVStds = radeon_output->default_tvStd; + tvout->SupportedTVStds = tvout->default_tvStd; if (tv_info->ucTV_SupportedStandard & NTSC_SUPPORT) { ErrorF("NTSC "); - radeon_output->SupportedTVStds |= TV_STD_NTSC; + tvout->SupportedTVStds |= TV_STD_NTSC; } if (tv_info->ucTV_SupportedStandard & NTSCJ_SUPPORT) { ErrorF("NTSC-J "); - radeon_output->SupportedTVStds |= TV_STD_NTSC_J; + tvout->SupportedTVStds |= TV_STD_NTSC_J; } if (tv_info->ucTV_SupportedStandard & PAL_SUPPORT) { ErrorF("PAL "); - radeon_output->SupportedTVStds |= TV_STD_PAL; + tvout->SupportedTVStds |= TV_STD_PAL; } if (tv_info->ucTV_SupportedStandard & PALM_SUPPORT) { ErrorF("PAL-M "); - radeon_output->SupportedTVStds |= TV_STD_PAL_M; + tvout->SupportedTVStds |= TV_STD_PAL_M; } if (tv_info->ucTV_SupportedStandard & PAL60_SUPPORT) { ErrorF("PAL-60 "); - radeon_output->SupportedTVStds |= TV_STD_PAL_60; + tvout->SupportedTVStds |= TV_STD_PAL_60; } ErrorF("\n"); @@ -1992,7 +2080,84 @@ RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_ return TRUE; } +uint32_t +radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supported_device, int dac) +{ + RADEONInfoPtr info = RADEONPTR (pScrn); + uint32_t ret = 0; + + switch (supported_device) { + case ATOM_DEVICE_CRT1_SUPPORT: + case ATOM_DEVICE_TV1_SUPPORT: + case ATOM_DEVICE_TV2_SUPPORT: + case ATOM_DEVICE_CRT2_SUPPORT: + case ATOM_DEVICE_CV_SUPPORT: + switch (dac) { + // primary dac + case 1: + if ((info->ChipFamily == CHIP_FAMILY_RS300) || + (info->ChipFamily == CHIP_FAMILY_RS400) || + (info->ChipFamily == CHIP_FAMILY_RS480)) + ret = ENCODER_OBJECT_ID_INTERNAL_DAC2; + else if (IS_AVIVO_VARIANT) + ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1; + else + ret = ENCODER_OBJECT_ID_INTERNAL_DAC1; + break; + // secondary dac + case 2: + if (IS_AVIVO_VARIANT) + ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2; + else { + /*if (info->ChipFamily == CHIP_FAMILY_R200) + ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; + else*/ + ret = ENCODER_OBJECT_ID_INTERNAL_DAC2; + } + break; + // external dac + case 3: + if (IS_AVIVO_VARIANT) + ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1; + else + ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; + break; + } + break; + case ATOM_DEVICE_LCD1_SUPPORT: + if (IS_AVIVO_VARIANT) + ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1; + else + ret = ENCODER_OBJECT_ID_INTERNAL_LVDS; + break; + case ATOM_DEVICE_DFP1_SUPPORT: + if ((info->ChipFamily == CHIP_FAMILY_RS300) || + (info->ChipFamily == CHIP_FAMILY_RS400) || + (info->ChipFamily == CHIP_FAMILY_RS480)) + ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; + else if (IS_AVIVO_VARIANT) + ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1; + else + ret = ENCODER_OBJECT_ID_INTERNAL_TMDS1; + break; + case ATOM_DEVICE_LCD2_SUPPORT: + case ATOM_DEVICE_DFP2_SUPPORT: + if ((info->ChipFamily == CHIP_FAMILY_RS600) || + (info->ChipFamily == CHIP_FAMILY_RS690) || + (info->ChipFamily == CHIP_FAMILY_RS740)) + ret = ENCODER_OBJECT_ID_INTERNAL_DDI; + else if (IS_AVIVO_VARIANT) + ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1; + else + ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; + break; + case ATOM_DEVICE_DFP3_SUPPORT: + ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1; + break; + } + return ret; +} Bool RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn) @@ -2049,8 +2214,6 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn) continue; } - info->BiosConnector[i].DACType = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC; - /* don't assign a gpio for tv */ if ((i == ATOM_DEVICE_TV1_INDEX) || (i == ATOM_DEVICE_TV2_INDEX) || @@ -2069,19 +2232,11 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn) info->BiosConnector[i].ddc_i2c = RADEONLookupGPIOLineForDDC(pScrn, ci.sucI2cId.sbfAccess.bfI2C_LineMux); - if (i == ATOM_DEVICE_DFP1_INDEX) - info->BiosConnector[i].TMDSType = TMDS_INT; - else if (i == ATOM_DEVICE_DFP2_INDEX) { - if ((info->ChipFamily == CHIP_FAMILY_RS600) || - (info->ChipFamily == CHIP_FAMILY_RS690) || - (info->ChipFamily == CHIP_FAMILY_RS740)) - info->BiosConnector[i].TMDSType = TMDS_DDIA; - else - info->BiosConnector[i].TMDSType = TMDS_EXT; - } else if (i == ATOM_DEVICE_DFP3_INDEX) - info->BiosConnector[i].TMDSType = TMDS_LVTMA; - else - info->BiosConnector[i].TMDSType = TMDS_NONE; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, (1 << i), + ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC), + (1 << i))) + return FALSE; /* Always set the connector type to VGA for CRT1/CRT2. if they are * shared with a DVI port, we'll pick up the DVI connector below when we @@ -2126,15 +2281,15 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn) if (((i == ATOM_DEVICE_DFP1_INDEX) || (i == ATOM_DEVICE_DFP2_INDEX) || (i == ATOM_DEVICE_DFP3_INDEX)) && - ((j == ATOM_DEVICE_CRT1_INDEX) || (j == ATOM_DEVICE_CRT2_INDEX))) { - info->BiosConnector[i].DACType = info->BiosConnector[j].DACType; + ((j == ATOM_DEVICE_CRT1_INDEX) || + (j == ATOM_DEVICE_CRT2_INDEX))) { info->BiosConnector[i].devices |= info->BiosConnector[j].devices; info->BiosConnector[j].valid = FALSE; } else if (((j == ATOM_DEVICE_DFP1_INDEX) || - (j == ATOM_DEVICE_DFP2_INDEX) || - (j == ATOM_DEVICE_DFP3_INDEX)) && - ((i == ATOM_DEVICE_CRT1_INDEX) || (i == ATOM_DEVICE_CRT2_INDEX))) { - info->BiosConnector[j].DACType = info->BiosConnector[i].DACType; + (j == ATOM_DEVICE_DFP2_INDEX) || + (j == ATOM_DEVICE_DFP3_INDEX)) && + ((i == ATOM_DEVICE_CRT1_INDEX) || + (i == ATOM_DEVICE_CRT2_INDEX))) { info->BiosConnector[j].devices |= info->BiosConnector[i].devices; info->BiosConnector[i].valid = FALSE; } else { @@ -2148,13 +2303,9 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn) } } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n"); for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { - if (info->BiosConnector[i].valid) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-0x%x, DACType-%d, TMDSType-%d, ConnectorType-%d, hpd_mask-0x%x\n", - i, (unsigned int)info->BiosConnector[i].ddc_i2c.mask_clk_reg, info->BiosConnector[i].DACType, - info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType, - info->BiosConnector[i].hpd_mask); + if (info->encoders[i] != NULL) { + ErrorF("encoder: 0x%x\n", info->encoders[i]->encoder_id); } } diff --git a/src/radeon_atombios.h b/src/radeon_atombios.h index a0163598..efebc626 100644 --- a/src/radeon_atombios.h +++ b/src/radeon_atombios.h @@ -125,9 +125,6 @@ atombios_static_pwrmgt_setup(ScrnInfoPtr pScrn, int enable); extern Bool RADEONGetATOMTVInfo(xf86OutputPtr output); -extern Bool -RADEONGetATOMLVDSInfo(xf86OutputPtr output); - extern int atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode); @@ -269,4 +266,13 @@ typedef struct _atomBiosHandle { extern Bool RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, int32_t *pixel_clock); +extern uint32_t +radeon_get_device_index(uint32_t device_support); +extern radeon_encoder_ptr +radeon_get_encoder(xf86OutputPtr output); +extern Bool +radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_support); +extern uint32_t +radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supported_device, int dac); + #endif /* RHD_ATOMBIOS_H_ */ diff --git a/src/radeon_bios.c b/src/radeon_bios.c index 37954d35..6fc0cf4f 100644 --- a/src/radeon_bios.c +++ b/src/radeon_bios.c @@ -441,16 +441,6 @@ static void RADEONApplyLegacyQuirks(ScrnInfoPtr pScrn, int index) { RADEONInfoPtr info = RADEONPTR (pScrn); - /* For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC - * Also there is no internal TMDS - */ - if ((info->ChipFamily == CHIP_FAMILY_RS300) || - (info->ChipFamily == CHIP_FAMILY_RS400) || - (info->ChipFamily == CHIP_FAMILY_RS480)) { - info->BiosConnector[index].DACType = DAC_TVDAC; - info->BiosConnector[index].TMDSType = TMDS_EXT; - } - /* XPRESS DDC quirks */ if ((info->ChipFamily == CHIP_FAMILY_RS400 || info->ChipFamily == CHIP_FAMILY_RS480) && @@ -513,7 +503,7 @@ static void RADEONApplyLegacyQuirks(ScrnInfoPtr pScrn, int index) if (info->Chipset == PCI_CHIP_R200_QL && PCI_SUB_VENDOR_ID(info->PciInfo) == 0x1569 && PCI_SUB_DEVICE_ID(info->PciInfo) == 0x514c && - info->BiosConnector[index].DACType == DAC_PRIMARY) { + (info->BiosConnector[index].devices & ATOM_DEVICE_CRT1_SUPPORT)) { info->BiosConnector[index].load_detection = FALSE; } @@ -543,21 +533,126 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn) switch (ConnectorType) { case CONNECTOR_PROPRIETARY_LEGACY: info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_D; + if ((tmp >> 4) & 0x1) { + info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP2_SUPPORT, + 0), + ATOM_DEVICE_DFP2_SUPPORT)) + return FALSE; + } else { + info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP1_SUPPORT, + 0), + ATOM_DEVICE_DFP1_SUPPORT)) + return FALSE; + } break; case CONNECTOR_CRT_LEGACY: info->BiosConnector[i].ConnectorType = CONNECTOR_VGA; + if (tmp & 0x1) { + info->BiosConnector[i].load_detection = FALSE; + info->BiosConnector[i].devices |= ATOM_DEVICE_CRT2_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT2_SUPPORT, + 2), + ATOM_DEVICE_CRT2_SUPPORT)) + return FALSE; + } else { + info->BiosConnector[i].load_detection = TRUE; + info->BiosConnector[i].devices |= ATOM_DEVICE_CRT1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT)) + return FALSE; + } break; case CONNECTOR_DVI_I_LEGACY: info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_I; + if (tmp & 0x1) { + info->BiosConnector[i].load_detection = FALSE; + info->BiosConnector[i].devices |= ATOM_DEVICE_CRT2_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT2_SUPPORT, + 2), + ATOM_DEVICE_CRT2_SUPPORT)) + return FALSE; + } else { + info->BiosConnector[i].load_detection = TRUE; + info->BiosConnector[i].devices |= ATOM_DEVICE_CRT1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT)) + return FALSE; + } + if ((tmp >> 4) & 0x1) { + info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP2_SUPPORT, + 0), + ATOM_DEVICE_DFP2_SUPPORT)) + return FALSE; + } else { + info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP1_SUPPORT, + 0), + ATOM_DEVICE_DFP1_SUPPORT)) + return FALSE; + } break; case CONNECTOR_DVI_D_LEGACY: info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_D; + if ((tmp >> 4) & 0x1) { + info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP2_SUPPORT, + 0), + ATOM_DEVICE_DFP2_SUPPORT)) + return FALSE; + } else { + info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP1_SUPPORT, + 0), + ATOM_DEVICE_DFP1_SUPPORT)) + return FALSE; + } break; case CONNECTOR_CTV_LEGACY: info->BiosConnector[i].ConnectorType = CONNECTOR_CTV; + info->BiosConnector[i].load_detection = FALSE; + info->BiosConnector[i].devices = ATOM_DEVICE_TV1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_TV1_SUPPORT, + 2), + ATOM_DEVICE_TV1_SUPPORT)) + return FALSE; break; case CONNECTOR_STV_LEGACY: info->BiosConnector[i].ConnectorType = CONNECTOR_STV; + info->BiosConnector[i].load_detection = FALSE; + info->BiosConnector[i].devices = ATOM_DEVICE_TV1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_TV1_SUPPORT, + 2), + ATOM_DEVICE_TV1_SUPPORT)) + return FALSE; break; default: xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown Connector Type: %d\n", ConnectorType); @@ -586,21 +681,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn) break; } - if (tmp & 0x1) - info->BiosConnector[i].DACType = DAC_TVDAC; - else - info->BiosConnector[i].DACType = DAC_PRIMARY; - - if ((tmp >> 4) & 0x1) - info->BiosConnector[i].TMDSType = TMDS_EXT; - else - info->BiosConnector[i].TMDSType = TMDS_INT; - - if (info->BiosConnector[i].DACType == DAC_TVDAC) - info->BiosConnector[i].load_detection = FALSE; - else - info->BiosConnector[i].load_detection = TRUE; - RADEONApplyLegacyQuirks(pScrn, i); } @@ -616,9 +696,21 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn) "Found DFP table, assuming DVI connector\n"); info->BiosConnector[0].valid = TRUE; info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I; - info->BiosConnector[0].DACType = DAC_PRIMARY; - info->BiosConnector[0].TMDSType = TMDS_INT; + info->BiosConnector[0].load_detection = TRUE; info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); + info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP1_SUPPORT, + 0), + ATOM_DEVICE_DFP1_SUPPORT)) + return FALSE; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT)) + return FALSE; } else return FALSE; } @@ -630,10 +722,16 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn) if (offset) { info->BiosConnector[4].valid = TRUE; info->BiosConnector[4].ConnectorType = CONNECTOR_LVDS; - info->BiosConnector[4].DACType = DAC_NONE; - info->BiosConnector[4].TMDSType = TMDS_NONE; info->BiosConnector[4].ddc_i2c.valid = FALSE; + info->BiosConnector[4].devices = ATOM_DEVICE_LCD1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_LCD1_SUPPORT, + 0), + ATOM_DEVICE_LCD1_SUPPORT)) + return FALSE; + tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42); if (tmp) { tmp0 = RADEON_BIOS16(tmp + 0x15); @@ -696,23 +794,19 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn) info->BiosConnector[5].valid = TRUE; /* assume s-video for now */ info->BiosConnector[5].ConnectorType = CONNECTOR_STV; - info->BiosConnector[5].DACType = DAC_TVDAC; info->BiosConnector[5].load_detection = FALSE; - info->BiosConnector[5].TMDSType = TMDS_NONE; info->BiosConnector[5].ddc_i2c.valid = FALSE; + info->BiosConnector[5].devices = ATOM_DEVICE_TV1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_TV1_SUPPORT, + 2), + ATOM_DEVICE_TV1_SUPPORT)) + return FALSE; } } } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n"); - for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) { - if (info->BiosConnector[i].valid) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-0x%x, DACType-%d, TMDSType-%d, ConnectorType-%d\n", - i, (unsigned int)info->BiosConnector[i].ddc_i2c.mask_clk_reg, info->BiosConnector[i].DACType, - info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType); - } - } - return TRUE; } @@ -732,83 +826,84 @@ Bool RADEONGetTVInfoFromBIOS (xf86OutputPtr output) { ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_tvout_ptr tvout = &radeon_output->tvout; int offset, refclk, stds; if (!info->VBIOS) return FALSE; - if (info->IsAtomBios) { + if (info->IsAtomBios) return RADEONGetATOMTVInfo(output); - } else { + else { offset = RADEON_BIOS16(info->ROMHeaderStart + 0x32); if (offset) { if (RADEON_BIOS8(offset + 6) == 'T') { switch (RADEON_BIOS8(offset + 7) & 0xf) { case 1: - radeon_output->default_tvStd = TV_STD_NTSC; + tvout->default_tvStd = TV_STD_NTSC; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC\n"); break; case 2: - radeon_output->default_tvStd = TV_STD_PAL; + tvout->default_tvStd = TV_STD_PAL; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL\n"); break; case 3: - radeon_output->default_tvStd = TV_STD_PAL_M; + tvout->default_tvStd = TV_STD_PAL_M; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-M\n"); break; case 4: - radeon_output->default_tvStd = TV_STD_PAL_60; + tvout->default_tvStd = TV_STD_PAL_60; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-60\n"); break; case 5: - radeon_output->default_tvStd = TV_STD_NTSC_J; + tvout->default_tvStd = TV_STD_NTSC_J; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC-J\n"); break; case 6: - radeon_output->default_tvStd = TV_STD_SCART_PAL; + tvout->default_tvStd = TV_STD_SCART_PAL; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: SCART-PAL\n"); break; default: - radeon_output->default_tvStd = TV_STD_NTSC; + tvout->default_tvStd = TV_STD_NTSC; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Unknown TV standard; defaulting to NTSC\n"); break; } - radeon_output->tvStd = radeon_output->default_tvStd; + tvout->tvStd = tvout->default_tvStd; refclk = (RADEON_BIOS8(offset + 9) >> 2) & 0x3; if (refclk == 0) - radeon_output->TVRefClk = 29.498928713; /* MHz */ + tvout->TVRefClk = 29.498928713; /* MHz */ else if (refclk == 1) - radeon_output->TVRefClk = 28.636360000; + tvout->TVRefClk = 28.636360000; else if (refclk == 2) - radeon_output->TVRefClk = 14.318180000; + tvout->TVRefClk = 14.318180000; else if (refclk == 3) - radeon_output->TVRefClk = 27.000000000; + tvout->TVRefClk = 27.000000000; - radeon_output->SupportedTVStds = radeon_output->default_tvStd; + tvout->SupportedTVStds = tvout->default_tvStd; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standards supported by chip: "); stds = RADEON_BIOS8(offset + 10) & 0x1f; if (stds & TV_STD_NTSC) { - radeon_output->SupportedTVStds |= TV_STD_NTSC; + tvout->SupportedTVStds |= TV_STD_NTSC; ErrorF("NTSC "); } if (stds & TV_STD_PAL) { - radeon_output->SupportedTVStds |= TV_STD_PAL; + tvout->SupportedTVStds |= TV_STD_PAL; ErrorF("PAL "); } if (stds & TV_STD_PAL_M) { - radeon_output->SupportedTVStds |= TV_STD_PAL_M; + tvout->SupportedTVStds |= TV_STD_PAL_M; ErrorF("PAL-M "); } if (stds & TV_STD_PAL_60) { - radeon_output->SupportedTVStds |= TV_STD_PAL_60; + tvout->SupportedTVStds |= TV_STD_PAL_60; ErrorF("PAL-60 "); } if (stds & TV_STD_NTSC_J) { - radeon_output->SupportedTVStds |= TV_STD_NTSC_J; + tvout->SupportedTVStds |= TV_STD_NTSC_J; ErrorF("NTSC-J "); } if (stds & TV_STD_SCART_PAL) { - radeon_output->SupportedTVStds |= TV_STD_SCART_PAL; + tvout->SupportedTVStds |= TV_STD_SCART_PAL; ErrorF("SCART-PAL"); } ErrorF("\n"); @@ -896,11 +991,9 @@ Bool RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn) return TRUE; } -Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output) +Bool RADEONGetDAC2InfoFromBIOS (ScrnInfoPtr pScrn, radeon_tvdac_ptr tvdac) { - ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONOutputPrivatePtr radeon_output = output->driver_private; int offset, rev, bg, dac; if (!info->VBIOS) return FALSE; @@ -919,29 +1012,29 @@ Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output) if (rev > 4) { bg = RADEON_BIOS8(offset + 0xc) & 0xf; dac = RADEON_BIOS8(offset + 0xd) & 0xf; - radeon_output->ps2_tvdac_adj = (bg << 16) | (dac << 20); + tvdac->ps2_tvdac_adj = (bg << 16) | (dac << 20); bg = RADEON_BIOS8(offset + 0xe) & 0xf; dac = RADEON_BIOS8(offset + 0xf) & 0xf; - radeon_output->pal_tvdac_adj = (bg << 16) | (dac << 20); + tvdac->pal_tvdac_adj = (bg << 16) | (dac << 20); bg = RADEON_BIOS8(offset + 0x10) & 0xf; dac = RADEON_BIOS8(offset + 0x11) & 0xf; - radeon_output->ntsc_tvdac_adj = (bg << 16) | (dac << 20); + tvdac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); return TRUE; } else if (rev > 1) { bg = RADEON_BIOS8(offset + 0xc) & 0xf; dac = (RADEON_BIOS8(offset + 0xc) >> 4) & 0xf; - radeon_output->ps2_tvdac_adj = (bg << 16) | (dac << 20); + tvdac->ps2_tvdac_adj = (bg << 16) | (dac << 20); bg = RADEON_BIOS8(offset + 0xd) & 0xf; dac = (RADEON_BIOS8(offset + 0xd) >> 4) & 0xf; - radeon_output->pal_tvdac_adj = (bg << 16) | (dac << 20); + tvdac->pal_tvdac_adj = (bg << 16) | (dac << 20); bg = RADEON_BIOS8(offset + 0xe) & 0xf; dac = (RADEON_BIOS8(offset + 0xe) >> 4) & 0xf; - radeon_output->ntsc_tvdac_adj = (bg << 16) | (dac << 20); + tvdac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); return TRUE; } @@ -953,17 +1046,17 @@ Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output) if (rev < 2) { bg = RADEON_BIOS8(offset + 0x3) & 0xf; dac = (RADEON_BIOS8(offset + 0x3) >> 4) & 0xf; - radeon_output->ps2_tvdac_adj = (bg << 16) | (dac << 20); - radeon_output->pal_tvdac_adj = radeon_output->ps2_tvdac_adj; - radeon_output->ntsc_tvdac_adj = radeon_output->ps2_tvdac_adj; + tvdac->ps2_tvdac_adj = (bg << 16) | (dac << 20); + tvdac->pal_tvdac_adj = tvdac->ps2_tvdac_adj; + tvdac->ntsc_tvdac_adj = tvdac->ps2_tvdac_adj; return TRUE; } else { bg = RADEON_BIOS8(offset + 0x4) & 0xf; dac = RADEON_BIOS8(offset + 0x5) & 0xf; - radeon_output->ps2_tvdac_adj = (bg << 16) | (dac << 20); - radeon_output->pal_tvdac_adj = radeon_output->ps2_tvdac_adj; - radeon_output->ntsc_tvdac_adj = radeon_output->ps2_tvdac_adj; + tvdac->ps2_tvdac_adj = (bg << 16) | (dac << 20); + tvdac->pal_tvdac_adj = tvdac->ps2_tvdac_adj; + tvdac->ntsc_tvdac_adj = tvdac->ps2_tvdac_adj; return TRUE; } @@ -973,19 +1066,17 @@ Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output) return FALSE; } -Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output) +Bool +RADEONGetLVDSInfoFromBIOS(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds) { - ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_native_mode_ptr native_mode = &lvds->native_mode; unsigned long tmp, i; - if (!info->VBIOS) return FALSE; - - if (info->IsAtomBios) - return RADEONGetATOMLVDSInfo(output); - else { + if (!info->VBIOS) + return FALSE; + if (!info->IsAtomBios) { tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x40); if (!tmp) { @@ -1003,14 +1094,14 @@ Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel ID string: %s\n", stmp); - radeon_output->PanelXRes = RADEON_BIOS16(tmp+25); - radeon_output->PanelYRes = RADEON_BIOS16(tmp+27); + native_mode->PanelXRes = RADEON_BIOS16(tmp+25); + native_mode->PanelYRes = RADEON_BIOS16(tmp+27); xf86DrvMsg(0, X_INFO, "Panel Size from BIOS: %dx%d\n", - radeon_output->PanelXRes, radeon_output->PanelYRes); + native_mode->PanelXRes, native_mode->PanelYRes); - radeon_output->PanelPwrDly = RADEON_BIOS16(tmp+44); - if (radeon_output->PanelPwrDly > 2000 || radeon_output->PanelPwrDly < 0) - radeon_output->PanelPwrDly = 2000; + lvds->PanelPwrDly = RADEON_BIOS16(tmp+44); + if (lvds->PanelPwrDly > 2000 || lvds->PanelPwrDly < 0) + lvds->PanelPwrDly = 2000; /* some panels only work well with certain divider combinations. */ @@ -1031,35 +1122,36 @@ Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output) for (i = 0; i < 32; i++) { tmp0 = RADEON_BIOS16(tmp+64+i*2); if (tmp0 == 0) break; - if ((RADEON_BIOS16(tmp0) == radeon_output->PanelXRes) && - (RADEON_BIOS16(tmp0+2) == radeon_output->PanelYRes)) { - radeon_output->HBlank = (RADEON_BIOS16(tmp0+17) - - RADEON_BIOS16(tmp0+19)) * 8; - radeon_output->HOverPlus = (RADEON_BIOS16(tmp0+21) - - RADEON_BIOS16(tmp0+19) - 1) * 8; - radeon_output->HSyncWidth = RADEON_BIOS8(tmp0+23) * 8; - radeon_output->VBlank = (RADEON_BIOS16(tmp0+24) - - RADEON_BIOS16(tmp0+26)); - radeon_output->VOverPlus = ((RADEON_BIOS16(tmp0+28) & 0x7ff) - - RADEON_BIOS16(tmp0+26)); - radeon_output->VSyncWidth = ((RADEON_BIOS16(tmp0+28) & 0xf800) >> 11); - radeon_output->DotClock = RADEON_BIOS16(tmp0+9) * 10; - radeon_output->Flags = 0; + if ((RADEON_BIOS16(tmp0) == native_mode->PanelXRes) && + (RADEON_BIOS16(tmp0+2) == native_mode->PanelYRes)) { + native_mode->HBlank = (RADEON_BIOS16(tmp0+17) - + RADEON_BIOS16(tmp0+19)) * 8; + native_mode->HOverPlus = (RADEON_BIOS16(tmp0+21) - + RADEON_BIOS16(tmp0+19) - 1) * 8; + native_mode->HSyncWidth = RADEON_BIOS8(tmp0+23) * 8; + native_mode->VBlank = (RADEON_BIOS16(tmp0+24) - + RADEON_BIOS16(tmp0+26)); + native_mode->VOverPlus = ((RADEON_BIOS16(tmp0+28) & 0x7ff) - + RADEON_BIOS16(tmp0+26)); + native_mode->VSyncWidth = ((RADEON_BIOS16(tmp0+28) & 0xf800) >> 11); + native_mode->DotClock = RADEON_BIOS16(tmp0+9) * 10; + native_mode->Flags = 0; } } } - } - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "LVDS Info:\n" - "XRes: %d, YRes: %d, DotClock: %d\n" - "HBlank: %d, HOverPlus: %d, HSyncWidth: %d\n" - "VBlank: %d, VOverPlus: %d, VSyncWidth: %d\n", - radeon_output->PanelXRes, radeon_output->PanelYRes, radeon_output->DotClock, - radeon_output->HBlank, radeon_output->HOverPlus, radeon_output->HSyncWidth, - radeon_output->VBlank, radeon_output->VOverPlus, radeon_output->VSyncWidth); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "LVDS Info:\n" + "XRes: %d, YRes: %d, DotClock: %d\n" + "HBlank: %d, HOverPlus: %d, HSyncWidth: %d\n" + "VBlank: %d, VOverPlus: %d, VSyncWidth: %d\n", + native_mode->PanelXRes, native_mode->PanelYRes, native_mode->DotClock, + native_mode->HBlank, native_mode->HOverPlus, native_mode->HSyncWidth, + native_mode->VBlank, native_mode->VOverPlus, native_mode->VSyncWidth); - return TRUE; + return TRUE; + } + return FALSE; } xf86MonPtr RADEONGetHardCodedEDIDFromBIOS (xf86OutputPtr output) @@ -1085,11 +1177,9 @@ xf86MonPtr RADEONGetHardCodedEDIDFromBIOS (xf86OutputPtr output) return mon; } -Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output) +Bool RADEONGetTMDSInfoFromBIOS (ScrnInfoPtr pScrn, radeon_tmds_ptr tmds) { - ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONOutputPrivatePtr radeon_output = output->driver_private; uint32_t tmp, maxfreq; int i, n; @@ -1099,21 +1189,21 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output) if((tmp = RADEON_BIOS16 (info->MasterDataStart + 18))) { maxfreq = RADEON_BIOS16(tmp+4); - + for (i=0; i<4; i++) { - radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*6+6); + tmds->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*6+6); /* This assumes each field in TMDS_PLL has 6 bit as in R300/R420 */ - radeon_output->tmds_pll[i].value = ((RADEON_BIOS8(tmp+i*6+8) & 0x3f) | + tmds->tmds_pll[i].value = ((RADEON_BIOS8(tmp+i*6+8) & 0x3f) | ((RADEON_BIOS8(tmp+i*6+10) & 0x3f)<<6) | ((RADEON_BIOS8(tmp+i*6+9) & 0xf)<<12) | ((RADEON_BIOS8(tmp+i*6+11) & 0xf)<<16)); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "TMDS PLL from BIOS: %u %x\n", - (unsigned)radeon_output->tmds_pll[i].freq, - (unsigned)radeon_output->tmds_pll[i].value); - - if (maxfreq == radeon_output->tmds_pll[i].freq) { - radeon_output->tmds_pll[i].freq = 0xffffffff; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "TMDS PLL from BIOS: %u %x\n", + (unsigned)tmds->tmds_pll[i].freq, + (unsigned)tmds->tmds_pll[i].value); + + if (maxfreq == tmds->tmds_pll[i].freq) { + tmds->tmds_pll[i].freq = 0xffffffff; break; } } @@ -1129,8 +1219,8 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output) n = RADEON_BIOS8(tmp + 5) + 1; if (n > 4) n = 4; for (i=0; i<n; i++) { - radeon_output->tmds_pll[i].value = RADEON_BIOS32(tmp+i*10+0x08); - radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*10+0x10); + tmds->tmds_pll[i].value = RADEON_BIOS32(tmp+i*10+0x08); + tmds->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*10+0x10); } return TRUE; } else if (RADEON_BIOS8(tmp) == 4) { @@ -1138,8 +1228,8 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output) n = RADEON_BIOS8(tmp + 5) + 1; if (n > 4) n = 4; for (i=0; i<n; i++) { - radeon_output->tmds_pll[i].value = RADEON_BIOS32(tmp+stride+0x08); - radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+stride+0x10); + tmds->tmds_pll[i].value = RADEON_BIOS32(tmp+stride+0x08); + tmds->tmds_pll[i].freq = RADEON_BIOS16(tmp+stride+0x10); if (i == 0) stride += 10; else stride += 6; } @@ -1194,18 +1284,17 @@ RADEONLookupI2CBlock(ScrnInfoPtr pScrn, int id) return i2c; } -Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output) +Bool RADEONGetExtTMDSInfoFromBIOS (ScrnInfoPtr pScrn, radeon_dvo_ptr dvo) { - ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONOutputPrivatePtr radeon_output = output->driver_private; int offset, table_start, max_freq, gpio_reg, flags; - if (!info->VBIOS) return FALSE; + if (!info->VBIOS) + return FALSE; - if (info->IsAtomBios) { + if (info->IsAtomBios) return FALSE; - } else if (info->IsIGP) { + else if (info->IsIGP) { /* RS4xx TMDS stuff is in the mobile table */ offset = RADEON_BIOS16(info->ROMHeaderStart + 0x42); if (offset) { @@ -1218,7 +1307,7 @@ Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output) if (offset && (rev > 1)) { int blocks = RADEON_BIOS8(offset + 3); int index = offset + 4; - radeon_output->dvo_i2c.valid = FALSE; + dvo->dvo_i2c.valid = FALSE; while (blocks > 0) { int id = RADEON_BIOS16(index); index += 2; @@ -1236,10 +1325,10 @@ Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output) index += 2; break; case 6: - radeon_output->dvo_i2c_slave_addr = + dvo->dvo_i2c_slave_addr = RADEON_BIOS16(index) & 0xff; index += 2; - radeon_output->dvo_i2c = + dvo->dvo_i2c = RADEONLookupI2CBlock(pScrn, RADEON_BIOS8(index)); return TRUE; default: @@ -1259,17 +1348,17 @@ Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output) RADEON_BIOS8(offset)); table_start = offset+4; max_freq = RADEON_BIOS16(table_start); - radeon_output->dvo_i2c_slave_addr = RADEON_BIOS8(table_start+2); - radeon_output->dvo_i2c.valid = FALSE; + dvo->dvo_i2c_slave_addr = RADEON_BIOS8(table_start+2); + dvo->dvo_i2c.valid = FALSE; gpio_reg = RADEON_BIOS8(table_start+3); if (gpio_reg == 1) - radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); + dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); else if (gpio_reg == 2) - radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); + dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); else if (gpio_reg == 3) - radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); + dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); else if (gpio_reg == 4) - radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); + dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); else if (gpio_reg == 5) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "unsupported MM gpio_reg\n"); @@ -1280,8 +1369,8 @@ Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output) return FALSE; } flags = RADEON_BIOS8(table_start+5); - radeon_output->dvo_duallink = flags & 0x01; - if (radeon_output->dvo_duallink) { + dvo->dvo_duallink = flags & 0x01; + if (dvo->dvo_duallink) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Duallink TMDS detected\n"); } @@ -1300,15 +1389,25 @@ Bool RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); + radeon_dvo_ptr dvo = NULL; int offset, index, id; uint32_t val, reg, and_mask, or_mask; - if (!info->VBIOS) return FALSE; + if (radeon_encoder == NULL) + return FALSE; - if (info->IsAtomBios) { + dvo = (radeon_dvo_ptr)radeon_encoder->dev_priv; + + if (dvo == NULL) + return FALSE; + + if (!info->VBIOS) + return FALSE; + + if (info->IsAtomBios) return FALSE; - } else if (info->IsIGP) { + else if (info->IsIGP) { /* RS4xx TMDS stuff is in the mobile table */ offset = RADEON_BIOS16(info->ROMHeaderStart + 0x42); if (offset) { @@ -1365,7 +1464,7 @@ Bool RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output) index++; ErrorF("i2c write: 0x%x, 0x%x\n", (unsigned)reg, (unsigned)val); - RADEONDVOWriteByte(radeon_output->DVOChip, reg, val); + RADEONDVOWriteByte(dvo->DVOChip, reg, val); break; default: ErrorF("unknown id %d\n", id>>13); @@ -1430,7 +1529,7 @@ Bool RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output) index += 1; ErrorF("i2c write: 0x%x, 0x%x\n", (unsigned)reg, (unsigned)val); - RADEONDVOWriteByte(radeon_output->DVOChip, reg, val); + RADEONDVOWriteByte(dvo->DVOChip, reg, val); break; default: ErrorF("unknown id %d\n", id>>13); diff --git a/src/radeon_modes.c b/src/radeon_modes.c index ed2fee20..e06f8ddf 100644 --- a/src/radeon_modes.c +++ b/src/radeon_modes.c @@ -131,28 +131,29 @@ static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output) { ScrnInfoPtr pScrn = output->scrn; RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_native_mode_ptr native_mode = &radeon_output->native_mode; DisplayModePtr new = NULL; char stmp[32]; - if (radeon_output->PanelXRes != 0 && - radeon_output->PanelYRes != 0 && - radeon_output->DotClock != 0) { + if (native_mode->PanelXRes != 0 && + native_mode->PanelYRes != 0 && + native_mode->DotClock != 0) { new = xnfcalloc(1, sizeof (DisplayModeRec)); - sprintf(stmp, "%dx%d", radeon_output->PanelXRes, radeon_output->PanelYRes); + sprintf(stmp, "%dx%d", native_mode->PanelXRes, native_mode->PanelYRes); new->name = xnfalloc(strlen(stmp) + 1); strcpy(new->name, stmp); - new->HDisplay = radeon_output->PanelXRes; - new->VDisplay = radeon_output->PanelYRes; + new->HDisplay = native_mode->PanelXRes; + new->VDisplay = native_mode->PanelYRes; - new->HTotal = new->HDisplay + radeon_output->HBlank; - new->HSyncStart = new->HDisplay + radeon_output->HOverPlus; - new->HSyncEnd = new->HSyncStart + radeon_output->HSyncWidth; - new->VTotal = new->VDisplay + radeon_output->VBlank; - new->VSyncStart = new->VDisplay + radeon_output->VOverPlus; - new->VSyncEnd = new->VSyncStart + radeon_output->VSyncWidth; + new->HTotal = new->HDisplay + native_mode->HBlank; + new->HSyncStart = new->HDisplay + native_mode->HOverPlus; + new->HSyncEnd = new->HSyncStart + native_mode->HSyncWidth; + new->VTotal = new->VDisplay + native_mode->VBlank; + new->VSyncStart = new->VDisplay + native_mode->VOverPlus; + new->VSyncEnd = new->VSyncStart + native_mode->VSyncWidth; - new->Clock = radeon_output->DotClock; + new->Clock = native_mode->DotClock; new->Flags = 0; if (new) { @@ -163,7 +164,7 @@ static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output) } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Added native panel mode: %dx%d\n", - radeon_output->PanelXRes, radeon_output->PanelYRes); + native_mode->PanelXRes, native_mode->PanelYRes); } return new; @@ -233,6 +234,7 @@ static void RADEONAddScreenModes(xf86OutputPtr output, DisplayModePtr *modeList) { ScrnInfoPtr pScrn = output->scrn; RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_native_mode_ptr native_mode = &radeon_output->native_mode; DisplayModePtr last = NULL; DisplayModePtr new = NULL; DisplayModePtr first = NULL; @@ -249,9 +251,9 @@ static void RADEONAddScreenModes(xf86OutputPtr output, DisplayModePtr *modeList) if (sscanf(ppModeName[i], "%dx%d", &width, &height) != 2) continue; - if (radeon_output->type == OUTPUT_LVDS) { + if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { /* already added the native mode */ - if (width == radeon_output->PanelXRes && height == radeon_output->PanelYRes) + if (width == native_mode->PanelXRes && height == native_mode->PanelYRes) continue; /* Note: We allow all non-standard modes as long as they do not @@ -259,13 +261,13 @@ static void RADEONAddScreenModes(xf86OutputPtr output, DisplayModePtr *modeList) * need the internal RMX unit in the video chips (and there is * only one per card), this will only apply to the primary head. */ - if (width < 320 || width > radeon_output->PanelXRes || - height < 200 || height > radeon_output->PanelYRes) { + if (width < 320 || width > native_mode->PanelXRes || + height < 200 || height > native_mode->PanelYRes) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Mode %s is out of range.\n", ppModeName[i]); xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Valid FP modes must be between 320x200-%dx%d\n", - radeon_output->PanelXRes, radeon_output->PanelYRes); + native_mode->PanelXRes, native_mode->PanelYRes); continue; } } @@ -299,6 +301,116 @@ static void RADEONAddScreenModes(xf86OutputPtr output, DisplayModePtr *modeList) } +/* BIOS may not have right panel size, we search through all supported + * DDC modes looking for the maximum panel size. + */ +static void +RADEONUpdatePanelSize(xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_native_mode_ptr native_mode = &radeon_output->native_mode; + int j; + xf86MonPtr ddc = output->MonInfo; + DisplayModePtr p; + + // update output's native mode + if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { + radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); + if (radeon_encoder) { + radeon_lvds_ptr lvds = (radeon_lvds_ptr)radeon_encoder->dev_priv; + if (lvds) + radeon_output->native_mode = lvds->native_mode; + } + } + + // crtc should handle? + if ((info->UseBiosDividers && native_mode->DotClock != 0) || (ddc == NULL)) + return; + + /* Go thru detailed timing table first */ + for (j = 0; j < 4; j++) { + if (ddc->det_mon[j].type == 0) { + struct detailed_timings *d_timings = + &ddc->det_mon[j].section.d_timings; + int match = 0; + + /* If we didn't get a panel clock or guessed one, try to match the + * mode with the panel size. We do that because we _need_ a panel + * clock, or ValidateFPModes will fail, even when UseBiosDividers + * is set. + */ + if (native_mode->DotClock == 0 && + native_mode->PanelXRes == d_timings->h_active && + native_mode->PanelYRes == d_timings->v_active) + match = 1; + + /* If we don't have a BIOS provided panel data with fixed dividers, + * check for a larger panel size + */ + if (native_mode->PanelXRes < d_timings->h_active && + native_mode->PanelYRes < d_timings->v_active && + !info->UseBiosDividers) + match = 1; + + if (match) { + native_mode->PanelXRes = d_timings->h_active; + native_mode->PanelYRes = d_timings->v_active; + native_mode->DotClock = d_timings->clock / 1000; + native_mode->HOverPlus = d_timings->h_sync_off; + native_mode->HSyncWidth = d_timings->h_sync_width; + native_mode->HBlank = d_timings->h_blanking; + native_mode->VOverPlus = d_timings->v_sync_off; + native_mode->VSyncWidth = d_timings->v_sync_width; + native_mode->VBlank = d_timings->v_blanking; + native_mode->Flags = (d_timings->interlaced ? V_INTERLACE : 0); + switch (d_timings->misc) { + case 0: native_mode->Flags |= V_NHSYNC | V_NVSYNC; break; + case 1: native_mode->Flags |= V_PHSYNC | V_NVSYNC; break; + case 2: native_mode->Flags |= V_NHSYNC | V_PVSYNC; break; + case 3: native_mode->Flags |= V_PHSYNC | V_PVSYNC; break; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC detailed: %dx%d\n", + native_mode->PanelXRes, native_mode->PanelYRes); + } + } + } + + if (info->UseBiosDividers && native_mode->DotClock != 0) + return; + + /* Search thru standard VESA modes from EDID */ + for (j = 0; j < 8; j++) { + if ((native_mode->PanelXRes < ddc->timings2[j].hsize) && + (native_mode->PanelYRes < ddc->timings2[j].vsize)) { + for (p = pScrn->monitor->Modes; p; p = p->next) { + if ((ddc->timings2[j].hsize == p->HDisplay) && + (ddc->timings2[j].vsize == p->VDisplay)) { + float refresh = + (float)p->Clock * 1000.0 / p->HTotal / p->VTotal; + + if (abs((float)ddc->timings2[j].refresh - refresh) < 1.0) { + /* Is this good enough? */ + native_mode->PanelXRes = ddc->timings2[j].hsize; + native_mode->PanelYRes = ddc->timings2[j].vsize; + native_mode->HBlank = p->HTotal - p->HDisplay; + native_mode->HOverPlus = p->HSyncStart - p->HDisplay; + native_mode->HSyncWidth = p->HSyncEnd - p->HSyncStart; + native_mode->VBlank = p->VTotal - p->VDisplay; + native_mode->VOverPlus = p->VSyncStart - p->VDisplay; + native_mode->VSyncWidth = p->VSyncEnd - p->VSyncStart; + native_mode->DotClock = p->Clock; + native_mode->Flags = p->Flags; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC VESA/EDID: %dx%d\n", + native_mode->PanelXRes, native_mode->PanelYRes); + } + } + } + } + } +} + DisplayModePtr RADEONProbeOutputModes(xf86OutputPtr output) { @@ -309,31 +421,31 @@ RADEONProbeOutputModes(xf86OutputPtr output) AtomBiosArgRec atomBiosArg; AtomBiosResult atomBiosResult; - ErrorF("in RADEONProbeOutputModes\n"); - if (output->status == XF86OutputStatusConnected) { - if (OUTPUT_IS_TV) { + if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) { if (IS_AVIVO_VARIANT) modes = RADEONATOMTVModes(output); else modes = RADEONTVModes(output); - } else if (radeon_output->type == OUTPUT_CV) { + } else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) { atomBiosResult = RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS, ATOMBIOS_GET_CV_MODES, &atomBiosArg); if (atomBiosResult == ATOM_SUCCESS) { modes = atomBiosArg.modes; } } else { + if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) + RADEONUpdatePanelSize(output); if (output->MonInfo) modes = xf86OutputGetEDIDModes (output); #if defined(__powerpc__) if ((info->MacModel == RADEON_MAC_EMAC) && - (radeon_output->DACType == DAC_PRIMARY) && + (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) && (modes == NULL)) modes = RADEONeMacModes(output); #endif if (modes == NULL) { - if ((radeon_output->type == OUTPUT_LVDS) && info->IsAtomBios) { + if ((radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) && info->IsAtomBios) { atomBiosResult = RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS, ATOMBIOS_GET_PANEL_EDID, &atomBiosArg); @@ -344,7 +456,7 @@ RADEONProbeOutputModes(xf86OutputPtr output) } } if (modes == NULL) { - if (radeon_output->type == OUTPUT_LVDS) + if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) modes = RADEONFPNativeMode(output); /* add the screen modes */ RADEONAddScreenModes(output, &modes); diff --git a/src/radeon_output.c b/src/radeon_output.c index dae4e1b7..ba4cb7f1 100644 --- a/src/radeon_output.c +++ b/src/radeon_output.c @@ -48,46 +48,41 @@ #include "radeon_tv.h" #include "radeon_atombios.h" -const char *MonTypeName[10] = { - "AUTO", - "NONE", - "CRT", - "LVDS", - "TMDS", - "CTV", - "STV", - "CV", - "HDMI", - "DP" -}; - -const RADEONMonitorType MonTypeID[10] = { - MT_UNKNOWN, /* this is just a dummy value for AUTO DETECTION */ - MT_NONE, /* NONE -> NONE */ - MT_CRT, /* CRT -> CRT */ - MT_LCD, /* Laptop LCDs are driven via LVDS port */ - MT_DFP, /* DFPs are driven via TMDS */ - MT_CTV, /* CTV -> CTV */ - MT_STV, /* STV -> STV */ - MT_CV, - MT_HDMI, - MT_DP -}; - -const char *TMDSTypeName[6] = { - "None", - "Internal", - "External", - "LVTMA", - "DDIA", - "UNIPHY" -}; - -const char *DACTypeName[4] = { - "None", - "Primary", - "TVDAC/ExtDAC", - "ExtDac" +const char *encoder_name[34] = { + "NONE", + "INTERNAL_LVDS", + "INTERNAL_TMDS1", + "INTERNAL_TMDS2", + "INTERNAL_DAC1", + "INTERNAL_DAC2", + "INTERNAL_SDVOA", + "INTERNAL_SDVOB", + "SI170B", + "CH7303", + "CH7301", + "INTERNAL_DVO1", + "EXTERNAL_SDVOA", + "EXTERNAL_SDVOB", + "TITFP513", + "INTERNAL_LVTM1", + "VT1623", + "HDMI_SI1930", + "HDMI_INTERNAL", + "INTERNAL_KLDSCP_TMDS1", + "INTERNAL_KLDSCP_DVO1", + "INTERNAL_KLDSCP_DAC1", + "INTERNAL_KLDSCP_DAC2", + "SI178", + "MVPU_FPGA", + "INTERNAL_DDI", + "VT1625", + "HDMI_SI1932", + "DP_AN9801", + "DP_DP501", + "INTERNAL_UNIPHY", + "INTERNAL_KLDSCP_LVTMA", + "INTERNAL_UNIPHY1", + "INTERNAL_UNIPHY2", }; const char *ConnectorTypeName[17] = { @@ -96,8 +91,8 @@ const char *ConnectorTypeName[17] = { "DVI-I", "DVI-D", "DVI-A", - "STV", - "CTV", + "S-video", + "Composite", "LVDS", "Digital", "SCART", @@ -110,75 +105,11 @@ const char *ConnectorTypeName[17] = { "Unsupported" }; -const char *OutputType[11] = { - "None", - "VGA", - "DVI", - "DVI", - "DVI", - "LVDS", - "S-video", - "Composite", - "Component", - "HDMI", - "DisplayPort", -}; - -static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] = -{ - {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_UNKNOW*/ - {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_LEGACY*/ - {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RADEON*/ - {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV100*/ - {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS100*/ - {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV200*/ - {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS200*/ - {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R200*/ - {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV250*/ - {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS300*/ - {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, /*CHIP_FAMILY_RV280*/ - {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R300*/ - {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R350*/ - {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV350*/ - {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV380*/ - {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R420*/ - {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV410*/ /* FIXME: just values from r420 used... */ - {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS400*/ /* FIXME: just values from rv380 used... */ - {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS480*/ /* FIXME: just values from rv380 used... */ -}; - -static const uint32_t default_tvdac_adj [CHIP_FAMILY_LAST] = -{ - 0x00000000, /* unknown */ - 0x00000000, /* legacy */ - 0x00000000, /* r100 */ - 0x00280000, /* rv100 */ - 0x00000000, /* rs100 */ - 0x00880000, /* rv200 */ - 0x00000000, /* rs200 */ - 0x00000000, /* r200 */ - 0x00770000, /* rv250 */ - 0x00290000, /* rs300 */ - 0x00560000, /* rv280 */ - 0x00780000, /* r300 */ - 0x00770000, /* r350 */ - 0x00780000, /* rv350 */ - 0x00780000, /* rv380 */ - 0x01080000, /* r420 */ - 0x01080000, /* rv410 */ /* FIXME: just values from r420 used... */ - 0x00780000, /* rs400 */ /* FIXME: just values from rv380 used... */ - 0x00780000, /* rs480 */ /* FIXME: just values from rv380 used... */ -}; - - -static void RADEONUpdatePanelSize(xf86OutputPtr output); -static void RADEONGetTMDSInfoFromTable(xf86OutputPtr output); - extern void atombios_output_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode); extern void atombios_output_dpms(xf86OutputPtr output, int mode); -extern RADEONMonitorType atombios_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output); +extern RADEONMonitorType atombios_dac_detect(xf86OutputPtr output); extern int atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode); extern AtomBiosResult atombios_lock_crtc(atomBiosHandlePtr atomBIOS, int crtc, int lock); @@ -191,6 +122,7 @@ radeon_bios_output_lock(xf86OutputPtr output, Bool lock); void RADEONPrintPortMap(ScrnInfoPtr pScrn) { + RADEONInfoPtr info = RADEONPTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); RADEONOutputPrivatePtr radeon_output; xf86OutputPtr output; @@ -200,18 +132,82 @@ void RADEONPrintPortMap(ScrnInfoPtr pScrn) output = xf86_config->output[o]; radeon_output = output->driver_private; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Port%d:\n Monitor -- %s\n Connector -- %s\n DAC Type -- %s\n TMDS Type -- %s\n DDC Type -- 0x%x\n", - o, - MonTypeName[radeon_output->MonType+1], - ConnectorTypeName[radeon_output->ConnectorType], - DACTypeName[radeon_output->DACType], - TMDSTypeName[radeon_output->TMDSType], - (unsigned int)radeon_output->ddc_i2c.mask_clk_reg); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d:\n", o); + ErrorF(" XRANDR name: %s\n", output->name); + ErrorF(" Connector: %s\n", ConnectorTypeName[radeon_output->ConnectorType]); + if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) + ErrorF(" CRT1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id]); + if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) + ErrorF(" CRT2: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CRT2_INDEX]->encoder_id]); + if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) + ErrorF(" LCD1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_LCD1_INDEX]->encoder_id]); + if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) + ErrorF(" DFP1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP1_INDEX]->encoder_id]); + if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) + ErrorF(" DFP2: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP2_INDEX]->encoder_id]); + if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) + ErrorF(" DFP3: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP3_INDEX]->encoder_id]); + if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT) + ErrorF(" DFP4: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP4_INDEX]->encoder_id]); + if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT) + ErrorF(" DFP5: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP5_INDEX]->encoder_id]); + if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) + ErrorF(" TV1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_TV1_INDEX]->encoder_id]); + if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) + ErrorF(" CV: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id]); + ErrorF(" DDC reg: 0x%x\n",(unsigned int)radeon_output->ddc_i2c.mask_clk_reg); } } +static void +radeon_set_active_device(xf86OutputPtr output) +{ + RADEONOutputPrivatePtr radeon_output = output->driver_private; + + radeon_output->active_device = 0; + + switch (radeon_output->MonType) { + case MT_DFP: + if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) + radeon_output->active_device = ATOM_DEVICE_DFP1_SUPPORT; + else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) + radeon_output->active_device = ATOM_DEVICE_DFP2_SUPPORT; + else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) + radeon_output->active_device = ATOM_DEVICE_DFP3_SUPPORT; + else if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT) + radeon_output->active_device = ATOM_DEVICE_DFP4_SUPPORT; + else if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT) + radeon_output->active_device = ATOM_DEVICE_DFP5_SUPPORT; + break; + case MT_CRT: + if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) + radeon_output->active_device = ATOM_DEVICE_CRT1_SUPPORT; + else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) + radeon_output->active_device = ATOM_DEVICE_CRT2_SUPPORT; + break; + case MT_LCD: + if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) + radeon_output->active_device = ATOM_DEVICE_LCD1_SUPPORT; + else if (radeon_output->devices & ATOM_DEVICE_LCD2_SUPPORT) + radeon_output->active_device = ATOM_DEVICE_LCD2_SUPPORT; + break; + case MT_STV: + case MT_CTV: + if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) + radeon_output->active_device = ATOM_DEVICE_TV1_SUPPORT; + else if (radeon_output->devices & ATOM_DEVICE_TV2_SUPPORT) + radeon_output->active_device = ATOM_DEVICE_TV2_SUPPORT; + break; + case MT_CV: + if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) + radeon_output->active_device = ATOM_DEVICE_CV_SUPPORT; + break; + default: + radeon_output->active_device = 0; + } +} + static RADEONMonitorType radeon_ddc_connected(xf86OutputPtr output) { @@ -243,32 +239,40 @@ radeon_ddc_connected(xf86OutputPtr output) } } if (MonInfo) { - if (radeon_output->type == OUTPUT_LVDS) + switch (radeon_output->ConnectorType) { + case CONNECTOR_LVDS: MonType = MT_LCD; - else if (radeon_output->type == OUTPUT_DVI_D) - MonType = MT_DFP; - else if (radeon_output->type == OUTPUT_HDMI) - MonType = MT_DFP; - else if (radeon_output->type == OUTPUT_DP) - MonType = MT_DFP; - else if (radeon_output->type == OUTPUT_DVI_I && - (MonInfo->rawData[0x14] & 0x80)) /* if it's digital and DVI */ - MonType = MT_DFP; - else - MonType = MT_CRT; - - if (radeon_output->shared_ddc) { - if (radeon_output->type == OUTPUT_VGA) { - if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and VGA */ - MonType = MT_NONE; - else - MonType = MT_CRT; - } else { + break; + case CONNECTOR_DVI_D: + case CONNECTOR_HDMI_TYPE_A: + case CONNECTOR_HDMI_TYPE_B: + if (radeon_output->shared_ddc) { if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and DVI/HDMI/etc. */ MonType = MT_DFP; else MonType = MT_NONE; - } + } else + MonType = MT_DFP; + break; + case CONNECTOR_DISPLAY_PORT: + MonType = MT_DP; + case CONNECTOR_DVI_I: + if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and DVI */ + MonType = MT_DFP; + else + MonType = MT_CRT; + break; + case CONNECTOR_VGA: + case CONNECTOR_DVI_A: + default: + if (radeon_output->shared_ddc) { + if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and VGA */ + MonType = MT_NONE; + else + MonType = MT_CRT; + } else + MonType = MT_CRT; + break; } if (MonType != MT_NONE) @@ -330,50 +334,6 @@ RADEONDetectLidStatus(ScrnInfoPtr pScrn) #endif /* __powerpc__ */ static void -RADEONConnectorFindMonitor(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONOutputPrivatePtr radeon_output = output->driver_private; - - if (radeon_output->MonType == MT_UNKNOWN) { - radeon_output->MonType = radeon_ddc_connected(output); - if (!radeon_output->MonType) { - if (radeon_output->type == OUTPUT_LVDS) { - if (xf86ReturnOptValBool(info->Options, OPTION_IGNORE_LID_STATUS, TRUE)) - radeon_output->MonType = MT_LCD; - else -#if defined(__powerpc__) - radeon_output->MonType = MT_LCD; -#else - radeon_output->MonType = RADEONDetectLidStatus(pScrn); -#endif - } else { - if (info->IsAtomBios) - radeon_output->MonType = atombios_dac_detect(pScrn, output); - else - radeon_output->MonType = legacy_dac_detect(pScrn, output); - } - } - } - - /* update panel info for RMX */ - if (radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP) - RADEONUpdatePanelSize(output); - - /* panel is probably busted or not connected */ - if ((radeon_output->MonType == MT_LCD) && - ((radeon_output->PanelXRes == 0) || (radeon_output->PanelYRes == 0))) - radeon_output->MonType = MT_NONE; - - if (output->MonInfo) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on output: %s ----------------------\n", - output->name); - xf86PrintEDID( output->MonInfo ); - } -} - -static void radeon_dpms(xf86OutputPtr output, int mode) { RADEONInfoPtr info = RADEONPTR(output->scrn); @@ -412,6 +372,7 @@ static int radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) { RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_native_mode_ptr native_mode = &radeon_output->native_mode; ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); @@ -426,11 +387,11 @@ radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) return MODE_BANDWIDTH; } - if (OUTPUT_IS_TV) { - /* FIXME: Update when more modes are added */ - if (IS_AVIVO_VARIANT) { + if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) { + if (IS_AVIVO_VARIANT) return MODE_OK; - } else { + else { + /* FIXME: Update when more modes are added */ if (pMode->HDisplay == 800 && pMode->VDisplay == 600) return MODE_OK; else @@ -438,14 +399,14 @@ radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) } } - if (radeon_output->type == OUTPUT_LVDS) { + if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { if (radeon_output->rmx_type == RMX_OFF) { - if (pMode->HDisplay != radeon_output->PanelXRes || - pMode->VDisplay != radeon_output->PanelYRes) + if (pMode->HDisplay != native_mode->PanelXRes || + pMode->VDisplay != native_mode->PanelYRes) return MODE_PANEL; } - if (pMode->HDisplay > radeon_output->PanelXRes || - pMode->VDisplay > radeon_output->PanelYRes) + if (pMode->HDisplay > native_mode->PanelXRes || + pMode->VDisplay > native_mode->PanelYRes) return MODE_PANEL; } @@ -458,67 +419,68 @@ radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, { RADEONInfoPtr info = RADEONPTR(output->scrn); RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_native_mode_ptr native_mode = &radeon_output->native_mode; radeon_output->Flags &= ~RADEON_USE_RMX; - /* - * Refresh the Crtc values without INTERLACE_HALVE_V - * Should we use output->scrn->adjustFlags like xf86RandRModeConvert() does? + /* + * Refresh the Crtc values without INTERLACE_HALVE_V + * Should we use output->scrn->adjustFlags like xf86RandRModeConvert() does? */ xf86SetModeCrtc(adjusted_mode, 0); /* decide if we are using RMX */ - if ((radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP) + if ((radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) && radeon_output->rmx_type != RMX_OFF) { xf86CrtcPtr crtc = output->crtc; RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; if (IS_AVIVO_VARIANT || radeon_crtc->crtc_id == 0) { - if (mode->HDisplay < radeon_output->PanelXRes || - mode->VDisplay < radeon_output->PanelYRes) { + if (mode->HDisplay < native_mode->PanelXRes || + mode->VDisplay < native_mode->PanelYRes) { radeon_output->Flags |= RADEON_USE_RMX; if (IS_AVIVO_VARIANT) { /* set to the panel's native mode */ - adjusted_mode->HDisplay = radeon_output->PanelXRes; - adjusted_mode->VDisplay = radeon_output->PanelYRes; - adjusted_mode->HTotal = radeon_output->PanelXRes + radeon_output->HBlank; - adjusted_mode->HSyncStart = radeon_output->PanelXRes + radeon_output->HOverPlus; - adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + radeon_output->HSyncWidth; - adjusted_mode->VTotal = radeon_output->PanelYRes + radeon_output->VBlank; - adjusted_mode->VSyncStart = radeon_output->PanelYRes + radeon_output->VOverPlus; - adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + radeon_output->VSyncWidth; + adjusted_mode->HDisplay = native_mode->PanelXRes; + adjusted_mode->VDisplay = native_mode->PanelYRes; + adjusted_mode->HTotal = native_mode->PanelXRes + native_mode->HBlank; + adjusted_mode->HSyncStart = native_mode->PanelXRes + native_mode->HOverPlus; + adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + native_mode->HSyncWidth; + adjusted_mode->VTotal = native_mode->PanelYRes + native_mode->VBlank; + adjusted_mode->VSyncStart = native_mode->PanelYRes + native_mode->VOverPlus; + adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + native_mode->VSyncWidth; /* update crtc values */ xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); /* adjust crtc values */ - adjusted_mode->CrtcHDisplay = radeon_output->PanelXRes; - adjusted_mode->CrtcVDisplay = radeon_output->PanelYRes; - adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + radeon_output->HBlank; - adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + radeon_output->HOverPlus; - adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + radeon_output->HSyncWidth; - adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + radeon_output->VBlank; - adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + radeon_output->VOverPlus; - adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + radeon_output->VSyncWidth; + adjusted_mode->CrtcHDisplay = native_mode->PanelXRes; + adjusted_mode->CrtcVDisplay = native_mode->PanelYRes; + adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + native_mode->HBlank; + adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + native_mode->HOverPlus; + adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + native_mode->HSyncWidth; + adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + native_mode->VBlank; + adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + native_mode->VOverPlus; + adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + native_mode->VSyncWidth; } else { /* set to the panel's native mode */ - adjusted_mode->HTotal = radeon_output->PanelXRes + radeon_output->HBlank; - adjusted_mode->HSyncStart = radeon_output->PanelXRes + radeon_output->HOverPlus; - adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + radeon_output->HSyncWidth; - adjusted_mode->VTotal = radeon_output->PanelYRes + radeon_output->VBlank; - adjusted_mode->VSyncStart = radeon_output->PanelYRes + radeon_output->VOverPlus; - adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + radeon_output->VSyncWidth; - adjusted_mode->Clock = radeon_output->DotClock; + adjusted_mode->HTotal = native_mode->PanelXRes + native_mode->HBlank; + adjusted_mode->HSyncStart = native_mode->PanelXRes + native_mode->HOverPlus; + adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + native_mode->HSyncWidth; + adjusted_mode->VTotal = native_mode->PanelYRes + native_mode->VBlank; + adjusted_mode->VSyncStart = native_mode->PanelYRes + native_mode->VOverPlus; + adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + native_mode->VSyncWidth; + adjusted_mode->Clock = native_mode->DotClock; /* update crtc values */ xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); /* adjust crtc values */ - adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + radeon_output->HBlank; - adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + radeon_output->HOverPlus; - adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + radeon_output->HSyncWidth; - adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + radeon_output->VBlank; - adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + radeon_output->VOverPlus; - adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + radeon_output->VSyncWidth; + adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + native_mode->HBlank; + adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + native_mode->HOverPlus; + adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + native_mode->HSyncWidth; + adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + native_mode->VBlank; + adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + native_mode->VOverPlus; + adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + native_mode->VSyncWidth; } - adjusted_mode->Clock = radeon_output->DotClock; - adjusted_mode->Flags = radeon_output->Flags; + adjusted_mode->Clock = native_mode->DotClock; + adjusted_mode->Flags = native_mode->Flags; } } } @@ -641,79 +603,85 @@ radeon_bios_output_dpms(xf86OutputPtr output, int mode) RADEONSavePtr save = info->ModeReg; if (info->IsAtomBios) { - if (mode == DPMSModeOn) { - if (radeon_output->MonType == MT_STV || - radeon_output->MonType == MT_CTV) { - if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) { - save->bios_2_scratch &= ~ATOM_S2_TV1_DPMS_STATE; - save->bios_3_scratch |= ATOM_S3_TV1_ACTIVE; - } - } else if (radeon_output->MonType == MT_CV) { - if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) { - save->bios_2_scratch &= ~ATOM_S2_CV_DPMS_STATE; - save->bios_3_scratch |= ATOM_S3_CV_ACTIVE; - } - } else if (radeon_output->MonType == MT_CRT) { - if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) { - save->bios_2_scratch &= ~ATOM_S2_CRT1_DPMS_STATE; - save->bios_3_scratch |= ATOM_S3_CRT1_ACTIVE; - } else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) { - save->bios_2_scratch &= ~ATOM_S2_CRT2_DPMS_STATE; - save->bios_3_scratch |= ATOM_S3_CRT2_ACTIVE; - } - } else if (radeon_output->MonType == MT_LCD) { - if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) { - save->bios_2_scratch &= ~ATOM_S2_LCD1_DPMS_STATE; - save->bios_3_scratch |= ATOM_S3_LCD1_ACTIVE; - } - } else if (radeon_output->MonType == MT_DFP) { - if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) { - save->bios_2_scratch &= ~ATOM_S2_DFP1_DPMS_STATE; - save->bios_3_scratch |= ATOM_S3_DFP1_ACTIVE; - } else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) { - save->bios_2_scratch &= ~ATOM_S2_DFP2_DPMS_STATE; - save->bios_3_scratch |= ATOM_S3_DFP2_ACTIVE; - } else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) { - save->bios_2_scratch &= ~ATOM_S2_DFP3_DPMS_STATE; - save->bios_3_scratch |= ATOM_S3_DFP3_ACTIVE; - } + if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) { + if (mode == DPMSModeOn) { + save->bios_2_scratch &= ~ATOM_S2_TV1_DPMS_STATE; + save->bios_3_scratch |= ATOM_S3_TV1_ACTIVE; + } else { + save->bios_2_scratch |= ATOM_S2_TV1_DPMS_STATE; + save->bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE; } - } else { - if (radeon_output->MonType == MT_STV || - radeon_output->MonType == MT_CTV) { - if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) { - save->bios_2_scratch |= ATOM_S2_TV1_DPMS_STATE; - save->bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE; - } - } else if (radeon_output->MonType == MT_CV) { - if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) { - save->bios_2_scratch |= ATOM_S2_CV_DPMS_STATE; - save->bios_3_scratch &= ~ATOM_S3_CV_ACTIVE; - } - } else if (radeon_output->MonType == MT_CRT) { - if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) { - save->bios_2_scratch |= ATOM_S2_CRT1_DPMS_STATE; - save->bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE; - } else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) { - save->bios_2_scratch |= ATOM_S2_CRT2_DPMS_STATE; - save->bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE; - } - } else if (radeon_output->MonType == MT_LCD) { - if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) { - save->bios_2_scratch |= ATOM_S2_LCD1_DPMS_STATE; - save->bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE; - } - } else if (radeon_output->MonType == MT_DFP) { - if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) { - save->bios_2_scratch |= ATOM_S2_DFP1_DPMS_STATE; - save->bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE; - } else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) { - save->bios_2_scratch |= ATOM_S2_DFP2_DPMS_STATE; - save->bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE; - } else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) { - save->bios_2_scratch |= ATOM_S2_DFP3_DPMS_STATE; - save->bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE; - } + } else if (radeon_output->active_device & ATOM_DEVICE_CV_SUPPORT) { + if (mode == DPMSModeOn) { + save->bios_2_scratch &= ~ATOM_S2_CV_DPMS_STATE; + save->bios_3_scratch |= ATOM_S3_CV_ACTIVE; + } else { + save->bios_2_scratch |= ATOM_S2_CV_DPMS_STATE; + save->bios_3_scratch &= ~ATOM_S3_CV_ACTIVE; + } + } else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) { + if (mode == DPMSModeOn) { + save->bios_2_scratch &= ~ATOM_S2_CRT1_DPMS_STATE; + save->bios_3_scratch |= ATOM_S3_CRT1_ACTIVE; + } else { + save->bios_2_scratch |= ATOM_S2_CRT1_DPMS_STATE; + save->bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE; + } + } else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) { + if (mode == DPMSModeOn) { + save->bios_2_scratch &= ~ATOM_S2_CRT2_DPMS_STATE; + save->bios_3_scratch |= ATOM_S3_CRT2_ACTIVE; + } else { + save->bios_2_scratch |= ATOM_S2_CRT2_DPMS_STATE; + save->bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE; + } + } else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) { + if (mode == DPMSModeOn) { + save->bios_2_scratch &= ~ATOM_S2_LCD1_DPMS_STATE; + save->bios_3_scratch |= ATOM_S3_LCD1_ACTIVE; + } else { + save->bios_2_scratch |= ATOM_S2_LCD1_DPMS_STATE; + save->bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE; + } + } else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) { + if (mode == DPMSModeOn) { + save->bios_2_scratch &= ~ATOM_S2_DFP1_DPMS_STATE; + save->bios_3_scratch |= ATOM_S3_DFP1_ACTIVE; + } else { + save->bios_2_scratch |= ATOM_S2_DFP1_DPMS_STATE; + save->bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE; + } + } else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) { + if (mode == DPMSModeOn) { + save->bios_2_scratch &= ~ATOM_S2_DFP2_DPMS_STATE; + save->bios_3_scratch |= ATOM_S3_DFP2_ACTIVE; + } else { + save->bios_2_scratch |= ATOM_S2_DFP2_DPMS_STATE; + save->bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE; + } + } else if (radeon_output->active_device & ATOM_DEVICE_DFP3_SUPPORT) { + if (mode == DPMSModeOn) { + save->bios_2_scratch &= ~ATOM_S2_DFP3_DPMS_STATE; + save->bios_3_scratch |= ATOM_S3_DFP3_ACTIVE; + } else { + save->bios_2_scratch |= ATOM_S2_DFP3_DPMS_STATE; + save->bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE; + } + } else if (radeon_output->active_device & ATOM_DEVICE_DFP4_SUPPORT) { + if (mode == DPMSModeOn) { + save->bios_2_scratch &= ~ATOM_S2_DFP4_DPMS_STATE; + save->bios_3_scratch |= ATOM_S3_DFP4_ACTIVE; + } else { + save->bios_2_scratch |= ATOM_S2_DFP4_DPMS_STATE; + save->bios_3_scratch &= ~ATOM_S3_DFP4_ACTIVE; + } + } else if (radeon_output->active_device & ATOM_DEVICE_DFP5_SUPPORT) { + if (mode == DPMSModeOn) { + save->bios_2_scratch &= ~ATOM_S2_DFP5_DPMS_STATE; + save->bios_3_scratch |= ATOM_S3_DFP5_ACTIVE; + } else { + save->bios_2_scratch |= ATOM_S2_DFP5_DPMS_STATE; + save->bios_3_scratch &= ~ATOM_S3_DFP5_ACTIVE; } } if (info->ChipFamily >= CHIP_FAMILY_R600) { @@ -727,47 +695,56 @@ radeon_bios_output_dpms(xf86OutputPtr output, int mode) if (mode == DPMSModeOn) { save->bios_6_scratch &= ~(RADEON_DPMS_MASK | RADEON_SCREEN_BLANKING); save->bios_6_scratch |= RADEON_DPMS_ON; - if (radeon_output->MonType == MT_STV || - radeon_output->MonType == MT_CTV) { - save->bios_5_scratch |= RADEON_TV1_ON; - save->bios_6_scratch |= RADEON_TV_DPMS_ON; - } else if (radeon_output->MonType == MT_CRT) { - if (radeon_output->DACType == DAC_PRIMARY) - save->bios_5_scratch |= RADEON_CRT1_ON; - else - save->bios_5_scratch |= RADEON_CRT2_ON; - save->bios_6_scratch |= RADEON_CRT_DPMS_ON; - } else if (radeon_output->MonType == MT_LCD) { - save->bios_5_scratch |= RADEON_LCD1_ON; - save->bios_6_scratch |= RADEON_LCD_DPMS_ON; - } else if (radeon_output->MonType == MT_DFP) { - if (radeon_output->TMDSType == TMDS_INT) - save->bios_5_scratch |= RADEON_DFP1_ON; - else - save->bios_5_scratch |= RADEON_DFP2_ON; - save->bios_6_scratch |= RADEON_DFP_DPMS_ON; - } } else { save->bios_6_scratch &= ~RADEON_DPMS_MASK; save->bios_6_scratch |= (RADEON_DPMS_OFF | RADEON_SCREEN_BLANKING); - if (radeon_output->MonType == MT_STV || - radeon_output->MonType == MT_CTV) { + } + if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) { + if (mode == DPMSModeOn) { + save->bios_5_scratch |= RADEON_TV1_ON; + save->bios_6_scratch |= RADEON_TV_DPMS_ON; + } else { save->bios_5_scratch &= ~RADEON_TV1_ON; save->bios_6_scratch &= ~RADEON_TV_DPMS_ON; - } else if (radeon_output->MonType == MT_CRT) { - if (radeon_output->DACType == DAC_PRIMARY) - save->bios_5_scratch &= ~RADEON_CRT1_ON; - else - save->bios_5_scratch &= ~RADEON_CRT2_ON; + } + } else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) { + if (mode == DPMSModeOn) { + save->bios_5_scratch |= RADEON_CRT1_ON; + save->bios_6_scratch |= RADEON_CRT_DPMS_ON; + } else { + save->bios_5_scratch &= ~RADEON_CRT1_ON; + save->bios_6_scratch &= ~RADEON_CRT_DPMS_ON; + } + } else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) { + if (mode == DPMSModeOn) { + save->bios_5_scratch |= RADEON_CRT2_ON; + save->bios_6_scratch |= RADEON_CRT_DPMS_ON; + } else { + save->bios_5_scratch &= ~RADEON_CRT2_ON; save->bios_6_scratch &= ~RADEON_CRT_DPMS_ON; - } else if (radeon_output->MonType == MT_LCD) { + } + } else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) { + if (mode == DPMSModeOn) { + save->bios_5_scratch |= RADEON_LCD1_ON; + save->bios_6_scratch |= RADEON_LCD_DPMS_ON; + } else { save->bios_5_scratch &= ~RADEON_LCD1_ON; save->bios_6_scratch &= ~RADEON_LCD_DPMS_ON; - } else if (radeon_output->MonType == MT_DFP) { - if (radeon_output->TMDSType == TMDS_INT) - save->bios_5_scratch &= ~RADEON_DFP1_ON; - else - save->bios_5_scratch &= ~RADEON_DFP2_ON; + } + } else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) { + if (mode == DPMSModeOn) { + save->bios_5_scratch |= RADEON_DFP1_ON; + save->bios_6_scratch |= RADEON_DFP_DPMS_ON; + } else { + save->bios_5_scratch &= ~RADEON_DFP1_ON; + save->bios_6_scratch &= ~RADEON_DFP_DPMS_ON; + } + } else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) { + if (mode == DPMSModeOn) { + save->bios_5_scratch |= RADEON_DFP2_ON; + save->bios_6_scratch |= RADEON_DFP_DPMS_ON; + } else { + save->bios_5_scratch &= ~RADEON_DFP2_ON; save->bios_6_scratch &= ~RADEON_DFP_DPMS_ON; } } @@ -788,70 +765,54 @@ radeon_bios_output_crtc(xf86OutputPtr output) RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; if (info->IsAtomBios) { - if (radeon_output->MonType == MT_STV || - radeon_output->MonType == MT_CTV) { - if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) { - save->bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE; - save->bios_3_scratch |= (radeon_crtc->crtc_id << 18); - } - } else if (radeon_output->MonType == MT_CV) { - if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) { - save->bios_2_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE; - save->bios_3_scratch |= (radeon_crtc->crtc_id << 24); - } - } else if (radeon_output->MonType == MT_CRT) { - if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) { - save->bios_2_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE; - save->bios_3_scratch |= (radeon_crtc->crtc_id << 16); - } else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) { - save->bios_2_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE; - save->bios_3_scratch |= (radeon_crtc->crtc_id << 20); - } - } else if (radeon_output->MonType == MT_LCD) { - if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) { - save->bios_2_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE; - save->bios_3_scratch |= (radeon_crtc->crtc_id << 17); - } - } else if (radeon_output->MonType == MT_DFP) { - if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) { - save->bios_2_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE; - save->bios_3_scratch |= (radeon_crtc->crtc_id << 19); - } else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) { - save->bios_2_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE; - save->bios_3_scratch |= (radeon_crtc->crtc_id << 23); - } else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) { - save->bios_2_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE; - save->bios_3_scratch |= (radeon_crtc->crtc_id << 25); - } + if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) { + save->bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE; + save->bios_3_scratch |= (radeon_crtc->crtc_id << 18); + } else if (radeon_output->active_device & ATOM_DEVICE_CV_SUPPORT) { + save->bios_2_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE; + save->bios_3_scratch |= (radeon_crtc->crtc_id << 24); + } else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) { + save->bios_2_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE; + save->bios_3_scratch |= (radeon_crtc->crtc_id << 16); + } else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) { + save->bios_2_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE; + save->bios_3_scratch |= (radeon_crtc->crtc_id << 20); + } else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) { + save->bios_2_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE; + save->bios_3_scratch |= (radeon_crtc->crtc_id << 17); + } else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) { + save->bios_2_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE; + save->bios_3_scratch |= (radeon_crtc->crtc_id << 19); + } else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) { + save->bios_2_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE; + save->bios_3_scratch |= (radeon_crtc->crtc_id << 23); + } else if (radeon_output->active_device & ATOM_DEVICE_DFP3_SUPPORT) { + save->bios_2_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE; + save->bios_3_scratch |= (radeon_crtc->crtc_id << 25); } if (info->ChipFamily >= CHIP_FAMILY_R600) OUTREG(R600_BIOS_3_SCRATCH, save->bios_3_scratch); else OUTREG(RADEON_BIOS_3_SCRATCH, save->bios_3_scratch); } else { - if (radeon_output->MonType == MT_STV || - radeon_output->MonType == MT_CTV) { + if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) { save->bios_5_scratch &= ~RADEON_TV1_CRTC_MASK; save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_TV1_CRTC_SHIFT); - } else if (radeon_output->MonType == MT_CRT) { - if (radeon_output->DACType == DAC_PRIMARY) { - save->bios_5_scratch &= ~RADEON_CRT1_CRTC_MASK; - save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT1_CRTC_SHIFT); - } else { - save->bios_5_scratch &= ~RADEON_CRT2_CRTC_MASK; - save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT2_CRTC_SHIFT); - } - } else if (radeon_output->MonType == MT_LCD) { + } else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) { + save->bios_5_scratch &= ~RADEON_CRT1_CRTC_MASK; + save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT1_CRTC_SHIFT); + } else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) { + save->bios_5_scratch &= ~RADEON_CRT2_CRTC_MASK; + save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT2_CRTC_SHIFT); + } else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) { save->bios_5_scratch &= ~RADEON_LCD1_CRTC_MASK; save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_LCD1_CRTC_SHIFT); - } else if (radeon_output->MonType == MT_DFP) { - if (radeon_output->TMDSType == TMDS_INT) { - save->bios_5_scratch &= ~RADEON_DFP1_CRTC_MASK; - save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP1_CRTC_SHIFT); - } else { - save->bios_5_scratch &= ~RADEON_DFP2_CRTC_MASK; - save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP2_CRTC_SHIFT); - } + } else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) { + save->bios_5_scratch &= ~RADEON_DFP1_CRTC_MASK; + save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP1_CRTC_SHIFT); + } else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) { + save->bios_5_scratch &= ~RADEON_DFP2_CRTC_MASK; + save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP2_CRTC_SHIFT); } OUTREG(RADEON_BIOS_5_SCRATCH, save->bios_5_scratch); } @@ -866,97 +827,110 @@ radeon_bios_output_connected(xf86OutputPtr output, Bool connected) unsigned char *RADEONMMIO = info->MMIO; RADEONSavePtr save = info->ModeReg; - if (info->ChipFamily >= CHIP_FAMILY_R600) - return; - if (info->IsAtomBios) { - if (connected) { - if (radeon_output->MonType == MT_STV) { - /* taken care of by load detection */ - } else if (radeon_output->MonType == MT_CTV) { - /* taken care of by load detection */ - } else if (radeon_output->MonType == MT_CV) { - /* taken care of by load detection */ - } else if (radeon_output->MonType == MT_CRT) { - if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) - save->bios_0_scratch |= ATOM_S0_CRT1_COLOR; - else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) - save->bios_0_scratch |= ATOM_S0_CRT2_COLOR; - } else if (radeon_output->MonType == MT_LCD) { - if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) - save->bios_0_scratch |= ATOM_S0_LCD1; - } else if (radeon_output->MonType == MT_DFP) { - if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) - save->bios_0_scratch |= ATOM_S0_DFP1; - else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) - save->bios_0_scratch |= ATOM_S0_DFP2; - else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) - save->bios_0_scratch |= ATOM_S0_DFP3; - } - } else { - if (OUTPUT_IS_TV) { - if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) - save->bios_0_scratch &= ~ATOM_S0_TV1_MASK; - } - if (radeon_output->type == OUTPUT_CV) { - if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) - save->bios_0_scratch &= ~ATOM_S0_CV_MASK; - } - if (radeon_output->DACType) { - if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) - save->bios_0_scratch &= ~ATOM_S0_CRT1_MASK; - else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) - save->bios_0_scratch &= ~ATOM_S0_CRT2_MASK; - } - if (radeon_output->type == OUTPUT_LVDS) { - if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) - save->bios_0_scratch &= ~ATOM_S0_LCD1; - } - if (radeon_output->TMDSType) { - if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) - save->bios_0_scratch &= ~ATOM_S0_DFP1; - else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) - save->bios_0_scratch &= ~ATOM_S0_DFP2; - else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) - save->bios_0_scratch &= ~ATOM_S0_DFP3; - } + switch (radeon_output->active_device) { + case ATOM_DEVICE_TV1_SUPPORT: + if (!connected) + save->bios_0_scratch &= ~ATOM_S0_TV1_MASK; + break; + case ATOM_DEVICE_CV_SUPPORT: + if (!connected) + save->bios_0_scratch &= ~ATOM_S0_CV_MASK; + break; + case ATOM_DEVICE_LCD1_SUPPORT: + if (connected) + save->bios_0_scratch |= ATOM_S0_LCD1; + else + save->bios_0_scratch &= ~ATOM_S0_LCD1; + break; + case ATOM_DEVICE_CRT1_SUPPORT: + if (connected) + save->bios_0_scratch |= ATOM_S0_CRT1_COLOR; + else + save->bios_0_scratch &= ~ATOM_S0_CRT1_MASK; + break; + case ATOM_DEVICE_CRT2_SUPPORT: + if (connected) + save->bios_0_scratch |= ATOM_S0_CRT2_COLOR; + else + save->bios_0_scratch &= ~ATOM_S0_CRT2_MASK; + break; + case ATOM_DEVICE_DFP1_SUPPORT: + if (connected) + save->bios_0_scratch |= ATOM_S0_DFP1; + else + save->bios_0_scratch &= ~ATOM_S0_DFP1; + break; + case ATOM_DEVICE_DFP2_SUPPORT: + if (connected) + save->bios_0_scratch |= ATOM_S0_DFP2; + else + save->bios_0_scratch &= ~ATOM_S0_DFP2; + break; + case ATOM_DEVICE_DFP3_SUPPORT: + if (connected) + save->bios_0_scratch |= ATOM_S0_DFP3; + else + save->bios_0_scratch &= ~ATOM_S0_DFP3; + break; + case ATOM_DEVICE_DFP4_SUPPORT: + if (connected) + save->bios_0_scratch |= ATOM_S0_DFP4; + else + save->bios_0_scratch &= ~ATOM_S0_DFP4; + break; + case ATOM_DEVICE_DFP5_SUPPORT: + if (connected) + save->bios_0_scratch |= ATOM_S0_DFP5; + else + save->bios_0_scratch &= ~ATOM_S0_DFP5; + break; } if (info->ChipFamily >= CHIP_FAMILY_R600) OUTREG(R600_BIOS_0_SCRATCH, save->bios_0_scratch); else OUTREG(RADEON_BIOS_0_SCRATCH, save->bios_0_scratch); } else { - if (connected) { - if (radeon_output->MonType == MT_STV) - save->bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO; - else if (radeon_output->MonType == MT_CTV) - save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP; - else if (radeon_output->MonType == MT_CRT) { - if (radeon_output->DACType == DAC_PRIMARY) - save->bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR; - else - save->bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR; - } else if (radeon_output->MonType == MT_LCD) - save->bios_4_scratch |= RADEON_LCD1_ATTACHED; - else if (radeon_output->MonType == MT_DFP) { - if (radeon_output->TMDSType == TMDS_INT) - save->bios_4_scratch |= RADEON_DFP1_ATTACHED; - else - save->bios_4_scratch |= RADEON_DFP2_ATTACHED; - } - } else { - if (OUTPUT_IS_TV) + switch (radeon_output->active_device) { + case ATOM_DEVICE_TV1_SUPPORT: + if (connected) { + if (radeon_output->MonType == MT_STV) + save->bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO; + else if (radeon_output->MonType == MT_CTV) + save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP; + } else save->bios_4_scratch &= ~RADEON_TV1_ATTACHED_MASK; - else if (radeon_output->DACType == DAC_TVDAC) - save->bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK; - if (radeon_output->DACType == DAC_PRIMARY) - save->bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK; - if (radeon_output->type == OUTPUT_LVDS) + break; + case ATOM_DEVICE_LCD1_SUPPORT: + if (connected) + save->bios_4_scratch |= RADEON_LCD1_ATTACHED; + else save->bios_4_scratch &= ~RADEON_LCD1_ATTACHED; - if (radeon_output->TMDSType == TMDS_INT) + break; + case ATOM_DEVICE_CRT1_SUPPORT: + if (connected) + save->bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR; + else + save->bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK; + break; + case ATOM_DEVICE_CRT2_SUPPORT: + if (connected) + save->bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR; + else + save->bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK; + break; + case ATOM_DEVICE_DFP1_SUPPORT: + if (connected) + save->bios_4_scratch |= RADEON_DFP1_ATTACHED; + else save->bios_4_scratch &= ~RADEON_DFP1_ATTACHED; - if (radeon_output->TMDSType == TMDS_EXT) + break; + case ATOM_DEVICE_DFP2_SUPPORT: + if (connected) + save->bios_4_scratch |= RADEON_DFP2_ATTACHED; + else save->bios_4_scratch &= ~RADEON_DFP2_ATTACHED; + break; } OUTREG(RADEON_BIOS_4_SCRATCH, save->bios_4_scratch); } @@ -973,27 +947,62 @@ radeon_detect(xf86OutputPtr output) radeon_output->MonType = MT_UNKNOWN; radeon_bios_output_connected(output, FALSE); - RADEONConnectorFindMonitor(output); + radeon_output->MonType = radeon_ddc_connected(output); + if (!radeon_output->MonType) { + if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) { + if (xf86ReturnOptValBool(info->Options, OPTION_IGNORE_LID_STATUS, TRUE)) + radeon_output->MonType = MT_LCD; + else +#if defined(__powerpc__) + radeon_output->MonType = MT_LCD; +#else + radeon_output->MonType = RADEONDetectLidStatus(pScrn); +#endif + } else { + if (info->IsAtomBios) + radeon_output->MonType = atombios_dac_detect(output); + else + radeon_output->MonType = legacy_dac_detect(output); + } + } + + // if size is zero panel probably broken or not connected + if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) { + radeon_encoder_ptr radeon_encoder = info->encoders[ATOM_DEVICE_LCD1_INDEX]; + if (radeon_encoder) { + radeon_lvds_ptr lvds = (radeon_lvds_ptr)radeon_encoder->dev_priv; + if (lvds) { + if ((lvds->native_mode.PanelXRes == 0) || (lvds->native_mode.PanelYRes == 0)) + radeon_output->MonType = MT_NONE; + } + } + } + + + if (output->MonInfo) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on output: %s ----------------------\n", + output->name); + xf86PrintEDID( output->MonInfo ); + } /* nothing connected, light up some defaults so the server comes up */ if (radeon_output->MonType == MT_NONE && info->first_load_no_devices) { if (info->IsMobility) { - if (radeon_output->type == OUTPUT_LVDS) { + if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) { radeon_output->MonType = MT_LCD; info->first_load_no_devices = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using LVDS default\n"); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using LCD default\n"); } } else { - if (radeon_output->type == OUTPUT_VGA || - radeon_output->type == OUTPUT_DVI_I) { + if (radeon_output->devices & (ATOM_DEVICE_CRT_SUPPORT)) { radeon_output->MonType = MT_CRT; info->first_load_no_devices = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using VGA default\n"); - } else if (radeon_output->type == OUTPUT_DVI_D) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using CRT default\n"); + } else if (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT)) { radeon_output->MonType = MT_DFP; info->first_load_no_devices = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using DVI default\n"); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using DFP default\n"); } } } @@ -1003,51 +1012,51 @@ radeon_detect(xf86OutputPtr output) /* set montype so users can force outputs on even if detection fails */ if (radeon_output->MonType == MT_NONE) { connected = FALSE; - if (radeon_output->type == OUTPUT_LVDS) + switch (radeon_output->ConnectorType) { + case CONNECTOR_LVDS: radeon_output->MonType = MT_LCD; - else if (radeon_output->type == OUTPUT_VGA) - radeon_output->MonType = MT_CRT; - else if (radeon_output->type == OUTPUT_STV) - radeon_output->MonType = MT_STV; - else if (radeon_output->type == OUTPUT_CTV) - radeon_output->MonType = MT_CTV; - else if (radeon_output->type == OUTPUT_CV) - radeon_output->MonType = MT_CV; - else if (radeon_output->type == OUTPUT_DVI_D) - radeon_output->MonType = MT_DFP; - else if (radeon_output->type == OUTPUT_HDMI) + break; + case CONNECTOR_DVI_D: + case CONNECTOR_HDMI_TYPE_A: + case CONNECTOR_HDMI_TYPE_B: radeon_output->MonType = MT_DFP; - else if (radeon_output->type == OUTPUT_DVI_A) + break; + case CONNECTOR_VGA: + case CONNECTOR_DVI_A: + default: radeon_output->MonType = MT_CRT; - else if (radeon_output->type == OUTPUT_DVI_I) { + break; + case CONNECTOR_DVI_I: if (radeon_output->DVIType == DVI_ANALOG) radeon_output->MonType = MT_CRT; else if (radeon_output->DVIType == DVI_DIGITAL) radeon_output->MonType = MT_DFP; + break; + case CONNECTOR_STV: + radeon_output->MonType = MT_STV; + break; + case CONNECTOR_CTV: + radeon_output->MonType = MT_CTV; + break; + case CONNECTOR_DIN: + radeon_output->MonType = MT_CV; + break; + case CONNECTOR_DISPLAY_PORT: + break; } } - if (radeon_output->MonType == MT_UNKNOWN) { - output->subpixel_order = SubPixelUnknown; - return XF86OutputStatusUnknown; - } else { + radeon_set_active_device(output); - switch(radeon_output->MonType) { - case MT_LCD: - case MT_DFP: - output->subpixel_order = SubPixelHorizontalRGB; - break; - default: - output->subpixel_order = SubPixelNone; - break; - } - - if (connected) - return XF86OutputStatusConnected; - else - return XF86OutputStatusDisconnected; - } + if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) + output->subpixel_order = SubPixelHorizontalRGB; + else + output->subpixel_order = SubPixelNone; + if (connected) + return XF86OutputStatusConnected; + else + return XF86OutputStatusDisconnected; } static DisplayModePtr @@ -1108,6 +1117,7 @@ radeon_create_resources(xf86OutputPtr output) int data, err; const char *s; +#if 0 /* backlight control */ if (radeon_output->type == OUTPUT_LVDS) { backlight_atom = MAKE_ATOM("backlight"); @@ -1131,9 +1141,9 @@ radeon_create_resources(xf86OutputPtr output) "RRChangeOutputProperty error, %d\n", err); } } +#endif - if (radeon_output->DACType == DAC_PRIMARY || - radeon_output->DACType == DAC_TVDAC) { + if (radeon_output->devices & (ATOM_DEVICE_CRT_SUPPORT)) { load_detection_atom = MAKE_ATOM("load_detection"); range[0] = 0; /* off */ @@ -1146,9 +1156,9 @@ radeon_create_resources(xf86OutputPtr output) } if (radeon_output->load_detection) - data = 1; /* user forces on tv dac load detection */ + data = 1; else - data = 0; /* shared tvdac between vga/dvi/tv */ + data = 0; err = RRChangeOutputProperty(output->randr_output, load_detection_atom, XA_INTEGER, 32, PropModeReplace, 1, &data, @@ -1159,7 +1169,7 @@ radeon_create_resources(xf86OutputPtr output) } } - if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) { + if (IS_AVIVO_VARIANT && (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT))) { coherent_mode_atom = MAKE_ATOM("coherent_mode"); range[0] = 0; /* off */ @@ -1182,7 +1192,7 @@ radeon_create_resources(xf86OutputPtr output) } } - if (OUTPUT_IS_DVI && radeon_output->TMDSType == TMDS_INT) { + if ((!IS_AVIVO_VARIANT) && (radeon_output->devices & (ATOM_DEVICE_DFP2_SUPPORT))) { tmds_pll_atom = MAKE_ATOM("tmds_pll"); err = RRConfigureOutputProperty(output->randr_output, tmds_pll_atom, @@ -1213,7 +1223,7 @@ radeon_create_resources(xf86OutputPtr output) /* RMX control - fullscreen, centered, keep ratio, off */ /* actually more of a crtc property as only crtc1 has rmx */ - if (radeon_output->type == OUTPUT_LVDS || OUTPUT_IS_DVI) { + if (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { rmx_atom = MAKE_ATOM("scaler"); err = RRConfigureOutputProperty(output->randr_output, rmx_atom, @@ -1223,7 +1233,7 @@ radeon_create_resources(xf86OutputPtr output) "RRConfigureOutputProperty error, %d\n", err); } /* Set the current value of the property */ - if (radeon_output->type == OUTPUT_LVDS) + if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) s = "full"; else s = "off"; @@ -1237,7 +1247,8 @@ radeon_create_resources(xf86OutputPtr output) } /* force auto/analog/digital for DVI-I ports */ - if (radeon_output->type == OUTPUT_DVI_I) { + if ((radeon_output->devices & (ATOM_DEVICE_CRT_SUPPORT)) && + (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT))){ monitor_type_atom = MAKE_ATOM("dvi_monitor_type"); err = RRConfigureOutputProperty(output->randr_output, monitor_type_atom, @@ -1257,7 +1268,8 @@ radeon_create_resources(xf86OutputPtr output) } } - if (OUTPUT_IS_TV) { + if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT)) { + radeon_tvout_ptr tvout = &radeon_output->tvout; if (!IS_AVIVO_VARIANT) { tv_hsize_atom = MAKE_ATOM("tv_horizontal_size"); @@ -1327,7 +1339,7 @@ radeon_create_resources(xf86OutputPtr output) } /* Set the current value of the property */ - switch (radeon_output->tvStd) { + switch (tvout->tvStd) { case TV_STD_PAL: s = "pal"; break; @@ -1460,16 +1472,23 @@ radeon_set_property(xf86OutputPtr output, Atom property, return FALSE; } } else if (property == tmds_pll_atom) { + radeon_tmds_ptr tmds = NULL; const char *s; + + if (info->encoders[ATOM_DEVICE_DFP1_INDEX] && info->encoders[ATOM_DEVICE_DFP1_INDEX]->dev_priv) + tmds = (radeon_tmds_ptr)info->encoders[ATOM_DEVICE_DFP1_INDEX]->dev_priv; + else + return FALSE; + if (value->type != XA_STRING || value->format != 8) return FALSE; s = (char*)value->data; if (value->size == strlen("bios") && !strncmp("bios", s, strlen("bios"))) { - if (!RADEONGetTMDSInfoFromBIOS(output)) - RADEONGetTMDSInfoFromTable(output); - } else if (value->size == strlen("driver") && !strncmp("driver", s, strlen("driver"))) { - RADEONGetTMDSInfoFromTable(output); - } else + if (!RADEONGetTMDSInfoFromBIOS(output->scrn, tmds)) + RADEONGetTMDSInfoFromTable(output->scrn, tmds); + } else if (value->size == strlen("driver") && !strncmp("driver", s, strlen("driver"))) + RADEONGetTMDSInfoFromTable(output->scrn, tmds); + else return FALSE; return radeon_set_mode_for_property(output); @@ -1490,6 +1509,7 @@ radeon_set_property(xf86OutputPtr output, Atom property, } else return FALSE; } else if (property == tv_hsize_atom) { + radeon_tvout_ptr tvout = &radeon_output->tvout; if (value->type != XA_INTEGER || value->format != 32 || value->size != 1) { @@ -1500,11 +1520,12 @@ radeon_set_property(xf86OutputPtr output, Atom property, if (val < -MAX_H_SIZE || val > MAX_H_SIZE) return FALSE; - radeon_output->hSize = val; - if (radeon_output->tv_on && !IS_AVIVO_VARIANT) + tvout->hSize = val; + if (tvout->tv_on && !IS_AVIVO_VARIANT) RADEONUpdateHVPosition(output, &output->crtc->mode); } else if (property == tv_hpos_atom) { + radeon_tvout_ptr tvout = &radeon_output->tvout; if (value->type != XA_INTEGER || value->format != 32 || value->size != 1) { @@ -1515,11 +1536,12 @@ radeon_set_property(xf86OutputPtr output, Atom property, if (val < -MAX_H_POSITION || val > MAX_H_POSITION) return FALSE; - radeon_output->hPos = val; - if (radeon_output->tv_on && !IS_AVIVO_VARIANT) + tvout->hPos = val; + if (tvout->tv_on && !IS_AVIVO_VARIANT) RADEONUpdateHVPosition(output, &output->crtc->mode); } else if (property == tv_vpos_atom) { + radeon_tvout_ptr tvout = &radeon_output->tvout; if (value->type != XA_INTEGER || value->format != 32 || value->size != 1) { @@ -1530,38 +1552,39 @@ radeon_set_property(xf86OutputPtr output, Atom property, if (val < -MAX_H_POSITION || val > MAX_H_POSITION) return FALSE; - radeon_output->vPos = val; - if (radeon_output->tv_on && !IS_AVIVO_VARIANT) + tvout->vPos = val; + if (tvout->tv_on && !IS_AVIVO_VARIANT) RADEONUpdateHVPosition(output, &output->crtc->mode); } else if (property == tv_std_atom) { const char *s; - TVStd std = radeon_output->tvStd; + radeon_tvout_ptr tvout = &radeon_output->tvout; + TVStd std = tvout->tvStd; if (value->type != XA_STRING || value->format != 8) return FALSE; s = (char*)value->data; if (value->size == strlen("ntsc") && !strncmp("ntsc", s, strlen("ntsc"))) { - radeon_output->tvStd = TV_STD_NTSC; + tvout->tvStd = TV_STD_NTSC; } else if (value->size == strlen("pal") && !strncmp("pal", s, strlen("pal"))) { - radeon_output->tvStd = TV_STD_PAL; + tvout->tvStd = TV_STD_PAL; } else if (value->size == strlen("pal-m") && !strncmp("pal-m", s, strlen("pal-m"))) { - radeon_output->tvStd = TV_STD_PAL_M; + tvout->tvStd = TV_STD_PAL_M; } else if (value->size == strlen("pal-60") && !strncmp("pal-60", s, strlen("pal-60"))) { - radeon_output->tvStd = TV_STD_PAL_60; + tvout->tvStd = TV_STD_PAL_60; } else if (value->size == strlen("ntsc-j") && !strncmp("ntsc-j", s, strlen("ntsc-j"))) { - radeon_output->tvStd = TV_STD_NTSC_J; + tvout->tvStd = TV_STD_NTSC_J; } else if (value->size == strlen("scart-pal") && !strncmp("scart-pal", s, strlen("scart-pal"))) { - radeon_output->tvStd = TV_STD_SCART_PAL; + tvout->tvStd = TV_STD_SCART_PAL; } else if (value->size == strlen("pal-cn") && !strncmp("pal-cn", s, strlen("pal-cn"))) { - radeon_output->tvStd = TV_STD_PAL_CN; + tvout->tvStd = TV_STD_PAL_CN; } else if (value->size == strlen("secam") && !strncmp("secam", s, strlen("secam"))) { - radeon_output->tvStd = TV_STD_SECAM; + tvout->tvStd = TV_STD_SECAM; } else return FALSE; if (!radeon_set_mode_for_property(output)) { - radeon_output->tvStd = std; + tvout->tvStd = std; (void)radeon_set_mode_for_property(output); return FALSE; } @@ -1586,59 +1609,6 @@ static const xf86OutputFuncsRec radeon_output_funcs = { .destroy = radeon_destroy }; -void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output) -{ - RADEONOutputType output = OUTPUT_NONE; - - switch(radeon_output->ConnectorType) { - case CONNECTOR_VGA: - output = OUTPUT_VGA; break; - case CONNECTOR_DVI_I: - output = OUTPUT_DVI_I; break; - case CONNECTOR_DVI_D: - output = OUTPUT_DVI_D; break; - case CONNECTOR_DVI_A: - output = OUTPUT_DVI_A; break; - case CONNECTOR_DIN: - if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) - output = OUTPUT_CV; - else if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) - output = OUTPUT_STV; - break; - case CONNECTOR_STV: - output = OUTPUT_STV; break; - case CONNECTOR_CTV: - output = OUTPUT_CTV; break; - case CONNECTOR_LVDS: - output = OUTPUT_LVDS; break; - case CONNECTOR_HDMI_TYPE_A: - case CONNECTOR_HDMI_TYPE_B: - output = OUTPUT_HDMI; break; - case CONNECTOR_DISPLAY_PORT: - output = OUTPUT_DP; break; - case CONNECTOR_DIGITAL: - case CONNECTOR_NONE: - case CONNECTOR_UNSUPPORTED: - default: - output = OUTPUT_NONE; break; - } - radeon_output->type = output; -} - -#if 0 -static -Bool AVIVOI2CReset(ScrnInfoPtr pScrn) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - unsigned char *RADEONMMIO = info->MMIO; - - OUTREG(AVIVO_I2C_STOP, 1); - INREG(AVIVO_I2C_STOP); - OUTREG(AVIVO_I2C_STOP, 0x0); - return TRUE; -} -#endif - Bool RADEONI2CDoLock(xf86OutputPtr output, int lock_state) { @@ -1716,13 +1686,10 @@ static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data) } -static Bool -RADEONI2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name, Bool dvo) +Bool +RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, char *name, RADEONI2CBusPtr pRADEONI2CBus) { - ScrnInfoPtr pScrn = output->scrn; - RADEONOutputPrivatePtr radeon_output = output->driver_private; I2CBusPtr pI2CBus; - RADEONI2CBusPtr pRADEONI2CBus; pI2CBus = xf86CreateI2CBusRec(); if (!pI2CBus) return FALSE; @@ -1733,12 +1700,6 @@ RADEONI2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name, Bool dvo) pI2CBus->I2CGetBits = RADEONI2CGetBits; pI2CBus->AcknTimeout = 5; - if (dvo) { - pRADEONI2CBus = &(radeon_output->dvo_i2c); - } else { - pRADEONI2CBus = &(radeon_output->ddc_i2c); - } - pI2CBus->DriverPrivate.ptr = (pointer)pRADEONI2CBus; if (!xf86I2CBusInit(pI2CBus)) @@ -1835,297 +1796,41 @@ atom_setup_i2c_bus(int ddc_line) } static void -RADEONGetPanelInfoFromReg (xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONOutputPrivatePtr radeon_output = output->driver_private; - unsigned char *RADEONMMIO = info->MMIO; - uint32_t fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH); - uint32_t fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH); - - radeon_output->PanelPwrDly = 200; - if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) { - radeon_output->PanelYRes = ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >> - RADEON_VERT_PANEL_SHIFT) + 1; - } else { - radeon_output->PanelYRes = (INREG(RADEON_CRTC_V_TOTAL_DISP)>>16) + 1; - } - if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) { - radeon_output->PanelXRes = (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >> - RADEON_HORZ_PANEL_SHIFT) + 1) * 8; - } else { - radeon_output->PanelXRes = ((INREG(RADEON_CRTC_H_TOTAL_DISP)>>16) + 1) * 8; - } - - if ((radeon_output->PanelXRes < 640) || (radeon_output->PanelYRes < 480)) { - radeon_output->PanelXRes = 640; - radeon_output->PanelYRes = 480; - } - - // move this to crtc function - if (xf86ReturnOptValBool(info->Options, OPTION_LVDS_PROBE_PLL, TRUE)) { - uint32_t ppll_div_sel, ppll_val; - - ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3; - RADEONPllErrataAfterIndex(info); - ppll_val = INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel); - if ((ppll_val & 0x000707ff) == 0x1bb) - goto noprobe; - info->FeedbackDivider = ppll_val & 0x7ff; - info->PostDivider = (ppll_val >> 16) & 0x7; - info->RefDivider = info->pll.reference_div; - info->UseBiosDividers = TRUE; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Existing panel PLL dividers will be used.\n"); - } - noprobe: - - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Panel size %dx%d is derived, this may not be correct.\n" - "If not, use PanelSize option to overwrite this setting\n", - radeon_output->PanelXRes, radeon_output->PanelYRes); -} - -/* BIOS may not have right panel size, we search through all supported - * DDC modes looking for the maximum panel size. - */ -static void -RADEONUpdatePanelSize(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONOutputPrivatePtr radeon_output = output->driver_private; - int j; - /* XXX: fixme */ - //xf86MonPtr ddc = pScrn->monitor->DDC; - xf86MonPtr ddc = output->MonInfo; - DisplayModePtr p; - - // crtc should handle? - if ((info->UseBiosDividers && radeon_output->DotClock != 0) || (ddc == NULL)) - return; - - /* Go thru detailed timing table first */ - for (j = 0; j < 4; j++) { - if (ddc->det_mon[j].type == 0) { - struct detailed_timings *d_timings = - &ddc->det_mon[j].section.d_timings; - int match = 0; - - /* If we didn't get a panel clock or guessed one, try to match the - * mode with the panel size. We do that because we _need_ a panel - * clock, or ValidateFPModes will fail, even when UseBiosDividers - * is set. - */ - if (radeon_output->DotClock == 0 && - radeon_output->PanelXRes == d_timings->h_active && - radeon_output->PanelYRes == d_timings->v_active) - match = 1; - - /* If we don't have a BIOS provided panel data with fixed dividers, - * check for a larger panel size - */ - if (radeon_output->PanelXRes < d_timings->h_active && - radeon_output->PanelYRes < d_timings->v_active && - !info->UseBiosDividers) - match = 1; - - if (match) { - radeon_output->PanelXRes = d_timings->h_active; - radeon_output->PanelYRes = d_timings->v_active; - radeon_output->DotClock = d_timings->clock / 1000; - radeon_output->HOverPlus = d_timings->h_sync_off; - radeon_output->HSyncWidth = d_timings->h_sync_width; - radeon_output->HBlank = d_timings->h_blanking; - radeon_output->VOverPlus = d_timings->v_sync_off; - radeon_output->VSyncWidth = d_timings->v_sync_width; - radeon_output->VBlank = d_timings->v_blanking; - radeon_output->Flags = (d_timings->interlaced ? V_INTERLACE : 0); - switch (d_timings->misc) { - case 0: radeon_output->Flags |= V_NHSYNC | V_NVSYNC; break; - case 1: radeon_output->Flags |= V_PHSYNC | V_NVSYNC; break; - case 2: radeon_output->Flags |= V_NHSYNC | V_PVSYNC; break; - case 3: radeon_output->Flags |= V_PHSYNC | V_PVSYNC; break; - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC detailed: %dx%d\n", - radeon_output->PanelXRes, radeon_output->PanelYRes); - } - } - } - - if (info->UseBiosDividers && radeon_output->DotClock != 0) - return; - - /* Search thru standard VESA modes from EDID */ - for (j = 0; j < 8; j++) { - if ((radeon_output->PanelXRes < ddc->timings2[j].hsize) && - (radeon_output->PanelYRes < ddc->timings2[j].vsize)) { - for (p = pScrn->monitor->Modes; p; p = p->next) { - if ((ddc->timings2[j].hsize == p->HDisplay) && - (ddc->timings2[j].vsize == p->VDisplay)) { - float refresh = - (float)p->Clock * 1000.0 / p->HTotal / p->VTotal; - - if (abs((float)ddc->timings2[j].refresh - refresh) < 1.0) { - /* Is this good enough? */ - radeon_output->PanelXRes = ddc->timings2[j].hsize; - radeon_output->PanelYRes = ddc->timings2[j].vsize; - radeon_output->HBlank = p->HTotal - p->HDisplay; - radeon_output->HOverPlus = p->HSyncStart - p->HDisplay; - radeon_output->HSyncWidth = p->HSyncEnd - p->HSyncStart; - radeon_output->VBlank = p->VTotal - p->VDisplay; - radeon_output->VOverPlus = p->VSyncStart - p->VDisplay; - radeon_output->VSyncWidth = p->VSyncEnd - p->VSyncStart; - radeon_output->DotClock = p->Clock; - radeon_output->Flags = p->Flags; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC VESA/EDID: %dx%d\n", - radeon_output->PanelXRes, radeon_output->PanelYRes); - } - } - } - } - } -} - -static Bool -RADEONGetLVDSInfo (xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONOutputPrivatePtr radeon_output = output->driver_private; - char* s; - - if (!RADEONGetLVDSInfoFromBIOS(output)) - RADEONGetPanelInfoFromReg(output); - - if ((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) { - radeon_output->PanelPwrDly = 200; - if (sscanf (s, "%dx%d", &radeon_output->PanelXRes, &radeon_output->PanelYRes) != 2) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid PanelSize option: %s\n", s); - RADEONGetPanelInfoFromReg(output); - } - } - - /* The panel size we collected from BIOS may not be the - * maximum size supported by the panel. If not, we update - * it now. These will be used if no matching mode can be - * found from EDID data. - */ - RADEONUpdatePanelSize(output); - - if (radeon_output->DotClock == 0) { - DisplayModePtr tmp_mode = NULL; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "No valid timing info from BIOS.\n"); - /* No timing information for the native mode, - use whatever specified in the Modeline. - If no Modeline specified, we'll just pick - the VESA mode at 60Hz refresh rate which - is likely to be the best for a flat panel. - */ - tmp_mode = pScrn->monitor->Modes; - while(tmp_mode) { - if ((tmp_mode->HDisplay == radeon_output->PanelXRes) && - (tmp_mode->VDisplay == radeon_output->PanelYRes)) { - - float refresh = - (float)tmp_mode->Clock * 1000.0 / tmp_mode->HTotal / tmp_mode->VTotal; - if ((abs(60.0 - refresh) < 1.0) || - (tmp_mode->type == 0)) { - radeon_output->HBlank = tmp_mode->HTotal - tmp_mode->HDisplay; - radeon_output->HOverPlus = tmp_mode->HSyncStart - tmp_mode->HDisplay; - radeon_output->HSyncWidth = tmp_mode->HSyncEnd - tmp_mode->HSyncStart; - radeon_output->VBlank = tmp_mode->VTotal - tmp_mode->VDisplay; - radeon_output->VOverPlus = tmp_mode->VSyncStart - tmp_mode->VDisplay; - radeon_output->VSyncWidth = tmp_mode->VSyncEnd - tmp_mode->VSyncStart; - radeon_output->DotClock = tmp_mode->Clock; - radeon_output->Flags = 0; - break; - } - } - - tmp_mode = tmp_mode->next; - - if (tmp_mode == pScrn->monitor->Modes) - break; - } - if ((radeon_output->DotClock == 0) && !output->MonInfo) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Panel size is not correctly detected.\n" - "Please try to use PanelSize option for correct settings.\n"); - return FALSE; - } - } - - return TRUE; -} - -static void -RADEONGetTMDSInfoFromTable(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONOutputPrivatePtr radeon_output = output->driver_private; - int i; - - for (i=0; i<4; i++) { - radeon_output->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value; - radeon_output->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq; - } -} - -static void -RADEONGetTMDSInfo(xf86OutputPtr output) -{ - RADEONOutputPrivatePtr radeon_output = output->driver_private; - int i; - - for (i=0; i<4; i++) { - radeon_output->tmds_pll[i].value = 0; - radeon_output->tmds_pll[i].freq = 0; - } - - if (!RADEONGetTMDSInfoFromBIOS(output)) - RADEONGetTMDSInfoFromTable(output); - -} - -static void RADEONGetTVInfo(xf86OutputPtr output) { ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_tvout_ptr tvout = &radeon_output->tvout; char *optstr; - radeon_output->hPos = 0; - radeon_output->vPos = 0; - radeon_output->hSize = 0; + tvout->hPos = 0; + tvout->vPos = 0; + tvout->hSize = 0; + tvout->tv_on = FALSE; if (!RADEONGetTVInfoFromBIOS(output)) { /* set some reasonable defaults */ - radeon_output->default_tvStd = TV_STD_NTSC; - radeon_output->tvStd = TV_STD_NTSC; - radeon_output->TVRefClk = 27.000000000; - radeon_output->SupportedTVStds = TV_STD_NTSC | TV_STD_PAL; + tvout->default_tvStd = TV_STD_NTSC; + tvout->tvStd = TV_STD_NTSC; + tvout->TVRefClk = 27.000000000; + tvout->SupportedTVStds = TV_STD_NTSC | TV_STD_PAL; } optstr = (char *)xf86GetOptValString(info->Options, OPTION_TVSTD); if (optstr) { if (!strncmp("ntsc", optstr, strlen("ntsc"))) - radeon_output->tvStd = TV_STD_NTSC; + tvout->tvStd = TV_STD_NTSC; else if (!strncmp("pal", optstr, strlen("pal"))) - radeon_output->tvStd = TV_STD_PAL; + tvout->tvStd = TV_STD_PAL; else if (!strncmp("pal-m", optstr, strlen("pal-m"))) - radeon_output->tvStd = TV_STD_PAL_M; + tvout->tvStd = TV_STD_PAL_M; else if (!strncmp("pal-60", optstr, strlen("pal-60"))) - radeon_output->tvStd = TV_STD_PAL_60; + tvout->tvStd = TV_STD_PAL_60; else if (!strncmp("ntsc-j", optstr, strlen("ntsc-j"))) - radeon_output->tvStd = TV_STD_NTSC_J; + tvout->tvStd = TV_STD_NTSC_J; else if (!strncmp("scart-pal", optstr, strlen("scart-pal"))) - radeon_output->tvStd = TV_STD_SCART_PAL; + tvout->tvStd = TV_STD_SCART_PAL; else { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid TV Standard: %s\n", optstr); } @@ -2133,77 +1838,29 @@ RADEONGetTVInfo(xf86OutputPtr output) } -static void -RADEONGetTVDacAdjInfo(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONOutputPrivatePtr radeon_output = output->driver_private; - - if (!RADEONGetDAC2InfoFromBIOS(output)) { - radeon_output->ps2_tvdac_adj = default_tvdac_adj[info->ChipFamily]; - if (info->IsMobility) { /* some mobility chips may different */ - if (info->ChipFamily == CHIP_FAMILY_RV250) - radeon_output->ps2_tvdac_adj = 0x00880000; - } - radeon_output->pal_tvdac_adj = radeon_output->ps2_tvdac_adj; - radeon_output->ntsc_tvdac_adj = radeon_output->ps2_tvdac_adj; - } - -} - void RADEONInitConnector(xf86OutputPtr output) { ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONOutputPrivatePtr radeon_output = output->driver_private; - if ((radeon_output->DACType == DAC_TVDAC) && - xf86ReturnOptValBool(info->Options, OPTION_TVDAC_LOAD_DETECT, FALSE)) - radeon_output->load_detection = 1; + radeon_output->rmx_type = RMX_OFF; - if (radeon_output->type == OUTPUT_LVDS) { - radeon_output->rmx_type = RMX_FULL; - RADEONGetLVDSInfo(output); - } - - if (OUTPUT_IS_DVI) { - I2CBusPtr pDVOBus; - radeon_output->rmx_type = RMX_OFF; - if ((!info->IsAtomBios) && radeon_output->TMDSType == TMDS_EXT) { -#if defined(__powerpc__) - radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); - radeon_output->dvo_i2c_slave_addr = 0x70; -#else - if (!RADEONGetExtTMDSInfoFromBIOS(output)) { - radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); - radeon_output->dvo_i2c_slave_addr = 0x70; - } -#endif - if (RADEONI2CInit(output, &pDVOBus, "DVO", TRUE)) { - radeon_output->DVOChip = - RADEONDVODeviceInit(pDVOBus, - radeon_output->dvo_i2c_slave_addr); - if (!radeon_output->DVOChip) - xfree(pDVOBus); - } - } else - RADEONGetTMDSInfo(output); + if (!IS_AVIVO_VARIANT) { + if (radeon_output->devices & (ATOM_DEVICE_CRT2_SUPPORT)) { + if (xf86ReturnOptValBool(info->Options, OPTION_TVDAC_LOAD_DETECT, FALSE)) + radeon_output->load_detection = 1; + } } - if (OUTPUT_IS_TV) + if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT)) RADEONGetTVInfo(output); - if (radeon_output->DACType == DAC_TVDAC) { - radeon_output->tv_on = FALSE; - RADEONGetTVDacAdjInfo(output); - } - - if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) + if (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT)) radeon_output->coherent_mode = TRUE; if (radeon_output->ddc_i2c.valid) - RADEONI2CInit(output, &radeon_output->pI2CBus, output->name, FALSE); + RADEONI2CInit(pScrn, &radeon_output->pI2CBus, output->name, &radeon_output->ddc_i2c); } @@ -2216,136 +1873,254 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn) switch (info->MacModel) { case RADEON_MAC_IBOOK: info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); - info->BiosConnector[0].DACType = DAC_NONE; - info->BiosConnector[0].TMDSType = TMDS_NONE; info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; info->BiosConnector[0].valid = TRUE; + info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_LCD1_SUPPORT, + 0), + ATOM_DEVICE_LCD1_SUPPORT)) + return FALSE; info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); - info->BiosConnector[1].DACType = DAC_TVDAC; info->BiosConnector[1].load_detection = FALSE; - info->BiosConnector[1].TMDSType = TMDS_NONE; info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; info->BiosConnector[1].valid = TRUE; + info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT2_SUPPORT, + 2), + ATOM_DEVICE_CRT2_SUPPORT)) + return FALSE; info->BiosConnector[2].ConnectorType = CONNECTOR_STV; - info->BiosConnector[2].DACType = DAC_TVDAC; info->BiosConnector[2].load_detection = FALSE; - info->BiosConnector[2].TMDSType = TMDS_NONE; info->BiosConnector[2].ddc_i2c.valid = FALSE; info->BiosConnector[2].valid = TRUE; + info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_TV1_SUPPORT, + 2), + ATOM_DEVICE_TV1_SUPPORT)) + return FALSE; return TRUE; case RADEON_MAC_POWERBOOK_EXTERNAL: info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); - info->BiosConnector[0].DACType = DAC_NONE; - info->BiosConnector[0].TMDSType = TMDS_NONE; info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; info->BiosConnector[0].valid = TRUE; + info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_LCD1_SUPPORT, + 0), + ATOM_DEVICE_LCD1_SUPPORT)) + return FALSE; info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); - info->BiosConnector[1].DACType = DAC_PRIMARY; - info->BiosConnector[1].TMDSType = TMDS_EXT; info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I; info->BiosConnector[1].valid = TRUE; + info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT)) + return FALSE; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP2_SUPPORT, + 0), + ATOM_DEVICE_DFP2_SUPPORT)) + return FALSE; info->BiosConnector[2].ConnectorType = CONNECTOR_STV; - info->BiosConnector[2].DACType = DAC_TVDAC; info->BiosConnector[2].load_detection = FALSE; - info->BiosConnector[2].TMDSType = TMDS_NONE; info->BiosConnector[2].ddc_i2c.valid = FALSE; info->BiosConnector[2].valid = TRUE; + info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_TV1_SUPPORT, + 2), + ATOM_DEVICE_TV1_SUPPORT)) + return FALSE; return TRUE; - case RADEON_MAC_POWERBOOK_INTERNAL: info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); - info->BiosConnector[0].DACType = DAC_NONE; - info->BiosConnector[0].TMDSType = TMDS_NONE; info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; info->BiosConnector[0].valid = TRUE; + info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_LCD1_SUPPORT, + 0), + ATOM_DEVICE_LCD1_SUPPORT)) + return FALSE; info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); - info->BiosConnector[1].DACType = DAC_PRIMARY; - info->BiosConnector[1].TMDSType = TMDS_INT; info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I; info->BiosConnector[1].valid = TRUE; + info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT)) + return FALSE; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP1_SUPPORT, + 0), + ATOM_DEVICE_DFP1_SUPPORT)) + return FALSE; info->BiosConnector[2].ConnectorType = CONNECTOR_STV; - info->BiosConnector[2].DACType = DAC_TVDAC; info->BiosConnector[2].load_detection = FALSE; - info->BiosConnector[2].TMDSType = TMDS_NONE; info->BiosConnector[2].ddc_i2c.valid = FALSE; info->BiosConnector[2].valid = TRUE; + info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_TV1_SUPPORT, + 2), + ATOM_DEVICE_TV1_SUPPORT)) + return FALSE; return TRUE; case RADEON_MAC_POWERBOOK_VGA: info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); - info->BiosConnector[0].DACType = DAC_NONE; - info->BiosConnector[0].TMDSType = TMDS_NONE; info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; info->BiosConnector[0].valid = TRUE; + info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_LCD1_SUPPORT, + 0), + ATOM_DEVICE_LCD1_SUPPORT)) + return FALSE; info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); - info->BiosConnector[1].DACType = DAC_PRIMARY; - info->BiosConnector[1].TMDSType = TMDS_NONE; info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; info->BiosConnector[1].valid = TRUE; + info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT)) + return FALSE; info->BiosConnector[2].ConnectorType = CONNECTOR_STV; - info->BiosConnector[2].DACType = DAC_TVDAC; info->BiosConnector[2].load_detection = FALSE; - info->BiosConnector[2].TMDSType = TMDS_NONE; info->BiosConnector[2].ddc_i2c.valid = FALSE; info->BiosConnector[2].valid = TRUE; + info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_TV1_SUPPORT, + 2), + ATOM_DEVICE_TV1_SUPPORT)) + return FALSE; return TRUE; case RADEON_MAC_MINI_EXTERNAL: info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); - info->BiosConnector[0].DACType = DAC_TVDAC; info->BiosConnector[0].load_detection = FALSE; - info->BiosConnector[0].TMDSType = TMDS_EXT; info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I; info->BiosConnector[0].valid = TRUE; + info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT)) + return FALSE; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP2_SUPPORT, + 0), + ATOM_DEVICE_DFP2_SUPPORT)) + return FALSE; info->BiosConnector[1].ConnectorType = CONNECTOR_STV; - info->BiosConnector[1].DACType = DAC_TVDAC; info->BiosConnector[1].load_detection = FALSE; - info->BiosConnector[1].TMDSType = TMDS_NONE; info->BiosConnector[1].ddc_i2c.valid = FALSE; info->BiosConnector[1].valid = TRUE; + info->BiosConnector[1].devices = ATOM_DEVICE_TV1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_TV1_SUPPORT, + 2), + ATOM_DEVICE_TV1_SUPPORT)) + return FALSE; return TRUE; case RADEON_MAC_MINI_INTERNAL: info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); - info->BiosConnector[0].DACType = DAC_TVDAC; info->BiosConnector[0].load_detection = FALSE; - info->BiosConnector[0].TMDSType = TMDS_INT; info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I; info->BiosConnector[0].valid = TRUE; + info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT)) + return FALSE; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP1_SUPPORT, + 0), + ATOM_DEVICE_DFP1_SUPPORT)) + return FALSE; info->BiosConnector[1].ConnectorType = CONNECTOR_STV; - info->BiosConnector[1].DACType = DAC_TVDAC; info->BiosConnector[1].load_detection = FALSE; - info->BiosConnector[1].TMDSType = TMDS_NONE; info->BiosConnector[1].ddc_i2c.valid = FALSE; info->BiosConnector[1].valid = TRUE; + info->BiosConnector[1].devices = ATOM_DEVICE_TV1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_TV1_SUPPORT, + 2), + ATOM_DEVICE_TV1_SUPPORT)) + return FALSE; return TRUE; case RADEON_MAC_IMAC_G5_ISIGHT: info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); - info->BiosConnector[0].DACType = DAC_NONE; - info->BiosConnector[0].TMDSType = TMDS_INT; info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_D; info->BiosConnector[0].valid = TRUE; + info->BiosConnector[0].devices = ATOM_DEVICE_DFP1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP1_SUPPORT, + 0), + ATOM_DEVICE_DFP1_SUPPORT)) + return FALSE; info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); - info->BiosConnector[1].DACType = DAC_TVDAC; info->BiosConnector[1].load_detection = FALSE; - info->BiosConnector[1].TMDSType = TMDS_NONE; info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; info->BiosConnector[1].valid = TRUE; + info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT2_SUPPORT, + 2), + ATOM_DEVICE_CRT2_SUPPORT)) + return FALSE; info->BiosConnector[2].ConnectorType = CONNECTOR_STV; - info->BiosConnector[2].DACType = DAC_TVDAC; info->BiosConnector[2].load_detection = FALSE; - info->BiosConnector[2].TMDSType = TMDS_NONE; info->BiosConnector[2].ddc_i2c.valid = FALSE; info->BiosConnector[2].valid = TRUE; + info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_TV1_SUPPORT, + 2), + ATOM_DEVICE_TV1_SUPPORT)) + return FALSE; return TRUE; case RADEON_MAC_EMAC: /* eMac G4 800/1.0 with radeon 7500, no EDID on internal monitor @@ -2353,24 +2128,39 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn) * different ddc setups. need to verify */ info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); - info->BiosConnector[0].DACType = DAC_PRIMARY; - info->BiosConnector[0].TMDSType = TMDS_NONE; info->BiosConnector[0].ConnectorType = CONNECTOR_VGA; info->BiosConnector[0].valid = TRUE; + info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT)) + return FALSE; info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); - info->BiosConnector[1].DACType = DAC_TVDAC; info->BiosConnector[1].load_detection = FALSE; - info->BiosConnector[1].TMDSType = TMDS_NONE; info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; info->BiosConnector[1].valid = TRUE; + info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT2_SUPPORT, + 2), + ATOM_DEVICE_CRT2_SUPPORT)) + return FALSE; info->BiosConnector[2].ConnectorType = CONNECTOR_STV; - info->BiosConnector[2].DACType = DAC_TVDAC; info->BiosConnector[2].load_detection = FALSE; - info->BiosConnector[2].TMDSType = TMDS_NONE; info->BiosConnector[2].ddc_i2c.valid = FALSE; info->BiosConnector[2].valid = TRUE; + info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_TV1_SUPPORT, + 2), + ATOM_DEVICE_TV1_SUPPORT)) + return FALSE; return TRUE; default: return FALSE; @@ -2385,152 +2175,170 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn) RADEONInfoPtr info = RADEONPTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + if (IS_AVIVO_VARIANT) + return; + if (!pRADEONEnt->HasCRTC2) { info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); - info->BiosConnector[0].DACType = DAC_PRIMARY; - info->BiosConnector[0].TMDSType = TMDS_NONE; info->BiosConnector[0].ConnectorType = CONNECTOR_VGA; info->BiosConnector[0].valid = TRUE; + info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT; + radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT); return; } - if (IS_AVIVO_VARIANT) { - if (info->IsMobility) { - info->BiosConnector[0].ddc_i2c = atom_setup_i2c_bus(0x7e60); - info->BiosConnector[0].DACType = DAC_NONE; - info->BiosConnector[0].TMDSType = TMDS_NONE; + if (info->IsMobility) { + /* Below is the most common setting, but may not be true */ + if (info->IsIGP) { + info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK); info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; - info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; info->BiosConnector[0].valid = TRUE; - - info->BiosConnector[1].ddc_i2c = atom_setup_i2c_bus(0x7e40); - info->BiosConnector[1].DACType = DAC_PRIMARY; - info->BiosConnector[1].TMDSType = TMDS_NONE; + info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; + radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_LCD1_SUPPORT, + 0), + ATOM_DEVICE_LCD1_SUPPORT); + + /* IGP only has TVDAC */ + if ((info->ChipFamily == CHIP_FAMILY_RS400) || + (info->ChipFamily == CHIP_FAMILY_RS480)) + info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); + else + info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); + info->BiosConnector[1].load_detection = FALSE; info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; - info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT; info->BiosConnector[1].valid = TRUE; + info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT; + radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 2), + ATOM_DEVICE_CRT1_SUPPORT); } else { - info->BiosConnector[0].ddc_i2c = atom_setup_i2c_bus(0x7e50); - info->BiosConnector[0].DACType = DAC_TVDAC; - info->BiosConnector[0].TMDSType = TMDS_INT; - info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I; - info->BiosConnector[0].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT; +#if defined(__powerpc__) + info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); +#else + info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK); +#endif + info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; info->BiosConnector[0].valid = TRUE; + info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; + radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_LCD1_SUPPORT, + 0), + ATOM_DEVICE_LCD1_SUPPORT); - info->BiosConnector[1].ddc_i2c = atom_setup_i2c_bus(0x7e40); - info->BiosConnector[1].DACType = DAC_PRIMARY; - info->BiosConnector[1].TMDSType = TMDS_NONE; + info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; - info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT; info->BiosConnector[1].valid = TRUE; + info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT; + radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT); } - - info->BiosConnector[2].ConnectorType = CONNECTOR_STV; - info->BiosConnector[2].DACType = DAC_TVDAC; - info->BiosConnector[2].TMDSType = TMDS_NONE; - info->BiosConnector[2].ddc_i2c.valid = FALSE; - info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; - info->BiosConnector[2].valid = TRUE; } else { - if (info->IsMobility) { - /* Below is the most common setting, but may not be true */ - if (info->IsIGP) { - info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK); - info->BiosConnector[0].DACType = DAC_NONE; - info->BiosConnector[0].TMDSType = TMDS_NONE; - info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; - info->BiosConnector[0].valid = TRUE; - - /* IGP only has TVDAC */ - if ((info->ChipFamily == CHIP_FAMILY_RS400) || - (info->ChipFamily == CHIP_FAMILY_RS480)) - info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); - else - info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); - info->BiosConnector[1].DACType = DAC_TVDAC; - info->BiosConnector[1].load_detection = FALSE; - info->BiosConnector[1].TMDSType = TMDS_NONE; - info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; - info->BiosConnector[1].valid = TRUE; - } else { -#if defined(__powerpc__) - info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); -#else - info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK); -#endif - info->BiosConnector[0].DACType = DAC_NONE; - info->BiosConnector[0].TMDSType = TMDS_NONE; - info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; - info->BiosConnector[0].valid = TRUE; - - info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); - info->BiosConnector[1].DACType = DAC_PRIMARY; - info->BiosConnector[1].TMDSType = TMDS_NONE; - info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; - info->BiosConnector[1].valid = TRUE; - } + /* Below is the most common setting, but may not be true */ + if (info->IsIGP) { + if ((info->ChipFamily == CHIP_FAMILY_RS400) || + (info->ChipFamily == CHIP_FAMILY_RS480)) + info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); + else + info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); + info->BiosConnector[0].load_detection = FALSE; + info->BiosConnector[0].ConnectorType = CONNECTOR_VGA; + info->BiosConnector[0].valid = TRUE; + info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT; + radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT); + + /* not sure what a good default DDCType for DVI on + * IGP desktop chips is + */ + info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); /* DDC_DVI? */ + info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_D; + info->BiosConnector[1].valid = TRUE; + info->BiosConnector[1].devices = ATOM_DEVICE_DFP1_SUPPORT; + radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP1_SUPPORT, + 0), + ATOM_DEVICE_DFP1_SUPPORT); } else { - /* Below is the most common setting, but may not be true */ - if (info->IsIGP) { - if ((info->ChipFamily == CHIP_FAMILY_RS400) || - (info->ChipFamily == CHIP_FAMILY_RS480)) - info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); - else - info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); - info->BiosConnector[0].DACType = DAC_TVDAC; - info->BiosConnector[0].load_detection = FALSE; - info->BiosConnector[0].TMDSType = TMDS_NONE; - info->BiosConnector[0].ConnectorType = CONNECTOR_VGA; - info->BiosConnector[0].valid = TRUE; - - /* not sure what a good default DDCType for DVI on - * IGP desktop chips is - */ - info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); /* DDC_DVI? */ - info->BiosConnector[1].DACType = DAC_NONE; - info->BiosConnector[1].TMDSType = TMDS_EXT; - info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_D; - info->BiosConnector[1].valid = TRUE; - } else { - info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); - info->BiosConnector[0].DACType = DAC_TVDAC; - info->BiosConnector[0].load_detection = FALSE; - info->BiosConnector[0].TMDSType = TMDS_INT; - info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I; - info->BiosConnector[0].valid = TRUE; + info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); + info->BiosConnector[0].load_detection = FALSE; + info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I; + info->BiosConnector[0].valid = TRUE; + info->BiosConnector[0].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT; + radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT2_SUPPORT, + 2), + ATOM_DEVICE_CRT2_SUPPORT); + radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP1_SUPPORT, + 0), + ATOM_DEVICE_DFP1_SUPPORT); #if defined(__powerpc__) - info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); - info->BiosConnector[1].DACType = DAC_PRIMARY; - info->BiosConnector[1].TMDSType = TMDS_EXT; - info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I; - info->BiosConnector[1].valid = TRUE; + info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); + info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I; + info->BiosConnector[1].valid = TRUE; + info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT; + radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT); + radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP2_SUPPORT, + 0), + ATOM_DEVICE_DFP2_SUPPORT); #else - info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); - info->BiosConnector[1].DACType = DAC_PRIMARY; - info->BiosConnector[1].TMDSType = TMDS_EXT; - info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; - info->BiosConnector[1].valid = TRUE; + info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); + info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; + info->BiosConnector[1].valid = TRUE; + info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT; + radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT); #endif - } } + } - if (info->InternalTVOut) { - info->BiosConnector[2].ConnectorType = CONNECTOR_STV; - info->BiosConnector[2].DACType = DAC_TVDAC; - info->BiosConnector[2].load_detection = FALSE; - info->BiosConnector[2].TMDSType = TMDS_NONE; - info->BiosConnector[2].ddc_i2c.valid = FALSE; - info->BiosConnector[2].valid = TRUE; - } + if (info->InternalTVOut) { + info->BiosConnector[2].ConnectorType = CONNECTOR_STV; + info->BiosConnector[2].load_detection = FALSE; + info->BiosConnector[2].ddc_i2c.valid = FALSE; + info->BiosConnector[2].valid = TRUE; + info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; + radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_TV1_SUPPORT, + 2), + ATOM_DEVICE_TV1_SUPPORT); + } - /* Some cards have the DDC lines swapped and we have no way to - * detect it yet (Mac cards) - */ - if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) { - info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); - info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); - } + /* Some cards have the DDC lines swapped and we have no way to + * detect it yet (Mac cards) + */ + if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) { + info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); + info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); } } @@ -2666,21 +2474,21 @@ radeon_output_clones (ScrnInfoPtr pScrn, xf86OutputPtr output) return index_mask; /* LVDS is too wacky */ - if (radeon_output->type == OUTPUT_LVDS) + if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) + return index_mask; + + if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT)) return index_mask; for (o = 0; o < config->num_output; o++) { xf86OutputPtr clone = config->output[o]; RADEONOutputPrivatePtr radeon_clone = clone->driver_private; + if (output == clone) /* don't clone yourself */ continue; - else if (radeon_clone->type == OUTPUT_LVDS) /* LVDS */ + else if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT)) /* LVDS */ continue; - else if ((radeon_output->DACType != DAC_NONE) && - (radeon_output->DACType == radeon_clone->DACType)) /* shared dac */ - continue; - else if ((radeon_output->TMDSType != TMDS_NONE) && - (radeon_output->TMDSType == radeon_clone->TMDSType)) /* shared tmds */ + else if (radeon_clone->devices & (ATOM_DEVICE_TV_SUPPORT)) /* TV */ continue; else index_mask |= (1 << o); @@ -2697,7 +2505,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) RADEONInfoPtr info = RADEONPTR(pScrn); xf86OutputPtr output; char *optstr; - int i = 0; + int i; int num_vga = 0; int num_dvi = 0; int num_hdmi = 0; @@ -2707,13 +2515,13 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) * The information should be correct even on a OEM card. */ for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) { + info->encoders[i] = NULL; info->BiosConnector[i].valid = FALSE; info->BiosConnector[i].load_detection = TRUE; info->BiosConnector[i].shared_ddc = FALSE; info->BiosConnector[i].ddc_i2c.valid = FALSE; - info->BiosConnector[i].DACType = DAC_NONE; - info->BiosConnector[i].TMDSType = TMDS_NONE; info->BiosConnector[i].ConnectorType = CONNECTOR_NONE; + info->BiosConnector[i].devices = 0; } #if defined(__powerpc__) @@ -2768,40 +2576,75 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) if (optstr) { unsigned int ddc_line[2]; + int DACType[2], TMDSType[2]; for (i = 2; i < RADEON_MAX_BIOS_CONNECTOR; i++) { info->BiosConnector[i].valid = FALSE; } - info->BiosConnector[0].valid = TRUE; - info->BiosConnector[1].valid = TRUE; + if (sscanf(optstr, "%u,%u,%u,%u,%u,%u,%u,%u", &ddc_line[0], - &info->BiosConnector[0].DACType, - &info->BiosConnector[0].TMDSType, + &DACType[0], + &TMDSType[0], &info->BiosConnector[0].ConnectorType, &ddc_line[1], - &info->BiosConnector[1].DACType, - &info->BiosConnector[1].TMDSType, + &DACType[1], + &TMDSType[1], &info->BiosConnector[1].ConnectorType) != 8) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid ConnectorTable option: %s\n", optstr); return FALSE; } - if (info->BiosConnector[0].DACType == DAC_TVDAC) - info->BiosConnector[0].load_detection = FALSE; - if (info->BiosConnector[1].DACType == DAC_TVDAC) - info->BiosConnector[1].load_detection = FALSE; - - info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(ddc_line[0]); - info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(ddc_line[1]); + for (i = 0; i < 2; i++) { + info->BiosConnector[i].valid = TRUE; + info->BiosConnector[i].ddc_i2c = legacy_setup_i2c_bus(ddc_line[i]); + switch (DACType[i]) { + case 1: + info->BiosConnector[i].devices |= ATOM_DEVICE_CRT1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT)) + return FALSE; + info->BiosConnector[i].load_detection = TRUE; + break; + case 2: + info->BiosConnector[i].devices |= ATOM_DEVICE_CRT2_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_CRT1_SUPPORT, + 2), + ATOM_DEVICE_CRT1_SUPPORT)) + return FALSE; + info->BiosConnector[i].load_detection = FALSE; + break; + } + switch (TMDSType[i]) { + case 1: + info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP1_SUPPORT, + 0), + ATOM_DEVICE_DFP1_SUPPORT)) + return FALSE; + break; + case 2: + info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT; + if (!radeon_add_encoder(pScrn, + radeon_get_encoder_id_from_supported_device(pScrn, + ATOM_DEVICE_DFP2_SUPPORT, + 0), + ATOM_DEVICE_DFP2_SUPPORT)) + return FALSE; + break; + } + } } - info->tvdac_use_count = 0; for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) { if (info->BiosConnector[i].valid) { - if (info->BiosConnector[i].DACType == DAC_TVDAC) - info->tvdac_use_count++; - if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) || (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I) || (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A)) { @@ -2815,14 +2658,6 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) } } - /* clear the enable masks */ - info->output_crt1 = 0; - info->output_crt2 = 0; - info->output_dfp1 = 0; - info->output_dfp2 = 0; - info->output_lcd1 = 0; - info->output_tv1 = 0; - for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) { if (info->BiosConnector[i].valid) { RADEONOutputPrivatePtr radeon_output; @@ -2837,23 +2672,13 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) radeon_output->MonType = MT_UNKNOWN; radeon_output->ConnectorType = info->BiosConnector[i].ConnectorType; radeon_output->devices = info->BiosConnector[i].devices; - radeon_output->output_id = info->BiosConnector[i].output_id; radeon_output->ddc_i2c = info->BiosConnector[i].ddc_i2c; radeon_output->igp_lane_info = info->BiosConnector[i].igp_lane_info; radeon_output->shared_ddc = info->BiosConnector[i].shared_ddc; radeon_output->load_detection = info->BiosConnector[i].load_detection; + radeon_output->linkb = info->BiosConnector[i].linkb; + radeon_output->connector_id = info->BiosConnector[i].connector_object; - if (radeon_output->ConnectorType == CONNECTOR_DVI_D) - radeon_output->DACType = DAC_NONE; - else - radeon_output->DACType = info->BiosConnector[i].DACType; - - if (radeon_output->ConnectorType == CONNECTOR_VGA) - radeon_output->TMDSType = TMDS_NONE; - else - radeon_output->TMDSType = info->BiosConnector[i].TMDSType; - - RADEONSetOutputType(pScrn, radeon_output); if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) || (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I) || (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A)) { @@ -2879,7 +2704,8 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) output = xf86OutputCreate(pScrn, &radeon_output_funcs, "HDMI-0"); } } else - output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]); + output = xf86OutputCreate(pScrn, &radeon_output_funcs, + ConnectorTypeName[radeon_output->ConnectorType]); if (!output) { return FALSE; @@ -2887,10 +2713,10 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) output->driver_private = radeon_output; output->possible_crtcs = 1; /* crtc2 can drive LVDS, it just doesn't have RMX */ - if (radeon_output->type != OUTPUT_LVDS) + if (!(radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT))) output->possible_crtcs |= 2; - /* we can clone the DACs, and probably TV-out, + /* we can clone the DACs, and probably TV-out, but I'm not sure it's worth the trouble */ output->possible_clones = 0; diff --git a/src/radeon_probe.h b/src/radeon_probe.h index 5cd610cc..28df6962 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -52,6 +52,9 @@ extern DriverRec RADEON; +#define RADEON_MAX_CRTC 2 +#define RADEON_MAX_BIOS_CONNECTOR 16 + typedef enum { MT_UNKNOWN = -1, @@ -89,26 +92,6 @@ typedef enum typedef enum { - DAC_NONE = 0, - DAC_PRIMARY = 1, - DAC_TVDAC = 2, - DAC_EXT = 3 -} RADEONDacType; - -typedef enum -{ - TMDS_NONE = 0, - TMDS_INT = 1, - TMDS_EXT = 2, - TMDS_LVTMA = 3, - TMDS_DDIA = 4, - TMDS_UNIPHY = 5, - TMDS_UNIPHY1 = 6, - TMDS_UNIPHY2 = 7 -} RADEONTmdsType; - -typedef enum -{ DVI_AUTO, DVI_DIGITAL, DVI_ANALOG @@ -126,27 +109,6 @@ typedef struct { uint32_t value; }RADEONTMDSPll; -typedef enum -{ - OUTPUT_NONE, - OUTPUT_VGA, - OUTPUT_DVI_I, - OUTPUT_DVI_D, - OUTPUT_DVI_A, - OUTPUT_LVDS, - OUTPUT_STV, - OUTPUT_CTV, - OUTPUT_CV, - OUTPUT_HDMI, - OUTPUT_DP -} RADEONOutputType; - -#define OUTPUT_IS_DVI ((radeon_output->type == OUTPUT_DVI_D || \ - radeon_output->type == OUTPUT_DVI_I || \ - radeon_output->type == OUTPUT_DVI_A)) -#define OUTPUT_IS_TV ((radeon_output->type == OUTPUT_STV || \ - radeon_output->type == OUTPUT_CTV)) - /* standards */ typedef enum { @@ -197,38 +159,25 @@ typedef struct _RADEONCrtcPrivateRec { Bool enabled; } RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr; -typedef struct { - RADEONDacType DACType; - RADEONTmdsType TMDSType; - RADEONConnectorType ConnectorType; - Bool valid; - int output_id; - int devices; - int hpd_mask; - RADEONI2CBusRec ddc_i2c; - int igp_lane_info; - Bool shared_ddc; - int i2c_line_mux; - Bool load_detection; -} RADEONBIOSConnector; - -typedef struct _RADEONOutputPrivateRec { - int num; - RADEONOutputType type; +typedef struct _radeon_encoder { + uint16_t encoder_id; + int use_count; void *dev_priv; - uint32_t ddc_line; - RADEONDacType DACType; - RADEONDviType DVIType; - RADEONTmdsType TMDSType; - RADEONConnectorType ConnectorType; - RADEONMonitorType MonType; - int crtc_num; - int DDCReg; - I2CBusPtr pI2CBus; - RADEONI2CBusRec ddc_i2c; - uint32_t ps2_tvdac_adj; - uint32_t pal_tvdac_adj; - uint32_t ntsc_tvdac_adj; +} radeon_encoder_rec, *radeon_encoder_ptr; + +typedef struct _radeon_tvout { + /* TV out */ + TVStd default_tvStd; + TVStd tvStd; + int hPos; + int vPos; + int hSize; + float TVRefClk; + int SupportedTVStds; + Bool tv_on; +} radeon_tvout_rec, *radeon_tvout_ptr; + +typedef struct _radeon_native_mode { /* panel stuff */ int PanelXRes; int PanelYRes; @@ -238,38 +187,90 @@ typedef struct _RADEONOutputPrivateRec { int VOverPlus; int VSyncWidth; int VBlank; - int Flags; /* Saved copy of mode flags */ + int Flags; int DotClock; +} radeon_native_mode_rec, *radeon_native_mode_ptr; + +typedef struct _radeon_tvdac { + // tv dac + uint32_t ps2_tvdac_adj; + uint32_t pal_tvdac_adj; + uint32_t ntsc_tvdac_adj; +} radeon_tvdac_rec, *radeon_tvdac_ptr; + +typedef struct _radeon_tmds { + // tmds + RADEONTMDSPll tmds_pll[4]; +} radeon_tmds_rec, *radeon_tmds_ptr; + +typedef struct _radeon_lvds { + // panel mode + radeon_native_mode_rec native_mode; + // lvds int PanelPwrDly; int lvds_misc; int lvds_ss_id; - RADEONTMDSPll tmds_pll[4]; - RADEONRMXType rmx_type; +} radeon_lvds_rec, *radeon_lvds_ptr; + +typedef struct _radeon_dvo { /* dvo */ I2CDevPtr DVOChip; RADEONI2CBusRec dvo_i2c; int dvo_i2c_slave_addr; Bool dvo_duallink; - /* TV out */ - TVStd default_tvStd; - TVStd tvStd; - int hPos; - int vPos; - int hSize; - float TVRefClk; - int SupportedTVStds; - Bool tv_on; - int load_detection; - /* dig block */ - int transmitter_config; - Bool coherent_mode; +} radeon_dvo_rec, *radeon_dvo_ptr; + +typedef struct { + RADEONConnectorType ConnectorType; + Bool valid; + int output_id; + int devices; + int hpd_mask; + RADEONI2CBusRec ddc_i2c; int igp_lane_info; + Bool shared_ddc; + int i2c_line_mux; + Bool load_detection; + Bool linkb; + uint16_t connector_object; +} RADEONBIOSConnector; - char *name; - int output_id; - int devices; +typedef struct _RADEONOutputPrivateRec { + uint16_t connector_id; + uint32_t devices; + uint32_t active_device; Bool enabled; + + int load_detection; + + // DVI/HDMI + Bool coherent_mode; + Bool linkb; + + RADEONConnectorType ConnectorType; + RADEONDviType DVIType; + RADEONMonitorType MonType; + + // DDC info + I2CBusPtr pI2CBus; + RADEONI2CBusRec ddc_i2c; Bool shared_ddc; + // router info + // HDP info + + // panel mode + radeon_native_mode_rec native_mode; + + // RMX + RADEONRMXType rmx_type; + int Flags; + + //tvout - move to encoder + radeon_tvout_rec tvout; + + /* dce 3.x dig block */ + int transmitter_config; + int igp_lane_info; } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr; struct avivo_pll_state { @@ -573,9 +574,6 @@ typedef struct { } RADEONSaveRec, *RADEONSavePtr; -#define RADEON_MAX_CRTC 2 -#define RADEON_MAX_BIOS_CONNECTOR 16 - typedef struct { Bool HasSecondary; diff --git a/src/radeon_tv.c b/src/radeon_tv.c index 90d1ac96..98e3b0ab 100644 --- a/src/radeon_tv.c +++ b/src/radeon_tv.c @@ -23,6 +23,7 @@ #include "radeon_probe.h" #include "radeon_version.h" #include "radeon_tv.h" +#include "radeon_atombios.h" /********************************************************************** * @@ -597,6 +598,7 @@ static Bool RADEONInitTVRestarts(xf86OutputPtr output, RADEONSavePtr save, DisplayModePtr mode) { RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_tvout_ptr tvout = &radeon_output->tvout; RADEONInfoPtr info = RADEONPTR(output->scrn); RADEONPLLPtr pll = &info->pll; int restart; @@ -612,9 +614,9 @@ static Bool RADEONInitTVRestarts(xf86OutputPtr output, RADEONSavePtr save, const TVModeConstants *constPtr; /* FIXME: need to revisit this when we add more modes */ - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M) { + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M) { if (pll->reference_freq == 2700) constPtr = &availableTVModes[0]; else @@ -629,20 +631,20 @@ static Bool RADEONInitTVRestarts(xf86OutputPtr output, RADEONSavePtr save, hTotal = constPtr->horTotal; vTotal = constPtr->verTotal; - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M || - radeon_output->tvStd == TV_STD_PAL_60) + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M || + tvout->tvStd == TV_STD_PAL_60) fTotal = NTSC_TV_VFTOTAL + 1; else fTotal = PAL_TV_VFTOTAL + 1; /* Adjust positions 1&2 in hor. code timing table */ - hOffset = radeon_output->hPos * H_POS_UNIT; + hOffset = tvout->hPos * H_POS_UNIT; - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M) { + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M) { /* improve image centering */ hOffset -= 50; p1 = hor_timing_NTSC[ H_TABLE_POS1 ]; @@ -672,18 +674,18 @@ static Bool RADEONInitTVRestarts(xf86OutputPtr output, RADEONSavePtr save, * Convert vPos TV lines to n. of CRTC pixels * Be verrrrry careful when mixing signed & unsigned values in C.. */ - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M || - radeon_output->tvStd == TV_STD_PAL_60) - vOffset = ((int)(vTotal * hTotal) * 2 * radeon_output->vPos) / (int)(NTSC_TV_LINES_PER_FRAME); + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M || + tvout->tvStd == TV_STD_PAL_60) + vOffset = ((int)(vTotal * hTotal) * 2 * tvout->vPos) / (int)(NTSC_TV_LINES_PER_FRAME); else - vOffset = ((int)(vTotal * hTotal) * 2 * radeon_output->vPos) / (int)(PAL_TV_LINES_PER_FRAME); + vOffset = ((int)(vTotal * hTotal) * 2 * tvout->vPos) / (int)(PAL_TV_LINES_PER_FRAME); restart -= vOffset + hOffset; ErrorF("computeRestarts: def = %u, h = %d, v = %d, p1=%04x, p2=%04x, restart = %d\n", - constPtr->defRestart , radeon_output->hPos , radeon_output->vPos , p1 , p2 , restart); + constPtr->defRestart , tvout->hPos , tvout->vPos , p1 , p2 , restart); save->tv_hrestart = restart % hTotal; restart /= hTotal; @@ -696,19 +698,19 @@ static Bool RADEONInitTVRestarts(xf86OutputPtr output, RADEONSavePtr save, (unsigned)save->tv_hrestart); /* Compute H_INC from hSize */ - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M) + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M) hInc = (uint16_t)((int)(constPtr->horResolution * 4096 * NTSC_TV_CLOCK_T) / - (radeon_output->hSize * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE))); + (tvout->hSize * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE))); else hInc = (uint16_t)((int)(constPtr->horResolution * 4096 * PAL_TV_CLOCK_T) / - (radeon_output->hSize * (int)(PAL_TV_H_SIZE_UNIT) + (int)(PAL_TV_ZERO_H_SIZE))); + (tvout->hSize * (int)(PAL_TV_H_SIZE_UNIT) + (int)(PAL_TV_ZERO_H_SIZE))); save->tv_timing_cntl = (save->tv_timing_cntl & ~RADEON_H_INC_MASK) | ((uint32_t)hInc << RADEON_H_INC_SHIFT); - ErrorF("computeRestarts: hSize=%d,hInc=%u\n" , radeon_output->hSize , hInc); + ErrorF("computeRestarts: hSize=%d,hInc=%u\n" , tvout->hSize , hInc); return hChanged; } @@ -719,6 +721,7 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save, { ScrnInfoPtr pScrn = output->scrn; RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_tvout_ptr tvout = &radeon_output->tvout; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONPLLPtr pll = &info->pll; unsigned m, n, p; @@ -728,11 +731,21 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save, const TVModeConstants *constPtr; const uint16_t *hor_timing; const uint16_t *vert_timing; + radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); + radeon_tvdac_ptr tvdac = NULL; + + if (radeon_encoder == NULL) + return; + + tvdac = (radeon_tvdac_ptr)radeon_encoder->dev_priv; + + if (tvdac == NULL) + return; /* FIXME: need to revisit this when we add more modes */ - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M) { + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M) { if (pll->reference_freq == 2700) constPtr = &availableTVModes[0]; else @@ -764,8 +777,8 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save, if (!IS_R300_VARIANT) save->tv_master_cntl |= RADEON_TVCLK_ALWAYS_ONb; - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J) + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J) save->tv_master_cntl |= RADEON_RESTART_PHASE_FIX; save->tv_modulator_cntl1 = RADEON_SLEW_RATE_LIMIT @@ -774,13 +787,13 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save, | RADEON_UVFLT_EN | (6 << RADEON_CY_FILT_BLEND_SHIFT); - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J) { + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J) { save->tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT) | (0x3b << RADEON_BLANK_LEVEL_SHIFT); save->tv_modulator_cntl2 = (-111 & RADEON_TV_U_BURST_LEVEL_MASK) | ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT); - } else if (radeon_output->tvStd == TV_STD_SCART_PAL) { + } else if (tvout->tvStd == TV_STD_SCART_PAL) { save->tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN; save->tv_modulator_cntl2 = (0 & RADEON_TV_U_BURST_LEVEL_MASK) | ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT); @@ -817,10 +830,10 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save, save->tv_sync_size = constPtr->horResolution + 8; - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M || - radeon_output->tvStd == TV_STD_PAL_60) + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M || + tvout->tvStd == TV_STD_PAL_60) vert_space = constPtr->verTotal * 2 * 10000 / NTSC_TV_LINES_PER_FRAME; else vert_space = constPtr->verTotal * 2 * 10000 / PAL_TV_LINES_PER_FRAME; @@ -837,10 +850,10 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save, else save->tv_vscaler_cntl1 |= (2 << RADEON_Y_DEL_W_SIG_SHIFT); - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M || - radeon_output->tvStd == TV_STD_PAL_60) + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M || + tvout->tvStd == TV_STD_PAL_60) flicker_removal = (float) constPtr->verTotal * 2.0 / NTSC_TV_LINES_PER_FRAME + 0.5; else @@ -876,18 +889,18 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save, tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000; save->tv_timing_cntl = tmp; - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M || - radeon_output->tvStd == TV_STD_PAL_60) - save->tv_dac_cntl = radeon_output->ntsc_tvdac_adj; + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M || + tvout->tvStd == TV_STD_PAL_60) + save->tv_dac_cntl = tvdac->ntsc_tvdac_adj; else - save->tv_dac_cntl = radeon_output->pal_tvdac_adj; + save->tv_dac_cntl = tvdac->pal_tvdac_adj; save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD); - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J) + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J) save->tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC; else save->tv_dac_cntl |= RADEON_TV_DAC_STD_PAL; @@ -907,8 +920,8 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save, } #endif - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J) { + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J) { if (pll->reference_freq == 2700) { m = NTSC_TV_PLL_M_27; n = NTSC_TV_PLL_N_27; @@ -948,28 +961,28 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save, save->tv_vdisp = constPtr->verResolution - 1; - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M || - radeon_output->tvStd == TV_STD_PAL_60) + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M || + tvout->tvStd == TV_STD_PAL_60) save->tv_ftotal = NTSC_TV_VFTOTAL; else save->tv_ftotal = PAL_TV_VFTOTAL; save->tv_vtotal = constPtr->verTotal - 1; - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M) { + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M) { hor_timing = hor_timing_NTSC; } else { hor_timing = hor_timing_PAL; } - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M || - radeon_output->tvStd == TV_STD_PAL_60) { + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M || + tvout->tvStd == TV_STD_PAL_60) { vert_timing = vert_timing_NTSC; } else { vert_timing = vert_timing_PAL; @@ -1049,13 +1062,14 @@ void RADEONAdjustCrtcRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save, { const TVModeConstants *constPtr; RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_tvout_ptr tvout = &radeon_output->tvout; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONPLLPtr pll = &info->pll; /* FIXME: need to revisit this when we add more modes */ - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M) { + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M) { if (pll->reference_freq == 2700) constPtr = &availableTVModes[0]; else @@ -1089,13 +1103,14 @@ void RADEONAdjustPLLRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save, unsigned postDiv; const TVModeConstants *constPtr; RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_tvout_ptr tvout = &radeon_output->tvout; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONPLLPtr pll = &info->pll; /* FIXME: need to revisit this when we add more modes */ - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M) { + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M) { if (pll->reference_freq == 2700) constPtr = &availableTVModes[0]; else @@ -1151,13 +1166,14 @@ void RADEONAdjustCrtc2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save, { const TVModeConstants *constPtr; RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_tvout_ptr tvout = &radeon_output->tvout; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONPLLPtr pll = &info->pll; /* FIXME: need to revisit this when we add more modes */ - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M) { + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M) { if (pll->reference_freq == 2700) constPtr = &availableTVModes[0]; else @@ -1191,13 +1207,14 @@ void RADEONAdjustPLL2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save, unsigned postDiv; const TVModeConstants *constPtr; RADEONOutputPrivatePtr radeon_output = output->driver_private; + radeon_tvout_ptr tvout = &radeon_output->tvout; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONPLLPtr pll = &info->pll; /* FIXME: need to revisit this when we add more modes */ - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M) { + if (tvout->tvStd == TV_STD_NTSC || + tvout->tvStd == TV_STD_NTSC_J || + tvout->tvStd == TV_STD_PAL_M) { if (pll->reference_freq == 2700) constPtr = &availableTVModes[0]; else diff --git a/src/radeon_video.c b/src/radeon_video.c index 423ea28b..2fb5fcce 100644 --- a/src/radeon_video.c +++ b/src/radeon_video.c @@ -2559,7 +2559,7 @@ RADEONDisplayVideo( radeon_output = output->driver_private; if (radeon_output->Flags & RADEON_USE_RMX) v_inc = ((src_h * mode->CrtcVDisplay / - radeon_output->PanelYRes) << v_inc_shift) / drw_h; + radeon_output->native_mode.PanelYRes) << v_inc_shift) / drw_h; break; } } |