[U-Boot] [PATCH v5 6/8] net: macb: Extend MACB driver for SiFive Unleashed board
Ramon Fried
rfried.dev at gmail.com
Thu Jun 20 09:18:08 UTC 2019
On Thu, Jun 20, 2019 at 9:49 AM Anup Patel <Anup.Patel at wdc.com> wrote:
> The SiFive MACB ethernet has a custom TX_CLK_SEL register to select
> different TX clock for 1000mbps vs 10/100mbps.
>
> This patch adds SiFive MACB compatible string and extends the MACB
> ethernet driver to change TX clock using TX_CLK_SEL register for
> SiFive MACB.
>
> Signed-off-by: Anup Patel <anup.patel at wdc.com>
> ---
> drivers/net/macb.c | 53 +++++++++++++++++++++++++++++++++++++++-------
> 1 file changed, 45 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/macb.c b/drivers/net/macb.c
> index c072f99d8f..6a29ee3064 100644
> --- a/drivers/net/macb.c
> +++ b/drivers/net/macb.c
> @@ -83,6 +83,9 @@ struct macb_dma_desc {
>
> struct macb_device {
> void *regs;
> + void *regs_sifive_gemgxl;
This needs needs to be part of the specific config structure.
> +
> + bool skip_dma_config;
Why do you ever need to skip_dma_config ?
> unsigned int dma_burst_length;
>
> unsigned int rx_tail;
> @@ -122,7 +125,9 @@ struct macb_device {
> };
>
> struct macb_config {
> + bool skip_dma_config;
> unsigned int dma_burst_length;
> + bool has_sifive_gemgxl;
> };
>
> #ifndef CONFIG_DM_ETH
> @@ -486,18 +491,11 @@ static int macb_phy_find(struct macb_device *macb, const char *name)
> int __weak macb_linkspd_cb(struct udevice *dev, unsigned int speed)
> {
> #ifdef CONFIG_CLK
> + struct macb_device *macb = dev_get_priv(dev);
> struct clk tx_clk;
> ulong rate;
> int ret;
>
> - /*
> - * "tx_clk" is an optional clock source for MACB.
> - * Ignore if it does not exist in DT.
> - */
> - ret = clk_get_by_name(dev, "tx_clk", &tx_clk);
> - if (ret)
> - return 0;
> -
> switch (speed) {
> case _10BASET:
> rate = 2500000; /* 2.5 MHz */
> @@ -513,6 +511,26 @@ int __weak macb_linkspd_cb(struct udevice *dev, unsigned int speed)
> return 0;
> }
>
> + if (macb->regs_sifive_gemgxl) {
> + /*
> + * SiFive GEMGXL TX clock operation mode:
> + *
> + * 0 = GMII mode. Use 125 MHz gemgxlclk from PRCI in TX logic
> + * and output clock on GMII output signal GTX_CLK
> + * 1 = MII mode. Use MII input signal TX_CLK in TX logic
> + */
> + writel(rate != 125000000, macb->regs_sifive_gemgxl);
> + return 0;
> + }
move to dedicated clock init.
> +
> + /*
> + * "tx_clk" is an optional clock source for MACB.
> + * Ignore if it does not exist in DT.
> + */
> + ret = clk_get_by_name(dev, "tx_clk", &tx_clk);
> + if (ret)
> + return 0;
> +
> if (tx_clk.dev) {
> ret = clk_set_rate(&tx_clk, rate);
> if (ret)
> @@ -701,6 +719,9 @@ static void gmac_configure_dma(struct macb_device *macb)
> u32 buffer_size;
> u32 dmacfg;
>
> + if (macb->skip_dma_config)
> + return;
> +
Same as before, why do you skip it ?
> buffer_size = 128 / RX_BUFFER_MULTIPLE;
> dmacfg = gem_readl(macb, DMACFG) & ~GEM_BF(RXBS, -1L);
> dmacfg |= GEM_BF(RXBS, buffer_size);
> @@ -1178,6 +1199,7 @@ static int macb_eth_probe(struct udevice *dev)
> struct macb_device *macb = dev_get_priv(dev);
> const char *phy_mode;
> __maybe_unused int ret;
> + fdt_addr_t addr;
>
> phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
> NULL);
> @@ -1194,6 +1216,7 @@ static int macb_eth_probe(struct udevice *dev)
> if (!macb_config)
> macb_config = &default_gem_config;
>
> + macb->skip_dma_config = macb_config->skip_dma_config;
> macb->dma_burst_length = macb_config->dma_burst_length;
> #ifdef CONFIG_CLK
> ret = macb_enable_clk(dev);
> @@ -1201,6 +1224,13 @@ static int macb_eth_probe(struct udevice *dev)
> return ret;
> #endif
>
> + if (macb_config->has_sifive_gemgxl) {
> + addr = dev_read_addr_index(dev, 1);
> + if (addr == FDT_ADDR_T_NONE)
> + return -ENODEV;
> + macb->regs_sifive_gemgxl = (void __iomem *)addr;
> + }
This should be all done in a a specific sifive init function.
You can define init function and clock init function CB functions in
config (Like in Linux):
"
int (*clk_init)(struct platform_device *pdev, struct clk **pclk,
struct clk **hclk, struct clk **tx_clk,
struct clk **rx_clk);
int (*init)(struct platform_device *pdev);
"
and add your specific SOC initialization there.
This function should be generic as possible.
> +
> _macb_eth_initialize(macb);
>
> #if defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
> @@ -1259,6 +1289,12 @@ static const struct macb_config sama5d4_config = {
> .dma_burst_length = 4,
> };
>
> +static const struct macb_config sifive_config = {
> + .skip_dma_config = true,
> + .dma_burst_length = 0,
Don't mention it if it's zero, and by the way, I assume it should be not zero.
You're wasting memory cycles, try to find the correct value. (I think
4 is the default in macb)
> + .has_sifive_gemgxl = true,
can be dropped if callback functions are declared.
> +};
> +
> static const struct udevice_id macb_eth_ids[] = {
> { .compatible = "cdns,macb" },
> { .compatible = "cdns,at91sam9260-macb" },
> @@ -1266,6 +1302,7 @@ static const struct udevice_id macb_eth_ids[] = {
> { .compatible = "atmel,sama5d3-gem" },
> { .compatible = "atmel,sama5d4-gem", .data = (ulong)&sama5d4_config },
> { .compatible = "cdns,zynq-gem" },
> + { .compatible = "sifive,fu540-macb", .data = (ulong)&sifive_config },
> { }
> };
>
> --
> 2.17.1
>
Thanks,
Ramon.
More information about the U-Boot
mailing list