1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2021 MediaTek Inc.
4 * Copyright (c) 2024 Collabora Ltd.
5 * AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
8 #include <linux/arm-smccc.h>
9 #include <linux/bitfield.h>
10 #include <linux/iopoll.h>
11 #include <linux/module.h>
13 #include <linux/of_platform.h>
14 #include <linux/platform_device.h>
15 #include <linux/soc/mediatek/dvfsrc.h>
16 #include <linux/soc/mediatek/mtk_sip_svc.h>
19 #define DVFSRC_V1_LEVEL_TARGET_LEVEL GENMASK(15, 0)
20 #define DVFSRC_TGT_LEVEL_IDLE 0x00
21 #define DVFSRC_V1_LEVEL_CURRENT_LEVEL GENMASK(31, 16)
23 /* DVFSRC_SW_REQ, DVFSRC_SW_REQ2 */
24 #define DVFSRC_V1_SW_REQ2_DRAM_LEVEL GENMASK(1, 0)
25 #define DVFSRC_V1_SW_REQ2_VCORE_LEVEL GENMASK(3, 2)
27 #define DVFSRC_V2_SW_REQ_DRAM_LEVEL GENMASK(3, 0)
28 #define DVFSRC_V2_SW_REQ_VCORE_LEVEL GENMASK(6, 4)
31 #define DVFSRC_V2_VCORE_REQ_VSCP_LEVEL GENMASK(14, 12)
33 #define DVFSRC_POLL_TIMEOUT_US 1000
34 #define STARTUP_TIME_US 1
36 #define MTK_SIP_DVFSRC_INIT 0x0
37 #define MTK_SIP_DVFSRC_START 0x1
39 struct dvfsrc_bw_constraints
{
50 struct dvfsrc_opp_desc
{
51 const struct dvfsrc_opp
*opps
;
55 struct dvfsrc_soc_data
;
58 struct platform_device
*icc
;
59 struct platform_device
*regulator
;
60 const struct dvfsrc_soc_data
*dvd
;
61 const struct dvfsrc_opp_desc
*curr_opps
;
66 struct dvfsrc_soc_data
{
68 const struct dvfsrc_opp_desc
*opps_desc
;
69 u32 (*get_target_level
)(struct mtk_dvfsrc
*dvfsrc
);
70 u32 (*get_current_level
)(struct mtk_dvfsrc
*dvfsrc
);
71 u32 (*get_vcore_level
)(struct mtk_dvfsrc
*dvfsrc
);
72 u32 (*get_vscp_level
)(struct mtk_dvfsrc
*dvfsrc
);
73 void (*set_dram_bw
)(struct mtk_dvfsrc
*dvfsrc
, u64 bw
);
74 void (*set_dram_peak_bw
)(struct mtk_dvfsrc
*dvfsrc
, u64 bw
);
75 void (*set_dram_hrt_bw
)(struct mtk_dvfsrc
*dvfsrc
, u64 bw
);
76 void (*set_opp_level
)(struct mtk_dvfsrc
*dvfsrc
, u32 level
);
77 void (*set_vcore_level
)(struct mtk_dvfsrc
*dvfsrc
, u32 level
);
78 void (*set_vscp_level
)(struct mtk_dvfsrc
*dvfsrc
, u32 level
);
79 int (*wait_for_opp_level
)(struct mtk_dvfsrc
*dvfsrc
, u32 level
);
80 int (*wait_for_vcore_level
)(struct mtk_dvfsrc
*dvfsrc
, u32 level
);
81 const struct dvfsrc_bw_constraints
*bw_constraints
;
84 static u32
dvfsrc_readl(struct mtk_dvfsrc
*dvfs
, u32 offset
)
86 return readl(dvfs
->regs
+ dvfs
->dvd
->regs
[offset
]);
89 static void dvfsrc_writel(struct mtk_dvfsrc
*dvfs
, u32 offset
, u32 val
)
91 writel(val
, dvfs
->regs
+ dvfs
->dvd
->regs
[offset
]);
106 static const int dvfsrc_mt8183_regs
[] = {
107 [DVFSRC_SW_REQ
] = 0x4,
108 [DVFSRC_SW_REQ2
] = 0x8,
109 [DVFSRC_LEVEL
] = 0xDC,
110 [DVFSRC_SW_BW
] = 0x160,
113 static const int dvfsrc_mt8195_regs
[] = {
114 [DVFSRC_SW_REQ
] = 0xc,
115 [DVFSRC_VCORE
] = 0x6c,
116 [DVFSRC_SW_PEAK_BW
] = 0x278,
117 [DVFSRC_SW_BW
] = 0x26c,
118 [DVFSRC_SW_HRT_BW
] = 0x290,
119 [DVFSRC_LEVEL
] = 0xd44,
120 [DVFSRC_TARGET_LEVEL
] = 0xd48,
123 static const struct dvfsrc_opp
*dvfsrc_get_current_opp(struct mtk_dvfsrc
*dvfsrc
)
125 u32 level
= dvfsrc
->dvd
->get_current_level(dvfsrc
);
127 return &dvfsrc
->curr_opps
->opps
[level
];
130 static bool dvfsrc_is_idle(struct mtk_dvfsrc
*dvfsrc
)
132 if (!dvfsrc
->dvd
->get_target_level
)
135 return dvfsrc
->dvd
->get_target_level(dvfsrc
) == DVFSRC_TGT_LEVEL_IDLE
;
138 static int dvfsrc_wait_for_vcore_level_v1(struct mtk_dvfsrc
*dvfsrc
, u32 level
)
140 const struct dvfsrc_opp
*curr
;
142 return readx_poll_timeout_atomic(dvfsrc_get_current_opp
, dvfsrc
, curr
,
143 curr
->vcore_opp
>= level
, STARTUP_TIME_US
,
144 DVFSRC_POLL_TIMEOUT_US
);
147 static int dvfsrc_wait_for_opp_level_v1(struct mtk_dvfsrc
*dvfsrc
, u32 level
)
149 const struct dvfsrc_opp
*target
, *curr
;
152 target
= &dvfsrc
->curr_opps
->opps
[level
];
153 ret
= readx_poll_timeout_atomic(dvfsrc_get_current_opp
, dvfsrc
, curr
,
154 curr
->dram_opp
>= target
->dram_opp
&&
155 curr
->vcore_opp
>= target
->vcore_opp
,
156 STARTUP_TIME_US
, DVFSRC_POLL_TIMEOUT_US
);
158 dev_warn(dvfsrc
->dev
,
159 "timeout! target OPP: %u, dram: %d, vcore: %d\n", level
,
160 curr
->dram_opp
, curr
->vcore_opp
);
167 static int dvfsrc_wait_for_opp_level_v2(struct mtk_dvfsrc
*dvfsrc
, u32 level
)
169 const struct dvfsrc_opp
*target
, *curr
;
172 target
= &dvfsrc
->curr_opps
->opps
[level
];
173 ret
= readx_poll_timeout_atomic(dvfsrc_get_current_opp
, dvfsrc
, curr
,
174 curr
->dram_opp
>= target
->dram_opp
&&
175 curr
->vcore_opp
>= target
->vcore_opp
,
176 STARTUP_TIME_US
, DVFSRC_POLL_TIMEOUT_US
);
178 dev_warn(dvfsrc
->dev
,
179 "timeout! target OPP: %u, dram: %d\n", level
, curr
->dram_opp
);
186 static u32
dvfsrc_get_target_level_v1(struct mtk_dvfsrc
*dvfsrc
)
188 u32 val
= dvfsrc_readl(dvfsrc
, DVFSRC_LEVEL
);
190 return FIELD_GET(DVFSRC_V1_LEVEL_TARGET_LEVEL
, val
);
193 static u32
dvfsrc_get_current_level_v1(struct mtk_dvfsrc
*dvfsrc
)
195 u32 val
= dvfsrc_readl(dvfsrc
, DVFSRC_LEVEL
);
196 u32 current_level
= FIELD_GET(DVFSRC_V1_LEVEL_CURRENT_LEVEL
, val
);
198 return ffs(current_level
) - 1;
201 static u32
dvfsrc_get_target_level_v2(struct mtk_dvfsrc
*dvfsrc
)
203 return dvfsrc_readl(dvfsrc
, DVFSRC_TARGET_LEVEL
);
206 static u32
dvfsrc_get_current_level_v2(struct mtk_dvfsrc
*dvfsrc
)
208 u32 val
= dvfsrc_readl(dvfsrc
, DVFSRC_LEVEL
);
209 u32 level
= ffs(val
);
212 if (level
< dvfsrc
->curr_opps
->num_opp
)
213 return dvfsrc
->curr_opps
->num_opp
- level
;
215 /* Zero for level 0 or invalid level */
219 static u32
dvfsrc_get_vcore_level_v1(struct mtk_dvfsrc
*dvfsrc
)
221 u32 val
= dvfsrc_readl(dvfsrc
, DVFSRC_SW_REQ2
);
223 return FIELD_GET(DVFSRC_V1_SW_REQ2_VCORE_LEVEL
, val
);
226 static void dvfsrc_set_vcore_level_v1(struct mtk_dvfsrc
*dvfsrc
, u32 level
)
228 u32 val
= dvfsrc_readl(dvfsrc
, DVFSRC_SW_REQ2
);
230 val
&= ~DVFSRC_V1_SW_REQ2_VCORE_LEVEL
;
231 val
|= FIELD_PREP(DVFSRC_V1_SW_REQ2_VCORE_LEVEL
, level
);
233 dvfsrc_writel(dvfsrc
, DVFSRC_SW_REQ2
, val
);
236 static u32
dvfsrc_get_vcore_level_v2(struct mtk_dvfsrc
*dvfsrc
)
238 u32 val
= dvfsrc_readl(dvfsrc
, DVFSRC_SW_REQ
);
240 return FIELD_GET(DVFSRC_V2_SW_REQ_VCORE_LEVEL
, val
);
243 static void dvfsrc_set_vcore_level_v2(struct mtk_dvfsrc
*dvfsrc
, u32 level
)
245 u32 val
= dvfsrc_readl(dvfsrc
, DVFSRC_SW_REQ
);
247 val
&= ~DVFSRC_V2_SW_REQ_VCORE_LEVEL
;
248 val
|= FIELD_PREP(DVFSRC_V2_SW_REQ_VCORE_LEVEL
, level
);
250 dvfsrc_writel(dvfsrc
, DVFSRC_SW_REQ
, val
);
253 static u32
dvfsrc_get_vscp_level_v2(struct mtk_dvfsrc
*dvfsrc
)
255 u32 val
= dvfsrc_readl(dvfsrc
, DVFSRC_VCORE
);
257 return FIELD_GET(DVFSRC_V2_VCORE_REQ_VSCP_LEVEL
, val
);
260 static void dvfsrc_set_vscp_level_v2(struct mtk_dvfsrc
*dvfsrc
, u32 level
)
262 u32 val
= dvfsrc_readl(dvfsrc
, DVFSRC_VCORE
);
264 val
&= ~DVFSRC_V2_VCORE_REQ_VSCP_LEVEL
;
265 val
|= FIELD_PREP(DVFSRC_V2_VCORE_REQ_VSCP_LEVEL
, level
);
267 dvfsrc_writel(dvfsrc
, DVFSRC_VCORE
, val
);
270 static void __dvfsrc_set_dram_bw_v1(struct mtk_dvfsrc
*dvfsrc
, u32 reg
,
271 u16 max_bw
, u16 min_bw
, u64 bw
)
273 u32 new_bw
= (u32
)div_u64(bw
, 100 * 1000);
275 /* If bw constraints (in mbps) are defined make sure to respect them */
277 new_bw
= min(new_bw
, max_bw
);
278 if (min_bw
&& new_bw
> 0)
279 new_bw
= max(new_bw
, min_bw
);
281 dvfsrc_writel(dvfsrc
, reg
, new_bw
);
284 static void dvfsrc_set_dram_bw_v1(struct mtk_dvfsrc
*dvfsrc
, u64 bw
)
286 u64 max_bw
= dvfsrc
->dvd
->bw_constraints
->max_dram_nom_bw
;
288 __dvfsrc_set_dram_bw_v1(dvfsrc
, DVFSRC_SW_BW
, max_bw
, 0, bw
);
291 static void dvfsrc_set_dram_peak_bw_v1(struct mtk_dvfsrc
*dvfsrc
, u64 bw
)
293 u64 max_bw
= dvfsrc
->dvd
->bw_constraints
->max_dram_peak_bw
;
295 __dvfsrc_set_dram_bw_v1(dvfsrc
, DVFSRC_SW_PEAK_BW
, max_bw
, 0, bw
);
298 static void dvfsrc_set_dram_hrt_bw_v1(struct mtk_dvfsrc
*dvfsrc
, u64 bw
)
300 u64 max_bw
= dvfsrc
->dvd
->bw_constraints
->max_dram_hrt_bw
;
302 __dvfsrc_set_dram_bw_v1(dvfsrc
, DVFSRC_SW_HRT_BW
, max_bw
, 0, bw
);
305 static void dvfsrc_set_opp_level_v1(struct mtk_dvfsrc
*dvfsrc
, u32 level
)
307 const struct dvfsrc_opp
*opp
= &dvfsrc
->curr_opps
->opps
[level
];
310 /* Translate Pstate to DVFSRC level and set it to DVFSRC HW */
311 val
= FIELD_PREP(DVFSRC_V1_SW_REQ2_DRAM_LEVEL
, opp
->dram_opp
);
312 val
|= FIELD_PREP(DVFSRC_V1_SW_REQ2_VCORE_LEVEL
, opp
->vcore_opp
);
314 dev_dbg(dvfsrc
->dev
, "vcore_opp: %d, dram_opp: %d\n", opp
->vcore_opp
, opp
->dram_opp
);
315 dvfsrc_writel(dvfsrc
, DVFSRC_SW_REQ
, val
);
318 int mtk_dvfsrc_send_request(const struct device
*dev
, u32 cmd
, u64 data
)
320 struct mtk_dvfsrc
*dvfsrc
= dev_get_drvdata(dev
);
324 dev_dbg(dvfsrc
->dev
, "cmd: %d, data: %llu\n", cmd
, data
);
327 case MTK_DVFSRC_CMD_BW
:
328 dvfsrc
->dvd
->set_dram_bw(dvfsrc
, data
);
330 case MTK_DVFSRC_CMD_HRT_BW
:
331 if (dvfsrc
->dvd
->set_dram_hrt_bw
)
332 dvfsrc
->dvd
->set_dram_hrt_bw(dvfsrc
, data
);
334 case MTK_DVFSRC_CMD_PEAK_BW
:
335 if (dvfsrc
->dvd
->set_dram_peak_bw
)
336 dvfsrc
->dvd
->set_dram_peak_bw(dvfsrc
, data
);
338 case MTK_DVFSRC_CMD_OPP
:
339 if (!dvfsrc
->dvd
->set_opp_level
)
342 dvfsrc
->dvd
->set_opp_level(dvfsrc
, data
);
344 case MTK_DVFSRC_CMD_VCORE_LEVEL
:
345 dvfsrc
->dvd
->set_vcore_level(dvfsrc
, data
);
347 case MTK_DVFSRC_CMD_VSCP_LEVEL
:
348 if (!dvfsrc
->dvd
->set_vscp_level
)
351 dvfsrc
->dvd
->set_vscp_level(dvfsrc
, data
);
354 dev_err(dvfsrc
->dev
, "unknown command: %d\n", cmd
);
358 /* DVFSRC needs at least 2T(~196ns) to handle a request */
359 udelay(STARTUP_TIME_US
);
361 ret
= readx_poll_timeout_atomic(dvfsrc_is_idle
, dvfsrc
, state
, state
,
362 STARTUP_TIME_US
, DVFSRC_POLL_TIMEOUT_US
);
364 dev_warn(dvfsrc
->dev
,
365 "%d: idle timeout, data: %llu, last: %d -> %d\n", cmd
, data
,
366 dvfsrc
->dvd
->get_current_level(dvfsrc
),
367 dvfsrc
->dvd
->get_target_level(dvfsrc
));
371 if (cmd
== MTK_DVFSRC_CMD_OPP
)
372 ret
= dvfsrc
->dvd
->wait_for_opp_level(dvfsrc
, data
);
374 ret
= dvfsrc
->dvd
->wait_for_vcore_level(dvfsrc
, data
);
377 dev_warn(dvfsrc
->dev
,
378 "%d: wait timeout, data: %llu, last: %d -> %d\n",
380 dvfsrc
->dvd
->get_current_level(dvfsrc
),
381 dvfsrc
->dvd
->get_target_level(dvfsrc
));
387 EXPORT_SYMBOL(mtk_dvfsrc_send_request
);
389 int mtk_dvfsrc_query_info(const struct device
*dev
, u32 cmd
, int *data
)
391 struct mtk_dvfsrc
*dvfsrc
= dev_get_drvdata(dev
);
394 case MTK_DVFSRC_CMD_VCORE_LEVEL
:
395 *data
= dvfsrc
->dvd
->get_vcore_level(dvfsrc
);
397 case MTK_DVFSRC_CMD_VSCP_LEVEL
:
398 *data
= dvfsrc
->dvd
->get_vscp_level(dvfsrc
);
406 EXPORT_SYMBOL(mtk_dvfsrc_query_info
);
408 static int mtk_dvfsrc_probe(struct platform_device
*pdev
)
410 struct arm_smccc_res ares
;
411 struct mtk_dvfsrc
*dvfsrc
;
414 dvfsrc
= devm_kzalloc(&pdev
->dev
, sizeof(*dvfsrc
), GFP_KERNEL
);
418 dvfsrc
->dvd
= of_device_get_match_data(&pdev
->dev
);
419 dvfsrc
->dev
= &pdev
->dev
;
421 dvfsrc
->regs
= devm_platform_get_and_ioremap_resource(pdev
, 0, NULL
);
422 if (IS_ERR(dvfsrc
->regs
))
423 return PTR_ERR(dvfsrc
->regs
);
425 arm_smccc_smc(MTK_SIP_DVFSRC_VCOREFS_CONTROL
, MTK_SIP_DVFSRC_INIT
,
426 0, 0, 0, 0, 0, 0, &ares
);
428 return dev_err_probe(&pdev
->dev
, -EINVAL
, "DVFSRC init failed: %lu\n", ares
.a0
);
430 dvfsrc
->dram_type
= ares
.a1
;
431 dev_dbg(&pdev
->dev
, "DRAM Type: %d\n", dvfsrc
->dram_type
);
433 dvfsrc
->curr_opps
= &dvfsrc
->dvd
->opps_desc
[dvfsrc
->dram_type
];
434 platform_set_drvdata(pdev
, dvfsrc
);
436 ret
= devm_of_platform_populate(&pdev
->dev
);
438 return dev_err_probe(&pdev
->dev
, ret
, "Failed to populate child devices\n");
440 /* Everything is set up - make it run! */
441 arm_smccc_smc(MTK_SIP_DVFSRC_VCOREFS_CONTROL
, MTK_SIP_DVFSRC_START
,
442 0, 0, 0, 0, 0, 0, &ares
);
444 return dev_err_probe(&pdev
->dev
, -EINVAL
, "Cannot start DVFSRC: %lu\n", ares
.a0
);
449 static const struct dvfsrc_opp dvfsrc_opp_mt8183_lp4
[] = {
450 { 0, 0 }, { 0, 1 }, { 0, 2 }, { 1, 2 },
453 static const struct dvfsrc_opp dvfsrc_opp_mt8183_lp3
[] = {
454 { 0, 0 }, { 0, 1 }, { 1, 1 }, { 1, 2 },
457 static const struct dvfsrc_opp_desc dvfsrc_opp_mt8183_desc
[] = {
459 .opps
= dvfsrc_opp_mt8183_lp4
,
460 .num_opp
= ARRAY_SIZE(dvfsrc_opp_mt8183_lp4
),
463 .opps
= dvfsrc_opp_mt8183_lp3
,
464 .num_opp
= ARRAY_SIZE(dvfsrc_opp_mt8183_lp3
),
467 .opps
= dvfsrc_opp_mt8183_lp3
,
468 .num_opp
= ARRAY_SIZE(dvfsrc_opp_mt8183_lp3
),
472 static const struct dvfsrc_bw_constraints dvfsrc_bw_constr_mt8183
= { 0, 0, 0 };
474 static const struct dvfsrc_soc_data mt8183_data
= {
475 .opps_desc
= dvfsrc_opp_mt8183_desc
,
476 .regs
= dvfsrc_mt8183_regs
,
477 .get_target_level
= dvfsrc_get_target_level_v1
,
478 .get_current_level
= dvfsrc_get_current_level_v1
,
479 .get_vcore_level
= dvfsrc_get_vcore_level_v1
,
480 .set_dram_bw
= dvfsrc_set_dram_bw_v1
,
481 .set_opp_level
= dvfsrc_set_opp_level_v1
,
482 .set_vcore_level
= dvfsrc_set_vcore_level_v1
,
483 .wait_for_opp_level
= dvfsrc_wait_for_opp_level_v1
,
484 .wait_for_vcore_level
= dvfsrc_wait_for_vcore_level_v1
,
485 .bw_constraints
= &dvfsrc_bw_constr_mt8183
,
488 static const struct dvfsrc_opp dvfsrc_opp_mt8195_lp4
[] = {
489 { 0, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 },
490 { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 },
491 { 0, 2 }, { 1, 2 }, { 2, 2 }, { 3, 2 },
492 { 1, 3 }, { 2, 3 }, { 3, 3 }, { 1, 4 },
493 { 2, 4 }, { 3, 4 }, { 2, 5 }, { 3, 5 },
497 static const struct dvfsrc_opp_desc dvfsrc_opp_mt8195_desc
[] = {
499 .opps
= dvfsrc_opp_mt8195_lp4
,
500 .num_opp
= ARRAY_SIZE(dvfsrc_opp_mt8195_lp4
),
504 static const struct dvfsrc_bw_constraints dvfsrc_bw_constr_mt8195
= {
505 .max_dram_nom_bw
= 255,
506 .max_dram_peak_bw
= 255,
507 .max_dram_hrt_bw
= 1023,
510 static const struct dvfsrc_soc_data mt8195_data
= {
511 .opps_desc
= dvfsrc_opp_mt8195_desc
,
512 .regs
= dvfsrc_mt8195_regs
,
513 .get_target_level
= dvfsrc_get_target_level_v2
,
514 .get_current_level
= dvfsrc_get_current_level_v2
,
515 .get_vcore_level
= dvfsrc_get_vcore_level_v2
,
516 .get_vscp_level
= dvfsrc_get_vscp_level_v2
,
517 .set_dram_bw
= dvfsrc_set_dram_bw_v1
,
518 .set_dram_peak_bw
= dvfsrc_set_dram_peak_bw_v1
,
519 .set_dram_hrt_bw
= dvfsrc_set_dram_hrt_bw_v1
,
520 .set_vcore_level
= dvfsrc_set_vcore_level_v2
,
521 .set_vscp_level
= dvfsrc_set_vscp_level_v2
,
522 .wait_for_opp_level
= dvfsrc_wait_for_opp_level_v2
,
523 .wait_for_vcore_level
= dvfsrc_wait_for_vcore_level_v1
,
524 .bw_constraints
= &dvfsrc_bw_constr_mt8195
,
527 static const struct of_device_id mtk_dvfsrc_of_match
[] = {
528 { .compatible
= "mediatek,mt8183-dvfsrc", .data
= &mt8183_data
},
529 { .compatible
= "mediatek,mt8195-dvfsrc", .data
= &mt8195_data
},
533 static struct platform_driver mtk_dvfsrc_driver
= {
534 .probe
= mtk_dvfsrc_probe
,
536 .name
= "mtk-dvfsrc",
537 .of_match_table
= mtk_dvfsrc_of_match
,
540 module_platform_driver(mtk_dvfsrc_driver
);
542 MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>");
543 MODULE_AUTHOR("Dawei Chien <dawei.chien@mediatek.com>");
544 MODULE_LICENSE("GPL");
545 MODULE_DESCRIPTION("MediaTek DVFSRC driver");