1 /*
2 * Copyright (c) 2022, MediaTek Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <errno.h>
8
9 #include <lib/mmio.h>
10
11 #include "mt_cpu_pm_mbox.h"
12 #include <platform_def.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
21
22 #define MCUPM_MBOX_3_BASE (CPU_EB_TCM_BASE + CPU_EB_MBOX3_OFFSET)
23 #define MCUPM_MBOX_WRITE(id, val) mmio_write_32(MCUPM_MBOX_3_BASE + 4 * (id), val)
24 #define MCUPM_MBOX_READ(id) mmio_read_32(MCUPM_MBOX_3_BASE + 4 * (id))
25
mtk_set_mcupm_pll_mode(unsigned int mode)26 void mtk_set_mcupm_pll_mode(unsigned int mode)
27 {
28 if (mode < NF_MCUPM_ARMPLL_MODE) {
29 MCUPM_MBOX_WRITE(MCUPM_MBOX_ARMPLL_MODE, mode);
30 }
31 }
32
mtk_get_mcupm_pll_mode(void)33 int mtk_get_mcupm_pll_mode(void)
34 {
35 return MCUPM_MBOX_READ(MCUPM_MBOX_ARMPLL_MODE);
36 }
37
mtk_set_mcupm_buck_mode(unsigned int mode)38 void mtk_set_mcupm_buck_mode(unsigned int mode)
39 {
40 if (mode < NF_MCUPM_BUCK_MODE) {
41 MCUPM_MBOX_WRITE(MCUPM_MBOX_BUCK_MODE, mode);
42 }
43 }
44
mtk_get_mcupm_buck_mode(void)45 int mtk_get_mcupm_buck_mode(void)
46 {
47 return MCUPM_MBOX_READ(MCUPM_MBOX_BUCK_MODE);
48 }
49
mtk_set_cpu_pm_preffered_cpu(unsigned int cpuid)50 void mtk_set_cpu_pm_preffered_cpu(unsigned int cpuid)
51 {
52 return MCUPM_MBOX_WRITE(MCUPM_MBOX_WAKEUP_CPU, cpuid);
53 }
54
mtk_get_cpu_pm_preffered_cpu(void)55 unsigned int mtk_get_cpu_pm_preffered_cpu(void)
56 {
57 return MCUPM_MBOX_READ(MCUPM_MBOX_WAKEUP_CPU);
58 }
59
mtk_wait_mbox_init_done(void)60 static int mtk_wait_mbox_init_done(void)
61 {
62 int status = MCUPM_MBOX_READ(MCUPM_MBOX_TASK_STA);
63
64 if (status != MCUPM_TASK_INIT) {
65 return status;
66 }
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, (MCUPM_MCUSYS_CTRL | MCUPM_CM_CTRL |
72 MCUPM_BUCK_CTRL | MCUPM_ARMPLL_CTRL));
73
74 return status;
75 }
76
mtk_lp_depd_condition(enum cpupm_mbox_depd_type type)77 int mtk_lp_depd_condition(enum cpupm_mbox_depd_type type)
78 {
79 int status;
80
81 if (type == CPUPM_MBOX_WAIT_DEV_INIT) {
82 status = mtk_wait_mbox_init_done();
83 if (MCDI_UNLIKELY(status != MCUPM_TASK_INIT)) {
84 return -ENXIO;
85 }
86 MCUPM_MBOX_WRITE(MCUPM_MBOX_AP_READY, 1);
87 } else if (type == CPUPM_MBOX_WAIT_TASK_READY) {
88 status = MCUPM_MBOX_READ(MCUPM_MBOX_TASK_STA);
89 if (MCDI_UNLIKELY((status != MCUPM_TASK_WAIT) &&
90 (status != MCUPM_TASK_INIT_FINISH))) {
91 return -ENXIO;
92 }
93 }
94 return 0;
95 }
96