clk: meson8b: clean up fixed factor clocks
[cascardo/linux.git] / drivers / clk / meson / clkc.h
1 /*
2  * Copyright (c) 2015 Endless Mobile, Inc.
3  * Author: Carlo Caione <carlo@endlessm.com>
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #ifndef __CLKC_H
19 #define __CLKC_H
20
21 #define PMASK(width)                    GENMASK(width - 1, 0)
22 #define SETPMASK(width, shift)          GENMASK(shift + width - 1, shift)
23 #define CLRPMASK(width, shift)          (~SETPMASK(width, shift))
24
25 #define PARM_GET(width, shift, reg)                                     \
26         (((reg) & SETPMASK(width, shift)) >> (shift))
27 #define PARM_SET(width, shift, reg, val)                                \
28         (((reg) & CLRPMASK(width, shift)) | (val << (shift)))
29
30 #define MESON_PARM_APPLICABLE(p)                (!!((p)->width))
31
32 struct parm {
33         u16     reg_off;
34         u8      shift;
35         u8      width;
36 };
37
38 #define PARM(_r, _s, _w)                                               \
39 {                                                                      \
40         .reg_off        = (_r),                                        \
41         .shift          = (_s),                                        \
42         .width          = (_w),                                        \
43 }                                                                      \
44
45 struct pll_rate_table {
46         unsigned long   rate;
47         u16             m;
48         u16             n;
49         u16             od;
50 };
51 #define PLL_RATE(_r, _m, _n, _od)                                       \
52         {                                                               \
53                 .rate           = (_r),                                 \
54                 .m              = (_m),                                 \
55                 .n              = (_n),                                 \
56                 .od             = (_od),                                \
57         }                                                               \
58
59 struct meson_clk_pll {
60         struct clk_hw hw;
61         void __iomem *base;
62         struct parm m;
63         struct parm n;
64         struct parm od;
65         const struct pll_rate_table *rate_table;
66         unsigned int rate_count;
67         spinlock_t *lock;
68 };
69
70 #define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
71
72 struct composite_conf {
73         struct parm             mux_parm;
74         struct parm             div_parm;
75         struct parm             gate_parm;
76         struct clk_div_table    *div_table;
77         u32                     *mux_table;
78         u8                      mux_flags;
79         u8                      div_flags;
80         u8                      gate_flags;
81 };
82
83 #define PNAME(x) static const char *x[]
84
85 enum clk_type {
86         CLK_COMPOSITE,
87         CLK_CPU,
88 };
89
90 struct clk_conf {
91         u16                             reg_off;
92         enum clk_type                   clk_type;
93         unsigned int                    clk_id;
94         const char                      *clk_name;
95         const char                      **clks_parent;
96         int                             num_parents;
97         unsigned long                   flags;
98         union {
99                 const struct composite_conf             *composite;
100                 const struct clk_div_table      *div_table;
101         } conf;
102 };
103
104 #define CPU(_ro, _ci, _cn, _cp, _dt)                                    \
105         {                                                               \
106                 .reg_off                        = (_ro),                \
107                 .clk_type                       = CLK_CPU,              \
108                 .clk_id                         = (_ci),                \
109                 .clk_name                       = (_cn),                \
110                 .clks_parent                    = (_cp),                \
111                 .num_parents                    = ARRAY_SIZE(_cp),      \
112                 .conf.div_table                 = (_dt),                \
113         }                                                               \
114
115 #define COMPOSITE(_ro, _ci, _cn, _cp, _f, _c)                           \
116         {                                                               \
117                 .reg_off                        = (_ro),                \
118                 .clk_type                       = CLK_COMPOSITE,        \
119                 .clk_id                         = (_ci),                \
120                 .clk_name                       = (_cn),                \
121                 .clks_parent                    = (_cp),                \
122                 .num_parents                    = ARRAY_SIZE(_cp),      \
123                 .flags                          = (_f),                 \
124                 .conf.composite                 = (_c),                 \
125         }                                                               \
126
127 struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks);
128 void meson_clk_register_clks(const struct clk_conf *clk_confs,
129                              unsigned int nr_confs, void __iomem *clk_base);
130 struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf,
131                                    void __iomem *reg_base, spinlock_t *lock);
132
133 /* shared data */
134 extern spinlock_t clk_lock;
135
136 /* clk_ops */
137 extern const struct clk_ops meson_clk_pll_ro_ops;
138 extern const struct clk_ops meson_clk_pll_ops;
139
140 #endif /* __CLKC_H */