Merge branches 'for-next/kvm-build-fix', 'for-next/va-refactor', 'for-next/lto',...
[linux-2.6-microblaze.git] / drivers / clk / baikal-t1 / ccu-div.h
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
4  *
5  * Baikal-T1 CCU Dividers interface driver
6  */
7 #ifndef __CLK_BT1_CCU_DIV_H__
8 #define __CLK_BT1_CCU_DIV_H__
9
10 #include <linux/clk-provider.h>
11 #include <linux/spinlock.h>
12 #include <linux/regmap.h>
13 #include <linux/bits.h>
14 #include <linux/of.h>
15
16 /*
17  * CCU Divider private flags
18  * @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1.
19  *                    It can be 0 though, which is functionally the same.
20  * @CCU_DIV_SKIP_ONE_TO_THREE: For some reason divider can't be within [1,3].
21  *                             It can be either 0 or greater than 3.
22  * @CCU_DIV_LOCK_SHIFTED: Find lock-bit at non-standard position.
23  * @CCU_DIV_RESET_DOMAIN: Provide reset clock domain method.
24  */
25 #define CCU_DIV_SKIP_ONE                BIT(1)
26 #define CCU_DIV_SKIP_ONE_TO_THREE       BIT(2)
27 #define CCU_DIV_LOCK_SHIFTED            BIT(3)
28 #define CCU_DIV_RESET_DOMAIN            BIT(4)
29
30 /*
31  * enum ccu_div_type - CCU Divider types
32  * @CCU_DIV_VAR: Clocks gate with variable divider.
33  * @CCU_DIV_GATE: Clocks gate with fixed divider.
34  * @CCU_DIV_FIXED: Ungateable clock with fixed divider.
35  */
36 enum ccu_div_type {
37         CCU_DIV_VAR,
38         CCU_DIV_GATE,
39         CCU_DIV_FIXED
40 };
41
42 /*
43  * struct ccu_div_init_data - CCU Divider initialization data
44  * @id: Clocks private identifier.
45  * @name: Clocks name.
46  * @parent_name: Parent clocks name in a fw node.
47  * @base: Divider register base address with respect to the sys_regs base.
48  * @sys_regs: Baikal-T1 System Controller registers map.
49  * @np: Pointer to the node describing the CCU Dividers.
50  * @type: CCU divider type (variable, fixed with and without gate).
51  * @width: Divider width if it's variable.
52  * @divider: Divider fixed value.
53  * @flags: CCU Divider clock flags.
54  * @features: CCU Divider private features.
55  */
56 struct ccu_div_init_data {
57         unsigned int id;
58         const char *name;
59         const char *parent_name;
60         unsigned int base;
61         struct regmap *sys_regs;
62         struct device_node *np;
63         enum ccu_div_type type;
64         union {
65                 unsigned int width;
66                 unsigned int divider;
67         };
68         unsigned long flags;
69         unsigned long features;
70 };
71
72 /*
73  * struct ccu_div - CCU Divider descriptor
74  * @hw: clk_hw of the divider.
75  * @id: Clock private identifier.
76  * @reg_ctl: Divider control register base address.
77  * @sys_regs: Baikal-T1 System Controller registers map.
78  * @lock: Divider state change spin-lock.
79  * @mask: Divider field mask.
80  * @divider: Divider fixed value.
81  * @flags: Divider clock flags.
82  * @features: CCU Divider private features.
83  */
84 struct ccu_div {
85         struct clk_hw hw;
86         unsigned int id;
87         unsigned int reg_ctl;
88         struct regmap *sys_regs;
89         spinlock_t lock;
90         union {
91                 u32 mask;
92                 unsigned int divider;
93         };
94         unsigned long flags;
95         unsigned long features;
96 };
97 #define to_ccu_div(_hw) container_of(_hw, struct ccu_div, hw)
98
99 static inline struct clk_hw *ccu_div_get_clk_hw(struct ccu_div *div)
100 {
101         return div ? &div->hw : NULL;
102 }
103
104 struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *init);
105
106 void ccu_div_hw_unregister(struct ccu_div *div);
107
108 int ccu_div_reset_domain(struct ccu_div *div);
109
110 #endif /* __CLK_BT1_CCU_DIV_H__ */