Hi Joe
> From: Padmarao Begari [mailto:[email protected]]
> Sent: Tuesday, December 22, 2020 9:12 PM
> To: [email protected]; [email protected]; Rick Jian-Zhi Chen(陳建志);
> [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]
> Cc: [email protected]; [email protected];
> [email protected]; [email protected];
> [email protected]; 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 <[email protected]>
> Reviewed-by: Anup Patel <[email protected]>
> Tested-by: Bin Meng <[email protected]>
> ---
> 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)µchip_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.