linux/drivers/clk/samsung/clk.h
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
   3 * Copyright (c) 2013 Linaro Ltd.
   4 * Author: Thomas Abraham <thomas.ab@samsung.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 * Common Clock Framework support for all Samsung platforms
  11*/
  12
  13#ifndef __SAMSUNG_CLK_H
  14#define __SAMSUNG_CLK_H
  15
  16#include <linux/clk-provider.h>
  17#include "clk-pll.h"
  18
  19/**
  20 * struct samsung_clk_provider: information about clock provider
  21 * @reg_base: virtual address for the register base.
  22 * @lock: maintains exclusion between callbacks for a given clock-provider.
  23 * @clk_data: holds clock related data like clk_hw* and number of clocks.
  24 */
  25struct samsung_clk_provider {
  26        void __iomem *reg_base;
  27        spinlock_t lock;
  28        /* clk_data must be the last entry due to variable lenght '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 */
  38struct 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 */
  61struct 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 */
  87struct 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 * @dev_name: name of the device to which this clock belongs.
 110 * @name: name of this mux clock.
 111 * @parent_names: array of pointer to parent clock names.
 112 * @num_parents: number of parents listed in @parent_names.
 113 * @flags: optional flags for basic clock.
 114 * @offset: offset of the register for configuring the mux.
 115 * @shift: starting bit location of the mux control bit-field in @reg.
 116 * @width: width of the mux control bit-field in @reg.
 117 * @mux_flags: flags for mux-type clock.
 118 * @alias: optional clock alias name to be assigned to this clock.
 119 */
 120struct samsung_mux_clock {
 121        unsigned int            id;
 122        const char              *dev_name;
 123        const char              *name;
 124        const char              *const *parent_names;
 125        u8                      num_parents;
 126        unsigned long           flags;
 127        unsigned long           offset;
 128        u8                      shift;
 129        u8                      width;
 130        u8                      mux_flags;
 131        const char              *alias;
 132};
 133
 134#define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a)     \
 135        {                                                       \
 136                .id             = _id,                          \
 137                .dev_name       = dname,                        \
 138                .name           = cname,                        \
 139                .parent_names   = pnames,                       \
 140                .num_parents    = ARRAY_SIZE(pnames),           \
 141                .flags          = (f) | CLK_SET_RATE_NO_REPARENT, \
 142                .offset         = o,                            \
 143                .shift          = s,                            \
 144                .width          = w,                            \
 145                .mux_flags      = mf,                           \
 146                .alias          = a,                            \
 147        }
 148
 149#define MUX(_id, cname, pnames, o, s, w)                        \
 150        __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL)
 151
 152#define MUX_A(_id, cname, pnames, o, s, w, a)                   \
 153        __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a)
 154
 155#define MUX_F(_id, cname, pnames, o, s, w, f, mf)               \
 156        __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL)
 157
 158#define MUX_FA(_id, cname, pnames, o, s, w, f, mf, a)           \
 159        __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, a)
 160
 161/**
 162 * @id: platform specific id of the clock.
 163 * struct samsung_div_clock: information about div clock
 164 * @dev_name: name of the device to which this clock belongs.
 165 * @name: name of this div clock.
 166 * @parent_name: name of the parent clock.
 167 * @flags: optional flags for basic clock.
 168 * @offset: offset of the register for configuring the div.
 169 * @shift: starting bit location of the div control bit-field in @reg.
 170 * @div_flags: flags for div-type clock.
 171 * @alias: optional clock alias name to be assigned to this clock.
 172 */
 173struct samsung_div_clock {
 174        unsigned int            id;
 175        const char              *dev_name;
 176        const char              *name;
 177        const char              *parent_name;
 178        unsigned long           flags;
 179        unsigned long           offset;
 180        u8                      shift;
 181        u8                      width;
 182        u8                      div_flags;
 183        const char              *alias;
 184        struct clk_div_table    *table;
 185};
 186
 187#define __DIV(_id, dname, cname, pname, o, s, w, f, df, a, t)   \
 188        {                                                       \
 189                .id             = _id,                          \
 190                .dev_name       = dname,                        \
 191                .name           = cname,                        \
 192                .parent_name    = pname,                        \
 193                .flags          = f,                            \
 194                .offset         = o,                            \
 195                .shift          = s,                            \
 196                .width          = w,                            \
 197                .div_flags      = df,                           \
 198                .alias          = a,                            \
 199                .table          = t,                            \
 200        }
 201
 202#define DIV(_id, cname, pname, o, s, w)                         \
 203        __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, NULL)
 204
 205#define DIV_A(_id, cname, pname, o, s, w, a)                    \
 206        __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a, NULL)
 207
 208#define DIV_F(_id, cname, pname, o, s, w, f, df)                \
 209        __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL, NULL)
 210
 211#define DIV_T(_id, cname, pname, o, s, w, t)                    \
 212        __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, t)
 213
 214/**
 215 * struct samsung_gate_clock: information about gate clock
 216 * @id: platform specific id of the clock.
 217 * @dev_name: name of the device to which this clock belongs.
 218 * @name: name of this gate clock.
 219 * @parent_name: name of the parent clock.
 220 * @flags: optional flags for basic clock.
 221 * @offset: offset of the register for configuring the gate.
 222 * @bit_idx: bit index of the gate control bit-field in @reg.
 223 * @gate_flags: flags for gate-type clock.
 224 * @alias: optional clock alias name to be assigned to this clock.
 225 */
 226struct samsung_gate_clock {
 227        unsigned int            id;
 228        const char              *dev_name;
 229        const char              *name;
 230        const char              *parent_name;
 231        unsigned long           flags;
 232        unsigned long           offset;
 233        u8                      bit_idx;
 234        u8                      gate_flags;
 235        const char              *alias;
 236};
 237
 238#define __GATE(_id, dname, cname, pname, o, b, f, gf, a)        \
 239        {                                                       \
 240                .id             = _id,                          \
 241                .dev_name       = dname,                        \
 242                .name           = cname,                        \
 243                .parent_name    = pname,                        \
 244                .flags          = f,                            \
 245                .offset         = o,                            \
 246                .bit_idx        = b,                            \
 247                .gate_flags     = gf,                           \
 248                .alias          = a,                            \
 249        }
 250
 251#define GATE(_id, cname, pname, o, b, f, gf)                    \
 252        __GATE(_id, NULL, cname, pname, o, b, f, gf, NULL)
 253
 254#define GATE_A(_id, cname, pname, o, b, f, gf, a)               \
 255        __GATE(_id, NULL, cname, pname, o, b, f, gf, a)
 256
 257#define GATE_D(_id, dname, cname, pname, o, b, f, gf)           \
 258        __GATE(_id, dname, cname, pname, o, b, f, gf, NULL)
 259
 260#define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a)       \
 261        __GATE(_id, dname, cname, pname, o, b, f, gf, a)
 262
 263#define PNAME(x) static const char * const x[] __initconst
 264
 265/**
 266 * struct samsung_clk_reg_dump: register dump of clock controller registers.
 267 * @offset: clock register offset from the controller base address.
 268 * @value: the value to be register at offset.
 269 */
 270struct samsung_clk_reg_dump {
 271        u32     offset;
 272        u32     value;
 273};
 274
 275/**
 276 * struct samsung_pll_clock: information about pll clock
 277 * @id: platform specific id of the clock.
 278 * @dev_name: name of the device to which this clock belongs.
 279 * @name: name of this pll clock.
 280 * @parent_name: name of the parent clock.
 281 * @flags: optional flags for basic clock.
 282 * @con_offset: offset of the register for configuring the PLL.
 283 * @lock_offset: offset of the register for locking the PLL.
 284 * @type: Type of PLL to be registered.
 285 * @alias: optional clock alias name to be assigned to this clock.
 286 */
 287struct samsung_pll_clock {
 288        unsigned int            id;
 289        const char              *dev_name;
 290        const char              *name;
 291        const char              *parent_name;
 292        unsigned long           flags;
 293        int                     con_offset;
 294        int                     lock_offset;
 295        enum samsung_pll_type   type;
 296        const struct samsung_pll_rate_table *rate_table;
 297        const char              *alias;
 298};
 299
 300#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con,    \
 301                _rtable, _alias)                                        \
 302        {                                                               \
 303                .id             = _id,                                  \
 304                .type           = _typ,                                 \
 305                .dev_name       = _dname,                               \
 306                .name           = _name,                                \
 307                .parent_name    = _pname,                               \
 308                .flags          = CLK_GET_RATE_NOCACHE,                 \
 309                .con_offset     = _con,                                 \
 310                .lock_offset    = _lock,                                \
 311                .rate_table     = _rtable,                              \
 312                .alias          = _alias,                               \
 313        }
 314
 315#define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable)     \
 316        __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,     \
 317                _lock, _con, _rtable, _name)
 318
 319#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias, _rtable) \
 320        __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,     \
 321                _lock, _con, _rtable, _alias)
 322
 323struct samsung_clock_reg_cache {
 324        struct list_head node;
 325        void __iomem *reg_base;
 326        struct samsung_clk_reg_dump *rdump;
 327        unsigned int rd_num;
 328};
 329
 330struct samsung_cmu_info {
 331        /* list of pll clocks and respective count */
 332        const struct samsung_pll_clock *pll_clks;
 333        unsigned int nr_pll_clks;
 334        /* list of mux clocks and respective count */
 335        const struct samsung_mux_clock *mux_clks;
 336        unsigned int nr_mux_clks;
 337        /* list of div clocks and respective count */
 338        const struct samsung_div_clock *div_clks;
 339        unsigned int nr_div_clks;
 340        /* list of gate clocks and respective count */
 341        const struct samsung_gate_clock *gate_clks;
 342        unsigned int nr_gate_clks;
 343        /* list of fixed clocks and respective count */
 344        const struct samsung_fixed_rate_clock *fixed_clks;
 345        unsigned int nr_fixed_clks;
 346        /* list of fixed factor clocks and respective count */
 347        const struct samsung_fixed_factor_clock *fixed_factor_clks;
 348        unsigned int nr_fixed_factor_clks;
 349        /* total number of clocks with IDs assigned*/
 350        unsigned int nr_clk_ids;
 351
 352        /* list and number of clocks registers */
 353        const unsigned long *clk_regs;
 354        unsigned int nr_clk_regs;
 355};
 356
 357extern struct samsung_clk_provider *__init samsung_clk_init(
 358                        struct device_node *np, void __iomem *base,
 359                        unsigned long nr_clks);
 360extern void __init samsung_clk_of_add_provider(struct device_node *np,
 361                        struct samsung_clk_provider *ctx);
 362extern void __init samsung_clk_of_register_fixed_ext(
 363                        struct samsung_clk_provider *ctx,
 364                        struct samsung_fixed_rate_clock *fixed_rate_clk,
 365                        unsigned int nr_fixed_rate_clk,
 366                        const struct of_device_id *clk_matches);
 367
 368extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
 369                        struct clk_hw *clk_hw, unsigned int id);
 370
 371extern void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx,
 372                        const struct samsung_clock_alias *list,
 373                        unsigned int nr_clk);
 374extern void __init samsung_clk_register_fixed_rate(
 375                        struct samsung_clk_provider *ctx,
 376                        const struct samsung_fixed_rate_clock *clk_list,
 377                        unsigned int nr_clk);
 378extern void __init samsung_clk_register_fixed_factor(
 379                        struct samsung_clk_provider *ctx,
 380                        const struct samsung_fixed_factor_clock *list,
 381                        unsigned int nr_clk);
 382extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
 383                        const struct samsung_mux_clock *clk_list,
 384                        unsigned int nr_clk);
 385extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
 386                        const struct samsung_div_clock *clk_list,
 387                        unsigned int nr_clk);
 388extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
 389                        const struct samsung_gate_clock *clk_list,
 390                        unsigned int nr_clk);
 391extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 392                        const struct samsung_pll_clock *pll_list,
 393                        unsigned int nr_clk, void __iomem *base);
 394
 395extern struct samsung_clk_provider __init *samsung_cmu_register_one(
 396                        struct device_node *,
 397                        const struct samsung_cmu_info *);
 398
 399extern unsigned long _get_rate(const char *clk_name);
 400
 401extern void samsung_clk_sleep_init(void __iomem *reg_base,
 402                        const unsigned long *rdump,
 403                        unsigned long nr_rdump);
 404
 405extern void samsung_clk_save(void __iomem *base,
 406                        struct samsung_clk_reg_dump *rd,
 407                        unsigned int num_regs);
 408extern void samsung_clk_restore(void __iomem *base,
 409                        const struct samsung_clk_reg_dump *rd,
 410                        unsigned int num_regs);
 411extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
 412                        const unsigned long *rdump,
 413                        unsigned long nr_rdump);
 414
 415#endif /* __SAMSUNG_CLK_H */
 416