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