1 /*
2 * Copyright (c) 2025, MediaTek Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <errno.h>
8 #include <lib/mmio.h>
9 #include <platform_def.h>
10
11 #include <mcupm_cfg.h>
12 #include "mt_cpu_pm_mbox.h"
13
14 #ifdef __GNUC__
15 #define mcdi_likely(x) __builtin_expect(!!(x), 1)
16 #define mcdi_unlikely(x) __builtin_expect(!!(x), 0)
17 #else
18 #define mcdi_likely(x) (x)
19 #define mcdi_unlikely(x) (x)
20 #endif /* __GNUC__ */
21
22 #define MCUPM_MBOX_3_BASE (CPU_EB_TCM_BASE + CPU_EB_MBOX3_OFFSET)
23
24 #define _mcupm_mbox_write(id, val) \
25 mmio_write_32(MCUPM_MBOX_3_BASE + 4 * (id), val)
26 #define _mcupm_mbox_read(id) \
27 mmio_read_32(MCUPM_MBOX_3_BASE + 4 * (id))
28
mtk_set_mcupm_pll_mode(unsigned int mode)29 void mtk_set_mcupm_pll_mode(unsigned int mode)
30 {
31 if (mode < NF_MCUPM_ARMPLL_MODE)
32 _mcupm_mbox_write(MCUPM_MBOX_ARMPLL_MODE, mode);
33 }
34
mtk_get_mcupm_pll_mode(void)35 int mtk_get_mcupm_pll_mode(void)
36 {
37 return _mcupm_mbox_read(MCUPM_MBOX_ARMPLL_MODE);
38 }
39
mtk_set_mcupm_buck_mode(unsigned int mode)40 void mtk_set_mcupm_buck_mode(unsigned int mode)
41 {
42 if (mode < NF_MCUPM_BUCK_MODE)
43 _mcupm_mbox_write(MCUPM_MBOX_BUCK_MODE, mode);
44 }
45
mtk_get_mcupm_buck_mode(void)46 int mtk_get_mcupm_buck_mode(void)
47 {
48 return _mcupm_mbox_read(MCUPM_MBOX_BUCK_MODE);
49 }
50
mtk_set_cpu_pm_preffered_cpu(unsigned int cpuid)51 void mtk_set_cpu_pm_preffered_cpu(unsigned int cpuid)
52 {
53 return _mcupm_mbox_write(MCUPM_MBOX_WAKEUP_CPU, cpuid);
54 }
55
mtk_get_cpu_pm_preffered_cpu(void)56 unsigned int mtk_get_cpu_pm_preffered_cpu(void)
57 {
58 return _mcupm_mbox_read(MCUPM_MBOX_WAKEUP_CPU);
59 }
60
mtk_wait_mbox_init_done(void)61 static int mtk_wait_mbox_init_done(void)
62 {
63 int sta = _mcupm_mbox_read(MCUPM_MBOX_TASK_STA);
64
65 if (sta != MCUPM_TASK_INIT)
66 return sta;
67
68 mtk_set_mcupm_pll_mode(MCUPM_ARMPLL_OFF);
69 mtk_set_mcupm_buck_mode(MCUPM_BUCK_OFF_MODE);
70
71 _mcupm_mbox_write(MCUPM_MBOX_PWR_CTRL_EN,
72 MCUPM_MCUSYS_CTRL |
73 MCUPM_CM_CTRL |
74 MCUPM_BUCK_CTRL |
75 MCUPM_ARMPLL_CTRL);
76
77 return sta;
78 }
79
mtk_lp_depd_condition(enum cpupm_mbox_depd_type type)80 int mtk_lp_depd_condition(enum cpupm_mbox_depd_type type)
81 {
82 int ret = 0, status = 0;
83
84 if (type == CPUPM_MBOX_WAIT_DEV_INIT) {
85 status = mtk_wait_mbox_init_done();
86 if (mcdi_unlikely(status != MCUPM_TASK_INIT))
87 ret = -ENXIO;
88 else
89 _mcupm_mbox_write(MCUPM_MBOX_AP_READY, 1);
90 } else if (type == CPUPM_MBOX_WAIT_TASK_READY) {
91 status = _mcupm_mbox_read(MCUPM_MBOX_TASK_STA);
92 if (mcdi_unlikely((status != MCUPM_TASK_WAIT) &&
93 (status != MCUPM_TASK_INIT_FINISH)))
94 ret = -ENXIO;
95 }
96 return ret;
97 }
98
mtk_set_mcupm_group_hint(unsigned int gmask)99 void mtk_set_mcupm_group_hint(unsigned int gmask)
100 {
101 _mcupm_mbox_write(MCUPM_MBOX_GROUP, gmask);
102 }
103