Only in xf86-video-ati-6.9.0-all: ;q diff -urpw xf86-video-ati-6.9.0/src/radeon_driver.c xf86-video-ati-6.9.0-all/src/radeon_driver.c --- xf86-video-ati-6.9.0/src/radeon_driver.c 2008-06-23 21:38:42.000000000 +0800 +++ xf86-video-ati-6.9.0-all/src/radeon_driver.c 2008-12-19 05:01:53.000000000 +0800 @@ -2673,6 +2673,9 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, in info->IsSecondary = FALSE; info->IsPrimary = FALSE; + info->modes[0] = NULL; + info->modes[1] = NULL; + info->pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]); if (info->pEnt->location.type != BUS_PCI) goto fail; @@ -5571,10 +5574,22 @@ void RADEONFreeScreen(int scrnIndex, int { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; RADEONInfoPtr info = RADEONPTR(pScrn); + int i; + DisplayModePtr pm; xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "RADEONFreeScreen\n"); + for (i = 0; i < 2; i++) + { + pm = info->modes[i]; + while (pm) + { + xfree(pm); + pm = pm->next; + } + } + /* when server quits at PreInit, we don't need do this anymore*/ if (!info) return; diff -urpw xf86-video-ati-6.9.0/src/radeon.h xf86-video-ati-6.9.0-all/src/radeon.h --- xf86-video-ati-6.9.0/src/radeon.h 2008-06-25 14:56:40.000000000 +0800 +++ xf86-video-ati-6.9.0-all/src/radeon.h 2008-12-19 04:56:37.000000000 +0800 @@ -774,6 +774,7 @@ typedef struct { int num_gb_pipes; Bool has_tcl; + DisplayModePtr modes[2]; } RADEONInfoRec, *RADEONInfoPtr; #define RADEONWaitForFifo(pScrn, entries) \ diff -urpw xf86-video-ati-6.9.0/src/radeon_modes.c xf86-video-ati-6.9.0-all/src/radeon_modes.c --- xf86-video-ati-6.9.0/src/radeon_modes.c 2008-06-09 23:49:42.000000000 +0800 +++ xf86-video-ati-6.9.0-all/src/radeon_modes.c 2008-12-19 05:39:15.000000000 +0800 @@ -263,7 +263,9 @@ RADEONProbeOutputModes(xf86OutputPtr out RADEONOutputPrivatePtr radeon_output = output->driver_private; ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); - DisplayModePtr modes = NULL; + DisplayModePtr modes = NULL, pm = NULL, qm = NULL, hm = NULL, new = NULL; + DisplayModePtr edidModes = NULL; + int i; AtomBiosArgRec atomBiosArg; AtomBiosResult atomBiosResult; @@ -283,7 +285,10 @@ RADEONProbeOutputModes(xf86OutputPtr out } } else { if (output->MonInfo) + { modes = xf86OutputGetEDIDModes (output); + edidModes = modes; + } if (modes == NULL) { if ((radeon_output->type == OUTPUT_LVDS) && info->IsAtomBios) { atomBiosResult = RHDAtomBiosFunc(pScrn->scrnIndex, @@ -305,6 +310,35 @@ RADEONProbeOutputModes(xf86OutputPtr out } } + if (info->ChipFamily == CHIP_FAMILY_RV100) + { + pm = modes; + + for (i = 0; i < 2; i++) + { + if (edidModes && !info->modes[i]) + { + while (pm) + { + new = xnfcalloc(1, sizeof(DisplayModeRec)); + memcpy(new, pm, sizeof(DisplayModeRec)); + if (!hm) + hm = new; + if (qm) + { + qm->next = new; + new->prev = qm; + } + qm = new; + pm = pm->next; + } + qm->next = NULL; + info->modes[i] = hm; + break; + } + } + } + return modes; } diff -urpw xf86-video-ati-6.9.0/src/radeon_output.c xf86-video-ati-6.9.0-all/src/radeon_output.c --- xf86-video-ati-6.9.0/src/radeon_output.c 2008-06-25 14:56:40.000000000 +0800 +++ xf86-video-ati-6.9.0-all/src/radeon_output.c 2008-12-22 22:08:35.000000000 +0800 @@ -455,6 +455,21 @@ radeon_restore(xf86OutputPtr restore) } +static Bool +radeon_find_mode(DisplayModePtr mode, DisplayModePtr saveMode) +{ + DisplayModePtr pm = saveMode; + while (pm) + { + if (xf86ModesEqual(mode, pm)) + { + return TRUE; + } + pm = pm->next; + } + return FALSE; +} + static int radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) { @@ -462,7 +477,6 @@ radeon_mode_valid(xf86OutputPtr output, ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - /* * RN50 has effective maximum mode bandwidth of about 300MiB/s. * XXX should really do this for all chips by properly computing @@ -472,6 +486,24 @@ radeon_mode_valid(xf86OutputPtr output, if (xf86ModeBandwidth(pMode, pScrn->bitsPerPixel) > 300) return MODE_BANDWIDTH; } + if (info->ChipFamily == CHIP_FAMILY_RV100) + { + if (info->modes[0] && !info->modes[1]) + { + if (!radeon_find_mode(pMode, info->modes[0])) + return MODE_BAD; + } + else if (info->modes[1] && !info->modes[0]) + { + if (!radeon_find_mode(pMode, info->modes[1])) + return MODE_BAD; + } + else if (info->modes[0] && info->modes[1]) + { + if (!radeon_find_mode(pMode, info->modes[0]) || !radeon_find_mode(pMode, info->modes[1])) + return MODE_BAD; + } + } if (OUTPUT_IS_TV) { /* FIXME: Update when more modes are added */ @@ -613,12 +645,37 @@ radeon_mode_set(xf86OutputPtr output, Di DisplayModePtr adjusted_mode) { RADEONInfoPtr info = RADEONPTR(output->scrn); + RADEONOutputPrivatePtr radeon_output = output->driver_private; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(output->scrn); if (IS_AVIVO_VARIANT) + { atombios_output_mode_set(output, mode, adjusted_mode); + radeon_bios_output_crtc(output); + } + else + { + /* + * For RN50, we should set twice, first set DFP, then set CRT. + */ + if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) + { + radeon_output->MonType = MT_DFP; + radeon_output->TMDSType = TMDS_EXT; + legacy_output_mode_set(output, mode, adjusted_mode); + radeon_bios_output_crtc(output); + + radeon_output->DACType = DAC_PRIMARY; + radeon_output->MonType = MT_CRT; + legacy_output_mode_set(output, mode, adjusted_mode); + radeon_bios_output_crtc(output); + } else + { legacy_output_mode_set(output, mode, adjusted_mode); radeon_bios_output_crtc(output); + } + } }