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 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 33 int mtk_get_mcupm_pll_mode(void) 34 { 35 return MCUPM_MBOX_READ(MCUPM_MBOX_ARMPLL_MODE); 36 } 37 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 45 int mtk_get_mcupm_buck_mode(void) 46 { 47 return MCUPM_MBOX_READ(MCUPM_MBOX_BUCK_MODE); 48 } 49 50 void mtk_set_cpu_pm_preffered_cpu(unsigned int cpuid) 51 { 52 return MCUPM_MBOX_WRITE(MCUPM_MBOX_WAKEUP_CPU, cpuid); 53 } 54 55 unsigned int mtk_get_cpu_pm_preffered_cpu(void) 56 { 57 return MCUPM_MBOX_READ(MCUPM_MBOX_WAKEUP_CPU); 58 } 59 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 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