xref: /OK3568_Linux_fs/kernel/drivers/clk/zte/clk.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright 2015 Linaro Ltd.
4*4882a593Smuzhiyun  * Copyright (C) 2014 ZTE Corporation.
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #ifndef __ZTE_CLK_H
8*4882a593Smuzhiyun #define __ZTE_CLK_H
9*4882a593Smuzhiyun #include <linux/clk-provider.h>
10*4882a593Smuzhiyun #include <linux/spinlock.h>
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #define PNAME(x) static const char *x[]
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun struct zx_pll_config {
15*4882a593Smuzhiyun 	unsigned long rate;
16*4882a593Smuzhiyun 	u32 cfg0;
17*4882a593Smuzhiyun 	u32 cfg1;
18*4882a593Smuzhiyun };
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun struct clk_zx_pll {
21*4882a593Smuzhiyun 	struct clk_hw hw;
22*4882a593Smuzhiyun 	void __iomem *reg_base;
23*4882a593Smuzhiyun 	const struct zx_pll_config *lookup_table; /* order by rate asc */
24*4882a593Smuzhiyun 	int count;
25*4882a593Smuzhiyun 	spinlock_t *lock;
26*4882a593Smuzhiyun 	u8 pd_bit;		/* power down bit */
27*4882a593Smuzhiyun 	u8 lock_bit;		/* pll lock flag bit */
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define PLL_RATE(_rate, _cfg0, _cfg1)	\
31*4882a593Smuzhiyun {					\
32*4882a593Smuzhiyun 	.rate = _rate,			\
33*4882a593Smuzhiyun 	.cfg0 = _cfg0,			\
34*4882a593Smuzhiyun 	.cfg1 = _cfg1,			\
35*4882a593Smuzhiyun }
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun #define ZX_PLL(_name, _parent, _reg, _table, _pd, _lock)		\
38*4882a593Smuzhiyun {									\
39*4882a593Smuzhiyun 	.reg_base	= (void __iomem *) _reg,			\
40*4882a593Smuzhiyun 	.lookup_table	= _table,					\
41*4882a593Smuzhiyun 	.count		= ARRAY_SIZE(_table),				\
42*4882a593Smuzhiyun 	.pd_bit		= _pd,						\
43*4882a593Smuzhiyun 	.lock_bit	= _lock,					\
44*4882a593Smuzhiyun 	.hw.init	 = CLK_HW_INIT(_name, _parent, &zx_pll_ops,	\
45*4882a593Smuzhiyun 				CLK_GET_RATE_NOCACHE),			\
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun /*
49*4882a593Smuzhiyun  * The pd_bit is not available on ZX296718, so let's pass something
50*4882a593Smuzhiyun  * bigger than 31, e.g. 0xff, to indicate that.
51*4882a593Smuzhiyun  */
52*4882a593Smuzhiyun #define ZX296718_PLL(_name, _parent, _reg, _table)			\
53*4882a593Smuzhiyun ZX_PLL(_name, _parent, _reg, _table, 0xff, 30)
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun struct zx_clk_gate {
56*4882a593Smuzhiyun 	struct clk_gate gate;
57*4882a593Smuzhiyun 	u16		id;
58*4882a593Smuzhiyun };
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun #define GATE(_id, _name, _parent, _reg, _bit, _flag, _gflags)		\
61*4882a593Smuzhiyun {									\
62*4882a593Smuzhiyun 	.gate = {							\
63*4882a593Smuzhiyun 		.reg = (void __iomem *) _reg,				\
64*4882a593Smuzhiyun 		.bit_idx = (_bit),					\
65*4882a593Smuzhiyun 		.flags = _gflags,					\
66*4882a593Smuzhiyun 		.lock = &clk_lock,					\
67*4882a593Smuzhiyun 		.hw.init = CLK_HW_INIT(_name,				\
68*4882a593Smuzhiyun 					_parent,			\
69*4882a593Smuzhiyun 					&clk_gate_ops,			\
70*4882a593Smuzhiyun 					_flag | CLK_IGNORE_UNUSED),	\
71*4882a593Smuzhiyun 	},								\
72*4882a593Smuzhiyun 	.id	= _id,							\
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun struct zx_clk_fixed_factor {
76*4882a593Smuzhiyun 	struct clk_fixed_factor factor;
77*4882a593Smuzhiyun 	u16	id;
78*4882a593Smuzhiyun };
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun #define FFACTOR(_id, _name, _parent, _mult, _div, _flag)		\
81*4882a593Smuzhiyun {									\
82*4882a593Smuzhiyun 	.factor = {							\
83*4882a593Smuzhiyun 		.div		= _div,					\
84*4882a593Smuzhiyun 		.mult		= _mult,				\
85*4882a593Smuzhiyun 		.hw.init	= CLK_HW_INIT(_name,			\
86*4882a593Smuzhiyun 					      _parent,			\
87*4882a593Smuzhiyun 					      &clk_fixed_factor_ops,	\
88*4882a593Smuzhiyun 					      _flag),			\
89*4882a593Smuzhiyun 	},								\
90*4882a593Smuzhiyun 	.id = _id,							\
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun struct zx_clk_mux {
94*4882a593Smuzhiyun 	struct clk_mux mux;
95*4882a593Smuzhiyun 	u16	id;
96*4882a593Smuzhiyun };
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun #define MUX_F(_id, _name, _parent, _reg, _shift, _width, _flag, _mflag)	\
99*4882a593Smuzhiyun {									\
100*4882a593Smuzhiyun 	.mux = {							\
101*4882a593Smuzhiyun 		.reg		= (void __iomem *) _reg,		\
102*4882a593Smuzhiyun 		.mask		= BIT(_width) - 1,			\
103*4882a593Smuzhiyun 		.shift		= _shift,				\
104*4882a593Smuzhiyun 		.flags		= _mflag,				\
105*4882a593Smuzhiyun 		.lock		= &clk_lock,				\
106*4882a593Smuzhiyun 		.hw.init	= CLK_HW_INIT_PARENTS(_name,		\
107*4882a593Smuzhiyun 						      _parent,		\
108*4882a593Smuzhiyun 						      &clk_mux_ops,	\
109*4882a593Smuzhiyun 						      _flag),		\
110*4882a593Smuzhiyun 	},								\
111*4882a593Smuzhiyun 	.id = _id,							\
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun #define MUX(_id, _name, _parent, _reg, _shift, _width)			\
115*4882a593Smuzhiyun MUX_F(_id, _name, _parent, _reg, _shift, _width, 0, 0)
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun struct zx_clk_div {
118*4882a593Smuzhiyun 	struct clk_divider div;
119*4882a593Smuzhiyun 	u16	id;
120*4882a593Smuzhiyun };
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun #define DIV_T(_id, _name, _parent, _reg, _shift, _width, _flag, _table)	\
123*4882a593Smuzhiyun {									\
124*4882a593Smuzhiyun 	.div = {							\
125*4882a593Smuzhiyun 		.reg		= (void __iomem *) _reg,		\
126*4882a593Smuzhiyun 		.shift		= _shift,				\
127*4882a593Smuzhiyun 		.width		= _width,				\
128*4882a593Smuzhiyun 		.flags		= 0,					\
129*4882a593Smuzhiyun 		.table		= _table,				\
130*4882a593Smuzhiyun 		.lock		= &clk_lock,				\
131*4882a593Smuzhiyun 		.hw.init	= CLK_HW_INIT(_name,			\
132*4882a593Smuzhiyun 					      _parent,			\
133*4882a593Smuzhiyun 					      &clk_divider_ops,		\
134*4882a593Smuzhiyun 					      _flag),			\
135*4882a593Smuzhiyun 	},								\
136*4882a593Smuzhiyun 	.id = _id,							\
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun struct clk_zx_audio_divider {
140*4882a593Smuzhiyun 	struct clk_hw				hw;
141*4882a593Smuzhiyun 	void __iomem				*reg_base;
142*4882a593Smuzhiyun 	unsigned int				rate_count;
143*4882a593Smuzhiyun 	spinlock_t				*lock;
144*4882a593Smuzhiyun 	u16					id;
145*4882a593Smuzhiyun };
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun #define AUDIO_DIV(_id, _name, _parent, _reg)				\
148*4882a593Smuzhiyun {									\
149*4882a593Smuzhiyun 	.reg_base	= (void __iomem *) _reg,			\
150*4882a593Smuzhiyun 	.lock		= &clk_lock,					\
151*4882a593Smuzhiyun 	.hw.init	= CLK_HW_INIT(_name,				\
152*4882a593Smuzhiyun 				      _parent,				\
153*4882a593Smuzhiyun 				      &zx_audio_div_ops,		\
154*4882a593Smuzhiyun 				      0),				\
155*4882a593Smuzhiyun 	.id = _id,							\
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun struct clk *clk_register_zx_pll(const char *name, const char *parent_name,
159*4882a593Smuzhiyun 	unsigned long flags, void __iomem *reg_base,
160*4882a593Smuzhiyun 	const struct zx_pll_config *lookup_table, int count, spinlock_t *lock);
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun struct clk_zx_audio {
163*4882a593Smuzhiyun 	struct clk_hw hw;
164*4882a593Smuzhiyun 	void __iomem *reg_base;
165*4882a593Smuzhiyun };
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun struct clk *clk_register_zx_audio(const char *name,
168*4882a593Smuzhiyun 				  const char * const parent_name,
169*4882a593Smuzhiyun 				  unsigned long flags, void __iomem *reg_base);
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun extern const struct clk_ops zx_pll_ops;
172*4882a593Smuzhiyun extern const struct clk_ops zx_audio_div_ops;
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun #endif
175