blob: d6fdd7a789aa746a72f939fb51c552004941fd37 [file] [log] [blame]
Maxime Ripard1d80c142016-06-29 21:05:23 +02001/*
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)
Maxime Ripard7c09b852017-01-19 22:49:26 +010024#define CCU_FEATURE_ALL_PREDIV BIT(4)
Chen-Yu Tsai3de64bf2017-01-28 20:22:33 +080025#define CCU_FEATURE_LOCK_REG BIT(5)
Maxime Ripard1d80c142016-06-29 21:05:23 +020026
27struct device_node;
28
29#define CLK_HW_INIT(_name, _parent, _ops, _flags) \
30 &(struct clk_init_data) { \
31 .flags = _flags, \
32 .name = _name, \
33 .parent_names = (const char *[]) { _parent }, \
34 .num_parents = 1, \
35 .ops = _ops, \
36 }
37
38#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \
39 &(struct clk_init_data) { \
40 .flags = _flags, \
41 .name = _name, \
42 .parent_names = _parents, \
43 .num_parents = ARRAY_SIZE(_parents), \
44 .ops = _ops, \
45 }
46
47#define CLK_FIXED_FACTOR(_struct, _name, _parent, \
48 _div, _mult, _flags) \
49 struct clk_fixed_factor _struct = { \
50 .div = _div, \
51 .mult = _mult, \
52 .hw.init = CLK_HW_INIT(_name, \
53 _parent, \
54 &clk_fixed_factor_ops, \
55 _flags), \
56 }
57
58struct ccu_common {
59 void __iomem *base;
60 u16 reg;
Chen-Yu Tsai3de64bf2017-01-28 20:22:33 +080061 u16 lock_reg;
Maxime Ripard7c09b852017-01-19 22:49:26 +010062 u32 prediv;
Maxime Ripard1d80c142016-06-29 21:05:23 +020063
64 unsigned long features;
65 spinlock_t *lock;
66 struct clk_hw hw;
67};
68
69static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw)
70{
71 return container_of(hw, struct ccu_common, hw);
72}
73
74struct sunxi_ccu_desc {
75 struct ccu_common **ccu_clks;
76 unsigned long num_ccu_clks;
77
78 struct clk_hw_onecell_data *hw_clks;
79
80 struct ccu_reset_map *resets;
81 unsigned long num_resets;
82};
83
84void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock);
85
Chen-Yu Tsai02ae2bc2017-04-13 10:13:52 +080086struct ccu_pll_nb {
87 struct notifier_block clk_nb;
88 struct ccu_common *common;
89
90 u32 enable;
91 u32 lock;
92};
93
94#define to_ccu_pll_nb(_nb) container_of(_nb, struct ccu_pll_nb, clk_nb)
95
96int ccu_pll_notifier_register(struct ccu_pll_nb *pll_nb);
97
Maxime Ripard1d80c142016-06-29 21:05:23 +020098int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
99 const struct sunxi_ccu_desc *desc);
100
101#endif /* _COMMON_H_ */