1 /* 2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 #include <mmio.h> 7 #include <mt8173_def.h> 8 #include <debug.h> 9 #include <mtcmos.h> 10 #include <spm.h> 11 #include <spm_mcdi.h> 12 #include <delay_timer.h> 13 14 enum { 15 SRAM_ISOINT_B = 1U << 6, 16 SRAM_CKISO = 1U << 5, 17 PWR_CLK_DIS = 1U << 4, 18 PWR_ON_2ND = 1U << 3, 19 PWR_ON = 1U << 2, 20 PWR_ISO = 1U << 1, 21 PWR_RST_B = 1U << 0 22 }; 23 24 enum { 25 L1_PDN_ACK = 1U << 8, 26 L1_PDN = 1U << 0 27 }; 28 29 enum { 30 LITTLE_CPU3 = 1U << 12, 31 LITTLE_CPU2 = 1U << 11, 32 LITTLE_CPU1 = 1U << 10, 33 }; 34 35 enum { 36 SRAM_PDN = 0xf << 8, 37 DIS_SRAM_ACK = 0x1 << 12, 38 AUD_SRAM_ACK = 0xf << 12, 39 }; 40 41 enum { 42 DIS_PWR_STA_MASK = 0x1 << 3, 43 AUD_PWR_STA_MASK = 0x1 << 24, 44 }; 45 46 #define SPM_VDE_PWR_CON 0x0210 47 #define SPM_MFG_PWR_CON 0x0214 48 #define SPM_VEN_PWR_CON 0x0230 49 #define SPM_ISP_PWR_CON 0x0238 50 #define SPM_DIS_PWR_CON 0x023c 51 #define SPM_VEN2_PWR_CON 0x0298 52 #define SPM_AUDIO_PWR_CON 0x029c 53 #define SPM_MFG_2D_PWR_CON 0x02c0 54 #define SPM_MFG_ASYNC_PWR_CON 0x02c4 55 #define SPM_USB_PWR_CON 0x02cc 56 57 #define MTCMOS_CTRL_SUCCESS 0 58 #define MTCMOS_CTRL_ERROR -1 59 60 #define MTCMOS_CTRL_EN (0x1 << 18) 61 62 #define VDE_PWR_ON 0 63 #define VEN_PWR_ON 1 64 #define ISP_PWR_ON 2 65 #define DIS_PWR_ON 3 66 #define VEN2_PWR_ON 4 67 #define AUDIO_PWR_ON 5 68 #define MFG_ASYNC_PWR_ON 6 69 #define MFG_2D_PWR_ON 7 70 #define MFG_PWR_ON 8 71 #define USB_PWR_ON 9 72 73 #define VDE_PWR_OFF 10 74 #define VEN_PWR_OFF 11 75 #define ISP_PWR_OFF 12 76 #define DIS_PWR_OFF 13 77 #define VEN2_PWR_OFF 14 78 #define AUDIO_PWR_OFF 15 79 #define MFG_ASYNC_PWR_OFF 16 80 #define MFG_2D_PWR_OFF 17 81 #define MFG_PWR_OFF 18 82 #define USB_PWR_OFF 19 83 84 #define VDE_PWR_CON_PWR_STA 7 85 #define VEN_PWR_CON_PWR_STA 21 86 #define ISP_PWR_CON_PWR_STA 5 87 #define DIS_PWR_CON_PWR_STA 3 88 #define VEN2_PWR_CON_PWR_STA 20 89 #define AUDIO_PWR_CON_PWR_STA 24 90 #define MFG_ASYNC_PWR_CON_PWR_STA 23 91 #define MFG_2D_PWR_CON_PWR_STA 22 92 #define MFG_PWR_CON_PWR_STA 4 93 #define USB_PWR_CON_PWR_STA 25 94 95 /* 96 * Timeout if the ack is not signled after 1 second. 97 * According to designer, one mtcmos operation should be done 98 * around 10us. 99 */ 100 #define MTCMOS_ACK_POLLING_MAX_COUNT 10000 101 #define MTCMOS_ACK_POLLING_INTERVAL 10 102 103 static void mtcmos_ctrl_little_off(unsigned int linear_id) 104 { 105 uint32_t reg_pwr_con; 106 uint32_t reg_l1_pdn; 107 uint32_t bit_cpu; 108 109 switch (linear_id) { 110 case 1: 111 reg_pwr_con = SPM_CA7_CPU1_PWR_CON; 112 reg_l1_pdn = SPM_CA7_CPU1_L1_PDN; 113 bit_cpu = LITTLE_CPU1; 114 break; 115 case 2: 116 reg_pwr_con = SPM_CA7_CPU2_PWR_CON; 117 reg_l1_pdn = SPM_CA7_CPU2_L1_PDN; 118 bit_cpu = LITTLE_CPU2; 119 break; 120 case 3: 121 reg_pwr_con = SPM_CA7_CPU3_PWR_CON; 122 reg_l1_pdn = SPM_CA7_CPU3_L1_PDN; 123 bit_cpu = LITTLE_CPU3; 124 break; 125 default: 126 /* should never come to here */ 127 return; 128 } 129 130 /* enable register control */ 131 mmio_write_32(SPM_POWERON_CONFIG_SET, 132 (SPM_PROJECT_CODE << 16) | (1U << 0)); 133 134 mmio_setbits_32(reg_pwr_con, PWR_ISO); 135 mmio_setbits_32(reg_pwr_con, SRAM_CKISO); 136 mmio_clrbits_32(reg_pwr_con, SRAM_ISOINT_B); 137 mmio_setbits_32(reg_l1_pdn, L1_PDN); 138 139 while (!(mmio_read_32(reg_l1_pdn) & L1_PDN_ACK)) 140 continue; 141 142 mmio_clrbits_32(reg_pwr_con, PWR_RST_B); 143 mmio_setbits_32(reg_pwr_con, PWR_CLK_DIS); 144 mmio_clrbits_32(reg_pwr_con, PWR_ON); 145 mmio_clrbits_32(reg_pwr_con, PWR_ON_2ND); 146 147 while ((mmio_read_32(SPM_PWR_STATUS) & bit_cpu) || 148 (mmio_read_32(SPM_PWR_STATUS_2ND) & bit_cpu)) 149 continue; 150 } 151 152 void mtcmos_little_cpu_off(void) 153 { 154 /* turn off little cpu 1 - 3 */ 155 mtcmos_ctrl_little_off(1); 156 mtcmos_ctrl_little_off(2); 157 mtcmos_ctrl_little_off(3); 158 } 159 160 uint32_t wait_mtcmos_ack(uint32_t on, uint32_t pwr_ctrl, uint32_t spm_pwr_sta) 161 { 162 int i = 0; 163 uint32_t cmp, pwr_sta, pwr_sta_2nd; 164 165 while (1) { 166 cmp = mmio_read_32(SPM_PCM_PASR_DPD_3) & pwr_ctrl; 167 pwr_sta = (mmio_read_32(SPM_PWR_STATUS) >> spm_pwr_sta) & 1; 168 pwr_sta_2nd = 169 (mmio_read_32(SPM_PWR_STATUS_2ND) >> spm_pwr_sta) & 1; 170 if (cmp && (pwr_sta == on) && (pwr_sta_2nd == on)) { 171 mmio_write_32(SPM_PCM_RESERVE2, 0); 172 return MTCMOS_CTRL_SUCCESS; 173 } 174 udelay(MTCMOS_ACK_POLLING_INTERVAL); 175 i++; 176 if (i > MTCMOS_ACK_POLLING_MAX_COUNT) { 177 INFO("MTCMOS control failed(%d), SPM_PWR_STA(%d),\n" 178 "SPM_PCM_RESERVE=0x%x,SPM_PCM_RESERVE2=0x%x,\n" 179 "SPM_PWR_STATUS=0x%x,SPM_PWR_STATUS_2ND=0x%x\n" 180 "SPM_PCM_PASR_DPD_3 = 0x%x\n", 181 on, spm_pwr_sta, mmio_read_32(SPM_PCM_RESERVE), 182 mmio_read_32(SPM_PCM_RESERVE2), 183 mmio_read_32(SPM_PWR_STATUS), 184 mmio_read_32(SPM_PWR_STATUS_2ND), 185 mmio_read_32(SPM_PCM_PASR_DPD_3)); 186 mmio_write_32(SPM_PCM_RESERVE2, 0); 187 return MTCMOS_CTRL_ERROR; 188 } 189 } 190 } 191 192 uint32_t mtcmos_non_cpu_ctrl(uint32_t on, uint32_t mtcmos_num) 193 { 194 uint32_t ret = MTCMOS_CTRL_SUCCESS; 195 uint32_t power_on; 196 uint32_t power_off; 197 uint32_t power_ctrl; 198 uint32_t power_status; 199 200 spm_lock_get(); 201 spm_mcdi_prepare_for_mtcmos(); 202 mmio_setbits_32(SPM_PCM_RESERVE, MTCMOS_CTRL_EN); 203 204 switch (mtcmos_num) { 205 case SPM_VDE_PWR_CON: 206 power_on = VDE_PWR_ON; 207 power_off = VDE_PWR_OFF; 208 power_status = VDE_PWR_CON_PWR_STA; 209 break; 210 case SPM_MFG_PWR_CON: 211 power_on = MFG_PWR_ON; 212 power_off = MFG_PWR_OFF; 213 power_status = MFG_PWR_CON_PWR_STA; 214 break; 215 case SPM_VEN_PWR_CON: 216 power_on = VEN_PWR_ON; 217 power_off = VEN_PWR_OFF; 218 power_status = VEN_PWR_CON_PWR_STA; 219 break; 220 case SPM_ISP_PWR_CON: 221 power_on = ISP_PWR_ON; 222 power_off = ISP_PWR_OFF; 223 power_status = ISP_PWR_CON_PWR_STA; 224 break; 225 case SPM_DIS_PWR_CON: 226 power_on = DIS_PWR_ON; 227 power_off = DIS_PWR_OFF; 228 power_status = DIS_PWR_CON_PWR_STA; 229 break; 230 case SPM_VEN2_PWR_CON: 231 power_on = VEN2_PWR_ON; 232 power_off = VEN2_PWR_OFF; 233 power_status = VEN2_PWR_CON_PWR_STA; 234 break; 235 case SPM_AUDIO_PWR_CON: 236 power_on = AUDIO_PWR_ON; 237 power_off = AUDIO_PWR_OFF; 238 power_status = AUDIO_PWR_CON_PWR_STA; 239 break; 240 case SPM_MFG_2D_PWR_CON: 241 power_on = MFG_2D_PWR_ON; 242 power_off = MFG_2D_PWR_OFF; 243 power_status = MFG_2D_PWR_CON_PWR_STA; 244 break; 245 case SPM_MFG_ASYNC_PWR_CON: 246 power_on = MFG_ASYNC_PWR_ON; 247 power_off = MFG_ASYNC_PWR_OFF; 248 power_status = MFG_ASYNC_PWR_CON_PWR_STA; 249 break; 250 case SPM_USB_PWR_CON: 251 power_on = USB_PWR_ON; 252 power_off = USB_PWR_OFF; 253 power_status = USB_PWR_CON_PWR_STA; 254 break; 255 default: 256 ret = MTCMOS_CTRL_ERROR; 257 INFO("No mapping MTCMOS(%d), ret = %d\n", mtcmos_num, ret); 258 break; 259 } 260 if (ret == MTCMOS_CTRL_SUCCESS) { 261 power_ctrl = on ? (1 << power_on) : (1 << power_off); 262 mmio_setbits_32(SPM_PCM_RESERVE2, power_ctrl); 263 ret = wait_mtcmos_ack(on, power_ctrl, power_status); 264 VERBOSE("0x%x(%d), PWR_STATUS(0x%x), ret(%d)\n", 265 power_ctrl, on, mmio_read_32(SPM_PWR_STATUS), ret); 266 } 267 268 mmio_clrbits_32(SPM_PCM_RESERVE, MTCMOS_CTRL_EN); 269 spm_lock_release(); 270 271 return ret; 272 } 273