[PATCH v7 2/7] net: macb: Add DMA 64-bit address support for macb

Rick Chen rickchen36 at gmail.com
Tue Jan 5 02:51:33 CET 2021


Hi Joe

> From: Padmarao Begari [mailto:padmarao.begari at microchip.com]
> Sent: Tuesday, December 22, 2020 9:12 PM
> To: u-boot at lists.denx.de; bmeng.cn at gmail.com; Rick Jian-Zhi Chen(陳建志); anup.patel at wdc.com; lukas.auer at aisec.fraunhofer.de; joe.hershberger at ni.com; lukma at denx.de; atish.patra at wdc.com
> Cc: cyril.jean at microchip.com; lewis.hanly at microchip.com; ivan.griffin at emdalo.com; daire.mcnamara at emdalo.com; conor.dooley at microchip.com; Padmarao Begari
> Subject: [PATCH v7 2/7] net: macb: Add DMA 64-bit address support for macb
>
> Enable 32-bit or 64-bit DMA in the macb driver based on the macb
> hardware compatibility and it is configured with structure macb_config
> in the driver.
>
> The Microchip PolarFire SoC Memory Protection Unit(MPU) gives the 64-bit
> DMA access with the GEM, the MPU transactions on the AXI bus is 64-bit
> not 32-bit So 64-bit DMA is enabled for the Microchip PolarFire SoC GEM.
>
> Signed-off-by: Padmarao Begari <padmarao.begari at microchip.com>
> Reviewed-by: Anup Patel <anup.patel at wdc.com>
> Tested-by: Bin Meng <bin.meng at windriver.com>
> ---
>  drivers/net/macb.c | 131 +++++++++++++++++++++++++++++++++++++++------
>  drivers/net/macb.h |   6 +++
>  2 files changed, 120 insertions(+), 17 deletions(-)
>

Do you have any comment with this series about net macb driver.
If you are ok with it, I will pull via riscv tree.

Thanks,
Rick

> diff --git a/drivers/net/macb.c b/drivers/net/macb.c
> index b80a259ff7..626ee49227 100644
> --- a/drivers/net/macb.c
> +++ b/drivers/net/macb.c
> @@ -83,7 +83,16 @@ struct macb_dma_desc {
>         u32     ctrl;
>  };
>
> -#define DMA_DESC_BYTES(n)      (n * sizeof(struct macb_dma_desc))
> +struct macb_dma_desc_64 {
> +       u32 addrh;
> +       u32 unused;
> +};
> +
> +#define HW_DMA_CAP_32B         0
> +#define HW_DMA_CAP_64B         1
> +
> +#define DMA_DESC_SIZE          16
> +#define DMA_DESC_BYTES(n)      ((n) * DMA_DESC_SIZE)
>  #define MACB_TX_DMA_DESC_SIZE  (DMA_DESC_BYTES(MACB_TX_RING_SIZE))
>  #define MACB_RX_DMA_DESC_SIZE  (DMA_DESC_BYTES(MACB_RX_RING_SIZE))
>  #define MACB_TX_DUMMY_DMA_DESC_SIZE    (DMA_DESC_BYTES(1))
> @@ -137,6 +146,7 @@ struct macb_device {
>
>  struct macb_config {
>         unsigned int            dma_burst_length;
> +       unsigned int            hw_dma_cap;
>
>         int                     (*clk_init)(struct udevice *dev, ulong rate);
>  };
> @@ -307,6 +317,24 @@ static inline void macb_invalidate_rx_buffer(struct macb_device *macb)
>
>  #if defined(CONFIG_CMD_NET)
>
> +static struct macb_dma_desc_64 *macb_64b_desc(struct macb_dma_desc *desc)
> +{
> +       return (struct macb_dma_desc_64 *)((void *)desc
> +               + sizeof(struct macb_dma_desc));
> +}
> +
> +static void macb_set_addr(struct macb_device *macb, struct macb_dma_desc *desc,
> +                         ulong addr)
> +{
> +       struct macb_dma_desc_64 *desc_64;
> +
> +       if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
> +               desc_64 = macb_64b_desc(desc);
> +               desc_64->addrh = upper_32_bits(addr);
> +       }
> +       desc->addr = lower_32_bits(addr);
> +}
> +
>  static int _macb_send(struct macb_device *macb, const char *name, void *packet,
>                       int length)
>  {
> @@ -325,8 +353,12 @@ static int _macb_send(struct macb_device *macb, const char *name, void *packet,
>                 macb->tx_head++;
>         }
>
> +       if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
> +               tx_head = tx_head * 2;
> +
>         macb->tx_ring[tx_head].ctrl = ctrl;
> -       macb->tx_ring[tx_head].addr = paddr;
> +       macb_set_addr(macb, &macb->tx_ring[tx_head], paddr);
> +
>         barrier();
>         macb_flush_ring_desc(macb, TX);
>         macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
> @@ -363,19 +395,28 @@ static void reclaim_rx_buffers(struct macb_device *macb,
>                                unsigned int new_tail)
>  {
>         unsigned int i;
> +       unsigned int count;
>
>         i = macb->rx_tail;
>
>         macb_invalidate_ring_desc(macb, RX);
>         while (i > new_tail) {
> -               macb->rx_ring[i].addr &= ~MACB_BIT(RX_USED);
> +               if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
> +                       count = i * 2;
> +               else
> +                       count = i;
> +               macb->rx_ring[count].addr &= ~MACB_BIT(RX_USED);
>                 i++;
>                 if (i > MACB_RX_RING_SIZE)
>                         i = 0;
>         }
>
>         while (i < new_tail) {
> -               macb->rx_ring[i].addr &= ~MACB_BIT(RX_USED);
> +               if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
> +                       count = i * 2;
> +               else
> +                       count = i;
> +               macb->rx_ring[count].addr &= ~MACB_BIT(RX_USED);
>                 i++;
>         }
>
> @@ -390,16 +431,25 @@ static int _macb_recv(struct macb_device *macb, uchar **packetp)
>         void *buffer;
>         int length;
>         u32 status;
> +       u8 flag = false;
>
>         macb->wrapped = false;
>         for (;;) {
>                 macb_invalidate_ring_desc(macb, RX);
>
> +               if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
> +                       next_rx_tail = next_rx_tail * 2;
> +
>                 if (!(macb->rx_ring[next_rx_tail].addr & MACB_BIT(RX_USED)))
>                         return -EAGAIN;
>
>                 status = macb->rx_ring[next_rx_tail].ctrl;
>                 if (status & MACB_BIT(RX_SOF)) {
> +                       if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
> +                               next_rx_tail = next_rx_tail / 2;
> +                               flag = true;
> +                       }
> +
>                         if (next_rx_tail != macb->rx_tail)
>                                 reclaim_rx_buffers(macb, next_rx_tail);
>                         macb->wrapped = false;
> @@ -426,11 +476,22 @@ static int _macb_recv(struct macb_device *macb, uchar **packetp)
>                                 *packetp = buffer;
>                         }
>
> +                       if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
> +                               if (!flag)
> +                                       next_rx_tail = next_rx_tail / 2;
> +                       }
> +
>                         if (++next_rx_tail >= MACB_RX_RING_SIZE)
>                                 next_rx_tail = 0;
>                         macb->next_rx_tail = next_rx_tail;
>                         return length;
>                 } else {
> +                       if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
> +                               if (!flag)
> +                                       next_rx_tail = next_rx_tail / 2;
> +                               flag = false;
> +                       }
> +
>                         if (++next_rx_tail >= MACB_RX_RING_SIZE) {
>                                 macb->wrapped = true;
>                                 next_rx_tail = 0;
> @@ -718,6 +779,7 @@ static int gmac_init_multi_queues(struct macb_device *macb)
>  {
>         int i, num_queues = 1;
>         u32 queue_mask;
> +       unsigned long paddr;
>
>         /* bit 0 is never set but queue 0 always exists */
>         queue_mask = gem_readl(macb, DCFG6) & 0xff;
> @@ -731,10 +793,18 @@ static int gmac_init_multi_queues(struct macb_device *macb)
>         macb->dummy_desc->addr = 0;
>         flush_dcache_range(macb->dummy_desc_dma, macb->dummy_desc_dma +
>                         ALIGN(MACB_TX_DUMMY_DMA_DESC_SIZE, PKTALIGN));
> -
> -       for (i = 1; i < num_queues; i++)
> -               gem_writel_queue_TBQP(macb, macb->dummy_desc_dma, i - 1);
> -
> +       paddr = macb->dummy_desc_dma;
> +
> +       for (i = 1; i < num_queues; i++) {
> +               gem_writel_queue_TBQP(macb, lower_32_bits(paddr), i - 1);
> +               gem_writel_queue_RBQP(macb, lower_32_bits(paddr), i - 1);
> +               if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
> +                       gem_writel_queue_TBQPH(macb, upper_32_bits(paddr),
> +                                              i - 1);
> +                       gem_writel_queue_RBQPH(macb, upper_32_bits(paddr),
> +                                              i - 1);
> +               }
> +       }
>         return 0;
>  }
>
> @@ -760,6 +830,9 @@ static void gmac_configure_dma(struct macb_device *macb)
>                 dmacfg &= ~GEM_BIT(ENDIA_DESC);
>
>         dmacfg &= ~GEM_BIT(ADDR64);
> +       if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
> +               dmacfg |= GEM_BIT(ADDR64);
> +
>         gem_writel(macb, DMACFG, dmacfg);
>  }
>
> @@ -775,6 +848,7 @@ static int _macb_init(struct macb_device *macb, const char *name)
>         unsigned long paddr;
>         int ret;
>         int i;
> +       int count;
>
>         /*
>          * macb_halt should have been called at some point before now,
> @@ -786,20 +860,28 @@ static int _macb_init(struct macb_device *macb, const char *name)
>         for (i = 0; i < MACB_RX_RING_SIZE; i++) {
>                 if (i == (MACB_RX_RING_SIZE - 1))
>                         paddr |= MACB_BIT(RX_WRAP);
> -               macb->rx_ring[i].addr = paddr;
> -               macb->rx_ring[i].ctrl = 0;
> +               if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
> +                       count = i * 2;
> +               else
> +                       count = i;
> +               macb->rx_ring[count].ctrl = 0;
> +               macb_set_addr(macb, &macb->rx_ring[count], paddr);
>                 paddr += macb->rx_buffer_size;
>         }
>         macb_flush_ring_desc(macb, RX);
>         macb_flush_rx_buffer(macb);
>
>         for (i = 0; i < MACB_TX_RING_SIZE; i++) {
> -               macb->tx_ring[i].addr = 0;
> +               if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
> +                       count = i * 2;
> +               else
> +                       count = i;
> +               macb_set_addr(macb, &macb->tx_ring[count], 0);
>                 if (i == (MACB_TX_RING_SIZE - 1))
> -                       macb->tx_ring[i].ctrl = MACB_BIT(TX_USED) |
> +                       macb->tx_ring[count].ctrl = MACB_BIT(TX_USED) |
>                                 MACB_BIT(TX_WRAP);
>                 else
> -                       macb->tx_ring[i].ctrl = MACB_BIT(TX_USED);
> +                       macb->tx_ring[count].ctrl = MACB_BIT(TX_USED);
>         }
>         macb_flush_ring_desc(macb, TX);
>
> @@ -812,8 +894,12 @@ static int _macb_init(struct macb_device *macb, const char *name)
>         gem_writel(macb, DMACFG, MACB_ZYNQ_GEM_DMACR_INIT);
>  #endif
>
> -       macb_writel(macb, RBQP, macb->rx_ring_dma);
> -       macb_writel(macb, TBQP, macb->tx_ring_dma);
> +       macb_writel(macb, RBQP, lower_32_bits(macb->rx_ring_dma));
> +       macb_writel(macb, TBQP, lower_32_bits(macb->tx_ring_dma));
> +       if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
> +               macb_writel(macb, RBQPH, upper_32_bits(macb->rx_ring_dma));
> +               macb_writel(macb, TBQPH, upper_32_bits(macb->tx_ring_dma));
> +       }
>
>         if (macb_is_gem(macb)) {
>                 /* Initialize DMA properties */
> @@ -1217,6 +1303,7 @@ static int macb_enable_clk(struct udevice *dev)
>
>  static const struct macb_config default_gem_config = {
>         .dma_burst_length = 16,
> +       .hw_dma_cap = HW_DMA_CAP_32B,
>         .clk_init = NULL,
>  };
>
> @@ -1227,8 +1314,8 @@ static int macb_eth_probe(struct udevice *dev)
>         const char *phy_mode;
>         int ret;
>
> -       phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
> -                              NULL);
> +       phy_mode = dev_read_prop(dev, "phy-mode", NULL);
> +
>         if (phy_mode)
>                 macb->phy_interface = phy_get_interface_by_name(phy_mode);
>         if (macb->phy_interface == -1) {
> @@ -1304,13 +1391,21 @@ static int macb_eth_ofdata_to_platdata(struct udevice *dev)
>         return macb_late_eth_ofdata_to_platdata(dev);
>  }
>
> +static const struct macb_config microchip_config = {
> +       .dma_burst_length = 16,
> +       .hw_dma_cap = HW_DMA_CAP_64B,
> +       .clk_init = NULL,
> +};
> +
>  static const struct macb_config sama5d4_config = {
>         .dma_burst_length = 4,
> +       .hw_dma_cap = HW_DMA_CAP_32B,
>         .clk_init = NULL,
>  };
>
>  static const struct macb_config sifive_config = {
>         .dma_burst_length = 16,
> +       .hw_dma_cap = HW_DMA_CAP_32B,
>         .clk_init = macb_sifive_clk_init,
>  };
>
> @@ -1324,6 +1419,8 @@ static const struct udevice_id macb_eth_ids[] = {
>         { .compatible = "cdns,zynq-gem" },
>         { .compatible = "sifive,fu540-c000-gem",
>           .data = (ulong)&sifive_config },
> +       { .compatible = "microchip,mpfs-mss-gem",
> +         .data = (ulong)&microchip_config },
>         { }
>  };
>
> diff --git a/drivers/net/macb.h b/drivers/net/macb.h
> index 9b16383eba..72b84ae96e 100644
> --- a/drivers/net/macb.h
> +++ b/drivers/net/macb.h
> @@ -768,5 +768,11 @@
>  #define GEM_RX_CSUM_CHECKED_MASK               2
>  #define gem_writel_queue_TBQP(port, value, queue_num)  \
>         writel((value), (port)->regs + GEM_TBQP(queue_num))
> +#define gem_writel_queue_TBQPH(port, value, queue_num) \
> +       writel((value), (port)->regs + GEM_TBQPH(queue_num))
> +#define gem_writel_queue_RBQP(port, value, queue_num)  \
> +       writel((value), (port)->regs + GEM_RBQP(queue_num))
> +#define gem_writel_queue_RBQPH(port, value, queue_num) \
> +       writel((value), (port)->regs + GEM_RBQPH(queue_num))
>
>  #endif /* __DRIVERS_MACB_H__ */
> --
> 2.17.1
>
> CONFIDENTIALITY NOTICE:
>
> This e-mail (and its attachments) may contain confidential and legally privileged information or information protected from disclosure. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information contained herein is strictly prohibited. In this case, please immediately notify the sender by return e-mail, delete the message (and any accompanying documents) and destroy all printed hard copies. Thank you for your cooperation.
>
> Copyright ANDES TECHNOLOGY CORPORATION - All Rights Reserved.


More information about the U-Boot mailing list