aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/meson/clkc.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/meson/clkc.h')
-rw-r--r--drivers/clk/meson/clkc.h107
1 files changed, 41 insertions, 66 deletions
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index c2ff0520ce53..8fe73c4edca8 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -18,6 +18,9 @@
18#ifndef __CLKC_H 18#ifndef __CLKC_H
19#define __CLKC_H 19#define __CLKC_H
20 20
21#include <linux/clk-provider.h>
22#include "clk-regmap.h"
23
21#define PMASK(width) GENMASK(width - 1, 0) 24#define PMASK(width) GENMASK(width - 1, 0)
22#define SETPMASK(width, shift) GENMASK(shift + width - 1, shift) 25#define SETPMASK(width, shift) GENMASK(shift + width - 1, shift)
23#define CLRPMASK(width, shift) (~SETPMASK(width, shift)) 26#define CLRPMASK(width, shift) (~SETPMASK(width, shift))
@@ -35,13 +38,29 @@ struct parm {
35 u8 width; 38 u8 width;
36}; 39};
37 40
41static inline unsigned int meson_parm_read(struct regmap *map, struct parm *p)
42{
43 unsigned int val;
44
45 regmap_read(map, p->reg_off, &val);
46 return PARM_GET(p->width, p->shift, val);
47}
48
49static inline void meson_parm_write(struct regmap *map, struct parm *p,
50 unsigned int val)
51{
52 regmap_update_bits(map, p->reg_off, SETPMASK(p->width, p->shift),
53 val << p->shift);
54}
55
56
38struct pll_rate_table { 57struct pll_rate_table {
39 unsigned long rate; 58 unsigned long rate;
40 u16 m; 59 u16 m;
41 u16 n; 60 u16 n;
42 u16 od; 61 u16 od;
43 u16 od2; 62 u16 od2;
44 u16 frac; 63 u16 od3;
45}; 64};
46 65
47#define PLL_RATE(_r, _m, _n, _od) \ 66#define PLL_RATE(_r, _m, _n, _od) \
@@ -50,97 +69,53 @@ struct pll_rate_table {
50 .m = (_m), \ 69 .m = (_m), \
51 .n = (_n), \ 70 .n = (_n), \
52 .od = (_od), \ 71 .od = (_od), \
53 } \
54
55#define PLL_FRAC_RATE(_r, _m, _n, _od, _od2, _frac) \
56 { \
57 .rate = (_r), \
58 .m = (_m), \
59 .n = (_n), \
60 .od = (_od), \
61 .od2 = (_od2), \
62 .frac = (_frac), \
63 } \
64
65struct pll_params_table {
66 unsigned int reg_off;
67 unsigned int value;
68};
69
70#define PLL_PARAM(_reg, _val) \
71 { \
72 .reg_off = (_reg), \
73 .value = (_val), \
74 } 72 }
75 73
76struct pll_setup_params { 74#define CLK_MESON_PLL_ROUND_CLOSEST BIT(0)
77 struct pll_params_table *params_table;
78 unsigned int params_count;
79 /* Workaround for GP0, do not reset before configuring */
80 bool no_init_reset;
81 /* Workaround for GP0, unreset right before checking for lock */
82 bool clear_reset_for_lock;
83 /* Workaround for GXL GP0, reset in the lock checking loop */
84 bool reset_lock_loop;
85};
86 75
87struct meson_clk_pll { 76struct meson_clk_pll_data {
88 struct clk_hw hw;
89 void __iomem *base;
90 struct parm m; 77 struct parm m;
91 struct parm n; 78 struct parm n;
92 struct parm frac; 79 struct parm frac;
93 struct parm od; 80 struct parm od;
94 struct parm od2; 81 struct parm od2;
95 const struct pll_setup_params params; 82 struct parm od3;
96 const struct pll_rate_table *rate_table; 83 struct parm l;
97 unsigned int rate_count; 84 struct parm rst;
98 spinlock_t *lock; 85 const struct reg_sequence *init_regs;
86 unsigned int init_count;
87 const struct pll_rate_table *table;
88 u8 flags;
99}; 89};
100 90
101#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw) 91#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
102 92
103struct meson_clk_cpu { 93struct meson_clk_mpll_data {
104 struct clk_hw hw;
105 void __iomem *base;
106 u16 reg_off;
107 struct notifier_block clk_nb;
108 const struct clk_div_table *div_table;
109};
110
111int meson_clk_cpu_notifier_cb(struct notifier_block *nb, unsigned long event,
112 void *data);
113
114struct meson_clk_mpll {
115 struct clk_hw hw;
116 void __iomem *base;
117 struct parm sdm; 94 struct parm sdm;
118 struct parm sdm_en; 95 struct parm sdm_en;
119 struct parm n2; 96 struct parm n2;
120 struct parm en;
121 struct parm ssen; 97 struct parm ssen;
98 struct parm misc;
122 spinlock_t *lock; 99 spinlock_t *lock;
123}; 100};
124 101
125struct meson_clk_audio_divider { 102struct meson_clk_audio_div_data {
126 struct clk_hw hw;
127 void __iomem *base;
128 struct parm div; 103 struct parm div;
129 u8 flags; 104 u8 flags;
130 spinlock_t *lock;
131}; 105};
132 106
133#define MESON_GATE(_name, _reg, _bit) \ 107#define MESON_GATE(_name, _reg, _bit) \
134struct clk_gate _name = { \ 108struct clk_regmap _name = { \
135 .reg = (void __iomem *) _reg, \ 109 .data = &(struct clk_regmap_gate_data){ \
136 .bit_idx = (_bit), \ 110 .offset = (_reg), \
137 .lock = &meson_clk_lock, \ 111 .bit_idx = (_bit), \
138 .hw.init = &(struct clk_init_data) { \ 112 }, \
139 .name = #_name, \ 113 .hw.init = &(struct clk_init_data) { \
140 .ops = &clk_gate_ops, \ 114 .name = #_name, \
115 .ops = &clk_regmap_gate_ops, \
141 .parent_names = (const char *[]){ "clk81" }, \ 116 .parent_names = (const char *[]){ "clk81" }, \
142 .num_parents = 1, \ 117 .num_parents = 1, \
143 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ 118 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
144 }, \ 119 }, \
145}; 120};
146 121