blob: 44af4b010b45db45b97fd18fc9bb490df42132da [file] [log] [blame]
Sheetal Tigadoli58a9eca2019-12-18 20:05:09 +05301/*
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
63static void paxc_reg_dump(void)
64{
65}
66#else
67/* total number of PAXC registers */
68#define NR_PAXC_REGS 53
69static 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
82static void mhb_reg_dump(void)
83{
84}
85#else
86#define NR_MHB_REGS 227
87static 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
99static 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
106static 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 */
116static 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 */
130static 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
139void 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
212void 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}