linux/drivers/clk/mediatek/clk-mtk.h
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2014 MediaTek Inc.
   3 * Author: James Liao <jamesjj.liao@mediatek.com>
   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 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 */
  14
  15#ifndef __DRV_CLK_MTK_H
  16#define __DRV_CLK_MTK_H
  17
  18#include <linux/regmap.h>
  19#include <linux/bitops.h>
  20#include <linux/clk-provider.h>
  21
  22struct clk;
  23struct clk_onecell_data;
  24
  25#define MAX_MUX_GATE_BIT        31
  26#define INVALID_MUX_GATE_BIT    (MAX_MUX_GATE_BIT + 1)
  27
  28#define MHZ (1000 * 1000)
  29
  30struct mtk_fixed_clk {
  31        int id;
  32        const char *name;
  33        const char *parent;
  34        unsigned long rate;
  35};
  36
  37#define FIXED_CLK(_id, _name, _parent, _rate) {         \
  38                .id = _id,                              \
  39                .name = _name,                          \
  40                .parent = _parent,                      \
  41                .rate = _rate,                          \
  42        }
  43
  44void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
  45                int num, struct clk_onecell_data *clk_data);
  46
  47struct mtk_fixed_factor {
  48        int id;
  49        const char *name;
  50        const char *parent_name;
  51        int mult;
  52        int div;
  53};
  54
  55#define FACTOR(_id, _name, _parent, _mult, _div) {      \
  56                .id = _id,                              \
  57                .name = _name,                          \
  58                .parent_name = _parent,                 \
  59                .mult = _mult,                          \
  60                .div = _div,                            \
  61        }
  62
  63void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
  64                int num, struct clk_onecell_data *clk_data);
  65
  66struct mtk_composite {
  67        int id;
  68        const char *name;
  69        const char * const *parent_names;
  70        const char *parent;
  71        unsigned flags;
  72
  73        uint32_t mux_reg;
  74        uint32_t divider_reg;
  75        uint32_t gate_reg;
  76
  77        signed char mux_shift;
  78        signed char mux_width;
  79        signed char gate_shift;
  80
  81        signed char divider_shift;
  82        signed char divider_width;
  83
  84        signed char num_parents;
  85};
  86
  87/*
  88 * In case the rate change propagation to parent clocks is undesirable,
  89 * this macro allows to specify the clock flags manually.
  90 */
  91#define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width,      \
  92                        _gate, _flags) {                                \
  93                .id = _id,                                              \
  94                .name = _name,                                          \
  95                .mux_reg = _reg,                                        \
  96                .mux_shift = _shift,                                    \
  97                .mux_width = _width,                                    \
  98                .gate_reg = _reg,                                       \
  99                .gate_shift = _gate,                                    \
 100                .divider_shift = -1,                                    \
 101                .parent_names = _parents,                               \
 102                .num_parents = ARRAY_SIZE(_parents),                    \
 103                .flags = _flags,                                        \
 104        }
 105
 106/*
 107 * Unless necessary, all MUX_GATE clocks propagate rate changes to their
 108 * parent clock by default.
 109 */
 110#define MUX_GATE(_id, _name, _parents, _reg, _shift, _width, _gate)     \
 111        MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width,      \
 112                _gate, CLK_SET_RATE_PARENT)
 113
 114#define MUX(_id, _name, _parents, _reg, _shift, _width) {               \
 115                .id = _id,                                              \
 116                .name = _name,                                          \
 117                .mux_reg = _reg,                                        \
 118                .mux_shift = _shift,                                    \
 119                .mux_width = _width,                                    \
 120                .gate_shift = -1,                                       \
 121                .divider_shift = -1,                                    \
 122                .parent_names = _parents,                               \
 123                .num_parents = ARRAY_SIZE(_parents),                    \
 124                .flags = CLK_SET_RATE_PARENT,                           \
 125        }
 126
 127#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, \
 128                                        _div_width, _div_shift) {       \
 129                .id = _id,                                              \
 130                .parent = _parent,                                      \
 131                .name = _name,                                          \
 132                .divider_reg = _div_reg,                                \
 133                .divider_shift = _div_shift,                            \
 134                .divider_width = _div_width,                            \
 135                .gate_reg = _gate_reg,                                  \
 136                .gate_shift = _gate_shift,                              \
 137                .mux_shift = -1,                                        \
 138                .flags = 0,                                             \
 139        }
 140
 141struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
 142                void __iomem *base, spinlock_t *lock);
 143
 144void mtk_clk_register_composites(const struct mtk_composite *mcs,
 145                int num, void __iomem *base, spinlock_t *lock,
 146                struct clk_onecell_data *clk_data);
 147
 148struct mtk_gate_regs {
 149        u32 sta_ofs;
 150        u32 clr_ofs;
 151        u32 set_ofs;
 152};
 153
 154struct mtk_gate {
 155        int id;
 156        const char *name;
 157        const char *parent_name;
 158        const struct mtk_gate_regs *regs;
 159        int shift;
 160        const struct clk_ops *ops;
 161};
 162
 163int mtk_clk_register_gates(struct device_node *node,
 164                        const struct mtk_gate *clks, int num,
 165                        struct clk_onecell_data *clk_data);
 166
 167struct mtk_clk_divider {
 168        int id;
 169        const char *name;
 170        const char *parent_name;
 171        unsigned long flags;
 172
 173        u32 div_reg;
 174        unsigned char div_shift;
 175        unsigned char div_width;
 176        unsigned char clk_divider_flags;
 177        const struct clk_div_table *clk_div_table;
 178};
 179
 180#define DIV_ADJ(_id, _name, _parent, _reg, _shift, _width) {    \
 181                .id = _id,                                      \
 182                .name = _name,                                  \
 183                .parent_name = _parent,                         \
 184                .div_reg = _reg,                                \
 185                .div_shift = _shift,                            \
 186                .div_width = _width,                            \
 187}
 188
 189void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
 190                        int num, void __iomem *base, spinlock_t *lock,
 191                                struct clk_onecell_data *clk_data);
 192
 193struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num);
 194
 195#define HAVE_RST_BAR    BIT(0)
 196#define PLL_AO          BIT(1)
 197
 198struct mtk_pll_div_table {
 199        u32 div;
 200        unsigned long freq;
 201};
 202
 203struct mtk_pll_data {
 204        int id;
 205        const char *name;
 206        uint32_t reg;
 207        uint32_t pwr_reg;
 208        uint32_t en_mask;
 209        uint32_t pd_reg;
 210        uint32_t tuner_reg;
 211        uint32_t tuner_en_reg;
 212        uint8_t tuner_en_bit;
 213        int pd_shift;
 214        unsigned int flags;
 215        const struct clk_ops *ops;
 216        u32 rst_bar_mask;
 217        unsigned long fmax;
 218        int pcwbits;
 219        uint32_t pcw_reg;
 220        int pcw_shift;
 221        const struct mtk_pll_div_table *div_table;
 222        const char *parent_name;
 223};
 224
 225void mtk_clk_register_plls(struct device_node *node,
 226                const struct mtk_pll_data *plls, int num_plls,
 227                struct clk_onecell_data *clk_data);
 228
 229struct clk *mtk_clk_register_ref2usb_tx(const char *name,
 230                        const char *parent_name, void __iomem *reg);
 231
 232void mtk_register_reset_controller(struct device_node *np,
 233                        unsigned int num_regs, int regofs);
 234
 235#endif /* __DRV_CLK_MTK_H */
 236