1 /*******************************************************************************
2  * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  *
24  * PolarFire and PolarFire SoC PCIe subsystem software driver public API
25  * and data structure.
26  *
27  */
28 /*=========================================================================*//**
29   @mainpage PolarFire and PolarFire SoC PCIe Bare Metal Driver.
30 
31   @section intro_sec Introduction
32     Microsemi PolarFire™ FPGAs(PolarFire and PolarFire SoC devices) contain
33     a fully integrated PCIe endpoint and root port subsystems with optimized
34     embedded controller blocks that connect to the physical layer interface of
35     the PolarFire transceiver. Each PolarFire device includes two PolarFire
36     embedded PCIe subsystem (PCIESS) blocks. The PCIESS is a hard PCI Express
37     protocol stack embedded within every PolarFire device. It includes the
38     transaction layer, data link layer, and physical layer. The PolarFire
39     PCIESS includes both a physical coding sublayer (PCS) and a physical
40     medium attachment (PMA) sublayer that supports x1, x2, and x4 endpoint
41     and root port configurations at up to 5 Gbps (Gen 2) speeds.
42 
43     Note: All references to PolarFire in this document include both
44     PolarFire and PolarFire SoC devices unless stated otherwise.
45 
46     The PolarFire PCIe software driver, provided as C source code, supports a
47     set of functions for controlling PCIe as part of a bare-metal system where
48     no operating system is available. The driver can be adapted for use as part
49     of an operating system, but the implementation of the adaptation layer
50     between the driver and the operating system's driver model is outside the
51     scope of the driver.
52 
53   @section theory_op Theory of Operation
54 
55     The PolarFire PCIe driver functions are grouped into the following categories:
56         • Enumeration
57         • Memory Allocation
58         • MSI Enabling
59         • Configuration Space Read and Write
60         • Address Translation Table
61         • Interrupt Control
62         • End Point DMA Operation
63         • Supports PCIe for both PolarFire and PolarFire SoC devices
64 
65     Enumeration
66     If the PolarFire PCI Express is configured as a root port, the application
67     must call the PF_PCIE_enumeration() function to enumerate the PCIe system
68     components. The PF_PCIE_enumeration() function uses the PCIe base address,
69     the dual PCIe controller number, and the ECAM base address as its
70     parameters, and returns the number of PCIe bridges/switches and endpoint
71     devices attached to the PCIe system. The initial ECAM base address for
72     the enumeration must start with 0 for bus, device, and function numbers.
73 
74     Memory Allocation
75     The PF_PCIE_allocate_memory() function allocates memory on the PCIe root
76     port host processor for the PCIe endpoints. The application must call this
77     function after it calls the PF_PCIE_enumeration() function. This function
78     uses the ECAM base address and allocated memory address from the host
79     processor memory map as its parameters.
80 
81     MSI Enabling
82     The PF_PCIE_enable_config_space_msi() enables MSI in the PCIe configuration
83     space of the MSI capability register set. The application must call this
84     function after it calls the PF_PCIE_enumeration() function. The function must
85     be called separately to enable MSI in the PCIe root port and PCIe endpoint.
86 
87     Configuration Space Read and Write
88     The following functions are used for configuration space read and write:
89         • PF_PCIE_type1_header_read()
90         • PF_PCIE_config_space_atr_table_init()
91         • PF_PCIE_config_space_atr_table_terminate()
92         • PF_PCIE_config_space_read()
93         • PF_PCIE_config_space_write()
94 
95     The PF_PCIE_config_space_read() and PF_PCIE_config_space_write() functions
96     are used by the application to read and write data to the PCIe type 0 or
97     type 1 configuration space registers. Before calling the configuration space
98     read or write function, the application must initialize the address
99     translation table for the configuration space using the
100     PF_PCIE_config_space_atr_table_init() function. The application can terminate
101     the configuration space read or write operation using the
102     PF_PCIE_config_space_atr_table_terminate() function. The application can
103     read the entire PCIe type 1 configuration space header information using the
104     PF_PCIE_type1_header_read() function.
105 
106     Address Translation table
107     The following functions are used for address translation table setup:
108         • PF_PCIE_master_atr_table_init()
109         • PF_PCIE_slave_atr_table_init()
110     The PF_PCIE_master_atr_table_init() function initializes the address
111     translation table for the PCIe to perform address translation from the
112     PCIe address space (BAR) to the AXI4 master.
113     The PF_PCIE_slave_atr_table_init() function initializes the address
114     translation table for the PCIe to perform address translation from the
115     AXI4 slave to the PCIe address space.
116 
117     Interrupt Control
118     Interrupts generated by the PCIe controller configured for MSI, INTx, and
119     DMA transfer using the following functions:
120         • PF_PCIE_enable_interrupts()
121         • PF_PCIE_disable_interrupts()
122         • PF_PCIE_isr()
123     The PF_PCIE_enable_interrupts() function is used to enable the local MSI,
124     INTx, and DMA transfer interrupts on the PCIe Root Port.
125     The PF_PCIE_disable_interrupts() function is used to disable the local MSI,
126     INTx, and DMA transfer interrupts on the PCIe Root Port.
127     The PF_PCIE_isr() function is used to handle the PCIe interrupts. The user
128     must call the PF_PCIE_isr() function from the system level interrupt handler.
129 
130     End Point DMA Operation
131     The Application on the PCIe Root Port host processor initializes and configures
132     the PolarFire PCIe End Point DMA engine for DMA transfer.
133 
134     The following functions are used for DMA transfer:
135         • PF_PCIE_dma_init()
136         • PF_PCIE_dma_read()
137         • PF_PCIE_dma_write()
138         • PF_PCIE_dma_abort()
139         • PF_PCIE_set_dma_write_callback()
140         • PF_PCIE_set_dma_read_callback()
141         • PF_PCIE_dma_get_transfer_status()
142 
143     Initialization
144     The PF_PCIE_dma_init() function in the PCIe root port application initializes
145     the PolarFire PCIe endpoint DMA. This function must be called before any
146     other PolarFire PCIe DMA driver functions. This function uses the allocated
147     memory address from the memory map for the PCIe endpoint BAR on the host
148     processor as its parameter. The application can call this function after
149     the PF_PCIE_enumeration() and PF_PCIE_allocate_memory() functions.
150 
151     Data Transfer Control
152     The PF_PCIE_dma_read() function starts a DMA transfer from the PCIe endpoint
153     memory to the PCIe root port memory. It reads the data from the PCIe
154     endpoint memory and writes it to the PCIe root port memory.
155 
156     The PF_PCIE_dma_write() function starts a DMA transfer from PCIe root port
157     memory to the PCIe endpoint memory. It reads the data from the PCIe root
158     port memory and writes it to the PCIe endpoint memory.
159     For all DMA transfers, the user must provide the source and destination
160     address, along with the transfer size.
161 
162     The PF_PCIE_dma_abort() function aborts a dma transfer that is in progress.
163 
164     Data transfer status
165     The status of the PCIe DMA transfer initiated by the last call to PF_PCIE_dma_read()
166     or PF_PCIE_dma_write() can be retrieved using the PF_PCIE_dma_get_transfer_status()
167     function.
168 
169     Interrupt Handling
170     PCIe DMA read and write operations are interrupt driven. The application must
171     register read and write callback functions with the driver. This relevant callback
172     function is then called by the PCIe driver every time data is written to or read
173     from the destination address.
174     The PF_PCIE_set_dma_read_callback() and PF_PCIE_set_dma_write_callback()
175     functions are used to register a handler function that is called by the
176     driver when the endpoint DMA transfer is completed. The driver passes the
177     outcome of the transfer to the completion handler in the form of a
178     pf_pcie_ep_dma_status_t parameter, which indicates whether the transfer
179     was successful, and in case of an error during the transfer, indicates
180     the type of error that occurred. The user must create and register
181     transfer completion handler functions suitable for the application.
182 
183     The user must call the PF_PCIE_enable_interupts() function or the
184     PF_PCIE_disable_interupts() function to enable or disable PCIe interrupts.
185     And also, the user must call the PF_PCIE_isr() function from the system
186     level interrupt handler for handling DMA interrupts.
187 
188 *//*=========================================================================*/
189 #ifndef PF_PCIESS_H_
190 #define PF_PCIESS_H_
191 
192 #include "pf_pcie_regs.h"
193 #include "pf_pcie_types.h"
194 
195 #ifdef __cplusplus
196 extern "C" {
197 #endif
198 
199 /*****************************************************************************/
200 /* PCIe Controller 0 */
201 #define PF_PCIE_CTRL_0                 0u
202 /* PCIe Controller 1 */
203 #define PF_PCIE_CTRL_1                 1u
204 
205 /* It indicates that the ATR table is enabled */
206 #define PF_PCIE_ATR_TABLE_ENABLE       1u
207 /* It indicates that the the ATR table is disabled */
208 #define PF_PCIE_ATR_TABLE_DISABLE      0u
209 /*****************************************************************************
210   The address translation table initialization is successfully assigned to
211   a ATR table of AXI4 master/slave
212 */
213 #define PF_PCIE_ATR_TABLE_INIT_SUCCESS  0u
214 /*****************************************************************************
215   The address translation table initialization is not successfully assigned to
216   a ATR table of AXI4 master/slave
217 */
218 #define PF_PCIE_ATR_TABLE_INIT_FAILURE  1u
219 
220 /******************************************************************************
221   The PF_PCIE_enumeration() function enumerates all the components in a PCIe
222   system, including endpoints, bridges, and switches connected to the system.
223 
224   @param apb_addr
225     Specifies the base address in the processor's memory map for the registers
226     of the PCI Express hardware instance being initialized.
227 
228   @param pcie_ctrl_num
229     Specifies the PCIe controller number 0 or 1.
230 
231   @param ecam_addr
232     Specifies the ECAM address of PCIe system. The address is  calculated based
233     on the bus number, device number, function number, and the PCIe AXI4 slave
234     base address from the processor’s memory map. The bus, device, and function
235     number should be 0 so the enumeration starts with bus number 0 and ends with
236     bus number 8.
237 
238   @return
239     The PF_PCIE_enumeration() function returns a pointer to the PCIe enumerate
240     buffer structure for all the devices and bridges connected to the PCIe system.
241 
242   @code
243         uint64_t apb_addr = 0x60000000
244 
245         uint64_t ecam_addr = 0x70000000;
246         uint8_t slv_table_no = 0;
247         uint8_t tlp = PF_PCIE_TLP_MEM;
248 
249         pf_pcie_slave_atr_cfg_t  s_cfg;
250         pf_pcie_ebuff_t * p_pcie_enum_data;
251 
252         s_cfg.state = PF_PCIE_ATR_TABLE_ENABLE;
253         s_cfg.size = PF_PCIE_SIZE_256MB;
254         s_cfg.src_addr = 0x70000000;
255         s_cfg.src_addr_msb = 0;
256         s_cfg.trns_addr = 0x70000000;
257         s_cfg.trns_addr_msb = 0;
258 
259         PF_PCIE_slave_atr_table_init(apb_addr, PF_PCIE_CTRL_1, &s_cfg, slv_table_no, tlp);
260 
261         p_pcie_enumer_data = PF_PCIE_enumeration(apb_addr, PF_PCIE_CTRL_1, ecam_addr);
262 
263         if(p_pcie_enum_data->no_of_devices_attached != 0)
264         {
265 
266         }
267   @endcode
268 */
269 pf_pcie_ebuff_t *
270 PF_PCIE_enumeration
271 (
272     uint64_t apb_addr,
273     uint8_t pcie_ctrl_num,
274     uint64_t ecam_addr
275 );
276 
277 /****************************************************************************
278   The PF_PCIE_allocate_memory() function allocates memory on the PCIe root
279   port host processor for the PCIe endpoint BARs. This function must be called
280   after the PF_PCIE_enumeration() function.
281 
282   @param ecam_addr
283     Specifies the ECAM address of the PCIe system. The address is calculated
284     based on the bus number, device number, function number, and PCIe AXI4 slave
285     base address from the processor’s memory map.
286 
287   @param allocate_addr
288     Provides the translated address from the PCIe root port AXI4 slave address
289     translation table. This address is assigned to the PCIe endpoint BAR.
290 
291   @return
292     The PF_PCIE_allocate_memory() function returns a pointer to the PCIe bar
293     info structure for the assigned BAR address and BAR size to the PCIe endpoint.
294 
295    @code
296 
297         uint64_t apb_addr = 0x60000000
298         uint64_t ecam_addr = 0x70000000;
299         uint64_t ecam_addr1 = 0x70100000;
300         uint8_t slv_table_no = 0;
301         uint8_t tlp = PF_PCIE_TLP_MEM;
302 
303         pf_pcie_slave_atr_cfg_t  s_cfg;
304         pf_pcie_bar_info_t *p_pcie_bar_data;
305         pf_pcie_ebuff_t * p_pcie_enum_data;
306 
307         s_cfg.state = PF_PCIE_ATR_TABLE_ENABLE;
308         s_cfg.size = PF_PCIE_SIZE_256MB;
309         s_cfg.src_addr = 0x70000000;
310         s_cfg.src_addr_msb = 0;
311         s_cfg.trns_addr = 0x70000000;
312         s_cfg.trns_addr_msb = 0;
313 
314         PF_PCIE_slave_atr_table_init(apb_addr, PF_PCIE_CTRL_1, &s_cfg, slv_table_no, tlp);
315 
316         p_pcie_enumer_data = PF_PCIE_enumeration(apb_addr, PF_PCIE_CTRL_1, ecam_addr);
317         if(p_pcie_enum_data->no_of_devices_attached != 0)
318         {
319             p_pcie_bar_data = PF_PCIE_allocate_memory(ecam_addr1, 0x70000000);
320         }
321 
322   @endcode
323 */
324 pf_pcie_bar_info_t *
325 PF_PCIE_allocate_memory
326 (
327     uint64_t ecam_addr,
328     uint64_t allocate_addr
329 );
330 
331 /****************************************************************************
332   The PF_PCIE_enable_config_space_msi() function enables the PCIe root port or
333   endpoint MSI in the PCIe configuration space. It also sets up the message
334   address and other data required to generate MSI.
335 
336   @param ecam_addr
337     Specifies the ECAM address of the PCIe system. The address is calculated
338     based on the bus number, device number, function number, and PCIe AXI4
339     slave base address from the processor’s memory map.
340 
341   @param msi_addr
342     Specifies the target memory address on the PCIe root port to generate MSI
343     from the PCIe endpoint.
344 
345   @param msi_data
346     Specifies the data value to write into the msi_addr    parameter.
347 
348   @return
349     The PF_PCIE_enable_config_space_msi() function does not return a value.
350 
351    @code
352         uint64_t apb_addr = 0x60000000
353         uint64_t ecam_addr = 0x70000000;
354         uint64_t ecam_addr1 = 0x70100000;
355         uint8_t slv_table_no = 0;
356         uint8_t tlp = PF_PCIE_TLP_MEM;
357 
358         pf_pcie_slave_atr_cfg_t  s_cfg;
359         pf_pcie_master_atr_cfg_t  m_cfg;
360         pf_pcie_bar_info_t *p_pcie_bar_data;
361         pf_pcie_ebuff_t * p_pcie_enum_data;
362 
363         s_cfg.state = PF_PCIE_ATR_TABLE_ENABLE;
364         s_cfg.size = PF_PCIE_SIZE_256MB;
365         s_cfg.src_addr = 0x70000000;
366         s_cfg.src_addr_msb = 0;
367         s_cfg.trns_addr = 0x70000000;
368         s_cfg.trns_addr_msb = 0;
369 
370         PF_PCIE_slave_atr_table_init(apb_addr, PF_PCIE_CTRL_1, &s_cfg, slv_table_no, tlp);
371 
372         m_cfg.state =  PF_PCIE_ATR_TABLE_ENABLE;
373         m_cfg.bar_type = PF_PCIE_BAR_TYPE_64BIT_PREFET_MEM;
374         m_cfg.bar_size = PF_PCIE_SIZE_64KB;
375         m_cfg.table_size = PF_PCIE_SIZE_64KB;
376         m_cfg.src_addr = 0x10000000;
377         m_cfg.src_addr_msb = 0;
378         m_cfg.trns_addr = 0x00000000;
379         m_cfg.trns_addr_msb = 0;
380 
381         PF_PCIE_master_atr_table_init(apb_addr, PF_PCIE_CTRL_1, &m_cfg, slv_table_no, tlp);
382 
383         p_pcie_enumer_data = PF_PCIE_enumeration(apb_addr, PF_PCIE_CTRL_1, ecam_addr);
384         if(p_pcie_enum_data->no_of_devices_attached != 0)
385         {
386             PF_PCIE_enable_config_space_msi(ecam_addr, 0x190, 0x120);
387             PF_PCIE_enable_config_space_msi(ecam_addr1, 0x190, 0x120);
388         }
389 
390   @endcode
391 */
392 void
393 PF_PCIE_enable_config_space_msi
394 (
395     uint64_t ecam_addr,
396     uint64_t msi_addr,
397     uint16_t msi_data
398 );
399 
400 /****************************************************************************
401   The PF_PCIE_type1_header_read() function reads the PCIe type1 (bridge or switch)
402   configuration space header information.
403 
404   @param apb_addr
405     Specifies the base address in the processor's memory map for the registers
406     of the PCI Express hardware instance being initialized.
407 
408   @param pcie_ctrl_num
409     Specifies the PCIe controller number, 0 or 1.
410 
411   @param ecam_addr
412     Specifies the ECAM address of the PCIe system. The address is calculated
413     based on the bus number, device number, function number, and PCIe AXI4
414     slave base address from the processor’s memory map.
415 
416   @param p_type1_header
417     Contains the output of the PCIe type1 header. The PCIe bridge/switch type 1
418     header information is stored in this parameter.
419 
420   @return
421    The PF_PCIE_type1_header_read() function does not return a value.
422 
423   @code
424 
425         uint64_t apb_addr = 0x60000000
426         uint64_t ecam_addr = 0x70000000;
427         PCIE_ROOT_CONF read_type1_header;
428 
429         PF_PCIE_type1_header_read(apb_addr, PF_PCIE_CTRL_1, ecam_addr, &read_type1_header)
430 
431   @endcode
432 */
433 void
434 PF_PCIE_type1_header_read
435 (
436     uint64_t apb_addr,
437     uint8_t pcie_ctrl_num,
438     uint64_t ecam_addr,
439     PCIE_ROOT_CONF * p_type1_header
440 );
441 
442 /****************************************************************************
443   The PF_PCIE_config_space_atr_table_init() function initializes the PCIe AXI4
444   slave address translation table using the ecam_addr parameter, and enables
445   the PCIe configuration interface to read or write data to the configuration
446   space registers.
447 
448   @param apb_addr
449     Specifies the base address in the processor's memory map for the registers
450     of the PCI Express hardware instance being initialized.
451 
452   @param pcie_ctrl_num
453     Specifies the PCIe controller number, 0 or 1.
454 
455   @param ecam_addr
456     Specifies the ECAM address of the PCIe system. The address is calculated
457     based on the bus number, device number, function number, and PCIe AXI4
458     slave base address from the processor’s memory map.
459 
460   @return
461     The PF_PCIE_config_space_atr_table_init() function returns success or failure
462     of the PCIe ATR table initialization. The two possible return values are:
463         -PF_PCIE_ATR_TABLE_INIT_SUCCESS
464         -PF_PCIE_ATR_TABLE_INIT_FAILURE
465 */
466 uint8_t
467 PF_PCIE_config_space_atr_table_init
468 (
469     uint64_t apb_addr,
470     uint8_t pcie_ctrl_num,
471     uint64_t ecam_addr
472 );
473 
474 /****************************************************************************
475   The PF_PCIE_config_space_atr_table_terminate() function disables the PCIe
476   configuration interface in the address translation table and enables the PCIe
477   Tx/Rx interface for PCIe transactions.
478 
479   @param
480     The PF_PCIE_config_space_atr_table_terminate() function does not have parameters.
481 
482   @return
483     The PF_PCIE_config_space_atr_table_terminate() function does not return a value.
484 */
485 void PF_PCIE_config_space_atr_table_terminate(void);
486 
487 /****************************************************************************
488   The PF_PCIE_config_space_read() function reads the data from configuration
489   space of PCIe device register, bridge/switch register.
490 
491   @param ecam_addr
492     Specifies the ECAM address of the PCIe system. The address is calculated
493     based on the bus number, device number, function number, and PCIe AXI4
494     slave base address from the processor’s memory map.
495 
496   @param config_space_offset
497     Specifies a PCIe type 0/1 configuration space address offset.
498 
499   @param value
500     Specifies the output value to read from the PCIe type 0/1 configuration space.
501 
502   @return
503    The PF_PCIE_config_space_read() function does not return a value.
504 
505   @code
506         uint64_t apb_addr = 0x60000000
507         uint64_t ecam_addr = 0x70100000;
508         uint32_t read_value0;
509         uint32_t read_value1;
510 
511         PF_PCIE_config_space_atr_table_init(apb_addr, PF_PCIE_CTRL_1, ecam_addr);
512 
513         PF_PCIE_config_space_read(ecam_addr, DEVICE_VID_DEVID, &read_value0);
514 
515         PF_PCIE_config_space_read(ecam_addr, DEVICE_CFG_PRMSCR, &read_value1);
516 
517         PF_PCIE_config_space_atr_table_terminate();
518 
519   @endcode
520 */
521 void
522 PF_PCIE_config_space_read
523 (
524     uint64_t ecam_addr,
525     uint16_t config_space_offset,
526     uint32_t *value
527 );
528 
529 /****************************************************************************
530   The PF_PCIE_config_space_write() function writes the data on configuration
531   space of PCIe device, bridge/switch register.
532 
533   @param ecam_addr
534     Specifies the ECAM address of the PCIe system. The address is calculated
535     based on the bus number, device number, function number, and PCIe AXI4
536     slave base address from the processor’s memory map.
537 
538   @param config_space_offset
539     Specifies a PCIe type 0/1 configuration    space address offset.
540 
541   @param value
542     Specifies the input value to write on the PCIe type 0/1 configuration space.
543 
544   @return
545    The PF_PCIE_config_space_write() function does not return a value.
546 
547   @code
548         uint64_t apb_addr = 0x60000000
549         uint64_t ecam_addr = 0x70100000;
550         uint32_t write_value0 = 0x11AA;
551         uint32_t write_value1 = 0x6;
552 
553         PF_PCIE_config_space_atr_table_init(apb_addr, PF_PCIE_CTRL_1, ecam_addr);
554 
555         PF_PCIE_config_space_write(ecam_addr, DEVICE_VID_DEVID, write_value0);
556 
557         PF_PCIE_config_space_write(ecam_addr, DEVICE_CFG_PRMSCR, write_value1);
558 
559         PF_PCIE_config_space_atr_table_terminate();
560 
561   @endcode
562 */
563 void
564 PF_PCIE_config_space_write
565 (
566     uint64_t ecam_addr,
567     uint16_t config_space_offset,
568     uint32_t value
569 );
570 
571 /****************************************************************************
572   The PF_PCIE_master_atr_table_init() function sets up the address translation
573   table for the PCIe AXI4 master.
574 
575   @param apb_addr
576     Specifies the base address in the processor's memory map for the registers
577     of the PCI Express hardware instance being initialized.
578 
579   @param pcie_ctrl_num
580     Specifies the PCIe controller number, 0 or 1.
581 
582   @param cfg
583     Specifies the configuration data structure of the PCIe AXI4 Master address
584     translation table.
585 
586   @param master_table_num
587     Specifies the PCIe to AXI4 master address translation table number. There
588     are a total of six AXI master address translation tables in the PCIESS.
589 
590   @param tlp_type
591     Specifies the Transaction Layer Packet(TLP) type. Available options are:
592         • PF_PCIE_TLP_MEM
593         • PF_PCIE_TLP_MEM_LOCKED
594         • PF_PCIE_TLP_IO
595         • PF_PCIE_TLP_TRSNL_REQUEST
596         • PF_PCIE_TLP_MESSAGE
597         • PF_PCIE_TLP_MEM_TRSNL_REQUEST
598 
599   @return
600     The PF_PCIE_master_atr_table_init() function returns success or failure of
601     the PCIe ATR table initialization. The two possible return values are:
602         -PF_PCIE_ATR_TABLE_INIT_SUCCESS
603         -PF_PCIE_ATR_TABLE_INIT_FAILURE
604 
605   @code
606         pf_pcie_master_atr_cfg_t m_cfg;
607         uint64_t apb_addr = 0x60000000
608         uint8_t mst_table_no = 0;
609         uint8_t tlp = PF_PCIE_TLP_MEM;
610 
611         m_cfg.state = PF_PCIE_ATR_TABLE_ENABLE;
612         m_cfg.bar_type = PF_PCIE_BAR_TYPE_64BIT_PREFET_MEM;
613         m_cfg.bar_size = PF_PCIE_SIZE_64KB;
614         m_cfg.table_size = PF_PCIE_SIZE_64KB;
615         m_cfg.src_addr = 0x10000000;
616         m_cfg.src_addr_msb = 0;
617         m_cfg.trns_addr = 0x00000000;
618         m_cfg.trns_addr_msb = 0;
619 
620         PF_PCIE_master_atr_table_init(apb_addr, PF_PCIE_CTRL_1, &m_cfg, mst_table_no, tlp);
621 
622 
623   @endcode
624 */
625 uint8_t
626 PF_PCIE_master_atr_table_init
627 (
628     uint64_t apb_addr,
629     uint8_t pcie_ctrl_num,
630     pf_pcie_master_atr_cfg_t * cfg,
631     uint8_t master_table_num,
632     uint8_t tlp_type
633 );
634 
635 /****************************************************************************
636   The PF_PCIE_slave_atr_table_init() function sets up the address translation table
637   for the PCIe AXI4 slave.
638 
639   @param apb_addr
640     Specifies the base address in the processor's memory map for the registers
641     of the PCI Express hardware instance being initialized.
642 
643   @param pcie_ctrl_num
644     Specifies the PCIe controller number, 0 or 1.
645 
646   @param cfg
647     Specifies the configuration data structure of AXI4 slave to PCIe address
648     translation table.
649 
650   @param slave_table_num
651     Specifies the AXI4 slave to PCIe transaction address translation table
652     number. There are a total of eight AXI slave address translation tables
653     in the PCIESS.
654 
655   @param tlp_type
656     Specifies the transaction layer packet(TLP) type.
657         • PF_PCIE_TLP_MEM
658         • PF_PCIE_TLP_MEM_LOCKED
659         • PF_PCIE_TLP_IO
660         • PF_PCIE_TLP_TRSNL_REQUEST
661         • PF_PCIE_TLP_MESSAGE
662         • PF_PCIE_TLP_MEM_TRSNL_REQUEST
663 
664 
665   @return
666     The PF_PCIE_slave_atr_table_init() function returns success or failure of
667     the PCIe ATR table initialization. The two possible return values are:
668         -PF_PCIE_ATR_TABLE_INIT_SUCCESS
669         -PF_PCIE_ATR_TABLE_INIT_FAILURE
670 
671   @code
672         uint64_t apb_addr = 0x60000000
673         uint8_t slv_table_no = 0;
674         uint8_t tlp = PF_PCIE_TLP_MEM;
675         pf_pcie_slave_atr_cfg_t  s_cfg;
676 
677         s_cfg.state = PF_PCIE_ATR_TABLE_ENABLE;
678         s_cfg.size = PF_PCIE_SIZE_256MB;
679         s_cfg.src_addr = 0x70000000;
680         s_cfg.src_addr_msb = 0;
681         s_cfg.trns_addr = 0x70000000;
682         s_cfg.trns_addr_msb = 0;
683 
684         PF_PCIE_slave_atr_table_init(apb_addr, PF_PCIE_CTRL_1, &s_cfg, slv_table_no, tlp);
685 
686 
687   @endcode
688 */
689 uint8_t
690 PF_PCIE_slave_atr_table_init
691 (
692     uint64_t apb_addr,
693     uint8_t pcie_ctrl_num,
694     pf_pcie_slave_atr_cfg_t * cfg,
695     uint8_t slave_table_num,
696     uint8_t tlp_type
697 );
698 
699 /****************************************************************************
700   The PF_PCIE_dma_init() function initializes the PCIe endpoint DMA from the
701   PCIe root port host processor.
702 
703   @param allocated_addr
704     Specifies the memory address allocated on the PCIe root port host processor
705     for PCIe endpoint BAR. The BAR accesses    the endpoint DMA engine.
706 
707   @return
708    The PF_PCIE_dma_init() function does not return a value.
709 */
710 void PF_PCIE_dma_init(uint64_t  allocated_addr);
711 
712 /*******************************************************************************
713   The PF_pcie_set_dma_write_callback() function registers the function called by
714   the PCIe driver when the data has been written.
715 
716   @param write_callback
717     Points to the function that will be called when the data is written by the PCIe DMA.
718 
719   @return
720     The PF_PCIE_set_dma_write_callback() function does not return a value.
721 
722   @code
723         void transfer_complete_handler(pf_pcie_ep_dma_status_t status);
724         volatile uint32_t g_xfer_in_progress = 0;
725 
726         uint8_t External_30_IRQHandler(void)
727         {
728             PF_PCIE_isr();
729             return(EXT_IRQ_KEEP_ENABLED);
730         }
731         void demo_transfer(void)
732         {
733             PF_PCIE_dma_init(0x70008000);
734             PF_PCIE_set_dma_write_callback(transfer_complete_handler);
735             g_xfer_in_progress = 1;
736             PF_PCIE_enable_interrupts();
737             HAL_enable_interrupts();
738             PF_PCIE_dma_write(RP_SRAM_ADDR, EP_SRAM_ADDR, 128);
739             while(g_xfer_in_progress)
740             {
741                 ;
742             }
743         }
744         void transfer_complete_handler(pf_pcie_ep_dma_status_t status)
745         {
746             g_xfer_in_progress = 0;
747             switch(status)
748             {
749                 case PF_PCIE_EP_DMA_COMPLETED:
750                     display("Transfer complete");
751                 break;
752                 case PF_PCIE_EP_DMA_ERROR:
753                     display("Transfer failed: error");
754                 break;
755             }
756         }
757 
758   @endcode
759 */
760 void
761 PF_PCIE_set_dma_write_callback
762 (
763     pf_pcie_write_callback_t write_callback
764 );
765 
766 /*******************************************************************************
767   The PF_PCIE_set_dma_read_callback() function registers the function called by
768   the PCIe driver when the data has been read.
769 
770   @param read_callback
771     Points to the function that will be called when the data is read by the PCIe DMA.
772 
773   @return
774     The PF_PCIE_set_dma_read_callback() function does not return a value.
775   @code
776         void transfer_complete_handler(pf_pcie_ep_dma_status_t status);
777         volatile uint32_t g_xfer_in_progress = 0;
778 
779         uint8_t External_30_IRQHandler(void)
780         {
781             PF_PCIE_isr();
782             return(EXT_IRQ_KEEP_ENABLED);
783         }
784         void demo_transfer(void)
785         {
786             PF_PCIE_dma_init(0x70008000);
787             PF_PCIE_set_dma_read_callback(transfer_complete_handler);
788             g_xfer_in_progress = 1;
789             PF_PCIE_enable_interrupts();
790             HAL_enable_interrupts();
791             PF_PCIE_dma_write(EP_SRAM_ADDR, RP_SRAM_ADDR, 128);
792             while(g_xfer_in_progress)
793             {
794                 ;
795             }
796         }
797         void transfer_complete_handler(pf_pcie_ep_dma_status_t status)
798         {
799             g_xfer_in_progress = 0;
800             switch(status)
801             {
802                 case PF_PCIE_EP_DMA_COMPLETED:
803                     display("Transfer complete");
804                 break;
805                 case PF_PCIE_EP_DMA_ERROR:
806                     display("Transfer failed: error");
807                 break;
808             }
809         }
810 
811   @endcode
812 */
813 void
814 PF_PCIE_set_dma_read_callback
815 (
816     pf_pcie_read_callback_t read_callback
817 );
818 
819 /****************************************************************************
820   The PF_PCIE_dma_read() function initiates PCIe endpoint DMA data transfer
821   from the PCIe root port host processor. Its parameters specify the source and
822   destination addresses of the transfer, as well as its size. The PCIe DMA data
823   transfers for read operations always use the PCIe endpoint memory as the
824   source and the PCIe root port memory as the destination for the transfer.
825 
826   Note: A call to PF_PCIE_dma_read() while a transfer is in progress will not
827   initiate a new transfer. Use the PF_PCIE_dma_get_transfer_status() function
828   or a completion handler registered by the PF_PCIE_set_dma_read_callback()
829   function  to check the status of the current transfer before calling the
830   PF_PCIE_dma_read() function again.
831 
832   @param src_address
833     Specifies the source address of the PCIe endpoint memory (AXI4 master ATR
834     table sourceaddress).
835 
836   @param dest_address
837     Specifies the destination address of the PCIe root port memory (AXI4 master
838     ATR table destination address).
839 
840   @param rx_lenth
841     Specifies the length (in bytes) of the data to be read.
842 
843   @return
844    The PF_PCIE_dma_read() function does not return a value.
845 */
846 void
847 PF_PCIE_dma_read
848 (
849     uint64_t  src_address,
850     uint64_t  dest_address,
851     uint32_t  rx_lenth
852 );
853 
854 /*******************************************************************************
855   The PF_PCIE_dma_write() function initiates PCIe endpoint DMA data transfer
856   from the PCIe root port host processor. Its parameters specify the source and
857   destination addresses of the transfer as well as its size. The PCIe DMA data
858   transfers for write operations always use the PCIe root port memory as the
859   source and the PCIe endpoint memory as the destination for the transfer.
860 
861   Note: A call to PF_pcie_dma_write() while a transfer is in progress will not
862   initiate a new transfer. Use the PF_pcie_dma_get_transfer_status() function
863   or a completion handler registered by the PF_pcie_set_dma_write_callback()
864   function  to check the status of the current transfer before calling the
865   PF_pcie_dma_write() function again.
866 
867   @param src_address
868     Specifies the source address of the PCIe root port memory (AXI4 master ATR
869     table source address).
870 
871   @param dest_address
872     Specifies the destination address of the PCIe endpoint memory (AXI4 master
873     ATR table destination address).
874 
875   @param tx_lenth
876     Specifies the length (in bytes) of the data to be written.
877 
878   @return
879     The PF_PCIE_dma_write() function does not return a value.
880 */
881 void
882 PF_PCIE_dma_write
883 (
884     uint64_t  src_address,
885     uint64_t  dest_address,
886     uint32_t  tx_lenth
887 );
888 
889 /*******************************************************************************
890   The PF_PCIE_dma_abort() function aborts a PCIe DMA transfer that is in progress.
891 
892   @param
893     The PF_PCIE_dma_abort() function has no parameters.
894 
895   @return
896     The PF_PCIE_dma_abort() function does not return a value.
897 */
898 void PF_PCIE_dma_abort(void);
899 
900 /*******************************************************************************
901   The PF_PCIE_dma_get_transfer_status() function indicates the status of a PCIe
902   endpoint DMA transfer initiated by a call to the PF_PCIE_dma_write() or
903   PF_PCIE_dma_read() function.
904 
905   @param
906     The PF_PCIE_dma_get_transfer_status() function has no parameters.
907 
908   @return
909     The PF_PCIE_dma_get_transfer_status() function returns the status of the PCIE DMA
910     transfer as a value of  type pf_pcie_ep_dma_status_t. The possible return values are:
911         - PF_PCIE_EP_DMA_NOT_INITIALIZED
912         - PF_PCIE_EP_DMA_IN_PROGRESS
913         - PF_PCIE_EP_DMA_COMPLETED
914         - PF_PCIE_EP_DMA_ERROR
915   @code
916         void copy_ep_to_rp(void)
917         {
918             PF_PCIE_dma_init(0x70008000);
919             PF_PCIE_dma_read(EP_SRAM_ADDR, RP_SRAM_ADDR, 128);
920             do {
921                 xfer_state = PF_PCIE_dma_get_transfer_status();
922             }while(PF_PCIE_EP_DMA_IN_PROGRESS == xfer_state);
923         }
924 
925   @endcode
926 
927 */
928 pf_pcie_ep_dma_status_t
929 PF_PCIE_dma_get_transfer_status
930 (
931     void
932 );
933 
934 /****************************************************************************
935   The PF_pcie_enable_interrupts() function enables local interrupts(MSI, INTx,
936   DMAx) on the PCIe RootPort.
937 
938   @param
939     The PF_PCIE_enable_interrupts() function has no parameters.
940 
941   @return
942     The PF_PCIE_enable_interrupts() function does not return a value.
943 */
944 void PF_PCIE_enable_interrupts(void);
945 
946 /****************************************************************************
947   The PF_pcie_disable_interrupts() function disables the local interrupts
948   on the PCIe RootPort.
949 
950   @param
951     The PF_PCIE_disable_interrupts() function has no parameters.
952 
953   @return
954     The PF_PCIE_disable_interrupts() function does not return a value.
955 */
956 void PF_PCIE_disable_interrupts(void);
957 
958 /*******************************************************************************
959  The PF_PCIE_isr() function is a PCIe root port local interrupt handler. The
960  PF_PCIE_isr() function is the top level interrupt handler function for the
961  PolarFire PCIe driver. The user must call the PF_PCIE_isr() function from
962  the system level interrupt handler assigned to the interrupt triggered by
963  the PF_PCIE/PCIE_#_INTERRUPT_OUT signal.
964 
965   @param
966     The PF_PCIE_isr() function does not take any parameters
967 
968   @return
969     The PF_PCIE_isr() function does not return a value.
970 
971   @code
972         uint8_t External_30_IRQHandler(void)
973         {
974             PF_PCIE_isr();
975             return(EXT_IRQ_KEEP_ENABLED);
976         }
977   @endcode
978 */
979 void PF_PCIE_isr(void);
980 
981 /*****************************************************************************/
982 
983 uint64_t
984 ecam_address_calc
985 (
986     uint64_t axi_addr,
987     uint8_t bus,
988     uint8_t device,
989     uint8_t function
990 );
991 /*****************************************************************************/
992 #ifdef __cplusplus
993 }
994 #endif
995 
996 #endif /* PF_PCIESS_H_ */
997