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