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 #include "clk-cpu.h" 16 17 /** 18 * struct samsung_clk_provider - information about clock provider 19 * @reg_base: virtual address for the register base 20 * @dev: clock provider device needed for runtime PM 21 * @lock: maintains exclusion between callbacks for a given clock-provider 22 * @clk_data: holds clock related data like clk_hw* and number of clocks 23 */ 24 struct samsung_clk_provider { 25 void __iomem *reg_base; 26 struct device *dev; 27 spinlock_t lock; 28 /* clk_data must be the last entry due to variable length 'hws' array */ 29 struct clk_hw_onecell_data clk_data; 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 * @name: name of this mux clock 110 * @parent_names: array of pointer to parent clock names 111 * @num_parents: number of parents listed in @parent_names 112 * @flags: optional flags for basic clock 113 * @offset: offset of the register for configuring the mux 114 * @shift: starting bit location of the mux control bit-field in @reg 115 * @width: width of the mux control bit-field in @reg 116 * @mux_flags: flags for mux-type clock 117 */ 118 struct samsung_mux_clock { 119 unsigned int id; 120 const char *name; 121 const char *const *parent_names; 122 u8 num_parents; 123 unsigned long flags; 124 unsigned long offset; 125 u8 shift; 126 u8 width; 127 u8 mux_flags; 128 }; 129 130 #define __MUX(_id, cname, pnames, o, s, w, f, mf) \ 131 { \ 132 .id = _id, \ 133 .name = cname, \ 134 .parent_names = pnames, \ 135 .num_parents = ARRAY_SIZE(pnames), \ 136 .flags = f, \ 137 .offset = o, \ 138 .shift = s, \ 139 .width = w, \ 140 .mux_flags = mf, \ 141 } 142 143 #define MUX(_id, cname, pnames, o, s, w) \ 144 __MUX(_id, cname, pnames, o, s, w, CLK_SET_RATE_NO_REPARENT, 0) 145 146 #define MUX_F(_id, cname, pnames, o, s, w, f, mf) \ 147 __MUX(_id, cname, pnames, o, s, w, (f) | CLK_SET_RATE_NO_REPARENT, mf) 148 149 /* Used by MUX clocks where reparenting on clock rate change is allowed. */ 150 #define nMUX(_id, cname, pnames, o, s, w) \ 151 __MUX(_id, cname, pnames, o, s, w, 0, 0) 152 153 #define nMUX_F(_id, cname, pnames, o, s, w, f, mf) \ 154 __MUX(_id, cname, pnames, o, s, w, f, mf) 155 156 /** 157 * struct samsung_div_clock - information about div clock 158 * @id: platform specific id of the clock 159 * @name: name of this div clock 160 * @parent_name: name of the parent clock 161 * @flags: optional flags for basic clock 162 * @offset: offset of the register for configuring the div 163 * @shift: starting bit location of the div control bit-field in @reg 164 * @width: width of the bitfield 165 * @div_flags: flags for div-type clock 166 * @table: array of divider/value pairs ending with a div set to 0 167 */ 168 struct samsung_div_clock { 169 unsigned int id; 170 const char *name; 171 const char *parent_name; 172 unsigned long flags; 173 unsigned long offset; 174 u8 shift; 175 u8 width; 176 u8 div_flags; 177 struct clk_div_table *table; 178 }; 179 180 #define __DIV(_id, cname, pname, o, s, w, f, df, t) \ 181 { \ 182 .id = _id, \ 183 .name = cname, \ 184 .parent_name = pname, \ 185 .flags = f, \ 186 .offset = o, \ 187 .shift = s, \ 188 .width = w, \ 189 .div_flags = df, \ 190 .table = t, \ 191 } 192 193 #define DIV(_id, cname, pname, o, s, w) \ 194 __DIV(_id, cname, pname, o, s, w, 0, 0, NULL) 195 196 #define DIV_F(_id, cname, pname, o, s, w, f, df) \ 197 __DIV(_id, cname, pname, o, s, w, f, df, NULL) 198 199 #define DIV_T(_id, cname, pname, o, s, w, t) \ 200 __DIV(_id, cname, pname, o, s, w, 0, 0, t) 201 202 /** 203 * struct samsung_gate_clock - information about gate clock 204 * @id: platform specific id of the clock 205 * @name: name of this gate clock 206 * @parent_name: name of the parent clock 207 * @flags: optional flags for basic clock 208 * @offset: offset of the register for configuring the gate 209 * @bit_idx: bit index of the gate control bit-field in @reg 210 * @gate_flags: flags for gate-type clock 211 */ 212 struct samsung_gate_clock { 213 unsigned int id; 214 const char *name; 215 const char *parent_name; 216 unsigned long flags; 217 unsigned long offset; 218 u8 bit_idx; 219 u8 gate_flags; 220 }; 221 222 #define __GATE(_id, cname, pname, o, b, f, gf) \ 223 { \ 224 .id = _id, \ 225 .name = cname, \ 226 .parent_name = pname, \ 227 .flags = f, \ 228 .offset = o, \ 229 .bit_idx = b, \ 230 .gate_flags = gf, \ 231 } 232 233 #define GATE(_id, cname, pname, o, b, f, gf) \ 234 __GATE(_id, cname, pname, o, b, f, gf) 235 236 #define PNAME(x) static const char * const x[] __initconst 237 238 /** 239 * struct samsung_clk_reg_dump - register dump of clock controller registers 240 * @offset: clock register offset from the controller base address 241 * @value: the value to be register at offset 242 */ 243 struct samsung_clk_reg_dump { 244 u32 offset; 245 u32 value; 246 }; 247 248 /** 249 * struct samsung_pll_clock - information about pll clock 250 * @id: platform specific id of the clock 251 * @name: name of this pll clock 252 * @parent_name: name of the parent clock 253 * @flags: optional flags for basic clock 254 * @con_offset: offset of the register for configuring the PLL 255 * @lock_offset: offset of the register for locking the PLL 256 * @type: type of PLL to be registered 257 * @rate_table: array of PLL settings for possible PLL rates 258 */ 259 struct samsung_pll_clock { 260 unsigned int id; 261 const char *name; 262 const char *parent_name; 263 unsigned long flags; 264 int con_offset; 265 int lock_offset; 266 enum samsung_pll_type type; 267 const struct samsung_pll_rate_table *rate_table; 268 }; 269 270 #define __PLL(_typ, _id, _name, _pname, _flags, _lock, _con, _rtable) \ 271 { \ 272 .id = _id, \ 273 .type = _typ, \ 274 .name = _name, \ 275 .parent_name = _pname, \ 276 .flags = _flags, \ 277 .con_offset = _con, \ 278 .lock_offset = _lock, \ 279 .rate_table = _rtable, \ 280 } 281 282 #define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable) \ 283 __PLL(_typ, _id, _name, _pname, CLK_GET_RATE_NOCACHE, _lock, \ 284 _con, _rtable) 285 286 struct samsung_cpu_clock { 287 unsigned int id; 288 const char *name; 289 unsigned int parent_id; 290 unsigned int alt_parent_id; 291 unsigned long flags; 292 int offset; 293 enum exynos_cpuclk_layout reg_layout; 294 const struct exynos_cpuclk_cfg_data *cfg; 295 }; 296 297 #define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _layout, _cfg) \ 298 { \ 299 .id = _id, \ 300 .name = _name, \ 301 .parent_id = _pid, \ 302 .alt_parent_id = _apid, \ 303 .flags = _flags, \ 304 .offset = _offset, \ 305 .reg_layout = _layout, \ 306 .cfg = _cfg, \ 307 } 308 309 struct samsung_clock_reg_cache { 310 struct list_head node; 311 void __iomem *reg_base; 312 struct samsung_clk_reg_dump *rdump; 313 unsigned int rd_num; 314 const struct samsung_clk_reg_dump *rsuspend; 315 unsigned int rsuspend_num; 316 }; 317 318 /** 319 * struct samsung_cmu_info - all clocks information needed for CMU registration 320 * @pll_clks: list of PLL clocks 321 * @nr_pll_clks: count of clocks in @pll_clks 322 * @mux_clks: list of mux clocks 323 * @nr_mux_clks: count of clocks in @mux_clks 324 * @div_clks: list of div clocks 325 * @nr_div_clks: count of clocks in @div_clks 326 * @gate_clks: list of gate clocks 327 * @nr_gate_clks: count of clocks in @gate_clks 328 * @fixed_clks: list of fixed clocks 329 * @nr_fixed_clks: count clocks in @fixed_clks 330 * @fixed_factor_clks: list of fixed factor clocks 331 * @nr_fixed_factor_clks: count of clocks in @fixed_factor_clks 332 * @nr_clk_ids: total number of clocks with IDs assigned 333 * @cpu_clks: list of CPU clocks 334 * @nr_cpu_clks: count of clocks in @cpu_clks 335 * @clk_regs: list of clock registers 336 * @nr_clk_regs: count of clock registers in @clk_regs 337 * @suspend_regs: list of clock registers to set before suspend 338 * @nr_suspend_regs: count of clock registers in @suspend_regs 339 * @clk_name: name of the parent clock needed for CMU register access 340 * @manual_plls: Enable manual control for PLL clocks 341 */ 342 struct samsung_cmu_info { 343 const struct samsung_pll_clock *pll_clks; 344 unsigned int nr_pll_clks; 345 const struct samsung_mux_clock *mux_clks; 346 unsigned int nr_mux_clks; 347 const struct samsung_div_clock *div_clks; 348 unsigned int nr_div_clks; 349 const struct samsung_gate_clock *gate_clks; 350 unsigned int nr_gate_clks; 351 const struct samsung_fixed_rate_clock *fixed_clks; 352 unsigned int nr_fixed_clks; 353 const struct samsung_fixed_factor_clock *fixed_factor_clks; 354 unsigned int nr_fixed_factor_clks; 355 unsigned int nr_clk_ids; 356 const struct samsung_cpu_clock *cpu_clks; 357 unsigned int nr_cpu_clks; 358 359 const unsigned long *clk_regs; 360 unsigned int nr_clk_regs; 361 362 const struct samsung_clk_reg_dump *suspend_regs; 363 unsigned int nr_suspend_regs; 364 const char *clk_name; 365 366 /* ARM64 Exynos CMUs */ 367 bool manual_plls; 368 }; 369 370 struct samsung_clk_provider *samsung_clk_init(struct device *dev, 371 void __iomem *base, unsigned long nr_clks); 372 void samsung_clk_of_add_provider(struct device_node *np, 373 struct samsung_clk_provider *ctx); 374 void samsung_clk_of_register_fixed_ext( 375 struct samsung_clk_provider *ctx, 376 struct samsung_fixed_rate_clock *fixed_rate_clk, 377 unsigned int nr_fixed_rate_clk, 378 const struct of_device_id *clk_matches); 379 380 void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, 381 struct clk_hw *clk_hw, unsigned int id); 382 383 void samsung_clk_register_alias(struct samsung_clk_provider *ctx, 384 const struct samsung_clock_alias *list, 385 unsigned int nr_clk); 386 void samsung_clk_register_fixed_rate( 387 struct samsung_clk_provider *ctx, 388 const struct samsung_fixed_rate_clock *clk_list, 389 unsigned int nr_clk); 390 void samsung_clk_register_fixed_factor( 391 struct samsung_clk_provider *ctx, 392 const struct samsung_fixed_factor_clock *list, 393 unsigned int nr_clk); 394 void samsung_clk_register_mux(struct samsung_clk_provider *ctx, 395 const struct samsung_mux_clock *clk_list, 396 unsigned int nr_clk); 397 void samsung_clk_register_div(struct samsung_clk_provider *ctx, 398 const struct samsung_div_clock *clk_list, 399 unsigned int nr_clk); 400 void samsung_clk_register_gate(struct samsung_clk_provider *ctx, 401 const struct samsung_gate_clock *clk_list, 402 unsigned int nr_clk); 403 void samsung_clk_register_pll(struct samsung_clk_provider *ctx, 404 const struct samsung_pll_clock *pll_list, 405 unsigned int nr_clk); 406 void samsung_clk_register_cpu(struct samsung_clk_provider *ctx, 407 const struct samsung_cpu_clock *list, unsigned int nr_clk); 408 409 void samsung_cmu_register_clocks(struct samsung_clk_provider *ctx, 410 const struct samsung_cmu_info *cmu); 411 struct samsung_clk_provider *samsung_cmu_register_one( 412 struct device_node *, 413 const struct samsung_cmu_info *); 414 415 #ifdef CONFIG_PM_SLEEP 416 void samsung_clk_extended_sleep_init(void __iomem *reg_base, 417 const unsigned long *rdump, 418 unsigned long nr_rdump, 419 const struct samsung_clk_reg_dump *rsuspend, 420 unsigned long nr_rsuspend); 421 #else 422 static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base, 423 const unsigned long *rdump, 424 unsigned long nr_rdump, 425 const struct samsung_clk_reg_dump *rsuspend, 426 unsigned long nr_rsuspend) {} 427 #endif 428 #define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \ 429 samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0) 430 431 void samsung_clk_save(void __iomem *base, 432 struct samsung_clk_reg_dump *rd, 433 unsigned int num_regs); 434 void samsung_clk_restore(void __iomem *base, 435 const struct samsung_clk_reg_dump *rd, 436 unsigned int num_regs); 437 struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( 438 const unsigned long *rdump, 439 unsigned long nr_rdump); 440 441 #endif /* __SAMSUNG_CLK_H */ 442