xref: /linux/drivers/clk/pxa/clk-pxa.h (revision 80d443e8876602be2c130f79c4de81e12e2a700d)
1 /*
2  * Marvell PXA family clocks
3  *
4  * Copyright (C) 2014 Robert Jarzmik
5  *
6  * Common clock code for PXA clocks ("CKEN" type clocks + DT)
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; version 2 of the License.
11  *
12  */
13 #ifndef _CLK_PXA_
14 #define _CLK_PXA_
15 
16 #define CLKCFG_TURBO		0x1
17 #define CLKCFG_FCS		0x2
18 #define CLKCFG_HALFTURBO	0x4
19 #define CLKCFG_FASTBUS		0x8
20 
21 #define PARENTS(name) \
22 	static const char *const name ## _parents[] __initconst
23 #define MUX_RO_RATE_RO_OPS(name, clk_name)			\
24 	static struct clk_hw name ## _mux_hw;			\
25 	static struct clk_hw name ## _rate_hw;			\
26 	static struct clk_ops name ## _mux_ops = {		\
27 		.get_parent = name ## _get_parent,		\
28 		.set_parent = dummy_clk_set_parent,		\
29 	};							\
30 	static struct clk_ops name ## _rate_ops = {		\
31 		.recalc_rate = name ## _get_rate,		\
32 	};							\
33 	static struct clk * __init clk_register_ ## name(void)	\
34 	{							\
35 		return clk_register_composite(NULL, clk_name,	\
36 			name ## _parents,			\
37 			ARRAY_SIZE(name ## _parents),		\
38 			&name ## _mux_hw, &name ## _mux_ops,	\
39 			&name ## _rate_hw, &name ## _rate_ops,	\
40 			NULL, NULL, CLK_GET_RATE_NOCACHE);	\
41 	}
42 
43 #define RATE_RO_OPS(name, clk_name)				\
44 	static struct clk_hw name ## _rate_hw;			\
45 	static const struct clk_ops name ## _rate_ops = {		\
46 		.recalc_rate = name ## _get_rate,		\
47 	};							\
48 	static struct clk * __init clk_register_ ## name(void)	\
49 	{							\
50 		return clk_register_composite(NULL, clk_name,	\
51 			name ## _parents,			\
52 			ARRAY_SIZE(name ## _parents),		\
53 			NULL, NULL,				\
54 			&name ## _rate_hw, &name ## _rate_ops,	\
55 			NULL, NULL, CLK_GET_RATE_NOCACHE);	\
56 	}
57 
58 #define RATE_OPS(name, clk_name)				\
59 	static struct clk_hw name ## _rate_hw;			\
60 	static struct clk_ops name ## _rate_ops = {		\
61 		.recalc_rate = name ## _get_rate,		\
62 		.set_rate = name ## _set_rate,			\
63 		.determine_rate = name ## _determine_rate,	\
64 	};							\
65 	static struct clk * __init clk_register_ ## name(void)	\
66 	{							\
67 		return clk_register_composite(NULL, clk_name,	\
68 			name ## _parents,			\
69 			ARRAY_SIZE(name ## _parents),		\
70 			NULL, NULL,				\
71 			&name ## _rate_hw, &name ## _rate_ops,	\
72 			NULL, NULL, CLK_GET_RATE_NOCACHE);	\
73 	}
74 
75 #define MUX_OPS(name, clk_name, flags)				\
76 	static struct clk_hw name ## _mux_hw;			\
77 	static const struct clk_ops name ## _mux_ops = {	\
78 		.get_parent = name ## _get_parent,		\
79 		.set_parent = name ## _set_parent,		\
80 		.determine_rate = name ## _determine_rate,	\
81 	};							\
82 	static struct clk * __init clk_register_ ## name(void)	\
83 	{							\
84 		return clk_register_composite(NULL, clk_name,	\
85 			name ## _parents,			\
86 			ARRAY_SIZE(name ## _parents),		\
87 			&name ## _mux_hw, &name ## _mux_ops,	\
88 			NULL, NULL,				\
89 			NULL, NULL,				\
90 			CLK_GET_RATE_NOCACHE | flags); \
91 	}
92 
93 /*
94  * CKEN clock type
95  * This clock takes it source from 2 possible parents :
96  *  - a low power parent
97  *  - a normal parent
98  *
99  *  +------------+     +-----------+
100  *  |  Low Power | --- | x mult_lp |
101  *  |    Clock   |     | / div_lp  |\
102  *  +------------+     +-----------+ \+-----+   +-----------+
103  *                                    | Mux |---| CKEN gate |
104  *  +------------+     +-----------+ /+-----+   +-----------+
105  *  | High Power |     | x mult_hp |/
106  *  |    Clock   | --- | / div_hp  |
107  *  +------------+     +-----------+
108  */
109 struct desc_clk_cken {
110 	struct clk_hw hw;
111 	int ckid;
112 	const char *name;
113 	const char *dev_id;
114 	const char *con_id;
115 	const char * const *parent_names;
116 	struct clk_fixed_factor lp;
117 	struct clk_fixed_factor hp;
118 	struct clk_gate gate;
119 	bool (*is_in_low_power)(void);
120 	const unsigned long flags;
121 };
122 
123 #define PXA_CKEN(_dev_id, _con_id, _name, parents, _mult_lp, _div_lp,	\
124 		 _mult_hp, _div_hp, is_lp, _cken_reg, _cken_bit, flag)	\
125 	{ .ckid = CLK_ ## _name, .name = #_name,			\
126 	  .dev_id = _dev_id, .con_id = _con_id,	.parent_names = parents,\
127 	  .lp = { .mult = _mult_lp, .div = _div_lp },			\
128 	  .hp = { .mult = _mult_hp, .div = _div_hp },			\
129 	  .is_in_low_power = is_lp,					\
130 	  .gate = { .reg = (void __iomem *)_cken_reg, .bit_idx = _cken_bit }, \
131 	  .flags = flag,						\
132 	}
133 #define PXA_CKEN_1RATE(dev_id, con_id, name, parents, cken_reg,		\
134 			    cken_bit, flag)				\
135 	PXA_CKEN(dev_id, con_id, name, parents, 1, 1, 1, 1,		\
136 		 NULL, cken_reg, cken_bit, flag)
137 
138 struct pxa2xx_freq {
139 	unsigned long cpll;
140 	unsigned int membus_khz;
141 	unsigned int cccr;
142 	unsigned int div2;
143 	unsigned int clkcfg;
144 };
145 
146 static inline int dummy_clk_set_parent(struct clk_hw *hw, u8 index)
147 {
148 	return 0;
149 }
150 
151 extern void clkdev_pxa_register(int ckid, const char *con_id,
152 				const char *dev_id, struct clk *clk);
153 extern int clk_pxa_cken_init(const struct desc_clk_cken *clks, int nb_clks);
154 void clk_pxa_dt_common_init(struct device_node *np);
155 
156 void pxa2xx_core_turbo_switch(bool on);
157 void pxa2xx_cpll_change(struct pxa2xx_freq *freq,
158 			u32 (*mdrefr_dri)(unsigned int), void __iomem *mdrefr,
159 			void __iomem *cccr);
160 int pxa2xx_determine_rate(struct clk_rate_request *req,
161 			  struct pxa2xx_freq *freqs,  int nb_freqs);
162 
163 #endif
164