1 /*****************************************************************************
2 * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * PolarFire and PolarFire SoC PCIe subsystem software driver implementation.
7 *
8 */
9
10 #include "pf_pcie.h"
11
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15
16 /**************************************************************************/
17 /* Preprocessor Macros */
18 /**************************************************************************/
19 /* PCIe enumeration values */
20 /* At Present PCIe supports one Root Port and End Point */
21 #define PCIE_CFG_MAX_NUM_OF_BUS 8u
22 #define PCIE_CFG_MAX_NUM_OF_DEV 2u
23 #define PCIE_CFG_MAX_NUM_OF_FUN 8u
24
25 #define PCIE_CFG_FUN_NOT_IMP_MASK 0xFFFFu
26 #define PCIE_CFG_HEADER_TYPE_MASK 0x00EF0000u
27 #define PCIE_CFG_MUL_FUN_DEV_MASK 0x00800000u
28
29 #define PCIE_CFG_HEADER_O_TYPE 0x00000000u
30 #define PCIE_CFG_CATCHE_SIZE 0x10u
31
32 /* ECAM Address Register bitmaps and masks */
33 /* Mask of all valid bits */
34 #define PCIE_ECAM_MASK 0x0FFFFFFFu
35 /* Bus Number Mask */
36 #define PCIE_ECAM_BUS_MASK 0x0FF00000u
37 /* Device Number Mask */
38 #define PCIE_ECAM_DEV_MASK 0x000F8000u
39 /* Function Number Mask */
40 #define PCIE_ECAM_FUN_MASK 0x00007000u
41 /* Bus Number Shift Value */
42 #define PCIE_ECAM_BUS_SHIFT 20u
43 /* Device Number Shift Value */
44 #define PCIE_ECAM_DEV_SHIFT 15u
45 /* Function Number Shift Value */
46 #define PCIE_ECAM_FUN_SHIFT 12u
47
48 #define BAR_MASK 0xFFFFFFFFu
49 #define BAR_SIZE_MASK 0xFFFFFFF0u
50 #define BAR_LSB_MASK 0x0000000Fu
51 #define VENDOR_ID_MASK 0xFFFFu
52 /* 64-bit Address space of BAR */
53 #define ADDR_SPACE_64BIT 0x00000004u
54 /* Translated ID */
55 #define PCIE_TX_RX_INTERFACE 0x00000000u
56 #define PCIE_CONFIG_INTERFACE 0x00000001u
57 #define AXI4_MASTER_0_INTERFACE 0x00000004u
58 /* Translation table size 256MB */
59 #define SIZE_256MB_TRANSLATE_TABLE_EN 0x00000037u
60 /*
61 PCIe Root Port
62 Control & Status Register: enable I/O, memory access,
63 bus master,Parity Error
64 Response and SERR#
65 */
66 #define RP_CFG_PRMSCR_DATA 0x00000147u
67 /*
68 PCIe EndPoint
69 Control & Status Register: enable Memory access, bus master
70 */
71 #define EP_CFG_PRMSCR_DATA 0x00000006u
72
73 /* device conrol status register: maxrdreq=512, maxpayloadsize=256 */
74 #define RP_DEVICE_CTRL_STATUS_DATA 0x0000202Fu
75 #define EP_DEVICE_CTRL_STATUS_DATA 0x00FF2830u
76
77 /* PCIe Sub bus:FF, sec bus:0, prim bus:0 */
78 #define PRIM_SEC_SUB_BUS_DEFAULT 0x00FF0000u
79
80 /* Non-prefetchable Limit, Non-prefetchable Base */
81 #define RP_MEM_LIMIT_BASE_DATA 0xEEE0EEE0u
82 /* Prefetchable Limit, Prefetchable Base */
83 #define RP_PREF_MEM_LIMIT_BASE_DATA 0xFFF1FFF1u
84 /* Prefetchable Base upper */
85 #define RP_PREF_BASE_UPPER_DATA 0xFFFFFFFFu
86 /* Prefetchable upper limit*/
87 #define RP_PREF_LIMIT_UPPER_DATA 0x00000000u
88
89 /* PCIe Config space MSI capability structure */
90 #define PCIE_ENABLE_MSI 0x00010000u
91 #define PCIE_CAPB_ID_MSI 0x05u
92 #define PCIE_CAPB_ID_MASK 0xFFu
93 #define PCIE_CONFIG_CAPB_ID_MASK 0xFFFFFFFFFFFFFF00u
94 #define PCIE_MSI_64BIT_CAPB_ADDR 0x00800000u
95 #define PCIE_MSI_MULTI_VECTOR_SHIFT 17u
96 #define PCIE_MSI_MULTI_VECTOR_MASK 7u
97 #define PCIE_MSI_MULTI_ENABLE_SHIFT 20u
98
99 /* PCI Express Capability structure ID */
100 #define PCIE_CAPB_ID_STRUCT 0x10u
101 /****************************************************************************/
102 /* PCIe AXI master table init defines */
103 #define ATR0_PCIE_WIN0_OFFSET 0x600u
104 #define ATR_WIN_REG_TABLE_SIZE 0x20u
105 #define WIN0_SRCADDR_PARAM 0x00u
106 #define WIN0_SRC_ADDR 0x01u
107 #define WIN0_TRSL_ADDR_LSB 0x02u
108 #define WIN0_TRSL_ADDR_UDW 0x03u
109 #define WIN0_TRSL_PARAM 0x04u
110 #define ATR_ADDR_MASK 0xFFFFF000u
111 #define TLP_SHIFT 16u
112 #define BAR_01_DW0 0xE4u
113 /****************************************************************************/
114 /* PCIe AXI slave table init defines */
115 #define ATR0_AXI4_SLV0_OFFSET 0x800u
116 #define ATR_SLV_REG_TABLE_SIZE 0x20u
117 #define SLV0_SRCADDR_PARAM 0x00u
118 #define SLV0_SRC_ADDR 0x01u
119 #define SLV0_TRSL_ADDR_LSB 0x02u
120 #define SLV0_TRSL_ADDR_UDW 0x03u
121 #define SLV0_TRSL_PARAM 0x04u
122 /****************************************************************************/
123 /* DMA */
124 #define EP_DMA_START_DATA 0x00002321u
125 #define EP_DMA_INTERFACE_AXI 0x00000004u
126 #define EP_DMA_INTERFACE_PCIE 0x00000000u
127
128 /* EP DMA interrupt and error status */
129 #define DMA_INT_STATUS 0x00000003u
130 #define DMA_ERR_STATUS 0x00000300u
131
132 /* Enable PCIe Host MSI, INTx DMAx interrupts */
133 #define PCIE_HOST_INT_ENABLE 0x1F000FFFu
134 /* Enable PCIe local DMAx, DMA error interrupts */
135 #define PCIE_LOCAL_INT_ENABLE 0x1F0000FFu
136 /****************************************************************************/
137 /* Clear PCIe interrupt events */
138 #define PCIE_EVENT_INT_DATA 0x00070007u
139 #define PCIE_ECC_DISABLE 0x0F000000u
140 #define PCIE_SEC_ERROR_INT_CLEAR 0x0000FFFFu
141 #define PCIE_DED_ERROR_INT_CLEAR 0x0000FFFFu
142 #define PCIE_ISTATUS_CLEAR 0xFFFFFFFFu
143 #define PCIE_CLEAR 0x00000000u
144 #define PCIE_SET 0x00000001u
145
146 #define ROOT_PORT_ENABLE 0x00000001u
147
148 #define NULL_POINTER ((void *)0)
149
150 #define MASK_32BIT 0xFFFFFFFFu
151 #define SHIFT_32BIT 32u
152
153 struct pcie_dma_instance_t
154 {
155 volatile pf_pcie_ep_dma_status_t state;
156 pf_pcie_write_callback_t tx_complete_handler;
157 pf_pcie_read_callback_t rx_complete_handler;
158 };
159
160 /* EP dma struct variable */
161 static struct pcie_dma_instance_t g_pcie_dma;
162
163 /* RP and EP bridge and controller structure variable */
164 static PCIE_BRIDGE * g_rp_pcie_bridge = PCIE_CLEAR;
165 static PCIE_BRIDGE * g_ep_bridge_reg = PCIE_CLEAR;
166 static PCIE_CTRL * g_ep_ctrl_reg = PCIE_CLEAR;
167 static PCIE_CTRL * g_rp_pcie_ctrl = PCIE_CLEAR;
168
169 /* Enumeration and BAR structure variable */
170 pf_pcie_ebuff_t g_pcie_enumeration;
171 pf_pcie_bar_info_t g_pcie_bar_allocate;
172
173 /**************************************************************************//**
174 * See pf_pciess.h for details of how to use this function.
175 *
176 * This function is valid only when IP is configured as a root complex.
177 *
178 */
179 pf_pcie_ebuff_t *
PF_PCIE_enumeration(uint64_t apb_addr,uint8_t pcie_ctrl_num,uint64_t ecam_addr)180 PF_PCIE_enumeration
181 (
182 uint64_t apb_addr,
183 uint8_t pcie_ctrl_num,
184 uint64_t ecam_addr
185 )
186 {
187 PCIE_BRIDGE * p_pcie_bridge;
188 PCIE_END_CONF * p_pcie_config_space;
189 PCIE_ROOT_CONF * p_pcie_root_config;
190 PCIE_CTRL * p_pcie_ctrl;
191 uint32_t * p_pcie_ep_config_space = PCIE_CLEAR;
192 uint32_t pcie_header_type;
193 uint32_t pcie_multi_fun;
194 uint8_t pcie_bus_num;
195 uint8_t pcie_dev_num;
196 uint8_t pcie_fun_num;
197 uint16_t pcie_vendor_id;
198 uint64_t src_ecam_addr;
199 uint32_t addr_inc;
200 uint32_t p_reg;
201 uint32_t ecam_addr_low;
202 uint32_t ecam_addr_high;
203 /* Default attached bridges and devices are 0 */
204 uint8_t bridges_attached = PCIE_CLEAR;
205 uint8_t devices_attached = PCIE_CLEAR;
206 uint32_t prim_sec_num = PRIM_SEC_SUB_BUS_DEFAULT;
207 /* Default bridge and device enumeration number is 0 */
208 g_pcie_enumeration.no_of_bridges_attached = PCIE_CLEAR;
209 g_pcie_enumeration.no_of_devices_attached = PCIE_CLEAR;
210 /* Check PCIe Controller is 0 or 1 */
211 if (PF_PCIE_CTRL_0 == pcie_ctrl_num)
212 {
213 /* PCIe Bridge Controller 0 */
214 p_pcie_bridge = ((PCIE_BRIDGE *)((uintptr_t)(apb_addr + PCIE0_BRIDGE_PHY_ADDR_OFFSET)));
215 p_pcie_ctrl = ((PCIE_CTRL *)((uintptr_t)(apb_addr + PCIE0_CRTL_PHY_ADDR_OFFSET)));
216 }
217 else if (PF_PCIE_CTRL_1 == pcie_ctrl_num)
218 {
219 /* PCIe Bridge Controller 1 */
220 p_pcie_bridge = ((PCIE_BRIDGE *)((uintptr_t)(apb_addr + PCIE1_BRIDGE_PHY_ADDR_OFFSET)));
221 p_pcie_ctrl = ((PCIE_CTRL *)((uintptr_t)(apb_addr + PCIE1_CRTL_PHY_ADDR_OFFSET)));
222 }
223 else
224 {
225 /* Not supports PCIe Bridge Controller */
226 p_pcie_bridge = PCIE_CLEAR;
227 }
228 /* Check Root Port is enabled or not */
229 if ((NULL_POINTER != p_pcie_bridge) &&
230 (ROOT_PORT_ENABLE == ((p_pcie_bridge->GEN_SETTINGS) & ROOT_PORT_ENABLE)))
231 {
232 g_rp_pcie_bridge = p_pcie_bridge;
233 g_rp_pcie_ctrl = p_pcie_ctrl;
234 /* Clear interrupts on PCIe RootPort */
235 p_pcie_ctrl->ECC_CONTROL = PCIE_ECC_DISABLE;
236 p_pcie_ctrl->PCIE_EVENT_INT = PCIE_EVENT_INT_DATA;
237 p_pcie_ctrl->SEC_ERROR_INT = PCIE_SEC_ERROR_INT_CLEAR;
238 p_pcie_ctrl->DED_ERROR_INT = PCIE_DED_ERROR_INT_CLEAR;
239 p_pcie_bridge->ISTATUS_LOCAL = PCIE_ISTATUS_CLEAR;
240 p_pcie_bridge->IMASK_LOCAL = PCIE_CLEAR;
241 p_pcie_bridge->ISTATUS_HOST = PCIE_ISTATUS_CLEAR;
242 p_pcie_bridge->IMASK_HOST = PCIE_CLEAR;
243
244 ecam_addr_low = (uint32_t)(ecam_addr & MASK_32BIT);
245 ecam_addr_high = (uint32_t)((ecam_addr >> SHIFT_32BIT) & MASK_32BIT);
246 /* Select PCIe Config space */
247 p_pcie_bridge->ATR0_AXI4_SLV0_TRSL_PARAM = PCIE_CONFIG_INTERFACE;
248 /* Address Translation table setup */
249 p_pcie_bridge->ATR0_AXI4_SLV0_SRCADDR_PARAM = ecam_addr_low | SIZE_256MB_TRANSLATE_TABLE_EN;
250 p_pcie_bridge->ATR0_AXI4_SLV0_SRC_ADDR = ecam_addr_high;
251 p_pcie_bridge->ATR0_AXI4_SLV0_TRSL_ADDR_LSB = ecam_addr_low;
252 p_pcie_bridge->ATR0_AXI4_SLV0_TRSL_ADDR_UDW = ecam_addr_high;
253 /* Enumeration starts here */
254 for (pcie_bus_num = PCIE_CLEAR; pcie_bus_num < PCIE_CFG_MAX_NUM_OF_BUS; pcie_bus_num++)
255 {
256 for (pcie_dev_num = PCIE_CLEAR; pcie_dev_num < PCIE_CFG_MAX_NUM_OF_DEV; pcie_dev_num++)
257 {
258 for (pcie_fun_num = PCIE_CLEAR; pcie_fun_num < PCIE_CFG_MAX_NUM_OF_FUN; pcie_fun_num++)
259 {
260 /* Calculate ECAM address based on AXI slave base address and bus, device and fun num */
261 src_ecam_addr = ecam_address_calc(ecam_addr, pcie_bus_num, pcie_dev_num, pcie_fun_num);
262 p_pcie_config_space = (PCIE_END_CONF *)((uintptr_t)src_ecam_addr);
263 /* Read Vendor ID of PCIe RP or EP */
264 pcie_vendor_id = ((uint16_t)((p_pcie_config_space->VID_DEVID) & VENDOR_ID_MASK));
265 /* Check Vendor ID is 0xFFFF then no need search */
266 if (PCIE_CFG_FUN_NOT_IMP_MASK == pcie_vendor_id)
267 {
268 if (PCIE_CLEAR == pcie_fun_num)
269 {
270 /*
271 * don't need to search
272 * further on this device.
273 */
274 break;
275 }
276 }
277 else
278 {
279 /* Header Type */
280 pcie_header_type = p_pcie_config_space->BIST_HEADER & PCIE_CFG_HEADER_TYPE_MASK;
281 pcie_multi_fun = p_pcie_config_space->BIST_HEADER & PCIE_CFG_MUL_FUN_DEV_MASK;
282 /* Check header type is type0 for PCIe EndPoint */
283 if (PCIE_CFG_HEADER_O_TYPE == pcie_header_type)
284 {
285 g_pcie_enumeration.devices[devices_attached].bus_num = pcie_bus_num;
286 g_pcie_enumeration.devices[devices_attached].dev_num = pcie_dev_num;
287 g_pcie_enumeration.devices[devices_attached].fun_num = pcie_fun_num;
288 g_pcie_enumeration.devices[devices_attached].vendor_id = pcie_vendor_id;
289 ++devices_attached;
290 g_pcie_enumeration.no_of_devices_attached = devices_attached;
291 /* Enable config space memory access bus master and cache size */
292 p_pcie_config_space->CFG_PRMSCR |= (EP_CFG_PRMSCR_DATA);
293 p_pcie_config_space->BIST_HEADER = PCIE_CFG_CATCHE_SIZE;
294
295 p_pcie_ep_config_space = (uint32_t *)((uintptr_t)src_ecam_addr);
296 /* PCIe configuration header starts after standard size - 0x40/4 = 0x10 */
297 p_pcie_ep_config_space = p_pcie_ep_config_space + 0x10u;
298
299 for (addr_inc = PCIE_CLEAR; addr_inc < 48u; ++addr_inc)
300 {
301 /* Read Capability ID 10h for PCI Express Capability structure */
302 p_reg = *(p_pcie_ep_config_space + addr_inc);
303 if (PCIE_CAPB_ID_STRUCT == (p_reg & PCIE_CAPB_ID_MASK))
304 {
305 break;
306 }
307 }
308 if (addr_inc < 48u)
309 {
310 /* Device control and status offset */
311 addr_inc = addr_inc + 2u;
312 /* End Point control and status configure */
313 *(p_pcie_ep_config_space + addr_inc) = EP_DEVICE_CTRL_STATUS_DATA;
314 }
315 }
316 else
317 {
318 /* Header type is Type1
319 * This is a bridge or Root Port
320 */
321 /* Check bus num is '0' for Root Port*/
322 if (PCIE_CLEAR == pcie_bus_num)
323 {
324 p_pcie_root_config = (PCIE_ROOT_CONF *)((uintptr_t)src_ecam_addr);
325 prim_sec_num |= (uint32_t)(((((uint32_t)pcie_bus_num) + PCIE_SET) << 8u) | pcie_bus_num);
326 /* Sub bus num 0xFF, sec bus num 1, and prime bus num 0 */
327 p_pcie_root_config->PRIM_SEC_BUS_NUM = prim_sec_num;
328 /* Control & Status Register: enable bus master,
329 * Parity Error Response and SERR#
330 */
331 p_pcie_root_config->CFG_PRMSCR = RP_CFG_PRMSCR_DATA;
332 /* Non-prefetchable Limit, Non-prefetchable Base */
333 p_pcie_root_config->MEM_LIMIT_BASE = RP_MEM_LIMIT_BASE_DATA;
334 /* Prefetchable Limit, Prefetchable Base */
335 p_pcie_root_config->PREF_MEM_LIMIT_BASE = RP_PREF_MEM_LIMIT_BASE_DATA;
336 /* Prefetchable Base upper */
337 p_pcie_root_config->PREF_BASE_UPPER = RP_PREF_BASE_UPPER_DATA;
338 /* Prefetchable upper limit*/
339 p_pcie_root_config->PREF_LIMIT_UPPER = RP_PREF_LIMIT_UPPER_DATA;
340 p_pcie_root_config->DEVICE_CTRL_STAT = RP_DEVICE_CTRL_STATUS_DATA;
341 }
342 else
343 {
344 /* The PCIe bridge primary and secondary bus setup */
345 prim_sec_num |= (uint32_t)(((((uint32_t)pcie_bus_num) + PCIE_SET) << 8u) | pcie_bus_num);
346 p_pcie_root_config = (PCIE_ROOT_CONF *)((uintptr_t)src_ecam_addr);
347 p_pcie_root_config->PRIM_SEC_BUS_NUM = prim_sec_num;
348 p_pcie_root_config->CFG_PRMSCR = RP_CFG_PRMSCR_DATA;
349 }
350 g_pcie_enumeration.bridges[bridges_attached].bus_num = pcie_bus_num;
351 g_pcie_enumeration.bridges[bridges_attached].dev_num = pcie_dev_num;
352 g_pcie_enumeration.bridges[bridges_attached].fun_num = pcie_fun_num;
353 g_pcie_enumeration.bridges[bridges_attached].vendor_id = pcie_vendor_id;
354 ++bridges_attached;
355 g_pcie_enumeration.no_of_bridges_attached = bridges_attached;
356 }
357 if ((PCIE_CLEAR == pcie_fun_num) && (PCIE_CLEAR == pcie_multi_fun))
358 {
359 /*
360 * If it is function 0 and it is not a
361 * multi function device, don't need
362 * to search further on this device
363 */
364 break;
365 }
366 }
367 }
368 }
369 }
370 /* Selects PCIe Tx/RxInterface */
371 p_pcie_bridge->ATR0_AXI4_SLV0_TRSL_PARAM = PCIE_TX_RX_INTERFACE;
372 }
373 return &g_pcie_enumeration;
374 }
375
376 /**************************************************************************//**
377 * See pf_pciess.h for details of how to use this function.
378 *
379 */
380 pf_pcie_bar_info_t *
PF_PCIE_allocate_memory(uint64_t ecam_addr,uint64_t allocate_addr)381 PF_PCIE_allocate_memory
382 (
383 uint64_t ecam_addr,
384 uint64_t allocate_addr
385 )
386 {
387 PCIE_END_CONF * p_pcie_config_space;
388 uint32_t pcie_header_type;
389 uint64_t axi_trns_base_addr = allocate_addr;
390 uint32_t axi_trns_base_addr_low;
391 uint32_t axi_trns_base_addr_high;
392 uint32_t read_bar, lsb4bits_bar;
393
394 axi_trns_base_addr_low = (uint32_t)(allocate_addr & MASK_32BIT);
395 axi_trns_base_addr_high = (uint32_t)((allocate_addr >> SHIFT_32BIT) & MASK_32BIT);
396 /* Default BAR and BAR size is 0 */
397 g_pcie_bar_allocate.bar0_address = PCIE_CLEAR;
398 g_pcie_bar_allocate.bar0_size = PCIE_CLEAR;
399 g_pcie_bar_allocate.bar1_address = PCIE_CLEAR;
400 g_pcie_bar_allocate.bar1_size = PCIE_CLEAR;
401 g_pcie_bar_allocate.bar2_address = PCIE_CLEAR;
402 g_pcie_bar_allocate.bar2_size = PCIE_CLEAR;
403 g_pcie_bar_allocate.bar3_address = PCIE_CLEAR;
404 g_pcie_bar_allocate.bar3_size = PCIE_CLEAR;
405 g_pcie_bar_allocate.bar4_address = PCIE_CLEAR;
406 g_pcie_bar_allocate.bar4_size = PCIE_CLEAR;
407 g_pcie_bar_allocate.bar5_address = PCIE_CLEAR;
408 g_pcie_bar_allocate.bar5_size = PCIE_CLEAR;
409 /* Check PCIe bridge is enabled */
410 if (NULL_POINTER != g_rp_pcie_bridge)
411 {
412 /* Select PCIe Config space */
413 g_rp_pcie_bridge->ATR0_AXI4_SLV0_TRSL_PARAM = PCIE_CONFIG_INTERFACE;
414
415 p_pcie_config_space = (PCIE_END_CONF *)((uintptr_t)ecam_addr);
416 pcie_header_type = PCIE_CLEAR;
417 /* Header Type */
418 pcie_header_type = p_pcie_config_space->BIST_HEADER & PCIE_CFG_HEADER_TYPE_MASK;
419 /* Write 0xFFFFFFFF to read PCIe BAR0 */
420 p_pcie_config_space->BAR0 = BAR_MASK;
421 /* Read BAR0 */
422 read_bar = p_pcie_config_space->BAR0;
423 /* Lower 4-bits of BAR0 */
424 lsb4bits_bar = read_bar & BAR_LSB_MASK;
425 /* Calculate BAR0 size */
426 read_bar &= BAR_SIZE_MASK;
427 read_bar = ~(read_bar) + PCIE_SET;
428 if (read_bar != PCIE_CLEAR)
429 {
430 /* Write Translation address in EP BAR0 */
431 p_pcie_config_space->BAR0 = axi_trns_base_addr_low | lsb4bits_bar;
432 if (ADDR_SPACE_64BIT == (lsb4bits_bar & ADDR_SPACE_64BIT))
433 {
434 p_pcie_config_space->BAR1 = axi_trns_base_addr_high;
435 g_pcie_bar_allocate.bar1_address = axi_trns_base_addr_high;
436 }
437 g_pcie_bar_allocate.bar0_address = axi_trns_base_addr_low;
438 g_pcie_bar_allocate.bar0_size = read_bar;
439 axi_trns_base_addr = axi_trns_base_addr + read_bar;
440 }
441 /* Check BAR0 is not 64-bit address space */
442 if (ADDR_SPACE_64BIT != (lsb4bits_bar & ADDR_SPACE_64BIT))
443 {
444 axi_trns_base_addr_low = (uint32_t)(axi_trns_base_addr & MASK_32BIT);
445 axi_trns_base_addr_high = (uint32_t)((axi_trns_base_addr >> SHIFT_32BIT) & MASK_32BIT);
446
447 /* Write 0xFFFFFFFF to read PCIe BAR1 */
448 p_pcie_config_space->BAR1 = BAR_MASK;
449 /* Read BAR1 */
450 read_bar = p_pcie_config_space->BAR1;
451 lsb4bits_bar = read_bar & BAR_LSB_MASK;
452 /* Calculate BAR1 size */
453 read_bar &= BAR_SIZE_MASK;
454 read_bar = ~(read_bar) + PCIE_SET;
455 if (read_bar != PCIE_CLEAR)
456 {
457 /* Write Translation address in EP BAR1 */
458 p_pcie_config_space->BAR1 = axi_trns_base_addr_low | lsb4bits_bar;
459 g_pcie_bar_allocate.bar1_address = axi_trns_base_addr_low;
460 g_pcie_bar_allocate.bar1_size = read_bar;
461 axi_trns_base_addr = axi_trns_base_addr + read_bar;
462 }
463 }
464 if (PCIE_CFG_HEADER_O_TYPE == pcie_header_type)
465 {
466 axi_trns_base_addr_low = (uint32_t)(axi_trns_base_addr & MASK_32BIT);
467 axi_trns_base_addr_high = (uint32_t)((axi_trns_base_addr >> SHIFT_32BIT) & MASK_32BIT);
468 /* Write 0xFFFFFFFF to read PCIe BAR2 */
469 p_pcie_config_space->BAR2 = BAR_MASK;
470 /* Read BAR2 */
471 read_bar = p_pcie_config_space->BAR2;
472 lsb4bits_bar = read_bar & BAR_LSB_MASK;
473
474 /* Calculate BAR2 size */
475 read_bar &= BAR_SIZE_MASK;
476 read_bar = ~(read_bar) + PCIE_SET;
477 if (read_bar != PCIE_CLEAR)
478 {
479 /* Write Translation address in EP BAR2 */
480 p_pcie_config_space->BAR2 = axi_trns_base_addr_low | lsb4bits_bar;
481 if (ADDR_SPACE_64BIT == (lsb4bits_bar & ADDR_SPACE_64BIT))
482 {
483 p_pcie_config_space->BAR3 = axi_trns_base_addr_high;
484 g_pcie_bar_allocate.bar3_address = axi_trns_base_addr_high;
485 }
486 g_pcie_bar_allocate.bar2_address = axi_trns_base_addr_low;
487 g_pcie_bar_allocate.bar2_size = read_bar;
488 axi_trns_base_addr = axi_trns_base_addr + read_bar;
489 }
490
491 /* Check BAR2 is not 64-bit address space */
492 if (ADDR_SPACE_64BIT != (lsb4bits_bar & ADDR_SPACE_64BIT))
493 {
494 axi_trns_base_addr_low = (uint32_t)(axi_trns_base_addr & MASK_32BIT);
495 axi_trns_base_addr_high = (uint32_t)((axi_trns_base_addr >> SHIFT_32BIT) & MASK_32BIT);
496 /* Write 0xFFFFFFFF to read PCIe BAR3 */
497 p_pcie_config_space->BAR3 = BAR_MASK;
498 /* Read BAR3 */
499 read_bar = p_pcie_config_space->BAR3;
500 lsb4bits_bar = read_bar & BAR_LSB_MASK;
501
502 /* Calculate BAR3 size */
503 read_bar &= BAR_SIZE_MASK;
504 read_bar = ~(read_bar) + PCIE_SET;
505 if (read_bar != PCIE_CLEAR)
506 {
507 /* Write Translation address in EP BAR3 */
508 p_pcie_config_space->BAR3 = axi_trns_base_addr_low | lsb4bits_bar;
509 g_pcie_bar_allocate.bar3_address = axi_trns_base_addr_low;
510 g_pcie_bar_allocate.bar3_size = read_bar;
511 axi_trns_base_addr = axi_trns_base_addr + read_bar;
512 }
513 }
514 axi_trns_base_addr_low = (uint32_t)(axi_trns_base_addr & MASK_32BIT);
515 axi_trns_base_addr_high = (uint32_t)((axi_trns_base_addr >> SHIFT_32BIT) & MASK_32BIT);
516 /* Write 0xFFFFFFFF to read PCIe BAR4 */
517 p_pcie_config_space->BAR4 = BAR_MASK;
518 /* Read BAR4 */
519 read_bar = p_pcie_config_space->BAR4;
520 lsb4bits_bar = read_bar & BAR_LSB_MASK;
521
522 /* Calculate BAR4 size */
523 read_bar &= BAR_SIZE_MASK;
524 read_bar = ~(read_bar) + PCIE_SET;
525 if (read_bar != PCIE_CLEAR)
526 {
527 /* Write Translation address in EP BAR4 */
528 p_pcie_config_space->BAR4 = axi_trns_base_addr_low | lsb4bits_bar;
529 if (ADDR_SPACE_64BIT == (lsb4bits_bar & ADDR_SPACE_64BIT))
530 {
531 p_pcie_config_space->BAR5 = axi_trns_base_addr_high;
532 g_pcie_bar_allocate.bar5_address = axi_trns_base_addr_high;
533 }
534 g_pcie_bar_allocate.bar4_address = axi_trns_base_addr_low;
535 g_pcie_bar_allocate.bar4_size = read_bar;
536 axi_trns_base_addr = axi_trns_base_addr + read_bar;
537 }
538
539 /* Check BAR4 is not 64-bit address space */
540 if (ADDR_SPACE_64BIT != (lsb4bits_bar & ADDR_SPACE_64BIT))
541 {
542 axi_trns_base_addr_low = (uint32_t)(axi_trns_base_addr & MASK_32BIT);
543 axi_trns_base_addr_high = (uint32_t)((axi_trns_base_addr >> SHIFT_32BIT) & MASK_32BIT);
544 /* Write 0xFFFFFFFF to read PCIe BAR5 */
545 p_pcie_config_space->BAR5 = BAR_MASK;
546 /* Read BAR5 */
547 read_bar = p_pcie_config_space->BAR5;
548 lsb4bits_bar = read_bar & BAR_LSB_MASK;
549
550 /* Calculate BAR5 size */
551 read_bar &= BAR_SIZE_MASK;
552 read_bar = ~(read_bar) + PCIE_SET;
553 if (read_bar != PCIE_CLEAR)
554 {
555 /* Write Translation address in EP BAR5 */
556 p_pcie_config_space->BAR5 = axi_trns_base_addr_low | lsb4bits_bar;
557 g_pcie_bar_allocate.bar5_address = axi_trns_base_addr_low;
558 g_pcie_bar_allocate.bar5_size = read_bar;
559 axi_trns_base_addr = axi_trns_base_addr + read_bar;
560 }
561 }
562 }
563 /* Selects PCIe Tx/RxInterface */
564 g_rp_pcie_bridge->ATR0_AXI4_SLV0_TRSL_PARAM = PCIE_TX_RX_INTERFACE;
565 }
566 return &g_pcie_bar_allocate;
567 }
568
569 /**************************************************************************//**
570 * See pf_pciess.h for details of how to use this function.
571 *
572 */
573 void
PF_PCIE_enable_config_space_msi(uint64_t ecam_addr,uint64_t msi_addr,uint16_t msi_data)574 PF_PCIE_enable_config_space_msi
575 (
576 uint64_t ecam_addr,
577 uint64_t msi_addr,
578 uint16_t msi_data
579 )
580 {
581 uint32_t * p_pcie_config_space;
582 uint32_t addr_inc;
583 uint32_t p_reg;
584 uint32_t msi_addr_low;
585 uint32_t msi_addr_high;
586
587 if (NULL_POINTER != g_rp_pcie_bridge)
588 {
589 msi_addr_low = (uint32_t)(msi_addr & MASK_32BIT);
590 msi_addr_high = (uint32_t)((msi_addr >> SHIFT_32BIT) & MASK_32BIT);
591
592 /* Select PCIe Config space */
593 g_rp_pcie_bridge->ATR0_AXI4_SLV0_TRSL_PARAM = PCIE_CONFIG_INTERFACE;
594
595 p_pcie_config_space = (uint32_t *)((uintptr_t)(ecam_addr & PCIE_CONFIG_CAPB_ID_MASK));
596
597 /* PCIe configuration header starts after standard size - 0x40/4 = 0x10*/
598 p_pcie_config_space = p_pcie_config_space + 0x10u;
599
600 for (addr_inc = PCIE_CLEAR; addr_inc < 48u; ++addr_inc)
601 {
602 /* Read Capability ID 05h for MSI */
603 p_reg = *(p_pcie_config_space + addr_inc);
604 if (PCIE_CAPB_ID_MSI == (p_reg & PCIE_CAPB_ID_MASK))
605 {
606 break;
607 }
608 }
609 if (addr_inc < 48u)
610 {
611 p_reg = *(p_pcie_config_space + addr_inc);
612
613 /* Read number of requested vectors(multiple messages capable) */
614 p_reg = (p_reg >> PCIE_MSI_MULTI_VECTOR_SHIFT) & PCIE_MSI_MULTI_VECTOR_MASK;
615
616 /* Numbers of allocated vectors (multiple messages enable) */
617 p_reg = p_reg << PCIE_MSI_MULTI_ENABLE_SHIFT;
618
619 /* Enable MSI */
620 *(p_pcie_config_space + addr_inc) |= (p_reg | PCIE_ENABLE_MSI);
621 p_reg = *(p_pcie_config_space + addr_inc);
622 ++addr_inc;
623
624 /* MSI message lower address */
625 *(p_pcie_config_space + addr_inc) = msi_addr_low;
626 ++addr_inc;
627
628 /* MSI mesage upper address */
629 if (PCIE_MSI_64BIT_CAPB_ADDR == (p_reg & PCIE_MSI_64BIT_CAPB_ADDR))
630 {
631 *(p_pcie_config_space + addr_inc) = msi_addr_high;
632 ++addr_inc;
633 }
634 /* MSI message data */
635 *(p_pcie_config_space + addr_inc) = msi_data;
636 }
637 /* Selects PCIe Tx/RxInterface */
638 g_rp_pcie_bridge->ATR0_AXI4_SLV0_TRSL_PARAM = PCIE_TX_RX_INTERFACE;
639 }
640
641 }
642
643 /**************************************************************************//**
644 * See pf_pciess.h for details of how to use this function.
645 * PCIe reads type1 configuration space of pcie bridge or switch.
646 */
647 void
PF_PCIE_type1_header_read(uint64_t apb_addr,uint8_t pcie_ctrl_num,uint64_t ecam_addr,PCIE_ROOT_CONF * p_type1_header)648 PF_PCIE_type1_header_read
649 (
650 uint64_t apb_addr,
651 uint8_t pcie_ctrl_num,
652 uint64_t ecam_addr,
653 PCIE_ROOT_CONF * p_type1_header
654 )
655 {
656 PCIE_BRIDGE * p_pcie_bridge;
657 PCIE_ROOT_CONF * p_pcie_type1_header;
658
659 uint32_t pcie_header_type;
660 uint32_t ecam_addr_low;
661 uint32_t ecam_addr_high;
662
663 if (PF_PCIE_CTRL_0 == pcie_ctrl_num)
664 {
665 p_pcie_bridge = ((PCIE_BRIDGE *)((uintptr_t)(apb_addr + PCIE0_BRIDGE_PHY_ADDR_OFFSET)));
666 }
667 else if (PF_PCIE_CTRL_1 == pcie_ctrl_num)
668 {
669 p_pcie_bridge = ((PCIE_BRIDGE *)((uintptr_t)(apb_addr + PCIE1_BRIDGE_PHY_ADDR_OFFSET)));
670 }
671 else
672 {
673 p_pcie_bridge = NULL_POINTER;
674 }
675
676 /* Check Root Port */
677 if ((NULL_POINTER != p_pcie_bridge) &&
678 (ROOT_PORT_ENABLE == (p_pcie_bridge->GEN_SETTINGS & ROOT_PORT_ENABLE)))
679 {
680 ecam_addr_low = (uint32_t)(ecam_addr & MASK_32BIT);
681 ecam_addr_high = (uint32_t)((ecam_addr >> SHIFT_32BIT) & MASK_32BIT);
682
683 /* Selects PCIe Config space */
684 p_pcie_bridge->ATR0_AXI4_SLV0_TRSL_PARAM = PCIE_CONFIG_INTERFACE;
685
686 p_pcie_bridge->ATR0_AXI4_SLV0_SRCADDR_PARAM = ecam_addr_low | SIZE_256MB_TRANSLATE_TABLE_EN ;
687 p_pcie_bridge->ATR0_AXI4_SLV0_SRC_ADDR = ecam_addr_high;
688 p_pcie_bridge->ATR0_AXI4_SLV0_TRSL_ADDR_LSB = ecam_addr_low;
689 p_pcie_bridge->ATR0_AXI4_SLV0_TRSL_ADDR_UDW = ecam_addr_high;
690
691 p_pcie_type1_header = (PCIE_ROOT_CONF *)((uintptr_t)ecam_addr);
692 /* Header Type */
693 pcie_header_type = p_pcie_type1_header->BIST_HEADER & PCIE_CFG_HEADER_TYPE_MASK;
694 if (PCIE_CFG_HEADER_O_TYPE != pcie_header_type)
695 {
696 p_type1_header->VID_DEVID = p_pcie_type1_header->VID_DEVID;
697 p_type1_header->CFG_PRMSCR = p_pcie_type1_header->CFG_PRMSCR;
698 p_type1_header->CLASS_CODE = p_pcie_type1_header->CLASS_CODE;
699 p_type1_header->BIST_HEADER = p_pcie_type1_header->BIST_HEADER;
700 p_type1_header->BAR0 = p_pcie_type1_header->BAR0;
701 p_type1_header->BAR1 = p_pcie_type1_header->BAR1;
702 p_type1_header->PRIM_SEC_BUS_NUM = p_pcie_type1_header->PRIM_SEC_BUS_NUM;
703 p_type1_header->IO_LIMIT_BASE = p_pcie_type1_header->IO_LIMIT_BASE;
704 p_type1_header->MEM_LIMIT_BASE = p_pcie_type1_header->MEM_LIMIT_BASE;
705 p_type1_header->PREF_MEM_LIMIT_BASE = p_pcie_type1_header->PREF_MEM_LIMIT_BASE;
706 p_type1_header->PREF_BASE_UPPER = p_pcie_type1_header->PREF_BASE_UPPER;
707 p_type1_header->PREF_LIMIT_UPPER = p_pcie_type1_header->PREF_LIMIT_UPPER;
708 p_type1_header->IO_LIMIT_BASE_UPPER = p_pcie_type1_header->IO_LIMIT_BASE_UPPER;
709 p_type1_header->CAPAB_POINTER = p_pcie_type1_header->CAPAB_POINTER;
710 p_type1_header->EXPAN_ROM_BASE = p_pcie_type1_header->EXPAN_ROM_BASE;
711 p_type1_header->INT_LINE_PIN = p_pcie_type1_header->INT_LINE_PIN;
712 }
713 /* Selects PCIe Tx/RxInterface */
714 p_pcie_bridge->ATR0_AXI4_SLV0_TRSL_PARAM = PCIE_TX_RX_INTERFACE;
715 }
716 }
717
718 /**************************************************************************//**
719 * See pf_pciess.h for details of how to use this function.
720 *
721 */
722 uint8_t
PF_PCIE_config_space_atr_table_init(uint64_t apb_addr,uint8_t pcie_ctrl_num,uint64_t ecam_addr)723 PF_PCIE_config_space_atr_table_init
724 (
725 uint64_t apb_addr,
726 uint8_t pcie_ctrl_num,
727 uint64_t ecam_addr
728 )
729 {
730 uint8_t returnval = PF_PCIE_ATR_TABLE_INIT_SUCCESS;
731 uint32_t ecam_addr_low;
732 uint32_t ecam_addr_high;
733
734 if (NULL_POINTER == g_rp_pcie_bridge)
735 {
736 if (PF_PCIE_CTRL_0 == pcie_ctrl_num)
737 {
738 g_rp_pcie_bridge = ((PCIE_BRIDGE *)((uintptr_t)(apb_addr + PCIE0_BRIDGE_PHY_ADDR_OFFSET)));
739 g_rp_pcie_ctrl = ((PCIE_CTRL *)((uintptr_t)(apb_addr + PCIE0_CRTL_PHY_ADDR_OFFSET)));
740 }
741 else if (PF_PCIE_CTRL_1 == pcie_ctrl_num)
742 {
743 g_rp_pcie_bridge = ((PCIE_BRIDGE *)((uintptr_t)(apb_addr + PCIE1_BRIDGE_PHY_ADDR_OFFSET)));
744 g_rp_pcie_ctrl = ((PCIE_CTRL *)((uintptr_t)(apb_addr + PCIE1_CRTL_PHY_ADDR_OFFSET)));
745 }
746 else
747 {
748 g_rp_pcie_bridge = NULL_POINTER;
749 returnval = PF_PCIE_ATR_TABLE_INIT_FAILURE;
750 }
751
752 if (NULL_POINTER != g_rp_pcie_bridge)
753 {
754 /* Clear interrupts on PCIe RootPort */
755 g_rp_pcie_ctrl->ECC_CONTROL = PCIE_ECC_DISABLE;
756 g_rp_pcie_ctrl->PCIE_EVENT_INT = PCIE_EVENT_INT_DATA;
757 g_rp_pcie_ctrl->SEC_ERROR_INT = PCIE_SEC_ERROR_INT_CLEAR;
758 g_rp_pcie_ctrl->DED_ERROR_INT = PCIE_DED_ERROR_INT_CLEAR;
759
760 g_rp_pcie_bridge->ISTATUS_LOCAL = PCIE_ISTATUS_CLEAR;
761 g_rp_pcie_bridge->IMASK_LOCAL = PCIE_CLEAR;
762 g_rp_pcie_bridge->ISTATUS_HOST = PCIE_ISTATUS_CLEAR;
763 g_rp_pcie_bridge->IMASK_HOST = PCIE_CLEAR;
764 }
765 }
766
767 if (NULL_POINTER != g_rp_pcie_bridge)
768 {
769 /* Check Root Port */
770 if (ROOT_PORT_ENABLE == (g_rp_pcie_bridge->GEN_SETTINGS & ROOT_PORT_ENABLE))
771 {
772 ecam_addr_low = (uint32_t)(ecam_addr & MASK_32BIT);
773 ecam_addr_high = (uint32_t)((ecam_addr >> SHIFT_32BIT) & MASK_32BIT);
774 /* Selects PCIe Config space */
775 g_rp_pcie_bridge->ATR0_AXI4_SLV0_TRSL_PARAM = PCIE_CONFIG_INTERFACE;
776
777 g_rp_pcie_bridge->ATR0_AXI4_SLV0_SRCADDR_PARAM = ecam_addr_low |
778 SIZE_256MB_TRANSLATE_TABLE_EN;
779 g_rp_pcie_bridge->ATR0_AXI4_SLV0_SRC_ADDR = ecam_addr_high;
780 g_rp_pcie_bridge->ATR0_AXI4_SLV0_TRSL_ADDR_LSB = ecam_addr_low;
781 g_rp_pcie_bridge->ATR0_AXI4_SLV0_TRSL_ADDR_UDW = ecam_addr_high;
782 }
783 else
784 {
785 returnval = PF_PCIE_ATR_TABLE_INIT_FAILURE;
786 }
787 }
788 return returnval;
789 }
790
791 /**************************************************************************//**
792 * See pf_pciess.h for details of how to use this function.
793 *
794 */
PF_PCIE_config_space_atr_table_terminate(void)795 void PF_PCIE_config_space_atr_table_terminate(void)
796 {
797 if (NULL_POINTER != g_rp_pcie_bridge)
798 {
799 /* Selects PCIe Tx/Rx Interface, disable PCIe Config space */
800 g_rp_pcie_bridge->ATR0_AXI4_SLV0_TRSL_PARAM = PCIE_TX_RX_INTERFACE;
801 }
802 }
803
804 /**************************************************************************//**
805 * See pf_pciess.h for details of how to use this function.
806 * PCIe reads configuration space of end point or root port.
807 */
808 void
PF_PCIE_config_space_read(uint64_t ecam_addr,uint16_t config_space_offset,uint32_t * value)809 PF_PCIE_config_space_read
810 (
811 uint64_t ecam_addr,
812 uint16_t config_space_offset,
813 uint32_t * value
814 )
815 {
816 volatile uint32_t * cfg_reg = (uint32_t *)((uintptr_t)(ecam_addr + config_space_offset));
817 *value = *(cfg_reg);
818 }
819
820 /**************************************************************************//**
821 * See pf_pciess.h for details of how to use this function.
822 * PCIe writes configuration space of end point or root port.
823 */
824 void
PF_PCIE_config_space_write(uint64_t ecam_addr,uint16_t config_space_offset,uint32_t value)825 PF_PCIE_config_space_write
826 (
827 uint64_t ecam_addr,
828 uint16_t config_space_offset,
829 uint32_t value
830 )
831 {
832 volatile uint32_t * cfg_reg = (uint32_t *)((uintptr_t)(ecam_addr + config_space_offset));
833 *(cfg_reg) = value;
834 }
835
836 /**************************************************************************//**
837 * See pf_pciess.h for details of how to use this function.
838 *
839 */
840 uint8_t
PF_PCIE_master_atr_table_init(uint64_t apb_addr,uint8_t pcie_ctrl_num,pf_pcie_master_atr_cfg_t * cfg,uint8_t master_table_num,uint8_t tlp_type)841 PF_PCIE_master_atr_table_init
842 (
843 uint64_t apb_addr,
844 uint8_t pcie_ctrl_num,
845 pf_pcie_master_atr_cfg_t * cfg,
846 uint8_t master_table_num,
847 uint8_t tlp_type
848 )
849 {
850 uint32_t * p_pcie_master_table;
851 uint32_t * p_pcie_bar;
852 PCIE_BRIDGE * p_pcie_bridge;
853 uint32_t phy_reg;
854 uint8_t returnval = PF_PCIE_ATR_TABLE_INIT_SUCCESS;
855
856 /* Set pcie bridge base address for ATR master table based on pcie controller 0/1 */
857 if (PF_PCIE_CTRL_0 == pcie_ctrl_num)
858 {
859 p_pcie_bridge = ((PCIE_BRIDGE *)((uintptr_t)(apb_addr + PCIE0_BRIDGE_PHY_ADDR_OFFSET)));
860 p_pcie_master_table = ((uint32_t *)((uintptr_t)(apb_addr + PCIE0_BRIDGE_PHY_ADDR_OFFSET +
861 ATR0_PCIE_WIN0_OFFSET + (master_table_num * ATR_WIN_REG_TABLE_SIZE))));
862
863 if (cfg->bar_type == PF_PCIE_BAR_TYPE_64BIT_PREFET_MEM)
864 {
865 p_pcie_bar = ((uint32_t *)((uintptr_t)(apb_addr + PCIE0_BRIDGE_PHY_ADDR_OFFSET + BAR_01_DW0 + (master_table_num * 8u))));
866 }
867 else
868 {
869 p_pcie_bar = ((uint32_t *)((uintptr_t)(apb_addr + PCIE0_BRIDGE_PHY_ADDR_OFFSET + BAR_01_DW0 + (master_table_num * 4u))));
870 }
871 }
872 else if (PF_PCIE_CTRL_1 == pcie_ctrl_num)
873 {
874 p_pcie_bridge = ((PCIE_BRIDGE *)((uintptr_t)(apb_addr + PCIE1_BRIDGE_PHY_ADDR_OFFSET)));
875 p_pcie_master_table = ((uint32_t *)((uintptr_t)(apb_addr + PCIE1_BRIDGE_PHY_ADDR_OFFSET +
876 ATR0_PCIE_WIN0_OFFSET + (master_table_num * ATR_WIN_REG_TABLE_SIZE))));
877
878 if (cfg->bar_type == PF_PCIE_BAR_TYPE_64BIT_PREFET_MEM)
879 {
880 p_pcie_bar = ((uint32_t *)((uintptr_t)(apb_addr + PCIE1_BRIDGE_PHY_ADDR_OFFSET + BAR_01_DW0 + (master_table_num * 8u))));
881 }
882 else
883 {
884 p_pcie_bar = ((uint32_t *)((uintptr_t)(apb_addr + PCIE1_BRIDGE_PHY_ADDR_OFFSET + BAR_01_DW0 + (master_table_num * 4u))));
885 }
886 }
887 else
888 {
889 p_pcie_bridge = NULL_POINTER;
890 }
891
892 /* Check for pcie bridge controller base address */
893 if (NULL_POINTER != p_pcie_bridge)
894 {
895 /* Check for PCIe Root Port */
896 if (ROOT_PORT_ENABLE == (p_pcie_bridge->GEN_SETTINGS & ROOT_PORT_ENABLE))
897 {
898 if (master_table_num < 2u)
899 {
900 /* Write BAR_01 or BAR_23 size and bar type */
901 phy_reg = ~((1u << (cfg->bar_size + 1u)) -1u);
902 *p_pcie_bar = (phy_reg | cfg->bar_type);
903
904 if (cfg->bar_type == PF_PCIE_BAR_TYPE_64BIT_PREFET_MEM)
905 {
906 /* Bar size mask in BAR_01/23_DW1 [64:32] bit */
907 *(p_pcie_bar + 1u) = BAR_MASK;
908 }
909 }
910 else
911 {
912 returnval = PF_PCIE_ATR_TABLE_INIT_FAILURE;
913 }
914 }
915 else /* End Point */
916 {
917 if (master_table_num < 6u)
918 {
919 /* Write BAR_01 or BAR_23 or BAR_45 size and bar type */
920 phy_reg = ~((1u << (cfg->bar_size + 1u)) -1u);
921 *p_pcie_bar = (phy_reg | cfg->bar_type);
922
923 if (cfg->bar_type == PF_PCIE_BAR_TYPE_64BIT_PREFET_MEM)
924 {
925 /* Bar size mask in BAR_01/23/45_DW1 [64:32] bit */
926 *(p_pcie_bar + 1u) = BAR_MASK;
927 }
928 }
929 else
930 {
931 returnval = PF_PCIE_ATR_TABLE_INIT_FAILURE;
932 }
933 }
934
935 if (PF_PCIE_ATR_TABLE_INIT_SUCCESS == returnval)
936 {
937 phy_reg = (uint32_t)(cfg->src_addr & ATR_ADDR_MASK);
938 phy_reg |= (uint32_t)((cfg->table_size) << PCIE_SET);
939 phy_reg |= (uint32_t)(cfg->state);
940
941 /* Set ATR Master SRC LSB address */
942 *(p_pcie_master_table + WIN0_SRCADDR_PARAM) = phy_reg;
943 /* Set ATR Master SRC MSB address */
944 *(p_pcie_master_table + WIN0_SRC_ADDR) = (cfg->src_addr_msb);
945 /* Set ATR Master TRNSL LSB address */
946 *(p_pcie_master_table + WIN0_TRSL_ADDR_LSB) = (cfg->trns_addr & ATR_ADDR_MASK);
947 /* Set ATR Master TRNSL MSB address */
948 *(p_pcie_master_table + WIN0_TRSL_ADDR_UDW) = (cfg->trns_addr_msb);
949 /* Set TLP type and TRSL_ID value */
950 *(p_pcie_master_table + WIN0_TRSL_PARAM) = ((uint32_t)tlp_type << TLP_SHIFT) | AXI4_MASTER_0_INTERFACE;
951 }
952 }
953 else
954 {
955 returnval = PF_PCIE_ATR_TABLE_INIT_FAILURE;
956 }
957
958 return returnval;
959 }
960
961 /**************************************************************************//**
962 * See pf_pciess.h for details of how to use this function.
963 *
964 */
965 uint8_t
PF_PCIE_slave_atr_table_init(uint64_t apb_addr,uint8_t pcie_ctrl_num,pf_pcie_slave_atr_cfg_t * cfg,uint8_t slave_table_num,uint8_t tlp_type)966 PF_PCIE_slave_atr_table_init
967 (
968 uint64_t apb_addr,
969 uint8_t pcie_ctrl_num,
970 pf_pcie_slave_atr_cfg_t * cfg,
971 uint8_t slave_table_num,
972 uint8_t tlp_type
973 )
974 {
975 uint32_t * p_pcie_slave;
976 uint32_t phy_reg = PCIE_CLEAR;
977 uint8_t returnval = PF_PCIE_ATR_TABLE_INIT_SUCCESS;
978
979 /* Set pcie bridge base address for ATR slave table based on pcie controlle 0/1 */
980 if (PF_PCIE_CTRL_0 == pcie_ctrl_num)
981 {
982 p_pcie_slave = ((uint32_t * )((uintptr_t)(apb_addr + PCIE0_BRIDGE_PHY_ADDR_OFFSET +
983 ATR0_AXI4_SLV0_OFFSET + (slave_table_num * ATR_SLV_REG_TABLE_SIZE))));
984 }
985 else if (PF_PCIE_CTRL_1 == pcie_ctrl_num)
986 {
987 p_pcie_slave = ((uint32_t * )((uintptr_t)(apb_addr + PCIE1_BRIDGE_PHY_ADDR_OFFSET +
988 ATR0_AXI4_SLV0_OFFSET + (slave_table_num * ATR_SLV_REG_TABLE_SIZE))));
989 }
990 else
991 {
992 p_pcie_slave = NULL_POINTER;
993 }
994
995 /* Check for pcie bridge controller base address */
996 if (NULL_POINTER != p_pcie_slave)
997 {
998 phy_reg = (uint32_t)(cfg->src_addr & ATR_ADDR_MASK);
999 phy_reg |= (uint32_t)((cfg->size) << PCIE_SET);
1000 phy_reg |= (uint32_t)(cfg->state);
1001 /* Set ATR slave SRC LSB address */
1002 *(p_pcie_slave + SLV0_SRCADDR_PARAM) = phy_reg;
1003 /* Set ATR slave SRC MSB address */
1004 *(p_pcie_slave + SLV0_SRC_ADDR) = (cfg->src_addr_msb);
1005 /* Set ATR slave TRNSL LSB address */
1006 phy_reg = (cfg->trns_addr & ATR_ADDR_MASK);
1007 *(p_pcie_slave + SLV0_TRSL_ADDR_LSB) = phy_reg;
1008 /* Set ATR slave TRNSL LSB address */
1009 *(p_pcie_slave + SLV0_TRSL_ADDR_UDW) = (cfg->trns_addr_msb);
1010 /* Set TLP type */
1011 *(p_pcie_slave + SLV0_TRSL_PARAM) = ((uint32_t)tlp_type << TLP_SHIFT) | PCIE_TX_RX_INTERFACE;
1012 }
1013 else
1014 {
1015 returnval = PF_PCIE_ATR_TABLE_INIT_FAILURE;
1016 }
1017 return returnval;
1018 }
1019
1020 /**************************************************************************//**
1021 * See pf_pciess.h for details of how to use this function.
1022 *
1023 */
PF_PCIE_dma_init(uint64_t allocated_addr)1024 void PF_PCIE_dma_init(uint64_t allocated_addr)
1025 {
1026 g_ep_bridge_reg = (PCIE_BRIDGE *)((uintptr_t)allocated_addr);
1027 g_ep_ctrl_reg = (PCIE_CTRL *)((uintptr_t)(allocated_addr + 0x2000u));
1028
1029 /* Disable EP ECC interrupts and clear status bits */
1030 g_ep_ctrl_reg->ECC_CONTROL = PCIE_ECC_DISABLE;
1031 g_ep_ctrl_reg->PCIE_EVENT_INT = PCIE_EVENT_INT_DATA;
1032 g_ep_ctrl_reg->SEC_ERROR_INT = PCIE_SEC_ERROR_INT_CLEAR;
1033 g_ep_ctrl_reg->DED_ERROR_INT = PCIE_DED_ERROR_INT_CLEAR;
1034
1035 /* Disable and clear Local and Host interrupts on EP */
1036 g_ep_bridge_reg->IMASK_LOCAL = PCIE_CLEAR;
1037 g_ep_bridge_reg->ISTATUS_LOCAL = PCIE_ISTATUS_CLEAR;
1038 g_ep_bridge_reg->IMASK_HOST = PCIE_CLEAR;
1039 g_ep_bridge_reg->ISTATUS_HOST = PCIE_ISTATUS_CLEAR;
1040
1041 /* Enable PCIe Host MSI, INTx DMAx interrupts on EP */
1042 g_ep_bridge_reg->IMASK_HOST= PCIE_HOST_INT_ENABLE;
1043 g_ep_bridge_reg->ISTATUS_HOST = PCIE_ISTATUS_CLEAR;
1044
1045 /* initialize default interrupt handlers */
1046 g_pcie_dma.tx_complete_handler = NULL_POINTER;
1047 g_pcie_dma.rx_complete_handler = NULL_POINTER;
1048
1049 g_pcie_dma.state = PF_PCIE_EP_DMA_COMPLETED;
1050 }
1051
1052 /**************************************************************************//**
1053 * See pf_pciess.h for details of how to use this function.
1054 *
1055 */
1056 void
PF_PCIE_set_dma_write_callback(pf_pcie_write_callback_t write_callback)1057 PF_PCIE_set_dma_write_callback
1058 (
1059 pf_pcie_write_callback_t write_callback
1060 )
1061 {
1062 g_pcie_dma.tx_complete_handler = write_callback;
1063 }
1064
1065 /**************************************************************************//**
1066 * See pf_pciess.h for details of how to use this function.
1067 *
1068 */
1069 void
PF_PCIE_set_dma_read_callback(pf_pcie_read_callback_t rx_callback)1070 PF_PCIE_set_dma_read_callback
1071 (
1072 pf_pcie_read_callback_t rx_callback
1073 )
1074 {
1075 g_pcie_dma.rx_complete_handler = rx_callback;
1076 }
1077
1078 /**************************************************************************//**
1079 * See pf_pciess.h for details of how to use this function.
1080 *
1081 */
PF_PCIE_dma_abort(void)1082 void PF_PCIE_dma_abort(void)
1083 {
1084 if(NULL_POINTER != g_ep_bridge_reg)
1085 {
1086 g_ep_bridge_reg->DMA0_CONTROL = PCIE_CLEAR;
1087 g_ep_bridge_reg->DMA1_CONTROL = PCIE_CLEAR;
1088 }
1089 g_pcie_dma.state = PF_PCIE_EP_DMA_COMPLETED;
1090 }
1091
1092 /**************************************************************************//**
1093 * See pf_pciess.h for details of how to use this function.
1094 *
1095 */
1096 void
PF_PCIE_dma_read(uint64_t src_address,uint64_t dest_address,uint32_t rx_lenth)1097 PF_PCIE_dma_read
1098 (
1099 uint64_t src_address,
1100 uint64_t dest_address,
1101 uint32_t rx_lenth
1102 )
1103 {
1104 /* Check EP bridge access enabled with DMA */
1105 if (NULL_POINTER != g_ep_bridge_reg)
1106 {
1107 if ((PF_PCIE_EP_DMA_IN_PROGRESS != g_pcie_dma.state) && (rx_lenth > 0u))
1108 {
1109 g_ep_bridge_reg->DMA1_CONTROL = PCIE_CLEAR;
1110 /* DMA from EP to RP - source EP AXI-Master, destination PCIe - DMA1 */
1111 /* AXI4-Master Interface for Source*/
1112 g_ep_bridge_reg->DMA1_SRC_PARAM = EP_DMA_INTERFACE_AXI;
1113 /* PCIe Interface for Destination */
1114 g_ep_bridge_reg->DMA1_DESTPARAM = EP_DMA_INTERFACE_PCIE;
1115 /* Set source address */
1116 g_ep_bridge_reg->DMA1_SRCADDR_LDW = (uint32_t)(src_address & MASK_32BIT);
1117 g_ep_bridge_reg->DMA1_SRCADDR_UDW = (uint32_t)((src_address >> SHIFT_32BIT) & MASK_32BIT);
1118 /* Set destination address*/
1119 g_ep_bridge_reg->DMA1_DESTADDR_LDW = (uint32_t)(dest_address & MASK_32BIT);
1120 g_ep_bridge_reg->DMA1_DESTADDR_UDW = (uint32_t)((dest_address >> SHIFT_32BIT) & MASK_32BIT);
1121 /* Set dma size */
1122 g_ep_bridge_reg->DMA1_LENGTH = rx_lenth;
1123 /*Start dma transaction */
1124 g_ep_bridge_reg->DMA1_CONTROL = EP_DMA_START_DATA;
1125
1126 g_pcie_dma.state = PF_PCIE_EP_DMA_IN_PROGRESS;
1127 }
1128 }
1129 else
1130 {
1131 g_pcie_dma.state = PF_PCIE_EP_DMA_NOT_INITIALIZED;
1132 }
1133 }
1134
1135 /**************************************************************************//**
1136 * See pf_pciess.h for details of how to use this function.
1137 *
1138 */
1139 void
PF_PCIE_dma_write(uint64_t src_address,uint64_t dest_address,uint32_t tx_lenth)1140 PF_PCIE_dma_write
1141 (
1142 uint64_t src_address,
1143 uint64_t dest_address,
1144 uint32_t tx_lenth
1145 )
1146 {
1147 /* Check EP bridge access enabled with DMA */
1148 if (NULL_POINTER != g_ep_bridge_reg)
1149 {
1150 if ((PF_PCIE_EP_DMA_IN_PROGRESS != g_pcie_dma.state) && (tx_lenth > 0u))
1151 {
1152 g_ep_bridge_reg->DMA0_CONTROL = PCIE_CLEAR;
1153 /* DMA from RP to EP - source RP-PCIe, destination AXI-Master - DMA0 */
1154 /* PCIe Interface for Source */
1155 g_ep_bridge_reg->DMA0_SRC_PARAM = EP_DMA_INTERFACE_PCIE;
1156 /*AXI4-Master Interface for Destination*/
1157 g_ep_bridge_reg->DMA0_DESTPARAM = EP_DMA_INTERFACE_AXI;
1158 /* Set source address */
1159 g_ep_bridge_reg->DMA0_SRCADDR_LDW = (uint32_t)(src_address & MASK_32BIT);
1160 g_ep_bridge_reg->DMA0_SRCADDR_UDW = (uint32_t)((src_address >> SHIFT_32BIT) & MASK_32BIT);
1161 /* Set destination address*/
1162 g_ep_bridge_reg->DMA0_DESTADDR_LDW = (uint32_t)(dest_address & MASK_32BIT);
1163 g_ep_bridge_reg->DMA0_DESTADDR_UDW = (uint32_t)((dest_address >> SHIFT_32BIT) & MASK_32BIT);
1164 /* Set dma size */
1165 g_ep_bridge_reg->DMA0_LENGTH = tx_lenth;
1166 /*Start dma transaction */
1167 g_ep_bridge_reg->DMA0_CONTROL = EP_DMA_START_DATA;
1168
1169 g_pcie_dma.state = PF_PCIE_EP_DMA_IN_PROGRESS;
1170 }
1171 }
1172 else
1173 {
1174 g_pcie_dma.state = PF_PCIE_EP_DMA_NOT_INITIALIZED;
1175 }
1176 }
1177
1178 /**************************************************************************//**
1179 * See pf_pciess.h for details of how to use this function.
1180 *
1181 */
1182 pf_pcie_ep_dma_status_t
PF_PCIE_dma_get_transfer_status(void)1183 PF_PCIE_dma_get_transfer_status
1184 (
1185 void
1186 )
1187 {
1188 return g_pcie_dma.state;
1189 }
1190
1191 /**************************************************************************//**
1192 * See pf_pciess.h for details of how to use this function.
1193 *
1194 */
PF_PCIE_enable_interrupts(void)1195 void PF_PCIE_enable_interrupts(void)
1196 {
1197 /* Check RP bridge access enabled */
1198 if (NULL_POINTER != g_rp_pcie_bridge)
1199 {
1200 g_rp_pcie_bridge->IMASK_LOCAL = PCIE_LOCAL_INT_ENABLE;
1201 g_rp_pcie_bridge->ISTATUS_LOCAL = PCIE_ISTATUS_CLEAR;
1202 g_rp_pcie_bridge->ISTATUS_MSI = PCIE_ISTATUS_CLEAR;
1203 }
1204 }
1205
1206 /**************************************************************************//**
1207 * See pf_pciess.h for details of how to use this function.
1208 *
1209 */
PF_PCIE_disable_interrupts(void)1210 void PF_PCIE_disable_interrupts(void)
1211 {
1212 /* Check RP bridge access enabled */
1213 if (NULL_POINTER != g_rp_pcie_bridge)
1214 {
1215 g_rp_pcie_bridge->ISTATUS_LOCAL = PCIE_ISTATUS_CLEAR;
1216 g_rp_pcie_bridge->IMASK_LOCAL= PCIE_CLEAR;
1217 }
1218 }
1219
1220 /**************************************************************************//**
1221 * See pf_pciess.h for details of how to use this function.
1222 *
1223 */
PF_PCIE_isr(void)1224 void PF_PCIE_isr(void)
1225 {
1226 uint32_t phy_reg;
1227 /* Check RP bridge access enabled */
1228 if (NULL_POINTER != g_rp_pcie_bridge)
1229 {
1230 phy_reg = g_rp_pcie_bridge->ISTATUS_LOCAL;
1231 phy_reg = g_rp_pcie_bridge->ISTATUS_MSI;
1232
1233 /* Check EP bridge access enabled with DMA */
1234 if (NULL_POINTER != g_ep_bridge_reg)
1235 {
1236 phy_reg = g_ep_bridge_reg->ISTATUS_HOST;
1237
1238 /* Check EP DMA0/1 interrupt occurred */
1239 if (PCIE_CLEAR != (phy_reg & DMA_INT_STATUS))
1240 {
1241 g_ep_bridge_reg->ISTATUS_HOST = DMA_INT_STATUS;
1242 g_pcie_dma.state = PF_PCIE_EP_DMA_COMPLETED;
1243
1244 if (NULL_POINTER != g_pcie_dma.tx_complete_handler)
1245 {
1246 g_pcie_dma.tx_complete_handler(PF_PCIE_EP_DMA_COMPLETED);
1247 }
1248 }
1249 else if (PCIE_CLEAR != (phy_reg & DMA_ERR_STATUS))
1250 {
1251 g_ep_bridge_reg->ISTATUS_HOST = DMA_ERR_STATUS;
1252 g_pcie_dma.state = PF_PCIE_EP_DMA_ERROR;
1253
1254 if (NULL_POINTER != g_pcie_dma.rx_complete_handler)
1255 {
1256 g_pcie_dma.rx_complete_handler(PF_PCIE_EP_DMA_ERROR);
1257 }
1258 }
1259 else
1260 {
1261 g_ep_bridge_reg->ISTATUS_HOST = PCIE_ISTATUS_CLEAR;
1262 }
1263 }
1264 g_rp_pcie_bridge->ISTATUS_MSI = PCIE_ISTATUS_CLEAR;
1265 g_rp_pcie_bridge->ISTATUS_LOCAL = PCIE_ISTATUS_CLEAR;
1266 }
1267 }
1268
1269 /****************************************************************************
1270
1271 Compose an address to be written to configuration address port
1272
1273 @param Bus is the external PCIe function's Bus number.
1274 @param Device is the external PCIe function's Device number.
1275 @param Function is the external PCIe function's Function number.
1276 @return 32 bit composed value (address).
1277
1278 */
1279 uint64_t
ecam_address_calc(uint64_t axi_addr,uint8_t bus,uint8_t device,uint8_t function)1280 ecam_address_calc
1281 (
1282 uint64_t axi_addr,
1283 uint8_t bus,
1284 uint8_t device,
1285 uint8_t function
1286 )
1287 {
1288 uint64_t location = PCIE_CLEAR;
1289
1290 location |= ((((uint64_t)bus) << PCIE_ECAM_BUS_SHIFT) & PCIE_ECAM_BUS_MASK);
1291 location |= ((((uint64_t)device) << PCIE_ECAM_DEV_SHIFT) & PCIE_ECAM_DEV_MASK);
1292 location |= ((((uint64_t)function) << PCIE_ECAM_FUN_SHIFT) & PCIE_ECAM_FUN_MASK);
1293
1294 location &= PCIE_ECAM_MASK;
1295 axi_addr = axi_addr + location;
1296 return axi_addr;
1297 }
1298
1299 #ifdef __cplusplus
1300 }
1301 #endif
1302