0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/of_address.h>
0009 #include <linux/types.h>
0010
0011 #include <asm/machine.h>
0012 #include <asm/mipsregs.h>
0013 #include <asm/time.h>
0014
0015 #define GOLDFISH_TIMER_LOW 0x00
0016 #define GOLDFISH_TIMER_HIGH 0x04
0017
0018 static __init u64 read_rtc_time(void __iomem *base)
0019 {
0020 u32 time_low;
0021 u32 time_high;
0022
0023
0024
0025
0026
0027
0028 time_low = readl(base + GOLDFISH_TIMER_LOW);
0029 time_high = readl(base + GOLDFISH_TIMER_HIGH);
0030
0031 return ((u64)time_high << 32) | time_low;
0032 }
0033
0034 static __init unsigned int ranchu_measure_hpt_freq(void)
0035 {
0036 u64 rtc_start, rtc_current, rtc_delta;
0037 unsigned int start, count;
0038 struct device_node *np;
0039 void __iomem *rtc_base;
0040
0041 np = of_find_compatible_node(NULL, NULL, "google,goldfish-rtc");
0042 if (!np)
0043 panic("%s(): Failed to find 'google,goldfish-rtc' dt node!",
0044 __func__);
0045
0046 rtc_base = of_iomap(np, 0);
0047 of_node_put(np);
0048 if (!rtc_base)
0049 panic("%s(): Failed to ioremap Goldfish RTC base!", __func__);
0050
0051
0052
0053
0054
0055 rtc_start = read_rtc_time(rtc_base);
0056 start = read_c0_count();
0057
0058 do {
0059 rtc_current = read_rtc_time(rtc_base);
0060 rtc_delta = rtc_current - rtc_start;
0061 } while (rtc_delta < NSEC_PER_SEC);
0062
0063 count = read_c0_count() - start;
0064
0065
0066
0067
0068
0069
0070
0071
0072 count += 5000;
0073 count -= count % 10000;
0074
0075 iounmap(rtc_base);
0076
0077 return count;
0078 }
0079
0080 static const struct of_device_id ranchu_of_match[] __initconst = {
0081 {
0082 .compatible = "mti,ranchu",
0083 },
0084 {}
0085 };
0086
0087 MIPS_MACHINE(ranchu) = {
0088 .matches = ranchu_of_match,
0089 .measure_hpt_freq = ranchu_measure_hpt_freq,
0090 };