Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/clk/baikal-t1/ccu-div.h
26282 views
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 clock IDs
18
* @CCU_SYS_SATA_CLK: CCU SATA internal clock
19
* @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock
20
*/
21
#define CCU_SYS_SATA_CLK -1
22
#define CCU_SYS_XGMAC_CLK -2
23
24
/*
25
* CCU Divider private flags
26
* @CCU_DIV_BASIC: Basic divider clock required by the kernel as early as
27
* possible.
28
* @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1.
29
* It can be 0 though, which is functionally the same.
30
* @CCU_DIV_SKIP_ONE_TO_THREE: For some reason divider can't be within [1,3].
31
* It can be either 0 or greater than 3.
32
* @CCU_DIV_LOCK_SHIFTED: Find lock-bit at non-standard position.
33
* @CCU_DIV_RESET_DOMAIN: There is a clock domain reset handle.
34
*/
35
#define CCU_DIV_BASIC BIT(0)
36
#define CCU_DIV_SKIP_ONE BIT(1)
37
#define CCU_DIV_SKIP_ONE_TO_THREE BIT(2)
38
#define CCU_DIV_LOCK_SHIFTED BIT(3)
39
#define CCU_DIV_RESET_DOMAIN BIT(4)
40
41
/*
42
* enum ccu_div_type - CCU Divider types
43
* @CCU_DIV_VAR: Clocks gate with variable divider.
44
* @CCU_DIV_GATE: Clocks gate with fixed divider.
45
* @CCU_DIV_BUF: Clock gate with no divider.
46
* @CCU_DIV_FIXED: Ungateable clock with fixed divider.
47
*/
48
enum ccu_div_type {
49
CCU_DIV_VAR,
50
CCU_DIV_GATE,
51
CCU_DIV_BUF,
52
CCU_DIV_FIXED
53
};
54
55
/*
56
* struct ccu_div_init_data - CCU Divider initialization data
57
* @id: Clocks private identifier.
58
* @name: Clocks name.
59
* @parent_name: Parent clocks name in a fw node.
60
* @base: Divider register base address with respect to the sys_regs base.
61
* @sys_regs: Baikal-T1 System Controller registers map.
62
* @np: Pointer to the node describing the CCU Dividers.
63
* @type: CCU divider type (variable, fixed with and without gate).
64
* @width: Divider width if it's variable.
65
* @divider: Divider fixed value.
66
* @flags: CCU Divider clock flags.
67
* @features: CCU Divider private features.
68
*/
69
struct ccu_div_init_data {
70
unsigned int id;
71
const char *name;
72
const char *parent_name;
73
unsigned int base;
74
struct regmap *sys_regs;
75
struct device_node *np;
76
enum ccu_div_type type;
77
union {
78
unsigned int width;
79
unsigned int divider;
80
};
81
unsigned long flags;
82
unsigned long features;
83
};
84
85
/*
86
* struct ccu_div - CCU Divider descriptor
87
* @hw: clk_hw of the divider.
88
* @id: Clock private identifier.
89
* @reg_ctl: Divider control register base address.
90
* @sys_regs: Baikal-T1 System Controller registers map.
91
* @lock: Divider state change spin-lock.
92
* @mask: Divider field mask.
93
* @divider: Divider fixed value.
94
* @flags: Divider clock flags.
95
* @features: CCU Divider private features.
96
*/
97
struct ccu_div {
98
struct clk_hw hw;
99
unsigned int id;
100
unsigned int reg_ctl;
101
struct regmap *sys_regs;
102
spinlock_t lock;
103
union {
104
u32 mask;
105
unsigned int divider;
106
};
107
unsigned long flags;
108
unsigned long features;
109
};
110
#define to_ccu_div(_hw) container_of(_hw, struct ccu_div, hw)
111
112
static inline struct clk_hw *ccu_div_get_clk_hw(struct ccu_div *div)
113
{
114
return div ? &div->hw : NULL;
115
}
116
117
struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *init);
118
119
void ccu_div_hw_unregister(struct ccu_div *div);
120
121
#endif /* __CLK_BT1_CCU_DIV_H__ */
122
123