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