clkc.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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_params_table {
  36. u16 m;
  37. u16 n;
  38. };
  39. #define PLL_PARAMS(_m, _n) \
  40. { \
  41. .m = (_m), \
  42. .n = (_n), \
  43. }
  44. #define CLK_MESON_PLL_ROUND_CLOSEST BIT(0)
  45. struct meson_clk_pll_data {
  46. struct parm en;
  47. struct parm m;
  48. struct parm n;
  49. struct parm frac;
  50. struct parm l;
  51. struct parm rst;
  52. const struct reg_sequence *init_regs;
  53. unsigned int init_count;
  54. const struct pll_params_table *table;
  55. u8 flags;
  56. };
  57. #define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
  58. struct meson_clk_mpll_data {
  59. struct parm sdm;
  60. struct parm sdm_en;
  61. struct parm n2;
  62. struct parm ssen;
  63. struct parm misc;
  64. spinlock_t *lock;
  65. u8 flags;
  66. };
  67. #define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0)
  68. struct meson_clk_phase_data {
  69. struct parm ph;
  70. };
  71. int meson_clk_degrees_from_val(unsigned int val, unsigned int width);
  72. unsigned int meson_clk_degrees_to_val(int degrees, unsigned int width);
  73. #define MESON_GATE(_name, _reg, _bit) \
  74. struct clk_regmap _name = { \
  75. .data = &(struct clk_regmap_gate_data){ \
  76. .offset = (_reg), \
  77. .bit_idx = (_bit), \
  78. }, \
  79. .hw.init = &(struct clk_init_data) { \
  80. .name = #_name, \
  81. .ops = &clk_regmap_gate_ops, \
  82. .parent_names = (const char *[]){ "clk81" }, \
  83. .num_parents = 1, \
  84. .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
  85. }, \
  86. };
  87. /* clk_ops */
  88. extern const struct clk_ops meson_clk_pll_ro_ops;
  89. extern const struct clk_ops meson_clk_pll_ops;
  90. extern const struct clk_ops meson_clk_cpu_ops;
  91. extern const struct clk_ops meson_clk_mpll_ro_ops;
  92. extern const struct clk_ops meson_clk_mpll_ops;
  93. extern const struct clk_ops meson_clk_phase_ops;
  94. #endif /* __CLKC_H */