clock-sh7619.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * arch/sh/kernel/cpu/sh2/clock-sh7619.c
  3. *
  4. * SH7619 support for the clock framework
  5. *
  6. * Copyright (C) 2006 Yoshinori Sato
  7. *
  8. * Based on clock-sh4.c
  9. * Copyright (C) 2005 Paul Mundt
  10. *
  11. * This file is subject to the terms and conditions of the GNU General Public
  12. * License. See the file "COPYING" in the main directory of this archive
  13. * for more details.
  14. */
  15. #include <linux/init.h>
  16. #include <linux/kernel.h>
  17. #include <asm/clock.h>
  18. #include <asm/freq.h>
  19. #include <asm/io.h>
  20. static const int pll1rate[] = {1,2};
  21. static const int pfc_divisors[] = {1,2,0,4};
  22. #if (CONFIG_SH_CLK_MD == 1) || (CONFIG_SH_CLK_MD == 2)
  23. #define PLL2 (4)
  24. #elif (CONFIG_SH_CLK_MD == 5) || (CONFIG_SH_CLK_MD == 6)
  25. #define PLL2 (2)
  26. #else
  27. #error "Illigal Clock Mode!"
  28. #endif
  29. static void master_clk_init(struct clk *clk)
  30. {
  31. clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 7];
  32. }
  33. static struct clk_ops sh7619_master_clk_ops = {
  34. .init = master_clk_init,
  35. };
  36. static unsigned long module_clk_recalc(struct clk *clk)
  37. {
  38. int idx = (ctrl_inw(FREQCR) & 0x0007);
  39. return clk->parent->rate / pfc_divisors[idx];
  40. }
  41. static struct clk_ops sh7619_module_clk_ops = {
  42. .recalc = module_clk_recalc,
  43. };
  44. static unsigned long bus_clk_recalc(struct clk *clk)
  45. {
  46. return clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 7];
  47. }
  48. static struct clk_ops sh7619_bus_clk_ops = {
  49. .recalc = bus_clk_recalc,
  50. };
  51. static struct clk_ops sh7619_cpu_clk_ops = {
  52. .recalc = followparent_recalc,
  53. };
  54. static struct clk_ops *sh7619_clk_ops[] = {
  55. &sh7619_master_clk_ops,
  56. &sh7619_module_clk_ops,
  57. &sh7619_bus_clk_ops,
  58. &sh7619_cpu_clk_ops,
  59. };
  60. void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
  61. {
  62. if (idx < ARRAY_SIZE(sh7619_clk_ops))
  63. *ops = sh7619_clk_ops[idx];
  64. }