123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- /*
- * Copyright 2014 Freescale Semiconductor, Inc.
- *
- * SPDX-License-Identifier: GPL-2.0+
- *
- * This file handles the board muxing between the RGMII/SGMII PHYs on
- * Freescale LS1021AQDS board. The RGMII PHYs are the three on-board 1Gb
- * ports. The SGMII PHYs are provided by the standard Freescale four-port
- * SGMII riser card.
- *
- * Muxing is handled via the PIXIS BRDCFG4 register. The EMI1 bits control
- * muxing among the RGMII PHYs and the SGMII PHYs. The value for RGMII depends
- * on which port is used. The value for SGMII depends on which slot the riser
- * is inserted in.
- */
- #include <common.h>
- #include <netdev.h>
- #include <asm/arch/fsl_serdes.h>
- #include <fsl_mdio.h>
- #include <tsec.h>
- #include <malloc.h>
- #include "../common/sgmii_riser.h"
- #include "../common/qixis.h"
- #define EMI1_MASK 0x1f
- #define EMI1_RGMII0 1
- #define EMI1_RGMII1 2
- #define EMI1_RGMII2 3
- #define EMI1_SGMII1 0x1c
- #define EMI1_SGMII2 0x1d
- struct ls1021a_mdio {
- struct mii_dev *realbus;
- };
- static void ls1021a_mux_mdio(int addr)
- {
- u8 brdcfg4;
- brdcfg4 = QIXIS_READ(brdcfg[4]);
- brdcfg4 &= EMI1_MASK;
- switch (addr) {
- case EMI1_RGMII0:
- brdcfg4 |= 0;
- break;
- case EMI1_RGMII1:
- brdcfg4 |= 0x20;
- break;
- case EMI1_RGMII2:
- brdcfg4 |= 0x40;
- break;
- case EMI1_SGMII1:
- brdcfg4 |= 0x60;
- break;
- case EMI1_SGMII2:
- brdcfg4 |= 0x80;
- break;
- default:
- brdcfg4 |= 0xa0;
- break;
- }
- QIXIS_WRITE(brdcfg[4], brdcfg4);
- }
- static int ls1021a_mdio_read(struct mii_dev *bus, int addr, int devad,
- int regnum)
- {
- struct ls1021a_mdio *priv = bus->priv;
- ls1021a_mux_mdio(addr);
- return priv->realbus->read(priv->realbus, addr, devad, regnum);
- }
- static int ls1021a_mdio_write(struct mii_dev *bus, int addr, int devad,
- int regnum, u16 value)
- {
- struct ls1021a_mdio *priv = bus->priv;
- ls1021a_mux_mdio(addr);
- return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
- }
- static int ls1021a_mdio_reset(struct mii_dev *bus)
- {
- struct ls1021a_mdio *priv = bus->priv;
- return priv->realbus->reset(priv->realbus);
- }
- static int ls1021a_mdio_init(char *realbusname, char *fakebusname)
- {
- struct ls1021a_mdio *lsmdio;
- struct mii_dev *bus = mdio_alloc();
- if (!bus) {
- printf("Failed to allocate LS102xA MDIO bus\n");
- return -1;
- }
- lsmdio = malloc(sizeof(*lsmdio));
- if (!lsmdio) {
- printf("Failed to allocate LS102xA private data\n");
- free(bus);
- return -1;
- }
- bus->read = ls1021a_mdio_read;
- bus->write = ls1021a_mdio_write;
- bus->reset = ls1021a_mdio_reset;
- strcpy(bus->name, fakebusname);
- lsmdio->realbus = miiphy_get_dev_by_name(realbusname);
- if (!lsmdio->realbus) {
- printf("No bus with name %s\n", realbusname);
- free(bus);
- free(lsmdio);
- return -1;
- }
- bus->priv = lsmdio;
- return mdio_register(bus);
- }
- int board_eth_init(bd_t *bis)
- {
- struct fsl_pq_mdio_info mdio_info;
- struct tsec_info_struct tsec_info[3];
- int num = 0;
- #ifdef CONFIG_TSEC1
- SET_STD_TSEC_INFO(tsec_info[num], 1);
- if (is_serdes_configured(SGMII_TSEC1)) {
- puts("eTSEC1 is in sgmii mode\n");
- tsec_info[num].flags |= TSEC_SGMII;
- tsec_info[num].mii_devname = "LS1021A_SGMII_MDIO";
- } else {
- tsec_info[num].mii_devname = "LS1021A_RGMII_MDIO";
- }
- num++;
- #endif
- #ifdef CONFIG_TSEC2
- SET_STD_TSEC_INFO(tsec_info[num], 2);
- if (is_serdes_configured(SGMII_TSEC2)) {
- puts("eTSEC2 is in sgmii mode\n");
- tsec_info[num].flags |= TSEC_SGMII;
- tsec_info[num].mii_devname = "LS1021A_SGMII_MDIO";
- } else {
- tsec_info[num].mii_devname = "LS1021A_RGMII_MDIO";
- }
- num++;
- #endif
- #ifdef CONFIG_TSEC3
- SET_STD_TSEC_INFO(tsec_info[num], 3);
- tsec_info[num].mii_devname = "LS1021A_RGMII_MDIO";
- num++;
- #endif
- if (!num) {
- printf("No TSECs initialized\n");
- return 0;
- }
- #ifdef CONFIG_FSL_SGMII_RISER
- fsl_sgmii_riser_init(tsec_info, num);
- #endif
- mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR;
- mdio_info.name = DEFAULT_MII_NAME;
- fsl_pq_mdio_init(bis, &mdio_info);
- /* Register the virtual MDIO front-ends */
- ls1021a_mdio_init(DEFAULT_MII_NAME, "LS1021A_RGMII_MDIO");
- ls1021a_mdio_init(DEFAULT_MII_NAME, "LS1021A_SGMII_MDIO");
- tsec_eth_init(bis, tsec_info, num);
- return pci_eth_init(bis);
- }
|