linux/drivers/clk/zte/clk.h
<<
>>
Prefs
   1/*
   2 * Copyright 2015 Linaro Ltd.
   3 * Copyright (C) 2014 ZTE Corporation.
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 as
   7 * published by the Free Software Foundation.
   8 */
   9
  10#ifndef __ZTE_CLK_H
  11#define __ZTE_CLK_H
  12#include <linux/clk-provider.h>
  13#include <linux/spinlock.h>
  14
  15#define PNAME(x) static const char *x[]
  16
  17#define CLK_HW_INIT(_name, _parent, _ops, _flags)                       \
  18        &(struct clk_init_data) {                                       \
  19                .flags          = _flags,                               \
  20                .name           = _name,                                \
  21                .parent_names   = (const char *[]) { _parent },         \
  22                .num_parents    = 1,                                    \
  23                .ops            = _ops,                                 \
  24        }
  25
  26#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags)              \
  27        &(struct clk_init_data) {                                       \
  28                .flags          = _flags,                               \
  29                .name           = _name,                                \
  30                .parent_names   = _parents,                             \
  31                .num_parents    = ARRAY_SIZE(_parents),                 \
  32                .ops            = _ops,                                 \
  33        }
  34
  35struct zx_pll_config {
  36        unsigned long rate;
  37        u32 cfg0;
  38        u32 cfg1;
  39};
  40
  41struct clk_zx_pll {
  42        struct clk_hw hw;
  43        void __iomem *reg_base;
  44        const struct zx_pll_config *lookup_table; /* order by rate asc */
  45        int count;
  46        spinlock_t *lock;
  47        u8 pd_bit;              /* power down bit */
  48        u8 lock_bit;            /* pll lock flag bit */
  49};
  50
  51#define PLL_RATE(_rate, _cfg0, _cfg1)   \
  52{                                       \
  53        .rate = _rate,                  \
  54        .cfg0 = _cfg0,                  \
  55        .cfg1 = _cfg1,                  \
  56}
  57
  58#define ZX_PLL(_name, _parent, _reg, _table, _pd, _lock)                \
  59{                                                                       \
  60        .reg_base       = (void __iomem *) _reg,                        \
  61        .lookup_table   = _table,                                       \
  62        .count          = ARRAY_SIZE(_table),                           \
  63        .pd_bit         = _pd,                                          \
  64        .lock_bit       = _lock,                                        \
  65        .hw.init         = CLK_HW_INIT(_name, _parent, &zx_pll_ops,     \
  66                                CLK_GET_RATE_NOCACHE),                  \
  67}
  68
  69/*
  70 * The pd_bit is not available on ZX296718, so let's pass something
  71 * bigger than 31, e.g. 0xff, to indicate that.
  72 */
  73#define ZX296718_PLL(_name, _parent, _reg, _table)                      \
  74ZX_PLL(_name, _parent, _reg, _table, 0xff, 30)
  75
  76struct zx_clk_gate {
  77        struct clk_gate gate;
  78        u16             id;
  79};
  80
  81#define GATE(_id, _name, _parent, _reg, _bit, _flag, _gflags)           \
  82{                                                                       \
  83        .gate = {                                                       \
  84                .reg = (void __iomem *) _reg,                           \
  85                .bit_idx = (_bit),                                      \
  86                .flags = _gflags,                                       \
  87                .lock = &clk_lock,                                      \
  88                .hw.init = CLK_HW_INIT(_name,                           \
  89                                        _parent,                        \
  90                                        &clk_gate_ops,                  \
  91                                        _flag | CLK_IGNORE_UNUSED),     \
  92        },                                                              \
  93        .id     = _id,                                                  \
  94}
  95
  96struct zx_clk_fixed_factor {
  97        struct clk_fixed_factor factor;
  98        u16     id;
  99};
 100
 101#define FFACTOR(_id, _name, _parent, _mult, _div, _flag)                \
 102{                                                                       \
 103        .factor = {                                                     \
 104                .div            = _div,                                 \
 105                .mult           = _mult,                                \
 106                .hw.init        = CLK_HW_INIT(_name,                    \
 107                                              _parent,                  \
 108                                              &clk_fixed_factor_ops,    \
 109                                              _flag),                   \
 110        },                                                              \
 111        .id = _id,                                                      \
 112}
 113
 114struct zx_clk_mux {
 115        struct clk_mux mux;
 116        u16     id;
 117};
 118
 119#define MUX_F(_id, _name, _parent, _reg, _shift, _width, _flag, _mflag) \
 120{                                                                       \
 121        .mux = {                                                        \
 122                .reg            = (void __iomem *) _reg,                \
 123                .mask           = BIT(_width) - 1,                      \
 124                .shift          = _shift,                               \
 125                .flags          = _mflag,                               \
 126                .lock           = &clk_lock,                            \
 127                .hw.init        = CLK_HW_INIT_PARENTS(_name,            \
 128                                                      _parent,          \
 129                                                      &clk_mux_ops,     \
 130                                                      _flag),           \
 131        },                                                              \
 132        .id = _id,                                                      \
 133}
 134
 135#define MUX(_id, _name, _parent, _reg, _shift, _width)                  \
 136MUX_F(_id, _name, _parent, _reg, _shift, _width, 0, 0)
 137
 138struct zx_clk_div {
 139        struct clk_divider div;
 140        u16     id;
 141};
 142
 143#define DIV_T(_id, _name, _parent, _reg, _shift, _width, _flag, _table) \
 144{                                                                       \
 145        .div = {                                                        \
 146                .reg            = (void __iomem *) _reg,                \
 147                .shift          = _shift,                               \
 148                .width          = _width,                               \
 149                .flags          = 0,                                    \
 150                .table          = _table,                               \
 151                .lock           = &clk_lock,                            \
 152                .hw.init        = CLK_HW_INIT(_name,                    \
 153                                              _parent,                  \
 154                                              &clk_divider_ops,         \
 155                                              _flag),                   \
 156        },                                                              \
 157        .id = _id,                                                      \
 158}
 159
 160struct clk_zx_audio_divider {
 161        struct clk_hw                           hw;
 162        void __iomem                            *reg_base;
 163        unsigned int                            rate_count;
 164        spinlock_t                              *lock;
 165        u16                                     id;
 166};
 167
 168#define AUDIO_DIV(_id, _name, _parent, _reg)                            \
 169{                                                                       \
 170        .reg_base       = (void __iomem *) _reg,                        \
 171        .lock           = &clk_lock,                                    \
 172        .hw.init        = CLK_HW_INIT(_name,                            \
 173                                      _parent,                          \
 174                                      &zx_audio_div_ops,                \
 175                                      0),                               \
 176        .id = _id,                                                      \
 177}
 178
 179struct clk *clk_register_zx_pll(const char *name, const char *parent_name,
 180        unsigned long flags, void __iomem *reg_base,
 181        const struct zx_pll_config *lookup_table, int count, spinlock_t *lock);
 182
 183struct clk_zx_audio {
 184        struct clk_hw hw;
 185        void __iomem *reg_base;
 186};
 187
 188struct clk *clk_register_zx_audio(const char *name,
 189                                  const char * const parent_name,
 190                                  unsigned long flags, void __iomem *reg_base);
 191
 192extern const struct clk_ops zx_pll_ops;
 193extern const struct clk_ops zx_audio_div_ops;
 194
 195#endif
 196