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