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