1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
|
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ARCH_ARM_MACH_MSM_CLOCK_LOCAL_2_H
#define __ARCH_ARM_MACH_MSM_CLOCK_LOCAL_2_H
#include <linux/spinlock.h>
#include <linux/clk/msm-clk-provider.h>
#include <linux/clk/msm-clk.h>
/*
* Generic frequency-definition structs and macros
*/
/**
* @freq_hz: output rate
* @src_freq: source freq for dynamic pll. For fixed plls, set to 0.
* @src_clk: source clock for freq_hz
* @m_val: M value corresponding to freq_hz
* @n_val: N value corresponding to freq_hz
* @d_val: D value corresponding to freq_hz
* @div_src_val: Pre divider value and source selection mux index for freq_hz
* @sys_vdd: Voltage level required for freq_hz
*/
struct clk_freq_tbl {
unsigned long freq_hz;
unsigned long src_freq;
struct clk *src_clk;
u32 m_val;
u32 n_val;
u32 d_val;
u32 div_src_val;
const unsigned sys_vdd;
};
#define FREQ_END (ULONG_MAX-1)
#define F_END { .freq_hz = FREQ_END }
#define FIXED_CLK_SRC 0
/*
* Generic clock-definition struct and macros
*/
/**
* struct rcg_clk - root clock generator
* @cmd_rcgr_reg: command register
* @set_rate: function to set frequency
* @freq_tbl: frequency table for this RCG
* @current_freq: current RCG frequency
* @c: generic clock data
* @non_local_children: set if RCG has at least one branch owned by a diff EE
* @non_local_control_timeout: configurable RCG timeout needed when all RCG
* children can be controlled by an entity outside of
HLOS.
* @force_enable_rcgr: set if RCG needs to be force enabled/disabled during
* power sequence
* @base: pointer to base address of ioremapped registers.
*/
struct rcg_clk {
u32 cmd_rcgr_reg;
void (*set_rate)(struct rcg_clk *, struct clk_freq_tbl *);
struct clk_freq_tbl *freq_tbl;
struct clk_freq_tbl *current_freq;
struct clk c;
bool non_local_children;
int non_local_control_timeout;
bool force_enable_rcgr;
void *const __iomem *base;
};
static inline struct rcg_clk *to_rcg_clk(struct clk *clk)
{
return container_of(clk, struct rcg_clk, c);
}
extern struct clk_freq_tbl rcg_dummy_freq;
/**
* struct branch_clk - branch clock
* @set_rate: Set the frequency of this branch clock.
* @c: clk
* @cbcr_reg: branch control register
* @bcr_reg: block reset register
* @has_sibling: true if other branches are derived from this branch's source
* @cur_div: current branch divider value
* @max_div: maximum branch divider value (if zero, no divider exists)
* @halt_check: halt checking type
* @toggle_memory: toggle memory during enable/disable if true
* @no_halt_check_on_disable: When set, do not check status bit during
* clk_disable().
* @check_enable_bit: Check the enable bit to determine clock status
during handoff.
* @aggr_sibling_rates: Set if there are multiple branch clocks with rate
setting capability on the common RCG.
* @is_prepared: Set if clock's prepare count is greater than 0.
* @base: pointer to base address of ioremapped registers.
*/
struct branch_clk {
void (*set_rate)(struct branch_clk *, struct clk_freq_tbl *);
struct clk c;
u32 cbcr_reg;
u32 bcr_reg;
int has_sibling;
u32 cur_div;
u32 max_div;
const u32 halt_check;
bool toggle_memory;
bool no_halt_check_on_disable;
bool check_enable_bit;
bool aggr_sibling_rates;
bool is_prepared;
void *const __iomem *base;
};
static inline struct branch_clk *to_branch_clk(struct clk *clk)
{
return container_of(clk, struct branch_clk, c);
}
/**
* struct hw_ctl_clk - Clock structure to enable/disable dynamic clock gating
* @c: clk
* @cbcr_reg: branch control register
* @base: pointer to base address of ioremapped registers.
*/
struct hw_ctl_clk {
struct clk c;
u32 cbcr_reg;
void __iomem *const *base;
};
static inline struct hw_ctl_clk *to_hw_ctl_clk(struct clk *clk)
{
return container_of(clk, struct hw_ctl_clk, c);
}
/**
* struct local_vote_clk - Voteable branch clock
* @c: clk
* @cbcr_reg: branch control register
* @vote_reg: voting register
* @en_mask: enable mask
* @halt_check: halt checking type
* @base: pointer to base address of ioremapped registers.
* An on/off switch with a rate derived from the parent.
*/
struct local_vote_clk {
struct clk c;
u32 cbcr_reg;
u32 vote_reg;
u32 bcr_reg;
u32 en_mask;
const u32 halt_check;
void * __iomem *base;
};
static inline struct local_vote_clk *to_local_vote_clk(struct clk *clk)
{
return container_of(clk, struct local_vote_clk, c);
}
/**
* struct reset_clk - Reset clock
* @c: clk
* @reset_reg: block reset register
* @base: pointer to base address of ioremapped registers.
*/
struct reset_clk {
struct clk c;
u32 reset_reg;
void *__iomem *base;
};
static inline struct reset_clk *to_reset_clk(struct clk *clk)
{
return container_of(clk, struct reset_clk, c);
}
/**
* struct measure_clk - for rate measurement debug use
* @sample_ticks: sample period in reference clock ticks
* @multiplier: measurement scale-up factor
* @divider: measurement scale-down factor
* @c: clk
*/
struct measure_clk {
u64 sample_ticks;
u32 multiplier;
u32 divider;
struct clk c;
};
struct measure_clk_data {
struct clk *cxo;
u32 plltest_reg;
u32 plltest_val;
u32 xo_div4_cbcr;
u32 ctl_reg;
u32 status_reg;
void *const __iomem *base;
};
static inline struct measure_clk *to_measure_clk(struct clk *clk)
{
return container_of(clk, struct measure_clk, c);
}
/**
* struct gate_clk
* @c: clk
* @en_mask: ORed with @en_reg to enable gate clk
* @en_reg: register used to enable/disable gate clk
* @base: pointer to base address of ioremapped registers
*/
struct gate_clk {
struct clk c;
u32 en_mask;
u32 en_reg;
unsigned int delay_us;
void *const __iomem *base;
};
static inline struct gate_clk *to_gate_clk(struct clk *clk)
{
return container_of(clk, struct gate_clk, c);
}
/*
* Generic set-rate implementations
*/
void set_rate_mnd(struct rcg_clk *clk, struct clk_freq_tbl *nf);
void set_rate_hid(struct rcg_clk *clk, struct clk_freq_tbl *nf);
/*
* Variables from the clock-local driver
*/
extern spinlock_t local_clock_reg_lock;
extern struct clk_ops clk_ops_empty;
extern struct clk_ops clk_ops_rcg;
extern struct clk_ops clk_ops_rcg_mnd;
extern struct clk_ops clk_ops_branch;
extern struct clk_ops clk_ops_branch_hw_ctl;
extern struct clk_ops clk_ops_vote;
extern struct clk_ops clk_ops_rcg_hdmi;
extern struct clk_ops clk_ops_rcg_edp;
extern struct clk_ops clk_ops_rcg_dp;
extern struct clk_ops clk_ops_byte;
extern struct clk_ops clk_ops_pixel;
extern struct clk_ops clk_ops_byte_multiparent;
extern struct clk_ops clk_ops_pixel_multiparent;
extern struct clk_ops clk_ops_edppixel;
extern struct clk_ops clk_ops_gate;
extern struct clk_ops clk_ops_rst;
extern struct clk_mux_ops mux_reg_ops;
extern struct mux_div_ops rcg_mux_div_ops;
extern struct clk_div_ops postdiv_reg_ops;
enum handoff pixel_rcg_handoff(struct clk *clk);
enum handoff byte_rcg_handoff(struct clk *clk);
unsigned long measure_get_rate(struct clk *c);
/*
* Clock definition macros
*/
#define DEFINE_CLK_MEASURE(name) \
struct clk name = { \
.ops = &clk_ops_empty, \
.dbg_name = #name, \
CLK_INIT(name), \
}; \
#endif /* __ARCH_ARM_MACH_MSM_CLOCK_LOCAL_2_H */
|