xref: /OK3568_Linux_fs/u-boot/board/gdsys/mpc8308/hrcon.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2014
3*4882a593Smuzhiyun  * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <common.h>
9*4882a593Smuzhiyun #include <hwconfig.h>
10*4882a593Smuzhiyun #include <i2c.h>
11*4882a593Smuzhiyun #include <spi.h>
12*4882a593Smuzhiyun #include <linux/libfdt.h>
13*4882a593Smuzhiyun #include <fdt_support.h>
14*4882a593Smuzhiyun #include <pci.h>
15*4882a593Smuzhiyun #include <mpc83xx.h>
16*4882a593Smuzhiyun #include <fsl_esdhc.h>
17*4882a593Smuzhiyun #include <asm/io.h>
18*4882a593Smuzhiyun #include <asm/fsl_serdes.h>
19*4882a593Smuzhiyun #include <asm/fsl_mpc83xx_serdes.h>
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #include "mpc8308.h"
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #include <gdsys_fpga.h>
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #include "../common/ioep-fpga.h"
26*4882a593Smuzhiyun #include "../common/osd.h"
27*4882a593Smuzhiyun #include "../common/mclink.h"
28*4882a593Smuzhiyun #include "../common/phy.h"
29*4882a593Smuzhiyun #include "../common/fanctrl.h"
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #include <pca953x.h>
32*4882a593Smuzhiyun #include <pca9698.h>
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun #include <miiphy.h>
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun #define MAX_MUX_CHANNELS 2
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun enum {
41*4882a593Smuzhiyun 	MCFPGA_DONE = 1 << 0,
42*4882a593Smuzhiyun 	MCFPGA_INIT_N = 1 << 1,
43*4882a593Smuzhiyun 	MCFPGA_PROGRAM_N = 1 << 2,
44*4882a593Smuzhiyun 	MCFPGA_UPDATE_ENABLE_N = 1 << 3,
45*4882a593Smuzhiyun 	MCFPGA_RESET_N = 1 << 4,
46*4882a593Smuzhiyun };
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun enum {
49*4882a593Smuzhiyun 	GPIO_MDC = 1 << 14,
50*4882a593Smuzhiyun 	GPIO_MDIO = 1 << 15,
51*4882a593Smuzhiyun };
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun unsigned int mclink_fpgacount;
54*4882a593Smuzhiyun struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR;
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun struct {
57*4882a593Smuzhiyun 	u8 bus;
58*4882a593Smuzhiyun 	u8 addr;
59*4882a593Smuzhiyun } hrcon_fans[] = CONFIG_HRCON_FANS;
60*4882a593Smuzhiyun 
fpga_set_reg(u32 fpga,u16 * reg,off_t regoff,u16 data)61*4882a593Smuzhiyun int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun 	int res;
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 	switch (fpga) {
66*4882a593Smuzhiyun 	case 0:
67*4882a593Smuzhiyun 		out_le16(reg, data);
68*4882a593Smuzhiyun 		break;
69*4882a593Smuzhiyun 	default:
70*4882a593Smuzhiyun 		res = mclink_send(fpga - 1, regoff, data);
71*4882a593Smuzhiyun 		if (res < 0) {
72*4882a593Smuzhiyun 			printf("mclink_send reg %02lx data %04x returned %d\n",
73*4882a593Smuzhiyun 			       regoff, data, res);
74*4882a593Smuzhiyun 			return res;
75*4882a593Smuzhiyun 		}
76*4882a593Smuzhiyun 		break;
77*4882a593Smuzhiyun 	}
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	return 0;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun 
fpga_get_reg(u32 fpga,u16 * reg,off_t regoff,u16 * data)82*4882a593Smuzhiyun int fpga_get_reg(u32 fpga, u16 *reg, off_t regoff, u16 *data)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun 	int res;
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	switch (fpga) {
87*4882a593Smuzhiyun 	case 0:
88*4882a593Smuzhiyun 		*data = in_le16(reg);
89*4882a593Smuzhiyun 		break;
90*4882a593Smuzhiyun 	default:
91*4882a593Smuzhiyun 		if (fpga > mclink_fpgacount)
92*4882a593Smuzhiyun 			return -EINVAL;
93*4882a593Smuzhiyun 		res = mclink_receive(fpga - 1, regoff, data);
94*4882a593Smuzhiyun 		if (res < 0) {
95*4882a593Smuzhiyun 			printf("mclink_receive reg %02lx returned %d\n",
96*4882a593Smuzhiyun 			       regoff, res);
97*4882a593Smuzhiyun 			return res;
98*4882a593Smuzhiyun 		}
99*4882a593Smuzhiyun 	}
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	return 0;
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun 
checkboard(void)104*4882a593Smuzhiyun int checkboard(void)
105*4882a593Smuzhiyun {
106*4882a593Smuzhiyun 	char *s = env_get("serial#");
107*4882a593Smuzhiyun 	bool hw_type_cat = pca9698_get_value(0x20, 20);
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	puts("Board: ");
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	printf("HRCon %s", hw_type_cat ? "CAT" : "Fiber");
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 	if (s != NULL) {
114*4882a593Smuzhiyun 		puts(", serial# ");
115*4882a593Smuzhiyun 		puts(s);
116*4882a593Smuzhiyun 	}
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 	puts("\n");
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	return 0;
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun 
last_stage_init(void)123*4882a593Smuzhiyun int last_stage_init(void)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun 	int slaves;
126*4882a593Smuzhiyun 	unsigned int k;
127*4882a593Smuzhiyun 	unsigned int mux_ch;
128*4882a593Smuzhiyun 	unsigned char mclink_controllers[] = { 0x3c, 0x3d, 0x3e };
129*4882a593Smuzhiyun 	u16 fpga_features;
130*4882a593Smuzhiyun 	bool hw_type_cat = pca9698_get_value(0x20, 20);
131*4882a593Smuzhiyun 	bool ch0_rgmii2_present = false;
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	FPGA_GET_REG(0, fpga_features, &fpga_features);
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	/* Turn on Parade DP501 */
136*4882a593Smuzhiyun 	pca9698_direction_output(0x20, 10, 1);
137*4882a593Smuzhiyun 	pca9698_direction_output(0x20, 11, 1);
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	ch0_rgmii2_present = !pca9698_get_value(0x20, 30);
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	/* wait for FPGA done, then reset FPGA */
142*4882a593Smuzhiyun 	for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) {
143*4882a593Smuzhiyun 		unsigned int ctr = 0;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 		if (i2c_probe(mclink_controllers[k]))
146*4882a593Smuzhiyun 			continue;
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 		while (!(pca953x_get_val(mclink_controllers[k])
149*4882a593Smuzhiyun 		       & MCFPGA_DONE)) {
150*4882a593Smuzhiyun 			udelay(100000);
151*4882a593Smuzhiyun 			if (ctr++ > 5) {
152*4882a593Smuzhiyun 				printf("no done for mclink_controller %d\n", k);
153*4882a593Smuzhiyun 				break;
154*4882a593Smuzhiyun 			}
155*4882a593Smuzhiyun 		}
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 		pca953x_set_dir(mclink_controllers[k], MCFPGA_RESET_N, 0);
158*4882a593Smuzhiyun 		pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, 0);
159*4882a593Smuzhiyun 		udelay(10);
160*4882a593Smuzhiyun 		pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N,
161*4882a593Smuzhiyun 				MCFPGA_RESET_N);
162*4882a593Smuzhiyun 	}
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	if (hw_type_cat) {
165*4882a593Smuzhiyun 		int retval;
166*4882a593Smuzhiyun 		struct mii_dev *mdiodev = mdio_alloc();
167*4882a593Smuzhiyun 		if (!mdiodev)
168*4882a593Smuzhiyun 			return -ENOMEM;
169*4882a593Smuzhiyun 		strncpy(mdiodev->name, bb_miiphy_buses[0].name, MDIO_NAME_LEN);
170*4882a593Smuzhiyun 		mdiodev->read = bb_miiphy_read;
171*4882a593Smuzhiyun 		mdiodev->write = bb_miiphy_write;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 		retval = mdio_register(mdiodev);
174*4882a593Smuzhiyun 		if (retval < 0)
175*4882a593Smuzhiyun 			return retval;
176*4882a593Smuzhiyun 		for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) {
177*4882a593Smuzhiyun 			if ((mux_ch == 1) && !ch0_rgmii2_present)
178*4882a593Smuzhiyun 				continue;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 			setup_88e1514(bb_miiphy_buses[0].name, mux_ch);
181*4882a593Smuzhiyun 		}
182*4882a593Smuzhiyun 	}
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	/* give slave-PLLs and Parade DP501 some time to be up and running */
185*4882a593Smuzhiyun 	udelay(500000);
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 	mclink_fpgacount = CONFIG_SYS_MCLINK_MAX;
188*4882a593Smuzhiyun 	slaves = mclink_probe();
189*4882a593Smuzhiyun 	mclink_fpgacount = 0;
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	ioep_fpga_print_info(0);
192*4882a593Smuzhiyun 	osd_probe(0);
193*4882a593Smuzhiyun #ifdef CONFIG_SYS_OSD_DH
194*4882a593Smuzhiyun 	osd_probe(4);
195*4882a593Smuzhiyun #endif
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	if (slaves <= 0)
198*4882a593Smuzhiyun 		return 0;
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	mclink_fpgacount = slaves;
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	for (k = 1; k <= slaves; ++k) {
203*4882a593Smuzhiyun 		FPGA_GET_REG(k, fpga_features, &fpga_features);
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 		ioep_fpga_print_info(k);
206*4882a593Smuzhiyun 		osd_probe(k);
207*4882a593Smuzhiyun #ifdef CONFIG_SYS_OSD_DH
208*4882a593Smuzhiyun 		osd_probe(k + 4);
209*4882a593Smuzhiyun #endif
210*4882a593Smuzhiyun 		if (hw_type_cat) {
211*4882a593Smuzhiyun 			int retval;
212*4882a593Smuzhiyun 			struct mii_dev *mdiodev = mdio_alloc();
213*4882a593Smuzhiyun 			if (!mdiodev)
214*4882a593Smuzhiyun 				return -ENOMEM;
215*4882a593Smuzhiyun 			strncpy(mdiodev->name, bb_miiphy_buses[k].name,
216*4882a593Smuzhiyun 				MDIO_NAME_LEN);
217*4882a593Smuzhiyun 			mdiodev->read = bb_miiphy_read;
218*4882a593Smuzhiyun 			mdiodev->write = bb_miiphy_write;
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 			retval = mdio_register(mdiodev);
221*4882a593Smuzhiyun 			if (retval < 0)
222*4882a593Smuzhiyun 				return retval;
223*4882a593Smuzhiyun 			setup_88e1514(bb_miiphy_buses[k].name, 0);
224*4882a593Smuzhiyun 		}
225*4882a593Smuzhiyun 	}
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	for (k = 0; k < ARRAY_SIZE(hrcon_fans); ++k) {
228*4882a593Smuzhiyun 		i2c_set_bus_num(hrcon_fans[k].bus);
229*4882a593Smuzhiyun 		init_fan_controller(hrcon_fans[k].addr);
230*4882a593Smuzhiyun 	}
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	return 0;
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun /*
236*4882a593Smuzhiyun  * provide access to fpga gpios and controls (for I2C bitbang)
237*4882a593Smuzhiyun  * (these may look all too simple but make iocon.h much more readable)
238*4882a593Smuzhiyun  */
fpga_gpio_set(unsigned int bus,int pin)239*4882a593Smuzhiyun void fpga_gpio_set(unsigned int bus, int pin)
240*4882a593Smuzhiyun {
241*4882a593Smuzhiyun 	FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, gpio.set, pin);
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun 
fpga_gpio_clear(unsigned int bus,int pin)244*4882a593Smuzhiyun void fpga_gpio_clear(unsigned int bus, int pin)
245*4882a593Smuzhiyun {
246*4882a593Smuzhiyun 	FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, gpio.clear, pin);
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun 
fpga_gpio_get(unsigned int bus,int pin)249*4882a593Smuzhiyun int fpga_gpio_get(unsigned int bus, int pin)
250*4882a593Smuzhiyun {
251*4882a593Smuzhiyun 	u16 val;
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, gpio.read, &val);
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	return val & pin;
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun 
fpga_control_set(unsigned int bus,int pin)258*4882a593Smuzhiyun void fpga_control_set(unsigned int bus, int pin)
259*4882a593Smuzhiyun {
260*4882a593Smuzhiyun 	u16 val;
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun 	FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, control, &val);
263*4882a593Smuzhiyun 	FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, control, val | pin);
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun 
fpga_control_clear(unsigned int bus,int pin)266*4882a593Smuzhiyun void fpga_control_clear(unsigned int bus, int pin)
267*4882a593Smuzhiyun {
268*4882a593Smuzhiyun 	u16 val;
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, control, &val);
271*4882a593Smuzhiyun 	FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, control, val & ~pin);
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun 
mpc8308_init(void)274*4882a593Smuzhiyun void mpc8308_init(void)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun 	pca9698_direction_output(0x20, 4, 1);
277*4882a593Smuzhiyun }
278*4882a593Smuzhiyun 
mpc8308_set_fpga_reset(unsigned state)279*4882a593Smuzhiyun void mpc8308_set_fpga_reset(unsigned state)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun 	pca9698_set_value(0x20, 4, state ? 0 : 1);
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun 
mpc8308_setup_hw(void)284*4882a593Smuzhiyun void mpc8308_setup_hw(void)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun 	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	/*
289*4882a593Smuzhiyun 	 * set "startup-finished"-gpios
290*4882a593Smuzhiyun 	 */
291*4882a593Smuzhiyun 	setbits_be32(&immr->gpio[0].dir, (1 << (31-11)) | (1 << (31-12)));
292*4882a593Smuzhiyun 	setbits_be32(&immr->gpio[0].dat, 1 << (31-12));
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun 
mpc8308_get_fpga_done(unsigned fpga)295*4882a593Smuzhiyun int mpc8308_get_fpga_done(unsigned fpga)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun 	return pca9698_get_value(0x20, 19);
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun #ifdef CONFIG_FSL_ESDHC
board_mmc_init(bd_t * bd)301*4882a593Smuzhiyun int board_mmc_init(bd_t *bd)
302*4882a593Smuzhiyun {
303*4882a593Smuzhiyun 	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
304*4882a593Smuzhiyun 	sysconf83xx_t *sysconf = &immr->sysconf;
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	/* Enable cache snooping in eSDHC system configuration register */
307*4882a593Smuzhiyun 	out_be32(&sysconf->sdhccr, 0x02000000);
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	return fsl_esdhc_mmc_init(bd);
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun #endif
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun static struct pci_region pcie_regions_0[] = {
314*4882a593Smuzhiyun 	{
315*4882a593Smuzhiyun 		.bus_start = CONFIG_SYS_PCIE1_MEM_BASE,
316*4882a593Smuzhiyun 		.phys_start = CONFIG_SYS_PCIE1_MEM_PHYS,
317*4882a593Smuzhiyun 		.size = CONFIG_SYS_PCIE1_MEM_SIZE,
318*4882a593Smuzhiyun 		.flags = PCI_REGION_MEM,
319*4882a593Smuzhiyun 	},
320*4882a593Smuzhiyun 	{
321*4882a593Smuzhiyun 		.bus_start = CONFIG_SYS_PCIE1_IO_BASE,
322*4882a593Smuzhiyun 		.phys_start = CONFIG_SYS_PCIE1_IO_PHYS,
323*4882a593Smuzhiyun 		.size = CONFIG_SYS_PCIE1_IO_SIZE,
324*4882a593Smuzhiyun 		.flags = PCI_REGION_IO,
325*4882a593Smuzhiyun 	},
326*4882a593Smuzhiyun };
327*4882a593Smuzhiyun 
pci_init_board(void)328*4882a593Smuzhiyun void pci_init_board(void)
329*4882a593Smuzhiyun {
330*4882a593Smuzhiyun 	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
331*4882a593Smuzhiyun 	sysconf83xx_t *sysconf = &immr->sysconf;
332*4882a593Smuzhiyun 	law83xx_t *pcie_law = sysconf->pcielaw;
333*4882a593Smuzhiyun 	struct pci_region *pcie_reg[] = { pcie_regions_0 };
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 	fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_PEX,
336*4882a593Smuzhiyun 			 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun 	/* Deassert the resets in the control register */
339*4882a593Smuzhiyun 	out_be32(&sysconf->pecr1, 0xE0008000);
340*4882a593Smuzhiyun 	udelay(2000);
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	/* Configure PCI Express Local Access Windows */
343*4882a593Smuzhiyun 	out_be32(&pcie_law[0].bar, CONFIG_SYS_PCIE1_BASE & LAWBAR_BAR);
344*4882a593Smuzhiyun 	out_be32(&pcie_law[0].ar, LBLAWAR_EN | LBLAWAR_512MB);
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 	mpc83xx_pcie_init(1, pcie_reg);
347*4882a593Smuzhiyun }
348*4882a593Smuzhiyun 
board_flash_get_legacy(ulong base,int banknum,flash_info_t * info)349*4882a593Smuzhiyun ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
350*4882a593Smuzhiyun {
351*4882a593Smuzhiyun 	info->portwidth = FLASH_CFI_16BIT;
352*4882a593Smuzhiyun 	info->chipwidth = FLASH_CFI_BY16;
353*4882a593Smuzhiyun 	info->interface = FLASH_CFI_X16;
354*4882a593Smuzhiyun 	return 1;
355*4882a593Smuzhiyun }
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun #if defined(CONFIG_OF_BOARD_SETUP)
ft_board_setup(void * blob,bd_t * bd)358*4882a593Smuzhiyun int ft_board_setup(void *blob, bd_t *bd)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun 	ft_cpu_setup(blob, bd);
361*4882a593Smuzhiyun 	fsl_fdt_fixup_dr_usb(blob, bd);
362*4882a593Smuzhiyun 	fdt_fixup_esdhc(blob, bd);
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	return 0;
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun #endif
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun /*
369*4882a593Smuzhiyun  * FPGA MII bitbang implementation
370*4882a593Smuzhiyun  */
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun struct fpga_mii {
373*4882a593Smuzhiyun 	unsigned fpga;
374*4882a593Smuzhiyun 	int mdio;
375*4882a593Smuzhiyun } fpga_mii[] = {
376*4882a593Smuzhiyun 	{ 0, 1},
377*4882a593Smuzhiyun 	{ 1, 1},
378*4882a593Smuzhiyun 	{ 2, 1},
379*4882a593Smuzhiyun 	{ 3, 1},
380*4882a593Smuzhiyun };
381*4882a593Smuzhiyun 
mii_dummy_init(struct bb_miiphy_bus * bus)382*4882a593Smuzhiyun static int mii_dummy_init(struct bb_miiphy_bus *bus)
383*4882a593Smuzhiyun {
384*4882a593Smuzhiyun 	return 0;
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun 
mii_mdio_active(struct bb_miiphy_bus * bus)387*4882a593Smuzhiyun static int mii_mdio_active(struct bb_miiphy_bus *bus)
388*4882a593Smuzhiyun {
389*4882a593Smuzhiyun 	struct fpga_mii *fpga_mii = bus->priv;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	if (fpga_mii->mdio)
392*4882a593Smuzhiyun 		FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
393*4882a593Smuzhiyun 	else
394*4882a593Smuzhiyun 		FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 	return 0;
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun 
mii_mdio_tristate(struct bb_miiphy_bus * bus)399*4882a593Smuzhiyun static int mii_mdio_tristate(struct bb_miiphy_bus *bus)
400*4882a593Smuzhiyun {
401*4882a593Smuzhiyun 	struct fpga_mii *fpga_mii = bus->priv;
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 	FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun 	return 0;
406*4882a593Smuzhiyun }
407*4882a593Smuzhiyun 
mii_set_mdio(struct bb_miiphy_bus * bus,int v)408*4882a593Smuzhiyun static int mii_set_mdio(struct bb_miiphy_bus *bus, int v)
409*4882a593Smuzhiyun {
410*4882a593Smuzhiyun 	struct fpga_mii *fpga_mii = bus->priv;
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	if (v)
413*4882a593Smuzhiyun 		FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
414*4882a593Smuzhiyun 	else
415*4882a593Smuzhiyun 		FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	fpga_mii->mdio = v;
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 	return 0;
420*4882a593Smuzhiyun }
421*4882a593Smuzhiyun 
mii_get_mdio(struct bb_miiphy_bus * bus,int * v)422*4882a593Smuzhiyun static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v)
423*4882a593Smuzhiyun {
424*4882a593Smuzhiyun 	u16 gpio;
425*4882a593Smuzhiyun 	struct fpga_mii *fpga_mii = bus->priv;
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun 	FPGA_GET_REG(fpga_mii->fpga, gpio.read, &gpio);
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 	*v = ((gpio & GPIO_MDIO) != 0);
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun 	return 0;
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun 
mii_set_mdc(struct bb_miiphy_bus * bus,int v)434*4882a593Smuzhiyun static int mii_set_mdc(struct bb_miiphy_bus *bus, int v)
435*4882a593Smuzhiyun {
436*4882a593Smuzhiyun 	struct fpga_mii *fpga_mii = bus->priv;
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 	if (v)
439*4882a593Smuzhiyun 		FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDC);
440*4882a593Smuzhiyun 	else
441*4882a593Smuzhiyun 		FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDC);
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun 	return 0;
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun 
mii_delay(struct bb_miiphy_bus * bus)446*4882a593Smuzhiyun static int mii_delay(struct bb_miiphy_bus *bus)
447*4882a593Smuzhiyun {
448*4882a593Smuzhiyun 	udelay(1);
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun 	return 0;
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun struct bb_miiphy_bus bb_miiphy_buses[] = {
454*4882a593Smuzhiyun 	{
455*4882a593Smuzhiyun 		.name = "board0",
456*4882a593Smuzhiyun 		.init = mii_dummy_init,
457*4882a593Smuzhiyun 		.mdio_active = mii_mdio_active,
458*4882a593Smuzhiyun 		.mdio_tristate = mii_mdio_tristate,
459*4882a593Smuzhiyun 		.set_mdio = mii_set_mdio,
460*4882a593Smuzhiyun 		.get_mdio = mii_get_mdio,
461*4882a593Smuzhiyun 		.set_mdc = mii_set_mdc,
462*4882a593Smuzhiyun 		.delay = mii_delay,
463*4882a593Smuzhiyun 		.priv = &fpga_mii[0],
464*4882a593Smuzhiyun 	},
465*4882a593Smuzhiyun 	{
466*4882a593Smuzhiyun 		.name = "board1",
467*4882a593Smuzhiyun 		.init = mii_dummy_init,
468*4882a593Smuzhiyun 		.mdio_active = mii_mdio_active,
469*4882a593Smuzhiyun 		.mdio_tristate = mii_mdio_tristate,
470*4882a593Smuzhiyun 		.set_mdio = mii_set_mdio,
471*4882a593Smuzhiyun 		.get_mdio = mii_get_mdio,
472*4882a593Smuzhiyun 		.set_mdc = mii_set_mdc,
473*4882a593Smuzhiyun 		.delay = mii_delay,
474*4882a593Smuzhiyun 		.priv = &fpga_mii[1],
475*4882a593Smuzhiyun 	},
476*4882a593Smuzhiyun 	{
477*4882a593Smuzhiyun 		.name = "board2",
478*4882a593Smuzhiyun 		.init = mii_dummy_init,
479*4882a593Smuzhiyun 		.mdio_active = mii_mdio_active,
480*4882a593Smuzhiyun 		.mdio_tristate = mii_mdio_tristate,
481*4882a593Smuzhiyun 		.set_mdio = mii_set_mdio,
482*4882a593Smuzhiyun 		.get_mdio = mii_get_mdio,
483*4882a593Smuzhiyun 		.set_mdc = mii_set_mdc,
484*4882a593Smuzhiyun 		.delay = mii_delay,
485*4882a593Smuzhiyun 		.priv = &fpga_mii[2],
486*4882a593Smuzhiyun 	},
487*4882a593Smuzhiyun 	{
488*4882a593Smuzhiyun 		.name = "board3",
489*4882a593Smuzhiyun 		.init = mii_dummy_init,
490*4882a593Smuzhiyun 		.mdio_active = mii_mdio_active,
491*4882a593Smuzhiyun 		.mdio_tristate = mii_mdio_tristate,
492*4882a593Smuzhiyun 		.set_mdio = mii_set_mdio,
493*4882a593Smuzhiyun 		.get_mdio = mii_get_mdio,
494*4882a593Smuzhiyun 		.set_mdc = mii_set_mdc,
495*4882a593Smuzhiyun 		.delay = mii_delay,
496*4882a593Smuzhiyun 		.priv = &fpga_mii[3],
497*4882a593Smuzhiyun 	},
498*4882a593Smuzhiyun };
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
501*4882a593Smuzhiyun 			  sizeof(bb_miiphy_buses[0]);
502