1 /* 2 * Copyright (C) 2018 Marvell International Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * https://spdx.org/licenses 6 */ 7 8 /* AP807 Marvell SoC driver */ 9 10 #include <common/debug.h> 11 #include <drivers/marvell/cache_llc.h> 12 #include <drivers/marvell/ccu.h> 13 #include <drivers/marvell/io_win.h> 14 #include <drivers/marvell/iob.h> 15 #include <drivers/marvell/mci.h> 16 #include <drivers/marvell/mochi/ap_setup.h> 17 #include <lib/mmio.h> 18 #include <lib/utils_def.h> 19 20 #include <a8k_plat_def.h> 21 22 #define SMMU_sACR (MVEBU_SMMU_BASE + 0x10) 23 #define SMMU_sACR_PG_64K (1 << 16) 24 25 #define CCU_GSPMU_CR (MVEBU_CCU_BASE(MVEBU_AP0) \ 26 + 0x3F0) 27 #define GSPMU_CPU_CONTROL (0x1 << 0) 28 29 #define CCU_HTC_CR (MVEBU_CCU_BASE(MVEBU_AP0) \ 30 + 0x200) 31 #define CCU_SET_POC_OFFSET 5 32 33 #define DSS_CR0 (MVEBU_RFU_BASE + 0x100) 34 #define DVM_48BIT_VA_ENABLE (1 << 21) 35 36 37 /* SoC RFU / IHBx4 Control */ 38 #define MCIX4_807_REG_START_ADDR_REG(unit_id) (MVEBU_RFU_BASE + \ 39 0x4258 + (unit_id * 0x4)) 40 41 /* Secure MoChi incoming access */ 42 #define SEC_MOCHI_IN_ACC_REG (MVEBU_RFU_BASE + 0x4738) 43 #define SEC_MOCHI_IN_ACC_IHB0_EN (1) 44 #define SEC_MOCHI_IN_ACC_IHB1_EN (1 << 3) 45 #define SEC_MOCHI_IN_ACC_IHB2_EN (1 << 6) 46 #define SEC_MOCHI_IN_ACC_PIDI_EN (1 << 9) 47 #define SEC_IN_ACCESS_ENA_ALL_MASTERS (SEC_MOCHI_IN_ACC_IHB0_EN | \ 48 SEC_MOCHI_IN_ACC_IHB1_EN | \ 49 SEC_MOCHI_IN_ACC_IHB2_EN | \ 50 SEC_MOCHI_IN_ACC_PIDI_EN) 51 #define MOCHI_IN_ACC_LEVEL_FORCE_NONSEC (0) 52 #define MOCHI_IN_ACC_LEVEL_FORCE_SEC (1) 53 #define MOCHI_IN_ACC_LEVEL_LEAVE_ORIG (2) 54 #define MOCHI_IN_ACC_LEVEL_MASK_ALL (3) 55 #define SEC_MOCHI_IN_ACC_IHB0_LEVEL(l) ((l) << 1) 56 #define SEC_MOCHI_IN_ACC_IHB1_LEVEL(l) ((l) << 4) 57 #define SEC_MOCHI_IN_ACC_PIDI_LEVEL(l) ((l) << 10) 58 59 60 /* SYSRST_OUTn Config definitions */ 61 #define MVEBU_SYSRST_OUT_CONFIG_REG (MVEBU_MISC_SOC_BASE + 0x4) 62 #define WD_MASK_SYS_RST_OUT (1 << 2) 63 64 /* DSS PHY for DRAM */ 65 #define DSS_SCR_REG (MVEBU_RFU_BASE + 0x208) 66 #define DSS_PPROT_OFFS 4 67 #define DSS_PPROT_MASK 0x7 68 #define DSS_PPROT_PRIV_SECURE_DATA 0x1 69 70 /* Used for Units of AP-807 (e.g. SDIO and etc) */ 71 #define MVEBU_AXI_ATTR_BASE (MVEBU_REGS_BASE + 0x6F4580) 72 #define MVEBU_AXI_ATTR_REG(index) (MVEBU_AXI_ATTR_BASE + \ 73 0x4 * index) 74 75 #define XOR_STREAM_ID_REG(ch) (MVEBU_REGS_BASE + 0x410010 + (ch) * 0x20000) 76 #define XOR_STREAM_ID_MASK 0xFFFF 77 #define SDIO_STREAM_ID_REG (MVEBU_RFU_BASE + 0x4600) 78 #define SDIO_STREAM_ID_MASK 0xFF 79 80 /* Do not use the default Stream ID 0 */ 81 #define A807_STREAM_ID_BASE (0x1) 82 83 static uintptr_t stream_id_reg[] = { 84 XOR_STREAM_ID_REG(0), 85 XOR_STREAM_ID_REG(1), 86 XOR_STREAM_ID_REG(2), 87 XOR_STREAM_ID_REG(3), 88 SDIO_STREAM_ID_REG, 89 0 90 }; 91 92 enum axi_attr { 93 AXI_SDIO_ATTR = 0, 94 AXI_DFX_ATTR, 95 AXI_MAX_ATTR, 96 }; 97 98 static void ap_sec_masters_access_en(uint32_t enable) 99 { 100 /* Open/Close incoming access for all masters. 101 * The access is disabled in trusted boot mode 102 * Could only be done in EL3 103 */ 104 if (enable != 0) { 105 mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, 0x0U, /* no clear */ 106 SEC_IN_ACCESS_ENA_ALL_MASTERS); 107 #if LLC_SRAM 108 /* Do not change access security level 109 * for PIDI masters 110 */ 111 mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, 112 SEC_MOCHI_IN_ACC_PIDI_LEVEL( 113 MOCHI_IN_ACC_LEVEL_MASK_ALL), 114 SEC_MOCHI_IN_ACC_PIDI_LEVEL( 115 MOCHI_IN_ACC_LEVEL_LEAVE_ORIG)); 116 #endif 117 } else { 118 mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, 119 SEC_IN_ACCESS_ENA_ALL_MASTERS, 120 0x0U /* no set */); 121 #if LLC_SRAM 122 /* Return PIDI access level to the default */ 123 mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, 124 SEC_MOCHI_IN_ACC_PIDI_LEVEL( 125 MOCHI_IN_ACC_LEVEL_MASK_ALL), 126 SEC_MOCHI_IN_ACC_PIDI_LEVEL( 127 MOCHI_IN_ACC_LEVEL_FORCE_NONSEC)); 128 #endif 129 } 130 } 131 132 static void setup_smmu(void) 133 { 134 uint32_t reg; 135 136 /* Set the SMMU page size to 64 KB */ 137 reg = mmio_read_32(SMMU_sACR); 138 reg |= SMMU_sACR_PG_64K; 139 mmio_write_32(SMMU_sACR, reg); 140 } 141 142 static void init_aurora2(void) 143 { 144 uint32_t reg; 145 146 /* Enable GSPMU control by CPU */ 147 reg = mmio_read_32(CCU_GSPMU_CR); 148 reg |= GSPMU_CPU_CONTROL; 149 mmio_write_32(CCU_GSPMU_CR, reg); 150 151 #if LLC_ENABLE 152 /* Enable LLC for AP807 in exclusive mode */ 153 llc_enable(0, 1); 154 155 /* Set point of coherency to DDR. 156 * This is required by units which have 157 * SW cache coherency 158 */ 159 reg = mmio_read_32(CCU_HTC_CR); 160 reg |= (0x1 << CCU_SET_POC_OFFSET); 161 mmio_write_32(CCU_HTC_CR, reg); 162 #endif /* LLC_ENABLE */ 163 164 errata_wa_init(); 165 } 166 167 168 /* MCIx indirect access register are based by default at 0xf4000000/0xf6000000 169 * to avoid conflict of internal registers of units connected via MCIx, which 170 * can be based on the same address (i.e CP1 base is also 0xf4000000), 171 * the following routines remaps the MCIx indirect bases to another domain 172 */ 173 static void mci_remap_indirect_access_base(void) 174 { 175 uint32_t mci; 176 177 for (mci = 0; mci < MCI_MAX_UNIT_ID; mci++) 178 mmio_write_32(MCIX4_807_REG_START_ADDR_REG(mci), 179 MVEBU_MCI_REG_BASE_REMAP(mci) >> 180 MCI_REMAP_OFF_SHIFT); 181 } 182 183 /* Set a unique stream id for all DMA capable devices */ 184 static void ap807_stream_id_init(void) 185 { 186 uint32_t i; 187 188 for (i = 0; 189 stream_id_reg[i] != 0 && i < ARRAY_SIZE(stream_id_reg); i++) { 190 uint32_t mask = stream_id_reg[i] == SDIO_STREAM_ID_REG ? 191 SDIO_STREAM_ID_MASK : XOR_STREAM_ID_MASK; 192 193 mmio_clrsetbits_32(stream_id_reg[i], mask, 194 i + A807_STREAM_ID_BASE); 195 } 196 } 197 198 static void ap807_axi_attr_init(void) 199 { 200 uint32_t index, data; 201 202 /* Initialize AXI attributes for AP807 */ 203 /* Go over the AXI attributes and set Ax-Cache and Ax-Domain */ 204 for (index = 0; index < AXI_MAX_ATTR; index++) { 205 switch (index) { 206 /* DFX works with no coherent only - 207 * there's no option to configure the Ax-Cache and Ax-Domain 208 */ 209 case AXI_DFX_ATTR: 210 continue; 211 default: 212 /* Set Ax-Cache as cacheable, no allocate, modifiable, 213 * bufferable. 214 * The values are different because Read & Write 215 * definition is different in Ax-Cache 216 */ 217 data = mmio_read_32(MVEBU_AXI_ATTR_REG(index)); 218 data &= ~MVEBU_AXI_ATTR_ARCACHE_MASK; 219 data |= (CACHE_ATTR_WRITE_ALLOC | 220 CACHE_ATTR_CACHEABLE | 221 CACHE_ATTR_BUFFERABLE) << 222 MVEBU_AXI_ATTR_ARCACHE_OFFSET; 223 data &= ~MVEBU_AXI_ATTR_AWCACHE_MASK; 224 data |= (CACHE_ATTR_READ_ALLOC | 225 CACHE_ATTR_CACHEABLE | 226 CACHE_ATTR_BUFFERABLE) << 227 MVEBU_AXI_ATTR_AWCACHE_OFFSET; 228 /* Set Ax-Domain as Outer domain */ 229 data &= ~MVEBU_AXI_ATTR_ARDOMAIN_MASK; 230 data |= DOMAIN_OUTER_SHAREABLE << 231 MVEBU_AXI_ATTR_ARDOMAIN_OFFSET; 232 data &= ~MVEBU_AXI_ATTR_AWDOMAIN_MASK; 233 data |= DOMAIN_OUTER_SHAREABLE << 234 MVEBU_AXI_ATTR_AWDOMAIN_OFFSET; 235 mmio_write_32(MVEBU_AXI_ATTR_REG(index), data); 236 } 237 } 238 } 239 240 static void misc_soc_configurations(void) 241 { 242 uint32_t reg; 243 244 /* Enable 48-bit VA */ 245 mmio_setbits_32(DSS_CR0, DVM_48BIT_VA_ENABLE); 246 247 /* Un-mask Watchdog reset from influencing the SYSRST_OUTn. 248 * Otherwise, upon WD timeout, the WD reset signal won't trigger reset 249 */ 250 reg = mmio_read_32(MVEBU_SYSRST_OUT_CONFIG_REG); 251 reg &= ~(WD_MASK_SYS_RST_OUT); 252 mmio_write_32(MVEBU_SYSRST_OUT_CONFIG_REG, reg); 253 } 254 255 /* 256 * By default all external CPs start with configuration address space set to 257 * 0xf200_0000. To overcome this issue, go in the loop and initialize the 258 * CP one by one, using temporary window configuration which allows to access 259 * each CP and update its configuration space according to decoding 260 * windows scheme defined for each platform. 261 */ 262 void update_cp110_default_win(int cp_id) 263 { 264 int mci_id = cp_id - 1; 265 uintptr_t cp110_base, cp110_temp_base; 266 267 /* CP110 default configuration address space */ 268 cp110_temp_base = MVEBU_AP_IO_BASE(MVEBU_AP0); 269 270 struct addr_map_win iowin_temp_win = { 271 .base_addr = cp110_temp_base, 272 .win_size = MVEBU_CP_OFFSET, 273 }; 274 275 iowin_temp_win.target_id = mci_id; 276 iow_temp_win_insert(0, &iowin_temp_win, 1); 277 278 /* Calculate the new CP110 - base address */ 279 cp110_base = MVEBU_CP_REGS_BASE(cp_id); 280 /* Go and update the CP110 configuration address space */ 281 iob_cfg_space_update(0, cp_id, cp110_temp_base, cp110_base); 282 283 /* Remove the temporary IO-WIN window */ 284 iow_temp_win_remove(0, &iowin_temp_win, 1); 285 } 286 287 void ap_init(void) 288 { 289 /* Setup Aurora2. */ 290 init_aurora2(); 291 292 /* configure MCI mapping */ 293 mci_remap_indirect_access_base(); 294 295 /* configure IO_WIN windows */ 296 init_io_win(MVEBU_AP0); 297 298 /* configure CCU windows */ 299 init_ccu(MVEBU_AP0); 300 301 /* Set the stream IDs for DMA masters */ 302 ap807_stream_id_init(); 303 304 /* configure the SMMU */ 305 setup_smmu(); 306 307 /* Open AP incoming access for all masters */ 308 ap_sec_masters_access_en(1); 309 310 /* configure axi for AP */ 311 ap807_axi_attr_init(); 312 313 /* misc configuration of the SoC */ 314 misc_soc_configurations(); 315 } 316 317 static void ap807_dram_phy_access_config(void) 318 { 319 uint32_t reg_val; 320 /* Update DSS port access permission to DSS_PHY */ 321 reg_val = mmio_read_32(DSS_SCR_REG); 322 reg_val &= ~(DSS_PPROT_MASK << DSS_PPROT_OFFS); 323 reg_val |= ((DSS_PPROT_PRIV_SECURE_DATA & DSS_PPROT_MASK) << 324 DSS_PPROT_OFFS); 325 mmio_write_32(DSS_SCR_REG, reg_val); 326 } 327 328 void ap_ble_init(void) 329 { 330 /* Enable DSS port */ 331 ap807_dram_phy_access_config(); 332 } 333 334 int ap_get_count(void) 335 { 336 return 1; 337 } 338 339 340