Home | History | Annotate | Download | only in mpc8308
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) Copyright 2014
      4  * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach (at) gdsys.cc
      5  */
      6 
      7 #include <common.h>
      8 #include <hwconfig.h>
      9 #include <i2c.h>
     10 #include <spi.h>
     11 #include <linux/libfdt.h>
     12 #include <fdt_support.h>
     13 #include <pci.h>
     14 #include <mpc83xx.h>
     15 #include <fsl_esdhc.h>
     16 #include <asm/io.h>
     17 #include <asm/fsl_serdes.h>
     18 #include <asm/fsl_mpc83xx_serdes.h>
     19 
     20 #include "mpc8308.h"
     21 
     22 #include <gdsys_fpga.h>
     23 
     24 #include "../common/adv7611.h"
     25 #include "../common/ch7301.h"
     26 #include "../common/dp501.h"
     27 #include "../common/ioep-fpga.h"
     28 #include "../common/mclink.h"
     29 #include "../common/osd.h"
     30 #include "../common/phy.h"
     31 #include "../common/fanctrl.h"
     32 
     33 #include <pca953x.h>
     34 #include <pca9698.h>
     35 
     36 #include <miiphy.h>
     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 } strider_fans[] = CONFIG_STRIDER_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 = env_get("serial#");
    107 	bool hw_type_cat = pca9698_get_value(0x20, 18);
    108 
    109 	puts("Board: ");
    110 
    111 	printf("Strider %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_dvi[] = { 0x3c, 0x3d, 0x3e };
    129 #ifdef CONFIG_STRIDER_CPU
    130 	unsigned char mclink_controllers_dp[] = { 0x24, 0x25, 0x26 };
    131 #endif
    132 	bool hw_type_cat = pca9698_get_value(0x20, 18);
    133 #ifdef CONFIG_STRIDER_CON_DP
    134 	bool is_dh = pca9698_get_value(0x20, 25);
    135 #endif
    136 	bool ch0_sgmii2_present = false;
    137 
    138 	/* Turn on Analog Devices ADV7611 */
    139 	pca9698_direction_output(0x20, 8, 0);
    140 
    141 	/* Turn on Parade DP501 */
    142 	pca9698_direction_output(0x20, 10, 1);
    143 	pca9698_direction_output(0x20, 11, 1);
    144 
    145 	ch0_sgmii2_present = !pca9698_get_value(0x20, 37);
    146 
    147 	/* wait for FPGA done, then reset FPGA */
    148 	for (k = 0; k < ARRAY_SIZE(mclink_controllers_dvi); ++k) {
    149 		unsigned int ctr = 0;
    150 		unsigned char *mclink_controllers = mclink_controllers_dvi;
    151 
    152 #ifdef CONFIG_STRIDER_CPU
    153 		if (i2c_probe(mclink_controllers[k])) {
    154 			mclink_controllers = mclink_controllers_dp;
    155 			if (i2c_probe(mclink_controllers[k]))
    156 				continue;
    157 		}
    158 #else
    159 		if (i2c_probe(mclink_controllers[k]))
    160 			continue;
    161 #endif
    162 		while (!(pca953x_get_val(mclink_controllers[k])
    163 		       & MCFPGA_DONE)) {
    164 			udelay(100000);
    165 			if (ctr++ > 5) {
    166 				printf("no done for mclink_controller %d\n", k);
    167 				break;
    168 			}
    169 		}
    170 
    171 		pca953x_set_dir(mclink_controllers[k], MCFPGA_RESET_N, 0);
    172 		pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, 0);
    173 		udelay(10);
    174 		pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N,
    175 				MCFPGA_RESET_N);
    176 	}
    177 
    178 	if (hw_type_cat) {
    179 		int retval;
    180 		struct mii_dev *mdiodev = mdio_alloc();
    181 		if (!mdiodev)
    182 			return -ENOMEM;
    183 		strncpy(mdiodev->name, bb_miiphy_buses[0].name, MDIO_NAME_LEN);
    184 		mdiodev->read = bb_miiphy_read;
    185 		mdiodev->write = bb_miiphy_write;
    186 
    187 		retval = mdio_register(mdiodev);
    188 		if (retval < 0)
    189 			return retval;
    190 		for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) {
    191 			if ((mux_ch == 1) && !ch0_sgmii2_present)
    192 				continue;
    193 
    194 			setup_88e1514(bb_miiphy_buses[0].name, mux_ch);
    195 		}
    196 	}
    197 
    198 	/* give slave-PLLs and Parade DP501 some time to be up and running */
    199 	udelay(500000);
    200 
    201 	mclink_fpgacount = CONFIG_SYS_MCLINK_MAX;
    202 	slaves = mclink_probe();
    203 	mclink_fpgacount = 0;
    204 
    205 	ioep_fpga_print_info(0);
    206 
    207 	if (!adv7611_probe(0))
    208 		printf("       Advantiv ADV7611 HDMI Receiver\n");
    209 
    210 #ifdef CONFIG_STRIDER_CON
    211 	if (ioep_fpga_has_osd(0))
    212 		osd_probe(0);
    213 #endif
    214 
    215 #ifdef CONFIG_STRIDER_CON_DP
    216 	if (ioep_fpga_has_osd(0)) {
    217 		osd_probe(0);
    218 		if (is_dh)
    219 			osd_probe(4);
    220 	}
    221 #endif
    222 
    223 #ifdef CONFIG_STRIDER_CPU
    224 	ch7301_probe(0, false);
    225 	dp501_probe(0, false);
    226 #endif
    227 
    228 	if (slaves <= 0)
    229 		return 0;
    230 
    231 	mclink_fpgacount = slaves;
    232 
    233 #ifdef CONFIG_STRIDER_CPU
    234 	/* get ADV7611 out of reset, power up DP501, give some time to wakeup */
    235 	for (k = 1; k <= slaves; ++k)
    236 		FPGA_SET_REG(k, extended_control, 0x10); /* enable video */
    237 
    238 	udelay(500000);
    239 #endif
    240 
    241 	for (k = 1; k <= slaves; ++k) {
    242 		ioep_fpga_print_info(k);
    243 #ifdef CONFIG_STRIDER_CON
    244 		if (ioep_fpga_has_osd(k))
    245 			osd_probe(k);
    246 #endif
    247 #ifdef CONFIG_STRIDER_CON_DP
    248 		if (ioep_fpga_has_osd(k)) {
    249 			osd_probe(k);
    250 			if (is_dh)
    251 				osd_probe(k + 4);
    252 		}
    253 #endif
    254 #ifdef CONFIG_STRIDER_CPU
    255 		if (!adv7611_probe(k))
    256 			printf("       Advantiv ADV7611 HDMI Receiver\n");
    257 		ch7301_probe(k, false);
    258 		dp501_probe(k, false);
    259 #endif
    260 		if (hw_type_cat) {
    261 			int retval;
    262 			struct mii_dev *mdiodev = mdio_alloc();
    263 			if (!mdiodev)
    264 				return -ENOMEM;
    265 			strncpy(mdiodev->name, bb_miiphy_buses[k].name,
    266 				MDIO_NAME_LEN);
    267 			mdiodev->read = bb_miiphy_read;
    268 			mdiodev->write = bb_miiphy_write;
    269 
    270 			retval = mdio_register(mdiodev);
    271 			if (retval < 0)
    272 				return retval;
    273 			setup_88e1514(bb_miiphy_buses[k].name, 0);
    274 		}
    275 	}
    276 
    277 	for (k = 0; k < ARRAY_SIZE(strider_fans); ++k) {
    278 		i2c_set_bus_num(strider_fans[k].bus);
    279 		init_fan_controller(strider_fans[k].addr);
    280 	}
    281 
    282 	return 0;
    283 }
    284 
    285 /*
    286  * provide access to fpga gpios (for I2C bitbang)
    287  * (these may look all too simple but make iocon.h much more readable)
    288  */
    289 void fpga_gpio_set(unsigned int bus, int pin)
    290 {
    291 	FPGA_SET_REG(bus, gpio.set, pin);
    292 }
    293 
    294 void fpga_gpio_clear(unsigned int bus, int pin)
    295 {
    296 	FPGA_SET_REG(bus, gpio.clear, pin);
    297 }
    298 
    299 int fpga_gpio_get(unsigned int bus, int pin)
    300 {
    301 	u16 val;
    302 
    303 	FPGA_GET_REG(bus, gpio.read, &val);
    304 
    305 	return val & pin;
    306 }
    307 
    308 #ifdef CONFIG_STRIDER_CON_DP
    309 void fpga_control_set(unsigned int bus, int pin)
    310 {
    311 	u16 val;
    312 
    313 	FPGA_GET_REG(bus, control, &val);
    314 	FPGA_SET_REG(bus, control, val | pin);
    315 }
    316 
    317 void fpga_control_clear(unsigned int bus, int pin)
    318 {
    319 	u16 val;
    320 
    321 	FPGA_GET_REG(bus, control, &val);
    322 	FPGA_SET_REG(bus, control, val & ~pin);
    323 }
    324 #endif
    325 
    326 void mpc8308_init(void)
    327 {
    328 	pca9698_direction_output(0x20, 26, 1);
    329 }
    330 
    331 void mpc8308_set_fpga_reset(unsigned state)
    332 {
    333 	pca9698_set_value(0x20, 26, state ? 0 : 1);
    334 }
    335 
    336 void mpc8308_setup_hw(void)
    337 {
    338 	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
    339 
    340 	/*
    341 	 * set "startup-finished"-gpios
    342 	 */
    343 	setbits_be32(&immr->gpio[0].dir, (1 << (31-11)) | (1 << (31-12)));
    344 	setbits_be32(&immr->gpio[0].dat, 1 << (31-12));
    345 }
    346 
    347 int mpc8308_get_fpga_done(unsigned fpga)
    348 {
    349 	return pca9698_get_value(0x20, 20);
    350 }
    351 
    352 #ifdef CONFIG_FSL_ESDHC
    353 int board_mmc_init(bd_t *bd)
    354 {
    355 	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
    356 	sysconf83xx_t *sysconf = &immr->sysconf;
    357 
    358 	/* Enable cache snooping in eSDHC system configuration register */
    359 	out_be32(&sysconf->sdhccr, 0x02000000);
    360 
    361 	return fsl_esdhc_mmc_init(bd);
    362 }
    363 #endif
    364 
    365 static struct pci_region pcie_regions_0[] = {
    366 	{
    367 		.bus_start = CONFIG_SYS_PCIE1_MEM_BASE,
    368 		.phys_start = CONFIG_SYS_PCIE1_MEM_PHYS,
    369 		.size = CONFIG_SYS_PCIE1_MEM_SIZE,
    370 		.flags = PCI_REGION_MEM,
    371 	},
    372 	{
    373 		.bus_start = CONFIG_SYS_PCIE1_IO_BASE,
    374 		.phys_start = CONFIG_SYS_PCIE1_IO_PHYS,
    375 		.size = CONFIG_SYS_PCIE1_IO_SIZE,
    376 		.flags = PCI_REGION_IO,
    377 	},
    378 };
    379 
    380 void pci_init_board(void)
    381 {
    382 	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
    383 	sysconf83xx_t *sysconf = &immr->sysconf;
    384 	law83xx_t *pcie_law = sysconf->pcielaw;
    385 	struct pci_region *pcie_reg[] = { pcie_regions_0 };
    386 
    387 	fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_PEX,
    388 			 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
    389 
    390 	/* Deassert the resets in the control register */
    391 	out_be32(&sysconf->pecr1, 0xE0008000);
    392 	udelay(2000);
    393 
    394 	/* Configure PCI Express Local Access Windows */
    395 	out_be32(&pcie_law[0].bar, CONFIG_SYS_PCIE1_BASE & LAWBAR_BAR);
    396 	out_be32(&pcie_law[0].ar, LBLAWAR_EN | LBLAWAR_512MB);
    397 
    398 	mpc83xx_pcie_init(1, pcie_reg);
    399 }
    400 
    401 ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
    402 {
    403 	info->portwidth = FLASH_CFI_16BIT;
    404 	info->chipwidth = FLASH_CFI_BY16;
    405 	info->interface = FLASH_CFI_X16;
    406 	return 1;
    407 }
    408 
    409 #if defined(CONFIG_OF_BOARD_SETUP)
    410 int ft_board_setup(void *blob, bd_t *bd)
    411 {
    412 	ft_cpu_setup(blob, bd);
    413 	fsl_fdt_fixup_dr_usb(blob, bd);
    414 	fdt_fixup_esdhc(blob, bd);
    415 
    416 	return 0;
    417 }
    418 #endif
    419 
    420 /*
    421  * FPGA MII bitbang implementation
    422  */
    423 
    424 struct fpga_mii {
    425 	unsigned fpga;
    426 	int mdio;
    427 } fpga_mii[] = {
    428 	{ 0, 1},
    429 	{ 1, 1},
    430 	{ 2, 1},
    431 	{ 3, 1},
    432 };
    433 
    434 static int mii_dummy_init(struct bb_miiphy_bus *bus)
    435 {
    436 	return 0;
    437 }
    438 
    439 static int mii_mdio_active(struct bb_miiphy_bus *bus)
    440 {
    441 	struct fpga_mii *fpga_mii = bus->priv;
    442 
    443 	if (fpga_mii->mdio)
    444 		FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
    445 	else
    446 		FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
    447 
    448 	return 0;
    449 }
    450 
    451 static int mii_mdio_tristate(struct bb_miiphy_bus *bus)
    452 {
    453 	struct fpga_mii *fpga_mii = bus->priv;
    454 
    455 	FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
    456 
    457 	return 0;
    458 }
    459 
    460 static int mii_set_mdio(struct bb_miiphy_bus *bus, int v)
    461 {
    462 	struct fpga_mii *fpga_mii = bus->priv;
    463 
    464 	if (v)
    465 		FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
    466 	else
    467 		FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
    468 
    469 	fpga_mii->mdio = v;
    470 
    471 	return 0;
    472 }
    473 
    474 static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v)
    475 {
    476 	u16 gpio;
    477 	struct fpga_mii *fpga_mii = bus->priv;
    478 
    479 	FPGA_GET_REG(fpga_mii->fpga, gpio.read, &gpio);
    480 
    481 	*v = ((gpio & GPIO_MDIO) != 0);
    482 
    483 	return 0;
    484 }
    485 
    486 static int mii_set_mdc(struct bb_miiphy_bus *bus, int v)
    487 {
    488 	struct fpga_mii *fpga_mii = bus->priv;
    489 
    490 	if (v)
    491 		FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDC);
    492 	else
    493 		FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDC);
    494 
    495 	return 0;
    496 }
    497 
    498 static int mii_delay(struct bb_miiphy_bus *bus)
    499 {
    500 	udelay(1);
    501 
    502 	return 0;
    503 }
    504 
    505 struct bb_miiphy_bus bb_miiphy_buses[] = {
    506 	{
    507 		.name = "board0",
    508 		.init = mii_dummy_init,
    509 		.mdio_active = mii_mdio_active,
    510 		.mdio_tristate = mii_mdio_tristate,
    511 		.set_mdio = mii_set_mdio,
    512 		.get_mdio = mii_get_mdio,
    513 		.set_mdc = mii_set_mdc,
    514 		.delay = mii_delay,
    515 		.priv = &fpga_mii[0],
    516 	},
    517 	{
    518 		.name = "board1",
    519 		.init = mii_dummy_init,
    520 		.mdio_active = mii_mdio_active,
    521 		.mdio_tristate = mii_mdio_tristate,
    522 		.set_mdio = mii_set_mdio,
    523 		.get_mdio = mii_get_mdio,
    524 		.set_mdc = mii_set_mdc,
    525 		.delay = mii_delay,
    526 		.priv = &fpga_mii[1],
    527 	},
    528 	{
    529 		.name = "board2",
    530 		.init = mii_dummy_init,
    531 		.mdio_active = mii_mdio_active,
    532 		.mdio_tristate = mii_mdio_tristate,
    533 		.set_mdio = mii_set_mdio,
    534 		.get_mdio = mii_get_mdio,
    535 		.set_mdc = mii_set_mdc,
    536 		.delay = mii_delay,
    537 		.priv = &fpga_mii[2],
    538 	},
    539 	{
    540 		.name = "board3",
    541 		.init = mii_dummy_init,
    542 		.mdio_active = mii_mdio_active,
    543 		.mdio_tristate = mii_mdio_tristate,
    544 		.set_mdio = mii_set_mdio,
    545 		.get_mdio = mii_get_mdio,
    546 		.set_mdc = mii_set_mdc,
    547 		.delay = mii_delay,
    548 		.priv = &fpga_mii[3],
    549 	},
    550 };
    551 
    552 int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
    553 			  sizeof(bb_miiphy_buses[0]);
    554