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 /** 20 * struct samsung_clk_provider: information about clock provider 21 * @reg_base: virtual address for the register base. 22 * @lock: maintains exclusion between callbacks for a given clock-provider. 23 * @clk_data: holds clock related data like clk_hw* and number of clocks. 24 */ 25 struct samsung_clk_provider { 26 void __iomem *reg_base; 27 struct device *dev; 28 spinlock_t lock; 29 /* clk_data must be the last entry due to variable lenght 'hws' array */ 30 struct clk_hw_onecell_data clk_data; 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 * @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 */ 119 struct samsung_mux_clock { 120 unsigned int id; 121 const char *name; 122 const char *const *parent_names; 123 u8 num_parents; 124 unsigned long flags; 125 unsigned long offset; 126 u8 shift; 127 u8 width; 128 u8 mux_flags; 129 }; 130 131 #define __MUX(_id, cname, pnames, o, s, w, f, mf) \ 132 { \ 133 .id = _id, \ 134 .name = cname, \ 135 .parent_names = pnames, \ 136 .num_parents = ARRAY_SIZE(pnames), \ 137 .flags = (f) | CLK_SET_RATE_NO_REPARENT, \ 138 .offset = o, \ 139 .shift = s, \ 140 .width = w, \ 141 .mux_flags = mf, \ 142 } 143 144 #define MUX(_id, cname, pnames, o, s, w) \ 145 __MUX(_id, cname, pnames, o, s, w, 0, 0) 146 147 #define MUX_F(_id, cname, pnames, o, s, w, f, mf) \ 148 __MUX(_id, cname, pnames, o, s, w, f, mf) 149 150 /** 151 * @id: platform specific id of the clock. 152 * struct samsung_div_clock: information about div clock 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 */ 160 struct samsung_div_clock { 161 unsigned int id; 162 const char *name; 163 const char *parent_name; 164 unsigned long flags; 165 unsigned long offset; 166 u8 shift; 167 u8 width; 168 u8 div_flags; 169 struct clk_div_table *table; 170 }; 171 172 #define __DIV(_id, cname, pname, o, s, w, f, df, t) \ 173 { \ 174 .id = _id, \ 175 .name = cname, \ 176 .parent_name = pname, \ 177 .flags = f, \ 178 .offset = o, \ 179 .shift = s, \ 180 .width = w, \ 181 .div_flags = df, \ 182 .table = t, \ 183 } 184 185 #define DIV(_id, cname, pname, o, s, w) \ 186 __DIV(_id, cname, pname, o, s, w, 0, 0, NULL) 187 188 #define DIV_F(_id, cname, pname, o, s, w, f, df) \ 189 __DIV(_id, cname, pname, o, s, w, f, df, NULL) 190 191 #define DIV_T(_id, cname, pname, o, s, w, t) \ 192 __DIV(_id, cname, pname, o, s, w, 0, 0, t) 193 194 /** 195 * struct samsung_gate_clock: information about gate clock 196 * @id: platform specific id of the clock. 197 * @name: name of this gate clock. 198 * @parent_name: name of the parent clock. 199 * @flags: optional flags for basic clock. 200 * @offset: offset of the register for configuring the gate. 201 * @bit_idx: bit index of the gate control bit-field in @reg. 202 * @gate_flags: flags for gate-type clock. 203 */ 204 struct samsung_gate_clock { 205 unsigned int id; 206 const char *name; 207 const char *parent_name; 208 unsigned long flags; 209 unsigned long offset; 210 u8 bit_idx; 211 u8 gate_flags; 212 }; 213 214 #define __GATE(_id, cname, pname, o, b, f, gf) \ 215 { \ 216 .id = _id, \ 217 .name = cname, \ 218 .parent_name = pname, \ 219 .flags = f, \ 220 .offset = o, \ 221 .bit_idx = b, \ 222 .gate_flags = gf, \ 223 } 224 225 #define GATE(_id, cname, pname, o, b, f, gf) \ 226 __GATE(_id, cname, pname, o, b, f, gf) 227 228 #define PNAME(x) static const char * const x[] __initconst 229 230 /** 231 * struct samsung_clk_reg_dump: register dump of clock controller registers. 232 * @offset: clock register offset from the controller base address. 233 * @value: the value to be register at offset. 234 */ 235 struct samsung_clk_reg_dump { 236 u32 offset; 237 u32 value; 238 }; 239 240 /** 241 * struct samsung_pll_clock: information about pll clock 242 * @id: platform specific id of the clock. 243 * @name: name of this pll clock. 244 * @parent_name: name of the parent clock. 245 * @flags: optional flags for basic clock. 246 * @con_offset: offset of the register for configuring the PLL. 247 * @lock_offset: offset of the register for locking the PLL. 248 * @type: Type of PLL to be registered. 249 */ 250 struct samsung_pll_clock { 251 unsigned int id; 252 const char *name; 253 const char *parent_name; 254 unsigned long flags; 255 int con_offset; 256 int lock_offset; 257 enum samsung_pll_type type; 258 const struct samsung_pll_rate_table *rate_table; 259 }; 260 261 #define __PLL(_typ, _id, _name, _pname, _flags, _lock, _con, _rtable) \ 262 { \ 263 .id = _id, \ 264 .type = _typ, \ 265 .name = _name, \ 266 .parent_name = _pname, \ 267 .flags = _flags, \ 268 .con_offset = _con, \ 269 .lock_offset = _lock, \ 270 .rate_table = _rtable, \ 271 } 272 273 #define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable) \ 274 __PLL(_typ, _id, _name, _pname, CLK_GET_RATE_NOCACHE, _lock, \ 275 _con, _rtable) 276 277 struct samsung_clock_reg_cache { 278 struct list_head node; 279 void __iomem *reg_base; 280 struct samsung_clk_reg_dump *rdump; 281 unsigned int rd_num; 282 const struct samsung_clk_reg_dump *rsuspend; 283 unsigned int rsuspend_num; 284 }; 285 286 struct samsung_cmu_info { 287 /* list of pll clocks and respective count */ 288 const struct samsung_pll_clock *pll_clks; 289 unsigned int nr_pll_clks; 290 /* list of mux clocks and respective count */ 291 const struct samsung_mux_clock *mux_clks; 292 unsigned int nr_mux_clks; 293 /* list of div clocks and respective count */ 294 const struct samsung_div_clock *div_clks; 295 unsigned int nr_div_clks; 296 /* list of gate clocks and respective count */ 297 const struct samsung_gate_clock *gate_clks; 298 unsigned int nr_gate_clks; 299 /* list of fixed clocks and respective count */ 300 const struct samsung_fixed_rate_clock *fixed_clks; 301 unsigned int nr_fixed_clks; 302 /* list of fixed factor clocks and respective count */ 303 const struct samsung_fixed_factor_clock *fixed_factor_clks; 304 unsigned int nr_fixed_factor_clks; 305 /* total number of clocks with IDs assigned*/ 306 unsigned int nr_clk_ids; 307 308 /* list and number of clocks registers */ 309 const unsigned long *clk_regs; 310 unsigned int nr_clk_regs; 311 312 /* list and number of clocks registers to set before suspend */ 313 const struct samsung_clk_reg_dump *suspend_regs; 314 unsigned int nr_suspend_regs; 315 /* name of the parent clock needed for CMU register access */ 316 const char *clk_name; 317 }; 318 319 extern struct samsung_clk_provider *__init samsung_clk_init( 320 struct device_node *np, void __iomem *base, 321 unsigned long nr_clks); 322 extern void __init samsung_clk_of_add_provider(struct device_node *np, 323 struct samsung_clk_provider *ctx); 324 extern void __init samsung_clk_of_register_fixed_ext( 325 struct samsung_clk_provider *ctx, 326 struct samsung_fixed_rate_clock *fixed_rate_clk, 327 unsigned int nr_fixed_rate_clk, 328 const struct of_device_id *clk_matches); 329 330 extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, 331 struct clk_hw *clk_hw, unsigned int id); 332 333 extern void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx, 334 const struct samsung_clock_alias *list, 335 unsigned int nr_clk); 336 extern void __init samsung_clk_register_fixed_rate( 337 struct samsung_clk_provider *ctx, 338 const struct samsung_fixed_rate_clock *clk_list, 339 unsigned int nr_clk); 340 extern void __init samsung_clk_register_fixed_factor( 341 struct samsung_clk_provider *ctx, 342 const struct samsung_fixed_factor_clock *list, 343 unsigned int nr_clk); 344 extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx, 345 const struct samsung_mux_clock *clk_list, 346 unsigned int nr_clk); 347 extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, 348 const struct samsung_div_clock *clk_list, 349 unsigned int nr_clk); 350 extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, 351 const struct samsung_gate_clock *clk_list, 352 unsigned int nr_clk); 353 extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, 354 const struct samsung_pll_clock *pll_list, 355 unsigned int nr_clk, void __iomem *base); 356 357 extern struct samsung_clk_provider __init *samsung_cmu_register_one( 358 struct device_node *, 359 const struct samsung_cmu_info *); 360 361 extern unsigned long _get_rate(const char *clk_name); 362 363 #ifdef CONFIG_PM_SLEEP 364 extern void samsung_clk_extended_sleep_init(void __iomem *reg_base, 365 const unsigned long *rdump, 366 unsigned long nr_rdump, 367 const struct samsung_clk_reg_dump *rsuspend, 368 unsigned long nr_rsuspend); 369 #else 370 static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base, 371 const unsigned long *rdump, 372 unsigned long nr_rdump, 373 const struct samsung_clk_reg_dump *rsuspend, 374 unsigned long nr_rsuspend) {} 375 #endif 376 #define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \ 377 samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0) 378 379 extern void samsung_clk_save(void __iomem *base, 380 struct samsung_clk_reg_dump *rd, 381 unsigned int num_regs); 382 extern void samsung_clk_restore(void __iomem *base, 383 const struct samsung_clk_reg_dump *rd, 384 unsigned int num_regs); 385 extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( 386 const unsigned long *rdump, 387 unsigned long nr_rdump); 388 389 #endif /* __SAMSUNG_CLK_H */ 390