Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 492 lines 15 kB view raw
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 <linux/mod_devicetable.h> 15#include <linux/regmap.h> 16#include "clk-pll.h" 17#include "clk-cpu.h" 18 19/** 20 * struct samsung_clk_provider - information about clock provider 21 * @reg_base: virtual address for the register base 22 * @dev: clock provider device needed for runtime PM 23 * @sysreg: syscon regmap for clock-provider sysreg controller 24 * @lock: maintains exclusion between callbacks for a given clock-provider 25 * @auto_clock_gate: enable auto clk mode for all clocks in clock-provider 26 * @gate_dbg_offset: gate debug reg offset. Used for all gates in auto clk mode 27 * @option_offset: option reg offset. Enables auto mode for clock-provider 28 * @drcg_offset: dynamic root clk gate enable register offset in sysreg 29 * @memclk_offset: memclk enable register offset in sysreg 30 * @clk_data: holds clock related data like clk_hw* and number of clocks 31 */ 32struct samsung_clk_provider { 33 void __iomem *reg_base; 34 struct device *dev; 35 struct regmap *sysreg; 36 spinlock_t lock; 37 bool auto_clock_gate; 38 u32 gate_dbg_offset; 39 u32 option_offset; 40 u32 drcg_offset; 41 u32 memclk_offset; 42 /* clk_data must be the last entry due to variable length 'hws' array */ 43 struct clk_hw_onecell_data clk_data; 44}; 45 46/** 47 * struct samsung_clock_alias - information about mux clock 48 * @id: platform specific id of the clock 49 * @dev_name: name of the device to which this clock belongs 50 * @alias: optional clock alias name to be assigned to this clock 51 */ 52struct samsung_clock_alias { 53 unsigned int id; 54 const char *dev_name; 55 const char *alias; 56}; 57 58#define ALIAS(_id, dname, a) \ 59 { \ 60 .id = _id, \ 61 .dev_name = dname, \ 62 .alias = a, \ 63 } 64 65#define MHZ (1000 * 1000) 66 67/** 68 * struct samsung_fixed_rate_clock - information about fixed-rate clock 69 * @id: platform specific id of the clock 70 * @name: name of this fixed-rate clock 71 * @parent_name: optional parent clock name 72 * @flags: optional fixed-rate clock flags 73 * @fixed_rate: fixed clock rate of this clock 74 */ 75struct samsung_fixed_rate_clock { 76 unsigned int id; 77 char *name; 78 const char *parent_name; 79 unsigned long flags; 80 unsigned long fixed_rate; 81}; 82 83#define FRATE(_id, cname, pname, f, frate) \ 84 { \ 85 .id = _id, \ 86 .name = cname, \ 87 .parent_name = pname, \ 88 .flags = f, \ 89 .fixed_rate = frate, \ 90 } 91 92/** 93 * struct samsung_fixed_factor_clock - information about fixed-factor clock 94 * @id: platform specific id of the clock 95 * @name: name of this fixed-factor clock 96 * @parent_name: parent clock name 97 * @mult: fixed multiplication factor 98 * @div: fixed division factor 99 * @flags: optional fixed-factor clock flags 100 */ 101struct samsung_fixed_factor_clock { 102 unsigned int id; 103 char *name; 104 const char *parent_name; 105 unsigned long mult; 106 unsigned long div; 107 unsigned long flags; 108}; 109 110#define FFACTOR(_id, cname, pname, m, d, f) \ 111 { \ 112 .id = _id, \ 113 .name = cname, \ 114 .parent_name = pname, \ 115 .mult = m, \ 116 .div = d, \ 117 .flags = f, \ 118 } 119 120/** 121 * struct samsung_mux_clock - information about mux clock 122 * @id: platform specific id of the clock 123 * @name: name of this mux clock 124 * @parent_names: array of pointer to parent clock names 125 * @num_parents: number of parents listed in @parent_names 126 * @flags: optional flags for basic clock 127 * @offset: offset of the register for configuring the mux 128 * @shift: starting bit location of the mux control bit-field in @reg 129 * @width: width of the mux control bit-field in @reg 130 * @mux_flags: flags for mux-type clock 131 */ 132struct samsung_mux_clock { 133 unsigned int id; 134 const char *name; 135 const char *const *parent_names; 136 u8 num_parents; 137 unsigned long flags; 138 unsigned long offset; 139 u8 shift; 140 u8 width; 141 u8 mux_flags; 142}; 143 144#define __MUX(_id, cname, pnames, o, s, w, f, mf) \ 145 { \ 146 .id = _id, \ 147 .name = cname, \ 148 .parent_names = pnames, \ 149 .num_parents = ARRAY_SIZE(pnames), \ 150 .flags = f, \ 151 .offset = o, \ 152 .shift = s, \ 153 .width = w, \ 154 .mux_flags = mf, \ 155 } 156 157#define MUX(_id, cname, pnames, o, s, w) \ 158 __MUX(_id, cname, pnames, o, s, w, CLK_SET_RATE_NO_REPARENT, 0) 159 160#define MUX_F(_id, cname, pnames, o, s, w, f, mf) \ 161 __MUX(_id, cname, pnames, o, s, w, (f) | CLK_SET_RATE_NO_REPARENT, mf) 162 163/* Used by MUX clocks where reparenting on clock rate change is allowed. */ 164#define nMUX(_id, cname, pnames, o, s, w) \ 165 __MUX(_id, cname, pnames, o, s, w, 0, 0) 166 167#define nMUX_F(_id, cname, pnames, o, s, w, f, mf) \ 168 __MUX(_id, cname, pnames, o, s, w, f, mf) 169 170/** 171 * struct samsung_div_clock - information about div clock 172 * @id: platform specific id of the clock 173 * @name: name of this div clock 174 * @parent_name: name of the parent clock 175 * @flags: optional flags for basic clock 176 * @offset: offset of the register for configuring the div 177 * @shift: starting bit location of the div control bit-field in @reg 178 * @width: width of the bitfield 179 * @div_flags: flags for div-type clock 180 * @table: array of divider/value pairs ending with a div set to 0 181 */ 182struct samsung_div_clock { 183 unsigned int id; 184 const char *name; 185 const char *parent_name; 186 unsigned long flags; 187 unsigned long offset; 188 u8 shift; 189 u8 width; 190 u8 div_flags; 191 struct clk_div_table *table; 192}; 193 194#define __DIV(_id, cname, pname, o, s, w, f, df, t) \ 195 { \ 196 .id = _id, \ 197 .name = cname, \ 198 .parent_name = pname, \ 199 .flags = f, \ 200 .offset = o, \ 201 .shift = s, \ 202 .width = w, \ 203 .div_flags = df, \ 204 .table = t, \ 205 } 206 207#define DIV(_id, cname, pname, o, s, w) \ 208 __DIV(_id, cname, pname, o, s, w, 0, 0, NULL) 209 210#define DIV_F(_id, cname, pname, o, s, w, f, df) \ 211 __DIV(_id, cname, pname, o, s, w, f, df, NULL) 212 213#define DIV_T(_id, cname, pname, o, s, w, t) \ 214 __DIV(_id, cname, pname, o, s, w, 0, 0, t) 215 216/** 217 * struct samsung_gate_clock - information about gate clock 218 * @id: platform specific id of the clock 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 */ 226struct samsung_gate_clock { 227 unsigned int id; 228 const char *name; 229 const char *parent_name; 230 unsigned long flags; 231 unsigned long offset; 232 u8 bit_idx; 233 u8 gate_flags; 234}; 235 236#define __GATE(_id, cname, pname, o, b, f, gf) \ 237 { \ 238 .id = _id, \ 239 .name = cname, \ 240 .parent_name = pname, \ 241 .flags = f, \ 242 .offset = o, \ 243 .bit_idx = b, \ 244 .gate_flags = gf, \ 245 } 246 247#define GATE(_id, cname, pname, o, b, f, gf) \ 248 __GATE(_id, cname, pname, o, b, f, gf) 249 250#define PNAME(x) static const char * const x[] __initconst 251 252/** 253 * struct samsung_clk_reg_dump - register dump of clock controller registers 254 * @offset: clock register offset from the controller base address 255 * @value: the value to be register at offset 256 */ 257struct samsung_clk_reg_dump { 258 u32 offset; 259 u32 value; 260}; 261 262/** 263 * struct samsung_pll_clock - information about pll clock 264 * @id: platform specific id of the clock 265 * @name: name of this pll clock 266 * @parent_name: name of the parent clock 267 * @flags: optional flags for basic clock 268 * @con_offset: offset of the register for configuring the PLL 269 * @lock_offset: offset of the register for locking the PLL 270 * @type: type of PLL to be registered 271 * @rate_table: array of PLL settings for possible PLL rates 272 */ 273struct samsung_pll_clock { 274 unsigned int id; 275 const char *name; 276 const char *parent_name; 277 unsigned long flags; 278 int con_offset; 279 int lock_offset; 280 enum samsung_pll_type type; 281 const struct samsung_pll_rate_table *rate_table; 282}; 283 284#define __PLL(_typ, _id, _name, _pname, _flags, _lock, _con, _rtable) \ 285 { \ 286 .id = _id, \ 287 .type = _typ, \ 288 .name = _name, \ 289 .parent_name = _pname, \ 290 .flags = _flags, \ 291 .con_offset = _con, \ 292 .lock_offset = _lock, \ 293 .rate_table = _rtable, \ 294 } 295 296#define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable) \ 297 __PLL(_typ, _id, _name, _pname, CLK_GET_RATE_NOCACHE, _lock, \ 298 _con, _rtable) 299 300struct samsung_cpu_clock { 301 unsigned int id; 302 const char *name; 303 unsigned int parent_id; 304 unsigned int alt_parent_id; 305 unsigned long flags; 306 int offset; 307 enum exynos_cpuclk_layout reg_layout; 308 const struct exynos_cpuclk_cfg_data *cfg; 309}; 310 311#define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _layout, _cfg) \ 312 { \ 313 .id = _id, \ 314 .name = _name, \ 315 .parent_id = _pid, \ 316 .alt_parent_id = _apid, \ 317 .flags = _flags, \ 318 .offset = _offset, \ 319 .reg_layout = _layout, \ 320 .cfg = _cfg, \ 321 } 322 323struct samsung_clock_reg_cache { 324 struct list_head node; 325 void __iomem *reg_base; 326 struct regmap *sysreg; 327 struct samsung_clk_reg_dump *rdump; 328 unsigned int rd_num; 329 const struct samsung_clk_reg_dump *rsuspend; 330 unsigned int rsuspend_num; 331}; 332 333/** 334 * struct samsung_cmu_info - all clocks information needed for CMU registration 335 * @pll_clks: list of PLL clocks 336 * @nr_pll_clks: count of clocks in @pll_clks 337 * @mux_clks: list of mux clocks 338 * @nr_mux_clks: count of clocks in @mux_clks 339 * @div_clks: list of div clocks 340 * @nr_div_clks: count of clocks in @div_clks 341 * @gate_clks: list of gate clocks 342 * @nr_gate_clks: count of clocks in @gate_clks 343 * @fixed_clks: list of fixed clocks 344 * @nr_fixed_clks: count clocks in @fixed_clks 345 * @fixed_factor_clks: list of fixed factor clocks 346 * @nr_fixed_factor_clks: count of clocks in @fixed_factor_clks 347 * @nr_clk_ids: total number of clocks with IDs assigned 348 * @cpu_clks: list of CPU clocks 349 * @nr_cpu_clks: count of clocks in @cpu_clks 350 * @clk_regs: list of clock registers 351 * @nr_clk_regs: count of clock registers in @clk_regs 352 * @suspend_regs: list of clock registers to set before suspend 353 * @nr_suspend_regs: count of clock registers in @suspend_regs 354 * @clk_name: name of the parent clock needed for CMU register access 355 * @sysreg_clk_regs: list of sysreg clock registers 356 * @nr_sysreg_clk_regs: count of clock registers in @sysreg_clk_regs 357 * @manual_plls: Enable manual control for PLL clocks 358 * @auto_clock_gate: enable auto clock mode for all components in CMU 359 * @gate_dbg_offset: gate debug reg offset. Used by all gates in auto clk mode 360 * @option_offset: option reg offset. Enables auto clk mode for entire CMU 361 * @drcg_offset: dynamic root clk gate enable register offset in sysreg 362 * @memclk_offset: memclk enable register offset in sysreg 363 */ 364struct samsung_cmu_info { 365 const struct samsung_pll_clock *pll_clks; 366 unsigned int nr_pll_clks; 367 const struct samsung_mux_clock *mux_clks; 368 unsigned int nr_mux_clks; 369 const struct samsung_div_clock *div_clks; 370 unsigned int nr_div_clks; 371 const struct samsung_gate_clock *gate_clks; 372 unsigned int nr_gate_clks; 373 const struct samsung_fixed_rate_clock *fixed_clks; 374 unsigned int nr_fixed_clks; 375 const struct samsung_fixed_factor_clock *fixed_factor_clks; 376 unsigned int nr_fixed_factor_clks; 377 unsigned int nr_clk_ids; 378 const struct samsung_cpu_clock *cpu_clks; 379 unsigned int nr_cpu_clks; 380 381 const unsigned long *clk_regs; 382 unsigned int nr_clk_regs; 383 384 const struct samsung_clk_reg_dump *suspend_regs; 385 unsigned int nr_suspend_regs; 386 const char *clk_name; 387 388 const unsigned long *sysreg_clk_regs; 389 unsigned int nr_sysreg_clk_regs; 390 391 /* ARM64 Exynos CMUs */ 392 bool manual_plls; 393 bool auto_clock_gate; 394 u32 gate_dbg_offset; 395 u32 option_offset; 396 u32 drcg_offset; 397 u32 memclk_offset; 398}; 399 400struct samsung_clk_provider *samsung_clk_init(struct device *dev, 401 void __iomem *base, unsigned long nr_clks); 402void samsung_clk_of_add_provider(struct device_node *np, 403 struct samsung_clk_provider *ctx); 404void samsung_clk_of_register_fixed_ext( 405 struct samsung_clk_provider *ctx, 406 struct samsung_fixed_rate_clock *fixed_rate_clk, 407 unsigned int nr_fixed_rate_clk, 408 const struct of_device_id *clk_matches); 409 410void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, 411 struct clk_hw *clk_hw, unsigned int id); 412 413void samsung_clk_register_alias(struct samsung_clk_provider *ctx, 414 const struct samsung_clock_alias *list, 415 unsigned int nr_clk); 416void samsung_clk_register_fixed_rate( 417 struct samsung_clk_provider *ctx, 418 const struct samsung_fixed_rate_clock *clk_list, 419 unsigned int nr_clk); 420void samsung_clk_register_fixed_factor( 421 struct samsung_clk_provider *ctx, 422 const struct samsung_fixed_factor_clock *list, 423 unsigned int nr_clk); 424void samsung_clk_register_mux(struct samsung_clk_provider *ctx, 425 const struct samsung_mux_clock *clk_list, 426 unsigned int nr_clk); 427void samsung_clk_register_div(struct samsung_clk_provider *ctx, 428 const struct samsung_div_clock *clk_list, 429 unsigned int nr_clk); 430void samsung_clk_register_gate(struct samsung_clk_provider *ctx, 431 const struct samsung_gate_clock *clk_list, 432 unsigned int nr_clk); 433void samsung_clk_register_pll(struct samsung_clk_provider *ctx, 434 const struct samsung_pll_clock *pll_list, 435 unsigned int nr_clk); 436void samsung_clk_register_cpu(struct samsung_clk_provider *ctx, 437 const struct samsung_cpu_clock *list, unsigned int nr_clk); 438 439void samsung_cmu_register_clocks(struct samsung_clk_provider *ctx, 440 const struct samsung_cmu_info *cmu, 441 struct device_node *np); 442struct samsung_clk_provider *samsung_cmu_register_one( 443 struct device_node *, 444 const struct samsung_cmu_info *); 445 446#ifdef CONFIG_PM_SLEEP 447void samsung_clk_extended_sleep_init(void __iomem *reg_base, 448 struct regmap *sysreg, 449 const unsigned long *rdump, 450 unsigned long nr_rdump, 451 const struct samsung_clk_reg_dump *rsuspend, 452 unsigned long nr_rsuspend); 453#else 454static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base, 455 struct regmap *sysreg, 456 const unsigned long *rdump, 457 unsigned long nr_rdump, 458 const struct samsung_clk_reg_dump *rsuspend, 459 unsigned long nr_rsuspend) {} 460#endif 461#define samsung_clk_sleep_init(reg_base, sysreg, rdump, nr_rdump) \ 462 samsung_clk_extended_sleep_init(reg_base, sysreg, rdump, nr_rdump, \ 463 NULL, 0) 464 465void samsung_clk_save(void __iomem *base, 466 struct regmap *regmap, 467 struct samsung_clk_reg_dump *rd, 468 unsigned int num_regs); 469void samsung_clk_restore(void __iomem *base, 470 struct regmap *regmap, 471 const struct samsung_clk_reg_dump *rd, 472 unsigned int num_regs); 473struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( 474 const unsigned long *rdump, 475 unsigned long nr_rdump); 476 477void samsung_en_dyn_root_clk_gating(struct device_node *np, 478 struct samsung_clk_provider *ctx, 479 const struct samsung_cmu_info *cmu, 480 bool cmu_has_pm); 481 482struct clk_hw *samsung_register_auto_gate(struct device *dev, 483 struct device_node *np, const char *name, 484 const char *parent_name, const struct clk_hw *parent_hw, 485 const struct clk_parent_data *parent_data, 486 unsigned long flags, 487 void __iomem *reg, u8 bit_idx, 488 u8 clk_gate_flags, spinlock_t *lock); 489 490bool samsung_is_auto_capable(struct device_node *np); 491 492#endif /* __SAMSUNG_CLK_H */