xref: /freebsd/sys/contrib/alpine-hal/al_hal_pcie.c (revision d002f039aeb370370cd2cba63ad55cc4cf16c932)
1f4b37ed0SZbigniew Bodek /*-
2f4b37ed0SZbigniew Bodek ********************************************************************************
3f4b37ed0SZbigniew Bodek Copyright (C) 2015 Annapurna Labs Ltd.
4f4b37ed0SZbigniew Bodek 
5f4b37ed0SZbigniew Bodek This file may be licensed under the terms of the Annapurna Labs Commercial
6f4b37ed0SZbigniew Bodek License Agreement.
7f4b37ed0SZbigniew Bodek 
8f4b37ed0SZbigniew Bodek Alternatively, this file can be distributed under the terms of the GNU General
9f4b37ed0SZbigniew Bodek Public License V2 as published by the Free Software Foundation and can be
10f4b37ed0SZbigniew Bodek found at http://www.gnu.org/licenses/gpl-2.0.html
11f4b37ed0SZbigniew Bodek 
12f4b37ed0SZbigniew Bodek Alternatively, redistribution and use in source and binary forms, with or
13f4b37ed0SZbigniew Bodek without modification, are permitted provided that the following conditions are
14f4b37ed0SZbigniew Bodek met:
15f4b37ed0SZbigniew Bodek 
16f4b37ed0SZbigniew Bodek     *     Redistributions of source code must retain the above copyright notice,
17f4b37ed0SZbigniew Bodek this list of conditions and the following disclaimer.
18f4b37ed0SZbigniew Bodek 
19f4b37ed0SZbigniew Bodek     *     Redistributions in binary form must reproduce the above copyright
20f4b37ed0SZbigniew Bodek notice, this list of conditions and the following disclaimer in
21f4b37ed0SZbigniew Bodek the documentation and/or other materials provided with the
22f4b37ed0SZbigniew Bodek distribution.
23f4b37ed0SZbigniew Bodek 
24f4b37ed0SZbigniew Bodek THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25f4b37ed0SZbigniew Bodek ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26f4b37ed0SZbigniew Bodek WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27f4b37ed0SZbigniew Bodek DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
28f4b37ed0SZbigniew Bodek ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29f4b37ed0SZbigniew Bodek (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30f4b37ed0SZbigniew Bodek LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31f4b37ed0SZbigniew Bodek ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32f4b37ed0SZbigniew Bodek (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33f4b37ed0SZbigniew Bodek SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34f4b37ed0SZbigniew Bodek 
35f4b37ed0SZbigniew Bodek *******************************************************************************/
36f4b37ed0SZbigniew Bodek 
37f4b37ed0SZbigniew Bodek #include <sys/cdefs.h>
38f4b37ed0SZbigniew Bodek __FBSDID("$FreeBSD$");
39f4b37ed0SZbigniew Bodek 
40f4b37ed0SZbigniew Bodek #include <sys/param.h>
41f4b37ed0SZbigniew Bodek #include <sys/systm.h>
42f4b37ed0SZbigniew Bodek #include <sys/kernel.h>
43f4b37ed0SZbigniew Bodek 
44f4b37ed0SZbigniew Bodek #include "al_hal_pcie.h"
45f4b37ed0SZbigniew Bodek #include "al_hal_pbs_regs.h"
46f4b37ed0SZbigniew Bodek #include "al_hal_unit_adapter_regs.h"
47f4b37ed0SZbigniew Bodek 
48f4b37ed0SZbigniew Bodek /**
49f4b37ed0SZbigniew Bodek  * Parameter definitions
50f4b37ed0SZbigniew Bodek  */
51f4b37ed0SZbigniew Bodek #define AL_PCIE_AXI_REGS_OFFSET			0x0
52f4b37ed0SZbigniew Bodek 
53f4b37ed0SZbigniew Bodek #define AL_PCIE_LTSSM_STATE_L0			0x11
54f4b37ed0SZbigniew Bodek #define AL_PCIE_LTSSM_STATE_L0S			0x12
55f4b37ed0SZbigniew Bodek #define AL_PCIE_DEVCTL_PAYLOAD_128B		0x00
56f4b37ed0SZbigniew Bodek #define AL_PCIE_DEVCTL_PAYLOAD_256B		0x20
57f4b37ed0SZbigniew Bodek 
58f4b37ed0SZbigniew Bodek #define AL_PCIE_SECBUS_DEFAULT			0x1
59f4b37ed0SZbigniew Bodek #define AL_PCIE_SUBBUS_DEFAULT			0x1
60f4b37ed0SZbigniew Bodek #define AL_PCIE_LINKUP_WAIT_INTERVAL		50	/* measured in usec */
61f4b37ed0SZbigniew Bodek #define AL_PCIE_LINKUP_WAIT_INTERVALS_PER_SEC	20
62f4b37ed0SZbigniew Bodek 
63f4b37ed0SZbigniew Bodek #define AL_PCIE_LINKUP_RETRIES			8
64f4b37ed0SZbigniew Bodek 
65f4b37ed0SZbigniew Bodek #define AL_PCIE_MAX_32_MEMORY_BAR_SIZE		(0x100000000ULL)
66f4b37ed0SZbigniew Bodek #define AL_PCIE_MIN_MEMORY_BAR_SIZE		(1 << 12)
67f4b37ed0SZbigniew Bodek #define AL_PCIE_MIN_IO_BAR_SIZE			(1 << 8)
68f4b37ed0SZbigniew Bodek 
69f4b37ed0SZbigniew Bodek /**
70f4b37ed0SZbigniew Bodek  * inbound header credits and outstanding outbound reads defaults
71f4b37ed0SZbigniew Bodek  */
72f4b37ed0SZbigniew Bodek /** RC - Revisions 1/2 */
73f4b37ed0SZbigniew Bodek #define AL_PCIE_REV_1_2_RC_OB_OS_READS_DEFAULT	(8)
74f4b37ed0SZbigniew Bodek #define AL_PCIE_REV_1_2_RC_NOF_CPL_HDR_DEFAULT	(41)
75f4b37ed0SZbigniew Bodek #define AL_PCIE_REV_1_2_RC_NOF_NP_HDR_DEFAULT	(25)
76f4b37ed0SZbigniew Bodek #define AL_PCIE_REV_1_2_RC_NOF_P_HDR_DEFAULT	(31)
77f4b37ed0SZbigniew Bodek /** EP - Revisions 1/2 */
78f4b37ed0SZbigniew Bodek #define AL_PCIE_REV_1_2_EP_OB_OS_READS_DEFAULT	(15)
79f4b37ed0SZbigniew Bodek #define AL_PCIE_REV_1_2_EP_NOF_CPL_HDR_DEFAULT	(76)
80f4b37ed0SZbigniew Bodek #define AL_PCIE_REV_1_2_EP_NOF_NP_HDR_DEFAULT	(6)
81f4b37ed0SZbigniew Bodek #define AL_PCIE_REV_1_2_EP_NOF_P_HDR_DEFAULT	(15)
82f4b37ed0SZbigniew Bodek /** RC - Revision 3 */
83f4b37ed0SZbigniew Bodek #define AL_PCIE_REV_3_RC_OB_OS_READS_DEFAULT	(32)
84f4b37ed0SZbigniew Bodek #define AL_PCIE_REV_3_RC_NOF_CPL_HDR_DEFAULT	(161)
85f4b37ed0SZbigniew Bodek #define AL_PCIE_REV_3_RC_NOF_NP_HDR_DEFAULT	(38)
86f4b37ed0SZbigniew Bodek #define AL_PCIE_REV_3_RC_NOF_P_HDR_DEFAULT	(60)
87f4b37ed0SZbigniew Bodek /** EP - Revision 3 */
88f4b37ed0SZbigniew Bodek #define AL_PCIE_REV_3_EP_OB_OS_READS_DEFAULT	(32)
89f4b37ed0SZbigniew Bodek #define AL_PCIE_REV_3_EP_NOF_CPL_HDR_DEFAULT	(161)
90f4b37ed0SZbigniew Bodek #define AL_PCIE_REV_3_EP_NOF_NP_HDR_DEFAULT	(38)
91f4b37ed0SZbigniew Bodek #define AL_PCIE_REV_3_EP_NOF_P_HDR_DEFAULT	(60)
92f4b37ed0SZbigniew Bodek 
93f4b37ed0SZbigniew Bodek /**
94f4b37ed0SZbigniew Bodek  * MACROS
95f4b37ed0SZbigniew Bodek  */
96f4b37ed0SZbigniew Bodek #define AL_PCIE_PARSE_LANES(v)		(((1 << v) - 1) << \
97f4b37ed0SZbigniew Bodek 		PCIE_REVX_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_SHIFT)
98f4b37ed0SZbigniew Bodek 
99*3fc36ee0SWojciech Macek #define AL_PCIE_FLR_DONE_INTERVAL		10
100*3fc36ee0SWojciech Macek 
101f4b37ed0SZbigniew Bodek /**
102f4b37ed0SZbigniew Bodek  * Static functions
103f4b37ed0SZbigniew Bodek  */
104f4b37ed0SZbigniew Bodek static void
al_pcie_port_wr_to_ro_set(struct al_pcie_port * pcie_port,al_bool enable)105f4b37ed0SZbigniew Bodek al_pcie_port_wr_to_ro_set(struct al_pcie_port *pcie_port, al_bool enable)
106f4b37ed0SZbigniew Bodek {
107f4b37ed0SZbigniew Bodek 	/* when disabling writes to RO, make sure any previous writes to
108f4b37ed0SZbigniew Bodek 	 * config space were committed
109f4b37ed0SZbigniew Bodek 	 */
110f4b37ed0SZbigniew Bodek 	if (enable == AL_FALSE)
111f4b37ed0SZbigniew Bodek 		al_local_data_memory_barrier();
112f4b37ed0SZbigniew Bodek 
113f4b37ed0SZbigniew Bodek 	al_reg_write32(&pcie_port->regs->port_regs->rd_only_wr_en,
114f4b37ed0SZbigniew Bodek 		       (enable == AL_TRUE) ? 1 : 0);
115f4b37ed0SZbigniew Bodek 
116f4b37ed0SZbigniew Bodek 	/* when enabling writes to RO, make sure it is committed before trying
117f4b37ed0SZbigniew Bodek 	 * to write to RO config space
118f4b37ed0SZbigniew Bodek 	 */
119f4b37ed0SZbigniew Bodek 	if (enable == AL_TRUE)
120f4b37ed0SZbigniew Bodek 		al_local_data_memory_barrier();
121f4b37ed0SZbigniew Bodek }
122f4b37ed0SZbigniew Bodek 
123f4b37ed0SZbigniew Bodek /** helper function to access dbi_cs2 registers */
124f4b37ed0SZbigniew Bodek static void
al_reg_write32_dbi_cs2(struct al_pcie_port * pcie_port,uint32_t * offset,uint32_t val)125f4b37ed0SZbigniew Bodek al_reg_write32_dbi_cs2(
126f4b37ed0SZbigniew Bodek 	struct al_pcie_port	*pcie_port,
127f4b37ed0SZbigniew Bodek 	uint32_t		*offset,
128f4b37ed0SZbigniew Bodek 	uint32_t		val)
129f4b37ed0SZbigniew Bodek {
130f4b37ed0SZbigniew Bodek 	uintptr_t cs2_bit =
131f4b37ed0SZbigniew Bodek 		(pcie_port->rev_id == AL_PCIE_REV_ID_3) ? 0x4000 : 0x1000;
132f4b37ed0SZbigniew Bodek 
133f4b37ed0SZbigniew Bodek 	al_reg_write32((uint32_t *)((uintptr_t)offset | cs2_bit), val);
134f4b37ed0SZbigniew Bodek }
135f4b37ed0SZbigniew Bodek 
136f4b37ed0SZbigniew Bodek static unsigned int
al_pcie_speed_gen_code(enum al_pcie_link_speed speed)137f4b37ed0SZbigniew Bodek al_pcie_speed_gen_code(enum al_pcie_link_speed speed)
138f4b37ed0SZbigniew Bodek {
139f4b37ed0SZbigniew Bodek 	if (speed == AL_PCIE_LINK_SPEED_GEN1)
140f4b37ed0SZbigniew Bodek 		return 1;
141f4b37ed0SZbigniew Bodek 	if (speed == AL_PCIE_LINK_SPEED_GEN2)
142f4b37ed0SZbigniew Bodek 		return 2;
143f4b37ed0SZbigniew Bodek 	if (speed == AL_PCIE_LINK_SPEED_GEN3)
144f4b37ed0SZbigniew Bodek 		return 3;
145f4b37ed0SZbigniew Bodek 	/* must not be reached */
146f4b37ed0SZbigniew Bodek 	return 0;
147f4b37ed0SZbigniew Bodek }
148f4b37ed0SZbigniew Bodek 
149f4b37ed0SZbigniew Bodek static inline void
al_pcie_port_link_speed_ctrl_set(struct al_pcie_port * pcie_port,enum al_pcie_link_speed max_speed)150f4b37ed0SZbigniew Bodek al_pcie_port_link_speed_ctrl_set(
151f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
152f4b37ed0SZbigniew Bodek 	enum al_pcie_link_speed max_speed)
153f4b37ed0SZbigniew Bodek {
154f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
155f4b37ed0SZbigniew Bodek 
156f4b37ed0SZbigniew Bodek 	al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE);
157f4b37ed0SZbigniew Bodek 
158f4b37ed0SZbigniew Bodek 	if (max_speed != AL_PCIE_LINK_SPEED_DEFAULT) {
159f4b37ed0SZbigniew Bodek 		uint16_t max_speed_val = (uint16_t)al_pcie_speed_gen_code(max_speed);
160f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(
161f4b37ed0SZbigniew Bodek 			(uint32_t __iomem *)(regs->core_space[0].pcie_link_cap_base),
162f4b37ed0SZbigniew Bodek 			0xF, max_speed_val);
163f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(
164f4b37ed0SZbigniew Bodek 			(uint32_t __iomem *)(regs->core_space[0].pcie_cap_base
165f4b37ed0SZbigniew Bodek 			+ (AL_PCI_EXP_LNKCTL2 >> 2)),
166f4b37ed0SZbigniew Bodek 			0xF, max_speed_val);
167f4b37ed0SZbigniew Bodek 	}
168f4b37ed0SZbigniew Bodek 
169f4b37ed0SZbigniew Bodek 	al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE);
170f4b37ed0SZbigniew Bodek }
171f4b37ed0SZbigniew Bodek 
172f4b37ed0SZbigniew Bodek static int
al_pcie_port_link_config(struct al_pcie_port * pcie_port,const struct al_pcie_link_params * link_params)173f4b37ed0SZbigniew Bodek al_pcie_port_link_config(
174f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
175f4b37ed0SZbigniew Bodek 	const struct al_pcie_link_params *link_params)
176f4b37ed0SZbigniew Bodek {
177f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
178f4b37ed0SZbigniew Bodek 	uint8_t max_lanes = pcie_port->max_lanes;
179f4b37ed0SZbigniew Bodek 
180f4b37ed0SZbigniew Bodek 	if ((link_params->max_payload_size != AL_PCIE_MPS_DEFAULT)	&&
181f4b37ed0SZbigniew Bodek 	    (link_params->max_payload_size != AL_PCIE_MPS_128)		&&
182f4b37ed0SZbigniew Bodek 	    (link_params->max_payload_size != AL_PCIE_MPS_256)) {
183f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: unsupported Max Payload Size (%u)\n",
184f4b37ed0SZbigniew Bodek 		       pcie_port->port_id, link_params->max_payload_size);
185f4b37ed0SZbigniew Bodek 		return -EINVAL;
186f4b37ed0SZbigniew Bodek 	}
187f4b37ed0SZbigniew Bodek 
188f4b37ed0SZbigniew Bodek 	al_pcie_port_link_speed_ctrl_set(pcie_port, link_params->max_speed);
189f4b37ed0SZbigniew Bodek 
190f4b37ed0SZbigniew Bodek 	/* Change Max Payload Size, if needed.
191f4b37ed0SZbigniew Bodek 	 * The Max Payload Size is only valid for PF0.
192f4b37ed0SZbigniew Bodek 	 */
193f4b37ed0SZbigniew Bodek 	if (link_params->max_payload_size != AL_PCIE_MPS_DEFAULT)
194f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(regs->core_space[0].pcie_dev_ctrl_status,
195f4b37ed0SZbigniew Bodek 				      PCIE_PORT_DEV_CTRL_STATUS_MPS_MASK,
196f4b37ed0SZbigniew Bodek 				      link_params->max_payload_size <<
197f4b37ed0SZbigniew Bodek 					PCIE_PORT_DEV_CTRL_STATUS_MPS_SHIFT);
198f4b37ed0SZbigniew Bodek 
199f4b37ed0SZbigniew Bodek 	/** Snap from PCIe core spec:
200f4b37ed0SZbigniew Bodek 	 * Link Mode Enable. Sets the number of lanes in the link that you want
201f4b37ed0SZbigniew Bodek 	 * to connect to the link partner. When you have unused lanes in your
202f4b37ed0SZbigniew Bodek 	 * system, then you must change the value in this register to reflect
203f4b37ed0SZbigniew Bodek 	 * the number of lanes. You must also change the value in the
204f4b37ed0SZbigniew Bodek 	 * "Predetermined Number of Lanes" field of the "Link Width and Speed
205f4b37ed0SZbigniew Bodek 	 * Change Control Register".
206f4b37ed0SZbigniew Bodek 	 * 000001: x1
207f4b37ed0SZbigniew Bodek 	 * 000011: x2
208f4b37ed0SZbigniew Bodek 	 * 000111: x4
209f4b37ed0SZbigniew Bodek 	 * 001111: x8
210f4b37ed0SZbigniew Bodek 	 * 011111: x16
211f4b37ed0SZbigniew Bodek 	 * 111111: x32 (not supported)
212f4b37ed0SZbigniew Bodek 	 */
213f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(&regs->port_regs->gen2_ctrl,
214f4b37ed0SZbigniew Bodek 				PCIE_PORT_GEN2_CTRL_NUM_OF_LANES_MASK,
215f4b37ed0SZbigniew Bodek 				max_lanes << PCIE_PORT_GEN2_CTRL_NUM_OF_LANES_SHIFT);
216f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(&regs->port_regs->port_link_ctrl,
217f4b37ed0SZbigniew Bodek 				PCIE_PORT_LINK_CTRL_LINK_CAPABLE_MASK,
218f4b37ed0SZbigniew Bodek 				(max_lanes + (max_lanes-1))
219f4b37ed0SZbigniew Bodek 				<< PCIE_PORT_LINK_CTRL_LINK_CAPABLE_SHIFT);
220f4b37ed0SZbigniew Bodek 
221f4b37ed0SZbigniew Bodek 	return 0;
222f4b37ed0SZbigniew Bodek }
223f4b37ed0SZbigniew Bodek 
224f4b37ed0SZbigniew Bodek static void
al_pcie_port_ram_parity_int_config(struct al_pcie_port * pcie_port,al_bool enable)225f4b37ed0SZbigniew Bodek al_pcie_port_ram_parity_int_config(
226f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
227f4b37ed0SZbigniew Bodek 	al_bool enable)
228f4b37ed0SZbigniew Bodek {
229f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
230f4b37ed0SZbigniew Bodek 
231f4b37ed0SZbigniew Bodek 	al_reg_write32(&regs->app.parity->en_core,
232f4b37ed0SZbigniew Bodek 		(enable == AL_TRUE) ? 0xffffffff : 0x0);
233f4b37ed0SZbigniew Bodek 
234f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(&regs->app.int_grp_b->mask,
235f4b37ed0SZbigniew Bodek 	      PCIE_W_INT_GRP_B_CAUSE_B_PARITY_ERROR_CORE,
236f4b37ed0SZbigniew Bodek 	      (enable != AL_TRUE) ?
237f4b37ed0SZbigniew Bodek 	      PCIE_W_INT_GRP_B_CAUSE_B_PARITY_ERROR_CORE : 0);
238f4b37ed0SZbigniew Bodek 
239f4b37ed0SZbigniew Bodek }
240f4b37ed0SZbigniew Bodek 
241f4b37ed0SZbigniew Bodek static void
al_pcie_port_axi_parity_int_config(struct al_pcie_port * pcie_port,al_bool enable)242f4b37ed0SZbigniew Bodek al_pcie_port_axi_parity_int_config(
243f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
244f4b37ed0SZbigniew Bodek 	al_bool enable)
245f4b37ed0SZbigniew Bodek {
246f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
247f4b37ed0SZbigniew Bodek 	uint32_t parity_enable_mask = 0xffffffff;
248f4b37ed0SZbigniew Bodek 
249f4b37ed0SZbigniew Bodek 	/**
250f4b37ed0SZbigniew Bodek 	 * Addressing RMN: 5603
251f4b37ed0SZbigniew Bodek 	 *
252f4b37ed0SZbigniew Bodek 	 * RMN description:
253f4b37ed0SZbigniew Bodek 	 * u4_ram2p signal false parity error
254f4b37ed0SZbigniew Bodek 	 *
255f4b37ed0SZbigniew Bodek 	 * Software flow:
256f4b37ed0SZbigniew Bodek 	 * Disable parity check for this memory
257f4b37ed0SZbigniew Bodek 	 */
258f4b37ed0SZbigniew Bodek 	if (pcie_port->rev_id >= AL_PCIE_REV_ID_3)
259f4b37ed0SZbigniew Bodek 		parity_enable_mask &= ~PCIE_AXI_PARITY_EN_AXI_U4_RAM2P;
260f4b37ed0SZbigniew Bodek 
261f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->axi.parity.en_axi,
262f4b37ed0SZbigniew Bodek 		       (enable == AL_TRUE) ? parity_enable_mask : 0x0);
263f4b37ed0SZbigniew Bodek 
264f4b37ed0SZbigniew Bodek 	if (pcie_port->rev_id == AL_PCIE_REV_ID_3) {
265f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(regs->axi.ctrl.global,
266f4b37ed0SZbigniew Bodek 			PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_MSTR |
267f4b37ed0SZbigniew Bodek 			PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_ERR_EN_RD |
268f4b37ed0SZbigniew Bodek 			PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV |
269f4b37ed0SZbigniew Bodek 			PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_ERR_EN_WR,
270f4b37ed0SZbigniew Bodek 			(enable == AL_TRUE) ?
271f4b37ed0SZbigniew Bodek 			PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_MSTR |
272f4b37ed0SZbigniew Bodek 			PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_ERR_EN_RD |
273f4b37ed0SZbigniew Bodek 			PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV |
274f4b37ed0SZbigniew Bodek 			PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_ERR_EN_WR :
275f4b37ed0SZbigniew Bodek 			PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV);
276f4b37ed0SZbigniew Bodek 	} else {
277f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(regs->axi.ctrl.global,
278f4b37ed0SZbigniew Bodek 			PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_MSTR |
279f4b37ed0SZbigniew Bodek 			PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_ERR_EN_RD |
280f4b37ed0SZbigniew Bodek 			PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV |
281f4b37ed0SZbigniew Bodek 			PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_ERR_EN_WR,
282f4b37ed0SZbigniew Bodek 			(enable == AL_TRUE) ?
283f4b37ed0SZbigniew Bodek 			PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_MSTR |
284f4b37ed0SZbigniew Bodek 			PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_ERR_EN_RD |
285f4b37ed0SZbigniew Bodek 			PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV |
286f4b37ed0SZbigniew Bodek 			PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_ERR_EN_WR :
287f4b37ed0SZbigniew Bodek 			PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV);
288f4b37ed0SZbigniew Bodek 	}
289f4b37ed0SZbigniew Bodek 
290f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(&regs->axi.int_grp_a->mask,
291f4b37ed0SZbigniew Bodek 		PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_DATA_PATH_RD |
292f4b37ed0SZbigniew Bodek 		PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_ADDR_RD |
293f4b37ed0SZbigniew Bodek 		PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_ADDR_WR |
294f4b37ed0SZbigniew Bodek 		PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_DATA_WR |
295f4b37ed0SZbigniew Bodek 		PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERROR_AXI,
296f4b37ed0SZbigniew Bodek 		(enable != AL_TRUE) ?
297f4b37ed0SZbigniew Bodek 		(PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_DATA_PATH_RD |
298f4b37ed0SZbigniew Bodek 		PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_ADDR_RD |
299f4b37ed0SZbigniew Bodek 		PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_ADDR_WR |
300f4b37ed0SZbigniew Bodek 		PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_DATA_WR |
301f4b37ed0SZbigniew Bodek 		PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERROR_AXI) : 0);
302f4b37ed0SZbigniew Bodek }
303f4b37ed0SZbigniew Bodek 
304f4b37ed0SZbigniew Bodek static void
al_pcie_port_relaxed_pcie_ordering_config(struct al_pcie_port * pcie_port,struct al_pcie_relaxed_ordering_params * relaxed_ordering_params)305f4b37ed0SZbigniew Bodek al_pcie_port_relaxed_pcie_ordering_config(
306f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
307f4b37ed0SZbigniew Bodek 	struct al_pcie_relaxed_ordering_params *relaxed_ordering_params)
308f4b37ed0SZbigniew Bodek {
309f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
310f4b37ed0SZbigniew Bodek 	enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port);
311f4b37ed0SZbigniew Bodek 	/**
312f4b37ed0SZbigniew Bodek 	 * Default:
313f4b37ed0SZbigniew Bodek 	 *  - RC: Rx relaxed ordering only
314f4b37ed0SZbigniew Bodek 	 *  - EP: TX relaxed ordering only
315f4b37ed0SZbigniew Bodek 	 */
316f4b37ed0SZbigniew Bodek 	al_bool tx_relaxed_ordering = (op_mode == AL_PCIE_OPERATING_MODE_RC ? AL_FALSE : AL_TRUE);
317f4b37ed0SZbigniew Bodek 	al_bool rx_relaxed_ordering = (op_mode == AL_PCIE_OPERATING_MODE_RC ? AL_TRUE : AL_FALSE);
318f4b37ed0SZbigniew Bodek 
319f4b37ed0SZbigniew Bodek 	if (relaxed_ordering_params) {
320f4b37ed0SZbigniew Bodek 		tx_relaxed_ordering = relaxed_ordering_params->enable_tx_relaxed_ordering;
321f4b37ed0SZbigniew Bodek 		rx_relaxed_ordering = relaxed_ordering_params->enable_rx_relaxed_ordering;
322f4b37ed0SZbigniew Bodek 	}
323f4b37ed0SZbigniew Bodek 
324f4b37ed0SZbigniew Bodek 	/** PCIe ordering:
325f4b37ed0SZbigniew Bodek 	 *  - disable outbound completion must be stalled behind outbound write
326f4b37ed0SZbigniew Bodek 	 *    ordering rule enforcement is disabled for root-port
327f4b37ed0SZbigniew Bodek 	 *  - disables read completion on the master port push slave writes for end-point
328f4b37ed0SZbigniew Bodek 	 */
329f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(
330f4b37ed0SZbigniew Bodek 		regs->axi.ordering.pos_cntl,
331f4b37ed0SZbigniew Bodek 		PCIE_AXI_POS_ORDER_BYPASS_CMPL_AFTER_WR_FIX |
332f4b37ed0SZbigniew Bodek 		PCIE_AXI_POS_ORDER_EP_CMPL_AFTER_WR_DIS |
333f4b37ed0SZbigniew Bodek 		PCIE_AXI_POS_ORDER_EP_CMPL_AFTER_WR_SUPPORT_INTERLV_DIS |
334f4b37ed0SZbigniew Bodek 		PCIE_AXI_POS_ORDER_SEGMENT_BUFFER_DONT_WAIT_FOR_P_WRITES,
335f4b37ed0SZbigniew Bodek 		(tx_relaxed_ordering ?
336f4b37ed0SZbigniew Bodek 		(PCIE_AXI_POS_ORDER_BYPASS_CMPL_AFTER_WR_FIX |
337f4b37ed0SZbigniew Bodek 		PCIE_AXI_POS_ORDER_SEGMENT_BUFFER_DONT_WAIT_FOR_P_WRITES) : 0) |
338f4b37ed0SZbigniew Bodek 		(rx_relaxed_ordering ?
339f4b37ed0SZbigniew Bodek 		(PCIE_AXI_POS_ORDER_EP_CMPL_AFTER_WR_DIS |
340f4b37ed0SZbigniew Bodek 		PCIE_AXI_POS_ORDER_EP_CMPL_AFTER_WR_SUPPORT_INTERLV_DIS) : 0));
341f4b37ed0SZbigniew Bodek }
342f4b37ed0SZbigniew Bodek 
343f4b37ed0SZbigniew Bodek static int
al_pcie_rev_id_get(void __iomem * pbs_reg_base,void __iomem * pcie_reg_base)344f4b37ed0SZbigniew Bodek al_pcie_rev_id_get(
345f4b37ed0SZbigniew Bodek 	void __iomem *pbs_reg_base,
346f4b37ed0SZbigniew Bodek 	void __iomem *pcie_reg_base)
347f4b37ed0SZbigniew Bodek {
348f4b37ed0SZbigniew Bodek 	uint32_t chip_id;
349f4b37ed0SZbigniew Bodek 	uint16_t chip_id_dev;
350f4b37ed0SZbigniew Bodek 	uint8_t rev_id;
351f4b37ed0SZbigniew Bodek 	struct al_pbs_regs *pbs_regs = pbs_reg_base;
352f4b37ed0SZbigniew Bodek 
353f4b37ed0SZbigniew Bodek 	/* get revision ID from PBS' chip_id register */
354f4b37ed0SZbigniew Bodek 	chip_id = al_reg_read32(&pbs_regs->unit.chip_id);
355f4b37ed0SZbigniew Bodek 	chip_id_dev = AL_REG_FIELD_GET(chip_id,
356f4b37ed0SZbigniew Bodek 				       PBS_UNIT_CHIP_ID_DEV_ID_MASK,
357f4b37ed0SZbigniew Bodek 				       PBS_UNIT_CHIP_ID_DEV_ID_SHIFT);
358f4b37ed0SZbigniew Bodek 
359*3fc36ee0SWojciech Macek 	if (chip_id_dev == PBS_UNIT_CHIP_ID_DEV_ID_ALPINE_V1) {
360*3fc36ee0SWojciech Macek 		rev_id = AL_PCIE_REV_ID_1;
361*3fc36ee0SWojciech Macek 	} else if (chip_id_dev == PBS_UNIT_CHIP_ID_DEV_ID_ALPINE_V2) {
362f4b37ed0SZbigniew Bodek 		struct al_pcie_revx_regs __iomem *regs =
363f4b37ed0SZbigniew Bodek 			(struct al_pcie_revx_regs __iomem *)pcie_reg_base;
364f4b37ed0SZbigniew Bodek 		uint32_t dev_id;
365f4b37ed0SZbigniew Bodek 
366f4b37ed0SZbigniew Bodek 		dev_id = al_reg_read32(&regs->axi.device_id.device_rev_id) &
367f4b37ed0SZbigniew Bodek 			PCIE_AXI_DEVICE_ID_REG_DEV_ID_MASK;
368f4b37ed0SZbigniew Bodek 		if (dev_id == PCIE_AXI_DEVICE_ID_REG_DEV_ID_X4) {
369f4b37ed0SZbigniew Bodek 			rev_id = AL_PCIE_REV_ID_2;
370f4b37ed0SZbigniew Bodek 		} else if (dev_id == PCIE_AXI_DEVICE_ID_REG_DEV_ID_X8) {
371f4b37ed0SZbigniew Bodek 			rev_id = AL_PCIE_REV_ID_3;
372f4b37ed0SZbigniew Bodek 		} else {
373f4b37ed0SZbigniew Bodek 			al_warn("%s: Revision ID is unknown\n",
374f4b37ed0SZbigniew Bodek 				__func__);
375f4b37ed0SZbigniew Bodek 			return -EINVAL;
376f4b37ed0SZbigniew Bodek 		}
377f4b37ed0SZbigniew Bodek 	} else {
378f4b37ed0SZbigniew Bodek 		al_warn("%s: Revision ID is unknown\n",
379f4b37ed0SZbigniew Bodek 			__func__);
380f4b37ed0SZbigniew Bodek 		return -EINVAL;
381f4b37ed0SZbigniew Bodek 	}
382f4b37ed0SZbigniew Bodek 	return rev_id;
383f4b37ed0SZbigniew Bodek }
384f4b37ed0SZbigniew Bodek 
385f4b37ed0SZbigniew Bodek static int
al_pcie_port_lat_rply_timers_config(struct al_pcie_port * pcie_port,const struct al_pcie_latency_replay_timers * lat_rply_timers)386f4b37ed0SZbigniew Bodek al_pcie_port_lat_rply_timers_config(
387f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
388f4b37ed0SZbigniew Bodek 	const struct al_pcie_latency_replay_timers  *lat_rply_timers)
389f4b37ed0SZbigniew Bodek {
390f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
391f4b37ed0SZbigniew Bodek 	uint32_t	reg = 0;
392f4b37ed0SZbigniew Bodek 
393f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, 0xFFFF, 0, lat_rply_timers->round_trip_lat_limit);
394f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, 0xFFFF0000, 16, lat_rply_timers->replay_timer_limit);
395f4b37ed0SZbigniew Bodek 
396f4b37ed0SZbigniew Bodek 	al_reg_write32(&regs->port_regs->ack_lat_rply_timer, reg);
397f4b37ed0SZbigniew Bodek 	return 0;
398f4b37ed0SZbigniew Bodek }
399f4b37ed0SZbigniew Bodek 
400f4b37ed0SZbigniew Bodek static void
al_pcie_ib_hcrd_os_ob_reads_config_default(struct al_pcie_port * pcie_port)401f4b37ed0SZbigniew Bodek al_pcie_ib_hcrd_os_ob_reads_config_default(
402f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port)
403f4b37ed0SZbigniew Bodek {
404f4b37ed0SZbigniew Bodek 
405f4b37ed0SZbigniew Bodek 	struct al_pcie_ib_hcrd_os_ob_reads_config ib_hcrd_os_ob_reads_config;
406f4b37ed0SZbigniew Bodek 
407f4b37ed0SZbigniew Bodek 	switch (al_pcie_operating_mode_get(pcie_port)) {
408f4b37ed0SZbigniew Bodek 	case AL_PCIE_OPERATING_MODE_RC:
409f4b37ed0SZbigniew Bodek 		if (pcie_port->rev_id == AL_PCIE_REV_ID_3) {
410f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config.nof_outstanding_ob_reads =
411f4b37ed0SZbigniew Bodek 				AL_PCIE_REV_3_RC_OB_OS_READS_DEFAULT;
412f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config.nof_cpl_hdr =
413f4b37ed0SZbigniew Bodek 				AL_PCIE_REV_3_RC_NOF_CPL_HDR_DEFAULT;
414f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config.nof_np_hdr =
415f4b37ed0SZbigniew Bodek 				AL_PCIE_REV_3_RC_NOF_NP_HDR_DEFAULT;
416f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config.nof_p_hdr =
417f4b37ed0SZbigniew Bodek 				AL_PCIE_REV_3_RC_NOF_P_HDR_DEFAULT;
418f4b37ed0SZbigniew Bodek 		} else {
419f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config.nof_outstanding_ob_reads =
420f4b37ed0SZbigniew Bodek 				AL_PCIE_REV_1_2_RC_OB_OS_READS_DEFAULT;
421f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config.nof_cpl_hdr =
422f4b37ed0SZbigniew Bodek 				AL_PCIE_REV_1_2_RC_NOF_CPL_HDR_DEFAULT;
423f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config.nof_np_hdr =
424f4b37ed0SZbigniew Bodek 				AL_PCIE_REV_1_2_RC_NOF_NP_HDR_DEFAULT;
425f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config.nof_p_hdr =
426f4b37ed0SZbigniew Bodek 				AL_PCIE_REV_1_2_RC_NOF_P_HDR_DEFAULT;
427f4b37ed0SZbigniew Bodek 		}
428f4b37ed0SZbigniew Bodek 		break;
429f4b37ed0SZbigniew Bodek 
430f4b37ed0SZbigniew Bodek 	case AL_PCIE_OPERATING_MODE_EP:
431f4b37ed0SZbigniew Bodek 		if (pcie_port->rev_id == AL_PCIE_REV_ID_3) {
432f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config.nof_outstanding_ob_reads =
433f4b37ed0SZbigniew Bodek 				AL_PCIE_REV_3_EP_OB_OS_READS_DEFAULT;
434f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config.nof_cpl_hdr =
435f4b37ed0SZbigniew Bodek 				AL_PCIE_REV_3_EP_NOF_CPL_HDR_DEFAULT;
436f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config.nof_np_hdr =
437f4b37ed0SZbigniew Bodek 				AL_PCIE_REV_3_EP_NOF_NP_HDR_DEFAULT;
438f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config.nof_p_hdr =
439f4b37ed0SZbigniew Bodek 				AL_PCIE_REV_3_EP_NOF_P_HDR_DEFAULT;
440f4b37ed0SZbigniew Bodek 		} else {
441f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config.nof_outstanding_ob_reads =
442f4b37ed0SZbigniew Bodek 				AL_PCIE_REV_1_2_EP_OB_OS_READS_DEFAULT;
443f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config.nof_cpl_hdr =
444f4b37ed0SZbigniew Bodek 				AL_PCIE_REV_1_2_EP_NOF_CPL_HDR_DEFAULT;
445f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config.nof_np_hdr =
446f4b37ed0SZbigniew Bodek 				AL_PCIE_REV_1_2_EP_NOF_NP_HDR_DEFAULT;
447f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config.nof_p_hdr =
448f4b37ed0SZbigniew Bodek 				AL_PCIE_REV_1_2_EP_NOF_P_HDR_DEFAULT;
449f4b37ed0SZbigniew Bodek 		}
450f4b37ed0SZbigniew Bodek 		break;
451f4b37ed0SZbigniew Bodek 
452f4b37ed0SZbigniew Bodek 	default:
453f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: outstanding outbound transactions could not be configured - unknown operating mode\n",
454f4b37ed0SZbigniew Bodek 			pcie_port->port_id);
455f4b37ed0SZbigniew Bodek 		al_assert(0);
456f4b37ed0SZbigniew Bodek 	}
457f4b37ed0SZbigniew Bodek 
458f4b37ed0SZbigniew Bodek 	al_pcie_port_ib_hcrd_os_ob_reads_config(pcie_port, &ib_hcrd_os_ob_reads_config);
459f4b37ed0SZbigniew Bodek };
460f4b37ed0SZbigniew Bodek 
461f4b37ed0SZbigniew Bodek /** return AL_TRUE if link is up, AL_FALSE otherwise */
462f4b37ed0SZbigniew Bodek static al_bool
al_pcie_check_link(struct al_pcie_port * pcie_port,uint8_t * ltssm_ret)463f4b37ed0SZbigniew Bodek al_pcie_check_link(
464f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
465f4b37ed0SZbigniew Bodek 	uint8_t *ltssm_ret)
466f4b37ed0SZbigniew Bodek {
467f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs;
468f4b37ed0SZbigniew Bodek 	uint32_t info_0;
469f4b37ed0SZbigniew Bodek 	uint8_t	ltssm_state;
470f4b37ed0SZbigniew Bodek 
471f4b37ed0SZbigniew Bodek 	info_0 = al_reg_read32(&regs->app.debug->info_0);
472f4b37ed0SZbigniew Bodek 
473f4b37ed0SZbigniew Bodek 	ltssm_state = AL_REG_FIELD_GET(info_0,
474f4b37ed0SZbigniew Bodek 			PCIE_W_DEBUG_INFO_0_LTSSM_STATE_MASK,
475f4b37ed0SZbigniew Bodek 			PCIE_W_DEBUG_INFO_0_LTSSM_STATE_SHIFT);
476f4b37ed0SZbigniew Bodek 
477f4b37ed0SZbigniew Bodek 	al_dbg("PCIe %d: Port Debug 0: 0x%08x. LTSSM state :0x%x\n",
478f4b37ed0SZbigniew Bodek 		pcie_port->port_id, info_0, ltssm_state);
479f4b37ed0SZbigniew Bodek 
480f4b37ed0SZbigniew Bodek 	if (ltssm_ret)
481f4b37ed0SZbigniew Bodek 		*ltssm_ret = ltssm_state;
482f4b37ed0SZbigniew Bodek 
483f4b37ed0SZbigniew Bodek 	if ((ltssm_state == AL_PCIE_LTSSM_STATE_L0) ||
484f4b37ed0SZbigniew Bodek 			(ltssm_state == AL_PCIE_LTSSM_STATE_L0S))
485f4b37ed0SZbigniew Bodek 		return AL_TRUE;
486f4b37ed0SZbigniew Bodek 	return AL_FALSE;
487f4b37ed0SZbigniew Bodek }
488f4b37ed0SZbigniew Bodek 
489f4b37ed0SZbigniew Bodek static int
al_pcie_port_gen2_params_config(struct al_pcie_port * pcie_port,const struct al_pcie_gen2_params * gen2_params)490f4b37ed0SZbigniew Bodek al_pcie_port_gen2_params_config(struct al_pcie_port *pcie_port,
491f4b37ed0SZbigniew Bodek 				const struct al_pcie_gen2_params *gen2_params)
492f4b37ed0SZbigniew Bodek {
493f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
494f4b37ed0SZbigniew Bodek 	uint32_t gen2_ctrl;
495f4b37ed0SZbigniew Bodek 
496f4b37ed0SZbigniew Bodek 	al_dbg("PCIe %d: Gen2 params config: Tx Swing %s, interrupt on link Eq %s, set Deemphasis %s\n",
497f4b37ed0SZbigniew Bodek 	       pcie_port->port_id,
498f4b37ed0SZbigniew Bodek 	       gen2_params->tx_swing_low ? "Low" : "Full",
499f4b37ed0SZbigniew Bodek 	       gen2_params->tx_compliance_receive_enable? "enable" : "disable",
500f4b37ed0SZbigniew Bodek 	       gen2_params->set_deemphasis? "enable" : "disable");
501f4b37ed0SZbigniew Bodek 
502f4b37ed0SZbigniew Bodek 	gen2_ctrl = al_reg_read32(&regs->port_regs->gen2_ctrl);
503f4b37ed0SZbigniew Bodek 
504f4b37ed0SZbigniew Bodek 	if (gen2_params->tx_swing_low)
505f4b37ed0SZbigniew Bodek 		AL_REG_BIT_SET(gen2_ctrl, PCIE_PORT_GEN2_CTRL_TX_SWING_LOW_SHIFT);
506f4b37ed0SZbigniew Bodek 	else
507f4b37ed0SZbigniew Bodek 		AL_REG_BIT_CLEAR(gen2_ctrl, PCIE_PORT_GEN2_CTRL_TX_SWING_LOW_SHIFT);
508f4b37ed0SZbigniew Bodek 
509f4b37ed0SZbigniew Bodek 	if (gen2_params->tx_compliance_receive_enable)
510f4b37ed0SZbigniew Bodek 		AL_REG_BIT_SET(gen2_ctrl, PCIE_PORT_GEN2_CTRL_TX_COMPLIANCE_RCV_SHIFT);
511f4b37ed0SZbigniew Bodek 	else
512f4b37ed0SZbigniew Bodek 		AL_REG_BIT_CLEAR(gen2_ctrl, PCIE_PORT_GEN2_CTRL_TX_COMPLIANCE_RCV_SHIFT);
513f4b37ed0SZbigniew Bodek 
514f4b37ed0SZbigniew Bodek 	if (gen2_params->set_deemphasis)
515f4b37ed0SZbigniew Bodek 		AL_REG_BIT_SET(gen2_ctrl, PCIE_PORT_GEN2_CTRL_DEEMPHASIS_SET_SHIFT);
516f4b37ed0SZbigniew Bodek 	else
517f4b37ed0SZbigniew Bodek 		AL_REG_BIT_CLEAR(gen2_ctrl, PCIE_PORT_GEN2_CTRL_DEEMPHASIS_SET_SHIFT);
518f4b37ed0SZbigniew Bodek 
519f4b37ed0SZbigniew Bodek 	al_reg_write32(&regs->port_regs->gen2_ctrl, gen2_ctrl);
520f4b37ed0SZbigniew Bodek 
521f4b37ed0SZbigniew Bodek 	return 0;
522f4b37ed0SZbigniew Bodek }
523f4b37ed0SZbigniew Bodek 
524f4b37ed0SZbigniew Bodek 
525f4b37ed0SZbigniew Bodek static uint16_t
gen3_lane_eq_param_to_val(const struct al_pcie_gen3_lane_eq_params * eq_params)526f4b37ed0SZbigniew Bodek gen3_lane_eq_param_to_val(const struct al_pcie_gen3_lane_eq_params *eq_params)
527f4b37ed0SZbigniew Bodek {
528f4b37ed0SZbigniew Bodek 	uint16_t eq_control = 0;
529f4b37ed0SZbigniew Bodek 
530f4b37ed0SZbigniew Bodek 	eq_control = eq_params->downstream_port_transmitter_preset & 0xF;
531f4b37ed0SZbigniew Bodek 	eq_control |= (eq_params->downstream_port_receiver_preset_hint & 0x7) << 4;
532f4b37ed0SZbigniew Bodek 	eq_control |= (eq_params->upstream_port_transmitter_preset & 0xF) << 8;
533f4b37ed0SZbigniew Bodek 	eq_control |= (eq_params->upstream_port_receiver_preset_hint & 0x7) << 12;
534f4b37ed0SZbigniew Bodek 
535f4b37ed0SZbigniew Bodek 	return eq_control;
536f4b37ed0SZbigniew Bodek }
537f4b37ed0SZbigniew Bodek 
538f4b37ed0SZbigniew Bodek static int
al_pcie_port_gen3_params_config(struct al_pcie_port * pcie_port,const struct al_pcie_gen3_params * gen3_params)539f4b37ed0SZbigniew Bodek al_pcie_port_gen3_params_config(struct al_pcie_port *pcie_port,
540f4b37ed0SZbigniew Bodek 				const struct al_pcie_gen3_params *gen3_params)
541f4b37ed0SZbigniew Bodek {
542f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
543f4b37ed0SZbigniew Bodek 	uint32_t reg = 0;
544f4b37ed0SZbigniew Bodek 	uint16_t __iomem *lanes_eq_base = (uint16_t __iomem *)(regs->core_space[0].pcie_sec_ext_cap_base + (0xC >> 2));
545f4b37ed0SZbigniew Bodek 	int i;
546f4b37ed0SZbigniew Bodek 
547f4b37ed0SZbigniew Bodek 	al_dbg("PCIe %d: Gen3 params config: Equalization %s, interrupt on link Eq %s\n",
548f4b37ed0SZbigniew Bodek 	       pcie_port->port_id,
549f4b37ed0SZbigniew Bodek 	       gen3_params->perform_eq ? "enable" : "disable",
550f4b37ed0SZbigniew Bodek 	       gen3_params->interrupt_enable_on_link_eq_request? "enable" : "disable");
551f4b37ed0SZbigniew Bodek 
552f4b37ed0SZbigniew Bodek 	if (gen3_params->perform_eq)
553f4b37ed0SZbigniew Bodek 		AL_REG_BIT_SET(reg, 0);
554f4b37ed0SZbigniew Bodek 	if (gen3_params->interrupt_enable_on_link_eq_request)
555f4b37ed0SZbigniew Bodek 		AL_REG_BIT_SET(reg, 1);
556f4b37ed0SZbigniew Bodek 
557f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->core_space[0].pcie_sec_ext_cap_base + (4 >> 2),
558f4b37ed0SZbigniew Bodek 		       reg);
559f4b37ed0SZbigniew Bodek 
560f4b37ed0SZbigniew Bodek 	al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE);
561f4b37ed0SZbigniew Bodek 
562f4b37ed0SZbigniew Bodek 	for (i = 0; i < gen3_params->eq_params_elements; i += 2) {
563f4b37ed0SZbigniew Bodek 		uint32_t eq_control =
564f4b37ed0SZbigniew Bodek 			(uint32_t)gen3_lane_eq_param_to_val(gen3_params->eq_params + i) |
565f4b37ed0SZbigniew Bodek 			(uint32_t)gen3_lane_eq_param_to_val(gen3_params->eq_params + i + 1) << 16;
566f4b37ed0SZbigniew Bodek 
567f4b37ed0SZbigniew Bodek 		al_dbg("PCIe %d: Set EQ (0x%08x) for lane %d, %d\n", pcie_port->port_id, eq_control, i, i + 1);
568f4b37ed0SZbigniew Bodek 		al_reg_write32((uint32_t *)(lanes_eq_base + i), eq_control);
569f4b37ed0SZbigniew Bodek 	}
570f4b37ed0SZbigniew Bodek 
571f4b37ed0SZbigniew Bodek 	al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE);
572f4b37ed0SZbigniew Bodek 
573f4b37ed0SZbigniew Bodek 	reg = al_reg_read32(&regs->port_regs->gen3_ctrl);
574f4b37ed0SZbigniew Bodek 	if (gen3_params->eq_disable)
575f4b37ed0SZbigniew Bodek 		AL_REG_BIT_SET(reg, PCIE_PORT_GEN3_CTRL_EQ_DISABLE_SHIFT);
576f4b37ed0SZbigniew Bodek 	else
577f4b37ed0SZbigniew Bodek 		AL_REG_BIT_CLEAR(reg, PCIE_PORT_GEN3_CTRL_EQ_DISABLE_SHIFT);
578f4b37ed0SZbigniew Bodek 
579f4b37ed0SZbigniew Bodek 	if (gen3_params->eq_phase2_3_disable)
580f4b37ed0SZbigniew Bodek 		AL_REG_BIT_SET(reg, PCIE_PORT_GEN3_CTRL_EQ_PHASE_2_3_DISABLE_SHIFT);
581f4b37ed0SZbigniew Bodek 	else
582f4b37ed0SZbigniew Bodek 		AL_REG_BIT_CLEAR(reg, PCIE_PORT_GEN3_CTRL_EQ_PHASE_2_3_DISABLE_SHIFT);
583f4b37ed0SZbigniew Bodek 
584f4b37ed0SZbigniew Bodek 	al_reg_write32(&regs->port_regs->gen3_ctrl, reg);
585f4b37ed0SZbigniew Bodek 
586f4b37ed0SZbigniew Bodek 	reg = 0;
587f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, PCIE_PORT_GEN3_EQ_LF_MASK,
588f4b37ed0SZbigniew Bodek 			 PCIE_PORT_GEN3_EQ_LF_SHIFT,
589f4b37ed0SZbigniew Bodek 			 gen3_params->local_lf);
590f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, PCIE_PORT_GEN3_EQ_FS_MASK,
591f4b37ed0SZbigniew Bodek 			 PCIE_PORT_GEN3_EQ_FS_SHIFT,
592f4b37ed0SZbigniew Bodek 			 gen3_params->local_fs);
593f4b37ed0SZbigniew Bodek 
594f4b37ed0SZbigniew Bodek 	al_reg_write32(&regs->port_regs->gen3_eq_fs_lf, reg);
595f4b37ed0SZbigniew Bodek 
596f4b37ed0SZbigniew Bodek 	reg = 0;
597f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_LF_MASK,
598f4b37ed0SZbigniew Bodek 			 PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_LF_SHIFT,
599f4b37ed0SZbigniew Bodek 			 gen3_params->local_lf);
600f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_FS_MASK,
601f4b37ed0SZbigniew Bodek 			 PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_FS_SHIFT,
602f4b37ed0SZbigniew Bodek 			 gen3_params->local_fs);
603f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->axi.conf.zero_lane0, reg);
604f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->axi.conf.zero_lane1, reg);
605f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->axi.conf.zero_lane2, reg);
606f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->axi.conf.zero_lane3, reg);
607f4b37ed0SZbigniew Bodek 	if (pcie_port->rev_id == AL_PCIE_REV_ID_3) {
608f4b37ed0SZbigniew Bodek 		al_reg_write32(regs->axi.conf.zero_lane4, reg);
609f4b37ed0SZbigniew Bodek 		al_reg_write32(regs->axi.conf.zero_lane5, reg);
610f4b37ed0SZbigniew Bodek 		al_reg_write32(regs->axi.conf.zero_lane6, reg);
611f4b37ed0SZbigniew Bodek 		al_reg_write32(regs->axi.conf.zero_lane7, reg);
612f4b37ed0SZbigniew Bodek 	}
613f4b37ed0SZbigniew Bodek 
614f4b37ed0SZbigniew Bodek 	/*
615f4b37ed0SZbigniew Bodek 	 * Gen3 EQ Control Register:
616f4b37ed0SZbigniew Bodek 	 * - Preset Request Vector - request 9
617f4b37ed0SZbigniew Bodek 	 * - Behavior After 24 ms Timeout (when optimal settings are not
618f4b37ed0SZbigniew Bodek 	 *   found): Recovery.Equalization.RcvrLock
619f4b37ed0SZbigniew Bodek 	 * - Phase2_3 2 ms Timeout Disable
620f4b37ed0SZbigniew Bodek 	 * - Feedback Mode - Figure Of Merit
621f4b37ed0SZbigniew Bodek 	 */
622f4b37ed0SZbigniew Bodek 	reg = 0x00020031;
623f4b37ed0SZbigniew Bodek 	al_reg_write32(&regs->port_regs->gen3_eq_ctrl, reg);
624f4b37ed0SZbigniew Bodek 
625f4b37ed0SZbigniew Bodek 	return 0;
626f4b37ed0SZbigniew Bodek }
627f4b37ed0SZbigniew Bodek 
628f4b37ed0SZbigniew Bodek static int
al_pcie_port_pf_params_config(struct al_pcie_pf * pcie_pf,const struct al_pcie_pf_config_params * pf_params)629f4b37ed0SZbigniew Bodek al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf,
630f4b37ed0SZbigniew Bodek 			      const struct al_pcie_pf_config_params *pf_params)
631f4b37ed0SZbigniew Bodek {
632f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port = pcie_pf->pcie_port;
633f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
634f4b37ed0SZbigniew Bodek 	unsigned int pf_num = pcie_pf->pf_num;
635f4b37ed0SZbigniew Bodek 	int bar_idx;
636f4b37ed0SZbigniew Bodek 	int ret;
637f4b37ed0SZbigniew Bodek 
638f4b37ed0SZbigniew Bodek 	al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE);
639f4b37ed0SZbigniew Bodek 
640f4b37ed0SZbigniew Bodek 	/* Disable D1 and D3hot capabilities */
641f4b37ed0SZbigniew Bodek 	if (pf_params->cap_d1_d3hot_dis)
642f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(
643f4b37ed0SZbigniew Bodek 			regs->core_space[pf_num].pcie_pm_cap_base,
644f4b37ed0SZbigniew Bodek 			AL_FIELD_MASK(26, 25) | AL_FIELD_MASK(31, 28), 0);
645f4b37ed0SZbigniew Bodek 
646*3fc36ee0SWojciech Macek 	/* Set/Clear FLR bit */
647f4b37ed0SZbigniew Bodek 	if (pf_params->cap_flr_dis)
648f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(
649f4b37ed0SZbigniew Bodek 			regs->core_space[pf_num].pcie_dev_cap_base,
650*3fc36ee0SWojciech Macek 			AL_PCI_EXP_DEVCAP_FLR, 0);
651*3fc36ee0SWojciech Macek 	else
652*3fc36ee0SWojciech Macek 		al_reg_write32_masked(
653*3fc36ee0SWojciech Macek 			regs->core_space[pcie_pf->pf_num].pcie_dev_cap_base,
654*3fc36ee0SWojciech Macek 			AL_PCI_EXP_DEVCAP_FLR, AL_PCI_EXP_DEVCAP_FLR);
655f4b37ed0SZbigniew Bodek 
656f4b37ed0SZbigniew Bodek 	/* Disable ASPM capability */
657f4b37ed0SZbigniew Bodek 	if (pf_params->cap_aspm_dis) {
658f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(
659f4b37ed0SZbigniew Bodek 			regs->core_space[pf_num].pcie_cap_base + (AL_PCI_EXP_LNKCAP >> 2),
660f4b37ed0SZbigniew Bodek 			AL_PCI_EXP_LNKCAP_ASPMS, 0);
661f4b37ed0SZbigniew Bodek 	}
662f4b37ed0SZbigniew Bodek 
663f4b37ed0SZbigniew Bodek 	if (!pf_params->bar_params_valid) {
664f4b37ed0SZbigniew Bodek 		ret = 0;
665f4b37ed0SZbigniew Bodek 		goto done;
666f4b37ed0SZbigniew Bodek 	}
667f4b37ed0SZbigniew Bodek 
668f4b37ed0SZbigniew Bodek 	for (bar_idx = 0; bar_idx < 6;){ /* bar_idx will be incremented depending on bar type */
669f4b37ed0SZbigniew Bodek 		const struct al_pcie_ep_bar_params *params = pf_params->bar_params + bar_idx;
670f4b37ed0SZbigniew Bodek 		uint32_t mask = 0;
671f4b37ed0SZbigniew Bodek 		uint32_t ctrl = 0;
672f4b37ed0SZbigniew Bodek 		uint32_t __iomem *bar_addr = &regs->core_space[pf_num].config_header[(AL_PCI_BASE_ADDRESS_0 >> 2) + bar_idx];
673f4b37ed0SZbigniew Bodek 
674f4b37ed0SZbigniew Bodek 		if (params->enable) {
675f4b37ed0SZbigniew Bodek 			uint64_t size = params->size;
676f4b37ed0SZbigniew Bodek 
677f4b37ed0SZbigniew Bodek 			if (params->memory_64_bit) {
678f4b37ed0SZbigniew Bodek 				const struct al_pcie_ep_bar_params *next_params = params + 1;
679f4b37ed0SZbigniew Bodek 				/* 64 bars start at even index (BAR0, BAR 2 or BAR 4) */
680f4b37ed0SZbigniew Bodek 				if (bar_idx & 1) {
681f4b37ed0SZbigniew Bodek 					ret = -EINVAL;
682f4b37ed0SZbigniew Bodek 					goto done;
683f4b37ed0SZbigniew Bodek 				}
684f4b37ed0SZbigniew Bodek 
685f4b37ed0SZbigniew Bodek 				/* next BAR must be disabled */
686f4b37ed0SZbigniew Bodek 				if (next_params->enable) {
687f4b37ed0SZbigniew Bodek 					ret = -EINVAL;
688f4b37ed0SZbigniew Bodek 					goto done;
689f4b37ed0SZbigniew Bodek 				}
690f4b37ed0SZbigniew Bodek 
691f4b37ed0SZbigniew Bodek 				/* 64 bar must be memory bar */
692f4b37ed0SZbigniew Bodek 				if (!params->memory_space) {
693f4b37ed0SZbigniew Bodek 					ret = -EINVAL;
694f4b37ed0SZbigniew Bodek 					goto done;
695f4b37ed0SZbigniew Bodek 				}
696f4b37ed0SZbigniew Bodek 			} else {
697f4b37ed0SZbigniew Bodek 				if (size > AL_PCIE_MAX_32_MEMORY_BAR_SIZE)
698f4b37ed0SZbigniew Bodek 					return -EINVAL;
699f4b37ed0SZbigniew Bodek 				/* 32 bit space can't be prefetchable */
700f4b37ed0SZbigniew Bodek 				if (params->memory_is_prefetchable) {
701f4b37ed0SZbigniew Bodek 					ret = -EINVAL;
702f4b37ed0SZbigniew Bodek 					goto done;
703f4b37ed0SZbigniew Bodek 				}
704f4b37ed0SZbigniew Bodek 			}
705f4b37ed0SZbigniew Bodek 
706f4b37ed0SZbigniew Bodek 			if (params->memory_space) {
707f4b37ed0SZbigniew Bodek 				if (size < AL_PCIE_MIN_MEMORY_BAR_SIZE) {
708*3fc36ee0SWojciech Macek 					al_err("PCIe %d: memory BAR %d: size (0x%jx) less that minimal allowed value\n",
709*3fc36ee0SWojciech Macek 						pcie_port->port_id, bar_idx,
710*3fc36ee0SWojciech Macek 						(uintmax_t)size);
711f4b37ed0SZbigniew Bodek 					ret = -EINVAL;
712f4b37ed0SZbigniew Bodek 					goto done;
713f4b37ed0SZbigniew Bodek 				}
714f4b37ed0SZbigniew Bodek 			} else {
715f4b37ed0SZbigniew Bodek 				/* IO can't be prefetchable */
716f4b37ed0SZbigniew Bodek 				if (params->memory_is_prefetchable) {
717f4b37ed0SZbigniew Bodek 					ret = -EINVAL;
718f4b37ed0SZbigniew Bodek 					goto done;
719f4b37ed0SZbigniew Bodek 				}
720f4b37ed0SZbigniew Bodek 
721f4b37ed0SZbigniew Bodek 				if (size < AL_PCIE_MIN_IO_BAR_SIZE) {
722*3fc36ee0SWojciech Macek 					al_err("PCIe %d: IO BAR %d: size (0x%jx) less that minimal allowed value\n",
723*3fc36ee0SWojciech Macek 						pcie_port->port_id, bar_idx,
724*3fc36ee0SWojciech Macek 						(uintmax_t)size);
725f4b37ed0SZbigniew Bodek 					ret = -EINVAL;
726f4b37ed0SZbigniew Bodek 					goto done;
727f4b37ed0SZbigniew Bodek 				}
728f4b37ed0SZbigniew Bodek 			}
729f4b37ed0SZbigniew Bodek 
730f4b37ed0SZbigniew Bodek 			/* size must be power of 2 */
731f4b37ed0SZbigniew Bodek 			if (size & (size - 1)) {
732*3fc36ee0SWojciech Macek 				al_err("PCIe %d: BAR %d:size (0x%jx) must be "
733f4b37ed0SZbigniew Bodek 					"power of 2\n",
734*3fc36ee0SWojciech Macek 					pcie_port->port_id, bar_idx, (uintmax_t)size);
735f4b37ed0SZbigniew Bodek 				ret = -EINVAL;
736f4b37ed0SZbigniew Bodek 				goto done;
737f4b37ed0SZbigniew Bodek 			}
738f4b37ed0SZbigniew Bodek 
739f4b37ed0SZbigniew Bodek 			/* If BAR is 64-bit, disable the next BAR before
740f4b37ed0SZbigniew Bodek 			 * configuring this one
741f4b37ed0SZbigniew Bodek 			 */
742f4b37ed0SZbigniew Bodek 			if (params->memory_64_bit)
743f4b37ed0SZbigniew Bodek 				al_reg_write32_dbi_cs2(pcie_port, bar_addr + 1, 0);
744f4b37ed0SZbigniew Bodek 
745f4b37ed0SZbigniew Bodek 			mask = 1; /* enable bit*/
746f4b37ed0SZbigniew Bodek 			mask |= (params->size - 1) & 0xFFFFFFFF;
747f4b37ed0SZbigniew Bodek 
748f4b37ed0SZbigniew Bodek 			al_reg_write32_dbi_cs2(pcie_port, bar_addr , mask);
749f4b37ed0SZbigniew Bodek 
750f4b37ed0SZbigniew Bodek 			if (params->memory_space == AL_FALSE)
751f4b37ed0SZbigniew Bodek 				ctrl = AL_PCI_BASE_ADDRESS_SPACE_IO;
752f4b37ed0SZbigniew Bodek 			if (params->memory_64_bit)
753f4b37ed0SZbigniew Bodek 				ctrl |= AL_PCI_BASE_ADDRESS_MEM_TYPE_64;
754f4b37ed0SZbigniew Bodek 			if (params->memory_is_prefetchable)
755f4b37ed0SZbigniew Bodek 				ctrl |= AL_PCI_BASE_ADDRESS_MEM_PREFETCH;
756f4b37ed0SZbigniew Bodek 			al_reg_write32(bar_addr, ctrl);
757f4b37ed0SZbigniew Bodek 
758f4b37ed0SZbigniew Bodek 			if (params->memory_64_bit) {
759f4b37ed0SZbigniew Bodek 				mask = ((params->size - 1) >> 32) & 0xFFFFFFFF;
760f4b37ed0SZbigniew Bodek 				al_reg_write32_dbi_cs2(pcie_port, bar_addr + 1, mask);
761f4b37ed0SZbigniew Bodek 			}
762f4b37ed0SZbigniew Bodek 
763f4b37ed0SZbigniew Bodek 		} else {
764f4b37ed0SZbigniew Bodek 			al_reg_write32_dbi_cs2(pcie_port, bar_addr , mask);
765f4b37ed0SZbigniew Bodek 		}
766f4b37ed0SZbigniew Bodek 		if (params->enable && params->memory_64_bit)
767f4b37ed0SZbigniew Bodek 			bar_idx += 2;
768f4b37ed0SZbigniew Bodek 		else
769f4b37ed0SZbigniew Bodek 			bar_idx += 1;
770f4b37ed0SZbigniew Bodek 	}
771f4b37ed0SZbigniew Bodek 
772f4b37ed0SZbigniew Bodek 	if (pf_params->exp_bar_params.enable) {
773f4b37ed0SZbigniew Bodek 		if (pcie_port->rev_id != AL_PCIE_REV_ID_3) {
774f4b37ed0SZbigniew Bodek 			al_err("PCIe %d: Expansion BAR enable not supported\n", pcie_port->port_id);
775f4b37ed0SZbigniew Bodek 			ret = -ENOSYS;
776f4b37ed0SZbigniew Bodek 			goto done;
777f4b37ed0SZbigniew Bodek 		} else {
778f4b37ed0SZbigniew Bodek 			/* Enable exp ROM */
779f4b37ed0SZbigniew Bodek 			uint32_t __iomem *exp_rom_bar_addr =
780f4b37ed0SZbigniew Bodek 			&regs->core_space[pf_num].config_header[AL_PCI_EXP_ROM_BASE_ADDRESS >> 2];
781f4b37ed0SZbigniew Bodek 			uint32_t mask = 1; /* enable bit*/
782f4b37ed0SZbigniew Bodek 			mask |= (pf_params->exp_bar_params.size - 1) & 0xFFFFFFFF;
783f4b37ed0SZbigniew Bodek 			al_reg_write32_dbi_cs2(pcie_port, exp_rom_bar_addr , mask);
784f4b37ed0SZbigniew Bodek 		}
785f4b37ed0SZbigniew Bodek 	} else if (pcie_port->rev_id == AL_PCIE_REV_ID_3) {
786f4b37ed0SZbigniew Bodek 		/* Disable exp ROM */
787f4b37ed0SZbigniew Bodek 		uint32_t __iomem *exp_rom_bar_addr =
788f4b37ed0SZbigniew Bodek 			&regs->core_space[pf_num].config_header[AL_PCI_EXP_ROM_BASE_ADDRESS >> 2];
789f4b37ed0SZbigniew Bodek 		al_reg_write32_dbi_cs2(pcie_port, exp_rom_bar_addr , 0);
790f4b37ed0SZbigniew Bodek 	}
791f4b37ed0SZbigniew Bodek 
792f4b37ed0SZbigniew Bodek 	/* Open CPU generated msi and legacy interrupts in pcie wrapper logic */
793*3fc36ee0SWojciech Macek 	if (pcie_port->rev_id == AL_PCIE_REV_ID_1) {
794f4b37ed0SZbigniew Bodek 		al_reg_write32(regs->app.soc_int[pf_num].mask_inta_leg_0, (1 << 21));
795f4b37ed0SZbigniew Bodek 	} else if ((pcie_port->rev_id == AL_PCIE_REV_ID_2) ||
796f4b37ed0SZbigniew Bodek 		(pcie_port->rev_id == AL_PCIE_REV_ID_3)) {
797f4b37ed0SZbigniew Bodek 		al_reg_write32(regs->app.soc_int[pf_num].mask_inta_leg_3, (1 << 18));
798f4b37ed0SZbigniew Bodek 	} else {
799f4b37ed0SZbigniew Bodek 		al_assert(0);
800f4b37ed0SZbigniew Bodek 		ret = -ENOSYS;
801f4b37ed0SZbigniew Bodek 		goto done;
802f4b37ed0SZbigniew Bodek 	}
803f4b37ed0SZbigniew Bodek 
804f4b37ed0SZbigniew Bodek 	/**
805f4b37ed0SZbigniew Bodek 	 * Addressing RMN: 1547
806f4b37ed0SZbigniew Bodek 	 *
807f4b37ed0SZbigniew Bodek 	 * RMN description:
808f4b37ed0SZbigniew Bodek 	 * 1. Whenever writing to 0x2xx offset, the write also happens to
809f4b37ed0SZbigniew Bodek 	 * 0x3xx address, meaning two registers are written instead of one.
810f4b37ed0SZbigniew Bodek 	 * 2. Read and write from 0x3xx work ok.
811f4b37ed0SZbigniew Bodek 	 *
812f4b37ed0SZbigniew Bodek 	 * Software flow:
813f4b37ed0SZbigniew Bodek 	 * Backup the value of the app.int_grp_a.mask_a register, because
814f4b37ed0SZbigniew Bodek 	 * app.int_grp_a.mask_clear_a gets overwritten during the write to
815f4b37ed0SZbigniew Bodek 	 * app.soc.mask_msi_leg_0 register.
816f4b37ed0SZbigniew Bodek 	 * Restore the original value after the write to app.soc.mask_msi_leg_0
817f4b37ed0SZbigniew Bodek 	 * register.
818f4b37ed0SZbigniew Bodek 	 */
819*3fc36ee0SWojciech Macek 	if (pcie_port->rev_id == AL_PCIE_REV_ID_1) {
820f4b37ed0SZbigniew Bodek 		al_reg_write32(regs->app.soc_int[pf_num].mask_msi_leg_0, (1 << 22));
821f4b37ed0SZbigniew Bodek 	} else if ((pcie_port->rev_id == AL_PCIE_REV_ID_2) ||
822f4b37ed0SZbigniew Bodek 		(pcie_port->rev_id == AL_PCIE_REV_ID_3)) {
823f4b37ed0SZbigniew Bodek 		al_reg_write32(regs->app.soc_int[pf_num].mask_msi_leg_3, (1 << 19));
824f4b37ed0SZbigniew Bodek 	} else {
825f4b37ed0SZbigniew Bodek 		al_assert(0);
826f4b37ed0SZbigniew Bodek 		ret = -ENOSYS;
827f4b37ed0SZbigniew Bodek 		goto done;
828f4b37ed0SZbigniew Bodek 	}
829f4b37ed0SZbigniew Bodek 
830f4b37ed0SZbigniew Bodek 	ret = 0;
831f4b37ed0SZbigniew Bodek 
832f4b37ed0SZbigniew Bodek done:
833f4b37ed0SZbigniew Bodek 	al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE);
834f4b37ed0SZbigniew Bodek 
835f4b37ed0SZbigniew Bodek 	return ret;
836f4b37ed0SZbigniew Bodek }
837f4b37ed0SZbigniew Bodek 
838f4b37ed0SZbigniew Bodek static int
al_pcie_port_sris_config(struct al_pcie_port * pcie_port,struct al_pcie_sris_params * sris_params,enum al_pcie_link_speed link_speed)839f4b37ed0SZbigniew Bodek al_pcie_port_sris_config(
840f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
841f4b37ed0SZbigniew Bodek 	struct al_pcie_sris_params *sris_params,
842f4b37ed0SZbigniew Bodek 	enum al_pcie_link_speed link_speed)
843f4b37ed0SZbigniew Bodek {
844f4b37ed0SZbigniew Bodek 	int rc = 0;
845f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
846f4b37ed0SZbigniew Bodek 
847f4b37ed0SZbigniew Bodek 	if (sris_params->use_defaults) {
848f4b37ed0SZbigniew Bodek 		sris_params->kp_counter_gen3 = (pcie_port->rev_id > AL_PCIE_REV_ID_1) ?
849f4b37ed0SZbigniew Bodek 						PCIE_SRIS_KP_COUNTER_GEN3_DEFAULT_VAL : 0;
850f4b37ed0SZbigniew Bodek 		sris_params->kp_counter_gen21 = PCIE_SRIS_KP_COUNTER_GEN21_DEFAULT_VAL;
851f4b37ed0SZbigniew Bodek 
852f4b37ed0SZbigniew Bodek 		al_dbg("PCIe %d: configuring SRIS with default values kp_gen3[%d] kp_gen21[%d]\n",
853f4b37ed0SZbigniew Bodek 			pcie_port->port_id,
854f4b37ed0SZbigniew Bodek 			sris_params->kp_counter_gen3,
855f4b37ed0SZbigniew Bodek 			sris_params->kp_counter_gen21);
856f4b37ed0SZbigniew Bodek 	}
857f4b37ed0SZbigniew Bodek 
858f4b37ed0SZbigniew Bodek 	switch (pcie_port->rev_id) {
859f4b37ed0SZbigniew Bodek 	case AL_PCIE_REV_ID_3:
860*3fc36ee0SWojciech Macek 		al_reg_write32_masked(&regs->app.cfg_func_ext->cfg,
861*3fc36ee0SWojciech Macek 				PCIE_W_CFG_FUNC_EXT_CFG_APP_SRIS_MODE,
862*3fc36ee0SWojciech Macek 				PCIE_W_CFG_FUNC_EXT_CFG_APP_SRIS_MODE);
863f4b37ed0SZbigniew Bodek 	case AL_PCIE_REV_ID_2:
864f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(regs->app.global_ctrl.sris_kp_counter,
865f4b37ed0SZbigniew Bodek 			PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN3_SRIS_MASK |
866f4b37ed0SZbigniew Bodek 			PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN21_SRIS_MASK |
867f4b37ed0SZbigniew Bodek 			PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_PCIE_X4_SRIS_EN,
868f4b37ed0SZbigniew Bodek 			(sris_params->kp_counter_gen3 <<
869f4b37ed0SZbigniew Bodek 				PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN3_SRIS_SHIFT) |
870f4b37ed0SZbigniew Bodek 			(sris_params->kp_counter_gen21 <<
871f4b37ed0SZbigniew Bodek 				PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN21_SRIS_SHIFT) |
872f4b37ed0SZbigniew Bodek 			PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_PCIE_X4_SRIS_EN);
873f4b37ed0SZbigniew Bodek 		break;
874f4b37ed0SZbigniew Bodek 
875f4b37ed0SZbigniew Bodek 	case AL_PCIE_REV_ID_1:
876f4b37ed0SZbigniew Bodek 		if ((link_speed == AL_PCIE_LINK_SPEED_GEN3) && (sris_params->kp_counter_gen3)) {
877f4b37ed0SZbigniew Bodek 			al_err("PCIe %d: cannot config Gen%d SRIS with rev_id[%d]\n",
878f4b37ed0SZbigniew Bodek 				pcie_port->port_id, al_pcie_speed_gen_code(link_speed),
879f4b37ed0SZbigniew Bodek 				pcie_port->rev_id);
880f4b37ed0SZbigniew Bodek 			return -EINVAL;
881f4b37ed0SZbigniew Bodek 		}
882f4b37ed0SZbigniew Bodek 
883f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(&regs->port_regs->filter_mask_reg_1,
884f4b37ed0SZbigniew Bodek 			PCIE_FLT_MASK_SKP_INT_VAL_MASK,
885f4b37ed0SZbigniew Bodek 			sris_params->kp_counter_gen21);
886f4b37ed0SZbigniew Bodek 		break;
887f4b37ed0SZbigniew Bodek 
888f4b37ed0SZbigniew Bodek 	default:
889f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: SRIS config is not supported in rev_id[%d]\n",
890f4b37ed0SZbigniew Bodek 			pcie_port->port_id, pcie_port->rev_id);
891f4b37ed0SZbigniew Bodek 		al_assert(0);
892f4b37ed0SZbigniew Bodek 		return -EINVAL;
893f4b37ed0SZbigniew Bodek 	}
894f4b37ed0SZbigniew Bodek 
895f4b37ed0SZbigniew Bodek 	return rc;
896f4b37ed0SZbigniew Bodek }
897f4b37ed0SZbigniew Bodek 
898f4b37ed0SZbigniew Bodek static void
al_pcie_port_ib_hcrd_config(struct al_pcie_port * pcie_port)899f4b37ed0SZbigniew Bodek al_pcie_port_ib_hcrd_config(struct al_pcie_port *pcie_port)
900f4b37ed0SZbigniew Bodek {
901f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
902f4b37ed0SZbigniew Bodek 
903f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(
904f4b37ed0SZbigniew Bodek 		&regs->port_regs->vc0_posted_rcv_q_ctrl,
905f4b37ed0SZbigniew Bodek 		RADM_PQ_HCRD_VC0_MASK,
906f4b37ed0SZbigniew Bodek 		(pcie_port->ib_hcrd_config.nof_p_hdr - 1)
907f4b37ed0SZbigniew Bodek 			<< RADM_PQ_HCRD_VC0_SHIFT);
908f4b37ed0SZbigniew Bodek 
909f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(
910f4b37ed0SZbigniew Bodek 		&regs->port_regs->vc0_non_posted_rcv_q_ctrl,
911f4b37ed0SZbigniew Bodek 		RADM_NPQ_HCRD_VC0_MASK,
912f4b37ed0SZbigniew Bodek 		(pcie_port->ib_hcrd_config.nof_np_hdr - 1)
913f4b37ed0SZbigniew Bodek 			<< RADM_NPQ_HCRD_VC0_SHIFT);
914f4b37ed0SZbigniew Bodek }
915f4b37ed0SZbigniew Bodek 
916f4b37ed0SZbigniew Bodek static unsigned int
al_pcie_port_max_num_of_pfs_get(struct al_pcie_port * pcie_port)917f4b37ed0SZbigniew Bodek al_pcie_port_max_num_of_pfs_get(struct al_pcie_port *pcie_port)
918f4b37ed0SZbigniew Bodek {
919f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
920f4b37ed0SZbigniew Bodek 	uint32_t max_func_num;
921f4b37ed0SZbigniew Bodek 	uint32_t max_num_of_pfs;
922f4b37ed0SZbigniew Bodek 
923f4b37ed0SZbigniew Bodek 	/**
924f4b37ed0SZbigniew Bodek 	 * Only in REV3, when port is already enabled, max_num_of_pfs is already
925f4b37ed0SZbigniew Bodek 	 * initialized, return it. Otherwise, return default: 1 PF
926f4b37ed0SZbigniew Bodek 	 */
927f4b37ed0SZbigniew Bodek 	if ((pcie_port->rev_id == AL_PCIE_REV_ID_3)
928f4b37ed0SZbigniew Bodek 		&& al_pcie_port_is_enabled(pcie_port)) {
929f4b37ed0SZbigniew Bodek 		max_func_num = al_reg_read32(&regs->port_regs->timer_ctrl_max_func_num);
930f4b37ed0SZbigniew Bodek 		max_num_of_pfs = AL_REG_FIELD_GET(max_func_num, PCIE_PORT_GEN3_MAX_FUNC_NUM, 0) + 1;
931f4b37ed0SZbigniew Bodek 		return max_num_of_pfs;
932f4b37ed0SZbigniew Bodek 	}
933f4b37ed0SZbigniew Bodek 	return 1;
934f4b37ed0SZbigniew Bodek }
935f4b37ed0SZbigniew Bodek 
936*3fc36ee0SWojciech Macek /** Enable ecrc generation in outbound atu (Addressing RMN: 5119) */
al_pcie_ecrc_gen_ob_atu_enable(struct al_pcie_port * pcie_port,unsigned int pf_num)937*3fc36ee0SWojciech Macek static void al_pcie_ecrc_gen_ob_atu_enable(struct al_pcie_port *pcie_port, unsigned int pf_num)
938*3fc36ee0SWojciech Macek {
939*3fc36ee0SWojciech Macek 	struct al_pcie_regs *regs = pcie_port->regs;
940*3fc36ee0SWojciech Macek 	int max_ob_atu = (pcie_port->rev_id == AL_PCIE_REV_ID_3) ?
941*3fc36ee0SWojciech Macek 		AL_PCIE_REV_3_ATU_NUM_OUTBOUND_REGIONS : AL_PCIE_REV_1_2_ATU_NUM_OUTBOUND_REGIONS;
942*3fc36ee0SWojciech Macek 	int i;
943*3fc36ee0SWojciech Macek 	for (i = 0; i < max_ob_atu; i++) {
944*3fc36ee0SWojciech Macek 		al_bool enable = 0;
945*3fc36ee0SWojciech Macek 		uint32_t reg = 0;
946*3fc36ee0SWojciech Macek 		unsigned int func_num;
947*3fc36ee0SWojciech Macek 		AL_REG_FIELD_SET(reg, 0xF, 0, i);
948*3fc36ee0SWojciech Macek 		AL_REG_BIT_VAL_SET(reg, 31, AL_PCIE_ATU_DIR_OUTBOUND);
949*3fc36ee0SWojciech Macek 		al_reg_write32(&regs->port_regs->iatu.index, reg);
950*3fc36ee0SWojciech Macek 		reg = al_reg_read32(&regs->port_regs->iatu.cr2);
951*3fc36ee0SWojciech Macek 		enable = AL_REG_BIT_GET(reg, 31) ? AL_TRUE : AL_FALSE;
952*3fc36ee0SWojciech Macek 		reg = al_reg_read32(&regs->port_regs->iatu.cr1);
953*3fc36ee0SWojciech Macek 		func_num = AL_REG_FIELD_GET(reg,
954*3fc36ee0SWojciech Macek 				PCIE_IATU_CR1_FUNC_NUM_MASK,
955*3fc36ee0SWojciech Macek 				PCIE_IATU_CR1_FUNC_NUM_SHIFT);
956*3fc36ee0SWojciech Macek 		if ((enable == AL_TRUE) && (pf_num == func_num)) {
957*3fc36ee0SWojciech Macek 			/* Set TD bit */
958*3fc36ee0SWojciech Macek 			AL_REG_BIT_SET(reg, 8);
959*3fc36ee0SWojciech Macek 			al_reg_write32(&regs->port_regs->iatu.cr1, reg);
960*3fc36ee0SWojciech Macek 		}
961*3fc36ee0SWojciech Macek 	}
962*3fc36ee0SWojciech Macek }
963*3fc36ee0SWojciech Macek 
964f4b37ed0SZbigniew Bodek /******************************************************************************/
965f4b37ed0SZbigniew Bodek /***************************** API Implementation *****************************/
966f4b37ed0SZbigniew Bodek /******************************************************************************/
967f4b37ed0SZbigniew Bodek 
968f4b37ed0SZbigniew Bodek /*************************** PCIe Initialization API **************************/
969f4b37ed0SZbigniew Bodek 
970f4b37ed0SZbigniew Bodek /**
971f4b37ed0SZbigniew Bodek  * Initializes a PCIe port handle structure
972f4b37ed0SZbigniew Bodek  * Caution: this function should not read/write to any register except for
973f4b37ed0SZbigniew Bodek  * reading RO register (REV_ID for example)
974f4b37ed0SZbigniew Bodek  */
975f4b37ed0SZbigniew Bodek int
al_pcie_port_handle_init(struct al_pcie_port * pcie_port,void __iomem * pcie_reg_base,void __iomem * pbs_reg_base,unsigned int port_id)976f4b37ed0SZbigniew Bodek al_pcie_port_handle_init(
977f4b37ed0SZbigniew Bodek 	struct al_pcie_port 	*pcie_port,
978f4b37ed0SZbigniew Bodek 	void __iomem		*pcie_reg_base,
979f4b37ed0SZbigniew Bodek 	void __iomem		*pbs_reg_base,
980f4b37ed0SZbigniew Bodek 	unsigned int		port_id)
981f4b37ed0SZbigniew Bodek {
982f4b37ed0SZbigniew Bodek 	int i, ret;
983f4b37ed0SZbigniew Bodek 
984f4b37ed0SZbigniew Bodek 	pcie_port->pcie_reg_base = pcie_reg_base;
985f4b37ed0SZbigniew Bodek 	pcie_port->regs = &pcie_port->regs_ptrs;
986f4b37ed0SZbigniew Bodek 	pcie_port->ex_regs = NULL;
987f4b37ed0SZbigniew Bodek 	pcie_port->pbs_regs = pbs_reg_base;
988f4b37ed0SZbigniew Bodek 	pcie_port->port_id = port_id;
989f4b37ed0SZbigniew Bodek 	pcie_port->max_lanes = 0;
990f4b37ed0SZbigniew Bodek 
991f4b37ed0SZbigniew Bodek 	ret = al_pcie_rev_id_get(pbs_reg_base, pcie_reg_base);
992f4b37ed0SZbigniew Bodek 	if (ret < 0)
993f4b37ed0SZbigniew Bodek 		return ret;
994f4b37ed0SZbigniew Bodek 
995f4b37ed0SZbigniew Bodek 	pcie_port->rev_id = ret;
996f4b37ed0SZbigniew Bodek 
997f4b37ed0SZbigniew Bodek 	/* Zero all regs */
998f4b37ed0SZbigniew Bodek 	al_memset(pcie_port->regs, 0, sizeof(struct al_pcie_regs));
999f4b37ed0SZbigniew Bodek 
1000*3fc36ee0SWojciech Macek 	if (pcie_port->rev_id == AL_PCIE_REV_ID_1) {
1001f4b37ed0SZbigniew Bodek 		struct al_pcie_rev1_regs __iomem *regs =
1002f4b37ed0SZbigniew Bodek 			(struct al_pcie_rev1_regs __iomem *)pcie_reg_base;
1003f4b37ed0SZbigniew Bodek 
1004f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ctrl.global = &regs->axi.ctrl.global;
1005*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ctrl.master_rctl = &regs->axi.ctrl.master_rctl;
1006*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ctrl.master_ctl = &regs->axi.ctrl.master_ctl;
1007f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ctrl.master_arctl = &regs->axi.ctrl.master_arctl;
1008f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ctrl.master_awctl = &regs->axi.ctrl.master_awctl;
1009f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ctrl.slv_ctl = &regs->axi.ctrl.slv_ctl;
1010f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.cfg_target_bus = &regs->axi.ob_ctrl.cfg_target_bus;
1011f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.cfg_control = &regs->axi.ob_ctrl.cfg_control;
1012f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.io_start_l = &regs->axi.ob_ctrl.io_start_l;
1013f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.io_start_h = &regs->axi.ob_ctrl.io_start_h;
1014f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.io_limit_l = &regs->axi.ob_ctrl.io_limit_l;
1015f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.io_limit_h = &regs->axi.ob_ctrl.io_limit_h;
1016f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.pcie_global.conf = &regs->axi.pcie_global.conf;
1017f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.conf.zero_lane0 = &regs->axi.conf.zero_lane0;
1018f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.conf.zero_lane1 = &regs->axi.conf.zero_lane1;
1019f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.conf.zero_lane2 = &regs->axi.conf.zero_lane2;
1020f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.conf.zero_lane3 = &regs->axi.conf.zero_lane3;
1021f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.status.lane[0] = &regs->axi.status.lane0;
1022f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.status.lane[1] = &regs->axi.status.lane1;
1023f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.status.lane[2] = &regs->axi.status.lane2;
1024f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.status.lane[3] = &regs->axi.status.lane3;
1025f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.parity.en_axi = &regs->axi.parity.en_axi;
1026f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ordering.pos_cntl = &regs->axi.ordering.pos_cntl;
1027f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.pre_configuration.pcie_core_setup = &regs->axi.pre_configuration.pcie_core_setup;
1028f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.init_fc.cfg = &regs->axi.init_fc.cfg;
1029f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.int_grp_a = &regs->axi.int_grp_a;
1030f4b37ed0SZbigniew Bodek 
1031f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.global_ctrl.port_init = &regs->app.global_ctrl.port_init;
1032f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.global_ctrl.pm_control = &regs->app.global_ctrl.pm_control;
1033f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.global_ctrl.events_gen[0] = &regs->app.global_ctrl.events_gen;
1034f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.debug = &regs->app.debug;
1035*3fc36ee0SWojciech Macek 		pcie_port->regs->app.soc_int[0].status_0 = &regs->app.soc_int.status_0;
1036*3fc36ee0SWojciech Macek 		pcie_port->regs->app.soc_int[0].status_1 = &regs->app.soc_int.status_1;
1037*3fc36ee0SWojciech Macek 		pcie_port->regs->app.soc_int[0].status_2 = &regs->app.soc_int.status_2;
1038f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.soc_int[0].mask_inta_leg_0 = &regs->app.soc_int.mask_inta_leg_0;
1039*3fc36ee0SWojciech Macek 		pcie_port->regs->app.soc_int[0].mask_inta_leg_1 = &regs->app.soc_int.mask_inta_leg_1;
1040*3fc36ee0SWojciech Macek 		pcie_port->regs->app.soc_int[0].mask_inta_leg_2 = &regs->app.soc_int.mask_inta_leg_2;
1041f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.soc_int[0].mask_msi_leg_0 = &regs->app.soc_int.mask_msi_leg_0;
1042*3fc36ee0SWojciech Macek 		pcie_port->regs->app.soc_int[0].mask_msi_leg_1 = &regs->app.soc_int.mask_msi_leg_1;
1043*3fc36ee0SWojciech Macek 		pcie_port->regs->app.soc_int[0].mask_msi_leg_2 = &regs->app.soc_int.mask_msi_leg_2;
1044f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.ctrl_gen = &regs->app.ctrl_gen;
1045f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.parity = &regs->app.parity;
1046f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.atu.in_mask_pair = regs->app.atu.in_mask_pair;
1047f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.atu.out_mask_pair = regs->app.atu.out_mask_pair;
1048f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.int_grp_a = &regs->app.int_grp_a;
1049f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.int_grp_b = &regs->app.int_grp_b;
1050f4b37ed0SZbigniew Bodek 
1051f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].config_header = regs->core_space.config_header;
1052f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].pcie_pm_cap_base = &regs->core_space.pcie_pm_cap_base;
1053f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].pcie_cap_base = &regs->core_space.pcie_cap_base;
1054f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].pcie_dev_cap_base = &regs->core_space.pcie_dev_cap_base;
1055f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].pcie_dev_ctrl_status = &regs->core_space.pcie_dev_ctrl_status;
1056f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].pcie_link_cap_base = &regs->core_space.pcie_link_cap_base;
1057f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].msix_cap_base = &regs->core_space.msix_cap_base;
1058f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].aer = &regs->core_space.aer;
1059f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].pcie_sec_ext_cap_base = &regs->core_space.pcie_sec_ext_cap_base;
1060f4b37ed0SZbigniew Bodek 
1061f4b37ed0SZbigniew Bodek 		pcie_port->regs->port_regs = &regs->core_space.port_regs;
1062f4b37ed0SZbigniew Bodek 
1063f4b37ed0SZbigniew Bodek 	} else if (pcie_port->rev_id == AL_PCIE_REV_ID_2) {
1064f4b37ed0SZbigniew Bodek 		struct al_pcie_rev2_regs __iomem *regs =
1065f4b37ed0SZbigniew Bodek 			(struct al_pcie_rev2_regs __iomem *)pcie_reg_base;
1066f4b37ed0SZbigniew Bodek 
1067f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ctrl.global = &regs->axi.ctrl.global;
1068*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ctrl.master_rctl = &regs->axi.ctrl.master_rctl;
1069*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ctrl.master_ctl = &regs->axi.ctrl.master_ctl;
1070f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ctrl.master_arctl = &regs->axi.ctrl.master_arctl;
1071f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ctrl.master_awctl = &regs->axi.ctrl.master_awctl;
1072f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ctrl.slv_ctl = &regs->axi.ctrl.slv_ctl;
1073f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.cfg_target_bus = &regs->axi.ob_ctrl.cfg_target_bus;
1074f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.cfg_control = &regs->axi.ob_ctrl.cfg_control;
1075f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.io_start_l = &regs->axi.ob_ctrl.io_start_l;
1076f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.io_start_h = &regs->axi.ob_ctrl.io_start_h;
1077f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.io_limit_l = &regs->axi.ob_ctrl.io_limit_l;
1078f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.io_limit_h = &regs->axi.ob_ctrl.io_limit_h;
1079*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ob_ctrl.tgtid_reg_ovrd = &regs->axi.ob_ctrl.tgtid_reg_ovrd;
1080*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ob_ctrl.addr_high_reg_ovrd_sel = &regs->axi.ob_ctrl.addr_high_reg_ovrd_sel;
1081*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ob_ctrl.addr_high_reg_ovrd_value = &regs->axi.ob_ctrl.addr_high_reg_ovrd_value;
1082*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ob_ctrl.addr_size_replace = &regs->axi.ob_ctrl.addr_size_replace;
1083f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.pcie_global.conf = &regs->axi.pcie_global.conf;
1084f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.conf.zero_lane0 = &regs->axi.conf.zero_lane0;
1085f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.conf.zero_lane1 = &regs->axi.conf.zero_lane1;
1086f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.conf.zero_lane2 = &regs->axi.conf.zero_lane2;
1087f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.conf.zero_lane3 = &regs->axi.conf.zero_lane3;
1088f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.status.lane[0] = &regs->axi.status.lane0;
1089f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.status.lane[1] = &regs->axi.status.lane1;
1090f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.status.lane[2] = &regs->axi.status.lane2;
1091f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.status.lane[3] = &regs->axi.status.lane3;
1092f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.parity.en_axi = &regs->axi.parity.en_axi;
1093f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ordering.pos_cntl = &regs->axi.ordering.pos_cntl;
1094f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.pre_configuration.pcie_core_setup = &regs->axi.pre_configuration.pcie_core_setup;
1095f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.init_fc.cfg = &regs->axi.init_fc.cfg;
1096f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.int_grp_a = &regs->axi.int_grp_a;
1097f4b37ed0SZbigniew Bodek 
1098f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.global_ctrl.port_init = &regs->app.global_ctrl.port_init;
1099f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.global_ctrl.pm_control = &regs->app.global_ctrl.pm_control;
1100f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.global_ctrl.events_gen[0] = &regs->app.global_ctrl.events_gen;
1101f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.global_ctrl.corr_err_sts_int = &regs->app.global_ctrl.pended_corr_err_sts_int;
1102f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.global_ctrl.uncorr_err_sts_int = &regs->app.global_ctrl.pended_uncorr_err_sts_int;
1103*3fc36ee0SWojciech Macek 		pcie_port->regs->app.global_ctrl.sris_kp_counter = &regs->app.global_ctrl.sris_kp_counter_value;
1104f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.debug = &regs->app.debug;
1105f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.ap_user_send_msg = &regs->app.ap_user_send_msg;
1106*3fc36ee0SWojciech Macek 		pcie_port->regs->app.soc_int[0].status_0 = &regs->app.soc_int.status_0;
1107*3fc36ee0SWojciech Macek 		pcie_port->regs->app.soc_int[0].status_1 = &regs->app.soc_int.status_1;
1108*3fc36ee0SWojciech Macek 		pcie_port->regs->app.soc_int[0].status_2 = &regs->app.soc_int.status_2;
1109*3fc36ee0SWojciech Macek 		pcie_port->regs->app.soc_int[0].status_3 = &regs->app.soc_int.status_3;
1110f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.soc_int[0].mask_inta_leg_0 = &regs->app.soc_int.mask_inta_leg_0;
1111*3fc36ee0SWojciech Macek 		pcie_port->regs->app.soc_int[0].mask_inta_leg_1 = &regs->app.soc_int.mask_inta_leg_1;
1112*3fc36ee0SWojciech Macek 		pcie_port->regs->app.soc_int[0].mask_inta_leg_2 = &regs->app.soc_int.mask_inta_leg_2;
1113f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.soc_int[0].mask_inta_leg_3 = &regs->app.soc_int.mask_inta_leg_3;
1114f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.soc_int[0].mask_msi_leg_0 = &regs->app.soc_int.mask_msi_leg_0;
1115*3fc36ee0SWojciech Macek 		pcie_port->regs->app.soc_int[0].mask_msi_leg_1 = &regs->app.soc_int.mask_msi_leg_1;
1116*3fc36ee0SWojciech Macek 		pcie_port->regs->app.soc_int[0].mask_msi_leg_2 = &regs->app.soc_int.mask_msi_leg_2;
1117f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.soc_int[0].mask_msi_leg_3 = &regs->app.soc_int.mask_msi_leg_3;
1118f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.ctrl_gen = &regs->app.ctrl_gen;
1119f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.parity = &regs->app.parity;
1120f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.atu.in_mask_pair = regs->app.atu.in_mask_pair;
1121f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.atu.out_mask_pair = regs->app.atu.out_mask_pair;
1122f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.status_per_func[0] = &regs->app.status_per_func;
1123f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.int_grp_a = &regs->app.int_grp_a;
1124f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.int_grp_b = &regs->app.int_grp_b;
1125f4b37ed0SZbigniew Bodek 
1126f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].config_header = regs->core_space.config_header;
1127f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].pcie_pm_cap_base = &regs->core_space.pcie_pm_cap_base;
1128f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].pcie_cap_base = &regs->core_space.pcie_cap_base;
1129f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].pcie_dev_cap_base = &regs->core_space.pcie_dev_cap_base;
1130f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].pcie_dev_ctrl_status = &regs->core_space.pcie_dev_ctrl_status;
1131f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].pcie_link_cap_base = &regs->core_space.pcie_link_cap_base;
1132f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].msix_cap_base = &regs->core_space.msix_cap_base;
1133f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].aer = &regs->core_space.aer;
1134f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].pcie_sec_ext_cap_base = &regs->core_space.pcie_sec_ext_cap_base;
1135f4b37ed0SZbigniew Bodek 
1136f4b37ed0SZbigniew Bodek 		pcie_port->regs->port_regs = &regs->core_space.port_regs;
1137f4b37ed0SZbigniew Bodek 
1138f4b37ed0SZbigniew Bodek 	} else if (pcie_port->rev_id == AL_PCIE_REV_ID_3) {
1139f4b37ed0SZbigniew Bodek 		struct al_pcie_rev3_regs __iomem *regs =
1140f4b37ed0SZbigniew Bodek 			(struct al_pcie_rev3_regs __iomem *)pcie_reg_base;
1141f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ctrl.global = &regs->axi.ctrl.global;
1142*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ctrl.master_rctl = &regs->axi.ctrl.master_rctl;
1143*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ctrl.master_ctl = &regs->axi.ctrl.master_ctl;
1144f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ctrl.master_arctl = &regs->axi.ctrl.master_arctl;
1145f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ctrl.master_awctl = &regs->axi.ctrl.master_awctl;
1146f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ctrl.slv_ctl = &regs->axi.ctrl.slv_ctl;
1147f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.cfg_target_bus = &regs->axi.ob_ctrl.cfg_target_bus;
1148f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.cfg_control = &regs->axi.ob_ctrl.cfg_control;
1149f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.io_start_l = &regs->axi.ob_ctrl.io_start_l;
1150f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.io_start_h = &regs->axi.ob_ctrl.io_start_h;
1151f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.io_limit_l = &regs->axi.ob_ctrl.io_limit_l;
1152f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ob_ctrl.io_limit_h = &regs->axi.ob_ctrl.io_limit_h;
1153*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ob_ctrl.io_addr_mask_h = &regs->axi.ob_ctrl.io_addr_mask_h;
1154*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ob_ctrl.ar_msg_addr_mask_h = &regs->axi.ob_ctrl.ar_msg_addr_mask_h;
1155*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ob_ctrl.aw_msg_addr_mask_h = &regs->axi.ob_ctrl.aw_msg_addr_mask_h;
1156*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ob_ctrl.tgtid_reg_ovrd = &regs->axi.ob_ctrl.tgtid_reg_ovrd;
1157*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ob_ctrl.addr_high_reg_ovrd_sel = &regs->axi.ob_ctrl.addr_high_reg_ovrd_sel;
1158*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ob_ctrl.addr_high_reg_ovrd_value = &regs->axi.ob_ctrl.addr_high_reg_ovrd_value;
1159*3fc36ee0SWojciech Macek 		pcie_port->regs->axi.ob_ctrl.addr_size_replace = &regs->axi.ob_ctrl.addr_size_replace;
1160f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.pcie_global.conf = &regs->axi.pcie_global.conf;
1161f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.conf.zero_lane0 = &regs->axi.conf.zero_lane0;
1162f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.conf.zero_lane1 = &regs->axi.conf.zero_lane1;
1163f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.conf.zero_lane2 = &regs->axi.conf.zero_lane2;
1164f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.conf.zero_lane3 = &regs->axi.conf.zero_lane3;
1165f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.conf.zero_lane4 = &regs->axi.conf.zero_lane4;
1166f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.conf.zero_lane5 = &regs->axi.conf.zero_lane5;
1167f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.conf.zero_lane6 = &regs->axi.conf.zero_lane6;
1168f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.conf.zero_lane7 = &regs->axi.conf.zero_lane7;
1169f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.status.lane[0] = &regs->axi.status.lane0;
1170f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.status.lane[1] = &regs->axi.status.lane1;
1171f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.status.lane[2] = &regs->axi.status.lane2;
1172f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.status.lane[3] = &regs->axi.status.lane3;
1173f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.status.lane[4] = &regs->axi.status.lane4;
1174f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.status.lane[5] = &regs->axi.status.lane5;
1175f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.status.lane[6] = &regs->axi.status.lane6;
1176f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.status.lane[7] = &regs->axi.status.lane7;
1177f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.parity.en_axi = &regs->axi.parity.en_axi;
1178f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.ordering.pos_cntl = &regs->axi.ordering.pos_cntl;
1179f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.pre_configuration.pcie_core_setup = &regs->axi.pre_configuration.pcie_core_setup;
1180f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.init_fc.cfg = &regs->axi.init_fc.cfg;
1181f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.int_grp_a = &regs->axi.int_grp_a;
1182f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.axi_attr_ovrd.write_msg_ctrl_0 = &regs->axi.axi_attr_ovrd.write_msg_ctrl_0;
1183f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.axi_attr_ovrd.write_msg_ctrl_1 = &regs->axi.axi_attr_ovrd.write_msg_ctrl_1;
1184f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.axi_attr_ovrd.pf_sel = &regs->axi.axi_attr_ovrd.pf_sel;
1185f4b37ed0SZbigniew Bodek 
1186f4b37ed0SZbigniew Bodek 		for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) {
1187f4b37ed0SZbigniew Bodek 			pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_0 = &regs->axi.pf_axi_attr_ovrd[i].func_ctrl_0;
1188f4b37ed0SZbigniew Bodek 			pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_1 = &regs->axi.pf_axi_attr_ovrd[i].func_ctrl_1;
1189f4b37ed0SZbigniew Bodek 			pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_2 = &regs->axi.pf_axi_attr_ovrd[i].func_ctrl_2;
1190f4b37ed0SZbigniew Bodek 			pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_3 = &regs->axi.pf_axi_attr_ovrd[i].func_ctrl_3;
1191f4b37ed0SZbigniew Bodek 			pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_4 = &regs->axi.pf_axi_attr_ovrd[i].func_ctrl_4;
1192f4b37ed0SZbigniew Bodek 			pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_5 = &regs->axi.pf_axi_attr_ovrd[i].func_ctrl_5;
1193f4b37ed0SZbigniew Bodek 			pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_6 = &regs->axi.pf_axi_attr_ovrd[i].func_ctrl_6;
1194f4b37ed0SZbigniew Bodek 			pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_7 = &regs->axi.pf_axi_attr_ovrd[i].func_ctrl_7;
1195f4b37ed0SZbigniew Bodek 			pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_8 = &regs->axi.pf_axi_attr_ovrd[i].func_ctrl_8;
1196f4b37ed0SZbigniew Bodek 			pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_9 = &regs->axi.pf_axi_attr_ovrd[i].func_ctrl_9;
1197f4b37ed0SZbigniew Bodek 		}
1198f4b37ed0SZbigniew Bodek 
1199f4b37ed0SZbigniew Bodek 		pcie_port->regs->axi.msg_attr_axuser_table.entry_vec = &regs->axi.msg_attr_axuser_table.entry_vec;
1200f4b37ed0SZbigniew Bodek 
1201f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.global_ctrl.port_init = &regs->app.global_ctrl.port_init;
1202f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.global_ctrl.pm_control = &regs->app.global_ctrl.pm_control;
1203f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.global_ctrl.corr_err_sts_int = &regs->app.global_ctrl.pended_corr_err_sts_int;
1204f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.global_ctrl.uncorr_err_sts_int = &regs->app.global_ctrl.pended_uncorr_err_sts_int;
1205f4b37ed0SZbigniew Bodek 
1206f4b37ed0SZbigniew Bodek 		for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) {
1207f4b37ed0SZbigniew Bodek 			pcie_port->regs->app.global_ctrl.events_gen[i] = &regs->app.events_gen_per_func[i].events_gen;
1208f4b37ed0SZbigniew Bodek 		}
1209f4b37ed0SZbigniew Bodek 
1210f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.global_ctrl.sris_kp_counter = &regs->app.global_ctrl.sris_kp_counter_value;
1211f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.debug = &regs->app.debug;
1212f4b37ed0SZbigniew Bodek 
1213f4b37ed0SZbigniew Bodek 		for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) {
1214*3fc36ee0SWojciech Macek 			pcie_port->regs->app.soc_int[i].status_0 = &regs->app.soc_int_per_func[i].status_0;
1215*3fc36ee0SWojciech Macek 			pcie_port->regs->app.soc_int[i].status_1 = &regs->app.soc_int_per_func[i].status_1;
1216*3fc36ee0SWojciech Macek 			pcie_port->regs->app.soc_int[i].status_2 = &regs->app.soc_int_per_func[i].status_2;
1217*3fc36ee0SWojciech Macek 			pcie_port->regs->app.soc_int[i].status_3 = &regs->app.soc_int_per_func[i].status_3;
1218f4b37ed0SZbigniew Bodek 			pcie_port->regs->app.soc_int[i].mask_inta_leg_0 = &regs->app.soc_int_per_func[i].mask_inta_leg_0;
1219*3fc36ee0SWojciech Macek 			pcie_port->regs->app.soc_int[i].mask_inta_leg_1 = &regs->app.soc_int_per_func[i].mask_inta_leg_1;
1220*3fc36ee0SWojciech Macek 			pcie_port->regs->app.soc_int[i].mask_inta_leg_2 = &regs->app.soc_int_per_func[i].mask_inta_leg_2;
1221f4b37ed0SZbigniew Bodek 			pcie_port->regs->app.soc_int[i].mask_inta_leg_3 = &regs->app.soc_int_per_func[i].mask_inta_leg_3;
1222f4b37ed0SZbigniew Bodek 			pcie_port->regs->app.soc_int[i].mask_msi_leg_0 = &regs->app.soc_int_per_func[i].mask_msi_leg_0;
1223*3fc36ee0SWojciech Macek 			pcie_port->regs->app.soc_int[i].mask_msi_leg_1 = &regs->app.soc_int_per_func[i].mask_msi_leg_1;
1224*3fc36ee0SWojciech Macek 			pcie_port->regs->app.soc_int[i].mask_msi_leg_2 = &regs->app.soc_int_per_func[i].mask_msi_leg_2;
1225f4b37ed0SZbigniew Bodek 			pcie_port->regs->app.soc_int[i].mask_msi_leg_3 = &regs->app.soc_int_per_func[i].mask_msi_leg_3;
1226f4b37ed0SZbigniew Bodek 		}
1227f4b37ed0SZbigniew Bodek 
1228f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.ap_user_send_msg = &regs->app.ap_user_send_msg;
1229f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.ctrl_gen = &regs->app.ctrl_gen;
1230f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.parity = &regs->app.parity;
1231f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.atu.in_mask_pair = regs->app.atu.in_mask_pair;
1232f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.atu.out_mask_pair = regs->app.atu.out_mask_pair;
1233*3fc36ee0SWojciech Macek 		pcie_port->regs->app.cfg_func_ext = &regs->app.cfg_func_ext;
1234f4b37ed0SZbigniew Bodek 
1235f4b37ed0SZbigniew Bodek 		for (i = 0; i < AL_MAX_NUM_OF_PFS; i++)
1236f4b37ed0SZbigniew Bodek 			pcie_port->regs->app.status_per_func[i] = &regs->app.status_per_func[i];
1237f4b37ed0SZbigniew Bodek 
1238f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.int_grp_a = &regs->app.int_grp_a;
1239f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.int_grp_b = &regs->app.int_grp_b;
1240f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.int_grp_c = &regs->app.int_grp_c;
1241f4b37ed0SZbigniew Bodek 		pcie_port->regs->app.int_grp_d = &regs->app.int_grp_d;
1242f4b37ed0SZbigniew Bodek 
1243f4b37ed0SZbigniew Bodek 		for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) {
1244f4b37ed0SZbigniew Bodek 			pcie_port->regs->core_space[i].config_header = regs->core_space.func[i].config_header;
1245f4b37ed0SZbigniew Bodek 			pcie_port->regs->core_space[i].pcie_pm_cap_base = &regs->core_space.func[i].pcie_pm_cap_base;
1246f4b37ed0SZbigniew Bodek 			pcie_port->regs->core_space[i].pcie_cap_base = &regs->core_space.func[i].pcie_cap_base;
1247f4b37ed0SZbigniew Bodek 			pcie_port->regs->core_space[i].pcie_dev_cap_base = &regs->core_space.func[i].pcie_dev_cap_base;
1248f4b37ed0SZbigniew Bodek 			pcie_port->regs->core_space[i].pcie_dev_ctrl_status = &regs->core_space.func[i].pcie_dev_ctrl_status;
1249f4b37ed0SZbigniew Bodek 			pcie_port->regs->core_space[i].pcie_link_cap_base = &regs->core_space.func[i].pcie_link_cap_base;
1250f4b37ed0SZbigniew Bodek 			pcie_port->regs->core_space[i].msix_cap_base = &regs->core_space.func[i].msix_cap_base;
1251f4b37ed0SZbigniew Bodek 			pcie_port->regs->core_space[i].aer = &regs->core_space.func[i].aer;
1252f4b37ed0SZbigniew Bodek 			pcie_port->regs->core_space[i].tph_cap_base = &regs->core_space.func[i].tph_cap_base;
1253f4b37ed0SZbigniew Bodek 
1254f4b37ed0SZbigniew Bodek 		}
1255f4b37ed0SZbigniew Bodek 
1256f4b37ed0SZbigniew Bodek 		/* secondary extension capability only for PF0 */
1257f4b37ed0SZbigniew Bodek 		pcie_port->regs->core_space[0].pcie_sec_ext_cap_base = &regs->core_space.func[0].pcie_sec_ext_cap_base;
1258f4b37ed0SZbigniew Bodek 
1259f4b37ed0SZbigniew Bodek 		pcie_port->regs->port_regs = &regs->core_space.func[0].port_regs;
1260f4b37ed0SZbigniew Bodek 
1261f4b37ed0SZbigniew Bodek 	} else {
1262f4b37ed0SZbigniew Bodek 		al_warn("%s: Revision ID is unknown\n",
1263f4b37ed0SZbigniew Bodek 			__func__);
1264f4b37ed0SZbigniew Bodek 		return -EINVAL;
1265f4b37ed0SZbigniew Bodek 	}
1266f4b37ed0SZbigniew Bodek 
1267f4b37ed0SZbigniew Bodek 	/* set maximum number of physical functions */
1268f4b37ed0SZbigniew Bodek 	pcie_port->max_num_of_pfs = al_pcie_port_max_num_of_pfs_get(pcie_port);
1269f4b37ed0SZbigniew Bodek 
1270*3fc36ee0SWojciech Macek 	/* Clear 'nof_p_hdr' & 'nof_np_hdr' to later know if they where changed by the user */
1271*3fc36ee0SWojciech Macek 	pcie_port->ib_hcrd_config.nof_np_hdr = 0;
1272*3fc36ee0SWojciech Macek 	pcie_port->ib_hcrd_config.nof_p_hdr = 0;
1273*3fc36ee0SWojciech Macek 
1274f4b37ed0SZbigniew Bodek 	al_dbg("pcie port handle initialized. port id: %d, rev_id %d, regs base %p\n",
1275f4b37ed0SZbigniew Bodek 	       port_id, pcie_port->rev_id, pcie_reg_base);
1276f4b37ed0SZbigniew Bodek 	return 0;
1277f4b37ed0SZbigniew Bodek }
1278f4b37ed0SZbigniew Bodek 
1279f4b37ed0SZbigniew Bodek /**
1280f4b37ed0SZbigniew Bodek  * Initializes a PCIe Physical function handle structure
1281f4b37ed0SZbigniew Bodek  * Caution: this function should not read/write to any register except for
1282f4b37ed0SZbigniew Bodek  * reading RO register (REV_ID for example)
1283f4b37ed0SZbigniew Bodek  */
1284f4b37ed0SZbigniew Bodek int
al_pcie_pf_handle_init(struct al_pcie_pf * pcie_pf,struct al_pcie_port * pcie_port,unsigned int pf_num)1285f4b37ed0SZbigniew Bodek al_pcie_pf_handle_init(
1286f4b37ed0SZbigniew Bodek 	struct al_pcie_pf *pcie_pf,
1287f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
1288f4b37ed0SZbigniew Bodek 	unsigned int pf_num)
1289f4b37ed0SZbigniew Bodek {
1290f4b37ed0SZbigniew Bodek 	enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port);
1291f4b37ed0SZbigniew Bodek 	al_assert(pf_num < pcie_port->max_num_of_pfs);
1292f4b37ed0SZbigniew Bodek 
1293f4b37ed0SZbigniew Bodek 	if (op_mode != AL_PCIE_OPERATING_MODE_EP) {
1294f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: can't init PF handle with operating mode [%d]\n",
1295f4b37ed0SZbigniew Bodek 			pcie_port->port_id, op_mode);
1296f4b37ed0SZbigniew Bodek 		return -EINVAL;
1297f4b37ed0SZbigniew Bodek 	}
1298f4b37ed0SZbigniew Bodek 
1299f4b37ed0SZbigniew Bodek 	pcie_pf->pf_num = pf_num;
1300f4b37ed0SZbigniew Bodek 	pcie_pf->pcie_port = pcie_port;
1301f4b37ed0SZbigniew Bodek 
1302f4b37ed0SZbigniew Bodek 	al_dbg("PCIe %d: pf handle initialized. pf number: %d, rev_id %d, regs %p\n",
1303f4b37ed0SZbigniew Bodek 	       pcie_port->port_id, pcie_pf->pf_num, pcie_port->rev_id,
1304f4b37ed0SZbigniew Bodek 	       pcie_port->regs);
1305f4b37ed0SZbigniew Bodek 	return 0;
1306f4b37ed0SZbigniew Bodek }
1307f4b37ed0SZbigniew Bodek 
1308*3fc36ee0SWojciech Macek /** Get port revision ID */
al_pcie_port_rev_id_get(struct al_pcie_port * pcie_port)1309*3fc36ee0SWojciech Macek int al_pcie_port_rev_id_get(struct al_pcie_port *pcie_port)
1310*3fc36ee0SWojciech Macek {
1311*3fc36ee0SWojciech Macek 	return pcie_port->rev_id;
1312*3fc36ee0SWojciech Macek }
1313*3fc36ee0SWojciech Macek 
1314f4b37ed0SZbigniew Bodek /************************** Pre PCIe Port Enable API **************************/
1315f4b37ed0SZbigniew Bodek 
1316f4b37ed0SZbigniew Bodek /** configure pcie operating mode (root complex or endpoint) */
1317f4b37ed0SZbigniew Bodek int
al_pcie_port_operating_mode_config(struct al_pcie_port * pcie_port,enum al_pcie_operating_mode mode)1318f4b37ed0SZbigniew Bodek al_pcie_port_operating_mode_config(
1319f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
1320f4b37ed0SZbigniew Bodek 	enum al_pcie_operating_mode mode)
1321f4b37ed0SZbigniew Bodek {
1322f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
1323f4b37ed0SZbigniew Bodek 	uint32_t reg, device_type, new_device_type;
1324f4b37ed0SZbigniew Bodek 
1325f4b37ed0SZbigniew Bodek 	if (al_pcie_port_is_enabled(pcie_port)) {
1326f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: already enabled, cannot set operating mode\n",
1327f4b37ed0SZbigniew Bodek 			pcie_port->port_id);
1328f4b37ed0SZbigniew Bodek 		return -EINVAL;
1329f4b37ed0SZbigniew Bodek 	}
1330f4b37ed0SZbigniew Bodek 
1331f4b37ed0SZbigniew Bodek 	reg = al_reg_read32(regs->axi.pcie_global.conf);
1332f4b37ed0SZbigniew Bodek 
1333f4b37ed0SZbigniew Bodek 	device_type = AL_REG_FIELD_GET(reg,
1334f4b37ed0SZbigniew Bodek 			PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_MASK,
1335f4b37ed0SZbigniew Bodek 			PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_SHIFT);
1336f4b37ed0SZbigniew Bodek 	if (mode == AL_PCIE_OPERATING_MODE_EP) {
1337f4b37ed0SZbigniew Bodek 		new_device_type = PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_EP;
1338f4b37ed0SZbigniew Bodek 	} else if (mode == AL_PCIE_OPERATING_MODE_RC) {
1339f4b37ed0SZbigniew Bodek 		new_device_type = PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_RC;
1340f4b37ed0SZbigniew Bodek 
1341f4b37ed0SZbigniew Bodek 		if (pcie_port->rev_id == AL_PCIE_REV_ID_3) {
1342f4b37ed0SZbigniew Bodek 			/* config 1 PF in RC mode */
1343f4b37ed0SZbigniew Bodek 			al_reg_write32_masked(regs->axi.axi_attr_ovrd.pf_sel,
1344f4b37ed0SZbigniew Bodek 				PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_OVRD_FROM_AXUSER |
1345f4b37ed0SZbigniew Bodek 				PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_OVRD_FROM_REG |
1346f4b37ed0SZbigniew Bodek 				PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_ADDR_OFFSET_MASK |
1347f4b37ed0SZbigniew Bodek 				PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_CFG_PF_BIT0_OVRD |
1348f4b37ed0SZbigniew Bodek 				PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_OVRD_FROM_AXUSER |
1349f4b37ed0SZbigniew Bodek 				PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_OVRD_FROM_REG |
1350f4b37ed0SZbigniew Bodek 				PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_ADDR_OFFSET_MASK |
1351f4b37ed0SZbigniew Bodek 				PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_CFG_PF_BIT1_OVRD,
1352f4b37ed0SZbigniew Bodek 				PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_OVRD_FROM_REG |
1353f4b37ed0SZbigniew Bodek 				PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_OVRD_FROM_REG);
1354f4b37ed0SZbigniew Bodek 		}
1355f4b37ed0SZbigniew Bodek 	} else {
1356f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: unknown operating mode: %d\n", pcie_port->port_id, mode);
1357f4b37ed0SZbigniew Bodek 		return -EINVAL;
1358f4b37ed0SZbigniew Bodek 	}
1359f4b37ed0SZbigniew Bodek 
1360f4b37ed0SZbigniew Bodek 	if (new_device_type == device_type) {
1361f4b37ed0SZbigniew Bodek 		al_dbg("PCIe %d: operating mode already set to %s\n",
1362f4b37ed0SZbigniew Bodek 		       pcie_port->port_id, (mode == AL_PCIE_OPERATING_MODE_EP) ?
1363f4b37ed0SZbigniew Bodek 		       "EndPoint" : "Root Complex");
1364f4b37ed0SZbigniew Bodek 		return 0;
1365f4b37ed0SZbigniew Bodek 	}
1366*3fc36ee0SWojciech Macek 	al_dbg("PCIe %d: set operating mode to %s\n",
1367f4b37ed0SZbigniew Bodek 		pcie_port->port_id, (mode == AL_PCIE_OPERATING_MODE_EP) ?
1368f4b37ed0SZbigniew Bodek 		"EndPoint" : "Root Complex");
1369f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_MASK,
1370f4b37ed0SZbigniew Bodek 			 PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_SHIFT,
1371f4b37ed0SZbigniew Bodek 			 new_device_type);
1372f4b37ed0SZbigniew Bodek 
1373f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->axi.pcie_global.conf, reg);
1374f4b37ed0SZbigniew Bodek 
1375f4b37ed0SZbigniew Bodek 	return 0;
1376f4b37ed0SZbigniew Bodek }
1377f4b37ed0SZbigniew Bodek 
1378f4b37ed0SZbigniew Bodek int
al_pcie_port_max_lanes_set(struct al_pcie_port * pcie_port,uint8_t lanes)1379f4b37ed0SZbigniew Bodek al_pcie_port_max_lanes_set(struct al_pcie_port *pcie_port, uint8_t lanes)
1380f4b37ed0SZbigniew Bodek {
1381f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
1382*3fc36ee0SWojciech Macek 	uint32_t active_lanes_val;
1383f4b37ed0SZbigniew Bodek 
1384f4b37ed0SZbigniew Bodek 	if (al_pcie_port_is_enabled(pcie_port)) {
1385f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: already enabled, cannot set max lanes\n",
1386f4b37ed0SZbigniew Bodek 			pcie_port->port_id);
1387f4b37ed0SZbigniew Bodek 		return -EINVAL;
1388f4b37ed0SZbigniew Bodek 	}
1389f4b37ed0SZbigniew Bodek 
1390f4b37ed0SZbigniew Bodek 	/* convert to bitmask format (4 ->'b1111, 2 ->'b11, 1 -> 'b1) */
1391*3fc36ee0SWojciech Macek 	active_lanes_val = AL_PCIE_PARSE_LANES(lanes);
1392f4b37ed0SZbigniew Bodek 
1393f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(regs->axi.pcie_global.conf,
1394f4b37ed0SZbigniew Bodek 		(pcie_port->rev_id == AL_PCIE_REV_ID_3) ?
1395f4b37ed0SZbigniew Bodek 		PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_MASK :
1396f4b37ed0SZbigniew Bodek 		PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_MASK,
1397f4b37ed0SZbigniew Bodek 		active_lanes_val);
1398f4b37ed0SZbigniew Bodek 
1399f4b37ed0SZbigniew Bodek 	pcie_port->max_lanes = lanes;
1400f4b37ed0SZbigniew Bodek 	return 0;
1401f4b37ed0SZbigniew Bodek }
1402f4b37ed0SZbigniew Bodek 
1403f4b37ed0SZbigniew Bodek int
al_pcie_port_max_num_of_pfs_set(struct al_pcie_port * pcie_port,uint8_t max_num_of_pfs)1404f4b37ed0SZbigniew Bodek al_pcie_port_max_num_of_pfs_set(
1405f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
1406f4b37ed0SZbigniew Bodek 	uint8_t max_num_of_pfs)
1407f4b37ed0SZbigniew Bodek {
1408*3fc36ee0SWojciech Macek 	struct al_pcie_regs *regs = pcie_port->regs;
1409f4b37ed0SZbigniew Bodek 
1410f4b37ed0SZbigniew Bodek 	if (pcie_port->rev_id == AL_PCIE_REV_ID_3)
1411f4b37ed0SZbigniew Bodek 		al_assert(max_num_of_pfs <= REV3_MAX_NUM_OF_PFS);
1412f4b37ed0SZbigniew Bodek 	else
1413f4b37ed0SZbigniew Bodek 		al_assert(max_num_of_pfs == REV1_2_MAX_NUM_OF_PFS);
1414f4b37ed0SZbigniew Bodek 
1415f4b37ed0SZbigniew Bodek 	pcie_port->max_num_of_pfs = max_num_of_pfs;
1416f4b37ed0SZbigniew Bodek 
1417*3fc36ee0SWojciech Macek 	if (al_pcie_port_is_enabled(pcie_port) && (pcie_port->rev_id == AL_PCIE_REV_ID_3)) {
1418*3fc36ee0SWojciech Macek 		enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port);
1419*3fc36ee0SWojciech Macek 
1420*3fc36ee0SWojciech Macek 		al_bool is_multi_pf =
1421*3fc36ee0SWojciech Macek 			((op_mode == AL_PCIE_OPERATING_MODE_EP) && (pcie_port->max_num_of_pfs > 1));
1422*3fc36ee0SWojciech Macek 
1423*3fc36ee0SWojciech Macek 		/* Set maximum physical function numbers */
1424*3fc36ee0SWojciech Macek 		al_reg_write32_masked(
1425*3fc36ee0SWojciech Macek 			&regs->port_regs->timer_ctrl_max_func_num,
1426*3fc36ee0SWojciech Macek 			PCIE_PORT_GEN3_MAX_FUNC_NUM,
1427*3fc36ee0SWojciech Macek 			pcie_port->max_num_of_pfs - 1);
1428*3fc36ee0SWojciech Macek 
1429*3fc36ee0SWojciech Macek 		al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE);
1430*3fc36ee0SWojciech Macek 
1431*3fc36ee0SWojciech Macek 		/**
1432*3fc36ee0SWojciech Macek 		 * in EP mode, when we have more than 1 PF we need to assert
1433*3fc36ee0SWojciech Macek 		 * multi-pf support so the host scan all PFs
1434*3fc36ee0SWojciech Macek 		 */
1435*3fc36ee0SWojciech Macek 		al_reg_write32_masked((uint32_t __iomem *)
1436*3fc36ee0SWojciech Macek 			(&regs->core_space[0].config_header[0] +
1437*3fc36ee0SWojciech Macek 			(PCIE_BIST_HEADER_TYPE_BASE >> 2)),
1438*3fc36ee0SWojciech Macek 			PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK,
1439*3fc36ee0SWojciech Macek 			is_multi_pf ? PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK : 0);
1440*3fc36ee0SWojciech Macek 
1441*3fc36ee0SWojciech Macek 		al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE);
1442*3fc36ee0SWojciech Macek 	}
1443*3fc36ee0SWojciech Macek 
1444f4b37ed0SZbigniew Bodek 	return 0;
1445f4b37ed0SZbigniew Bodek }
1446f4b37ed0SZbigniew Bodek 
1447f4b37ed0SZbigniew Bodek /* Inbound header credits and outstanding outbound reads configuration */
1448f4b37ed0SZbigniew Bodek int
al_pcie_port_ib_hcrd_os_ob_reads_config(struct al_pcie_port * pcie_port,struct al_pcie_ib_hcrd_os_ob_reads_config * ib_hcrd_os_ob_reads_config)1449f4b37ed0SZbigniew Bodek al_pcie_port_ib_hcrd_os_ob_reads_config(
1450f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
1451f4b37ed0SZbigniew Bodek 	struct al_pcie_ib_hcrd_os_ob_reads_config *ib_hcrd_os_ob_reads_config)
1452f4b37ed0SZbigniew Bodek {
1453f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
1454f4b37ed0SZbigniew Bodek 
1455f4b37ed0SZbigniew Bodek 	if (al_pcie_port_is_enabled(pcie_port)) {
1456f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: already enabled, cannot configure IB credits and OB OS reads\n",
1457f4b37ed0SZbigniew Bodek 			pcie_port->port_id);
1458f4b37ed0SZbigniew Bodek 		return -EINVAL;
1459f4b37ed0SZbigniew Bodek 	}
1460f4b37ed0SZbigniew Bodek 
1461f4b37ed0SZbigniew Bodek 	al_assert(ib_hcrd_os_ob_reads_config->nof_np_hdr > 0);
1462f4b37ed0SZbigniew Bodek 
1463f4b37ed0SZbigniew Bodek 	al_assert(ib_hcrd_os_ob_reads_config->nof_p_hdr > 0);
1464f4b37ed0SZbigniew Bodek 
1465f4b37ed0SZbigniew Bodek 	al_assert(ib_hcrd_os_ob_reads_config->nof_cpl_hdr > 0);
1466f4b37ed0SZbigniew Bodek 
1467f4b37ed0SZbigniew Bodek 	if (pcie_port->rev_id == AL_PCIE_REV_ID_3) {
1468f4b37ed0SZbigniew Bodek 		al_assert(
1469f4b37ed0SZbigniew Bodek 			(ib_hcrd_os_ob_reads_config->nof_cpl_hdr +
1470f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config->nof_np_hdr +
1471f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config->nof_p_hdr) ==
1472f4b37ed0SZbigniew Bodek 			AL_PCIE_REV3_IB_HCRD_SUM);
1473f4b37ed0SZbigniew Bodek 
1474f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(
1475f4b37ed0SZbigniew Bodek 			regs->axi.init_fc.cfg,
1476f4b37ed0SZbigniew Bodek 			PCIE_AXI_REV3_INIT_FC_CFG_NOF_P_HDR_MASK |
1477f4b37ed0SZbigniew Bodek 			PCIE_AXI_REV3_INIT_FC_CFG_NOF_NP_HDR_MASK |
1478f4b37ed0SZbigniew Bodek 			PCIE_AXI_REV3_INIT_FC_CFG_NOF_CPL_HDR_MASK,
1479f4b37ed0SZbigniew Bodek 			(ib_hcrd_os_ob_reads_config->nof_p_hdr <<
1480f4b37ed0SZbigniew Bodek 			 PCIE_AXI_REV3_INIT_FC_CFG_NOF_P_HDR_SHIFT) |
1481f4b37ed0SZbigniew Bodek 			(ib_hcrd_os_ob_reads_config->nof_np_hdr <<
1482f4b37ed0SZbigniew Bodek 			 PCIE_AXI_REV3_INIT_FC_CFG_NOF_NP_HDR_SHIFT) |
1483f4b37ed0SZbigniew Bodek 			(ib_hcrd_os_ob_reads_config->nof_cpl_hdr <<
1484f4b37ed0SZbigniew Bodek 			 PCIE_AXI_REV3_INIT_FC_CFG_NOF_CPL_HDR_SHIFT));
1485f4b37ed0SZbigniew Bodek 	} else {
1486f4b37ed0SZbigniew Bodek 		al_assert(
1487f4b37ed0SZbigniew Bodek 			(ib_hcrd_os_ob_reads_config->nof_cpl_hdr +
1488f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config->nof_np_hdr +
1489f4b37ed0SZbigniew Bodek 			ib_hcrd_os_ob_reads_config->nof_p_hdr) ==
1490f4b37ed0SZbigniew Bodek 			AL_PCIE_REV_1_2_IB_HCRD_SUM);
1491f4b37ed0SZbigniew Bodek 
1492f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(
1493f4b37ed0SZbigniew Bodek 			regs->axi.init_fc.cfg,
1494f4b37ed0SZbigniew Bodek 			PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_P_HDR_MASK |
1495f4b37ed0SZbigniew Bodek 			PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_NP_HDR_MASK |
1496f4b37ed0SZbigniew Bodek 			PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_CPL_HDR_MASK,
1497f4b37ed0SZbigniew Bodek 			(ib_hcrd_os_ob_reads_config->nof_p_hdr <<
1498f4b37ed0SZbigniew Bodek 			 PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_P_HDR_SHIFT) |
1499f4b37ed0SZbigniew Bodek 			(ib_hcrd_os_ob_reads_config->nof_np_hdr <<
1500f4b37ed0SZbigniew Bodek 			 PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_NP_HDR_SHIFT) |
1501f4b37ed0SZbigniew Bodek 			(ib_hcrd_os_ob_reads_config->nof_cpl_hdr <<
1502f4b37ed0SZbigniew Bodek 			 PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_CPL_HDR_SHIFT));
1503f4b37ed0SZbigniew Bodek 	}
1504f4b37ed0SZbigniew Bodek 
1505f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(
1506f4b37ed0SZbigniew Bodek 		regs->axi.pre_configuration.pcie_core_setup,
1507f4b37ed0SZbigniew Bodek 		PCIE_AXI_CORE_SETUP_NOF_READS_ONSLAVE_INTRF_PCIE_CORE_MASK,
1508f4b37ed0SZbigniew Bodek 		ib_hcrd_os_ob_reads_config->nof_outstanding_ob_reads <<
1509f4b37ed0SZbigniew Bodek 		PCIE_AXI_CORE_SETUP_NOF_READS_ONSLAVE_INTRF_PCIE_CORE_SHIFT);
1510f4b37ed0SZbigniew Bodek 
1511f4b37ed0SZbigniew Bodek 	/* Store 'nof_p_hdr' and 'nof_np_hdr' to be set in the core later */
1512f4b37ed0SZbigniew Bodek 	pcie_port->ib_hcrd_config.nof_np_hdr =
1513f4b37ed0SZbigniew Bodek 		ib_hcrd_os_ob_reads_config->nof_np_hdr;
1514f4b37ed0SZbigniew Bodek 	pcie_port->ib_hcrd_config.nof_p_hdr =
1515f4b37ed0SZbigniew Bodek 		ib_hcrd_os_ob_reads_config->nof_p_hdr;
1516f4b37ed0SZbigniew Bodek 
1517f4b37ed0SZbigniew Bodek 	return 0;
1518f4b37ed0SZbigniew Bodek }
1519f4b37ed0SZbigniew Bodek 
1520f4b37ed0SZbigniew Bodek enum al_pcie_operating_mode
al_pcie_operating_mode_get(struct al_pcie_port * pcie_port)1521f4b37ed0SZbigniew Bodek al_pcie_operating_mode_get(
1522f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port)
1523f4b37ed0SZbigniew Bodek {
1524f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
1525f4b37ed0SZbigniew Bodek 	uint32_t reg, device_type;
1526f4b37ed0SZbigniew Bodek 
1527f4b37ed0SZbigniew Bodek 	al_assert(pcie_port);
1528f4b37ed0SZbigniew Bodek 
1529f4b37ed0SZbigniew Bodek 	reg = al_reg_read32(regs->axi.pcie_global.conf);
1530f4b37ed0SZbigniew Bodek 
1531f4b37ed0SZbigniew Bodek 	device_type = AL_REG_FIELD_GET(reg,
1532f4b37ed0SZbigniew Bodek 			PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_MASK,
1533f4b37ed0SZbigniew Bodek 			PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_SHIFT);
1534f4b37ed0SZbigniew Bodek 
1535f4b37ed0SZbigniew Bodek 	switch (device_type) {
1536f4b37ed0SZbigniew Bodek 	case PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_EP:
1537f4b37ed0SZbigniew Bodek 		return AL_PCIE_OPERATING_MODE_EP;
1538f4b37ed0SZbigniew Bodek 	case PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_RC:
1539f4b37ed0SZbigniew Bodek 		return AL_PCIE_OPERATING_MODE_RC;
1540f4b37ed0SZbigniew Bodek 	default:
1541f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: unknown device type (%d) in global conf register.\n",
1542f4b37ed0SZbigniew Bodek 			pcie_port->port_id, device_type);
1543f4b37ed0SZbigniew Bodek 	}
1544f4b37ed0SZbigniew Bodek 	return AL_PCIE_OPERATING_MODE_UNKNOWN;
1545f4b37ed0SZbigniew Bodek }
1546f4b37ed0SZbigniew Bodek 
1547*3fc36ee0SWojciech Macek /* PCIe AXI quality of service configuration */
al_pcie_axi_qos_config(struct al_pcie_port * pcie_port,unsigned int arqos,unsigned int awqos)1548*3fc36ee0SWojciech Macek void al_pcie_axi_qos_config(
1549*3fc36ee0SWojciech Macek 	struct al_pcie_port	*pcie_port,
1550*3fc36ee0SWojciech Macek 	unsigned int		arqos,
1551*3fc36ee0SWojciech Macek 	unsigned int		awqos)
1552*3fc36ee0SWojciech Macek {
1553*3fc36ee0SWojciech Macek 	struct al_pcie_regs *regs = pcie_port->regs;
1554*3fc36ee0SWojciech Macek 
1555*3fc36ee0SWojciech Macek 	al_assert(pcie_port);
1556*3fc36ee0SWojciech Macek 	al_assert(arqos <= PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_VAL_MAX);
1557*3fc36ee0SWojciech Macek 	al_assert(awqos <= PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_VAL_MAX);
1558*3fc36ee0SWojciech Macek 
1559*3fc36ee0SWojciech Macek 	al_reg_write32_masked(
1560*3fc36ee0SWojciech Macek 		regs->axi.ctrl.master_arctl,
1561*3fc36ee0SWojciech Macek 		PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_MASK,
1562*3fc36ee0SWojciech Macek 		arqos << PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_SHIFT);
1563*3fc36ee0SWojciech Macek 	al_reg_write32_masked(
1564*3fc36ee0SWojciech Macek 		regs->axi.ctrl.master_awctl,
1565*3fc36ee0SWojciech Macek 		PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_MASK,
1566*3fc36ee0SWojciech Macek 		awqos << PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_SHIFT);
1567*3fc36ee0SWojciech Macek }
1568*3fc36ee0SWojciech Macek 
1569f4b37ed0SZbigniew Bodek /**************************** PCIe Port Enable API ****************************/
1570f4b37ed0SZbigniew Bodek 
1571f4b37ed0SZbigniew Bodek /** Enable PCIe port (deassert reset) */
1572f4b37ed0SZbigniew Bodek int
al_pcie_port_enable(struct al_pcie_port * pcie_port)1573f4b37ed0SZbigniew Bodek al_pcie_port_enable(struct al_pcie_port *pcie_port)
1574f4b37ed0SZbigniew Bodek {
1575f4b37ed0SZbigniew Bodek 	struct al_pbs_regs *pbs_reg_base =
1576f4b37ed0SZbigniew Bodek 				(struct al_pbs_regs *)pcie_port->pbs_regs;
1577f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
1578f4b37ed0SZbigniew Bodek 	unsigned int port_id = pcie_port->port_id;
1579f4b37ed0SZbigniew Bodek 
1580f4b37ed0SZbigniew Bodek 	/* pre-port-enable default functionality should be here */
1581f4b37ed0SZbigniew Bodek 
1582f4b37ed0SZbigniew Bodek 	/**
1583f4b37ed0SZbigniew Bodek 	 * Set inbound header credit and outstanding outbound reads defaults
1584*3fc36ee0SWojciech Macek 	 * if the port initiator doesn't set it.
1585f4b37ed0SZbigniew Bodek 	 * Must be called before port enable (PCIE_EXIST)
1586f4b37ed0SZbigniew Bodek 	 */
1587*3fc36ee0SWojciech Macek 	if ((pcie_port->ib_hcrd_config.nof_np_hdr == 0) ||
1588*3fc36ee0SWojciech Macek 			(pcie_port->ib_hcrd_config.nof_p_hdr == 0))
1589f4b37ed0SZbigniew Bodek 		al_pcie_ib_hcrd_os_ob_reads_config_default(pcie_port);
1590f4b37ed0SZbigniew Bodek 
1591f4b37ed0SZbigniew Bodek 	/*
1592f4b37ed0SZbigniew Bodek 	 * Disable ATS capability
1593f4b37ed0SZbigniew Bodek 	 * - must be done before core reset deasserted
1594f4b37ed0SZbigniew Bodek 	 * - rev_id 0 - no effect, but no harm
1595f4b37ed0SZbigniew Bodek 	 */
1596*3fc36ee0SWojciech Macek 	if ((pcie_port->rev_id == AL_PCIE_REV_ID_1) ||
1597f4b37ed0SZbigniew Bodek 		(pcie_port->rev_id == AL_PCIE_REV_ID_2)) {
1598f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(
1599f4b37ed0SZbigniew Bodek 			regs->axi.ordering.pos_cntl,
1600f4b37ed0SZbigniew Bodek 			PCIE_AXI_CORE_SETUP_ATS_CAP_DIS,
1601f4b37ed0SZbigniew Bodek 			PCIE_AXI_CORE_SETUP_ATS_CAP_DIS);
1602f4b37ed0SZbigniew Bodek 	}
1603f4b37ed0SZbigniew Bodek 
1604f4b37ed0SZbigniew Bodek 	/* Deassert core reset */
1605f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(
1606f4b37ed0SZbigniew Bodek 		&pbs_reg_base->unit.pcie_conf_1,
1607f4b37ed0SZbigniew Bodek 		1 << (port_id + PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_SHIFT),
1608f4b37ed0SZbigniew Bodek 		1 << (port_id + PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_SHIFT));
1609f4b37ed0SZbigniew Bodek 
1610f4b37ed0SZbigniew Bodek 	return 0;
1611f4b37ed0SZbigniew Bodek }
1612f4b37ed0SZbigniew Bodek 
1613f4b37ed0SZbigniew Bodek /** Disable PCIe port (assert reset) */
1614f4b37ed0SZbigniew Bodek void
al_pcie_port_disable(struct al_pcie_port * pcie_port)1615f4b37ed0SZbigniew Bodek al_pcie_port_disable(struct al_pcie_port *pcie_port)
1616f4b37ed0SZbigniew Bodek {
1617f4b37ed0SZbigniew Bodek 	struct al_pbs_regs *pbs_reg_base =
1618f4b37ed0SZbigniew Bodek 				(struct al_pbs_regs *)pcie_port->pbs_regs;
1619f4b37ed0SZbigniew Bodek 	unsigned int port_id = pcie_port->port_id;
1620f4b37ed0SZbigniew Bodek 
1621f4b37ed0SZbigniew Bodek 	if (!al_pcie_port_is_enabled(pcie_port)) {
1622f4b37ed0SZbigniew Bodek 		al_warn("PCIe %d: trying to disable a non-enabled port\n",
1623f4b37ed0SZbigniew Bodek 			pcie_port->port_id);
1624f4b37ed0SZbigniew Bodek 	}
1625f4b37ed0SZbigniew Bodek 
1626f4b37ed0SZbigniew Bodek 	/* Assert core reset */
1627f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(
1628f4b37ed0SZbigniew Bodek 		&pbs_reg_base->unit.pcie_conf_1,
1629f4b37ed0SZbigniew Bodek 		1 << (port_id + PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_SHIFT),
1630f4b37ed0SZbigniew Bodek 		0);
1631f4b37ed0SZbigniew Bodek }
1632f4b37ed0SZbigniew Bodek 
1633f4b37ed0SZbigniew Bodek int
al_pcie_port_memory_shutdown_set(struct al_pcie_port * pcie_port,al_bool enable)1634f4b37ed0SZbigniew Bodek al_pcie_port_memory_shutdown_set(
1635f4b37ed0SZbigniew Bodek 	struct al_pcie_port	*pcie_port,
1636f4b37ed0SZbigniew Bodek 	al_bool			enable)
1637f4b37ed0SZbigniew Bodek {
1638f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
1639f4b37ed0SZbigniew Bodek 	uint32_t mask = (pcie_port->rev_id == AL_PCIE_REV_ID_3) ?
1640f4b37ed0SZbigniew Bodek 		PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_MEM_SHUTDOWN :
1641f4b37ed0SZbigniew Bodek 		PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_MEM_SHUTDOWN;
1642f4b37ed0SZbigniew Bodek 
1643f4b37ed0SZbigniew Bodek 	if (!al_pcie_port_is_enabled(pcie_port)) {
1644f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: not enabled, cannot shutdown memory\n",
1645f4b37ed0SZbigniew Bodek 			pcie_port->port_id);
1646f4b37ed0SZbigniew Bodek 		return -EINVAL;
1647f4b37ed0SZbigniew Bodek 	}
1648f4b37ed0SZbigniew Bodek 
1649f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(regs->axi.pcie_global.conf,
1650f4b37ed0SZbigniew Bodek 		mask, enable == AL_TRUE ? mask : 0);
1651f4b37ed0SZbigniew Bodek 
1652f4b37ed0SZbigniew Bodek 	return 0;
1653f4b37ed0SZbigniew Bodek }
1654f4b37ed0SZbigniew Bodek 
1655f4b37ed0SZbigniew Bodek al_bool
al_pcie_port_is_enabled(struct al_pcie_port * pcie_port)1656f4b37ed0SZbigniew Bodek al_pcie_port_is_enabled(struct al_pcie_port *pcie_port)
1657f4b37ed0SZbigniew Bodek {
1658f4b37ed0SZbigniew Bodek 	struct al_pbs_regs *pbs_reg_base = (struct al_pbs_regs *)pcie_port->pbs_regs;
1659f4b37ed0SZbigniew Bodek 	uint32_t pcie_exist = al_reg_read32(&pbs_reg_base->unit.pcie_conf_1);
1660f4b37ed0SZbigniew Bodek 
1661f4b37ed0SZbigniew Bodek 	uint32_t ports_enabled = AL_REG_FIELD_GET(pcie_exist,
1662f4b37ed0SZbigniew Bodek 		PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_MASK,
1663f4b37ed0SZbigniew Bodek 		PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_SHIFT);
1664f4b37ed0SZbigniew Bodek 
1665f4b37ed0SZbigniew Bodek 	return (AL_REG_FIELD_GET(ports_enabled, AL_BIT(pcie_port->port_id),
1666f4b37ed0SZbigniew Bodek 		pcie_port->port_id) == 1);
1667f4b37ed0SZbigniew Bodek }
1668f4b37ed0SZbigniew Bodek 
1669f4b37ed0SZbigniew Bodek /*************************** PCIe Configuration API ***************************/
1670f4b37ed0SZbigniew Bodek 
1671f4b37ed0SZbigniew Bodek /** configure pcie port (link params, etc..) */
1672f4b37ed0SZbigniew Bodek int
al_pcie_port_config(struct al_pcie_port * pcie_port,const struct al_pcie_port_config_params * params)1673f4b37ed0SZbigniew Bodek al_pcie_port_config(struct al_pcie_port *pcie_port,
1674f4b37ed0SZbigniew Bodek 			const struct al_pcie_port_config_params *params)
1675f4b37ed0SZbigniew Bodek {
1676f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
1677f4b37ed0SZbigniew Bodek 	enum al_pcie_operating_mode op_mode;
1678f4b37ed0SZbigniew Bodek 	int status = 0;
1679f4b37ed0SZbigniew Bodek 	int i;
1680f4b37ed0SZbigniew Bodek 
1681f4b37ed0SZbigniew Bodek 	if (!al_pcie_port_is_enabled(pcie_port)) {
1682f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: port not enabled, cannot configure port\n",
1683f4b37ed0SZbigniew Bodek 			pcie_port->port_id);
1684f4b37ed0SZbigniew Bodek 		return -EINVAL;
1685f4b37ed0SZbigniew Bodek 	}
1686f4b37ed0SZbigniew Bodek 
1687f4b37ed0SZbigniew Bodek 	if (al_pcie_is_link_started(pcie_port)) {
1688f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: link already started, cannot configure port\n",
1689f4b37ed0SZbigniew Bodek 			pcie_port->port_id);
1690f4b37ed0SZbigniew Bodek 		return -EINVAL;
1691f4b37ed0SZbigniew Bodek 	}
1692f4b37ed0SZbigniew Bodek 
1693f4b37ed0SZbigniew Bodek 	al_assert(pcie_port);
1694f4b37ed0SZbigniew Bodek 	al_assert(params);
1695f4b37ed0SZbigniew Bodek 
1696f4b37ed0SZbigniew Bodek 	al_dbg("PCIe %d: port config\n", pcie_port->port_id);
1697f4b37ed0SZbigniew Bodek 
1698f4b37ed0SZbigniew Bodek 	op_mode = al_pcie_operating_mode_get(pcie_port);
1699f4b37ed0SZbigniew Bodek 
1700f4b37ed0SZbigniew Bodek 	/* if max lanes not specifies, read it from register */
1701f4b37ed0SZbigniew Bodek 	if (pcie_port->max_lanes == 0) {
1702f4b37ed0SZbigniew Bodek 		uint32_t global_conf = al_reg_read32(regs->axi.pcie_global.conf);
1703f4b37ed0SZbigniew Bodek 		uint32_t act_lanes = AL_REG_FIELD_GET(global_conf,
1704f4b37ed0SZbigniew Bodek 			(pcie_port->rev_id == AL_PCIE_REV_ID_3) ?
1705f4b37ed0SZbigniew Bodek 			PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_MASK :
1706f4b37ed0SZbigniew Bodek 			PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_MASK,
1707f4b37ed0SZbigniew Bodek 			PCIE_REVX_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_SHIFT);
1708f4b37ed0SZbigniew Bodek 
1709f4b37ed0SZbigniew Bodek 		switch(act_lanes) {
1710f4b37ed0SZbigniew Bodek 		case 0x1:
1711f4b37ed0SZbigniew Bodek 			pcie_port->max_lanes = 1;
1712f4b37ed0SZbigniew Bodek 			break;
1713f4b37ed0SZbigniew Bodek 		case 0x3:
1714f4b37ed0SZbigniew Bodek 			pcie_port->max_lanes = 2;
1715f4b37ed0SZbigniew Bodek 			break;
1716f4b37ed0SZbigniew Bodek 		case 0xf:
1717f4b37ed0SZbigniew Bodek 			pcie_port->max_lanes = 4;
1718f4b37ed0SZbigniew Bodek 			break;
1719f4b37ed0SZbigniew Bodek 		case 0xff:
1720f4b37ed0SZbigniew Bodek 			pcie_port->max_lanes = 8;
1721f4b37ed0SZbigniew Bodek 			break;
1722f4b37ed0SZbigniew Bodek 		default:
1723f4b37ed0SZbigniew Bodek 			pcie_port->max_lanes = 0;
1724f4b37ed0SZbigniew Bodek 			al_err("PCIe %d: invalid max lanes val (0x%x)\n", pcie_port->port_id, act_lanes);
1725f4b37ed0SZbigniew Bodek 			break;
1726f4b37ed0SZbigniew Bodek 		}
1727f4b37ed0SZbigniew Bodek 	}
1728f4b37ed0SZbigniew Bodek 
1729f4b37ed0SZbigniew Bodek 	if (params->link_params)
1730f4b37ed0SZbigniew Bodek 		status = al_pcie_port_link_config(pcie_port, params->link_params);
1731f4b37ed0SZbigniew Bodek 	if (status)
1732f4b37ed0SZbigniew Bodek 		goto done;
1733f4b37ed0SZbigniew Bodek 
1734f4b37ed0SZbigniew Bodek 	/* Change max read request size to 256 bytes
1735f4b37ed0SZbigniew Bodek 	 * Max Payload Size is remained untouched- it is the responsibility of
1736f4b37ed0SZbigniew Bodek 	 * the host to change the MPS, if needed.
1737f4b37ed0SZbigniew Bodek 	 */
1738f4b37ed0SZbigniew Bodek 	for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) {
1739f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(regs->core_space[i].pcie_dev_ctrl_status,
1740f4b37ed0SZbigniew Bodek 			PCIE_PORT_DEV_CTRL_STATUS_MRRS_MASK,
1741f4b37ed0SZbigniew Bodek 			PCIE_PORT_DEV_CTRL_STATUS_MRRS_VAL_256);
1742f4b37ed0SZbigniew Bodek 		if (pcie_port->rev_id != AL_PCIE_REV_ID_3)
1743f4b37ed0SZbigniew Bodek 			break;
1744f4b37ed0SZbigniew Bodek 	}
1745f4b37ed0SZbigniew Bodek 
1746f4b37ed0SZbigniew Bodek 	if (pcie_port->rev_id == AL_PCIE_REV_ID_3) {
1747f4b37ed0SZbigniew Bodek 		al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE);
1748f4b37ed0SZbigniew Bodek 
1749f4b37ed0SZbigniew Bodek 		/* Disable TPH next pointer */
1750f4b37ed0SZbigniew Bodek 		for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) {
1751f4b37ed0SZbigniew Bodek 			al_reg_write32_masked(regs->core_space[i].tph_cap_base,
1752f4b37ed0SZbigniew Bodek 			PCIE_TPH_NEXT_POINTER, 0);
1753f4b37ed0SZbigniew Bodek 		}
1754f4b37ed0SZbigniew Bodek 
1755f4b37ed0SZbigniew Bodek 		al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE);
1756f4b37ed0SZbigniew Bodek 	}
1757f4b37ed0SZbigniew Bodek 
1758f4b37ed0SZbigniew Bodek 
1759f4b37ed0SZbigniew Bodek 	status = al_pcie_port_snoop_config(pcie_port, params->enable_axi_snoop);
1760f4b37ed0SZbigniew Bodek 	if (status)
1761f4b37ed0SZbigniew Bodek 		goto done;
1762f4b37ed0SZbigniew Bodek 
1763*3fc36ee0SWojciech Macek 	al_pcie_port_max_num_of_pfs_set(pcie_port, pcie_port->max_num_of_pfs);
1764*3fc36ee0SWojciech Macek 
1765f4b37ed0SZbigniew Bodek 	al_pcie_port_ram_parity_int_config(pcie_port, params->enable_ram_parity_int);
1766f4b37ed0SZbigniew Bodek 
1767f4b37ed0SZbigniew Bodek 	al_pcie_port_axi_parity_int_config(pcie_port, params->enable_axi_parity_int);
1768f4b37ed0SZbigniew Bodek 
1769f4b37ed0SZbigniew Bodek 	al_pcie_port_relaxed_pcie_ordering_config(pcie_port, params->relaxed_ordering_params);
1770f4b37ed0SZbigniew Bodek 
1771f4b37ed0SZbigniew Bodek 	if (params->lat_rply_timers)
1772f4b37ed0SZbigniew Bodek 		status = al_pcie_port_lat_rply_timers_config(pcie_port, params->lat_rply_timers);
1773f4b37ed0SZbigniew Bodek 	if (status)
1774f4b37ed0SZbigniew Bodek 		goto done;
1775f4b37ed0SZbigniew Bodek 
1776f4b37ed0SZbigniew Bodek 	if (params->gen2_params)
1777f4b37ed0SZbigniew Bodek 		status = al_pcie_port_gen2_params_config(pcie_port, params->gen2_params);
1778f4b37ed0SZbigniew Bodek 	if (status)
1779f4b37ed0SZbigniew Bodek 		goto done;
1780f4b37ed0SZbigniew Bodek 
1781f4b37ed0SZbigniew Bodek 	if (params->gen3_params)
1782f4b37ed0SZbigniew Bodek 		status = al_pcie_port_gen3_params_config(pcie_port, params->gen3_params);
1783f4b37ed0SZbigniew Bodek 	if (status)
1784f4b37ed0SZbigniew Bodek 		goto done;
1785f4b37ed0SZbigniew Bodek 
1786f4b37ed0SZbigniew Bodek 	if (params->sris_params)
1787f4b37ed0SZbigniew Bodek 		status = al_pcie_port_sris_config(pcie_port, params->sris_params,
1788f4b37ed0SZbigniew Bodek 						params->link_params->max_speed);
1789f4b37ed0SZbigniew Bodek 	if (status)
1790f4b37ed0SZbigniew Bodek 		goto done;
1791f4b37ed0SZbigniew Bodek 
1792f4b37ed0SZbigniew Bodek 	al_pcie_port_ib_hcrd_config(pcie_port);
1793f4b37ed0SZbigniew Bodek 
1794f4b37ed0SZbigniew Bodek 	if (params->fast_link_mode) {
1795f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(&regs->port_regs->port_link_ctrl,
1796f4b37ed0SZbigniew Bodek 			      1 << PCIE_PORT_LINK_CTRL_FAST_LINK_EN_SHIFT,
1797f4b37ed0SZbigniew Bodek 			      1 << PCIE_PORT_LINK_CTRL_FAST_LINK_EN_SHIFT);
1798f4b37ed0SZbigniew Bodek 	}
1799f4b37ed0SZbigniew Bodek 
1800f4b37ed0SZbigniew Bodek 	if (params->enable_axi_slave_err_resp)
1801f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(&regs->port_regs->axi_slave_err_resp,
1802f4b37ed0SZbigniew Bodek 				1 << PCIE_PORT_AXI_SLAVE_ERR_RESP_ALL_MAPPING_SHIFT,
1803f4b37ed0SZbigniew Bodek 				1 << PCIE_PORT_AXI_SLAVE_ERR_RESP_ALL_MAPPING_SHIFT);
1804f4b37ed0SZbigniew Bodek 
1805f4b37ed0SZbigniew Bodek 	/**
1806f4b37ed0SZbigniew Bodek 	 * Addressing RMN: 5477
1807f4b37ed0SZbigniew Bodek 	 *
1808f4b37ed0SZbigniew Bodek 	 * RMN description:
1809f4b37ed0SZbigniew Bodek 	 * address-decoder logic performs sub-target decoding even for transactions
1810f4b37ed0SZbigniew Bodek 	 * which undergo target enforcement. thus, in case transaction's address is
1811f4b37ed0SZbigniew Bodek 	 * inside any ECAM bar, the sub-target decoding will be set to ECAM, which
1812f4b37ed0SZbigniew Bodek 	 * causes wrong handling by PCIe unit
1813f4b37ed0SZbigniew Bodek 	 *
1814f4b37ed0SZbigniew Bodek 	 * Software flow:
1815f4b37ed0SZbigniew Bodek 	 * on EP mode only, turning on the iATU-enable bit (with the relevant mask
1816f4b37ed0SZbigniew Bodek 	 * below) allows the PCIe unit to discard the ECAM bit which was asserted
1817f4b37ed0SZbigniew Bodek 	 * by-mistake in the address-decoder
1818f4b37ed0SZbigniew Bodek 	 */
1819f4b37ed0SZbigniew Bodek 	if (op_mode == AL_PCIE_OPERATING_MODE_EP) {
1820f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(regs->axi.ob_ctrl.cfg_target_bus,
1821f4b37ed0SZbigniew Bodek 			PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK,
1822f4b37ed0SZbigniew Bodek 			(0) << PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_SHIFT);
1823f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(regs->axi.ob_ctrl.cfg_control,
1824f4b37ed0SZbigniew Bodek 			PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_IATU_EN,
1825f4b37ed0SZbigniew Bodek 			PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_IATU_EN);
1826f4b37ed0SZbigniew Bodek 	}
1827f4b37ed0SZbigniew Bodek 
1828f4b37ed0SZbigniew Bodek 	if (op_mode == AL_PCIE_OPERATING_MODE_RC) {
1829f4b37ed0SZbigniew Bodek 		/**
1830f4b37ed0SZbigniew Bodek 		 * enable memory and I/O access from port when in RC mode
1831f4b37ed0SZbigniew Bodek 		 * in RC mode, only core_space[0] is valid.
1832f4b37ed0SZbigniew Bodek 		 */
1833f4b37ed0SZbigniew Bodek 		al_reg_write16_masked(
1834f4b37ed0SZbigniew Bodek 			(uint16_t __iomem *)(&regs->core_space[0].config_header[0] + (0x4 >> 2)),
1835f4b37ed0SZbigniew Bodek 			0x7, /* Mem, MSE, IO */
1836f4b37ed0SZbigniew Bodek 			0x7);
1837f4b37ed0SZbigniew Bodek 
1838f4b37ed0SZbigniew Bodek 		/* change the class code to match pci bridge */
1839f4b37ed0SZbigniew Bodek 		al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE);
1840f4b37ed0SZbigniew Bodek 
1841f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(
1842f4b37ed0SZbigniew Bodek 			(uint32_t __iomem *)(&regs->core_space[0].config_header[0]
1843f4b37ed0SZbigniew Bodek 			+ (PCI_CLASS_REVISION >> 2)),
1844f4b37ed0SZbigniew Bodek 			0xFFFFFF00,
1845f4b37ed0SZbigniew Bodek 			0x06040000);
1846f4b37ed0SZbigniew Bodek 
1847f4b37ed0SZbigniew Bodek 		al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE);
1848f4b37ed0SZbigniew Bodek 
1849f4b37ed0SZbigniew Bodek 		/**
1850f4b37ed0SZbigniew Bodek 		 * Addressing RMN: 5702
1851f4b37ed0SZbigniew Bodek 		 *
1852f4b37ed0SZbigniew Bodek 		 * RMN description:
1853f4b37ed0SZbigniew Bodek 		 * target bus mask default value in HW is: 0xFE, this enforces
1854f4b37ed0SZbigniew Bodek 		 * setting the target bus for ports 1 and 3 when running on RC
1855f4b37ed0SZbigniew Bodek 		 * mode since bit[20] in ECAM address in these cases is set
1856f4b37ed0SZbigniew Bodek 		 *
1857f4b37ed0SZbigniew Bodek 		 * Software flow:
1858f4b37ed0SZbigniew Bodek 		 * on RC mode only, set target-bus value to 0xFF to prevent this
1859f4b37ed0SZbigniew Bodek 		 * enforcement
1860f4b37ed0SZbigniew Bodek 		 */
1861f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(regs->axi.ob_ctrl.cfg_target_bus,
1862f4b37ed0SZbigniew Bodek 			PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK,
1863f4b37ed0SZbigniew Bodek 			PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK);
1864f4b37ed0SZbigniew Bodek 	}
1865f4b37ed0SZbigniew Bodek done:
1866f4b37ed0SZbigniew Bodek 	al_dbg("PCIe %d: port config %s\n", pcie_port->port_id, status? "failed": "done");
1867f4b37ed0SZbigniew Bodek 
1868f4b37ed0SZbigniew Bodek 	return status;
1869f4b37ed0SZbigniew Bodek }
1870f4b37ed0SZbigniew Bodek 
1871f4b37ed0SZbigniew Bodek int
al_pcie_pf_config(struct al_pcie_pf * pcie_pf,const struct al_pcie_pf_config_params * params)1872f4b37ed0SZbigniew Bodek al_pcie_pf_config(
1873f4b37ed0SZbigniew Bodek 	struct al_pcie_pf *pcie_pf,
1874f4b37ed0SZbigniew Bodek 	const struct al_pcie_pf_config_params *params)
1875f4b37ed0SZbigniew Bodek {
1876f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port;
1877f4b37ed0SZbigniew Bodek 	int status = 0;
1878f4b37ed0SZbigniew Bodek 
1879f4b37ed0SZbigniew Bodek 	al_assert(pcie_pf);
1880f4b37ed0SZbigniew Bodek 	al_assert(params);
1881f4b37ed0SZbigniew Bodek 
1882f4b37ed0SZbigniew Bodek 	pcie_port = pcie_pf->pcie_port;
1883f4b37ed0SZbigniew Bodek 
1884f4b37ed0SZbigniew Bodek 	if (!al_pcie_port_is_enabled(pcie_port)) {
1885f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: port not enabled, cannot configure port\n", pcie_port->port_id);
1886f4b37ed0SZbigniew Bodek 		return -EINVAL;
1887f4b37ed0SZbigniew Bodek 	}
1888f4b37ed0SZbigniew Bodek 
1889f4b37ed0SZbigniew Bodek 	al_dbg("PCIe %d: pf %d config\n", pcie_port->port_id, pcie_pf->pf_num);
1890f4b37ed0SZbigniew Bodek 
1891f4b37ed0SZbigniew Bodek 	if (params)
1892f4b37ed0SZbigniew Bodek 		status = al_pcie_port_pf_params_config(pcie_pf, params);
1893f4b37ed0SZbigniew Bodek 	if (status)
1894f4b37ed0SZbigniew Bodek 		goto done;
1895f4b37ed0SZbigniew Bodek 
1896f4b37ed0SZbigniew Bodek done:
1897f4b37ed0SZbigniew Bodek 	al_dbg("PCIe %d: pf %d config %s\n",
1898f4b37ed0SZbigniew Bodek 		pcie_port->port_id, pcie_pf->pf_num, status ? "failed" : "done");
1899f4b37ed0SZbigniew Bodek 
1900f4b37ed0SZbigniew Bodek 	return status;
1901f4b37ed0SZbigniew Bodek }
1902f4b37ed0SZbigniew Bodek 
1903f4b37ed0SZbigniew Bodek /************************** PCIe Link Operations API **************************/
1904f4b37ed0SZbigniew Bodek 
1905f4b37ed0SZbigniew Bodek /* start pcie link */
1906f4b37ed0SZbigniew Bodek int
al_pcie_link_start(struct al_pcie_port * pcie_port)1907f4b37ed0SZbigniew Bodek al_pcie_link_start(struct al_pcie_port *pcie_port)
1908f4b37ed0SZbigniew Bodek {
1909f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs;
1910f4b37ed0SZbigniew Bodek 
1911f4b37ed0SZbigniew Bodek 	if (!al_pcie_port_is_enabled(pcie_port)) {
1912f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: port not enabled, cannot start link\n",
1913f4b37ed0SZbigniew Bodek 			pcie_port->port_id);
1914f4b37ed0SZbigniew Bodek 		return -EINVAL;
1915f4b37ed0SZbigniew Bodek 	}
1916f4b37ed0SZbigniew Bodek 
1917f4b37ed0SZbigniew Bodek 	al_dbg("PCIe_%d: start port link.\n", pcie_port->port_id);
1918f4b37ed0SZbigniew Bodek 
1919f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(
1920f4b37ed0SZbigniew Bodek 			regs->app.global_ctrl.port_init,
1921f4b37ed0SZbigniew Bodek 			PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK,
1922f4b37ed0SZbigniew Bodek 			PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK);
1923f4b37ed0SZbigniew Bodek 
1924f4b37ed0SZbigniew Bodek 	return 0;
1925f4b37ed0SZbigniew Bodek }
1926f4b37ed0SZbigniew Bodek 
1927f4b37ed0SZbigniew Bodek /* stop pcie link */
1928f4b37ed0SZbigniew Bodek int
al_pcie_link_stop(struct al_pcie_port * pcie_port)1929f4b37ed0SZbigniew Bodek al_pcie_link_stop(struct al_pcie_port *pcie_port)
1930f4b37ed0SZbigniew Bodek {
1931f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs;
1932f4b37ed0SZbigniew Bodek 
1933f4b37ed0SZbigniew Bodek 	if (!al_pcie_is_link_started(pcie_port)) {
1934f4b37ed0SZbigniew Bodek 		al_warn("PCIe %d: trying to stop a non-started link\n",
1935f4b37ed0SZbigniew Bodek 			pcie_port->port_id);
1936f4b37ed0SZbigniew Bodek 	}
1937f4b37ed0SZbigniew Bodek 
1938f4b37ed0SZbigniew Bodek 	al_dbg("PCIe_%d: stop port link.\n", pcie_port->port_id);
1939f4b37ed0SZbigniew Bodek 
1940f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(
1941f4b37ed0SZbigniew Bodek 			regs->app.global_ctrl.port_init,
1942f4b37ed0SZbigniew Bodek 			PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK,
1943f4b37ed0SZbigniew Bodek 			~PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK);
1944f4b37ed0SZbigniew Bodek 
1945f4b37ed0SZbigniew Bodek 	return 0;
1946f4b37ed0SZbigniew Bodek }
1947f4b37ed0SZbigniew Bodek 
1948*3fc36ee0SWojciech Macek /** return AL_TRUE is link started (LTSSM enabled) and AL_FALSE otherwise */
al_pcie_is_link_started(struct al_pcie_port * pcie_port)1949*3fc36ee0SWojciech Macek al_bool al_pcie_is_link_started(struct al_pcie_port *pcie_port)
1950*3fc36ee0SWojciech Macek {
1951*3fc36ee0SWojciech Macek 	struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs;
1952*3fc36ee0SWojciech Macek 
1953*3fc36ee0SWojciech Macek 	uint32_t port_init = al_reg_read32(regs->app.global_ctrl.port_init);
1954*3fc36ee0SWojciech Macek 	uint8_t ltssm_en = AL_REG_FIELD_GET(port_init,
1955*3fc36ee0SWojciech Macek 		PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK,
1956*3fc36ee0SWojciech Macek 		PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_SHIFT);
1957*3fc36ee0SWojciech Macek 
1958*3fc36ee0SWojciech Macek 	return ltssm_en;
1959*3fc36ee0SWojciech Macek }
1960*3fc36ee0SWojciech Macek 
1961f4b37ed0SZbigniew Bodek /* wait for link up indication */
1962f4b37ed0SZbigniew Bodek int
al_pcie_link_up_wait(struct al_pcie_port * pcie_port,uint32_t timeout_ms)1963f4b37ed0SZbigniew Bodek al_pcie_link_up_wait(struct al_pcie_port *pcie_port, uint32_t timeout_ms)
1964f4b37ed0SZbigniew Bodek {
1965f4b37ed0SZbigniew Bodek 	int wait_count = timeout_ms * AL_PCIE_LINKUP_WAIT_INTERVALS_PER_SEC;
1966f4b37ed0SZbigniew Bodek 
1967f4b37ed0SZbigniew Bodek 	while (wait_count-- > 0)	{
1968f4b37ed0SZbigniew Bodek 		if (al_pcie_check_link(pcie_port, NULL)) {
1969*3fc36ee0SWojciech Macek 			al_dbg("PCIe_%d: <<<<<<<<< Link up >>>>>>>>>\n", pcie_port->port_id);
1970f4b37ed0SZbigniew Bodek 			return 0;
1971f4b37ed0SZbigniew Bodek 		} else
1972f4b37ed0SZbigniew Bodek 			al_dbg("PCIe_%d: No link up, %d attempts remaining\n",
1973f4b37ed0SZbigniew Bodek 				pcie_port->port_id, wait_count);
1974f4b37ed0SZbigniew Bodek 
1975f4b37ed0SZbigniew Bodek 		al_udelay(AL_PCIE_LINKUP_WAIT_INTERVAL);
1976f4b37ed0SZbigniew Bodek 	}
1977*3fc36ee0SWojciech Macek 	al_dbg("PCIE_%d: link is not established in time\n",
1978f4b37ed0SZbigniew Bodek 				pcie_port->port_id);
1979f4b37ed0SZbigniew Bodek 
1980f4b37ed0SZbigniew Bodek 	return ETIMEDOUT;
1981f4b37ed0SZbigniew Bodek }
1982f4b37ed0SZbigniew Bodek 
1983f4b37ed0SZbigniew Bodek /** get link status */
1984f4b37ed0SZbigniew Bodek int
al_pcie_link_status(struct al_pcie_port * pcie_port,struct al_pcie_link_status * status)1985f4b37ed0SZbigniew Bodek al_pcie_link_status(struct al_pcie_port *pcie_port,
1986f4b37ed0SZbigniew Bodek 			struct al_pcie_link_status *status)
1987f4b37ed0SZbigniew Bodek {
1988f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
1989f4b37ed0SZbigniew Bodek 	uint16_t	pcie_lnksta;
1990f4b37ed0SZbigniew Bodek 
1991f4b37ed0SZbigniew Bodek 	al_assert(status);
1992f4b37ed0SZbigniew Bodek 
1993*3fc36ee0SWojciech Macek 	if (!al_pcie_port_is_enabled(pcie_port)) {
1994*3fc36ee0SWojciech Macek 		al_dbg("PCIe %d: port not enabled, no link.\n", pcie_port->port_id);
1995*3fc36ee0SWojciech Macek 		status->link_up = AL_FALSE;
1996*3fc36ee0SWojciech Macek 		status->speed = AL_PCIE_LINK_SPEED_DEFAULT;
1997*3fc36ee0SWojciech Macek 		status->lanes = 0;
1998*3fc36ee0SWojciech Macek 		status->ltssm_state = 0;
1999*3fc36ee0SWojciech Macek 		return 0;
2000*3fc36ee0SWojciech Macek 	}
2001*3fc36ee0SWojciech Macek 
2002f4b37ed0SZbigniew Bodek 	status->link_up = al_pcie_check_link(pcie_port, &status->ltssm_state);
2003f4b37ed0SZbigniew Bodek 
2004f4b37ed0SZbigniew Bodek 	if (!status->link_up) {
2005f4b37ed0SZbigniew Bodek 		status->speed = AL_PCIE_LINK_SPEED_DEFAULT;
2006f4b37ed0SZbigniew Bodek 		status->lanes = 0;
2007f4b37ed0SZbigniew Bodek 		return 0;
2008f4b37ed0SZbigniew Bodek 	}
2009f4b37ed0SZbigniew Bodek 
2010f4b37ed0SZbigniew Bodek 	pcie_lnksta = al_reg_read16((uint16_t __iomem *)regs->core_space[0].pcie_cap_base + (AL_PCI_EXP_LNKSTA >> 1));
2011f4b37ed0SZbigniew Bodek 
2012f4b37ed0SZbigniew Bodek 	switch(pcie_lnksta & AL_PCI_EXP_LNKSTA_CLS) {
2013f4b37ed0SZbigniew Bodek 		case AL_PCI_EXP_LNKSTA_CLS_2_5GB:
2014f4b37ed0SZbigniew Bodek 			status->speed = AL_PCIE_LINK_SPEED_GEN1;
2015f4b37ed0SZbigniew Bodek 			break;
2016f4b37ed0SZbigniew Bodek 		case AL_PCI_EXP_LNKSTA_CLS_5_0GB:
2017f4b37ed0SZbigniew Bodek 			status->speed = AL_PCIE_LINK_SPEED_GEN2;
2018f4b37ed0SZbigniew Bodek 			break;
2019f4b37ed0SZbigniew Bodek 		case AL_PCI_EXP_LNKSTA_CLS_8_0GB:
2020f4b37ed0SZbigniew Bodek 			status->speed = AL_PCIE_LINK_SPEED_GEN3;
2021f4b37ed0SZbigniew Bodek 			break;
2022f4b37ed0SZbigniew Bodek 		default:
2023f4b37ed0SZbigniew Bodek 			status->speed = AL_PCIE_LINK_SPEED_DEFAULT;
2024f4b37ed0SZbigniew Bodek 			al_err("PCIe %d: unknown link speed indication. PCIE LINK STATUS %x\n",
2025f4b37ed0SZbigniew Bodek 				pcie_port->port_id, pcie_lnksta);
2026f4b37ed0SZbigniew Bodek 	}
2027f4b37ed0SZbigniew Bodek 	status->lanes = (pcie_lnksta & AL_PCI_EXP_LNKSTA_NLW) >> AL_PCI_EXP_LNKSTA_NLW_SHIFT;
2028*3fc36ee0SWojciech Macek 	al_dbg("PCIe %d: Link up. speed gen%d negotiated width %d\n",
2029f4b37ed0SZbigniew Bodek 		pcie_port->port_id, status->speed, status->lanes);
2030f4b37ed0SZbigniew Bodek 
2031f4b37ed0SZbigniew Bodek 	return 0;
2032f4b37ed0SZbigniew Bodek }
2033f4b37ed0SZbigniew Bodek 
2034f4b37ed0SZbigniew Bodek /** get lane status */
2035f4b37ed0SZbigniew Bodek void
al_pcie_lane_status_get(struct al_pcie_port * pcie_port,unsigned int lane,struct al_pcie_lane_status * status)2036f4b37ed0SZbigniew Bodek al_pcie_lane_status_get(
2037f4b37ed0SZbigniew Bodek 	struct al_pcie_port		*pcie_port,
2038f4b37ed0SZbigniew Bodek 	unsigned int			lane,
2039f4b37ed0SZbigniew Bodek 	struct al_pcie_lane_status	*status)
2040f4b37ed0SZbigniew Bodek {
2041f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
2042f4b37ed0SZbigniew Bodek 	uint32_t lane_status;
2043f4b37ed0SZbigniew Bodek 	uint32_t *reg_ptr;
2044f4b37ed0SZbigniew Bodek 
2045f4b37ed0SZbigniew Bodek 	al_assert(pcie_port);
2046f4b37ed0SZbigniew Bodek 	al_assert(status);
2047f4b37ed0SZbigniew Bodek 	al_assert((pcie_port->rev_id != AL_PCIE_REV_ID_1) || (lane < REV1_2_MAX_NUM_LANES));
2048f4b37ed0SZbigniew Bodek 	al_assert((pcie_port->rev_id != AL_PCIE_REV_ID_2) || (lane < REV1_2_MAX_NUM_LANES));
2049f4b37ed0SZbigniew Bodek 	al_assert((pcie_port->rev_id != AL_PCIE_REV_ID_3) || (lane < REV3_MAX_NUM_LANES));
2050f4b37ed0SZbigniew Bodek 
2051f4b37ed0SZbigniew Bodek 	reg_ptr = regs->axi.status.lane[lane];
2052f4b37ed0SZbigniew Bodek 
2053f4b37ed0SZbigniew Bodek 	/* Reset field is valid only when same value is read twice */
2054f4b37ed0SZbigniew Bodek 	do {
2055f4b37ed0SZbigniew Bodek 		lane_status = al_reg_read32(reg_ptr);
2056f4b37ed0SZbigniew Bodek 		status->is_reset = !!(lane_status & PCIE_AXI_STATUS_LANE_IS_RESET);
2057f4b37ed0SZbigniew Bodek 	} while (status->is_reset != (!!(al_reg_read32(reg_ptr) & PCIE_AXI_STATUS_LANE_IS_RESET)));
2058f4b37ed0SZbigniew Bodek 
2059f4b37ed0SZbigniew Bodek 	status->requested_speed =
2060f4b37ed0SZbigniew Bodek 		(lane_status & PCIE_AXI_STATUS_LANE_REQUESTED_SPEED_MASK) >>
2061f4b37ed0SZbigniew Bodek 		PCIE_AXI_STATUS_LANE_REQUESTED_SPEED_SHIFT;
2062f4b37ed0SZbigniew Bodek }
2063f4b37ed0SZbigniew Bodek 
2064f4b37ed0SZbigniew Bodek /** trigger hot reset */
2065f4b37ed0SZbigniew Bodek int
al_pcie_link_hot_reset(struct al_pcie_port * pcie_port,al_bool enable)2066f4b37ed0SZbigniew Bodek al_pcie_link_hot_reset(struct al_pcie_port *pcie_port, al_bool enable)
2067f4b37ed0SZbigniew Bodek {
2068f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
2069f4b37ed0SZbigniew Bodek 	uint32_t events_gen;
2070f4b37ed0SZbigniew Bodek 	al_bool app_reset_state;
2071f4b37ed0SZbigniew Bodek 	enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port);
2072f4b37ed0SZbigniew Bodek 
2073f4b37ed0SZbigniew Bodek 	if (op_mode != AL_PCIE_OPERATING_MODE_RC) {
2074f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: hot-reset is applicable only for RC mode\n", pcie_port->port_id);
2075f4b37ed0SZbigniew Bodek 		return -EINVAL;
2076f4b37ed0SZbigniew Bodek 	}
2077f4b37ed0SZbigniew Bodek 
2078f4b37ed0SZbigniew Bodek 	if (!al_pcie_is_link_started(pcie_port)) {
2079f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: link not started, cannot trigger hot-reset\n", pcie_port->port_id);
2080f4b37ed0SZbigniew Bodek 		return -EINVAL;
2081f4b37ed0SZbigniew Bodek 	}
2082f4b37ed0SZbigniew Bodek 
2083f4b37ed0SZbigniew Bodek 	events_gen = al_reg_read32(regs->app.global_ctrl.events_gen[0]);
2084f4b37ed0SZbigniew Bodek 	app_reset_state = events_gen & PCIE_W_GLOBAL_CTRL_EVENTS_GEN_APP_RST_INIT;
2085f4b37ed0SZbigniew Bodek 
2086f4b37ed0SZbigniew Bodek 	if (enable && app_reset_state) {
2087f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: link is already in hot-reset state\n", pcie_port->port_id);
2088f4b37ed0SZbigniew Bodek 		return -EINVAL;
2089f4b37ed0SZbigniew Bodek 	} else if ((!enable) && (!(app_reset_state))) {
2090f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: link is already in non-hot-reset state\n", pcie_port->port_id);
2091f4b37ed0SZbigniew Bodek 		return -EINVAL;
2092f4b37ed0SZbigniew Bodek 	} else {
2093f4b37ed0SZbigniew Bodek 		al_dbg("PCIe %d: %s hot-reset\n", pcie_port->port_id,
2094f4b37ed0SZbigniew Bodek 			(enable ? "enabling" : "disabling"));
2095f4b37ed0SZbigniew Bodek 		/* hot-reset functionality is implemented only for function 0 */
2096f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(regs->app.global_ctrl.events_gen[0],
2097f4b37ed0SZbigniew Bodek 			PCIE_W_GLOBAL_CTRL_EVENTS_GEN_APP_RST_INIT,
2098f4b37ed0SZbigniew Bodek 			(enable ? PCIE_W_GLOBAL_CTRL_EVENTS_GEN_APP_RST_INIT
2099f4b37ed0SZbigniew Bodek 				: ~PCIE_W_GLOBAL_CTRL_EVENTS_GEN_APP_RST_INIT));
2100f4b37ed0SZbigniew Bodek 		return 0;
2101f4b37ed0SZbigniew Bodek 	}
2102f4b37ed0SZbigniew Bodek }
2103f4b37ed0SZbigniew Bodek 
2104f4b37ed0SZbigniew Bodek /** disable port link */
2105f4b37ed0SZbigniew Bodek int
al_pcie_link_disable(struct al_pcie_port * pcie_port,al_bool disable)2106f4b37ed0SZbigniew Bodek al_pcie_link_disable(struct al_pcie_port *pcie_port, al_bool disable)
2107f4b37ed0SZbigniew Bodek {
2108f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
2109f4b37ed0SZbigniew Bodek 	uint32_t pcie_lnkctl;
2110f4b37ed0SZbigniew Bodek 	al_bool link_disable_state;
2111f4b37ed0SZbigniew Bodek 	enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port);
2112f4b37ed0SZbigniew Bodek 
2113f4b37ed0SZbigniew Bodek 	if (op_mode != AL_PCIE_OPERATING_MODE_RC) {
2114f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: hot-reset is applicable only for RC mode\n", pcie_port->port_id);
2115f4b37ed0SZbigniew Bodek 		return -EINVAL;
2116f4b37ed0SZbigniew Bodek 	}
2117f4b37ed0SZbigniew Bodek 
2118f4b37ed0SZbigniew Bodek 	if (!al_pcie_is_link_started(pcie_port)) {
2119f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: link not started, cannot disable link\n", pcie_port->port_id);
2120f4b37ed0SZbigniew Bodek 		return -EINVAL;
2121f4b37ed0SZbigniew Bodek 	}
2122f4b37ed0SZbigniew Bodek 
2123f4b37ed0SZbigniew Bodek 	pcie_lnkctl = al_reg_read32(regs->core_space[0].pcie_cap_base + (AL_PCI_EXP_LNKCTL >> 1));
2124f4b37ed0SZbigniew Bodek 	link_disable_state = pcie_lnkctl & AL_PCI_EXP_LNKCTL_LNK_DIS;
2125f4b37ed0SZbigniew Bodek 
2126f4b37ed0SZbigniew Bodek 	if (disable && link_disable_state) {
2127f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: link is already in disable state\n", pcie_port->port_id);
2128f4b37ed0SZbigniew Bodek 		return -EINVAL;
2129f4b37ed0SZbigniew Bodek 	} else if ((!disable) && (!(link_disable_state))) {
2130f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: link is already in enable state\n", pcie_port->port_id);
2131f4b37ed0SZbigniew Bodek 		return -EINVAL;
2132f4b37ed0SZbigniew Bodek 	}
2133f4b37ed0SZbigniew Bodek 
2134f4b37ed0SZbigniew Bodek 	al_dbg("PCIe %d: %s port\n", pcie_port->port_id, (disable ? "disabling" : "enabling"));
2135f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(regs->core_space[0].pcie_cap_base + (AL_PCI_EXP_LNKCTL >> 1),
2136f4b37ed0SZbigniew Bodek 		AL_PCI_EXP_LNKCTL_LNK_DIS,
2137f4b37ed0SZbigniew Bodek 		(disable ? AL_PCI_EXP_LNKCTL_LNK_DIS : ~AL_PCI_EXP_LNKCTL_LNK_DIS));
2138f4b37ed0SZbigniew Bodek 	return 0;
2139f4b37ed0SZbigniew Bodek }
2140f4b37ed0SZbigniew Bodek 
2141f4b37ed0SZbigniew Bodek /** retrain link */
2142f4b37ed0SZbigniew Bodek int
al_pcie_link_retrain(struct al_pcie_port * pcie_port)2143f4b37ed0SZbigniew Bodek al_pcie_link_retrain(struct al_pcie_port *pcie_port)
2144f4b37ed0SZbigniew Bodek {
2145f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
2146f4b37ed0SZbigniew Bodek 	enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port);
2147f4b37ed0SZbigniew Bodek 
2148f4b37ed0SZbigniew Bodek 	if (op_mode != AL_PCIE_OPERATING_MODE_RC) {
2149f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: link-retrain is applicable only for RC mode\n",
2150f4b37ed0SZbigniew Bodek 			pcie_port->port_id);
2151f4b37ed0SZbigniew Bodek 		return -EINVAL;
2152f4b37ed0SZbigniew Bodek 	}
2153f4b37ed0SZbigniew Bodek 
2154f4b37ed0SZbigniew Bodek 	if (!al_pcie_is_link_started(pcie_port)) {
2155f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: link not started, cannot link-retrain\n", pcie_port->port_id);
2156f4b37ed0SZbigniew Bodek 		return -EINVAL;
2157f4b37ed0SZbigniew Bodek 	}
2158f4b37ed0SZbigniew Bodek 
2159f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(regs->core_space[0].pcie_cap_base + (AL_PCI_EXP_LNKCTL >> 1),
2160f4b37ed0SZbigniew Bodek 	AL_PCI_EXP_LNKCTL_LNK_RTRN, AL_PCI_EXP_LNKCTL_LNK_RTRN);
2161f4b37ed0SZbigniew Bodek 
2162f4b37ed0SZbigniew Bodek 	return 0;
2163f4b37ed0SZbigniew Bodek }
2164f4b37ed0SZbigniew Bodek 
2165f4b37ed0SZbigniew Bodek /* trigger speed change */
2166f4b37ed0SZbigniew Bodek int
al_pcie_link_change_speed(struct al_pcie_port * pcie_port,enum al_pcie_link_speed new_speed)2167f4b37ed0SZbigniew Bodek al_pcie_link_change_speed(struct al_pcie_port *pcie_port,
2168f4b37ed0SZbigniew Bodek 			      enum al_pcie_link_speed new_speed)
2169f4b37ed0SZbigniew Bodek {
2170f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
2171f4b37ed0SZbigniew Bodek 
2172f4b37ed0SZbigniew Bodek 	if (!al_pcie_is_link_started(pcie_port)) {
2173f4b37ed0SZbigniew Bodek 		al_err("PCIe %d: link not started, cannot change speed\n", pcie_port->port_id);
2174f4b37ed0SZbigniew Bodek 		return -EINVAL;
2175f4b37ed0SZbigniew Bodek 	}
2176f4b37ed0SZbigniew Bodek 
2177f4b37ed0SZbigniew Bodek 	al_dbg("PCIe %d: changing speed to %d\n", pcie_port->port_id, new_speed);
2178f4b37ed0SZbigniew Bodek 
2179f4b37ed0SZbigniew Bodek 	al_pcie_port_link_speed_ctrl_set(pcie_port, new_speed);
2180f4b37ed0SZbigniew Bodek 
2181f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(&regs->port_regs->gen2_ctrl,
2182f4b37ed0SZbigniew Bodek 		PCIE_PORT_GEN2_CTRL_DIRECT_SPEED_CHANGE,
2183f4b37ed0SZbigniew Bodek 		PCIE_PORT_GEN2_CTRL_DIRECT_SPEED_CHANGE);
2184f4b37ed0SZbigniew Bodek 
2185f4b37ed0SZbigniew Bodek 	return 0;
2186f4b37ed0SZbigniew Bodek }
2187f4b37ed0SZbigniew Bodek 
2188f4b37ed0SZbigniew Bodek /* TODO: check if this function needed */
2189f4b37ed0SZbigniew Bodek int
al_pcie_link_change_width(struct al_pcie_port * pcie_port,uint8_t width)2190f4b37ed0SZbigniew Bodek al_pcie_link_change_width(struct al_pcie_port *pcie_port,
2191f4b37ed0SZbigniew Bodek 			      uint8_t width __attribute__((__unused__)))
2192f4b37ed0SZbigniew Bodek {
2193f4b37ed0SZbigniew Bodek 	al_err("PCIe %d: link change width not implemented\n",
2194f4b37ed0SZbigniew Bodek 		pcie_port->port_id);
2195f4b37ed0SZbigniew Bodek 
2196f4b37ed0SZbigniew Bodek 	return -ENOSYS;
2197f4b37ed0SZbigniew Bodek }
2198f4b37ed0SZbigniew Bodek 
2199f4b37ed0SZbigniew Bodek /**************************** Post Link Start API *****************************/
2200f4b37ed0SZbigniew Bodek 
2201f4b37ed0SZbigniew Bodek /************************** Snoop Configuration API ***************************/
2202f4b37ed0SZbigniew Bodek 
2203f4b37ed0SZbigniew Bodek int
al_pcie_port_snoop_config(struct al_pcie_port * pcie_port,al_bool enable_axi_snoop)2204f4b37ed0SZbigniew Bodek al_pcie_port_snoop_config(struct al_pcie_port *pcie_port, al_bool enable_axi_snoop)
2205f4b37ed0SZbigniew Bodek {
2206f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
2207f4b37ed0SZbigniew Bodek 
2208f4b37ed0SZbigniew Bodek 	/* Set snoop mode */
2209*3fc36ee0SWojciech Macek 	al_dbg("PCIE_%d: snoop mode %s\n",
2210f4b37ed0SZbigniew Bodek 			pcie_port->port_id, enable_axi_snoop ? "enable" : "disable");
2211f4b37ed0SZbigniew Bodek 
2212f4b37ed0SZbigniew Bodek 	if (enable_axi_snoop) {
2213f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(regs->axi.ctrl.master_arctl,
2214f4b37ed0SZbigniew Bodek 			PCIE_AXI_CTRL_MASTER_ARCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_ARCTL_SNOOP,
2215f4b37ed0SZbigniew Bodek 			PCIE_AXI_CTRL_MASTER_ARCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_ARCTL_SNOOP);
2216f4b37ed0SZbigniew Bodek 
2217f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(regs->axi.ctrl.master_awctl,
2218f4b37ed0SZbigniew Bodek 			PCIE_AXI_CTRL_MASTER_AWCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_AWCTL_SNOOP,
2219f4b37ed0SZbigniew Bodek 			PCIE_AXI_CTRL_MASTER_AWCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_AWCTL_SNOOP);
2220f4b37ed0SZbigniew Bodek 	} else {
2221f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(regs->axi.ctrl.master_arctl,
2222f4b37ed0SZbigniew Bodek 			PCIE_AXI_CTRL_MASTER_ARCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_ARCTL_SNOOP,
2223f4b37ed0SZbigniew Bodek 			PCIE_AXI_CTRL_MASTER_ARCTL_OVR_SNOOP);
2224f4b37ed0SZbigniew Bodek 
2225f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(regs->axi.ctrl.master_awctl,
2226f4b37ed0SZbigniew Bodek 			PCIE_AXI_CTRL_MASTER_AWCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_AWCTL_SNOOP,
2227f4b37ed0SZbigniew Bodek 			PCIE_AXI_CTRL_MASTER_AWCTL_OVR_SNOOP);
2228f4b37ed0SZbigniew Bodek 	}
2229f4b37ed0SZbigniew Bodek 	return 0;
2230f4b37ed0SZbigniew Bodek }
2231f4b37ed0SZbigniew Bodek 
2232f4b37ed0SZbigniew Bodek /************************** Configuration Space API ***************************/
2233f4b37ed0SZbigniew Bodek 
2234f4b37ed0SZbigniew Bodek /** get base address of pci configuration space header */
2235f4b37ed0SZbigniew Bodek int
al_pcie_config_space_get(struct al_pcie_pf * pcie_pf,uint8_t __iomem ** addr)2236f4b37ed0SZbigniew Bodek al_pcie_config_space_get(struct al_pcie_pf *pcie_pf,
2237f4b37ed0SZbigniew Bodek 			     uint8_t __iomem **addr)
2238f4b37ed0SZbigniew Bodek {
2239f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_pf->pcie_port->regs;
2240f4b37ed0SZbigniew Bodek 
2241f4b37ed0SZbigniew Bodek 	*addr = (uint8_t __iomem *)&regs->core_space[pcie_pf->pf_num].config_header[0];
2242f4b37ed0SZbigniew Bodek 	return 0;
2243f4b37ed0SZbigniew Bodek }
2244f4b37ed0SZbigniew Bodek 
2245f4b37ed0SZbigniew Bodek /* Read data from the local configuration space */
2246f4b37ed0SZbigniew Bodek uint32_t
al_pcie_local_cfg_space_read(struct al_pcie_pf * pcie_pf,unsigned int reg_offset)2247f4b37ed0SZbigniew Bodek al_pcie_local_cfg_space_read(
2248f4b37ed0SZbigniew Bodek 	struct al_pcie_pf	*pcie_pf,
2249f4b37ed0SZbigniew Bodek 	unsigned int		reg_offset)
2250f4b37ed0SZbigniew Bodek {
2251f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_pf->pcie_port->regs;
2252f4b37ed0SZbigniew Bodek 	uint32_t data;
2253f4b37ed0SZbigniew Bodek 
2254f4b37ed0SZbigniew Bodek 	data = al_reg_read32(&regs->core_space[pcie_pf->pf_num].config_header[reg_offset]);
2255f4b37ed0SZbigniew Bodek 
2256f4b37ed0SZbigniew Bodek 	return data;
2257f4b37ed0SZbigniew Bodek }
2258f4b37ed0SZbigniew Bodek 
2259f4b37ed0SZbigniew Bodek /* Write data to the local configuration space */
2260f4b37ed0SZbigniew Bodek void
al_pcie_local_cfg_space_write(struct al_pcie_pf * pcie_pf,unsigned int reg_offset,uint32_t data,al_bool cs2,al_bool allow_ro_wr)2261f4b37ed0SZbigniew Bodek al_pcie_local_cfg_space_write(
2262f4b37ed0SZbigniew Bodek 	struct al_pcie_pf	*pcie_pf,
2263f4b37ed0SZbigniew Bodek 	unsigned int		reg_offset,
2264f4b37ed0SZbigniew Bodek 	uint32_t		data,
2265f4b37ed0SZbigniew Bodek 	al_bool			cs2,
2266f4b37ed0SZbigniew Bodek 	al_bool			allow_ro_wr)
2267f4b37ed0SZbigniew Bodek {
2268f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port = pcie_pf->pcie_port;
2269f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
2270f4b37ed0SZbigniew Bodek 	unsigned int pf_num = pcie_pf->pf_num;
2271f4b37ed0SZbigniew Bodek 	uint32_t *offset = &regs->core_space[pf_num].config_header[reg_offset];
2272f4b37ed0SZbigniew Bodek 
2273f4b37ed0SZbigniew Bodek 	if (allow_ro_wr)
2274f4b37ed0SZbigniew Bodek 		al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE);
2275f4b37ed0SZbigniew Bodek 
2276f4b37ed0SZbigniew Bodek 	if (cs2 == AL_FALSE)
2277f4b37ed0SZbigniew Bodek 		al_reg_write32(offset, data);
2278f4b37ed0SZbigniew Bodek 	else
2279f4b37ed0SZbigniew Bodek 		al_reg_write32_dbi_cs2(pcie_port, offset, data);
2280f4b37ed0SZbigniew Bodek 
2281f4b37ed0SZbigniew Bodek 	if (allow_ro_wr)
2282f4b37ed0SZbigniew Bodek 		al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE);
2283f4b37ed0SZbigniew Bodek }
2284f4b37ed0SZbigniew Bodek 
2285f4b37ed0SZbigniew Bodek /** set target_bus and mask_target_bus */
2286f4b37ed0SZbigniew Bodek int
al_pcie_target_bus_set(struct al_pcie_port * pcie_port,uint8_t target_bus,uint8_t mask_target_bus)2287f4b37ed0SZbigniew Bodek al_pcie_target_bus_set(
2288f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
2289f4b37ed0SZbigniew Bodek 	uint8_t target_bus,
2290f4b37ed0SZbigniew Bodek 	uint8_t mask_target_bus)
2291f4b37ed0SZbigniew Bodek {
2292f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs;
2293f4b37ed0SZbigniew Bodek 	uint32_t reg;
2294f4b37ed0SZbigniew Bodek 
2295f4b37ed0SZbigniew Bodek 	reg = al_reg_read32(regs->axi.ob_ctrl.cfg_target_bus);
2296f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK,
2297f4b37ed0SZbigniew Bodek 			PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_SHIFT,
2298f4b37ed0SZbigniew Bodek 			mask_target_bus);
2299f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_BUSNUM_MASK,
2300f4b37ed0SZbigniew Bodek 			PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_BUSNUM_SHIFT,
2301f4b37ed0SZbigniew Bodek 			target_bus);
2302f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->axi.ob_ctrl.cfg_target_bus, reg);
2303f4b37ed0SZbigniew Bodek 	return 0;
2304f4b37ed0SZbigniew Bodek }
2305f4b37ed0SZbigniew Bodek 
2306f4b37ed0SZbigniew Bodek /** get target_bus and mask_target_bus */
2307f4b37ed0SZbigniew Bodek int
al_pcie_target_bus_get(struct al_pcie_port * pcie_port,uint8_t * target_bus,uint8_t * mask_target_bus)2308f4b37ed0SZbigniew Bodek al_pcie_target_bus_get(
2309f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
2310f4b37ed0SZbigniew Bodek 	uint8_t *target_bus,
2311f4b37ed0SZbigniew Bodek 	uint8_t *mask_target_bus)
2312f4b37ed0SZbigniew Bodek {
2313f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs;
2314f4b37ed0SZbigniew Bodek 	uint32_t reg;
2315f4b37ed0SZbigniew Bodek 
2316f4b37ed0SZbigniew Bodek 	al_assert(target_bus);
2317f4b37ed0SZbigniew Bodek 	al_assert(mask_target_bus);
2318f4b37ed0SZbigniew Bodek 
2319f4b37ed0SZbigniew Bodek 	reg = al_reg_read32(regs->axi.ob_ctrl.cfg_target_bus);
2320f4b37ed0SZbigniew Bodek 
2321f4b37ed0SZbigniew Bodek 	*mask_target_bus = AL_REG_FIELD_GET(reg,
2322f4b37ed0SZbigniew Bodek 				PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK,
2323f4b37ed0SZbigniew Bodek 				PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_SHIFT);
2324f4b37ed0SZbigniew Bodek 	*target_bus = AL_REG_FIELD_GET(reg,
2325f4b37ed0SZbigniew Bodek 			PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_BUSNUM_MASK,
2326f4b37ed0SZbigniew Bodek 			PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_BUSNUM_SHIFT);
2327f4b37ed0SZbigniew Bodek 	return 0;
2328f4b37ed0SZbigniew Bodek }
2329f4b37ed0SZbigniew Bodek 
2330f4b37ed0SZbigniew Bodek /** Set secondary bus number */
2331f4b37ed0SZbigniew Bodek int
al_pcie_secondary_bus_set(struct al_pcie_port * pcie_port,uint8_t secbus)2332f4b37ed0SZbigniew Bodek al_pcie_secondary_bus_set(struct al_pcie_port *pcie_port, uint8_t secbus)
2333f4b37ed0SZbigniew Bodek {
2334f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
2335f4b37ed0SZbigniew Bodek 
2336f4b37ed0SZbigniew Bodek 	uint32_t secbus_val = (secbus <<
2337f4b37ed0SZbigniew Bodek 			PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SEC_BUS_SHIFT);
2338f4b37ed0SZbigniew Bodek 
2339f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(
2340f4b37ed0SZbigniew Bodek 		regs->axi.ob_ctrl.cfg_control,
2341f4b37ed0SZbigniew Bodek 		PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SEC_BUS_MASK,
2342f4b37ed0SZbigniew Bodek 		secbus_val);
2343f4b37ed0SZbigniew Bodek 	return 0;
2344f4b37ed0SZbigniew Bodek }
2345f4b37ed0SZbigniew Bodek 
2346f4b37ed0SZbigniew Bodek /** Set sub-ordinary bus number */
2347f4b37ed0SZbigniew Bodek int
al_pcie_subordinary_bus_set(struct al_pcie_port * pcie_port,uint8_t subbus)2348f4b37ed0SZbigniew Bodek al_pcie_subordinary_bus_set(struct al_pcie_port *pcie_port, uint8_t subbus)
2349f4b37ed0SZbigniew Bodek {
2350f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
2351f4b37ed0SZbigniew Bodek 
2352f4b37ed0SZbigniew Bodek 	uint32_t subbus_val = (subbus <<
2353f4b37ed0SZbigniew Bodek 			PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SUBBUS_SHIFT);
2354f4b37ed0SZbigniew Bodek 
2355f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(
2356f4b37ed0SZbigniew Bodek 		regs->axi.ob_ctrl.cfg_control,
2357f4b37ed0SZbigniew Bodek 		PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SUBBUS_MASK,
2358f4b37ed0SZbigniew Bodek 		subbus_val);
2359f4b37ed0SZbigniew Bodek 	return 0;
2360f4b37ed0SZbigniew Bodek }
2361f4b37ed0SZbigniew Bodek 
2362f4b37ed0SZbigniew Bodek /* Enable/disable deferring incoming configuration requests */
2363f4b37ed0SZbigniew Bodek void
al_pcie_app_req_retry_set(struct al_pcie_port * pcie_port,al_bool en)2364f4b37ed0SZbigniew Bodek al_pcie_app_req_retry_set(
2365f4b37ed0SZbigniew Bodek 	struct al_pcie_port	*pcie_port,
2366f4b37ed0SZbigniew Bodek 	al_bool			en)
2367f4b37ed0SZbigniew Bodek {
2368f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
2369f4b37ed0SZbigniew Bodek 	uint32_t mask = (pcie_port->rev_id == AL_PCIE_REV_ID_3) ?
2370f4b37ed0SZbigniew Bodek 		PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_APP_REQ_RETRY_EN :
2371f4b37ed0SZbigniew Bodek 		PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_APP_REQ_RETRY_EN;
2372f4b37ed0SZbigniew Bodek 
2373f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(regs->app.global_ctrl.pm_control,
2374f4b37ed0SZbigniew Bodek 		mask, (en == AL_TRUE) ? mask : 0);
2375f4b37ed0SZbigniew Bodek }
2376f4b37ed0SZbigniew Bodek 
2377*3fc36ee0SWojciech Macek /* Check if deferring incoming configuration requests is enabled or not */
al_pcie_app_req_retry_get_status(struct al_pcie_port * pcie_port)2378*3fc36ee0SWojciech Macek al_bool al_pcie_app_req_retry_get_status(struct al_pcie_port	*pcie_port)
2379*3fc36ee0SWojciech Macek {
2380*3fc36ee0SWojciech Macek 	struct al_pcie_regs *regs = pcie_port->regs;
2381*3fc36ee0SWojciech Macek 	uint32_t pm_control;
2382*3fc36ee0SWojciech Macek 	uint32_t mask = (pcie_port->rev_id == AL_PCIE_REV_ID_3) ?
2383*3fc36ee0SWojciech Macek 		PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_APP_REQ_RETRY_EN :
2384*3fc36ee0SWojciech Macek 		PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_APP_REQ_RETRY_EN;
2385*3fc36ee0SWojciech Macek 
2386*3fc36ee0SWojciech Macek 	pm_control = al_reg_read32(regs->app.global_ctrl.pm_control);
2387*3fc36ee0SWojciech Macek 	return (pm_control & mask) ? AL_TRUE : AL_FALSE;
2388*3fc36ee0SWojciech Macek }
2389*3fc36ee0SWojciech Macek 
2390f4b37ed0SZbigniew Bodek /*************** Internal Address Translation Unit (ATU) API ******************/
2391f4b37ed0SZbigniew Bodek 
2392f4b37ed0SZbigniew Bodek /** program internal ATU region entry */
2393f4b37ed0SZbigniew Bodek int
al_pcie_atu_region_set(struct al_pcie_port * pcie_port,struct al_pcie_atu_region * atu_region)2394f4b37ed0SZbigniew Bodek al_pcie_atu_region_set(
2395f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
2396f4b37ed0SZbigniew Bodek 	struct al_pcie_atu_region *atu_region)
2397f4b37ed0SZbigniew Bodek {
2398f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
2399f4b37ed0SZbigniew Bodek 	enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port);
2400f4b37ed0SZbigniew Bodek 	uint32_t reg = 0;
2401f4b37ed0SZbigniew Bodek 
2402f4b37ed0SZbigniew Bodek 	/**
2403f4b37ed0SZbigniew Bodek 	 * Addressing RMN: 5384
2404f4b37ed0SZbigniew Bodek 	 *
2405f4b37ed0SZbigniew Bodek 	 * RMN description:
2406f4b37ed0SZbigniew Bodek 	 * From SNPS (also included in the data book) Dynamic iATU Programming
2407f4b37ed0SZbigniew Bodek 	 * With AHB/AXI Bridge Module When the bridge slave interface clock
2408f4b37ed0SZbigniew Bodek 	 * (hresetn or slv_aclk) is asynchronous to the PCIe native core clock
2409f4b37ed0SZbigniew Bodek 	 * (core_clk), you must not update the iATU registers while operations
2410f4b37ed0SZbigniew Bodek 	 * are in progress on the AHB/AXI bridge slave interface. The iATU
2411f4b37ed0SZbigniew Bodek 	 * registers are in the core_clk clock domain. The register outputs are
2412f4b37ed0SZbigniew Bodek 	 * used in the AHB/AXI bridge slave interface clock domain. There is no
2413f4b37ed0SZbigniew Bodek 	 * synchronization logic between these registers and the AHB/AXI bridge
2414f4b37ed0SZbigniew Bodek 	 * slave interface.
2415f4b37ed0SZbigniew Bodek 	 *
2416f4b37ed0SZbigniew Bodek 	 * Software flow:
2417f4b37ed0SZbigniew Bodek 	 * Do not allow configuring Outbound iATU after link is started
2418f4b37ed0SZbigniew Bodek 	 */
2419f4b37ed0SZbigniew Bodek 	if ((atu_region->direction == AL_PCIE_ATU_DIR_OUTBOUND)
2420f4b37ed0SZbigniew Bodek 		&& (al_pcie_is_link_started(pcie_port))) {
2421f4b37ed0SZbigniew Bodek 		if (!atu_region->enforce_ob_atu_region_set) {
2422f4b37ed0SZbigniew Bodek 			al_err("PCIe %d: setting OB iATU after link is started is not allowed\n",
2423f4b37ed0SZbigniew Bodek 				pcie_port->port_id);
2424*3fc36ee0SWojciech Macek 			al_assert(AL_FALSE);
2425f4b37ed0SZbigniew Bodek 			return -EINVAL;
2426f4b37ed0SZbigniew Bodek 		} else {
2427f4b37ed0SZbigniew Bodek 			al_info("PCIe %d: setting OB iATU even after link is started\n",
2428f4b37ed0SZbigniew Bodek 				pcie_port->port_id);
2429f4b37ed0SZbigniew Bodek 		}
2430f4b37ed0SZbigniew Bodek 	}
2431f4b37ed0SZbigniew Bodek 
2432f4b37ed0SZbigniew Bodek 	/*TODO : add sanity check */
2433f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, 0xF, 0, atu_region->index);
2434f4b37ed0SZbigniew Bodek 	AL_REG_BIT_VAL_SET(reg, 31, atu_region->direction);
2435f4b37ed0SZbigniew Bodek 	al_reg_write32(&regs->port_regs->iatu.index, reg);
2436f4b37ed0SZbigniew Bodek 
2437f4b37ed0SZbigniew Bodek 	al_reg_write32(&regs->port_regs->iatu.lower_base_addr,
2438f4b37ed0SZbigniew Bodek 			(uint32_t)(atu_region->base_addr & 0xFFFFFFFF));
2439f4b37ed0SZbigniew Bodek 	al_reg_write32(&regs->port_regs->iatu.upper_base_addr,
2440f4b37ed0SZbigniew Bodek 			(uint32_t)((atu_region->base_addr >> 32)& 0xFFFFFFFF));
2441f4b37ed0SZbigniew Bodek 	al_reg_write32(&regs->port_regs->iatu.lower_target_addr,
2442f4b37ed0SZbigniew Bodek 			(uint32_t)(atu_region->target_addr & 0xFFFFFFFF));
2443f4b37ed0SZbigniew Bodek 	al_reg_write32(&regs->port_regs->iatu.upper_target_addr,
2444f4b37ed0SZbigniew Bodek 			(uint32_t)((atu_region->target_addr >> 32)& 0xFFFFFFFF));
2445f4b37ed0SZbigniew Bodek 
2446f4b37ed0SZbigniew Bodek 	/* configure the limit, not needed when working in BAR match mode */
2447f4b37ed0SZbigniew Bodek 	if (atu_region->match_mode == 0) {
2448f4b37ed0SZbigniew Bodek 		uint32_t limit_reg_val;
2449f4b37ed0SZbigniew Bodek 		uint32_t *limit_ext_reg =
2450f4b37ed0SZbigniew Bodek 			(atu_region->direction == AL_PCIE_ATU_DIR_OUTBOUND) ?
2451f4b37ed0SZbigniew Bodek 			&regs->app.atu.out_mask_pair[atu_region->index / 2] :
2452f4b37ed0SZbigniew Bodek 			&regs->app.atu.in_mask_pair[atu_region->index / 2];
2453f4b37ed0SZbigniew Bodek 		uint32_t limit_ext_reg_mask =
2454f4b37ed0SZbigniew Bodek 			(atu_region->index % 2) ?
2455f4b37ed0SZbigniew Bodek 			PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_MASK :
2456f4b37ed0SZbigniew Bodek 			PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_MASK;
2457f4b37ed0SZbigniew Bodek 		unsigned int limit_ext_reg_shift =
2458f4b37ed0SZbigniew Bodek 			(atu_region->index % 2) ?
2459f4b37ed0SZbigniew Bodek 			PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_SHIFT :
2460f4b37ed0SZbigniew Bodek 			PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_SHIFT;
2461f4b37ed0SZbigniew Bodek 		uint64_t limit_sz_msk =
2462f4b37ed0SZbigniew Bodek 			atu_region->limit - atu_region->base_addr;
2463f4b37ed0SZbigniew Bodek 		uint32_t limit_ext_reg_val = (uint32_t)(((limit_sz_msk) >>
2464f4b37ed0SZbigniew Bodek 					32) & 0xFFFFFFFF);
2465f4b37ed0SZbigniew Bodek 
2466f4b37ed0SZbigniew Bodek 		if (limit_ext_reg_val) {
2467f4b37ed0SZbigniew Bodek 			limit_reg_val =	(uint32_t)((limit_sz_msk) & 0xFFFFFFFF);
2468f4b37ed0SZbigniew Bodek 			al_assert(limit_reg_val == 0xFFFFFFFF);
2469f4b37ed0SZbigniew Bodek 		} else {
2470f4b37ed0SZbigniew Bodek 			limit_reg_val = (uint32_t)(atu_region->limit &
2471f4b37ed0SZbigniew Bodek 					0xFFFFFFFF);
2472f4b37ed0SZbigniew Bodek 		}
2473f4b37ed0SZbigniew Bodek 
2474f4b37ed0SZbigniew Bodek 		al_reg_write32_masked(
2475f4b37ed0SZbigniew Bodek 				limit_ext_reg,
2476f4b37ed0SZbigniew Bodek 				limit_ext_reg_mask,
2477f4b37ed0SZbigniew Bodek 				limit_ext_reg_val << limit_ext_reg_shift);
2478f4b37ed0SZbigniew Bodek 
2479f4b37ed0SZbigniew Bodek 		al_reg_write32(&regs->port_regs->iatu.limit_addr,
2480f4b37ed0SZbigniew Bodek 				limit_reg_val);
2481f4b37ed0SZbigniew Bodek 	}
2482f4b37ed0SZbigniew Bodek 
2483*3fc36ee0SWojciech Macek 
2484*3fc36ee0SWojciech Macek 	/**
2485*3fc36ee0SWojciech Macek 	* Addressing RMN: 3186
2486*3fc36ee0SWojciech Macek 	*
2487*3fc36ee0SWojciech Macek 	* RMN description:
2488*3fc36ee0SWojciech Macek 	* Bug in SNPS IP (versions 4.21 , 4.10a-ea02)
2489*3fc36ee0SWojciech Macek 	* In CFG request created via outbound atu (shift mode) bits [27:12] go to
2490*3fc36ee0SWojciech Macek 	* [31:16] , the shifting is correct , however the ATU leaves bit [15:12]
2491*3fc36ee0SWojciech Macek 	* to their original values, this is then transmited in the tlp .
2492*3fc36ee0SWojciech Macek 	* Those bits are currently reserved ,bit might be non-resv. in future generations .
2493*3fc36ee0SWojciech Macek 	*
2494*3fc36ee0SWojciech Macek 	* Software flow:
2495*3fc36ee0SWojciech Macek 	* Enable HW fix
2496*3fc36ee0SWojciech Macek 	* rev=REV1,REV2 set bit 15 in corresponding app_reg.atu.out_mask
2497*3fc36ee0SWojciech Macek 	* rev>REV2 set corresponding bit is app_reg.atu.reg_out_mask
2498*3fc36ee0SWojciech Macek 	*/
2499*3fc36ee0SWojciech Macek 	if ((atu_region->cfg_shift_mode == AL_TRUE) &&
2500*3fc36ee0SWojciech Macek 		(atu_region->direction == AL_PCIE_ATU_DIR_OUTBOUND)) {
2501*3fc36ee0SWojciech Macek 		if (pcie_port->rev_id > AL_PCIE_REV_ID_2) {
2502*3fc36ee0SWojciech Macek 			al_reg_write32_masked(regs->app.atu.reg_out_mask,
2503*3fc36ee0SWojciech Macek 			1 << (atu_region->index) ,
2504*3fc36ee0SWojciech Macek 			1 << (atu_region->index));
2505*3fc36ee0SWojciech Macek 		} else {
2506*3fc36ee0SWojciech Macek 			uint32_t *limit_ext_reg =
2507*3fc36ee0SWojciech Macek 				(atu_region->direction == AL_PCIE_ATU_DIR_OUTBOUND) ?
2508*3fc36ee0SWojciech Macek 				&regs->app.atu.out_mask_pair[atu_region->index / 2] :
2509*3fc36ee0SWojciech Macek 				&regs->app.atu.in_mask_pair[atu_region->index / 2];
2510*3fc36ee0SWojciech Macek 			uint32_t limit_ext_reg_mask =
2511*3fc36ee0SWojciech Macek 				(atu_region->index % 2) ?
2512*3fc36ee0SWojciech Macek 				PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_MASK :
2513*3fc36ee0SWojciech Macek 				PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_MASK;
2514*3fc36ee0SWojciech Macek 			unsigned int limit_ext_reg_shift =
2515*3fc36ee0SWojciech Macek 				(atu_region->index % 2) ?
2516*3fc36ee0SWojciech Macek 				PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_SHIFT :
2517*3fc36ee0SWojciech Macek 				PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_SHIFT;
2518*3fc36ee0SWojciech Macek 
2519*3fc36ee0SWojciech Macek 			al_reg_write32_masked(
2520*3fc36ee0SWojciech Macek 				limit_ext_reg,
2521*3fc36ee0SWojciech Macek 				limit_ext_reg_mask,
2522*3fc36ee0SWojciech Macek 				(AL_BIT(15)) << limit_ext_reg_shift);
2523*3fc36ee0SWojciech Macek 		}
2524*3fc36ee0SWojciech Macek 	}
2525*3fc36ee0SWojciech Macek 
2526f4b37ed0SZbigniew Bodek 	reg = 0;
2527f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, 0x1F, 0, atu_region->tlp_type);
2528f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, 0x3 << 9, 9, atu_region->attr);
2529f4b37ed0SZbigniew Bodek 
2530f4b37ed0SZbigniew Bodek 
2531f4b37ed0SZbigniew Bodek 	if ((pcie_port->rev_id == AL_PCIE_REV_ID_3)
2532f4b37ed0SZbigniew Bodek 		&& (op_mode == AL_PCIE_OPERATING_MODE_EP)
2533f4b37ed0SZbigniew Bodek 		&& (atu_region->function_match_bypass_mode)) {
2534f4b37ed0SZbigniew Bodek 		AL_REG_FIELD_SET(reg,
2535f4b37ed0SZbigniew Bodek 			PCIE_IATU_CR1_FUNC_NUM_MASK,
2536f4b37ed0SZbigniew Bodek 			PCIE_IATU_CR1_FUNC_NUM_SHIFT,
2537f4b37ed0SZbigniew Bodek 			atu_region->function_match_bypass_mode_number);
2538f4b37ed0SZbigniew Bodek 	}
2539f4b37ed0SZbigniew Bodek 
2540f4b37ed0SZbigniew Bodek 	al_reg_write32(&regs->port_regs->iatu.cr1, reg);
2541f4b37ed0SZbigniew Bodek 
2542f4b37ed0SZbigniew Bodek 	/* Enable/disable the region. */
2543f4b37ed0SZbigniew Bodek 	reg = 0;
2544f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, 0xFF, 0, atu_region->msg_code);
2545f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, 0x700, 8, atu_region->bar_number);
2546f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, 0x3 << 24, 24, atu_region->response);
2547f4b37ed0SZbigniew Bodek 	AL_REG_BIT_VAL_SET(reg, 16, atu_region->enable_attr_match_mode == AL_TRUE);
2548f4b37ed0SZbigniew Bodek 	AL_REG_BIT_VAL_SET(reg, 21, atu_region->enable_msg_match_mode == AL_TRUE);
2549f4b37ed0SZbigniew Bodek 	AL_REG_BIT_VAL_SET(reg, 28, atu_region->cfg_shift_mode == AL_TRUE);
2550f4b37ed0SZbigniew Bodek 	AL_REG_BIT_VAL_SET(reg, 29, atu_region->invert_matching == AL_TRUE);
2551f4b37ed0SZbigniew Bodek 	if (atu_region->tlp_type == AL_PCIE_TLP_TYPE_MEM || atu_region->tlp_type == AL_PCIE_TLP_TYPE_IO)
2552f4b37ed0SZbigniew Bodek 		AL_REG_BIT_VAL_SET(reg, 30, !!atu_region->match_mode);
2553f4b37ed0SZbigniew Bodek 	AL_REG_BIT_VAL_SET(reg, 31, !!atu_region->enable);
2554f4b37ed0SZbigniew Bodek 
2555f4b37ed0SZbigniew Bodek 	/* In outbound, enable function bypass
2556f4b37ed0SZbigniew Bodek 	 * In inbound, enable function match mode
2557f4b37ed0SZbigniew Bodek 	 * Note: this is the same bit, has different meanings in ob/ib ATUs
2558f4b37ed0SZbigniew Bodek 	 */
2559f4b37ed0SZbigniew Bodek 	if (op_mode == AL_PCIE_OPERATING_MODE_EP)
2560f4b37ed0SZbigniew Bodek 		AL_REG_FIELD_SET(reg,
2561f4b37ed0SZbigniew Bodek 			PCIE_IATU_CR2_FUNC_NUM_TRANS_BYPASS_FUNC_MATCH_ENABLE_MASK,
2562f4b37ed0SZbigniew Bodek 			PCIE_IATU_CR2_FUNC_NUM_TRANS_BYPASS_FUNC_MATCH_ENABLE_SHIFT,
2563f4b37ed0SZbigniew Bodek 			atu_region->function_match_bypass_mode ? 0x1 : 0x0);
2564f4b37ed0SZbigniew Bodek 
2565f4b37ed0SZbigniew Bodek 	al_reg_write32(&regs->port_regs->iatu.cr2, reg);
2566f4b37ed0SZbigniew Bodek 
2567f4b37ed0SZbigniew Bodek 	return 0;
2568f4b37ed0SZbigniew Bodek }
2569f4b37ed0SZbigniew Bodek 
2570f4b37ed0SZbigniew Bodek /** obtains internal ATU region base/target addresses */
2571f4b37ed0SZbigniew Bodek void
al_pcie_atu_region_get_fields(struct al_pcie_port * pcie_port,enum al_pcie_atu_dir direction,uint8_t index,al_bool * enable,uint64_t * base_addr,uint64_t * target_addr)2572f4b37ed0SZbigniew Bodek al_pcie_atu_region_get_fields(
2573f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
2574f4b37ed0SZbigniew Bodek 	enum al_pcie_atu_dir direction, uint8_t index,
2575f4b37ed0SZbigniew Bodek 	al_bool *enable, uint64_t *base_addr, uint64_t *target_addr)
2576f4b37ed0SZbigniew Bodek {
2577f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
2578f4b37ed0SZbigniew Bodek 	uint64_t high_addr;
2579f4b37ed0SZbigniew Bodek 	uint32_t reg = 0;
2580f4b37ed0SZbigniew Bodek 
2581f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, 0xF, 0, index);
2582f4b37ed0SZbigniew Bodek 	AL_REG_BIT_VAL_SET(reg, 31, direction);
2583f4b37ed0SZbigniew Bodek 	al_reg_write32(&regs->port_regs->iatu.index, reg);
2584f4b37ed0SZbigniew Bodek 
2585f4b37ed0SZbigniew Bodek 	*base_addr = al_reg_read32(&regs->port_regs->iatu.lower_base_addr);
2586f4b37ed0SZbigniew Bodek 	high_addr = al_reg_read32(&regs->port_regs->iatu.upper_base_addr);
2587f4b37ed0SZbigniew Bodek 	high_addr <<= 32;
2588f4b37ed0SZbigniew Bodek 	*base_addr |= high_addr;
2589f4b37ed0SZbigniew Bodek 
2590f4b37ed0SZbigniew Bodek 	*target_addr = al_reg_read32(&regs->port_regs->iatu.lower_target_addr);
2591f4b37ed0SZbigniew Bodek 	high_addr = al_reg_read32(&regs->port_regs->iatu.upper_target_addr);
2592f4b37ed0SZbigniew Bodek 	high_addr <<= 32;
2593f4b37ed0SZbigniew Bodek 	*target_addr |= high_addr;
2594f4b37ed0SZbigniew Bodek 
2595f4b37ed0SZbigniew Bodek 	reg = al_reg_read32(&regs->port_regs->iatu.cr1);
2596f4b37ed0SZbigniew Bodek 	*enable = AL_REG_BIT_GET(reg, 31) ? AL_TRUE : AL_FALSE;
2597f4b37ed0SZbigniew Bodek }
2598f4b37ed0SZbigniew Bodek 
2599f4b37ed0SZbigniew Bodek void
al_pcie_axi_io_config(struct al_pcie_port * pcie_port,al_phys_addr_t start,al_phys_addr_t end)2600f4b37ed0SZbigniew Bodek al_pcie_axi_io_config(
2601f4b37ed0SZbigniew Bodek 	struct al_pcie_port *pcie_port,
2602f4b37ed0SZbigniew Bodek 	al_phys_addr_t start,
2603f4b37ed0SZbigniew Bodek 	al_phys_addr_t end)
2604f4b37ed0SZbigniew Bodek {
2605f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
2606f4b37ed0SZbigniew Bodek 
2607f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->axi.ob_ctrl.io_start_h,
2608f4b37ed0SZbigniew Bodek 			(uint32_t)((start >> 32) & 0xFFFFFFFF));
2609f4b37ed0SZbigniew Bodek 
2610f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->axi.ob_ctrl.io_start_l,
2611f4b37ed0SZbigniew Bodek 			(uint32_t)(start & 0xFFFFFFFF));
2612f4b37ed0SZbigniew Bodek 
2613f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->axi.ob_ctrl.io_limit_h,
2614f4b37ed0SZbigniew Bodek 			(uint32_t)((end >> 32) & 0xFFFFFFFF));
2615f4b37ed0SZbigniew Bodek 
2616f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->axi.ob_ctrl.io_limit_l,
2617f4b37ed0SZbigniew Bodek 			(uint32_t)(end & 0xFFFFFFFF));
2618f4b37ed0SZbigniew Bodek 
2619f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(regs->axi.ctrl.slv_ctl,
2620f4b37ed0SZbigniew Bodek 			      PCIE_AXI_CTRL_SLV_CTRL_IO_BAR_EN,
2621f4b37ed0SZbigniew Bodek 			      PCIE_AXI_CTRL_SLV_CTRL_IO_BAR_EN);
2622f4b37ed0SZbigniew Bodek }
2623f4b37ed0SZbigniew Bodek 
2624*3fc36ee0SWojciech Macek /************** Interrupt and Event generation (Endpoint mode Only) API *****************/
2625*3fc36ee0SWojciech Macek 
al_pcie_pf_flr_done_gen(struct al_pcie_pf * pcie_pf)2626*3fc36ee0SWojciech Macek int al_pcie_pf_flr_done_gen(struct al_pcie_pf		*pcie_pf)
2627*3fc36ee0SWojciech Macek {
2628*3fc36ee0SWojciech Macek 	struct al_pcie_regs *regs = pcie_pf->pcie_port->regs;
2629*3fc36ee0SWojciech Macek 	unsigned int pf_num = pcie_pf->pf_num;
2630*3fc36ee0SWojciech Macek 
2631*3fc36ee0SWojciech Macek 	al_reg_write32_masked(regs->app.global_ctrl.events_gen[pf_num],
2632*3fc36ee0SWojciech Macek 			PCIE_W_GLOBAL_CTRL_EVENTS_GEN_FLR_PF_DONE,
2633*3fc36ee0SWojciech Macek 			PCIE_W_GLOBAL_CTRL_EVENTS_GEN_FLR_PF_DONE);
2634*3fc36ee0SWojciech Macek 	al_udelay(AL_PCIE_FLR_DONE_INTERVAL);
2635*3fc36ee0SWojciech Macek 	al_reg_write32_masked(regs->app.global_ctrl.events_gen[pf_num],
2636*3fc36ee0SWojciech Macek 			PCIE_W_GLOBAL_CTRL_EVENTS_GEN_FLR_PF_DONE, 0);
2637*3fc36ee0SWojciech Macek 	return 0;
2638*3fc36ee0SWojciech Macek }
2639*3fc36ee0SWojciech Macek 
2640f4b37ed0SZbigniew Bodek 
2641f4b37ed0SZbigniew Bodek /** generate INTx Assert/DeAssert Message */
2642f4b37ed0SZbigniew Bodek int
al_pcie_legacy_int_gen(struct al_pcie_pf * pcie_pf,al_bool assert,enum al_pcie_legacy_int_type type)2643f4b37ed0SZbigniew Bodek al_pcie_legacy_int_gen(
2644f4b37ed0SZbigniew Bodek 	struct al_pcie_pf		*pcie_pf,
2645f4b37ed0SZbigniew Bodek 	al_bool				assert,
2646f4b37ed0SZbigniew Bodek 	enum al_pcie_legacy_int_type	type)
2647f4b37ed0SZbigniew Bodek {
2648f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_pf->pcie_port->regs;
2649f4b37ed0SZbigniew Bodek 	unsigned int pf_num = pcie_pf->pf_num;
2650f4b37ed0SZbigniew Bodek 	uint32_t reg;
2651f4b37ed0SZbigniew Bodek 
2652f4b37ed0SZbigniew Bodek 	al_assert(type == AL_PCIE_LEGACY_INTA); /* only INTA supported */
2653f4b37ed0SZbigniew Bodek 	reg = al_reg_read32(regs->app.global_ctrl.events_gen[pf_num]);
2654f4b37ed0SZbigniew Bodek 	AL_REG_BIT_VAL_SET(reg, 3, !!assert);
2655f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->app.global_ctrl.events_gen[pf_num], reg);
2656f4b37ed0SZbigniew Bodek 
2657f4b37ed0SZbigniew Bodek 	return 0;
2658f4b37ed0SZbigniew Bodek }
2659f4b37ed0SZbigniew Bodek 
2660f4b37ed0SZbigniew Bodek /** generate MSI interrupt */
2661f4b37ed0SZbigniew Bodek int
al_pcie_msi_int_gen(struct al_pcie_pf * pcie_pf,uint8_t vector)2662f4b37ed0SZbigniew Bodek al_pcie_msi_int_gen(struct al_pcie_pf *pcie_pf, uint8_t vector)
2663f4b37ed0SZbigniew Bodek {
2664f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_pf->pcie_port->regs;
2665f4b37ed0SZbigniew Bodek 	unsigned int pf_num = pcie_pf->pf_num;
2666f4b37ed0SZbigniew Bodek 	uint32_t reg;
2667f4b37ed0SZbigniew Bodek 
2668f4b37ed0SZbigniew Bodek 	/* set msi vector and clear MSI request */
2669f4b37ed0SZbigniew Bodek 	reg = al_reg_read32(regs->app.global_ctrl.events_gen[pf_num]);
2670f4b37ed0SZbigniew Bodek 	AL_REG_BIT_CLEAR(reg, 4);
2671f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg,
2672f4b37ed0SZbigniew Bodek 			PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_VECTOR_MASK,
2673f4b37ed0SZbigniew Bodek 			PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_VECTOR_SHIFT,
2674f4b37ed0SZbigniew Bodek 			vector);
2675f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->app.global_ctrl.events_gen[pf_num], reg);
2676f4b37ed0SZbigniew Bodek 	/* set MSI request */
2677f4b37ed0SZbigniew Bodek 	AL_REG_BIT_SET(reg, 4);
2678f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->app.global_ctrl.events_gen[pf_num], reg);
2679f4b37ed0SZbigniew Bodek 
2680f4b37ed0SZbigniew Bodek 	return 0;
2681f4b37ed0SZbigniew Bodek }
2682f4b37ed0SZbigniew Bodek 
2683f4b37ed0SZbigniew Bodek /** configure MSIX capability */
2684f4b37ed0SZbigniew Bodek int
al_pcie_msix_config(struct al_pcie_pf * pcie_pf,struct al_pcie_msix_params * msix_params)2685f4b37ed0SZbigniew Bodek al_pcie_msix_config(
2686f4b37ed0SZbigniew Bodek 	struct al_pcie_pf *pcie_pf,
2687f4b37ed0SZbigniew Bodek 	struct al_pcie_msix_params *msix_params)
2688f4b37ed0SZbigniew Bodek {
2689f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_pf->pcie_port->regs;
2690f4b37ed0SZbigniew Bodek 	unsigned int pf_num = pcie_pf->pf_num;
2691f4b37ed0SZbigniew Bodek 	uint32_t msix_reg0;
2692f4b37ed0SZbigniew Bodek 
2693f4b37ed0SZbigniew Bodek 	al_pcie_port_wr_to_ro_set(pcie_pf->pcie_port, AL_TRUE);
2694f4b37ed0SZbigniew Bodek 
2695f4b37ed0SZbigniew Bodek 	msix_reg0 = al_reg_read32(regs->core_space[pf_num].msix_cap_base);
2696f4b37ed0SZbigniew Bodek 
2697f4b37ed0SZbigniew Bodek 	msix_reg0 &= ~(AL_PCI_MSIX_MSGCTRL_TBL_SIZE << AL_PCI_MSIX_MSGCTRL_TBL_SIZE_SHIFT);
2698f4b37ed0SZbigniew Bodek 	msix_reg0 |= ((msix_params->table_size - 1) & AL_PCI_MSIX_MSGCTRL_TBL_SIZE) <<
2699f4b37ed0SZbigniew Bodek 			AL_PCI_MSIX_MSGCTRL_TBL_SIZE_SHIFT;
2700f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->core_space[pf_num].msix_cap_base, msix_reg0);
2701f4b37ed0SZbigniew Bodek 
2702f4b37ed0SZbigniew Bodek 	/* Table offset & BAR */
2703f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->core_space[pf_num].msix_cap_base + (AL_PCI_MSIX_TABLE >> 2),
2704f4b37ed0SZbigniew Bodek 		       (msix_params->table_offset & AL_PCI_MSIX_TABLE_OFFSET) |
2705f4b37ed0SZbigniew Bodek 			       (msix_params->table_bar & AL_PCI_MSIX_TABLE_BAR));
2706f4b37ed0SZbigniew Bodek 	/* PBA offset & BAR */
2707f4b37ed0SZbigniew Bodek 	al_reg_write32(regs->core_space[pf_num].msix_cap_base + (AL_PCI_MSIX_PBA >> 2),
2708f4b37ed0SZbigniew Bodek 		       (msix_params->pba_offset & AL_PCI_MSIX_PBA_OFFSET) |
2709f4b37ed0SZbigniew Bodek 			       (msix_params->pba_bar & AL_PCI_MSIX_PBA_BAR));
2710f4b37ed0SZbigniew Bodek 
2711f4b37ed0SZbigniew Bodek 	al_pcie_port_wr_to_ro_set(pcie_pf->pcie_port, AL_FALSE);
2712f4b37ed0SZbigniew Bodek 
2713f4b37ed0SZbigniew Bodek 	return 0;
2714f4b37ed0SZbigniew Bodek }
2715f4b37ed0SZbigniew Bodek 
2716f4b37ed0SZbigniew Bodek /** check whether MSIX is enabled */
2717f4b37ed0SZbigniew Bodek al_bool
al_pcie_msix_enabled(struct al_pcie_pf * pcie_pf)2718f4b37ed0SZbigniew Bodek al_pcie_msix_enabled(struct al_pcie_pf	*pcie_pf)
2719f4b37ed0SZbigniew Bodek {
2720f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_pf->pcie_port->regs;
2721f4b37ed0SZbigniew Bodek 	uint32_t msix_reg0 = al_reg_read32(regs->core_space[pcie_pf->pf_num].msix_cap_base);
2722f4b37ed0SZbigniew Bodek 
2723f4b37ed0SZbigniew Bodek 	if (msix_reg0 & AL_PCI_MSIX_MSGCTRL_EN)
2724f4b37ed0SZbigniew Bodek 		return AL_TRUE;
2725f4b37ed0SZbigniew Bodek 	return AL_FALSE;
2726f4b37ed0SZbigniew Bodek }
2727f4b37ed0SZbigniew Bodek 
2728f4b37ed0SZbigniew Bodek /** check whether MSIX is masked */
2729f4b37ed0SZbigniew Bodek al_bool
al_pcie_msix_masked(struct al_pcie_pf * pcie_pf)2730f4b37ed0SZbigniew Bodek al_pcie_msix_masked(struct al_pcie_pf *pcie_pf)
2731f4b37ed0SZbigniew Bodek {
2732f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_pf->pcie_port->regs;
2733f4b37ed0SZbigniew Bodek 	uint32_t msix_reg0 = al_reg_read32(regs->core_space[pcie_pf->pf_num].msix_cap_base);
2734f4b37ed0SZbigniew Bodek 
2735f4b37ed0SZbigniew Bodek 	if (msix_reg0 & AL_PCI_MSIX_MSGCTRL_MASK)
2736f4b37ed0SZbigniew Bodek 		return AL_TRUE;
2737f4b37ed0SZbigniew Bodek 	return AL_FALSE;
2738f4b37ed0SZbigniew Bodek }
2739f4b37ed0SZbigniew Bodek 
2740f4b37ed0SZbigniew Bodek /******************** Advanced Error Reporting (AER) API **********************/
2741*3fc36ee0SWojciech Macek /************************* Auxiliary functions ********************************/
2742*3fc36ee0SWojciech Macek /* configure AER capability */
2743*3fc36ee0SWojciech Macek static int
al_pcie_aer_config_aux(struct al_pcie_port * pcie_port,unsigned int pf_num,struct al_pcie_aer_params * params)2744*3fc36ee0SWojciech Macek al_pcie_aer_config_aux(
2745*3fc36ee0SWojciech Macek 		struct al_pcie_port		*pcie_port,
2746*3fc36ee0SWojciech Macek 		unsigned int	pf_num,
2747f4b37ed0SZbigniew Bodek 		struct al_pcie_aer_params	*params)
2748f4b37ed0SZbigniew Bodek {
2749*3fc36ee0SWojciech Macek 	struct al_pcie_regs *regs = pcie_port->regs;
2750*3fc36ee0SWojciech Macek 	struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pf_num].aer;
2751f4b37ed0SZbigniew Bodek 	uint32_t reg_val;
2752f4b37ed0SZbigniew Bodek 
2753f4b37ed0SZbigniew Bodek 	reg_val = al_reg_read32(&aer_regs->header);
2754f4b37ed0SZbigniew Bodek 
2755f4b37ed0SZbigniew Bodek 	if (((reg_val & PCIE_AER_CAP_ID_MASK) >> PCIE_AER_CAP_ID_SHIFT) !=
2756f4b37ed0SZbigniew Bodek 		PCIE_AER_CAP_ID_VAL)
2757f4b37ed0SZbigniew Bodek 		return -EIO;
2758f4b37ed0SZbigniew Bodek 
2759f4b37ed0SZbigniew Bodek 	if (((reg_val & PCIE_AER_CAP_VER_MASK) >> PCIE_AER_CAP_VER_SHIFT) !=
2760f4b37ed0SZbigniew Bodek 		PCIE_AER_CAP_VER_VAL)
2761f4b37ed0SZbigniew Bodek 		return -EIO;
2762f4b37ed0SZbigniew Bodek 
2763f4b37ed0SZbigniew Bodek 	al_reg_write32(&aer_regs->corr_err_mask, ~params->enabled_corr_err);
2764f4b37ed0SZbigniew Bodek 
2765f4b37ed0SZbigniew Bodek 	al_reg_write32(&aer_regs->uncorr_err_mask,
2766f4b37ed0SZbigniew Bodek 		(~params->enabled_uncorr_non_fatal_err) |
2767f4b37ed0SZbigniew Bodek 		(~params->enabled_uncorr_fatal_err));
2768f4b37ed0SZbigniew Bodek 
2769f4b37ed0SZbigniew Bodek 	al_reg_write32(&aer_regs->uncorr_err_severity,
2770f4b37ed0SZbigniew Bodek 		params->enabled_uncorr_fatal_err);
2771f4b37ed0SZbigniew Bodek 
2772f4b37ed0SZbigniew Bodek 	al_reg_write32(&aer_regs->cap_and_ctrl,
2773f4b37ed0SZbigniew Bodek 		(params->ecrc_gen_en ? PCIE_AER_CTRL_STAT_ECRC_GEN_EN : 0) |
2774f4b37ed0SZbigniew Bodek 		(params->ecrc_chk_en ? PCIE_AER_CTRL_STAT_ECRC_CHK_EN : 0));
2775f4b37ed0SZbigniew Bodek 
2776*3fc36ee0SWojciech Macek 	/**
2777*3fc36ee0SWojciech Macek 	 * Addressing RMN: 5119
2778*3fc36ee0SWojciech Macek 	 *
2779*3fc36ee0SWojciech Macek 	 * RMN description:
2780*3fc36ee0SWojciech Macek 	 * ECRC generation for outbound request translated by iATU is effected
2781*3fc36ee0SWojciech Macek 	 * by iATU setting instead of ecrc_gen_bit in AER
2782*3fc36ee0SWojciech Macek 	 *
2783*3fc36ee0SWojciech Macek 	 * Software flow:
2784*3fc36ee0SWojciech Macek 	 * When enabling ECRC generation, set the outbound iATU to generate ECRC
2785*3fc36ee0SWojciech Macek 	 */
2786*3fc36ee0SWojciech Macek 	if (params->ecrc_gen_en == AL_TRUE) {
2787*3fc36ee0SWojciech Macek 		al_pcie_ecrc_gen_ob_atu_enable(pcie_port, pf_num);
2788*3fc36ee0SWojciech Macek 	}
2789*3fc36ee0SWojciech Macek 
2790f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(
2791*3fc36ee0SWojciech Macek 		regs->core_space[pf_num].pcie_dev_ctrl_status,
2792f4b37ed0SZbigniew Bodek 		PCIE_PORT_DEV_CTRL_STATUS_CORR_ERR_REPORT_EN |
2793f4b37ed0SZbigniew Bodek 		PCIE_PORT_DEV_CTRL_STATUS_NON_FTL_ERR_REPORT_EN |
2794f4b37ed0SZbigniew Bodek 		PCIE_PORT_DEV_CTRL_STATUS_FTL_ERR_REPORT_EN |
2795f4b37ed0SZbigniew Bodek 		PCIE_PORT_DEV_CTRL_STATUS_UNSUP_REQ_REPORT_EN,
2796f4b37ed0SZbigniew Bodek 		(params->enabled_corr_err ?
2797f4b37ed0SZbigniew Bodek 		 PCIE_PORT_DEV_CTRL_STATUS_CORR_ERR_REPORT_EN : 0) |
2798f4b37ed0SZbigniew Bodek 		(params->enabled_uncorr_non_fatal_err ?
2799f4b37ed0SZbigniew Bodek 		 PCIE_PORT_DEV_CTRL_STATUS_NON_FTL_ERR_REPORT_EN : 0) |
2800f4b37ed0SZbigniew Bodek 		(params->enabled_uncorr_fatal_err ?
2801f4b37ed0SZbigniew Bodek 		 PCIE_PORT_DEV_CTRL_STATUS_FTL_ERR_REPORT_EN : 0) |
2802f4b37ed0SZbigniew Bodek 		((params->enabled_uncorr_non_fatal_err &
2803f4b37ed0SZbigniew Bodek 		  AL_PCIE_AER_UNCORR_UNSUPRT_REQ_ERR) ?
2804f4b37ed0SZbigniew Bodek 		 PCIE_PORT_DEV_CTRL_STATUS_UNSUP_REQ_REPORT_EN : 0) |
2805f4b37ed0SZbigniew Bodek 		((params->enabled_uncorr_fatal_err &
2806f4b37ed0SZbigniew Bodek 		  AL_PCIE_AER_UNCORR_UNSUPRT_REQ_ERR) ?
2807f4b37ed0SZbigniew Bodek 		 PCIE_PORT_DEV_CTRL_STATUS_UNSUP_REQ_REPORT_EN : 0));
2808f4b37ed0SZbigniew Bodek 
2809f4b37ed0SZbigniew Bodek 	return 0;
2810f4b37ed0SZbigniew Bodek }
2811f4b37ed0SZbigniew Bodek 
2812*3fc36ee0SWojciech Macek /** AER uncorrectable errors get and clear */
2813*3fc36ee0SWojciech Macek static unsigned int
al_pcie_aer_uncorr_get_and_clear_aux(struct al_pcie_port * pcie_port,unsigned int pf_num)2814*3fc36ee0SWojciech Macek al_pcie_aer_uncorr_get_and_clear_aux(
2815*3fc36ee0SWojciech Macek 		struct al_pcie_port		*pcie_port,
2816*3fc36ee0SWojciech Macek 		unsigned int	pf_num)
2817f4b37ed0SZbigniew Bodek {
2818*3fc36ee0SWojciech Macek 	struct al_pcie_regs *regs = pcie_port->regs;
2819*3fc36ee0SWojciech Macek 	struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pf_num].aer;
2820f4b37ed0SZbigniew Bodek 	uint32_t reg_val;
2821f4b37ed0SZbigniew Bodek 
2822f4b37ed0SZbigniew Bodek 	reg_val = al_reg_read32(&aer_regs->uncorr_err_stat);
2823f4b37ed0SZbigniew Bodek 	al_reg_write32(&aer_regs->uncorr_err_stat, reg_val);
2824f4b37ed0SZbigniew Bodek 
2825f4b37ed0SZbigniew Bodek 	return reg_val;
2826f4b37ed0SZbigniew Bodek }
2827f4b37ed0SZbigniew Bodek 
2828*3fc36ee0SWojciech Macek /** AER correctable errors get and clear */
2829*3fc36ee0SWojciech Macek static unsigned int
al_pcie_aer_corr_get_and_clear_aux(struct al_pcie_port * pcie_port,unsigned int pf_num)2830*3fc36ee0SWojciech Macek al_pcie_aer_corr_get_and_clear_aux(
2831*3fc36ee0SWojciech Macek 		struct al_pcie_port		*pcie_port,
2832*3fc36ee0SWojciech Macek 		unsigned int	pf_num)
2833f4b37ed0SZbigniew Bodek {
2834*3fc36ee0SWojciech Macek 	struct al_pcie_regs *regs = pcie_port->regs;
2835*3fc36ee0SWojciech Macek 	struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pf_num].aer;
2836f4b37ed0SZbigniew Bodek 	uint32_t reg_val;
2837f4b37ed0SZbigniew Bodek 
2838f4b37ed0SZbigniew Bodek 	reg_val = al_reg_read32(&aer_regs->corr_err_stat);
2839f4b37ed0SZbigniew Bodek 	al_reg_write32(&aer_regs->corr_err_stat, reg_val);
2840f4b37ed0SZbigniew Bodek 
2841f4b37ed0SZbigniew Bodek 	return reg_val;
2842f4b37ed0SZbigniew Bodek }
2843f4b37ed0SZbigniew Bodek 
2844f4b37ed0SZbigniew Bodek #if (AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS != 4)
2845f4b37ed0SZbigniew Bodek #error Wrong assumption!
2846f4b37ed0SZbigniew Bodek #endif
2847f4b37ed0SZbigniew Bodek 
2848f4b37ed0SZbigniew Bodek /** AER get the header for the TLP corresponding to a detected error */
2849*3fc36ee0SWojciech Macek static void
al_pcie_aer_err_tlp_hdr_get_aux(struct al_pcie_port * pcie_port,unsigned int pf_num,uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS])2850*3fc36ee0SWojciech Macek al_pcie_aer_err_tlp_hdr_get_aux(
2851*3fc36ee0SWojciech Macek 		struct al_pcie_port		*pcie_port,
2852*3fc36ee0SWojciech Macek 		unsigned int	pf_num,
2853f4b37ed0SZbigniew Bodek 	uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS])
2854f4b37ed0SZbigniew Bodek {
2855*3fc36ee0SWojciech Macek 	struct al_pcie_regs *regs = pcie_port->regs;
2856*3fc36ee0SWojciech Macek 	struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pf_num].aer;
2857f4b37ed0SZbigniew Bodek 	int i;
2858f4b37ed0SZbigniew Bodek 
2859f4b37ed0SZbigniew Bodek 	for (i = 0; i < AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS; i++)
2860f4b37ed0SZbigniew Bodek 		hdr[i] = al_reg_read32(&aer_regs->header_log[i]);
2861f4b37ed0SZbigniew Bodek }
2862f4b37ed0SZbigniew Bodek 
2863*3fc36ee0SWojciech Macek /******************** EP AER functions **********************/
2864*3fc36ee0SWojciech Macek /** configure EP physical function AER capability */
al_pcie_aer_config(struct al_pcie_pf * pcie_pf,struct al_pcie_aer_params * params)2865*3fc36ee0SWojciech Macek int al_pcie_aer_config(
2866*3fc36ee0SWojciech Macek 		struct al_pcie_pf *pcie_pf,
2867*3fc36ee0SWojciech Macek 		struct al_pcie_aer_params	*params)
2868*3fc36ee0SWojciech Macek {
2869*3fc36ee0SWojciech Macek 	al_assert(pcie_pf);
2870*3fc36ee0SWojciech Macek 	al_assert(params);
2871*3fc36ee0SWojciech Macek 
2872*3fc36ee0SWojciech Macek 	return al_pcie_aer_config_aux(
2873*3fc36ee0SWojciech Macek 			pcie_pf->pcie_port, pcie_pf->pf_num, params);
2874*3fc36ee0SWojciech Macek }
2875*3fc36ee0SWojciech Macek 
2876*3fc36ee0SWojciech Macek /** EP physical function AER uncorrectable errors get and clear */
al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf * pcie_pf)2877*3fc36ee0SWojciech Macek unsigned int al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf *pcie_pf)
2878*3fc36ee0SWojciech Macek {
2879*3fc36ee0SWojciech Macek 	al_assert(pcie_pf);
2880*3fc36ee0SWojciech Macek 
2881*3fc36ee0SWojciech Macek 	return al_pcie_aer_uncorr_get_and_clear_aux(
2882*3fc36ee0SWojciech Macek 			pcie_pf->pcie_port, pcie_pf->pf_num);
2883*3fc36ee0SWojciech Macek }
2884*3fc36ee0SWojciech Macek 
2885*3fc36ee0SWojciech Macek /** EP physical function AER correctable errors get and clear */
al_pcie_aer_corr_get_and_clear(struct al_pcie_pf * pcie_pf)2886*3fc36ee0SWojciech Macek unsigned int al_pcie_aer_corr_get_and_clear(struct al_pcie_pf *pcie_pf)
2887*3fc36ee0SWojciech Macek {
2888*3fc36ee0SWojciech Macek 	al_assert(pcie_pf);
2889*3fc36ee0SWojciech Macek 
2890*3fc36ee0SWojciech Macek 	return al_pcie_aer_corr_get_and_clear_aux(
2891*3fc36ee0SWojciech Macek 			pcie_pf->pcie_port, pcie_pf->pf_num);
2892*3fc36ee0SWojciech Macek }
2893*3fc36ee0SWojciech Macek 
2894*3fc36ee0SWojciech Macek /**
2895*3fc36ee0SWojciech Macek  * EP physical function AER get the header for
2896*3fc36ee0SWojciech Macek  * the TLP corresponding to a detected error
2897*3fc36ee0SWojciech Macek  * */
al_pcie_aer_err_tlp_hdr_get(struct al_pcie_pf * pcie_pf,uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS])2898*3fc36ee0SWojciech Macek void al_pcie_aer_err_tlp_hdr_get(
2899*3fc36ee0SWojciech Macek 		struct al_pcie_pf *pcie_pf,
2900*3fc36ee0SWojciech Macek 		uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS])
2901*3fc36ee0SWojciech Macek {
2902*3fc36ee0SWojciech Macek 	al_assert(pcie_pf);
2903*3fc36ee0SWojciech Macek 	al_assert(hdr);
2904*3fc36ee0SWojciech Macek 
2905*3fc36ee0SWojciech Macek 	al_pcie_aer_err_tlp_hdr_get_aux(
2906*3fc36ee0SWojciech Macek 			pcie_pf->pcie_port, pcie_pf->pf_num, hdr);
2907*3fc36ee0SWojciech Macek }
2908*3fc36ee0SWojciech Macek 
2909*3fc36ee0SWojciech Macek /******************** RC AER functions **********************/
2910*3fc36ee0SWojciech Macek /** configure RC port AER capability */
al_pcie_port_aer_config(struct al_pcie_port * pcie_port,struct al_pcie_aer_params * params)2911*3fc36ee0SWojciech Macek int al_pcie_port_aer_config(
2912*3fc36ee0SWojciech Macek 		struct al_pcie_port		*pcie_port,
2913*3fc36ee0SWojciech Macek 		struct al_pcie_aer_params	*params)
2914*3fc36ee0SWojciech Macek {
2915*3fc36ee0SWojciech Macek 	al_assert(pcie_port);
2916*3fc36ee0SWojciech Macek 	al_assert(params);
2917*3fc36ee0SWojciech Macek 
2918*3fc36ee0SWojciech Macek 	/**
2919*3fc36ee0SWojciech Macek 	* For RC mode there's no PFs (neither PF handles),
2920*3fc36ee0SWojciech Macek 	* therefore PF#0 is used
2921*3fc36ee0SWojciech Macek 	* */
2922*3fc36ee0SWojciech Macek 	return al_pcie_aer_config_aux(pcie_port, 0, params);
2923*3fc36ee0SWojciech Macek }
2924*3fc36ee0SWojciech Macek 
2925*3fc36ee0SWojciech Macek /** RC port AER uncorrectable errors get and clear */
al_pcie_port_aer_uncorr_get_and_clear(struct al_pcie_port * pcie_port)2926*3fc36ee0SWojciech Macek unsigned int al_pcie_port_aer_uncorr_get_and_clear(
2927*3fc36ee0SWojciech Macek 		struct al_pcie_port		*pcie_port)
2928*3fc36ee0SWojciech Macek {
2929*3fc36ee0SWojciech Macek 	al_assert(pcie_port);
2930*3fc36ee0SWojciech Macek 
2931*3fc36ee0SWojciech Macek 	/**
2932*3fc36ee0SWojciech Macek 	* For RC mode there's no PFs (neither PF handles),
2933*3fc36ee0SWojciech Macek 	* therefore PF#0 is used
2934*3fc36ee0SWojciech Macek 	* */
2935*3fc36ee0SWojciech Macek 	return al_pcie_aer_uncorr_get_and_clear_aux(pcie_port, 0);
2936*3fc36ee0SWojciech Macek }
2937*3fc36ee0SWojciech Macek 
2938*3fc36ee0SWojciech Macek /** RC port AER correctable errors get and clear */
al_pcie_port_aer_corr_get_and_clear(struct al_pcie_port * pcie_port)2939*3fc36ee0SWojciech Macek unsigned int al_pcie_port_aer_corr_get_and_clear(
2940*3fc36ee0SWojciech Macek 		struct al_pcie_port		*pcie_port)
2941*3fc36ee0SWojciech Macek {
2942*3fc36ee0SWojciech Macek 	al_assert(pcie_port);
2943*3fc36ee0SWojciech Macek 
2944*3fc36ee0SWojciech Macek 	/**
2945*3fc36ee0SWojciech Macek 	* For RC mode there's no PFs (neither PF handles),
2946*3fc36ee0SWojciech Macek 	* therefore PF#0 is used
2947*3fc36ee0SWojciech Macek 	* */
2948*3fc36ee0SWojciech Macek 	return al_pcie_aer_corr_get_and_clear_aux(pcie_port, 0);
2949*3fc36ee0SWojciech Macek }
2950*3fc36ee0SWojciech Macek 
2951*3fc36ee0SWojciech Macek /** RC port AER get the header for the TLP corresponding to a detected error */
al_pcie_port_aer_err_tlp_hdr_get(struct al_pcie_port * pcie_port,uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS])2952*3fc36ee0SWojciech Macek void al_pcie_port_aer_err_tlp_hdr_get(
2953*3fc36ee0SWojciech Macek 		struct al_pcie_port		*pcie_port,
2954*3fc36ee0SWojciech Macek 		uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS])
2955*3fc36ee0SWojciech Macek {
2956*3fc36ee0SWojciech Macek 	al_assert(pcie_port);
2957*3fc36ee0SWojciech Macek 	al_assert(hdr);
2958*3fc36ee0SWojciech Macek 
2959*3fc36ee0SWojciech Macek 	/**
2960*3fc36ee0SWojciech Macek 	* For RC mode there's no PFs (neither PF handles),
2961*3fc36ee0SWojciech Macek 	* therefore PF#0 is used
2962*3fc36ee0SWojciech Macek 	* */
2963*3fc36ee0SWojciech Macek 	al_pcie_aer_err_tlp_hdr_get_aux(pcie_port, 0, hdr);
2964*3fc36ee0SWojciech Macek }
2965*3fc36ee0SWojciech Macek 
2966f4b37ed0SZbigniew Bodek /********************** Loopback mode (RC and Endpoint modes) ************/
2967f4b37ed0SZbigniew Bodek 
2968f4b37ed0SZbigniew Bodek /** enter local pipe loopback mode */
2969f4b37ed0SZbigniew Bodek int
al_pcie_local_pipe_loopback_enter(struct al_pcie_port * pcie_port)2970f4b37ed0SZbigniew Bodek al_pcie_local_pipe_loopback_enter(struct al_pcie_port *pcie_port)
2971f4b37ed0SZbigniew Bodek {
2972f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
2973f4b37ed0SZbigniew Bodek 
2974f4b37ed0SZbigniew Bodek 	al_dbg("PCIe %d: Enter LOCAL PIPE Loopback mode", pcie_port->port_id);
2975f4b37ed0SZbigniew Bodek 
2976f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(&regs->port_regs->pipe_loopback_ctrl,
2977f4b37ed0SZbigniew Bodek 			      1 << PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT,
2978f4b37ed0SZbigniew Bodek 			      1 << PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT);
2979f4b37ed0SZbigniew Bodek 
2980f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(&regs->port_regs->port_link_ctrl,
2981f4b37ed0SZbigniew Bodek 			      1 << PCIE_PORT_LINK_CTRL_LB_EN_SHIFT,
2982f4b37ed0SZbigniew Bodek 			      1 << PCIE_PORT_LINK_CTRL_LB_EN_SHIFT);
2983f4b37ed0SZbigniew Bodek 
2984f4b37ed0SZbigniew Bodek 	return 0;
2985f4b37ed0SZbigniew Bodek }
2986f4b37ed0SZbigniew Bodek 
2987f4b37ed0SZbigniew Bodek /**
2988f4b37ed0SZbigniew Bodek  * @brief exit local pipe loopback mode
2989f4b37ed0SZbigniew Bodek  *
2990f4b37ed0SZbigniew Bodek  * @param pcie_port	pcie port handle
2991f4b37ed0SZbigniew Bodek  * @return		0 if no error found
2992f4b37ed0SZbigniew Bodek  */
2993f4b37ed0SZbigniew Bodek int
al_pcie_local_pipe_loopback_exit(struct al_pcie_port * pcie_port)2994f4b37ed0SZbigniew Bodek al_pcie_local_pipe_loopback_exit(struct al_pcie_port *pcie_port)
2995f4b37ed0SZbigniew Bodek {
2996f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
2997f4b37ed0SZbigniew Bodek 
2998f4b37ed0SZbigniew Bodek 	al_dbg("PCIe %d: Exit LOCAL PIPE Loopback mode", pcie_port->port_id);
2999f4b37ed0SZbigniew Bodek 
3000f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(&regs->port_regs->pipe_loopback_ctrl,
3001f4b37ed0SZbigniew Bodek 			      1 << PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT,
3002f4b37ed0SZbigniew Bodek 			      0);
3003f4b37ed0SZbigniew Bodek 
3004f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(&regs->port_regs->port_link_ctrl,
3005f4b37ed0SZbigniew Bodek 			      1 << PCIE_PORT_LINK_CTRL_LB_EN_SHIFT,
3006f4b37ed0SZbigniew Bodek 			      0);
3007f4b37ed0SZbigniew Bodek 	return 0;
3008f4b37ed0SZbigniew Bodek }
3009f4b37ed0SZbigniew Bodek 
3010f4b37ed0SZbigniew Bodek /** enter remote loopback mode */
3011f4b37ed0SZbigniew Bodek int
al_pcie_remote_loopback_enter(struct al_pcie_port * pcie_port)3012f4b37ed0SZbigniew Bodek al_pcie_remote_loopback_enter(struct al_pcie_port *pcie_port)
3013f4b37ed0SZbigniew Bodek {
3014f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
3015f4b37ed0SZbigniew Bodek 
3016f4b37ed0SZbigniew Bodek 	al_dbg("PCIe %d: Enter REMOTE Loopback mode", pcie_port->port_id);
3017f4b37ed0SZbigniew Bodek 
3018f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(&regs->port_regs->port_link_ctrl,
3019f4b37ed0SZbigniew Bodek 			      1 << PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT,
3020f4b37ed0SZbigniew Bodek 			      1 << PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT);
3021f4b37ed0SZbigniew Bodek 
3022f4b37ed0SZbigniew Bodek 	return 0;
3023f4b37ed0SZbigniew Bodek }
3024f4b37ed0SZbigniew Bodek 
3025f4b37ed0SZbigniew Bodek /**
3026f4b37ed0SZbigniew Bodek  * @brief   exit remote loopback mode
3027f4b37ed0SZbigniew Bodek  *
3028f4b37ed0SZbigniew Bodek  * @param   pcie_port pcie port handle
3029f4b37ed0SZbigniew Bodek  * @return  0 if no error found
3030f4b37ed0SZbigniew Bodek  */
3031f4b37ed0SZbigniew Bodek int
al_pcie_remote_loopback_exit(struct al_pcie_port * pcie_port)3032f4b37ed0SZbigniew Bodek al_pcie_remote_loopback_exit(struct al_pcie_port *pcie_port)
3033f4b37ed0SZbigniew Bodek {
3034f4b37ed0SZbigniew Bodek 	struct al_pcie_regs *regs = pcie_port->regs;
3035f4b37ed0SZbigniew Bodek 
3036f4b37ed0SZbigniew Bodek 	al_dbg("PCIe %d: Exit REMOTE Loopback mode", pcie_port->port_id);
3037f4b37ed0SZbigniew Bodek 
3038f4b37ed0SZbigniew Bodek 	al_reg_write32_masked(&regs->port_regs->port_link_ctrl,
3039f4b37ed0SZbigniew Bodek 			      1 << PCIE_PORT_LINK_CTRL_LB_EN_SHIFT,
3040f4b37ed0SZbigniew Bodek 			      0);
3041f4b37ed0SZbigniew Bodek 	return 0;
3042f4b37ed0SZbigniew Bodek }
3043