1 /* 2 * Copyright (c) 2020, MediaTek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 9 #include <common/debug.h> 10 #include <drivers/delay_timer.h> 11 #include <lib/mmio.h> 12 13 #include <mcucfg.h> 14 #include <mtspmc.h> 15 #include <mtspmc_private.h> 16 17 18 void mcucfg_disable_gic_wakeup(uint32_t cluster, uint32_t cpu) 19 { 20 mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(cpu)); 21 } 22 23 void mcucfg_enable_gic_wakeup(uint32_t cluster, uint32_t cpu) 24 { 25 mmio_clrbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(cpu)); 26 } 27 28 void mcucfg_set_bootaddr(uint32_t cluster, uint32_t cpu, uintptr_t bootaddr) 29 { 30 assert(cluster == 0U); 31 32 mmio_write_32(per_cpu(cluster, cpu, MCUCFG_BOOTADDR), bootaddr); 33 } 34 35 uintptr_t mcucfg_get_bootaddr(uint32_t cluster, uint32_t cpu) 36 { 37 assert(cluster == 0U); 38 39 return (uintptr_t)mmio_read_32(per_cpu(cluster, cpu, MCUCFG_BOOTADDR)); 40 } 41 42 void mcucfg_init_archstate(uint32_t cluster, uint32_t cpu, bool arm64) 43 { 44 uint32_t reg; 45 46 assert(cluster == 0U); 47 48 reg = per_cluster(cluster, MCUCFG_INITARCH); 49 50 if (arm64) { 51 mmio_setbits_32(reg, MCUCFG_INITARCH_CPU_BIT(cpu)); 52 } else { 53 mmio_clrbits_32(reg, MCUCFG_INITARCH_CPU_BIT(cpu)); 54 } 55 } 56 57 /** 58 * Return subsystem's power state. 59 * 60 * @mask: mask to SPM_CPU_PWR_STATUS to query the power state 61 * of one subsystem. 62 * RETURNS: 63 * 0 (the subsys was powered off) 64 * 1 (the subsys was powered on) 65 */ 66 bool spm_get_powerstate(uint32_t mask) 67 { 68 return (mmio_read_32(SPM_CPU_PWR_STATUS) & mask) != 0U; 69 } 70 71 bool spm_get_cluster_powerstate(uint32_t cluster) 72 { 73 assert(cluster == 0U); 74 75 return spm_get_powerstate(MP0_CPUTOP); 76 } 77 78 bool spm_get_cpu_powerstate(uint32_t cluster, uint32_t cpu) 79 { 80 uint32_t mask = BIT(cpu); 81 82 assert(cluster == 0U); 83 84 return spm_get_powerstate(mask); 85 } 86 87 int spmc_init(void) 88 { 89 INFO("SPM: enable CPC mode\n"); 90 91 mmio_write_32(SPM_POWERON_CONFIG_EN, PROJECT_CODE | BCLK_CG_EN); 92 93 mmio_setbits_32(per_cpu(0, 1, SPM_CPU_PWR), PWR_RST_B); 94 mmio_setbits_32(per_cpu(0, 2, SPM_CPU_PWR), PWR_RST_B); 95 mmio_setbits_32(per_cpu(0, 3, SPM_CPU_PWR), PWR_RST_B); 96 mmio_setbits_32(per_cpu(0, 4, SPM_CPU_PWR), PWR_RST_B); 97 mmio_setbits_32(per_cpu(0, 5, SPM_CPU_PWR), PWR_RST_B); 98 mmio_setbits_32(per_cpu(0, 6, SPM_CPU_PWR), PWR_RST_B); 99 mmio_setbits_32(per_cpu(0, 7, SPM_CPU_PWR), PWR_RST_B); 100 101 mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(1)); 102 mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(2)); 103 mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(3)); 104 mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(4)); 105 mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(5)); 106 mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(6)); 107 mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(7)); 108 109 mmio_clrbits_32(SPM_MCUSYS_PWR_CON, RESETPWRON_CONFIG); 110 mmio_clrbits_32(SPM_MP0_CPUTOP_PWR_CON, RESETPWRON_CONFIG); 111 mmio_clrbits_32(per_cpu(0, 0, SPM_CPU_PWR), RESETPWRON_CONFIG); 112 113 mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, CPC_CTRL_ENABLE); 114 115 return 0; 116 } 117 118 /** 119 * Power on a core with specified cluster and core index 120 * 121 * @cluster: the cluster ID of the CPU which to be powered on 122 * @cpu: the CPU ID of the CPU which to be powered on 123 */ 124 void spm_poweron_cpu(uint32_t cluster, uint32_t cpu) 125 { 126 /* set to 0 after BIG VPROC bulk on & before B-core power on seq. */ 127 if (cpu >= 4U) { 128 mmio_write_32(DREQ20_BIG_VPROC_ISO, 0U); 129 } 130 131 mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, SSPM_ALL_PWR_CTRL_EN); 132 mmio_setbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWR_ON); 133 134 while (!spm_get_cpu_powerstate(cluster, cpu)) { 135 } 136 137 mmio_clrbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, SSPM_ALL_PWR_CTRL_EN); 138 139 /* Enable Big CPU Last PC */ 140 if (cpu >= 4U) { 141 mmio_clrbits_32(LAST_PC_REG(cpu), BIT(3)); 142 } 143 } 144 145 /** 146 * Power off a core with specified cluster and core index 147 * 148 * @cluster: the cluster ID of the CPU which to be powered off 149 * @cpu: the CPU ID of the CPU which to be powered off 150 */ 151 void spm_poweroff_cpu(uint32_t cluster, uint32_t cpu) 152 { 153 /* Set mp0_spmc_pwr_on_cpuX = 0 */ 154 mmio_clrbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWR_ON); 155 } 156 157 /** 158 * Power off a cluster with specified index 159 * 160 * @cluster: the cluster index which to be powered off 161 */ 162 void spm_poweroff_cluster(uint32_t cluster) 163 { 164 /* No need to power on/off cluster on single cluster platform */ 165 assert(false); 166 } 167 168 /** 169 * Power on a cluster with specified index 170 * 171 * @cluster: the cluster index which to be powered on 172 */ 173 void spm_poweron_cluster(uint32_t cluster) 174 { 175 /* No need to power on/off cluster on single cluster platform */ 176 assert(false); 177 } 178