xref: /openbmc/linux/drivers/clk/mmp/clk.h (revision 4b4193256c8d3bc3a5397b5cd9494c2ad386317d)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
26b63f023SChao Xie #ifndef __MACH_MMP_CLK_H
36b63f023SChao Xie #define __MACH_MMP_CLK_H
46b63f023SChao Xie 
56b63f023SChao Xie #include <linux/clk-provider.h>
6*ee4df236SLubomir Rintel #include <linux/pm_domain.h>
76b63f023SChao Xie #include <linux/clkdev.h>
86b63f023SChao Xie 
96b63f023SChao Xie #define APBC_NO_BUS_CTRL	BIT(0)
106b63f023SChao Xie #define APBC_POWER_CTRL		BIT(1)
116b63f023SChao Xie 
123a2b2f84SChao Xie 
133a2b2f84SChao Xie /* Clock type "factor" */
142bd1e256SChao Xie struct mmp_clk_factor_masks {
156b63f023SChao Xie 	unsigned int factor;
166b63f023SChao Xie 	unsigned int num_mask;
176b63f023SChao Xie 	unsigned int den_mask;
186b63f023SChao Xie 	unsigned int num_shift;
196b63f023SChao Xie 	unsigned int den_shift;
205278acc4SLubomir Rintel 	unsigned int enable_mask;
216b63f023SChao Xie };
226b63f023SChao Xie 
232bd1e256SChao Xie struct mmp_clk_factor_tbl {
246b63f023SChao Xie 	unsigned int num;
256b63f023SChao Xie 	unsigned int den;
266b63f023SChao Xie };
276b63f023SChao Xie 
283a2b2f84SChao Xie struct mmp_clk_factor {
293a2b2f84SChao Xie 	struct clk_hw hw;
303a2b2f84SChao Xie 	void __iomem *base;
313a2b2f84SChao Xie 	struct mmp_clk_factor_masks *masks;
323a2b2f84SChao Xie 	struct mmp_clk_factor_tbl *ftbl;
333a2b2f84SChao Xie 	unsigned int ftbl_cnt;
343a2b2f84SChao Xie 	spinlock_t *lock;
353a2b2f84SChao Xie };
363a2b2f84SChao Xie 
373a2b2f84SChao Xie extern struct clk *mmp_clk_register_factor(const char *name,
383a2b2f84SChao Xie 		const char *parent_name, unsigned long flags,
393a2b2f84SChao Xie 		void __iomem *base, struct mmp_clk_factor_masks *masks,
403a2b2f84SChao Xie 		struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
413a2b2f84SChao Xie 		spinlock_t *lock);
423a2b2f84SChao Xie 
43ee81f4eeSChao Xie /* Clock type "mix" */
44ee81f4eeSChao Xie #define MMP_CLK_BITS_MASK(width, shift)			\
45ee81f4eeSChao Xie 		(((1 << (width)) - 1) << (shift))
46ee81f4eeSChao Xie #define MMP_CLK_BITS_GET_VAL(data, width, shift)	\
47ee81f4eeSChao Xie 		((data & MMP_CLK_BITS_MASK(width, shift)) >> (shift))
48ee81f4eeSChao Xie #define MMP_CLK_BITS_SET_VAL(val, width, shift)		\
49ee81f4eeSChao Xie 		(((val) << (shift)) & MMP_CLK_BITS_MASK(width, shift))
50ee81f4eeSChao Xie 
51ee81f4eeSChao Xie enum {
52ee81f4eeSChao Xie 	MMP_CLK_MIX_TYPE_V1,
53ee81f4eeSChao Xie 	MMP_CLK_MIX_TYPE_V2,
54ee81f4eeSChao Xie 	MMP_CLK_MIX_TYPE_V3,
55ee81f4eeSChao Xie };
56ee81f4eeSChao Xie 
57ee81f4eeSChao Xie /* The register layout */
58ee81f4eeSChao Xie struct mmp_clk_mix_reg_info {
59ee81f4eeSChao Xie 	void __iomem *reg_clk_ctrl;
60ee81f4eeSChao Xie 	void __iomem *reg_clk_sel;
61ee81f4eeSChao Xie 	u8 width_div;
62ee81f4eeSChao Xie 	u8 shift_div;
63ee81f4eeSChao Xie 	u8 width_mux;
64ee81f4eeSChao Xie 	u8 shift_mux;
65ee81f4eeSChao Xie 	u8 bit_fc;
66ee81f4eeSChao Xie };
67ee81f4eeSChao Xie 
68ee81f4eeSChao Xie /* The suggested clock table from user. */
69ee81f4eeSChao Xie struct mmp_clk_mix_clk_table {
70ee81f4eeSChao Xie 	unsigned long rate;
71ee81f4eeSChao Xie 	u8 parent_index;
72ee81f4eeSChao Xie 	unsigned int divisor;
73ee81f4eeSChao Xie 	unsigned int valid;
74ee81f4eeSChao Xie };
75ee81f4eeSChao Xie 
76ee81f4eeSChao Xie struct mmp_clk_mix_config {
77ee81f4eeSChao Xie 	struct mmp_clk_mix_reg_info reg_info;
78ee81f4eeSChao Xie 	struct mmp_clk_mix_clk_table *table;
79ee81f4eeSChao Xie 	unsigned int table_size;
80ee81f4eeSChao Xie 	u32 *mux_table;
81ee81f4eeSChao Xie 	struct clk_div_table *div_table;
82ee81f4eeSChao Xie 	u8 div_flags;
83ee81f4eeSChao Xie 	u8 mux_flags;
84ee81f4eeSChao Xie };
85ee81f4eeSChao Xie 
86ee81f4eeSChao Xie struct mmp_clk_mix {
87ee81f4eeSChao Xie 	struct clk_hw hw;
88ee81f4eeSChao Xie 	struct mmp_clk_mix_reg_info reg_info;
89ee81f4eeSChao Xie 	struct mmp_clk_mix_clk_table *table;
90ee81f4eeSChao Xie 	u32 *mux_table;
91ee81f4eeSChao Xie 	struct clk_div_table *div_table;
92ee81f4eeSChao Xie 	unsigned int table_size;
93ee81f4eeSChao Xie 	u8 div_flags;
94ee81f4eeSChao Xie 	u8 mux_flags;
95ee81f4eeSChao Xie 	unsigned int type;
96ee81f4eeSChao Xie 	spinlock_t *lock;
97ee81f4eeSChao Xie };
98ee81f4eeSChao Xie 
99ee81f4eeSChao Xie extern const struct clk_ops mmp_clk_mix_ops;
100ee81f4eeSChao Xie extern struct clk *mmp_clk_register_mix(struct device *dev,
101ee81f4eeSChao Xie 					const char *name,
102cb8dbfe8SLubomir Rintel 					const char * const *parent_names,
1034661fda1SChao Xie 					u8 num_parents,
104ee81f4eeSChao Xie 					unsigned long flags,
105ee81f4eeSChao Xie 					struct mmp_clk_mix_config *config,
106ee81f4eeSChao Xie 					spinlock_t *lock);
107ee81f4eeSChao Xie 
108ee81f4eeSChao Xie 
109cdce3546SChao Xie /* Clock type "gate". MMP private gate */
110cdce3546SChao Xie #define MMP_CLK_GATE_NEED_DELAY		BIT(0)
111cdce3546SChao Xie 
112cdce3546SChao Xie struct mmp_clk_gate {
113cdce3546SChao Xie 	struct clk_hw hw;
114cdce3546SChao Xie 	void __iomem *reg;
115cdce3546SChao Xie 	u32 mask;
116cdce3546SChao Xie 	u32 val_enable;
117cdce3546SChao Xie 	u32 val_disable;
118cdce3546SChao Xie 	unsigned int flags;
119cdce3546SChao Xie 	spinlock_t *lock;
120cdce3546SChao Xie };
121cdce3546SChao Xie 
122cdce3546SChao Xie extern const struct clk_ops mmp_clk_gate_ops;
123cdce3546SChao Xie extern struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
124cdce3546SChao Xie 			const char *parent_name, unsigned long flags,
125cdce3546SChao Xie 			void __iomem *reg, u32 mask, u32 val_enable,
126cdce3546SChao Xie 			u32 val_disable, unsigned int gate_flags,
127cdce3546SChao Xie 			spinlock_t *lock);
128cdce3546SChao Xie 
1296b63f023SChao Xie extern struct clk *mmp_clk_register_apbc(const char *name,
1306b63f023SChao Xie 		const char *parent_name, void __iomem *base,
1316b63f023SChao Xie 		unsigned int delay, unsigned int apbc_flags, spinlock_t *lock);
1326b63f023SChao Xie extern struct clk *mmp_clk_register_apmu(const char *name,
1336b63f023SChao Xie 		const char *parent_name, void __iomem *base, u32 enable_mask,
1346b63f023SChao Xie 		spinlock_t *lock);
1354661fda1SChao Xie 
1364661fda1SChao Xie struct mmp_clk_unit {
1374661fda1SChao Xie 	unsigned int nr_clks;
1384661fda1SChao Xie 	struct clk **clk_table;
1394661fda1SChao Xie 	struct clk_onecell_data clk_data;
1404661fda1SChao Xie };
1414661fda1SChao Xie 
1424661fda1SChao Xie struct mmp_param_fixed_rate_clk {
1434661fda1SChao Xie 	unsigned int id;
1444661fda1SChao Xie 	char *name;
1454661fda1SChao Xie 	const char *parent_name;
1464661fda1SChao Xie 	unsigned long flags;
1474661fda1SChao Xie 	unsigned long fixed_rate;
1484661fda1SChao Xie };
1494661fda1SChao Xie void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit,
1504661fda1SChao Xie 				struct mmp_param_fixed_rate_clk *clks,
1514661fda1SChao Xie 				int size);
1524661fda1SChao Xie 
1534661fda1SChao Xie struct mmp_param_fixed_factor_clk {
1544661fda1SChao Xie 	unsigned int id;
1554661fda1SChao Xie 	char *name;
1564661fda1SChao Xie 	const char *parent_name;
1574661fda1SChao Xie 	unsigned long mult;
1584661fda1SChao Xie 	unsigned long div;
1594661fda1SChao Xie 	unsigned long flags;
1604661fda1SChao Xie };
1614661fda1SChao Xie void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit,
1624661fda1SChao Xie 				struct mmp_param_fixed_factor_clk *clks,
1634661fda1SChao Xie 				int size);
1644661fda1SChao Xie 
1654661fda1SChao Xie struct mmp_param_general_gate_clk {
1664661fda1SChao Xie 	unsigned int id;
1674661fda1SChao Xie 	const char *name;
1684661fda1SChao Xie 	const char *parent_name;
1694661fda1SChao Xie 	unsigned long flags;
1704661fda1SChao Xie 	unsigned long offset;
1714661fda1SChao Xie 	u8 bit_idx;
1724661fda1SChao Xie 	u8 gate_flags;
1734661fda1SChao Xie 	spinlock_t *lock;
1744661fda1SChao Xie };
1754661fda1SChao Xie void mmp_register_general_gate_clks(struct mmp_clk_unit *unit,
1764661fda1SChao Xie 				struct mmp_param_general_gate_clk *clks,
1774661fda1SChao Xie 				void __iomem *base, int size);
1784661fda1SChao Xie 
1794661fda1SChao Xie struct mmp_param_gate_clk {
1804661fda1SChao Xie 	unsigned int id;
1814661fda1SChao Xie 	char *name;
1824661fda1SChao Xie 	const char *parent_name;
1834661fda1SChao Xie 	unsigned long flags;
1844661fda1SChao Xie 	unsigned long offset;
1854661fda1SChao Xie 	u32 mask;
1864661fda1SChao Xie 	u32 val_enable;
1874661fda1SChao Xie 	u32 val_disable;
1884661fda1SChao Xie 	unsigned int gate_flags;
1894661fda1SChao Xie 	spinlock_t *lock;
1904661fda1SChao Xie };
1914661fda1SChao Xie void mmp_register_gate_clks(struct mmp_clk_unit *unit,
1924661fda1SChao Xie 			struct mmp_param_gate_clk *clks,
1934661fda1SChao Xie 			void __iomem *base, int size);
1944661fda1SChao Xie 
1954661fda1SChao Xie struct mmp_param_mux_clk {
1964661fda1SChao Xie 	unsigned int id;
1974661fda1SChao Xie 	char *name;
198cb8dbfe8SLubomir Rintel 	const char * const *parent_name;
1994661fda1SChao Xie 	u8 num_parents;
2004661fda1SChao Xie 	unsigned long flags;
2014661fda1SChao Xie 	unsigned long offset;
2024661fda1SChao Xie 	u8 shift;
2034661fda1SChao Xie 	u8 width;
2044661fda1SChao Xie 	u8 mux_flags;
2054661fda1SChao Xie 	spinlock_t *lock;
2064661fda1SChao Xie };
2074661fda1SChao Xie void mmp_register_mux_clks(struct mmp_clk_unit *unit,
2084661fda1SChao Xie 			struct mmp_param_mux_clk *clks,
2094661fda1SChao Xie 			void __iomem *base, int size);
2104661fda1SChao Xie 
2114661fda1SChao Xie struct mmp_param_div_clk {
2124661fda1SChao Xie 	unsigned int id;
2134661fda1SChao Xie 	char *name;
2144661fda1SChao Xie 	const char *parent_name;
2154661fda1SChao Xie 	unsigned long flags;
2164661fda1SChao Xie 	unsigned long offset;
2174661fda1SChao Xie 	u8 shift;
2184661fda1SChao Xie 	u8 width;
2194661fda1SChao Xie 	u8 div_flags;
2204661fda1SChao Xie 	spinlock_t *lock;
2214661fda1SChao Xie };
2224661fda1SChao Xie void mmp_register_div_clks(struct mmp_clk_unit *unit,
2234661fda1SChao Xie 			struct mmp_param_div_clk *clks,
2244661fda1SChao Xie 			void __iomem *base, int size);
2254661fda1SChao Xie 
2265d34d0b3SLubomir Rintel struct mmp_param_pll_clk {
2275d34d0b3SLubomir Rintel 	unsigned int id;
2285d34d0b3SLubomir Rintel 	char *name;
2295d34d0b3SLubomir Rintel 	unsigned long default_rate;
2305d34d0b3SLubomir Rintel 	unsigned long enable_offset;
2315d34d0b3SLubomir Rintel 	u32 enable;
2325d34d0b3SLubomir Rintel 	unsigned long offset;
2335d34d0b3SLubomir Rintel 	u8 shift;
2345d34d0b3SLubomir Rintel 	/* MMP3 specific: */
2355d34d0b3SLubomir Rintel 	unsigned long input_rate;
2365d34d0b3SLubomir Rintel 	unsigned long postdiv_offset;
2375d34d0b3SLubomir Rintel 	unsigned long postdiv_shift;
2385d34d0b3SLubomir Rintel };
2395d34d0b3SLubomir Rintel void mmp_register_pll_clks(struct mmp_clk_unit *unit,
2405d34d0b3SLubomir Rintel 			struct mmp_param_pll_clk *clks,
2415d34d0b3SLubomir Rintel 			void __iomem *base, int size);
2425d34d0b3SLubomir Rintel 
2434661fda1SChao Xie #define DEFINE_MIX_REG_INFO(w_d, s_d, w_m, s_m, fc)	\
2444661fda1SChao Xie {							\
2454661fda1SChao Xie 	.width_div = (w_d),				\
2464661fda1SChao Xie 	.shift_div = (s_d),				\
2474661fda1SChao Xie 	.width_mux = (w_m),				\
2484661fda1SChao Xie 	.shift_mux = (s_m),				\
2494661fda1SChao Xie 	.bit_fc = (fc),					\
2504661fda1SChao Xie }
2514661fda1SChao Xie 
2524661fda1SChao Xie void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
2534661fda1SChao Xie 		int nr_clks);
2544661fda1SChao Xie void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
2554661fda1SChao Xie 		struct clk *clk);
256*ee4df236SLubomir Rintel 
257*ee4df236SLubomir Rintel /* Power islands */
258*ee4df236SLubomir Rintel #define MMP_PM_DOMAIN_NO_DISABLE		BIT(0)
259*ee4df236SLubomir Rintel 
260*ee4df236SLubomir Rintel struct generic_pm_domain *mmp_pm_domain_register(const char *name,
261*ee4df236SLubomir Rintel 		void __iomem *reg,
262*ee4df236SLubomir Rintel 		u32 power_on, u32 reset, u32 clock_enable,
263*ee4df236SLubomir Rintel 		unsigned int flags, spinlock_t *lock);
264*ee4df236SLubomir Rintel 
2656b63f023SChao Xie #endif
266