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 <common/debug.h> 11 #include <drivers/marvell/ccu.h> 12 #include <drivers/marvell/cache_llc.h> 13 #include <drivers/marvell/io_win.h> 14 #include <drivers/marvell/mci.h> 15 #include <drivers/marvell/mochi/ap_setup.h> 16 #include <lib/mmio.h> 17 18 #include <a8k_plat_def.h> 19 20 #define SMMU_sACR (MVEBU_SMMU_BASE + 0x10) 21 #define SMMU_sACR_PG_64K (1 << 16) 22 23 #define CCU_GSPMU_CR (MVEBU_CCU_BASE(MVEBU_AP0) + \ 24 0x3F0) 25 #define GSPMU_CPU_CONTROL (0x1 << 0) 26 27 #define CCU_HTC_CR (MVEBU_CCU_BASE(MVEBU_AP0) + \ 28 0x200) 29 #define CCU_SET_POC_OFFSET 5 30 31 #define DSS_CR0 (MVEBU_RFU_BASE + 0x100) 32 #define DVM_48BIT_VA_ENABLE (1 << 21) 33 34 /* Secure MoChi incoming access */ 35 #define SEC_MOCHI_IN_ACC_REG (MVEBU_RFU_BASE + 0x4738) 36 #define SEC_MOCHI_IN_ACC_IHB0_EN (1) 37 #define SEC_MOCHI_IN_ACC_IHB1_EN (1 << 3) 38 #define SEC_MOCHI_IN_ACC_IHB2_EN (1 << 6) 39 #define SEC_MOCHI_IN_ACC_PIDI_EN (1 << 9) 40 #define SEC_IN_ACCESS_ENA_ALL_MASTERS (SEC_MOCHI_IN_ACC_IHB0_EN | \ 41 SEC_MOCHI_IN_ACC_IHB1_EN | \ 42 SEC_MOCHI_IN_ACC_IHB2_EN | \ 43 SEC_MOCHI_IN_ACC_PIDI_EN) 44 #define MOCHI_IN_ACC_LEVEL_FORCE_NONSEC (0) 45 #define MOCHI_IN_ACC_LEVEL_FORCE_SEC (1) 46 #define MOCHI_IN_ACC_LEVEL_LEAVE_ORIG (2) 47 #define MOCHI_IN_ACC_LEVEL_MASK_ALL (3) 48 #define SEC_MOCHI_IN_ACC_IHB0_LEVEL(l) ((l) << 1) 49 #define SEC_MOCHI_IN_ACC_IHB1_LEVEL(l) ((l) << 4) 50 #define SEC_MOCHI_IN_ACC_PIDI_LEVEL(l) ((l) << 10) 51 52 53 /* SYSRST_OUTn Config definitions */ 54 #define MVEBU_SYSRST_OUT_CONFIG_REG (MVEBU_MISC_SOC_BASE + 0x4) 55 #define WD_MASK_SYS_RST_OUT (1 << 2) 56 57 /* Generic Timer System Controller */ 58 #define MVEBU_MSS_GTCR_REG (MVEBU_REGS_BASE + 0x581000) 59 #define MVEBU_MSS_GTCR_ENABLE_BIT 0x1 60 61 /* 62 * AXI Configuration. 63 */ 64 65 /* Used for Units of AP-806 (e.g. SDIO and etc) */ 66 #define MVEBU_AXI_ATTR_BASE (MVEBU_REGS_BASE + 0x6F4580) 67 #define MVEBU_AXI_ATTR_REG(index) (MVEBU_AXI_ATTR_BASE + \ 68 0x4 * index) 69 70 #define XOR_STREAM_ID_REG(ch) (MVEBU_REGS_BASE + 0x410010 + (ch) * 0x20000) 71 #define XOR_STREAM_ID_MASK 0xFFFF 72 #define SDIO_STREAM_ID_REG (MVEBU_RFU_BASE + 0x4600) 73 #define SDIO_STREAM_ID_MASK 0xFF 74 75 /* Do not use the default Stream ID 0 */ 76 #define A806_STREAM_ID_BASE (0x1) 77 78 static uintptr_t stream_id_reg[] = { 79 XOR_STREAM_ID_REG(0), 80 XOR_STREAM_ID_REG(1), 81 XOR_STREAM_ID_REG(2), 82 XOR_STREAM_ID_REG(3), 83 SDIO_STREAM_ID_REG, 84 0 85 }; 86 87 enum axi_attr { 88 AXI_SDIO_ATTR = 0, 89 AXI_DFX_ATTR, 90 AXI_MAX_ATTR, 91 }; 92 93 static void apn_sec_masters_access_en(uint32_t enable) 94 { 95 /* Open/Close incoming access for all masters. 96 * The access is disabled in trusted boot mode 97 * Could only be done in EL3 98 */ 99 if (enable != 0) { 100 mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, 0x0U, /* no clear */ 101 SEC_IN_ACCESS_ENA_ALL_MASTERS); 102 #if LLC_SRAM 103 /* Do not change access security level 104 * for PIDI masters 105 */ 106 mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, 107 SEC_MOCHI_IN_ACC_PIDI_LEVEL( 108 MOCHI_IN_ACC_LEVEL_MASK_ALL), 109 SEC_MOCHI_IN_ACC_PIDI_LEVEL( 110 MOCHI_IN_ACC_LEVEL_LEAVE_ORIG)); 111 #endif 112 } else { 113 mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, 114 SEC_IN_ACCESS_ENA_ALL_MASTERS, 115 0x0U /* no set */); 116 #if LLC_SRAM 117 /* Return PIDI access level to the default */ 118 mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, 119 SEC_MOCHI_IN_ACC_PIDI_LEVEL( 120 MOCHI_IN_ACC_LEVEL_MASK_ALL), 121 SEC_MOCHI_IN_ACC_PIDI_LEVEL( 122 MOCHI_IN_ACC_LEVEL_FORCE_NONSEC)); 123 #endif 124 } 125 } 126 127 static void setup_smmu(void) 128 { 129 uint32_t reg; 130 131 /* Set the SMMU page size to 64 KB */ 132 reg = mmio_read_32(SMMU_sACR); 133 reg |= SMMU_sACR_PG_64K; 134 mmio_write_32(SMMU_sACR, reg); 135 } 136 137 static void init_aurora2(void) 138 { 139 uint32_t reg; 140 141 /* Enable GSPMU control by CPU */ 142 reg = mmio_read_32(CCU_GSPMU_CR); 143 reg |= GSPMU_CPU_CONTROL; 144 mmio_write_32(CCU_GSPMU_CR, reg); 145 146 #if LLC_ENABLE 147 /* Enable LLC for AP806 in exclusive mode */ 148 llc_enable(0, 1); 149 150 /* Set point of coherency to DDR. 151 * This is required by units which have 152 * SW cache coherency 153 */ 154 reg = mmio_read_32(CCU_HTC_CR); 155 reg |= (0x1 << CCU_SET_POC_OFFSET); 156 mmio_write_32(CCU_HTC_CR, reg); 157 #endif /* LLC_ENABLE */ 158 159 errata_wa_init(); 160 } 161 162 163 /* MCIx indirect access register are based by default at 0xf4000000/0xf6000000 164 * to avoid conflict of internal registers of units connected via MCIx, which 165 * can be based on the same address (i.e CP1 base is also 0xf4000000), 166 * the following routines remaps the MCIx indirect bases to another domain 167 */ 168 static void mci_remap_indirect_access_base(void) 169 { 170 uint32_t mci; 171 172 for (mci = 0; mci < MCI_MAX_UNIT_ID; mci++) 173 mmio_write_32(MCIX4_REG_START_ADDRESS_REG(mci), 174 MVEBU_MCI_REG_BASE_REMAP(mci) >> 175 MCI_REMAP_OFF_SHIFT); 176 } 177 178 /* Set a unique stream id for all DMA capable devices */ 179 static void ap806_stream_id_init(void) 180 { 181 int i; 182 183 for (i = 0; stream_id_reg[i] != 0; i++) { 184 uint32_t mask = stream_id_reg[i] == SDIO_STREAM_ID_REG ? 185 SDIO_STREAM_ID_MASK : XOR_STREAM_ID_MASK; 186 187 mmio_clrsetbits_32(stream_id_reg[i], mask, 188 i + A806_STREAM_ID_BASE); 189 } 190 } 191 192 static void apn806_axi_attr_init(void) 193 { 194 uint32_t index, data; 195 196 /* Initialize AXI attributes for APN806 */ 197 198 /* Go over the AXI attributes and set Ax-Cache and Ax-Domain */ 199 for (index = 0; index < AXI_MAX_ATTR; index++) { 200 switch (index) { 201 /* DFX works with no coherent only - 202 * there's no option to configure the Ax-Cache and Ax-Domain 203 */ 204 case AXI_DFX_ATTR: 205 continue; 206 default: 207 /* Set Ax-Cache as cacheable, no allocate, modifiable, 208 * bufferable 209 * The values are different because Read & Write 210 * definition is different in Ax-Cache 211 */ 212 data = mmio_read_32(MVEBU_AXI_ATTR_REG(index)); 213 data &= ~MVEBU_AXI_ATTR_ARCACHE_MASK; 214 data |= (CACHE_ATTR_WRITE_ALLOC | 215 CACHE_ATTR_CACHEABLE | 216 CACHE_ATTR_BUFFERABLE) << 217 MVEBU_AXI_ATTR_ARCACHE_OFFSET; 218 data &= ~MVEBU_AXI_ATTR_AWCACHE_MASK; 219 data |= (CACHE_ATTR_READ_ALLOC | 220 CACHE_ATTR_CACHEABLE | 221 CACHE_ATTR_BUFFERABLE) << 222 MVEBU_AXI_ATTR_AWCACHE_OFFSET; 223 /* Set Ax-Domain as Outer domain */ 224 data &= ~MVEBU_AXI_ATTR_ARDOMAIN_MASK; 225 data |= DOMAIN_OUTER_SHAREABLE << 226 MVEBU_AXI_ATTR_ARDOMAIN_OFFSET; 227 data &= ~MVEBU_AXI_ATTR_AWDOMAIN_MASK; 228 data |= DOMAIN_OUTER_SHAREABLE << 229 MVEBU_AXI_ATTR_AWDOMAIN_OFFSET; 230 mmio_write_32(MVEBU_AXI_ATTR_REG(index), data); 231 } 232 } 233 } 234 235 static void dss_setup(void) 236 { 237 /* Enable 48-bit VA */ 238 mmio_setbits_32(DSS_CR0, DVM_48BIT_VA_ENABLE); 239 } 240 241 void misc_soc_configurations(void) 242 { 243 uint32_t reg; 244 245 /* Un-mask Watchdog reset from influencing the SYSRST_OUTn. 246 * Otherwise, upon WD timeout, the WD reset signal won't trigger reset 247 */ 248 reg = mmio_read_32(MVEBU_SYSRST_OUT_CONFIG_REG); 249 reg &= ~(WD_MASK_SYS_RST_OUT); 250 mmio_write_32(MVEBU_SYSRST_OUT_CONFIG_REG, reg); 251 } 252 253 void ap_init(void) 254 { 255 /* Setup Aurora2. */ 256 init_aurora2(); 257 258 /* configure MCI mapping */ 259 mci_remap_indirect_access_base(); 260 261 /* configure IO_WIN windows */ 262 init_io_win(MVEBU_AP0); 263 264 /* configure CCU windows */ 265 init_ccu(MVEBU_AP0); 266 267 /* configure DSS */ 268 dss_setup(); 269 270 /* Set the stream IDs for DMA masters */ 271 ap806_stream_id_init(); 272 273 /* configure the SMMU */ 274 setup_smmu(); 275 276 /* Open APN incoming access for all masters */ 277 apn_sec_masters_access_en(1); 278 279 /* configure axi for APN*/ 280 apn806_axi_attr_init(); 281 282 /* misc configuration of the SoC */ 283 misc_soc_configurations(); 284 } 285 286 void ap_ble_init(void) 287 { 288 } 289 290 int ap_get_count(void) 291 { 292 return 1; 293 } 294 295 void update_cp110_default_win(int cp_id) 296 { 297 } 298