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
paxc_reg_dump(void)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
paxc_reg_dump(void)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
mhb_reg_dump(void)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
mhb_reg_dump(void)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
paxc_rc_cfg_write(uint32_t where,uint32_t val)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
paxc_rc_cfg_read(uint32_t where)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 */
paxc_cfg_link_cap(void)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 */
paxc_cfg_id(void)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
paxc_init(void)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
paxc_mhb_ns_init(void)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