diff --git a/configure.ac b/configure.ac index 5f18d2b..5216eff 100644 --- a/configure.ac +++ b/configure.ac @@ -79,7 +79,7 @@ sdkdir=$(pkg-config --variable=sdkdir xorg-server) # Checks for header files. AC_HEADER_STDC -if test "$DRI" != no; then +if test "x$DRI" = xauto; then AC_CHECK_FILE([${sdkdir}/dri.h], [have_dri_h="yes"], [have_dri_h="no"]) AC_CHECK_FILE([${sdkdir}/sarea.h], diff --git a/man/radeon.man b/man/radeon.man index 35dd701..9168254 100644 --- a/man/radeon.man +++ b/man/radeon.man @@ -383,6 +383,14 @@ case. This is only useful for LVDS panels (laptop internal panels). The default is .B on. .TP +.BI "Option \*qLVDSBiosNativeMode\*q \*q" boolean \*q +On some laptops, the LVDS mode from the timing tables in the bios does +not work properly. In those cases, a CVT mode seems to work better. +If you get a blank screen or have LVDS display problems, disable this +option to use a CVT mode. +The default is +.B on. +.TP .BI "Option \*qDRI\*q \*q" boolean \*q Enable DRI support. This option allows you to enable to disable the DRI. The default is diff --git a/src/Makefile.am b/src/Makefile.am index 1eea432..ff1e225 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -66,6 +66,17 @@ atimisc_drv_la_SOURCES = \ atiload.c atimisc.c atimach64probe.c $(ATIMISC_CPIO_SOURCES) \ $(ATIMISC_DGA_SOURCES) $(ATIMISC_DRI_SRCS) $(ATIMISC_EXA_SOURCES) +if XSERVER_LIBPCIACCESS +# r128 has not been ported yet +else +r128_drv_la_LTLIBRARIES = r128_drv.la +r128_drv_la_LDFLAGS = -module -avoid-version +r128_drv_ladir = @moduledir@/drivers +r128_drv_la_SOURCES = \ + r128_accel.c r128_cursor.c r128_dga.c r128_driver.c \ + r128_video.c r128_misc.c r128_probe.c $(R128_DRI_SRCS) +endif + radeon_drv_la_LTLIBRARIES = radeon_drv.la radeon_drv_la_LDFLAGS = -module -avoid-version radeon_drv_ladir = @moduledir@/drivers @@ -76,16 +87,6 @@ radeon_drv_la_SOURCES = \ radeon_crtc.c radeon_output.c radeon_modes.c radeon_tv.c \ $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES) -if XSERVER_LIBPCIACCESS -# r128 and theatre have not been ported yet -else -r128_drv_la_LTLIBRARIES = r128_drv.la -r128_drv_la_LDFLAGS = -module -avoid-version -r128_drv_ladir = @moduledir@/drivers -r128_drv_la_SOURCES = \ - r128_accel.c r128_cursor.c r128_dga.c r128_driver.c \ - r128_video.c r128_misc.c r128_probe.c $(R128_DRI_SRCS) - theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la theatre_detect_drv_la_LDFLAGS = -module -avoid-version theatre_detect_drv_ladir = @moduledir@/multimedia @@ -106,7 +107,6 @@ theatre200_drv_la_CFLAGS = \ $(AM_CFLAGS) -DMICROC_DIR=\"$(theatre200_drv_ladir)\" theatre200_drv_la_SOURCES = \ theatre200.c theatre200_module.c -endif EXTRA_DIST = \ atimach64render.c \ diff --git a/src/atiprint.c b/src/atiprint.c index 60d9c21..3a1debb 100644 --- a/src/atiprint.c +++ b/src/atiprint.c @@ -26,6 +26,7 @@ #include #include +#include #include "ati.h" #include "atichip.h" diff --git a/src/atiprobe.c b/src/atiprobe.c index 78b3edd..38ce90d 100644 --- a/src/atiprobe.c +++ b/src/atiprobe.c @@ -26,6 +26,7 @@ #include #include +#include #include "ati.h" #include "atibus.h" diff --git a/src/radeon.h b/src/radeon.h index ad94cc5..6ee43b2 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -157,7 +157,8 @@ typedef enum { #if defined(__powerpc__) OPTION_MAC_MODEL, #endif - OPTION_DEFAULT_TMDS_PLL + OPTION_DEFAULT_TMDS_PLL, + OPTION_LVDS_BIOS_NATIVE_MODE } RADEONOpts; @@ -816,6 +817,8 @@ typedef struct { RADEONMacModel MacModel; #endif + Bool LVDSBiosNativeMode; + Rotation rotation; void (*PointerMoved)(int, int, int); CreateScreenResourcesProcPtr CreateScreenResources; @@ -910,6 +913,8 @@ extern void RADEONRestoreFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr restore); extern void RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore); +extern void RADEONRestoreBIOSRegisters(ScrnInfoPtr pScrn, + RADEONSavePtr restore); extern void RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore); extern void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn, diff --git a/src/radeon_bios.c b/src/radeon_bios.c index 65c2bb0..1b46746 100644 --- a/src/radeon_bios.c +++ b/src/radeon_bios.c @@ -176,6 +176,9 @@ static Bool RADEONGetATOMConnectorInfoFromBIOS (ScrnInfoPtr pScrn) case RADEON_LCD_GPIO_MASK: info->BiosConnector[i].DDCType = DDC_LCD; break; + case RADEON_MDGPIO_EN_REG: + info->BiosConnector[i].DDCType = DDC_GPIO; + break; default: info->BiosConnector[i].DDCType = DDC_NONE_DETECTED; break; @@ -254,6 +257,23 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn) info->BiosConnector[i].DDCType = DDC_MONID; } + /* XPRESS desktop chips seem to have a proprietary connector listed for + * DVI-D, try and do the right thing here. + */ + if ((!info->IsMobility) && + (info->BiosConnector[i].ConnectorType == CONNECTOR_PROPRIETARY)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Proprietary connector found, assuming DVI-D\n"); + info->BiosConnector[i].DACType = DAC_NONE; + info->BiosConnector[i].TMDSType = TMDS_EXT; + info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_D; + } + + if (info->BiosConnector[i].ConnectorType >= CONNECTOR_UNSUPPORTED) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown connector type: %d!\n", + info->BiosConnector[i].ConnectorType); + info->BiosConnector[i].valid = FALSE; + } } } else { @@ -277,7 +297,7 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn) tmp1 = RADEON_BIOS8(tmp0+2) & 0x07; if (tmp1) { info->BiosConnector[4].DDCType = tmp1; - if (info->BiosConnector[4].DDCType > DDC_LCD) { + if (info->BiosConnector[4].DDCType > DDC_GPIO) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown DDCType %d found\n", info->BiosConnector[4].DDCType); diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c index 47e46f3..eeb1c6c 100644 --- a/src/radeon_crtc.c +++ b/src/radeon_crtc.c @@ -311,7 +311,7 @@ RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save, return FALSE; } - save->bios_4_scratch = info->SavedReg.bios_4_scratch; + /*save->bios_4_scratch = info->SavedReg.bios_4_scratch;*/ save->crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN | RADEON_CRTC_EN | (format << 8) @@ -348,11 +348,10 @@ RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save, hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8; if (!hsync_wid) hsync_wid = 1; - if (hsync_wid > 0x3f) hsync_wid = 0x3f; hsync_start = mode->CrtcHSyncStart - 8; save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) - | (hsync_wid << 16) + | ((hsync_wid & 0x3f) << 16) | ((mode->Flags & V_NHSYNC) ? RADEON_CRTC_H_SYNC_POL : 0)); @@ -363,10 +362,9 @@ RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save, vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; if (!vsync_wid) vsync_wid = 1; - if (vsync_wid > 0x1f) vsync_wid = 0x1f; save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff) - | (vsync_wid << 16) + | ((vsync_wid & 0x1f) << 16) | ((mode->Flags & V_NVSYNC) ? RADEON_CRTC_V_SYNC_POL : 0)); @@ -545,11 +543,10 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save, hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8; if (!hsync_wid) hsync_wid = 1; - if (hsync_wid > 0x3f) hsync_wid = 0x3f; hsync_start = mode->CrtcHSyncStart - 8; save->crtc2_h_sync_strt_wid = ((hsync_start & 0x1fff) - | (hsync_wid << 16) + | ((hsync_wid & 0x3f) << 16) | ((mode->Flags & V_NHSYNC) ? RADEON_CRTC_H_SYNC_POL : 0)); @@ -560,10 +557,9 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save, vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; if (!vsync_wid) vsync_wid = 1; - if (vsync_wid > 0x1f) vsync_wid = 0x1f; save->crtc2_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff) - | (vsync_wid << 16) + | ((vsync_wid & 0x1f) << 16) | ((mode->Flags & V_NVSYNC) ? RADEON_CRTC2_V_SYNC_POL : 0)); @@ -768,6 +764,18 @@ RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, } static void +RADEONInitBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + /* tell the bios not to muck with the hardware on events */ + save->bios_4_scratch = 0; + save->bios_5_scratch = 0xff00; + save->bios_6_scratch = info->SavedReg.bios_6_scratch | 0x40000000; + +} + +static void radeon_update_tv_routing(ScrnInfoPtr pScrn, RADEONSavePtr restore) { /* pixclks_cntl controls tv clock routing */ @@ -813,6 +821,9 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, } } + if (info->IsMobility) + RADEONInitBIOSRegisters(pScrn, &info->ModeReg); + ErrorF("init memmap\n"); RADEONInitMemMapRegisters(pScrn, &info->ModeReg, info); ErrorF("init common\n"); @@ -868,6 +879,9 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, } } + if (info->IsMobility) + RADEONRestoreBIOSRegisters(pScrn, &info->ModeReg); + ErrorF("restore memmap\n"); RADEONRestoreMemMapRegisters(pScrn, &info->ModeReg); ErrorF("restore common\n"); diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 03f531e..40e1d98 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -190,6 +190,7 @@ static const OptionInfoRec RADEONOptions[] = { #if defined(__powerpc__) { OPTION_MAC_MODEL, "MacModel", OPTV_STRING, {0}, FALSE }, #endif + { OPTION_LVDS_BIOS_NATIVE_MODE, "LVDSBiosNativeMode", OPTV_BOOLEAN, {0}, TRUE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -4235,14 +4236,27 @@ void RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) if (info->IsMobility) { OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl); - OUTREG(RADEON_LVDS_PLL_CNTL, restore->lvds_pll_cntl); - /*OUTREG(RADEON_BIOS_4_SCRATCH, restore->bios_4_scratch); - OUTREG(RADEON_BIOS_5_SCRATCH, restore->bios_5_scratch); - OUTREG(RADEON_BIOS_6_SCRATCH, restore->bios_6_scratch);*/ + OUTREG(RADEON_LVDS_PLL_CNTL, restore->lvds_pll_cntl); } } +void RADEONRestoreBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 bios_6_scratch = INREG(RADEON_BIOS_6_SCRATCH); + + OUTREG(RADEON_BIOS_4_SCRATCH, restore->bios_4_scratch); + OUTREG(RADEON_BIOS_5_SCRATCH, restore->bios_5_scratch); + if (restore->bios_6_scratch & 0x40000000) + bios_6_scratch |= 0x40000000; + else + bios_6_scratch &= ~0x40000000; + OUTREG(RADEON_BIOS_6_SCRATCH, bios_6_scratch); + +} + /* Write to TV FIFO RAM */ static void RADEONWriteTVFIFO(ScrnInfoPtr pScrn, CARD16 addr, CARD32 value) @@ -5082,6 +5096,16 @@ static void RADEONSaveDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) } +static void RADEONSaveBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + save->bios_4_scratch = INREG(RADEON_BIOS_4_SCRATCH); + save->bios_5_scratch = INREG(RADEON_BIOS_5_SCRATCH); + save->bios_6_scratch = INREG(RADEON_BIOS_6_SCRATCH); +} + /* Read flat panel registers */ static void RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) { @@ -5096,9 +5120,6 @@ static void RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) save->lvds_pll_cntl = INREG(RADEON_LVDS_PLL_CNTL); save->tmds_pll_cntl = INREG(RADEON_TMDS_PLL_CNTL); save->tmds_transmitter_cntl= INREG(RADEON_TMDS_TRANSMITTER_CNTL); - save->bios_4_scratch = INREG(RADEON_BIOS_4_SCRATCH); - save->bios_5_scratch = INREG(RADEON_BIOS_5_SCRATCH); - save->bios_6_scratch = INREG(RADEON_BIOS_6_SCRATCH); if (info->ChipFamily == CHIP_FAMILY_RV280) { /* bit 22 of TMDS_PLL_CNTL is read-back inverted */ @@ -5325,7 +5346,7 @@ static void RADEONSave(ScrnInfoPtr pScrn) vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */ # else /* Save mode * & fonts & cmap */ - vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS); + vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL); # endif vgaHWLock(hwp); } @@ -5340,6 +5361,7 @@ static void RADEONSave(ScrnInfoPtr pScrn) RADEONSavePLLRegisters(pScrn, save); RADEONSaveCrtcRegisters(pScrn, save); RADEONSaveFPRegisters(pScrn, save); + RADEONSaveBIOSRegisters(pScrn, save); RADEONSaveDACRegisters(pScrn, save); if (pRADEONEnt->HasCRTC2) { RADEONSaveCrtc2Registers(pScrn, save); @@ -5386,6 +5408,7 @@ void RADEONRestore(ScrnInfoPtr pScrn) RADEONRestorePLL2Registers(pScrn, restore); } + RADEONRestoreBIOSRegisters(pScrn, restore); RADEONRestoreCrtcRegisters(pScrn, restore); RADEONRestorePLLRegisters(pScrn, restore); RADEONRestoreRMXRegisters(pScrn, restore); @@ -5417,7 +5440,7 @@ void RADEONRestore(ScrnInfoPtr pScrn) */ vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE ); # else - vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS ); + vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_ALL ); # endif vgaHWLock(hwp); } diff --git a/src/radeon_modes.c b/src/radeon_modes.c index ea2c229..e01c1e1 100644 --- a/src/radeon_modes.c +++ b/src/radeon_modes.c @@ -95,20 +95,45 @@ static DisplayModePtr RADEONTVModes(xf86OutputPtr output) static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output) { ScrnInfoPtr pScrn = output->scrn; + RADEONInfoPtr info = RADEONPTR(pScrn); RADEONOutputPrivatePtr radeon_output = output->driver_private; DisplayModePtr new = NULL; + char stmp[32]; if (radeon_output->PanelXRes != 0 && radeon_output->PanelYRes != 0 && radeon_output->DotClock != 0) { - /* Add native panel size */ - new = xf86CVTMode(radeon_output->PanelXRes, radeon_output->PanelYRes, 60.0, TRUE, FALSE); + if (info->LVDSBiosNativeMode) { + new = xnfcalloc(1, sizeof (DisplayModeRec)); + sprintf(stmp, "%dx%d", radeon_output->PanelXRes, radeon_output->PanelYRes); + new->name = xnfalloc(strlen(stmp) + 1); + strcpy(new->name, stmp); + new->HDisplay = radeon_output->PanelXRes; + new->VDisplay = radeon_output->PanelYRes; - new->type = M_T_DRIVER | M_T_PREFERRED; + 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->next = NULL; - new->prev = NULL; + new->Clock = radeon_output->DotClock; + new->Flags = 0; + + } else { + /* Add native panel size */ + new = xf86CVTMode(radeon_output->PanelXRes, radeon_output->PanelYRes, 60.0, FALSE, FALSE); + + } + + if (new) { + new->type = M_T_DRIVER | M_T_PREFERRED; + + new->next = NULL; + new->prev = NULL; + } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Added native panel mode: %dx%d\n", radeon_output->PanelXRes, radeon_output->PanelYRes); @@ -159,7 +184,7 @@ static void RADEONAddScreenModes(xf86OutputPtr output, DisplayModePtr *modeList) } } - new = xf86CVTMode(width, height, 60.0, TRUE, FALSE); + new = xf86CVTMode(width, height, 60.0, FALSE, FALSE); new->type |= M_T_USERDEF; @@ -199,11 +224,13 @@ RADEONProbeOutputModes(xf86OutputPtr output) if (output->status == XF86OutputStatusConnected) { if (radeon_output->type == OUTPUT_DVI || radeon_output->type == OUTPUT_VGA) { - edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus); - xf86OutputSetEDID (output, edid_mon); + if (output->MonInfo) { + edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus); + xf86OutputSetEDID (output, edid_mon); - modes = xf86OutputGetEDIDModes (output); - return modes; + modes = xf86OutputGetEDIDModes (output); + return modes; + } } if (radeon_output->type == OUTPUT_STV || radeon_output->type == OUTPUT_CTV) { modes = RADEONTVModes(output); diff --git a/src/radeon_output.c b/src/radeon_output.c index a6da78e..e2f26e7 100644 --- a/src/radeon_output.c +++ b/src/radeon_output.c @@ -75,13 +75,14 @@ const char *TMDSTypeName[4] = { "None" }; -const char *DDCTypeName[6] = { +const char *DDCTypeName[7] = { "None", "MONID", "DVI_DDC", "VGA_DDC", "CRT2_DDC", - "LCD_DDC" + "LCD_DDC", + "GPIO_DDC" }; const char *DACTypeName[4] = { @@ -277,7 +278,7 @@ RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output) DDCReg = radeon_output->DDCReg; /* Read and output monitor info using DDC2 over I2C bus */ - if (radeon_output->pI2CBus && info->ddc2 && (DDCReg != RADEON_LCD_GPIO_MASK)) { + if (radeon_output->pI2CBus && info->ddc2 && (DDCReg != RADEON_LCD_GPIO_MASK) && (DDCReg != RADEON_MDGPIO_EN_REG)) { OUTREG(DDCReg, INREG(DDCReg) & (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1)); @@ -331,7 +332,7 @@ RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output) usleep(15000); if(*MonInfo) break; } - } else if (radeon_output->pI2CBus && info->ddc2 && DDCReg == RADEON_LCD_GPIO_MASK) { + } else if (radeon_output->pI2CBus && info->ddc2 && ((DDCReg == RADEON_LCD_GPIO_MASK) || (DDCReg == RADEON_MDGPIO_EN_REG))) { *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, radeon_output->pI2CBus); } else { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DDC2/I2C is not properly initialized\n"); @@ -669,9 +670,19 @@ static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr RADEONOutputPrivatePtr radeon_output = output->driver_private; RADEONMonitorType MonType = MT_NONE; - if (radeon_output->type == OUTPUT_LVDS) { - MonType = MT_LCD; +#if defined(__powerpc__) + /* not sure on ppc, OF? */ +#else + if (!info->IsAtomBios) { + /* see if the lid is closed -- only works at boot */ + if (INREG(RADEON_BIOS_6_SCRATCH) & 0x10) + MonType = MT_NONE; + else + MonType = MT_LCD; + } else +#endif + MonType = MT_LCD; } else if (radeon_output->type == OUTPUT_DVI) { if (radeon_output->TMDSType == TMDS_INT) { if (INREG(RADEON_FP_GEN_CNTL) & RADEON_FP_DETECT_SENSE) @@ -765,10 +776,14 @@ radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, } } - /* update clock for LVDS always and DFP if RMX is active */ - if ((radeon_output->MonType == MT_LCD) || - ((radeon_output->MonType == MT_DFP) && - (radeon_output->Flags & RADEON_USE_RMX))) { + /* update timing for LVDS and DFP if RMX is active */ + if (radeon_output->Flags & RADEON_USE_RMX) { + adjusted_mode->CrtcHTotal = mode->CrtcHDisplay + radeon_output->HBlank; + adjusted_mode->CrtcHSyncStart = mode->CrtcHDisplay + radeon_output->HOverPlus; + adjusted_mode->CrtcHSyncEnd = mode->CrtcHSyncStart + radeon_output->HSyncWidth; + adjusted_mode->CrtcVTotal = mode->CrtcVDisplay + radeon_output->VBlank; + adjusted_mode->CrtcVSyncStart = mode->CrtcVDisplay + radeon_output->VOverPlus; + adjusted_mode->CrtcVSyncEnd = mode->CrtcVSyncStart + radeon_output->VSyncWidth; adjusted_mode->Clock = radeon_output->DotClock; adjusted_mode->Flags = radeon_output->Flags; } @@ -1636,6 +1651,16 @@ radeon_detect(xf86OutputPtr output) break; } + if (!connected) { + /* default to unknown for flaky chips/connectors + * so we can get something on the screen + */ + if (((radeon_output->type == OUTPUT_VGA || radeon_output->type == OUTPUT_DVI) && + radeon_output->DACType == DAC_TVDAC) || + (info->IsIGP && radeon_output->type == OUTPUT_DVI)) + return XF86OutputStatusUnknown; + } + if (connected) return XF86OutputStatusConnected; else @@ -1911,7 +1936,7 @@ radeon_create_resources(xf86OutputPtr output) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RRConfigureOutputProperty error, %d\n", err); } - /* Set the current value of the backlight property */ + /* Set the current value of the property */ switch (radeon_output->default_tvStd) { case TV_STD_PAL: s = "pal"; @@ -2081,47 +2106,23 @@ radeon_set_property(xf86OutputPtr output, Atom property, return FALSE; s = (char*)value->data; if (value->size == strlen("ntsc") && !strncmp("ntsc", s, strlen("ntsc"))) { - if (radeon_output->SupportedTVStds & TV_STD_NTSC) { - radeon_output->tvStd = TV_STD_NTSC; - return TRUE; - } else { - return FALSE; - } + radeon_output->tvStd = TV_STD_NTSC; + return TRUE; } else if (value->size == strlen("pal") && !strncmp("pal", s, strlen("pal"))) { - if (radeon_output->SupportedTVStds & TV_STD_PAL) { - radeon_output->tvStd = TV_STD_PAL; - return TRUE; - } else { - return FALSE; - } + radeon_output->tvStd = TV_STD_PAL; + return TRUE; } else if (value->size == strlen("pal-m") && !strncmp("pal-m", s, strlen("pal-m"))) { - if (radeon_output->SupportedTVStds & TV_STD_PAL_M) { - radeon_output->tvStd = TV_STD_PAL_M; - return TRUE; - } else { - return FALSE; - } + radeon_output->tvStd = TV_STD_PAL_M; + return TRUE; } else if (value->size == strlen("pal-60") && !strncmp("pal-60", s, strlen("pal-60"))) { - if (radeon_output->SupportedTVStds & TV_STD_PAL_60) { - radeon_output->tvStd = TV_STD_PAL_60; - return TRUE; - } else { - return FALSE; - } + radeon_output->tvStd = TV_STD_PAL_60; + return TRUE; } else if (value->size == strlen("ntsc-j") && !strncmp("ntsc-j", s, strlen("ntsc-j"))) { - if (radeon_output->SupportedTVStds & TV_STD_NTSC_J) { - radeon_output->tvStd = TV_STD_NTSC_J; - return TRUE; - } else { - return FALSE; - } + radeon_output->tvStd = TV_STD_NTSC_J; + return TRUE; } else if (value->size == strlen("scart-pal") && !strncmp("scart-pal", s, strlen("scart-pal"))) { - if (radeon_output->SupportedTVStds & TV_STD_SCART_PAL) { - radeon_output->tvStd = TV_STD_SCART_PAL; - return TRUE; - } else { - return FALSE; - } + radeon_output->tvStd = TV_STD_SCART_PAL; + return TRUE; } return FALSE; } @@ -2206,6 +2207,10 @@ static void RADEONI2CGetBits(I2CBusPtr b, int *Clock, int *data) val = INREG(b->DriverPrivate.uval+4); *Clock = (val & (1<<13)) != 0; *data = (val & (1<<12)) != 0; + } else if (b->DriverPrivate.uval == RADEON_MDGPIO_EN_REG) { + val = INREG(b->DriverPrivate.uval+4); + *Clock = (val & (1<<19)) != 0; + *data = (val & (1<<18)) != 0; } else { val = INREG(b->DriverPrivate.uval); *Clock = (val & RADEON_GPIO_Y_1) != 0; @@ -2225,6 +2230,11 @@ static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data) val |= (Clock ? 0:(1<<13)); val |= (data ? 0:(1<<12)); OUTREG(b->DriverPrivate.uval, val); + } else if (b->DriverPrivate.uval == RADEON_MDGPIO_EN_REG) { + val = INREG(b->DriverPrivate.uval) & (CARD32)~((1<<18) | (1<<19)); + val |= (Clock ? 0:(1<<19)); + val |= (data ? 0:(1<<18)); + OUTREG(b->DriverPrivate.uval, val); } else { val = INREG(b->DriverPrivate.uval) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1); val |= (Clock ? 0:RADEON_GPIO_EN_1); @@ -2430,6 +2440,15 @@ RADEONGetLVDSInfo (xf86OutputPtr output) } } + info->LVDSBiosNativeMode = TRUE; + if (!xf86ReturnOptValBool(info->Options, OPTION_LVDS_BIOS_NATIVE_MODE, TRUE)) { + info->LVDSBiosNativeMode = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using CVT mode for LVDS\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using LVDS Native Mode\n"); + } + + /* 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 @@ -2547,6 +2566,7 @@ void RADEONInitConnector(xf86OutputPtr output) case DDC_VGA : DDCReg = RADEON_GPIO_VGA_DDC; break; case DDC_CRT2 : DDCReg = RADEON_GPIO_CRT2_DDC; break; case DDC_LCD : DDCReg = RADEON_LCD_GPIO_MASK; break; + case DDC_GPIO : DDCReg = RADEON_MDGPIO_EN_REG; break; default: break; } @@ -2791,6 +2811,78 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn) } +#if defined(__powerpc__) + +/* + * Returns RADEONMacModel or 0 based on lines 'detected as' and 'machine' + * in /proc/cpuinfo (on Linux) */ +static RADEONMacModel RADEONDetectMacModel(ScrnInfoPtr pScrn) +{ + RADEONMacModel ret = 0; +#ifdef __linux__ + char cpuline[50]; /* 50 should be sufficient for our purposes */ + FILE *f = fopen ("/proc/cpuinfo", "r"); + + if (f != NULL) { + while (fgets(cpuline, sizeof cpuline, f)) { + if (!strncmp(cpuline, "machine", strlen ("machine"))) { + if (strstr(cpuline, "PowerBook5,6") || + strstr(cpuline, "PowerBook5,7") || + strstr(cpuline, "PowerBook5,8") || + strstr(cpuline, "PowerBook5,9")) { + ret = RADEON_MAC_POWERBOOK_DL; + break; + } + + if (strstr(cpuline, "PowerMac10,1") || + strstr(cpuline, "PowerMac10,2")) { + ret = RADEON_MAC_MINI; + break; + } + } else if (!strncmp(cpuline, "detected as", strlen("detected as"))) { + if (strstr(cpuline, "iBook")) { + ret = RADEON_MAC_IBOOK; + break; + } else if (strstr(cpuline, "PowerBook")) { + ret = RADEON_MAC_POWERBOOK_DL; + break; + } + + /* No known PowerMac model detected */ + break; + } + } + + fclose (f); + } else + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Cannot detect PowerMac model because /proc/cpuinfo not " + "readable.\n"); + +#endif /* __linux */ + + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Detected %s.\n", + ret == RADEON_MAC_POWERBOOK_DL ? "PowerBook with dual link DVI" : + ret == RADEON_MAC_POWERBOOK ? "PowerBook with single link DVI" : + ret == RADEON_MAC_IBOOK ? "iBook" : + "Mac Mini"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "If this is not correct, try Option \"MacModel\" and " + "consider reporting to the\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "xorg-driver-ati@lists.x.org mailing list" +#ifdef __linux__ + " with the contents of /proc/cpuinfo" +#endif + ".\n"); + } + + return ret; +} + +#endif /* __powerpc__ */ + /* * initialise the static data sos we don't have to re-do at randr change */ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) @@ -2816,9 +2908,8 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) } #if defined(__powerpc__) - optstr = (char *)xf86GetOptValString(info->Options, OPTION_MAC_MODEL); - info->MacModel = 0; + optstr = (char *)xf86GetOptValString(info->Options, OPTION_MAC_MODEL); if (optstr) { if (!strncmp("ibook", optstr, strlen("ibook"))) info->MacModel = RADEON_MAC_IBOOK; @@ -2830,12 +2921,16 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) info->MacModel = RADEON_MAC_MINI; else { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid Mac Model: %s\n", optstr); - return FALSE; } + } + + if (!info->MacModel) { + info->MacModel = RADEONDetectMacModel(pScrn); + } + if (info->MacModel){ if (!RADEONSetupAppleConnectors(pScrn)) RADEONSetupGenericConnectors(pScrn); - } else #endif if (xf86ReturnOptValBool(info->Options, OPTION_DEFAULT_CONNECTOR_TABLE, FALSE)) { diff --git a/src/radeon_probe.h b/src/radeon_probe.h index dbd50d7..66ece94 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -60,6 +60,7 @@ typedef enum DDC_VGA, DDC_CRT2, DDC_LCD, + DDC_GPIO, } RADEONDDCType; typedef enum