1 /* program the DAC */ 2 /* Authors: 3 Mark Watson 2/2000, 4 Apsed 2002, 5 Rudolf Cornelissen 9/2002-4/2003 6 */ 7 8 #define MODULE_BIT 0x00010000 9 10 #include "mga_std.h" 11 12 static status_t milx_dac_pix_pll_find( 13 display_mode target,float * calc_pclk,uint8 * m_result,uint8 * n_result,uint8 * p_result); 14 static status_t g100_g400max_dac_pix_pll_find( 15 display_mode target,float * calc_pclk,uint8 * m_result,uint8 * n_result,uint8 * p_result, uint8 test); 16 static status_t g450_g550_dac_pix_pll_find( 17 display_mode target,float * calc_pclk,uint8 * m_result,uint8 * n_result,uint8 * p_result, uint8 test); 18 static status_t g100_g400max_dac_sys_pll_find( 19 float req_sclk,float * calc_sclk,uint8 * m_result,uint8 * n_result,uint8 * p_result); 20 static status_t g450_g550_dac_sys_pll_find( 21 float req_sclk,float * calc_sclk,uint8 * m_result,uint8 * n_result,uint8 * p_result); 22 23 /*set the mode, brightness is a value from 0->2 (where 1 is equivalent to direct)*/ 24 status_t gx00_dac_mode(int mode,float brightness) 25 { 26 uint8 *r,*g,*b,t[64]; 27 int i; 28 29 /*set colour arrays to point to space reserved in shared info*/ 30 r=si->color_data; 31 g=r+256; 32 b=g+256; 33 34 LOG(4,("DAC: Setting screen mode %d brightness %f\n", mode, brightness)); 35 /*init a basic palette for brightness specified*/ 36 for (i=0;i<256;i++) 37 { 38 int ri = i*brightness; // apsed 39 if (ri > 255) ri = 255; 40 r[i]=ri; 41 } 42 43 /*modify the palette for the specified mode (&validate mode)*/ 44 switch(mode) 45 { 46 case BPP8: 47 case BPP24:case BPP32: 48 for (i=0;i<256;i++) 49 { 50 b[i]=g[i]=r[i]; 51 } 52 break; 53 case BPP16: 54 for (i=0;i<64;i++) 55 { 56 t[i]=r[i<<2]; 57 } 58 for (i=0;i<64;i++) 59 { 60 g[i]=t[i]; 61 } 62 for (i=0;i<32;i++) 63 { 64 b[i]=r[i]=t[i<<1]; 65 } 66 break; 67 case BPP15: 68 for (i=0;i<32;i++) 69 { 70 t[i]=r[i<<3]; 71 } 72 for (i=0;i<32;i++) 73 { 74 g[i]=r[i]=b[i]=t[i]; 75 } 76 break; 77 case BPP32DIR: 78 break; 79 default: 80 LOG(8,("DAC: Invalid bit depth requested\n")); 81 return B_ERROR; 82 break; 83 } 84 85 if (gx00_dac_palette(r,g,b)!=B_OK) return B_ERROR; 86 87 /*set the mode - also sets VCLK dividor*/ 88 if (si->ps.card_type >= G100) 89 { 90 DXIW(MULCTRL, mode); 91 LOG(2,("DAC: mulctrl 0x%02x\n", DXIR(MULCTRL))); 92 } 93 else 94 { 95 /* MIL1/2 differs here (TVP3026DAC) */ 96 uint8 miscctrl = 0, latchctrl = 0; 97 uint8 tcolctrl = 0, mulctrl = 0; 98 99 /* set the mode */ 100 switch (mode) 101 { 102 /* presetting mulctrl for DAC pixelbus_width of 32 */ 103 case BPP8: 104 miscctrl=0x00; latchctrl=0x06; tcolctrl=0x80; mulctrl=0x4b; 105 break; 106 case BPP15: 107 miscctrl=0x20; latchctrl=0x06; tcolctrl=0x04; mulctrl=0x53; 108 break; 109 case BPP16: 110 miscctrl=0x20; latchctrl=0x06; tcolctrl=0x05; mulctrl=0x53; 111 break; 112 case BPP24: 113 miscctrl=0x20; latchctrl=0x06; tcolctrl=0x1f; mulctrl=0x5b; 114 break; 115 case BPP32: 116 miscctrl=0x20; latchctrl=0x07; tcolctrl=0x06; mulctrl=0x5b; 117 break; 118 case BPP32DIR: 119 miscctrl=0x20; latchctrl=0x07; tcolctrl=0x06; mulctrl=0x5b; 120 break; 121 } 122 123 /* modify mulctrl if DAC pixelbus_width is 64 */ 124 //fixme? do 32bit DACbus MIL 1/2 cards exist? if so, setup via si->ps... 125 if (true) mulctrl += 1; 126 127 DXIW(MISCCTRL, (DXIR(MISCCTRL) & 0x1d) | miscctrl); 128 DXIW(TVP_LATCHCTRL, latchctrl); 129 DXIW(TVP_TCOLCTRL, tcolctrl); 130 DXIW(MULCTRL, mulctrl); 131 132 LOG(2,("DAC: TVP miscctrl 0x%02x, TVP latchctrl 0x%02x\n", 133 DXIR(MISCCTRL), DXIR(TVP_LATCHCTRL))); 134 LOG(2,("DAC: TVP tcolctrl 0x%02x, TVP mulctrl 0x%02x\n", 135 DXIR(TVP_TCOLCTRL), DXIR(MULCTRL))); 136 } 137 138 /* disable palette RAM adressing mask */ 139 DACW(PIXRDMSK,0xff); 140 LOG(2,("DAC: pixrdmsk 0x%02x\n", DACR(PIXRDMSK))); 141 142 return B_OK; 143 } 144 145 /*program the DAC palette using the given r,g,b values*/ 146 status_t gx00_dac_palette(uint8 r[256],uint8 g[256],uint8 b[256]) 147 { 148 int i; 149 150 LOG(4,("DAC: setting palette\n")); 151 152 /* clear palwtadd before starting programming (LUT index) */ 153 DACW(PALWTADD,0); 154 155 /*loop through all 256 to program DAC*/ 156 for (i=0;i<256;i++) 157 { 158 DACW(PALDATA,r[i]); 159 DACW(PALDATA,g[i]); 160 DACW(PALDATA,b[i]); 161 } 162 if (DACR(PALWTADD)!=0) 163 { 164 LOG(8,("DAC: PALWTADD is not 0 after programming\n")); 165 return B_ERROR; 166 } 167 if (0) 168 {// apsed: reread LUT 169 uint8 R, G, B; 170 171 /* clear LUT color (modulo 3 counter) */ 172 DACW(PALRDADD,0); 173 for (i=0;i<256;i++) 174 { 175 R = DACR(PALDATA); 176 G = DACR(PALDATA); 177 B = DACR(PALDATA); 178 if ((r[i] != R) || (g[i] != G) || (b[i] != B)) 179 LOG(1,("DAC palette %d: w %x %x %x, r %x %x %x\n", i, r[i], g[i], b[i], R, G, B)); // apsed 180 } 181 } 182 183 return B_OK; 184 } 185 186 /*program the pixpll - frequency in kHz*/ 187 /*important notes: 188 * MISC(clksel) = select A,B,C PIXPLL (25,28,none) 189 * PIXPLLC is used - others should be kept as is 190 * VCLK is quadword clock (max is PIXPLL/2) - set according to DEPTH 191 * BESCLK,CRTC2 are not touched 192 */ 193 status_t gx00_dac_set_pix_pll(display_mode target) 194 { 195 uint8 m=0,n=0,p=0; 196 uint time = 0; 197 198 float pix_setting, req_pclk; 199 status_t result; 200 201 req_pclk = (target.timing.pixel_clock)/1000.0; 202 LOG(4,("DAC: Setting PIX PLL for pixelclock %f\n", req_pclk)); 203 204 /* signal that we actually want to set the mode */ 205 result = gx00_dac_pix_pll_find(target,&pix_setting,&m,&n,&p, 1); 206 if (result != B_OK) 207 { 208 return result; 209 } 210 211 /*reprogram (disable,select,wait for stability,enable)*/ 212 DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0x0F)|0x04); /*disable the PIXPLL*/ 213 DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0x0C)|0x01); /*select the PIXPLL*/ 214 VGAW(MISCW,((VGAR(MISCR)&0xF3)|0x8)); /*select PIXPLLC*/ 215 DXIW(PIXPLLCM,(m)); /*set m value*/ 216 DXIW(PIXPLLCN,(n)); /*set n value*/ 217 DXIW(PIXPLLCP,(p)); /*set p value*/ 218 219 /* Wait for the PIXPLL frequency to lock until timeout occurs */ 220 while((!(DXIR(PIXPLLSTAT)&0x40)) & (time <= 2000)) 221 { 222 time++; 223 snooze(1); 224 } 225 226 if (time > 2000) 227 LOG(2,("DAC: PIX PLL frequency not locked!\n")); 228 else 229 LOG(2,("DAC: PIX PLL frequency locked\n")); 230 DXIW(PIXCLKCTRL,DXIR(PIXCLKCTRL)&0x0B); /*enable the PIXPLL*/ 231 232 return B_OK; 233 } 234 235 static status_t gx50_dac_check_pix_pll(uint8 m, uint8 n, uint8 p) 236 { 237 uint time = 0, count = 0; 238 239 /*reprogram (disable,select,wait for stability,enable)*/ 240 DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0x0C)|0x01); /*select the PIXPLL*/ 241 VGAW(MISCW,((VGAR(MISCR)&0xF3)|0x8)); /*select PIXPLLC*/ 242 DXIW(PIXPLLCM,(m)); /*set m value*/ 243 DXIW(PIXPLLCN,(n)); /*set n value*/ 244 DXIW(PIXPLLCP,(p)); /*set p value*/ 245 246 /* give the PLL 1mS at least to get a lock */ 247 time = 0; 248 while((!(DXIR(PIXPLLSTAT)&0x40)) & (time <= 1000)) 249 { 250 time++; 251 snooze(1); 252 } 253 254 /* no lock aquired, not useable */ 255 if (time > 1000) return B_ERROR; 256 257 /* check if lock holds for at least 90% of the time */ 258 for (time = 0, count = 0; time <= 1000; time++) 259 { 260 if(DXIR(PIXPLLSTAT)&0x40) count++; 261 snooze(1); 262 } 263 /* we have a winner */ 264 if (count >= 900) return B_OK; 265 266 /* nogo, the PLL does not stabilize */ 267 return B_ERROR; 268 } 269 270 static status_t gx50_dac_check_pix_pll_range(uint8 m, uint8 n, uint8 *p, uint8 *q) 271 { 272 uint8 s=0, p_backup = *p; 273 274 /* preset no candidate, non working setting */ 275 *q = 0; 276 /* preset lowest range filter */ 277 *p &= 0x47; 278 279 /* iterate through all possible filtersettings */ 280 DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0x0F)|0x04); /*disable the PIXPLL*/ 281 282 for (s = 0; s < 8 ;s++) 283 { 284 if (gx50_dac_check_pix_pll(m, n, *p)== B_OK) 285 { 286 /* now check 3 closest lower and higher settings */ 287 if ((gx50_dac_check_pix_pll(m, n - 3, *p)== B_OK) && 288 (gx50_dac_check_pix_pll(m, n - 2, *p)== B_OK) && 289 (gx50_dac_check_pix_pll(m, n - 1, *p)== B_OK) && 290 (gx50_dac_check_pix_pll(m, n + 1, *p)== B_OK) && 291 (gx50_dac_check_pix_pll(m, n + 2, *p)== B_OK) && 292 (gx50_dac_check_pix_pll(m, n + 3, *p)== B_OK)) 293 { 294 LOG(2,("DAC: found optimal working VCO filter: #%d\n",s)); 295 /* preset first choice setting found */ 296 *q = 1; 297 /* we are done */ 298 DXIW(PIXCLKCTRL,DXIR(PIXCLKCTRL)&0x0B); /*enable the PIXPLL*/ 299 return B_OK; 300 } 301 else 302 { 303 LOG(2,("DAC: found critical but working VCO filter: #%d\n",s)); 304 /* preset backup setting found */ 305 *q = 2; 306 /* remember this setting */ 307 p_backup = *p; 308 /* let's continue to see if a better filter exists */ 309 } 310 } 311 /* new filtersetting to try */ 312 *p += (1 << 3); 313 } 314 315 /* return the (last found) backup result, or the original p value */ 316 *p = p_backup; 317 DXIW(PIXCLKCTRL,DXIR(PIXCLKCTRL)&0x0B); /*enable the PIXPLL*/ 318 /* we found only a non-optimal value */ 319 if (*q == 2) return B_OK; 320 321 /* nothing worked at all */ 322 LOG(2,("DAC: no working VCO filter found!\n")); 323 return B_ERROR; 324 } 325 326 /* find nearest valid pix pll */ 327 status_t gx00_dac_pix_pll_find 328 (display_mode target,float * calc_pclk,uint8 * m_result,uint8 * n_result,uint8 * p_result, uint8 test) 329 { 330 switch (si->ps.card_type) { 331 case G550: 332 case G450: return g450_g550_dac_pix_pll_find(target, calc_pclk, m_result, n_result, p_result, test); 333 case MIL2: 334 case MIL1: return milx_dac_pix_pll_find(target, calc_pclk, m_result, n_result, p_result); 335 default: return g100_g400max_dac_pix_pll_find(target, calc_pclk, m_result, n_result, p_result, test); 336 } 337 return B_ERROR; 338 } 339 340 341 /* find nearest valid pixel PLL setting: rewritten by rudolf */ 342 static status_t milx_dac_pix_pll_find( 343 display_mode target, float* calc_pclk, uint8* m_result, uint8* n_result, 344 uint8* p_result) 345 { 346 int m = 0, n = 0, p = 0; 347 float error, error_best = INFINITY; 348 int best[3] = {0, 0, 0}; 349 float f_vco, max_pclk; 350 float req_pclk = target.timing.pixel_clock / 1000.0; 351 352 LOG(4, ("DAC: MIL1/MIL2 TVP restrictions apply\n")); 353 354 /* determine the max. pixelclock for the current videomode */ 355 switch (target.space) 356 { 357 case B_CMAP8: 358 max_pclk = si->ps.max_dac1_clock_8; 359 break; 360 case B_RGB15_LITTLE: 361 case B_RGB16_LITTLE: 362 max_pclk = si->ps.max_dac1_clock_16; 363 break; 364 case B_RGB24_LITTLE: 365 max_pclk = si->ps.max_dac1_clock_24; 366 break; 367 case B_RGB32_LITTLE: 368 max_pclk = si->ps.max_dac1_clock_32; 369 break; 370 default: 371 /* use fail-safe value */ 372 max_pclk = si->ps.max_dac1_clock_32; 373 break; 374 } 375 376 /* Make sure the requested pixelclock is within the PLL's operational limits */ 377 /* lower limit is min_pixel_vco divided by highest postscaler-factor */ 378 if (req_pclk < (si->ps.min_pixel_vco / 8.0)) 379 { 380 LOG(4, ("DAC: TVP clamping pixclock: requested %fMHz, set to %fMHz\n", 381 req_pclk, (float)(si->ps.min_pixel_vco / 8.0))); 382 req_pclk = (si->ps.min_pixel_vco / 8.0); 383 } 384 /* upper limit is given by pins in combination with current active mode */ 385 if (req_pclk > max_pclk) 386 { 387 LOG(4, ("DAC: TVP clamping pixclock: requested %fMHz, set to %fMHz\n", 388 req_pclk, (float)max_pclk)); 389 req_pclk = max_pclk; 390 } 391 392 /* iterate through all valid PLL postscaler settings */ 393 for (p=0x01; p < 0x10; p = p<<1) 394 { 395 /* calculate the needed VCO frequency for this postscaler setting */ 396 f_vco = req_pclk * p; 397 398 /* check if this is within range of the VCO specs */ 399 if ((f_vco >= si->ps.min_pixel_vco) && (f_vco <= si->ps.max_pixel_vco)) 400 { 401 /* iterate trough all valid reference-frequency postscaler settings */ 402 for (n = 3; n <= 25; n++) 403 { 404 /* calculate VCO postscaler setting for current setup.. */ 405 m = (int)(((f_vco * n) / (8 * si->ps.f_ref)) + 0.5); 406 /* ..and check for validity */ 407 if ((m < 3) || (m > 64)) continue; 408 409 /* find error in frequency this setting gives */ 410 error = fabs(req_pclk - ((((8 * si->ps.f_ref) / n) * m) / p)); 411 412 /* note the setting if best yet */ 413 if (error < error_best) 414 { 415 error_best = error; 416 best[0]=m; 417 best[1]=n; 418 best[2]=p; 419 } 420 } 421 } 422 } 423 424 m = best[0]; 425 n = best[1]; 426 p = best[2]; 427 428 f_vco = (((8 * si->ps.f_ref) / n) * m); 429 LOG(2, ("DAC: TVP pix VCO frequency found %fMhz\n", f_vco)); 430 431 /* setup the scalers programming values for found optimum setting */ 432 *calc_pclk = (f_vco / p); 433 *m_result = (65 - m); 434 *n_result = (65 - n); 435 436 switch (p) 437 { 438 case 1: 439 p = 0x00; 440 break; 441 case 2: 442 p = 0x01; 443 break; 444 case 4: 445 p = 0x02; 446 break; 447 case 8: 448 p = 0x03; 449 break; 450 } 451 *p_result = p; 452 453 /* display the found pixelclock values */ 454 LOG(2, ("DAC: TVP pix PLL check: requested %fMHz got %fMHz, mnp 0x%02x 0x%02x 0x%02x\n", 455 req_pclk, *calc_pclk, *m_result, *n_result, *p_result)); 456 457 return B_OK; 458 } 459 460 461 /* find nearest valid pixel PLL setting: rewritten by rudolf */ 462 static status_t g100_g400max_dac_pix_pll_find( 463 display_mode target, float* calc_pclk, uint8* m_result, uint8* n_result, 464 uint8* p_result, uint8 test) 465 { 466 int m = 0, n = 0, p = 0, m_max; 467 float error, error_best = INFINITY; 468 int best[3] = {0, 0, 0}; 469 float f_vco, max_pclk; 470 float req_pclk = target.timing.pixel_clock/1000.0; 471 472 /* determine the max. reference-frequency postscaler setting for the 473 * current card (see G100, G200 and G400 specs). */ 474 switch (si->ps.card_type) 475 { 476 case G100: 477 LOG(4, ("DAC: G100 restrictions apply\n")); 478 m_max = 7; 479 break; 480 case G200: 481 LOG(4, ("DAC: G200 restrictions apply\n")); 482 m_max = 7; 483 break; 484 default: 485 LOG(4, ("DAC: G400/G400MAX restrictions apply\n")); 486 m_max = 32; 487 break; 488 } 489 490 /* make sure the pixelPLL and the videoPLL have a little different settings to 491 * minimize distortions in the outputs due to crosstalk: 492 * do *not* change the videoPLL setting because it must be exact if TVout is enabled! */ 493 /* Note: 494 * only modify the clock if we are actually going to set the mode */ 495 if ((target.flags & DUALHEAD_BITS) && test) 496 { 497 LOG(4, ("DAC: dualhead mode active: modified requested pixelclock +1.5%%\n")); 498 req_pclk *= 1.015; 499 } 500 501 /* determine the max. pixelclock for the current videomode */ 502 switch (target.space) 503 { 504 case B_CMAP8: 505 max_pclk = si->ps.max_dac1_clock_8; 506 break; 507 case B_RGB15_LITTLE: 508 case B_RGB16_LITTLE: 509 max_pclk = si->ps.max_dac1_clock_16; 510 break; 511 case B_RGB24_LITTLE: 512 max_pclk = si->ps.max_dac1_clock_24; 513 break; 514 case B_RGB32_LITTLE: 515 max_pclk = si->ps.max_dac1_clock_32; 516 break; 517 default: 518 /* use fail-safe value */ 519 max_pclk = si->ps.max_dac1_clock_32; 520 break; 521 } 522 /* if some dualhead mode is active, an extra restriction might apply */ 523 if ((target.flags & DUALHEAD_BITS) && (target.space == B_RGB32_LITTLE)) 524 max_pclk = si->ps.max_dac1_clock_32dh; 525 526 /* Make sure the requested pixelclock is within the PLL's operational limits */ 527 /* lower limit is min_pixel_vco divided by highest postscaler-factor */ 528 if (req_pclk < (si->ps.min_pixel_vco / 8.0)) 529 { 530 LOG(4, ("DAC: clamping pixclock: requested %fMHz, set to %fMHz\n", 531 req_pclk, (float)(si->ps.min_pixel_vco / 8.0))); 532 req_pclk = (si->ps.min_pixel_vco / 8.0); 533 } 534 /* upper limit is given by pins in combination with current active mode */ 535 if (req_pclk > max_pclk) 536 { 537 LOG(4, ("DAC: clamping pixclock: requested %fMHz, set to %fMHz\n", 538 req_pclk, (float)max_pclk)); 539 req_pclk = max_pclk; 540 } 541 542 /* iterate through all valid PLL postscaler settings */ 543 for (p=0x01; p < 0x10; p = p<<1) 544 { 545 /* calculate the needed VCO frequency for this postscaler setting */ 546 f_vco = req_pclk * p; 547 548 /* check if this is within range of the VCO specs */ 549 if ((f_vco >= si->ps.min_pixel_vco) && (f_vco <= si->ps.max_pixel_vco)) 550 { 551 /* iterate trough all valid reference-frequency postscaler settings */ 552 for (m = 2; m <= m_max; m++) 553 { 554 /* calculate VCO postscaler setting for current setup.. */ 555 n = (int)(((f_vco * m) / si->ps.f_ref) + 0.5); 556 /* ..and check for validity */ 557 if ((n < 8) || (n > 128)) continue; 558 559 /* find error in frequency this setting gives */ 560 error = fabs(req_pclk - (((si->ps.f_ref / m) * n) / p)); 561 562 /* note the setting if best yet */ 563 if (error < error_best) 564 { 565 error_best = error; 566 best[0]=m; 567 best[1]=n; 568 best[2]=p; 569 } 570 } 571 } 572 } 573 574 /* setup the scalers programming values for found optimum setting */ 575 m=best[0] - 1; 576 n=best[1] - 1; 577 p=best[2] - 1; 578 579 /* calc the needed PLL loopbackfilter setting belonging to current VCO speed, 580 * for the current card (see G100, G200 and G400 specs). */ 581 f_vco = (si->ps.f_ref / (m + 1)) * (n + 1); 582 LOG(2, ("DAC: pix VCO frequency found %fMhz\n", f_vco)); 583 584 switch (si->ps.card_type) 585 { 586 case G100: 587 case G200: 588 for (;;) 589 { 590 if (f_vco >= 180) {p |= (0x03 << 3); break;}; 591 if (f_vco >= 140) {p |= (0x02 << 3); break;}; 592 if (f_vco >= 100) {p |= (0x01 << 3); break;}; 593 break; 594 } 595 break; 596 default: 597 for (;;) 598 { 599 if (f_vco >= 240) {p |= (0x03 << 3); break;}; 600 if (f_vco >= 170) {p |= (0x02 << 3); break;}; 601 if (f_vco >= 110) {p |= (0x01 << 3); break;}; 602 break; 603 } 604 break; 605 } 606 607 /* return the results */ 608 *calc_pclk = f_vco / ((p & 0x07) + 1); 609 *m_result = m; 610 *n_result = n; 611 *p_result = p; 612 613 /* display the found pixelclock values */ 614 LOG(2, ("DAC: pix PLL check: requested %fMHz got %fMHz, mnp 0x%02x 0x%02x 0x%02x\n", 615 req_pclk, *calc_pclk, *m_result, *n_result, *p_result)); 616 617 return B_OK; 618 } 619 620 621 /* find nearest valid pixel PLL setting: rewritten by rudolf */ 622 static status_t g450_g550_dac_pix_pll_find 623 (display_mode target, float* calc_pclk, uint8* m_result, uint8* n_result, 624 uint8* p_result, uint8 test) 625 { 626 int m = 0, n = 0; 627 uint8 p = 0, q = 0; 628 float error, error_best = INFINITY; 629 int best[3] = {0, 0, 0}; 630 float f_vco, max_pclk; 631 float req_pclk = target.timing.pixel_clock / 1000.0; 632 633 LOG(4, ("DAC: G450/G550 restrictions apply\n")); 634 635 /* determine the max. pixelclock for the current videomode */ 636 switch (target.space) 637 { 638 case B_CMAP8: 639 max_pclk = si->ps.max_dac1_clock_8; 640 break; 641 case B_RGB15_LITTLE: 642 case B_RGB16_LITTLE: 643 max_pclk = si->ps.max_dac1_clock_16; 644 break; 645 case B_RGB24_LITTLE: 646 max_pclk = si->ps.max_dac1_clock_24; 647 break; 648 case B_RGB32_LITTLE: 649 max_pclk = si->ps.max_dac1_clock_32; 650 break; 651 default: 652 /* use fail-safe value */ 653 max_pclk = si->ps.max_dac1_clock_32; 654 break; 655 } 656 /* if some dualhead mode is active, an extra restriction might apply */ 657 if ((target.flags & DUALHEAD_BITS) && (target.space == B_RGB32_LITTLE)) 658 max_pclk = si->ps.max_dac1_clock_32dh; 659 660 /* Make sure the requested pixelclock is within the PLL's operational limits */ 661 /* lower limit is min_pixel_vco divided by highest postscaler-factor */ 662 if (req_pclk < (si->ps.min_pixel_vco / 16.0)) 663 { 664 LOG(4, ("DAC: clamping pixclock: requested %fMHz, set to %fMHz\n", 665 req_pclk, (float)(si->ps.min_pixel_vco / 16.0))); 666 req_pclk = (si->ps.min_pixel_vco / 16.0); 667 } 668 /* upper limit is given by pins in combination with current active mode */ 669 if (req_pclk > max_pclk) 670 { 671 LOG(4, ("DAC: clamping pixclock: requested %fMHz, set to %fMHz\n", 672 req_pclk, (float)max_pclk)); 673 req_pclk = max_pclk; 674 } 675 676 /* iterate through all valid PLL postscaler settings */ 677 for (p=0x01; p < 0x20; p = p<<1) 678 { 679 /* calculate the needed VCO frequency for this postscaler setting */ 680 f_vco = req_pclk * p; 681 682 /* check if this is within range of the VCO specs */ 683 if ((f_vco >= si->ps.min_pixel_vco) && (f_vco <= si->ps.max_pixel_vco)) 684 { 685 /* iterate trough all valid reference-frequency postscaler settings */ 686 for (m = 2; m <= 32; m++) 687 { 688 /* calculate VCO postscaler setting for current setup.. */ 689 n = (int)(((f_vco * m) / (si->ps.f_ref * 2)) + 0.5); 690 /* ..and check for validity, BUT: 691 * Keep in mind that we need to be able to test n-3 ... n+3! */ 692 if ((n < (8 + 3)) || (n > (128 - 3))) continue; 693 694 /* find error in frequency this setting gives */ 695 error = fabs(req_pclk - ((((si->ps.f_ref * 2)/ m) * n) / p)); 696 697 /* note the setting if best yet */ 698 if (error < error_best) 699 { 700 error_best = error; 701 best[0]=m; 702 best[1]=n; 703 best[2]=p; 704 } 705 } 706 } 707 } 708 709 /* setup the scalers programming values for found optimum setting */ 710 m=best[0] - 1; 711 n=best[1] - 2; 712 switch (best[2]) 713 { 714 case 1: 715 p = 0x40; 716 break; 717 case 2: 718 p = 0x00; 719 break; 720 case 4: 721 p = 0x01; 722 break; 723 case 8: 724 p = 0x02; 725 break; 726 case 16: 727 p = 0x03; 728 break; 729 } 730 731 /* log the closest VCO speed found */ 732 f_vco = ((si->ps.f_ref * 2) / (m + 1)) * (n + 2); 733 LOG(2, ("DAC: pix VCO frequency found %fMhz\n", f_vco)); 734 735 /* now find the filtersetting that matches best with this frequency by testing. 736 * for now we assume this routine succeeds to get us a stable setting */ 737 if (test) 738 gx50_dac_check_pix_pll_range(m, n, &p, &q); 739 else 740 LOG(2, ("DAC: Not testing G450/G550 VCO feedback filters\n")); 741 742 /* return the results */ 743 *calc_pclk = f_vco / best[2]; 744 *m_result = m; 745 *n_result = n; 746 *p_result = p; 747 748 /* display the found pixelclock values */ 749 LOG(2, ("DAC: pix PLL check: requested %fMHz got %fMHz, mnp 0x%02x 0x%02x 0x%02x\n", 750 req_pclk, *calc_pclk, *m_result, *n_result, *p_result)); 751 752 return B_OK; 753 } 754 755 756 /* find nearest valid system PLL setting */ 757 static status_t g100_g400max_dac_sys_pll_find( 758 float req_sclk, float* calc_sclk, uint8* m_result, uint8* n_result, 759 uint8 * p_result) 760 { 761 int m = 0, n = 0, p = 0, m_max; 762 float error, error_best = INFINITY; 763 int best[3] = {0, 0, 0}; 764 float f_vco; 765 766 /* determine the max. reference-frequency postscaler setting for the 767 * current card (see G100, G200 and G400 specs). */ 768 switch (si->ps.card_type) 769 { 770 case G100: 771 LOG(4, ("DAC: G100 restrictions apply\n")); 772 m_max = 7; 773 break; 774 case G200: 775 LOG(4, ("DAC: G200 restrictions apply\n")); 776 m_max = 7; 777 break; 778 default: 779 LOG(4, ("DAC: G400/G400MAX restrictions apply\n")); 780 m_max = 32; 781 break; 782 } 783 784 /* Make sure the requested systemclock is within the PLL's operational limits */ 785 /* lower limit is min_system_vco divided by highest postscaler-factor */ 786 if (req_sclk < (si->ps.min_system_vco / 8.0)) 787 { 788 LOG(4, ("DAC: clamping sysclock: requested %fMHz, set to %fMHz\n", 789 req_sclk, (float)(si->ps.min_system_vco / 8.0))); 790 req_sclk = (si->ps.min_system_vco / 8.0); 791 } 792 /* upper limit is max_system_vco */ 793 if (req_sclk > si->ps.max_system_vco) 794 { 795 LOG(4, ("DAC: clamping sysclock: requested %fMHz, set to %fMHz\n", 796 req_sclk, (float)si->ps.max_system_vco)); 797 req_sclk = si->ps.max_system_vco; 798 } 799 800 /* iterate through all valid PLL postscaler settings */ 801 for (p=0x01; p < 0x10; p = p<<1) 802 { 803 /* calculate the needed VCO frequency for this postscaler setting */ 804 f_vco = req_sclk * p; 805 806 /* check if this is within range of the VCO specs */ 807 if ((f_vco >= si->ps.min_system_vco) && (f_vco <= si->ps.max_system_vco)) 808 { 809 /* iterate trough all valid reference-frequency postscaler settings */ 810 for (m = 2; m <= m_max; m++) 811 { 812 /* calculate VCO postscaler setting for current setup.. */ 813 n = (int)(((f_vco * m) / si->ps.f_ref) + 0.5); 814 /* ..and check for validity */ 815 if ((n < 8) || (n > 128)) continue; 816 817 /* find error in frequency this setting gives */ 818 error = fabs(req_sclk - (((si->ps.f_ref / m) * n) / p)); 819 820 /* note the setting if best yet */ 821 if (error < error_best) 822 { 823 error_best = error; 824 best[0]=m; 825 best[1]=n; 826 best[2]=p; 827 } 828 } 829 } 830 } 831 832 /* setup the scalers programming values for found optimum setting */ 833 m=best[0] - 1; 834 n=best[1] - 1; 835 p=best[2] - 1; 836 837 /* calc the needed PLL loopbackfilter setting belonging to current VCO speed, 838 * for the current card (see G100, G200 and G400 specs). */ 839 f_vco = (si->ps.f_ref / (m + 1)) * (n + 1); 840 LOG(2, ("DAC: sys VCO frequency found %fMhz\n", f_vco)); 841 842 switch (si->ps.card_type) 843 { 844 case G100: 845 case G200: 846 for (;;) 847 { 848 if (f_vco >= 180) {p |= (0x03 << 3); break;}; 849 if (f_vco >= 140) {p |= (0x02 << 3); break;}; 850 if (f_vco >= 100) {p |= (0x01 << 3); break;}; 851 break; 852 } 853 break; 854 default: 855 for (;;) 856 { 857 if (f_vco >= 240) {p |= (0x03 << 3); break;}; 858 if (f_vco >= 170) {p |= (0x02 << 3); break;}; 859 if (f_vco >= 110) {p |= (0x01 << 3); break;}; 860 break; 861 } 862 break; 863 } 864 865 /* return the results */ 866 *calc_sclk = f_vco / ((p & 0x07) + 1); 867 *m_result = m; 868 *n_result = n; 869 *p_result = p; 870 871 /* display the found pixelclock values */ 872 LOG(2, ("DAC: sys PLL check: requested %fMHz got %fMHz, mnp 0x%02x 0x%02x 0x%02x\n", 873 req_sclk, *calc_sclk, *m_result, *n_result, *p_result)); 874 875 return B_OK; 876 } 877 878 879 static status_t gx50_dac_check_sys_pll(uint8 m, uint8 n, uint8 p) 880 { 881 uint time = 0, count = 0; 882 883 /* program the new clock */ 884 DXIW(SYSPLLM, m); 885 DXIW(SYSPLLN, n); 886 DXIW(SYSPLLP, p); 887 888 /* Wait for the SYSPLL frequency to lock until timeout occurs */ 889 time = 0; 890 while((!(DXIR(SYSPLLSTAT)&0x40)) & (time <= 1000)) 891 { 892 time++; 893 snooze(1); 894 } 895 896 /* no lock aquired, not useable */ 897 if (time > 1000) return B_ERROR; 898 899 /* check if lock holds for at least 90% of the time */ 900 for (time = 0, count = 0; time <= 1000; time++) 901 { 902 if(DXIR(SYSPLLSTAT)&0x40) count++; 903 snooze(1); 904 } 905 /* we have a winner */ 906 if (count >= 900) return B_OK; 907 908 /* nogo, the PLL does not stabilize */ 909 return B_ERROR; 910 } 911 912 static status_t gx50_dac_check_sys_pll_range(uint8 m, uint8 n, uint8 *p, uint8 *q) 913 { 914 uint8 s=0, p_backup = *p; 915 916 /* preset no candidate, non working setting */ 917 *q = 0; 918 /* preset lowest range filter */ 919 *p &= 0x47; 920 921 /* iterate through all possible filtersettings */ 922 for (s = 0; s < 8 ;s++) 923 { 924 if (gx50_dac_check_sys_pll(m, n, *p)== B_OK) 925 { 926 /* now check 3 closest lower and higher settings */ 927 if ((gx50_dac_check_sys_pll(m, n - 3, *p)== B_OK) && 928 (gx50_dac_check_sys_pll(m, n - 2, *p)== B_OK) && 929 (gx50_dac_check_sys_pll(m, n - 1, *p)== B_OK) && 930 (gx50_dac_check_sys_pll(m, n + 1, *p)== B_OK) && 931 (gx50_dac_check_sys_pll(m, n + 2, *p)== B_OK) && 932 (gx50_dac_check_sys_pll(m, n + 3, *p)== B_OK)) 933 { 934 LOG(2,("DAC: found optimal working VCO filter: #%d\n",s)); 935 /* preset first choice setting found */ 936 *q = 1; 937 /* we are done */ 938 return B_OK; 939 } 940 else 941 { 942 LOG(2,("DAC: found critical but working VCO filter: #%d\n",s)); 943 /* preset backup setting found */ 944 *q = 2; 945 /* remember this setting */ 946 p_backup = *p; 947 /* let's continue to see if a better filter exists */ 948 } 949 } 950 /* new filtersetting to try */ 951 *p += (1 << 3); 952 } 953 954 /* return the (last found) backup result, or the original p value */ 955 *p = p_backup; 956 /* we found only a non-optimal value */ 957 if (*q == 2) return B_OK; 958 959 /* nothing worked at all */ 960 LOG(2, ("DAC: no working VCO filter found!\n")); 961 return B_ERROR; 962 } 963 964 965 /* find nearest valid system PLL setting */ 966 static status_t g450_g550_dac_sys_pll_find( 967 float req_sclk, float* calc_sclk, uint8* m_result, uint8* n_result, 968 uint8* p_result) 969 { 970 int m = 0, n = 0; 971 uint8 p = 0, q = 0; 972 float error, error_best = INFINITY; 973 int best[3] = {0, 0, 0}; 974 float f_vco; 975 976 LOG(4, ("DAC: G450/G550 restrictions apply\n")); 977 978 /* Make sure the requested pixelclock is within the PLL's operational limits */ 979 /* lower limit is min_system_vco divided by highest postscaler-factor */ 980 if (req_sclk < (si->ps.min_system_vco / 16.0)) 981 { 982 LOG(4, ("DAC: clamping sysclock: requested %fMHz, set to %fMHz\n", 983 req_sclk, (float)(si->ps.min_system_vco / 16.0))); 984 req_sclk = (si->ps.min_system_vco / 16.0); 985 } 986 /* upper limit is max_system_vco */ 987 if (req_sclk > si->ps.max_system_vco) 988 { 989 LOG(4, ("DAC: clamping sysclock: requested %fMHz, set to %fMHz\n", 990 req_sclk, (float)si->ps.max_system_vco)); 991 req_sclk = si->ps.max_system_vco; 992 } 993 994 /* iterate through all valid PLL postscaler settings */ 995 for (p=0x01; p < 0x20; p = p<<1) 996 { 997 /* calculate the needed VCO frequency for this postscaler setting */ 998 f_vco = req_sclk * p; 999 1000 /* check if this is within range of the VCO specs */ 1001 if ((f_vco >= si->ps.min_system_vco) && (f_vco <= si->ps.max_system_vco)) 1002 { 1003 /* iterate trough all valid reference-frequency postscaler settings */ 1004 for (m = 2; m <= 32; m++) 1005 { 1006 /* calculate VCO postscaler setting for current setup.. */ 1007 n = (int)(((f_vco * m) / (si->ps.f_ref * 2)) + 0.5); 1008 /* ..and check for validity, BUT: 1009 * Keep in mind that we need to be able to test n-3 ... n+3! */ 1010 if ((n < (8 + 3)) || (n > (128 - 3))) continue; 1011 1012 /* find error in frequency this setting gives */ 1013 error = fabs(req_sclk - ((((si->ps.f_ref * 2)/ m) * n) / p)); 1014 1015 /* note the setting if best yet */ 1016 if (error < error_best) 1017 { 1018 error_best = error; 1019 best[0]=m; 1020 best[1]=n; 1021 best[2]=p; 1022 } 1023 } 1024 } 1025 } 1026 1027 /* setup the scalers programming values for found optimum setting */ 1028 m=best[0] - 1; 1029 n=best[1] - 2; 1030 switch(best[2]) 1031 { 1032 case 1: 1033 p = 0x40; 1034 break; 1035 case 2: 1036 p = 0x00; 1037 break; 1038 case 4: 1039 p = 0x01; 1040 break; 1041 case 8: 1042 p = 0x02; 1043 break; 1044 case 16: 1045 p = 0x03; 1046 break; 1047 } 1048 1049 /* log the closest VCO speed found */ 1050 f_vco = ((si->ps.f_ref * 2) / (m + 1)) * (n + 2); 1051 LOG(2,("DAC: sys VCO frequency found %fMhz\n", f_vco)); 1052 1053 /* now find the filtersetting that matches best with this frequency by testing. 1054 * for now we assume this routine succeeds to get us a stable setting */ 1055 gx50_dac_check_sys_pll_range(m, n, &p, &q); 1056 1057 /* return the results */ 1058 *calc_sclk = f_vco / best[2]; 1059 *m_result = m; 1060 *n_result = n; 1061 *p_result = p; 1062 1063 /* display the found pixelclock values */ 1064 LOG(2,("DAC: sys PLL check: requested %fMHz got %fMHz, mnp 0x%02x 0x%02x 0x%02x\n", 1065 req_sclk, *calc_sclk, *m_result, *n_result, *p_result)); 1066 1067 return B_OK; 1068 } 1069 1070 /*set up system pll - NB mclk is memory clock */ 1071 status_t g100_dac_set_sys_pll() 1072 { 1073 /* values for DAC sys pll registers */ 1074 uint8 m, n, p; 1075 uint time = 0; 1076 uint32 temp; 1077 float calc_sclk; 1078 1079 LOG(1,("DAC: Setting up G100 system clock\n")); 1080 g100_g400max_dac_sys_pll_find((float)si->ps.std_engine_clock, &calc_sclk, &m, &n, &p); 1081 1082 /* reprogram the clock - set PCI/AGP, program, set to programmed */ 1083 /* disable the SYSPLL */ 1084 CFGW(OPTION, CFGR(OPTION) | 0x04); 1085 /* select the PCI/AGP clock */ 1086 CFGW(OPTION, CFGR(OPTION) & 0xfffffffc); 1087 /* enable the SYSPLL */ 1088 CFGW(OPTION, CFGR(OPTION) & 0xfffffffb); 1089 1090 /* program the new clock */ 1091 DXIW(SYSPLLM, m); 1092 DXIW(SYSPLLN, n); 1093 DXIW(SYSPLLP, p); 1094 1095 /* Wait for the SYSPLL frequency to lock until timeout occurs */ 1096 while((!(DXIR(SYSPLLSTAT)&0x40)) & (time <= 2000)) 1097 { 1098 time++; 1099 snooze(1); 1100 } 1101 1102 if (time > 2000) 1103 LOG(2,("DAC: sys PLL frequency not locked!\n")); 1104 else 1105 LOG(2,("DAC: sys PLL frequency locked\n")); 1106 1107 /* disable the SYSPLL */ 1108 CFGW(OPTION, CFGR(OPTION) | 0x04); 1109 /* setup Gclk, Mclk and FMclk divisors according to PINS */ 1110 temp = (CFGR(OPTION) & 0xffffff27); 1111 if (si->ps.v3_clk_div & 0x01) temp |= 0x08; 1112 if (si->ps.v3_clk_div & 0x02) temp |= 0x10; 1113 if (si->ps.v3_clk_div & 0x04) temp |= 0x80; 1114 /* fixme: swapPLL can only be done when the rest of the driver respects this also! */ 1115 //never used AFAIK: 1116 //if (si->ps.v3_clk_div & 0x08) temp |= 0x40; 1117 /* select the SYSPLL as system clock source */ 1118 temp |= 0x01; 1119 CFGW(OPTION, temp); 1120 /* enable the SYSPLL (and make sure the SYSPLL is indeed powered up) */ 1121 CFGW(OPTION, (CFGR(OPTION) & 0xfffffffb) | 0x20); 1122 1123 return B_OK; 1124 } 1125 1126 /*set up system pll - NB mclk is memory clock */ 1127 status_t g200_dac_set_sys_pll() 1128 { 1129 /* values for DAC sys pll registers */ 1130 uint8 m, n, p; 1131 uint time = 0; 1132 uint32 temp; 1133 float calc_sclk; 1134 1135 LOG(1,("DAC: Setting up G200 system clock\n")); 1136 g100_g400max_dac_sys_pll_find((float)si->ps.std_engine_clock, &calc_sclk, &m, &n, &p); 1137 1138 /* reprogram the clock - set PCI/AGP, program, set to programmed */ 1139 /* disable the SYSPLL */ 1140 CFGW(OPTION, CFGR(OPTION) | 0x04); 1141 /* select the PCI/AGP clock */ 1142 CFGW(OPTION, CFGR(OPTION) & 0xfffffffc); 1143 /* enable the SYSPLL */ 1144 CFGW(OPTION, CFGR(OPTION) & 0xfffffffb); 1145 1146 /* program the new clock */ 1147 DXIW(SYSPLLM, m); 1148 DXIW(SYSPLLN, n); 1149 DXIW(SYSPLLP, p); 1150 1151 /* Wait for the SYSPLL frequency to lock until timeout occurs */ 1152 while((!(DXIR(SYSPLLSTAT)&0x40)) & (time <= 2000)) 1153 { 1154 time++; 1155 snooze(1); 1156 } 1157 1158 if (time > 2000) 1159 LOG(2,("DAC: sys PLL frequency not locked!\n")); 1160 else 1161 LOG(2,("DAC: sys PLL frequency locked\n")); 1162 1163 /* disable the SYSPLL */ 1164 CFGW(OPTION, CFGR(OPTION) | 0x04); 1165 /* setup Wclk divisor and enable/disable Wclk, Gclk and Mclk divisors 1166 * according to PINS */ 1167 temp = (CFGR(OPTION2) & 0x00383000); 1168 if (si->ps.v3_option2_reg & 0x04) temp |= 0x00004000; 1169 if (si->ps.v3_option2_reg & 0x08) temp |= 0x00008000; 1170 if (si->ps.v3_option2_reg & 0x10) temp |= 0x00010000; 1171 if (si->ps.v3_option2_reg & 0x20) temp |= 0x00020000; 1172 CFGW(OPTION2, temp); 1173 /* setup Gclk and Mclk divisors according to PINS */ 1174 temp = (CFGR(OPTION) & 0xffffff27); 1175 if (si->ps.v3_clk_div & 0x01) temp |= 0x08; 1176 if (si->ps.v3_clk_div & 0x02) temp |= 0x10; 1177 /* fixme: swapPLL can only be done when the rest of the driver respects this also! */ 1178 //never used AFAIK: 1179 //if (si->ps.v3_clk_div & 0x08) temp |= 0x40; 1180 /* select the SYSPLL as system clock source */ 1181 temp |= 0x01; 1182 CFGW(OPTION, temp); 1183 /* enable the SYSPLL (and make sure the SYSPLL is indeed powered up) */ 1184 CFGW(OPTION, (CFGR(OPTION) & 0xfffffffb) | 0x20); 1185 1186 return B_OK; 1187 } 1188 1189 /*set up system pll - NB mclk is memory clock */ 1190 status_t g400_dac_set_sys_pll() 1191 { 1192 /* values for DAC sys pll registers */ 1193 uint8 m, n, p; 1194 uint time = 0; 1195 float calc_sclk; 1196 1197 LOG(1,("DAC: Setting up G400/G400MAX system clock\n")); 1198 g100_g400max_dac_sys_pll_find((float)si->ps.std_engine_clock, &calc_sclk, &m, &n, &p); 1199 1200 /* reprogram the clock - set PCI/AGP, program, set to programmed */ 1201 /* clear, so don't o/clock addons */ 1202 CFGW(OPTION2, 0); 1203 /* disable the SYSPLL */ 1204 CFGW(OPTION, CFGR(OPTION) | 0x04); 1205 /* select the PCI/AGP clock */ 1206 CFGW(OPTION3, 0); 1207 /* enable the SYSPLL */ 1208 CFGW(OPTION, CFGR(OPTION) & 0xfffffffb); 1209 1210 /* program the new clock */ 1211 DXIW(SYSPLLM, m); 1212 DXIW(SYSPLLN, n); 1213 DXIW(SYSPLLP, p); 1214 1215 /* Wait for the SYSPLL frequency to lock until timeout occurs */ 1216 while((!(DXIR(SYSPLLSTAT)&0x40)) & (time <= 2000)) 1217 { 1218 time++; 1219 snooze(1); 1220 } 1221 1222 if (time > 2000) 1223 LOG(2,("DAC: sys PLL frequency not locked!\n")); 1224 else 1225 LOG(2,("DAC: sys PLL frequency locked\n")); 1226 1227 /* disable the SYSPLL */ 1228 CFGW(OPTION, CFGR(OPTION) | 0x04); 1229 /* setup Gclk, Mclk and Wclk divs via PINS and select SYSPLL as system clock source */ 1230 CFGW(OPTION3, si->ps.option3_reg); 1231 /* make sure the PLLs are not swapped (set default config) */ 1232 CFGW(OPTION, CFGR(OPTION) & 0xffffffbf); 1233 /* enable the SYSPLL (and make sure the SYSPLL is indeed powered up) */ 1234 CFGW(OPTION, (CFGR(OPTION) & 0xfffffffb) | 0x20); 1235 1236 return B_OK; 1237 } 1238 1239 /*set up system pll - NB mclk is memory clock */ 1240 status_t g450_dac_set_sys_pll() 1241 { 1242 /* values for DAC sys pll registers */ 1243 uint8 m, n, p; 1244 uint time = 0; 1245 float calc_sclk; 1246 1247 LOG(1,("DAC: Setting up G450/G550 system clock\n")); 1248 /* reprogram the clock - set PCI/AGP, program, set to programmed */ 1249 /* clear, so don't o/clock addons */ 1250 CFGW(OPTION2, 0); 1251 /* setup OPTION via pins */ 1252 CFGW(OPTION, si->ps.option_reg); 1253 /* disable the SYSPLL */ 1254 CFGW(OPTION, CFGR(OPTION) | 0x04); 1255 /* select the PCI/AGP clock */ 1256 CFGW(OPTION3, 0); 1257 /* enable the SYSPLL */ 1258 CFGW(OPTION, CFGR(OPTION) & 0xfffffffb); 1259 1260 /* this routine also tests the filters, so it actually programs the clock already */ 1261 g450_g550_dac_sys_pll_find((float)si->ps.std_engine_clock, &calc_sclk, &m, &n, &p); 1262 1263 /* program the new clock */ 1264 DXIW(SYSPLLM, m); 1265 DXIW(SYSPLLN, n); 1266 DXIW(SYSPLLP, p); 1267 1268 /* Wait for the SYSPLL frequency to lock until timeout occurs */ 1269 while((!(DXIR(SYSPLLSTAT)&0x40)) & (time <= 2000)) 1270 { 1271 time++; 1272 snooze(1); 1273 } 1274 1275 if (time > 2000) 1276 LOG(2,("DAC: sys PLL frequency not locked!\n")); 1277 else 1278 LOG(2,("DAC: sys PLL frequency locked\n")); 1279 1280 /* disable the SYSPLL */ 1281 CFGW(OPTION, CFGR(OPTION) | 0x04); 1282 /* setup Gclk, Mclk and Wclk divs via PINS and select SYSPLL as system clock source */ 1283 CFGW(OPTION3, si->ps.option3_reg); 1284 /* setup option2 via pins */ 1285 CFGW(OPTION2, si->ps.option2_reg); 1286 /* make sure the PLLs are not swapped (set default config) */ 1287 /* fixme: swapPLL can only be done when the rest of the driver respects this also! 1288 * (never used AFAIK) */ 1289 CFGW(OPTION, CFGR(OPTION) & 0xffffffbf); 1290 /* enable the SYSPLL (and make sure the SYSPLL is indeed powered up) */ 1291 CFGW(OPTION, (CFGR(OPTION) & 0xfffffffb) | 0x20); 1292 1293 return B_OK; 1294 } 1295