linux/arch/mips/generic/board-ranchu.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Support code for virtual Ranchu board for MIPS.
   4 *
   5 * Author: Miodrag Dinic <miodrag.dinic@mips.com>
   6 */
   7
   8#include <linux/of_address.h>
   9#include <linux/types.h>
  10
  11#include <asm/machine.h>
  12#include <asm/mipsregs.h>
  13#include <asm/time.h>
  14
  15#define GOLDFISH_TIMER_LOW              0x00
  16#define GOLDFISH_TIMER_HIGH             0x04
  17
  18static __init u64 read_rtc_time(void __iomem *base)
  19{
  20        u32 time_low;
  21        u32 time_high;
  22
  23        /*
  24         * Reading the low address latches the high value
  25         * as well so there is no fear that we may read
  26         * inaccurate high value.
  27         */
  28        time_low = readl(base + GOLDFISH_TIMER_LOW);
  29        time_high = readl(base + GOLDFISH_TIMER_HIGH);
  30
  31        return ((u64)time_high << 32) | time_low;
  32}
  33
  34static __init unsigned int ranchu_measure_hpt_freq(void)
  35{
  36        u64 rtc_start, rtc_current, rtc_delta;
  37        unsigned int start, count;
  38        struct device_node *np;
  39        void __iomem *rtc_base;
  40
  41        np = of_find_compatible_node(NULL, NULL, "google,goldfish-rtc");
  42        if (!np)
  43                panic("%s(): Failed to find 'google,goldfish-rtc' dt node!",
  44                      __func__);
  45
  46        rtc_base = of_iomap(np, 0);
  47        if (!rtc_base)
  48                panic("%s(): Failed to ioremap Goldfish RTC base!", __func__);
  49
  50        /*
  51         * Poll the nanosecond resolution RTC for one
  52         * second to calibrate the CPU frequency.
  53         */
  54        rtc_start = read_rtc_time(rtc_base);
  55        start = read_c0_count();
  56
  57        do {
  58                rtc_current = read_rtc_time(rtc_base);
  59                rtc_delta = rtc_current - rtc_start;
  60        } while (rtc_delta < NSEC_PER_SEC);
  61
  62        count = read_c0_count() - start;
  63
  64        /*
  65         * Make sure the frequency will be a round number.
  66         * Without this correction, the returned value may vary
  67         * between subsequent emulation executions.
  68         *
  69         * TODO: Set this value using device tree.
  70         */
  71        count += 5000;
  72        count -= count % 10000;
  73
  74        iounmap(rtc_base);
  75
  76        return count;
  77}
  78
  79static const struct of_device_id ranchu_of_match[] __initconst = {
  80        {
  81                .compatible = "mti,ranchu",
  82        },
  83        {}
  84};
  85
  86MIPS_MACHINE(ranchu) = {
  87        .matches = ranchu_of_match,
  88        .measure_hpt_freq = ranchu_measure_hpt_freq,
  89};
  90