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