1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright (c) 2013 Samsung Electronics Co., Ltd. 4 * Copyright (c) 2013 Linaro Ltd. 5 * Author: Thomas Abraham <thomas.ab@samsung.com> 6 * 7 * Common Clock Framework support for all Samsung platforms 8 */ 9 10 #ifndef __SAMSUNG_CLK_H 11 #define __SAMSUNG_CLK_H 12 13 #include <linux/clk-provider.h> 14 #include "clk-pll.h" 15 16 /** 17 * struct samsung_clk_provider - information about clock provider 18 * @reg_base: virtual address for the register base 19 * @dev: clock provider device needed for runtime PM 20 * @lock: maintains exclusion between callbacks for a given clock-provider 21 * @clk_data: holds clock related data like clk_hw* and number of clocks 22 */ 23 struct samsung_clk_provider { 24 void __iomem *reg_base; 25 struct device *dev; 26 spinlock_t lock; 27 /* clk_data must be the last entry due to variable length 'hws' array */ 28 struct clk_hw_onecell_data clk_data; 29 }; 30 31 /** 32 * struct samsung_clock_alias - information about mux clock 33 * @id: platform specific id of the clock 34 * @dev_name: name of the device to which this clock belongs 35 * @alias: optional clock alias name to be assigned to this clock 36 */ 37 struct samsung_clock_alias { 38 unsigned int id; 39 const char *dev_name; 40 const char *alias; 41 }; 42 43 #define ALIAS(_id, dname, a) \ 44 { \ 45 .id = _id, \ 46 .dev_name = dname, \ 47 .alias = a, \ 48 } 49 50 #define MHZ (1000 * 1000) 51 52 /** 53 * struct samsung_fixed_rate_clock - information about fixed-rate clock 54 * @id: platform specific id of the clock 55 * @name: name of this fixed-rate clock 56 * @parent_name: optional parent clock name 57 * @flags: optional fixed-rate clock flags 58 * @fixed_rate: fixed clock rate of this clock 59 */ 60 struct samsung_fixed_rate_clock { 61 unsigned int id; 62 char *name; 63 const char *parent_name; 64 unsigned long flags; 65 unsigned long fixed_rate; 66 }; 67 68 #define FRATE(_id, cname, pname, f, frate) \ 69 { \ 70 .id = _id, \ 71 .name = cname, \ 72 .parent_name = pname, \ 73 .flags = f, \ 74 .fixed_rate = frate, \ 75 } 76 77 /** 78 * struct samsung_fixed_factor_clock - information about fixed-factor clock 79 * @id: platform specific id of the clock 80 * @name: name of this fixed-factor clock 81 * @parent_name: parent clock name 82 * @mult: fixed multiplication factor 83 * @div: fixed division factor 84 * @flags: optional fixed-factor clock flags 85 */ 86 struct samsung_fixed_factor_clock { 87 unsigned int id; 88 char *name; 89 const char *parent_name; 90 unsigned long mult; 91 unsigned long div; 92 unsigned long flags; 93 }; 94 95 #define FFACTOR(_id, cname, pname, m, d, f) \ 96 { \ 97 .id = _id, \ 98 .name = cname, \ 99 .parent_name = pname, \ 100 .mult = m, \ 101 .div = d, \ 102 .flags = f, \ 103 } 104 105 /** 106 * struct samsung_mux_clock - information about mux clock 107 * @id: platform specific id of the clock 108 * @name: name of this mux clock 109 * @parent_names: array of pointer to parent clock names 110 * @num_parents: number of parents listed in @parent_names 111 * @flags: optional flags for basic clock 112 * @offset: offset of the register for configuring the mux 113 * @shift: starting bit location of the mux control bit-field in @reg 114 * @width: width of the mux control bit-field in @reg 115 * @mux_flags: flags for mux-type clock 116 */ 117 struct samsung_mux_clock { 118 unsigned int id; 119 const char *name; 120 const char *const *parent_names; 121 u8 num_parents; 122 unsigned long flags; 123 unsigned long offset; 124 u8 shift; 125 u8 width; 126 u8 mux_flags; 127 }; 128 129 #define __MUX(_id, cname, pnames, o, s, w, f, mf) \ 130 { \ 131 .id = _id, \ 132 .name = cname, \ 133 .parent_names = pnames, \ 134 .num_parents = ARRAY_SIZE(pnames), \ 135 .flags = (f) | CLK_SET_RATE_NO_REPARENT, \ 136 .offset = o, \ 137 .shift = s, \ 138 .width = w, \ 139 .mux_flags = mf, \ 140 } 141 142 #define MUX(_id, cname, pnames, o, s, w) \ 143 __MUX(_id, cname, pnames, o, s, w, 0, 0) 144 145 #define MUX_F(_id, cname, pnames, o, s, w, f, mf) \ 146 __MUX(_id, cname, pnames, o, s, w, f, mf) 147 148 /** 149 * struct samsung_div_clock - information about div clock 150 * @id: platform specific id of the clock 151 * @name: name of this div clock 152 * @parent_name: name of the parent clock 153 * @flags: optional flags for basic clock 154 * @offset: offset of the register for configuring the div 155 * @shift: starting bit location of the div control bit-field in @reg 156 * @width: width of the bitfield 157 * @div_flags: flags for div-type clock 158 * @table: array of divider/value pairs ending with a div set to 0 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 * @rate_table: array of PLL settings for possible PLL rates 250 */ 251 struct samsung_pll_clock { 252 unsigned int id; 253 const char *name; 254 const char *parent_name; 255 unsigned long flags; 256 int con_offset; 257 int lock_offset; 258 enum samsung_pll_type type; 259 const struct samsung_pll_rate_table *rate_table; 260 }; 261 262 #define __PLL(_typ, _id, _name, _pname, _flags, _lock, _con, _rtable) \ 263 { \ 264 .id = _id, \ 265 .type = _typ, \ 266 .name = _name, \ 267 .parent_name = _pname, \ 268 .flags = _flags, \ 269 .con_offset = _con, \ 270 .lock_offset = _lock, \ 271 .rate_table = _rtable, \ 272 } 273 274 #define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable) \ 275 __PLL(_typ, _id, _name, _pname, CLK_GET_RATE_NOCACHE, _lock, \ 276 _con, _rtable) 277 278 struct samsung_cpu_clock { 279 unsigned int id; 280 const char *name; 281 unsigned int parent_id; 282 unsigned int alt_parent_id; 283 unsigned long flags; 284 int offset; 285 const struct exynos_cpuclk_cfg_data *cfg; 286 }; 287 288 #define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _cfg) \ 289 { \ 290 .id = _id, \ 291 .name = _name, \ 292 .parent_id = _pid, \ 293 .alt_parent_id = _apid, \ 294 .flags = _flags, \ 295 .offset = _offset, \ 296 .cfg = _cfg, \ 297 } 298 299 struct samsung_clock_reg_cache { 300 struct list_head node; 301 void __iomem *reg_base; 302 struct samsung_clk_reg_dump *rdump; 303 unsigned int rd_num; 304 const struct samsung_clk_reg_dump *rsuspend; 305 unsigned int rsuspend_num; 306 }; 307 308 /** 309 * struct samsung_cmu_info - all clocks information needed for CMU registration 310 * @pll_clks: list of PLL clocks 311 * @nr_pll_clks: count of clocks in @pll_clks 312 * @mux_clks: list of mux clocks 313 * @nr_mux_clks: count of clocks in @mux_clks 314 * @div_clks: list of div clocks 315 * @nr_div_clks: count of clocks in @div_clks 316 * @gate_clks: list of gate clocks 317 * @nr_gate_clks: count of clocks in @gate_clks 318 * @fixed_clks: list of fixed clocks 319 * @nr_fixed_clks: count clocks in @fixed_clks 320 * @fixed_factor_clks: list of fixed factor clocks 321 * @nr_fixed_factor_clks: count of clocks in @fixed_factor_clks 322 * @nr_clk_ids: total number of clocks with IDs assigned 323 * @cpu_clks: list of CPU clocks 324 * @nr_cpu_clks: count of clocks in @cpu_clks 325 * @clk_regs: list of clock registers 326 * @nr_clk_regs: count of clock registers in @clk_regs 327 * @suspend_regs: list of clock registers to set before suspend 328 * @nr_suspend_regs: count of clock registers in @suspend_regs 329 * @clk_name: name of the parent clock needed for CMU register access 330 */ 331 struct samsung_cmu_info { 332 const struct samsung_pll_clock *pll_clks; 333 unsigned int nr_pll_clks; 334 const struct samsung_mux_clock *mux_clks; 335 unsigned int nr_mux_clks; 336 const struct samsung_div_clock *div_clks; 337 unsigned int nr_div_clks; 338 const struct samsung_gate_clock *gate_clks; 339 unsigned int nr_gate_clks; 340 const struct samsung_fixed_rate_clock *fixed_clks; 341 unsigned int nr_fixed_clks; 342 const struct samsung_fixed_factor_clock *fixed_factor_clks; 343 unsigned int nr_fixed_factor_clks; 344 unsigned int nr_clk_ids; 345 const struct samsung_cpu_clock *cpu_clks; 346 unsigned int nr_cpu_clks; 347 348 const unsigned long *clk_regs; 349 unsigned int nr_clk_regs; 350 351 const struct samsung_clk_reg_dump *suspend_regs; 352 unsigned int nr_suspend_regs; 353 const char *clk_name; 354 }; 355 356 struct samsung_clk_provider *samsung_clk_init(struct device *dev, 357 void __iomem *base, unsigned long nr_clks); 358 void samsung_clk_of_add_provider(struct device_node *np, 359 struct samsung_clk_provider *ctx); 360 void samsung_clk_of_register_fixed_ext( 361 struct samsung_clk_provider *ctx, 362 struct samsung_fixed_rate_clock *fixed_rate_clk, 363 unsigned int nr_fixed_rate_clk, 364 const struct of_device_id *clk_matches); 365 366 void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, 367 struct clk_hw *clk_hw, unsigned int id); 368 369 void samsung_clk_register_alias(struct samsung_clk_provider *ctx, 370 const struct samsung_clock_alias *list, 371 unsigned int nr_clk); 372 void samsung_clk_register_fixed_rate( 373 struct samsung_clk_provider *ctx, 374 const struct samsung_fixed_rate_clock *clk_list, 375 unsigned int nr_clk); 376 void samsung_clk_register_fixed_factor( 377 struct samsung_clk_provider *ctx, 378 const struct samsung_fixed_factor_clock *list, 379 unsigned int nr_clk); 380 void samsung_clk_register_mux(struct samsung_clk_provider *ctx, 381 const struct samsung_mux_clock *clk_list, 382 unsigned int nr_clk); 383 void samsung_clk_register_div(struct samsung_clk_provider *ctx, 384 const struct samsung_div_clock *clk_list, 385 unsigned int nr_clk); 386 void samsung_clk_register_gate(struct samsung_clk_provider *ctx, 387 const struct samsung_gate_clock *clk_list, 388 unsigned int nr_clk); 389 void samsung_clk_register_pll(struct samsung_clk_provider *ctx, 390 const struct samsung_pll_clock *pll_list, 391 unsigned int nr_clk); 392 void samsung_clk_register_cpu(struct samsung_clk_provider *ctx, 393 const struct samsung_cpu_clock *list, unsigned int nr_clk); 394 395 void samsung_cmu_register_clocks(struct samsung_clk_provider *ctx, 396 const struct samsung_cmu_info *cmu); 397 struct samsung_clk_provider *samsung_cmu_register_one( 398 struct device_node *, 399 const struct samsung_cmu_info *); 400 401 #ifdef CONFIG_PM_SLEEP 402 void samsung_clk_extended_sleep_init(void __iomem *reg_base, 403 const unsigned long *rdump, 404 unsigned long nr_rdump, 405 const struct samsung_clk_reg_dump *rsuspend, 406 unsigned long nr_rsuspend); 407 #else 408 static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base, 409 const unsigned long *rdump, 410 unsigned long nr_rdump, 411 const struct samsung_clk_reg_dump *rsuspend, 412 unsigned long nr_rsuspend) {} 413 #endif 414 #define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \ 415 samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0) 416 417 void samsung_clk_save(void __iomem *base, 418 struct samsung_clk_reg_dump *rd, 419 unsigned int num_regs); 420 void samsung_clk_restore(void __iomem *base, 421 const struct samsung_clk_reg_dump *rd, 422 unsigned int num_regs); 423 struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( 424 const unsigned long *rdump, 425 unsigned long nr_rdump); 426 427 #endif /* __SAMSUNG_CLK_H */ 428