diff options
Diffstat (limited to 'src/radeon_driver.c')
-rw-r--r-- | src/radeon_driver.c | 3272 |
1 files changed, 1013 insertions, 2259 deletions
diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 74323c9..f338d16 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -74,7 +74,6 @@ #include "radeon_macros.h" #include "radeon_probe.h" #include "radeon_version.h" -#include "radeon_mergedfb.h" #ifdef XF86DRI #define _XF86DRI_SERVER_ @@ -94,6 +93,7 @@ #include "xf86_ansic.h" /* For xf86getsecs() */ #include "xf86_OSproc.h" #include "xf86RAC.h" +#include "xf86RandR12.h" #include "xf86Resources.h" #include "xf86cmap.h" #include "vbe.h" @@ -116,10 +116,7 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen); static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode); static void RADEONSave(ScrnInfoPtr pScrn); -static void RADEONRestore(ScrnInfoPtr pScrn); -static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); -static void RADEONGetMergedFBOptions(ScrnInfoPtr pScrn); static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode); static void RADEONForceSomeClocks(ScrnInfoPtr pScrn); static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save); @@ -128,9 +125,11 @@ static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save); static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save); #endif -/* psuedo xinerama support */ +DisplayModePtr +RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode); -extern Bool RADEONnoPanoramiXExtension; +static void RADEONWaitPLLLock(ScrnInfoPtr pScrn, unsigned nTests, + unsigned nWaitLoops, unsigned cntThreshold); static const OptionInfoRec RADEONOptions[] = { { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, @@ -159,19 +158,8 @@ static const OptionInfoRec RADEONOptions[] = { #endif #endif { OPTION_DDC_MODE, "DDCMode", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_MONITOR_LAYOUT, "MonitorLayout", OPTV_ANYSTR, {0}, FALSE }, { OPTION_IGNORE_EDID, "IgnoreEDID", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_MERGEDFB, "MergedFB", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_CRT2HSYNC, "CRT2HSync", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_CRT2VREFRESH, "CRT2VRefresh", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_CRT2POS, "CRT2Position", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_METAMODES, "MetaModes", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_MERGEDDPI, "MergedDPI", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_RADEONXINERAMA, "MergedXinerama", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_CRT2ISSCRN0, "MergedXineramaCRT2IsScreen0", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_MERGEDFBNONRECT, "MergedNonRectangular", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_MERGEDFBMOUSER, "MergedMouseRestriction", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_DISP_PRIORITY, "DisplayPriority", OPTV_ANYSTR, {0}, FALSE }, { OPTION_PANEL_SIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE }, { OPTION_MIN_DOTCLOCK, "ForceMinDotClock", OPTV_FREQ, {0}, FALSE }, @@ -198,8 +186,8 @@ static const OptionInfoRec RADEONOptions[] = { { OPTION_LVDS_PROBE_PLL, "LVDSProbePLL", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, { OPTION_CONSTANTDPI, "ConstantDPI", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_REVERSE_DISPLAY,"ReverseDisplay", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_CONNECTORTABLE, "ConnectorTable", OPTV_STRING, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -441,6 +429,24 @@ struct RADEONInt10Save { static Bool RADEONMapMMIO(ScrnInfoPtr pScrn); static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn); +#if 0 +static Bool +RADEONCreateScreenResources (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + pScreen->CreateScreenResources = info->CreateScreenResources; + if (!(*pScreen->CreateScreenResources)(pScreen)) + return FALSE; + + if (!xf86RandR12CreateScreenResources(pScreen)) + return FALSE; + + return TRUE; +} +#endif + RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn) { DevUnion *pPriv; @@ -534,48 +540,6 @@ static Bool RADEONGetRec(ScrnInfoPtr pScrn) /* Free our private RADEONInfoRec */ static void RADEONFreeRec(ScrnInfoPtr pScrn) { - RADEONInfoPtr info = RADEONPTR(pScrn); - if(info->CRT2HSync) xfree(info->CRT2HSync); - info->CRT2HSync = NULL; - if(info->CRT2VRefresh) xfree(info->CRT2VRefresh); - info->CRT2VRefresh = NULL; - if(info->MetaModes) xfree(info->MetaModes); - info->MetaModes = NULL; - if(info->CRT2pScrn) { - if(info->CRT2pScrn->modes) { - while(info->CRT2pScrn->modes) - xf86DeleteMode(&info->CRT2pScrn->modes, info->CRT2pScrn->modes); - } - if(info->CRT2pScrn->monitor) { - if(info->CRT2pScrn->monitor->Modes) { - while(info->CRT2pScrn->monitor->Modes) - xf86DeleteMode(&info->CRT2pScrn->monitor->Modes, info->CRT2pScrn->monitor->Modes); - } - if(info->CRT2pScrn->monitor->DDC) xfree(info->CRT2pScrn->monitor->DDC); - xfree(info->CRT2pScrn->monitor); - } - xfree(info->CRT2pScrn); - info->CRT2pScrn = NULL; - } - if(info->CRT1Modes) { - if(info->CRT1Modes != pScrn->modes) { - if(pScrn->modes) { - pScrn->currentMode = pScrn->modes; - do { - DisplayModePtr p = pScrn->currentMode->next; - if(pScrn->currentMode->Private) - xfree(pScrn->currentMode->Private); - xfree(pScrn->currentMode); - pScrn->currentMode = p; - } while(pScrn->currentMode != pScrn->modes); - } - pScrn->currentMode = info->CRT1CurrentMode; - pScrn->modes = info->CRT1Modes; - info->CRT1CurrentMode = NULL; - info->CRT1Modes = NULL; - } - } - if (!pScrn || !pScrn->driverPrivate) return; xfree(pScrn->driverPrivate); pScrn->driverPrivate = NULL; @@ -1203,7 +1167,7 @@ static Bool RADEONPreInitWeight(ScrnInfoPtr pScrn) return TRUE; } -static void RADEONInitMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, +void RADEONInitMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, RADEONInfoPtr info) { save->mc_fb_location = info->mc_fb_location; @@ -1466,24 +1430,6 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, from, "Mapped VideoRAM: %d kByte (%d bit %s SDRAM)\n", pScrn->videoRam, info->RamWidth, info->IsDDR?"DDR":"SDR"); - /* FIXME: For now, split FB into two equal sections. This should - * be able to be adjusted by user with a config option. */ - if (info->IsPrimary) { - pScrn->videoRam /= 2; - info->MergedFB = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %dk of videoram for primary head\n", - pScrn->videoRam); - } - - if (info->IsSecondary) { - pScrn->videoRam /= 2; - info->LinearAddr += pScrn->videoRam * 1024; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %dk of videoram for secondary head\n", - pScrn->videoRam); - } - pScrn->videoRam &= ~1023; info->FbMapSize = pScrn->videoRam * 1024; @@ -1550,6 +1496,7 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn) info->IsIGP = FALSE; info->IsDellServer = FALSE; info->HasSingleDAC = FALSE; + info->InternalTVOut = TRUE; switch (info->Chipset) { case PCI_CHIP_RADEON_LY: case PCI_CHIP_RADEON_LZ: @@ -1609,6 +1556,7 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn) case PCI_CHIP_R200_QL: case PCI_CHIP_R200_QM: info->ChipFamily = CHIP_FAMILY_R200; + info->InternalTVOut = FALSE; break; case PCI_CHIP_RADEON_LW: @@ -1791,6 +1739,7 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn) /* Original Radeon/7200 */ info->ChipFamily = CHIP_FAMILY_RADEON; pRADEONEnt->HasCRTC2 = FALSE; + info->InternalTVOut = FALSE; } @@ -1969,9 +1918,7 @@ static void RADEONPreInitDDC(ScrnInfoPtr pScrn) if (info->ddc2) { if (xf86LoadSubModule(pScrn, "i2c")) { xf86LoaderReqSymLists(i2cSymbols,NULL); - info->ddc2 = RADEONI2cInit(pScrn); } - else info->ddc2 = FALSE; } } @@ -1984,405 +1931,6 @@ static Bool RADEONPreInitGamma(ScrnInfoPtr pScrn) return TRUE; } -/* This is called by RADEONPreInit to validate modes and compute - * parameters for all of the valid modes. - */ -static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - ClockRangePtr clockRanges; - int modesFound; - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - char *s; - RADEONConnector *connector; - /* This option has two purposes: - * - * 1. For CRT, if this option is on, xf86ValidateModes (to - * LOOKUP_BEST_REFRESH) is not going to be used for mode - * validation. Instead, we'll validate modes by matching exactly - * the modes supported from the DDC data. This option can be - * used (a) to enable non-standard modes listed in the Detailed - * Timings block of EDID, like 2048x1536 (not included in - * xf86DefModes), (b) to avoid unstable modes for some flat - * panels working in analog mode (some modes validated by - * xf86ValidateModes don't really work with these panels). - * - * 2. For DFP on primary head, with this option on, the validation - * routine will try to use supported modes from DDC data first - * before trying on-chip RMX streching. By default, native mode - * + RMX streching is used for all non-native modes, it appears - * more reliable. Some non-native modes listed in the DDC data - * may not work properly if they are used directly. This seems to - * only happen to a few panels (haven't nailed this down yet, it - * may related to the incorrect setting in TMDS_PLL_CNTL when - * pixel clock is changed). Use this option may give you better - * refresh rate for some non-native modes. The 2nd DVI port will - * always use DDC modes directly (only have one on-chip RMX - * unit). - * - * Note: This option will be dismissed if no DDC data is available. - */ - - if (info->MergedFB) { - if (!(pScrn->display->virtualX)) - info->NoVirtual = TRUE; - else - info->NoVirtual = FALSE; - } - - info->ddc_mode = - xf86ReturnOptValBool(info->Options, OPTION_DDC_MODE, FALSE); - - /* don't use RMX if we have a dual-tmds panels */ - if (pRADEONEnt->PortInfo[1]->MonType == MT_DFP) - info->ddc_mode = TRUE; - /* don't use RMX if we are Dell Server */ - if (info->IsDellServer) - info->ddc_mode = TRUE; - /* IBM Lewis server have troubles using the on-chip RMX mode */ - if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2 && pRADEONEnt->PortInfo[0]->MonInfo) { - struct vendor *ven = &pRADEONEnt->PortInfo[0]->MonInfo->vendor; - if (ven && ven->prod_id == 0x029a && ven->serial == 0x01010101) - info->ddc_mode = TRUE; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Validating modes on %s head ---------\n", - info->IsSecondary ? "Secondary" : "Primary"); - - if (!pRADEONEnt->PortInfo[0]->MonInfo && !pRADEONEnt->PortInfo[1]->MonInfo && info->ddc_mode) { - info->ddc_mode = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "No DDC data available, DDCMode option is dismissed\n"); - } - - if ((info->DisplayType == MT_DFP) || - (info->DisplayType == MT_LCD)) { - if ((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) { - int PanelX, PanelY; - DisplayModePtr tmp_mode = NULL; - if (sscanf(s, "%dx%d", &PanelX, &PanelY) == 2) { - info->PanelXRes = PanelX; - info->PanelYRes = PanelY; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Panel size is forced to: %s\n", s); - - /* We can't trust BIOS or DDC timings anymore, - 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. - */ - info->ddc_mode = FALSE; - pScrn->monitor->DDC = NULL; - tmp_mode = pScrn->monitor->Modes; - while(tmp_mode) { - if ((tmp_mode->HDisplay == PanelX) && - (tmp_mode->VDisplay == PanelY)) { - - 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)) { - info->HBlank = tmp_mode->HTotal - tmp_mode->HDisplay; - info->HOverPlus = tmp_mode->HSyncStart - tmp_mode->HDisplay; - info->HSyncWidth = tmp_mode->HSyncEnd - tmp_mode->HSyncStart; - info->VBlank = tmp_mode->VTotal - tmp_mode->VDisplay; - info->VOverPlus = tmp_mode->VSyncStart - tmp_mode->VDisplay; - info->VSyncWidth = tmp_mode->VSyncEnd - tmp_mode->VSyncStart; - info->DotClock = tmp_mode->Clock; - info->Flags = 0; - break; - } - } - tmp_mode = tmp_mode->next; - } - if (info->DotClock == 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid timing info for specified panel size.\n" - "Please specify the Modeline for this panel\n"); - return FALSE; - } - } else { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Invalid PanelSize value: %s\n", s); - } - } else - RADEONGetPanelInfo(pScrn); - } - - if (pScrn->monitor->DDC) { - /* If we still don't know sync range yet, let's try EDID. - * - * Note that, since we can have dual heads, Xconfigurator - * may not be able to probe both monitors correctly through - * vbe probe function (RADEONProbeDDC). Here we provide an - * additional way to auto-detect sync ranges if they haven't - * been added to XF86Config manually. - */ - if (pScrn->monitor->nHsync <= 0) - RADEONSetSyncRangeFromEdid(pScrn, 1); - if (pScrn->monitor->nVrefresh <= 0) - RADEONSetSyncRangeFromEdid(pScrn, 0); - } - - /* Get mode information */ - pScrn->progClock = TRUE; - clockRanges = xnfcalloc(sizeof(*clockRanges), 1); - clockRanges->next = NULL; - clockRanges->minClock = info->pll.min_pll_freq; - clockRanges->maxClock = info->pll.max_pll_freq * 10; - clockRanges->clockIndex = -1; - clockRanges->interlaceAllowed = (info->DisplayType == MT_CRT); - clockRanges->doubleScanAllowed = (info->DisplayType == MT_CRT); - - /* We'll use our own mode validation routine for DFP/LCD, since - * xf86ValidateModes does not work correctly with the DFP/LCD modes - * 'stretched' from their native mode. - */ - if (info->DisplayType == MT_CRT && !info->ddc_mode) { - xf86SetDDCproperties(pScrn, pScrn->monitor->DDC); - modesFound = - xf86ValidateModes(pScrn, - pScrn->monitor->Modes, - pScrn->display->modes, - clockRanges, - NULL, /* linePitches */ - 8 * 64, /* minPitch */ - 8 * 1024, /* maxPitch */ - info->allowColorTiling ? 2048 : - 64 * pScrn->bitsPerPixel, /* pitchInc */ - 128, /* minHeight */ - info->MaxLines, /* maxHeight */ - pScrn->display->virtualX, - pScrn->display->virtualY, - info->FbMapSize, - LOOKUP_BEST_REFRESH); - - if (modesFound < 1 && info->FBDev) { - fbdevHWUseBuildinMode(pScrn); - pScrn->displayWidth = fbdevHWGetLineLength(pScrn) - / info->CurrentLayout.pixel_bytes; - modesFound = 1; - } - - if (modesFound == -1) return FALSE; - - xf86PruneDriverModes(pScrn); - if (!modesFound || !pScrn->modes) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); - return FALSE; - } - - } else { - /* First, free any allocated modes during configuration, since - * we don't need them - */ - while (pScrn->modes) - xf86DeleteMode(&pScrn->modes, pScrn->modes); - while (pScrn->modePool) - xf86DeleteMode(&pScrn->modePool, pScrn->modePool); - - /* Next try to add DDC modes */ - modesFound = RADEONValidateDDCModes(pScrn, pScrn->display->modes, - info->DisplayType, 0); - - /* If that fails and we're connect to a flat panel, then try to - * add the flat panel modes - */ - if (info->DisplayType != MT_CRT) { - - /* some panels have DDC, but don't have internal scaler. - * in this case, we need to validate additional modes - * by using on-chip RMX. - */ - int user_modes_asked = 0, user_modes_found = 0, i; - DisplayModePtr tmp_mode = pScrn->modes; - while (pScrn->display->modes[user_modes_asked]) user_modes_asked++; - if (tmp_mode) { - for (i = 0; i < modesFound; i++) { - if (tmp_mode->type & M_T_USERDEF) user_modes_found++; - tmp_mode = tmp_mode->next; - } - } - - if ((modesFound <= 1) || (user_modes_found < user_modes_asked)) { - /* when panel size is not valid, try to validate - * mode using xf86ValidateModes routine - * This can happen when DDC is disabled. - */ - if (info->PanelXRes < 320 || info->PanelYRes < 200) - modesFound = - xf86ValidateModes(pScrn, - pScrn->monitor->Modes, - pScrn->display->modes, - clockRanges, - NULL, /* linePitches */ - 8 * 64, /* minPitch */ - 8 * 1024, /* maxPitch */ - info->allowColorTiling ? 2048 : - 64 * pScrn->bitsPerPixel, /* pitchInc */ - 128, /* minHeight */ - info->MaxLines, /* maxHeight */ - pScrn->display->virtualX, - pScrn->display->virtualY, - info->FbMapSize, - LOOKUP_BEST_REFRESH); - else if (!info->IsSecondary && !info->ddc_mode) - modesFound = RADEONValidateFPModes(pScrn, pScrn->display->modes); - } - } - - /* Setup the screen's clockRanges for the VidMode extension */ - if (!pScrn->clockRanges) { - pScrn->clockRanges = xnfcalloc(sizeof(*(pScrn->clockRanges)), 1); - memcpy(pScrn->clockRanges, clockRanges, sizeof(*clockRanges)); - pScrn->clockRanges->strategy = LOOKUP_BEST_REFRESH; - } - - /* Fail if we still don't have any valid modes */ - if (modesFound < 1) { - if (info->DisplayType == MT_CRT) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid DDC modes found for this CRT\n"); - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Try turning off the \"DDCMode\" option\n"); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid mode found for this DFP/LCD\n"); - } - return FALSE; - } - } - - xf86SetCrtcForModes(pScrn, 0); - - if (pRADEONEnt->HasCRTC2) { - if (pRADEONEnt->Controller[1]->binding == 1) { - - /* If we have 2 screens from the config file, we don't need - * to do clone thing, let each screen handles one head. - */ - if (info->MergedFB) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Validating CRTC2 modes for MergedFB ------------ \n"); - - modesFound = RADEONValidateMergeModes(pScrn); - if (modesFound < 1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid mode found for CRTC2, disabling MergedFB\n"); - info->MergedFB = FALSE; - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Total of %d CRTC2 modes found for MergedFB------------ \n", - modesFound); - } - } - } - - pScrn->currentMode = pScrn->modes; - if(info->MergedFB) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Modes for CRT1: ********************\n"); - } - xf86PrintModes(pScrn); - - - if (pRADEONEnt->HasCRTC2) { - if(pRADEONEnt->Controller[1]->binding == 1 && info->MergedFB) { - - xf86SetCrtcForModes(info->CRT2pScrn, INTERLACE_HALVE_V); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Modes for CRT2: ********************\n"); - - xf86PrintModes(info->CRT2pScrn); - - info->CRT1Modes = pScrn->modes; - info->CRT1CurrentMode = pScrn->currentMode; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Generating MergedFB mode list\n"); - - if (info->NoVirtual) { - pScrn->display->virtualX = 0; - pScrn->display->virtualY = 0; - } - pScrn->modes = RADEONGenerateModeList(pScrn, info->MetaModes, - info->CRT1Modes, info->CRT2pScrn->modes, - info->CRT2Position); - - if(!pScrn->modes) { - - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to parse MetaModes or no modes found. MergeFB mode disabled.\n"); - if(info->CRT2pScrn) { - if(info->CRT2pScrn->modes) { - while(info->CRT2pScrn->modes) - xf86DeleteMode(&info->CRT2pScrn->modes, info->CRT2pScrn->modes); - } - if(info->CRT2pScrn->monitor) { - if(info->CRT2pScrn->monitor->Modes) { - while(info->CRT2pScrn->monitor->Modes) - xf86DeleteMode(&info->CRT2pScrn->monitor->Modes, info->CRT2pScrn->monitor->Modes); - } - if(info->CRT2pScrn->monitor->DDC) xfree(info->CRT2pScrn->monitor->DDC); - xfree(info->CRT2pScrn->monitor); - } - xfree(info->CRT2pScrn); - info->CRT2pScrn = NULL; - } - pScrn->modes = info->CRT1Modes; - info->CRT1Modes = NULL; - info->MergedFB = FALSE; - - } - } - else - info->MergedFB = FALSE; - } - else - info->MergedFB = FALSE; - - if (info->MergedFB) { - /* If no virtual dimension was given by the user, - * calculate a sane one now. Adapts pScrn->virtualX, - * pScrn->virtualY and pScrn->displayWidth. - */ - RADEONRecalcDefaultVirtualSize(pScrn); - info->CRT2pScrn->virtualX = pScrn->virtualX; - info->CRT2pScrn->virtualY = pScrn->virtualY; - RADEONSetPitch(pScrn); - RADEONSetPitch(info->CRT2pScrn); - - pScrn->modes = pScrn->modes->next; /* We get the last from GenerateModeList() */ - pScrn->currentMode = pScrn->modes; - - /* Update CurrentLayout */ - info->CurrentLayout.mode = pScrn->currentMode; - info->CurrentLayout.displayWidth = pScrn->displayWidth; - } - - /* Set DPI */ - /* xf86SetDpi(pScrn, 0, 0); */ - - if (info->MergedFB) { - RADEONMergedFBSetDpi(pScrn, info->CRT2pScrn, info->CRT2Position); - } else { - xf86SetDpi(pScrn, 0, 0); - info->RADEONDPIVX = pScrn->virtualX; - info->RADEONDPIVY = pScrn->virtualY; - } - - /* Get ScreenInit function */ - if (!xf86LoadSubModule(pScrn, "fb")) return FALSE; - - xf86LoaderReqSymLists(fbSymbols, NULL); - - info->CurrentLayout.displayWidth = pScrn->displayWidth; - info->CurrentLayout.mode = pScrn->currentMode; - - return TRUE; -} - /* This is called by RADEONPreInit to initialize the hardware cursor */ static Bool RADEONPreInitCursor(ScrnInfoPtr pScrn) { @@ -2519,18 +2067,6 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn) info->pLibDRMVersion = NULL; info->pKernelDRMVersion = NULL; - if (xf86IsEntityShared(info->pEnt->index)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Direct Rendering Disabled -- " - "Dual-head configuration is not working with " - "DRI at present.\n" - "Please use the radeon MergedFB option if you " - "want Dual-head with DRI.\n"); - return FALSE; - } - if (info->IsSecondary) - return FALSE; - if (info->Chipset == PCI_CHIP_RN50_515E || info->Chipset == PCI_CHIP_RN50_5969) { if (xf86ReturnOptValBool(info->Options, OPTION_DRI, FALSE)) { @@ -2727,6 +2263,7 @@ static void RADEONPreInitColorTiling(ScrnInfoPtr pScrn) info->allowColorTiling = xf86ReturnOptValBool(info->Options, OPTION_COLOR_TILING, TRUE); if (IS_R300_VARIANT) { + /* this may be 4096 on r4xx -- need to double check */ info->MaxSurfaceWidth = 3968; /* one would have thought 4096...*/ info->MaxLines = 4096; } else { @@ -2753,14 +2290,7 @@ static void RADEONPreInitColorTiling(ScrnInfoPtr pScrn) } #endif /* XF86DRI */ - if ((info->allowColorTiling) && (info->IsSecondary)) { - /* can't have tiling on the 2nd head (as long as it can't use drm). - * We'd never get the surface save/restore (vt switching) right... - */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Color tiling disabled for 2nd head\n"); - info->allowColorTiling = FALSE; - } - else if ((info->allowColorTiling) && (info->FBDev)) { + if ((info->allowColorTiling) && (info->FBDev)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Color tiling not supported with UseFBDev option\n"); info->allowColorTiling = FALSE; @@ -2960,30 +2490,39 @@ static Bool RADEONPreInitXv(ScrnInfoPtr pScrn) return TRUE; } -static Bool RADEONPreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) +static void RADEONPreInitBIOS(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) { - RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONGetBIOSInfo(pScrn, pInt10); +#if 0 + RADEONGetBIOSInitTableOffsets(pScrn); + RADEONPostCardFromBIOSTables(pScrn); +#endif +} - if (!info->IsSecondary) { - if (!RADEONAllocateConnectors(pScrn)) - return FALSE; +static Bool RADEONPreInitControllers(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; - if (!RADEONAllocateControllers(pScrn)) + if (!RADEONAllocateControllers(pScrn)) return FALSE; - - } - RADEONGetBIOSInfo(pScrn, pInt10); + RADEONGetClockInfo(pScrn); - if (!info->IsSecondary) { - RADEONSetupConnectors(pScrn); + if (!RADEONSetupConnectors(pScrn)) { + return FALSE; } - RADEONMapControllers(pScrn); + + RADEONPrintPortMap(pScrn); - RADEONGetClockInfo(pScrn); - RADEONGetPanelInfo(pScrn); - RADEONGetTVDacAdjInfo(pScrn); - + for (i = 0; i < config->num_output; i++) + { + xf86OutputPtr output = config->output[i]; + + output->status = (*output->funcs->detect) (output); + ErrorF("finished output detect: %d\n", i); + } + ErrorF("finished all detect\n"); return TRUE; } @@ -2998,13 +2537,28 @@ RADEONProbeDDC(ScrnInfoPtr pScrn, int indx) } } -Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) +static Bool +RADEONCRTCResize(ScrnInfoPtr scrn, int width, int height) +{ + scrn->virtualX = width; + scrn->virtualY = height; + /* RADEONSetPitch(scrn); */ + return TRUE; +} + +static const xf86CrtcConfigFuncsRec RADEONCRTCResizeFuncs = { + RADEONCRTCResize +}; + +_X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) { + xf86CrtcConfigPtr xf86_config; RADEONInfoPtr info; xf86Int10InfoPtr pInt10 = NULL; void *int10_save = NULL; const char *s; MessageType from; + int crtc_max_X, crtc_max_Y; xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "RADEONPreInit\n"); @@ -3013,10 +2567,6 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) if (!RADEONGetRec(pScrn)) return FALSE; info = RADEONPTR(pScrn); - info->IsSecondary = FALSE; - info->IsPrimary = FALSE; - info->MergedFB = FALSE; - info->IsSwitching = FALSE; info->MMIO = NULL; info->pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]); @@ -3060,30 +2610,6 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) RADEONPreInt10Save(pScrn, &int10_save); #endif - if (xf86IsEntityShared(info->pEnt->index)) { - if (xf86IsPrimInitDone(info->pEnt->index)) { - - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - - info->IsSecondary = TRUE; - if (!pRADEONEnt->HasSecondary) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Only one monitor detected, Second screen " - "will NOT be created\n"); - goto fail2; - } - pRADEONEnt->pSecondaryScrn = pScrn; - } else { - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - - info->IsPrimary = TRUE; - - xf86SetPrimInitDone(info->pEnt->index); - - pRADEONEnt->pPrimaryScrn = pScrn; - } - } - if (flags & PROBE_DETECT) { RADEONProbeDDC(pScrn, info->pEnt->index); RADEONPostInt10Check(pScrn, int10_save); @@ -3107,6 +2633,11 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR; pScrn->monitor = pScrn->confScreen->monitor; + /* Allocate an xf86CrtcConfig */ + xf86CrtcConfigInit (pScrn, &RADEONCRTCResizeFuncs); + xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + if (!RADEONPreInitVisual(pScrn)) goto fail; @@ -3211,33 +2742,69 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) if (!RADEONPreInitChipType(pScrn)) goto fail; + RADEONPreInitBIOS(pScrn, pInt10); + #ifdef XF86DRI /* PreInit DRI first of all since we need that for getting a proper * memory map */ info->directRenderingEnabled = RADEONPreInitDRI(pScrn); #endif - if (!RADEONPreInitVRAM(pScrn)) goto fail; RADEONPreInitColorTiling(pScrn); + /* we really need an FB manager... */ + if (pScrn->display->virtualX) { + crtc_max_X = pScrn->display->virtualX; + crtc_max_Y = pScrn->display->virtualY; + if (info->allowColorTiling) { + if (crtc_max_X > info->MaxSurfaceWidth) + crtc_max_X = info->MaxSurfaceWidth; + if (crtc_max_Y > info->MaxLines) + crtc_max_Y = info->MaxLines; + } else { + if (crtc_max_X > 8192) + crtc_max_X = 8192; + if (crtc_max_Y > 8192) + crtc_max_Y = 8192; + } + } else { + crtc_max_X = 1600; + crtc_max_Y = 1200; + } + + /*xf86CrtcSetSizeRange (pScrn, 320, 200, info->MaxSurfaceWidth, info->MaxLines);*/ + xf86CrtcSetSizeRange (pScrn, 320, 200, crtc_max_X, crtc_max_Y); + RADEONPreInitDDC(pScrn); - if (!RADEONPreInitControllers(pScrn, pInt10)) + if (!RADEONPreInitControllers(pScrn)) goto fail; - /* collect MergedFB options */ - /* only parse mergedfb options on the primary head. - Mergedfb is already disabled in xinerama/screen based - multihead */ - if (!info->IsSecondary) - RADEONGetMergedFBOptions(pScrn); - if (!RADEONPreInitGamma(pScrn)) goto fail; + ErrorF("before xf86InitialConfiguration\n"); + + if (!xf86InitialConfiguration (pScrn, FALSE)) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); + goto fail; + } + + ErrorF("after xf86InitialConfiguration\n"); + + RADEONSetPitch(pScrn); + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); - if (!RADEONPreInitModes(pScrn, pInt10)) goto fail; + /* Get ScreenInit function */ + if (!xf86LoadSubModule(pScrn, "fb")) return FALSE; + + xf86LoaderReqSymLists(fbSymbols, NULL); + + if (!RADEONPreInitGamma(pScrn)) goto fail; if (!RADEONPreInitCursor(pScrn)) goto fail; @@ -3245,6 +2812,17 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) if (!RADEONPreInitXv(pScrn)) goto fail; + if (!xf86RandR12PreInit (pScrn)) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n"); + goto fail; + } + + if (pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); + goto fail; + } + /* Free the video bios (if applicable) */ if (info->VBIOS) { xfree(info->VBIOS); @@ -3266,10 +2844,6 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) fail: /* Pre-init failed. */ - if (info->IsSecondary) { - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - pRADEONEnt->HasSecondary = FALSE; - } /* Free the video bios (if applicable) */ if (info->VBIOS) { xfree(info->VBIOS); @@ -3285,7 +2859,6 @@ fail: vgaHWFreeHWRec(pScrn); #endif - fail2: if(info->MMIO) RADEONUnmapMMIO(pScrn); info->MMIO = NULL; @@ -3300,10 +2873,11 @@ static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, VisualPtr pVisual) { RADEONInfoPtr info = RADEONPTR(pScrn); - unsigned char *RADEONMMIO = info->MMIO; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int i; - int idx, j; - unsigned char r, g, b; + int index, j; + CARD16 lut_r[256], lut_g[256], lut_b[256]; + int c; #ifdef XF86DRI if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0); @@ -3315,109 +2889,59 @@ static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors, if (info->FBDev) { fbdevHWLoadPalette(pScrn, numColors, indices, colors, pVisual); } else { - /* If the second monitor is connected, we also need to deal with - * the secondary palette - */ - if (info->IsSecondary) j = 1; - else j = 0; - - PAL_SELECT(j); - - if (info->CurrentLayout.depth == 15) { - /* 15bpp mode. This sends 32 values. */ - for (i = 0; i < numColors; i++) { - idx = indices[i]; - r = colors[idx].red; - g = colors[idx].green; - b = colors[idx].blue; - OUTPAL(idx * 8, r, g, b); - } - } else if (info->CurrentLayout.depth == 16) { - /* 16bpp mode. This sends 64 values. - * - * There are twice as many green values as there are values - * for red and blue. So, we take each red and blue pair, - * and combine it with each of the two green values. - */ - for (i = 0; i < numColors; i++) { - idx = indices[i]; - r = colors[idx / 2].red; - g = colors[idx].green; - b = colors[idx / 2].blue; - RADEONWaitForFifo(pScrn, 32); /* delay */ - OUTPAL(idx * 4, r, g, b); - - /* AH - Added to write extra green data - How come this isn't - * needed on R128? We didn't load the extra green data in the - * other routine - */ - if (idx <= 31) { - r = colors[idx].red; - g = colors[(idx * 2) + 1].green; - b = colors[idx].blue; - RADEONWaitForFifo(pScrn, 32); /* delay */ - OUTPAL(idx * 8, r, g, b); - } - } - } else { - /* 8bpp mode. This sends 256 values. */ - for (i = 0; i < numColors; i++) { - idx = indices[i]; - r = colors[idx].red; - b = colors[idx].blue; - g = colors[idx].green; - RADEONWaitForFifo(pScrn, 32); /* delay */ - OUTPAL(idx, r, g, b); - } - } - if (info->MergedFB) { - PAL_SELECT(1); - if (info->CurrentLayout.depth == 15) { - /* 15bpp mode. This sends 32 values. */ - for (i = 0; i < numColors; i++) { - idx = indices[i]; - r = colors[idx].red; - g = colors[idx].green; - b = colors[idx].blue; - OUTPAL(idx * 8, r, g, b); - } - } else if (info->CurrentLayout.depth == 16) { - /* 16bpp mode. This sends 64 values. - * - * There are twice as many green values as there are values - * for red and blue. So, we take each red and blue pair, - * and combine it with each of the two green values. - */ - for (i = 0; i < numColors; i++) { - idx = indices[i]; - r = colors[idx / 2].red; - g = colors[idx].green; - b = colors[idx / 2].blue; - OUTPAL(idx * 4, r, g, b); - - /* AH - Added to write extra green data - How come - * this isn't needed on R128? We didn't load the - * extra green data in the other routine. - */ - if (idx <= 31) { - r = colors[idx].red; - g = colors[(idx * 2) + 1].green; - b = colors[idx].blue; - OUTPAL(idx * 8, r, g, b); - } - } - } else { - /* 8bpp mode. This sends 256 values. */ - for (i = 0; i < numColors; i++) { - idx = indices[i]; - r = colors[idx].red; - b = colors[idx].blue; - g = colors[idx].green; - OUTPAL(idx, r, g, b); - } - } - } + for (c = 0; c < xf86_config->num_crtc; c++) { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + + for (i = 0 ; i < 256; i++) { + lut_r[i] = radeon_crtc->lut_r[i] << 8; + lut_g[i] = radeon_crtc->lut_g[i] << 8; + lut_b[i] = radeon_crtc->lut_b[i] << 8; + } + + switch (info->CurrentLayout.depth) { + case 15: + for (i = 0; i < numColors; i++) { + index = indices[i]; + for (j = 0; j < 8; j++) { + lut_r[index * 8 + j] = colors[index].red << 8; + lut_g[index * 8 + j] = colors[index].green << 8; + lut_b[index * 8 + j] = colors[index].blue << 8; + } + } + case 16: + for (i = 0; i < numColors; i++) { + index = indices[i]; + + if (i <= 31) { + for (j = 0; j < 8; j++) { + lut_r[index * 8 + j] = colors[index].red << 8; + lut_b[index * 8 + j] = colors[index].blue << 8; + } + } + + for (j = 0; j < 4; j++) { + lut_g[index * 4 + j] = colors[index].green << 8; + } + } + default: + for (i = 0; i < numColors; i++) { + index = indices[i]; + lut_r[index] = colors[index].red << 8; + lut_g[index] = colors[index].green << 8; + lut_b[index] = colors[index].blue << 8; + } + break; + } + + /* Make the change through RandR */ +#ifdef RANDR_12_INTERFACE + RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); +#else + crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256); +#endif + } } #ifdef XF86DRI @@ -3786,12 +3310,40 @@ Bool RADEONSetupMemXAA(int scrnIndex, ScreenPtr pScreen) } #endif /* USE_XAA */ +static void +RADEONPointerMoved(int index, int x, int y) +{ + ScrnInfoPtr pScrn = xf86Screens[index]; + RADEONInfoPtr info = RADEONPTR(pScrn); + int newX = x, newY = y; + + switch (info->rotation) { + case RR_Rotate_0: + break; + case RR_Rotate_90: + newX = y; + newY = pScrn->pScreen->width - x - 1; + break; + case RR_Rotate_180: + newX = pScrn->pScreen->width - x - 1; + newY = pScrn->pScreen->height - y - 1; + break; + case RR_Rotate_270: + newX = pScrn->pScreen->height - y - 1; + newY = x; + break; + } + + (*info->PointerMoved)(index, newX, newY); +} + /* Called at the start of each server generation. */ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int hasDRI = 0; #ifdef RENDER int subPixelOrder = SubPixelUnknown; @@ -3815,7 +3367,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, #ifdef XF86DRI pScrn->fbOffset = info->frontOffset; #endif - if (info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024; + if (!RADEONMapMem(pScrn)) return FALSE; #ifdef XF86DRI @@ -3825,9 +3377,14 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, info->PaletteSavedOnVT = FALSE; + info->crtc_on = FALSE; + info->crtc2_on = FALSE; + RADEONSave(pScrn); - if ((!info->IsSecondary) && info->IsMobility) { + RADEONDisableDisplays(pScrn); + + if (info->IsMobility) { if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) { RADEONSetDynamicClock(pScrn, 1); } else { @@ -3835,8 +3392,8 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, } } - if ((!info->IsSecondary) && (IS_R300_VARIANT || IS_RV100_VARIANT)) - RADEONForceSomeClocks(pScrn); + if (IS_R300_VARIANT || IS_RV100_VARIANT) + RADEONForceSomeClocks(pScrn); if (info->allowColorTiling && (pScrn->virtualX > info->MaxSurfaceWidth)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -3845,17 +3402,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, info->allowColorTiling = FALSE; } if (info->allowColorTiling) { - if (info->MergedFB) { - if ((((RADEONMergedDisplayModePtr)pScrn->currentMode->Private)->CRT1->Flags & - (V_DBLSCAN | V_INTERLACE)) || - (((RADEONMergedDisplayModePtr)pScrn->currentMode->Private)->CRT2->Flags & - (V_DBLSCAN | V_INTERLACE))) - info->tilingEnabled = FALSE; - else info->tilingEnabled = TRUE; - } - else { - info->tilingEnabled = (pScrn->currentMode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE; - } + info->tilingEnabled = (pScrn->currentMode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE; } /* Visual setup */ @@ -3896,15 +3443,13 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, */ RADEONInitMemoryMap(pScrn); - if (!info->IsSecondary) { - /* empty the surfaces */ - unsigned char *RADEONMMIO = info->MMIO; - unsigned int i; - for (i = 0; i < 8; i++) { - OUTREG(RADEON_SURFACE0_INFO + 16 * i, 0); - OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * i, 0); - OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * i, 0); - } + /* empty the surfaces */ + unsigned char *RADEONMMIO = info->MMIO; + unsigned int i; + for (i = 0; i < 8; i++) { + OUTREG(RADEON_SURFACE0_INFO + 16 * i, 0); + OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * i, 0); + OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * i, 0); } #ifdef XF86DRI @@ -3924,11 +3469,9 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, #endif /* Initial setup of surfaces */ - if (!info->IsSecondary) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, - "Setting up initial surfaces\n"); - RADEONChangeSurfaces(pScrn); - } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, + "Setting up initial surfaces\n"); + RADEONChangeSurfaces(pScrn); /* Memory manager setup */ @@ -4076,18 +3619,9 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, else if (strcmp(s, "NONE") == 0) subPixelOrder = SubPixelNone; PictureSetSubpixelOrder (pScreen, subPixelOrder); } - - if (PictureGetSubpixelOrder (pScreen) == SubPixelUnknown) { - switch (info->DisplayType) { - case MT_NONE: subPixelOrder = SubPixelUnknown; break; - case MT_LCD: subPixelOrder = SubPixelHorizontalRGB; break; - case MT_DFP: subPixelOrder = SubPixelHorizontalRGB; break; - default: subPixelOrder = SubPixelNone; break; - } - PictureSetSubpixelOrder (pScreen, subPixelOrder); - } #endif + pScrn->vtSema = TRUE; if (info->FBDev) { unsigned char *RADEONMMIO = info->MMIO; @@ -4099,12 +3633,29 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, info->ModeReg.surface_cntl = INREG(RADEON_SURFACE_CNTL); info->ModeReg.surface_cntl &= ~RADEON_SURF_TRANSLATION_DIS; } else { - if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE; + int i; + for (i = 0; i < xf86_config->num_crtc; i++) + { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + + /* Mark that we'll need to re-set the mode for sure */ + memset(&crtc->mode, 0, sizeof(crtc->mode)); + if (!crtc->desiredMode.CrtcHDisplay) { + crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode); + crtc->desiredRotation = RR_Rotate_0; + crtc->desiredX = 0; + crtc->desiredY = 0; + } + + if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation, crtc->desiredX, crtc->desiredY)) + return FALSE; + + } } RADEONSaveScreen(pScreen, SCREEN_SAVER_ON); - pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + // pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); /* Backing store setup */ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, @@ -4158,15 +3709,10 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, #endif /* Make sure surfaces are allright since DRI setup may have changed them */ - if (!info->IsSecondary) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, - "Setting up final surfaces\n"); - RADEONChangeSurfaces(pScrn); - } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, + "Setting up final surfaces\n"); - if(info->MergedFB) - /* need this here to fix up sarea values */ - RADEONAdjustFrameMerged(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + RADEONChangeSurfaces(pScrn); /* Enable aceleration */ if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) { @@ -4189,7 +3735,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, /* Init DPMS */ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "Initializing DPMS\n"); - xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0); + xf86DPMSInit(pScreen, xf86DPMSSet, 0); xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "Initializing Cursor\n"); @@ -4229,45 +3775,16 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); } - /* Colormap setup */ - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, - "Initializing color map\n"); - if (!miCreateDefColormap(pScreen)) return FALSE; - if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8, - RADEONLoadPalette, NULL, - CMAP_PALETTED_TRUECOLOR -#if 0 /* This option messes up text mode! (eich@suse.de) */ - | CMAP_LOAD_EVEN_IF_OFFSCREEN -#endif - | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; - /* DGA setup */ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "Initializing DGA\n"); RADEONDGAInit(pScreen); - /* Wrap some funcs for MergedFB */ - if(info->MergedFB) { - info->PointerMoved = pScrn->PointerMoved; - pScrn->PointerMoved = RADEONMergePointerMoved; - /* Psuedo xinerama */ - if(info->UseRADEONXinerama) { - RADEONnoPanoramiXExtension = FALSE; - RADEONXineramaExtensionInit(pScrn); - } else { - info->MouseRestrictions = FALSE; - } - } - /* Init Xv */ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "Initializing Xv\n"); RADEONInitVideo(pScreen); - if(info->MergedFB) - /* need this here to fix up sarea values */ - RADEONAdjustFrameMerged(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - /* Provide SaveScreen & wrap BlockHandler and CloseScreen */ /* Wrap CloseScreen */ info->CloseScreen = pScreen->CloseScreen; @@ -4276,6 +3793,25 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, info->BlockHandler = pScreen->BlockHandler; pScreen->BlockHandler = RADEONBlockHandler; + if (!xf86CrtcScreenInit (pScreen)) + return FALSE; + + /* Wrap pointer motion to flip touch screen around */ + info->PointerMoved = pScrn->PointerMoved; + pScrn->PointerMoved = RADEONPointerMoved; + + /* Colormap setup */ + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, + "Initializing color map\n"); + if (!miCreateDefColormap(pScreen)) return FALSE; + if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8, + RADEONLoadPalette, NULL, + CMAP_PALETTED_TRUECOLOR +#if 0 /* This option messes up text mode! (eich@suse.de) */ + | CMAP_LOAD_EVEN_IF_OFFSCREEN +#endif + | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; + /* Note unused options */ if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); @@ -4287,7 +3823,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, } /* Write memory mapping registers */ -static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn, +void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -4500,7 +4036,7 @@ static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) #endif /* Write common registers */ -static void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn, +void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -4525,17 +4061,13 @@ static void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn, * CRT are connected. */ if (pRADEONEnt->HasCRTC2 && - !info->IsSwitching && info->ChipFamily != CHIP_FAMILY_R200 && !IS_R300_VARIANT) { CARD32 tmp; - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - if (pRADEONEnt->HasSecondary || info->MergedFB) { - tmp = INREG(RADEON_DAC_CNTL2); - OUTREG(RADEON_DAC_CNTL2, tmp & ~RADEON_DAC2_DAC_CLK_SEL); - usleep(100000); - } + tmp = INREG(RADEON_DAC_CNTL2); + OUTREG(RADEON_DAC_CNTL2, tmp & ~RADEON_DAC2_DAC_CLK_SEL); + usleep(100000); } } @@ -4565,8 +4097,44 @@ static void RADEONRestoreFBDevRegisters(ScrnInfoPtr pScrn, #endif } +void RADEONRestoreDACRegisters(ScrnInfoPtr pScrn, + RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + if (IS_R300_VARIANT) + OUTREGP(RADEON_GPIOPAD_A, restore->gpiopad_a, ~1); + + OUTREGP(RADEON_DAC_CNTL, + restore->dac_cntl, + RADEON_DAC_RANGE_CNTL | + RADEON_DAC_BLANKING); + + OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl); + + if ((info->ChipFamily != CHIP_FAMILY_RADEON) && + (info->ChipFamily != CHIP_FAMILY_R200)) + OUTREG (RADEON_TV_DAC_CNTL, restore->tv_dac_cntl); + + OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl); + + if ((info->ChipFamily == CHIP_FAMILY_R200) || + IS_R300_VARIANT) { + OUTREG(RADEON_DISP_TV_OUT_CNTL, restore->disp_tv_out_cntl); + } else { + OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug); + } + + OUTREG(RADEON_DAC_MACRO_CNTL, restore->dac_macro_cntl); + + /* R200 DAC connected via DVO */ + if (info->ChipFamily == CHIP_FAMILY_R200) + OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl); +} + /* Write CRTC registers */ -static void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn, +void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -4588,11 +4156,6 @@ static void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn, RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_DISPLAY_DIS); - OUTREGP(RADEON_DAC_CNTL, - restore->dac_cntl, - RADEON_DAC_RANGE_CNTL | - RADEON_DAC_BLANKING); - OUTREG(RADEON_CRTC_H_TOTAL_DISP, restore->crtc_h_total_disp); OUTREG(RADEON_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid); OUTREG(RADEON_CRTC_V_TOTAL_DISP, restore->crtc_v_total_disp); @@ -4603,8 +4166,11 @@ static void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn, OUTREG(RADEON_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp); OUTREG(RADEON_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp); - OUTREG(RADEON_CRTC_OFFSET, restore->crtc_offset); + if (IS_R300_VARIANT) + OUTREG(R300_CRTC_TILE_X0_Y0, restore->crtc_tile_x0_y0); OUTREG(RADEON_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl); + OUTREG(RADEON_CRTC_OFFSET, restore->crtc_offset); + OUTREG(RADEON_CRTC_PITCH, restore->crtc_pitch); OUTREG(RADEON_DISP_MERGE_CNTL, restore->disp_merge_cntl); OUTREG(RADEON_CRTC_MORE_CNTL, restore->crtc_more_cntl); @@ -4620,43 +4186,24 @@ static void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn, } /* Write CRTC2 registers */ -static void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn, +void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr restore) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - CARD32 crtc2_gen_cntl; + /* CARD32 crtc2_gen_cntl;*/ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "Programming CRTC2, offset: 0x%08lx\n", restore->crtc2_offset); - crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL) & - (RADEON_CRTC2_VSYNC_DIS | - RADEON_CRTC2_HSYNC_DIS | - RADEON_CRTC2_DISP_DIS); - crtc2_gen_cntl |= restore->crtc2_gen_cntl; - /* We prevent the CRTC from hitting the memory controller until * fully programmed */ OUTREG(RADEON_CRTC2_GEN_CNTL, - crtc2_gen_cntl | RADEON_CRTC2_DISP_REQ_EN_B); - - OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl); - - //OUTREG(RADEON_TV_DAC_CNTL, 0x00280203); - if ((info->ChipFamily != CHIP_FAMILY_RADEON) && - (info->ChipFamily != CHIP_FAMILY_R200)) - OUTREG (RADEON_TV_DAC_CNTL, restore->tv_dac_cntl); - - if ((info->ChipFamily == CHIP_FAMILY_R200) || - IS_R300_VARIANT) { - OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl); - OUTREG(RADEON_DISP_TV_OUT_CNTL, restore->disp_tv_out_cntl); - } else { - OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug); - } + restore->crtc2_gen_cntl | RADEON_CRTC2_VSYNC_DIS | + RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_DIS | + RADEON_CRTC2_DISP_REQ_EN_B); OUTREG(RADEON_CRTC2_H_TOTAL_DISP, restore->crtc2_h_total_disp); OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, restore->crtc2_h_sync_strt_wid); @@ -4666,8 +4213,11 @@ static void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn, OUTREG(RADEON_FP_H2_SYNC_STRT_WID, restore->fp_h2_sync_strt_wid); OUTREG(RADEON_FP_V2_SYNC_STRT_WID, restore->fp_v2_sync_strt_wid); - OUTREG(RADEON_CRTC2_OFFSET, restore->crtc2_offset); + if (IS_R300_VARIANT) + OUTREG(R300_CRTC2_TILE_X0_Y0, restore->crtc2_tile_x0_y0); OUTREG(RADEON_CRTC2_OFFSET_CNTL, restore->crtc2_offset_cntl); + OUTREG(RADEON_CRTC2_OFFSET, restore->crtc2_offset); + OUTREG(RADEON_CRTC2_PITCH, restore->crtc2_pitch); OUTREG(RADEON_DISP2_MERGE_CNTL, restore->disp2_merge_cntl); @@ -4677,12 +4227,12 @@ static void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn, OUTREG(RADEON_RS480_UNK_e38, restore->rs480_unk_e38); OUTREG(RADEON_RS480_UNK_e3c, restore->rs480_unk_e3c); } - OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); + OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl); } -/* Write flat panel registers */ -static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +/* Write TMDS registers */ +void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) { RADEONInfoPtr info = RADEONPTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); @@ -4690,8 +4240,6 @@ static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) OUTREG(RADEON_TMDS_PLL_CNTL, restore->tmds_pll_cntl); OUTREG(RADEON_TMDS_TRANSMITTER_CNTL,restore->tmds_transmitter_cntl); - OUTREG(RADEON_FP_HORZ_STRETCH, restore->fp_horz_stretch); - OUTREG(RADEON_FP_VERT_STRETCH, restore->fp_vert_stretch); OUTREG(RADEON_FP_GEN_CNTL, restore->fp_gen_cntl); /* old AIW Radeon has some BIOS initialization problem @@ -4701,7 +4249,40 @@ static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) OUTREG(RADEON_GRPH_BUFFER_CNTL, INREG(RADEON_GRPH_BUFFER_CNTL) & ~0x7f0000); +} + +/* Write FP2 registers */ +void RADEONRestoreFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl); + +} + +/* Write RMX registers */ +void RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_FP_HORZ_STRETCH, restore->fp_horz_stretch); + OUTREG(RADEON_FP_VERT_STRETCH, restore->fp_vert_stretch); + +} + +/* Write LVDS registers */ +void RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + 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); @@ -4709,6 +4290,276 @@ static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) } +/* Write to TV FIFO RAM */ +static void RADEONWriteTVFIFO(ScrnInfoPtr pScrn, CARD16 addr, + CARD32 value) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 tmp; + int i = 0; + + OUTREG(RADEON_TV_HOST_WRITE_DATA, value); + + OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr); + OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT); + + do { + tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL); + if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0) + break; + i++; + } + while (i < 10000); + /*while ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0);*/ + + OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0); +} + +/* Read from TV FIFO RAM */ +static CARD32 RADEONReadTVFIFO(ScrnInfoPtr pScrn, CARD16 addr) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 tmp; + int i = 0; + + OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr); + OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD); + + do { + tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL); + if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0) + break; + i++; + } + while (i < 10000); + /*while ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0);*/ + + OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0); + + return INREG(RADEON_TV_HOST_READ_DATA); +} + +/* Get FIFO addresses of horizontal & vertical code timing tables from + * settings of uv_adr register. + */ +static CARD16 RADEONGetHTimingTablesAddr(CARD32 tv_uv_adr) +{ + CARD16 hTable; + + switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) { + case 0: + hTable = RADEON_TV_MAX_FIFO_ADDR_INTERNAL; + break; + case 1: + hTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2; + break; + case 2: + hTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2; + break; + default: + /* Of course, this should never happen */ + hTable = 0; + break; + } + return hTable; +} + +static CARD16 RADEONGetVTimingTablesAddr(CARD32 tv_uv_adr) +{ + CARD16 vTable; + + switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) { + case 0: + vTable = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1; + break; + case 1: + vTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1; + break; + case 2: + vTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1; + break; + default: + /* Of course, this should never happen */ + vTable = 0; + break; + } + return vTable; +} + +/* Restore horizontal/vertical timing code tables */ +static void RADEONRestoreTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD16 hTable; + CARD16 vTable; + CARD32 tmp; + unsigned i; + + OUTREG(RADEON_TV_UV_ADR, restore->tv_uv_adr); + hTable = RADEONGetHTimingTablesAddr(restore->tv_uv_adr); + vTable = RADEONGetVTimingTablesAddr(restore->tv_uv_adr); + + OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST + | RADEON_CRT_ASYNC_RST + | RADEON_RESTART_PHASE_FIX + | RADEON_CRT_FIFO_CE_EN + | RADEON_TV_FIFO_CE_EN + | RADEON_TV_ON)); + + /*OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl | RADEON_TV_ON);*/ + + for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, hTable--) { + tmp = ((CARD32)restore->h_code_timing[ i ] << 14) | ((CARD32)restore->h_code_timing[ i + 1 ]); + RADEONWriteTVFIFO(pScrn, hTable, tmp); + if (restore->h_code_timing[ i ] == 0 || restore->h_code_timing[ i + 1 ] == 0) + break; + } + + for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, vTable++) { + tmp = ((CARD32)restore->v_code_timing[ i + 1 ] << 14) | ((CARD32)restore->v_code_timing[ i ]); + RADEONWriteTVFIFO(pScrn, vTable, tmp); + if (restore->v_code_timing[ i ] == 0 || restore->v_code_timing[ i + 1 ] == 0) + break; + } +} + +/* restore TV PLLs */ +static void RADEONRestoreTVPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + + OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL); + OUTPLL(pScrn, RADEON_TV_PLL_CNTL, restore->tv_pll_cntl); + OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET); + + RADEONWaitPLLLock(pScrn, 200, 800, 135); + + OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET); + + RADEONWaitPLLLock(pScrn, 300, 160, 27); + RADEONWaitPLLLock(pScrn, 200, 800, 135); + + OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~0xf); + OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL); + + OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK); + OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP); +} + +/* Restore TV horizontal/vertical settings */ +static void RADEONRestoreTVHVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_TV_RGB_CNTL, restore->tv_rgb_cntl); + + OUTREG(RADEON_TV_HTOTAL, restore->tv_htotal); + OUTREG(RADEON_TV_HDISP, restore->tv_hdisp); + OUTREG(RADEON_TV_HSTART, restore->tv_hstart); + + OUTREG(RADEON_TV_VTOTAL, restore->tv_vtotal); + OUTREG(RADEON_TV_VDISP, restore->tv_vdisp); + + OUTREG(RADEON_TV_FTOTAL, restore->tv_ftotal); + + OUTREG(RADEON_TV_VSCALER_CNTL1, restore->tv_vscaler_cntl1); + OUTREG(RADEON_TV_VSCALER_CNTL2, restore->tv_vscaler_cntl2); + + OUTREG(RADEON_TV_Y_FALL_CNTL, restore->tv_y_fall_cntl); + OUTREG(RADEON_TV_Y_RISE_CNTL, restore->tv_y_rise_cntl); + OUTREG(RADEON_TV_Y_SAW_TOOTH_CNTL, restore->tv_y_saw_tooth_cntl); +} + +/* restore TV RESTART registers */ +static void RADEONRestoreTVRestarts(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_TV_FRESTART, restore->tv_frestart); + OUTREG(RADEON_TV_HRESTART, restore->tv_hrestart); + OUTREG(RADEON_TV_VRESTART, restore->tv_vrestart); +} + +/* restore tv standard & output muxes */ +static void RADEONRestoreTVOutputStd(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_TV_SYNC_CNTL, restore->tv_sync_cntl); + + OUTREG(RADEON_TV_TIMING_CNTL, restore->tv_timing_cntl); + + OUTREG(RADEON_TV_MODULATOR_CNTL1, restore->tv_modulator_cntl1); + OUTREG(RADEON_TV_MODULATOR_CNTL2, restore->tv_modulator_cntl2); + + OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, restore->tv_pre_dac_mux_cntl); + + OUTREG(RADEON_TV_CRC_CNTL, restore->tv_crc_cntl); +} + +/* Restore TV out regs */ +void RADEONRestoreTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + ErrorF("Entering Restore TV\n"); + + OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl | RADEON_TV_ON); + + OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl + | RADEON_TV_ASYNC_RST + | RADEON_CRT_ASYNC_RST + | RADEON_RESTART_PHASE_FIX + | RADEON_TV_FIFO_ASYNC_RST)); + + /* Temporarily turn the TV DAC off */ + OUTREG(RADEON_TV_DAC_CNTL, ((restore->tv_dac_cntl & ~RADEON_TV_DAC_NBLANK) + | RADEON_TV_DAC_BGSLEEP + | RADEON_TV_DAC_RDACPD + | RADEON_TV_DAC_GDACPD + | RADEON_TV_DAC_BDACPD)); + + ErrorF("Restore TV PLL\n"); + RADEONRestoreTVPLLRegisters(pScrn, restore); + + ErrorF("Restore TVHV\n"); + RADEONRestoreTVHVRegisters(pScrn, restore); + + OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl + | RADEON_TV_ASYNC_RST + | RADEON_CRT_ASYNC_RST + | RADEON_RESTART_PHASE_FIX)); + + ErrorF("Restore TV Restarts\n"); + RADEONRestoreTVRestarts(pScrn, restore); + + ErrorF("Restore Timing Tables\n"); + RADEONRestoreTVTimingTables(pScrn, restore); + + + OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl + | RADEON_TV_ASYNC_RST + | RADEON_RESTART_PHASE_FIX)); + + ErrorF("Restore TV standard\n"); + RADEONRestoreTVOutputStd(pScrn, restore); + + OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl); + + OUTREG(RADEON_TV_GAIN_LIMIT_SETTINGS, restore->tv_gain_limit_settings); + OUTREG(RADEON_TV_LINEAR_GAIN_SETTINGS, restore->tv_linear_gain_settings); + + OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl); + + ErrorF("Leaving Restore TV\n"); +} + static void RADEONPLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn) { int i = 0; @@ -4755,12 +4606,81 @@ static void RADEONPLL2WriteUpdate(ScrnInfoPtr pScrn) ~(RADEON_P2PLL_ATOMIC_UPDATE_W)); } +static CARD8 RADEONComputePLLGain(CARD16 reference_freq, CARD16 ref_div, + CARD16 fb_div) +{ + unsigned vcoFreq; + + if (!ref_div) + return 1; + + vcoFreq = ((unsigned)reference_freq * fb_div) / ref_div; + + /* + * This is horribly crude: the VCO frequency range is divided into + * 3 parts, each part having a fixed PLL gain value. + */ + if (vcoFreq >= 30000) + /* + * [300..max] MHz : 7 + */ + return 7; + else if (vcoFreq >= 18000) + /* + * [180..300) MHz : 4 + */ + return 4; + else + /* + * [0..180) MHz : 1 + */ + return 1; +} + +/* Wait for PLLs to lock */ +static void RADEONWaitPLLLock(ScrnInfoPtr pScrn, unsigned nTests, + unsigned nWaitLoops, unsigned cntThreshold) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 savePLLTest; + unsigned i; + unsigned j; + + OUTREG(RADEON_TEST_DEBUG_MUX, (INREG(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100); + + savePLLTest = INPLL(pScrn, RADEON_PLL_TEST_CNTL); + + OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest & ~RADEON_PLL_MASK_READ_B); + + /* XXX: these should probably be OUTPLL to avoid various PLL errata */ + + OUTREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL); + + for (i = 0; i < nTests; i++) { + OUTREG8(RADEON_CLOCK_CNTL_DATA + 3, 0); + + for (j = 0; j < nWaitLoops; j++) + if (INREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cntThreshold) + break; + } + + OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest); + + OUTREG(RADEON_TEST_DEBUG_MUX, INREG(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff); +} + /* Write PLL registers */ -static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn, - RADEONSavePtr restore) +void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn, + RADEONSavePtr restore) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; + CARD8 pllGain; + + pllGain = RADEONComputePLLGain(info->pll.reference_freq, + restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK, + restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK); if (info->IsMobility) { /* A temporal workaround for the occational blanking on certain laptop panels. @@ -4788,10 +4708,12 @@ static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn, RADEON_PPLL_CNTL, RADEON_PPLL_RESET | RADEON_PPLL_ATOMIC_UPDATE_EN - | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN, + | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN + | ((CARD32)pllGain << RADEON_PPLL_PVG_SHIFT), ~(RADEON_PPLL_RESET | RADEON_PPLL_ATOMIC_UPDATE_EN - | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN)); + | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN + | RADEON_PPLL_PVG_MASK)); OUTREGP(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_DIV_SEL, @@ -4854,16 +4776,28 @@ static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn, usleep(50000); /* Let the clock to lock */ - OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, + /* OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, RADEON_VCLK_SRC_SEL_PPLLCLK, - ~(RADEON_VCLK_SRC_SEL_MASK)); + ~(RADEON_VCLK_SRC_SEL_MASK));*/ + OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, restore->vclk_ecp_cntl); + + ErrorF("finished PLL1\n"); + } /* Write PLL2 registers */ -static void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn, - RADEONSavePtr restore) +void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn, + RADEONSavePtr restore) { + RADEONInfoPtr info = RADEONPTR(pScrn); + CARD8 pllGain; + + pllGain = RADEONComputePLLGain(info->pll.reference_freq, + restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK, + restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK); + + OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, RADEON_PIX2CLK_SRC_SEL_CPUCLK, ~(RADEON_PIX2CLK_SRC_SEL_MASK)); @@ -4871,9 +4805,11 @@ static void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn, OUTPLLP(pScrn, RADEON_P2PLL_CNTL, RADEON_P2PLL_RESET - | RADEON_P2PLL_ATOMIC_UPDATE_EN, + | RADEON_P2PLL_ATOMIC_UPDATE_EN + | ((CARD32)pllGain << RADEON_P2PLL_PVG_SHIFT), ~(RADEON_P2PLL_RESET - | RADEON_P2PLL_ATOMIC_UPDATE_EN)); + | RADEON_P2PLL_ATOMIC_UPDATE_EN + | RADEON_P2PLL_PVG_MASK)); OUTPLLP(pScrn, RADEON_P2PLL_REF_DIV, @@ -4913,9 +4849,13 @@ static void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn, usleep(5000); /* Let the clock to lock */ - OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, + /*OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, RADEON_PIX2CLK_SRC_SEL_P2PLLCLK, - ~(RADEON_PIX2CLK_SRC_SEL_MASK)); + ~(RADEON_PIX2CLK_SRC_SEL_MASK));*/ + OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, restore->pixclks_cntl); + + ErrorF("finished PLL2\n"); + } @@ -5082,143 +5022,24 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn) unsigned int surf_info = swap_pattern; unsigned char *RADEONMMIO = info->MMIO; /* we don't need anything like WaitForFifo, no? */ - if (!info->IsSecondary) { - if (info->tilingEnabled) { - if (IS_R300_VARIANT) - surf_info |= (width_bytes / 8) | color_pattern; - else - surf_info |= (width_bytes / 16) | color_pattern; - } - OUTREG(RADEON_SURFACE0_INFO, surf_info); - OUTREG(RADEON_SURFACE0_LOWER_BOUND, 0); - OUTREG(RADEON_SURFACE0_UPPER_BOUND, bufferSize - 1); + if (info->tilingEnabled) { + if (IS_R300_VARIANT) + surf_info |= (width_bytes / 8) | color_pattern; + else + surf_info |= (width_bytes / 16) | color_pattern; + } + OUTREG(RADEON_SURFACE0_INFO, surf_info); + OUTREG(RADEON_SURFACE0_LOWER_BOUND, 0); + OUTREG(RADEON_SURFACE0_UPPER_BOUND, bufferSize - 1); /* xf86DrvMsg(pScrn->scrnIndex, X_INFO, "surface0 set to %x, LB 0x%x UB 0x%x\n", surf_info, 0, bufferSize - 1024);*/ - } } /* Update surface images */ RADEONSaveSurfaces(pScrn, &info->ModeReg); } -#if 0 -/* Write palette data */ -static void RADEONRestorePalette(ScrnInfoPtr pScrn, RADEONSavePtr restore) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - unsigned char *RADEONMMIO = info->MMIO; - int i; - - if (!restore->palette_valid) return; - - PAL_SELECT(1); - OUTPAL_START(0); - for (i = 0; i < 256; i++) { - RADEONWaitForFifo(pScrn, 32); /* delay */ - OUTPAL_NEXT_CARD32(restore->palette2[i]); - } - - PAL_SELECT(0); - OUTPAL_START(0); - for (i = 0; i < 256; i++) { - RADEONWaitForFifo(pScrn, 32); /* delay */ - OUTPAL_NEXT_CARD32(restore->palette[i]); - } -} -#endif - -/* Write out state to define a new video mode */ -static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - RADEONController* pCRTC1 = pRADEONEnt->Controller[0]; - RADEONController* pCRTC2 = pRADEONEnt->Controller[1]; - RADEONConnector *pPort; - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, - "RADEONRestoreMode(%p)\n", restore); - - /* For Non-dual head card, we don't have private field in the Entity */ - if (!pRADEONEnt->HasCRTC2) { - RADEONRestoreMemMapRegisters(pScrn, restore); - RADEONRestoreCommonRegisters(pScrn, restore); - RADEONRestoreCrtcRegisters(pScrn, restore); - RADEONRestoreFPRegisters(pScrn, restore); - RADEONRestorePLLRegisters(pScrn, restore); - return; - } - - /* Disable all outputs at initial mode set. the ones we want will - get set by RADEONEnableDisplay() - */ - if (!info->IsSwitching && !info->IsSecondary) - RADEONDisableDisplays(pScrn); - - /* When changing mode with Dual-head card, care must be taken for - * the special order in setting registers. CRTC2 has to be set - * before changing CRTC_EXT register. In the dual-head setup, X - * server calls this routine twice with primary and secondary pScrn - * pointers respectively. The calls can come with different - * order. Regardless the order of X server issuing the calls, we - * have to ensure we set registers in the right order!!! Otherwise - * we may get a blank screen. - * - * We always restore MemMap first, the saverec should be up to date - * in all cases - */ - if (info->IsSwitching) { - if (info->IsSecondary) { - RADEONRestoreMemMapRegisters(pScrn, restore); - RADEONRestoreCommonRegisters(pScrn, restore); - RADEONRestoreCrtc2Registers(pScrn, restore); - RADEONRestorePLL2Registers(pScrn, restore); - RADEONRestoreFPRegisters(pScrn, restore); - RADEONEnableDisplay(pScrn, pRADEONEnt->PortInfo[1], TRUE); - pCRTC2->IsActive = TRUE; - } else { - RADEONRestoreMemMapRegisters(pScrn, restore); - RADEONRestoreCommonRegisters(pScrn, restore); - if (pCRTC2->binding == 1) { - RADEONRestoreCrtc2Registers(pScrn, restore); - RADEONRestorePLL2Registers(pScrn, restore); - } - - RADEONRestoreCrtcRegisters(pScrn, restore); - RADEONRestorePLLRegisters(pScrn, restore); - RADEONRestoreFPRegisters(pScrn, restore); - RADEONEnableDisplay(pScrn, pRADEONEnt->PortInfo[0], TRUE); - pCRTC1->IsActive = TRUE; - if (pCRTC2->binding == 1) { - RADEONEnableDisplay(pScrn, pRADEONEnt->PortInfo[1], TRUE); - pCRTC2->IsActive = TRUE; - } - } - } else { - RADEONRestoreMemMapRegisters(pScrn, restore); - RADEONRestoreCommonRegisters(pScrn, restore); - if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) { - RADEONRestoreCrtc2Registers(pScrn, restore); - RADEONRestorePLL2Registers(pScrn, restore); - } - - RADEONRestoreCrtcRegisters(pScrn, restore); - RADEONRestorePLLRegisters(pScrn, restore); - RADEONRestoreFPRegisters(pScrn, restore); - RADEONEnableDisplay(pScrn, pRADEONEnt->PortInfo[0], TRUE); - pCRTC1->IsActive = TRUE; - if (pCRTC2->binding == 1) { - RADEONEnableDisplay(pScrn, pRADEONEnt->PortInfo[1], TRUE); - pCRTC2->IsActive = TRUE; - } - } - -#if 0 - RADEONRestorePalette(pScrn, &info->SavedReg); -#endif -} - /* Read memory map */ static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) { @@ -5285,7 +5106,6 @@ static void RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) save->crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL); save->crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL); - save->dac_cntl = INREG(RADEON_DAC_CNTL); save->crtc_h_total_disp = INREG(RADEON_CRTC_H_TOTAL_DISP); save->crtc_h_sync_strt_wid = INREG(RADEON_CRTC_H_SYNC_STRT_WID); save->crtc_v_total_disp = INREG(RADEON_CRTC_V_TOTAL_DISP); @@ -5302,12 +5122,39 @@ static void RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) save->disp_merge_cntl = INREG(RADEON_DISP_MERGE_CNTL); save->crtc_more_cntl = INREG(RADEON_CRTC_MORE_CNTL); + if (IS_R300_VARIANT) + save->crtc_tile_x0_y0 = INREG(R300_CRTC_TILE_X0_Y0); + if (info->IsDellServer) { save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL); save->dac2_cntl = INREG(RADEON_DAC_CNTL2); save->disp_hw_debug = INREG (RADEON_DISP_HW_DEBUG); save->crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL); } + + /* track if the crtc is enabled for text restore */ + if (save->crtc_ext_cntl & RADEON_CRTC_DISPLAY_DIS) + info->crtc_on = FALSE; + else + info->crtc_on = TRUE; + +} + +/* Read DAC registers */ +static void RADEONSaveDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + save->dac_cntl = INREG(RADEON_DAC_CNTL); + save->dac2_cntl = INREG(RADEON_DAC_CNTL2); + save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL); + save->disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL); + save->disp_tv_out_cntl = INREG(RADEON_DISP_TV_OUT_CNTL); + save->disp_hw_debug = INREG(RADEON_DISP_HW_DEBUG); + save->dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL); + save->gpiopad_a = INREG(RADEON_GPIOPAD_A); + } /* Read flat panel registers */ @@ -5340,12 +5187,6 @@ static void RADEONSaveCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save) RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - save->dac2_cntl = INREG(RADEON_DAC_CNTL2); - save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL); - save->disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL); - save->disp_tv_out_cntl = INREG(RADEON_DISP_TV_OUT_CNTL); - save->disp_hw_debug = INREG (RADEON_DISP_HW_DEBUG); - save->crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL); save->crtc2_h_total_disp = INREG(RADEON_CRTC2_H_TOTAL_DISP); save->crtc2_h_sync_strt_wid = INREG(RADEON_CRTC2_H_SYNC_STRT_WID); @@ -5355,6 +5196,9 @@ static void RADEONSaveCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save) save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL); save->crtc2_pitch = INREG(RADEON_CRTC2_PITCH); + if (IS_R300_VARIANT) + save->crtc2_tile_x0_y0 = INREG(R300_CRTC2_TILE_X0_Y0); + save->fp_h2_sync_strt_wid = INREG (RADEON_FP_H2_SYNC_STRT_WID); save->fp_v2_sync_strt_wid = INREG (RADEON_FP_V2_SYNC_STRT_WID); @@ -5366,6 +5210,106 @@ static void RADEONSaveCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save) } save->disp2_merge_cntl = INREG(RADEON_DISP2_MERGE_CNTL); + + /* track if the crtc is enabled for text restore */ + if (save->crtc2_gen_cntl & RADEON_CRTC2_DISP_DIS) + info->crtc2_on = FALSE; + else + info->crtc2_on = TRUE; + +} + +/* Save horizontal/vertical timing code tables */ +static void RADEONSaveTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD16 hTable; + CARD16 vTable; + CARD32 tmp; + unsigned i; + + save->tv_uv_adr = INREG(RADEON_TV_UV_ADR); + hTable = RADEONGetHTimingTablesAddr(save->tv_uv_adr); + vTable = RADEONGetVTimingTablesAddr(save->tv_uv_adr); + + /* + * Reset FIFO arbiter in order to be able to access FIFO RAM + */ + + OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST + | RADEON_CRT_ASYNC_RST + | RADEON_RESTART_PHASE_FIX + | RADEON_CRT_FIFO_CE_EN + | RADEON_TV_FIFO_CE_EN + | RADEON_TV_ON)); + + /*OUTREG(RADEON_TV_MASTER_CNTL, save->tv_master_cntl | RADEON_TV_ON);*/ + + ErrorF("saveTimingTables: reading timing tables\n"); + + for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2) { + tmp = RADEONReadTVFIFO(pScrn, hTable--); + save->h_code_timing[ i ] = (CARD16)((tmp >> 14) & 0x3fff); + save->h_code_timing[ i + 1 ] = (CARD16)(tmp & 0x3fff); + + if (save->h_code_timing[ i ] == 0 || save->h_code_timing[ i + 1 ] == 0) + break; + } + + for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2) { + tmp = RADEONReadTVFIFO(pScrn, vTable++); + save->v_code_timing[ i ] = (CARD16)(tmp & 0x3fff); + save->v_code_timing[ i + 1 ] = (CARD16)((tmp >> 14) & 0x3fff); + + if (save->v_code_timing[ i ] == 0 || save->v_code_timing[ i + 1 ] == 0) + break; + } +} + +/* read TV regs */ +static void RADEONSaveTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + unsigned i; + + ErrorF("Entering TV Save\n"); + + save->tv_crc_cntl = INREG(RADEON_TV_CRC_CNTL); + save->tv_frestart = INREG(RADEON_TV_FRESTART); + save->tv_hrestart = INREG(RADEON_TV_HRESTART); + save->tv_vrestart = INREG(RADEON_TV_VRESTART); + save->tv_gain_limit_settings = INREG(RADEON_TV_GAIN_LIMIT_SETTINGS); + save->tv_hdisp = INREG(RADEON_TV_HDISP); + save->tv_hstart = INREG(RADEON_TV_HSTART); + save->tv_htotal = INREG(RADEON_TV_HTOTAL); + save->tv_linear_gain_settings = INREG(RADEON_TV_LINEAR_GAIN_SETTINGS); + save->tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL); + save->tv_rgb_cntl = INREG(RADEON_TV_RGB_CNTL); + save->tv_modulator_cntl1 = INREG(RADEON_TV_MODULATOR_CNTL1); + save->tv_modulator_cntl2 = INREG(RADEON_TV_MODULATOR_CNTL2); + save->tv_pre_dac_mux_cntl = INREG(RADEON_TV_PRE_DAC_MUX_CNTL); + save->tv_sync_cntl = INREG(RADEON_TV_SYNC_CNTL); + save->tv_timing_cntl = INREG(RADEON_TV_TIMING_CNTL); + save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL); + save->tv_upsamp_and_gain_cntl = INREG(RADEON_TV_UPSAMP_AND_GAIN_CNTL); + save->tv_vdisp = INREG(RADEON_TV_VDISP); + save->tv_ftotal = INREG(RADEON_TV_FTOTAL); + save->tv_vscaler_cntl1 = INREG(RADEON_TV_VSCALER_CNTL1); + save->tv_vscaler_cntl2 = INREG(RADEON_TV_VSCALER_CNTL2); + save->tv_vtotal = INREG(RADEON_TV_VTOTAL); + save->tv_y_fall_cntl = INREG(RADEON_TV_Y_FALL_CNTL); + save->tv_y_rise_cntl = INREG(RADEON_TV_Y_RISE_CNTL); + save->tv_y_saw_tooth_cntl = INREG(RADEON_TV_Y_SAW_TOOTH_CNTL); + + save->tv_pll_cntl = INPLL(pScrn, RADEON_TV_PLL_CNTL); + + ErrorF("Save TV timing tables\n"); + + RADEONSaveTVTimingTables(pScrn, save); + + ErrorF("TV Save done\n"); } /* Read PLL registers */ @@ -5374,7 +5318,7 @@ static void RADEONSavePLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) save->ppll_ref_div = INPLL(pScrn, RADEON_PPLL_REF_DIV); save->ppll_div_3 = INPLL(pScrn, RADEON_PPLL_DIV_3); save->htotal_cntl = INPLL(pScrn, RADEON_HTOTAL_CNTL); - save->vclk_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL); + save->vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL); xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "Read: 0x%08x 0x%08x 0x%08lx\n", @@ -5431,26 +5375,22 @@ static void RADEONSavePalette(ScrnInfoPtr pScrn, RADEONSavePtr save) /* Save state that defines current video mode */ static void RADEONSaveMode(ScrnInfoPtr pScrn, RADEONSavePtr save) { - RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONInfoPtr info = RADEONPTR(pScrn); xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "RADEONSaveMode(%p)\n", save); - if (info->IsSecondary) { - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - RADEONInfoPtr info0 = RADEONPTR(pRADEONEnt->pPrimaryScrn); - memcpy(&info->SavedReg, &info0->SavedReg, sizeof(RADEONSaveRec)); - } else { - RADEONSaveMemMapRegisters(pScrn, save); - RADEONSaveCommonRegisters(pScrn, save); - RADEONSavePLLRegisters (pScrn, save); - RADEONSaveCrtcRegisters (pScrn, save); - RADEONSaveFPRegisters (pScrn, save); - RADEONSaveCrtc2Registers (pScrn, save); - RADEONSavePLL2Registers (pScrn, save); - /*RADEONSavePalette(pScrn, save);*/ - /*memcpy(&info->ModeReg, &info->SavedReg, sizeof(RADEONSaveRec));*/ - } + RADEONSaveMemMapRegisters(pScrn, save); + RADEONSaveCommonRegisters(pScrn, save); + RADEONSavePLLRegisters(pScrn, save); + RADEONSaveCrtcRegisters(pScrn, save); + RADEONSaveFPRegisters(pScrn, save); + RADEONSaveDACRegisters(pScrn, save); + RADEONSaveCrtc2Registers(pScrn, save); + RADEONSavePLL2Registers(pScrn, save); + if (info->InternalTVOut) + RADEONSaveTVRegisters(pScrn, save); + /*RADEONSavePalette(pScrn, save);*/ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "RADEONSaveMode returns %p\n", save); @@ -5472,43 +5412,44 @@ static void RADEONSave(ScrnInfoPtr pScrn) return; } - if (!info->IsSecondary) { + #ifdef WITH_VGAHW - if (info->VGAAccess) { - vgaHWPtr hwp = VGAHWPTR(pScrn); + if (info->VGAAccess) { + vgaHWPtr hwp = VGAHWPTR(pScrn); - vgaHWUnlock(hwp); + vgaHWUnlock(hwp); # if defined(__powerpc__) - /* temporary hack to prevent crashing on PowerMacs when trying to - * read VGA fonts and colormap, will find a better solution - * in the future. TODO: Check if there's actually some VGA stuff - * setup in the card at all !! - */ - vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */ + /* temporary hack to prevent crashing on PowerMacs when trying to + * read VGA fonts and colormap, will find a better solution + * in the future. TODO: Check if there's actually some VGA stuff + * setup in the card at all !! + */ + 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); + /* Save mode * & fonts & cmap */ + vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS); # endif - vgaHWLock(hwp); - } -#endif - save->dp_datatype = INREG(RADEON_DP_DATATYPE); - save->rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET); - save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); - RADEONPllErrataAfterIndex(info); + vgaHWLock(hwp); } +#endif + save->dp_datatype = INREG(RADEON_DP_DATATYPE); + save->rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET); + save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); + RADEONPllErrataAfterIndex(info); RADEONSaveMode(pScrn, save); - if (!info->IsSecondary) - RADEONSaveSurfaces(pScrn, save); + RADEONSaveSurfaces(pScrn, save); } /* Restore the original (text) mode */ -static void RADEONRestore(ScrnInfoPtr pScrn) +void RADEONRestore(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); unsigned char *RADEONMMIO = info->MMIO; RADEONSavePtr restore = &info->SavedReg; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86CrtcPtr crtc; xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "RADEONRestore\n"); @@ -5522,7 +5463,7 @@ static void RADEONRestore(ScrnInfoPtr pScrn) fbdevHWRestore(pScrn); return; } - RADEONBlank(pScrn, TRUE); + RADEONBlank(pScrn); OUTREG(RADEON_CLOCK_CNTL_INDEX, restore->clock_cntl_index); RADEONPllErrataAfterIndex(info); @@ -5540,11 +5481,27 @@ static void RADEONRestore(ScrnInfoPtr pScrn) OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl); #endif - RADEONRestoreMode(pScrn, restore); - if (!info->IsSecondary) - RADEONRestoreSurfaces(pScrn, restore); + RADEONRestoreMemMapRegisters(pScrn, restore); + RADEONRestoreCommonRegisters(pScrn, restore); -#if 0 + if (pRADEONEnt->HasCRTC2) { + RADEONRestoreCrtc2Registers(pScrn, restore); + RADEONRestorePLL2Registers(pScrn, restore); + } + + RADEONRestoreCrtcRegisters(pScrn, restore); + RADEONRestorePLLRegisters(pScrn, restore); + RADEONRestoreRMXRegisters(pScrn, restore); + RADEONRestoreFPRegisters(pScrn, restore); + RADEONRestoreFP2Registers(pScrn, restore); + RADEONRestoreLVDSRegisters(pScrn, restore); + + if (info->InternalTVOut) + RADEONRestoreTVRegisters(pScrn, restore); + + RADEONRestoreSurfaces(pScrn, restore); + +#if 1 /* Temp fix to "solve" VT switch problems. When switching VTs on * some systems, the console can either hang or the fonts can be * corrupted. This hack solves the problem 99% of the time. A @@ -5556,829 +5513,36 @@ static void RADEONRestore(ScrnInfoPtr pScrn) #ifdef WITH_VGAHW if (info->VGAAccess) { vgaHWPtr hwp = VGAHWPTR(pScrn); - if (!info->IsSecondary) { - vgaHWUnlock(hwp); + vgaHWUnlock(hwp); # if defined(__powerpc__) - /* Temporary hack to prevent crashing on PowerMacs when trying to - * write VGA fonts, will find a better solution in the future - */ - vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE ); + /* Temporary hack to prevent crashing on PowerMacs when trying to + * write VGA fonts, will find a better solution in the future + */ + vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE ); # else - vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS ); + vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS ); # endif - vgaHWLock(hwp); - } else { - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - ScrnInfoPtr pScrn0 = pRADEONEnt->pPrimaryScrn; - RADEONInfoPtr info0 = RADEONPTR(pScrn0); - vgaHWPtr hwp0; - - if (info0->VGAAccess) { - hwp0 = VGAHWPTR(pScrn0); - vgaHWUnlock(hwp0); -#if defined(__powerpc__) - vgaHWRestore(pScrn0, &hwp0->SavedReg, VGA_SR_MODE); -#else - vgaHWRestore(pScrn0, &hwp0->SavedReg, VGA_SR_MODE | VGA_SR_FONTS ); -#endif - vgaHWLock(hwp0); - } - } + vgaHWLock(hwp); } #endif - RADEONBlank(pScrn, FALSE); - -#if 0 - RADEONWaitForVerticalSync(pScrn); -#endif -} - -/* Define common registers for requested video mode */ -static void RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info) -{ - save->ovr_clr = 0; - save->ovr_wid_left_right = 0; - save->ovr_wid_top_bottom = 0; - save->ov0_scale_cntl = 0; - save->subpic_cntl = 0; - save->viph_control = 0; - save->i2c_cntl_1 = 0; - save->rbbm_soft_reset = 0; - save->cap0_trig_cntl = 0; - save->cap1_trig_cntl = 0; - save->bus_cntl = info->BusCntl; - /* - * If bursts are enabled, turn on discards - * Radeon doesn't have write bursts - */ - if (save->bus_cntl & (RADEON_BUS_READ_BURST)) - save->bus_cntl |= RADEON_BUS_RD_DISCARD_EN; -} - -/* XXX: fix me */ -static void RADEONInitTvDacCntl(ScrnInfoPtr pScrn, RADEONSavePtr save) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - if (info->ChipFamily == CHIP_FAMILY_R420 || - info->ChipFamily == CHIP_FAMILY_RV410) { - save->tv_dac_cntl = info->SavedReg.tv_dac_cntl & - ~(RADEON_TV_DAC_STD_MASK | - RADEON_TV_DAC_BGADJ_MASK | - R420_TV_DAC_DACADJ_MASK | - R420_TV_DAC_RDACPD | - R420_TV_DAC_GDACPD | - R420_TV_DAC_GDACPD | - R420_TV_DAC_TVENABLE); - } else { - save->tv_dac_cntl = info->SavedReg.tv_dac_cntl & - ~(RADEON_TV_DAC_STD_MASK | - RADEON_TV_DAC_BGADJ_MASK | - RADEON_TV_DAC_DACADJ_MASK | - RADEON_TV_DAC_RDACPD | - RADEON_TV_DAC_GDACPD | - RADEON_TV_DAC_GDACPD); - } - /* FIXME: doesn't make sense, this just replaces the previous value... */ - save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | - RADEON_TV_DAC_NHOLD | - RADEON_TV_DAC_STD_PS2); - // info->tv_dac_adj); -} - -static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, - DisplayModePtr mode, BOOL IsPrimary) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - int i; - CARD32 tmp = info->SavedReg.tmds_pll_cntl & 0xfffff; - - for (i=0; i<4; i++) { - if (info->tmds_pll[i].freq == 0) break; - if ((CARD32)(mode->Clock/10) < info->tmds_pll[i].freq) { - tmp = info->tmds_pll[i].value ; - break; - } - } - - if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RV280)) { - if (tmp & 0xfff00000) - save->tmds_pll_cntl = tmp; - else { - save->tmds_pll_cntl = info->SavedReg.tmds_pll_cntl & 0xfff00000; - save->tmds_pll_cntl |= tmp; - } - } else save->tmds_pll_cntl = tmp; - - save->tmds_transmitter_cntl = info->SavedReg.tmds_transmitter_cntl & - ~(RADEON_TMDS_TRANSMITTER_PLLRST); - - if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_R200) || !pRADEONEnt->HasCRTC2) - save->tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN); - else /* weird, RV chips got this bit reversed? */ - save->tmds_transmitter_cntl |= (RADEON_TMDS_TRANSMITTER_PLLEN); - - save->fp_gen_cntl = info->SavedReg.fp_gen_cntl | - (RADEON_FP_CRTC_DONT_SHADOW_VPAR | - RADEON_FP_CRTC_DONT_SHADOW_HEND ); - - if (pScrn->rgbBits == 8) - save->fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */ - else - save->fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */ - - - if (IsPrimary) { - if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) { - save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; - if (mode->Flags & RADEON_USE_RMX) - save->fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX; - else - save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1; - } else - save->fp_gen_cntl |= RADEON_FP_SEL_CRTC1; - } else { - if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) { - save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; - save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2; - } else - save->fp_gen_cntl |= RADEON_FP_SEL_CRTC2; - } - -} - -static void RADEONInitFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, - DisplayModePtr mode, BOOL IsPrimary) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - if (pScrn->rgbBits == 8) - save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl | - RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */ - else - save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl & - ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */ - - if (IsPrimary) { - if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) { - save->fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | - RADEON_FP2_DVO_EN | - RADEON_FP2_DVO_RATE_SEL_SDR); - if (mode->Flags & RADEON_USE_RMX) - save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX; - } else { - save->fp2_gen_cntl &= ~(RADEON_FP2_SRC_SEL_CRTC2 | - RADEON_FP2_DVO_RATE_SEL_SDR); - } - /*save->fp2_gen_cntl |= ( RADEON_FP2_ON | - RADEON_FP2_BLANK_EN | - RADEON_FP2_DVO_EN);*/ - } else { - if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) { - save->fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | - RADEON_FP2_DVO_RATE_SEL_SDR); - save->fp2_gen_cntl |= (R200_FP2_SOURCE_SEL_CRTC2 /*| - RADEON_FP2_PANEL_FORMAT | - RADEON_FP2_BLANK_EN | - RADEON_FP2_ON | - RADEON_FP2_DVO_EN*/); - } else { - save->fp2_gen_cntl &= ~(RADEON_FP2_DVO_RATE_SEL_SDR); - save->fp2_gen_cntl |= (RADEON_FP2_SRC_SEL_CRTC2 /*| - RADEON_FP2_PANEL_FORMAT | - RADEON_FP2_BLANK_EN | - RADEON_FP2_ON | - RADEON_FP2_DVO_EN*/); - } + /* need to make sure we don't enable a crtc by accident or we may get a hang */ + if (info->crtc2_on) { + crtc = xf86_config->crtc[1]; + crtc->funcs->dpms(crtc, DPMSModeOn); } - -} - -static void RADEONInitLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, - DisplayModePtr mode, BOOL IsPrimary) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); -/* XXX saved but never used??? */ - if (IsPrimary) - save->lvds_gen_cntl = info->SavedReg.lvds_gen_cntl & - ~RADEON_LVDS_SEL_CRTC2; - else - save->lvds_gen_cntl = info->SavedReg.lvds_gen_cntl | - RADEON_LVDS_SEL_CRTC2; - -} - -static void RADEONInitRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, - DisplayModePtr mode) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - int xres = mode->HDisplay; - int yres = mode->VDisplay; - float Hratio, Vratio; - - - if (info->PanelXRes == 0 || info->PanelYRes == 0) { - Hratio = 1.0; - Vratio = 1.0; - } else { - if (xres > info->PanelXRes) xres = info->PanelXRes; - if (yres > info->PanelYRes) yres = info->PanelYRes; - - Hratio = (float)xres/(float)info->PanelXRes; - Vratio = (float)yres/(float)info->PanelYRes; - } - - save->fp_vert_stretch = info->SavedReg.fp_vert_stretch & - RADEON_VERT_STRETCH_RESERVED; - save->fp_horz_stretch = info->SavedReg.fp_horz_stretch & - (RADEON_HORZ_FP_LOOP_STRETCH | - RADEON_HORZ_AUTO_RATIO_INC); - - if (Hratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) { - save->fp_horz_stretch |= ((xres/8-1)<<16); - } else { - save->fp_horz_stretch |= ((((unsigned long)(Hratio * RADEON_HORZ_STRETCH_RATIO_MAX + - 0.5)) & RADEON_HORZ_STRETCH_RATIO_MASK) | - RADEON_HORZ_STRETCH_BLEND | - RADEON_HORZ_STRETCH_ENABLE | - ((info->PanelXRes/8-1)<<16)); + if (info->crtc_on) { + crtc = xf86_config->crtc[0]; + crtc->funcs->dpms(crtc, DPMSModeOn); } - - if (Vratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) { - save->fp_vert_stretch |= ((yres-1)<<12); - } else { - save->fp_vert_stretch |= ((((unsigned long)(Vratio * RADEON_VERT_STRETCH_RATIO_MAX + - 0.5)) & RADEON_VERT_STRETCH_RATIO_MASK) | - RADEON_VERT_STRETCH_ENABLE | - RADEON_VERT_STRETCH_BLEND | - ((info->PanelYRes-1)<<12)); - } - -} - -static void RADEONInitDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, - DisplayModePtr mode, BOOL IsPrimary) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - - if (IsPrimary) { - if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) { - save->disp_output_cntl = info->SavedReg.disp_output_cntl & - ~RADEON_DISP_DAC_SOURCE_MASK; - } else { - save->dac2_cntl = info->SavedReg.dac2_cntl & ~(RADEON_DAC2_DAC_CLK_SEL); - } - save->dac_cntl = (RADEON_DAC_MASK_ALL - | RADEON_DAC_VGA_ADR_EN - | (info->dac6bits ? 0 : RADEON_DAC_8BIT_EN)); - - } else { - if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) { - save->disp_output_cntl = info->SavedReg.disp_output_cntl & - ~RADEON_DISP_DAC_SOURCE_MASK; - save->disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2; - } else { - save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC_CLK_SEL; - } - } -} - -static void RADEONInitDAC2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, - DisplayModePtr mode, BOOL IsPrimary) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - - /*0x0028023;*/ - RADEONInitTvDacCntl(pScrn, save); - - if (IsPrimary) { - /*save->crtc2_gen_cntl = info->SavedReg.crtc2_gen_cntl | RADEON_CRTC2_CRT2_ON;*/ - save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL; - if (IS_R300_VARIANT) { - save->disp_output_cntl = info->SavedReg.disp_output_cntl & - ~RADEON_DISP_TVDAC_SOURCE_MASK; - save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC; - } else if (info->ChipFamily == CHIP_FAMILY_R200) { - save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl & - ~(R200_FP2_SOURCE_SEL_MASK | - RADEON_FP2_DVO_RATE_SEL_SDR); - /*save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl | - (RADEON_FP2_ON | - RADEON_FP2_BLANK_EN | - RADEON_FP2_DVO_EN);*/ - } else { - save->disp_hw_debug = info->SavedReg.disp_hw_debug | RADEON_CRT2_DISP1_SEL; - } - } else { - save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL; - if (IS_R300_VARIANT) { - save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL; - save->disp_output_cntl = info->SavedReg.disp_output_cntl & - ~RADEON_DISP_TVDAC_SOURCE_MASK; - save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2; - } else if (info->ChipFamily == CHIP_FAMILY_R200) { - save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl & - ~(R200_FP2_SOURCE_SEL_MASK | - RADEON_FP2_DVO_RATE_SEL_SDR); - save->fp2_gen_cntl |= (R200_FP2_SOURCE_SEL_CRTC2 /*| - RADEON_FP2_BLANK_EN | - RADEON_FP2_ON | - RADEON_FP2_DVO_EN*/); - /*save->fp_h2_sync_strt_wid = save->crtc2_h_sync_strt_wid; - save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;*/ - } else { - save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL; - save->disp_hw_debug = info->SavedReg.disp_hw_debug & - ~RADEON_CRT2_DISP1_SEL; - } - } -} - -static void RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, DisplayModePtr mode, RADEONConnector *pPort, Bool IsPrimary) -{ - if (pPort->MonType == MT_CRT) { - if (pPort->DACType == DAC_PRIMARY) { - RADEONInitDACRegisters(pScrn, save, mode, IsPrimary); - } else { - RADEONInitDAC2Registers(pScrn, save, mode, IsPrimary); - } - } else if (pPort->MonType == MT_LCD) { - if (IsPrimary) - RADEONInitRMXRegisters(pScrn, save, mode); - RADEONInitLVDSRegisters(pScrn, save, mode, IsPrimary); - } else if (pPort->MonType == MT_DFP) { - if (IsPrimary) - RADEONInitRMXRegisters(pScrn, save, mode); - if (pPort->TMDSType == TMDS_INT) { - RADEONInitFPRegisters(pScrn, save, mode, IsPrimary); - } else { - RADEONInitFP2Registers(pScrn, save, mode, IsPrimary); - } - } -} - -/* Define CRTC registers for requested video mode */ -static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, - DisplayModePtr mode, RADEONInfoPtr info) -{ - int format; - int hsync_start; - int hsync_wid; - int vsync_wid; - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - - pRADEONEnt->Controller[0]->IsUsed = TRUE; - pRADEONEnt->Controller[0]->IsActive = TRUE; - pRADEONEnt->Controller[0]->pCurMode = mode; - - switch (info->CurrentLayout.pixel_code) { - case 4: format = 1; break; - case 8: format = 2; break; - case 15: format = 3; break; /* 555 */ - case 16: format = 4; break; /* 565 */ - case 24: format = 5; break; /* RGB */ - case 32: format = 6; break; /* xRGB */ - default: - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Unsupported pixel depth (%d)\n", - info->CurrentLayout.bitsPerPixel); - return FALSE; - } - - save->bios_4_scratch = info->SavedReg.bios_4_scratch; - save->crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN - | RADEON_CRTC_EN - | (format << 8) - | ((mode->Flags & V_DBLSCAN) - ? RADEON_CRTC_DBL_SCAN_EN - : 0) - | ((mode->Flags & V_CSYNC) - ? RADEON_CRTC_CSYNC_EN - : 0) - | ((mode->Flags & V_INTERLACE) - ? RADEON_CRTC_INTERLACE_EN - : 0)); - - save->crtc_ext_cntl |= (RADEON_CRTC_CRT_ON | - RADEON_CRTC_VSYNC_DIS | - RADEON_CRTC_HSYNC_DIS | - RADEON_CRTC_DISPLAY_DIS); - - save->surface_cntl = 0; - save->disp_merge_cntl = info->SavedReg.disp_merge_cntl; - save->disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN; - -#if X_BYTE_ORDER == X_BIG_ENDIAN - /* We must set both apertures as they can be both used to map the entire - * video memory. -BenH. - */ - switch (pScrn->bitsPerPixel) { - case 16: - save->surface_cntl |= RADEON_NONSURF_AP0_SWP_16BPP; - save->surface_cntl |= RADEON_NONSURF_AP1_SWP_16BPP; - break; - - case 32: - save->surface_cntl |= RADEON_NONSURF_AP0_SWP_32BPP; - save->surface_cntl |= RADEON_NONSURF_AP1_SWP_32BPP; - break; - } -#endif - - save->crtc_more_cntl = 0; - if ((info->ChipFamily == CHIP_FAMILY_RS100) || - (info->ChipFamily == CHIP_FAMILY_RS200)) { - /* This is to workaround the asic bug for RMX, some versions - of BIOS dosen't have this register initialized correctly. - */ - save->crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN; - } - - if (mode->Flags & RADEON_USE_RMX) { - mode->CrtcHTotal = mode->CrtcHDisplay + info->HBlank; - mode->CrtcHSyncStart = mode->CrtcHDisplay + info->HOverPlus; - mode->CrtcHSyncEnd = mode->CrtcHSyncStart + info->HSyncWidth; - mode->CrtcVTotal = mode->CrtcVDisplay + info->VBlank; - mode->CrtcVSyncStart = mode->CrtcVDisplay + info->VOverPlus; - mode->CrtcVSyncEnd = mode->CrtcVSyncStart + info->VSyncWidth; - mode->Clock = info->DotClock; - mode->Flags = info->Flags | RADEON_USE_RMX; - } - - - - save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0x3ff) - | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff) - << 16)); - - 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) - | ((mode->Flags & V_NHSYNC) - ? RADEON_CRTC_H_SYNC_POL - : 0)); - - /* This works for double scan mode. */ - save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff) - | ((mode->CrtcVDisplay - 1) << 16)); - - 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) - | ((mode->Flags & V_NVSYNC) - ? RADEON_CRTC_V_SYNC_POL - : 0)); - - save->crtc_offset = pScrn->fbOffset; - if (info->tilingEnabled) { - if (IS_R300_VARIANT) - save->crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN | - R300_CRTC_MICRO_TILE_BUFFER_DIS | - R300_CRTC_MACRO_TILE_EN); - else - save->crtc_offset_cntl |= RADEON_CRTC_TILE_EN; - } - else { - if (IS_R300_VARIANT) - save->crtc_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN | - R300_CRTC_MICRO_TILE_BUFFER_DIS | - R300_CRTC_MACRO_TILE_EN); - else - save->crtc_offset_cntl &= ~RADEON_CRTC_TILE_EN; - } - - save->crtc_pitch = (((pScrn->displayWidth * pScrn->bitsPerPixel) + - ((pScrn->bitsPerPixel * 8) -1)) / - (pScrn->bitsPerPixel * 8)); - save->crtc_pitch |= save->crtc_pitch << 16; - - save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid; - save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid; - save->fp_crtc_h_total_disp = save->crtc_h_total_disp; - save->fp_crtc_v_total_disp = save->crtc_v_total_disp; - - /* Set following registers for all cases first, if a DFP/LCD is connected on - internal TMDS/LVDS port, they will be set by RADEONInitFPRegister - */ - if (!info->IsSwitching) { - save->fp_gen_cntl = 0; - save->fp_vert_stretch = info->SavedReg.fp_vert_stretch & - RADEON_VERT_STRETCH_RESERVED; - save->fp_horz_stretch = info->SavedReg.fp_horz_stretch & - (RADEON_HORZ_FP_LOOP_STRETCH | - RADEON_HORZ_AUTO_RATIO_INC); - } - - /* get the output connected to this CRTC */ - RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[0], TRUE); - - if (info->IsDellServer) { - save->dac2_cntl = info->SavedReg.dac2_cntl; - save->tv_dac_cntl = info->SavedReg.tv_dac_cntl; - save->crtc2_gen_cntl = info->SavedReg.crtc2_gen_cntl; - save->disp_hw_debug = info->SavedReg.disp_hw_debug; - - save->dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL; - save->dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL; - - /* For CRT on DAC2, don't turn it on if BIOS didn't - enable it, even it's detected. - */ - save->disp_hw_debug |= RADEON_CRT2_DISP1_SEL; - save->tv_dac_cntl &= ~((1<<2) | (3<<8) | (7<<24) | (0xff<<16)); - save->tv_dac_cntl |= (0x03 | (2<<8) | (0x58<<16)); - } - - return TRUE; -} - -/* Define CRTC2 registers for requested video mode */ -static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, - DisplayModePtr mode, RADEONInfoPtr info) -{ - int format; - int hsync_start; - int hsync_wid; - int vsync_wid; - - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - RADEONInfoPtr info0 = NULL; - if (info->IsSecondary) - info0 = RADEONPTR(pRADEONEnt->pPrimaryScrn); - - pRADEONEnt->Controller[1]->IsUsed = TRUE; - pRADEONEnt->Controller[1]->IsActive = TRUE; - pRADEONEnt->Controller[1]->pCurMode = mode; - - switch (info->CurrentLayout.pixel_code) { - case 4: format = 1; break; - case 8: format = 2; break; - case 15: format = 3; break; /* 555 */ - case 16: format = 4; break; /* 565 */ - case 24: format = 5; break; /* RGB */ - case 32: format = 6; break; /* xRGB */ - default: - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Unsupported pixel depth (%d)\n", - info->CurrentLayout.bitsPerPixel); - return FALSE; - } - - save->crtc2_h_total_disp = - ((((mode->CrtcHTotal / 8) - 1) & 0x3ff) - | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff) << 16)); - - 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) - | ((mode->Flags & V_NHSYNC) - ? RADEON_CRTC_H_SYNC_POL - : 0)); - - /* This works for double scan mode. */ - save->crtc2_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff) - | ((mode->CrtcVDisplay - 1) << 16)); - - 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) - | ((mode->Flags & V_NVSYNC) - ? RADEON_CRTC2_V_SYNC_POL - : 0)); - - /* It seems all fancy options apart from pflip can be safely disabled - */ - save->crtc2_offset = pScrn->fbOffset; - save->crtc2_offset_cntl &= RADEON_CRTC_OFFSET_FLIP_CNTL; - if (info->tilingEnabled) { - if (IS_R300_VARIANT) - save->crtc2_offset_cntl |= (R300_CRTC_X_Y_MODE_EN | - R300_CRTC_MICRO_TILE_BUFFER_DIS | - R300_CRTC_MACRO_TILE_EN); - else - save->crtc2_offset_cntl |= RADEON_CRTC_TILE_EN; - } - else { - if (IS_R300_VARIANT) - save->crtc2_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN | - R300_CRTC_MICRO_TILE_BUFFER_DIS | - R300_CRTC_MACRO_TILE_EN); - else - save->crtc2_offset_cntl &= ~RADEON_CRTC_TILE_EN; - } - - save->crtc2_pitch = ((pScrn->displayWidth * pScrn->bitsPerPixel) + - ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8); - save->crtc2_pitch |= save->crtc2_pitch << 16; - - save->crtc2_gen_cntl = (RADEON_CRTC2_EN - | RADEON_CRTC2_CRT2_ON - | (format << 8) - | RADEON_CRTC2_VSYNC_DIS - | RADEON_CRTC2_HSYNC_DIS - | RADEON_CRTC2_DISP_DIS - | ((mode->Flags & V_DBLSCAN) - ? RADEON_CRTC2_DBL_SCAN_EN - : 0) - | ((mode->Flags & V_CSYNC) - ? RADEON_CRTC2_CSYNC_EN - : 0) - | ((mode->Flags & V_INTERLACE) - ? RADEON_CRTC2_INTERLACE_EN - : 0)); - - save->disp2_merge_cntl = info->SavedReg.disp2_merge_cntl; - save->disp2_merge_cntl &= ~(RADEON_DISP2_RGB_OFFSET_EN); - - save->fp_h2_sync_strt_wid = save->crtc2_h_sync_strt_wid; - save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid; - - /* get the output connected to this CRTC */ - RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[1], FALSE); - - /* We must set SURFACE_CNTL properly on the second screen too */ - save->surface_cntl = 0; -#if X_BYTE_ORDER == X_BIG_ENDIAN - /* We must set both apertures as they can be both used to map the entire - * video memory. -BenH. + /* to restore console mode, DAC registers should be set after every other registers are set, + * otherwise,we may get blank screen */ - switch (pScrn->bitsPerPixel) { - case 16: - save->surface_cntl |= RADEON_NONSURF_AP0_SWP_16BPP; - save->surface_cntl |= RADEON_NONSURF_AP1_SWP_16BPP; - break; + RADEONRestoreDACRegisters(pScrn, restore); - case 32: - save->surface_cntl |= RADEON_NONSURF_AP0_SWP_32BPP; - save->surface_cntl |= RADEON_NONSURF_AP1_SWP_32BPP; - break; - } +#if 0 + RADEONWaitForVerticalSync(pScrn); #endif - - if (info->ChipFamily == CHIP_FAMILY_RS400) { - save->rs480_unk_e30 = 0x105DC1CC; /* because I'm worth it */ - save->rs480_unk_e34 = 0x2749D000; /* AMD really should */ - save->rs480_unk_e38 = 0x29ca71dc; /* release docs */ - save->rs480_unk_e3c = 0x28FBC3AC; /* this is so a trade secret */ - } - - return TRUE; -} - - -/* Define PLL registers for requested video mode */ -static void RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONInfoPtr info, - RADEONSavePtr save, RADEONPLLPtr pll, - double dot_clock) -{ - unsigned long freq = dot_clock * 100; - - struct { - int divider; - int bitvalue; - } *post_div, post_divs[] = { - /* From RAGE 128 VR/RAGE 128 GL Register - * Reference Manual (Technical Reference - * Manual P/N RRG-G04100-C Rev. 0.04), page - * 3-17 (PLL_DIV_[3:0]). - */ - { 1, 0 }, /* VCLK_SRC */ - { 2, 1 }, /* VCLK_SRC/2 */ - { 4, 2 }, /* VCLK_SRC/4 */ - { 8, 3 }, /* VCLK_SRC/8 */ - { 3, 4 }, /* VCLK_SRC/3 */ - { 16, 5 }, /* VCLK_SRC/16 */ - { 6, 6 }, /* VCLK_SRC/6 */ - { 12, 7 }, /* VCLK_SRC/12 */ - { 0, 0 } - }; - - if (info->UseBiosDividers) { - save->ppll_ref_div = info->RefDivider; - save->ppll_div_3 = info->FeedbackDivider | (info->PostDivider << 16); - save->htotal_cntl = 0; - return; - } - - if (freq > pll->max_pll_freq) freq = pll->max_pll_freq; - if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12; - - for (post_div = &post_divs[0]; post_div->divider; ++post_div) { - save->pll_output_freq = post_div->divider * freq; - - if (save->pll_output_freq >= pll->min_pll_freq - && save->pll_output_freq <= pll->max_pll_freq) break; - } - - if (!post_div->divider) { - save->pll_output_freq = freq; - post_div = &post_divs[0]; - } - - save->dot_clock_freq = freq; - save->feedback_div = RADEONDiv(pll->reference_div - * save->pll_output_freq, - pll->reference_freq); - save->post_div = post_div->divider; - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, - "dc=%ld, of=%ld, fd=%d, pd=%d\n", - save->dot_clock_freq, - save->pll_output_freq, - save->feedback_div, - save->post_div); - - save->ppll_ref_div = pll->reference_div; - save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16)); - save->htotal_cntl = 0; - - save->vclk_cntl = (info->SavedReg.vclk_cntl & - ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK; - -} - -/* Define PLL2 registers for requested video mode */ -static void RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, - RADEONPLLPtr pll, double dot_clock, - int no_odd_postdiv) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - unsigned long freq = dot_clock * 100; - - struct { - int divider; - int bitvalue; - } *post_div, post_divs[] = { - /* From RAGE 128 VR/RAGE 128 GL Register - * Reference Manual (Technical Reference - * Manual P/N RRG-G04100-C Rev. 0.04), page - * 3-17 (PLL_DIV_[3:0]). - */ - { 1, 0 }, /* VCLK_SRC */ - { 2, 1 }, /* VCLK_SRC/2 */ - { 4, 2 }, /* VCLK_SRC/4 */ - { 8, 3 }, /* VCLK_SRC/8 */ - { 3, 4 }, /* VCLK_SRC/3 */ - { 6, 6 }, /* VCLK_SRC/6 */ - { 12, 7 }, /* VCLK_SRC/12 */ - { 0, 0 } - }; - - if (freq > pll->max_pll_freq) freq = pll->max_pll_freq; - if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12; - - for (post_div = &post_divs[0]; post_div->divider; ++post_div) { - /* Odd post divider value don't work properly on the second digital - * output - */ - if (no_odd_postdiv && (post_div->divider & 1)) - continue; - save->pll_output_freq_2 = post_div->divider * freq; - if (save->pll_output_freq_2 >= pll->min_pll_freq - && save->pll_output_freq_2 <= pll->max_pll_freq) break; - } - - if (!post_div->divider) { - save->pll_output_freq_2 = freq; - post_div = &post_divs[0]; - } - - save->dot_clock_freq_2 = freq; - save->feedback_div_2 = RADEONDiv(pll->reference_div - * save->pll_output_freq_2, - pll->reference_freq); - save->post_div_2 = post_div->divider; - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, - "dc=%ld, of=%ld, fd=%d, pd=%d\n", - save->dot_clock_freq_2, - save->pll_output_freq_2, - save->feedback_div_2, - save->post_div_2); - - save->p2pll_ref_div = pll->reference_div; - save->p2pll_div_0 = (save->feedback_div_2 | - (post_div->bitvalue << 16)); - save->htotal_cntl2 = 0; - - save->pixclks_cntl = ((info->SavedReg.pixclks_cntl & - ~(RADEON_PIX2CLK_SRC_SEL_MASK)) | - RADEON_PIX2CLK_SRC_SEL_P2PLLCLK); - } #if 0 @@ -6391,169 +5555,6 @@ static void RADEONInitPalette(RADEONSavePtr save) } #endif -/* Define registers for a requested video mode */ -static Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1, - DisplayModePtr crtc2, int crtc_mask, - RADEONSavePtr save) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - double dot_clock; - RADEONInfoPtr info0 = NULL; - ScrnInfoPtr pScrn0 = NULL; - - if (crtc1 && (crtc_mask & 1)) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, - "%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)%s%s%s%s%s%s%s\n", - crtc1->name, - crtc1->Clock/1000.0, - - crtc1->HDisplay, - crtc1->HSyncStart, - crtc1->HSyncEnd, - crtc1->HTotal, - - crtc1->VDisplay, - crtc1->VSyncStart, - crtc1->VSyncEnd, - crtc1->VTotal, - pScrn->depth, - pScrn->bitsPerPixel, - (crtc1->Flags & V_DBLSCAN) ? " D" : "", - (crtc1->Flags & V_CSYNC) ? " C" : "", - (crtc1->Flags & V_INTERLACE) ? " I" : "", - (crtc1->Flags & V_PHSYNC) ? " +H" : "", - (crtc1->Flags & V_NHSYNC) ? " -H" : "", - (crtc1->Flags & V_PVSYNC) ? " +V" : "", - (crtc1->Flags & V_NVSYNC) ? " -V" : ""); - } - if (crtc2 && (crtc_mask & 2)) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, - "%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)%s%s%s%s%s%s%s\n", - crtc2->name, - crtc2->Clock/1000.0, - - crtc2->CrtcHDisplay, - crtc2->CrtcHSyncStart, - crtc2->CrtcHSyncEnd, - crtc2->CrtcHTotal, - - crtc2->CrtcVDisplay, - crtc2->CrtcVSyncStart, - crtc2->CrtcVSyncEnd, - crtc2->CrtcVTotal, - pScrn->depth, - pScrn->bitsPerPixel, - (crtc2->Flags & V_DBLSCAN) ? " D" : "", - (crtc2->Flags & V_CSYNC) ? " C" : "", - (crtc2->Flags & V_INTERLACE) ? " I" : "", - (crtc2->Flags & V_PHSYNC) ? " +H" : "", - (crtc2->Flags & V_NHSYNC) ? " -H" : "", - (crtc2->Flags & V_PVSYNC) ? " +V" : "", - (crtc2->Flags & V_NVSYNC) ? " -V" : ""); - } - - if (crtc1 && (crtc_mask & 1)) - info->Flags = crtc1->Flags; - - RADEONInitMemMapRegisters(pScrn, save, info); - RADEONInitCommonRegisters(save, info); - - switch(crtc_mask) { - case 1: - if (!RADEONInitCrtcRegisters(pScrn, save, crtc1, info)) - return FALSE; - dot_clock = crtc1->Clock/1000.0; - if (dot_clock) { - RADEONInitPLLRegisters(pScrn, info, save, &info->pll, dot_clock); - } else { - save->ppll_ref_div = info->SavedReg.ppll_ref_div; - save->ppll_div_3 = info->SavedReg.ppll_div_3; - save->htotal_cntl = info->SavedReg.htotal_cntl; - } - if (pRADEONEnt->HasSecondary) { - pScrn0 = pRADEONEnt->pSecondaryScrn; - info0 = RADEONPTR(pScrn0); - /* carry over to secondary screen */ - memcpy(&info0->ModeReg, save, sizeof(RADEONSaveRec)); - } - - /* Not used for now: */ - /* if (!info->PaletteSavedOnVT) RADEONInitPalette(save); */ - break; - case 2: - pScrn0 = pRADEONEnt->pPrimaryScrn; - info0 = RADEONPTR(pScrn0); - dot_clock = crtc2->Clock/1000.0; - if (!RADEONInitCrtc2Registers(pScrn, save, crtc2, info)) - return FALSE; - RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, info->DisplayType != MT_CRT); - /* Make sure primary has the same copy */ - memcpy(&info0->ModeReg, save, sizeof(RADEONSaveRec)); - break; - case 3: - if (!RADEONInitCrtcRegisters(pScrn, save, - crtc1, info)) - return FALSE; - dot_clock = crtc1->Clock / 1000.0; - if (dot_clock) { - RADEONInitPLLRegisters(pScrn, info, save, &info->pll, dot_clock); - } else { - save->ppll_ref_div = info->SavedReg.ppll_ref_div; - save->ppll_div_3 = info->SavedReg.ppll_div_3; - save->htotal_cntl = info->SavedReg.htotal_cntl; - } - RADEONInitCrtc2Registers(pScrn, save, crtc2, info); - dot_clock = crtc2->Clock / 1000.0; - RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, info->MergeType != MT_CRT); - break; - default: - return FALSE; - } - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, - "RADEONInit returns %p\n", save); - return TRUE; -} - -static Bool RADEONInit(ScrnInfoPtr pScrn, DisplayModePtr mode, - RADEONSavePtr save) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - - if (info->IsSecondary) { - return RADEONInit2(pScrn, NULL, mode, 2, save); - } else if (info->MergedFB) { - return RADEONInit2(pScrn, ((RADEONMergedDisplayModePtr)mode->Private)->CRT1, - ((RADEONMergedDisplayModePtr)mode->Private)->CRT2, 3, save); - } else { - return RADEONInit2(pScrn, mode, NULL, 1, save); - } -} - -/* Initialize a new mode */ -static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, - "RADEONModeInit()\n"); - - if (!RADEONInit(pScrn, mode, &info->ModeReg)) return FALSE; - - pScrn->vtSema = TRUE; - RADEONBlank(pScrn, TRUE); - RADEONRestoreMode(pScrn, &info->ModeReg); - RADEONBlank(pScrn, FALSE); - - info->CurrentLayout.mode = mode; - - if (info->DispPriority) - RADEONInitDispBandwidth(pScrn); - - return TRUE; -} - static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; @@ -6567,9 +5568,9 @@ static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode) if ((pScrn != NULL) && pScrn->vtSema) { if (unblank) - RADEONBlank(pScrn, FALSE); + RADEONUnblank(pScrn); else - RADEONBlank(pScrn, TRUE); + RADEONBlank(pScrn); } return TRUE; } @@ -6613,17 +5614,7 @@ Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) "RADEONSwitchMode() !n"); if (info->allowColorTiling) { - if (info->MergedFB) { - if ((((RADEONMergedDisplayModePtr)mode->Private)->CRT1->Flags & - (V_DBLSCAN | V_INTERLACE)) || - (((RADEONMergedDisplayModePtr)mode->Private)->CRT2->Flags & - (V_DBLSCAN | V_INTERLACE))) - info->tilingEnabled = FALSE; - else info->tilingEnabled = TRUE; - } - else { - info->tilingEnabled = (mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE; - } + info->tilingEnabled = (mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE; #ifdef XF86DRI if (info->directRenderingEnabled && (info->tilingEnabled != tilingOld)) { RADEONSAREAPrivPtr pSAREAPriv; @@ -6648,9 +5639,7 @@ Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) RADEONRestoreFBDevRegisters(pScrn, &info->ModeReg); } else { - info->IsSwitching = TRUE; - ret = RADEONModeInit(xf86Screens[scrnIndex], mode); - info->IsSwitching = FALSE; + ret = xf86SetSingleMode (pScrn, mode, RR_Rotate_0); } if (info->tilingEnabled != tilingOld) { @@ -6676,10 +5665,7 @@ Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) /* Since RandR (indirectly) uses SwitchMode(), we need to * update our Xinerama info here, too, in case of resizing */ - if (info->MergedFB) { - RADEONMergedFBResetDpi(pScrn, FALSE); - RADEONUpdateXineramaScreenInfo(pScrn); - } else if(info->constantDPI) { + if(info->constantDPI) { RADEONResetDPI(pScrn, FALSE); } @@ -6717,11 +5703,11 @@ ModeStatus RADEONValidMode(int scrnIndex, DisplayModePtr mode, /* Adjust viewport into virtual desktop such that (0,0) in viewport * space is (x,y) in virtual space. */ -void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int clone) +void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, Bool crtc2) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - int reg, Base, regcntl, crtcoffsetcntl, xytilereg, crtcxytile = 0; + int Base, reg, regcntl, crtcoffsetcntl, xytilereg, crtcxytile = 0; #ifdef XF86DRI RADEONSAREAPrivPtr pSAREAPriv; XF86DRISAREAPtr pSAREA; @@ -6749,12 +5735,12 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int clone) pick up the new offset value at the end of each scanline, but the new offset_cntl value only after a vsync. We'd probably need to wait (in drm) for vsync and only then update OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */ - if (clone || info->IsSecondary) { - reg = RADEON_CRTC2_OFFSET; + if (crtc2) { + reg = RADEON_CRTC2_OFFSET; regcntl = RADEON_CRTC2_OFFSET_CNTL; xytilereg = R300_CRTC2_TILE_X0_Y0; } else { - reg = RADEON_CRTC_OFFSET; + reg = RADEON_CRTC_OFFSET; regcntl = RADEON_CRTC_OFFSET_CNTL; xytilereg = R300_CRTC_TILE_X0_Y0; } @@ -6806,7 +5792,7 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int clone) /* can't get at sarea in a semi-sane way? */ pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec)); - if (clone || info->IsSecondary) { + if (crtc2) { pSAREAPriv->crtc2_base = Base; } else { @@ -6824,20 +5810,23 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int clone) } #endif - OUTREG(reg, Base); - if (IS_R300_VARIANT) { - OUTREG(xytilereg, crtcxytile); + OUTREG(xytilereg, crtcxytile); } else { - OUTREG(regcntl, crtcoffsetcntl); + OUTREG(regcntl, crtcoffsetcntl); } + OUTREG(reg, Base); } void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86OutputPtr output = config->output[config->compat_output]; + xf86CrtcPtr crtc = output->crtc; #ifdef XF86DRI if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0); @@ -6846,14 +5835,20 @@ void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags) if (info->accelOn) RADEON_SYNC(info, pScrn); - if(info->MergedFB) { - RADEONAdjustFrameMerged(scrnIndex, x, y, flags); - } else if (info->FBDev) { - fbdevHWAdjustFrame(scrnIndex, x, y, flags); - } else { - RADEONDoAdjustFrame(pScrn, x, y, FALSE); + if (crtc && crtc->enabled) { + if (info->FBDev) { + fbdevHWAdjustFrame(scrnIndex, crtc->desiredX + x, crtc->desiredY + y, flags); + } else { + if (crtc == pRADEONEnt->pCrtc[0]) + RADEONDoAdjustFrame(pScrn, crtc->desiredX + x, crtc->desiredY + y, FALSE); + else + RADEONDoAdjustFrame(pScrn, crtc->desiredX + x, crtc->desiredY + y, TRUE); + } + crtc->x = output->initial_x + x; + crtc->y = output->initial_y + y; } + #ifdef XF86DRI if (info->CPStarted && pScrn->pScreen) DRIUnlock(pScrn->pScreen); #endif @@ -6867,6 +5862,7 @@ Bool RADEONEnterVT(int scrnIndex, int flags) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "RADEONEnterVT\n"); @@ -6893,11 +5889,30 @@ Bool RADEONEnterVT(int scrnIndex, int flags) info->ModeReg.surface_cntl = INREG(RADEON_SURFACE_CNTL); RADEONRestoreFBDevRegisters(pScrn, &info->ModeReg); - } else - if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE; + } else { + int i; + + pScrn->vtSema = TRUE; + for (i = 0; i < xf86_config->num_crtc; i++) + { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + /* Mark that we'll need to re-set the mode for sure */ + memset(&crtc->mode, 0, sizeof(crtc->mode)); + if (!crtc->desiredMode.CrtcHDisplay) { + crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode); + crtc->desiredRotation = RR_Rotate_0; + crtc->desiredX = 0; + crtc->desiredY = 0; + } + + if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation, + crtc->desiredX, crtc->desiredY)) + return FALSE; - if (!info->IsSecondary) - RADEONRestoreSurfaces(pScrn, &info->ModeReg); + } + } + + RADEONRestoreSurfaces(pScrn, &info->ModeReg); #ifdef XF86DRI if (info->directRenderingEnabled) { if (info->cardType == CARD_PCIE && info->pKernelDRMVersion->version_minor >= 19 && info->FbSecureSize) @@ -6910,6 +5925,7 @@ Bool RADEONEnterVT(int scrnIndex, int flags) RADEONDRISetVBlankInterrupt (pScrn, TRUE); RADEONDRIResume(pScrn->pScreen); RADEONAdjustMemMapRegisters(pScrn, &info->ModeReg); + } #endif /* this will get XVideo going again, but only if XVideo was initialised @@ -6927,7 +5943,7 @@ Bool RADEONEnterVT(int scrnIndex, int flags) } #endif - pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + // pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); return TRUE; } @@ -7025,7 +6041,6 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen) #endif /* USE_XAA */ if (pScrn->vtSema) { - RADEONDisplayPowerManagementSet(pScrn, DPMSModeOn, 0); RADEONRestore(pScrn); } @@ -7083,40 +6098,6 @@ void RADEONFreeScreen(int scrnIndex, int flags) /* when server quits at PreInit, we don't need do this anymore*/ if (!info) return; - if(info->MergedFB) { - if(pScrn->modes) { - pScrn->currentMode = pScrn->modes; - do { - DisplayModePtr p = pScrn->currentMode->next; - if(pScrn->currentMode->Private) - xfree(pScrn->currentMode->Private); - xfree(pScrn->currentMode); - pScrn->currentMode = p; - } while(pScrn->currentMode != pScrn->modes); - } - pScrn->currentMode = info->CRT1CurrentMode; - pScrn->modes = info->CRT1Modes; - info->CRT1CurrentMode = NULL; - info->CRT1Modes = NULL; - - if(info->CRT2pScrn) { - if(info->CRT2pScrn->modes) { - while(info->CRT2pScrn->modes) - xf86DeleteMode(&info->CRT2pScrn->modes, info->CRT2pScrn->modes); - } - if(info->CRT2pScrn->monitor) { - if(info->CRT2pScrn->monitor->Modes) { - while(info->CRT2pScrn->monitor->Modes) - xf86DeleteMode(&info->CRT2pScrn->monitor->Modes, info->CRT2pScrn->monitor->Modes); - } - if(info->CRT2pScrn->monitor->DDC) xfree(info->CRT2pScrn->monitor->DDC); - xfree(info->CRT2pScrn->monitor); - } - xfree(info->CRT2pScrn); - info->CRT2pScrn = NULL; - } - } - #ifdef WITH_VGAHW if (info->VGAAccess && xf86LoaderCheckSymbol("vgaHWFreeHWRec")) vgaHWFreeHWRec(pScrn); @@ -7124,233 +6105,6 @@ void RADEONFreeScreen(int scrnIndex, int flags) RADEONFreeRec(pScrn); } -static void -RADEONGetMergedFBOptions(ScrnInfoPtr pScrn) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - char *strptr; - char *default_hsync = "28-33"; - char *default_vrefresh = "43-72"; - Bool val; - Bool default_range = FALSE; - static const char *mybadparm = "\"%s\" is is not a valid parameter for option \"%s\"\n"; - - if (info->FBDev == TRUE) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "MergedFB does not work with Option UseFBDev, MergedFB mode is disabled\n"); - info->MergedFB = FALSE; - return; - } - - /* collect MergedFB options */ - info->MergedFB = TRUE; - info->UseRADEONXinerama = TRUE; - info->CRT2IsScrn0 = FALSE; - info->CRT2Position = radeonClone; - info->MergedFBXDPI = info->MergedFBYDPI = 0; - info->CRT1XOffs = info->CRT1YOffs = info->CRT2XOffs = info->CRT2YOffs = 0; - info->NonRect = info->HaveNonRect = info->HaveOffsRegions = FALSE; - info->MBXNR1XMAX = info->MBXNR1YMAX = info->MBXNR2XMAX = info->MBXNR2YMAX = 65536; - info->MouseRestrictions = TRUE; - - if (info->MergeType == MT_NONE) { - info->MergedFB = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to detect secondary monitor, MergedFB/Clone mode disabled\n"); - } else if (!pRADEONEnt->PortInfo[1]->MonInfo) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to detect secondary monitor DDC, default HSync and VRefresh used\n"); - default_range = TRUE; - } - - if (xf86GetOptValBool(info->Options, OPTION_MERGEDFB, &val)) { - if (val) { - info->MergedFB = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "MergedFB mode forced on.\n"); - } else { - info->MergedFB = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "MergedFB mode forced off.\n"); - } - } - - /* Do some MergedFB mode initialisation */ - if(info->MergedFB) { - info->CRT2pScrn = xalloc(sizeof(ScrnInfoRec)); - if(!info->CRT2pScrn) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate memory for merged pScrn, MergedFB mode is disabled\n"); - info->MergedFB = FALSE; - } else { - memcpy(info->CRT2pScrn, pScrn, sizeof(ScrnInfoRec)); - } - } - if(info->MergedFB) { - int result, ival; - Bool valid = FALSE; - char *tempstr; - strptr = (char *)xf86GetOptValString(info->Options, OPTION_CRT2POS); - if (strptr) { - tempstr = xalloc(strlen(strptr) + 1); - result = sscanf(strptr, "%s %d", tempstr, &ival); - } else { /* Not specified - default is "Clone" */ - tempstr = NULL; - result = 0; - info->CRT2Position = radeonClone; - valid = TRUE; - } - if(result >= 1) { - if(!xf86NameCmp(tempstr,"LeftOf")) { - info->CRT2Position = radeonLeftOf; - valid = TRUE; - if(result == 2) { - if(ival < 0) info->CRT1YOffs = -ival; - else info->CRT2YOffs = ival; - } - info->CRT2IsScrn0 = TRUE; - } else if(!xf86NameCmp(tempstr,"RightOf")) { - info->CRT2Position = radeonRightOf; - valid = TRUE; - if(result == 2) { - if(ival < 0) info->CRT1YOffs = -ival; - else info->CRT2YOffs = ival; - } - info->CRT2IsScrn0 = FALSE; - } else if(!xf86NameCmp(tempstr,"Above")) { - info->CRT2Position = radeonAbove; - valid = TRUE; - if(result == 2) { - if(ival < 0) info->CRT1XOffs = -ival; - else info->CRT2XOffs = ival; - } - info->CRT2IsScrn0 = FALSE; - } else if(!xf86NameCmp(tempstr,"Below")) { - info->CRT2Position = radeonBelow; - valid = TRUE; - if(result == 2) { - if(ival < 0) info->CRT1XOffs = -ival; - else info->CRT2XOffs = ival; - } - info->CRT2IsScrn0 = TRUE; - } else if(!xf86NameCmp(tempstr,"Clone")) { - info->CRT2Position = radeonClone; - if(result == 1) valid = TRUE; - /*info->CRT2IsScrn0 = TRUE;*/ - } - } - if(!valid) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "\"%s\" is not a valid parameter for Option \"CRT2Position\"\n", strptr); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Valid parameters are \"RightOf\", \"LeftOf\", \"Above\", \"Below\", or \"Clone\"\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Except for \"Clone\", the parameter may be followed by an integer.\n"); - } - xfree(tempstr); - - strptr = (char *)xf86GetOptValString(info->Options, OPTION_METAMODES); - if(strptr) { - info->MetaModes = xalloc(strlen(strptr) + 1); - if(info->MetaModes) memcpy(info->MetaModes, strptr, strlen(strptr) + 1); - } - strptr = (char *)xf86GetOptValString(info->Options, OPTION_CRT2HSYNC); - if(strptr) { - info->CRT2HSync = xalloc(strlen(strptr) + 1); - if(info->CRT2HSync) memcpy(info->CRT2HSync, strptr, strlen(strptr) + 1); - } - strptr = (char *)xf86GetOptValString(info->Options, OPTION_CRT2VREFRESH); - if(strptr) { - info->CRT2VRefresh = xalloc(strlen(strptr) + 1); - if(info->CRT2VRefresh) memcpy(info->CRT2VRefresh, strptr, strlen(strptr) + 1); - } - - if(xf86GetOptValBool(info->Options, OPTION_RADEONXINERAMA, &val)) { - if (!val) - info->UseRADEONXinerama = FALSE; - } - if(info->UseRADEONXinerama) { - if(xf86GetOptValBool(info->Options, OPTION_CRT2ISSCRN0, &val)) { - if(val) info->CRT2IsScrn0 = TRUE; - else info->CRT2IsScrn0 = FALSE; - } - if(xf86GetOptValBool(info->Options, OPTION_MERGEDFBNONRECT, &val)) { - info->NonRect = val ? TRUE : FALSE; - } - if(xf86GetOptValBool(info->Options, OPTION_MERGEDFBMOUSER, &val)) { - info->MouseRestrictions = val ? TRUE : FALSE; - } - } - strptr = (char *)xf86GetOptValString(info->Options, OPTION_MERGEDDPI); - if(strptr) { - int val1 = 0, val2 = 0; - sscanf(strptr, "%d %d", &val1, &val2); - if(val1 && val2) { - info->MergedFBXDPI = val1; - info->MergedFBYDPI = val2; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mybadparm, strptr, "MergedDPI"); - } - } - } - - if(info->MergedFB) { - /* fill in monitor */ - info->CRT2pScrn->monitor = xcalloc(1, sizeof(MonRec)); - if(info->CRT2pScrn->monitor) { - DisplayModePtr tempm = NULL, currentm = NULL, newm = NULL; - memcpy(info->CRT2pScrn->monitor, pScrn->monitor, sizeof(MonRec)); - info->CRT2pScrn->monitor->DDC = NULL; - info->CRT2pScrn->monitor->Modes = NULL; - info->CRT2pScrn->monitor->id = "CRT2 Monitor"; - tempm = pScrn->monitor->Modes; - while(tempm) { - if(!(newm = xalloc(sizeof(DisplayModeRec)))) break; - memcpy(newm, tempm, sizeof(DisplayModeRec)); - if(!(newm->name = xalloc(strlen(tempm->name) + 1))) { - xfree(newm); - break; - } - strcpy(newm->name, tempm->name); - if(!info->CRT2pScrn->monitor->Modes) - info->CRT2pScrn->monitor->Modes = newm; - if(currentm) { - currentm->next = newm; - newm->prev = currentm; - } - currentm = newm; - tempm = tempm->next; - } - info->CRT2pScrn->monitor->Last = currentm; - - /* xf86SetDDCproperties(info->CRT2pScrn, pRADEONEnt->MonInfo2); */ - - info->CRT2pScrn->monitor->DDC = pRADEONEnt->PortInfo[1]->MonInfo; - - if (default_range) { - RADEONStrToRanges(info->CRT2pScrn->monitor->hsync, default_hsync, MAX_HSYNC); - RADEONStrToRanges(info->CRT2pScrn->monitor->vrefresh, default_vrefresh, MAX_VREFRESH); - } - if(info->CRT2HSync) { - info->CRT2pScrn->monitor->nHsync = - RADEONStrToRanges(info->CRT2pScrn->monitor->hsync, info->CRT2HSync, MAX_HSYNC); - } - if(info->CRT2VRefresh) { - info->CRT2pScrn->monitor->nVrefresh = - RADEONStrToRanges(info->CRT2pScrn->monitor->vrefresh, info->CRT2VRefresh, MAX_VREFRESH); - } - - } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate memory for CRT2 monitor, MergedFB mode disabled.\n"); - if(info->CRT2pScrn) xfree(info->CRT2pScrn); - info->CRT2pScrn = NULL; - info->MergedFB = FALSE; - } - } -} - static void RADEONForceSomeClocks(ScrnInfoPtr pScrn) { /* It appears from r300 and rv100 may need some clocks forced-on */ |