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
paxc_reg_dump(void)63 static void paxc_reg_dump(void)
64 {
65 }
66 #else
67 /* total number of PAXC registers */
68 #define NR_PAXC_REGS               53
paxc_reg_dump(void)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
mhb_reg_dump(void)82 static void mhb_reg_dump(void)
83 {
84 }
85 #else
86 #define NR_MHB_REGS                227
mhb_reg_dump(void)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 
paxc_rc_cfg_write(uint32_t where,uint32_t val)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 
paxc_rc_cfg_read(uint32_t where)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  */
paxc_cfg_link_cap(void)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  */
paxc_cfg_id(void)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 
paxc_init(void)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 
paxc_mhb_ns_init(void)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