diff options
-rw-r--r-- | src/atombios_crtc.c | 7 | ||||
-rw-r--r-- | src/atombios_output.c | 33 | ||||
-rw-r--r-- | src/legacy_output.c | 256 | ||||
-rw-r--r-- | src/radeon.h | 14 | ||||
-rw-r--r-- | src/radeon_atombios.c | 179 | ||||
-rw-r--r-- | src/radeon_atombios.h | 3 | ||||
-rw-r--r-- | src/radeon_bios.c | 233 | ||||
-rw-r--r-- | src/radeon_modes.c | 175 | ||||
-rw-r--r-- | src/radeon_output.c | 449 | ||||
-rw-r--r-- | src/radeon_probe.h | 111 | ||||
-rw-r--r-- | src/radeon_tv.c | 163 | ||||
-rw-r--r-- | src/radeon_video.c | 2 |
12 files changed, 857 insertions, 768 deletions
diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c index cebd3287..212208eb 100644 --- a/src/atombios_crtc.c +++ b/src/atombios_crtc.c @@ -361,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 c8548db3..2aa9ba58 100644 --- a/src/atombios_output.c +++ b/src/atombios_output.c @@ -66,6 +66,7 @@ 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; @@ -96,7 +97,7 @@ atombios_output_dac_setup(xf86OutputPtr output, DisplayModePtr mode) else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) disp_data.ucDacStandard = ATOM_DAC1_CV; else { - switch (radeon_output->tvStd) { + switch (tvout->tvStd) { case TV_STD_PAL: case TV_STD_PAL_M: case TV_STD_SCART_PAL: @@ -132,6 +133,7 @@ static int 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; @@ -144,7 +146,7 @@ atombios_output_tv_setup(xf86OutputPtr output, DisplayModePtr mode) 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; @@ -264,10 +266,18 @@ atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode) unsigned char *space; int index; int major, minor; + int lvds_misc = 0; 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)); @@ -304,9 +314,9 @@ atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode) disp_data.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10); if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { - if (radeon_output->lvds_misc & (1 << 0)) + 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) @@ -337,18 +347,18 @@ atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode) disp_data2.ucTemporal = 0; disp_data2.ucFRC = 0; if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { - if (radeon_output->lvds_misc & (1 << 0)) + 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 { @@ -706,6 +716,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; @@ -716,7 +727,7 @@ atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode) disp_data.ucScaler = radeon_crtc->crtc_id; if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) { - switch (radeon_output->tvStd) { + switch (tvout->tvStd) { case TV_STD_NTSC: disp_data.ucTVStandard = ATOM_TV_NTSC; break; diff --git a/src/legacy_output.c b/src/legacy_output.c index 8ec6db2a..82291e57 100644 --- a/src/legacy_output.c +++ b/src/legacy_output.c @@ -56,7 +56,7 @@ static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color); static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn); extern Bool -RADEONI2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name, Bool dvo); +RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, char *name, RADEONI2CBusPtr pRADEONI2CBus); static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] = { @@ -105,84 +105,144 @@ static const uint32_t default_tvdac_adj [CHIP_FAMILY_LAST] = }; void -RADEONGetTVDacAdjInfo(xf86OutputPtr output) +RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn, radeon_tvdac_ptr tvdac) { - 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 (!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) - radeon_output->ps2_tvdac_adj = 0x00880000; + tvdac->ps2_tvdac_adj = 0x00880000; } - radeon_output->pal_tvdac_adj = radeon_output->ps2_tvdac_adj; - radeon_output->ntsc_tvdac_adj = radeon_output->ps2_tvdac_adj; + tvdac->pal_tvdac_adj = tvdac->ps2_tvdac_adj; + tvdac->ntsc_tvdac_adj = tvdac->ps2_tvdac_adj; } } void -RADEONGetTMDSInfoFromTable(xf86OutputPtr output) +RADEONGetTMDSInfoFromTable(ScrnInfoPtr pScrn, radeon_tmds_ptr tmds) { - 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; + 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(xf86OutputPtr output) +RADEONGetTMDSInfo(ScrnInfoPtr pScrn, radeon_tmds_ptr tmds) { - 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; + for (i = 0; i < 4; i++) { + tmds->tmds_pll[i].value = 0; + tmds->tmds_pll[i].freq = 0; } - if (!RADEONGetTMDSInfoFromBIOS(output)) - RADEONGetTMDSInfoFromTable(output); + if (!RADEONGetTMDSInfoFromBIOS(pScrn, tmds)) + RADEONGetTMDSInfoFromTable(pScrn, tmds); } void -RADEONGetExtTMDSInfo(xf86OutputPtr output) +RADEONGetExtTMDSInfo(ScrnInfoPtr pScrn, radeon_dvo_ptr dvo) { - ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONOutputPrivatePtr radeon_output = output->driver_private; I2CBusPtr pDVOBus; - radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); - - if (radeon_encoder == NULL) - return; if (!info->IsAtomBios) { #if defined(__powerpc__) - radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); - radeon_output->dvo_i2c_slave_addr = 0x70; + dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); + dvo->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; + if (!RADEONGetExtTMDSInfoFromBIOS(pScrn, dvo)) { + dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); + dvo->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) + 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) @@ -407,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_encoder == NULL) + return; - if (!radeon_output->DVOChip) + 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: @@ -836,15 +905,20 @@ legacy_output_dpms(xf86OutputPtr output, int 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 (radeon_output->PanelPwrDly * 1000); + 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; + } + break; case ENCODER_OBJECT_ID_INTERNAL_TMDS1: ErrorF("enable FP1\n"); tmp = INREG(RADEON_FP_GEN_CNTL); @@ -892,6 +966,7 @@ legacy_output_dpms(xf86OutputPtr output, int mode) 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) { @@ -990,7 +1065,7 @@ legacy_output_dpms(xf86OutputPtr output, int mode) tmp = INREG(RADEON_TV_MASTER_CNTL); tmp &= ~RADEON_TV_ON; OUTREG(RADEON_TV_MASTER_CNTL, tmp); - radeon_output->tv_on = FALSE; + radeon_output->tvout.tv_on = FALSE; } else { ErrorF("disable TVDAC\n"); if (info->ChipFamily == CHIP_FAMILY_R200) { @@ -1023,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; } } @@ -1233,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; @@ -1289,18 +1376,18 @@ RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save, if ((radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) || (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT))) { - ErrorF("RMX for DFP/LCD\n"); - - if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) { + if (native_mode->PanelXRes == 0 || native_mode->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 (xres > native_mode->PanelXRes) + xres = native_mode->PanelXRes; + if (yres > native_mode->PanelYRes) + yres = native_mode->PanelYRes; - if (xres == radeon_output->PanelXRes) + if (xres == native_mode->PanelXRes) Hscale = FALSE; - if (yres == radeon_output->PanelYRes) + if (yres == native_mode->PanelYRes) Vscale = FALSE; } @@ -1308,28 +1395,28 @@ RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save, (radeon_output->rmx_type == RMX_CENTER)) { save->fp_horz_stretch |= ((xres/8-1)<<16); } else { - CARD32 scale, inc; + uint32_t 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; + / native_mode->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)); + ((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; + uint32_t 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; + / native_mode->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)); + ((native_mode->PanelYRes-1)<<12)); } if ((radeon_output->rmx_type == RMX_CENTER) && @@ -1370,8 +1457,8 @@ RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save, ? 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)); } } @@ -1412,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) { @@ -1437,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); } diff --git a/src/radeon.h b/src/radeon.h index 9b724ec7..66b23304 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -881,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); @@ -923,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 d7d5f7ce..b2eea7d7 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, @@ -1612,6 +1616,25 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo 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; } } @@ -1620,7 +1643,66 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo 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"); @@ -1793,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; @@ -1807,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 @@ -1864,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; @@ -1873,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"); diff --git a/src/radeon_atombios.h b/src/radeon_atombios.h index 68df40d0..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); diff --git a/src/radeon_bios.c b/src/radeon_bios.c index 42b76b24..6fc0cf4f 100644 --- a/src/radeon_bios.c +++ b/src/radeon_bios.c @@ -826,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"); @@ -990,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; @@ -1013,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; } @@ -1047,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; } @@ -1067,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) { @@ -1097,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. */ @@ -1125,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) @@ -1179,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; @@ -1193,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; } } @@ -1223,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) { @@ -1232,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; } @@ -1288,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) { @@ -1312,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; @@ -1330,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: @@ -1353,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"); @@ -1374,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"); } @@ -1394,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) { @@ -1459,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); @@ -1524,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 50b32a9b..611589ef 100644 --- a/src/radeon_modes.c +++ b/src/radeon_modes.c @@ -95,36 +95,19 @@ RADEONTVModes(xf86OutputPtr output) static DisplayModePtr RADEONATOMTVModes(xf86OutputPtr output) { - RADEONOutputPrivatePtr radeon_output = output->driver_private; DisplayModePtr last = NULL; DisplayModePtr new = NULL; DisplayModePtr first = NULL; - int max_v, i; + int i; /* Add some common sizes */ int widths[5] = {640, 720, 800, 848, 1024}; - - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M) - max_v = 480; - else - max_v = 600; + int heights[5] = {480, 480, 600, 480, 768}; for (i = 0; i < 5; i++) { - new = xf86CVTMode(widths[i], max_v, 60.0, FALSE, FALSE); + new = xf86CVTMode(widths[i], heights[i], 60.0, FALSE, FALSE); new->type = M_T_DRIVER; - if (radeon_output->tvStd == TV_STD_NTSC || - radeon_output->tvStd == TV_STD_NTSC_J || - radeon_output->tvStd == TV_STD_PAL_M) { - if (widths[i] == 640) - new->type |= M_T_PREFERRED; - } else { - if (widths[i] == 800) - new->type |= M_T_PREFERRED; - } - new->next = NULL; new->prev = last; @@ -148,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) { @@ -180,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; @@ -250,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; @@ -268,7 +253,7 @@ static void RADEONAddScreenModes(xf86OutputPtr output, DisplayModePtr *modeList) 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 @@ -276,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; } } @@ -316,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) { @@ -326,8 +421,6 @@ RADEONProbeOutputModes(xf86OutputPtr output) AtomBiosArgRec atomBiosArg; AtomBiosResult atomBiosResult; - ErrorF("in RADEONProbeOutputModes\n"); - if (output->status == XF86OutputStatusConnected) { if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) { if (IS_AVIVO_VARIANT) @@ -341,6 +434,8 @@ RADEONProbeOutputModes(xf86OutputPtr output) 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__) diff --git a/src/radeon_output.c b/src/radeon_output.c index 78af9a72..fd94e2c1 100644 --- a/src/radeon_output.c +++ b/src/radeon_output.c @@ -105,7 +105,6 @@ const char *ConnectorTypeName[17] = { "Unsupported" }; -static void RADEONUpdatePanelSize(xf86OutputPtr output); extern void atombios_output_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode); @@ -114,14 +113,6 @@ 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); -extern void -RADEONGetExtTMDSInfo(xf86OutputPtr output); -extern void -RADEONGetTMDSInfoFromTable(xf86OutputPtr output); -extern void -RADEONGetTMDSInfo(xf86OutputPtr output); -extern void -RADEONGetTVDacAdjInfo(xf86OutputPtr output); static void radeon_bios_output_dpms(xf86OutputPtr output, int mode); static void @@ -381,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); @@ -407,12 +399,12 @@ radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) 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; } @@ -425,12 +417,13 @@ 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); @@ -441,51 +434,51 @@ radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, 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; } } } @@ -971,14 +964,18 @@ radeon_detect(xf86OutputPtr output) } } - /* update panel info for RMX */ - if (radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP) - RADEONUpdatePanelSize(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; + } + } + } - /* 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", @@ -1270,6 +1267,7 @@ radeon_create_resources(xf86OutputPtr output) } 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"); @@ -1339,7 +1337,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; @@ -1472,16 +1470,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); @@ -1502,6 +1507,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) { @@ -1512,11 +1518,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) { @@ -1527,11 +1534,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) { @@ -1542,38 +1550,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; } @@ -1676,12 +1685,9 @@ static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data) } Bool -RADEONI2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name, Bool dvo) +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; @@ -1692,12 +1698,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)) @@ -1794,267 +1794,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 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); } @@ -2071,27 +1845,12 @@ void RADEONInitConnector(xf86OutputPtr output) radeon_output->rmx_type = RMX_OFF; if (!IS_AVIVO_VARIANT) { - /* XXX fix me - move to encoders */ - - if (radeon_output->devices & (ATOM_DEVICE_DFP2_SUPPORT)) - RADEONGetExtTMDSInfo(output); - - if (radeon_output->devices & (ATOM_DEVICE_DFP1_SUPPORT)) - RADEONGetTMDSInfo(output); - if (radeon_output->devices & (ATOM_DEVICE_CRT2_SUPPORT)) { if (xf86ReturnOptValBool(info->Options, OPTION_TVDAC_LOAD_DETECT, FALSE)) radeon_output->load_detection = 1; - radeon_output->tv_on = FALSE; - RADEONGetTVDacAdjInfo(output); } } - if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) { - radeon_output->rmx_type = RMX_FULL; - RADEONGetLVDSInfo(output); - } - if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT)) RADEONGetTVInfo(output); @@ -2099,7 +1858,7 @@ void RADEONInitConnector(xf86OutputPtr output) 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); } diff --git a/src/radeon_probe.h b/src/radeon_probe.h index 6da24c27..28df6962 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -165,6 +165,61 @@ typedef struct _radeon_encoder { void *dev_priv; } 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; + int HOverPlus; + int HSyncWidth; + int HBlank; + int VOverPlus; + int VSyncWidth; + int VBlank; + 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; +} radeon_lvds_rec, *radeon_lvds_ptr; + +typedef struct _radeon_dvo { + /* dvo */ + I2CDevPtr DVOChip; + RADEONI2CBusRec dvo_i2c; + int dvo_i2c_slave_addr; + Bool dvo_duallink; +} radeon_dvo_rec, *radeon_dvo_ptr; + typedef struct { RADEONConnectorType ConnectorType; Bool valid; @@ -186,6 +241,12 @@ typedef struct _RADEONOutputPrivateRec { uint32_t active_device; Bool enabled; + int load_detection; + + // DVI/HDMI + Bool coherent_mode; + Bool linkb; + RADEONConnectorType ConnectorType; RADEONDviType DVIType; RADEONMonitorType MonType; @@ -197,57 +258,19 @@ typedef struct _RADEONOutputPrivateRec { // router info // HDP info - // tv dac - uint32_t ps2_tvdac_adj; - uint32_t pal_tvdac_adj; - uint32_t ntsc_tvdac_adj; - - /* panel stuff */ - int PanelXRes; - int PanelYRes; - int HOverPlus; - int HSyncWidth; - int HBlank; - int VOverPlus; - int VSyncWidth; - int VBlank; - int Flags; /* Saved copy of mode flags */ - int DotClock; - - // lvds - int PanelPwrDly; - int lvds_misc; - int lvds_ss_id; - - // tmds - RADEONTMDSPll tmds_pll[4]; + // panel mode + radeon_native_mode_rec native_mode; // RMX RADEONRMXType rmx_type; + int Flags; - /* dvo */ - I2CDevPtr DVOChip; - RADEONI2CBusRec dvo_i2c; - int dvo_i2c_slave_addr; - Bool dvo_duallink; + //tvout - move to encoder + radeon_tvout_rec tvout; - /* 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 */ + /* dce 3.x dig block */ int transmitter_config; - Bool coherent_mode; int igp_lane_info; - Bool linkb; - } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr; struct avivo_pll_state { 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; } } |