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 /* find nearest valid pixel PLL setting: rewritten by rudolf */ 341 static status_t milx_dac_pix_pll_find( 342 display_mode target,float * calc_pclk,uint8 * m_result,uint8 * n_result,uint8 * p_result) 343 { 344 int m = 0, n = 0, p = 0; 345 float error, error_best = 999999999; 346 int best[3]; 347 float f_vco, max_pclk; 348 float req_pclk = target.timing.pixel_clock/1000.0; 349 350 LOG(4,("DAC: MIL1/MIL2 TVP restrictions apply\n")); 351 352 /* determine the max. pixelclock for the current videomode */ 353 switch (target.space) 354 { 355 case B_CMAP8: 356 max_pclk = si->ps.max_dac1_clock_8; 357 break; 358 case B_RGB15_LITTLE: 359 case B_RGB16_LITTLE: 360 max_pclk = si->ps.max_dac1_clock_16; 361 break; 362 case B_RGB24_LITTLE: 363 max_pclk = si->ps.max_dac1_clock_24; 364 break; 365 case B_RGB32_LITTLE: 366 max_pclk = si->ps.max_dac1_clock_32; 367 break; 368 default: 369 /* use fail-safe value */ 370 max_pclk = si->ps.max_dac1_clock_32; 371 break; 372 } 373 374 /* Make sure the requested pixelclock is within the PLL's operational limits */ 375 /* lower limit is min_pixel_vco divided by highest postscaler-factor */ 376 if (req_pclk < (si->ps.min_pixel_vco / 8.0)) 377 { 378 LOG(4,("DAC: TVP clamping pixclock: requested %fMHz, set to %fMHz\n", 379 req_pclk, (float)(si->ps.min_pixel_vco / 8.0))); 380 req_pclk = (si->ps.min_pixel_vco / 8.0); 381 } 382 /* upper limit is given by pins in combination with current active mode */ 383 if (req_pclk > max_pclk) 384 { 385 LOG(4,("DAC: TVP clamping pixclock: requested %fMHz, set to %fMHz\n", 386 req_pclk, (float)max_pclk)); 387 req_pclk = max_pclk; 388 } 389 390 /* iterate through all valid PLL postscaler settings */ 391 for (p=0x01; p < 0x10; p = p<<1) 392 { 393 /* calculate the needed VCO frequency for this postscaler setting */ 394 f_vco = req_pclk * p; 395 396 /* check if this is within range of the VCO specs */ 397 if ((f_vco >= si->ps.min_pixel_vco) && (f_vco <= si->ps.max_pixel_vco)) 398 { 399 /* iterate trough all valid reference-frequency postscaler settings */ 400 for (n = 3; n <= 25; n++) 401 { 402 /* calculate VCO postscaler setting for current setup.. */ 403 m = (int)(((f_vco * n) / (8 * si->ps.f_ref)) + 0.5); 404 /* ..and check for validity */ 405 if ((m < 3) || (m > 64)) continue; 406 407 /* find error in frequency this setting gives */ 408 error = fabs(req_pclk - ((((8 * si->ps.f_ref) / n) * m) / p)); 409 410 /* note the setting if best yet */ 411 if (error < error_best) 412 { 413 error_best = error; 414 best[0]=m; 415 best[1]=n; 416 best[2]=p; 417 } 418 } 419 } 420 } 421 422 m = best[0]; 423 n = best[1]; 424 p = best[2]; 425 426 f_vco = (((8 * si->ps.f_ref) / n) * m); 427 LOG(2,("DAC: TVP pix VCO frequency found %fMhz\n", f_vco)); 428 429 /* setup the scalers programming values for found optimum setting */ 430 *calc_pclk = (f_vco / p); 431 *m_result = (65 - m); 432 *n_result = (65 - n); 433 434 switch(p) 435 { 436 case 1: 437 p = 0x00; 438 break; 439 case 2: 440 p = 0x01; 441 break; 442 case 4: 443 p = 0x02; 444 break; 445 case 8: 446 p = 0x03; 447 break; 448 } 449 *p_result = p; 450 451 /* display the found pixelclock values */ 452 LOG(2,("DAC: TVP pix PLL check: requested %fMHz got %fMHz, mnp 0x%02x 0x%02x 0x%02x\n", 453 req_pclk, *calc_pclk, *m_result, *n_result, *p_result)); 454 455 return B_OK; 456 } 457 458 /* find nearest valid pixel PLL setting: rewritten by rudolf */ 459 static status_t g100_g400max_dac_pix_pll_find( 460 display_mode target,float * calc_pclk,uint8 * m_result,uint8 * n_result,uint8 * p_result, uint8 test) 461 { 462 int m = 0, n = 0, p = 0, m_max; 463 float error, error_best = 999999999; 464 int best[3]; 465 float f_vco, max_pclk; 466 float req_pclk = target.timing.pixel_clock/1000.0; 467 468 /* determine the max. reference-frequency postscaler setting for the 469 * current card (see G100, G200 and G400 specs). */ 470 switch(si->ps.card_type) 471 { 472 case G100: 473 LOG(4,("DAC: G100 restrictions apply\n")); 474 m_max = 7; 475 break; 476 case G200: 477 LOG(4,("DAC: G200 restrictions apply\n")); 478 m_max = 7; 479 break; 480 default: 481 LOG(4,("DAC: G400/G400MAX restrictions apply\n")); 482 m_max = 32; 483 break; 484 } 485 486 /* make sure the pixelPLL and the videoPLL have a little different settings to 487 * minimize distortions in the outputs due to crosstalk: 488 * do *not* change the videoPLL setting because it must be exact if TVout is enabled! */ 489 /* Note: 490 * only modify the clock if we are actually going to set the mode */ 491 if ((target.flags & DUALHEAD_BITS) && test) 492 { 493 LOG(4,("DAC: dualhead mode active: modified requested pixelclock +1.5%%\n")); 494 req_pclk *= 1.015; 495 } 496 497 /* determine the max. pixelclock for the current videomode */ 498 switch (target.space) 499 { 500 case B_CMAP8: 501 max_pclk = si->ps.max_dac1_clock_8; 502 break; 503 case B_RGB15_LITTLE: 504 case B_RGB16_LITTLE: 505 max_pclk = si->ps.max_dac1_clock_16; 506 break; 507 case B_RGB24_LITTLE: 508 max_pclk = si->ps.max_dac1_clock_24; 509 break; 510 case B_RGB32_LITTLE: 511 max_pclk = si->ps.max_dac1_clock_32; 512 break; 513 default: 514 /* use fail-safe value */ 515 max_pclk = si->ps.max_dac1_clock_32; 516 break; 517 } 518 /* if some dualhead mode is active, an extra restriction might apply */ 519 if ((target.flags & DUALHEAD_BITS) && (target.space == B_RGB32_LITTLE)) 520 max_pclk = si->ps.max_dac1_clock_32dh; 521 522 /* Make sure the requested pixelclock is within the PLL's operational limits */ 523 /* lower limit is min_pixel_vco divided by highest postscaler-factor */ 524 if (req_pclk < (si->ps.min_pixel_vco / 8.0)) 525 { 526 LOG(4,("DAC: clamping pixclock: requested %fMHz, set to %fMHz\n", 527 req_pclk, (float)(si->ps.min_pixel_vco / 8.0))); 528 req_pclk = (si->ps.min_pixel_vco / 8.0); 529 } 530 /* upper limit is given by pins in combination with current active mode */ 531 if (req_pclk > max_pclk) 532 { 533 LOG(4,("DAC: clamping pixclock: requested %fMHz, set to %fMHz\n", 534 req_pclk, (float)max_pclk)); 535 req_pclk = max_pclk; 536 } 537 538 /* iterate through all valid PLL postscaler settings */ 539 for (p=0x01; p < 0x10; p = p<<1) 540 { 541 /* calculate the needed VCO frequency for this postscaler setting */ 542 f_vco = req_pclk * p; 543 544 /* check if this is within range of the VCO specs */ 545 if ((f_vco >= si->ps.min_pixel_vco) && (f_vco <= si->ps.max_pixel_vco)) 546 { 547 /* iterate trough all valid reference-frequency postscaler settings */ 548 for (m = 2; m <= m_max; m++) 549 { 550 /* calculate VCO postscaler setting for current setup.. */ 551 n = (int)(((f_vco * m) / si->ps.f_ref) + 0.5); 552 /* ..and check for validity */ 553 if ((n < 8) || (n > 128)) continue; 554 555 /* find error in frequency this setting gives */ 556 error = fabs(req_pclk - (((si->ps.f_ref / m) * n) / p)); 557 558 /* note the setting if best yet */ 559 if (error < error_best) 560 { 561 error_best = error; 562 best[0]=m; 563 best[1]=n; 564 best[2]=p; 565 } 566 } 567 } 568 } 569 570 /* setup the scalers programming values for found optimum setting */ 571 m=best[0] - 1; 572 n=best[1] - 1; 573 p=best[2] - 1; 574 575 /* calc the needed PLL loopbackfilter setting belonging to current VCO speed, 576 * for the current card (see G100, G200 and G400 specs). */ 577 f_vco = (si->ps.f_ref / (m + 1)) * (n + 1); 578 LOG(2,("DAC: pix VCO frequency found %fMhz\n", f_vco)); 579 580 switch(si->ps.card_type) 581 { 582 case G100: 583 case G200: 584 for(;;) 585 { 586 if (f_vco >= 180) {p |= (0x03 << 3); break;}; 587 if (f_vco >= 140) {p |= (0x02 << 3); break;}; 588 if (f_vco >= 100) {p |= (0x01 << 3); break;}; 589 break; 590 } 591 break; 592 default: 593 for(;;) 594 { 595 if (f_vco >= 240) {p |= (0x03 << 3); break;}; 596 if (f_vco >= 170) {p |= (0x02 << 3); break;}; 597 if (f_vco >= 110) {p |= (0x01 << 3); break;}; 598 break; 599 } 600 break; 601 } 602 603 /* return the results */ 604 *calc_pclk = f_vco / ((p & 0x07) + 1); 605 *m_result = m; 606 *n_result = n; 607 *p_result = p; 608 609 /* display the found pixelclock values */ 610 LOG(2,("DAC: pix PLL check: requested %fMHz got %fMHz, mnp 0x%02x 0x%02x 0x%02x\n", 611 req_pclk, *calc_pclk, *m_result, *n_result, *p_result)); 612 613 return B_OK; 614 } 615 616 /* find nearest valid pixel PLL setting: rewritten by rudolf */ 617 static status_t g450_g550_dac_pix_pll_find 618 (display_mode target,float * calc_pclk,uint8 * m_result,uint8 * n_result,uint8 * p_result, uint8 test) 619 { 620 int m = 0, n = 0; 621 uint8 p = 0, q = 0; 622 float error, error_best = 999999999; 623 int best[3]; 624 float f_vco, max_pclk; 625 float req_pclk = target.timing.pixel_clock/1000.0; 626 627 LOG(4,("DAC: G450/G550 restrictions apply\n")); 628 629 /* determine the max. pixelclock for the current videomode */ 630 switch (target.space) 631 { 632 case B_CMAP8: 633 max_pclk = si->ps.max_dac1_clock_8; 634 break; 635 case B_RGB15_LITTLE: 636 case B_RGB16_LITTLE: 637 max_pclk = si->ps.max_dac1_clock_16; 638 break; 639 case B_RGB24_LITTLE: 640 max_pclk = si->ps.max_dac1_clock_24; 641 break; 642 case B_RGB32_LITTLE: 643 max_pclk = si->ps.max_dac1_clock_32; 644 break; 645 default: 646 /* use fail-safe value */ 647 max_pclk = si->ps.max_dac1_clock_32; 648 break; 649 } 650 /* if some dualhead mode is active, an extra restriction might apply */ 651 if ((target.flags & DUALHEAD_BITS) && (target.space == B_RGB32_LITTLE)) 652 max_pclk = si->ps.max_dac1_clock_32dh; 653 654 /* Make sure the requested pixelclock is within the PLL's operational limits */ 655 /* lower limit is min_pixel_vco divided by highest postscaler-factor */ 656 if (req_pclk < (si->ps.min_pixel_vco / 16.0)) 657 { 658 LOG(4,("DAC: clamping pixclock: requested %fMHz, set to %fMHz\n", 659 req_pclk, (float)(si->ps.min_pixel_vco / 16.0))); 660 req_pclk = (si->ps.min_pixel_vco / 16.0); 661 } 662 /* upper limit is given by pins in combination with current active mode */ 663 if (req_pclk > max_pclk) 664 { 665 LOG(4,("DAC: clamping pixclock: requested %fMHz, set to %fMHz\n", 666 req_pclk, (float)max_pclk)); 667 req_pclk = max_pclk; 668 } 669 670 /* iterate through all valid PLL postscaler settings */ 671 for (p=0x01; p < 0x20; p = p<<1) 672 { 673 /* calculate the needed VCO frequency for this postscaler setting */ 674 f_vco = req_pclk * p; 675 676 /* check if this is within range of the VCO specs */ 677 if ((f_vco >= si->ps.min_pixel_vco) && (f_vco <= si->ps.max_pixel_vco)) 678 { 679 /* iterate trough all valid reference-frequency postscaler settings */ 680 for (m = 2; m <= 32; m++) 681 { 682 /* calculate VCO postscaler setting for current setup.. */ 683 n = (int)(((f_vco * m) / (si->ps.f_ref * 2)) + 0.5); 684 /* ..and check for validity, BUT: 685 * Keep in mind that we need to be able to test n-3 ... n+3! */ 686 if ((n < (8 + 3)) || (n > (128 - 3))) continue; 687 688 /* find error in frequency this setting gives */ 689 error = fabs(req_pclk - ((((si->ps.f_ref * 2)/ m) * n) / p)); 690 691 /* note the setting if best yet */ 692 if (error < error_best) 693 { 694 error_best = error; 695 best[0]=m; 696 best[1]=n; 697 best[2]=p; 698 } 699 } 700 } 701 } 702 703 /* setup the scalers programming values for found optimum setting */ 704 m=best[0] - 1; 705 n=best[1] - 2; 706 switch(best[2]) 707 { 708 case 1: 709 p = 0x40; 710 break; 711 case 2: 712 p = 0x00; 713 break; 714 case 4: 715 p = 0x01; 716 break; 717 case 8: 718 p = 0x02; 719 break; 720 case 16: 721 p = 0x03; 722 break; 723 } 724 725 /* log the closest VCO speed found */ 726 f_vco = ((si->ps.f_ref * 2) / (m + 1)) * (n + 2); 727 LOG(2,("DAC: pix VCO frequency found %fMhz\n", f_vco)); 728 729 /* now find the filtersetting that matches best with this frequency by testing. 730 * for now we assume this routine succeeds to get us a stable setting */ 731 if (test) 732 gx50_dac_check_pix_pll_range(m, n, &p, &q); 733 else 734 LOG(2,("DAC: Not testing G450/G550 VCO feedback filters\n")); 735 736 /* return the results */ 737 *calc_pclk = f_vco / best[2]; 738 *m_result = m; 739 *n_result = n; 740 *p_result = p; 741 742 /* display the found pixelclock values */ 743 LOG(2,("DAC: pix PLL check: requested %fMHz got %fMHz, mnp 0x%02x 0x%02x 0x%02x\n", 744 req_pclk, *calc_pclk, *m_result, *n_result, *p_result)); 745 746 return B_OK; 747 } 748 749 /* find nearest valid system PLL setting */ 750 static status_t g100_g400max_dac_sys_pll_find( 751 float req_sclk,float * calc_sclk,uint8 * m_result,uint8 * n_result,uint8 * p_result) 752 { 753 int m = 0, n = 0, p = 0, m_max; 754 float error, error_best = 999999999; 755 int best[3]; 756 float f_vco; 757 758 /* determine the max. reference-frequency postscaler setting for the 759 * current card (see G100, G200 and G400 specs). */ 760 switch(si->ps.card_type) 761 { 762 case G100: 763 LOG(4,("DAC: G100 restrictions apply\n")); 764 m_max = 7; 765 break; 766 case G200: 767 LOG(4,("DAC: G200 restrictions apply\n")); 768 m_max = 7; 769 break; 770 default: 771 LOG(4,("DAC: G400/G400MAX restrictions apply\n")); 772 m_max = 32; 773 break; 774 } 775 776 /* Make sure the requested systemclock is within the PLL's operational limits */ 777 /* lower limit is min_system_vco divided by highest postscaler-factor */ 778 if (req_sclk < (si->ps.min_system_vco / 8.0)) 779 { 780 LOG(4,("DAC: clamping sysclock: requested %fMHz, set to %fMHz\n", 781 req_sclk, (float)(si->ps.min_system_vco / 8.0))); 782 req_sclk = (si->ps.min_system_vco / 8.0); 783 } 784 /* upper limit is max_system_vco */ 785 if (req_sclk > si->ps.max_system_vco) 786 { 787 LOG(4,("DAC: clamping sysclock: requested %fMHz, set to %fMHz\n", 788 req_sclk, (float)si->ps.max_system_vco)); 789 req_sclk = si->ps.max_system_vco; 790 } 791 792 /* iterate through all valid PLL postscaler settings */ 793 for (p=0x01; p < 0x10; p = p<<1) 794 { 795 /* calculate the needed VCO frequency for this postscaler setting */ 796 f_vco = req_sclk * p; 797 798 /* check if this is within range of the VCO specs */ 799 if ((f_vco >= si->ps.min_system_vco) && (f_vco <= si->ps.max_system_vco)) 800 { 801 /* iterate trough all valid reference-frequency postscaler settings */ 802 for (m = 2; m <= m_max; m++) 803 { 804 /* calculate VCO postscaler setting for current setup.. */ 805 n = (int)(((f_vco * m) / si->ps.f_ref) + 0.5); 806 /* ..and check for validity */ 807 if ((n < 8) || (n > 128)) continue; 808 809 /* find error in frequency this setting gives */ 810 error = fabs(req_sclk - (((si->ps.f_ref / m) * n) / p)); 811 812 /* note the setting if best yet */ 813 if (error < error_best) 814 { 815 error_best = error; 816 best[0]=m; 817 best[1]=n; 818 best[2]=p; 819 } 820 } 821 } 822 } 823 824 /* setup the scalers programming values for found optimum setting */ 825 m=best[0] - 1; 826 n=best[1] - 1; 827 p=best[2] - 1; 828 829 /* calc the needed PLL loopbackfilter setting belonging to current VCO speed, 830 * for the current card (see G100, G200 and G400 specs). */ 831 f_vco = (si->ps.f_ref / (m + 1)) * (n + 1); 832 LOG(2,("DAC: sys VCO frequency found %fMhz\n", f_vco)); 833 834 switch(si->ps.card_type) 835 { 836 case G100: 837 case G200: 838 for(;;) 839 { 840 if (f_vco >= 180) {p |= (0x03 << 3); break;}; 841 if (f_vco >= 140) {p |= (0x02 << 3); break;}; 842 if (f_vco >= 100) {p |= (0x01 << 3); break;}; 843 break; 844 } 845 break; 846 default: 847 for(;;) 848 { 849 if (f_vco >= 240) {p |= (0x03 << 3); break;}; 850 if (f_vco >= 170) {p |= (0x02 << 3); break;}; 851 if (f_vco >= 110) {p |= (0x01 << 3); break;}; 852 break; 853 } 854 break; 855 } 856 857 /* return the results */ 858 *calc_sclk = f_vco / ((p & 0x07) + 1); 859 *m_result = m; 860 *n_result = n; 861 *p_result = p; 862 863 /* display the found pixelclock values */ 864 LOG(2,("DAC: sys PLL check: requested %fMHz got %fMHz, mnp 0x%02x 0x%02x 0x%02x\n", 865 req_sclk, *calc_sclk, *m_result, *n_result, *p_result)); 866 867 return B_OK; 868 } 869 870 static status_t gx50_dac_check_sys_pll(uint8 m, uint8 n, uint8 p) 871 { 872 uint time = 0, count = 0; 873 874 /* program the new clock */ 875 DXIW(SYSPLLM, m); 876 DXIW(SYSPLLN, n); 877 DXIW(SYSPLLP, p); 878 879 /* Wait for the SYSPLL frequency to lock until timeout occurs */ 880 time = 0; 881 while((!(DXIR(SYSPLLSTAT)&0x40)) & (time <= 1000)) 882 { 883 time++; 884 snooze(1); 885 } 886 887 /* no lock aquired, not useable */ 888 if (time > 1000) return B_ERROR; 889 890 /* check if lock holds for at least 90% of the time */ 891 for (time = 0, count = 0; time <= 1000; time++) 892 { 893 if(DXIR(SYSPLLSTAT)&0x40) count++; 894 snooze(1); 895 } 896 /* we have a winner */ 897 if (count >= 900) return B_OK; 898 899 /* nogo, the PLL does not stabilize */ 900 return B_ERROR; 901 } 902 903 static status_t gx50_dac_check_sys_pll_range(uint8 m, uint8 n, uint8 *p, uint8 *q) 904 { 905 uint8 s=0, p_backup = *p; 906 907 /* preset no candidate, non working setting */ 908 *q = 0; 909 /* preset lowest range filter */ 910 *p &= 0x47; 911 912 /* iterate through all possible filtersettings */ 913 for (s = 0; s < 8 ;s++) 914 { 915 if (gx50_dac_check_sys_pll(m, n, *p)== B_OK) 916 { 917 /* now check 3 closest lower and higher settings */ 918 if ((gx50_dac_check_sys_pll(m, n - 3, *p)== B_OK) && 919 (gx50_dac_check_sys_pll(m, n - 2, *p)== B_OK) && 920 (gx50_dac_check_sys_pll(m, n - 1, *p)== B_OK) && 921 (gx50_dac_check_sys_pll(m, n + 1, *p)== B_OK) && 922 (gx50_dac_check_sys_pll(m, n + 2, *p)== B_OK) && 923 (gx50_dac_check_sys_pll(m, n + 3, *p)== B_OK)) 924 { 925 LOG(2,("DAC: found optimal working VCO filter: #%d\n",s)); 926 /* preset first choice setting found */ 927 *q = 1; 928 /* we are done */ 929 return B_OK; 930 } 931 else 932 { 933 LOG(2,("DAC: found critical but working VCO filter: #%d\n",s)); 934 /* preset backup setting found */ 935 *q = 2; 936 /* remember this setting */ 937 p_backup = *p; 938 /* let's continue to see if a better filter exists */ 939 } 940 } 941 /* new filtersetting to try */ 942 *p += (1 << 3); 943 } 944 945 /* return the (last found) backup result, or the original p value */ 946 *p = p_backup; 947 /* we found only a non-optimal value */ 948 if (*q == 2) return B_OK; 949 950 /* nothing worked at all */ 951 LOG(2,("DAC: no working VCO filter found!\n")); 952 return B_ERROR; 953 } 954 955 /* find nearest valid system PLL setting */ 956 static status_t g450_g550_dac_sys_pll_find( 957 float req_sclk,float * calc_sclk,uint8 * m_result,uint8 * n_result,uint8 * p_result) 958 { 959 int m = 0, n = 0; 960 uint8 p = 0, q = 0; 961 float error, error_best = 999999999; 962 int best[3]; 963 float f_vco; 964 965 LOG(4,("DAC: G450/G550 restrictions apply\n")); 966 967 /* Make sure the requested pixelclock is within the PLL's operational limits */ 968 /* lower limit is min_system_vco divided by highest postscaler-factor */ 969 if (req_sclk < (si->ps.min_system_vco / 16.0)) 970 { 971 LOG(4,("DAC: clamping sysclock: requested %fMHz, set to %fMHz\n", 972 req_sclk, (float)(si->ps.min_system_vco / 16.0))); 973 req_sclk = (si->ps.min_system_vco / 16.0); 974 } 975 /* upper limit is max_system_vco */ 976 if (req_sclk > si->ps.max_system_vco) 977 { 978 LOG(4,("DAC: clamping sysclock: requested %fMHz, set to %fMHz\n", 979 req_sclk, (float)si->ps.max_system_vco)); 980 req_sclk = si->ps.max_system_vco; 981 } 982 983 /* iterate through all valid PLL postscaler settings */ 984 for (p=0x01; p < 0x20; p = p<<1) 985 { 986 /* calculate the needed VCO frequency for this postscaler setting */ 987 f_vco = req_sclk * p; 988 989 /* check if this is within range of the VCO specs */ 990 if ((f_vco >= si->ps.min_system_vco) && (f_vco <= si->ps.max_system_vco)) 991 { 992 /* iterate trough all valid reference-frequency postscaler settings */ 993 for (m = 2; m <= 32; m++) 994 { 995 /* calculate VCO postscaler setting for current setup.. */ 996 n = (int)(((f_vco * m) / (si->ps.f_ref * 2)) + 0.5); 997 /* ..and check for validity, BUT: 998 * Keep in mind that we need to be able to test n-3 ... n+3! */ 999 if ((n < (8 + 3)) || (n > (128 - 3))) continue; 1000 1001 /* find error in frequency this setting gives */ 1002 error = fabs(req_sclk - ((((si->ps.f_ref * 2)/ m) * n) / p)); 1003 1004 /* note the setting if best yet */ 1005 if (error < error_best) 1006 { 1007 error_best = error; 1008 best[0]=m; 1009 best[1]=n; 1010 best[2]=p; 1011 } 1012 } 1013 } 1014 } 1015 1016 /* setup the scalers programming values for found optimum setting */ 1017 m=best[0] - 1; 1018 n=best[1] - 2; 1019 switch(best[2]) 1020 { 1021 case 1: 1022 p = 0x40; 1023 break; 1024 case 2: 1025 p = 0x00; 1026 break; 1027 case 4: 1028 p = 0x01; 1029 break; 1030 case 8: 1031 p = 0x02; 1032 break; 1033 case 16: 1034 p = 0x03; 1035 break; 1036 } 1037 1038 /* log the closest VCO speed found */ 1039 f_vco = ((si->ps.f_ref * 2) / (m + 1)) * (n + 2); 1040 LOG(2,("DAC: sys VCO frequency found %fMhz\n", f_vco)); 1041 1042 /* now find the filtersetting that matches best with this frequency by testing. 1043 * for now we assume this routine succeeds to get us a stable setting */ 1044 gx50_dac_check_sys_pll_range(m, n, &p, &q); 1045 1046 /* return the results */ 1047 *calc_sclk = f_vco / best[2]; 1048 *m_result = m; 1049 *n_result = n; 1050 *p_result = p; 1051 1052 /* display the found pixelclock values */ 1053 LOG(2,("DAC: sys PLL check: requested %fMHz got %fMHz, mnp 0x%02x 0x%02x 0x%02x\n", 1054 req_sclk, *calc_sclk, *m_result, *n_result, *p_result)); 1055 1056 return B_OK; 1057 } 1058 1059 /*set up system pll - NB mclk is memory clock */ 1060 status_t g100_dac_set_sys_pll() 1061 { 1062 /* values for DAC sys pll registers */ 1063 uint8 m, n, p; 1064 uint time = 0; 1065 uint32 temp; 1066 float calc_sclk; 1067 1068 LOG(1,("DAC: Setting up G100 system clock\n")); 1069 g100_g400max_dac_sys_pll_find((float)si->ps.std_engine_clock, &calc_sclk, &m, &n, &p); 1070 1071 /* reprogram the clock - set PCI/AGP, program, set to programmed */ 1072 /* disable the SYSPLL */ 1073 CFGW(OPTION, CFGR(OPTION) | 0x04); 1074 /* select the PCI/AGP clock */ 1075 CFGW(OPTION, CFGR(OPTION) & 0xfffffffc); 1076 /* enable the SYSPLL */ 1077 CFGW(OPTION, CFGR(OPTION) & 0xfffffffb); 1078 1079 /* program the new clock */ 1080 DXIW(SYSPLLM, m); 1081 DXIW(SYSPLLN, n); 1082 DXIW(SYSPLLP, p); 1083 1084 /* Wait for the SYSPLL frequency to lock until timeout occurs */ 1085 while((!(DXIR(SYSPLLSTAT)&0x40)) & (time <= 2000)) 1086 { 1087 time++; 1088 snooze(1); 1089 } 1090 1091 if (time > 2000) 1092 LOG(2,("DAC: sys PLL frequency not locked!\n")); 1093 else 1094 LOG(2,("DAC: sys PLL frequency locked\n")); 1095 1096 /* disable the SYSPLL */ 1097 CFGW(OPTION, CFGR(OPTION) | 0x04); 1098 /* setup Gclk, Mclk and FMclk divisors according to PINS */ 1099 temp = (CFGR(OPTION) & 0xffffff27); 1100 if (si->ps.v3_clk_div & 0x01) temp |= 0x08; 1101 if (si->ps.v3_clk_div & 0x02) temp |= 0x10; 1102 if (si->ps.v3_clk_div & 0x04) temp |= 0x80; 1103 /* fixme: swapPLL can only be done when the rest of the driver respects this also! */ 1104 //never used AFAIK: 1105 //if (si->ps.v3_clk_div & 0x08) temp |= 0x40; 1106 /* select the SYSPLL as system clock source */ 1107 temp |= 0x01; 1108 CFGW(OPTION, temp); 1109 /* enable the SYSPLL (and make sure the SYSPLL is indeed powered up) */ 1110 CFGW(OPTION, (CFGR(OPTION) & 0xfffffffb) | 0x20); 1111 1112 return B_OK; 1113 } 1114 1115 /*set up system pll - NB mclk is memory clock */ 1116 status_t g200_dac_set_sys_pll() 1117 { 1118 /* values for DAC sys pll registers */ 1119 uint8 m, n, p; 1120 uint time = 0; 1121 uint32 temp; 1122 float calc_sclk; 1123 1124 LOG(1,("DAC: Setting up G200 system clock\n")); 1125 g100_g400max_dac_sys_pll_find((float)si->ps.std_engine_clock, &calc_sclk, &m, &n, &p); 1126 1127 /* reprogram the clock - set PCI/AGP, program, set to programmed */ 1128 /* disable the SYSPLL */ 1129 CFGW(OPTION, CFGR(OPTION) | 0x04); 1130 /* select the PCI/AGP clock */ 1131 CFGW(OPTION, CFGR(OPTION) & 0xfffffffc); 1132 /* enable the SYSPLL */ 1133 CFGW(OPTION, CFGR(OPTION) & 0xfffffffb); 1134 1135 /* program the new clock */ 1136 DXIW(SYSPLLM, m); 1137 DXIW(SYSPLLN, n); 1138 DXIW(SYSPLLP, p); 1139 1140 /* Wait for the SYSPLL frequency to lock until timeout occurs */ 1141 while((!(DXIR(SYSPLLSTAT)&0x40)) & (time <= 2000)) 1142 { 1143 time++; 1144 snooze(1); 1145 } 1146 1147 if (time > 2000) 1148 LOG(2,("DAC: sys PLL frequency not locked!\n")); 1149 else 1150 LOG(2,("DAC: sys PLL frequency locked\n")); 1151 1152 /* disable the SYSPLL */ 1153 CFGW(OPTION, CFGR(OPTION) | 0x04); 1154 /* setup Wclk divisor and enable/disable Wclk, Gclk and Mclk divisors 1155 * according to PINS */ 1156 temp = (CFGR(OPTION2) & 0x00383000); 1157 if (si->ps.v3_option2_reg & 0x04) temp |= 0x00004000; 1158 if (si->ps.v3_option2_reg & 0x08) temp |= 0x00008000; 1159 if (si->ps.v3_option2_reg & 0x10) temp |= 0x00010000; 1160 if (si->ps.v3_option2_reg & 0x20) temp |= 0x00020000; 1161 CFGW(OPTION2, temp); 1162 /* setup Gclk and Mclk divisors according to PINS */ 1163 temp = (CFGR(OPTION) & 0xffffff27); 1164 if (si->ps.v3_clk_div & 0x01) temp |= 0x08; 1165 if (si->ps.v3_clk_div & 0x02) temp |= 0x10; 1166 /* fixme: swapPLL can only be done when the rest of the driver respects this also! */ 1167 //never used AFAIK: 1168 //if (si->ps.v3_clk_div & 0x08) temp |= 0x40; 1169 /* select the SYSPLL as system clock source */ 1170 temp |= 0x01; 1171 CFGW(OPTION, temp); 1172 /* enable the SYSPLL (and make sure the SYSPLL is indeed powered up) */ 1173 CFGW(OPTION, (CFGR(OPTION) & 0xfffffffb) | 0x20); 1174 1175 return B_OK; 1176 } 1177 1178 /*set up system pll - NB mclk is memory clock */ 1179 status_t g400_dac_set_sys_pll() 1180 { 1181 /* values for DAC sys pll registers */ 1182 uint8 m, n, p; 1183 uint time = 0; 1184 float calc_sclk; 1185 1186 LOG(1,("DAC: Setting up G400/G400MAX system clock\n")); 1187 g100_g400max_dac_sys_pll_find((float)si->ps.std_engine_clock, &calc_sclk, &m, &n, &p); 1188 1189 /* reprogram the clock - set PCI/AGP, program, set to programmed */ 1190 /* clear, so don't o/clock addons */ 1191 CFGW(OPTION2, 0); 1192 /* disable the SYSPLL */ 1193 CFGW(OPTION, CFGR(OPTION) | 0x04); 1194 /* select the PCI/AGP clock */ 1195 CFGW(OPTION3, 0); 1196 /* enable the SYSPLL */ 1197 CFGW(OPTION, CFGR(OPTION) & 0xfffffffb); 1198 1199 /* program the new clock */ 1200 DXIW(SYSPLLM, m); 1201 DXIW(SYSPLLN, n); 1202 DXIW(SYSPLLP, p); 1203 1204 /* Wait for the SYSPLL frequency to lock until timeout occurs */ 1205 while((!(DXIR(SYSPLLSTAT)&0x40)) & (time <= 2000)) 1206 { 1207 time++; 1208 snooze(1); 1209 } 1210 1211 if (time > 2000) 1212 LOG(2,("DAC: sys PLL frequency not locked!\n")); 1213 else 1214 LOG(2,("DAC: sys PLL frequency locked\n")); 1215 1216 /* disable the SYSPLL */ 1217 CFGW(OPTION, CFGR(OPTION) | 0x04); 1218 /* setup Gclk, Mclk and Wclk divs via PINS and select SYSPLL as system clock source */ 1219 CFGW(OPTION3, si->ps.option3_reg); 1220 /* make sure the PLLs are not swapped (set default config) */ 1221 CFGW(OPTION, CFGR(OPTION) & 0xffffffbf); 1222 /* enable the SYSPLL (and make sure the SYSPLL is indeed powered up) */ 1223 CFGW(OPTION, (CFGR(OPTION) & 0xfffffffb) | 0x20); 1224 1225 return B_OK; 1226 } 1227 1228 /*set up system pll - NB mclk is memory clock */ 1229 status_t g450_dac_set_sys_pll() 1230 { 1231 /* values for DAC sys pll registers */ 1232 uint8 m, n, p; 1233 uint time = 0; 1234 float calc_sclk; 1235 1236 LOG(1,("DAC: Setting up G450/G550 system clock\n")); 1237 /* reprogram the clock - set PCI/AGP, program, set to programmed */ 1238 /* clear, so don't o/clock addons */ 1239 CFGW(OPTION2, 0); 1240 /* setup OPTION via pins */ 1241 CFGW(OPTION, si->ps.option_reg); 1242 /* disable the SYSPLL */ 1243 CFGW(OPTION, CFGR(OPTION) | 0x04); 1244 /* select the PCI/AGP clock */ 1245 CFGW(OPTION3, 0); 1246 /* enable the SYSPLL */ 1247 CFGW(OPTION, CFGR(OPTION) & 0xfffffffb); 1248 1249 /* this routine also tests the filters, so it actually programs the clock already */ 1250 g450_g550_dac_sys_pll_find((float)si->ps.std_engine_clock, &calc_sclk, &m, &n, &p); 1251 1252 /* program the new clock */ 1253 DXIW(SYSPLLM, m); 1254 DXIW(SYSPLLN, n); 1255 DXIW(SYSPLLP, p); 1256 1257 /* Wait for the SYSPLL frequency to lock until timeout occurs */ 1258 while((!(DXIR(SYSPLLSTAT)&0x40)) & (time <= 2000)) 1259 { 1260 time++; 1261 snooze(1); 1262 } 1263 1264 if (time > 2000) 1265 LOG(2,("DAC: sys PLL frequency not locked!\n")); 1266 else 1267 LOG(2,("DAC: sys PLL frequency locked\n")); 1268 1269 /* disable the SYSPLL */ 1270 CFGW(OPTION, CFGR(OPTION) | 0x04); 1271 /* setup Gclk, Mclk and Wclk divs via PINS and select SYSPLL as system clock source */ 1272 CFGW(OPTION3, si->ps.option3_reg); 1273 /* setup option2 via pins */ 1274 CFGW(OPTION2, si->ps.option2_reg); 1275 /* make sure the PLLs are not swapped (set default config) */ 1276 /* fixme: swapPLL can only be done when the rest of the driver respects this also! 1277 * (never used AFAIK) */ 1278 CFGW(OPTION, CFGR(OPTION) & 0xffffffbf); 1279 /* enable the SYSPLL (and make sure the SYSPLL is indeed powered up) */ 1280 CFGW(OPTION, (CFGR(OPTION) & 0xfffffffb) | 0x20); 1281 1282 return B_OK; 1283 } 1284