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
|
/*
* Copyright (c) 2011-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_ACPUCLOCK_KRAIT_H
#define __ARCH_ARM_MACH_MSM_ACPUCLOCK_KRAIT_H
#define L2(x) (x)
#define BW_MBPS(_bw) \
{ \
.vectors = (struct msm_bus_vectors[]){ \
{\
.src = MSM_BUS_MASTER_AMPSS_M0, \
.dst = MSM_BUS_SLAVE_EBI_CH0, \
.ib = (_bw) * 1000000ULL, \
}, \
{ \
.src = MSM_BUS_MASTER_AMPSS_M1, \
.dst = MSM_BUS_SLAVE_EBI_CH0, \
.ib = (_bw) * 1000000ULL, \
}, \
}, \
.num_paths = 2, \
}
/**
* src_id - Clock source IDs.
*/
enum src_id {
PLL_0 = 0,
HFPLL,
PLL_8,
NUM_SRC_ID,
};
/**
* enum pvs - IDs to distinguish between CPU frequency tables.
*/
enum pvs {
PVS_SLOW = 0,
PVS_NOMINAL = 1,
PVS_FAST = 3,
PVS_FASTER = 4,
NUM_PVS = 7
};
/**
* The maximum number of speed bins.
*/
#define NUM_SPEED_BINS (16)
/**
* enum scalables - IDs of frequency scalable hardware blocks.
*/
enum scalables {
CPU0 = 0,
CPU1,
CPU2,
CPU3,
L2,
};
/**
* enum hfpll_vdd_level - IDs of HFPLL voltage levels.
*/
enum hfpll_vdd_levels {
HFPLL_VDD_NONE,
HFPLL_VDD_LOW,
HFPLL_VDD_NOM,
HFPLL_VDD_HIGH,
NUM_HFPLL_VDD
};
/**
* enum vregs - IDs of voltage regulators.
*/
enum vregs {
VREG_CORE,
VREG_MEM,
VREG_DIG,
VREG_HFPLL_A,
VREG_HFPLL_B,
NUM_VREG
};
/**
* struct vreg - Voltage regulator data.
* @name: Name of requlator.
* @max_vdd: Limit the maximum-settable voltage.
* @reg: Regulator handle.
* @rpm_reg: RPM Regulator handle.
* @cur_vdd: Last-set voltage in uV.
* @cur_ua: Last-set current in uA.
*/
struct vreg {
const char *name;
const int max_vdd;
struct regulator *reg;
struct rpm_regulator *rpm_reg;
int cur_vdd;
int cur_ua;
};
/**
* struct core_speed - Clock tree and configuration parameters.
* @khz: Clock rate in KHz.
* @src: Clock source ID.
* @pri_src_sel: Input to select on the primary MUX.
* @pll_l_val: HFPLL "L" value to be applied when an HFPLL source is selected.
*/
struct core_speed {
unsigned long khz;
int src;
u32 pri_src_sel;
u32 pll_l_val;
};
/**
* struct l2_level - L2 clock rate and associated voltage and b/w requirements.
* @speed: L2 clock configuration.
* @vdd_dig: vdd_dig voltage in uV.
* @vdd_mem: vdd_mem voltage in uV.
* @bw_level: Bandwidth performance level number.
*/
struct l2_level {
const struct core_speed speed;
const int vdd_dig;
const int vdd_mem;
const unsigned int bw_level;
};
/**
* struct acpu_level - CPU clock rate and L2 rate and voltage requirements.
* @use_for_scaling: Flag indicating whether or not the level should be used.
* @speed: CPU clock configuration.
* @l2_level: L2 configuration to use.
* @vdd_core: CPU core voltage in uV.
* @ua_core: CPU core current consumption in uA.
* @avsdscr_setting: AVS DSCR configuration.
*/
struct acpu_level {
const int use_for_scaling;
const struct core_speed speed;
const unsigned int l2_level;
int vdd_core;
int ua_core;
unsigned int avsdscr_setting;
};
/**
* struct hfpll_data - Descriptive data of HFPLL hardware.
* @mode_offset: Mode register offset from base address.
* @l_offset: "L" value register offset from base address.
* @m_offset: "M" value register offset from base address.
* @n_offset: "N" value register offset from base address.
* @config_offset: Configuration register offset from base address.
* @config_val: Value to initialize the @config_offset register to.
* @has_user_reg: Indicates the presence of an addition config register.
* @user_offset: User register offset from base address, if applicable.
* @user_val: Value to initialize the @user_offset register to.
* @user_vco_mask: Bit in the @user_offset to enable high-frequency VCO mode.
* @has_droop_ctl: Indicates the presence of a voltage droop controller.
* @droop_offset: Droop controller register offset from base address.
* @droop_val: Value to initialize the @config_offset register to.
* @low_vdd_l_max: Maximum "L" value supported at HFPLL_VDD_LOW.
* @nom_vdd_l_max: Maximum "L" value supported at HFPLL_VDD_NOM.
* @low_vco_l_max: Maximum "L" value supported in low-frequency VCO mode.
* @vdd: voltage requirements for each VDD level for the L2 PLL.
*/
struct hfpll_data {
const u32 mode_offset;
const u32 l_offset;
const u32 m_offset;
const u32 n_offset;
const u32 config_offset;
const u32 config_val;
const bool has_user_reg;
const u32 user_offset;
const u32 user_val;
const u32 user_vco_mask;
const bool has_droop_ctl;
const u32 droop_offset;
const u32 droop_val;
u32 low_vdd_l_max;
u32 nom_vdd_l_max;
const u32 low_vco_l_max;
const int vdd[NUM_HFPLL_VDD];
};
/**
* struct scalable - Register locations and state associated with a scalable HW.
* @hfpll_phys_base: Physical base address of HFPLL register.
* @hfpll_base: Virtual base address of HFPLL registers.
* @aux_clk_sel_phys: Physical address of auxiliary MUX.
* @aux_clk_sel: Auxiliary mux input to select at boot.
* @sec_clk_sel: Secondary mux input to select at boot.
* @l2cpmr_iaddr: Indirect address of the CPMR MUX/divider CP15 register.
* @cur_speed: Pointer to currently-set speed.
* @l2_vote: L2 performance level vote associate with the current CPU speed.
* @vreg: Array of voltage regulators needed by the scalable.
* @initialized: Flag set to true when per_cpu_init() has been called.
* @avs_enabled: True if avs is enabled for the scalabale. False otherwise.
*/
struct scalable {
const phys_addr_t hfpll_phys_base;
void __iomem *hfpll_base;
const phys_addr_t aux_clk_sel_phys;
const u32 aux_clk_sel;
const u32 sec_clk_sel;
const u32 l2cpmr_iaddr;
const struct core_speed *cur_speed;
unsigned int l2_vote;
struct vreg vreg[NUM_VREG];
bool initialized;
bool avs_enabled;
};
/**
* struct pvs_table - CPU performance level table and size.
* @table: CPU performance level table
* @size: sizeof(@table)
* @boost_uv: Voltage boost amount
*/
struct pvs_table {
struct acpu_level *table;
size_t size;
int boost_uv;
};
/**
* struct acpuclk_krait_params - SoC specific driver parameters.
* @scalable: Array of scalables.
* @scalable_size: Size of @scalable.
* @hfpll_data: HFPLL configuration data.
* @pvs_tables: 2D array of CPU frequency tables.
* @l2_freq_tbl: L2 frequency table.
* @l2_freq_tbl_size: Size of @l2_freq_tbl.
* @pte_efuse_phys: Physical address of PTE EFUSE.
* @bus_scale: MSM bus driver parameters.
* @stby_khz: KHz value corresponding to an always-on clock source.
*/
struct acpuclk_krait_params {
struct scalable *scalable;
size_t scalable_size;
struct hfpll_data *hfpll_data;
struct pvs_table (*pvs_tables)[NUM_PVS];
struct l2_level *l2_freq_tbl;
size_t l2_freq_tbl_size;
phys_addr_t pte_efuse_phys;
struct msm_bus_scale_pdata *bus_scale;
unsigned long stby_khz;
};
/**
* struct acpuclk_platform_data - PMIC configuration data.
* @uses_pm8917: Boolean indicates presence of pm8917.
*/
struct acpuclk_platform_data {
bool uses_pm8917;
};
/**
* acpuclk_krait_init - Initialize the Krait CPU clock driver give SoC params.
*/
extern int acpuclk_krait_init(struct device *dev,
const struct acpuclk_krait_params *params);
#endif
|