bbmiiphy clean up and DM alignment, finally gets rid of the static
bbmiiphy variables and plugs bbmiiphy into MDIO framework.
This commit is contained in:
Tom Rini
2025-02-26 14:32:16 -06:00
8 changed files with 501 additions and 532 deletions

View File

@@ -102,102 +102,6 @@ uint calculate_octo_phy_mask(void)
return octo_phy_mask;
}
int register_miiphy_bus(uint k, struct mii_dev **bus)
{
int retval;
struct mii_dev *mdiodev = mdio_alloc();
char *name = bb_miiphy_buses[k].name;
if (!mdiodev)
return -ENOMEM;
strlcpy(mdiodev->name, name, MDIO_NAME_LEN);
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
*bus = miiphy_get_dev_by_name(name);
return 0;
}
struct porttype *get_porttype(uint octo_phy_mask, uint k)
{
uint octo_index = k * 4;
if (!k) {
if (octo_phy_mask & 0x01)
return &porttypes[PORTTYPE_MAIN_CAT];
else if (!(octo_phy_mask & 0x03))
return &porttypes[PORTTYPE_16C_16F];
} else {
if (octo_phy_mask & (1 << octo_index))
return &porttypes[PORTTYPE_TOP_CAT];
}
return NULL;
}
int init_single_phy(struct porttype *porttype, struct mii_dev *bus,
uint bus_idx, uint m, uint phy_idx)
{
struct phy_device *phydev;
phydev = phy_find_by_mask(bus, BIT(m * 8 + phy_idx));
printf(" %u", bus_idx * 32 + m * 8 + phy_idx);
if (!phydev)
puts("!");
else
ihs_phy_config(phydev, porttype->phy_invert_in_pol,
porttype->phy_invert_out_pol);
return 0;
}
int init_octo_phys(uint octo_phy_mask)
{
uint bus_idx;
/* there are up to four octo-phys on each mdio bus */
for (bus_idx = 0; bus_idx < bb_miiphy_buses_num; ++bus_idx) {
uint m;
uint octo_index = bus_idx * 4;
struct mii_dev *bus = NULL;
struct porttype *porttype = NULL;
int ret;
porttype = get_porttype(octo_phy_mask, bus_idx);
if (!porttype)
continue;
for (m = 0; m < 4; ++m) {
uint phy_idx;
/**
* Register a bus device if there is at least one phy
* on the current bus
*/
if (!m && octo_phy_mask & (0xf << octo_index)) {
ret = register_miiphy_bus(bus_idx, &bus);
if (ret)
return ret;
}
if (!(octo_phy_mask & BIT(octo_index + m)))
continue;
for (phy_idx = 0; phy_idx < 8; ++phy_idx)
init_single_phy(porttype, bus, bus_idx, m,
phy_idx);
}
}
return 0;
}
/*
* MII GPIO bitbang implementation
* MDC MDIO bus
@@ -315,40 +219,109 @@ static int mii_delay(struct bb_miiphy_bus *bus)
return 0;
}
struct bb_miiphy_bus bb_miiphy_buses[] = {
{
.name = "ihs0",
.init = mii_mdio_init,
.mdio_active = mii_mdio_active,
.mdio_tristate = mii_mdio_tristate,
.set_mdio = mii_set_mdio,
.get_mdio = mii_get_mdio,
.set_mdc = mii_set_mdc,
.delay = mii_delay,
.priv = &gpio_mii_set[0],
},
{
.name = "ihs1",
.init = mii_mdio_init,
.mdio_active = mii_mdio_active,
.mdio_tristate = mii_mdio_tristate,
.set_mdio = mii_set_mdio,
.get_mdio = mii_get_mdio,
.set_mdc = mii_set_mdc,
.delay = mii_delay,
.priv = &gpio_mii_set[1],
},
{
.name = "ihs2",
.init = mii_mdio_init,
.mdio_active = mii_mdio_active,
.mdio_tristate = mii_mdio_tristate,
.set_mdio = mii_set_mdio,
.get_mdio = mii_get_mdio,
.set_mdc = mii_set_mdc,
.delay = mii_delay,
.priv = &gpio_mii_set[2],
},
};
int register_miiphy_bus(uint k, struct mii_dev **bus)
{
struct bb_miiphy_bus *bb_miiphy = bb_miiphy_alloc();
struct mii_dev *mdiodev;
int retval;
int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses);
if (!bb_miiphy)
return -ENOMEM;
mdiodev = &bb_miiphy->mii;
snprintf(mdiodev->name, MDIO_NAME_LEN, "ihs%d", k);
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
/* Copy the bus accessors and private data */
bb_miiphy->mdio_active = mii_mdio_active;
bb_miiphy->mdio_tristate = mii_mdio_tristate;
bb_miiphy->set_mdio = mii_set_mdio;
bb_miiphy->get_mdio = mii_get_mdio;
bb_miiphy->set_mdc = mii_set_mdc;
bb_miiphy->delay = mii_delay;
bb_miiphy->priv = &gpio_mii_set[k];
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
*bus = &bb_miiphy->mii;
return mii_mdio_init(bb_miiphy);
}
struct porttype *get_porttype(uint octo_phy_mask, uint k)
{
uint octo_index = k * 4;
if (!k) {
if (octo_phy_mask & 0x01)
return &porttypes[PORTTYPE_MAIN_CAT];
else if (!(octo_phy_mask & 0x03))
return &porttypes[PORTTYPE_16C_16F];
} else {
if (octo_phy_mask & (1 << octo_index))
return &porttypes[PORTTYPE_TOP_CAT];
}
return NULL;
}
int init_single_phy(struct porttype *porttype, struct mii_dev *bus,
uint bus_idx, uint m, uint phy_idx)
{
struct phy_device *phydev;
phydev = phy_find_by_mask(bus, BIT(m * 8 + phy_idx));
printf(" %u", bus_idx * 32 + m * 8 + phy_idx);
if (!phydev)
puts("!");
else
ihs_phy_config(phydev, porttype->phy_invert_in_pol,
porttype->phy_invert_out_pol);
return 0;
}
int init_octo_phys(uint octo_phy_mask)
{
uint bus_idx;
/* there are up to four octo-phys on each mdio bus */
for (bus_idx = 0; bus_idx < ARRAY_SIZE(gpio_mii_set); ++bus_idx) {
uint m;
uint octo_index = bus_idx * 4;
struct mii_dev *bus = NULL;
struct porttype *porttype = NULL;
int ret;
porttype = get_porttype(octo_phy_mask, bus_idx);
if (!porttype)
continue;
for (m = 0; m < 4; ++m) {
uint phy_idx;
/**
* Register a bus device if there is at least one phy
* on the current bus
*/
if (!m && octo_phy_mask & (0xf << octo_index)) {
ret = register_miiphy_bus(bus_idx, &bus);
if (ret)
return ret;
}
if (!(octo_phy_mask & BIT(octo_index + m)))
continue;
for (phy_idx = 0; phy_idx < 8; ++phy_idx)
init_single_phy(porttype, bus, bus_idx, m,
phy_idx);
}
}
return 0;
}

View File

@@ -749,9 +749,6 @@ static init_fnc_t init_sequence_r[] = {
#ifdef CONFIG_BOARD_LATE_INIT
board_late_init,
#endif
#ifdef CONFIG_BITBANGMII
bb_miiphy_init,
#endif
#ifdef CONFIG_PCI_ENDPOINT
pci_ep_init,
#endif

View File

@@ -65,6 +65,14 @@ void miiphy_init(void)
current_mii = NULL;
}
void mdio_init(struct mii_dev *bus)
{
memset(bus, 0, sizeof(*bus));
/* initialize mii_dev struct fields */
INIT_LIST_HEAD(&bus->link);
}
struct mii_dev *mdio_alloc(void)
{
struct mii_dev *bus;
@@ -73,10 +81,7 @@ struct mii_dev *mdio_alloc(void)
if (!bus)
return bus;
memset(bus, 0, sizeof(*bus));
/* initalize mii_dev struct fields */
INIT_LIST_HEAD(&bus->link);
mdio_init(bus);
return bus;
}

View File

@@ -226,6 +226,124 @@ static int dw_dm_mdio_init(const char *name, void *priv)
}
#endif
#if IS_ENABLED(CONFIG_BITBANGMII) && IS_ENABLED(CONFIG_DM_GPIO)
static int dw_eth_bb_mdio_active(struct bb_miiphy_bus *bus)
{
struct dw_eth_dev *priv = bus->priv;
struct gpio_desc *desc = &priv->mdio_gpio;
desc->flags = 0;
dm_gpio_set_dir_flags(&priv->mdio_gpio, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
return 0;
}
static int dw_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus)
{
struct dw_eth_dev *priv = bus->priv;
struct gpio_desc *desc = &priv->mdio_gpio;
desc->flags = 0;
dm_gpio_set_dir_flags(&priv->mdio_gpio, GPIOD_IS_IN);
return 0;
}
static int dw_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
{
struct dw_eth_dev *priv = bus->priv;
if (v)
dm_gpio_set_value(&priv->mdio_gpio, 1);
else
dm_gpio_set_value(&priv->mdio_gpio, 0);
return 0;
}
static int dw_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
{
struct dw_eth_dev *priv = bus->priv;
*v = dm_gpio_get_value(&priv->mdio_gpio);
return 0;
}
static int dw_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
{
struct dw_eth_dev *priv = bus->priv;
if (v)
dm_gpio_set_value(&priv->mdc_gpio, 1);
else
dm_gpio_set_value(&priv->mdc_gpio, 0);
return 0;
}
static int dw_eth_bb_delay(struct bb_miiphy_bus *bus)
{
struct dw_eth_dev *priv = bus->priv;
udelay(priv->bb_delay);
return 0;
}
static int dw_bb_mdio_init(const char *name, struct udevice *dev)
{
struct dw_eth_dev *dwpriv = dev_get_priv(dev);
struct bb_miiphy_bus *bb_miiphy = bb_miiphy_alloc();
struct mii_dev *bus;
int ret;
if (!bb_miiphy) {
printf("Failed to allocate MDIO bus\n");
return -ENOMEM;
}
bus = &bb_miiphy->mii;
debug("\n%s: use bitbang mii..\n", dev->name);
ret = gpio_request_by_name(dev, "snps,mdc-gpio", 0,
&dwpriv->mdc_gpio,
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
if (ret) {
debug("no mdc-gpio\n");
return ret;
}
ret = gpio_request_by_name(dev, "snps,mdio-gpio", 0,
&dwpriv->mdio_gpio,
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
if (ret) {
debug("no mdio-gpio\n");
return ret;
}
dwpriv->bb_delay = dev_read_u32_default(dev, "snps,bitbang-delay", 1);
dwpriv->bus = bus;
dwpriv->dev = dev;
snprintf(bus->name, sizeof(bus->name), "%s", name);
bus->read = bb_miiphy_read;
bus->write = bb_miiphy_write;
#if CONFIG_IS_ENABLED(DM_GPIO)
bus->reset = dw_mdio_reset;
#endif
bus->priv = dwpriv;
/* Copy the bus accessors and private data */
bb_miiphy->mdio_active = dw_eth_bb_mdio_active;
bb_miiphy->mdio_tristate = dw_eth_bb_mdio_tristate;
bb_miiphy->set_mdio = dw_eth_bb_set_mdio;
bb_miiphy->get_mdio = dw_eth_bb_get_mdio;
bb_miiphy->set_mdc = dw_eth_bb_set_mdc;
bb_miiphy->delay = dw_eth_bb_delay;
return mdio_register(bus);
}
#endif
static void tx_descs_init(struct dw_eth_dev *priv)
{
struct eth_dma_regs *dma_p = priv->dma_regs_p;
@@ -722,6 +840,7 @@ int designware_eth_probe(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_plat(dev);
struct dw_eth_dev *priv = dev_get_priv(dev);
bool __maybe_unused bbmiiphy = false;
phys_addr_t iobase = pdata->iobase;
void *ioaddr;
int ret, err;
@@ -812,51 +931,30 @@ int designware_eth_probe(struct udevice *dev)
priv->interface = pdata->phy_interface;
priv->max_speed = pdata->max_speed;
#if IS_ENABLED(CONFIG_DM_MDIO)
ret = dw_dm_mdio_init(dev->name, dev);
#else
ret = dw_mdio_init(dev->name, dev);
#endif
if (ret) {
err = ret;
goto mdio_err;
}
priv->bus = miiphy_get_dev_by_name(dev->name);
priv->dev = dev;
#if IS_ENABLED(CONFIG_BITBANGMII) && IS_ENABLED(CONFIG_DM_GPIO)
if (dev_read_bool(dev, "snps,bitbang-mii")) {
int bus_idx;
debug("\n%s: use bitbang mii..\n", dev->name);
ret = gpio_request_by_name(dev, "snps,mdc-gpio", 0,
&priv->mdc_gpio, GPIOD_IS_OUT
| GPIOD_IS_OUT_ACTIVE);
bbmiiphy = dev_read_bool(dev, "snps,bitbang-mii");
if (bbmiiphy) {
ret = dw_bb_mdio_init(dev->name, dev);
if (ret) {
debug("no mdc-gpio\n");
return ret;
err = ret;
goto mdio_err;
}
ret = gpio_request_by_name(dev, "snps,mdio-gpio", 0,
&priv->mdio_gpio, GPIOD_IS_OUT
| GPIOD_IS_OUT_ACTIVE);
if (ret) {
debug("no mdio-gpio\n");
return ret;
}
priv->bb_delay = dev_read_u32_default(dev, "snps,bitbang-delay", 1);
for (bus_idx = 0; bus_idx < bb_miiphy_buses_num; bus_idx++) {
if (!bb_miiphy_buses[bus_idx].priv) {
bb_miiphy_buses[bus_idx].priv = priv;
strlcpy(bb_miiphy_buses[bus_idx].name, priv->bus->name,
MDIO_NAME_LEN);
priv->bus->read = bb_miiphy_read;
priv->bus->write = bb_miiphy_write;
break;
}
}
}
} else
#endif
{
#if IS_ENABLED(CONFIG_DM_MDIO)
ret = dw_dm_mdio_init(dev->name, dev);
#else
ret = dw_mdio_init(dev->name, dev);
#endif
if (ret) {
err = ret;
goto mdio_err;
}
priv->bus = miiphy_get_dev_by_name(dev->name);
priv->dev = dev;
}
ret = dw_phy_init(priv, dev);
debug("%s, ret=%d\n", __func__, ret);
if (!ret)
@@ -865,7 +963,12 @@ int designware_eth_probe(struct udevice *dev)
/* continue here for cleanup if no PHY found */
err = ret;
mdio_unregister(priv->bus);
mdio_free(priv->bus);
#if IS_ENABLED(CONFIG_BITBANGMII) && IS_ENABLED(CONFIG_DM_GPIO)
if (bbmiiphy)
bb_miiphy_free(container_of(priv->bus, struct bb_miiphy_bus, mii));
else
#endif
mdio_free(priv->bus);
mdio_err:
#ifdef CONFIG_CLK
@@ -967,83 +1070,3 @@ static struct pci_device_id supported[] = {
};
U_BOOT_PCI_DEVICE(eth_designware, supported);
#if IS_ENABLED(CONFIG_BITBANGMII) && IS_ENABLED(CONFIG_DM_GPIO)
static int dw_eth_bb_mdio_active(struct bb_miiphy_bus *bus)
{
struct dw_eth_dev *priv = bus->priv;
struct gpio_desc *desc = &priv->mdio_gpio;
desc->flags = 0;
dm_gpio_set_dir_flags(&priv->mdio_gpio, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
return 0;
}
static int dw_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus)
{
struct dw_eth_dev *priv = bus->priv;
struct gpio_desc *desc = &priv->mdio_gpio;
desc->flags = 0;
dm_gpio_set_dir_flags(&priv->mdio_gpio, GPIOD_IS_IN);
return 0;
}
static int dw_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
{
struct dw_eth_dev *priv = bus->priv;
if (v)
dm_gpio_set_value(&priv->mdio_gpio, 1);
else
dm_gpio_set_value(&priv->mdio_gpio, 0);
return 0;
}
static int dw_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
{
struct dw_eth_dev *priv = bus->priv;
*v = dm_gpio_get_value(&priv->mdio_gpio);
return 0;
}
static int dw_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
{
struct dw_eth_dev *priv = bus->priv;
if (v)
dm_gpio_set_value(&priv->mdc_gpio, 1);
else
dm_gpio_set_value(&priv->mdc_gpio, 0);
return 0;
}
static int dw_eth_bb_delay(struct bb_miiphy_bus *bus)
{
struct dw_eth_dev *priv = bus->priv;
udelay(priv->bb_delay);
return 0;
}
struct bb_miiphy_bus bb_miiphy_buses[] = {
{
.name = BB_MII_DEVNAME,
.mdio_active = dw_eth_bb_mdio_active,
.mdio_tristate = dw_eth_bb_mdio_tristate,
.set_mdio = dw_eth_bb_set_mdio,
.get_mdio = dw_eth_bb_get_mdio,
.set_mdc = dw_eth_bb_set_mdc,
.delay = dw_eth_bb_delay,
.priv = NULL,
}
};
int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses);
#endif

View File

@@ -14,31 +14,31 @@
#include <ioports.h>
#include <ppc_asm.tmpl>
#include <malloc.h>
#include <miiphy.h>
#include <asm/global_data.h>
int bb_miiphy_init(void)
static inline struct bb_miiphy_bus *bb_miiphy_getbus(struct mii_dev *miidev)
{
int i;
for (i = 0; i < bb_miiphy_buses_num; i++)
if (bb_miiphy_buses[i].init != NULL)
bb_miiphy_buses[i].init(&bb_miiphy_buses[i]);
return 0;
return container_of(miidev, struct bb_miiphy_bus, mii);
}
static inline struct bb_miiphy_bus *bb_miiphy_getbus(const char *devname)
struct bb_miiphy_bus *bb_miiphy_alloc(void)
{
int i;
struct bb_miiphy_bus *bus;
/* Search the correct bus */
for (i = 0; i < bb_miiphy_buses_num; i++) {
if (!strcmp(bb_miiphy_buses[i].name, devname)) {
return &bb_miiphy_buses[i];
}
}
return NULL;
bus = malloc(sizeof(*bus));
if (!bus)
return bus;
mdio_init(&bus->mii);
return bus;
}
void bb_miiphy_free(struct bb_miiphy_bus *bus)
{
free(bus);
}
/*****************************************************************************
@@ -133,7 +133,7 @@ int bb_miiphy_read(struct mii_dev *miidev, int addr, int devad, int reg)
int j; /* counter */
struct bb_miiphy_bus *bus;
bus = bb_miiphy_getbus(miidev->name);
bus = bb_miiphy_getbus(miidev);
if (bus == NULL) {
return -1;
}
@@ -201,7 +201,7 @@ int bb_miiphy_write(struct mii_dev *miidev, int addr, int devad, int reg,
struct bb_miiphy_bus *bus;
int j; /* counter */
bus = bb_miiphy_getbus(miidev->name);
bus = bb_miiphy_getbus(miidev);
if (bus == NULL) {
/* Bus not found! */
return -1;

View File

@@ -490,81 +490,7 @@ static void ravb_stop(struct udevice *dev)
ravb_reset(dev);
}
static int ravb_probe(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_plat(dev);
struct ravb_priv *eth = dev_get_priv(dev);
struct mii_dev *mdiodev;
void __iomem *iobase;
int ret;
iobase = map_physmem(pdata->iobase, 0x1000, MAP_NOCACHE);
eth->iobase = iobase;
ret = clk_get_bulk(dev, &eth->clks);
if (ret < 0)
goto err_mdio_alloc;
mdiodev = mdio_alloc();
if (!mdiodev) {
ret = -ENOMEM;
goto err_mdio_alloc;
}
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
bb_miiphy_buses[0].priv = eth;
snprintf(mdiodev->name, sizeof(mdiodev->name), dev->name);
ret = mdio_register(mdiodev);
if (ret < 0)
goto err_mdio_register;
eth->bus = miiphy_get_dev_by_name(dev->name);
/* Bring up PHY */
ret = clk_enable_bulk(&eth->clks);
if (ret)
goto err_mdio_register;
ret = ravb_reset(dev);
if (ret)
goto err_mdio_reset;
ret = ravb_phy_config(dev);
if (ret)
goto err_mdio_reset;
return 0;
err_mdio_reset:
clk_release_bulk(&eth->clks);
err_mdio_register:
mdio_free(mdiodev);
err_mdio_alloc:
unmap_physmem(eth->iobase, MAP_NOCACHE);
return ret;
}
static int ravb_remove(struct udevice *dev)
{
struct ravb_priv *eth = dev_get_priv(dev);
clk_release_bulk(&eth->clks);
free(eth->phydev);
mdio_unregister(eth->bus);
mdio_free(eth->bus);
unmap_physmem(eth->iobase, MAP_NOCACHE);
return 0;
}
static int ravb_bb_init(struct bb_miiphy_bus *bus)
{
return 0;
}
/* Bitbang MDIO access */
static int ravb_bb_mdio_active(struct bb_miiphy_bus *bus)
{
struct ravb_priv *eth = bus->priv;
@@ -623,19 +549,86 @@ static int ravb_bb_delay(struct bb_miiphy_bus *bus)
return 0;
}
struct bb_miiphy_bus bb_miiphy_buses[] = {
{
.name = "ravb",
.init = ravb_bb_init,
.mdio_active = ravb_bb_mdio_active,
.mdio_tristate = ravb_bb_mdio_tristate,
.set_mdio = ravb_bb_set_mdio,
.get_mdio = ravb_bb_get_mdio,
.set_mdc = ravb_bb_set_mdc,
.delay = ravb_bb_delay,
},
};
int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses);
static int ravb_probe(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_plat(dev);
struct ravb_priv *eth = dev_get_priv(dev);
struct bb_miiphy_bus *bb_miiphy;
struct mii_dev *mdiodev;
void __iomem *iobase;
int ret;
iobase = map_physmem(pdata->iobase, 0x1000, MAP_NOCACHE);
eth->iobase = iobase;
ret = clk_get_bulk(dev, &eth->clks);
if (ret < 0)
goto err_mdio_alloc;
bb_miiphy = bb_miiphy_alloc();
if (!bb_miiphy) {
ret = -ENOMEM;
goto err_mdio_alloc;
}
mdiodev = &bb_miiphy->mii;
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
snprintf(mdiodev->name, sizeof(mdiodev->name), dev->name);
/* Copy the bus accessors and private data */
bb_miiphy->mdio_active = ravb_bb_mdio_active;
bb_miiphy->mdio_tristate = ravb_bb_mdio_tristate;
bb_miiphy->set_mdio = ravb_bb_set_mdio;
bb_miiphy->get_mdio = ravb_bb_get_mdio;
bb_miiphy->set_mdc = ravb_bb_set_mdc;
bb_miiphy->delay = ravb_bb_delay;
bb_miiphy->priv = eth;
ret = mdio_register(mdiodev);
if (ret < 0)
goto err_mdio_register;
eth->bus = &bb_miiphy->mii;
/* Bring up PHY */
ret = clk_enable_bulk(&eth->clks);
if (ret)
goto err_mdio_register;
ret = ravb_reset(dev);
if (ret)
goto err_mdio_reset;
ret = ravb_phy_config(dev);
if (ret)
goto err_mdio_reset;
return 0;
err_mdio_reset:
clk_release_bulk(&eth->clks);
err_mdio_register:
bb_miiphy_free(bb_miiphy);
err_mdio_alloc:
unmap_physmem(eth->iobase, MAP_NOCACHE);
return ret;
}
static int ravb_remove(struct udevice *dev)
{
struct ravb_priv *eth = dev_get_priv(dev);
clk_release_bulk(&eth->clks);
free(eth->phydev);
mdio_unregister(eth->bus);
mdio_free(eth->bus);
unmap_physmem(eth->iobase, MAP_NOCACHE);
return 0;
}
static const struct eth_ops ravb_ops = {
.start = ravb_start,
@@ -658,8 +651,6 @@ int ravb_of_to_plat(struct udevice *dev)
pdata->max_speed = dev_read_u32_default(dev, "max-speed", 1000);
sprintf(bb_miiphy_buses[0].name, dev->name);
return 0;
}

View File

@@ -643,145 +643,7 @@ static void sh_ether_stop(struct udevice *dev)
sh_eth_stop(&priv->shdev);
}
static int sh_ether_probe(struct udevice *udev)
{
struct eth_pdata *pdata = dev_get_plat(udev);
struct sh_ether_priv *priv = dev_get_priv(udev);
struct sh_eth_dev *eth = &priv->shdev;
struct mii_dev *mdiodev;
int ret;
priv->iobase = pdata->iobase;
#if CONFIG_IS_ENABLED(CLK)
ret = clk_get_by_index(udev, 0, &priv->clk);
if (ret < 0)
return ret;
#endif
mdiodev = mdio_alloc();
if (!mdiodev) {
ret = -ENOMEM;
return ret;
}
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
bb_miiphy_buses[0].priv = eth;
snprintf(mdiodev->name, sizeof(mdiodev->name), udev->name);
ret = mdio_register(mdiodev);
if (ret < 0)
goto err_mdio_register;
priv->bus = miiphy_get_dev_by_name(udev->name);
eth->port = CFG_SH_ETHER_USE_PORT;
eth->port_info[eth->port].phy_addr = CFG_SH_ETHER_PHY_ADDR;
eth->port_info[eth->port].iobase =
(void __iomem *)(uintptr_t)(BASE_IO_ADDR + 0x800 * eth->port);
#if CONFIG_IS_ENABLED(CLK)
ret = clk_enable(&priv->clk);
if (ret)
goto err_mdio_register;
#endif
ret = sh_eth_init_common(eth, pdata->enetaddr);
if (ret)
goto err_phy_config;
ret = sh_eth_phy_config(udev);
if (ret) {
printf(SHETHER_NAME ": phy config timeout\n");
goto err_phy_config;
}
return 0;
err_phy_config:
#if CONFIG_IS_ENABLED(CLK)
clk_disable(&priv->clk);
#endif
err_mdio_register:
mdio_free(mdiodev);
return ret;
}
static int sh_ether_remove(struct udevice *udev)
{
struct sh_ether_priv *priv = dev_get_priv(udev);
struct sh_eth_dev *eth = &priv->shdev;
struct sh_eth_info *port_info = &eth->port_info[eth->port];
#if CONFIG_IS_ENABLED(CLK)
clk_disable(&priv->clk);
#endif
free(port_info->phydev);
mdio_unregister(priv->bus);
mdio_free(priv->bus);
return 0;
}
static const struct eth_ops sh_ether_ops = {
.start = sh_ether_start,
.send = sh_ether_send,
.recv = sh_ether_recv,
.free_pkt = sh_ether_free_pkt,
.stop = sh_ether_stop,
.write_hwaddr = sh_ether_write_hwaddr,
};
int sh_ether_of_to_plat(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_plat(dev);
const fdt32_t *cell;
pdata->iobase = dev_read_addr(dev);
pdata->phy_interface = dev_read_phy_mode(dev);
if (pdata->phy_interface == PHY_INTERFACE_MODE_NA)
return -EINVAL;
pdata->max_speed = 1000;
cell = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "max-speed", NULL);
if (cell)
pdata->max_speed = fdt32_to_cpu(*cell);
sprintf(bb_miiphy_buses[0].name, dev->name);
return 0;
}
static const struct udevice_id sh_ether_ids[] = {
{ .compatible = "renesas,ether-r7s72100" },
{ .compatible = "renesas,ether-r8a7790" },
{ .compatible = "renesas,ether-r8a7791" },
{ .compatible = "renesas,ether-r8a7793" },
{ .compatible = "renesas,ether-r8a7794" },
{ .compatible = "renesas,gether-r8a77980" },
{ }
};
U_BOOT_DRIVER(eth_sh_ether) = {
.name = "sh_ether",
.id = UCLASS_ETH,
.of_match = sh_ether_ids,
.of_to_plat = sh_ether_of_to_plat,
.probe = sh_ether_probe,
.remove = sh_ether_remove,
.ops = &sh_ether_ops,
.priv_auto = sizeof(struct sh_ether_priv),
.plat_auto = sizeof(struct eth_pdata),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
};
/******* for bb_miiphy *******/
static int sh_eth_bb_init(struct bb_miiphy_bus *bus)
{
return 0;
}
static int sh_eth_bb_mdio_active(struct bb_miiphy_bus *bus)
{
struct sh_eth_dev *eth = bus->priv;
@@ -849,17 +711,144 @@ static int sh_eth_bb_delay(struct bb_miiphy_bus *bus)
return 0;
}
struct bb_miiphy_bus bb_miiphy_buses[] = {
{
.name = "sh_eth",
.init = sh_eth_bb_init,
.mdio_active = sh_eth_bb_mdio_active,
.mdio_tristate = sh_eth_bb_mdio_tristate,
.set_mdio = sh_eth_bb_set_mdio,
.get_mdio = sh_eth_bb_get_mdio,
.set_mdc = sh_eth_bb_set_mdc,
.delay = sh_eth_bb_delay,
static int sh_ether_probe(struct udevice *udev)
{
struct eth_pdata *pdata = dev_get_plat(udev);
struct sh_ether_priv *priv = dev_get_priv(udev);
struct sh_eth_dev *eth = &priv->shdev;
struct bb_miiphy_bus *bb_miiphy;
struct mii_dev *mdiodev;
int ret;
priv->iobase = pdata->iobase;
#if CONFIG_IS_ENABLED(CLK)
ret = clk_get_by_index(udev, 0, &priv->clk);
if (ret < 0)
return ret;
#endif
bb_miiphy = bb_miiphy_alloc();
if (!bb_miiphy) {
ret = -ENOMEM;
return ret;
}
mdiodev = &bb_miiphy->mii;
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
snprintf(mdiodev->name, sizeof(mdiodev->name), udev->name);
/* Copy the bus accessors and private data */
bb_miiphy->mdio_active = sh_eth_bb_mdio_active;
bb_miiphy->mdio_tristate = sh_eth_bb_mdio_tristate;
bb_miiphy->set_mdio = sh_eth_bb_set_mdio;
bb_miiphy->get_mdio = sh_eth_bb_get_mdio;
bb_miiphy->set_mdc = sh_eth_bb_set_mdc;
bb_miiphy->delay = sh_eth_bb_delay;
bb_miiphy->priv = eth;
ret = mdio_register(mdiodev);
if (ret < 0)
goto err_mdio_register;
priv->bus = &bb_miiphy->mii;
eth->port = CFG_SH_ETHER_USE_PORT;
eth->port_info[eth->port].phy_addr = CFG_SH_ETHER_PHY_ADDR;
eth->port_info[eth->port].iobase =
(void __iomem *)(uintptr_t)(BASE_IO_ADDR + 0x800 * eth->port);
#if CONFIG_IS_ENABLED(CLK)
ret = clk_enable(&priv->clk);
if (ret)
goto err_mdio_register;
#endif
ret = sh_eth_init_common(eth, pdata->enetaddr);
if (ret)
goto err_phy_config;
ret = sh_eth_phy_config(udev);
if (ret) {
printf(SHETHER_NAME ": phy config timeout\n");
goto err_phy_config;
}
return 0;
err_phy_config:
#if CONFIG_IS_ENABLED(CLK)
clk_disable(&priv->clk);
#endif
err_mdio_register:
bb_miiphy_free(bb_miiphy);
return ret;
}
static int sh_ether_remove(struct udevice *udev)
{
struct sh_ether_priv *priv = dev_get_priv(udev);
struct sh_eth_dev *eth = &priv->shdev;
struct sh_eth_info *port_info = &eth->port_info[eth->port];
#if CONFIG_IS_ENABLED(CLK)
clk_disable(&priv->clk);
#endif
free(port_info->phydev);
mdio_unregister(priv->bus);
mdio_free(priv->bus);
return 0;
}
static const struct eth_ops sh_ether_ops = {
.start = sh_ether_start,
.send = sh_ether_send,
.recv = sh_ether_recv,
.free_pkt = sh_ether_free_pkt,
.stop = sh_ether_stop,
.write_hwaddr = sh_ether_write_hwaddr,
};
int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses);
int sh_ether_of_to_plat(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_plat(dev);
const fdt32_t *cell;
pdata->iobase = dev_read_addr(dev);
pdata->phy_interface = dev_read_phy_mode(dev);
if (pdata->phy_interface == PHY_INTERFACE_MODE_NA)
return -EINVAL;
pdata->max_speed = 1000;
cell = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "max-speed", NULL);
if (cell)
pdata->max_speed = fdt32_to_cpu(*cell);
return 0;
}
static const struct udevice_id sh_ether_ids[] = {
{ .compatible = "renesas,ether-r7s72100" },
{ .compatible = "renesas,ether-r8a7790" },
{ .compatible = "renesas,ether-r8a7791" },
{ .compatible = "renesas,ether-r8a7793" },
{ .compatible = "renesas,ether-r8a7794" },
{ .compatible = "renesas,gether-r8a77980" },
{ }
};
U_BOOT_DRIVER(eth_sh_ether) = {
.name = "sh_ether",
.id = UCLASS_ETH,
.of_match = sh_ether_ids,
.of_to_plat = sh_ether_of_to_plat,
.probe = sh_ether_probe,
.remove = sh_ether_remove,
.ops = &sh_ether_ops,
.priv_auto = sizeof(struct sh_ether_priv),
.plat_auto = sizeof(struct eth_pdata),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
};

View File

@@ -44,6 +44,7 @@ struct phy_device *mdio_phydev_for_ethname(const char *devname);
void miiphy_listdev(void);
void mdio_init(struct mii_dev *bus);
struct mii_dev *mdio_alloc(void);
void mdio_free(struct mii_dev *bus);
int mdio_register(struct mii_dev *bus);
@@ -64,8 +65,6 @@ void mdio_list_devices(void);
#define BB_MII_DEVNAME "bb_miiphy"
struct bb_miiphy_bus {
char name[MDIO_NAME_LEN];
int (*init)(struct bb_miiphy_bus *bus);
int (*mdio_active)(struct bb_miiphy_bus *bus);
int (*mdio_tristate)(struct bb_miiphy_bus *bus);
int (*set_mdio)(struct bb_miiphy_bus *bus, int v);
@@ -73,19 +72,11 @@ struct bb_miiphy_bus {
int (*set_mdc)(struct bb_miiphy_bus *bus, int v);
int (*delay)(struct bb_miiphy_bus *bus);
void *priv;
struct mii_dev mii;
};
extern struct bb_miiphy_bus bb_miiphy_buses[];
extern int bb_miiphy_buses_num;
/**
* bb_miiphy_init() - Initialize bit-banged MII bus driver
*
* It is called during the generic post-relocation init sequence.
*
* Return: 0 if OK
*/
int bb_miiphy_init(void);
struct bb_miiphy_bus *bb_miiphy_alloc(void);
void bb_miiphy_free(struct bb_miiphy_bus *bus);
int bb_miiphy_read(struct mii_dev *miidev, int addr, int devad, int reg);
int bb_miiphy_write(struct mii_dev *miidev, int addr, int devad, int reg,