board-ranchu.c 2.0 KB

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