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