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