1 /* 2 * Copyright (c) 2021, MediaTek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <cdefs.h> 8 #include <common/debug.h> 9 #include <lib/mmio.h> 10 #include <lib/utils_def.h> 11 #include <mt_mcdi.h> 12 13 /* Read/Write */ 14 #define APMCU_MCUPM_MBOX_AP_READY U(0) 15 #define APMCU_MCUPM_MBOX_RESERVED_1 U(1) 16 #define APMCU_MCUPM_MBOX_RESERVED_2 U(2) 17 #define APMCU_MCUPM_MBOX_RESERVED_3 U(3) 18 #define APMCU_MCUPM_MBOX_PWR_CTRL_EN U(4) 19 #define APMCU_MCUPM_MBOX_L3_CACHE_MODE U(5) 20 #define APMCU_MCUPM_MBOX_BUCK_MODE U(6) 21 #define APMCU_MCUPM_MBOX_ARMPLL_MODE U(7) 22 /* Read only */ 23 #define APMCU_MCUPM_MBOX_TASK_STA U(8) 24 #define APMCU_MCUPM_MBOX_RESERVED_9 U(9) 25 #define APMCU_MCUPM_MBOX_RESERVED_10 U(10) 26 #define APMCU_MCUPM_MBOX_RESERVED_11 U(11) 27 28 /* CPC mode - Read/Write */ 29 #define APMCU_MCUPM_MBOX_WAKEUP_CPU U(12) 30 31 /* Mbox Slot: APMCU_MCUPM_MBOX_PWR_CTRL_EN */ 32 #define MCUPM_MCUSYS_CTRL BIT(0) 33 #define MCUPM_BUCK_CTRL BIT(1) 34 #define MCUPM_ARMPLL_CTRL BIT(2) 35 #define MCUPM_CM_CTRL BIT(3) 36 #define MCUPM_PWR_CTRL_MASK GENMASK(3, 0) 37 38 /* Mbox Slot: APMCU_MCUPM_MBOX_BUCK_MODE */ 39 #define MCUPM_BUCK_NORMAL_MODE U(0) /* default */ 40 #define MCUPM_BUCK_LP_MODE U(1) 41 #define MCUPM_BUCK_OFF_MODE U(2) 42 #define NF_MCUPM_BUCK_MODE U(3) 43 44 /* Mbox Slot: APMCU_MCUPM_MBOX_ARMPLL_MODE */ 45 #define MCUPM_ARMPLL_ON U(0) /* default */ 46 #define MCUPM_ARMPLL_GATING U(1) 47 #define MCUPM_ARMPLL_OFF U(2) 48 #define NF_MCUPM_ARMPLL_MODE U(3) 49 50 /* Mbox Slot: APMCU_MCUPM_MBOX_TASK_STA */ 51 #define MCUPM_TASK_UNINIT U(0) 52 #define MCUPM_TASK_INIT U(1) 53 #define MCUPM_TASK_INIT_FINISH U(2) 54 #define MCUPM_TASK_WAIT U(3) 55 #define MCUPM_TASK_RUN U(4) 56 #define MCUPM_TASK_PAUSE U(5) 57 58 #define SSPM_MBOX_3_BASE U(0x10420000) 59 60 #define MCDI_NOT_INIT U(0) 61 #define MCDI_INIT_1 U(1) 62 #define MCDI_INIT_2 U(2) 63 #define MCDI_INIT_DONE U(3) 64 65 static int mcdi_init_status __section("tzfw_coherent_mem"); 66 mcdi_mbox_read(uint32_t id)67static inline uint32_t mcdi_mbox_read(uint32_t id) 68 { 69 return mmio_read_32(SSPM_MBOX_3_BASE + (id << 2)); 70 } 71 mcdi_mbox_write(uint32_t id,uint32_t val)72static inline void mcdi_mbox_write(uint32_t id, uint32_t val) 73 { 74 mmio_write_32(SSPM_MBOX_3_BASE + (id << 2), val); 75 } 76 mtk_mcupm_pwr_ctrl_setting(uint32_t dev)77static void mtk_mcupm_pwr_ctrl_setting(uint32_t dev) 78 { 79 mcdi_mbox_write(APMCU_MCUPM_MBOX_PWR_CTRL_EN, dev); 80 } 81 mtk_set_mcupm_pll_mode(uint32_t mode)82static void mtk_set_mcupm_pll_mode(uint32_t mode) 83 { 84 if (mode < NF_MCUPM_ARMPLL_MODE) { 85 mcdi_mbox_write(APMCU_MCUPM_MBOX_ARMPLL_MODE, mode); 86 } 87 } 88 mtk_set_mcupm_buck_mode(uint32_t mode)89static void mtk_set_mcupm_buck_mode(uint32_t mode) 90 { 91 if (mode < NF_MCUPM_BUCK_MODE) { 92 mcdi_mbox_write(APMCU_MCUPM_MBOX_BUCK_MODE, mode); 93 } 94 } 95 mtk_mcupm_is_ready(void)96static int mtk_mcupm_is_ready(void) 97 { 98 unsigned int sta = mcdi_mbox_read(APMCU_MCUPM_MBOX_TASK_STA); 99 100 return ((sta == MCUPM_TASK_WAIT) || (sta == MCUPM_TASK_INIT_FINISH)); 101 } 102 mcdi_init_1(void)103static int mcdi_init_1(void) 104 { 105 unsigned int sta = mcdi_mbox_read(APMCU_MCUPM_MBOX_TASK_STA); 106 107 if (sta != MCUPM_TASK_INIT) { 108 return -1; 109 } 110 111 mtk_set_mcupm_pll_mode(MCUPM_ARMPLL_OFF); 112 mtk_set_mcupm_buck_mode(MCUPM_BUCK_OFF_MODE); 113 114 mtk_mcupm_pwr_ctrl_setting( 115 MCUPM_MCUSYS_CTRL | 116 MCUPM_BUCK_CTRL | 117 MCUPM_ARMPLL_CTRL); 118 119 mcdi_mbox_write(APMCU_MCUPM_MBOX_AP_READY, 1); 120 121 return 0; 122 } 123 mcdi_init_2(void)124static int mcdi_init_2(void) 125 { 126 return mtk_mcupm_is_ready() ? 0 : -1; 127 } 128 mcdi_try_init(void)129int mcdi_try_init(void) 130 { 131 if (mcdi_init_status == MCDI_INIT_DONE) { 132 return 0; 133 } 134 135 if (mcdi_init_status == MCDI_NOT_INIT) { 136 mcdi_init_status = MCDI_INIT_1; 137 } 138 139 if (mcdi_init_status == MCDI_INIT_1 && mcdi_init_1() == 0) { 140 mcdi_init_status = MCDI_INIT_2; 141 } 142 143 if (mcdi_init_status == MCDI_INIT_2 && mcdi_init_2() == 0) { 144 mcdi_init_status = MCDI_INIT_DONE; 145 } 146 147 INFO("mcdi ready for mcusys-off-idle and system suspend\n"); 148 149 return (mcdi_init_status == MCDI_INIT_DONE) ? 0 : mcdi_init_status; 150 } 151