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