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