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 #include "clk-pll.h" 23 24 /** 25 * struct samsung_clk_provider: information about clock provider 26 * @reg_base: virtual address for the register base. 27 * @clk_data: holds clock related data like clk* and number of clocks. 28 * @lock: maintains exclusion bwtween callbacks for a given clock-provider. 29 */ 30 struct samsung_clk_provider { 31 void __iomem *reg_base; 32 struct clk_onecell_data clk_data; 33 spinlock_t lock; 34 }; 35 36 /** 37 * struct samsung_clock_alias: information about mux clock 38 * @id: platform specific id of the clock. 39 * @dev_name: name of the device to which this clock belongs. 40 * @alias: optional clock alias name to be assigned to this clock. 41 */ 42 struct samsung_clock_alias { 43 unsigned int id; 44 const char *dev_name; 45 const char *alias; 46 }; 47 48 #define ALIAS(_id, dname, a) \ 49 { \ 50 .id = _id, \ 51 .dev_name = dname, \ 52 .alias = a, \ 53 } 54 55 #define MHZ (1000 * 1000) 56 57 /** 58 * struct samsung_fixed_rate_clock: information about fixed-rate clock 59 * @id: platform specific id of the clock. 60 * @name: name of this fixed-rate clock. 61 * @parent_name: optional parent clock name. 62 * @flags: optional fixed-rate clock flags. 63 * @fixed-rate: fixed clock rate of this clock. 64 */ 65 struct samsung_fixed_rate_clock { 66 unsigned int id; 67 char *name; 68 const char *parent_name; 69 unsigned long flags; 70 unsigned long fixed_rate; 71 }; 72 73 #define FRATE(_id, cname, pname, f, frate) \ 74 { \ 75 .id = _id, \ 76 .name = cname, \ 77 .parent_name = pname, \ 78 .flags = f, \ 79 .fixed_rate = frate, \ 80 } 81 82 /* 83 * struct samsung_fixed_factor_clock: information about fixed-factor clock 84 * @id: platform specific id of the clock. 85 * @name: name of this fixed-factor clock. 86 * @parent_name: parent clock name. 87 * @mult: fixed multiplication factor. 88 * @div: fixed division factor. 89 * @flags: optional fixed-factor clock flags. 90 */ 91 struct samsung_fixed_factor_clock { 92 unsigned int id; 93 char *name; 94 const char *parent_name; 95 unsigned long mult; 96 unsigned long div; 97 unsigned long flags; 98 }; 99 100 #define FFACTOR(_id, cname, pname, m, d, f) \ 101 { \ 102 .id = _id, \ 103 .name = cname, \ 104 .parent_name = pname, \ 105 .mult = m, \ 106 .div = d, \ 107 .flags = f, \ 108 } 109 110 /** 111 * struct samsung_mux_clock: information about mux clock 112 * @id: platform specific id of the clock. 113 * @dev_name: name of the device to which this clock belongs. 114 * @name: name of this mux clock. 115 * @parent_names: array of pointer to parent clock names. 116 * @num_parents: number of parents listed in @parent_names. 117 * @flags: optional flags for basic clock. 118 * @offset: offset of the register for configuring the mux. 119 * @shift: starting bit location of the mux control bit-field in @reg. 120 * @width: width of the mux control bit-field in @reg. 121 * @mux_flags: flags for mux-type clock. 122 * @alias: optional clock alias name to be assigned to this clock. 123 */ 124 struct samsung_mux_clock { 125 unsigned int id; 126 const char *dev_name; 127 const char *name; 128 const char **parent_names; 129 u8 num_parents; 130 unsigned long flags; 131 unsigned long offset; 132 u8 shift; 133 u8 width; 134 u8 mux_flags; 135 const char *alias; 136 }; 137 138 #define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a) \ 139 { \ 140 .id = _id, \ 141 .dev_name = dname, \ 142 .name = cname, \ 143 .parent_names = pnames, \ 144 .num_parents = ARRAY_SIZE(pnames), \ 145 .flags = (f) | CLK_SET_RATE_NO_REPARENT, \ 146 .offset = o, \ 147 .shift = s, \ 148 .width = w, \ 149 .mux_flags = mf, \ 150 .alias = a, \ 151 } 152 153 #define MUX(_id, cname, pnames, o, s, w) \ 154 __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL) 155 156 #define MUX_A(_id, cname, pnames, o, s, w, a) \ 157 __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a) 158 159 #define MUX_F(_id, cname, pnames, o, s, w, f, mf) \ 160 __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL) 161 162 #define MUX_FA(_id, cname, pnames, o, s, w, f, mf, a) \ 163 __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, a) 164 165 /** 166 * @id: platform specific id of the clock. 167 * struct samsung_div_clock: information about div clock 168 * @dev_name: name of the device to which this clock belongs. 169 * @name: name of this div clock. 170 * @parent_name: name of the parent clock. 171 * @flags: optional flags for basic clock. 172 * @offset: offset of the register for configuring the div. 173 * @shift: starting bit location of the div control bit-field in @reg. 174 * @div_flags: flags for div-type clock. 175 * @alias: optional clock alias name to be assigned to this clock. 176 */ 177 struct samsung_div_clock { 178 unsigned int id; 179 const char *dev_name; 180 const char *name; 181 const char *parent_name; 182 unsigned long flags; 183 unsigned long offset; 184 u8 shift; 185 u8 width; 186 u8 div_flags; 187 const char *alias; 188 struct clk_div_table *table; 189 }; 190 191 #define __DIV(_id, dname, cname, pname, o, s, w, f, df, a, t) \ 192 { \ 193 .id = _id, \ 194 .dev_name = dname, \ 195 .name = cname, \ 196 .parent_name = pname, \ 197 .flags = f, \ 198 .offset = o, \ 199 .shift = s, \ 200 .width = w, \ 201 .div_flags = df, \ 202 .alias = a, \ 203 .table = t, \ 204 } 205 206 #define DIV(_id, cname, pname, o, s, w) \ 207 __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, NULL) 208 209 #define DIV_A(_id, cname, pname, o, s, w, a) \ 210 __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a, NULL) 211 212 #define DIV_F(_id, cname, pname, o, s, w, f, df) \ 213 __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL, NULL) 214 215 #define DIV_T(_id, cname, pname, o, s, w, t) \ 216 __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, t) 217 218 /** 219 * struct samsung_gate_clock: information about gate clock 220 * @id: platform specific id of the clock. 221 * @dev_name: name of the device to which this clock belongs. 222 * @name: name of this gate clock. 223 * @parent_name: name of the parent clock. 224 * @flags: optional flags for basic clock. 225 * @offset: offset of the register for configuring the gate. 226 * @bit_idx: bit index of the gate control bit-field in @reg. 227 * @gate_flags: flags for gate-type clock. 228 * @alias: optional clock alias name to be assigned to this clock. 229 */ 230 struct samsung_gate_clock { 231 unsigned int id; 232 const char *dev_name; 233 const char *name; 234 const char *parent_name; 235 unsigned long flags; 236 unsigned long offset; 237 u8 bit_idx; 238 u8 gate_flags; 239 const char *alias; 240 }; 241 242 #define __GATE(_id, dname, cname, pname, o, b, f, gf, a) \ 243 { \ 244 .id = _id, \ 245 .dev_name = dname, \ 246 .name = cname, \ 247 .parent_name = pname, \ 248 .flags = f, \ 249 .offset = o, \ 250 .bit_idx = b, \ 251 .gate_flags = gf, \ 252 .alias = a, \ 253 } 254 255 #define GATE(_id, cname, pname, o, b, f, gf) \ 256 __GATE(_id, NULL, cname, pname, o, b, f, gf, NULL) 257 258 #define GATE_A(_id, cname, pname, o, b, f, gf, a) \ 259 __GATE(_id, NULL, cname, pname, o, b, f, gf, a) 260 261 #define GATE_D(_id, dname, cname, pname, o, b, f, gf) \ 262 __GATE(_id, dname, cname, pname, o, b, f, gf, NULL) 263 264 #define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a) \ 265 __GATE(_id, dname, cname, pname, o, b, f, gf, a) 266 267 #define PNAME(x) static const char *x[] __initdata 268 269 /** 270 * struct samsung_clk_reg_dump: register dump of clock controller registers. 271 * @offset: clock register offset from the controller base address. 272 * @value: the value to be register at offset. 273 */ 274 struct samsung_clk_reg_dump { 275 u32 offset; 276 u32 value; 277 }; 278 279 /** 280 * struct samsung_pll_clock: information about pll clock 281 * @id: platform specific id of the clock. 282 * @dev_name: name of the device to which this clock belongs. 283 * @name: name of this pll clock. 284 * @parent_name: name of the parent clock. 285 * @flags: optional flags for basic clock. 286 * @con_offset: offset of the register for configuring the PLL. 287 * @lock_offset: offset of the register for locking the PLL. 288 * @type: Type of PLL to be registered. 289 * @alias: optional clock alias name to be assigned to this clock. 290 */ 291 struct samsung_pll_clock { 292 unsigned int id; 293 const char *dev_name; 294 const char *name; 295 const char *parent_name; 296 unsigned long flags; 297 int con_offset; 298 int lock_offset; 299 enum samsung_pll_type type; 300 const struct samsung_pll_rate_table *rate_table; 301 const char *alias; 302 }; 303 304 #define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con, \ 305 _rtable, _alias) \ 306 { \ 307 .id = _id, \ 308 .type = _typ, \ 309 .dev_name = _dname, \ 310 .name = _name, \ 311 .parent_name = _pname, \ 312 .flags = CLK_GET_RATE_NOCACHE, \ 313 .con_offset = _con, \ 314 .lock_offset = _lock, \ 315 .rate_table = _rtable, \ 316 .alias = _alias, \ 317 } 318 319 #define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable) \ 320 __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \ 321 _lock, _con, _rtable, _name) 322 323 #define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias, _rtable) \ 324 __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \ 325 _lock, _con, _rtable, _alias) 326 327 extern struct samsung_clk_provider *__init samsung_clk_init( 328 struct device_node *np, void __iomem *base, 329 unsigned long nr_clks); 330 extern void __init samsung_clk_of_register_fixed_ext( 331 struct samsung_clk_provider *ctx, 332 struct samsung_fixed_rate_clock *fixed_rate_clk, 333 unsigned int nr_fixed_rate_clk, 334 struct of_device_id *clk_matches); 335 336 extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, 337 struct clk *clk, unsigned int id); 338 339 extern void samsung_clk_register_alias(struct samsung_clk_provider *ctx, 340 struct samsung_clock_alias *list, 341 unsigned int nr_clk); 342 extern void __init samsung_clk_register_fixed_rate( 343 struct samsung_clk_provider *ctx, 344 struct samsung_fixed_rate_clock *clk_list, 345 unsigned int nr_clk); 346 extern void __init samsung_clk_register_fixed_factor( 347 struct samsung_clk_provider *ctx, 348 struct samsung_fixed_factor_clock *list, 349 unsigned int nr_clk); 350 extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx, 351 struct samsung_mux_clock *clk_list, 352 unsigned int nr_clk); 353 extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, 354 struct samsung_div_clock *clk_list, 355 unsigned int nr_clk); 356 extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, 357 struct samsung_gate_clock *clk_list, 358 unsigned int nr_clk); 359 extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, 360 struct samsung_pll_clock *pll_list, 361 unsigned int nr_clk, void __iomem *base); 362 363 extern unsigned long _get_rate(const char *clk_name); 364 365 extern void samsung_clk_save(void __iomem *base, 366 struct samsung_clk_reg_dump *rd, 367 unsigned int num_regs); 368 extern void samsung_clk_restore(void __iomem *base, 369 const struct samsung_clk_reg_dump *rd, 370 unsigned int num_regs); 371 extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( 372 const unsigned long *rdump, 373 unsigned long nr_rdump); 374 375 #endif /* __SAMSUNG_CLK_H */ 376