1#include "ddk750_help.h" 2#include "ddk750_reg.h" 3#include "ddk750_chip.h" 4#include "ddk750_power.h" 5typedef struct _pllcalparam { 6 unsigned char power;/* d : 0~ 6*/ 7 unsigned char pod; 8 unsigned char od; 9 unsigned char value;/* value of 2 power d (2^d) */ 10} 11pllcalparam; 12 13 14logical_chip_type_t getChipType(void) 15{ 16 unsigned short physicalID; 17 char physicalRev; 18 logical_chip_type_t chip; 19 20 physicalID = devId750;//either 0x718 or 0x750 21 physicalRev = revId750; 22 23 if (physicalID == 0x718) 24 chip = SM718; 25 else if (physicalID == 0x750) { 26 chip = SM750; 27 /* SM750 and SM750LE are different in their revision ID only. */ 28 if (physicalRev == SM750LE_REVISION_ID) 29 chip = SM750LE; 30 } else 31 chip = SM_UNKNOWN; 32 33 return chip; 34} 35 36 37inline unsigned int twoToPowerOfx(unsigned long x) 38{ 39 unsigned long i; 40 unsigned long result = 1; 41 42 for (i = 1; i <= x; i++) 43 result *= 2; 44 return result; 45} 46 47inline unsigned int calcPLL(pll_value_t *pPLL) 48{ 49 return (pPLL->inputFreq * pPLL->M / pPLL->N / twoToPowerOfx(pPLL->OD) / twoToPowerOfx(pPLL->POD)); 50} 51 52unsigned int getPllValue(clock_type_t clockType, pll_value_t *pPLL) 53{ 54 unsigned int ulPllReg = 0; 55 56 pPLL->inputFreq = DEFAULT_INPUT_CLOCK; 57 pPLL->clockType = clockType; 58 59 switch (clockType) { 60 case MXCLK_PLL: 61 ulPllReg = PEEK32(MXCLK_PLL_CTRL); 62 break; 63 case PRIMARY_PLL: 64 ulPllReg = PEEK32(PANEL_PLL_CTRL); 65 break; 66 case SECONDARY_PLL: 67 ulPllReg = PEEK32(CRT_PLL_CTRL); 68 break; 69 case VGA0_PLL: 70 ulPllReg = PEEK32(VGA_PLL0_CTRL); 71 break; 72 case VGA1_PLL: 73 ulPllReg = PEEK32(VGA_PLL1_CTRL); 74 break; 75 } 76 77 pPLL->M = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, M); 78 pPLL->N = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, N); 79 pPLL->OD = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, OD); 80 pPLL->POD = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, POD); 81 82 return calcPLL(pPLL); 83} 84 85 86unsigned int getChipClock(void) 87{ 88 pll_value_t pll; 89#if 1 90 if (getChipType() == SM750LE) 91 return MHz(130); 92#endif 93 94 return getPllValue(MXCLK_PLL, &pll); 95} 96 97 98/* 99 * This function set up the main chip clock. 100 * 101 * Input: Frequency to be set. 102 */ 103void setChipClock(unsigned int frequency) 104{ 105 pll_value_t pll; 106 unsigned int ulActualMxClk; 107#if 1 108 /* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */ 109 if (getChipType() == SM750LE) 110 return; 111#endif 112 113 if (frequency) { 114 /* 115 * Set up PLL, a structure to hold the value to be set in clocks. 116 */ 117 pll.inputFreq = DEFAULT_INPUT_CLOCK; /* Defined in CLOCK.H */ 118 pll.clockType = MXCLK_PLL; 119 120 /* 121 * Call calcPllValue() to fill up the other fields for PLL structure. 122 * Sometime, the chip cannot set up the exact clock required by User. 123 * Return value from calcPllValue() gives the actual possible clock. 124 */ 125 ulActualMxClk = calcPllValue(frequency, &pll); 126 127 /* Master Clock Control: MXCLK_PLL */ 128 POKE32(MXCLK_PLL_CTRL, formatPllReg(&pll)); 129 } 130} 131 132 133 134void setMemoryClock(unsigned int frequency) 135{ 136 unsigned int ulReg, divisor; 137 #if 1 138 /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */ 139 if (getChipType() == SM750LE) 140 return; 141#endif 142 if (frequency) { 143 /* Set the frequency to the maximum frequency that the DDR Memory can take 144 which is 336MHz. */ 145 if (frequency > MHz(336)) 146 frequency = MHz(336); 147 148 /* Calculate the divisor */ 149 divisor = (unsigned int) roundedDiv(getChipClock(), frequency); 150 151 /* Set the corresponding divisor in the register. */ 152 ulReg = PEEK32(CURRENT_GATE); 153 switch (divisor) { 154 default: 155 case 1: 156 ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_1); 157 break; 158 case 2: 159 ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_2); 160 break; 161 case 3: 162 ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_3); 163 break; 164 case 4: 165 ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_4); 166 break; 167 } 168 169 setCurrentGate(ulReg); 170 } 171} 172 173 174/* 175 * This function set up the master clock (MCLK). 176 * 177 * Input: Frequency to be set. 178 * 179 * NOTE: 180 * The maximum frequency the engine can run is 168MHz. 181 */ 182void setMasterClock(unsigned int frequency) 183{ 184 unsigned int ulReg, divisor; 185#if 1 186 /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */ 187 if (getChipType() == SM750LE) 188 return; 189#endif 190 if (frequency) { 191 /* Set the frequency to the maximum frequency that the SM750 engine can 192 run, which is about 190 MHz. */ 193 if (frequency > MHz(190)) 194 frequency = MHz(190); 195 196 /* Calculate the divisor */ 197 divisor = (unsigned int) roundedDiv(getChipClock(), frequency); 198 199 /* Set the corresponding divisor in the register. */ 200 ulReg = PEEK32(CURRENT_GATE); 201 switch (divisor) { 202 default: 203 case 3: 204 ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_3); 205 break; 206 case 4: 207 ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_4); 208 break; 209 case 6: 210 ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_6); 211 break; 212 case 8: 213 ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_8); 214 break; 215 } 216 217 setCurrentGate(ulReg); 218 } 219} 220 221 222unsigned int ddk750_getVMSize(void) 223{ 224 unsigned int reg; 225 unsigned int data; 226 227 /* sm750le only use 64 mb memory*/ 228 if (getChipType() == SM750LE) 229 return MB(64); 230 231 /* for 750,always use power mode0*/ 232 reg = PEEK32(MODE0_GATE); 233 reg = FIELD_SET(reg, MODE0_GATE, GPIO, ON); 234 POKE32(MODE0_GATE, reg); 235 236 /* get frame buffer size from GPIO */ 237 reg = FIELD_GET(PEEK32(MISC_CTRL), MISC_CTRL, LOCALMEM_SIZE); 238 switch (reg) { 239 case MISC_CTRL_LOCALMEM_SIZE_8M: 240 data = MB(8); break; /* 8 Mega byte */ 241 case MISC_CTRL_LOCALMEM_SIZE_16M: 242 data = MB(16); break; /* 16 Mega byte */ 243 case MISC_CTRL_LOCALMEM_SIZE_32M: 244 data = MB(32); break; /* 32 Mega byte */ 245 case MISC_CTRL_LOCALMEM_SIZE_64M: 246 data = MB(64); break; /* 64 Mega byte */ 247 default: 248 data = 0; 249 break; 250 } 251 return data; 252 253} 254 255int ddk750_initHw(initchip_param_t *pInitParam) 256{ 257 258 unsigned int ulReg; 259#if 0 260 //move the code to map regiter function. 261 if (getChipType() == SM718) { 262 /* turn on big endian bit*/ 263 ulReg = PEEK32(0x74); 264 /* now consider register definition in a big endian pattern*/ 265 POKE32(0x74, ulReg|0x80000000); 266 } 267 268#endif 269 270 271 if (pInitParam->powerMode != 0 ) 272 pInitParam->powerMode = 0; 273 setPowerMode(pInitParam->powerMode); 274 275 /* Enable display power gate & LOCALMEM power gate*/ 276 ulReg = PEEK32(CURRENT_GATE); 277 ulReg = FIELD_SET(ulReg, CURRENT_GATE, DISPLAY, ON); 278 ulReg = FIELD_SET(ulReg, CURRENT_GATE, LOCALMEM, ON); 279 setCurrentGate(ulReg); 280 281 if (getChipType() != SM750LE) { 282 /* set panel pll and graphic mode via mmio_88 */ 283 ulReg = PEEK32(VGA_CONFIGURATION); 284 ulReg = FIELD_SET(ulReg, VGA_CONFIGURATION, PLL, PANEL); 285 ulReg = FIELD_SET(ulReg, VGA_CONFIGURATION, MODE, GRAPHIC); 286 POKE32(VGA_CONFIGURATION, ulReg); 287 } else { 288#if defined(__i386__) || defined( __x86_64__) 289 /* set graphic mode via IO method */ 290 outb_p(0x88, 0x3d4); 291 outb_p(0x06, 0x3d5); 292#endif 293 } 294 295 /* Set the Main Chip Clock */ 296 setChipClock(MHz((unsigned int)pInitParam->chipClock)); 297 298 /* Set up memory clock. */ 299 setMemoryClock(MHz(pInitParam->memClock)); 300 301 /* Set up master clock */ 302 setMasterClock(MHz(pInitParam->masterClock)); 303 304 305 /* Reset the memory controller. If the memory controller is not reset in SM750, 306 the system might hang when sw accesses the memory. 307 The memory should be resetted after changing the MXCLK. 308 */ 309 if (pInitParam->resetMemory == 1) { 310 ulReg = PEEK32(MISC_CTRL); 311 ulReg = FIELD_SET(ulReg, MISC_CTRL, LOCALMEM_RESET, RESET); 312 POKE32(MISC_CTRL, ulReg); 313 314 ulReg = FIELD_SET(ulReg, MISC_CTRL, LOCALMEM_RESET, NORMAL); 315 POKE32(MISC_CTRL, ulReg); 316 } 317 318 if (pInitParam->setAllEngOff == 1) { 319 enable2DEngine(0); 320 321 /* Disable Overlay, if a former application left it on */ 322 ulReg = PEEK32(VIDEO_DISPLAY_CTRL); 323 ulReg = FIELD_SET(ulReg, VIDEO_DISPLAY_CTRL, PLANE, DISABLE); 324 POKE32(VIDEO_DISPLAY_CTRL, ulReg); 325 326 /* Disable video alpha, if a former application left it on */ 327 ulReg = PEEK32(VIDEO_ALPHA_DISPLAY_CTRL); 328 ulReg = FIELD_SET(ulReg, VIDEO_ALPHA_DISPLAY_CTRL, PLANE, DISABLE); 329 POKE32(VIDEO_ALPHA_DISPLAY_CTRL, ulReg); 330 331 /* Disable alpha plane, if a former application left it on */ 332 ulReg = PEEK32(ALPHA_DISPLAY_CTRL); 333 ulReg = FIELD_SET(ulReg, ALPHA_DISPLAY_CTRL, PLANE, DISABLE); 334 POKE32(ALPHA_DISPLAY_CTRL, ulReg); 335 336#if 0 337 /* Disable LCD hardware cursor, if a former application left it on */ 338 ulReg = PEEK32(PANEL_HWC_ADDRESS); 339 ulReg = FIELD_SET(ulReg, PANEL_HWC_ADDRESS, ENABLE, DISABLE); 340 POKE32(PANEL_HWC_ADDRESS, ulReg); 341 342 /* Disable CRT hardware cursor, if a former application left it on */ 343 ulReg = PEEK32(CRT_HWC_ADDRESS); 344 ulReg = FIELD_SET(ulReg, CRT_HWC_ADDRESS, ENABLE, DISABLE); 345 POKE32(CRT_HWC_ADDRESS, ulReg); 346 347 /* Disable ZV Port 0, if a former application left it on */ 348 ulReg = PEEK32(ZV0_CAPTURE_CTRL); 349 ulReg = FIELD_SET(ulReg, ZV0_CAPTURE_CTRL, CAP, DISABLE); 350 POKE32(ZV0_CAPTURE_CTRL, ulReg); 351 352 /* Disable ZV Port 1, if a former application left it on */ 353 ulReg = PEEK32(ZV1_CAPTURE_CTRL); 354 ulReg = FIELD_SET(ulReg, ZV1_CAPTURE_CTRL, CAP, DISABLE); 355 POKE32(ZV1_CAPTURE_CTRL, ulReg); 356 357 /* Disable ZV Port Power, if a former application left it on */ 358 enableZVPort(0); 359 /* Disable DMA Channel, if a former application left it on */ 360 ulReg = PEEK32(DMA_ABORT_INTERRUPT); 361 ulReg = FIELD_SET(ulReg, DMA_ABORT_INTERRUPT, ABORT_1, ABORT); 362 POKE32(DMA_ABORT_INTERRUPT, ulReg); 363 364 /* Disable i2c */ 365 enableI2C(0); 366#endif 367 /* Disable DMA Channel, if a former application left it on */ 368 ulReg = PEEK32(DMA_ABORT_INTERRUPT); 369 ulReg = FIELD_SET(ulReg, DMA_ABORT_INTERRUPT, ABORT_1, ABORT); 370 POKE32(DMA_ABORT_INTERRUPT, ulReg); 371 372 /* Disable DMA Power, if a former application left it on */ 373 enableDMA(0); 374 } 375 376 /* We can add more initialization as needed. */ 377 378 return 0; 379} 380 381#if 0 382 383unsigned int absDiff(unsigned int a, unsigned int b) 384{ 385 if ( a > b ) 386 return(a - b); 387 else 388 return(b - a); 389} 390 391#endif 392/* 393 monk liu @ 4/6/2011: 394 re-write the calculatePLL function of ddk750. 395 the original version function does not use some mathematics tricks and shortcut 396 when it doing the calculation of the best N,M,D combination 397 I think this version gives a little upgrade in speed 398 399 750 pll clock formular: 400 Request Clock = (Input Clock * M )/(N * X) 401 402 Input Clock = 14318181 hz 403 X = 2 power D 404 D ={0,1,2,3,4,5,6} 405 M = {1,...,255} 406 N = {2,...,15} 407*/ 408unsigned int calcPllValue(unsigned int request_orig, pll_value_t *pll) 409{ 410 /* used for primary and secondary channel pixel clock pll */ 411 static pllcalparam xparm_PIXEL[] = { 412 /* 2^0 = 1*/ {0, 0, 0, 1}, 413 /* 2^ 1 =2*/ {1, 0, 1, 2}, 414 /* 2^ 2 = 4*/ {2, 0, 2, 4}, 415 {3, 0, 3, 8}, 416 {4, 1, 3, 16}, 417 {5, 2, 3, 32}, 418 /* 2^6 = 64 */ {6, 3, 3, 64}, 419 }; 420 421 /* used for MXCLK (chip clock) */ 422 static pllcalparam xparm_MXCLK[] = { 423 /* 2^0 = 1*/ {0, 0, 0, 1}, 424 /* 2^ 1 =2*/ {1, 0, 1, 2}, 425 /* 2^ 2 = 4*/ {2, 0, 2, 4}, 426 {3, 0, 3, 8}, 427 }; 428 429 /* as sm750 register definition, N located in 2,15 and M located in 1,255 */ 430 int N, M, X, d; 431 int xcnt; 432 int miniDiff; 433 unsigned int RN, quo, rem, fl_quo; 434 unsigned int input, request; 435 unsigned int tmpClock, ret; 436 pllcalparam * xparm; 437 438#if 1 439 if (getChipType() == SM750LE) { 440 /* SM750LE don't have prgrammable PLL and M/N values to work on. 441 Just return the requested clock. */ 442 return request_orig; 443 } 444#endif 445 446 ret = 0; 447 miniDiff = ~0; 448 request = request_orig / 1000; 449 input = pll->inputFreq / 1000; 450 451 /* for MXCLK register , no POD provided, so need be treated differently */ 452 453 if (pll->clockType != MXCLK_PLL) { 454 xparm = &xparm_PIXEL[0]; 455 xcnt = sizeof(xparm_PIXEL)/sizeof(xparm_PIXEL[0]); 456 } else { 457 xparm = &xparm_MXCLK[0]; 458 xcnt = sizeof(xparm_MXCLK)/sizeof(xparm_MXCLK[0]); 459 } 460 461 462 for (N = 15; N > 1; N--) { 463 /* RN will not exceed maximum long if @request <= 285 MHZ (for 32bit cpu) */ 464 RN = N * request; 465 quo = RN / input; 466 rem = RN % input;/* rem always small than 14318181 */ 467 fl_quo = (rem * 10000 /input); 468 469 for (d = xcnt - 1; d >= 0; d--) { 470 X = xparm[d].value; 471 M = quo*X; 472 M += fl_quo * X / 10000; 473 /* round step */ 474 M += (fl_quo*X % 10000)>5000?1:0; 475 if (M < 256 && M > 0) { 476 unsigned int diff; 477 tmpClock = pll->inputFreq *M / N / X; 478 diff = absDiff(tmpClock, request_orig); 479 if (diff < miniDiff) { 480 pll->M = M; 481 pll->N = N; 482 pll->OD = xparm[d].od; 483 pll->POD = xparm[d].pod; 484 miniDiff = diff; 485 ret = tmpClock; 486 } 487 } 488 } 489 } 490 491 //printk("Finally: pll->n[%lu],m[%lu],od[%lu],pod[%lu]\n",pll->N,pll->M,pll->OD,pll->POD); 492 return ret; 493} 494 495unsigned int calcPllValue2( 496unsigned int ulRequestClk, /* Required pixel clock in Hz unit */ 497pll_value_t *pPLL /* Structure to hold the value to be set in PLL */ 498) 499{ 500 unsigned int M, N, OD, POD = 0, diff, pllClk, odPower, podPower; 501 unsigned int bestDiff = 0xffffffff; /* biggest 32 bit unsigned number */ 502 unsigned int ret; 503 /* Init PLL structure to know states */ 504 pPLL->M = 0; 505 pPLL->N = 0; 506 pPLL->OD = 0; 507 pPLL->POD = 0; 508 509 /* Sanity check: None at the moment */ 510 511 /* Convert everything in Khz range in order to avoid calculation overflow */ 512 pPLL->inputFreq /= 1000; 513 ulRequestClk /= 1000; 514 515#ifndef VALIDATION_CHIP 516 /* The maximum of post divider is 8. */ 517 for (POD = 0; POD <= 3; POD++) 518#endif 519 { 520 521#ifndef VALIDATION_CHIP 522 /* MXCLK_PLL does not have post divider. */ 523 if ((POD > 0) && (pPLL->clockType == MXCLK_PLL)) 524 break; 525#endif 526 527 /* Work out 2 to the power of POD */ 528 podPower = twoToPowerOfx(POD); 529 530 /* OD has only 2 bits [15:14] and its value must between 0 to 3 */ 531 for (OD = 0; OD <= 3; OD++) { 532 /* Work out 2 to the power of OD */ 533 odPower = twoToPowerOfx(OD); 534 535#ifdef VALIDATION_CHIP 536 if (odPower > 4) 537 podPower = 4; 538 else 539 podPower = odPower; 540#endif 541 542 /* N has 4 bits [11:8] and its value must between 2 and 15. 543 The N == 1 will behave differently --> Result is not correct. */ 544 for (N = 2; N <= 15; N++) { 545 /* The formula for PLL is ulRequestClk = inputFreq * M / N / (2^OD) 546 In the following steps, we try to work out a best M value given the others are known. 547 To avoid decimal calculation, we use 1000 as multiplier for up to 3 decimal places of accuracy. 548 */ 549 M = ulRequestClk * N * odPower * 1000 / pPLL->inputFreq; 550 M = roundedDiv(M, 1000); 551 552 /* M field has only 8 bits, reject value bigger than 8 bits */ 553 if (M < 256) { 554 /* Calculate the actual clock for a given M & N */ 555 pllClk = pPLL->inputFreq * M / N / odPower / podPower; 556 557 /* How much are we different from the requirement */ 558 diff = absDiff(pllClk, ulRequestClk); 559 560 if (diff < bestDiff) { 561 bestDiff = diff; 562 563 /* Store M and N values */ 564 pPLL->M = M; 565 pPLL->N = N; 566 pPLL->OD = OD; 567 568#ifdef VALIDATION_CHIP 569 if (OD > 2) 570 POD = 2; 571 else 572 POD = OD; 573#endif 574 575 pPLL->POD = POD; 576 } 577 } 578 } 579 } 580 } 581 582 /* Restore input frequency from Khz to hz unit */ 583// pPLL->inputFreq *= 1000; 584 ulRequestClk *= 1000; 585 pPLL->inputFreq = DEFAULT_INPUT_CLOCK; /* Default reference clock */ 586 587 /* Output debug information */ 588 //DDKDEBUGPRINT((DISPLAY_LEVEL, "calcPllValue: Requested Frequency = %d\n", ulRequestClk)); 589 //DDKDEBUGPRINT((DISPLAY_LEVEL, "calcPllValue: Input CLK = %dHz, M=%d, N=%d, OD=%d, POD=%d\n", pPLL->inputFreq, pPLL->M, pPLL->N, pPLL->OD, pPLL->POD)); 590 591 /* Return actual frequency that the PLL can set */ 592 ret = calcPLL(pPLL); 593 return ret; 594} 595 596 597 598 599 600unsigned int formatPllReg(pll_value_t *pPLL) 601{ 602 unsigned int ulPllReg = 0; 603 604 /* Note that all PLL's have the same format. Here, we just use Panel PLL parameter 605 to work out the bit fields in the register. 606 On returning a 32 bit number, the value can be applied to any PLL in the calling function. 607 */ 608 ulPllReg = 609 FIELD_SET( 0, PANEL_PLL_CTRL, BYPASS, OFF) 610 | FIELD_SET( 0, PANEL_PLL_CTRL, POWER, ON) 611 | FIELD_SET( 0, PANEL_PLL_CTRL, INPUT, OSC) 612#ifndef VALIDATION_CHIP 613 | FIELD_VALUE(0, PANEL_PLL_CTRL, POD, pPLL->POD) 614#endif 615 | FIELD_VALUE(0, PANEL_PLL_CTRL, OD, pPLL->OD) 616 | FIELD_VALUE(0, PANEL_PLL_CTRL, N, pPLL->N) 617 | FIELD_VALUE(0, PANEL_PLL_CTRL, M, pPLL->M); 618 619 return ulPllReg; 620} 621 622 623