| Thomas Abraham | 721c42a | 2013-03-09 17:02:44 +0900 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (c) 2013 Samsung Electronics Co., Ltd. | 
|  | 3 | * Copyright (c) 2013 Linaro Ltd. | 
|  | 4 | * Author: Thomas Abraham <thomas.ab@samsung.com> | 
|  | 5 | * | 
|  | 6 | * This program is free software; you can redistribute it and/or modify | 
|  | 7 | * it under the terms of the GNU General Public License version 2 as | 
|  | 8 | * published by the Free Software Foundation. | 
|  | 9 | * | 
|  | 10 | * Common Clock Framework support for all Samsung platforms | 
|  | 11 | */ | 
|  | 12 |  | 
|  | 13 | #ifndef __SAMSUNG_CLK_H | 
|  | 14 | #define __SAMSUNG_CLK_H | 
|  | 15 |  | 
|  | 16 | #include <linux/clk.h> | 
|  | 17 | #include <linux/clkdev.h> | 
|  | 18 | #include <linux/io.h> | 
|  | 19 | #include <linux/clk-provider.h> | 
|  | 20 | #include <linux/of.h> | 
|  | 21 | #include <linux/of_address.h> | 
|  | 22 |  | 
|  | 23 | #include <mach/map.h> | 
|  | 24 |  | 
|  | 25 | /** | 
| Heiko Stuebner | 5e2e019 | 2013-03-18 13:43:56 +0900 | [diff] [blame^] | 26 | * struct samsung_clock_alias: information about mux clock | 
|  | 27 | * @id: platform specific id of the clock. | 
|  | 28 | * @dev_name: name of the device to which this clock belongs. | 
|  | 29 | * @alias: optional clock alias name to be assigned to this clock. | 
|  | 30 | */ | 
|  | 31 | struct samsung_clock_alias { | 
|  | 32 | unsigned int		id; | 
|  | 33 | const char		*dev_name; | 
|  | 34 | const char		*alias; | 
|  | 35 | }; | 
|  | 36 |  | 
|  | 37 | #define ALIAS(_id, dname, a)	\ | 
|  | 38 | {							\ | 
|  | 39 | .id		= _id,				\ | 
|  | 40 | .dev_name	= dname,			\ | 
|  | 41 | .alias		= a,				\ | 
|  | 42 | } | 
|  | 43 |  | 
|  | 44 | /** | 
| Thomas Abraham | 721c42a | 2013-03-09 17:02:44 +0900 | [diff] [blame] | 45 | * struct samsung_fixed_rate_clock: information about fixed-rate clock | 
|  | 46 | * @id: platform specific id of the clock. | 
|  | 47 | * @name: name of this fixed-rate clock. | 
|  | 48 | * @parent_name: optional parent clock name. | 
|  | 49 | * @flags: optional fixed-rate clock flags. | 
|  | 50 | * @fixed-rate: fixed clock rate of this clock. | 
|  | 51 | */ | 
|  | 52 | struct samsung_fixed_rate_clock { | 
|  | 53 | unsigned int		id; | 
|  | 54 | char			*name; | 
|  | 55 | const char		*parent_name; | 
|  | 56 | unsigned long		flags; | 
|  | 57 | unsigned long		fixed_rate; | 
|  | 58 | }; | 
|  | 59 |  | 
|  | 60 | #define FRATE(_id, cname, pname, f, frate)		\ | 
|  | 61 | {						\ | 
|  | 62 | .id		= _id,			\ | 
|  | 63 | .name		= cname,		\ | 
|  | 64 | .parent_name	= pname,		\ | 
|  | 65 | .flags		= f,			\ | 
|  | 66 | .fixed_rate	= frate,		\ | 
|  | 67 | } | 
|  | 68 |  | 
|  | 69 | /* | 
|  | 70 | * struct samsung_fixed_factor_clock: information about fixed-factor clock | 
|  | 71 | * @id: platform specific id of the clock. | 
|  | 72 | * @name: name of this fixed-factor clock. | 
|  | 73 | * @parent_name: parent clock name. | 
|  | 74 | * @mult: fixed multiplication factor. | 
|  | 75 | * @div: fixed division factor. | 
|  | 76 | * @flags: optional fixed-factor clock flags. | 
|  | 77 | */ | 
|  | 78 | struct samsung_fixed_factor_clock { | 
|  | 79 | unsigned int		id; | 
|  | 80 | char			*name; | 
|  | 81 | const char		*parent_name; | 
|  | 82 | unsigned long		mult; | 
|  | 83 | unsigned long		div; | 
|  | 84 | unsigned long		flags; | 
|  | 85 | }; | 
|  | 86 |  | 
|  | 87 | #define FFACTOR(_id, cname, pname, m, d, f)		\ | 
|  | 88 | {						\ | 
|  | 89 | .id		= _id,			\ | 
|  | 90 | .name		= cname,		\ | 
|  | 91 | .parent_name	= pname,		\ | 
|  | 92 | .mult		= m,			\ | 
|  | 93 | .div		= d,			\ | 
|  | 94 | .flags		= f,			\ | 
|  | 95 | } | 
|  | 96 |  | 
|  | 97 | /** | 
|  | 98 | * struct samsung_mux_clock: information about mux clock | 
|  | 99 | * @id: platform specific id of the clock. | 
|  | 100 | * @dev_name: name of the device to which this clock belongs. | 
|  | 101 | * @name: name of this mux clock. | 
|  | 102 | * @parent_names: array of pointer to parent clock names. | 
|  | 103 | * @num_parents: number of parents listed in @parent_names. | 
|  | 104 | * @flags: optional flags for basic clock. | 
|  | 105 | * @offset: offset of the register for configuring the mux. | 
|  | 106 | * @shift: starting bit location of the mux control bit-field in @reg. | 
|  | 107 | * @width: width of the mux control bit-field in @reg. | 
|  | 108 | * @mux_flags: flags for mux-type clock. | 
|  | 109 | * @alias: optional clock alias name to be assigned to this clock. | 
|  | 110 | */ | 
|  | 111 | struct samsung_mux_clock { | 
|  | 112 | unsigned int		id; | 
|  | 113 | const char		*dev_name; | 
|  | 114 | const char		*name; | 
|  | 115 | const char		**parent_names; | 
|  | 116 | u8			num_parents; | 
|  | 117 | unsigned long		flags; | 
|  | 118 | unsigned long		offset; | 
|  | 119 | u8			shift; | 
|  | 120 | u8			width; | 
|  | 121 | u8			mux_flags; | 
|  | 122 | const char		*alias; | 
|  | 123 | }; | 
|  | 124 |  | 
|  | 125 | #define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a)	\ | 
|  | 126 | {							\ | 
|  | 127 | .id		= _id,				\ | 
|  | 128 | .dev_name	= dname,			\ | 
|  | 129 | .name		= cname,			\ | 
|  | 130 | .parent_names	= pnames,			\ | 
|  | 131 | .num_parents	= ARRAY_SIZE(pnames),		\ | 
|  | 132 | .flags		= f,				\ | 
|  | 133 | .offset		= o,				\ | 
|  | 134 | .shift		= s,				\ | 
|  | 135 | .width		= w,				\ | 
|  | 136 | .mux_flags	= mf,				\ | 
|  | 137 | .alias		= a,				\ | 
|  | 138 | } | 
|  | 139 |  | 
|  | 140 | #define MUX(_id, cname, pnames, o, s, w)			\ | 
|  | 141 | __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL) | 
|  | 142 |  | 
|  | 143 | #define MUX_A(_id, cname, pnames, o, s, w, a)			\ | 
|  | 144 | __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a) | 
|  | 145 |  | 
|  | 146 | #define MUX_F(_id, cname, pnames, o, s, w, f, mf)		\ | 
|  | 147 | __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL) | 
|  | 148 |  | 
|  | 149 | /** | 
|  | 150 | * @id: platform specific id of the clock. | 
|  | 151 | * struct samsung_div_clock: information about div clock | 
|  | 152 | * @dev_name: name of the device to which this clock belongs. | 
|  | 153 | * @name: name of this div clock. | 
|  | 154 | * @parent_name: name of the parent clock. | 
|  | 155 | * @flags: optional flags for basic clock. | 
|  | 156 | * @offset: offset of the register for configuring the div. | 
|  | 157 | * @shift: starting bit location of the div control bit-field in @reg. | 
|  | 158 | * @div_flags: flags for div-type clock. | 
|  | 159 | * @alias: optional clock alias name to be assigned to this clock. | 
|  | 160 | */ | 
|  | 161 | struct samsung_div_clock { | 
|  | 162 | unsigned int		id; | 
|  | 163 | const char		*dev_name; | 
|  | 164 | const char		*name; | 
|  | 165 | const char		*parent_name; | 
|  | 166 | unsigned long		flags; | 
|  | 167 | unsigned long		offset; | 
|  | 168 | u8			shift; | 
|  | 169 | u8			width; | 
|  | 170 | u8			div_flags; | 
|  | 171 | const char		*alias; | 
| Heiko Stuebner | 798ed61 | 2013-03-18 13:43:52 +0900 | [diff] [blame] | 172 | struct clk_div_table	*table; | 
| Thomas Abraham | 721c42a | 2013-03-09 17:02:44 +0900 | [diff] [blame] | 173 | }; | 
|  | 174 |  | 
| Heiko Stuebner | 798ed61 | 2013-03-18 13:43:52 +0900 | [diff] [blame] | 175 | #define __DIV(_id, dname, cname, pname, o, s, w, f, df, a, t)	\ | 
| Thomas Abraham | 721c42a | 2013-03-09 17:02:44 +0900 | [diff] [blame] | 176 | {							\ | 
|  | 177 | .id		= _id,				\ | 
|  | 178 | .dev_name	= dname,			\ | 
|  | 179 | .name		= cname,			\ | 
|  | 180 | .parent_name	= pname,			\ | 
|  | 181 | .flags		= f,				\ | 
|  | 182 | .offset		= o,				\ | 
|  | 183 | .shift		= s,				\ | 
|  | 184 | .width		= w,				\ | 
|  | 185 | .div_flags	= df,				\ | 
|  | 186 | .alias		= a,				\ | 
| Heiko Stuebner | 798ed61 | 2013-03-18 13:43:52 +0900 | [diff] [blame] | 187 | .table		= t,				\ | 
| Thomas Abraham | 721c42a | 2013-03-09 17:02:44 +0900 | [diff] [blame] | 188 | } | 
|  | 189 |  | 
|  | 190 | #define DIV(_id, cname, pname, o, s, w)				\ | 
| Heiko Stuebner | 798ed61 | 2013-03-18 13:43:52 +0900 | [diff] [blame] | 191 | __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, NULL) | 
| Thomas Abraham | 721c42a | 2013-03-09 17:02:44 +0900 | [diff] [blame] | 192 |  | 
|  | 193 | #define DIV_A(_id, cname, pname, o, s, w, a)			\ | 
| Heiko Stuebner | 798ed61 | 2013-03-18 13:43:52 +0900 | [diff] [blame] | 194 | __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a, NULL) | 
| Thomas Abraham | 721c42a | 2013-03-09 17:02:44 +0900 | [diff] [blame] | 195 |  | 
|  | 196 | #define DIV_F(_id, cname, pname, o, s, w, f, df)		\ | 
| Heiko Stuebner | 798ed61 | 2013-03-18 13:43:52 +0900 | [diff] [blame] | 197 | __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL, NULL) | 
|  | 198 |  | 
|  | 199 | #define DIV_T(_id, cname, pname, o, s, w, t)			\ | 
|  | 200 | __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, t) | 
| Thomas Abraham | 721c42a | 2013-03-09 17:02:44 +0900 | [diff] [blame] | 201 |  | 
|  | 202 | /** | 
|  | 203 | * struct samsung_gate_clock: information about gate clock | 
|  | 204 | * @id: platform specific id of the clock. | 
|  | 205 | * @dev_name: name of the device to which this clock belongs. | 
|  | 206 | * @name: name of this gate clock. | 
|  | 207 | * @parent_name: name of the parent clock. | 
|  | 208 | * @flags: optional flags for basic clock. | 
|  | 209 | * @offset: offset of the register for configuring the gate. | 
|  | 210 | * @bit_idx: bit index of the gate control bit-field in @reg. | 
|  | 211 | * @gate_flags: flags for gate-type clock. | 
|  | 212 | * @alias: optional clock alias name to be assigned to this clock. | 
|  | 213 | */ | 
|  | 214 | struct samsung_gate_clock { | 
|  | 215 | unsigned int		id; | 
|  | 216 | const char		*dev_name; | 
|  | 217 | const char		*name; | 
|  | 218 | const char		*parent_name; | 
|  | 219 | unsigned long		flags; | 
|  | 220 | unsigned long		offset; | 
|  | 221 | u8			bit_idx; | 
|  | 222 | u8			gate_flags; | 
|  | 223 | const char		*alias; | 
|  | 224 | }; | 
|  | 225 |  | 
|  | 226 | #define __GATE(_id, dname, cname, pname, o, b, f, gf, a)	\ | 
|  | 227 | {							\ | 
|  | 228 | .id		= _id,				\ | 
|  | 229 | .dev_name	= dname,			\ | 
|  | 230 | .name		= cname,			\ | 
|  | 231 | .parent_name	= pname,			\ | 
|  | 232 | .flags		= f,				\ | 
|  | 233 | .offset		= o,				\ | 
|  | 234 | .bit_idx	= b,				\ | 
|  | 235 | .gate_flags	= gf,				\ | 
|  | 236 | .alias		= a,				\ | 
|  | 237 | } | 
|  | 238 |  | 
|  | 239 | #define GATE(_id, cname, pname, o, b, f, gf)			\ | 
|  | 240 | __GATE(_id, NULL, cname, pname, o, b, f, gf, NULL) | 
|  | 241 |  | 
|  | 242 | #define GATE_A(_id, cname, pname, o, b, f, gf, a)		\ | 
|  | 243 | __GATE(_id, NULL, cname, pname, o, b, f, gf, a) | 
|  | 244 |  | 
|  | 245 | #define GATE_D(_id, dname, cname, pname, o, b, f, gf)		\ | 
|  | 246 | __GATE(_id, dname, cname, pname, o, b, f, gf, NULL) | 
|  | 247 |  | 
|  | 248 | #define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a)	\ | 
|  | 249 | __GATE(_id, dname, cname, pname, o, b, f, gf, a) | 
|  | 250 |  | 
|  | 251 | #define PNAME(x) static const char *x[] __initdata | 
|  | 252 |  | 
|  | 253 | /** | 
|  | 254 | * struct samsung_clk_reg_dump: register dump of clock controller registers. | 
|  | 255 | * @offset: clock register offset from the controller base address. | 
|  | 256 | * @value: the value to be register at offset. | 
|  | 257 | */ | 
|  | 258 | struct samsung_clk_reg_dump { | 
|  | 259 | u32	offset; | 
|  | 260 | u32	value; | 
|  | 261 | }; | 
|  | 262 |  | 
|  | 263 | extern void __init samsung_clk_init(struct device_node *np, void __iomem *base, | 
|  | 264 | unsigned long nr_clks, unsigned long *rdump, | 
|  | 265 | unsigned long nr_rdump); | 
|  | 266 | extern void __init samsung_clk_of_register_fixed_ext( | 
|  | 267 | struct samsung_fixed_rate_clock *fixed_rate_clk, | 
|  | 268 | unsigned int nr_fixed_rate_clk, | 
|  | 269 | struct of_device_id *clk_matches); | 
|  | 270 |  | 
|  | 271 | extern void samsung_clk_add_lookup(struct clk *clk, unsigned int id); | 
|  | 272 |  | 
| Heiko Stuebner | 5e2e019 | 2013-03-18 13:43:56 +0900 | [diff] [blame^] | 273 | extern void samsung_clk_register_alias(struct samsung_clock_alias *list, | 
|  | 274 | unsigned int nr_clk); | 
| Thomas Abraham | 721c42a | 2013-03-09 17:02:44 +0900 | [diff] [blame] | 275 | extern void __init samsung_clk_register_fixed_rate( | 
|  | 276 | struct samsung_fixed_rate_clock *clk_list, unsigned int nr_clk); | 
|  | 277 | extern void __init samsung_clk_register_fixed_factor( | 
|  | 278 | struct samsung_fixed_factor_clock *list, unsigned int nr_clk); | 
|  | 279 | extern void __init samsung_clk_register_mux(struct samsung_mux_clock *clk_list, | 
|  | 280 | unsigned int nr_clk); | 
|  | 281 | extern void __init samsung_clk_register_div(struct samsung_div_clock *clk_list, | 
|  | 282 | unsigned int nr_clk); | 
|  | 283 | extern void __init samsung_clk_register_gate( | 
|  | 284 | struct samsung_gate_clock *clk_list, unsigned int nr_clk); | 
|  | 285 |  | 
|  | 286 | extern unsigned long _get_rate(const char *clk_name); | 
|  | 287 |  | 
|  | 288 | #endif /* __SAMSUNG_CLK_H */ |