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_clock_reg_cache {
 275        struct list_head node;
 276        void __iomem *reg_base;
 277        struct samsung_clk_reg_dump *rdump;
 278        unsigned int rd_num;
 279        const struct samsung_clk_reg_dump *rsuspend;
 280        unsigned int rsuspend_num;
 281};
 282
 283struct samsung_cmu_info {
 284        /* list of pll clocks and respective count */
 285        const struct samsung_pll_clock *pll_clks;
 286        unsigned int nr_pll_clks;
 287        /* list of mux clocks and respective count */
 288        const struct samsung_mux_clock *mux_clks;
 289        unsigned int nr_mux_clks;
 290        /* list of div clocks and respective count */
 291        const struct samsung_div_clock *div_clks;
 292        unsigned int nr_div_clks;
 293        /* list of gate clocks and respective count */
 294        const struct samsung_gate_clock *gate_clks;
 295        unsigned int nr_gate_clks;
 296        /* list of fixed clocks and respective count */
 297        const struct samsung_fixed_rate_clock *fixed_clks;
 298        unsigned int nr_fixed_clks;
 299        /* list of fixed factor clocks and respective count */
 300        const struct samsung_fixed_factor_clock *fixed_factor_clks;
 301        unsigned int nr_fixed_factor_clks;
 302        /* total number of clocks with IDs assigned*/
 303        unsigned int nr_clk_ids;
 304
 305        /* list and number of clocks registers */
 306        const unsigned long *clk_regs;
 307        unsigned int nr_clk_regs;
 308
 309        /* list and number of clocks registers to set before suspend */
 310        const struct samsung_clk_reg_dump *suspend_regs;
 311        unsigned int nr_suspend_regs;
 312        /* name of the parent clock needed for CMU register access */
 313        const char *clk_name;
 314};
 315
 316extern struct samsung_clk_provider *__init samsung_clk_init(
 317                        struct device_node *np, void __iomem *base,
 318                        unsigned long nr_clks);
 319extern void __init samsung_clk_of_add_provider(struct device_node *np,
 320                        struct samsung_clk_provider *ctx);
 321extern void __init samsung_clk_of_register_fixed_ext(
 322                        struct samsung_clk_provider *ctx,
 323                        struct samsung_fixed_rate_clock *fixed_rate_clk,
 324                        unsigned int nr_fixed_rate_clk,
 325                        const struct of_device_id *clk_matches);
 326
 327extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
 328                        struct clk_hw *clk_hw, unsigned int id);
 329
 330extern void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx,
 331                        const struct samsung_clock_alias *list,
 332                        unsigned int nr_clk);
 333extern void __init samsung_clk_register_fixed_rate(
 334                        struct samsung_clk_provider *ctx,
 335                        const struct samsung_fixed_rate_clock *clk_list,
 336                        unsigned int nr_clk);
 337extern void __init samsung_clk_register_fixed_factor(
 338                        struct samsung_clk_provider *ctx,
 339                        const struct samsung_fixed_factor_clock *list,
 340                        unsigned int nr_clk);
 341extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
 342                        const struct samsung_mux_clock *clk_list,
 343                        unsigned int nr_clk);
 344extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
 345                        const struct samsung_div_clock *clk_list,
 346                        unsigned int nr_clk);
 347extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
 348                        const struct samsung_gate_clock *clk_list,
 349                        unsigned int nr_clk);
 350extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 351                        const struct samsung_pll_clock *pll_list,
 352                        unsigned int nr_clk, void __iomem *base);
 353
 354extern struct samsung_clk_provider __init *samsung_cmu_register_one(
 355                        struct device_node *,
 356                        const struct samsung_cmu_info *);
 357
 358extern unsigned long _get_rate(const char *clk_name);
 359
 360#ifdef CONFIG_PM_SLEEP
 361extern void samsung_clk_extended_sleep_init(void __iomem *reg_base,
 362                        const unsigned long *rdump,
 363                        unsigned long nr_rdump,
 364                        const struct samsung_clk_reg_dump *rsuspend,
 365                        unsigned long nr_rsuspend);
 366#else
 367static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base,
 368                        const unsigned long *rdump,
 369                        unsigned long nr_rdump,
 370                        const struct samsung_clk_reg_dump *rsuspend,
 371                        unsigned long nr_rsuspend) {}
 372#endif
 373#define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \
 374        samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0)
 375
 376extern void samsung_clk_save(void __iomem *base,
 377                        struct samsung_clk_reg_dump *rd,
 378                        unsigned int num_regs);
 379extern void samsung_clk_restore(void __iomem *base,
 380                        const struct samsung_clk_reg_dump *rd,
 381                        unsigned int num_regs);
 382extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
 383                        const unsigned long *rdump,
 384                        unsigned long nr_rdump);
 385
 386#endif /* __SAMSUNG_CLK_H */
 387