1 /*- 2 ******************************************************************************** 3 Copyright (C) 2015 Annapurna Labs Ltd. 4 5 This file may be licensed under the terms of the Annapurna Labs Commercial 6 License Agreement. 7 8 Alternatively, this file can be distributed under the terms of the GNU General 9 Public License V2 as published by the Free Software Foundation and can be 10 found at http://www.gnu.org/licenses/gpl-2.0.html 11 12 Alternatively, redistribution and use in source and binary forms, with or 13 without modification, are permitted provided that the following conditions are 14 met: 15 16 * Redistributions of source code must retain the above copyright notice, 17 this list of conditions and the following disclaimer. 18 19 * Redistributions in binary form must reproduce the above copyright 20 notice, this list of conditions and the following disclaimer in 21 the documentation and/or other materials provided with the 22 distribution. 23 24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 25 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 28 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 31 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 35 *******************************************************************************/ 36 37 /** 38 * @defgroup grouppcie PCI Express Controller 39 * @{ 40 * @section overview Overview 41 * This header file provide API for the HAL driver of the pcie port, the driver 42 * provides the following functionalities: 43 * - Port initialization 44 * - Link operation 45 * - Interrupts transactions generation (Endpoint mode). 46 * - Configuration Access management functions 47 * - Internal Translation Unit programming 48 * 49 * This API does not provide the following: 50 * - PCIe transactions generation and reception (except interrupts as mentioned 51 * above) as this functionality is done by the port without need for sw 52 * intervention. 53 * - Configuration Access: those transactions are generated automatically by 54 * the port (ECAM or ATU mode) when the CPU issues memory transaction 55 * through the fabric toward the PCIe port. This API provides management 56 * function for controlling the Configuration Access type and bus destination 57 * - Interrupt Handling. 58 * - Message Generation: common used messages are automatically generated, also, 59 * the ATU generic mechanism for generating various kind of messages. 60 * - PCIe Port Management: both link and port power management features can be 61 * managed using the PCI/PCIe standard power management and PCIe capabilities 62 * registers. 63 * - PCIe link and protocol error handling: the feature can be managed using 64 * the Advanced Error Handling PCIe capability registers. 65 * 66 * @section flows Software Flows 67 * @subsection init Initialization 68 * - allocation and set zeros al_pcie_port and al_pcie_pf structures handles 69 * - call al_pcie_port_handle_init() with pointer to the allocated 70 * al_pcie_port handle, address of the port internal registers space, and 71 * port id. 72 * - call al_pcie_pf_handle_init() with pointer to the al_pcie_port handle 73 * and pf_number. 74 * - set the port mode, End-Point or Root-Compex (default). 75 * - set number of lanes connected to the controller. 76 * - enable the controller using the al_pcie_port_enable(). note that this 77 * function expect the virtual address of the PBS Functional Registers. 78 * - wait for 2000 South-bridge cycles. 79 * - prepare al_pcie_port_config_params and al_pcie_pf_config_params 80 * structures depending on chip, board and system configuration. 81 * for example, when using the port as root complex, the operating_mode 82 * field should be set to AL_PCIE_OPERATING_MODE_RC. In this example we 83 * prepare the following configuration: 84 * For port configuration 85 * - Root Complex mode 86 * - Set the Max Link Speed to Gen2 87 * - Set the max lanes width to 2 (x2) 88 * - Disable reversal mode 89 * - Enable Snoops to support I/O Hardware cache coherency 90 * - Enable pcie core RAM parity 91 * - Enable pcie core AXI parity 92 * - Keep transaction layer default credits 93 * For pf configuration 94 * - No EP parameters 95 * - No SR-IOV parameters 96 * so the structures we prepare: 97 * @code 98 * - struct al_pcie_link_params link_params = { 99 * AL_PCIE_LINK_SPEED_GEN2, 100 * AL_FALSE, // disable reversal mode 101 * AL_PCIE_MPS_DEFAULT}; 102 * 103 * - struct al_pcie_port_config_params config_params = { 104 * &link_params, 105 * AL_TRUE, // enable Snoop for inbound memory transactions 106 * AL_TRUE, // enable pcie port RAM parity 107 * AL_TRUE, // enable pcie port AXI parity 108 * NULL, // use default latency/replay timers 109 * NULL, // use default gen2 pipe params 110 * NULL, // gen3_params not needed when max speed set to Gen2 111 * NULL, // don't change TL credits 112 * NULL, // end point params not needed 113 * AL_FALSE, //no fast link 114 * AL_FALSE}; //return 0xFFFFFFFF for read transactions with 115 * //pci target error 116 * @endcode 117 * - now call al_pcie_port_config() with pcie_port and port_config_params 118 * @subsection link-init Link Initialization 119 * - once the port configured, we can start PCIe link: 120 * - call al_pcie_link_start() 121 * - call al_pcie_link_up_wait() 122 * - allocate al_pcie_link_status struct and call al_pcie_link_status() and 123 * check the link is established. 124 * 125 * @subsection cap Configuration Access Preparation 126 * - Once the link is established, we can prepare the port for pci 127 * configuration access, this stage requires system knowledge about the PCI 128 * buses enumeration. For example, if 5 buses were discovered on previously 129 * scanned root complex port, then we should start enumeration from bus 5 (PCI 130 * secondary bus), the sub-ordinary bus will be temporarily set to maximum 131 * value (255) until the scan process under this bus is finished, then it will 132 * updated to the maximum bus value found. So we use the following sequence: 133 * - call al_pcie_secondary_bus_set() with sec-bus = 5 134 * - call al_pcie_subordinary_bus_set() with sub-bus = 255 135 * 136 * @subsection cfg Configuration (Cfg) Access Generation 137 * - we assume using ECAM method, in this method, the software issues pcie Cfg 138 * access by accessing the ECAM memory space of the pcie port. For example, to 139 * issue 4 byte Cfg Read from bus B, Device D, Function F and register R, the 140 * software issues 4 byte read access to the following physical address 141 * ECAM base address of the port + (B << 20) + (D << 15) + (F << 12) + R. 142 * But, as the default size of the ECAM address space is less than 143 * needed full range (256MB), we modify the target_bus value prior to Cfg 144 * access in order make the port generate Cfg access with bus value set to the 145 * value of the target_bus rather than bits 27:20 of the physical address. 146 * - call al_pcie_target_bus_set() with target_bus set to the required bus of 147 * the next Cfg access to be issued, mask_target_bus will be set to 0xff. 148 * no need to call that function if the next Cfg access bus equals to the last 149 * value set to target_bus. 150 * 151 * @file al_hal_pcie.h 152 * @brief HAL Driver Header for the Annapurna Labs PCI Express port. 153 */ 154 155 #ifndef _AL_HAL_PCIE_H_ 156 #define _AL_HAL_PCIE_H_ 157 158 #include "al_hal_common.h" 159 #include "al_hal_pcie_regs.h" 160 161 /******************************************************************************/ 162 /********************************* Constants **********************************/ 163 /******************************************************************************/ 164 165 /** Inbound header credits sum - rev 0/1/2 */ 166 #define AL_PCIE_REV_1_2_IB_HCRD_SUM 97 167 /** Inbound header credits sum - rev 3 */ 168 #define AL_PCIE_REV3_IB_HCRD_SUM 259 169 170 /** Number of extended registers */ 171 #define AL_PCIE_EX_REGS_NUM 40 172 173 /******************************************************************************* 174 * PCIe AER uncorrectable error bits 175 * To be used with the following functions: 176 * - al_pcie_aer_config 177 * - al_pcie_aer_uncorr_get_and_clear 178 ******************************************************************************/ 179 /** Data Link Protocol Error */ 180 #define AL_PCIE_AER_UNCORR_DLP_ERR AL_BIT(4) 181 /** Poisoned TLP */ 182 #define AL_PCIE_AER_UNCORR_POISIONED_TLP AL_BIT(12) 183 /** Flow Control Protocol Error */ 184 #define AL_PCIE_AER_UNCORR_FLOW_CTRL_ERR AL_BIT(13) 185 /** Completion Timeout */ 186 #define AL_PCIE_AER_UNCORR_COMPL_TO AL_BIT(14) 187 /** Completer Abort */ 188 #define AL_PCIE_AER_UNCORR_COMPL_ABT AL_BIT(15) 189 /** Unexpected Completion */ 190 #define AL_PCIE_AER_UNCORR_UNEXPCTED_COMPL AL_BIT(16) 191 /** Receiver Overflow */ 192 #define AL_PCIE_AER_UNCORR_RCV_OVRFLW AL_BIT(17) 193 /** Malformed TLP */ 194 #define AL_PCIE_AER_UNCORR_MLFRM_TLP AL_BIT(18) 195 /** ECRC Error */ 196 #define AL_PCIE_AER_UNCORR_ECRC_ERR AL_BIT(19) 197 /** Unsupported Request Error */ 198 #define AL_PCIE_AER_UNCORR_UNSUPRT_REQ_ERR AL_BIT(20) 199 /** Uncorrectable Internal Error */ 200 #define AL_PCIE_AER_UNCORR_INT_ERR AL_BIT(22) 201 /** AtomicOp Egress Blocked */ 202 #define AL_PCIE_AER_UNCORR_ATOMIC_EGRESS_BLK AL_BIT(24) 203 204 /******************************************************************************* 205 * PCIe AER correctable error bits 206 * To be used with the following functions: 207 * - al_pcie_aer_config 208 * - al_pcie_aer_corr_get_and_clear 209 ******************************************************************************/ 210 /** Receiver Error */ 211 #define AL_PCIE_AER_CORR_RCV_ERR AL_BIT(0) 212 /** Bad TLP */ 213 #define AL_PCIE_AER_CORR_BAD_TLP AL_BIT(6) 214 /** Bad DLLP */ 215 #define AL_PCIE_AER_CORR_BAD_DLLP AL_BIT(7) 216 /** REPLAY_NUM Rollover */ 217 #define AL_PCIE_AER_CORR_RPLY_NUM_ROLL_OVR AL_BIT(8) 218 /** Replay Timer Timeout */ 219 #define AL_PCIE_AER_CORR_RPLY_TMR_TO AL_BIT(12) 220 /** Advisory Non-Fatal Error */ 221 #define AL_PCIE_AER_CORR_ADVISORY_NON_FTL_ERR AL_BIT(13) 222 /** Corrected Internal Error */ 223 #define AL_PCIE_AER_CORR_INT_ERR AL_BIT(14) 224 225 /** The AER erroneous TLP header length [num DWORDs] */ 226 #define AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS 4 227 228 /******************************************************************************/ 229 /************************* Data Structures and Types **************************/ 230 /******************************************************************************/ 231 232 /** 233 * al_pcie_ib_hcrd_config: data structure internally used in order to config 234 * inbound posted/non-posted parameters. 235 * Note: it's required to have this structure in pcie_port handle since it has 236 * a state (required/not-required) which is determined by outbound 237 * outstanding configuration 238 */ 239 struct al_pcie_ib_hcrd_config { 240 /* Internally used - see 'al_pcie_ib_hcrd_os_ob_reads_config' */ 241 unsigned int nof_np_hdr; 242 243 /* Internally used - see 'al_pcie_ib_hcrd_os_ob_reads_config' */ 244 unsigned int nof_p_hdr; 245 }; 246 247 /* The Max Payload Size. Measured in bytes. 248 * DEFAULT: do not change the current MPS 249 */ 250 enum al_pcie_max_payload_size { 251 AL_PCIE_MPS_DEFAULT, 252 AL_PCIE_MPS_128 = 0, 253 AL_PCIE_MPS_256 = 1, 254 AL_PCIE_MPS_512 = 2, 255 AL_PCIE_MPS_1024 = 3, 256 AL_PCIE_MPS_2048 = 4, 257 AL_PCIE_MPS_4096 = 5, 258 }; 259 260 /** 261 * al_pcie_port: data structure used by the HAL to handle a specific pcie port. 262 * this structure is allocated and set to zeros by the upper layer, then it is 263 * initialized by the al_pcie_port_handle_init() that should be called before any 264 * other function of this API. later, this handle passed to the API functions. 265 */ 266 struct al_pcie_port { 267 void __iomem *pcie_reg_base; 268 struct al_pcie_regs regs_ptrs; 269 struct al_pcie_regs *regs; 270 uint32_t *ex_regs_ptrs[AL_PCIE_EX_REGS_NUM]; 271 void *ex_regs; 272 void __iomem *pbs_regs; 273 274 /* Revision ID */ 275 uint8_t rev_id; 276 unsigned int port_id; 277 uint8_t max_lanes; 278 uint8_t max_num_of_pfs; 279 280 /* Internally used */ 281 struct al_pcie_ib_hcrd_config ib_hcrd_config; 282 }; 283 284 /** 285 * al_pcie_pf: the pf handle, a data structure used to handle PF specific 286 * functionality. Initialized using "al_pcie_pf_handle_init()" 287 */ 288 struct al_pcie_pf { 289 unsigned int pf_num; 290 struct al_pcie_port *pcie_port; 291 }; 292 293 /** Operating mode (endpoint, root complex) */ 294 enum al_pcie_operating_mode { 295 AL_PCIE_OPERATING_MODE_EP, 296 AL_PCIE_OPERATING_MODE_RC, 297 AL_PCIE_OPERATING_MODE_UNKNOWN 298 }; 299 300 /* The maximum link speed, measured GT/s (Giga transfer / second) 301 * DEFAULT: do not change the current speed 302 * GEN1: 2.5 GT/s 303 * GEN2: 5 GT/s 304 * GEN3: 8GT/s 305 * 306 * Note: The values of this enumerator are important for proper behavior 307 */ 308 enum al_pcie_link_speed { 309 AL_PCIE_LINK_SPEED_DEFAULT, 310 AL_PCIE_LINK_SPEED_GEN1 = 1, 311 AL_PCIE_LINK_SPEED_GEN2 = 2, 312 AL_PCIE_LINK_SPEED_GEN3 = 3 313 }; 314 315 /** PCIe capabilities that supported by a specific port */ 316 struct al_pcie_max_capability { 317 al_bool end_point_mode_supported; 318 al_bool root_complex_mode_supported; 319 enum al_pcie_link_speed max_speed; 320 uint8_t max_lanes; 321 al_bool reversal_supported; 322 uint8_t atu_regions_num; 323 uint32_t atu_min_size; 324 }; 325 326 /** PCIe link related parameters */ 327 struct al_pcie_link_params { 328 enum al_pcie_link_speed max_speed; 329 al_bool enable_reversal; 330 enum al_pcie_max_payload_size max_payload_size; 331 332 }; 333 334 /** PCIe gen2 link parameters */ 335 struct al_pcie_gen2_params { 336 al_bool tx_swing_low; /* set tx swing low when true, and tx swing full when false */ 337 al_bool tx_compliance_receive_enable; 338 al_bool set_deemphasis; 339 }; 340 341 /** PCIe gen 3 standard per lane equalization parameters */ 342 struct al_pcie_gen3_lane_eq_params { 343 uint8_t downstream_port_transmitter_preset; 344 uint8_t downstream_port_receiver_preset_hint; 345 uint8_t upstream_port_transmitter_preset; 346 uint8_t upstream_port_receiver_preset_hint; 347 }; 348 349 /** PCIe gen 3 equalization parameters */ 350 struct al_pcie_gen3_params { 351 al_bool perform_eq; 352 al_bool interrupt_enable_on_link_eq_request; 353 struct al_pcie_gen3_lane_eq_params *eq_params; /* array of lanes params */ 354 int eq_params_elements; /* number of elements in the eq_params array */ 355 356 al_bool eq_disable; /* disables the equalization feature */ 357 al_bool eq_phase2_3_disable; /* Equalization Phase 2 and Phase 3 */ 358 /* Disable (RC mode only) */ 359 uint8_t local_lf; /* Full Swing (FS) Value for Gen3 Transmit Equalization */ 360 /* Value Range: 12 through 63 (decimal).*/ 361 362 uint8_t local_fs; /* Low Frequency (LF) Value for Gen3 Transmit Equalization */ 363 }; 364 365 /** Transport Layer credits parameters */ 366 struct al_pcie_tl_credits_params { 367 }; 368 369 /** Various configuration features */ 370 struct al_pcie_features { 371 /** 372 * Enable MSI fix from the SATA to the PCIe EP 373 * Only valid for port 0, when enabled as EP 374 */ 375 al_bool sata_ep_msi_fix; 376 }; 377 378 /** 379 * Inbound posted/non-posted header credits and outstanding outbound reads 380 * completion header configuration 381 * 382 * Constraints: 383 * - nof_cpl_hdr + nof_np_hdr + nof_p_hdr == 384 * AL_PCIE_REV_1_2_IB_HCRD_SUM/AL_PCIE_REV3_IB_HCRD_SUM 385 * - nof_cpl_hdr > 0 386 * - nof_p_hdr > 0 387 * - nof_np_hdr > 0 388 */ 389 struct al_pcie_ib_hcrd_os_ob_reads_config { 390 /** Max number of outstanding outbound reads */ 391 uint8_t nof_outstanding_ob_reads; 392 393 /** 394 * This value set the possible outstanding headers CMPLs , the core 395 * can get (the core always advertise infinite credits for CMPLs). 396 */ 397 unsigned int nof_cpl_hdr; 398 399 /** 400 * This value set the possible outstanding headers reads (non-posted 401 * transactions), the core can get (it set the value in the init FC 402 * process). 403 */ 404 unsigned int nof_np_hdr; 405 406 /** 407 * This value set the possible outstanding headers writes (posted 408 * transactions), the core can get (it set the value in the init FC 409 * process). 410 */ 411 unsigned int nof_p_hdr; 412 }; 413 414 /** PCIe Ack/Nak Latency and Replay timers */ 415 struct al_pcie_latency_replay_timers { 416 uint16_t round_trip_lat_limit; 417 uint16_t replay_timer_limit; 418 }; 419 420 /* SRIS KP counter values */ 421 struct al_pcie_sris_params { 422 /** set to AL_TRUE to use defaults and ignore the other parameters */ 423 al_bool use_defaults; 424 uint16_t kp_counter_gen3; /* only for Gen3 */ 425 uint16_t kp_counter_gen21; 426 }; 427 428 /** Relaxed ordering params */ 429 struct al_pcie_relaxed_ordering_params { 430 al_bool enable_tx_relaxed_ordering; 431 al_bool enable_rx_relaxed_ordering; 432 }; 433 434 /** PCIe port configuration parameters 435 * This structure includes the parameters that the HAL should apply to the port 436 * (by al_pcie_port_config()). 437 * The fields that are pointers (e.g. link_params) can be set to NULL, in that 438 * case, the al_pcie_port_config() will keep the current HW settings. 439 */ 440 struct al_pcie_port_config_params { 441 struct al_pcie_link_params *link_params; 442 al_bool enable_axi_snoop; 443 al_bool enable_ram_parity_int; 444 al_bool enable_axi_parity_int; 445 struct al_pcie_latency_replay_timers *lat_rply_timers; 446 struct al_pcie_gen2_params *gen2_params; 447 struct al_pcie_gen3_params *gen3_params; 448 struct al_pcie_tl_credits_params *tl_credits; 449 struct al_pcie_features *features; 450 /* Sets all internal timers to Fast Mode for speeding up simulation.*/ 451 al_bool fast_link_mode; 452 /* 453 * when true, the PCI unit will return Slave Error/Decoding Error to the master unit in case 454 * of error. when false, the value 0xFFFFFFFF will be returned without error indication. 455 */ 456 al_bool enable_axi_slave_err_resp; 457 struct al_pcie_sris_params *sris_params; 458 struct al_pcie_relaxed_ordering_params *relaxed_ordering_params; 459 }; 460 461 /** BAR register configuration parameters (Endpoint Mode only) */ 462 struct al_pcie_ep_bar_params { 463 al_bool enable; 464 al_bool memory_space; /**< memory or io */ 465 al_bool memory_64_bit; /**< is memory space is 64 bit */ 466 al_bool memory_is_prefetchable; 467 uint64_t size; /* the bar size in bytes */ 468 }; 469 470 /** PF config params (EP mode only) */ 471 struct al_pcie_pf_config_params { 472 al_bool cap_d1_d3hot_dis; 473 al_bool cap_flr_dis; 474 al_bool cap_aspm_dis; 475 al_bool bar_params_valid; 476 struct al_pcie_ep_bar_params bar_params[6]; 477 struct al_pcie_ep_bar_params exp_bar_params;/* expansion ROM BAR*/ 478 }; 479 480 /** PCIe link status */ 481 struct al_pcie_link_status { 482 al_bool link_up; 483 enum al_pcie_link_speed speed; 484 uint8_t lanes; 485 uint8_t ltssm_state; 486 }; 487 488 /** PCIe lane status */ 489 struct al_pcie_lane_status { 490 al_bool is_reset; 491 enum al_pcie_link_speed requested_speed; 492 }; 493 494 /** PCIe MSIX capability configuration parameters */ 495 struct al_pcie_msix_params { 496 uint16_t table_size; 497 uint16_t table_offset; 498 uint8_t table_bar; 499 uint16_t pba_offset; 500 uint16_t pba_bar; 501 }; 502 503 /** PCIE AER capability parameters */ 504 struct al_pcie_aer_params { 505 /** ECRC Generation Enable */ 506 al_bool ecrc_gen_en; 507 /** ECRC Check Enable */ 508 al_bool ecrc_chk_en; 509 510 /** 511 * Enabled reporting of correctable errors (bit mask) 512 * See 'AL_PCIE_AER_CORR_*' for details 513 * 0 - no reporting at all 514 */ 515 unsigned int enabled_corr_err; 516 /** 517 * Enabled reporting of non-fatal uncorrectable errors (bit mask) 518 * See 'AL_PCIE_AER_UNCORR_*' for details 519 * 0 - no reporting at all 520 */ 521 unsigned int enabled_uncorr_non_fatal_err; 522 /** 523 * Enabled reporting of fatal uncorrectable errors (bit mask) 524 * See 'AL_PCIE_AER_UNCORR_*' for details 525 * 0 - no reporting at all 526 */ 527 unsigned int enabled_uncorr_fatal_err; 528 }; 529 530 /******************************************************************************/ 531 /********************************** PCIe API **********************************/ 532 /******************************************************************************/ 533 534 /*************************** PCIe Initialization API **************************/ 535 536 /** 537 * Initializes a PCIe port handle structure. 538 * 539 * @param pcie_port an allocated, non-initialized instance. 540 * @param pcie_reg_base the virtual base address of the port internal 541 * registers 542 * @param pbs_reg_base the virtual base address of the pbs functional 543 * registers 544 * @param port_id the port id (used mainly for debug messages) 545 * 546 * @return 0 if no error found. 547 */ 548 int al_pcie_port_handle_init(struct al_pcie_port *pcie_port, 549 void __iomem *pcie_reg_base, 550 void __iomem *pbs_reg_base, 551 unsigned int port_id); 552 553 /** 554 * Initializes a PCIe pf handle structure 555 * @param pcie_pf an allocated, non-initialized instance of pf handle 556 * @param pcie_port pcie port handle 557 * @param pf_num physical function number 558 * @return 0 if no error found 559 */ 560 int al_pcie_pf_handle_init( 561 struct al_pcie_pf *pcie_pf, 562 struct al_pcie_port *pcie_port, 563 unsigned int pf_num); 564 565 /************************** Pre PCIe Port Enable API **************************/ 566 567 /** 568 * @brief set current pcie operating mode (root complex or endpoint) 569 * This function can be called only before enabling the controller using 570 * al_pcie_port_enable(). 571 * 572 * @param pcie_port pcie port handle 573 * @param mode pcie operating mode 574 * 575 * @return 0 if no error found. 576 */ 577 int al_pcie_port_operating_mode_config(struct al_pcie_port *pcie_port, 578 enum al_pcie_operating_mode mode); 579 580 /** 581 * Configure number of lanes connected to this port. 582 * This function can be called only before enabling the controller using al_pcie_port_enable(). 583 * 584 * @param pcie_port pcie port handle 585 * @param lanes number of lanes 586 * Note: this function must be called before any al_pcie_port_config() calls 587 * 588 * @return 0 if no error found. 589 */ 590 int al_pcie_port_max_lanes_set(struct al_pcie_port *pcie_port, uint8_t lanes); 591 592 /** 593 * Set maximum physical function numbers 594 * @param pcie_port pcie port handle 595 * @param max_num_of_pfs number of physical functions 596 * Note: this function must be called before any al_pcie_pf_config() calls 597 */ 598 int al_pcie_port_max_num_of_pfs_set( 599 struct al_pcie_port *pcie_port, 600 uint8_t max_num_of_pfs); 601 602 /** 603 * @brief Inbound posted/non-posted header credits and outstanding outbound 604 * reads completion header configuration 605 * 606 * @param pcie_port pcie port handle 607 * @param ib_hcrd_os_ob_reads_config 608 * Inbound header credits and outstanding outbound reads 609 * configuration 610 */ 611 int al_pcie_port_ib_hcrd_os_ob_reads_config( 612 struct al_pcie_port *pcie_port, 613 struct al_pcie_ib_hcrd_os_ob_reads_config *ib_hcrd_os_ob_reads_config); 614 615 /** return PCIe operating mode 616 * @param pcie_port pcie port handle 617 * @return operating mode 618 */ 619 enum al_pcie_operating_mode al_pcie_operating_mode_get( 620 struct al_pcie_port *pcie_port); 621 622 /**************************** PCIe Port Enable API ****************************/ 623 624 /** Enable PCIe unit (deassert reset) 625 * 626 * @param pcie_port pcie port handle 627 * 628 * @return 0 if no error found. 629 */ 630 int al_pcie_port_enable(struct al_pcie_port *pcie_port); 631 632 /** Disable PCIe unit (assert reset) 633 * 634 * @param pcie_port pcie port handle 635 */ 636 void al_pcie_port_disable(struct al_pcie_port *pcie_port); 637 638 /** 639 * Port memory shutdown/up 640 * Caution: This function can be called only when the controller is disabled 641 * 642 * @param pcie_port pcie port handle 643 * @param enable memory shutdown enable or disable 644 * 645 */ 646 int al_pcie_port_memory_shutdown_set( 647 struct al_pcie_port *pcie_port, 648 al_bool enable); 649 650 /** 651 * Check if port enabled or not 652 * @param pcie_port pcie port handle 653 * @return AL_TRUE of port enabled and AL_FALSE otherwise 654 */ 655 al_bool al_pcie_port_is_enabled(struct al_pcie_port *pcie_port); 656 657 /*************************** PCIe Configuration API ***************************/ 658 659 /** 660 * @brief configure pcie port (mode, link params, etc..) 661 * this function must be called before initializing the link 662 * 663 * @param pcie_port pcie port handle 664 * @param params configuration structure. 665 * 666 * @return 0 if no error found 667 */ 668 int al_pcie_port_config(struct al_pcie_port *pcie_port, 669 const struct al_pcie_port_config_params *params); 670 671 /** 672 * @brief Configure a specific PF (EP params, sriov params, ...) 673 * this function must be called before any datapath transactions 674 * 675 * @param pcie_pf pcie pf handle 676 * @param params configuration structure. 677 * 678 * @return 0 if no error found 679 */ 680 int al_pcie_pf_config( 681 struct al_pcie_pf *pcie_pf, 682 const struct al_pcie_pf_config_params *params); 683 684 /************************** PCIe Link Operations API **************************/ 685 686 /** 687 * @brief start pcie link 688 * 689 * @param pcie_port pcie port handle 690 * 691 * @return 0 if no error found 692 */ 693 int al_pcie_link_start(struct al_pcie_port *pcie_port); 694 695 /** 696 * @brief stop pcie link 697 * 698 * @param pcie_port pcie port handle 699 * 700 * @return 0 if no error found 701 */ 702 int al_pcie_link_stop(struct al_pcie_port *pcie_port); 703 704 /** 705 * @brief trigger link-disable 706 * 707 * @param pcie_port pcie port handle 708 * @param disable AL_TRUE to disable the link and AL_FALSE to enable it 709 * 710 * Note: this functionality differs from "al_pcie_link_stop" as it's a spec 711 * functionality where both sides of the PCIe agrees to disable the link 712 * @return 0 if no error found 713 */ 714 int al_pcie_link_disable(struct al_pcie_port *pcie_port, al_bool disable); 715 716 /** 717 * @brief wait for link up indication 718 * this function waits for link up indication, it polls LTSSM state until link is ready 719 * 720 * @param pcie_port pcie port handle 721 * @param timeout_ms maximum timeout in milli-seconds to wait for link up 722 * 723 * @return 0 if link up indication detected 724 * -ETIME if not. 725 */ 726 int al_pcie_link_up_wait(struct al_pcie_port *pcie_port, uint32_t timeout_ms); 727 728 /** 729 * @brief get link status 730 * 731 * @param pcie_port pcie port handle 732 * @param status structure for link status 733 * 734 * @return 0 if no error found 735 */ 736 int al_pcie_link_status(struct al_pcie_port *pcie_port, struct al_pcie_link_status *status); 737 738 /** 739 * @brief get lane status 740 * 741 * @param pcie_port 742 * pcie port handle 743 * @param lane 744 * PCIe lane 745 * @param status 746 * Pointer to returned structure for lane status 747 * 748 */ 749 void al_pcie_lane_status_get( 750 struct al_pcie_port *pcie_port, 751 unsigned int lane, 752 struct al_pcie_lane_status *status); 753 754 /** 755 * @brief trigger hot reset 756 * 757 * @param pcie_port pcie port handle 758 * @param enable AL_TRUE to enable hot-reset and AL_FALSE to disable it 759 * 760 * @return 0 if no error found 761 */ 762 int al_pcie_link_hot_reset(struct al_pcie_port *pcie_port, al_bool enable); 763 764 /** 765 * @brief trigger link-retain 766 * this function initiates Link retraining by directing the Physical Layer LTSSM 767 * to the Recovery state. If the LTSSM is already in Recovery or Configuration, 768 * re-entering Recovery is permitted but not required. 769 770 * @param pcie_port pcie port handle 771 * 772 * Note: there's no need to disable initiating link-retrain 773 * @return 0 if no error found 774 */ 775 int al_pcie_link_retrain(struct al_pcie_port *pcie_port); 776 777 /** 778 * @brief change port speed 779 * this function changes the port speed, it doesn't wait for link re-establishment 780 * 781 * @param pcie_port pcie port handle 782 * @param new_speed the new speed gen to set 783 * 784 * @return 0 if no error found 785 */ 786 int al_pcie_link_change_speed(struct al_pcie_port *pcie_port, enum al_pcie_link_speed new_speed); 787 788 /* TODO: check if this function needed */ 789 int al_pcie_link_change_width(struct al_pcie_port *pcie_port, uint8_t width); 790 791 /**************************** Post Link Start API *****************************/ 792 793 /************************** Snoop Configuration API ***************************/ 794 795 /** 796 * @brief configure pcie port axi snoop 797 * 798 * @param pcie_port pcie port handle 799 * @param enable_axi_snoop enable snoop. 800 * 801 * @return 0 if no error found 802 */ 803 /* TODO: Can this API be called after port enable? */ 804 int al_pcie_port_snoop_config(struct al_pcie_port *pcie_port, 805 al_bool enable_axi_snoop); 806 807 /************************** Configuration Space API ***************************/ 808 809 /** 810 * Configuration Space Access Through PCI-E_ECAM_Ext PASW (RC mode only) 811 */ 812 813 /** 814 * @brief get base address of pci configuration space header 815 * @param pcie_pf pcie pf handle 816 * @param addr pointer for returned address; 817 * @return 0 if no error found 818 */ 819 int al_pcie_config_space_get( 820 struct al_pcie_pf *pcie_pf, 821 uint8_t __iomem **addr); 822 823 /** 824 * Read data from the local configuration space 825 * 826 * @param pcie_pf pcie pf handle 827 * @param reg_offset Configuration space register offset 828 * @return Read data 829 */ 830 uint32_t al_pcie_local_cfg_space_read( 831 struct al_pcie_pf *pcie_pf, 832 unsigned int reg_offset); 833 834 /** 835 * Write data to the local configuration space 836 * 837 * @param pcie_pf PCIe pf handle 838 * @param reg_offset Configuration space register offset 839 * @param data Data to write 840 * @param cs2 Should be AL_TRUE if dbi_cs2 must be asserted 841 * to enable writing to this register, according to 842 * the PCIe Core specifications 843 * @param allow_ro_wr AL_TRUE to allow writing into read-only regs 844 * 845 */ 846 void al_pcie_local_cfg_space_write( 847 struct al_pcie_pf *pcie_pf, 848 unsigned int reg_offset, 849 uint32_t data, 850 al_bool cs2, 851 al_bool allow_ro_wr); 852 853 /** 854 * @brief set target_bus and mask_target_bus 855 * @param pcie_port pcie port handle 856 * @param target_bus 857 * @param mask_target_bus 858 * @return 0 if no error found 859 */ 860 int al_pcie_target_bus_set(struct al_pcie_port *pcie_port, 861 uint8_t target_bus, 862 uint8_t mask_target_bus); 863 864 /** 865 * @brief get target_bus and mask_target_bus 866 * @param pcie_port pcie port handle 867 * @param target_bus 868 * @param mask_target_bus 869 * @return 0 if no error found 870 */ 871 int al_pcie_target_bus_get(struct al_pcie_port *pcie_port, 872 uint8_t *target_bus, 873 uint8_t *mask_target_bus); 874 875 /** 876 * Set secondary bus number 877 * 878 * @param pcie_port pcie port handle 879 * @param secbus pci secondary bus number 880 * 881 * @return 0 if no error found. 882 */ 883 int al_pcie_secondary_bus_set(struct al_pcie_port *pcie_port, uint8_t secbus); 884 885 /** 886 * Set subordinary bus number 887 * 888 * @param pcie_port pcie port handle 889 * @param subbus the highest bus number of all of the buses that can be reached 890 * downstream of the PCIE instance. 891 * 892 * @return 0 if no error found. 893 */ 894 int al_pcie_subordinary_bus_set(struct al_pcie_port *pcie_port,uint8_t subbus); 895 896 /** 897 * @brief Enable/disable deferring incoming configuration requests until 898 * initialization is complete. When enabled, the core completes incoming 899 * configuration requests with a Configuration Request Retry Status. 900 * Other incoming Requests complete with Unsupported Request status. 901 * 902 * @param pcie_port pcie port handle 903 * @param en enable/disable 904 */ 905 void al_pcie_app_req_retry_set(struct al_pcie_port *pcie_port, al_bool en); 906 907 /*************** Internal Address Translation Unit (ATU) API ******************/ 908 909 enum al_pcie_atu_dir { 910 AL_PCIE_ATU_DIR_OUTBOUND = 0, 911 AL_PCIE_ATU_DIR_INBOUND = 1, 912 }; 913 914 enum al_pcie_atu_tlp { 915 AL_PCIE_TLP_TYPE_MEM = 0, 916 AL_PCIE_TLP_TYPE_IO = 2, 917 AL_PCIE_TLP_TYPE_CFG0 = 4, 918 AL_PCIE_TLP_TYPE_CFG1 = 5, 919 AL_PCIE_TLP_TYPE_MSG = 0x10, 920 AL_PCIE_TLP_TYPE_RESERVED = 0x1f 921 }; 922 923 enum al_pcie_atu_response { 924 AL_PCIE_RESPONSE_NORMAL = 0, 925 AL_PCIE_RESPONSE_UR = 1, 926 AL_PCIE_RESPONSE_CA = 2 927 }; 928 929 struct al_pcie_atu_region { 930 al_bool enable; 931 /* outbound or inbound */ 932 enum al_pcie_atu_dir direction; 933 /* region index */ 934 uint8_t index; 935 uint64_t base_addr; 936 /** limit marks the region's end address. only bits [39:0] are valid 937 * given the Alpine PoC maximum physical address space 938 */ 939 uint64_t limit; 940 /** the address that matches will be translated to this address + offset 941 */ 942 uint64_t target_addr; 943 al_bool invert_matching; 944 /* pcie tlp type*/ 945 enum al_pcie_atu_tlp tlp_type; 946 /* pcie frame header attr field*/ 947 uint8_t attr; 948 /** 949 * outbound specific params 950 */ 951 /* pcie message code */ 952 uint8_t msg_code; 953 al_bool cfg_shift_mode; 954 /** 955 * inbound specific params 956 */ 957 uint8_t bar_number; 958 /* BAR match mode, used in EP for MEM and IO tlps*/ 959 uint8_t match_mode; 960 /** 961 * For outbound: enables taking the function number of the translated 962 * TLP from the PCIe core. For inbound: enables ATU function match mode 963 * Note: this boolean is ignored in RC mode 964 */ 965 al_bool function_match_bypass_mode; 966 /** 967 * The function number to match/bypass (see previous parameter) 968 * Note: this parameter is ignored when previous param is FALSE 969 */ 970 uint8_t function_match_bypass_mode_number; 971 /* response code */ 972 enum al_pcie_atu_response response; 973 al_bool enable_attr_match_mode; 974 al_bool enable_msg_match_mode; 975 /** 976 * USE WITH CAUTION: setting this boolean to AL_TRUE allows setting the 977 * outbound ATU even after link is already started. DO NOT SET this 978 * boolean to AL_TRUE unless there have been NO traffic before calling 979 * al_pcie_atu_region_set function 980 */ 981 al_bool enforce_ob_atu_region_set; 982 }; 983 984 /** 985 * @brief program internal ATU region entry 986 * @param pcie_port pcie port handle 987 * @param atu_region data structure that contains the region index and the 988 * translation parameters 989 * @return 0 if no error 990 */ 991 int al_pcie_atu_region_set( 992 struct al_pcie_port *pcie_port, 993 struct al_pcie_atu_region *atu_region); 994 995 /** 996 * @brief get internal ATU is enabled and base/target addresses 997 * @param pcie_port pcie port handle 998 * @param direction input: iATU direction (IB/OB) 999 * @param index input: iATU index 1000 * @param enable output: AL_TRUE if the iATU is enabled 1001 * @param base_addr output: the iATU base address 1002 * @param target_addr output: the iATU target address 1003 */ 1004 void al_pcie_atu_region_get_fields( 1005 struct al_pcie_port *pcie_port, 1006 enum al_pcie_atu_dir direction, uint8_t index, 1007 al_bool *enable, uint64_t *base_addr, uint64_t *target_addr); 1008 1009 /** 1010 * @brief Configure axi io bar. 1011 * every hit to this bar will override size to 4 bytes. 1012 * @param pcie_port pcie port handle 1013 * @param start the first address of the memory 1014 * @param end the last address of the memory 1015 * @return 1016 */ 1017 void al_pcie_axi_io_config( 1018 struct al_pcie_port *pcie_port, 1019 al_phys_addr_t start, 1020 al_phys_addr_t end); 1021 1022 /************** Interrupt generation (Endpoint mode Only) API *****************/ 1023 1024 enum al_pcie_legacy_int_type{ 1025 AL_PCIE_LEGACY_INTA = 0, 1026 AL_PCIE_LEGACY_INTB, 1027 AL_PCIE_LEGACY_INTC, 1028 AL_PCIE_LEGACY_INTD 1029 }; 1030 1031 /** 1032 * @brief generate INTx Assert/DeAssert Message 1033 * @param pcie_pf pcie pf handle 1034 * @param assert when true, Assert Message is sent 1035 * @param type type of message (INTA, INTB, etc) 1036 * @return 0 if no error found 1037 */ 1038 int al_pcie_legacy_int_gen( 1039 struct al_pcie_pf *pcie_pf, 1040 al_bool assert, 1041 enum al_pcie_legacy_int_type type); 1042 1043 /** 1044 * @brief generate MSI interrupt 1045 * @param pcie_pf pcie pf handle 1046 * @param vector the vector index to send interrupt for. 1047 * @return 0 if no error found 1048 */ 1049 int al_pcie_msi_int_gen(struct al_pcie_pf *pcie_pf, uint8_t vector); 1050 1051 /** 1052 * @brief configure MSIX capability 1053 * @param pcie_pf pcie pf handle 1054 * @param msix_params MSIX capability configuration parameters 1055 * @return 0 if no error found 1056 */ 1057 int al_pcie_msix_config( 1058 struct al_pcie_pf *pcie_pf, 1059 struct al_pcie_msix_params *msix_params); 1060 1061 /** 1062 * @brief check whether MSIX capability is enabled 1063 * @param pcie_pf pcie pf handle 1064 * @return AL_TRUE if MSIX capability is enabled, AL_FALSE otherwise 1065 */ 1066 al_bool al_pcie_msix_enabled(struct al_pcie_pf *pcie_pf); 1067 1068 /** 1069 * @brief check whether MSIX capability is masked 1070 * @param pcie_pf pcie pf handle 1071 * @return AL_TRUE if MSIX capability is masked, AL_FALSE otherwise 1072 */ 1073 al_bool al_pcie_msix_masked(struct al_pcie_pf *pcie_pf); 1074 1075 /******************** Advanced Error Reporting (AER) API **********************/ 1076 1077 /** 1078 * @brief configure AER capability 1079 * @param pcie_pf pcie pf handle 1080 * @param params AER capability configuration parameters 1081 * @return 0 if no error found 1082 */ 1083 int al_pcie_aer_config( 1084 struct al_pcie_pf *pcie_pf, 1085 struct al_pcie_aer_params *params); 1086 1087 /** 1088 * @brief AER uncorretable errors get and clear 1089 * @param pcie_pf pcie pf handle 1090 * @return bit mask of uncorrectable errors - see 'AL_PCIE_AER_UNCORR_*' for 1091 * details 1092 */ 1093 unsigned int al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf *pcie_pf); 1094 1095 /** 1096 * @brief AER corretable errors get and clear 1097 * @param pcie_pf pcie pf handle 1098 * @return bit mask of correctable errors - see 'AL_PCIE_AER_CORR_*' for 1099 * details 1100 */ 1101 unsigned int al_pcie_aer_corr_get_and_clear(struct al_pcie_pf *pcie_pf); 1102 1103 /** 1104 * @brief AER get the header for the TLP corresponding to a detected error 1105 * @param pcie_pf pcie pf handle 1106 * @param hdr pointer to an array for getting the header 1107 */ 1108 void al_pcie_aer_err_tlp_hdr_get( 1109 struct al_pcie_pf *pcie_pf, 1110 uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS]); 1111 1112 /******************** Loop-Back mode (RC and Endpoint modes) ******************/ 1113 1114 /** 1115 * @brief enter local pipe loop-back mode 1116 * This mode will connect the pipe RX signals to TX. 1117 * no need to start link when using this mode. 1118 * Gen3 equalization must be disabled before enabling this mode 1119 * The caller must make sure the port is ready to accept the TLPs it sends to 1120 * itself. for example, BARs should be initialized before sending memory TLPs. 1121 * 1122 * @param pcie_port pcie port handle 1123 * @return 0 if no error found 1124 */ 1125 int al_pcie_local_pipe_loopback_enter(struct al_pcie_port *pcie_port); 1126 1127 /** 1128 * @brief exit local pipe loopback mode 1129 * 1130 * @param pcie_port pcie port handle 1131 * @return 0 if no error found 1132 */ 1133 int al_pcie_local_pipe_loopback_exit(struct al_pcie_port *pcie_port); 1134 1135 /** 1136 * @brief enter master remote loopback mode 1137 * No need to configure the link partner to enter slave remote loopback mode 1138 * as this should be done as response to special training sequence directives 1139 * when master works in remote loopback mode. 1140 * The caller must make sure the port is ready to accept the TLPs it sends to 1141 * itself. for example, BARs should be initialized before sending memory TLPs. 1142 * 1143 * @param pcie_port pcie port handle 1144 * @return 0 if no error found 1145 */ 1146 int al_pcie_remote_loopback_enter(struct al_pcie_port *pcie_port); 1147 1148 /** 1149 * @brief exit remote loopback mode 1150 * 1151 * @param pcie_port pcie port handle 1152 * @return 0 if no error found 1153 */ 1154 int al_pcie_remote_loopback_exit(struct al_pcie_port *pcie_port); 1155 1156 #endif 1157 /** @} end of grouppcie group */ 1158