1 /* 2 * Copyright (C) 2018 Marvell International Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * https://spdx.org/licenses 6 */ 7 8 /* AP806 Marvell SoC driver */ 9 10 #include <ap_setup.h> 11 #include <ccu.h> 12 #include <cache_llc.h> 13 #include <debug.h> 14 #include <io_win.h> 15 #include <mci.h> 16 #include <mmio.h> 17 #include <mvebu_def.h> 18 19 #define SMMU_sACR (MVEBU_SMMU_BASE + 0x10) 20 #define SMMU_sACR_PG_64K (1 << 16) 21 22 #define CCU_GSPMU_CR (MVEBU_CCU_BASE(MVEBU_AP0) + \ 23 0x3F0) 24 #define GSPMU_CPU_CONTROL (0x1 << 0) 25 26 #define CCU_HTC_CR (MVEBU_CCU_BASE(MVEBU_AP0) + \ 27 0x200) 28 #define CCU_SET_POC_OFFSET 5 29 30 #define CCU_RGF(win) (MVEBU_CCU_BASE(MVEBU_AP0) + \ 31 0x90 + 4 * (win)) 32 33 #define DSS_CR0 (MVEBU_RFU_BASE + 0x100) 34 #define DVM_48BIT_VA_ENABLE (1 << 21) 35 36 /* Secure MoChi incoming access */ 37 #define SEC_MOCHI_IN_ACC_REG (MVEBU_RFU_BASE + 0x4738) 38 #define SEC_MOCHI_IN_ACC_IHB0_EN (1) 39 #define SEC_MOCHI_IN_ACC_IHB1_EN (1 << 3) 40 #define SEC_MOCHI_IN_ACC_IHB2_EN (1 << 6) 41 #define SEC_MOCHI_IN_ACC_PIDI_EN (1 << 9) 42 #define SEC_IN_ACCESS_ENA_ALL_MASTERS (SEC_MOCHI_IN_ACC_IHB0_EN | \ 43 SEC_MOCHI_IN_ACC_IHB1_EN | \ 44 SEC_MOCHI_IN_ACC_IHB2_EN | \ 45 SEC_MOCHI_IN_ACC_PIDI_EN) 46 47 /* SYSRST_OUTn Config definitions */ 48 #define MVEBU_SYSRST_OUT_CONFIG_REG (MVEBU_MISC_SOC_BASE + 0x4) 49 #define WD_MASK_SYS_RST_OUT (1 << 2) 50 51 /* Generic Timer System Controller */ 52 #define MVEBU_MSS_GTCR_REG (MVEBU_REGS_BASE + 0x581000) 53 #define MVEBU_MSS_GTCR_ENABLE_BIT 0x1 54 55 /* 56 * AXI Configuration. 57 */ 58 59 /* Used for Units of AP-806 (e.g. SDIO and etc) */ 60 #define MVEBU_AXI_ATTR_BASE (MVEBU_REGS_BASE + 0x6F4580) 61 #define MVEBU_AXI_ATTR_REG(index) (MVEBU_AXI_ATTR_BASE + \ 62 0x4 * index) 63 64 enum axi_attr { 65 AXI_SDIO_ATTR = 0, 66 AXI_DFX_ATTR, 67 AXI_MAX_ATTR, 68 }; 69 70 static void apn_sec_masters_access_en(uint32_t enable) 71 { 72 uint32_t reg; 73 74 /* Open/Close incoming access for all masters. 75 * The access is disabled in trusted boot mode 76 * Could only be done in EL3 77 */ 78 reg = mmio_read_32(SEC_MOCHI_IN_ACC_REG); 79 if (enable) 80 mmio_write_32(SEC_MOCHI_IN_ACC_REG, reg | 81 SEC_IN_ACCESS_ENA_ALL_MASTERS); 82 else 83 mmio_write_32(SEC_MOCHI_IN_ACC_REG, reg & 84 ~SEC_IN_ACCESS_ENA_ALL_MASTERS); 85 } 86 87 static void setup_smmu(void) 88 { 89 uint32_t reg; 90 91 /* Set the SMMU page size to 64 KB */ 92 reg = mmio_read_32(SMMU_sACR); 93 reg |= SMMU_sACR_PG_64K; 94 mmio_write_32(SMMU_sACR, reg); 95 } 96 97 static void apn806_errata_wa_init(void) 98 { 99 /* 100 * ERRATA ID: RES-3033912 - Internal Address Space Init state causes 101 * a hang upon accesses to [0xf070_0000, 0xf07f_ffff] 102 * Workaround: Boot Firmware (ATF) should configure CCU_RGF_WIN(4) to 103 * split [0x6e_0000, 0xff_ffff] to values [0x6e_0000, 0x6f_ffff] and 104 * [0x80_0000, 0xff_ffff] that cause accesses to the 105 * segment of [0xf070_0000, 0xf07f_ffff] to act as RAZWI. 106 */ 107 mmio_write_32(CCU_RGF(4), 0x37f9b809); 108 mmio_write_32(CCU_RGF(5), 0x7ffa0009); 109 } 110 111 static void init_aurora2(void) 112 { 113 uint32_t reg; 114 115 /* Enable GSPMU control by CPU */ 116 reg = mmio_read_32(CCU_GSPMU_CR); 117 reg |= GSPMU_CPU_CONTROL; 118 mmio_write_32(CCU_GSPMU_CR, reg); 119 120 #if LLC_ENABLE 121 /* Enable LLC for AP806 in exclusive mode */ 122 llc_enable(0, 1); 123 124 /* Set point of coherency to DDR. 125 * This is required by units which have 126 * SW cache coherency 127 */ 128 reg = mmio_read_32(CCU_HTC_CR); 129 reg |= (0x1 << CCU_SET_POC_OFFSET); 130 mmio_write_32(CCU_HTC_CR, reg); 131 #endif /* LLC_ENABLE */ 132 133 apn806_errata_wa_init(); 134 } 135 136 137 /* MCIx indirect access register are based by default at 0xf4000000/0xf6000000 138 * to avoid conflict of internal registers of units connected via MCIx, which 139 * can be based on the same address (i.e CP1 base is also 0xf4000000), 140 * the following routines remaps the MCIx indirect bases to another domain 141 */ 142 static void mci_remap_indirect_access_base(void) 143 { 144 uint32_t mci; 145 146 for (mci = 0; mci < MCI_MAX_UNIT_ID; mci++) 147 mmio_write_32(MCIX4_REG_START_ADDRESS_REG(mci), 148 MVEBU_MCI_REG_BASE_REMAP(mci) >> 149 MCI_REMAP_OFF_SHIFT); 150 } 151 152 static void apn806_axi_attr_init(void) 153 { 154 uint32_t index, data; 155 156 /* Initialize AXI attributes for APN806 */ 157 158 /* Go over the AXI attributes and set Ax-Cache and Ax-Domain */ 159 for (index = 0; index < AXI_MAX_ATTR; index++) { 160 switch (index) { 161 /* DFX works with no coherent only - 162 * there's no option to configure the Ax-Cache and Ax-Domain 163 */ 164 case AXI_DFX_ATTR: 165 continue; 166 default: 167 /* Set Ax-Cache as cacheable, no allocate, modifiable, 168 * bufferable 169 * The values are different because Read & Write 170 * definition is different in Ax-Cache 171 */ 172 data = mmio_read_32(MVEBU_AXI_ATTR_REG(index)); 173 data &= ~MVEBU_AXI_ATTR_ARCACHE_MASK; 174 data |= (CACHE_ATTR_WRITE_ALLOC | 175 CACHE_ATTR_CACHEABLE | 176 CACHE_ATTR_BUFFERABLE) << 177 MVEBU_AXI_ATTR_ARCACHE_OFFSET; 178 data &= ~MVEBU_AXI_ATTR_AWCACHE_MASK; 179 data |= (CACHE_ATTR_READ_ALLOC | 180 CACHE_ATTR_CACHEABLE | 181 CACHE_ATTR_BUFFERABLE) << 182 MVEBU_AXI_ATTR_AWCACHE_OFFSET; 183 /* Set Ax-Domain as Outer domain */ 184 data &= ~MVEBU_AXI_ATTR_ARDOMAIN_MASK; 185 data |= DOMAIN_OUTER_SHAREABLE << 186 MVEBU_AXI_ATTR_ARDOMAIN_OFFSET; 187 data &= ~MVEBU_AXI_ATTR_AWDOMAIN_MASK; 188 data |= DOMAIN_OUTER_SHAREABLE << 189 MVEBU_AXI_ATTR_AWDOMAIN_OFFSET; 190 mmio_write_32(MVEBU_AXI_ATTR_REG(index), data); 191 } 192 } 193 } 194 195 static void dss_setup(void) 196 { 197 /* Enable 48-bit VA */ 198 mmio_setbits_32(DSS_CR0, DVM_48BIT_VA_ENABLE); 199 } 200 201 void misc_soc_configurations(void) 202 { 203 uint32_t reg; 204 205 /* Un-mask Watchdog reset from influencing the SYSRST_OUTn. 206 * Otherwise, upon WD timeout, the WD reset signal won't trigger reset 207 */ 208 reg = mmio_read_32(MVEBU_SYSRST_OUT_CONFIG_REG); 209 reg &= ~(WD_MASK_SYS_RST_OUT); 210 mmio_write_32(MVEBU_SYSRST_OUT_CONFIG_REG, reg); 211 } 212 213 void ap_init(void) 214 { 215 /* Setup Aurora2. */ 216 init_aurora2(); 217 218 /* configure MCI mapping */ 219 mci_remap_indirect_access_base(); 220 221 /* configure IO_WIN windows */ 222 init_io_win(MVEBU_AP0); 223 224 /* configure CCU windows */ 225 init_ccu(MVEBU_AP0); 226 227 /* configure DSS */ 228 dss_setup(); 229 230 /* configure the SMMU */ 231 setup_smmu(); 232 233 /* Open APN incoming access for all masters */ 234 apn_sec_masters_access_en(1); 235 236 /* configure axi for APN*/ 237 apn806_axi_attr_init(); 238 239 /* misc configuration of the SoC */ 240 misc_soc_configurations(); 241 } 242 243 void ap_ble_init(void) 244 { 245 } 246 247 int ap_get_count(void) 248 { 249 return 1; 250 } 251 252