clkc.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright (c) 2015 Endless Mobile, Inc.
  3. * Author: Carlo Caione <carlo@endlessm.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms and conditions of the GNU General Public License,
  7. * version 2, as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #ifndef __CLKC_H
  18. #define __CLKC_H
  19. #include <linux/clk-provider.h>
  20. #include "clk-regmap.h"
  21. #define PMASK(width) GENMASK(width - 1, 0)
  22. #define SETPMASK(width, shift) GENMASK(shift + width - 1, shift)
  23. #define CLRPMASK(width, shift) (~SETPMASK(width, shift))
  24. #define PARM_GET(width, shift, reg) \
  25. (((reg) & SETPMASK(width, shift)) >> (shift))
  26. #define PARM_SET(width, shift, reg, val) \
  27. (((reg) & CLRPMASK(width, shift)) | ((val) << (shift)))
  28. #define MESON_PARM_APPLICABLE(p) (!!((p)->width))
  29. struct parm {
  30. u16 reg_off;
  31. u8 shift;
  32. u8 width;
  33. };
  34. static inline unsigned int meson_parm_read(struct regmap *map, struct parm *p)
  35. {
  36. unsigned int val;
  37. regmap_read(map, p->reg_off, &val);
  38. return PARM_GET(p->width, p->shift, val);
  39. }
  40. static inline void meson_parm_write(struct regmap *map, struct parm *p,
  41. unsigned int val)
  42. {
  43. regmap_update_bits(map, p->reg_off, SETPMASK(p->width, p->shift),
  44. val << p->shift);
  45. }
  46. struct pll_rate_table {
  47. unsigned long rate;
  48. u16 m;
  49. u16 n;
  50. u16 od;
  51. u16 od2;
  52. u16 od3;
  53. };
  54. #define PLL_RATE(_r, _m, _n, _od) \
  55. { \
  56. .rate = (_r), \
  57. .m = (_m), \
  58. .n = (_n), \
  59. .od = (_od), \
  60. }
  61. #define CLK_MESON_PLL_ROUND_CLOSEST BIT(0)
  62. struct meson_clk_pll_data {
  63. struct parm m;
  64. struct parm n;
  65. struct parm frac;
  66. struct parm od;
  67. struct parm od2;
  68. struct parm od3;
  69. struct parm l;
  70. struct parm rst;
  71. const struct reg_sequence *init_regs;
  72. unsigned int init_count;
  73. const struct pll_rate_table *table;
  74. u8 flags;
  75. };
  76. #define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
  77. struct meson_clk_mpll_data {
  78. struct parm sdm;
  79. struct parm sdm_en;
  80. struct parm n2;
  81. struct parm ssen;
  82. struct parm misc;
  83. spinlock_t *lock;
  84. };
  85. struct meson_clk_audio_div_data {
  86. struct parm div;
  87. u8 flags;
  88. };
  89. #define MESON_GATE(_name, _reg, _bit) \
  90. struct clk_regmap _name = { \
  91. .data = &(struct clk_regmap_gate_data){ \
  92. .offset = (_reg), \
  93. .bit_idx = (_bit), \
  94. }, \
  95. .hw.init = &(struct clk_init_data) { \
  96. .name = #_name, \
  97. .ops = &clk_regmap_gate_ops, \
  98. .parent_names = (const char *[]){ "clk81" }, \
  99. .num_parents = 1, \
  100. .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
  101. }, \
  102. };
  103. /* clk_ops */
  104. extern const struct clk_ops meson_clk_pll_ro_ops;
  105. extern const struct clk_ops meson_clk_pll_ops;
  106. extern const struct clk_ops meson_clk_cpu_ops;
  107. extern const struct clk_ops meson_clk_mpll_ro_ops;
  108. extern const struct clk_ops meson_clk_mpll_ops;
  109. extern const struct clk_ops meson_clk_audio_divider_ro_ops;
  110. extern const struct clk_ops meson_clk_audio_divider_ops;
  111. #endif /* __CLKC_H */