clkc.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (c) 2015 Endless Mobile, Inc.
  4. * Author: Carlo Caione <carlo@endlessm.com>
  5. */
  6. #ifndef __CLKC_H
  7. #define __CLKC_H
  8. #include <linux/clk-provider.h>
  9. #include "clk-regmap.h"
  10. #define PMASK(width) GENMASK(width - 1, 0)
  11. #define SETPMASK(width, shift) GENMASK(shift + width - 1, shift)
  12. #define CLRPMASK(width, shift) (~SETPMASK(width, shift))
  13. #define PARM_GET(width, shift, reg) \
  14. (((reg) & SETPMASK(width, shift)) >> (shift))
  15. #define PARM_SET(width, shift, reg, val) \
  16. (((reg) & CLRPMASK(width, shift)) | ((val) << (shift)))
  17. #define MESON_PARM_APPLICABLE(p) (!!((p)->width))
  18. struct parm {
  19. u16 reg_off;
  20. u8 shift;
  21. u8 width;
  22. };
  23. static inline unsigned int meson_parm_read(struct regmap *map, struct parm *p)
  24. {
  25. unsigned int val;
  26. regmap_read(map, p->reg_off, &val);
  27. return PARM_GET(p->width, p->shift, val);
  28. }
  29. static inline void meson_parm_write(struct regmap *map, struct parm *p,
  30. unsigned int val)
  31. {
  32. regmap_update_bits(map, p->reg_off, SETPMASK(p->width, p->shift),
  33. val << p->shift);
  34. }
  35. struct pll_rate_table {
  36. unsigned long rate;
  37. u16 m;
  38. u16 n;
  39. u16 od;
  40. u16 od2;
  41. u16 od3;
  42. };
  43. #define PLL_RATE(_r, _m, _n, _od) \
  44. { \
  45. .rate = (_r), \
  46. .m = (_m), \
  47. .n = (_n), \
  48. .od = (_od), \
  49. }
  50. #define CLK_MESON_PLL_ROUND_CLOSEST BIT(0)
  51. struct meson_clk_pll_data {
  52. struct parm m;
  53. struct parm n;
  54. struct parm frac;
  55. struct parm od;
  56. struct parm od2;
  57. struct parm od3;
  58. struct parm l;
  59. struct parm rst;
  60. const struct reg_sequence *init_regs;
  61. unsigned int init_count;
  62. const struct pll_rate_table *table;
  63. u8 flags;
  64. };
  65. #define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
  66. struct meson_clk_mpll_data {
  67. struct parm sdm;
  68. struct parm sdm_en;
  69. struct parm n2;
  70. struct parm ssen;
  71. struct parm misc;
  72. spinlock_t *lock;
  73. u8 flags;
  74. };
  75. #define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0)
  76. struct meson_clk_audio_div_data {
  77. struct parm div;
  78. u8 flags;
  79. };
  80. #define MESON_GATE(_name, _reg, _bit) \
  81. struct clk_regmap _name = { \
  82. .data = &(struct clk_regmap_gate_data){ \
  83. .offset = (_reg), \
  84. .bit_idx = (_bit), \
  85. }, \
  86. .hw.init = &(struct clk_init_data) { \
  87. .name = #_name, \
  88. .ops = &clk_regmap_gate_ops, \
  89. .parent_names = (const char *[]){ "clk81" }, \
  90. .num_parents = 1, \
  91. .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
  92. }, \
  93. };
  94. /* clk_ops */
  95. extern const struct clk_ops meson_clk_pll_ro_ops;
  96. extern const struct clk_ops meson_clk_pll_ops;
  97. extern const struct clk_ops meson_clk_cpu_ops;
  98. extern const struct clk_ops meson_clk_mpll_ro_ops;
  99. extern const struct clk_ops meson_clk_mpll_ops;
  100. extern const struct clk_ops meson_clk_audio_divider_ro_ops;
  101. extern const struct clk_ops meson_clk_audio_divider_ops;
  102. #endif /* __CLKC_H */