1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
4 * Copyright (C) 2021-2022 Linaro Ltd
6 * previous work of Thara Gopinath and msm-4.9 downstream sources.
10 #include <linux/interconnect.h>
11 #include <linux/interrupt.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
16 #include <linux/platform_device.h>
17 #include <linux/pm_opp.h>
18 #include <linux/regmap.h>
19 #include <linux/sizes.h>
22 * The BWMON samples data throughput within 'sample_ms' time. With three
23 * configurable thresholds (Low, Medium and High) gives four windows (called
24 * zones) of current bandwidth:
26 * Zone 0: byte count < THRES_LO
27 * Zone 1: THRES_LO < byte count < THRES_MED
28 * Zone 2: THRES_MED < byte count < THRES_HIGH
29 * Zone 3: THRES_HIGH < byte count
31 * Zones 0 and 2 are not used by this driver.
34 /* Internal sampling clock frequency */
35 #define HW_TIMER_HZ 19200000
37 #define BWMON_V4_GLOBAL_IRQ_CLEAR 0x108
38 #define BWMON_V4_GLOBAL_IRQ_ENABLE 0x10c
40 * All values here and further are matching regmap fields, so without absolute
43 #define BWMON_V4_GLOBAL_IRQ_ENABLE_ENABLE BIT(0)
46 * Starting with SDM845, the BWMON4 register space has changed a bit:
47 * the global registers were jammed into the beginning of the monitor region.
48 * To keep the proper offsets, one would have to map <GLOBAL_BASE 0x200> and
49 * <GLOBAL_BASE+0x100 0x300>, which is straight up wrong.
50 * To facilitate for that, while allowing the older, arguably more proper
51 * implementations to work, offset the global registers by -0x100 to avoid
52 * having to map half of the global registers twice.
54 #define BWMON_V4_845_OFFSET 0x100
55 #define BWMON_V4_GLOBAL_IRQ_CLEAR_845 (BWMON_V4_GLOBAL_IRQ_CLEAR - BWMON_V4_845_OFFSET)
56 #define BWMON_V4_GLOBAL_IRQ_ENABLE_845 (BWMON_V4_GLOBAL_IRQ_ENABLE - BWMON_V4_845_OFFSET)
58 #define BWMON_V4_IRQ_STATUS 0x100
59 #define BWMON_V4_IRQ_CLEAR 0x108
61 #define BWMON_V4_IRQ_ENABLE 0x10c
62 #define BWMON_IRQ_ENABLE_MASK (BIT(1) | BIT(3))
63 #define BWMON_V5_IRQ_STATUS 0x000
64 #define BWMON_V5_IRQ_CLEAR 0x008
65 #define BWMON_V5_IRQ_ENABLE 0x00c
67 #define BWMON_V4_ENABLE 0x2a0
68 #define BWMON_V5_ENABLE 0x010
69 #define BWMON_ENABLE_ENABLE BIT(0)
71 #define BWMON_V4_CLEAR 0x2a4
72 #define BWMON_V5_CLEAR 0x014
73 #define BWMON_CLEAR_CLEAR BIT(0)
74 #define BWMON_CLEAR_CLEAR_ALL BIT(1)
76 #define BWMON_V4_SAMPLE_WINDOW 0x2a8
77 #define BWMON_V5_SAMPLE_WINDOW 0x020
79 #define BWMON_V4_THRESHOLD_HIGH 0x2ac
80 #define BWMON_V4_THRESHOLD_MED 0x2b0
81 #define BWMON_V4_THRESHOLD_LOW 0x2b4
82 #define BWMON_V5_THRESHOLD_HIGH 0x024
83 #define BWMON_V5_THRESHOLD_MED 0x028
84 #define BWMON_V5_THRESHOLD_LOW 0x02c
86 #define BWMON_V4_ZONE_ACTIONS 0x2b8
87 #define BWMON_V5_ZONE_ACTIONS 0x030
89 * Actions to perform on some zone 'z' when current zone hits the threshold:
90 * Increment counter of zone 'z'
92 #define BWMON_ZONE_ACTIONS_INCREMENT(z) (0x2 << ((z) * 2))
93 /* Clear counter of zone 'z' */
94 #define BWMON_ZONE_ACTIONS_CLEAR(z) (0x1 << ((z) * 2))
96 /* Zone 0 threshold hit: Clear zone count */
97 #define BWMON_ZONE_ACTIONS_ZONE0 (BWMON_ZONE_ACTIONS_CLEAR(0))
99 /* Zone 1 threshold hit: Increment zone count & clear lower zones */
100 #define BWMON_ZONE_ACTIONS_ZONE1 (BWMON_ZONE_ACTIONS_INCREMENT(1) | \
101 BWMON_ZONE_ACTIONS_CLEAR(0))
103 /* Zone 2 threshold hit: Increment zone count & clear lower zones */
104 #define BWMON_ZONE_ACTIONS_ZONE2 (BWMON_ZONE_ACTIONS_INCREMENT(2) | \
105 BWMON_ZONE_ACTIONS_CLEAR(1) | \
106 BWMON_ZONE_ACTIONS_CLEAR(0))
108 /* Zone 3 threshold hit: Increment zone count & clear lower zones */
109 #define BWMON_ZONE_ACTIONS_ZONE3 (BWMON_ZONE_ACTIONS_INCREMENT(3) | \
110 BWMON_ZONE_ACTIONS_CLEAR(2) | \
111 BWMON_ZONE_ACTIONS_CLEAR(1) | \
112 BWMON_ZONE_ACTIONS_CLEAR(0))
115 * There is no clear documentation/explanation of BWMON_V4_THRESHOLD_COUNT
116 * register. Based on observations, this is number of times one threshold has to
117 * be reached, to trigger interrupt in given zone.
119 * 0xff are maximum values meant to ignore the zones 0 and 2.
121 #define BWMON_V4_THRESHOLD_COUNT 0x2bc
122 #define BWMON_V5_THRESHOLD_COUNT 0x034
123 #define BWMON_THRESHOLD_COUNT_ZONE0_DEFAULT 0xff
124 #define BWMON_THRESHOLD_COUNT_ZONE2_DEFAULT 0xff
126 #define BWMON_V4_ZONE_MAX(zone) (0x2e0 + 4 * (zone))
127 #define BWMON_V5_ZONE_MAX(zone) (0x044 + 4 * (zone))
129 /* Quirks for specific BWMON types */
130 #define BWMON_HAS_GLOBAL_IRQ BIT(0)
131 #define BWMON_NEEDS_FORCE_CLEAR BIT(1)
134 /* Global region fields, keep them at the top */
139 /* Monitor region fields */
140 F_IRQ_STATUS = F_NUM_GLOBAL_FIELDS,
149 F_ZONE_ACTIONS_ZONE0,
150 F_ZONE_ACTIONS_ZONE1,
151 F_ZONE_ACTIONS_ZONE2,
152 F_ZONE_ACTIONS_ZONE3,
153 F_THRESHOLD_COUNT_ZONE0,
154 F_THRESHOLD_COUNT_ZONE1,
155 F_THRESHOLD_COUNT_ZONE2,
156 F_THRESHOLD_COUNT_ZONE3,
165 struct icc_bwmon_data {
166 unsigned int sample_ms;
167 unsigned int count_unit_kb; /* kbytes */
168 u8 zone1_thres_count;
169 u8 zone3_thres_count;
172 const struct regmap_config *regmap_cfg;
173 const struct reg_field *regmap_fields;
175 const struct regmap_config *global_regmap_cfg;
176 const struct reg_field *global_regmap_fields;
181 const struct icc_bwmon_data *data;
184 struct regmap_field *regs[F_NUM_FIELDS];
185 struct regmap_field *global_regs[F_NUM_GLOBAL_FIELDS];
187 unsigned int max_bw_kbps;
188 unsigned int min_bw_kbps;
189 unsigned int target_kbps;
190 unsigned int current_kbps;
194 static const struct reg_field msm8998_bwmon_reg_fields[] = {
195 [F_GLOBAL_IRQ_CLEAR] = {},
196 [F_GLOBAL_IRQ_ENABLE] = {},
197 [F_IRQ_STATUS] = REG_FIELD(BWMON_V4_IRQ_STATUS, 4, 7),
198 [F_IRQ_CLEAR] = REG_FIELD(BWMON_V4_IRQ_CLEAR, 4, 7),
199 [F_IRQ_ENABLE] = REG_FIELD(BWMON_V4_IRQ_ENABLE, 4, 7),
200 /* F_ENABLE covers entire register to disable other features */
201 [F_ENABLE] = REG_FIELD(BWMON_V4_ENABLE, 0, 31),
202 [F_CLEAR] = REG_FIELD(BWMON_V4_CLEAR, 0, 1),
203 [F_SAMPLE_WINDOW] = REG_FIELD(BWMON_V4_SAMPLE_WINDOW, 0, 23),
204 [F_THRESHOLD_HIGH] = REG_FIELD(BWMON_V4_THRESHOLD_HIGH, 0, 11),
205 [F_THRESHOLD_MED] = REG_FIELD(BWMON_V4_THRESHOLD_MED, 0, 11),
206 [F_THRESHOLD_LOW] = REG_FIELD(BWMON_V4_THRESHOLD_LOW, 0, 11),
207 [F_ZONE_ACTIONS_ZONE0] = REG_FIELD(BWMON_V4_ZONE_ACTIONS, 0, 7),
208 [F_ZONE_ACTIONS_ZONE1] = REG_FIELD(BWMON_V4_ZONE_ACTIONS, 8, 15),
209 [F_ZONE_ACTIONS_ZONE2] = REG_FIELD(BWMON_V4_ZONE_ACTIONS, 16, 23),
210 [F_ZONE_ACTIONS_ZONE3] = REG_FIELD(BWMON_V4_ZONE_ACTIONS, 24, 31),
211 [F_THRESHOLD_COUNT_ZONE0] = REG_FIELD(BWMON_V4_THRESHOLD_COUNT, 0, 7),
212 [F_THRESHOLD_COUNT_ZONE1] = REG_FIELD(BWMON_V4_THRESHOLD_COUNT, 8, 15),
213 [F_THRESHOLD_COUNT_ZONE2] = REG_FIELD(BWMON_V4_THRESHOLD_COUNT, 16, 23),
214 [F_THRESHOLD_COUNT_ZONE3] = REG_FIELD(BWMON_V4_THRESHOLD_COUNT, 24, 31),
215 [F_ZONE0_MAX] = REG_FIELD(BWMON_V4_ZONE_MAX(0), 0, 11),
216 [F_ZONE1_MAX] = REG_FIELD(BWMON_V4_ZONE_MAX(1), 0, 11),
217 [F_ZONE2_MAX] = REG_FIELD(BWMON_V4_ZONE_MAX(2), 0, 11),
218 [F_ZONE3_MAX] = REG_FIELD(BWMON_V4_ZONE_MAX(3), 0, 11),
221 static const struct regmap_range msm8998_bwmon_reg_noread_ranges[] = {
222 regmap_reg_range(BWMON_V4_IRQ_CLEAR, BWMON_V4_IRQ_CLEAR),
223 regmap_reg_range(BWMON_V4_CLEAR, BWMON_V4_CLEAR),
226 static const struct regmap_access_table msm8998_bwmon_reg_read_table = {
227 .no_ranges = msm8998_bwmon_reg_noread_ranges,
228 .n_no_ranges = ARRAY_SIZE(msm8998_bwmon_reg_noread_ranges),
231 static const struct regmap_range msm8998_bwmon_reg_volatile_ranges[] = {
232 regmap_reg_range(BWMON_V4_IRQ_STATUS, BWMON_V4_IRQ_STATUS),
233 regmap_reg_range(BWMON_V4_ZONE_MAX(0), BWMON_V4_ZONE_MAX(3)),
236 static const struct regmap_access_table msm8998_bwmon_reg_volatile_table = {
237 .yes_ranges = msm8998_bwmon_reg_volatile_ranges,
238 .n_yes_ranges = ARRAY_SIZE(msm8998_bwmon_reg_volatile_ranges),
241 static const struct reg_field msm8998_bwmon_global_reg_fields[] = {
242 [F_GLOBAL_IRQ_CLEAR] = REG_FIELD(BWMON_V4_GLOBAL_IRQ_CLEAR, 0, 0),
243 [F_GLOBAL_IRQ_ENABLE] = REG_FIELD(BWMON_V4_GLOBAL_IRQ_ENABLE, 0, 0),
246 static const struct regmap_range msm8998_bwmon_global_reg_noread_ranges[] = {
247 regmap_reg_range(BWMON_V4_GLOBAL_IRQ_CLEAR, BWMON_V4_GLOBAL_IRQ_CLEAR),
250 static const struct regmap_access_table msm8998_bwmon_global_reg_read_table = {
251 .no_ranges = msm8998_bwmon_global_reg_noread_ranges,
252 .n_no_ranges = ARRAY_SIZE(msm8998_bwmon_global_reg_noread_ranges),
256 * Fill the cache for non-readable registers only as rest does not really
257 * matter and can be read from the device.
259 static const struct reg_default msm8998_bwmon_reg_defaults[] = {
260 { BWMON_V4_IRQ_CLEAR, 0x0 },
261 { BWMON_V4_CLEAR, 0x0 },
264 static const struct reg_default msm8998_bwmon_global_reg_defaults[] = {
265 { BWMON_V4_GLOBAL_IRQ_CLEAR, 0x0 },
268 static const struct regmap_config msm8998_bwmon_regmap_cfg = {
273 * No concurrent access expected - driver has one interrupt handler,
274 * regmap is not shared, no driver or user-space API.
276 .disable_locking = true,
277 .rd_table = &msm8998_bwmon_reg_read_table,
278 .volatile_table = &msm8998_bwmon_reg_volatile_table,
279 .reg_defaults = msm8998_bwmon_reg_defaults,
280 .num_reg_defaults = ARRAY_SIZE(msm8998_bwmon_reg_defaults),
282 * Cache is necessary for using regmap fields with non-readable
285 .cache_type = REGCACHE_MAPLE,
288 static const struct regmap_config msm8998_bwmon_global_regmap_cfg = {
293 * No concurrent access expected - driver has one interrupt handler,
294 * regmap is not shared, no driver or user-space API.
296 .disable_locking = true,
297 .rd_table = &msm8998_bwmon_global_reg_read_table,
298 .reg_defaults = msm8998_bwmon_global_reg_defaults,
299 .num_reg_defaults = ARRAY_SIZE(msm8998_bwmon_global_reg_defaults),
301 * Cache is necessary for using regmap fields with non-readable
304 .cache_type = REGCACHE_MAPLE,
307 static const struct reg_field sdm845_cpu_bwmon_reg_fields[] = {
308 [F_GLOBAL_IRQ_CLEAR] = REG_FIELD(BWMON_V4_GLOBAL_IRQ_CLEAR_845, 0, 0),
309 [F_GLOBAL_IRQ_ENABLE] = REG_FIELD(BWMON_V4_GLOBAL_IRQ_ENABLE_845, 0, 0),
310 [F_IRQ_STATUS] = REG_FIELD(BWMON_V4_IRQ_STATUS, 4, 7),
311 [F_IRQ_CLEAR] = REG_FIELD(BWMON_V4_IRQ_CLEAR, 4, 7),
312 [F_IRQ_ENABLE] = REG_FIELD(BWMON_V4_IRQ_ENABLE, 4, 7),
313 /* F_ENABLE covers entire register to disable other features */
314 [F_ENABLE] = REG_FIELD(BWMON_V4_ENABLE, 0, 31),
315 [F_CLEAR] = REG_FIELD(BWMON_V4_CLEAR, 0, 1),
316 [F_SAMPLE_WINDOW] = REG_FIELD(BWMON_V4_SAMPLE_WINDOW, 0, 23),
317 [F_THRESHOLD_HIGH] = REG_FIELD(BWMON_V4_THRESHOLD_HIGH, 0, 11),
318 [F_THRESHOLD_MED] = REG_FIELD(BWMON_V4_THRESHOLD_MED, 0, 11),
319 [F_THRESHOLD_LOW] = REG_FIELD(BWMON_V4_THRESHOLD_LOW, 0, 11),
320 [F_ZONE_ACTIONS_ZONE0] = REG_FIELD(BWMON_V4_ZONE_ACTIONS, 0, 7),
321 [F_ZONE_ACTIONS_ZONE1] = REG_FIELD(BWMON_V4_ZONE_ACTIONS, 8, 15),
322 [F_ZONE_ACTIONS_ZONE2] = REG_FIELD(BWMON_V4_ZONE_ACTIONS, 16, 23),
323 [F_ZONE_ACTIONS_ZONE3] = REG_FIELD(BWMON_V4_ZONE_ACTIONS, 24, 31),
324 [F_THRESHOLD_COUNT_ZONE0] = REG_FIELD(BWMON_V4_THRESHOLD_COUNT, 0, 7),
325 [F_THRESHOLD_COUNT_ZONE1] = REG_FIELD(BWMON_V4_THRESHOLD_COUNT, 8, 15),
326 [F_THRESHOLD_COUNT_ZONE2] = REG_FIELD(BWMON_V4_THRESHOLD_COUNT, 16, 23),
327 [F_THRESHOLD_COUNT_ZONE3] = REG_FIELD(BWMON_V4_THRESHOLD_COUNT, 24, 31),
328 [F_ZONE0_MAX] = REG_FIELD(BWMON_V4_ZONE_MAX(0), 0, 11),
329 [F_ZONE1_MAX] = REG_FIELD(BWMON_V4_ZONE_MAX(1), 0, 11),
330 [F_ZONE2_MAX] = REG_FIELD(BWMON_V4_ZONE_MAX(2), 0, 11),
331 [F_ZONE3_MAX] = REG_FIELD(BWMON_V4_ZONE_MAX(3), 0, 11),
334 static const struct regmap_range sdm845_cpu_bwmon_reg_noread_ranges[] = {
335 regmap_reg_range(BWMON_V4_GLOBAL_IRQ_CLEAR_845, BWMON_V4_GLOBAL_IRQ_CLEAR_845),
336 regmap_reg_range(BWMON_V4_IRQ_CLEAR, BWMON_V4_IRQ_CLEAR),
337 regmap_reg_range(BWMON_V4_CLEAR, BWMON_V4_CLEAR),
340 static const struct regmap_access_table sdm845_cpu_bwmon_reg_read_table = {
341 .no_ranges = sdm845_cpu_bwmon_reg_noread_ranges,
342 .n_no_ranges = ARRAY_SIZE(sdm845_cpu_bwmon_reg_noread_ranges),
346 * Fill the cache for non-readable registers only as rest does not really
347 * matter and can be read from the device.
349 static const struct reg_default sdm845_cpu_bwmon_reg_defaults[] = {
350 { BWMON_V4_GLOBAL_IRQ_CLEAR_845, 0x0 },
351 { BWMON_V4_IRQ_CLEAR, 0x0 },
352 { BWMON_V4_CLEAR, 0x0 },
355 static const struct regmap_config sdm845_cpu_bwmon_regmap_cfg = {
360 * No concurrent access expected - driver has one interrupt handler,
361 * regmap is not shared, no driver or user-space API.
363 .disable_locking = true,
364 .rd_table = &sdm845_cpu_bwmon_reg_read_table,
365 .volatile_table = &msm8998_bwmon_reg_volatile_table,
366 .reg_defaults = sdm845_cpu_bwmon_reg_defaults,
367 .num_reg_defaults = ARRAY_SIZE(sdm845_cpu_bwmon_reg_defaults),
369 * Cache is necessary for using regmap fields with non-readable
372 .cache_type = REGCACHE_MAPLE,
376 static const struct reg_field sdm845_llcc_bwmon_reg_fields[] = {
377 [F_GLOBAL_IRQ_CLEAR] = {},
378 [F_GLOBAL_IRQ_ENABLE] = {},
379 [F_IRQ_STATUS] = REG_FIELD(BWMON_V5_IRQ_STATUS, 0, 3),
380 [F_IRQ_CLEAR] = REG_FIELD(BWMON_V5_IRQ_CLEAR, 0, 3),
381 [F_IRQ_ENABLE] = REG_FIELD(BWMON_V5_IRQ_ENABLE, 0, 3),
382 /* F_ENABLE covers entire register to disable other features */
383 [F_ENABLE] = REG_FIELD(BWMON_V5_ENABLE, 0, 31),
384 [F_CLEAR] = REG_FIELD(BWMON_V5_CLEAR, 0, 1),
385 [F_SAMPLE_WINDOW] = REG_FIELD(BWMON_V5_SAMPLE_WINDOW, 0, 19),
386 [F_THRESHOLD_HIGH] = REG_FIELD(BWMON_V5_THRESHOLD_HIGH, 0, 11),
387 [F_THRESHOLD_MED] = REG_FIELD(BWMON_V5_THRESHOLD_MED, 0, 11),
388 [F_THRESHOLD_LOW] = REG_FIELD(BWMON_V5_THRESHOLD_LOW, 0, 11),
389 [F_ZONE_ACTIONS_ZONE0] = REG_FIELD(BWMON_V5_ZONE_ACTIONS, 0, 7),
390 [F_ZONE_ACTIONS_ZONE1] = REG_FIELD(BWMON_V5_ZONE_ACTIONS, 8, 15),
391 [F_ZONE_ACTIONS_ZONE2] = REG_FIELD(BWMON_V5_ZONE_ACTIONS, 16, 23),
392 [F_ZONE_ACTIONS_ZONE3] = REG_FIELD(BWMON_V5_ZONE_ACTIONS, 24, 31),
393 [F_THRESHOLD_COUNT_ZONE0] = REG_FIELD(BWMON_V5_THRESHOLD_COUNT, 0, 7),
394 [F_THRESHOLD_COUNT_ZONE1] = REG_FIELD(BWMON_V5_THRESHOLD_COUNT, 8, 15),
395 [F_THRESHOLD_COUNT_ZONE2] = REG_FIELD(BWMON_V5_THRESHOLD_COUNT, 16, 23),
396 [F_THRESHOLD_COUNT_ZONE3] = REG_FIELD(BWMON_V5_THRESHOLD_COUNT, 24, 31),
397 [F_ZONE0_MAX] = REG_FIELD(BWMON_V5_ZONE_MAX(0), 0, 11),
398 [F_ZONE1_MAX] = REG_FIELD(BWMON_V5_ZONE_MAX(1), 0, 11),
399 [F_ZONE2_MAX] = REG_FIELD(BWMON_V5_ZONE_MAX(2), 0, 11),
400 [F_ZONE3_MAX] = REG_FIELD(BWMON_V5_ZONE_MAX(3), 0, 11),
403 static const struct regmap_range sdm845_llcc_bwmon_reg_noread_ranges[] = {
404 regmap_reg_range(BWMON_V5_IRQ_CLEAR, BWMON_V5_IRQ_CLEAR),
405 regmap_reg_range(BWMON_V5_CLEAR, BWMON_V5_CLEAR),
408 static const struct regmap_access_table sdm845_llcc_bwmon_reg_read_table = {
409 .no_ranges = sdm845_llcc_bwmon_reg_noread_ranges,
410 .n_no_ranges = ARRAY_SIZE(sdm845_llcc_bwmon_reg_noread_ranges),
413 static const struct regmap_range sdm845_llcc_bwmon_reg_volatile_ranges[] = {
414 regmap_reg_range(BWMON_V5_IRQ_STATUS, BWMON_V5_IRQ_STATUS),
415 regmap_reg_range(BWMON_V5_ZONE_MAX(0), BWMON_V5_ZONE_MAX(3)),
418 static const struct regmap_access_table sdm845_llcc_bwmon_reg_volatile_table = {
419 .yes_ranges = sdm845_llcc_bwmon_reg_volatile_ranges,
420 .n_yes_ranges = ARRAY_SIZE(sdm845_llcc_bwmon_reg_volatile_ranges),
424 * Fill the cache for non-readable registers only as rest does not really
425 * matter and can be read from the device.
427 static const struct reg_default sdm845_llcc_bwmon_reg_defaults[] = {
428 { BWMON_V5_IRQ_CLEAR, 0x0 },
429 { BWMON_V5_CLEAR, 0x0 },
432 static const struct regmap_config sdm845_llcc_bwmon_regmap_cfg = {
437 * No concurrent access expected - driver has one interrupt handler,
438 * regmap is not shared, no driver or user-space API.
440 .disable_locking = true,
441 .rd_table = &sdm845_llcc_bwmon_reg_read_table,
442 .volatile_table = &sdm845_llcc_bwmon_reg_volatile_table,
443 .reg_defaults = sdm845_llcc_bwmon_reg_defaults,
444 .num_reg_defaults = ARRAY_SIZE(sdm845_llcc_bwmon_reg_defaults),
446 * Cache is necessary for using regmap fields with non-readable
449 .cache_type = REGCACHE_MAPLE,
452 static void bwmon_clear_counters(struct icc_bwmon *bwmon, bool clear_all)
454 unsigned int val = BWMON_CLEAR_CLEAR;
457 val |= BWMON_CLEAR_CLEAR_ALL;
459 * Clear counters. The order and barriers are
460 * important. Quoting downstream Qualcomm msm-4.9 tree:
462 * The counter clear and IRQ clear bits are not in the same 4KB
463 * region. So, we need to make sure the counter clear is completed
464 * before we try to clear the IRQ or do any other counter operations.
466 regmap_field_force_write(bwmon->regs[F_CLEAR], val);
467 if (bwmon->data->quirks & BWMON_NEEDS_FORCE_CLEAR)
468 regmap_field_force_write(bwmon->regs[F_CLEAR], 0);
471 static void bwmon_clear_irq(struct icc_bwmon *bwmon)
473 struct regmap_field *global_irq_clr;
475 if (bwmon->data->global_regmap_fields)
476 global_irq_clr = bwmon->global_regs[F_GLOBAL_IRQ_CLEAR];
478 global_irq_clr = bwmon->regs[F_GLOBAL_IRQ_CLEAR];
481 * Clear zone and global interrupts. The order and barriers are
482 * important. Quoting downstream Qualcomm msm-4.9 tree:
484 * Synchronize the local interrupt clear in mon_irq_clear()
485 * with the global interrupt clear here. Otherwise, the CPU
486 * may reorder the two writes and clear the global interrupt
487 * before the local interrupt, causing the global interrupt
488 * to be retriggered by the local interrupt still being high.
490 * Similarly, because the global registers are in a different
491 * region than the local registers, we need to ensure any register
492 * writes to enable the monitor after this call are ordered with the
493 * clearing here so that local writes don't happen before the
494 * interrupt is cleared.
496 regmap_field_force_write(bwmon->regs[F_IRQ_CLEAR], BWMON_IRQ_ENABLE_MASK);
497 if (bwmon->data->quirks & BWMON_NEEDS_FORCE_CLEAR)
498 regmap_field_force_write(bwmon->regs[F_IRQ_CLEAR], 0);
499 if (bwmon->data->quirks & BWMON_HAS_GLOBAL_IRQ)
500 regmap_field_force_write(global_irq_clr,
501 BWMON_V4_GLOBAL_IRQ_ENABLE_ENABLE);
504 static void bwmon_disable(struct icc_bwmon *bwmon)
506 struct regmap_field *global_irq_en;
508 if (bwmon->data->global_regmap_fields)
509 global_irq_en = bwmon->global_regs[F_GLOBAL_IRQ_ENABLE];
511 global_irq_en = bwmon->regs[F_GLOBAL_IRQ_ENABLE];
513 /* Disable interrupts. Strict ordering, see bwmon_clear_irq(). */
514 if (bwmon->data->quirks & BWMON_HAS_GLOBAL_IRQ)
515 regmap_field_write(global_irq_en, 0x0);
516 regmap_field_write(bwmon->regs[F_IRQ_ENABLE], 0x0);
519 * Disable bwmon. Must happen before bwmon_clear_irq() to avoid spurious
522 regmap_field_write(bwmon->regs[F_ENABLE], 0x0);
525 static void bwmon_enable(struct icc_bwmon *bwmon, unsigned int irq_enable)
527 struct regmap_field *global_irq_en;
529 if (bwmon->data->global_regmap_fields)
530 global_irq_en = bwmon->global_regs[F_GLOBAL_IRQ_ENABLE];
532 global_irq_en = bwmon->regs[F_GLOBAL_IRQ_ENABLE];
534 /* Enable interrupts */
535 if (bwmon->data->quirks & BWMON_HAS_GLOBAL_IRQ)
536 regmap_field_write(global_irq_en,
537 BWMON_V4_GLOBAL_IRQ_ENABLE_ENABLE);
539 regmap_field_write(bwmon->regs[F_IRQ_ENABLE], irq_enable);
542 regmap_field_write(bwmon->regs[F_ENABLE], BWMON_ENABLE_ENABLE);
545 static unsigned int bwmon_kbps_to_count(struct icc_bwmon *bwmon,
548 return kbps / bwmon->data->count_unit_kb;
551 static void bwmon_set_threshold(struct icc_bwmon *bwmon,
552 struct regmap_field *reg, unsigned int kbps)
556 thres = mult_frac(bwmon_kbps_to_count(bwmon, kbps),
557 bwmon->data->sample_ms, MSEC_PER_SEC);
558 regmap_field_write(reg, thres);
561 static void bwmon_start(struct icc_bwmon *bwmon)
563 const struct icc_bwmon_data *data = bwmon->data;
567 /* No need to check for errors, as this must have succeeded before. */
568 dev_pm_opp_put(dev_pm_opp_find_bw_ceil(bwmon->dev, &bw_low, 0));
570 bwmon_clear_counters(bwmon, true);
572 window = mult_frac(bwmon->data->sample_ms, HW_TIMER_HZ, MSEC_PER_SEC);
573 /* Maximum sampling window: 0xffffff for v4 and 0xfffff for v5 */
574 regmap_field_write(bwmon->regs[F_SAMPLE_WINDOW], window);
576 bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_HIGH], bw_low);
577 bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_MED], bw_low);
578 bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_LOW], 0);
580 regmap_field_write(bwmon->regs[F_THRESHOLD_COUNT_ZONE0],
581 BWMON_THRESHOLD_COUNT_ZONE0_DEFAULT);
582 regmap_field_write(bwmon->regs[F_THRESHOLD_COUNT_ZONE1],
583 data->zone1_thres_count);
584 regmap_field_write(bwmon->regs[F_THRESHOLD_COUNT_ZONE2],
585 BWMON_THRESHOLD_COUNT_ZONE2_DEFAULT);
586 regmap_field_write(bwmon->regs[F_THRESHOLD_COUNT_ZONE3],
587 data->zone3_thres_count);
589 regmap_field_write(bwmon->regs[F_ZONE_ACTIONS_ZONE0],
590 BWMON_ZONE_ACTIONS_ZONE0);
591 regmap_field_write(bwmon->regs[F_ZONE_ACTIONS_ZONE1],
592 BWMON_ZONE_ACTIONS_ZONE1);
593 regmap_field_write(bwmon->regs[F_ZONE_ACTIONS_ZONE2],
594 BWMON_ZONE_ACTIONS_ZONE2);
595 regmap_field_write(bwmon->regs[F_ZONE_ACTIONS_ZONE3],
596 BWMON_ZONE_ACTIONS_ZONE3);
598 bwmon_clear_irq(bwmon);
599 bwmon_enable(bwmon, BWMON_IRQ_ENABLE_MASK);
602 static irqreturn_t bwmon_intr(int irq, void *dev_id)
604 struct icc_bwmon *bwmon = dev_id;
605 unsigned int status, max;
608 if (regmap_field_read(bwmon->regs[F_IRQ_STATUS], &status))
611 status &= BWMON_IRQ_ENABLE_MASK;
614 * Only zone 1 and zone 3 interrupts are enabled but zone 2
615 * threshold could be hit and trigger interrupt even if not
617 * Such spurious interrupt might come with valuable max count or
618 * not, so solution would be to always check all
619 * BWMON_ZONE_MAX() registers to find the highest value.
620 * Such case is currently ignored.
625 bwmon_disable(bwmon);
627 zone = get_bitmask_order(status) - 1;
629 * Zone max bytes count register returns count units within sampling
630 * window. Downstream kernel for BWMONv4 (called BWMON type 2 in
631 * downstream) always increments the max bytes count by one.
633 if (regmap_field_read(bwmon->regs[F_ZONE0_MAX + zone], &max))
637 max *= bwmon->data->count_unit_kb;
638 bwmon->target_kbps = mult_frac(max, MSEC_PER_SEC, bwmon->data->sample_ms);
640 return IRQ_WAKE_THREAD;
643 static irqreturn_t bwmon_intr_thread(int irq, void *dev_id)
645 struct icc_bwmon *bwmon = dev_id;
646 unsigned int irq_enable = 0;
647 struct dev_pm_opp *opp, *target_opp;
648 unsigned int bw_kbps, up_kbps, down_kbps;
650 bw_kbps = bwmon->target_kbps;
652 target_opp = dev_pm_opp_find_bw_ceil(bwmon->dev, &bw_kbps, 0);
653 if (IS_ERR(target_opp) && PTR_ERR(target_opp) == -ERANGE)
654 target_opp = dev_pm_opp_find_bw_floor(bwmon->dev, &bw_kbps, 0);
656 bwmon->target_kbps = bw_kbps;
659 opp = dev_pm_opp_find_bw_floor(bwmon->dev, &bw_kbps, 0);
660 if (IS_ERR(opp) && PTR_ERR(opp) == -ERANGE)
661 down_kbps = bwmon->target_kbps;
665 up_kbps = bwmon->target_kbps + 1;
667 if (bwmon->target_kbps >= bwmon->max_bw_kbps)
669 else if (bwmon->target_kbps <= bwmon->min_bw_kbps)
672 irq_enable = BWMON_IRQ_ENABLE_MASK;
674 bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_HIGH],
676 bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_MED],
678 bwmon_clear_counters(bwmon, false);
679 bwmon_clear_irq(bwmon);
680 bwmon_enable(bwmon, irq_enable);
682 if (bwmon->target_kbps == bwmon->current_kbps)
685 dev_pm_opp_set_opp(bwmon->dev, target_opp);
686 bwmon->current_kbps = bwmon->target_kbps;
689 dev_pm_opp_put(target_opp);
696 static int bwmon_init_regmap(struct platform_device *pdev,
697 struct icc_bwmon *bwmon)
699 struct device *dev = &pdev->dev;
704 /* Map the monitor base */
705 base = devm_platform_ioremap_resource(pdev, 0);
707 return dev_err_probe(dev, PTR_ERR(base),
708 "failed to map bwmon registers\n");
710 map = devm_regmap_init_mmio(dev, base, bwmon->data->regmap_cfg);
712 return dev_err_probe(dev, PTR_ERR(map),
713 "failed to initialize regmap\n");
715 BUILD_BUG_ON(ARRAY_SIZE(msm8998_bwmon_global_reg_fields) != F_NUM_GLOBAL_FIELDS);
716 BUILD_BUG_ON(ARRAY_SIZE(msm8998_bwmon_reg_fields) != F_NUM_FIELDS);
717 BUILD_BUG_ON(ARRAY_SIZE(sdm845_cpu_bwmon_reg_fields) != F_NUM_FIELDS);
718 BUILD_BUG_ON(ARRAY_SIZE(sdm845_llcc_bwmon_reg_fields) != F_NUM_FIELDS);
720 ret = devm_regmap_field_bulk_alloc(dev, map, bwmon->regs,
721 bwmon->data->regmap_fields,
726 if (bwmon->data->global_regmap_cfg) {
727 /* Map the global base, if separate */
728 base = devm_platform_ioremap_resource(pdev, 1);
730 return dev_err_probe(dev, PTR_ERR(base),
731 "failed to map bwmon global registers\n");
733 map = devm_regmap_init_mmio(dev, base, bwmon->data->global_regmap_cfg);
735 return dev_err_probe(dev, PTR_ERR(map),
736 "failed to initialize global regmap\n");
738 ret = devm_regmap_field_bulk_alloc(dev, map, bwmon->global_regs,
739 bwmon->data->global_regmap_fields,
740 F_NUM_GLOBAL_FIELDS);
746 static int bwmon_probe(struct platform_device *pdev)
748 struct device *dev = &pdev->dev;
749 struct dev_pm_opp *opp;
750 struct icc_bwmon *bwmon;
753 bwmon = devm_kzalloc(dev, sizeof(*bwmon), GFP_KERNEL);
757 bwmon->data = of_device_get_match_data(dev);
759 ret = bwmon_init_regmap(pdev, bwmon);
763 bwmon->irq = platform_get_irq(pdev, 0);
767 ret = devm_pm_opp_of_add_table(dev);
769 return dev_err_probe(dev, ret, "failed to add OPP table\n");
771 bwmon->max_bw_kbps = UINT_MAX;
772 opp = dev_pm_opp_find_bw_floor(dev, &bwmon->max_bw_kbps, 0);
774 return dev_err_probe(dev, PTR_ERR(opp), "failed to find max peak bandwidth\n");
777 bwmon->min_bw_kbps = 0;
778 opp = dev_pm_opp_find_bw_ceil(dev, &bwmon->min_bw_kbps, 0);
780 return dev_err_probe(dev, PTR_ERR(opp), "failed to find min peak bandwidth\n");
785 bwmon_disable(bwmon);
788 * SoCs with multiple cpu-bwmon instances can end up using a shared interrupt
789 * line. Using the devm_ variant might result in the IRQ handler being executed
790 * after bwmon_disable in bwmon_remove()
792 ret = request_threaded_irq(bwmon->irq, bwmon_intr, bwmon_intr_thread,
793 IRQF_ONESHOT | IRQF_SHARED, dev_name(dev), bwmon);
795 return dev_err_probe(dev, ret, "failed to request IRQ\n");
797 platform_set_drvdata(pdev, bwmon);
803 static void bwmon_remove(struct platform_device *pdev)
805 struct icc_bwmon *bwmon = platform_get_drvdata(pdev);
807 bwmon_disable(bwmon);
808 free_irq(bwmon->irq, bwmon);
811 static const struct icc_bwmon_data msm8998_bwmon_data = {
813 .count_unit_kb = 1024,
814 .zone1_thres_count = 16,
815 .zone3_thres_count = 1,
816 .quirks = BWMON_HAS_GLOBAL_IRQ,
817 .regmap_fields = msm8998_bwmon_reg_fields,
818 .regmap_cfg = &msm8998_bwmon_regmap_cfg,
819 .global_regmap_fields = msm8998_bwmon_global_reg_fields,
820 .global_regmap_cfg = &msm8998_bwmon_global_regmap_cfg,
823 static const struct icc_bwmon_data sdm845_cpu_bwmon_data = {
826 .zone1_thres_count = 16,
827 .zone3_thres_count = 1,
828 .quirks = BWMON_HAS_GLOBAL_IRQ,
829 .regmap_fields = sdm845_cpu_bwmon_reg_fields,
830 .regmap_cfg = &sdm845_cpu_bwmon_regmap_cfg,
833 static const struct icc_bwmon_data sdm845_llcc_bwmon_data = {
835 .count_unit_kb = 1024,
836 .zone1_thres_count = 16,
837 .zone3_thres_count = 1,
838 .regmap_fields = sdm845_llcc_bwmon_reg_fields,
839 .regmap_cfg = &sdm845_llcc_bwmon_regmap_cfg,
842 static const struct icc_bwmon_data sc7280_llcc_bwmon_data = {
845 .zone1_thres_count = 16,
846 .zone3_thres_count = 1,
847 .quirks = BWMON_NEEDS_FORCE_CLEAR,
848 .regmap_fields = sdm845_llcc_bwmon_reg_fields,
849 .regmap_cfg = &sdm845_llcc_bwmon_regmap_cfg,
852 static const struct of_device_id bwmon_of_match[] = {
853 /* BWMONv4, separate monitor and global register spaces */
854 { .compatible = "qcom,msm8998-bwmon", .data = &msm8998_bwmon_data },
855 /* BWMONv4, unified register space */
856 { .compatible = "qcom,sdm845-bwmon", .data = &sdm845_cpu_bwmon_data },
858 { .compatible = "qcom,sdm845-llcc-bwmon", .data = &sdm845_llcc_bwmon_data },
859 { .compatible = "qcom,sc7280-llcc-bwmon", .data = &sc7280_llcc_bwmon_data },
861 /* Compatibles kept for legacy reasons */
862 { .compatible = "qcom,sc7280-cpu-bwmon", .data = &sdm845_cpu_bwmon_data },
863 { .compatible = "qcom,sc8280xp-cpu-bwmon", .data = &sdm845_cpu_bwmon_data },
864 { .compatible = "qcom,sm8550-cpu-bwmon", .data = &sdm845_cpu_bwmon_data },
867 MODULE_DEVICE_TABLE(of, bwmon_of_match);
869 static struct platform_driver bwmon_driver = {
870 .probe = bwmon_probe,
871 .remove_new = bwmon_remove,
873 .name = "qcom-bwmon",
874 .of_match_table = bwmon_of_match,
877 module_platform_driver(bwmon_driver);
880 MODULE_DESCRIPTION("QCOM BWMON driver");
881 MODULE_LICENSE("GPL");