void lpc31_setfdiv(enum lpc31_domainid_e dmnid, enum lpc31_clockid_e clkid, const struct lpc31_fdivconfig_s *fdiv) { uint32_t regaddr; unsigned int basefreq; int fdcndx; int bcrndx; /* Get the frequency divider associated with this clock */ fdcndx = lpc31_fdcndx(clkid, dmnid); /* Does this clock have a frequency divicer? */ if (fdcndx != FDCNDX_INVALID) { /* Yes.. Save the current reference frequency selection */ regaddr = LPC31_CGU_SSR((int)dmnid); basefreq = (getreg32(regaddr) & CGU_SSR_FS_MASK) >> CGU_SSR_FS_SHIFT; /* Switch domain to FFAST input */ lpc31_selectfreqin(dmnid, CGU_FS_FFAST); /* Get the index of the associated BCR register. Does this domain * have a BCR? */ bcrndx = lpc31_bcrndx(dmnid); if (bcrndx != BCRNDX_INVALID) { /* Yes... Disable the BCR */ regaddr = LPC31_CGU_BCR(bcrndx); putreg32(0, regaddr); } /* Change fractional divider to the provided settings */ lpc31_fdivinit(fdcndx, fdiv, true); /* Re-enable the BCR (if one is associated with this domain) */ if (bcrndx != BCRNDX_INVALID) { regaddr = LPC31_CGU_BCR(bcrndx); putreg32(CGU_BCR_FDRUN, regaddr); } /* Switch the domain back to its original base frequency */ lpc31_selectfreqin(dmnid, basefreq); }
void lpc31_selectfreqin(enum lpc31_domainid_e dmnid, uint32_t finsel) { uint32_t scraddr = LPC31_CGU_SCR(dmnid); uint32_t fs1addr = LPC31_CGU_FS1(dmnid); uint32_t fs2addr = LPC31_CGU_FS2(dmnid); uint32_t scrbits; /* Get the frequency selection from the switch configuration register (SCR) * for this domain. */ scrbits = getreg32(scraddr) & ~(CGU_SCR_ENF1|CGU_SCR_ENF2); /* If FS1 is currently enabled set the reference clock to FS2 and enable FS2 */ if ((getreg32(LPC31_CGU_SSR(dmnid)) & CGU_SSR_FS1STAT) != 0) { /* Check if the selected frequency, FS1, is same as requested */ if ((getreg32(fs1addr) & CGU_FS_MASK) != finsel) { /* No.. Set up FS2 */ putreg32(finsel, fs2addr); putreg32(scrbits | CGU_SCR_ENF2, scraddr); } } /* FS1 is not currently enabled, check if the selected frequency, FS2, * is same as requested */ else if ((getreg32(fs2addr) & CGU_FS_MASK) != finsel) { /* No.. Set up FS1 */ putreg32(finsel, fs1addr); putreg32(scrbits | CGU_SCR_ENF1, scraddr); } }