void cpu_powerstats(__unused void *arg) { cpu_data_t *cdp = current_cpu_datap(); __unused int cnum = cdp->cpu_number; uint32_t cl = 0, ch = 0, mpl = 0, mph = 0, apl = 0, aph = 0; rdmsr_carefully(MSR_IA32_MPERF, &mpl, &mph); rdmsr_carefully(MSR_IA32_APERF, &apl, &aph); cdp->cpu_mperf = ((uint64_t)mph << 32) | mpl; cdp->cpu_aperf = ((uint64_t)aph << 32) | apl; uint64_t ctime = mach_absolute_time(); cdp->cpu_rtime_total += ctime - cdp->cpu_ixtime; cdp->cpu_ixtime = ctime; rdmsr_carefully(MSR_IA32_CORE_C3_RESIDENCY, &cl, &ch); cdp->cpu_c3res = ((uint64_t)ch << 32) | cl; rdmsr_carefully(MSR_IA32_CORE_C6_RESIDENCY, &cl, &ch); cdp->cpu_c6res = ((uint64_t)ch << 32) | cl; rdmsr_carefully(MSR_IA32_CORE_C7_RESIDENCY, &cl, &ch); cdp->cpu_c7res = ((uint64_t)ch << 32) | cl; if (diag_pmc_enabled) { uint64_t insns = read_pmc(FIXED_PMC0); uint64_t ucc = read_pmc(FIXED_PMC1); uint64_t urc = read_pmc(FIXED_PMC2); cdp->cpu_cur_insns = insns; cdp->cpu_cur_ucc = ucc; cdp->cpu_cur_urc = urc; } }
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); } //*---------------------------------------------------------------------------- //* \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; }
/* 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); }
int do_pmc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { printk("PMC_PerfCtr0 - %lld\n", read_pmc(PMC_PerfCtr0)); printk("PMC_PerfCtr1 - %lld\n", read_pmc(PMC_PerfCtr1)); printk("TSC - %lld\n", rdtsc()); #ifdef CONFIG_VMWARE_CLIENT printk("VMWARE_PMC_HOST_TSC - %lld\n", read_pmc(VMWARE_PMC_HOST_TSC)); printk("VMWARE_PMC_ELAPSED_REAL_TIME - %lld\n", read_pmc(VMWARE_PMC_ELAPSED_REAL_TIME)); printk("VMWARE_PMC_ELAPSED_APPARENT_TIME - %lld\n", read_pmc(VMWARE_PMC_ELAPSED_APPARENT_TIME)); #endif return 0; }
static void mips_isuspend(struct perfctr_cpu_state *state) { struct per_cpu_cache *cache; unsigned int cstatus, nrctrs, i; int cpu; // it is on the cpu no 'cpu' that we suspended gathering statistics cpu = smp_processor_id(); // what are we going to with the stored 'cpu' no? telling somone // look this state was last suspended on cpu 'cpu' set_isuspend_cpu(state, cpu); /* early to limit cpu's live range */ // what are we caching? cache = __get_cpu_cache(cpu); cstatus = state->cstatus; nrctrs = perfctr_cstatus_nrctrs(cstatus); for(i = perfctr_cstatus_nractrs(cstatus); i < nrctrs; ++i) { unsigned int pmc, now; pmc = state->pmc[i].map; // instead of setting the freeze bits, just zero out the whole reg cache->ctrl_regs[pmc] = 0; write_pmctrl(pmc, cache->ctrl_regs[pmc]); now = read_pmc(pmc); state->pmc[i].sum += now - state->pmc[i].start; state->pmc[i].start = now; } /* cache->k1.id is still == state->k1.id */ // sampled the i-mode registers }
/* * 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_read_counters(struct perfctr_cpu_state *state, struct perfctr_low_ctrs *ctrs) { unsigned int cstatus, nrctrs, i; cstatus = state->cstatus; if (perfctr_cstatus_has_tsc(cstatus)) { ctrs->tsc = read_c0_count(); } nrctrs = perfctr_cstatus_nractrs(cstatus); for(i = 0; i < nrctrs; ++i) { unsigned int pmc = state->pmc[i].map; ctrs->pmc[i] = read_pmc(pmc); } }
// PREEMPT note: called in IRQ context with preemption disabled. static void vperfctr_ihandler(unsigned long pc) { struct task_struct *tsk = current; struct vperfctr *perfctr; unsigned int pmc, cstatus, now = 0; int i; perfctr = tsk->thread.perfctr; if (!perfctr) { return; } if (!perfctr_cstatus_has_ictrs(perfctr->cpu_state.cstatus)) { return; } // if someone has really overflown then continue else return // just read, don't freeze them cstatus = perfctr->cpu_state.cstatus; for (i = perfctr_cstatus_nractrs(cstatus); (i < perfctr_cstatus_nrctrs(cstatus)) && ((int)now >= 0); ++i) { pmc = perfctr->cpu_state.pmc[i].map; now = read_pmc(pmc); } if ((int)now >= 0) { return; } // Fine, we are suspending the counters and reading them. vperfctr_suspend() // in turn invokes _suspend() on i-mode ctrs (where they are frozen and read) // and a-mode counters (where they are just read) vperfctr_suspend(perfctr); // Ok, Signal to the userland is sent in the following routine. But before that // the following routine calls vperfctr_resume() if the TSC counting is on. // what happens in that resume is just the TSC value is read and stored in the // 'start' state of the TSC vperfctr_handle_overflow(tsk, perfctr); }
cycle_t pm_counter_counter_read(void) { return (cycle_t)read_pmc(VMWARE_PMC_ELAPSED_REAL_TIME); }