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