linux/drivers/clk/samsung/clk.h
<<
>>
Prefs
   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
 340extern struct samsung_clk_provider *__init samsung_clk_init(
 341                        struct device_node *np, void __iomem *base,
 342                        unsigned long nr_clks);
 343extern void __init samsung_clk_of_add_provider(struct device_node *np,
 344                        struct samsung_clk_provider *ctx);
 345extern void __init 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
 351extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
 352                        struct clk_hw *clk_hw, unsigned int id);
 353
 354extern void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx,
 355                        const struct samsung_clock_alias *list,
 356                        unsigned int nr_clk);
 357extern void __init 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);
 361extern void __init samsung_clk_register_fixed_factor(
 362                        struct samsung_clk_provider *ctx,
 363                        const struct samsung_fixed_factor_clock *list,
 364                        unsigned int nr_clk);
 365extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
 366                        const struct samsung_mux_clock *clk_list,
 367                        unsigned int nr_clk);
 368extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
 369                        const struct samsung_div_clock *clk_list,
 370                        unsigned int nr_clk);
 371extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
 372                        const struct samsung_gate_clock *clk_list,
 373                        unsigned int nr_clk);
 374extern void __init 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);
 377extern void samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
 378                const struct samsung_cpu_clock *list, unsigned int nr_clk);
 379
 380extern struct samsung_clk_provider __init *samsung_cmu_register_one(
 381                        struct device_node *,
 382                        const struct samsung_cmu_info *);
 383
 384extern unsigned long _get_rate(const char *clk_name);
 385
 386#ifdef CONFIG_PM_SLEEP
 387extern void samsung_clk_extended_sleep_init(void __iomem *reg_base,
 388                        const unsigned long *rdump,
 389                        unsigned long nr_rdump,
 390                        const struct samsung_clk_reg_dump *rsuspend,
 391                        unsigned long nr_rsuspend);
 392#else
 393static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base,
 394                        const unsigned long *rdump,
 395                        unsigned long nr_rdump,
 396                        const struct samsung_clk_reg_dump *rsuspend,
 397                        unsigned long nr_rsuspend) {}
 398#endif
 399#define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \
 400        samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0)
 401
 402extern void samsung_clk_save(void __iomem *base,
 403                        struct samsung_clk_reg_dump *rd,
 404                        unsigned int num_regs);
 405extern void samsung_clk_restore(void __iomem *base,
 406                        const struct samsung_clk_reg_dump *rd,
 407                        unsigned int num_regs);
 408extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
 409                        const unsigned long *rdump,
 410                        unsigned long nr_rdump);
 411
 412#endif /* __SAMSUNG_CLK_H */
 413