mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-13 14:14:37 +00:00
6ab5b6d16b
Fixes checkpatch.pl error: ERROR: need consistent spacing around operator Signed-off-by: Juston Li <juston.h.li@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
615 lines
15 KiB
C
615 lines
15 KiB
C
#include "ddk750_help.h"
|
|
#include "ddk750_reg.h"
|
|
#include "ddk750_chip.h"
|
|
#include "ddk750_power.h"
|
|
typedef struct _pllcalparam {
|
|
unsigned char power;/* d : 0~ 6*/
|
|
unsigned char pod;
|
|
unsigned char od;
|
|
unsigned char value;/* value of 2 power d (2^d) */
|
|
}
|
|
pllcalparam;
|
|
|
|
|
|
logical_chip_type_t getChipType(void)
|
|
{
|
|
unsigned short physicalID;
|
|
char physicalRev;
|
|
logical_chip_type_t chip;
|
|
|
|
physicalID = devId750; /* either 0x718 or 0x750 */
|
|
physicalRev = revId750;
|
|
|
|
if (physicalID == 0x718)
|
|
chip = SM718;
|
|
else if (physicalID == 0x750) {
|
|
chip = SM750;
|
|
/* SM750 and SM750LE are different in their revision ID only. */
|
|
if (physicalRev == SM750LE_REVISION_ID)
|
|
chip = SM750LE;
|
|
} else
|
|
chip = SM_UNKNOWN;
|
|
|
|
return chip;
|
|
}
|
|
|
|
|
|
inline unsigned int twoToPowerOfx(unsigned long x)
|
|
{
|
|
unsigned long i;
|
|
unsigned long result = 1;
|
|
|
|
for (i = 1; i <= x; i++)
|
|
result *= 2;
|
|
return result;
|
|
}
|
|
|
|
inline unsigned int calcPLL(pll_value_t *pPLL)
|
|
{
|
|
return (pPLL->inputFreq * pPLL->M / pPLL->N / twoToPowerOfx(pPLL->OD) / twoToPowerOfx(pPLL->POD));
|
|
}
|
|
|
|
unsigned int getPllValue(clock_type_t clockType, pll_value_t *pPLL)
|
|
{
|
|
unsigned int ulPllReg = 0;
|
|
|
|
pPLL->inputFreq = DEFAULT_INPUT_CLOCK;
|
|
pPLL->clockType = clockType;
|
|
|
|
switch (clockType) {
|
|
case MXCLK_PLL:
|
|
ulPllReg = PEEK32(MXCLK_PLL_CTRL);
|
|
break;
|
|
case PRIMARY_PLL:
|
|
ulPllReg = PEEK32(PANEL_PLL_CTRL);
|
|
break;
|
|
case SECONDARY_PLL:
|
|
ulPllReg = PEEK32(CRT_PLL_CTRL);
|
|
break;
|
|
case VGA0_PLL:
|
|
ulPllReg = PEEK32(VGA_PLL0_CTRL);
|
|
break;
|
|
case VGA1_PLL:
|
|
ulPllReg = PEEK32(VGA_PLL1_CTRL);
|
|
break;
|
|
}
|
|
|
|
pPLL->M = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, M);
|
|
pPLL->N = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, N);
|
|
pPLL->OD = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, OD);
|
|
pPLL->POD = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, POD);
|
|
|
|
return calcPLL(pPLL);
|
|
}
|
|
|
|
|
|
unsigned int getChipClock(void)
|
|
{
|
|
pll_value_t pll;
|
|
#if 1
|
|
if (getChipType() == SM750LE)
|
|
return MHz(130);
|
|
#endif
|
|
|
|
return getPllValue(MXCLK_PLL, &pll);
|
|
}
|
|
|
|
|
|
/*
|
|
* This function set up the main chip clock.
|
|
*
|
|
* Input: Frequency to be set.
|
|
*/
|
|
void setChipClock(unsigned int frequency)
|
|
{
|
|
pll_value_t pll;
|
|
unsigned int ulActualMxClk;
|
|
#if 1
|
|
/* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */
|
|
if (getChipType() == SM750LE)
|
|
return;
|
|
#endif
|
|
|
|
if (frequency) {
|
|
/*
|
|
* Set up PLL, a structure to hold the value to be set in clocks.
|
|
*/
|
|
pll.inputFreq = DEFAULT_INPUT_CLOCK; /* Defined in CLOCK.H */
|
|
pll.clockType = MXCLK_PLL;
|
|
|
|
/*
|
|
* Call calcPllValue() to fill up the other fields for PLL structure.
|
|
* Sometime, the chip cannot set up the exact clock required by User.
|
|
* Return value from calcPllValue() gives the actual possible clock.
|
|
*/
|
|
ulActualMxClk = calcPllValue(frequency, &pll);
|
|
|
|
/* Master Clock Control: MXCLK_PLL */
|
|
POKE32(MXCLK_PLL_CTRL, formatPllReg(&pll));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void setMemoryClock(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) {
|
|
/* 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 = (unsigned int) roundedDiv(getChipClock(), frequency);
|
|
|
|
/* Set the corresponding divisor in the register. */
|
|
ulReg = PEEK32(CURRENT_GATE);
|
|
switch (divisor) {
|
|
default:
|
|
case 1:
|
|
ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_1);
|
|
break;
|
|
case 2:
|
|
ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_2);
|
|
break;
|
|
case 3:
|
|
ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_3);
|
|
break;
|
|
case 4:
|
|
ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_4);
|
|
break;
|
|
}
|
|
|
|
setCurrentGate(ulReg);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* 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) {
|
|
/* 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);
|
|
}
|
|
}
|
|
|
|
|
|
unsigned int ddk750_getVMSize(void)
|
|
{
|
|
unsigned int reg;
|
|
unsigned int data;
|
|
|
|
/* sm750le only use 64 mb memory*/
|
|
if (getChipType() == SM750LE)
|
|
return MB(64);
|
|
|
|
/* for 750,always use power mode0*/
|
|
reg = PEEK32(MODE0_GATE);
|
|
reg = FIELD_SET(reg, MODE0_GATE, GPIO, ON);
|
|
POKE32(MODE0_GATE, reg);
|
|
|
|
/* get frame buffer size from GPIO */
|
|
reg = FIELD_GET(PEEK32(MISC_CTRL), MISC_CTRL, LOCALMEM_SIZE);
|
|
switch (reg) {
|
|
case MISC_CTRL_LOCALMEM_SIZE_8M:
|
|
data = MB(8); break; /* 8 Mega byte */
|
|
case MISC_CTRL_LOCALMEM_SIZE_16M:
|
|
data = MB(16); break; /* 16 Mega byte */
|
|
case MISC_CTRL_LOCALMEM_SIZE_32M:
|
|
data = MB(32); break; /* 32 Mega byte */
|
|
case MISC_CTRL_LOCALMEM_SIZE_64M:
|
|
data = MB(64); break; /* 64 Mega byte */
|
|
default:
|
|
data = 0;
|
|
break;
|
|
}
|
|
return data;
|
|
|
|
}
|
|
|
|
int ddk750_initHw(initchip_param_t *pInitParam)
|
|
{
|
|
|
|
unsigned int ulReg;
|
|
#if 0
|
|
/* move the code to map regiter function. */
|
|
if (getChipType() == SM718) {
|
|
/* turn on big endian bit*/
|
|
ulReg = PEEK32(0x74);
|
|
/* now consider register definition in a big endian pattern*/
|
|
POKE32(0x74, ulReg|0x80000000);
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
if (pInitParam->powerMode != 0)
|
|
pInitParam->powerMode = 0;
|
|
setPowerMode(pInitParam->powerMode);
|
|
|
|
/* Enable display power gate & LOCALMEM power gate*/
|
|
ulReg = PEEK32(CURRENT_GATE);
|
|
ulReg = FIELD_SET(ulReg, CURRENT_GATE, DISPLAY, ON);
|
|
ulReg = FIELD_SET(ulReg, CURRENT_GATE, LOCALMEM, ON);
|
|
setCurrentGate(ulReg);
|
|
|
|
if (getChipType() != SM750LE) {
|
|
/* set panel pll and graphic mode via mmio_88 */
|
|
ulReg = PEEK32(VGA_CONFIGURATION);
|
|
ulReg = FIELD_SET(ulReg, VGA_CONFIGURATION, PLL, PANEL);
|
|
ulReg = FIELD_SET(ulReg, VGA_CONFIGURATION, MODE, GRAPHIC);
|
|
POKE32(VGA_CONFIGURATION, ulReg);
|
|
} else {
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
/* set graphic mode via IO method */
|
|
outb_p(0x88, 0x3d4);
|
|
outb_p(0x06, 0x3d5);
|
|
#endif
|
|
}
|
|
|
|
/* Set the Main Chip Clock */
|
|
setChipClock(MHz((unsigned int)pInitParam->chipClock));
|
|
|
|
/* Set up memory clock. */
|
|
setMemoryClock(MHz(pInitParam->memClock));
|
|
|
|
/* Set up master clock */
|
|
setMasterClock(MHz(pInitParam->masterClock));
|
|
|
|
|
|
/* Reset the memory controller. If the memory controller is not reset in SM750,
|
|
the system might hang when sw accesses the memory.
|
|
The memory should be resetted after changing the MXCLK.
|
|
*/
|
|
if (pInitParam->resetMemory == 1) {
|
|
ulReg = PEEK32(MISC_CTRL);
|
|
ulReg = FIELD_SET(ulReg, MISC_CTRL, LOCALMEM_RESET, RESET);
|
|
POKE32(MISC_CTRL, ulReg);
|
|
|
|
ulReg = FIELD_SET(ulReg, MISC_CTRL, LOCALMEM_RESET, NORMAL);
|
|
POKE32(MISC_CTRL, ulReg);
|
|
}
|
|
|
|
if (pInitParam->setAllEngOff == 1) {
|
|
enable2DEngine(0);
|
|
|
|
/* Disable Overlay, if a former application left it on */
|
|
ulReg = PEEK32(VIDEO_DISPLAY_CTRL);
|
|
ulReg = FIELD_SET(ulReg, VIDEO_DISPLAY_CTRL, PLANE, DISABLE);
|
|
POKE32(VIDEO_DISPLAY_CTRL, ulReg);
|
|
|
|
/* Disable video alpha, if a former application left it on */
|
|
ulReg = PEEK32(VIDEO_ALPHA_DISPLAY_CTRL);
|
|
ulReg = FIELD_SET(ulReg, VIDEO_ALPHA_DISPLAY_CTRL, PLANE, DISABLE);
|
|
POKE32(VIDEO_ALPHA_DISPLAY_CTRL, ulReg);
|
|
|
|
/* Disable alpha plane, if a former application left it on */
|
|
ulReg = PEEK32(ALPHA_DISPLAY_CTRL);
|
|
ulReg = FIELD_SET(ulReg, ALPHA_DISPLAY_CTRL, PLANE, DISABLE);
|
|
POKE32(ALPHA_DISPLAY_CTRL, ulReg);
|
|
|
|
#if 0
|
|
/* Disable LCD hardware cursor, if a former application left it on */
|
|
ulReg = PEEK32(PANEL_HWC_ADDRESS);
|
|
ulReg = FIELD_SET(ulReg, PANEL_HWC_ADDRESS, ENABLE, DISABLE);
|
|
POKE32(PANEL_HWC_ADDRESS, ulReg);
|
|
|
|
/* Disable CRT hardware cursor, if a former application left it on */
|
|
ulReg = PEEK32(CRT_HWC_ADDRESS);
|
|
ulReg = FIELD_SET(ulReg, CRT_HWC_ADDRESS, ENABLE, DISABLE);
|
|
POKE32(CRT_HWC_ADDRESS, ulReg);
|
|
|
|
/* Disable ZV Port 0, if a former application left it on */
|
|
ulReg = PEEK32(ZV0_CAPTURE_CTRL);
|
|
ulReg = FIELD_SET(ulReg, ZV0_CAPTURE_CTRL, CAP, DISABLE);
|
|
POKE32(ZV0_CAPTURE_CTRL, ulReg);
|
|
|
|
/* Disable ZV Port 1, if a former application left it on */
|
|
ulReg = PEEK32(ZV1_CAPTURE_CTRL);
|
|
ulReg = FIELD_SET(ulReg, ZV1_CAPTURE_CTRL, CAP, DISABLE);
|
|
POKE32(ZV1_CAPTURE_CTRL, ulReg);
|
|
|
|
/* Disable ZV Port Power, if a former application left it on */
|
|
enableZVPort(0);
|
|
/* Disable DMA Channel, if a former application left it on */
|
|
ulReg = PEEK32(DMA_ABORT_INTERRUPT);
|
|
ulReg = FIELD_SET(ulReg, DMA_ABORT_INTERRUPT, ABORT_1, ABORT);
|
|
POKE32(DMA_ABORT_INTERRUPT, ulReg);
|
|
|
|
/* Disable i2c */
|
|
enableI2C(0);
|
|
#endif
|
|
/* Disable DMA Channel, if a former application left it on */
|
|
ulReg = PEEK32(DMA_ABORT_INTERRUPT);
|
|
ulReg = FIELD_SET(ulReg, DMA_ABORT_INTERRUPT, ABORT_1, ABORT);
|
|
POKE32(DMA_ABORT_INTERRUPT, ulReg);
|
|
|
|
/* Disable DMA Power, if a former application left it on */
|
|
enableDMA(0);
|
|
}
|
|
|
|
/* We can add more initialization as needed. */
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if 0
|
|
|
|
unsigned int absDiff(unsigned int a, unsigned int b)
|
|
{
|
|
if (a > b)
|
|
return(a - b);
|
|
else
|
|
return(b - a);
|
|
}
|
|
|
|
#endif
|
|
/*
|
|
monk liu @ 4/6/2011:
|
|
re-write the calculatePLL function of ddk750.
|
|
the original version function does not use some mathematics tricks and shortcut
|
|
when it doing the calculation of the best N,M,D combination
|
|
I think this version gives a little upgrade in speed
|
|
|
|
750 pll clock formular:
|
|
Request Clock = (Input Clock * M )/(N * X)
|
|
|
|
Input Clock = 14318181 hz
|
|
X = 2 power D
|
|
D ={0,1,2,3,4,5,6}
|
|
M = {1,...,255}
|
|
N = {2,...,15}
|
|
*/
|
|
unsigned int calcPllValue(unsigned int request_orig, pll_value_t *pll)
|
|
{
|
|
/* used for primary and secondary channel pixel clock pll */
|
|
static pllcalparam xparm_PIXEL[] = {
|
|
/* 2^0 = 1*/ {0, 0, 0, 1},
|
|
/* 2^ 1 =2*/ {1, 0, 1, 2},
|
|
/* 2^ 2 = 4*/ {2, 0, 2, 4},
|
|
{3, 0, 3, 8},
|
|
{4, 1, 3, 16},
|
|
{5, 2, 3, 32},
|
|
/* 2^6 = 64 */ {6, 3, 3, 64},
|
|
};
|
|
|
|
/* used for MXCLK (chip clock) */
|
|
static pllcalparam xparm_MXCLK[] = {
|
|
/* 2^0 = 1*/ {0, 0, 0, 1},
|
|
/* 2^ 1 =2*/ {1, 0, 1, 2},
|
|
/* 2^ 2 = 4*/ {2, 0, 2, 4},
|
|
{3, 0, 3, 8},
|
|
};
|
|
|
|
/* as sm750 register definition, N located in 2,15 and M located in 1,255 */
|
|
int N, M, X, d;
|
|
int xcnt;
|
|
int miniDiff;
|
|
unsigned int RN, quo, rem, fl_quo;
|
|
unsigned int input, request;
|
|
unsigned int tmpClock, ret;
|
|
pllcalparam *xparm;
|
|
|
|
#if 1
|
|
if (getChipType() == SM750LE) {
|
|
/* SM750LE don't have prgrammable PLL and M/N values to work on.
|
|
Just return the requested clock. */
|
|
return request_orig;
|
|
}
|
|
#endif
|
|
|
|
ret = 0;
|
|
miniDiff = ~0;
|
|
request = request_orig / 1000;
|
|
input = pll->inputFreq / 1000;
|
|
|
|
/* for MXCLK register , no POD provided, so need be treated differently */
|
|
|
|
if (pll->clockType != MXCLK_PLL) {
|
|
xparm = &xparm_PIXEL[0];
|
|
xcnt = sizeof(xparm_PIXEL)/sizeof(xparm_PIXEL[0]);
|
|
} else {
|
|
xparm = &xparm_MXCLK[0];
|
|
xcnt = sizeof(xparm_MXCLK)/sizeof(xparm_MXCLK[0]);
|
|
}
|
|
|
|
|
|
for (N = 15; N > 1; N--) {
|
|
/* RN will not exceed maximum long if @request <= 285 MHZ (for 32bit cpu) */
|
|
RN = N * request;
|
|
quo = RN / input;
|
|
rem = RN % input;/* rem always small than 14318181 */
|
|
fl_quo = (rem * 10000 / input);
|
|
|
|
for (d = xcnt - 1; d >= 0; d--) {
|
|
X = xparm[d].value;
|
|
M = quo*X;
|
|
M += fl_quo * X / 10000;
|
|
/* round step */
|
|
M += (fl_quo*X % 10000)>5000?1:0;
|
|
if (M < 256 && M > 0) {
|
|
unsigned int diff;
|
|
tmpClock = pll->inputFreq * M / N / X;
|
|
diff = absDiff(tmpClock, request_orig);
|
|
if (diff < miniDiff) {
|
|
pll->M = M;
|
|
pll->N = N;
|
|
pll->OD = xparm[d].od;
|
|
pll->POD = xparm[d].pod;
|
|
miniDiff = diff;
|
|
ret = tmpClock;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
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 */
|
|
ulRequestClk *= 1000;
|
|
pPLL->inputFreq = DEFAULT_INPUT_CLOCK; /* Default reference clock */
|
|
|
|
/* Return actual frequency that the PLL can set */
|
|
ret = calcPLL(pPLL);
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int formatPllReg(pll_value_t *pPLL)
|
|
{
|
|
unsigned int ulPllReg = 0;
|
|
|
|
/* Note that all PLL's have the same format. Here, we just use Panel PLL parameter
|
|
to work out the bit fields in the register.
|
|
On returning a 32 bit number, the value can be applied to any PLL in the calling function.
|
|
*/
|
|
ulPllReg =
|
|
FIELD_SET(0, PANEL_PLL_CTRL, BYPASS, OFF)
|
|
| FIELD_SET(0, PANEL_PLL_CTRL, POWER, ON)
|
|
| FIELD_SET(0, PANEL_PLL_CTRL, INPUT, OSC)
|
|
#ifndef VALIDATION_CHIP
|
|
| FIELD_VALUE(0, PANEL_PLL_CTRL, POD, pPLL->POD)
|
|
#endif
|
|
| FIELD_VALUE(0, PANEL_PLL_CTRL, OD, pPLL->OD)
|
|
| FIELD_VALUE(0, PANEL_PLL_CTRL, N, pPLL->N)
|
|
| FIELD_VALUE(0, PANEL_PLL_CTRL, M, pPLL->M);
|
|
|
|
return ulPllReg;
|
|
}
|
|
|
|
|