1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. 7 */ 8 #include <linux/init.h> 9 #include <linux/irqchip/mips-gic.h> 10 11 #include <asm/cpu.h> 12 #include <asm/setup.h> 13 #include <asm/time.h> 14 #include <asm/irq.h> 15 #include <asm/mips-boards/generic.h> 16 17 static void __iomem *status_reg = (void __iomem *)0xbf000410; 18 19 /* 20 * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect. 21 */ estimate_cpu_frequency(void)22static unsigned int __init estimate_cpu_frequency(void) 23 { 24 unsigned int prid = read_c0_prid() & (PRID_COMP_MASK | PRID_IMP_MASK); 25 unsigned int tick = 0; 26 unsigned int freq; 27 unsigned int orig; 28 unsigned long flags; 29 30 local_irq_save(flags); 31 32 orig = readl(status_reg) & 0x2; /* get original sample */ 33 /* wait for transition */ 34 while ((readl(status_reg) & 0x2) == orig) 35 ; 36 orig = orig ^ 0x2; /* flip the bit */ 37 38 write_c0_count(0); 39 40 /* wait 1 second (the sampling clock transitions every 10ms) */ 41 while (tick < 100) { 42 /* wait for transition */ 43 while ((readl(status_reg) & 0x2) == orig) 44 ; 45 orig = orig ^ 0x2; /* flip the bit */ 46 tick++; 47 } 48 49 freq = read_c0_count(); 50 51 local_irq_restore(flags); 52 53 mips_hpt_frequency = freq; 54 55 /* Adjust for processor */ 56 if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) && 57 (prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) 58 freq *= 2; 59 60 freq += 5000; /* rounding */ 61 freq -= freq%10000; 62 63 return freq ; 64 } 65 read_persistent_clock(struct timespec * ts)66void read_persistent_clock(struct timespec *ts) 67 { 68 ts->tv_sec = 0; 69 ts->tv_nsec = 0; 70 } 71 get_c0_perfcount_int(void)72int get_c0_perfcount_int(void) 73 { 74 if (gic_present) 75 return gic_get_c0_perfcount_int(); 76 if (cp0_perfcount_irq >= 0) 77 return MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; 78 return -1; 79 } 80 EXPORT_SYMBOL_GPL(get_c0_perfcount_int); 81 get_c0_compare_int(void)82unsigned int get_c0_compare_int(void) 83 { 84 if (gic_present) 85 return gic_get_c0_compare_int(); 86 return MIPS_CPU_IRQ_BASE + cp0_compare_irq; 87 } 88 plat_time_init(void)89void __init plat_time_init(void) 90 { 91 unsigned int est_freq; 92 93 est_freq = estimate_cpu_frequency(); 94 95 pr_debug("CPU frequency %d.%02d MHz\n", (est_freq / 1000000), 96 (est_freq % 1000000) * 100 / 1000000); 97 98 mips_scroll_message(); 99 } 100