Hi Joe > From: Padmarao Begari [mailto:padmarao.beg...@microchip.com] > Sent: Tuesday, December 22, 2020 9:12 PM > To: u-boot@lists.denx.de; bmeng...@gmail.com; Rick Jian-Zhi Chen(陳建志); > anup.pa...@wdc.com; lukas.a...@aisec.fraunhofer.de; joe.hershber...@ni.com; > lu...@denx.de; atish.pa...@wdc.com > Cc: cyril.j...@microchip.com; lewis.ha...@microchip.com; > ivan.grif...@emdalo.com; daire.mcnam...@emdalo.com; > conor.doo...@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.beg...@microchip.com> > Reviewed-by: Anup Patel <anup.pa...@wdc.com> > Tested-by: Bin Meng <bin.m...@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)µ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.