1/*-
2********************************************************************************
3Copyright (C) 2015 Annapurna Labs Ltd.
4
5This file may be licensed under the terms of the Annapurna Labs Commercial
6License Agreement.
7
8Alternatively, this file can be distributed under the terms of the GNU General
9Public License V2 as published by the Free Software Foundation and can be
10found at http://www.gnu.org/licenses/gpl-2.0.html
11
12Alternatively, redistribution and use in source and binary forms, with or
13without modification, are permitted provided that the following conditions are
14met:
15
16    *     Redistributions of source code must retain the above copyright notice,
17this list of conditions and the following disclaimer.
18
19    *     Redistributions in binary form must reproduce the above copyright
20notice, this list of conditions and the following disclaimer in
21the documentation and/or other materials provided with the
22distribution.
23
24THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
28ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31ANY 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
33SOFTWARE, 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 */
239struct 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 */
250enum 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 */
266struct 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 */
288struct al_pcie_pf {
289	unsigned int		pf_num;
290	struct al_pcie_port	*pcie_port;
291};
292
293/** Operating mode (endpoint, root complex) */
294enum 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 */
308enum 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 */
316struct 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 */
327struct 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 */
335struct 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 */
342struct 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 */
350struct 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 */
366struct al_pcie_tl_credits_params {
367};
368
369/** Various configuration features */
370struct 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 */
389struct 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 */
415struct 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 */
421struct 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 */
429struct 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 */
440struct 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) */
462struct 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) */
471struct 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 */
481struct 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 */
489struct 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 */
495struct 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 */
504struct 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 */
548int 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 */
560int 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 */
577int 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 */
590int 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 */
598int 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 */
611int 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 */
619enum 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 */
630int 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 */
636void 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 */
646int 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 */
655al_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 */
668int 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 */
680int 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 */
693int 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 */
702int 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 */
714int 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 */
726int 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 */
736int 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 */
749void 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 */
762int 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 */
775int 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 */
786int 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 */
789int 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? */
804int 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 */
819int 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 */
830uint32_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 */
846void 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 */
860int 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 */
871int 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 */
883int 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 */
894int 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 */
905void al_pcie_app_req_retry_set(struct al_pcie_port *pcie_port, al_bool en);
906
907/*************** Internal Address Translation Unit (ATU) API ******************/
908
909enum al_pcie_atu_dir {
910	AL_PCIE_ATU_DIR_OUTBOUND = 0,
911	AL_PCIE_ATU_DIR_INBOUND = 1,
912};
913
914enum 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
923enum al_pcie_atu_response {
924	AL_PCIE_RESPONSE_NORMAL = 0,
925	AL_PCIE_RESPONSE_UR = 1,
926	AL_PCIE_RESPONSE_CA = 2
927};
928
929struct 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 */
991int 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 */
1004void 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 */
1017void 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
1024enum 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 */
1038int 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 */
1049int 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 */
1057int 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 */
1066al_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 */
1073al_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 */
1083int 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 */
1093unsigned 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 */
1101unsigned 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 */
1108void 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 */
1125int 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 */
1133int 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 */
1146int 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 */
1154int al_pcie_remote_loopback_exit(struct al_pcie_port *pcie_port);
1155
1156#endif
1157/** @} end of grouppcie group */
1158