GNU Linux-libre 4.9.283-gnu1
[releases.git] / drivers / clk / sunxi-ng / ccu_common.h
1 /*
2  * Copyright (c) 2016 Maxime Ripard. All rights reserved.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14 #ifndef _COMMON_H_
15 #define _COMMON_H_
16
17 #include <linux/compiler.h>
18 #include <linux/clk-provider.h>
19
20 #define CCU_FEATURE_FRACTIONAL          BIT(0)
21 #define CCU_FEATURE_VARIABLE_PREDIV     BIT(1)
22 #define CCU_FEATURE_FIXED_PREDIV        BIT(2)
23 #define CCU_FEATURE_FIXED_POSTDIV       BIT(3)
24
25 struct device_node;
26
27 #define CLK_HW_INIT(_name, _parent, _ops, _flags)                       \
28         &(struct clk_init_data) {                                       \
29                 .flags          = _flags,                               \
30                 .name           = _name,                                \
31                 .parent_names   = (const char *[]) { _parent },         \
32                 .num_parents    = 1,                                    \
33                 .ops            = _ops,                                 \
34         }
35
36 #define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags)              \
37         &(struct clk_init_data) {                                       \
38                 .flags          = _flags,                               \
39                 .name           = _name,                                \
40                 .parent_names   = _parents,                             \
41                 .num_parents    = ARRAY_SIZE(_parents),                 \
42                 .ops            = _ops,                                 \
43         }
44
45 #define CLK_FIXED_FACTOR(_struct, _name, _parent,                       \
46                         _div, _mult, _flags)                            \
47         struct clk_fixed_factor _struct = {                             \
48                 .div            = _div,                                 \
49                 .mult           = _mult,                                \
50                 .hw.init        = CLK_HW_INIT(_name,                    \
51                                               _parent,                  \
52                                               &clk_fixed_factor_ops,    \
53                                               _flags),                  \
54         }
55
56 struct ccu_common {
57         void __iomem    *base;
58         u16             reg;
59
60         unsigned long   features;
61         spinlock_t      *lock;
62         struct clk_hw   hw;
63 };
64
65 static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw)
66 {
67         return container_of(hw, struct ccu_common, hw);
68 }
69
70 struct sunxi_ccu_desc {
71         struct ccu_common               **ccu_clks;
72         unsigned long                   num_ccu_clks;
73
74         struct clk_hw_onecell_data      *hw_clks;
75
76         struct ccu_reset_map            *resets;
77         unsigned long                   num_resets;
78 };
79
80 void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock);
81
82 int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
83                     const struct sunxi_ccu_desc *desc);
84
85 #endif /* _COMMON_H_ */