xref: /rk3399_rockchip-uboot/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c (revision f77309d34325369dbdf0bf62387c9e974f1b37da)
1edb47025SStefan Roese /*
2edb47025SStefan Roese  * Copyright (C) Marvell International Ltd. and its affiliates
3edb47025SStefan Roese  *
4edb47025SStefan Roese  * SPDX-License-Identifier:	GPL-2.0
5edb47025SStefan Roese  */
6edb47025SStefan Roese 
7edb47025SStefan Roese #include <common.h>
8edb47025SStefan Roese #include <spl.h>
9edb47025SStefan Roese #include <asm/io.h>
10edb47025SStefan Roese #include <asm/arch/cpu.h>
11edb47025SStefan Roese #include <asm/arch/soc.h>
12edb47025SStefan Roese 
13edb47025SStefan Roese #include "ctrl_pex.h"
14edb47025SStefan Roese #include "sys_env_lib.h"
15edb47025SStefan Roese 
board_pex_config(void)16*2ad43094SMario Six __weak void board_pex_config(void)
17*2ad43094SMario Six {
18*2ad43094SMario Six 	/* nothing in this weak default implementation */
19*2ad43094SMario Six }
20*2ad43094SMario Six 
hws_pex_config(const struct serdes_map * serdes_map,u8 count)21490753acSKevin Smith int hws_pex_config(const struct serdes_map *serdes_map, u8 count)
22edb47025SStefan Roese {
23edb47025SStefan Roese 	u32 pex_idx, tmp, next_busno, first_busno, temp_pex_reg,
24edb47025SStefan Roese 	    temp_reg, addr, dev_id, ctrl_mode;
25edb47025SStefan Roese 	enum serdes_type serdes_type;
26490753acSKevin Smith 	u32 idx;
27edb47025SStefan Roese 
28edb47025SStefan Roese 	DEBUG_INIT_FULL_S("\n### hws_pex_config ###\n");
29edb47025SStefan Roese 
30490753acSKevin Smith 	for (idx = 0; idx < count; idx++) {
31edb47025SStefan Roese 		serdes_type = serdes_map[idx].serdes_type;
32edb47025SStefan Roese 		/* configuration for PEX only */
33edb47025SStefan Roese 		if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
34edb47025SStefan Roese 		    (serdes_type != PEX2) && (serdes_type != PEX3))
35edb47025SStefan Roese 			continue;
36edb47025SStefan Roese 
37edb47025SStefan Roese 		if ((serdes_type != PEX0) &&
38edb47025SStefan Roese 		    ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
39edb47025SStefan Roese 		     (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
40edb47025SStefan Roese 			/* for PEX by4 - relevant for the first port only */
41edb47025SStefan Roese 			continue;
42edb47025SStefan Roese 		}
43edb47025SStefan Roese 
44edb47025SStefan Roese 		pex_idx = serdes_type - PEX0;
45edb47025SStefan Roese 		tmp = reg_read(PEX_CAPABILITIES_REG(pex_idx));
46edb47025SStefan Roese 		tmp &= ~(0xf << 20);
47edb47025SStefan Roese 		tmp |= (0x4 << 20);
48edb47025SStefan Roese 		reg_write(PEX_CAPABILITIES_REG(pex_idx), tmp);
49edb47025SStefan Roese 	}
50edb47025SStefan Roese 
51edb47025SStefan Roese 	tmp = reg_read(SOC_CTRL_REG);
52edb47025SStefan Roese 	tmp &= ~0x03;
53edb47025SStefan Roese 
54490753acSKevin Smith 	for (idx = 0; idx < count; idx++) {
55edb47025SStefan Roese 		serdes_type = serdes_map[idx].serdes_type;
56edb47025SStefan Roese 		if ((serdes_type != PEX0) &&
57edb47025SStefan Roese 		    ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
58edb47025SStefan Roese 		     (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
59edb47025SStefan Roese 			/* for PEX by4 - relevant for the first port only */
60edb47025SStefan Roese 			continue;
61edb47025SStefan Roese 		}
62edb47025SStefan Roese 
63edb47025SStefan Roese 		switch (serdes_type) {
64edb47025SStefan Roese 		case PEX0:
65edb47025SStefan Roese 			tmp |= 0x1 << PCIE0_ENABLE_OFFS;
66edb47025SStefan Roese 			break;
67edb47025SStefan Roese 		case PEX1:
68edb47025SStefan Roese 			tmp |= 0x1 << PCIE1_ENABLE_OFFS;
69edb47025SStefan Roese 			break;
70edb47025SStefan Roese 		case PEX2:
71edb47025SStefan Roese 			tmp |= 0x1 << PCIE2_ENABLE_OFFS;
72edb47025SStefan Roese 			break;
73edb47025SStefan Roese 		case PEX3:
74edb47025SStefan Roese 			tmp |= 0x1 << PCIE3_ENABLE_OFFS;
75edb47025SStefan Roese 			break;
76edb47025SStefan Roese 		default:
77edb47025SStefan Roese 			break;
78edb47025SStefan Roese 		}
79edb47025SStefan Roese 	}
80edb47025SStefan Roese 
81edb47025SStefan Roese 	reg_write(SOC_CTRL_REG, tmp);
82edb47025SStefan Roese 
83edb47025SStefan Roese 	/* Support gen1/gen2 */
84edb47025SStefan Roese 	DEBUG_INIT_FULL_S("Support gen1/gen2\n");
85*2ad43094SMario Six 
86*2ad43094SMario Six 	board_pex_config();
87*2ad43094SMario Six 
88edb47025SStefan Roese 	next_busno = 0;
89edb47025SStefan Roese 	mdelay(150);
90edb47025SStefan Roese 
91490753acSKevin Smith 	for (idx = 0; idx < count; idx++) {
92edb47025SStefan Roese 		serdes_type = serdes_map[idx].serdes_type;
93edb47025SStefan Roese 		DEBUG_INIT_FULL_S(" serdes_type=0x");
94edb47025SStefan Roese 		DEBUG_INIT_FULL_D(serdes_type, 8);
95edb47025SStefan Roese 		DEBUG_INIT_FULL_S("\n");
96edb47025SStefan Roese 		DEBUG_INIT_FULL_S(" idx=0x");
97edb47025SStefan Roese 		DEBUG_INIT_FULL_D(idx, 8);
98edb47025SStefan Roese 		DEBUG_INIT_FULL_S("\n");
99edb47025SStefan Roese 
100edb47025SStefan Roese 		/* Configuration for PEX only */
101edb47025SStefan Roese 		if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
102edb47025SStefan Roese 		    (serdes_type != PEX2) && (serdes_type != PEX3))
103edb47025SStefan Roese 			continue;
104edb47025SStefan Roese 
105edb47025SStefan Roese 		if ((serdes_type != PEX0) &&
106edb47025SStefan Roese 		    ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
107edb47025SStefan Roese 		     (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
108edb47025SStefan Roese 			/* for PEX by4 - relevant for the first port only */
109edb47025SStefan Roese 			continue;
110edb47025SStefan Roese 		}
111edb47025SStefan Roese 
112edb47025SStefan Roese 		pex_idx = serdes_type - PEX0;
113edb47025SStefan Roese 		tmp = reg_read(PEX_DBG_STATUS_REG(pex_idx));
114edb47025SStefan Roese 
115edb47025SStefan Roese 		first_busno = next_busno;
116edb47025SStefan Roese 		if ((tmp & 0x7f) != 0x7e) {
117edb47025SStefan Roese 			DEBUG_INIT_S("PCIe, Idx ");
118edb47025SStefan Roese 			DEBUG_INIT_D(pex_idx, 1);
119edb47025SStefan Roese 			DEBUG_INIT_S(": detected no link\n");
120edb47025SStefan Roese 			continue;
121edb47025SStefan Roese 		}
122edb47025SStefan Roese 
123edb47025SStefan Roese 		next_busno++;
124edb47025SStefan Roese 		temp_pex_reg = reg_read((PEX_CFG_DIRECT_ACCESS
125edb47025SStefan Roese 					 (pex_idx, PEX_LINK_CAPABILITY_REG)));
126edb47025SStefan Roese 		temp_pex_reg &= 0xf;
127edb47025SStefan Roese 		if (temp_pex_reg != 0x2)
128edb47025SStefan Roese 			continue;
129edb47025SStefan Roese 
130edb47025SStefan Roese 		temp_reg = (reg_read(PEX_CFG_DIRECT_ACCESS(
131edb47025SStefan Roese 					     pex_idx,
132edb47025SStefan Roese 					     PEX_LINK_CTRL_STAT_REG)) &
133edb47025SStefan Roese 			    0xf0000) >> 16;
134edb47025SStefan Roese 
135edb47025SStefan Roese 		/* Check if the link established is GEN1 */
136edb47025SStefan Roese 		DEBUG_INIT_FULL_S
137edb47025SStefan Roese 			("Checking if the link established is gen1\n");
138edb47025SStefan Roese 		if (temp_reg != 0x1)
139edb47025SStefan Roese 			continue;
140edb47025SStefan Roese 
141edb47025SStefan Roese 		pex_local_bus_num_set(pex_idx, first_busno);
142edb47025SStefan Roese 		pex_local_dev_num_set(pex_idx, 1);
143edb47025SStefan Roese 		DEBUG_INIT_FULL_S("PCIe, Idx ");
144edb47025SStefan Roese 		DEBUG_INIT_FULL_D(pex_idx, 1);
145edb47025SStefan Roese 
146edb47025SStefan Roese 		DEBUG_INIT_S(":** Link is Gen1, check the EP capability\n");
147edb47025SStefan Roese 		/* link is Gen1, check the EP capability */
148edb47025SStefan Roese 		addr = pex_config_read(pex_idx, first_busno, 0, 0, 0x34) & 0xff;
149edb47025SStefan Roese 		DEBUG_INIT_FULL_C("pex_config_read: return addr=0x%x", addr, 4);
150edb47025SStefan Roese 		if (addr == 0xff) {
151edb47025SStefan Roese 			DEBUG_INIT_FULL_C
152edb47025SStefan Roese 				("pex_config_read: return 0xff -->PCIe (%d): Detected No Link.",
153edb47025SStefan Roese 				 pex_idx, 1);
154edb47025SStefan Roese 			continue;
155edb47025SStefan Roese 		}
156edb47025SStefan Roese 
157edb47025SStefan Roese 		while ((pex_config_read(pex_idx, first_busno, 0, 0, addr)
158edb47025SStefan Roese 			& 0xff) != 0x10) {
159edb47025SStefan Roese 			addr = (pex_config_read(pex_idx, first_busno, 0,
160edb47025SStefan Roese 						0, addr) & 0xff00) >> 8;
161edb47025SStefan Roese 		}
162edb47025SStefan Roese 
163edb47025SStefan Roese 		/* Check for Gen2 and above */
164edb47025SStefan Roese 		if ((pex_config_read(pex_idx, first_busno, 0, 0,
165edb47025SStefan Roese 				     addr + 0xc) & 0xf) < 0x2) {
166edb47025SStefan Roese 			DEBUG_INIT_S("PCIe, Idx ");
167edb47025SStefan Roese 			DEBUG_INIT_D(pex_idx, 1);
168edb47025SStefan Roese 			DEBUG_INIT_S(": remains Gen1\n");
169edb47025SStefan Roese 			continue;
170edb47025SStefan Roese 		}
171edb47025SStefan Roese 
172edb47025SStefan Roese 		tmp = reg_read(PEX_LINK_CTRL_STATUS2_REG(pex_idx));
173edb47025SStefan Roese 		DEBUG_RD_REG(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
174edb47025SStefan Roese 		tmp &= ~(BIT(0) | BIT(1));
175edb47025SStefan Roese 		tmp |= BIT(1);
176edb47025SStefan Roese 		tmp |= BIT(6);	/* Select Deemphasize (-3.5d_b) */
177edb47025SStefan Roese 		reg_write(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
178edb47025SStefan Roese 		DEBUG_WR_REG(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
179edb47025SStefan Roese 
180edb47025SStefan Roese 		tmp = reg_read(PEX_CTRL_REG(pex_idx));
181edb47025SStefan Roese 		DEBUG_RD_REG(PEX_CTRL_REG(pex_idx), tmp);
182edb47025SStefan Roese 		tmp |= BIT(10);
183edb47025SStefan Roese 		reg_write(PEX_CTRL_REG(pex_idx), tmp);
184edb47025SStefan Roese 		DEBUG_WR_REG(PEX_CTRL_REG(pex_idx), tmp);
185edb47025SStefan Roese 
186edb47025SStefan Roese 		/*
187edb47025SStefan Roese 		 * We need to wait 10ms before reading the PEX_DBG_STATUS_REG
188edb47025SStefan Roese 		 * in order not to read the status of the former state
189edb47025SStefan Roese 		 */
190edb47025SStefan Roese 		mdelay(10);
191edb47025SStefan Roese 
192edb47025SStefan Roese 		DEBUG_INIT_S("PCIe, Idx ");
193edb47025SStefan Roese 		DEBUG_INIT_D(pex_idx, 1);
194edb47025SStefan Roese 		DEBUG_INIT_S
195c90d7ab6SChris Packham 			(": Link upgraded to Gen2 based on client capabilities\n");
196edb47025SStefan Roese 	}
197edb47025SStefan Roese 
198edb47025SStefan Roese 	/* Update pex DEVICE ID */
199edb47025SStefan Roese 	ctrl_mode = sys_env_model_get();
200edb47025SStefan Roese 
201490753acSKevin Smith 	for (idx = 0; idx < count; idx++) {
202edb47025SStefan Roese 		serdes_type = serdes_map[idx].serdes_type;
203edb47025SStefan Roese 		/* configuration for PEX only */
204edb47025SStefan Roese 		if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
205edb47025SStefan Roese 		    (serdes_type != PEX2) && (serdes_type != PEX3))
206edb47025SStefan Roese 			continue;
207edb47025SStefan Roese 
208edb47025SStefan Roese 		if ((serdes_type != PEX0) &&
209edb47025SStefan Roese 		    ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
210edb47025SStefan Roese 		     (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
211edb47025SStefan Roese 			/* for PEX by4 - relevant for the first port only */
212edb47025SStefan Roese 			continue;
213edb47025SStefan Roese 		}
214edb47025SStefan Roese 
215edb47025SStefan Roese 		pex_idx = serdes_type - PEX0;
216edb47025SStefan Roese 		dev_id = reg_read(PEX_CFG_DIRECT_ACCESS
217edb47025SStefan Roese 				  (pex_idx, PEX_DEVICE_AND_VENDOR_ID));
218edb47025SStefan Roese 		dev_id &= 0xffff;
219edb47025SStefan Roese 		dev_id |= ((ctrl_mode << 16) & 0xffff0000);
220edb47025SStefan Roese 		reg_write(PEX_CFG_DIRECT_ACCESS
221edb47025SStefan Roese 			  (pex_idx, PEX_DEVICE_AND_VENDOR_ID), dev_id);
222edb47025SStefan Roese 	}
223edb47025SStefan Roese 	DEBUG_INIT_FULL_C("Update PEX Device ID ", ctrl_mode, 4);
224edb47025SStefan Roese 
225edb47025SStefan Roese 	return MV_OK;
226edb47025SStefan Roese }
227edb47025SStefan Roese 
pex_local_bus_num_set(u32 pex_if,u32 bus_num)228edb47025SStefan Roese int pex_local_bus_num_set(u32 pex_if, u32 bus_num)
229edb47025SStefan Roese {
230edb47025SStefan Roese 	u32 pex_status;
231edb47025SStefan Roese 
232edb47025SStefan Roese 	DEBUG_INIT_FULL_S("\n### pex_local_bus_num_set ###\n");
233edb47025SStefan Roese 
234edb47025SStefan Roese 	if (bus_num >= MAX_PEX_BUSSES) {
235edb47025SStefan Roese 		DEBUG_INIT_C("pex_local_bus_num_set: Illegal bus number %d\n",
236edb47025SStefan Roese 			     bus_num, 4);
237edb47025SStefan Roese 		return MV_BAD_PARAM;
238edb47025SStefan Roese 	}
239edb47025SStefan Roese 
240edb47025SStefan Roese 	pex_status = reg_read(PEX_STATUS_REG(pex_if));
241edb47025SStefan Roese 	pex_status &= ~PXSR_PEX_BUS_NUM_MASK;
242edb47025SStefan Roese 	pex_status |=
243edb47025SStefan Roese 	    (bus_num << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
244edb47025SStefan Roese 	reg_write(PEX_STATUS_REG(pex_if), pex_status);
245edb47025SStefan Roese 
246edb47025SStefan Roese 	return MV_OK;
247edb47025SStefan Roese }
248edb47025SStefan Roese 
pex_local_dev_num_set(u32 pex_if,u32 dev_num)249edb47025SStefan Roese int pex_local_dev_num_set(u32 pex_if, u32 dev_num)
250edb47025SStefan Roese {
251edb47025SStefan Roese 	u32 pex_status;
252edb47025SStefan Roese 
253edb47025SStefan Roese 	DEBUG_INIT_FULL_S("\n### pex_local_dev_num_set ###\n");
254edb47025SStefan Roese 
255edb47025SStefan Roese 	pex_status = reg_read(PEX_STATUS_REG(pex_if));
256edb47025SStefan Roese 	pex_status &= ~PXSR_PEX_DEV_NUM_MASK;
257edb47025SStefan Roese 	pex_status |=
258edb47025SStefan Roese 	    (dev_num << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
259edb47025SStefan Roese 	reg_write(PEX_STATUS_REG(pex_if), pex_status);
260edb47025SStefan Roese 
261edb47025SStefan Roese 	return MV_OK;
262edb47025SStefan Roese }
263edb47025SStefan Roese 
264edb47025SStefan Roese /*
265edb47025SStefan Roese  * pex_config_read - Read from configuration space
266edb47025SStefan Roese  *
267edb47025SStefan Roese  * DESCRIPTION:
268edb47025SStefan Roese  *       This function performs a 32 bit read from PEX configuration space.
269edb47025SStefan Roese  *       It supports both type 0 and type 1 of Configuration Transactions
270edb47025SStefan Roese  *       (local and over bridge). In order to read from local bus segment, use
271edb47025SStefan Roese  *       bus number retrieved from pex_local_bus_num_get(). Other bus numbers
272edb47025SStefan Roese  *       will result configuration transaction of type 1 (over bridge).
273edb47025SStefan Roese  *
274edb47025SStefan Roese  * INPUT:
275edb47025SStefan Roese  *       pex_if   - PEX interface number.
276edb47025SStefan Roese  *       bus      - PEX segment bus number.
277edb47025SStefan Roese  *       dev      - PEX device number.
278edb47025SStefan Roese  *       func     - Function number.
279edb47025SStefan Roese  *       reg_offs - Register offset.
280edb47025SStefan Roese  *
281edb47025SStefan Roese  * OUTPUT:
282edb47025SStefan Roese  *       None.
283edb47025SStefan Roese  *
284edb47025SStefan Roese  * RETURN:
285edb47025SStefan Roese  *       32bit register data, 0xffffffff on error
286edb47025SStefan Roese  */
pex_config_read(u32 pex_if,u32 bus,u32 dev,u32 func,u32 reg_off)287edb47025SStefan Roese u32 pex_config_read(u32 pex_if, u32 bus, u32 dev, u32 func, u32 reg_off)
288edb47025SStefan Roese {
289edb47025SStefan Roese 	u32 pex_data = 0;
290edb47025SStefan Roese 	u32 local_dev, local_bus;
291edb47025SStefan Roese 	u32 pex_status;
292edb47025SStefan Roese 
293edb47025SStefan Roese 	pex_status = reg_read(PEX_STATUS_REG(pex_if));
294edb47025SStefan Roese 	local_dev =
295edb47025SStefan Roese 	    ((pex_status & PXSR_PEX_DEV_NUM_MASK) >> PXSR_PEX_DEV_NUM_OFFS);
296edb47025SStefan Roese 	local_bus =
297edb47025SStefan Roese 	    ((pex_status & PXSR_PEX_BUS_NUM_MASK) >> PXSR_PEX_BUS_NUM_OFFS);
298edb47025SStefan Roese 
299edb47025SStefan Roese 	/*
300edb47025SStefan Roese 	 * In PCI Express we have only one device number
301edb47025SStefan Roese 	 * and this number is the first number we encounter
302edb47025SStefan Roese 	 * else that the local_dev
303edb47025SStefan Roese 	 * spec pex define return on config read/write on any device
304edb47025SStefan Roese 	 */
305edb47025SStefan Roese 	if (bus == local_bus) {
306edb47025SStefan Roese 		if (local_dev == 0) {
307edb47025SStefan Roese 			/*
308edb47025SStefan Roese 			 * if local dev is 0 then the first number we encounter
309edb47025SStefan Roese 			 * after 0 is 1
310edb47025SStefan Roese 			 */
311edb47025SStefan Roese 			if ((dev != 1) && (dev != local_dev))
312edb47025SStefan Roese 				return MV_ERROR;
313edb47025SStefan Roese 		} else {
314edb47025SStefan Roese 			/*
315edb47025SStefan Roese 			 * if local dev is not 0 then the first number we
316edb47025SStefan Roese 			 * encounter is 0
317edb47025SStefan Roese 			 */
318edb47025SStefan Roese 			if ((dev != 0) && (dev != local_dev))
319edb47025SStefan Roese 				return MV_ERROR;
320edb47025SStefan Roese 		}
321edb47025SStefan Roese 	}
322edb47025SStefan Roese 
323edb47025SStefan Roese 	/* Creating PEX address to be passed */
324edb47025SStefan Roese 	pex_data = (bus << PXCAR_BUS_NUM_OFFS);
325edb47025SStefan Roese 	pex_data |= (dev << PXCAR_DEVICE_NUM_OFFS);
326edb47025SStefan Roese 	pex_data |= (func << PXCAR_FUNC_NUM_OFFS);
327edb47025SStefan Roese 	/* Legacy register space */
328edb47025SStefan Roese 	pex_data |= (reg_off & PXCAR_REG_NUM_MASK);
329edb47025SStefan Roese 	/* Extended register space */
330edb47025SStefan Roese 	pex_data |= (((reg_off & PXCAR_REAL_EXT_REG_NUM_MASK) >>
331edb47025SStefan Roese 		      PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
332edb47025SStefan Roese 	pex_data |= PXCAR_CONFIG_EN;
333edb47025SStefan Roese 
334edb47025SStefan Roese 	/* Write the address to the PEX configuration address register */
335edb47025SStefan Roese 	reg_write(PEX_CFG_ADDR_REG(pex_if), pex_data);
336edb47025SStefan Roese 
337edb47025SStefan Roese 	/*
338edb47025SStefan Roese 	 * In order to let the PEX controller absorbed the address
339edb47025SStefan Roese 	 * of the read transaction we perform a validity check that
340edb47025SStefan Roese 	 * the address was written
341edb47025SStefan Roese 	 */
342edb47025SStefan Roese 	if (pex_data != reg_read(PEX_CFG_ADDR_REG(pex_if)))
343edb47025SStefan Roese 		return MV_ERROR;
344edb47025SStefan Roese 
345edb47025SStefan Roese 	/* Cleaning Master Abort */
346edb47025SStefan Roese 	reg_bit_set(PEX_CFG_DIRECT_ACCESS(pex_if, PEX_STATUS_AND_COMMAND),
347edb47025SStefan Roese 		    PXSAC_MABORT);
348edb47025SStefan Roese 	/* Read the Data returned in the PEX Data register */
349edb47025SStefan Roese 	pex_data = reg_read(PEX_CFG_DATA_REG(pex_if));
350edb47025SStefan Roese 
351edb47025SStefan Roese 	DEBUG_INIT_FULL_C(" --> ", pex_data, 4);
352edb47025SStefan Roese 
353edb47025SStefan Roese 	return pex_data;
354edb47025SStefan Roese }
355