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/mci.h> 15 #include <drivers/marvell/mochi/ap_setup.h> 16 #include <lib/mmio.h> 17 18 #include <mvebu_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 35 /* SoC RFU / IHBx4 Control */ 36 #define MCIX4_807_REG_START_ADDR_REG(unit_id) (MVEBU_RFU_BASE + \ 37 0x4258 + (unit_id * 0x4)) 38 39 /* Secure MoChi incoming access */ 40 #define SEC_MOCHI_IN_ACC_REG (MVEBU_RFU_BASE + 0x4738) 41 #define SEC_MOCHI_IN_ACC_IHB0_EN (1) 42 #define SEC_MOCHI_IN_ACC_IHB1_EN (1 << 3) 43 #define SEC_MOCHI_IN_ACC_IHB2_EN (1 << 6) 44 #define SEC_MOCHI_IN_ACC_PIDI_EN (1 << 9) 45 #define SEC_IN_ACCESS_ENA_ALL_MASTERS (SEC_MOCHI_IN_ACC_IHB0_EN | \ 46 SEC_MOCHI_IN_ACC_IHB1_EN | \ 47 SEC_MOCHI_IN_ACC_IHB2_EN | \ 48 SEC_MOCHI_IN_ACC_PIDI_EN) 49 50 /* SYSRST_OUTn Config definitions */ 51 #define MVEBU_SYSRST_OUT_CONFIG_REG (MVEBU_MISC_SOC_BASE + 0x4) 52 #define WD_MASK_SYS_RST_OUT (1 << 2) 53 54 /* DSS PHY for DRAM */ 55 #define DSS_SCR_REG (MVEBU_RFU_BASE + 0x208) 56 #define DSS_PPROT_OFFS 4 57 #define DSS_PPROT_MASK 0x7 58 #define DSS_PPROT_PRIV_SECURE_DATA 0x1 59 60 /* Used for Units of AP-807 (e.g. SDIO and etc) */ 61 #define MVEBU_AXI_ATTR_BASE (MVEBU_REGS_BASE + 0x6F4580) 62 #define MVEBU_AXI_ATTR_REG(index) (MVEBU_AXI_ATTR_BASE + \ 63 0x4 * index) 64 65 enum axi_attr { 66 AXI_SDIO_ATTR = 0, 67 AXI_DFX_ATTR, 68 AXI_MAX_ATTR, 69 }; 70 71 static void ap_sec_masters_access_en(uint32_t enable) 72 { 73 uint32_t reg; 74 75 /* Open/Close incoming access for all masters. 76 * The access is disabled in trusted boot mode 77 * Could only be done in EL3 78 */ 79 reg = mmio_read_32(SEC_MOCHI_IN_ACC_REG); 80 if (enable) 81 mmio_write_32(SEC_MOCHI_IN_ACC_REG, reg | 82 SEC_IN_ACCESS_ENA_ALL_MASTERS); 83 else 84 mmio_write_32(SEC_MOCHI_IN_ACC_REG, 85 reg & ~SEC_IN_ACCESS_ENA_ALL_MASTERS); 86 } 87 88 static void setup_smmu(void) 89 { 90 uint32_t reg; 91 92 /* Set the SMMU page size to 64 KB */ 93 reg = mmio_read_32(SMMU_sACR); 94 reg |= SMMU_sACR_PG_64K; 95 mmio_write_32(SMMU_sACR, reg); 96 } 97 98 static void init_aurora2(void) 99 { 100 uint32_t reg; 101 102 /* Enable GSPMU control by CPU */ 103 reg = mmio_read_32(CCU_GSPMU_CR); 104 reg |= GSPMU_CPU_CONTROL; 105 mmio_write_32(CCU_GSPMU_CR, reg); 106 107 #if LLC_ENABLE 108 /* Enable LLC for AP807 in exclusive mode */ 109 llc_enable(0, 1); 110 111 /* Set point of coherency to DDR. 112 * This is required by units which have 113 * SW cache coherency 114 */ 115 reg = mmio_read_32(CCU_HTC_CR); 116 reg |= (0x1 << CCU_SET_POC_OFFSET); 117 mmio_write_32(CCU_HTC_CR, reg); 118 #endif /* LLC_ENABLE */ 119 } 120 121 122 /* MCIx indirect access register are based by default at 0xf4000000/0xf6000000 123 * to avoid conflict of internal registers of units connected via MCIx, which 124 * can be based on the same address (i.e CP1 base is also 0xf4000000), 125 * the following routines remaps the MCIx indirect bases to another domain 126 */ 127 static void mci_remap_indirect_access_base(void) 128 { 129 uint32_t mci; 130 131 for (mci = 0; mci < MCI_MAX_UNIT_ID; mci++) 132 mmio_write_32(MCIX4_807_REG_START_ADDR_REG(mci), 133 MVEBU_MCI_REG_BASE_REMAP(mci) >> 134 MCI_REMAP_OFF_SHIFT); 135 } 136 137 static void ap807_axi_attr_init(void) 138 { 139 uint32_t index, data; 140 141 /* Initialize AXI attributes for AP807 */ 142 /* Go over the AXI attributes and set Ax-Cache and Ax-Domain */ 143 for (index = 0; index < AXI_MAX_ATTR; index++) { 144 switch (index) { 145 /* DFX works with no coherent only - 146 * there's no option to configure the Ax-Cache and Ax-Domain 147 */ 148 case AXI_DFX_ATTR: 149 continue; 150 default: 151 /* Set Ax-Cache as cacheable, no allocate, modifiable, 152 * bufferable. 153 * The values are different because Read & Write 154 * definition is different in Ax-Cache 155 */ 156 data = mmio_read_32(MVEBU_AXI_ATTR_REG(index)); 157 data &= ~MVEBU_AXI_ATTR_ARCACHE_MASK; 158 data |= (CACHE_ATTR_WRITE_ALLOC | 159 CACHE_ATTR_CACHEABLE | 160 CACHE_ATTR_BUFFERABLE) << 161 MVEBU_AXI_ATTR_ARCACHE_OFFSET; 162 data &= ~MVEBU_AXI_ATTR_AWCACHE_MASK; 163 data |= (CACHE_ATTR_READ_ALLOC | 164 CACHE_ATTR_CACHEABLE | 165 CACHE_ATTR_BUFFERABLE) << 166 MVEBU_AXI_ATTR_AWCACHE_OFFSET; 167 /* Set Ax-Domain as Outer domain */ 168 data &= ~MVEBU_AXI_ATTR_ARDOMAIN_MASK; 169 data |= DOMAIN_OUTER_SHAREABLE << 170 MVEBU_AXI_ATTR_ARDOMAIN_OFFSET; 171 data &= ~MVEBU_AXI_ATTR_AWDOMAIN_MASK; 172 data |= DOMAIN_OUTER_SHAREABLE << 173 MVEBU_AXI_ATTR_AWDOMAIN_OFFSET; 174 mmio_write_32(MVEBU_AXI_ATTR_REG(index), data); 175 } 176 } 177 } 178 179 static void misc_soc_configurations(void) 180 { 181 uint32_t reg; 182 183 /* Enable 48-bit VA */ 184 mmio_setbits_32(DSS_CR0, DVM_48BIT_VA_ENABLE); 185 186 /* Un-mask Watchdog reset from influencing the SYSRST_OUTn. 187 * Otherwise, upon WD timeout, the WD reset signal won't trigger reset 188 */ 189 reg = mmio_read_32(MVEBU_SYSRST_OUT_CONFIG_REG); 190 reg &= ~(WD_MASK_SYS_RST_OUT); 191 mmio_write_32(MVEBU_SYSRST_OUT_CONFIG_REG, reg); 192 } 193 194 void ap_init(void) 195 { 196 /* Setup Aurora2. */ 197 init_aurora2(); 198 199 /* configure MCI mapping */ 200 mci_remap_indirect_access_base(); 201 202 /* configure IO_WIN windows */ 203 init_io_win(MVEBU_AP0); 204 205 /* configure CCU windows */ 206 init_ccu(MVEBU_AP0); 207 208 /* configure the SMMU */ 209 setup_smmu(); 210 211 /* Open AP incoming access for all masters */ 212 ap_sec_masters_access_en(1); 213 214 /* configure axi for AP */ 215 ap807_axi_attr_init(); 216 217 /* misc configuration of the SoC */ 218 misc_soc_configurations(); 219 } 220 221 static void ap807_dram_phy_access_config(void) 222 { 223 uint32_t reg_val; 224 /* Update DSS port access permission to DSS_PHY */ 225 reg_val = mmio_read_32(DSS_SCR_REG); 226 reg_val &= ~(DSS_PPROT_MASK << DSS_PPROT_OFFS); 227 reg_val |= ((DSS_PPROT_PRIV_SECURE_DATA & DSS_PPROT_MASK) << 228 DSS_PPROT_OFFS); 229 mmio_write_32(DSS_SCR_REG, reg_val); 230 } 231 232 void ap_ble_init(void) 233 { 234 /* Enable DSS port */ 235 ap807_dram_phy_access_config(); 236 } 237 238 int ap_get_count(void) 239 { 240 return 1; 241 } 242 243 244