xref: /openbmc/linux/drivers/soc/qcom/icc-bwmon.c (revision 4b7444ff)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
4  * Copyright (C) 2021-2022 Linaro Ltd
5  * Author: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>, based on
6  *         previous work of Thara Gopinath and msm-4.9 downstream sources.
7  */
8 #include <linux/interconnect.h>
9 #include <linux/interrupt.h>
10 #include <linux/io.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/of_device.h>
14 #include <linux/platform_device.h>
15 #include <linux/pm_opp.h>
16 #include <linux/sizes.h>
17 
18 /*
19  * The BWMON samples data throughput within 'sample_ms' time. With three
20  * configurable thresholds (Low, Medium and High) gives four windows (called
21  * zones) of current bandwidth:
22  *
23  * Zone 0: byte count < THRES_LO
24  * Zone 1: THRES_LO < byte count < THRES_MED
25  * Zone 2: THRES_MED < byte count < THRES_HIGH
26  * Zone 3: THRES_HIGH < byte count
27  *
28  * Zones 0 and 2 are not used by this driver.
29  */
30 
31 /* Internal sampling clock frequency */
32 #define HW_TIMER_HZ				19200000
33 
34 #define BWMON_GLOBAL_IRQ_STATUS			0x0
35 #define BWMON_GLOBAL_IRQ_CLEAR			0x8
36 #define BWMON_GLOBAL_IRQ_ENABLE			0xc
37 #define BWMON_GLOBAL_IRQ_ENABLE_ENABLE		BIT(0)
38 
39 #define BWMON_IRQ_STATUS			0x100
40 #define BWMON_IRQ_STATUS_ZONE_SHIFT		4
41 #define BWMON_IRQ_CLEAR				0x108
42 #define BWMON_IRQ_ENABLE			0x10c
43 #define BWMON_IRQ_ENABLE_ZONE1_SHIFT		5
44 #define BWMON_IRQ_ENABLE_ZONE2_SHIFT		6
45 #define BWMON_IRQ_ENABLE_ZONE3_SHIFT		7
46 #define BWMON_IRQ_ENABLE_MASK			(BIT(BWMON_IRQ_ENABLE_ZONE1_SHIFT) | \
47 						 BIT(BWMON_IRQ_ENABLE_ZONE3_SHIFT))
48 
49 #define BWMON_ENABLE				0x2a0
50 #define BWMON_ENABLE_ENABLE			BIT(0)
51 
52 #define BWMON_CLEAR				0x2a4
53 #define BWMON_CLEAR_CLEAR			BIT(0)
54 
55 #define BWMON_SAMPLE_WINDOW			0x2a8
56 #define BWMON_THRESHOLD_HIGH			0x2ac
57 #define BWMON_THRESHOLD_MED			0x2b0
58 #define BWMON_THRESHOLD_LOW			0x2b4
59 
60 #define BWMON_ZONE_ACTIONS			0x2b8
61 /*
62  * Actions to perform on some zone 'z' when current zone hits the threshold:
63  * Increment counter of zone 'z'
64  */
65 #define BWMON_ZONE_ACTIONS_INCREMENT(z)		(0x2 << ((z) * 2))
66 /* Clear counter of zone 'z' */
67 #define BWMON_ZONE_ACTIONS_CLEAR(z)		(0x1 << ((z) * 2))
68 
69 /* Zone 0 threshold hit: Clear zone count */
70 #define BWMON_ZONE_ACTIONS_ZONE0		(BWMON_ZONE_ACTIONS_CLEAR(0))
71 
72 /* Zone 1 threshold hit: Increment zone count & clear lower zones */
73 #define BWMON_ZONE_ACTIONS_ZONE1		(BWMON_ZONE_ACTIONS_INCREMENT(1) | \
74 						 BWMON_ZONE_ACTIONS_CLEAR(0))
75 
76 /* Zone 2 threshold hit: Increment zone count & clear lower zones */
77 #define BWMON_ZONE_ACTIONS_ZONE2		(BWMON_ZONE_ACTIONS_INCREMENT(2) | \
78 						 BWMON_ZONE_ACTIONS_CLEAR(1) | \
79 						 BWMON_ZONE_ACTIONS_CLEAR(0))
80 
81 /* Zone 3 threshold hit: Increment zone count & clear lower zones */
82 #define BWMON_ZONE_ACTIONS_ZONE3		(BWMON_ZONE_ACTIONS_INCREMENT(3) | \
83 						 BWMON_ZONE_ACTIONS_CLEAR(2) | \
84 						 BWMON_ZONE_ACTIONS_CLEAR(1) | \
85 						 BWMON_ZONE_ACTIONS_CLEAR(0))
86 /* Value for BWMON_ZONE_ACTIONS */
87 #define BWMON_ZONE_ACTIONS_DEFAULT		(BWMON_ZONE_ACTIONS_ZONE0 | \
88 						 BWMON_ZONE_ACTIONS_ZONE1 << 8 | \
89 						 BWMON_ZONE_ACTIONS_ZONE2 << 16 | \
90 						 BWMON_ZONE_ACTIONS_ZONE3 << 24)
91 
92 /*
93  * There is no clear documentation/explanation of BWMON_THRESHOLD_COUNT
94  * register. Based on observations, this is number of times one threshold has to
95  * be reached, to trigger interrupt in given zone.
96  *
97  * 0xff are maximum values meant to ignore the zones 0 and 2.
98  */
99 #define BWMON_THRESHOLD_COUNT			0x2bc
100 #define BWMON_THRESHOLD_COUNT_ZONE1_SHIFT	8
101 #define BWMON_THRESHOLD_COUNT_ZONE2_SHIFT	16
102 #define BWMON_THRESHOLD_COUNT_ZONE3_SHIFT	24
103 #define BWMON_THRESHOLD_COUNT_ZONE0_DEFAULT	0xff
104 #define BWMON_THRESHOLD_COUNT_ZONE2_DEFAULT	0xff
105 
106 /* BWMONv4 count registers use count unit of 64 kB */
107 #define BWMON_COUNT_UNIT_KB			64
108 #define BWMON_ZONE_COUNT			0x2d8
109 #define BWMON_ZONE_MAX(zone)			(0x2e0 + 4 * (zone))
110 
111 struct icc_bwmon_data {
112 	unsigned int sample_ms;
113 	unsigned int default_highbw_kbps;
114 	unsigned int default_medbw_kbps;
115 	unsigned int default_lowbw_kbps;
116 	u8 zone1_thres_count;
117 	u8 zone3_thres_count;
118 };
119 
120 struct icc_bwmon {
121 	struct device *dev;
122 	void __iomem *base;
123 	int irq;
124 
125 	unsigned int default_lowbw_kbps;
126 	unsigned int sample_ms;
127 	unsigned int max_bw_kbps;
128 	unsigned int min_bw_kbps;
129 	unsigned int target_kbps;
130 	unsigned int current_kbps;
131 };
132 
133 static void bwmon_clear_counters(struct icc_bwmon *bwmon)
134 {
135 	/*
136 	 * Clear counters. The order and barriers are
137 	 * important. Quoting downstream Qualcomm msm-4.9 tree:
138 	 *
139 	 * The counter clear and IRQ clear bits are not in the same 4KB
140 	 * region. So, we need to make sure the counter clear is completed
141 	 * before we try to clear the IRQ or do any other counter operations.
142 	 */
143 	writel(BWMON_CLEAR_CLEAR, bwmon->base + BWMON_CLEAR);
144 }
145 
146 static void bwmon_clear_irq(struct icc_bwmon *bwmon)
147 {
148 	/*
149 	 * Clear zone and global interrupts. The order and barriers are
150 	 * important. Quoting downstream Qualcomm msm-4.9 tree:
151 	 *
152 	 * Synchronize the local interrupt clear in mon_irq_clear()
153 	 * with the global interrupt clear here. Otherwise, the CPU
154 	 * may reorder the two writes and clear the global interrupt
155 	 * before the local interrupt, causing the global interrupt
156 	 * to be retriggered by the local interrupt still being high.
157 	 *
158 	 * Similarly, because the global registers are in a different
159 	 * region than the local registers, we need to ensure any register
160 	 * writes to enable the monitor after this call are ordered with the
161 	 * clearing here so that local writes don't happen before the
162 	 * interrupt is cleared.
163 	 */
164 	writel(BWMON_IRQ_ENABLE_MASK, bwmon->base + BWMON_IRQ_CLEAR);
165 	writel(BIT(0), bwmon->base + BWMON_GLOBAL_IRQ_CLEAR);
166 }
167 
168 static void bwmon_disable(struct icc_bwmon *bwmon)
169 {
170 	/* Disable interrupts. Strict ordering, see bwmon_clear_irq(). */
171 	writel(0x0, bwmon->base + BWMON_GLOBAL_IRQ_ENABLE);
172 	writel(0x0, bwmon->base + BWMON_IRQ_ENABLE);
173 
174 	/*
175 	 * Disable bwmon. Must happen before bwmon_clear_irq() to avoid spurious
176 	 * IRQ.
177 	 */
178 	writel(0x0, bwmon->base + BWMON_ENABLE);
179 }
180 
181 static void bwmon_enable(struct icc_bwmon *bwmon, unsigned int irq_enable)
182 {
183 	/* Enable interrupts */
184 	writel(BWMON_GLOBAL_IRQ_ENABLE_ENABLE,
185 	       bwmon->base + BWMON_GLOBAL_IRQ_ENABLE);
186 	writel(irq_enable, bwmon->base + BWMON_IRQ_ENABLE);
187 
188 	/* Enable bwmon */
189 	writel(BWMON_ENABLE_ENABLE, bwmon->base + BWMON_ENABLE);
190 }
191 
192 static unsigned int bwmon_kbps_to_count(unsigned int kbps)
193 {
194 	return kbps / BWMON_COUNT_UNIT_KB;
195 }
196 
197 static void bwmon_set_threshold(struct icc_bwmon *bwmon, unsigned int reg,
198 				unsigned int kbps)
199 {
200 	unsigned int thres;
201 
202 	thres = mult_frac(bwmon_kbps_to_count(kbps), bwmon->sample_ms,
203 			  MSEC_PER_SEC);
204 	writel_relaxed(thres, bwmon->base + reg);
205 }
206 
207 static void bwmon_start(struct icc_bwmon *bwmon,
208 			const struct icc_bwmon_data *data)
209 {
210 	unsigned int thres_count;
211 	int window;
212 
213 	bwmon_clear_counters(bwmon);
214 
215 	window = mult_frac(bwmon->sample_ms, HW_TIMER_HZ, MSEC_PER_SEC);
216 	/* Maximum sampling window: 0xfffff */
217 	writel_relaxed(window, bwmon->base + BWMON_SAMPLE_WINDOW);
218 
219 	bwmon_set_threshold(bwmon, BWMON_THRESHOLD_HIGH,
220 			    data->default_highbw_kbps);
221 	bwmon_set_threshold(bwmon, BWMON_THRESHOLD_MED,
222 			    data->default_medbw_kbps);
223 	bwmon_set_threshold(bwmon, BWMON_THRESHOLD_LOW,
224 			    data->default_lowbw_kbps);
225 
226 	thres_count = data->zone3_thres_count << BWMON_THRESHOLD_COUNT_ZONE3_SHIFT |
227 		      BWMON_THRESHOLD_COUNT_ZONE2_DEFAULT << BWMON_THRESHOLD_COUNT_ZONE2_SHIFT |
228 		      data->zone1_thres_count << BWMON_THRESHOLD_COUNT_ZONE1_SHIFT |
229 		      BWMON_THRESHOLD_COUNT_ZONE0_DEFAULT;
230 	writel_relaxed(thres_count, bwmon->base + BWMON_THRESHOLD_COUNT);
231 	writel_relaxed(BWMON_ZONE_ACTIONS_DEFAULT,
232 		       bwmon->base + BWMON_ZONE_ACTIONS);
233 	/* Write barriers in bwmon_clear_irq() */
234 
235 	bwmon_clear_irq(bwmon);
236 	bwmon_enable(bwmon, BWMON_IRQ_ENABLE_MASK);
237 }
238 
239 static irqreturn_t bwmon_intr(int irq, void *dev_id)
240 {
241 	struct icc_bwmon *bwmon = dev_id;
242 	unsigned int status, max;
243 	int zone;
244 
245 	status = readl(bwmon->base + BWMON_IRQ_STATUS);
246 	status &= BWMON_IRQ_ENABLE_MASK;
247 	if (!status) {
248 		/*
249 		 * Only zone 1 and zone 3 interrupts are enabled but zone 2
250 		 * threshold could be hit and trigger interrupt even if not
251 		 * enabled.
252 		 * Such spurious interrupt might come with valuable max count or
253 		 * not, so solution would be to always check all
254 		 * BWMON_ZONE_MAX() registers to find the highest value.
255 		 * Such case is currently ignored.
256 		 */
257 		return IRQ_NONE;
258 	}
259 
260 	bwmon_disable(bwmon);
261 
262 	zone = get_bitmask_order(status >> BWMON_IRQ_STATUS_ZONE_SHIFT) - 1;
263 	/*
264 	 * Zone max bytes count register returns count units within sampling
265 	 * window.  Downstream kernel for BWMONv4 (called BWMON type 2 in
266 	 * downstream) always increments the max bytes count by one.
267 	 */
268 	max = readl(bwmon->base + BWMON_ZONE_MAX(zone)) + 1;
269 	max *= BWMON_COUNT_UNIT_KB;
270 	bwmon->target_kbps = mult_frac(max, MSEC_PER_SEC, bwmon->sample_ms);
271 
272 	return IRQ_WAKE_THREAD;
273 }
274 
275 static irqreturn_t bwmon_intr_thread(int irq, void *dev_id)
276 {
277 	struct icc_bwmon *bwmon = dev_id;
278 	unsigned int irq_enable = 0;
279 	struct dev_pm_opp *opp, *target_opp;
280 	unsigned int bw_kbps, up_kbps, down_kbps;
281 
282 	bw_kbps = bwmon->target_kbps;
283 
284 	target_opp = dev_pm_opp_find_bw_ceil(bwmon->dev, &bw_kbps, 0);
285 	if (IS_ERR(target_opp) && PTR_ERR(target_opp) == -ERANGE)
286 		target_opp = dev_pm_opp_find_bw_floor(bwmon->dev, &bw_kbps, 0);
287 
288 	bwmon->target_kbps = bw_kbps;
289 
290 	bw_kbps--;
291 	opp = dev_pm_opp_find_bw_floor(bwmon->dev, &bw_kbps, 0);
292 	if (IS_ERR(opp) && PTR_ERR(opp) == -ERANGE)
293 		down_kbps = bwmon->target_kbps;
294 	else
295 		down_kbps = bw_kbps;
296 
297 	up_kbps = bwmon->target_kbps + 1;
298 
299 	if (bwmon->target_kbps >= bwmon->max_bw_kbps)
300 		irq_enable = BIT(BWMON_IRQ_ENABLE_ZONE1_SHIFT);
301 	else if (bwmon->target_kbps <= bwmon->min_bw_kbps)
302 		irq_enable = BIT(BWMON_IRQ_ENABLE_ZONE3_SHIFT);
303 	else
304 		irq_enable = BWMON_IRQ_ENABLE_MASK;
305 
306 	bwmon_set_threshold(bwmon, BWMON_THRESHOLD_HIGH, up_kbps);
307 	bwmon_set_threshold(bwmon, BWMON_THRESHOLD_MED, down_kbps);
308 	/* Write barriers in bwmon_clear_counters() */
309 	bwmon_clear_counters(bwmon);
310 	bwmon_clear_irq(bwmon);
311 	bwmon_enable(bwmon, irq_enable);
312 
313 	if (bwmon->target_kbps == bwmon->current_kbps)
314 		goto out;
315 
316 	dev_pm_opp_set_opp(bwmon->dev, target_opp);
317 	bwmon->current_kbps = bwmon->target_kbps;
318 
319 out:
320 	dev_pm_opp_put(target_opp);
321 	if (!IS_ERR(opp))
322 		dev_pm_opp_put(opp);
323 
324 	return IRQ_HANDLED;
325 }
326 
327 static int bwmon_probe(struct platform_device *pdev)
328 {
329 	struct device *dev = &pdev->dev;
330 	struct dev_pm_opp *opp;
331 	struct icc_bwmon *bwmon;
332 	const struct icc_bwmon_data *data;
333 	int ret;
334 
335 	bwmon = devm_kzalloc(dev, sizeof(*bwmon), GFP_KERNEL);
336 	if (!bwmon)
337 		return -ENOMEM;
338 
339 	data = of_device_get_match_data(dev);
340 
341 	bwmon->base = devm_platform_ioremap_resource(pdev, 0);
342 	if (IS_ERR(bwmon->base)) {
343 		dev_err(dev, "failed to map bwmon registers\n");
344 		return PTR_ERR(bwmon->base);
345 	}
346 
347 	bwmon->irq = platform_get_irq(pdev, 0);
348 	if (bwmon->irq < 0)
349 		return bwmon->irq;
350 
351 	ret = devm_pm_opp_of_add_table(dev);
352 	if (ret)
353 		return dev_err_probe(dev, ret, "failed to add OPP table\n");
354 
355 	bwmon->max_bw_kbps = UINT_MAX;
356 	opp = dev_pm_opp_find_bw_floor(dev, &bwmon->max_bw_kbps, 0);
357 	if (IS_ERR(opp))
358 		return dev_err_probe(dev, ret, "failed to find max peak bandwidth\n");
359 
360 	bwmon->min_bw_kbps = 0;
361 	opp = dev_pm_opp_find_bw_ceil(dev, &bwmon->min_bw_kbps, 0);
362 	if (IS_ERR(opp))
363 		return dev_err_probe(dev, ret, "failed to find min peak bandwidth\n");
364 
365 	bwmon->sample_ms = data->sample_ms;
366 	bwmon->default_lowbw_kbps = data->default_lowbw_kbps;
367 	bwmon->dev = dev;
368 
369 	bwmon_disable(bwmon);
370 	ret = devm_request_threaded_irq(dev, bwmon->irq, bwmon_intr,
371 					bwmon_intr_thread,
372 					IRQF_ONESHOT, dev_name(dev), bwmon);
373 	if (ret)
374 		return dev_err_probe(dev, ret, "failed to request IRQ\n");
375 
376 	platform_set_drvdata(pdev, bwmon);
377 	bwmon_start(bwmon, data);
378 
379 	return 0;
380 }
381 
382 static int bwmon_remove(struct platform_device *pdev)
383 {
384 	struct icc_bwmon *bwmon = platform_get_drvdata(pdev);
385 
386 	bwmon_disable(bwmon);
387 
388 	return 0;
389 }
390 
391 /* BWMON v4 */
392 static const struct icc_bwmon_data msm8998_bwmon_data = {
393 	.sample_ms = 4,
394 	.default_highbw_kbps = 4800 * 1024, /* 4.8 GBps */
395 	.default_medbw_kbps = 512 * 1024, /* 512 MBps */
396 	.default_lowbw_kbps = 0,
397 	.zone1_thres_count = 16,
398 	.zone3_thres_count = 1,
399 };
400 
401 static const struct of_device_id bwmon_of_match[] = {
402 	{ .compatible = "qcom,msm8998-bwmon", .data = &msm8998_bwmon_data },
403 	{}
404 };
405 MODULE_DEVICE_TABLE(of, bwmon_of_match);
406 
407 static struct platform_driver bwmon_driver = {
408 	.probe = bwmon_probe,
409 	.remove = bwmon_remove,
410 	.driver = {
411 		.name = "qcom-bwmon",
412 		.of_match_table = bwmon_of_match,
413 	},
414 };
415 module_platform_driver(bwmon_driver);
416 
417 MODULE_AUTHOR("Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>");
418 MODULE_DESCRIPTION("QCOM BWMON driver");
419 MODULE_LICENSE("GPL");
420