/* Read PMC registers */ static inline unsigned int read_pmc(unsigned int offset) { return readl(offset + AT91C_BASE_PMC); } //*---------------------------------------------------------------------------- //* \fn pmc_cfg_plla //* \brief Configure the pll frequency to the corresponding value. //*----------------------------------------------------------------------------*/ int pmc_cfg_plla(unsigned int pmc_pllar, unsigned int timeout) { write_pmc((unsigned int)PMC_PLLAR, pmc_pllar); while ( (timeout--) && !(read_pmc(PMC_SR) & AT91C_PMC_LOCKA) ); return (timeout) ? 0 : (-1); } //*---------------------------------------------------------------------------- //* \fn pmc_cfg_pllb //* \brief Configure the pll frequency to the corresponding value. //*----------------------------------------------------------------------------*/ int pmc_cfg_pllb(unsigned int pmc_pllbr, unsigned int timeout) { write_pmc(PMC_PLLBR, pmc_pllbr); while ( (timeout--) && !(read_pmc(PMC_SR) & AT91C_PMC_LOCKB) ); return (timeout) ? 0 : (-1); } //*---------------------------------------------------------------------------- //* \fn pmc_cfg_mck //* \brief Configure the main oscillator to the corresponding value. //*----------------------------------------------------------------------------*/ int pmc_cfg_mck(unsigned int pmc_mckr, unsigned int timeout) { write_pmc(PMC_MCKR, pmc_mckr); while ( (timeout--) && !(read_pmc(PMC_SR) & AT91C_PMC_MCKRDY) ); return (timeout) ? 0 : (-1); } //*---------------------------------------------------------------------------- //* \fn pmc_cfg_pck //* \brief Configure the PCK frequency to the corresponding value. //*----------------------------------------------------------------------------*/ int pmc_cfg_pck(unsigned char x, unsigned int clk_sel, unsigned int prescaler) { write_pmc(PMC_PCKR + x * 4, clk_sel | prescaler); write_pmc(PMC_SCER, 1 << (x + 8)); while ( !(read_pmc(PMC_SR) & (1 << (x + 8))) ); return 0; }
void lowlevel_clock_init() { #if defined(CONFIG_AT91SAM9X5EK) unsigned long tmp; tmp = read_pmc(PMC_MCKR); tmp &= ~AT91C_PMC_CSS; tmp |= AT91C_PMC_CSS_MAIN_CLK; write_pmc(PMC_MCKR, tmp); while (!(read_pmc(PMC_SR) & AT91C_PMC_MCKRDY)) ; if (!(read_pmc(PMC_SR) & AT91C_PMC_MOSCXTS)) { /* * Enable 12MHz Main Oscillator */ write_pmc(PMC_MOR, (0x37 << 16) | AT91C_CKGR_MOSCXTEN | (0x40 << 8) | AT91C_CKGR_MOSCSEL | AT91C_CKGR_MOSCRCEN); /* * Wait until 12MHz Main Oscillator is stable */ while (!(read_pmc(PMC_SR) & AT91C_PMC_MOSCXTS)) ; } /* * After stablization, switch to 12MHz Main Oscillator */ if ((read_pmc(PMC_MCKR) & AT91C_PMC_CSS) == AT91C_PMC_CSS_SLOW_CLK) { write_pmc(PMC_MCKR, AT91C_PMC_CSS_MAIN_CLK | AT91C_PMC_PRES_CLK); while (!(read_pmc(PMC_SR) & AT91C_PMC_MCKRDY)) ; } #else if (!(read_pmc(PMC_SR) & AT91C_PMC_MOSCS)) { /* * Enable 12MHz Main Oscillator */ write_pmc(PMC_MOR, AT91C_CKGR_MOSCEN | (0x40 << 8)); /* * Wait until 12MHz Main Oscillator is stable */ while (!(read_pmc(PMC_SR) & AT91C_PMC_MOSCS)) ; } /* * After stablization, switch to 12MHz Main Oscillator */ if ((read_pmc(PMC_MCKR) & AT91C_PMC_CSS) == AT91C_PMC_CSS_SLOW_CLK) { write_pmc(PMC_MCKR, AT91C_PMC_CSS_MAIN_CLK | AT91C_PMC_PRES_CLK); while (!(read_pmc(PMC_SR) & AT91C_PMC_MCKRDY)) ; } #endif return; }
/* Read PMC registers */ static inline unsigned int read_pmc(unsigned int offset) { return readl(offset + AT91C_BASE_PMC); } //*---------------------------------------------------------------------------- //* \fn pmc_cfg_plla //* \brief Configure the pll frequency to the corresponding value. //*----------------------------------------------------------------------------*/ int pmc_cfg_plla(unsigned int pmc_pllar, unsigned int timeout) { write_pmc((unsigned int)PMC_PLLAR, pmc_pllar); while ( (timeout--) && !(read_pmc(PMC_SR) & AT91C_PMC_LOCKA) ); return (timeout) ? 0 : (-1); } //*---------------------------------------------------------------------------- //* \fn pmc_cfg_pllb //* \brief Configure the pll frequency to the corresponding value. //*----------------------------------------------------------------------------*/ int pmc_cfg_pllb(unsigned int pmc_pllbr, unsigned int timeout) { write_pmc(PMC_PLLBR, pmc_pllbr); while ( (timeout--) && !(read_pmc(PMC_SR) & AT91C_PMC_LOCKB) ); return (timeout) ? 0 : (-1); } //*---------------------------------------------------------------------------- //* \fn pmc_cfg_mck //* \brief Configure the main oscillator to the corresponding value. //*----------------------------------------------------------------------------*/ int pmc_cfg_mck(unsigned int pmc_mckr, unsigned int timeout) { write_pmc(PMC_MCKR, pmc_mckr); while ( (timeout--) && !(read_pmc(PMC_SR) & AT91C_PMC_MCKRDY) ); return (timeout) ? 0 : (-1); }
/* Read PMC registers */ static inline unsigned int read_pmc(unsigned int offset) { return readl(offset + AT91C_BASE_PMC); } //*---------------------------------------------------------------------------- //* \fn pmc_cfg_plla //* \brief Configure the pll frequency to the corresponding value. //*----------------------------------------------------------------------------*/ int pmc_cfg_plla(unsigned int pmc_pllar, unsigned int timeout) { write_pmc((unsigned int)PMC_PLLAR, pmc_pllar); while ( (timeout--) && !(read_pmc(PMC_SR) & AT91C_PMC_LOCKA) ); return (timeout) ? 0 : (-1); } //*---------------------------------------------------------------------------- //* \fn pmc_cfg_pllb //* \brief Configure the pll frequency to the corresponding value. //*----------------------------------------------------------------------------*/ int pmc_cfg_pllb(unsigned int pmc_pllbr, unsigned int timeout) { write_pmc(PMC_PLLBR, pmc_pllbr); while ( (timeout--) && !(read_pmc(PMC_SR) & AT91C_PMC_LOCKB) ); return (timeout) ? 0 : (-1); }
/* Read PMC registers */ static inline unsigned int read_pmc(unsigned int offset) { return readl(offset + AT91C_BASE_PMC); } //*---------------------------------------------------------------------------- //* \fn pmc_cfg_plla //* \brief Configure the pll frequency to the corresponding value. //*----------------------------------------------------------------------------*/ int pmc_cfg_plla(unsigned int pmc_pllar, unsigned int timeout) { write_pmc((unsigned int)PMC_PLLAR, pmc_pllar); while ( (timeout--) && !(read_pmc(PMC_SR) & AT91C_PMC_LOCKA) ); return (timeout) ? 0 : (-1); }
/* * After stablization, switch to 12MHz Main Oscillator */ if ((read_pmc(PMC_MCKR) & AT91C_PMC_CSS) == AT91C_PMC_CSS_SLOW_CLK) { write_pmc(PMC_MCKR, AT91C_PMC_CSS_MAIN_CLK | AT91C_PMC_PRES_CLK); while (!(read_pmc(PMC_SR) & AT91C_PMC_MCKRDY)) ; } #endif return; } //*---------------------------------------------------------------------------- //* \fn pmc_cfg_plla //* \brief Configure the pll frequency to the corresponding value. //*----------------------------------------------------------------------------*/ int pmc_cfg_plla(unsigned int pmc_pllar, unsigned int timeout) { #if defined(CONFIG_AT91SAM9X5EK) write_pmc(PMC_PLLAR, 0); write_pmc(PMC_PLLAR, pmc_pllar); //while ((timeout--) && !(read_pmc(PMC_SR) & AT91C_PMC_LOCKA)) while (!(read_pmc(PMC_SR) & AT91C_PMC_LOCKA)) ; while (!(read_pmc(PMC_SR) & AT91C_PMC_MCKRDY)) ; return 0; #else write_pmc((unsigned int)PMC_PLLAR, pmc_pllar); while ((timeout--) && !(read_pmc(PMC_SR) & AT91C_PMC_LOCKA)) ; return (timeout) ? 0 : (-1); #endif }
static void mips_iresume(const struct perfctr_cpu_state *state) { struct per_cpu_cache *cache; unsigned int cstatus, nrctrs, i; int cpu; cpu = smp_processor_id(); cache = __get_cpu_cache(cpu); if (cache->k1.id == state->k1.id) { // we need to do this and force reload of control registers // to unfreeze control registers cache->k1.id = 0; // if no one else was scheduled after we were suspended, // the regiseters are still warm, actually hot and don't // have to reload them. Is that right ? // we are being rescheduled on the same processor if (is_isuspend_cpu(state, cpu)) return; /* skip reload of PMCs */ } // The CPU state wasn't ours. // The counters must be frozen before being reinitialised, // to prevent unexpected increments and missed overflows. // At this point, only the i-mode registers are frozen. Is there // any reason to freeze a-mode counters ?! // All unused counters must be reset to a non-overflow state. // accumulation mode registers are reset to zero, while the i-mode // registers are being written from state->pmc[i].start. The field // state->pmc[].start for i-mode registers was set to the values // specified in the .ireset field in the function ... cstatus = state->cstatus; nrctrs = perfctr_cstatus_nrctrs(cstatus); for(i = perfctr_cstatus_nractrs(cstatus); i < nrctrs; ++i) { unsigned int map = state->pmc[i].map; cache->ctrl_regs[map] = 0; write_pmctrl(map, 0); // zero value write_pmc(map, state->pmc[i].start); } // cache->k1.id remains != state->k1.id }