Пример #1
0
/*
 * This function initializes the emac hardware. It does NOT initialize
 * EMAC modules power or pin multiplexors, that is done by board_init()
 * much earlier in bootup process. Returns 1 on success, 0 otherwise.
 */
int davinci_emac_initialize(void)
{
	u_int32_t	phy_id;
	u_int16_t	tmp;
	int		i;
	int		ret;
	struct eth_device *dev;

	dev = malloc(sizeof *dev);

	if (dev == NULL)
		return -1;

	memset(dev, 0, sizeof *dev);
	strcpy(dev->name, "DaVinci-EMAC");

	dev->iobase = 0;
	dev->init = davinci_eth_open;
	dev->halt = davinci_eth_close;
	dev->send = davinci_eth_send_packet;
	dev->recv = davinci_eth_rcv_packet;
	dev->write_hwaddr = davinci_eth_set_mac_addr;

	eth_register(dev);

	davinci_eth_mdio_enable();

	/* let the EMAC detect the PHYs */
	udelay(5000);

	for (i = 0; i < 256; i++) {
		if (readl(&adap_mdio->ALIVE))
			break;
		udelay(1000);
	}

	if (i >= 256) {
		printf("No ETH PHY detected!!!\n");
		return(0);
	}

	/* Find if PHY(s) is/are connected */
	ret = davinci_eth_phy_detect();
	if (!ret)
		return(0);
	else
		debug_emac(" %d ETH PHY detected\n", ret);

	/* Get PHY ID and initialize phy_ops for a detected PHY */
	for (i = 0; i < num_phy; i++) {
		if (!davinci_eth_phy_read(active_phy_addr[i], MII_PHYSID1,
							&tmp)) {
			active_phy_addr[i] = 0xff;
			continue;
		}

		phy_id = (tmp << 16) & 0xffff0000;

		if (!davinci_eth_phy_read(active_phy_addr[i], MII_PHYSID2,
							&tmp)) {
			active_phy_addr[i] = 0xff;
			continue;
		}

		phy_id |= tmp & 0x0000ffff;

		switch (phy_id) {
#ifdef PHY_KSZ8873
		case PHY_KSZ8873:
			sprintf(phy[i].name, "KSZ8873 @ 0x%02x",
						active_phy_addr[i]);
			phy[i].init = ksz8873_init_phy;
			phy[i].is_phy_connected = ksz8873_is_phy_connected;
			phy[i].get_link_speed = ksz8873_get_link_speed;
			phy[i].auto_negotiate = ksz8873_auto_negotiate;
			break;
#endif
#ifdef PHY_LXT972
		case PHY_LXT972:
			sprintf(phy[i].name, "LXT972 @ 0x%02x",
						active_phy_addr[i]);
			phy[i].init = lxt972_init_phy;
			phy[i].is_phy_connected = lxt972_is_phy_connected;
			phy[i].get_link_speed = lxt972_get_link_speed;
			phy[i].auto_negotiate = lxt972_auto_negotiate;
			break;
#endif
#ifdef PHY_DP83848
		case PHY_DP83848:
			sprintf(phy[i].name, "DP83848 @ 0x%02x",
						active_phy_addr[i]);
			phy[i].init = dp83848_init_phy;
			phy[i].is_phy_connected = dp83848_is_phy_connected;
			phy[i].get_link_speed = dp83848_get_link_speed;
			phy[i].auto_negotiate = dp83848_auto_negotiate;
			break;
#endif
#ifdef PHY_ET1011C
		case PHY_ET1011C:
			sprintf(phy[i].name, "ET1011C @ 0x%02x",
						active_phy_addr[i]);
			phy[i].init = gen_init_phy;
			phy[i].is_phy_connected = gen_is_phy_connected;
			phy[i].get_link_speed = et1011c_get_link_speed;
			phy[i].auto_negotiate = gen_auto_negotiate;
			break;
#endif
		default:
			sprintf(phy[i].name, "GENERIC @ 0x%02x",
						active_phy_addr[i]);
			phy[i].init = gen_init_phy;
			phy[i].is_phy_connected = gen_is_phy_connected;
			phy[i].get_link_speed = gen_get_link_speed;
			phy[i].auto_negotiate = gen_auto_negotiate;
		}

		debug("Ethernet PHY: %s\n", phy[i].name);

		int retval;
		struct mii_dev *mdiodev = mdio_alloc();
		if (!mdiodev)
			return -ENOMEM;
		strncpy(mdiodev->name, phy[i].name, MDIO_NAME_LEN);
		mdiodev->read = davinci_mii_phy_read;
		mdiodev->write = davinci_mii_phy_write;

		retval = mdio_register(mdiodev);
		if (retval < 0)
			return retval;
#ifdef DAVINCI_EMAC_GIG_ENABLE
#define PHY_CONF_REG	22
		/* Enable PHY to clock out TX_CLK */
		davinci_eth_phy_read(active_phy_addr[i], PHY_CONF_REG, &tmp);
		tmp |= PHY_CONF_TXCLKEN;
		davinci_eth_phy_write(active_phy_addr[i], PHY_CONF_REG, tmp);
		davinci_eth_phy_read(active_phy_addr[i], PHY_CONF_REG, &tmp);
#endif
	}

#if defined(CONFIG_TI816X) || (defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
		defined(CONFIG_MACH_DAVINCI_DA850_EVM) && \
			!defined(CONFIG_DRIVER_TI_EMAC_RMII_NO_NEGOTIATE))
	for (i = 0; i < num_phy; i++) {
		if (phy[i].is_phy_connected(i))
			phy[i].auto_negotiate(i);
	}
#endif
	return(1);
}
Пример #2
0
static int ks2_eth_probe(struct udevice *dev)
{
	struct ks2_eth_priv *priv = dev_get_priv(dev);
	struct mii_dev *mdio_bus;
	int ret;

	priv->dev = dev;

	/* These clock enables has to be moved to common location */
	if (cpu_is_k2g())
		writel(KS2_ETHERNET_RGMII, KS2_ETHERNET_CFG);

	/* By default, select PA PLL clock as PA clock source */
#ifndef CONFIG_SOC_K2G
	if (psc_enable_module(KS2_LPSC_PA))
		return -EACCES;
#endif
	if (psc_enable_module(KS2_LPSC_CPGMAC))
		return -EACCES;
	if (psc_enable_module(KS2_LPSC_CRYPTO))
		return -EACCES;

	if (cpu_is_k2e() || cpu_is_k2l())
		pll_pa_clk_sel();


	priv->net_rx_buffs.buff_ptr = rx_buffs;
	priv->net_rx_buffs.num_buffs = RX_BUFF_NUMS;
	priv->net_rx_buffs.buff_len = RX_BUFF_LEN;

	if (priv->slave_port == 1) {
		/*
		 * Register MDIO bus for slave 0 only, other slave have
		 * to re-use the same
		 */
		mdio_bus = mdio_alloc();
		if (!mdio_bus) {
			error("MDIO alloc failed\n");
			return -ENOMEM;
		}
		priv->mdio_bus = mdio_bus;
		mdio_bus->read	= keystone2_mdio_read;
		mdio_bus->write	= keystone2_mdio_write;
		mdio_bus->reset	= keystone2_mdio_reset;
		mdio_bus->priv	= priv->mdio_base;
		sprintf(mdio_bus->name, "ethernet-mdio");

		ret = mdio_register(mdio_bus);
		if (ret) {
			error("MDIO bus register failed\n");
			return ret;
		}
	} else {
		/* Get the MDIO bus from slave 0 device */
		struct ks2_eth_priv *parent_priv;

		parent_priv = dev_get_priv(dev->parent);
		priv->mdio_bus = parent_priv->mdio_bus;
	}

#ifndef CONFIG_SOC_K2G
	keystone2_net_serdes_setup();
#endif

	priv->netcp_pktdma = &netcp_pktdma;

	if (priv->has_mdio) {
		priv->phydev = phy_connect(priv->mdio_bus, priv->phy_addr,
					   dev, priv->phy_if);
		phy_config(priv->phydev);
	}

	return 0;
}
Пример #3
0
int fec_init(unsigned phy_mask, struct enet* enet)
{
	struct eth_device *edev;
    struct phy_device *phydev;
	struct mii_dev *bus;
	int ret = 0;
    struct eth_device _eth;
	/* create and fill edev struct */
	edev = &_eth;
	memset(edev, 0, sizeof(*edev));

	edev->priv = (void*)enet;
	edev->write_hwaddr = NULL;

    /* Alocate the mdio bus */
	bus = mdio_alloc();
	if (!bus) {
		return -1;
	}
	bus->read = fec_phy_read;
	bus->write = fec_phy_write;
	bus->priv = enet;
	strcpy(bus->name, edev->name);
	ret = mdio_register(bus);
	if (ret) {
		free(bus);
		return -1;
	}

    /****** Configure phy ******/
    phydev = phy_connect_by_mask(bus, phy_mask, edev, PHY_INTERFACE_MODE_RGMII);
    if (!phydev) {
        return -1;
    }

    /* min rx data delay */
    ksz9021_phy_extended_write(phydev, MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0);
    /* min tx data delay */
    ksz9021_phy_extended_write(phydev, MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, 0x0);
    /* max rx/tx clock delay, min rx/tx control */
    ksz9021_phy_extended_write(phydev, MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0xf0f0);
    ksz9021_config(phydev);

	/* Start up the PHY */
	ret = ksz9021_startup(phydev);
	if (ret) {
		printf("Could not initialize PHY %s\n", phydev->dev->name);
		return ret;
	}

    printf("\n  * Link speed: %4i Mbps, ", phydev->speed);
    if(phydev->duplex == DUPLEX_FULL){
        enet_set_speed(enet, phydev->speed, 1);
        printf("full-duplex *\n");
    }else{
        enet_set_speed(enet, phydev->speed, 0);
        printf("half-duplex *\n");
    }

    udelay(100000);
    return 0;
}
Пример #4
0
int bcm_sf2_eth_register(bd_t *bis, u8 dev_num)
{
	struct eth_device *dev;
	struct eth_info *eth;
	int rc;

	dev = (struct eth_device *)malloc(sizeof(struct eth_device));
	if (dev == NULL) {
		error("%s: Not enough memory!\n", __func__);
		return -1;
	}

	eth = (struct eth_info *)malloc(sizeof(struct eth_info));
	if (eth == NULL) {
		error("%s: Not enough memory!\n", __func__);
		return -1;
	}

	printf(banner);

	memset(dev, 0, sizeof(*dev));
	sprintf(dev->name, "%s_%s-%hu", BCM_SF2_ETH_DEV_NAME,
		BCM_SF2_ETH_MAC_NAME, dev_num);

	dev->priv = (void *)eth;
	dev->iobase = 0;

	dev->init = bcm_sf2_eth_open;
	dev->halt = bcm_sf2_eth_close;
	dev->send = bcm_sf2_eth_send;
	dev->recv = bcm_sf2_eth_receive;
	dev->write_hwaddr = bcm_sf2_eth_write_hwaddr;

#ifdef CONFIG_BCM_SF2_ETH_GMAC
	if (gmac_add(dev)) {
		free(eth);
		free(dev);
		error("%s: Adding GMAC failed!\n", __func__);
		return -1;
	}
#else
#error "bcm_sf2_eth: NEED to register a MAC!"
#endif

	eth_register(dev);

#ifdef CONFIG_CMD_MII
	int retval;
	struct mii_dev *mdiodev = mdio_alloc();

	if (!mdiodev)
		return -ENOMEM;
	strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
	mdiodev->read = eth->miiphy_read;
	mdiodev->write = eth->miiphy_write;

	retval = mdio_register(mdiodev);
	if (retval < 0)
		return retval;
#endif

	/* Initialization */
	debug("Ethernet initialization ...");

	rc = bcm_sf2_eth_init(dev);
	if (rc != 0) {
		error("%s: configuration failed!\n", __func__);
		return -1;
	}

	printf("Basic ethernet functionality initialized\n");

	return 0;
}
Пример #5
0
/*
 * This function initializes the EMAC hardware.
 */
int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
{
	int res;
	struct eth_device *dev;
	struct phy_device *phy_dev;
	struct mdio_regs *adap_mdio = (struct mdio_regs *)EMAC_MDIO_BASE_ADDR;

	dev = malloc(sizeof(struct eth_device));
	if (dev == NULL)
		return -1;

	memset(dev, 0, sizeof(struct eth_device));

	strcpy(dev->name, eth_priv->int_name);
	dev->priv = eth_priv;

	keystone2_eth_read_mac_addr(dev);

	dev->iobase		= 0;
	dev->init		= keystone2_eth_open;
	dev->halt		= keystone2_eth_close;
	dev->send		= keystone2_eth_send_packet;
	dev->recv		= keystone2_eth_rcv_packet;
#ifdef CONFIG_MCAST_TFTP
	dev->mcast		= keystone2_eth_bcast_addr;
#endif

	eth_register(dev);

	/* Register MDIO bus if it's not registered yet */
	if (!mdio_bus) {
		mdio_bus	= mdio_alloc();
		mdio_bus->read	= keystone2_mdio_read;
		mdio_bus->write	= keystone2_mdio_write;
		mdio_bus->reset	= keystone2_mdio_reset;
		mdio_bus->priv	= (void *)EMAC_MDIO_BASE_ADDR;
		strcpy(mdio_bus->name, "ethernet-mdio");

		res = mdio_register(mdio_bus);
		if (res)
			return res;
	}

#ifndef CONFIG_SOC_K2G
	keystone2_net_serdes_setup();
#endif

	/* Create phy device and bind it with driver */
#ifdef CONFIG_KSNET_MDIO_PHY_CONFIG_ENABLE
	phy_dev = phy_connect(mdio_bus, eth_priv->phy_addr,
			      dev, eth_priv->phy_if);
	phy_config(phy_dev);
#else
	phy_dev = phy_find_by_mask(mdio_bus, 1 << eth_priv->phy_addr,
				   eth_priv->phy_if);
	phy_dev->dev = dev;
#endif
	eth_priv->phy_dev = phy_dev;

	return 0;
}
Пример #6
0
int last_stage_init(void)
{
	int slaves;
	uint k;
	uchar mclink_controllers[] = { 0x3c, 0x3d, 0x3e };
	u16 fpga_features;
	bool hw_type_cat = pca9698_get_value(0x20, 20);
	bool ch0_rgmii2_present;

	FPGA_GET_REG(0, fpga_features, &fpga_features);

	/* Turn on Parade DP501 */
	pca9698_direction_output(0x20, 10, 1);
	pca9698_direction_output(0x20, 11, 1);

	ch0_rgmii2_present = !pca9698_get_value(0x20, 30);

	/* wait for FPGA done, then reset FPGA */
	for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) {
		uint ctr = 0;

		if (i2c_probe(mclink_controllers[k]))
			continue;

		while (!(pca953x_get_val(mclink_controllers[k])
		       & MCFPGA_DONE)) {
			mdelay(100);
			if (ctr++ > 5) {
				printf("no done for mclink_controller %u\n", k);
				break;
			}
		}

		pca953x_set_dir(mclink_controllers[k], MCFPGA_RESET_N, 0);
		pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, 0);
		udelay(10);
		pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N,
				MCFPGA_RESET_N);
	}

	if (hw_type_cat) {
		uint mux_ch;
		int retval;
		struct mii_dev *mdiodev = mdio_alloc();

		if (!mdiodev)
			return -ENOMEM;
		strncpy(mdiodev->name, bb_miiphy_buses[0].name, MDIO_NAME_LEN);
		mdiodev->read = bb_miiphy_read;
		mdiodev->write = bb_miiphy_write;

		retval = mdio_register(mdiodev);
		if (retval < 0)
			return retval;
		for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) {
			if ((mux_ch == 1) && !ch0_rgmii2_present)
				continue;

			setup_88e1514(bb_miiphy_buses[0].name, mux_ch);
		}
	}

	/* give slave-PLLs and Parade DP501 some time to be up and running */
	mdelay(500);

	mclink_fpgacount = CONFIG_SYS_MCLINK_MAX;
	slaves = mclink_probe();
	mclink_fpgacount = 0;

	ioep_fpga_print_info(0);
	osd_probe(0);
#ifdef CONFIG_SYS_OSD_DH
	osd_probe(4);
#endif

	if (slaves <= 0)
		return 0;

	mclink_fpgacount = slaves;

	for (k = 1; k <= slaves; ++k) {
		FPGA_GET_REG(k, fpga_features, &fpga_features);

		ioep_fpga_print_info(k);
		osd_probe(k);
#ifdef CONFIG_SYS_OSD_DH
		osd_probe(k + 4);
#endif
		if (hw_type_cat) {
			int retval;
			struct mii_dev *mdiodev = mdio_alloc();

			if (!mdiodev)
				return -ENOMEM;
			strncpy(mdiodev->name, bb_miiphy_buses[k].name,
				MDIO_NAME_LEN);
			mdiodev->read = bb_miiphy_read;
			mdiodev->write = bb_miiphy_write;

			retval = mdio_register(mdiodev);
			if (retval < 0)
				return retval;
			setup_88e1514(bb_miiphy_buses[k].name, 0);
		}
	}

	for (k = 0; k < ARRAY_SIZE(hrcon_fans); ++k) {
		i2c_set_bus_num(hrcon_fans[k].bus);
		init_fan_controller(hrcon_fans[k].addr);
	}

	return 0;
}
Пример #7
0
int uec_initialize(bd_t *bis, uec_info_t *uec_info)
{
	struct eth_device	*dev;
	int			i;
	uec_private_t		*uec;
	int			err;

	dev = (struct eth_device *)malloc(sizeof(struct eth_device));
	if (!dev)
		return 0;
	memset(dev, 0, sizeof(struct eth_device));

	/* Allocate the UEC private struct */
	uec = (uec_private_t *)malloc(sizeof(uec_private_t));
	if (!uec) {
		return -ENOMEM;
	}
	memset(uec, 0, sizeof(uec_private_t));

	/* Adjust uec_info */
#if (MAX_QE_RISC == 4)
	uec_info->risc_tx = QE_RISC_ALLOCATION_FOUR_RISCS;
	uec_info->risc_rx = QE_RISC_ALLOCATION_FOUR_RISCS;
#endif

	devlist[uec_info->uf_info.ucc_num] = dev;

	uec->uec_info = uec_info;
	uec->dev = dev;

	sprintf(dev->name, "UEC%d", uec_info->uf_info.ucc_num);
	dev->iobase = 0;
	dev->priv = (void *)uec;
	dev->init = uec_init;
	dev->halt = uec_halt;
	dev->send = uec_send;
	dev->recv = uec_recv;

	/* Clear the ethnet address */
	for (i = 0; i < 6; i++)
		dev->enetaddr[i] = 0;

	eth_register(dev);

	err = uec_startup(uec);
	if (err) {
		printf("%s: Cannot configure net device, aborting.",dev->name);
		return err;
	}

#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
	int retval;
	struct mii_dev *mdiodev = mdio_alloc();
	if (!mdiodev)
		return -ENOMEM;
	strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
	mdiodev->read = uec_miiphy_read;
	mdiodev->write = uec_miiphy_write;

	retval = mdio_register(mdiodev);
	if (retval < 0)
		return retval;
#endif

	return 1;
}
Пример #8
0
struct mii_dev *cpsw_mdio_init(const char *name, u32 mdio_base,
			       u32 bus_freq, int fck_freq)
{
	struct cpsw_mdio *cpsw_mdio;
	int ret;

	cpsw_mdio = calloc(1, sizeof(*cpsw_mdio));
	if (!cpsw_mdio) {
		debug("failed to alloc cpsw_mdio\n");
		return NULL;
	}

	cpsw_mdio->bus = mdio_alloc();
	if (!cpsw_mdio->bus) {
		debug("failed to alloc mii bus\n");
		free(cpsw_mdio);
		return NULL;
	}

	cpsw_mdio->regs = (struct cpsw_mdio_regs *)mdio_base;

	if (!bus_freq || !fck_freq)
		cpsw_mdio->div = CPSW_MDIO_DIV_DEF;
	else
		cpsw_mdio->div = (fck_freq / bus_freq) - 1;
	cpsw_mdio->div &= CONTROL_DIV_MASK;

	/* set enable and clock divider */
	writel(cpsw_mdio->div | CONTROL_ENABLE | CONTROL_FAULT |
	       CONTROL_FAULT_ENABLE, &cpsw_mdio->regs->control);
	wait_for_bit_le32(&cpsw_mdio->regs->control,
			  CONTROL_IDLE, false, CPSW_MDIO_TIMEOUT, true);

	/*
	 * wait for scan logic to settle:
	 * the scan time consists of (a) a large fixed component, and (b) a
	 * small component that varies with the mii bus frequency.  These
	 * were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x
	 * silicon.  Since the effect of (b) was found to be largely
	 * negligible, we keep things simple here.
	 */
	mdelay(1);

	cpsw_mdio->bus->read = cpsw_mdio_read;
	cpsw_mdio->bus->write = cpsw_mdio_write;
	cpsw_mdio->bus->priv = cpsw_mdio;
	snprintf(cpsw_mdio->bus->name, sizeof(cpsw_mdio->bus->name), name);

	ret = mdio_register(cpsw_mdio->bus);
	if (ret < 0) {
		debug("failed to register mii bus\n");
		goto free_bus;
	}

	return cpsw_mdio->bus;

free_bus:
	mdio_free(cpsw_mdio->bus);
	free(cpsw_mdio);
	return NULL;
}
Пример #9
0
static int fec_probe(bd_t *bd, int dev_id, int phy_id, uint32_t base_addr)
{
	struct eth_device *edev;
	struct fec_priv *fec;
	struct mii_dev *bus;
	unsigned char ethaddr[6];
	uint32_t start;
	int ret = 0;

	/* create and fill edev struct */
	edev = (struct eth_device *)malloc(sizeof(struct eth_device));
	if (!edev) {
		puts("fec_mxc: not enough malloc memory for eth_device\n");
		ret = -ENOMEM;
		goto err1;
	}

	fec = (struct fec_priv *)malloc(sizeof(struct fec_priv));
	if (!fec) {
		puts("fec_mxc: not enough malloc memory for fec_priv\n");
		ret = -ENOMEM;
		goto err2;
	}

	memset(edev, 0, sizeof(*edev));
	memset(fec, 0, sizeof(*fec));

	edev->priv = fec;
	edev->init = fec_init;
	edev->send = fec_send;
	edev->recv = fec_recv;
	edev->halt = fec_halt;
	edev->write_hwaddr = fec_set_hwaddr;

	fec->eth = (struct ethernet_regs *)base_addr;
	fec->bd = bd;

	fec->xcv_type = CONFIG_FEC_XCV_TYPE;

	/* Reset chip. */
	writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_RESET, &fec->eth->ecntrl);
	start = get_timer(0);
	while (readl(&fec->eth->ecntrl) & FEC_ECNTRL_RESET) {
		if (get_timer(start) > (CONFIG_SYS_HZ * 5)) {
			printf("FEC MXC: Timeout reseting chip\n");
			goto err3;
		}
		udelay(10);
	}

	/*
	 * Set interrupt mask register
	 */
	writel(0x00000000, &fec->eth->imask);

	/*
	 * Clear FEC-Lite interrupt event register(IEVENT)
	 */
	writel(0xffffffff, &fec->eth->ievent);

	/*
	 * Set FEC-Lite receive control register(R_CNTRL):
	 */
	/*
	 * Frame length=1518; MII mode;
	 */
	writel((PKTSIZE << FEC_RCNTRL_MAX_FL_SHIFT) | FEC_RCNTRL_FCE |
		FEC_RCNTRL_MII_MODE, &fec->eth->r_cntrl);
	fec_mii_setspeed(fec);

	if (dev_id == -1) {
		sprintf(edev->name, "FEC");
		fec->dev_id = 0;
	} else {
		sprintf(edev->name, "FEC%i", dev_id);
		fec->dev_id = dev_id;
	}
	fec->phy_id = phy_id;

	bus = mdio_alloc();
	if (!bus) {
		printf("mdio_alloc failed\n");
		ret = -ENOMEM;
		goto err3;
	}
	bus->read = fec_phy_read;
	bus->write = fec_phy_write;
	sprintf(bus->name, edev->name);
#ifdef	CONFIG_MX28
	/*
	 * The i.MX28 has two ethernet interfaces, but they are not equal.
	 * Only the first one can access the MDIO bus.
	 */
	bus->priv = (struct ethernet_regs *)MXS_ENET0_BASE;
#else
	bus->priv = fec->eth;
#endif
	ret = mdio_register(bus);
	if (ret) {
		printf("mdio_register failed\n");
		free(bus);
		ret = -ENOMEM;
		goto err3;
	}
	fec->bus = bus;
	eth_register(edev);

	if (fec_get_hwaddr(edev, dev_id, ethaddr) == 0) {
		debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr);
		memcpy(edev->enetaddr, ethaddr, 6);
	}
	/* Configure phy */
	fec_eth_phy_config(edev);
	return ret;

err3:
	free(fec);
err2:
	free(edev);
err1:
	return ret;
}
Пример #10
0
int last_stage_init(void)
{
	int slaves;
	unsigned int k;
	unsigned int mux_ch;
	unsigned char mclink_controllers_dvi[] = { 0x3c, 0x3d, 0x3e };
#ifdef CONFIG_STRIDER_CPU
	unsigned char mclink_controllers_dp[] = { 0x24, 0x25, 0x26 };
#endif
	bool hw_type_cat = pca9698_get_value(0x20, 18);
#ifdef CONFIG_STRIDER_CON_DP
	bool is_dh = pca9698_get_value(0x20, 25);
#endif
	bool ch0_sgmii2_present = false;

	/* Turn on Analog Devices ADV7611 */
	pca9698_direction_output(0x20, 8, 0);

	/* Turn on Parade DP501 */
	pca9698_direction_output(0x20, 10, 1);
	pca9698_direction_output(0x20, 11, 1);

	ch0_sgmii2_present = !pca9698_get_value(0x20, 37);

	/* wait for FPGA done, then reset FPGA */
	for (k = 0; k < ARRAY_SIZE(mclink_controllers_dvi); ++k) {
		unsigned int ctr = 0;
		unsigned char *mclink_controllers = mclink_controllers_dvi;

#ifdef CONFIG_STRIDER_CPU
		if (i2c_probe(mclink_controllers[k])) {
			mclink_controllers = mclink_controllers_dp;
			if (i2c_probe(mclink_controllers[k]))
				continue;
		}
#else
		if (i2c_probe(mclink_controllers[k]))
			continue;
#endif
		while (!(pca953x_get_val(mclink_controllers[k])
		       & MCFPGA_DONE)) {
			udelay(100000);
			if (ctr++ > 5) {
				printf("no done for mclink_controller %d\n", k);
				break;
			}
		}

		pca953x_set_dir(mclink_controllers[k], MCFPGA_RESET_N, 0);
		pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, 0);
		udelay(10);
		pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N,
				MCFPGA_RESET_N);
	}

	if (hw_type_cat) {
		int retval;
		struct mii_dev *mdiodev = mdio_alloc();
		if (!mdiodev)
			return -ENOMEM;
		strncpy(mdiodev->name, bb_miiphy_buses[0].name, MDIO_NAME_LEN);
		mdiodev->read = bb_miiphy_read;
		mdiodev->write = bb_miiphy_write;

		retval = mdio_register(mdiodev);
		if (retval < 0)
			return retval;
		for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) {
			if ((mux_ch == 1) && !ch0_sgmii2_present)
				continue;

			setup_88e1514(bb_miiphy_buses[0].name, mux_ch);
		}
	}

	/* give slave-PLLs and Parade DP501 some time to be up and running */
	udelay(500000);

	mclink_fpgacount = CONFIG_SYS_MCLINK_MAX;
	slaves = mclink_probe();
	mclink_fpgacount = 0;

	ioep_fpga_print_info(0);

	if (!adv7611_probe(0))
		printf("       Advantiv ADV7611 HDMI Receiver\n");

#ifdef CONFIG_STRIDER_CON
	if (ioep_fpga_has_osd(0))
		osd_probe(0);
#endif

#ifdef CONFIG_STRIDER_CON_DP
	if (ioep_fpga_has_osd(0)) {
		osd_probe(0);
		if (is_dh)
			osd_probe(4);
	}
#endif

#ifdef CONFIG_STRIDER_CPU
	ch7301_probe(0, false);
	dp501_probe(0, false);
#endif

	if (slaves <= 0)
		return 0;

	mclink_fpgacount = slaves;

#ifdef CONFIG_STRIDER_CPU
	/* get ADV7611 out of reset, power up DP501, give some time to wakeup */
	for (k = 1; k <= slaves; ++k)
		FPGA_SET_REG(k, extended_control, 0x10); /* enable video */

	udelay(500000);
#endif

	for (k = 1; k <= slaves; ++k) {
		ioep_fpga_print_info(k);
#ifdef CONFIG_STRIDER_CON
		if (ioep_fpga_has_osd(k))
			osd_probe(k);
#endif
#ifdef CONFIG_STRIDER_CON_DP
		if (ioep_fpga_has_osd(k)) {
			osd_probe(k);
			if (is_dh)
				osd_probe(k + 4);
		}
#endif
#ifdef CONFIG_STRIDER_CPU
		if (!adv7611_probe(k))
			printf("       Advantiv ADV7611 HDMI Receiver\n");
		ch7301_probe(k, false);
		dp501_probe(k, false);
#endif
		if (hw_type_cat) {
			int retval;
			struct mii_dev *mdiodev = mdio_alloc();
			if (!mdiodev)
				return -ENOMEM;
			strncpy(mdiodev->name, bb_miiphy_buses[k].name,
				MDIO_NAME_LEN);
			mdiodev->read = bb_miiphy_read;
			mdiodev->write = bb_miiphy_write;

			retval = mdio_register(mdiodev);
			if (retval < 0)
				return retval;
			setup_88e1514(bb_miiphy_buses[k].name, 0);
		}
	}

	for (k = 0; k < ARRAY_SIZE(strider_fans); ++k) {
		i2c_set_bus_num(strider_fans[k].bus);
		init_fan_controller(strider_fans[k].addr);
	}

	return 0;
}