clk-versatile.c 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Clock driver for the ARM Integrator/AP, Integrator/CP, Versatile AB and
  4. * Versatile PB boards.
  5. * Copyright (C) 2012 Linus Walleij
  6. */
  7. #include <linux/clk-provider.h>
  8. #include <linux/err.h>
  9. #include <linux/of.h>
  10. #include <linux/of_address.h>
  11. #include "icst.h"
  12. #include "clk-icst.h"
  13. #define INTEGRATOR_HDR_LOCK_OFFSET 0x14
  14. #define VERSATILE_SYS_OSCCLCD_OFFSET 0x1c
  15. #define VERSATILE_SYS_LOCK_OFFSET 0x20
  16. /* Base offset for the core module */
  17. static void __iomem *cm_base;
  18. static const struct icst_params cp_auxosc_params = {
  19. .vco_max = ICST525_VCO_MAX_5V,
  20. .vco_min = ICST525_VCO_MIN,
  21. .vd_min = 8,
  22. .vd_max = 263,
  23. .rd_min = 3,
  24. .rd_max = 65,
  25. .s2div = icst525_s2div,
  26. .idx2s = icst525_idx2s,
  27. };
  28. static const struct clk_icst_desc cm_auxosc_desc __initconst = {
  29. .params = &cp_auxosc_params,
  30. .vco_offset = 0x1c,
  31. .lock_offset = INTEGRATOR_HDR_LOCK_OFFSET,
  32. };
  33. static const struct icst_params versatile_auxosc_params = {
  34. .vco_max = ICST307_VCO_MAX,
  35. .vco_min = ICST307_VCO_MIN,
  36. .vd_min = 4 + 8,
  37. .vd_max = 511 + 8,
  38. .rd_min = 1 + 2,
  39. .rd_max = 127 + 2,
  40. .s2div = icst307_s2div,
  41. .idx2s = icst307_idx2s,
  42. };
  43. static const struct clk_icst_desc versatile_auxosc_desc __initconst = {
  44. .params = &versatile_auxosc_params,
  45. .vco_offset = VERSATILE_SYS_OSCCLCD_OFFSET,
  46. .lock_offset = VERSATILE_SYS_LOCK_OFFSET,
  47. };
  48. static void __init cm_osc_setup(struct device_node *np,
  49. const struct clk_icst_desc *desc)
  50. {
  51. struct clk *clk;
  52. const char *clk_name = np->name;
  53. const char *parent_name;
  54. if (!cm_base) {
  55. /* Remap the core module base if not done yet */
  56. struct device_node *parent;
  57. parent = of_get_parent(np);
  58. if (!parent) {
  59. pr_err("no parent on core module clock\n");
  60. return;
  61. }
  62. cm_base = of_iomap(parent, 0);
  63. of_node_put(parent);
  64. if (!cm_base) {
  65. pr_err("could not remap core module base\n");
  66. return;
  67. }
  68. }
  69. parent_name = of_clk_get_parent_name(np, 0);
  70. clk = icst_clk_register(NULL, desc, clk_name, parent_name, cm_base);
  71. if (!IS_ERR(clk))
  72. of_clk_add_provider(np, of_clk_src_simple_get, clk);
  73. }
  74. static void __init of_integrator_cm_osc_setup(struct device_node *np)
  75. {
  76. cm_osc_setup(np, &cm_auxosc_desc);
  77. }
  78. CLK_OF_DECLARE(integrator_cm_auxosc_clk,
  79. "arm,integrator-cm-auxosc", of_integrator_cm_osc_setup);
  80. static void __init of_versatile_cm_osc_setup(struct device_node *np)
  81. {
  82. cm_osc_setup(np, &versatile_auxosc_desc);
  83. }
  84. CLK_OF_DECLARE(versatile_cm_auxosc_clk,
  85. "arm,versatile-cm-auxosc", of_versatile_cm_osc_setup);