xref: /rk3399_rockchip-uboot/board/theadorable/theadorable.c (revision 55e0306c92ea33721aeb0946eecf82f702954513)
1b20c38a9SStefan Roese /*
2b20c38a9SStefan Roese  * Copyright (C) 2015-2016 Stefan Roese <sr@denx.de>
3b20c38a9SStefan Roese  *
4b20c38a9SStefan Roese  * SPDX-License-Identifier:	GPL-2.0+
5b20c38a9SStefan Roese  */
6b20c38a9SStefan Roese 
7b20c38a9SStefan Roese #include <common.h>
8169a8550SStefan Roese #include <i2c.h>
9169a8550SStefan Roese #include <pci.h>
10ced0d849SStefan Roese #include <asm/gpio.h>
11b20c38a9SStefan Roese #include <asm/io.h>
12b20c38a9SStefan Roese #include <asm/arch/cpu.h>
13b20c38a9SStefan Roese #include <asm/arch/soc.h>
14169a8550SStefan Roese #include <linux/crc8.h>
15aea02abeSStefan Roese #include <linux/mbus.h>
16b20c38a9SStefan Roese #ifdef CONFIG_NET
17b20c38a9SStefan Roese #include <netdev.h>
18b20c38a9SStefan Roese #endif
19aea02abeSStefan Roese #include "theadorable.h"
20b20c38a9SStefan Roese 
21b20c38a9SStefan Roese #include "../drivers/ddr/marvell/axp/ddr3_hw_training.h"
22b20c38a9SStefan Roese #include "../arch/arm/mach-mvebu/serdes/axp/high_speed_env_spec.h"
23b20c38a9SStefan Roese 
24b20c38a9SStefan Roese DECLARE_GLOBAL_DATA_PTR;
25b20c38a9SStefan Roese 
26ced0d849SStefan Roese #define MV_USB_PHY_BASE			(MVEBU_AXP_USB_BASE + 0x800)
27ced0d849SStefan Roese #define PHY_CHANNEL_RX_CTRL0_REG(port, chan) \
28ced0d849SStefan Roese 	(MV_USB_PHY_BASE + ((port) << 12) + ((chan) << 6) + 0x8)
29ced0d849SStefan Roese 
30b20c38a9SStefan Roese #define THEADORABLE_GPP_OUT_ENA_LOW	0x00336780
31b20c38a9SStefan Roese #define THEADORABLE_GPP_OUT_ENA_MID	0x00003cf0
32b20c38a9SStefan Roese #define THEADORABLE_GPP_OUT_ENA_HIGH	(~(0x0))
33b20c38a9SStefan Roese 
34b20c38a9SStefan Roese #define THEADORABLE_GPP_OUT_VAL_LOW	0x2c0c983f
35b20c38a9SStefan Roese #define THEADORABLE_GPP_OUT_VAL_MID	0x0007000c
36b20c38a9SStefan Roese #define THEADORABLE_GPP_OUT_VAL_HIGH	0x00000000
37b20c38a9SStefan Roese 
38ced0d849SStefan Roese #define GPIO_USB0_PWR_ON		18
39ced0d849SStefan Roese #define GPIO_USB1_PWR_ON		19
40ced0d849SStefan Roese 
41169a8550SStefan Roese #define PEX_SWITCH_NOT_FOUNT_LIMIT	3
42169a8550SStefan Roese 
43169a8550SStefan Roese #define STM_I2C_BUS	1
44169a8550SStefan Roese #define STM_I2C_ADDR	0x27
45169a8550SStefan Roese #define REBOOT_DELAY	1000		/* reboot-delay in ms */
46169a8550SStefan Roese 
47b20c38a9SStefan Roese /* DDR3 static configuration */
48b20c38a9SStefan Roese static MV_DRAM_MC_INIT ddr3_theadorable[MV_MAX_DDR3_STATIC_SIZE] = {
49b20c38a9SStefan Roese 	{0x00001400, 0x7301ca28},	/* DDR SDRAM Configuration Register */
50b20c38a9SStefan Roese 	{0x00001404, 0x30000800},	/* Dunit Control Low Register */
51b20c38a9SStefan Roese 	{0x00001408, 0x44149887},	/* DDR SDRAM Timing (Low) Register */
52b20c38a9SStefan Roese 	{0x0000140C, 0x38d93fc7},	/* DDR SDRAM Timing (High) Register */
53b20c38a9SStefan Roese 	{0x00001410, 0x1b100001},	/* DDR SDRAM Address Control Register */
54b20c38a9SStefan Roese 	{0x00001424, 0x0000f3ff},	/* Dunit Control High Register */
55b20c38a9SStefan Roese 	{0x00001428, 0x000f8830},	/* ODT Timing (Low) Register */
56b20c38a9SStefan Roese 	{0x0000142C, 0x014c50f4},	/* DDR3 Timing Register */
57b20c38a9SStefan Roese 	{0x0000147C, 0x0000c671},	/* ODT Timing (High) Register */
58b20c38a9SStefan Roese 
59b20c38a9SStefan Roese 	{0x00001494, 0x00010000},	/* DDR SDRAM ODT Control (Low) Reg */
60b20c38a9SStefan Roese 	{0x0000149C, 0x00000001},	/* DDR Dunit ODT Control Register */
61b20c38a9SStefan Roese 	{0x000014A0, 0x00000001},	/* DRAM FIFO Control Register */
62b20c38a9SStefan Roese 	{0x000014A8, 0x00000101},	/* AXI Control Register */
63b20c38a9SStefan Roese 
64b20c38a9SStefan Roese 	/*
65b20c38a9SStefan Roese 	 * DO NOT Modify - Open Mbus Window - 2G - Mbus is required for the
66b20c38a9SStefan Roese 	 * training sequence
67b20c38a9SStefan Roese 	 */
68b20c38a9SStefan Roese 	{0x000200e8, 0x3fff0e01},
69b20c38a9SStefan Roese 	{0x00020184, 0x3fffffe0},	/* Close fast path Window to - 2G */
70b20c38a9SStefan Roese 
71b20c38a9SStefan Roese 	{0x0001504, 0x7fffffe1},	/* CS0 Size */
72b20c38a9SStefan Roese 	{0x000150C, 0x00000000},	/* CS1 Size */
73b20c38a9SStefan Roese 	{0x0001514, 0x00000000},	/* CS2 Size */
74b20c38a9SStefan Roese 	{0x000151C, 0x00000000},	/* CS3 Size */
75b20c38a9SStefan Roese 
76b20c38a9SStefan Roese 	{0x00020220, 0x00000007},	/* Reserved */
77b20c38a9SStefan Roese 
78b20c38a9SStefan Roese 	{0x00001538, 0x00000009},	/* Read Data Sample Delays Register */
79b20c38a9SStefan Roese 	{0x0000153C, 0x00000009},	/* Read Data Ready Delay Register */
80b20c38a9SStefan Roese 
81b20c38a9SStefan Roese 	{0x000015D0, 0x00000650},	/* MR0 */
82b20c38a9SStefan Roese 	{0x000015D4, 0x00000044},	/* MR1 */
83b20c38a9SStefan Roese 	{0x000015D8, 0x00000010},	/* MR2 */
84b20c38a9SStefan Roese 	{0x000015DC, 0x00000000},	/* MR3 */
85b20c38a9SStefan Roese 	{0x000015E0, 0x00000001},
86b20c38a9SStefan Roese 	{0x000015E4, 0x00203c18},	/* ZQDS Configuration Register */
87b20c38a9SStefan Roese 	{0x000015EC, 0xf800a225},	/* DDR PHY */
88b20c38a9SStefan Roese 
89b20c38a9SStefan Roese 	/* Recommended Settings from Marvell for 4 x 16 bit devices: */
90b20c38a9SStefan Roese 	{0x000014C0, 0x192424c9},	/* DRAM addr and Ctrl Driving Strenght*/
91b20c38a9SStefan Roese 	{0x000014C4, 0x0aaa24c9},	/* DRAM Data and DQS Driving Strenght */
92b20c38a9SStefan Roese 
93b20c38a9SStefan Roese 	{0x0, 0x0}
94b20c38a9SStefan Roese };
95b20c38a9SStefan Roese 
96b20c38a9SStefan Roese static MV_DRAM_MODES board_ddr_modes[MV_DDR3_MODES_NUMBER] = {
97b20c38a9SStefan Roese 	{"theadorable_1333-667", 0x3, 0x5, 0x0, A0, ddr3_theadorable,  NULL},
98b20c38a9SStefan Roese };
99b20c38a9SStefan Roese 
100b20c38a9SStefan Roese extern MV_SERDES_CHANGE_M_PHY serdes_change_m_phy[];
101b20c38a9SStefan Roese 
102b20c38a9SStefan Roese /*
103b20c38a9SStefan Roese  * Lane0 - PCIE0.0 X1 (to WIFI Module)
104b20c38a9SStefan Roese  * Lane5 - SATA0
105b20c38a9SStefan Roese  * Lane6 - SATA1
106b20c38a9SStefan Roese  * Lane7 - SGMII0 (to Ethernet Phy)
107b20c38a9SStefan Roese  * Lane8-11 - PCIE2.0 X4 (to PEX Switch)
108b20c38a9SStefan Roese  * all other lanes are disabled
109b20c38a9SStefan Roese  */
110b20c38a9SStefan Roese MV_BIN_SERDES_CFG theadorable_serdes_cfg[] = {
111b20c38a9SStefan Roese 	{ MV_PEX_ROOT_COMPLEX, 0x22200001, 0x00001111,
112b20c38a9SStefan Roese 	  { PEX_BUS_MODE_X1, PEX_BUS_DISABLED, PEX_BUS_MODE_X4,
113b20c38a9SStefan Roese 	    PEX_BUS_DISABLED },
114b20c38a9SStefan Roese 	  0x0060, serdes_change_m_phy
115b20c38a9SStefan Roese 	},
116b20c38a9SStefan Roese };
117b20c38a9SStefan Roese 
1189627ce2dSStefan Roese /*
1199627ce2dSStefan Roese  * Define a board-specific detection pulse-width array for the SerDes PCIe
1209627ce2dSStefan Roese  * interfaces. If not defined in the board code, the default of currently 2
1219627ce2dSStefan Roese  * is used. Values from 0...3 are possible (2 bits).
1229627ce2dSStefan Roese  */
1239627ce2dSStefan Roese u8 serdes_pex_pulse_width[4] = { 0, 2, 2, 2 };
1249627ce2dSStefan Roese 
ddr3_get_static_ddr_mode(void)125b20c38a9SStefan Roese MV_DRAM_MODES *ddr3_get_static_ddr_mode(void)
126b20c38a9SStefan Roese {
127b20c38a9SStefan Roese 	/* Only one mode supported for this board */
128b20c38a9SStefan Roese 	return &board_ddr_modes[0];
129b20c38a9SStefan Roese }
130b20c38a9SStefan Roese 
board_serdes_cfg_get(u8 pex_mode)131b20c38a9SStefan Roese MV_BIN_SERDES_CFG *board_serdes_cfg_get(u8 pex_mode)
132b20c38a9SStefan Roese {
133b20c38a9SStefan Roese 	return &theadorable_serdes_cfg[0];
134b20c38a9SStefan Roese }
135b20c38a9SStefan Roese 
board_sat_r_get(u8 dev_num,u8 reg)1369ed00b07SStefan Roese u8 board_sat_r_get(u8 dev_num, u8 reg)
1379ed00b07SStefan Roese {
1389ed00b07SStefan Roese 	/* Bit 0 enables PCI 2.0 link capabilities instead of PCI 1.x */
1399ed00b07SStefan Roese 	return 0x01;
1409ed00b07SStefan Roese }
1419ed00b07SStefan Roese 
board_early_init_f(void)142b20c38a9SStefan Roese int board_early_init_f(void)
143b20c38a9SStefan Roese {
144b20c38a9SStefan Roese 	/* Configure MPP */
145b20c38a9SStefan Roese 	writel(0x00000000, MVEBU_MPP_BASE + 0x00);
146b20c38a9SStefan Roese 	writel(0x03300000, MVEBU_MPP_BASE + 0x04);
147b20c38a9SStefan Roese 	writel(0x00000033, MVEBU_MPP_BASE + 0x08);
148b20c38a9SStefan Roese 	writel(0x00000000, MVEBU_MPP_BASE + 0x0c);
149b20c38a9SStefan Roese 	writel(0x11110000, MVEBU_MPP_BASE + 0x10);
150b20c38a9SStefan Roese 	writel(0x00221100, MVEBU_MPP_BASE + 0x14);
151b20c38a9SStefan Roese 	writel(0x00000000, MVEBU_MPP_BASE + 0x18);
152b20c38a9SStefan Roese 	writel(0x00000000, MVEBU_MPP_BASE + 0x1c);
153b20c38a9SStefan Roese 	writel(0x00000000, MVEBU_MPP_BASE + 0x20);
154b20c38a9SStefan Roese 
155b20c38a9SStefan Roese 	/* Configure GPIO */
156b20c38a9SStefan Roese 	writel(THEADORABLE_GPP_OUT_VAL_LOW, MVEBU_GPIO0_BASE + 0x00);
157b20c38a9SStefan Roese 	writel(THEADORABLE_GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04);
158b20c38a9SStefan Roese 	writel(THEADORABLE_GPP_OUT_VAL_MID, MVEBU_GPIO1_BASE + 0x00);
159b20c38a9SStefan Roese 	writel(THEADORABLE_GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04);
160b20c38a9SStefan Roese 	writel(THEADORABLE_GPP_OUT_VAL_HIGH, MVEBU_GPIO2_BASE + 0x00);
161b20c38a9SStefan Roese 	writel(THEADORABLE_GPP_OUT_ENA_HIGH, MVEBU_GPIO2_BASE + 0x04);
162b20c38a9SStefan Roese 
163b20c38a9SStefan Roese 	return 0;
164b20c38a9SStefan Roese }
165b20c38a9SStefan Roese 
board_init(void)166b20c38a9SStefan Roese int board_init(void)
167b20c38a9SStefan Roese {
168ced0d849SStefan Roese 	int ret;
169ced0d849SStefan Roese 
170b20c38a9SStefan Roese 	/* adress of boot parameters */
171b20c38a9SStefan Roese 	gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
172b20c38a9SStefan Roese 
173aea02abeSStefan Roese 	/*
174aea02abeSStefan Roese 	 * Map SPI devices via MBUS so that they can be accessed via
175aea02abeSStefan Roese 	 * the SPI direct access mode
176aea02abeSStefan Roese 	 */
177aea02abeSStefan Roese 	mbus_dt_setup_win(&mbus_state, SPI_BUS0_DEV1_BASE, SPI_BUS0_DEV1_SIZE,
178aea02abeSStefan Roese 			  CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_SPI0_CS1);
179aea02abeSStefan Roese 	mbus_dt_setup_win(&mbus_state, SPI_BUS1_DEV2_BASE, SPI_BUS0_DEV1_SIZE,
180aea02abeSStefan Roese 			  CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_SPI1_CS2);
181aea02abeSStefan Roese 
182ced0d849SStefan Roese 	/*
183ced0d849SStefan Roese 	 * Set RX Channel Control 0 Register:
184ced0d849SStefan Roese 	 * Tests have shown, that setting the LPF_COEF from 0 (1/8)
185ced0d849SStefan Roese 	 * to 3 (1/1) results in a more stable USB connection.
186ced0d849SStefan Roese 	 */
187ced0d849SStefan Roese 	setbits_le32(PHY_CHANNEL_RX_CTRL0_REG(0, 1), 0xc);
188ced0d849SStefan Roese 	setbits_le32(PHY_CHANNEL_RX_CTRL0_REG(0, 2), 0xc);
189ced0d849SStefan Roese 	setbits_le32(PHY_CHANNEL_RX_CTRL0_REG(0, 3), 0xc);
190ced0d849SStefan Roese 
191ced0d849SStefan Roese 	/* Toggle USB power */
192ced0d849SStefan Roese 	ret = gpio_request(GPIO_USB0_PWR_ON, "USB0_PWR_ON");
193ced0d849SStefan Roese 	if (ret < 0)
194ced0d849SStefan Roese 		return ret;
195ced0d849SStefan Roese 	gpio_direction_output(GPIO_USB0_PWR_ON, 0);
196ced0d849SStefan Roese 	ret = gpio_request(GPIO_USB1_PWR_ON, "USB1_PWR_ON");
197ced0d849SStefan Roese 	if (ret < 0)
198ced0d849SStefan Roese 		return ret;
199ced0d849SStefan Roese 	gpio_direction_output(GPIO_USB1_PWR_ON, 0);
200ced0d849SStefan Roese 	mdelay(1);
201ced0d849SStefan Roese 	gpio_set_value(GPIO_USB0_PWR_ON, 1);
202ced0d849SStefan Roese 	gpio_set_value(GPIO_USB1_PWR_ON, 1);
203ced0d849SStefan Roese 
204b20c38a9SStefan Roese 	return 0;
205b20c38a9SStefan Roese }
206b20c38a9SStefan Roese 
checkboard(void)207b20c38a9SStefan Roese int checkboard(void)
208b20c38a9SStefan Roese {
209aea02abeSStefan Roese 	board_fpga_add();
210aea02abeSStefan Roese 
211b20c38a9SStefan Roese 	return 0;
212b20c38a9SStefan Roese }
213b20c38a9SStefan Roese 
214b20c38a9SStefan Roese #ifdef CONFIG_NET
board_eth_init(bd_t * bis)215b20c38a9SStefan Roese int board_eth_init(bd_t *bis)
216b20c38a9SStefan Roese {
217b20c38a9SStefan Roese 	cpu_eth_init(bis); /* Built in controller(s) come first */
218b20c38a9SStefan Roese 	return pci_eth_init(bis);
219b20c38a9SStefan Roese }
220b20c38a9SStefan Roese #endif
221b20c38a9SStefan Roese 
board_video_init(void)222b20c38a9SStefan Roese int board_video_init(void)
223b20c38a9SStefan Roese {
224b20c38a9SStefan Roese 	struct mvebu_lcd_info lcd_info;
225b20c38a9SStefan Roese 
226b20c38a9SStefan Roese 	/* Reserved memory area via CONFIG_SYS_MEM_TOP_HIDE */
227b20c38a9SStefan Roese 	lcd_info.fb_base	= gd->ram_size;
228b20c38a9SStefan Roese 	lcd_info.x_res		= 240;
229b20c38a9SStefan Roese 	lcd_info.x_fp		= 1;
230b20c38a9SStefan Roese 	lcd_info.x_bp		= 45;
231b20c38a9SStefan Roese 	lcd_info.y_res		= 320;
232b20c38a9SStefan Roese 	lcd_info.y_fp		= 1;
233b20c38a9SStefan Roese 	lcd_info.y_bp		= 3;
234b20c38a9SStefan Roese 
235b20c38a9SStefan Roese 	return mvebu_lcd_register_init(&lcd_info);
236b20c38a9SStefan Roese }
237169a8550SStefan Roese 
238169a8550SStefan Roese #ifdef CONFIG_BOARD_LATE_INIT
board_late_init(void)239169a8550SStefan Roese int board_late_init(void)
240169a8550SStefan Roese {
241169a8550SStefan Roese 	pci_dev_t bdf;
242169a8550SStefan Roese 	ulong bootcount;
243169a8550SStefan Roese 
244169a8550SStefan Roese 	/*
245169a8550SStefan Roese 	 * Check if the PEX switch is detected (somtimes its not available
246169a8550SStefan Roese 	 * on the PCIe bus). In this case, try to recover by issuing a
247169a8550SStefan Roese 	 * soft-reset or even a power-cycle, depending on the bootcounter
248169a8550SStefan Roese 	 * value.
249169a8550SStefan Roese 	 */
250169a8550SStefan Roese 	bdf = pci_find_device(PCI_VENDOR_ID_PLX, 0x8619, 0);
251169a8550SStefan Roese 	if (bdf == -1) {
252169a8550SStefan Roese 		u8 i2c_buf[8];
253169a8550SStefan Roese 		int ret;
254169a8550SStefan Roese 
255169a8550SStefan Roese 		/* PEX switch not found! */
256169a8550SStefan Roese 		bootcount = bootcount_load();
257169a8550SStefan Roese 		printf("Failed to find PLX PEX-switch (bootcount=%ld)\n",
258169a8550SStefan Roese 		       bootcount);
259169a8550SStefan Roese 		if (bootcount > PEX_SWITCH_NOT_FOUNT_LIMIT) {
260169a8550SStefan Roese 			printf("Issuing power-switch via uC!\n");
261169a8550SStefan Roese 
262169a8550SStefan Roese 			printf("Issuing power-switch via uC!\n");
263169a8550SStefan Roese 			i2c_set_bus_num(STM_I2C_BUS);
264169a8550SStefan Roese 			i2c_buf[0] = STM_I2C_ADDR << 1;
265169a8550SStefan Roese 			i2c_buf[1] = 0xc5;	/* cmd */
266169a8550SStefan Roese 			i2c_buf[2] = 0x01;	/* enable */
267169a8550SStefan Roese 			/* Delay before reboot */
268169a8550SStefan Roese 			i2c_buf[3] = REBOOT_DELAY & 0x00ff;
269169a8550SStefan Roese 			i2c_buf[4] = (REBOOT_DELAY & 0xff00) >> 8;
270169a8550SStefan Roese 			/* Delay before shutdown */
271169a8550SStefan Roese 			i2c_buf[5] = 0x00;
272169a8550SStefan Roese 			i2c_buf[6] = 0x00;
273169a8550SStefan Roese 			i2c_buf[7] = crc8(0x72, &i2c_buf[0], 7);
274169a8550SStefan Roese 
275169a8550SStefan Roese 			ret = i2c_write(STM_I2C_ADDR, 0, 0, &i2c_buf[1], 7);
276169a8550SStefan Roese 			if (ret) {
277169a8550SStefan Roese 				printf("I2C write error (ret=%d)\n", ret);
278169a8550SStefan Roese 				printf("Issuing soft-reset...\n");
279169a8550SStefan Roese 				/* default handling: SOFT reset */
280169a8550SStefan Roese 				do_reset(NULL, 0, 0, NULL);
281169a8550SStefan Roese 			}
282169a8550SStefan Roese 
283169a8550SStefan Roese 			/* Wait for power-cycle to occur... */
284169a8550SStefan Roese 			printf("Waiting for power-cycle via uC...\n");
285169a8550SStefan Roese 			while (1)
286169a8550SStefan Roese 				;
287169a8550SStefan Roese 		} else {
288169a8550SStefan Roese 			printf("Issuing soft-reset...\n");
289169a8550SStefan Roese 			/* default handling: SOFT reset */
290169a8550SStefan Roese 			do_reset(NULL, 0, 0, NULL);
291169a8550SStefan Roese 		}
292169a8550SStefan Roese 	}
293169a8550SStefan Roese 
294169a8550SStefan Roese 	return 0;
295169a8550SStefan Roese }
296169a8550SStefan Roese #endif
297*55e0306cSStefan Roese 
298*55e0306cSStefan Roese #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_PCI)
do_pcie_test(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])299*55e0306cSStefan Roese int do_pcie_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
300*55e0306cSStefan Roese {
301*55e0306cSStefan Roese 	pci_dev_t bdf;
302*55e0306cSStefan Roese 	u16 ven_id, dev_id;
303*55e0306cSStefan Roese 
304*55e0306cSStefan Roese 	if (argc != 3)
305*55e0306cSStefan Roese 		return cmd_usage(cmdtp);
306*55e0306cSStefan Roese 
307*55e0306cSStefan Roese 	ven_id = simple_strtoul(argv[1], NULL, 16);
308*55e0306cSStefan Roese 	dev_id = simple_strtoul(argv[2], NULL, 16);
309*55e0306cSStefan Roese 
310*55e0306cSStefan Roese 	printf("Checking for PCIe device: VendorID 0x%04x, DeviceId 0x%04x\n",
311*55e0306cSStefan Roese 	       ven_id, dev_id);
312*55e0306cSStefan Roese 
313*55e0306cSStefan Roese 	/*
314*55e0306cSStefan Roese 	 * Check if the PCIe device is detected (somtimes its not available
315*55e0306cSStefan Roese 	 * on the PCIe bus)
316*55e0306cSStefan Roese 	 */
317*55e0306cSStefan Roese 	bdf = pci_find_device(ven_id, dev_id, 0);
318*55e0306cSStefan Roese 	if (bdf == -1) {
319*55e0306cSStefan Roese 		/* PCIe device not found! */
320*55e0306cSStefan Roese 		printf("Failed to find PCIe device\n");
321*55e0306cSStefan Roese 	} else {
322*55e0306cSStefan Roese 		/* PCIe device found! */
323*55e0306cSStefan Roese 		printf("PCIe device found, resetting board...\n");
324*55e0306cSStefan Roese 
325*55e0306cSStefan Roese 		/* default handling: SOFT reset */
326*55e0306cSStefan Roese 		do_reset(NULL, 0, 0, NULL);
327*55e0306cSStefan Roese 	}
328*55e0306cSStefan Roese 
329*55e0306cSStefan Roese 	return 0;
330*55e0306cSStefan Roese }
331*55e0306cSStefan Roese 
332*55e0306cSStefan Roese U_BOOT_CMD(
333*55e0306cSStefan Roese 	pcie,   3,   0,     do_pcie_test,
334*55e0306cSStefan Roese 	"Test for presence of a PCIe device",
335*55e0306cSStefan Roese 	"<VendorID> <DeviceID>"
336*55e0306cSStefan Roese );
337*55e0306cSStefan Roese #endif
338