clock.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * arch/metag/kernel/clock.c
  3. *
  4. * Copyright (C) 2012 Imagination Technologies Ltd.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <linux/clk.h>
  11. #include <linux/delay.h>
  12. #include <linux/io.h>
  13. #include <linux/of.h>
  14. #include <asm/param.h>
  15. #include <asm/clock.h>
  16. struct meta_clock_desc _meta_clock;
  17. /* Default machine get_core_freq callback. */
  18. static unsigned long get_core_freq_default(void)
  19. {
  20. #ifdef CONFIG_METAG_META21
  21. /*
  22. * Meta 2 cores divide down the core clock for the Meta timers, so we
  23. * can estimate the core clock from the divider.
  24. */
  25. return (metag_in32(EXPAND_TIMER_DIV) + 1) * 1000000;
  26. #else
  27. /*
  28. * On Meta 1 we don't know the core clock, but assuming the Meta timer
  29. * is correct it can be estimated based on loops_per_jiffy.
  30. */
  31. return (loops_per_jiffy * HZ * 5) >> 1;
  32. #endif
  33. }
  34. static struct clk *clk_core;
  35. /* Clk based get_core_freq callback. */
  36. static unsigned long get_core_freq_clk(void)
  37. {
  38. return clk_get_rate(clk_core);
  39. }
  40. /**
  41. * init_metag_core_clock() - Set up core clock from devicetree.
  42. *
  43. * Checks to see if a "core" clock is provided in the device tree, and overrides
  44. * the get_core_freq callback to use it.
  45. */
  46. static void __init init_metag_core_clock(void)
  47. {
  48. /*
  49. * See if a core clock is provided by the devicetree (and
  50. * registered by the init callback above).
  51. */
  52. struct device_node *node;
  53. node = of_find_compatible_node(NULL, NULL, "img,meta");
  54. if (!node) {
  55. pr_warn("%s: no compatible img,meta DT node found\n",
  56. __func__);
  57. return;
  58. }
  59. clk_core = of_clk_get_by_name(node, "core");
  60. if (IS_ERR(clk_core)) {
  61. pr_warn("%s: no core clock found in DT\n",
  62. __func__);
  63. return;
  64. }
  65. /*
  66. * Override the core frequency callback to use
  67. * this clk.
  68. */
  69. _meta_clock.get_core_freq = get_core_freq_clk;
  70. }
  71. /**
  72. * init_metag_clocks() - Set up clocks from devicetree.
  73. *
  74. * Set up important clocks from device tree. In particular any needed for clock
  75. * sources.
  76. */
  77. void __init init_metag_clocks(void)
  78. {
  79. init_metag_core_clock();
  80. pr_info("Core clock frequency: %lu Hz\n", get_coreclock());
  81. }
  82. /**
  83. * setup_meta_clocks() - Early set up of the Meta clock.
  84. * @desc: Clock descriptor usually provided by machine description
  85. *
  86. * Ensures all callbacks are valid.
  87. */
  88. void __init setup_meta_clocks(struct meta_clock_desc *desc)
  89. {
  90. /* copy callbacks */
  91. if (desc)
  92. _meta_clock = *desc;
  93. /* set fallback functions */
  94. if (!_meta_clock.get_core_freq)
  95. _meta_clock.get_core_freq = get_core_freq_default;
  96. }