board-ranchu.c 2.2 KB

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