1 /* 2 * Copyright (c) 2017 - 2020, Broadcom 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <common/debug.h> 8 #include <lib/mmio.h> 9 10 #include <iommu.h> 11 #include <platform_def.h> 12 #include <sr_utils.h> 13 14 #define PAXC_BASE 0x60400000 15 #define PAXC_AXI_CFG_PF 0x10 16 #define PAXC_AXI_CFG_PF_OFFSET(pf) (PAXC_AXI_CFG_PF + (pf) * 4) 17 #define PAXC_ARPROT_PF_CFG 0x40 18 #define PAXC_AWPROT_PF_CFG 0x44 19 20 #define PAXC_ARQOS_PF_CFG 0x48 21 #define PAXC_ARQOS_VAL 0xaaaaaaaa 22 23 #define PAXC_AWQOS_PF_CFG 0x4c 24 #define PAXC_AWQOS_VAL 0xeeeeeeee 25 26 #define PAXC_CFG_IND_ADDR_OFFSET 0x1f0 27 #define PAXC_CFG_IND_ADDR_MASK 0xffc 28 #define PAXC_CFG_IND_DATA_OFFSET 0x1f4 29 30 /* offsets for PAXC root complex configuration space registers */ 31 32 #define PAXC_CFG_ID_OFFSET 0x434 33 #define PAXC_RC_VENDOR_ID 0x14e4 34 #define PAXC_RC_VENDOR_ID_SHIFT 16 35 36 #define PAXC_RC_DEVICE_ID 0xd750 37 38 #define PAXC_CFG_LINK_CAP_OFFSET 0x4dc 39 #define PAXC_RC_LINK_CAP_SPD_SHIFT 0 40 #define PAXC_RC_LINK_CAP_SPD_MASK (0xf << PAXC_RC_LINK_CAP_SPD_SHIFT) 41 #define PAXC_RC_LINK_CAP_SPD 3 42 #define PAXC_RC_LINK_CAP_WIDTH_SHIFT 4 43 #define PAXC_RC_LINK_CAP_WIDTH_MASK (0x1f << PAXC_RC_LINK_CAP_WIDTH_SHIFT) 44 #define PAXC_RC_LINK_CAP_WIDTH 16 45 46 /* offsets for MHB registers */ 47 48 #define MHB_BASE 0x60401000 49 #define MHB_MEM_PWR_STATUS_PAXC (MHB_BASE + 0x1c0) 50 #define MHB_PWR_ARR_POWERON 0x8 51 #define MHB_PWR_ARR_POWEROK 0x4 52 #define MHB_PWR_POWERON 0x2 53 #define MHB_PWR_POWEROK 0x1 54 #define MHB_PWR_STATUS_MASK (MHB_PWR_ARR_POWERON | \ 55 MHB_PWR_ARR_POWEROK | \ 56 MHB_PWR_POWERON | \ 57 MHB_PWR_POWEROK) 58 59 /* max number of PFs from Nitro that PAXC sees */ 60 #define MAX_NR_NITRO_PF 8 61 62 #ifdef EMULATION_SETUP 63 static void paxc_reg_dump(void) 64 { 65 } 66 #else 67 /* total number of PAXC registers */ 68 #define NR_PAXC_REGS 53 69 static void paxc_reg_dump(void) 70 { 71 uint32_t idx, offset = 0; 72 73 VERBOSE("PAXC register dump start\n"); 74 for (idx = 0; idx < NR_PAXC_REGS; idx++, offset += 4) 75 VERBOSE("offset: 0x%x val: 0x%x\n", offset, 76 mmio_read_32(PAXC_BASE + offset)); 77 VERBOSE("PAXC register dump end\n"); 78 } 79 #endif /* EMULATION_SETUP */ 80 81 #ifdef EMULATION_SETUP 82 static void mhb_reg_dump(void) 83 { 84 } 85 #else 86 #define NR_MHB_REGS 227 87 static void mhb_reg_dump(void) 88 { 89 uint32_t idx, offset = 0; 90 91 VERBOSE("MHB register dump start\n"); 92 for (idx = 0; idx < NR_MHB_REGS; idx++, offset += 4) 93 VERBOSE("offset: 0x%x val: 0x%x\n", offset, 94 mmio_read_32(MHB_BASE + offset)); 95 VERBOSE("MHB register dump end\n"); 96 } 97 #endif /* EMULATION_SETUP */ 98 99 static void paxc_rc_cfg_write(uint32_t where, uint32_t val) 100 { 101 mmio_write_32(PAXC_BASE + PAXC_CFG_IND_ADDR_OFFSET, 102 where & PAXC_CFG_IND_ADDR_MASK); 103 mmio_write_32(PAXC_BASE + PAXC_CFG_IND_DATA_OFFSET, val); 104 } 105 106 static uint32_t paxc_rc_cfg_read(uint32_t where) 107 { 108 mmio_write_32(PAXC_BASE + PAXC_CFG_IND_ADDR_OFFSET, 109 where & PAXC_CFG_IND_ADDR_MASK); 110 return mmio_read_32(PAXC_BASE + PAXC_CFG_IND_DATA_OFFSET); 111 } 112 113 /* 114 * Function to program PAXC root complex link capability register 115 */ 116 static void paxc_cfg_link_cap(void) 117 { 118 uint32_t val; 119 120 val = paxc_rc_cfg_read(PAXC_CFG_LINK_CAP_OFFSET); 121 val &= ~(PAXC_RC_LINK_CAP_SPD_MASK | PAXC_RC_LINK_CAP_WIDTH_MASK); 122 val |= (PAXC_RC_LINK_CAP_SPD << PAXC_RC_LINK_CAP_SPD_SHIFT) | 123 (PAXC_RC_LINK_CAP_WIDTH << PAXC_RC_LINK_CAP_WIDTH_SHIFT); 124 paxc_rc_cfg_write(PAXC_CFG_LINK_CAP_OFFSET, val); 125 } 126 127 /* 128 * Function to program PAXC root complex vendor ID and device ID 129 */ 130 static void paxc_cfg_id(void) 131 { 132 uint32_t val; 133 134 val = (PAXC_RC_VENDOR_ID << PAXC_RC_VENDOR_ID_SHIFT) | 135 PAXC_RC_DEVICE_ID; 136 paxc_rc_cfg_write(PAXC_CFG_ID_OFFSET, val); 137 } 138 139 void paxc_init(void) 140 { 141 unsigned int pf_index; 142 unsigned int val; 143 144 val = mmio_read_32(MHB_MEM_PWR_STATUS_PAXC); 145 if ((val & MHB_PWR_STATUS_MASK) != MHB_PWR_STATUS_MASK) { 146 INFO("PAXC not powered\n"); 147 return; 148 } 149 150 paxc_cfg_id(); 151 paxc_cfg_link_cap(); 152 153 paxc_reg_dump(); 154 mhb_reg_dump(); 155 156 #ifdef USE_DDR 157 /* 158 * Set AWCACHE and ARCACHE to 0xff (Cacheable write-back, 159 * allocate on both reads and writes) per 160 * recommendation from the ASIC team 161 */ 162 val = 0xff; 163 #else 164 /* disable IO cache if non-DDR memory is used, e.g., external SRAM */ 165 val = 0x0; 166 #endif 167 for (pf_index = 0; pf_index < MAX_NR_NITRO_PF; pf_index++) 168 mmio_write_32(PAXC_BASE + PAXC_AXI_CFG_PF_OFFSET(pf_index), 169 val); 170 171 /* 172 * Set ARPROT and AWPROT to enable non-secure access from 173 * PAXC to all PFs, PF0 to PF7 174 */ 175 mmio_write_32(PAXC_BASE + PAXC_ARPROT_PF_CFG, 0x22222222); 176 mmio_write_32(PAXC_BASE + PAXC_AWPROT_PF_CFG, 0x22222222); 177 178 mmio_write_32(PAXC_BASE + PAXC_ARQOS_PF_CFG, PAXC_ARQOS_VAL); 179 mmio_write_32(PAXC_BASE + PAXC_AWQOS_PF_CFG, PAXC_AWQOS_VAL); 180 181 INFO("PAXC init done\n"); 182 } 183 184 /* 185 * These defines do not match the regfile but they are renamed in a way such 186 * that they are much more readible 187 */ 188 189 #define MHB_NIC_SECURITY_BASE 0x60500000 190 #define MHB_NIC_PAXC_AXI_NS 0x0008 191 #define MHB_NIC_IDM_NS 0x000c 192 #define MHB_NIC_MHB_APB_NS 0x0010 193 #define MHB_NIC_NITRO_AXI_NS 0x0014 194 #define MHB_NIC_PCIE_AXI_NS 0x0018 195 #define MHB_NIC_PAXC_APB_NS 0x001c 196 #define MHB_NIC_EP_APB_NS 0x0020 197 198 #define MHB_NIC_PAXC_APB_S_IDM_SHIFT 5 199 #define MHB_NIC_EP_APB_S_IDM_SHIFT 4 200 #define MHB_NIC_MHB_APB_S_IDM_SHIFT 3 201 #define MHB_NIC_PAXC_AXI_S_IDM_SHIFT 2 202 #define MHB_NIC_PCIE_AXI_S_IDM_SHIFT 1 203 #define MHB_NIC_NITRO_AXI_S_IDM_SHIFT 0 204 205 #define NIC400_NITRO_TOP_NIC_SECURITY_BASE 0x60d00000 206 207 #define NITRO_NIC_SECURITY_3_SHIFT 0x14 208 #define NITRO_NIC_SECURITY_4_SHIFT 0x18 209 #define NITRO_NIC_SECURITY_5_SHIFT 0x1c 210 #define NITRO_NIC_SECURITY_6_SHIFT 0x20 211 212 void paxc_mhb_ns_init(void) 213 { 214 unsigned int val; 215 uintptr_t mhb_nic_gpv = MHB_NIC_SECURITY_BASE; 216 #ifndef NITRO_SECURE_ACCESS 217 uintptr_t nic400_nitro_gpv = NIC400_NITRO_TOP_NIC_SECURITY_BASE; 218 #endif /* NITRO_SECURE_ACCESS */ 219 220 /* set PAXC AXI to allow non-secure access */ 221 val = mmio_read_32(mhb_nic_gpv + MHB_NIC_PAXC_AXI_NS); 222 val |= 0x1; 223 mmio_write_32(mhb_nic_gpv + MHB_NIC_PAXC_AXI_NS, val); 224 225 /* set various MHB IDM interfaces to allow non-secure access */ 226 val = mmio_read_32(mhb_nic_gpv + MHB_NIC_IDM_NS); 227 val |= (0x1 << MHB_NIC_PAXC_APB_S_IDM_SHIFT); 228 val |= (0x1 << MHB_NIC_EP_APB_S_IDM_SHIFT); 229 val |= (0x1 << MHB_NIC_MHB_APB_S_IDM_SHIFT); 230 val |= (0x1 << MHB_NIC_PAXC_AXI_S_IDM_SHIFT); 231 val |= (0x1 << MHB_NIC_PCIE_AXI_S_IDM_SHIFT); 232 val |= (0x1 << MHB_NIC_NITRO_AXI_S_IDM_SHIFT); 233 mmio_write_32(mhb_nic_gpv + MHB_NIC_IDM_NS, val); 234 235 /* set MHB APB to allow non-secure access */ 236 val = mmio_read_32(mhb_nic_gpv + MHB_NIC_MHB_APB_NS); 237 val |= 0x1; 238 mmio_write_32(mhb_nic_gpv + MHB_NIC_MHB_APB_NS, val); 239 240 /* set Nitro AXI to allow non-secure access */ 241 val = mmio_read_32(mhb_nic_gpv + MHB_NIC_NITRO_AXI_NS); 242 val |= 0x1; 243 mmio_write_32(mhb_nic_gpv + MHB_NIC_NITRO_AXI_NS, val); 244 245 /* set PCIe AXI to allow non-secure access */ 246 val = mmio_read_32(mhb_nic_gpv + MHB_NIC_PCIE_AXI_NS); 247 val |= 0x1; 248 mmio_write_32(mhb_nic_gpv + MHB_NIC_PCIE_AXI_NS, val); 249 250 /* set PAXC APB to allow non-secure access */ 251 val = mmio_read_32(mhb_nic_gpv + MHB_NIC_PAXC_APB_NS); 252 val |= 0x1; 253 mmio_write_32(mhb_nic_gpv + MHB_NIC_PAXC_APB_NS, val); 254 255 /* set EP APB to allow non-secure access */ 256 val = mmio_read_32(mhb_nic_gpv + MHB_NIC_EP_APB_NS); 257 val |= 0x1; 258 mmio_write_32(mhb_nic_gpv + MHB_NIC_EP_APB_NS, val); 259 260 #ifndef NITRO_SECURE_ACCESS 261 /* Set NIC400 to allow non-secure access */ 262 mmio_setbits_32(nic400_nitro_gpv + NITRO_NIC_SECURITY_3_SHIFT, 0x1); 263 mmio_setbits_32(nic400_nitro_gpv + NITRO_NIC_SECURITY_4_SHIFT, 0x1); 264 mmio_setbits_32(nic400_nitro_gpv + NITRO_NIC_SECURITY_5_SHIFT, 0x1); 265 mmio_setbits_32(nic400_nitro_gpv + NITRO_NIC_SECURITY_6_SHIFT, 0x1); 266 #endif /* NITRO_SECURE_ACCESS */ 267 } 268