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