clk: meson8b: clean up cpu 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 meson_clk_cpu {
73         struct clk_hw hw;
74         void __iomem *base;
75         u16 reg_off;
76         struct notifier_block clk_nb;
77         const struct clk_div_table *div_table;
78 };
79
80 struct composite_conf {
81         struct parm             mux_parm;
82         struct parm             div_parm;
83         struct parm             gate_parm;
84         struct clk_div_table    *div_table;
85         u32                     *mux_table;
86         u8                      mux_flags;
87         u8                      div_flags;
88         u8                      gate_flags;
89 };
90
91 #define PNAME(x) static const char *x[]
92
93 enum clk_type {
94         CLK_COMPOSITE,
95 };
96
97 struct clk_conf {
98         u16                             reg_off;
99         enum clk_type                   clk_type;
100         unsigned int                    clk_id;
101         const char                      *clk_name;
102         const char                      **clks_parent;
103         int                             num_parents;
104         unsigned long                   flags;
105         union {
106                 const struct composite_conf             *composite;
107                 const struct clk_div_table      *div_table;
108         } conf;
109 };
110
111 #define COMPOSITE(_ro, _ci, _cn, _cp, _f, _c)                           \
112         {                                                               \
113                 .reg_off                        = (_ro),                \
114                 .clk_type                       = CLK_COMPOSITE,        \
115                 .clk_id                         = (_ci),                \
116                 .clk_name                       = (_cn),                \
117                 .clks_parent                    = (_cp),                \
118                 .num_parents                    = ARRAY_SIZE(_cp),      \
119                 .flags                          = (_f),                 \
120                 .conf.composite                 = (_c),                 \
121         }                                                               \
122
123 struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks);
124 void meson_clk_register_clks(const struct clk_conf *clk_confs,
125                              unsigned int nr_confs, void __iomem *clk_base);
126 int meson_clk_cpu_notifier_cb(struct notifier_block *nb, unsigned long event,
127                 void *data);
128
129 /* shared data */
130 extern spinlock_t clk_lock;
131
132 /* clk_ops */
133 extern const struct clk_ops meson_clk_pll_ro_ops;
134 extern const struct clk_ops meson_clk_pll_ops;
135 extern const struct clk_ops meson_clk_cpu_ops;
136
137 #endif /* __CLKC_H */