/* * This function set up the master clock (MCLK). * * Input: Frequency to be set. * * NOTE: * The maximum frequency the engine can run is 168MHz. */ void setMasterClock(unsigned int frequency) { unsigned int ulReg, divisor; #if 1 /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */ if (getChipType() == SM750LE) return; #endif if (frequency != 0) { /* Set the frequency to the maximum frequency that the SM750 engine can run, which is about 190 MHz. */ if (frequency > MHz(190)) frequency = MHz(190); /* Calculate the divisor */ divisor = (unsigned int) roundedDiv(getChipClock(), frequency); /* Set the corresponding divisor in the register. */ ulReg = PEEK32(CURRENT_GATE); switch(divisor) { default: case 3: ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_3); break; case 4: ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_4); break; case 6: ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_6); break; case 8: ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_8); break; } setCurrentGate(ulReg); } }
static void setMemoryClock(unsigned int frequency) { unsigned int reg, divisor; /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */ if (getChipType() == SM750LE) return; if (frequency) { /* Set the frequency to the maximum frequency that the DDR Memory can take which is 336MHz. */ if (frequency > MHz(336)) frequency = MHz(336); /* Calculate the divisor */ divisor = roundedDiv(get_mxclk_freq(), frequency); /* Set the corresponding divisor in the register. */ reg = PEEK32(CURRENT_GATE) & ~CURRENT_GATE_M2XCLK_MASK; switch (divisor) { default: case 1: reg |= CURRENT_GATE_M2XCLK_DIV_1; break; case 2: reg |= CURRENT_GATE_M2XCLK_DIV_2; break; case 3: reg |= CURRENT_GATE_M2XCLK_DIV_3; break; case 4: reg |= CURRENT_GATE_M2XCLK_DIV_4; break; } setCurrentGate(reg); } }
/* * This function set up the master clock (MCLK). * * Input: Frequency to be set. * * NOTE: * The maximum frequency the engine can run is 168MHz. */ static void setMasterClock(unsigned int frequency) { unsigned int reg, divisor; /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */ if (getChipType() == SM750LE) return; if (frequency) { /* Set the frequency to the maximum frequency that the SM750 engine can run, which is about 190 MHz. */ if (frequency > MHz(190)) frequency = MHz(190); /* Calculate the divisor */ divisor = roundedDiv(get_mxclk_freq(), frequency); /* Set the corresponding divisor in the register. */ reg = PEEK32(CURRENT_GATE) & ~CURRENT_GATE_MCLK_MASK; switch (divisor) { default: case 3: reg |= CURRENT_GATE_MCLK_DIV_3; break; case 4: reg |= CURRENT_GATE_MCLK_DIV_4; break; case 6: reg |= CURRENT_GATE_MCLK_DIV_6; break; case 8: reg |= CURRENT_GATE_MCLK_DIV_8; break; } setCurrentGate(reg); } }
unsigned int calcPllValue2( unsigned int ulRequestClk, /* Required pixel clock in Hz unit */ pll_value_t *pPLL /* Structure to hold the value to be set in PLL */ ) { unsigned int M, N, OD, POD = 0, diff, pllClk, odPower, podPower; unsigned int bestDiff = 0xffffffff; /* biggest 32 bit unsigned number */ unsigned int ret; /* Init PLL structure to know states */ pPLL->M = 0; pPLL->N = 0; pPLL->OD = 0; pPLL->POD = 0; /* Sanity check: None at the moment */ /* Convert everything in Khz range in order to avoid calculation overflow */ pPLL->inputFreq /= 1000; ulRequestClk /= 1000; #ifndef VALIDATION_CHIP /* The maximum of post divider is 8. */ for (POD=0; POD<=3; POD++) #endif { #ifndef VALIDATION_CHIP /* MXCLK_PLL does not have post divider. */ if ((POD > 0) && (pPLL->clockType == MXCLK_PLL)) break; #endif /* Work out 2 to the power of POD */ podPower = twoToPowerOfx(POD); /* OD has only 2 bits [15:14] and its value must between 0 to 3 */ for (OD=0; OD<=3; OD++) { /* Work out 2 to the power of OD */ odPower = twoToPowerOfx(OD); #ifdef VALIDATION_CHIP if (odPower > 4) podPower = 4; else podPower = odPower; #endif /* N has 4 bits [11:8] and its value must between 2 and 15. The N == 1 will behave differently --> Result is not correct. */ for (N=2; N<=15; N++) { /* The formula for PLL is ulRequestClk = inputFreq * M / N / (2^OD) In the following steps, we try to work out a best M value given the others are known. To avoid decimal calculation, we use 1000 as multiplier for up to 3 decimal places of accuracy. */ M = ulRequestClk * N * odPower * 1000 / pPLL->inputFreq; M = roundedDiv(M, 1000); /* M field has only 8 bits, reject value bigger than 8 bits */ if (M < 256) { /* Calculate the actual clock for a given M & N */ pllClk = pPLL->inputFreq * M / N / odPower / podPower; /* How much are we different from the requirement */ diff = absDiff(pllClk, ulRequestClk); if (diff < bestDiff) { bestDiff = diff; /* Store M and N values */ pPLL->M = M; pPLL->N = N; pPLL->OD = OD; #ifdef VALIDATION_CHIP if (OD > 2) POD = 2; else POD = OD; #endif pPLL->POD = POD; } } } } } /* Restore input frequency from Khz to hz unit */ // pPLL->inputFreq *= 1000; ulRequestClk *= 1000; pPLL->inputFreq = DEFAULT_INPUT_CLOCK; /* Default reference clock */ /* Output debug information */ //DDKDEBUGPRINT((DISPLAY_LEVEL, "calcPllValue: Requested Frequency = %d\n", ulRequestClk)); //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)); /* Return actual frequency that the PLL can set */ ret = calcPLL(pPLL); return ret; }