/* * void __init iSeries_calibrate_decr() * * Description: * This routine retrieves the internal processor frequency from the VPD, * and sets up the kernel timer decrementer based on that value. * */ void __init iSeries_calibrate_decr(void) { unsigned long cyclesPerUsec; struct div_result divres; /* Compute decrementer (and TB) frequency in cycles/sec */ cyclesPerUsec = ppc_tb_freq / 1000000; /* * Set the amount to refresh the decrementer by. This * is the number of decrementer ticks it takes for * 1/HZ seconds. */ tb_ticks_per_jiffy = ppc_tb_freq / HZ; #if 0 /* TEST CODE FOR ADJTIME */ tb_ticks_per_jiffy += tb_ticks_per_jiffy / 5000; /* END OF TEST CODE */ #endif /* * tb_ticks_per_sec = freq; would give better accuracy * but tb_ticks_per_sec = tb_ticks_per_jiffy*HZ; assures * that jiffies (and xtime) will match the time returned * by do_gettimeofday. */ tb_ticks_per_sec = tb_ticks_per_jiffy * HZ; tb_ticks_per_usec = cyclesPerUsec; tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000); div128_by_32(1024 * 1024, 0, tb_ticks_per_sec, &divres); tb_to_xs = divres.result_low; setup_default_decr(); }
/* * This routine retrieves the internal processor frequency from the board * information structure, sets up the kernel timer decrementer based on * that value, enables the 4xx programmable interval timer (PIT) and sets * it up for auto-reload. */ static void __init ppc4xx_calibrate_decr(void) { unsigned int freq; bd_t *bip = &__res; #if defined(CONFIG_WALNUT) || defined(CONFIG_SYCAMORE) /* Walnut boot rom sets DCR CHCR1 (aka CPC0_CR1) bit CETE to 1 */ mtdcr(DCRN_CHCR1, mfdcr(DCRN_CHCR1) & ~CHR1_CETE); #endif freq = bip->bi_tbfreq; tb_ticks_per_jiffy = freq / HZ; tb_to_us = mulhwu_scale_factor(freq, 1000000); /* Set the time base to zero. ** At 200 Mhz, time base will rollover in ~2925 years. */ mtspr(SPRN_TBWL, 0); mtspr(SPRN_TBWU, 0); /* Clear any pending timer interrupts */ mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_PIS | TSR_FIS); mtspr(SPRN_TCR, TCR_PIE | TCR_ARE); /* Set the PIT reload value and just let it run. */ mtspr(SPRN_PIT, tb_ticks_per_jiffy); }
/* * This was taken from prep_setup.c * Use the NVRAM RTC to time a second to calibrate the decrementer. */ void __init todc_calibrate_decr(void) { ulong freq; ulong tbl, tbu; long i, loop_count; u_char sec; todc_time_init(); /* * Actually this is bad for precision, we should have a loop in * which we only read the seconds counter. todc_read_val writes * the address bytes on every call and this takes a lot of time. * Perhaps an nvram_wait_change method returning a time * stamp with a loop count as parameter would be the solution. */ /* * Need to make sure the tbl doesn't roll over so if tbu increments * during this test, we need to do it again. */ loop_count = 0; sec = todc_read_timereg(todc_info->seconds) & 0x7f; do { tbu = get_tbu(); for (i = 0 ; i < 10000000 ; i++) {/* may take up to 1 second */ tbl = get_tbl(); if ((todc_read_timereg(todc_info->seconds) & 0x7f) != sec) { break; } } sec = todc_read_timereg(todc_info->seconds) & 0x7f; for (i = 0 ; i < 10000000 ; i++) { /* Should take 1 second */ freq = get_tbl(); if ((todc_read_timereg(todc_info->seconds) & 0x7f) != sec) { break; } } freq -= tbl; } while ((get_tbu() != tbu) && (++loop_count < 2)); printk("time_init: decrementer frequency = %lu.%.6lu MHz\n", freq/1000000, freq%1000000); tb_ticks_per_jiffy = freq / HZ; tb_to_us = mulhwu_scale_factor(freq, 1000000); return; }
static void __init prpmc750_calibrate_decr(void) { unsigned long freq; int divisor = 4; freq = prpmc750_get_bus_speed(); tb_ticks_per_jiffy = freq / (HZ * divisor); tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000); }
/* The decrementer counts at the system (internal) clock frequency * divided by four. */ static void __init m8260_calibrate_decr(void) { bd_t *binfo = (bd_t *)__res; int freq, divisor; freq = binfo->bi_busfreq; divisor = 4; tb_ticks_per_jiffy = freq / HZ / divisor; tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000); }
static void __init glacier_calibrate_decr(void) { int freq, divisor; freq = 231000000/3.5; printk("hardcoded clock to 231MHz, need to calculate it\n"); divisor = 4; tb_ticks_per_jiffy = freq / HZ / divisor; tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000); }
static void __init ppc7d_calibrate_decr(void) { ulong freq; freq = 100000000 / 4; pr_debug("time_init: decrementer frequency = %lu.%.6lu MHz\n", freq / 1000000, freq % 1000000); tb_ticks_per_jiffy = freq / HZ; tb_to_us = mulhwu_scale_factor(freq, 1000000); }
/* The decrementer counts at the system (internal) clock freq divided by 4 */ void __init mpc83xx_calibrate_decr(void) { bd_t *binfo = (bd_t *) __res; unsigned int freq, divisor; freq = binfo->bi_busfreq; divisor = 4; tb_ticks_per_jiffy = freq / HZ / divisor; tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000); us_to_tb = (freq / divisor) / 1000000; }
static void __init powerpmc250_calibrate_decr(void) { unsigned long freq; int divisor = 4; //freq = powerpmc250_get_bus_speed(); #warning hardcoded bus freq freq = 100000000; tb_ticks_per_jiffy = freq / (HZ * divisor); tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); }
/************************************************************************** * FUNCTION: chestnut_calibrate_decr * * DESCRIPTION: initialize decrementer interrupt frequency (used as system * timer) * ****/ static void __init chestnut_calibrate_decr(void) { ulong freq; freq = CHESTNUT_BUS_SPEED / 4; printk("time_init: decrementer frequency = %lu.%.6lu MHz\n", freq/1000000, freq%1000000); tb_ticks_per_jiffy = freq / HZ; tb_to_us = mulhwu_scale_factor(freq, 1000000); }
void __init ibm44x_calibrate_decr(unsigned int freq) { tb_ticks_per_jiffy = freq / HZ; tb_to_us = mulhwu_scale_factor(freq, 1000000); /* Set the time base to zero */ mtspr(SPRN_TBWL, 0); mtspr(SPRN_TBWU, 0); /* Clear any pending timer interrupts */ mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); /* Enable decrementer interrupt */ mtspr(SPRN_TCR, TCR_DIE); }
/* The decrementer counts at the system (internal) clock freq divided by 8 */ void __init mpc86xx_calibrate_decr(void) { bd_t *binfo = (bd_t *) __res; unsigned int freq, divisor, temp; /* get the core frequency */ freq = binfo->bi_busfreq; /* The timebase is updated every 4 bus clocks */ divisor = 4; tb_ticks_per_jiffy = freq / divisor / HZ; tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000); /* Set the time base to zero */ mtspr(SPRN_TBWL, 0); mtspr(SPRN_TBWU, 0); temp = mfspr(SPRN_HID0); temp |= HID0_TBEN; mtspr(SPRN_HID0, temp); }
/* The decrementer counts at the system (internal) clock freq divided by 8 */ void __init mpc85xx_calibrate_decr(void) { bd_t *binfo = (bd_t *) __res; unsigned int freq, divisor; /* get the core frequency */ freq = binfo->bi_busfreq; /* The timebase is updated every 8 bus clocks, HID0[SEL_TBCLK] = 0 */ divisor = 8; tb_ticks_per_jiffy = freq / divisor / HZ; tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000); /* Set the time base to zero */ mtspr(SPRN_TBWL, 0); mtspr(SPRN_TBWU, 0); /* Clear any pending timer interrupts */ mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); /* Enable decrementer interrupt */ mtspr(SPRN_TCR, TCR_DIE); }
void __init mpc52xx_calibrate_decr(void) { int current_time, previous_time; int tbl_start, tbl_end; unsigned int xlbfreq, cpufreq, ipbfreq, pcifreq, divisor; xlbfreq = __res.bi_busfreq; /* if bootloader didn't pass bus frequencies, calculate them */ if (xlbfreq == 0) { /* Get RTC & Clock manager modules */ struct mpc52xx_rtc __iomem *rtc; struct mpc52xx_cdm __iomem *cdm; rtc = ioremap(MPC52xx_PA(MPC52xx_RTC_OFFSET), MPC52xx_RTC_SIZE); cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE); if ((rtc==NULL) || (cdm==NULL)) panic("Can't ioremap RTC/CDM while computing bus freq"); /* Count bus clock during 1/64 sec */ out_be32(&rtc->dividers, 0x8f1f0000); /* Set RTC 64x faster */ previous_time = in_be32(&rtc->time); while ((current_time = in_be32(&rtc->time)) == previous_time) ; tbl_start = get_tbl(); previous_time = current_time; while ((current_time = in_be32(&rtc->time)) == previous_time) ; tbl_end = get_tbl(); out_be32(&rtc->dividers, 0xffff0000); /* Restore RTC */ /* Compute all frequency from that & CDM settings */ xlbfreq = (tbl_end - tbl_start) << 8; cpufreq = (xlbfreq * core_mult[in_be32(&cdm->rstcfg)&0x1f])/10; ipbfreq = (in_8(&cdm->ipb_clk_sel) & 1) ? xlbfreq / 2 : xlbfreq; switch (in_8(&cdm->pci_clk_sel) & 3) { case 0: pcifreq = ipbfreq; break; case 1: pcifreq = ipbfreq / 2; break; default: pcifreq = xlbfreq / 4; break; } __res.bi_busfreq = xlbfreq; __res.bi_intfreq = cpufreq; __res.bi_ipbfreq = ipbfreq; __res.bi_pcifreq = pcifreq; /* Release mapping */ iounmap(rtc); iounmap(cdm); } divisor = 4; tb_ticks_per_jiffy = xlbfreq / HZ / divisor; tb_to_us = mulhwu_scale_factor(xlbfreq / divisor, 1000000); }