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