/* * ======== PMI_bypassPLL ======== */ PMI_Status PMI_bypassPLL(PMI_Pll pll) { unsigned pllbase; unsigned cpuCycles; unsigned postdiv = 1; unsigned prediv = 1; unsigned mult; /* determine appropriate PLL base address */ pllbase = pll == PMI_CPU ? BASE_PLL0 : BASE_PLL1; /* only do something if PLL is not already in bypass ... */ if ((REG(pllbase + PLLCTL) & PLL_PLLEN_BIT) != 0) { /* clear PLLEN bit in PLLCTL to bypass PLL */ REG(pllbase + PLLCTL) &= ~PLL_PLLEN_BIT; /* compute number CPU cycles to wait (for 4 OSCIN/CLKIN cycles) */ mult = (REG(pllbase + PLLM) & PLL_RATIO_MASK) + 1; if ((REG(pllbase + PREDIV) & PLL_ENABLE_MASK) != 0) { prediv = (REG(pllbase + PREDIV) & PLL_RATIO_MASK) + 1; } if ((REG(pllbase + POSTDIV) & PLL_ENABLE_MASK) != 0) { postdiv = (REG(pllbase + POSTDIV) & PLL_RATIO_MASK) + 1; } cpuCycles = ((4 * mult) / postdiv) / prediv; /* now, wait for bypass transition to complete... */ PMI_waitCpuCycles(cpuCycles); } return(PMI_OK); }
/* * ======== PMI_setVoltage ======== */ PMI_Status PMI_setVoltage(unsigned voltage, unsigned wait) { PMI_Status status = PMI_OK; unsigned voltageCode; unsigned data; /* lookup the voltage code corresponding to the new voltage */ switch (voltage) { case 1300: voltageCode = SP_1_3_VOLT; /* 1300 mV */ break; case 1200: voltageCode = SP_1_2_VOLT; /* 1200 mV */ break; case 1100: voltageCode = SP_1_1_VOLT; /* 1200 mV */ break; case 1000: voltageCode = SP_1_0_VOLT; /* 1200 mV */ break; default: status = PMI_FAIL; } /* command the PMIC to the new voltage */ if (status == PMI_OK) { /* write the new voltage code */ PMI_writeI2C(PMIC_ADDR, DEFDCDC3_REG, voltageCode); /* number of cycles to wait after initiating change to DCDC3 */ PMI_waitCpuCycles(_PMI_readBackDelay); /* read back the voltage code to confirm new setting */ PMI_readI2C(PMIC_ADDR, DEFDCDC3_REG, &data); if (data != voltageCode) { status = PMI_FAIL; } } /* optionally wait for voltage transition to complete */ if ((status == PMI_OK) && (wait != 0)) { /* wait until power good is asserted by the PMIC */ do { PMI_readI2C(PMIC_ADDR, PGOOD_REG, &data); } while ((data & PGOOD_BIT) == 0); } return (status); }
/* * ======== PMI_lockPLL ======== */ PMI_Status PMI_lockPLL(PMI_Pll pll, unsigned lockCycles) { unsigned pllbase; /* determine appropriate PLL base address */ pllbase = pll == PMI_CPU ? BASE_PLL0 : BASE_PLL1; /* Note - per spec, PLL reset must be asserted for 125nsec; at the fastest bypass frequency (50MHz) this would correspond to max of 7 CPU cycles; these cycles have already been consumed between time of reset assertion in PMI_configurePLL, and getting here, so no additional delay cycles are added. */ /* set the PLLRST bit to release PLL from reset */ REG(pllbase + PLLCTL) |= PLL_PLLRST_BIT; /* wait for PLL to lock */ PMI_waitCpuCycles(lockCycles); return (PMI_OK); }