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
|
/* Copyright (c) 2012, 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 <mach/clk-provider.h>
#include <mach/clk.h>
/*
* Generic frequency-definition structs and macros
*/
/**
* @freq_hz: output rate
* @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;
struct clk *src_clk;
const u32 m_val;
const u32 n_val;
const u32 d_val;
u32 div_src_val;
const unsigned sys_vdd;
};
#define FREQ_END (UINT_MAX-1)
#define F_END { .freq_hz = FREQ_END }
/*
* 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
* @base: pointer to base address of ioremapped registers.
*/
struct rcg_clk {
const 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;
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 fixed_clk - fixed rate clock (used for crystal oscillators)
* @rate: output rate
* @c: clk
*/
struct fixed_clk {
struct clk c;
};
/**
* struct branch_clk - branch clock
* @set_rate: Set the frequency of this branch clock.
* @parent: clock source
* @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
* @base: pointer to base address of ioremapped registers.
*/
struct branch_clk {
void (*set_rate)(struct branch_clk *, struct clk_freq_tbl *);
struct clk *parent;
struct clk c;
const u32 cbcr_reg;
const u32 bcr_reg;
int has_sibling;
u32 cur_div;
const u32 max_div;
const u32 halt_check;
void *const __iomem *base;
};
static inline struct branch_clk *to_branch_clk(struct clk *clk)
{
return container_of(clk, struct branch_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;
const u32 cbcr_reg;
const u32 vote_reg;
const u32 bcr_reg;
const u32 en_mask;
const u32 halt_check;
void *const __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 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;
};
static inline struct measure_clk *to_measure_clk(struct clk *clk)
{
return container_of(clk, struct measure_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_vote;
/*
* 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 */
|