xref: /linux/drivers/soc/mediatek/mtk-dvfsrc.c (revision 1fd1dc41724319406b0aff221a352a400b0ddfc5)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2021 MediaTek Inc.
4  * Copyright (c) 2024 Collabora Ltd.
5  *                    AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
6  */
7 
8 #include <linux/arm-smccc.h>
9 #include <linux/bitfield.h>
10 #include <linux/clk.h>
11 #include <linux/iopoll.h>
12 #include <linux/module.h>
13 #include <linux/of.h>
14 #include <linux/of_platform.h>
15 #include <linux/platform_device.h>
16 #include <linux/soc/mediatek/dvfsrc.h>
17 #include <linux/soc/mediatek/mtk_sip_svc.h>
18 
19 /* DVFSRC_BASIC_CONTROL */
20 #define DVFSRC_V4_BASIC_CTRL_OPP_COUNT	GENMASK(26, 20)
21 
22 /* DVFSRC_LEVEL */
23 #define DVFSRC_V1_LEVEL_TARGET_LEVEL	GENMASK(15, 0)
24 #define DVFSRC_TGT_LEVEL_IDLE		0x00
25 #define DVFSRC_V1_LEVEL_CURRENT_LEVEL	GENMASK(31, 16)
26 
27 #define DVFSRC_V4_LEVEL_TARGET_LEVEL	GENMASK(15, 8)
28 #define DVFSRC_V4_LEVEL_TARGET_PRESENT	BIT(16)
29 
30 /* DVFSRC_SW_REQ, DVFSRC_SW_REQ2 */
31 #define DVFSRC_V1_SW_REQ2_DRAM_LEVEL	GENMASK(1, 0)
32 #define DVFSRC_V1_SW_REQ2_VCORE_LEVEL	GENMASK(3, 2)
33 
34 #define DVFSRC_V2_SW_REQ_DRAM_LEVEL	GENMASK(3, 0)
35 #define DVFSRC_V2_SW_REQ_VCORE_LEVEL	GENMASK(6, 4)
36 
37 #define DVFSRC_V4_SW_REQ_EMI_LEVEL	GENMASK(3, 0)
38 #define DVFSRC_V4_SW_REQ_DRAM_LEVEL	GENMASK(15, 12)
39 
40 /* DVFSRC_VCORE */
41 #define DVFSRC_V2_VCORE_REQ_VSCP_LEVEL	GENMASK(14, 12)
42 
43 /* DVFSRC_TARGET_GEAR */
44 #define DVFSRC_V4_GEAR_TARGET_DRAM	GENMASK(7, 0)
45 #define DVFSRC_V4_GEAR_TARGET_VCORE	GENMASK(15, 8)
46 
47 /* DVFSRC_GEAR_INFO */
48 #define DVFSRC_V4_GEAR_INFO_REG_WIDTH	0x4
49 #define DVFSRC_V4_GEAR_INFO_REG_LEVELS	64
50 #define DVFSRC_V4_GEAR_INFO_VCORE	GENMASK(3, 0)
51 #define DVFSRC_V4_GEAR_INFO_EMI		GENMASK(7, 4)
52 #define DVFSRC_V4_GEAR_INFO_DRAM	GENMASK(15, 12)
53 
54 #define DVFSRC_POLL_TIMEOUT_US		1000
55 #define STARTUP_TIME_US			1
56 
57 #define MTK_SIP_DVFSRC_INIT		0x0
58 #define MTK_SIP_DVFSRC_START		0x1
59 
60 enum mtk_dvfsrc_bw_type {
61 	DVFSRC_BW_AVG,
62 	DVFSRC_BW_PEAK,
63 	DVFSRC_BW_HRT,
64 	DVFSRC_BW_MAX,
65 };
66 
67 struct dvfsrc_opp {
68 	u32 vcore_opp;
69 	u32 dram_opp;
70 	u32 emi_opp;
71 };
72 
73 struct dvfsrc_opp_desc {
74 	const struct dvfsrc_opp *opps;
75 	u32 num_opp;
76 };
77 
78 struct dvfsrc_soc_data;
79 struct mtk_dvfsrc {
80 	struct device *dev;
81 	struct clk *clk;
82 	struct platform_device *icc;
83 	struct platform_device *regulator;
84 	const struct dvfsrc_soc_data *dvd;
85 	const struct dvfsrc_opp_desc *curr_opps;
86 	void __iomem *regs;
87 	int dram_type;
88 };
89 
90 struct dvfsrc_soc_data {
91 	const int *regs;
92 	const u8 *bw_units;
93 	const bool has_emi_ddr;
94 	const struct dvfsrc_opp_desc *opps_desc;
95 	u32 (*calc_dram_bw)(struct mtk_dvfsrc *dvfsrc, enum mtk_dvfsrc_bw_type type, u64 bw);
96 	u32 (*get_target_level)(struct mtk_dvfsrc *dvfsrc);
97 	u32 (*get_current_level)(struct mtk_dvfsrc *dvfsrc);
98 	u32 (*get_vcore_level)(struct mtk_dvfsrc *dvfsrc);
99 	u32 (*get_vscp_level)(struct mtk_dvfsrc *dvfsrc);
100 	u32 (*get_opp_count)(struct mtk_dvfsrc *dvfsrc);
101 	int (*get_hw_opps)(struct mtk_dvfsrc *dvfsrc);
102 	void (*set_dram_bw)(struct mtk_dvfsrc *dvfsrc, u64 bw);
103 	void (*set_dram_peak_bw)(struct mtk_dvfsrc *dvfsrc, u64 bw);
104 	void (*set_dram_hrt_bw)(struct mtk_dvfsrc *dvfsrc, u64 bw);
105 	void (*set_opp_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
106 	void (*set_vcore_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
107 	void (*set_vscp_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
108 	int (*wait_for_opp_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
109 	int (*wait_for_vcore_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
110 
111 	/**
112 	 * @bw_max_constraints - array of maximum bandwidth for this hardware
113 	 *
114 	 * indexed by &enum mtk_dvfsrc_bw_type, storing the maximum permissible
115 	 * hardware value for each bandwidth type.
116 	 */
117 	const u32 *const bw_max_constraints;
118 
119 	/**
120 	 * @bw_min_constraints - array of minimum bandwidth for this hardware
121 	 *
122 	 * indexed by &enum mtk_dvfsrc_bw_type, storing the minimum permissible
123 	 * hardware value for each bandwidth type.
124 	 */
125 	const u32 *const bw_min_constraints;
126 };
127 
128 static u32 dvfsrc_readl(struct mtk_dvfsrc *dvfs, u32 offset)
129 {
130 	return readl(dvfs->regs + dvfs->dvd->regs[offset]);
131 }
132 
133 static void dvfsrc_writel(struct mtk_dvfsrc *dvfs, u32 offset, u32 val)
134 {
135 	writel(val, dvfs->regs + dvfs->dvd->regs[offset]);
136 }
137 
138 enum dvfsrc_regs {
139 	DVFSRC_BASIC_CONTROL,
140 	DVFSRC_SW_REQ,
141 	DVFSRC_SW_REQ2,
142 	DVFSRC_LEVEL,
143 	DVFSRC_TARGET_LEVEL,
144 	DVFSRC_SW_BW,
145 	DVFSRC_SW_PEAK_BW,
146 	DVFSRC_SW_HRT_BW,
147 	DVFSRC_SW_EMI_BW,
148 	DVFSRC_VCORE,
149 	DVFSRC_TARGET_GEAR,
150 	DVFSRC_GEAR_INFO_L,
151 	DVFSRC_GEAR_INFO_H,
152 	DVFSRC_REGS_MAX,
153 };
154 
155 static const int dvfsrc_mt8183_regs[] = {
156 	[DVFSRC_SW_REQ] = 0x4,
157 	[DVFSRC_SW_REQ2] = 0x8,
158 	[DVFSRC_LEVEL] = 0xDC,
159 	[DVFSRC_SW_BW] = 0x160,
160 };
161 
162 static const int dvfsrc_mt8195_regs[] = {
163 	[DVFSRC_SW_REQ] = 0xc,
164 	[DVFSRC_VCORE] = 0x6c,
165 	[DVFSRC_SW_PEAK_BW] = 0x278,
166 	[DVFSRC_SW_BW] = 0x26c,
167 	[DVFSRC_SW_HRT_BW] = 0x290,
168 	[DVFSRC_LEVEL] = 0xd44,
169 	[DVFSRC_TARGET_LEVEL] = 0xd48,
170 };
171 
172 static const int dvfsrc_mt8196_regs[] = {
173 	[DVFSRC_BASIC_CONTROL] = 0x0,
174 	[DVFSRC_SW_REQ] = 0x18,
175 	[DVFSRC_VCORE] = 0x80,
176 	[DVFSRC_GEAR_INFO_L] = 0xfc,
177 	[DVFSRC_SW_BW] = 0x1e8,
178 	[DVFSRC_SW_PEAK_BW] = 0x1f4,
179 	[DVFSRC_SW_HRT_BW] = 0x20c,
180 	[DVFSRC_LEVEL] = 0x5f0,
181 	[DVFSRC_TARGET_LEVEL] = 0x5f0,
182 	[DVFSRC_SW_REQ2] = 0x604,
183 	[DVFSRC_SW_EMI_BW] = 0x60c,
184 	[DVFSRC_TARGET_GEAR] = 0x6ac,
185 	[DVFSRC_GEAR_INFO_H] = 0x6b0,
186 };
187 
188 static const struct dvfsrc_opp *dvfsrc_get_current_opp(struct mtk_dvfsrc *dvfsrc)
189 {
190 	u32 level = dvfsrc->dvd->get_current_level(dvfsrc);
191 
192 	return &dvfsrc->curr_opps->opps[level];
193 }
194 
195 static u32 dvfsrc_get_current_target_vcore_gear(struct mtk_dvfsrc *dvfsrc)
196 {
197 	u32 val = dvfsrc_readl(dvfsrc, DVFSRC_TARGET_GEAR);
198 
199 	return FIELD_GET(DVFSRC_V4_GEAR_TARGET_VCORE, val);
200 }
201 
202 static u32 dvfsrc_get_current_target_dram_gear(struct mtk_dvfsrc *dvfsrc)
203 {
204 	u32 val = dvfsrc_readl(dvfsrc, DVFSRC_TARGET_GEAR);
205 
206 	return FIELD_GET(DVFSRC_V4_GEAR_TARGET_DRAM, val);
207 }
208 
209 static bool dvfsrc_is_idle(struct mtk_dvfsrc *dvfsrc)
210 {
211 	if (!dvfsrc->dvd->get_target_level)
212 		return true;
213 
214 	return dvfsrc->dvd->get_target_level(dvfsrc) == DVFSRC_TGT_LEVEL_IDLE;
215 }
216 
217 static int dvfsrc_wait_for_vcore_level_v1(struct mtk_dvfsrc *dvfsrc, u32 level)
218 {
219 	const struct dvfsrc_opp *curr;
220 
221 	return readx_poll_timeout_atomic(dvfsrc_get_current_opp, dvfsrc, curr,
222 					 curr->vcore_opp >= level, STARTUP_TIME_US,
223 					 DVFSRC_POLL_TIMEOUT_US);
224 }
225 
226 static int dvfsrc_wait_for_opp_level_v1(struct mtk_dvfsrc *dvfsrc, u32 level)
227 {
228 	const struct dvfsrc_opp *target, *curr;
229 	int ret;
230 
231 	target = &dvfsrc->curr_opps->opps[level];
232 	ret = readx_poll_timeout_atomic(dvfsrc_get_current_opp, dvfsrc, curr,
233 					curr->dram_opp >= target->dram_opp &&
234 					curr->vcore_opp >= target->vcore_opp,
235 					STARTUP_TIME_US, DVFSRC_POLL_TIMEOUT_US);
236 	if (ret < 0) {
237 		dev_warn(dvfsrc->dev,
238 			 "timeout! target OPP: %u, dram: %d, vcore: %d\n", level,
239 			 curr->dram_opp, curr->vcore_opp);
240 		return ret;
241 	}
242 
243 	return 0;
244 }
245 
246 static int dvfsrc_wait_for_opp_level_v2(struct mtk_dvfsrc *dvfsrc, u32 level)
247 {
248 	const struct dvfsrc_opp *target, *curr;
249 	int ret;
250 
251 	target = &dvfsrc->curr_opps->opps[level];
252 	ret = readx_poll_timeout_atomic(dvfsrc_get_current_opp, dvfsrc, curr,
253 					curr->dram_opp >= target->dram_opp &&
254 					curr->vcore_opp >= target->vcore_opp,
255 					STARTUP_TIME_US, DVFSRC_POLL_TIMEOUT_US);
256 	if (ret < 0) {
257 		dev_warn(dvfsrc->dev,
258 			 "timeout! target OPP: %u, dram: %d\n", level, curr->dram_opp);
259 		return ret;
260 	}
261 
262 	return 0;
263 }
264 
265 static int dvfsrc_wait_for_vcore_level_v4(struct mtk_dvfsrc *dvfsrc, u32 level)
266 {
267 	u32 val;
268 
269 	return readx_poll_timeout_atomic(dvfsrc_get_current_target_vcore_gear,
270 					 dvfsrc, val, val >= level,
271 					 STARTUP_TIME_US, DVFSRC_POLL_TIMEOUT_US);
272 }
273 
274 static int dvfsrc_wait_for_opp_level_v4(struct mtk_dvfsrc *dvfsrc, u32 level)
275 {
276 	u32 val;
277 
278 	return readx_poll_timeout_atomic(dvfsrc_get_current_target_dram_gear,
279 					 dvfsrc, val, val >= level,
280 					 STARTUP_TIME_US, DVFSRC_POLL_TIMEOUT_US);
281 }
282 
283 static u32 dvfsrc_get_target_level_v1(struct mtk_dvfsrc *dvfsrc)
284 {
285 	u32 val = dvfsrc_readl(dvfsrc, DVFSRC_LEVEL);
286 
287 	return FIELD_GET(DVFSRC_V1_LEVEL_TARGET_LEVEL, val);
288 }
289 
290 static u32 dvfsrc_get_current_level_v1(struct mtk_dvfsrc *dvfsrc)
291 {
292 	u32 val = dvfsrc_readl(dvfsrc, DVFSRC_LEVEL);
293 	u32 current_level = FIELD_GET(DVFSRC_V1_LEVEL_CURRENT_LEVEL, val);
294 
295 	return ffs(current_level) - 1;
296 }
297 
298 static u32 dvfsrc_get_target_level_v2(struct mtk_dvfsrc *dvfsrc)
299 {
300 	return dvfsrc_readl(dvfsrc, DVFSRC_TARGET_LEVEL);
301 }
302 
303 static u32 dvfsrc_get_current_level_v2(struct mtk_dvfsrc *dvfsrc)
304 {
305 	u32 val = dvfsrc_readl(dvfsrc, DVFSRC_LEVEL);
306 	u32 level = ffs(val);
307 
308 	/* Valid levels */
309 	if (level < dvfsrc->curr_opps->num_opp)
310 		return dvfsrc->curr_opps->num_opp - level;
311 
312 	/* Zero for level 0 or invalid level */
313 	return 0;
314 }
315 
316 static u32 dvfsrc_get_target_level_v4(struct mtk_dvfsrc *dvfsrc)
317 {
318 	u32 val = dvfsrc_readl(dvfsrc, DVFSRC_TARGET_LEVEL);
319 
320 	if (val & DVFSRC_V4_LEVEL_TARGET_PRESENT)
321 		return FIELD_GET(DVFSRC_V4_LEVEL_TARGET_LEVEL, val) + 1;
322 	return 0;
323 }
324 
325 static u32 dvfsrc_get_current_level_v4(struct mtk_dvfsrc *dvfsrc)
326 {
327 	u32 level = dvfsrc_readl(dvfsrc, DVFSRC_LEVEL) + 1;
328 
329 	/* Valid levels */
330 	if (level < dvfsrc->curr_opps->num_opp)
331 		return dvfsrc->curr_opps->num_opp - level;
332 
333 	/* Zero for level 0 or invalid level */
334 	return 0;
335 }
336 
337 static u32 dvfsrc_get_vcore_level_v1(struct mtk_dvfsrc *dvfsrc)
338 {
339 	u32 val = dvfsrc_readl(dvfsrc, DVFSRC_SW_REQ2);
340 
341 	return FIELD_GET(DVFSRC_V1_SW_REQ2_VCORE_LEVEL, val);
342 }
343 
344 static void dvfsrc_set_vcore_level_v1(struct mtk_dvfsrc *dvfsrc, u32 level)
345 {
346 	u32 val = dvfsrc_readl(dvfsrc, DVFSRC_SW_REQ2);
347 
348 	val &= ~DVFSRC_V1_SW_REQ2_VCORE_LEVEL;
349 	val |= FIELD_PREP(DVFSRC_V1_SW_REQ2_VCORE_LEVEL, level);
350 
351 	dvfsrc_writel(dvfsrc, DVFSRC_SW_REQ2, val);
352 }
353 
354 static u32 dvfsrc_get_vcore_level_v2(struct mtk_dvfsrc *dvfsrc)
355 {
356 	u32 val = dvfsrc_readl(dvfsrc, DVFSRC_SW_REQ);
357 
358 	return FIELD_GET(DVFSRC_V2_SW_REQ_VCORE_LEVEL, val);
359 }
360 
361 static void dvfsrc_set_vcore_level_v2(struct mtk_dvfsrc *dvfsrc, u32 level)
362 {
363 	u32 val = dvfsrc_readl(dvfsrc, DVFSRC_SW_REQ);
364 
365 	val &= ~DVFSRC_V2_SW_REQ_VCORE_LEVEL;
366 	val |= FIELD_PREP(DVFSRC_V2_SW_REQ_VCORE_LEVEL, level);
367 
368 	dvfsrc_writel(dvfsrc, DVFSRC_SW_REQ, val);
369 }
370 
371 static u32 dvfsrc_get_vscp_level_v2(struct mtk_dvfsrc *dvfsrc)
372 {
373 	u32 val = dvfsrc_readl(dvfsrc, DVFSRC_VCORE);
374 
375 	return FIELD_GET(DVFSRC_V2_VCORE_REQ_VSCP_LEVEL, val);
376 }
377 
378 static void dvfsrc_set_vscp_level_v2(struct mtk_dvfsrc *dvfsrc, u32 level)
379 {
380 	u32 val = dvfsrc_readl(dvfsrc, DVFSRC_VCORE);
381 
382 	val &= ~DVFSRC_V2_VCORE_REQ_VSCP_LEVEL;
383 	val |= FIELD_PREP(DVFSRC_V2_VCORE_REQ_VSCP_LEVEL, level);
384 
385 	dvfsrc_writel(dvfsrc, DVFSRC_VCORE, val);
386 }
387 
388 static u32 dvfsrc_get_opp_count_v4(struct mtk_dvfsrc *dvfsrc)
389 {
390 	u32 val = dvfsrc_readl(dvfsrc, DVFSRC_BASIC_CONTROL);
391 
392 	return FIELD_GET(DVFSRC_V4_BASIC_CTRL_OPP_COUNT, val) + 1;
393 }
394 
395 static u32
396 dvfsrc_calc_dram_bw_v1(struct mtk_dvfsrc *dvfsrc, enum mtk_dvfsrc_bw_type type, u64 bw)
397 {
398 	return clamp_val(div_u64(bw, 100 * 1000), dvfsrc->dvd->bw_min_constraints[type],
399 			 dvfsrc->dvd->bw_max_constraints[type]);
400 }
401 
402 /**
403  * dvfsrc_calc_dram_bw_v4 - convert kbps to hardware register bandwidth value
404  * @dvfsrc: pointer to the &struct mtk_dvfsrc of this driver instance
405  * @type: one of %DVFSRC_BW_AVG, %DVFSRC_BW_PEAK, or %DVFSRC_BW_HRT
406  * @bw: the bandwidth in kilobits per second
407  *
408  * Returns the hardware register value appropriate for expressing @bw, clamped
409  * to hardware limits.
410  */
411 static u32
412 dvfsrc_calc_dram_bw_v4(struct mtk_dvfsrc *dvfsrc, enum mtk_dvfsrc_bw_type type, u64 bw)
413 {
414 	u8 bw_unit = dvfsrc->dvd->bw_units[type];
415 	u64 bw_mbps;
416 	u32 bw_hw;
417 
418 	if (type < DVFSRC_BW_AVG || type >= DVFSRC_BW_MAX)
419 		return 0;
420 
421 	bw_mbps = div_u64(bw, 1000);
422 	bw_hw = div_u64((bw_mbps + bw_unit - 1), bw_unit);
423 	return clamp_val(bw_hw, dvfsrc->dvd->bw_min_constraints[type],
424 			 dvfsrc->dvd->bw_max_constraints[type]);
425 }
426 
427 static void __dvfsrc_set_dram_bw_v1(struct mtk_dvfsrc *dvfsrc, u32 reg,
428 				    enum mtk_dvfsrc_bw_type type, u64 bw)
429 {
430 	u32 bw_hw = dvfsrc->dvd->calc_dram_bw(dvfsrc, type, bw);
431 
432 	dvfsrc_writel(dvfsrc, reg, bw_hw);
433 
434 	if (type == DVFSRC_BW_AVG && dvfsrc->dvd->has_emi_ddr)
435 		dvfsrc_writel(dvfsrc, DVFSRC_SW_EMI_BW, bw_hw);
436 }
437 
438 static void dvfsrc_set_dram_bw_v1(struct mtk_dvfsrc *dvfsrc, u64 bw)
439 {
440 	__dvfsrc_set_dram_bw_v1(dvfsrc, DVFSRC_SW_BW, DVFSRC_BW_AVG, bw);
441 };
442 
443 static void dvfsrc_set_dram_peak_bw_v1(struct mtk_dvfsrc *dvfsrc, u64 bw)
444 {
445 	__dvfsrc_set_dram_bw_v1(dvfsrc, DVFSRC_SW_PEAK_BW, DVFSRC_BW_PEAK, bw);
446 }
447 
448 static void dvfsrc_set_dram_hrt_bw_v1(struct mtk_dvfsrc *dvfsrc, u64 bw)
449 {
450 	__dvfsrc_set_dram_bw_v1(dvfsrc, DVFSRC_SW_HRT_BW, DVFSRC_BW_HRT, bw);
451 }
452 
453 static void dvfsrc_set_opp_level_v1(struct mtk_dvfsrc *dvfsrc, u32 level)
454 {
455 	const struct dvfsrc_opp *opp = &dvfsrc->curr_opps->opps[level];
456 	u32 val;
457 
458 	/* Translate Pstate to DVFSRC level and set it to DVFSRC HW */
459 	val = FIELD_PREP(DVFSRC_V1_SW_REQ2_DRAM_LEVEL, opp->dram_opp);
460 	val |= FIELD_PREP(DVFSRC_V1_SW_REQ2_VCORE_LEVEL, opp->vcore_opp);
461 
462 	dev_dbg(dvfsrc->dev, "vcore_opp: %d, dram_opp: %d\n", opp->vcore_opp, opp->dram_opp);
463 	dvfsrc_writel(dvfsrc, DVFSRC_SW_REQ, val);
464 }
465 
466 static u32 dvfsrc_get_opp_gear(struct mtk_dvfsrc *dvfsrc, u8 level)
467 {
468 	u32 reg_ofst, val;
469 	u8 idx;
470 
471 	/* Calculate register offset and index for requested gear */
472 	if (level < DVFSRC_V4_GEAR_INFO_REG_LEVELS) {
473 		reg_ofst = dvfsrc->dvd->regs[DVFSRC_GEAR_INFO_L];
474 		idx = level;
475 	} else {
476 		reg_ofst = dvfsrc->dvd->regs[DVFSRC_GEAR_INFO_H];
477 		idx = level - DVFSRC_V4_GEAR_INFO_REG_LEVELS;
478 	}
479 	reg_ofst += DVFSRC_V4_GEAR_INFO_REG_WIDTH * (level / 2);
480 
481 	/* Read the corresponding gear register */
482 	val = readl(dvfsrc->regs + reg_ofst);
483 
484 	/* Each register contains two sets of data, 16 bits per gear */
485 	val >>= 16 * (idx % 2);
486 
487 	return val;
488 }
489 
490 static int dvfsrc_get_hw_opps_v4(struct mtk_dvfsrc *dvfsrc)
491 {
492 	struct dvfsrc_opp *dvfsrc_opps;
493 	struct dvfsrc_opp_desc *desc;
494 	u32 num_opps, gear_info;
495 	u8 num_vcore, num_dram;
496 	u8 num_emi;
497 	int i;
498 
499 	num_opps = dvfsrc_get_opp_count_v4(dvfsrc);
500 	if (num_opps == 0) {
501 		dev_err(dvfsrc->dev, "No OPPs programmed in DVFSRC MCU.\n");
502 		return -EINVAL;
503 	}
504 
505 	/*
506 	 * The first 16 bits set in the gear info table says how many OPPs
507 	 * and how many vcore, dram and emi table entries are available.
508 	 */
509 	gear_info = dvfsrc_readl(dvfsrc, DVFSRC_GEAR_INFO_L);
510 	if (gear_info == 0) {
511 		dev_err(dvfsrc->dev, "No gear info in DVFSRC MCU.\n");
512 		return -EINVAL;
513 	}
514 
515 	num_vcore = FIELD_GET(DVFSRC_V4_GEAR_INFO_VCORE, gear_info) + 1;
516 	num_dram = FIELD_GET(DVFSRC_V4_GEAR_INFO_DRAM, gear_info) + 1;
517 	num_emi = FIELD_GET(DVFSRC_V4_GEAR_INFO_EMI, gear_info) + 1;
518 	dev_info(dvfsrc->dev,
519 		 "Discovered %u gears and %u vcore, %u dram, %u emi table entries.\n",
520 		 num_opps, num_vcore, num_dram, num_emi);
521 
522 	/* Allocate everything now as anything else after that cannot fail */
523 	desc = devm_kzalloc(dvfsrc->dev, sizeof(*desc), GFP_KERNEL);
524 	if (!desc)
525 		return -ENOMEM;
526 
527 	dvfsrc_opps = devm_kcalloc(dvfsrc->dev, num_opps + 1,
528 				   sizeof(*dvfsrc_opps), GFP_KERNEL);
529 	if (!dvfsrc_opps)
530 		return -ENOMEM;
531 
532 	/* Read the OPP table gear indices */
533 	for (i = 0; i <= num_opps; i++) {
534 		gear_info = dvfsrc_get_opp_gear(dvfsrc, num_opps - i);
535 		dvfsrc_opps[i].vcore_opp = FIELD_GET(DVFSRC_V4_GEAR_INFO_VCORE, gear_info);
536 		dvfsrc_opps[i].dram_opp = FIELD_GET(DVFSRC_V4_GEAR_INFO_DRAM, gear_info);
537 		dvfsrc_opps[i].emi_opp = FIELD_GET(DVFSRC_V4_GEAR_INFO_EMI, gear_info);
538 	};
539 	desc->num_opp = num_opps + 1;
540 	desc->opps = dvfsrc_opps;
541 
542 	/* Assign to main structure now that everything is done! */
543 	dvfsrc->curr_opps = desc;
544 
545 	return 0;
546 }
547 
548 static void dvfsrc_set_dram_level_v4(struct mtk_dvfsrc *dvfsrc, u32 level)
549 {
550 	u32 val = dvfsrc_readl(dvfsrc, DVFSRC_SW_REQ);
551 
552 	val &= ~DVFSRC_V4_SW_REQ_DRAM_LEVEL;
553 	val |= FIELD_PREP(DVFSRC_V4_SW_REQ_DRAM_LEVEL, level);
554 
555 	dev_dbg(dvfsrc->dev, "%s level=%u\n", __func__, level);
556 
557 	dvfsrc_writel(dvfsrc, DVFSRC_SW_REQ, val);
558 }
559 
560 int mtk_dvfsrc_send_request(const struct device *dev, u32 cmd, u64 data)
561 {
562 	struct mtk_dvfsrc *dvfsrc = dev_get_drvdata(dev);
563 	bool state;
564 	int ret;
565 
566 	dev_dbg(dvfsrc->dev, "cmd: %d, data: %llu\n", cmd, data);
567 
568 	switch (cmd) {
569 	case MTK_DVFSRC_CMD_BW:
570 		dvfsrc->dvd->set_dram_bw(dvfsrc, data);
571 		return 0;
572 	case MTK_DVFSRC_CMD_HRT_BW:
573 		if (dvfsrc->dvd->set_dram_hrt_bw)
574 			dvfsrc->dvd->set_dram_hrt_bw(dvfsrc, data);
575 		return 0;
576 	case MTK_DVFSRC_CMD_PEAK_BW:
577 		if (dvfsrc->dvd->set_dram_peak_bw)
578 			dvfsrc->dvd->set_dram_peak_bw(dvfsrc, data);
579 		return 0;
580 	case MTK_DVFSRC_CMD_OPP:
581 		if (!dvfsrc->dvd->set_opp_level)
582 			return 0;
583 
584 		dvfsrc->dvd->set_opp_level(dvfsrc, data);
585 		break;
586 	case MTK_DVFSRC_CMD_VCORE_LEVEL:
587 		dvfsrc->dvd->set_vcore_level(dvfsrc, data);
588 		break;
589 	case MTK_DVFSRC_CMD_VSCP_LEVEL:
590 		if (!dvfsrc->dvd->set_vscp_level)
591 			return 0;
592 
593 		dvfsrc->dvd->set_vscp_level(dvfsrc, data);
594 		break;
595 	default:
596 		dev_err(dvfsrc->dev, "unknown command: %d\n", cmd);
597 		return -EOPNOTSUPP;
598 	}
599 
600 	/* DVFSRC needs at least 2T(~196ns) to handle a request */
601 	udelay(STARTUP_TIME_US);
602 
603 	ret = readx_poll_timeout_atomic(dvfsrc_is_idle, dvfsrc, state, state,
604 					STARTUP_TIME_US, DVFSRC_POLL_TIMEOUT_US);
605 	if (ret < 0) {
606 		dev_warn(dvfsrc->dev,
607 			 "%d: idle timeout, data: %llu, last: %d -> %d\n", cmd, data,
608 			 dvfsrc->dvd->get_current_level(dvfsrc),
609 			 dvfsrc->dvd->get_target_level(dvfsrc));
610 		return ret;
611 	}
612 
613 	if (cmd == MTK_DVFSRC_CMD_OPP)
614 		ret = dvfsrc->dvd->wait_for_opp_level(dvfsrc, data);
615 	else
616 		ret = dvfsrc->dvd->wait_for_vcore_level(dvfsrc, data);
617 
618 	if (ret < 0) {
619 		dev_warn(dvfsrc->dev,
620 			 "%d: wait timeout, data: %llu, last: %d -> %d\n",
621 			 cmd, data,
622 			 dvfsrc->dvd->get_current_level(dvfsrc),
623 			 dvfsrc->dvd->get_target_level(dvfsrc));
624 		return ret;
625 	}
626 
627 	return 0;
628 }
629 EXPORT_SYMBOL(mtk_dvfsrc_send_request);
630 
631 int mtk_dvfsrc_query_info(const struct device *dev, u32 cmd, int *data)
632 {
633 	struct mtk_dvfsrc *dvfsrc = dev_get_drvdata(dev);
634 
635 	switch (cmd) {
636 	case MTK_DVFSRC_CMD_VCORE_LEVEL:
637 		*data = dvfsrc->dvd->get_vcore_level(dvfsrc);
638 		break;
639 	case MTK_DVFSRC_CMD_VSCP_LEVEL:
640 		*data = dvfsrc->dvd->get_vscp_level(dvfsrc);
641 		break;
642 	default:
643 		return -EOPNOTSUPP;
644 	}
645 
646 	return 0;
647 }
648 EXPORT_SYMBOL(mtk_dvfsrc_query_info);
649 
650 static int mtk_dvfsrc_probe(struct platform_device *pdev)
651 {
652 	struct arm_smccc_res ares;
653 	struct mtk_dvfsrc *dvfsrc;
654 	int ret;
655 
656 	dvfsrc = devm_kzalloc(&pdev->dev, sizeof(*dvfsrc), GFP_KERNEL);
657 	if (!dvfsrc)
658 		return -ENOMEM;
659 
660 	dvfsrc->dvd = of_device_get_match_data(&pdev->dev);
661 	dvfsrc->dev = &pdev->dev;
662 
663 	dvfsrc->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
664 	if (IS_ERR(dvfsrc->regs))
665 		return PTR_ERR(dvfsrc->regs);
666 
667 	dvfsrc->clk = devm_clk_get_enabled(&pdev->dev, NULL);
668 	if (IS_ERR(dvfsrc->clk))
669 		return dev_err_probe(&pdev->dev, PTR_ERR(dvfsrc->clk),
670 				     "Couldn't get and enable DVFSRC clock\n");
671 
672 	arm_smccc_smc(MTK_SIP_DVFSRC_VCOREFS_CONTROL, MTK_SIP_DVFSRC_INIT,
673 		      0, 0, 0, 0, 0, 0, &ares);
674 	if (ares.a0)
675 		return dev_err_probe(&pdev->dev, -EINVAL, "DVFSRC init failed: %lu\n", ares.a0);
676 
677 	dvfsrc->dram_type = ares.a1;
678 	dev_dbg(&pdev->dev, "DRAM Type: %d\n", dvfsrc->dram_type);
679 
680 	/* Newer versions of the DVFSRC MCU have pre-programmed gear tables */
681 	if (dvfsrc->dvd->get_hw_opps) {
682 		ret = dvfsrc->dvd->get_hw_opps(dvfsrc);
683 		if (ret)
684 			return ret;
685 	} else {
686 		dvfsrc->curr_opps = &dvfsrc->dvd->opps_desc[dvfsrc->dram_type];
687 	}
688 	platform_set_drvdata(pdev, dvfsrc);
689 
690 	ret = devm_of_platform_populate(&pdev->dev);
691 	if (ret)
692 		return dev_err_probe(&pdev->dev, ret, "Failed to populate child devices\n");
693 
694 	/* Everything is set up - make it run! */
695 	arm_smccc_smc(MTK_SIP_DVFSRC_VCOREFS_CONTROL, MTK_SIP_DVFSRC_START,
696 		      0, 0, 0, 0, 0, 0, &ares);
697 	if (ares.a0 & BIT(0))
698 		return dev_err_probe(&pdev->dev, -EINVAL, "Cannot start DVFSRC: %lu\n", ares.a0);
699 
700 	return 0;
701 }
702 
703 static const u32 dvfsrc_bw_min_constr_none[DVFSRC_BW_MAX] = {
704 	[DVFSRC_BW_AVG] = 0,
705 	[DVFSRC_BW_PEAK] = 0,
706 	[DVFSRC_BW_HRT] = 0,
707 };
708 
709 static const u32 dvfsrc_bw_max_constr_v1[DVFSRC_BW_MAX] = {
710 	[DVFSRC_BW_AVG] = U32_MAX,
711 	[DVFSRC_BW_PEAK] = U32_MAX,
712 	[DVFSRC_BW_HRT] = U32_MAX,
713 };
714 
715 static const u32 dvfsrc_bw_max_constr_v2[DVFSRC_BW_MAX] = {
716 	[DVFSRC_BW_AVG] = 65535,
717 	[DVFSRC_BW_PEAK] = 65535,
718 	[DVFSRC_BW_HRT] = 1023,
719 };
720 
721 static const struct dvfsrc_opp dvfsrc_opp_mt6893_lp4[] = {
722 	{ 0, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 },
723 	{ 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 },
724 	{ 0, 2 }, { 1, 2 }, { 2, 2 }, { 3, 2 },
725 	{ 0, 3 }, { 1, 3 }, { 2, 3 }, { 3, 3 },
726 	{ 1, 4 }, { 2, 4 }, { 3, 4 }, { 2, 5 },
727 	{ 3, 5 }, { 3, 6 }, { 4, 6 }, { 4, 7 },
728 };
729 
730 static const struct dvfsrc_opp_desc dvfsrc_opp_mt6893_desc[] = {
731 	[0] = {
732 		.opps = dvfsrc_opp_mt6893_lp4,
733 		.num_opp = ARRAY_SIZE(dvfsrc_opp_mt6893_lp4),
734 	}
735 };
736 
737 static const struct dvfsrc_soc_data mt6893_data = {
738 	.opps_desc = dvfsrc_opp_mt6893_desc,
739 	.regs = dvfsrc_mt8195_regs,
740 	.get_target_level = dvfsrc_get_target_level_v2,
741 	.get_current_level = dvfsrc_get_current_level_v2,
742 	.get_vcore_level = dvfsrc_get_vcore_level_v2,
743 	.get_vscp_level = dvfsrc_get_vscp_level_v2,
744 	.set_dram_bw = dvfsrc_set_dram_bw_v1,
745 	.set_dram_peak_bw = dvfsrc_set_dram_peak_bw_v1,
746 	.set_dram_hrt_bw = dvfsrc_set_dram_hrt_bw_v1,
747 	.set_vcore_level = dvfsrc_set_vcore_level_v2,
748 	.set_vscp_level = dvfsrc_set_vscp_level_v2,
749 	.wait_for_opp_level = dvfsrc_wait_for_opp_level_v2,
750 	.wait_for_vcore_level = dvfsrc_wait_for_vcore_level_v1,
751 	.bw_max_constraints = dvfsrc_bw_max_constr_v2,
752 	.bw_min_constraints = dvfsrc_bw_min_constr_none,
753 };
754 
755 static const struct dvfsrc_opp dvfsrc_opp_mt8183_lp4[] = {
756 	{ 0, 0 }, { 0, 1 }, { 0, 2 }, { 1, 2 },
757 };
758 
759 static const struct dvfsrc_opp dvfsrc_opp_mt8183_lp3[] = {
760 	{ 0, 0 }, { 0, 1 }, { 1, 1 }, { 1, 2 },
761 };
762 
763 static const struct dvfsrc_opp_desc dvfsrc_opp_mt8183_desc[] = {
764 	[0] = {
765 		.opps = dvfsrc_opp_mt8183_lp4,
766 		.num_opp = ARRAY_SIZE(dvfsrc_opp_mt8183_lp4),
767 	},
768 	[1] = {
769 		.opps = dvfsrc_opp_mt8183_lp3,
770 		.num_opp = ARRAY_SIZE(dvfsrc_opp_mt8183_lp3),
771 	},
772 	[2] = {
773 		.opps = dvfsrc_opp_mt8183_lp3,
774 		.num_opp = ARRAY_SIZE(dvfsrc_opp_mt8183_lp3),
775 	}
776 };
777 
778 static const struct dvfsrc_soc_data mt8183_data = {
779 	.opps_desc = dvfsrc_opp_mt8183_desc,
780 	.regs = dvfsrc_mt8183_regs,
781 	.calc_dram_bw = dvfsrc_calc_dram_bw_v1,
782 	.get_target_level = dvfsrc_get_target_level_v1,
783 	.get_current_level = dvfsrc_get_current_level_v1,
784 	.get_vcore_level = dvfsrc_get_vcore_level_v1,
785 	.set_dram_bw = dvfsrc_set_dram_bw_v1,
786 	.set_opp_level = dvfsrc_set_opp_level_v1,
787 	.set_vcore_level = dvfsrc_set_vcore_level_v1,
788 	.wait_for_opp_level = dvfsrc_wait_for_opp_level_v1,
789 	.wait_for_vcore_level = dvfsrc_wait_for_vcore_level_v1,
790 	.bw_max_constraints = dvfsrc_bw_max_constr_v1,
791 	.bw_min_constraints = dvfsrc_bw_min_constr_none,
792 };
793 
794 static const struct dvfsrc_opp dvfsrc_opp_mt8195_lp4[] = {
795 	{ 0, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 },
796 	{ 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 },
797 	{ 0, 2 }, { 1, 2 }, { 2, 2 }, { 3, 2 },
798 	{ 1, 3 }, { 2, 3 }, { 3, 3 }, { 1, 4 },
799 	{ 2, 4 }, { 3, 4 }, { 2, 5 }, { 3, 5 },
800 	{ 3, 6 },
801 };
802 
803 static const struct dvfsrc_opp_desc dvfsrc_opp_mt8195_desc[] = {
804 	[0] = {
805 		.opps = dvfsrc_opp_mt8195_lp4,
806 		.num_opp = ARRAY_SIZE(dvfsrc_opp_mt8195_lp4),
807 	}
808 };
809 
810 static const struct dvfsrc_soc_data mt8195_data = {
811 	.opps_desc = dvfsrc_opp_mt8195_desc,
812 	.regs = dvfsrc_mt8195_regs,
813 	.calc_dram_bw = dvfsrc_calc_dram_bw_v1,
814 	.get_target_level = dvfsrc_get_target_level_v2,
815 	.get_current_level = dvfsrc_get_current_level_v2,
816 	.get_vcore_level = dvfsrc_get_vcore_level_v2,
817 	.get_vscp_level = dvfsrc_get_vscp_level_v2,
818 	.set_dram_bw = dvfsrc_set_dram_bw_v1,
819 	.set_dram_peak_bw = dvfsrc_set_dram_peak_bw_v1,
820 	.set_dram_hrt_bw = dvfsrc_set_dram_hrt_bw_v1,
821 	.set_vcore_level = dvfsrc_set_vcore_level_v2,
822 	.set_vscp_level = dvfsrc_set_vscp_level_v2,
823 	.wait_for_opp_level = dvfsrc_wait_for_opp_level_v2,
824 	.wait_for_vcore_level = dvfsrc_wait_for_vcore_level_v1,
825 	.bw_max_constraints = dvfsrc_bw_max_constr_v2,
826 	.bw_min_constraints = dvfsrc_bw_min_constr_none,
827 };
828 
829 static const u8 mt8196_bw_units[] = {
830 	[DVFSRC_BW_AVG] = 64,
831 	[DVFSRC_BW_PEAK] = 64,
832 	[DVFSRC_BW_HRT] = 30,
833 };
834 
835 static const struct dvfsrc_soc_data mt8196_data = {
836 	.regs = dvfsrc_mt8196_regs,
837 	.bw_units = mt8196_bw_units,
838 	.has_emi_ddr = true,
839 	.get_target_level = dvfsrc_get_target_level_v4,
840 	.get_current_level = dvfsrc_get_current_level_v4,
841 	.get_vcore_level = dvfsrc_get_vcore_level_v2,
842 	.get_vscp_level = dvfsrc_get_vscp_level_v2,
843 	.get_opp_count = dvfsrc_get_opp_count_v4,
844 	.get_hw_opps = dvfsrc_get_hw_opps_v4,
845 	.calc_dram_bw = dvfsrc_calc_dram_bw_v4,
846 	.set_dram_bw = dvfsrc_set_dram_bw_v1,
847 	.set_dram_peak_bw = dvfsrc_set_dram_peak_bw_v1,
848 	.set_dram_hrt_bw = dvfsrc_set_dram_hrt_bw_v1,
849 	.set_opp_level = dvfsrc_set_dram_level_v4,
850 	.set_vcore_level = dvfsrc_set_vcore_level_v2,
851 	.set_vscp_level = dvfsrc_set_vscp_level_v2,
852 	.wait_for_opp_level = dvfsrc_wait_for_opp_level_v4,
853 	.wait_for_vcore_level = dvfsrc_wait_for_vcore_level_v4,
854 	.bw_max_constraints = dvfsrc_bw_max_constr_v2,
855 	.bw_min_constraints = dvfsrc_bw_min_constr_none,
856 };
857 
858 static const struct of_device_id mtk_dvfsrc_of_match[] = {
859 	{ .compatible = "mediatek,mt6893-dvfsrc", .data = &mt6893_data },
860 	{ .compatible = "mediatek,mt8183-dvfsrc", .data = &mt8183_data },
861 	{ .compatible = "mediatek,mt8195-dvfsrc", .data = &mt8195_data },
862 	{ .compatible = "mediatek,mt8196-dvfsrc", .data = &mt8196_data },
863 	{ /* sentinel */ }
864 };
865 
866 static struct platform_driver mtk_dvfsrc_driver = {
867 	.probe	= mtk_dvfsrc_probe,
868 	.driver = {
869 		.name = "mtk-dvfsrc",
870 		.of_match_table = mtk_dvfsrc_of_match,
871 	},
872 };
873 module_platform_driver(mtk_dvfsrc_driver);
874 
875 MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>");
876 MODULE_AUTHOR("Dawei Chien <dawei.chien@mediatek.com>");
877 MODULE_LICENSE("GPL");
878 MODULE_DESCRIPTION("MediaTek DVFSRC driver");
879