[U-Boot] [PATCH 4/5] net: ftgmac100: add support for Aspeed SoC
Cédric Le Goater
clg at kaod.org
Mon Sep 10 14:21:47 UTC 2018
The Faraday ftgmac100 MAC controllers as found on the Aspeed SoCs have
some slight differences in the HW interface (End-Of-Rx/Tx-Ring
bits). Also include the Aspeed clock enablement.
Signed-off-by: Cédric Le Goater <clg at kaod.org>
---
drivers/net/ftgmac100.h | 5 +++
drivers/net/ftgmac100.c | 72 +++++++++++++++++++++++++++++++++++++----
2 files changed, 71 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ftgmac100.h b/drivers/net/ftgmac100.h
index 9a789e4d5bee..b8f99ddf48bc 100644
--- a/drivers/net/ftgmac100.h
+++ b/drivers/net/ftgmac100.h
@@ -129,6 +129,11 @@ struct ftgmac100 {
#define FTGMAC100_DMAFIFOS_RXDMA_REQ BIT(30)
#define FTGMAC100_DMAFIFOS_TXDMA_REQ BIT(31)
+/*
+ * Feature Register
+ */
+#define FTGMAC100_REVR_NEW_MDIO BIT(31)
+
/*
* Receive buffer size register
*/
diff --git a/drivers/net/ftgmac100.c b/drivers/net/ftgmac100.c
index 8d7bf5b9b351..3df48a82c1ad 100644
--- a/drivers/net/ftgmac100.c
+++ b/drivers/net/ftgmac100.c
@@ -27,6 +27,8 @@
/* PKTBUFSTX/PKTBUFSRX must both be power of 2 */
#define PKTBUFSTX 4
+#define FTGMAC100_ASPEED_NR_CLKS 2
+
struct ftgmac100_data {
phys_addr_t iobase;
@@ -40,6 +42,11 @@ struct ftgmac100_data {
struct mii_dev *bus;
u32 phy_mode;
u32 max_speed;
+
+ struct clk clks[FTGMAC100_ASPEED_NR_CLKS];
+ u32 rxdes0_edorr_mask;
+ u32 txdes0_edotr_mask;
+ bool is_aspeed;
};
/*
@@ -115,9 +122,15 @@ static int ftgmac100_mdio_write(struct mii_dev *bus, int phy_addr, int dev_addr,
static int ftgmac100_mdio_init(struct ftgmac100_data *priv, int dev_id)
{
+ struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)priv->iobase;
struct mii_dev *bus;
int ret;
+ if (priv->is_aspeed) {
+ /* This driver supports the old MDIO interface */
+ clrbits_le32(&ftgmac100->revr, FTGMAC100_REVR_NEW_MDIO);
+ };
+
bus = mdio_alloc();
if (!bus)
return -ENOMEM;
@@ -246,13 +259,13 @@ static int ftgmac100_start(struct udevice *dev)
priv->txdes[i].txdes3 = 0;
priv->txdes[i].txdes0 = 0;
}
- priv->txdes[PKTBUFSTX - 1].txdes0 = FTGMAC100_TXDES0_EDOTR;
+ priv->txdes[PKTBUFSTX - 1].txdes0 = priv->txdes0_edotr_mask;
for (i = 0; i < PKTBUFSRX; i++) {
priv->rxdes[i].rxdes3 = (unsigned int)net_rx_packets[i];
priv->rxdes[i].rxdes0 = 0;
}
- priv->rxdes[PKTBUFSRX - 1].rxdes0 = FTGMAC100_RXDES0_EDORR;
+ priv->rxdes[PKTBUFSRX - 1].rxdes0 = priv->rxdes0_edorr_mask;
/* transmit ring */
writel((u32)priv->txdes, &ftgmac100->txr_badr);
@@ -378,7 +391,7 @@ static int ftgmac100_send(struct udevice *dev, void *packet, int length)
flush_dcache_range(data_start, data_end);
/* only one descriptor on TXBUF */
- curr_des->txdes0 &= FTGMAC100_TXDES0_EDOTR;
+ curr_des->txdes0 &= priv->txdes0_edotr_mask;
curr_des->txdes0 |= FTGMAC100_TXDES0_FTS |
FTGMAC100_TXDES0_LTS |
FTGMAC100_TXDES0_TXBUF_SIZE(length) |
@@ -409,8 +422,11 @@ static int ftgmac100_write_hwaddr(struct udevice *dev)
static int ftgmac100_ofdata_to_platdata(struct udevice *dev)
{
+ struct ftgmac100_data *priv = dev_get_priv(dev);
struct eth_pdata *pdata = dev_get_platdata(dev);
const char *phy_mode;
+ int ret;
+ int i;
pdata->iobase = devfdt_get_addr(dev);
pdata->phy_interface = -1;
@@ -424,13 +440,39 @@ static int ftgmac100_ofdata_to_platdata(struct udevice *dev)
pdata->max_speed = dev_read_u32_default(dev, "max-speed", 0);
+ if (device_is_compatible(dev, "aspeed,ast2500-mac")) {
+ priv->rxdes0_edorr_mask = BIT(30);
+ priv->txdes0_edotr_mask = BIT(30);
+ priv->is_aspeed = true;
+ } else {
+ priv->rxdes0_edorr_mask = BIT(15);
+ priv->txdes0_edotr_mask = BIT(15);
+ }
+
+ if (priv->is_aspeed) {
+ for (i = 0; i < FTGMAC100_ASPEED_NR_CLKS; i++) {
+ ret = clk_get_by_index(dev, i, &priv->clks[i]);
+ if (ret) {
+ dev_err(dev, "Failed to get clock: %d\n", ret);
+ goto out_clk_free;
+ }
+ }
+ }
+
return 0;
+
+out_clk_free:
+ while (--i >= 0)
+ clk_free(&priv->clks[i]);
+
+ return ret;
}
static int ftgmac100_probe(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct ftgmac100_data *priv = dev_get_priv(dev);
+ int i;
int ret;
priv->iobase = pdata->iobase;
@@ -438,19 +480,33 @@ static int ftgmac100_probe(struct udevice *dev)
priv->max_speed = pdata->max_speed;
priv->phyaddr = 0;
+ if (priv->is_aspeed) {
+ for (i = 0; i < FTGMAC100_ASPEED_NR_CLKS; i++) {
+ ret = clk_enable(&priv->clks[i]);
+ if (ret) {
+ dev_err(dev, "Failed to enable clock: %d\n",
+ ret);
+ goto out_clk_release;
+ }
+ }
+ }
+
ret = ftgmac100_mdio_init(priv, dev->seq);
if (ret) {
dev_err(dev, "Failed to initialize mdiobus: %d\n", ret);
- goto out;
+ goto out_clk_release;
}
ret = ftgmac100_phy_init(priv, dev);
if (ret) {
dev_err(dev, "Failed to initialize PHY: %d\n", ret);
- goto out;
+ goto out_clk_release;
}
-out:
+out_clk_release:
+ if (ret && priv->is_aspeed)
+ clk_release_all(priv->clks, FTGMAC100_ASPEED_NR_CLKS);
+
return ret;
}
@@ -462,6 +518,9 @@ static int ftgmac100_remove(struct udevice *dev)
mdio_unregister(priv->bus);
mdio_free(priv->bus);
+ if (priv->is_aspeed)
+ clk_release_all(priv->clks, FTGMAC100_ASPEED_NR_CLKS);
+
return 0;
}
@@ -476,6 +535,7 @@ static const struct eth_ops ftgmac100_ops = {
static const struct udevice_id ftgmac100_ids[] = {
{ .compatible = "faraday,ftgmac100" },
+ { .compatible = "aspeed,ast2500-mac" },
{ }
};
--
2.17.1
More information about the U-Boot
mailing list