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