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