1fe5e51b7Smrg#ifdef HAVE_CONFIG_H 2fe5e51b7Smrg#include "config.h" 3fe5e51b7Smrg#endif 4fe5e51b7Smrg 5fe5e51b7Smrg/* All drivers should typically include these */ 6fe5e51b7Smrg#include "xf86.h" 7fe5e51b7Smrg#include "xf86_OSproc.h" 8fe5e51b7Smrg 9fe5e51b7Smrg/* Drivers that need to access the PCI config space directly need this */ 10fe5e51b7Smrg#include "xf86Pci.h" 11fe5e51b7Smrg 12fe5e51b7Smrg#include "mga_reg.h" 13fe5e51b7Smrg#include "mga.h" 14fe5e51b7Smrg 15fe5e51b7Smrg#define MNP_TABLE_SIZE 64 16fe5e51b7Smrg#define CLKSEL_MGA 0x0c 17fe5e51b7Smrg#define PLLLOCK 0x40 18fe5e51b7Smrg 19fe5e51b7Smrgstatic CARD32 G450ApplyPFactor(ScrnInfoPtr pScrn, CARD8 ucP, CARD32 *pulFIn) 20fe5e51b7Smrg{ 21fe5e51b7Smrg if(!(ucP & 0x40)) 22fe5e51b7Smrg { 23fe5e51b7Smrg *pulFIn = *pulFIn / (2L << (ucP & 3)); 24fe5e51b7Smrg } 25fe5e51b7Smrg 26fe5e51b7Smrg return TRUE; 27fe5e51b7Smrg} 28fe5e51b7Smrg 29fe5e51b7Smrg 30fe5e51b7Smrgstatic CARD32 G450RemovePFactor(ScrnInfoPtr pScrn, CARD8 ucP, CARD32 *pulFIn) 31fe5e51b7Smrg{ 32fe5e51b7Smrg if(!(ucP & 0x40)) 33fe5e51b7Smrg { 34fe5e51b7Smrg *pulFIn = *pulFIn * (2L << (ucP & 3)); 35fe5e51b7Smrg } 36fe5e51b7Smrg 37fe5e51b7Smrg return TRUE; 38fe5e51b7Smrg} 39fe5e51b7Smrg 40fe5e51b7Smrg 41fe5e51b7Smrgstatic CARD32 G450CalculVCO(ScrnInfoPtr pScrn, CARD32 ulMNP, CARD32 *pulF) 42fe5e51b7Smrg{ 43fe5e51b7Smrg CARD8 ucM, ucN; 44fe5e51b7Smrg 45fe5e51b7Smrg ucM = (CARD8)((ulMNP >> 16) & 0xff); 46fe5e51b7Smrg ucN = (CARD8)((ulMNP >> 8) & 0xff); 47fe5e51b7Smrg 48fe5e51b7Smrg *pulF = (27000 * (2 * (ucN + 2)) + ((ucM + 1) >> 1)) / (ucM + 1); 49fe5e51b7Smrg 50fe5e51b7Smrg return TRUE; 51fe5e51b7Smrg} 52fe5e51b7Smrg 53fe5e51b7Smrg 54fe5e51b7Smrgstatic CARD32 G450CalculDeltaFreq(ScrnInfoPtr pScrn, CARD32 ulF1, 55fe5e51b7Smrg CARD32 ulF2, CARD32 *pulDelta) 56fe5e51b7Smrg{ 57fe5e51b7Smrg if(ulF2 < ulF1) 58fe5e51b7Smrg { 59fe5e51b7Smrg *pulDelta = ((ulF1 - ulF2) * 1000) / ulF1; 60fe5e51b7Smrg } 61fe5e51b7Smrg else 62fe5e51b7Smrg { 63fe5e51b7Smrg *pulDelta = ((ulF2 - ulF1) * 1000) / ulF1; 64fe5e51b7Smrg } 65fe5e51b7Smrg 66fe5e51b7Smrg return TRUE; 67fe5e51b7Smrg} 68fe5e51b7Smrg 69fe5e51b7Smrg 70fe5e51b7Smrg 71fe5e51b7Smrg 72fe5e51b7Smrgstatic CARD32 G450FindNextPLLParam(ScrnInfoPtr pScrn, CARD32 ulFout, 73fe5e51b7Smrg CARD32 *pulPLLMNP) 74fe5e51b7Smrg{ 75fe5e51b7Smrg CARD8 ucM, ucN, ucP, ucS; 76fe5e51b7Smrg CARD32 ulVCO, ulVCOMin; 77fe5e51b7Smrg 78fe5e51b7Smrg ucM = (CARD8)((*pulPLLMNP >> 16) & 0xff); 79fe5e51b7Smrg ucN = (CARD8)((*pulPLLMNP >> 8) & 0xff); 80fe5e51b7Smrg ucP = (CARD8)(*pulPLLMNP & 0x43); 81fe5e51b7Smrg 82fe5e51b7Smrg ulVCOMin = 256000; 83fe5e51b7Smrg 84fe5e51b7Smrg if(ulVCOMin >= (255L * 8000)) 85fe5e51b7Smrg { 86fe5e51b7Smrg ulVCOMin = 230000; 87fe5e51b7Smrg } 88fe5e51b7Smrg 89fe5e51b7Smrg if((ucM == 9) && (ucP & 0x40)) 90fe5e51b7Smrg { 91fe5e51b7Smrg *pulPLLMNP = 0xffffffff; 92fe5e51b7Smrg } else if (ucM == 9) 93fe5e51b7Smrg { 94fe5e51b7Smrg if(ucP) 95fe5e51b7Smrg { 96fe5e51b7Smrg ucP--; 97fe5e51b7Smrg } 98fe5e51b7Smrg else 99fe5e51b7Smrg { 100fe5e51b7Smrg ucP = 0x40; 101fe5e51b7Smrg } 102fe5e51b7Smrg ucM = 0; 103fe5e51b7Smrg } 104fe5e51b7Smrg else 105fe5e51b7Smrg { 106fe5e51b7Smrg ucM++; 107fe5e51b7Smrg } 108fe5e51b7Smrg 109fe5e51b7Smrg ulVCO = ulFout; 110fe5e51b7Smrg 111fe5e51b7Smrg G450RemovePFactor(pScrn, ucP, &ulVCO); 112fe5e51b7Smrg 113fe5e51b7Smrg if(ulVCO < ulVCOMin) 114fe5e51b7Smrg { 115fe5e51b7Smrg *pulPLLMNP = 0xffffffff; 116fe5e51b7Smrg } 117fe5e51b7Smrg 118fe5e51b7Smrg if(*pulPLLMNP != 0xffffffff) 119fe5e51b7Smrg { 120fe5e51b7Smrg ucN = (CARD8)(((ulVCO * (ucM+1) + 27000)/(27000 * 2)) - 2); 121fe5e51b7Smrg 122fe5e51b7Smrg ucS = 5; 123fe5e51b7Smrg if(ulVCO < 1300000) ucS = 4; 124fe5e51b7Smrg if(ulVCO < 1100000) ucS = 3; 125fe5e51b7Smrg if(ulVCO < 900000) ucS = 2; 126fe5e51b7Smrg if(ulVCO < 700000) ucS = 1; 127fe5e51b7Smrg if(ulVCO < 550000) ucS = 0; 128fe5e51b7Smrg 129fe5e51b7Smrg ucP |= (CARD8)(ucS << 3); 130fe5e51b7Smrg 131fe5e51b7Smrg *pulPLLMNP &= 0xff000000; 132fe5e51b7Smrg *pulPLLMNP |= (CARD32)ucM << 16; 133fe5e51b7Smrg *pulPLLMNP |= (CARD32)ucN << 8; 134fe5e51b7Smrg *pulPLLMNP |= (CARD32)ucP; 135fe5e51b7Smrg 136fe5e51b7Smrg#ifdef DEBUG 13781f79626Smrg ErrorF("FINS_S: VCO = %d, S = %02X, *pulPLLMNP = %08X\n", (unsigned)ulVCO, (unsigned)ucS, (unsigned)*pulPLLMNP); 138fe5e51b7Smrg#endif 139fe5e51b7Smrg } 140fe5e51b7Smrg 141fe5e51b7Smrg return TRUE; 142fe5e51b7Smrg} 143fe5e51b7Smrg 144fe5e51b7Smrg 145fe5e51b7Smrgstatic CARD32 G450FindFirstPLLParam(ScrnInfoPtr pScrn, CARD32 ulFout, 146fe5e51b7Smrg CARD32 *pulPLLMNP) 147fe5e51b7Smrg{ 148fe5e51b7Smrg CARD8 ucP; 149fe5e51b7Smrg CARD32 ulVCO; 150fe5e51b7Smrg CARD32 ulVCOMax; 151fe5e51b7Smrg 152fe5e51b7Smrg /* Default value */ 153fe5e51b7Smrg ulVCOMax = 1300000; 154fe5e51b7Smrg 155fe5e51b7Smrg if(ulFout > (ulVCOMax/2)) 156fe5e51b7Smrg { 157fe5e51b7Smrg ucP = 0x40; 158fe5e51b7Smrg ulVCO = ulFout; 159fe5e51b7Smrg } 160fe5e51b7Smrg else 161fe5e51b7Smrg { 162fe5e51b7Smrg ucP = 3; 163fe5e51b7Smrg ulVCO = ulFout; 164fe5e51b7Smrg G450RemovePFactor(pScrn, ucP, &ulVCO); 165fe5e51b7Smrg while(ucP && (ulVCO > ulVCOMax)) 166fe5e51b7Smrg { 167fe5e51b7Smrg ucP--; 168fe5e51b7Smrg ulVCO = ulFout; 169fe5e51b7Smrg G450RemovePFactor(pScrn, ucP, &ulVCO); 170fe5e51b7Smrg } 171fe5e51b7Smrg } 172fe5e51b7Smrg 173fe5e51b7Smrg if(ulVCO > ulVCOMax) 174fe5e51b7Smrg { 175fe5e51b7Smrg *pulPLLMNP = 0xffffffff; 176fe5e51b7Smrg } 177fe5e51b7Smrg else 178fe5e51b7Smrg { 179fe5e51b7Smrg /* Pixel clock: 1 */ 180fe5e51b7Smrg *pulPLLMNP = (1 << 24) + 0xff0000 + ucP; 181fe5e51b7Smrg G450FindNextPLLParam(pScrn, ulFout, pulPLLMNP); 182fe5e51b7Smrg } 183fe5e51b7Smrg 184fe5e51b7Smrg return TRUE; 185fe5e51b7Smrg 186fe5e51b7Smrg} 187fe5e51b7Smrg 188fe5e51b7Smrg 189fe5e51b7Smrgstatic CARD32 G450WriteMNP(ScrnInfoPtr pScrn, CARD32 ulMNP) 190fe5e51b7Smrg{ 191fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 192fe5e51b7Smrg 193fe5e51b7Smrg if (!pMga->SecondCrtc) { 194fe5e51b7Smrg outMGAdac(MGA1064_PIX_PLLC_M, (CARD8)(ulMNP >> 16)); 195fe5e51b7Smrg outMGAdac(MGA1064_PIX_PLLC_N, (CARD8)(ulMNP >> 8)); 196fe5e51b7Smrg outMGAdac(MGA1064_PIX_PLLC_P, (CARD8) ulMNP); 197fe5e51b7Smrg } else { 198fe5e51b7Smrg outMGAdac(MGA1064_VID_PLL_M, (CARD8)(ulMNP >> 16)); 199fe5e51b7Smrg outMGAdac(MGA1064_VID_PLL_N, (CARD8)(ulMNP >> 8)); 200fe5e51b7Smrg outMGAdac(MGA1064_VID_PLL_P, (CARD8) ulMNP); 201fe5e51b7Smrg } 202fe5e51b7Smrg return TRUE; 203fe5e51b7Smrg} 204fe5e51b7Smrg 205fe5e51b7Smrgstatic CARD32 G450ReadMNP(ScrnInfoPtr pScrn) 206fe5e51b7Smrg{ 207fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 208fe5e51b7Smrg CARD32 ret = 0; 209fe5e51b7Smrg 210fe5e51b7Smrg if (!pMga->SecondCrtc) { 211fe5e51b7Smrg ret = (CARD8)inMGAdac(MGA1064_PIX_PLLC_M) << 16; 212fe5e51b7Smrg ret |= (CARD8)inMGAdac(MGA1064_PIX_PLLC_N) << 8; 213fe5e51b7Smrg ret |= (CARD8)inMGAdac(MGA1064_PIX_PLLC_P); 214fe5e51b7Smrg } else { 215fe5e51b7Smrg ret = (CARD8)inMGAdac(MGA1064_VID_PLL_M) << 16; 216fe5e51b7Smrg ret |= (CARD8)inMGAdac(MGA1064_VID_PLL_N) << 8; 217fe5e51b7Smrg ret |= (CARD8)inMGAdac(MGA1064_VID_PLL_P); 218fe5e51b7Smrg } 219fe5e51b7Smrg return ret; 220fe5e51b7Smrg} 221fe5e51b7Smrg 222fe5e51b7Smrg 223fe5e51b7Smrgstatic CARD32 G450CompareMNP(ScrnInfoPtr pScrn, CARD32 ulFout, CARD32 ulMNP1, 224fe5e51b7Smrg CARD32 ulMNP2, long *pulResult) 225fe5e51b7Smrg{ 226fe5e51b7Smrg CARD32 ulFreq, ulDelta1, ulDelta2; 227fe5e51b7Smrg 228fe5e51b7Smrg G450CalculVCO(pScrn, ulMNP1, &ulFreq); 229fe5e51b7Smrg G450ApplyPFactor(pScrn, (CARD8) ulMNP1, &ulFreq); 230fe5e51b7Smrg G450CalculDeltaFreq(pScrn, ulFout, ulFreq, &ulDelta1); 231fe5e51b7Smrg 232fe5e51b7Smrg G450CalculVCO(pScrn, ulMNP2, &ulFreq); 233fe5e51b7Smrg G450ApplyPFactor(pScrn, (CARD8) ulMNP2, &ulFreq); 234fe5e51b7Smrg G450CalculDeltaFreq(pScrn, ulFout, ulFreq, &ulDelta2); 235fe5e51b7Smrg 236fe5e51b7Smrg if(ulDelta1 < ulDelta2) 237fe5e51b7Smrg { 238fe5e51b7Smrg *pulResult = -1; 239fe5e51b7Smrg } 240fe5e51b7Smrg else if(ulDelta1 > ulDelta2) 241fe5e51b7Smrg { 242fe5e51b7Smrg *pulResult = 1; 243fe5e51b7Smrg } 244fe5e51b7Smrg else 245fe5e51b7Smrg { 246fe5e51b7Smrg *pulResult = 0; 247fe5e51b7Smrg } 248fe5e51b7Smrg 249fe5e51b7Smrg if((ulDelta1 <= 5) && (ulDelta2 <= 5)) 250fe5e51b7Smrg { 251fe5e51b7Smrg if((ulMNP1 & 0xff0000) < (ulMNP2 & 0xff0000)) 252fe5e51b7Smrg { 253fe5e51b7Smrg *pulResult = -1; 254fe5e51b7Smrg } 255fe5e51b7Smrg else if((ulMNP1 & 0xff0000) > (ulMNP2 & 0xff0000)) 256fe5e51b7Smrg { 257fe5e51b7Smrg *pulResult = 1; 258fe5e51b7Smrg } 259fe5e51b7Smrg } 260fe5e51b7Smrg 261fe5e51b7Smrg return TRUE; 262fe5e51b7Smrg} 263fe5e51b7Smrg 264fe5e51b7Smrg 265fe5e51b7Smrgstatic CARD32 G450IsPllLocked(ScrnInfoPtr pScrn, Bool *lpbLocked) 266fe5e51b7Smrg{ 267fe5e51b7Smrg CARD32 ulFallBackCounter, ulLockCount, ulCount; 268fe5e51b7Smrg CARD8 ucPLLStatus; 269fe5e51b7Smrg 270fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 271fe5e51b7Smrg 272fe5e51b7Smrg if (!pMga->SecondCrtc) 273fe5e51b7Smrg OUTREG8(0x3c00, MGA1064_PIX_PLL_STAT); 274fe5e51b7Smrg else 275fe5e51b7Smrg OUTREG8(0x3c00, MGA1064_VID_PLL_STAT); 276fe5e51b7Smrg 277fe5e51b7Smrg ulFallBackCounter = 0; 278fe5e51b7Smrg 279fe5e51b7Smrg do 280fe5e51b7Smrg { 281fe5e51b7Smrg ucPLLStatus = INREG8(0x3c0a); 282fe5e51b7Smrg ulFallBackCounter++; 283fe5e51b7Smrg } while(!(ucPLLStatus & PLLLOCK) && (ulFallBackCounter < 1000)); 284fe5e51b7Smrg 285fe5e51b7Smrg ulLockCount = 0; 286fe5e51b7Smrg if(ulFallBackCounter < 1000) 287fe5e51b7Smrg { 288fe5e51b7Smrg for(ulCount = 0; ulCount < 100; ulCount++) 289fe5e51b7Smrg { 290fe5e51b7Smrg ucPLLStatus = INREG8(0x3c0a); 291fe5e51b7Smrg if(ucPLLStatus & PLLLOCK) 292fe5e51b7Smrg { 293fe5e51b7Smrg ulLockCount++; 294fe5e51b7Smrg } 295fe5e51b7Smrg } 296fe5e51b7Smrg } 297fe5e51b7Smrg 298fe5e51b7Smrg *lpbLocked = ulLockCount >= 90; 299fe5e51b7Smrg 300fe5e51b7Smrg return TRUE; 301fe5e51b7Smrg} 302fe5e51b7Smrg 303fe5e51b7Smrg 304fe5e51b7Smrgdouble MGAG450SetPLLFreq(ScrnInfoPtr pScrn, long f_out) 305fe5e51b7Smrg{ 306fe5e51b7Smrg Bool bFoundValidPLL; 307fe5e51b7Smrg Bool bLocked; 308fe5e51b7Smrg CARD8 ucMisc, ucSIndex, ucSTable[4]; 309fe5e51b7Smrg CARD32 ulMaxIndex; 310fe5e51b7Smrg CARD32 ulMNP; 311fe5e51b7Smrg CARD32 ulMNPTable[MNP_TABLE_SIZE]; 312fe5e51b7Smrg CARD32 ulIndex; 313fe5e51b7Smrg CARD32 ulTryMNP; 314fe5e51b7Smrg long lCompareResult; 315fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 316fe5e51b7Smrg 317fe5e51b7Smrg#ifdef DEBUG 31881f79626Smrg xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Restoring PLLClk = %ld\n", f_out); 319fe5e51b7Smrg#endif 320fe5e51b7Smrg G450FindFirstPLLParam(pScrn, f_out, &ulMNP); 321fe5e51b7Smrg ulMNPTable[0] = ulMNP; 322fe5e51b7Smrg G450FindNextPLLParam(pScrn, f_out, &ulMNP); 323fe5e51b7Smrg ulMaxIndex = 1; 324fe5e51b7Smrg while(ulMNP != 0xffffffff) 325fe5e51b7Smrg { 326fe5e51b7Smrg int ulIndex; 327fe5e51b7Smrg Bool bSkipValue; 328fe5e51b7Smrg 329fe5e51b7Smrg bSkipValue = FALSE; 330fe5e51b7Smrg if(ulMaxIndex == MNP_TABLE_SIZE) 331fe5e51b7Smrg { 332fe5e51b7Smrg G450CompareMNP(pScrn, f_out, ulMNP, ulMNPTable[MNP_TABLE_SIZE - 1], 333fe5e51b7Smrg &lCompareResult); 334fe5e51b7Smrg 335fe5e51b7Smrg if(lCompareResult > 0) 336fe5e51b7Smrg { 337fe5e51b7Smrg bSkipValue = TRUE; 338fe5e51b7Smrg } 339fe5e51b7Smrg else 340fe5e51b7Smrg { 341fe5e51b7Smrg ulMaxIndex--; 342fe5e51b7Smrg } 343fe5e51b7Smrg } 344fe5e51b7Smrg 345fe5e51b7Smrg if(!bSkipValue) 346fe5e51b7Smrg { 347fe5e51b7Smrg for(ulIndex = ulMaxIndex; !bSkipValue && (ulIndex > 0); ulIndex--) 348fe5e51b7Smrg { 349fe5e51b7Smrg G450CompareMNP(pScrn, f_out, ulMNP, ulMNPTable[ulIndex - 1], 350fe5e51b7Smrg &lCompareResult); 351fe5e51b7Smrg 352fe5e51b7Smrg if(lCompareResult < 0) 353fe5e51b7Smrg { 354fe5e51b7Smrg ulMNPTable[ulIndex] = ulMNPTable[ulIndex - 1]; 355fe5e51b7Smrg } 356fe5e51b7Smrg else 357fe5e51b7Smrg { 358fe5e51b7Smrg break; 359fe5e51b7Smrg } 360fe5e51b7Smrg } 361fe5e51b7Smrg ulMNPTable[ulIndex] = ulMNP; 362fe5e51b7Smrg ulMaxIndex++; 363fe5e51b7Smrg } 364fe5e51b7Smrg 365fe5e51b7Smrg G450FindNextPLLParam(pScrn, f_out, &ulMNP); 366fe5e51b7Smrg } 367fe5e51b7Smrg 368fe5e51b7Smrg bFoundValidPLL = FALSE; 369fe5e51b7Smrg ulMNP = 0; 370fe5e51b7Smrg 371fe5e51b7Smrg /* For pixel pll */ 372fe5e51b7Smrg if (!pMga->SecondCrtc) { 373fe5e51b7Smrg ucMisc = INREG8(0x1FCC); 374fe5e51b7Smrg OUTREG8(0x1fc2, (CARD8)(ucMisc | CLKSEL_MGA)); 375fe5e51b7Smrg } 376fe5e51b7Smrg 377fe5e51b7Smrg for(ulIndex = 0; !bFoundValidPLL && (ulIndex < ulMaxIndex); ulIndex++) 378fe5e51b7Smrg { 379fe5e51b7Smrg ulTryMNP = ulMNPTable[ulIndex]; 380fe5e51b7Smrg 381fe5e51b7Smrg ucSTable[3] = 0xff; 382fe5e51b7Smrg ucSTable[2] = 0xff; 383fe5e51b7Smrg ucSTable[0] = (CARD8) (ulTryMNP & 0x38); 384fe5e51b7Smrg 385fe5e51b7Smrg if (ucSTable[0] != 0) { 386fe5e51b7Smrg ucSTable[1] = ucSTable[0] - 8; 387fe5e51b7Smrg if (ucSTable[0] != 0x38) { 388fe5e51b7Smrg ucSTable[2] = ucSTable[0] + 8; 389fe5e51b7Smrg } 390fe5e51b7Smrg } else { 391fe5e51b7Smrg ucSTable[1] = 8; 392fe5e51b7Smrg } 393fe5e51b7Smrg 394fe5e51b7Smrg for(ucSIndex = 0; !bFoundValidPLL && (ucSTable[ucSIndex] != 0xff); 395fe5e51b7Smrg ucSIndex++) { 396fe5e51b7Smrg ulTryMNP &= 0xffffffc7; 397fe5e51b7Smrg ulTryMNP |= (CARD32)ucSTable[ucSIndex]; 398fe5e51b7Smrg 399fe5e51b7Smrg bLocked = TRUE; 400fe5e51b7Smrg if((ulMNPTable[ulIndex] & 0xff00) < 0x300 || 401fe5e51b7Smrg (ulMNPTable[ulIndex] & 0xff00) > 0x7a00) 402fe5e51b7Smrg { 403fe5e51b7Smrg bLocked = FALSE; 404fe5e51b7Smrg } 405fe5e51b7Smrg 406fe5e51b7Smrg if(bLocked) 407fe5e51b7Smrg { 408fe5e51b7Smrg G450WriteMNP(pScrn, ulTryMNP - 0x300); 409fe5e51b7Smrg G450IsPllLocked(pScrn, &bLocked); 410fe5e51b7Smrg } 411fe5e51b7Smrg 412fe5e51b7Smrg if(bLocked) 413fe5e51b7Smrg { 414fe5e51b7Smrg G450WriteMNP(pScrn, ulTryMNP + 0x300); 415fe5e51b7Smrg G450IsPllLocked(pScrn, &bLocked); 416fe5e51b7Smrg } 417fe5e51b7Smrg 418fe5e51b7Smrg if(bLocked) 419fe5e51b7Smrg { 420fe5e51b7Smrg G450WriteMNP(pScrn, ulTryMNP - 0x200); 421fe5e51b7Smrg G450IsPllLocked(pScrn, &bLocked); 422fe5e51b7Smrg } 423fe5e51b7Smrg 424fe5e51b7Smrg if(bLocked) 425fe5e51b7Smrg { 426fe5e51b7Smrg G450WriteMNP(pScrn, ulTryMNP + 0x200); 427fe5e51b7Smrg G450IsPllLocked(pScrn, &bLocked); 428fe5e51b7Smrg } 429fe5e51b7Smrg 430fe5e51b7Smrg if(bLocked) 431fe5e51b7Smrg { 432fe5e51b7Smrg G450WriteMNP(pScrn, ulTryMNP - 0x100); 433fe5e51b7Smrg G450IsPllLocked(pScrn, &bLocked); 434fe5e51b7Smrg } 435fe5e51b7Smrg 436fe5e51b7Smrg if(bLocked) 437fe5e51b7Smrg { 438fe5e51b7Smrg G450WriteMNP(pScrn, ulTryMNP + 0x100); 439fe5e51b7Smrg G450IsPllLocked(pScrn, &bLocked); 440fe5e51b7Smrg } 441fe5e51b7Smrg 442fe5e51b7Smrg if(bLocked) 443fe5e51b7Smrg { 444fe5e51b7Smrg G450WriteMNP(pScrn, ulTryMNP); 445fe5e51b7Smrg G450IsPllLocked(pScrn, &bLocked); 446fe5e51b7Smrg } 447fe5e51b7Smrg else if(!ulMNP) 448fe5e51b7Smrg { 449fe5e51b7Smrg G450WriteMNP(pScrn, ulTryMNP); 450fe5e51b7Smrg G450IsPllLocked(pScrn, &bLocked); 451fe5e51b7Smrg if(bLocked) 452fe5e51b7Smrg { 453fe5e51b7Smrg ulMNP = ulMNPTable[ulIndex]; 454fe5e51b7Smrg } 455fe5e51b7Smrg bLocked = FALSE; 456fe5e51b7Smrg } 457fe5e51b7Smrg 458fe5e51b7Smrg if(bLocked) 459fe5e51b7Smrg { 460fe5e51b7Smrg bFoundValidPLL = TRUE; 461fe5e51b7Smrg } 462fe5e51b7Smrg } 463fe5e51b7Smrg } 464fe5e51b7Smrg 465fe5e51b7Smrg if(!bFoundValidPLL) 466fe5e51b7Smrg { 467fe5e51b7Smrg if(ulMNP) 468fe5e51b7Smrg { 469fe5e51b7Smrg G450WriteMNP(pScrn, ulMNP); 470fe5e51b7Smrg } 471fe5e51b7Smrg else 472fe5e51b7Smrg { 473fe5e51b7Smrg G450WriteMNP(pScrn, ulMNPTable[0]); 474fe5e51b7Smrg } 475fe5e51b7Smrg } 476fe5e51b7Smrg 477fe5e51b7Smrg return TRUE; 478fe5e51b7Smrg} 479fe5e51b7Smrg 480fe5e51b7Smrglong 481fe5e51b7SmrgMGAG450SavePLLFreq(ScrnInfoPtr pScrn) 482fe5e51b7Smrg{ 483fe5e51b7Smrg CARD32 ulMNP = G450ReadMNP(pScrn); 484fe5e51b7Smrg CARD8 ucP; 485fe5e51b7Smrg CARD32 freq; 486fe5e51b7Smrg 487fe5e51b7Smrg G450CalculVCO(pScrn, ulMNP, &freq); 488fe5e51b7Smrg ucP = (CARD8)(ulMNP & 0x03); 489fe5e51b7Smrg G450ApplyPFactor(pScrn, ucP, &freq); 490fe5e51b7Smrg 491fe5e51b7Smrg#ifdef DEBUG 49281f79626Smrg xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Saved PLLClk = %u\n", (unsigned)freq); 493fe5e51b7Smrg#endif 494fe5e51b7Smrg return freq; 495fe5e51b7Smrg} 496fe5e51b7Smrg 497fe5e51b7Smrg#ifdef DEBUG 498fe5e51b7Smrgvoid 499fe5e51b7SmrgMGAG450PrintPLL(ScrnInfoPtr pScrn) 500fe5e51b7Smrg{ 501fe5e51b7Smrg CARD32 ulMNP = G450ReadMNP(pScrn); 502fe5e51b7Smrg CARD8 ucP; 503fe5e51b7Smrg CARD32 freq; 504fe5e51b7Smrg 505fe5e51b7Smrg G450CalculVCO(pScrn, ulMNP, &freq); 506fe5e51b7Smrg ucP = (CARD8)(ulMNP & 0x03); 507fe5e51b7Smrg G450ApplyPFactor(pScrn, ucP, &freq); 508fe5e51b7Smrg 50981f79626Smrg xf86DrvMsg(pScrn->scrnIndex,X_INFO,"MGAGClock = %u -- MNP = 0x%x\n", 51081f79626Smrg (unsigned)freq, (unsigned)ulMNP); 511fe5e51b7Smrg} 512fe5e51b7Smrg#endif 513