Message ID | 20201202203211.2843-3-padmarao.begari@microchip.com |
---|---|
State | Superseded |
Delegated to: | Andes |
Headers | show |
Series | Microchip PolarFire SoC support | expand |
Hi Padmarao, On Thu, Dec 3, 2020 at 4:44 AM Padmarao Begari <padmarao.begari@microchip.com> wrote: > > Enable 32-bit or 64-bit DMA in the macb driver based on the macb > compatible string of the device tree node. > > Signed-off-by: Padmarao Begari <padmarao.begari@microchip.com> > Reviewed-by: Anup Patel <anup.patel@wdc.com> > --- > drivers/net/macb.c | 131 +++++++++++++++++++++++++++++++++++++++------ > drivers/net/macb.h | 6 +++ > 2 files changed, 120 insertions(+), 17 deletions(-) > > diff --git a/drivers/net/macb.c b/drivers/net/macb.c > index b80a259ff7..e7c93d4747 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)) > @@ -133,6 +142,7 @@ struct macb_device { > #endif > phy_interface_t phy_interface; > #endif > + unsigned short hw_dma_cap; > }; > > struct macb_config { > @@ -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->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->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->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->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->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->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->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->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->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->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->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->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->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 */ > @@ -1225,10 +1311,11 @@ static int macb_eth_probe(struct udevice *dev) > struct eth_pdata *pdata = dev_get_platdata(dev); > struct macb_device *macb = dev_get_priv(dev); > const char *phy_mode; > + const char *compatible; > 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) { > @@ -1236,6 +1323,15 @@ static int macb_eth_probe(struct udevice *dev) > return -EINVAL; > } > > + compatible = dev_read_prop(dev, "compatible", NULL); > + > + if (compatible) { > + if (!strcmp(compatible, "microchip,mpfs-mss-gem")) > + macb->hw_dma_cap = HW_DMA_CAP_64B; > + else > + macb->hw_dma_cap = HW_DMA_CAP_32B; > + } > + > macb->regs = (void *)pdata->iobase; > > macb->is_big_endian = (cpu_to_be32(0x12345678) == 0x12345678); > @@ -1324,6 +1420,7 @@ 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" }, Can we make the hw_dma_cap part of the .data (struct macb_config), like: static const struct macb_config default_gem_config = { .dma_burst_length = 16, .hw_dma_cap = HW_DMA_CAP_32B, .clk_init = NULL, }; > { } > }; > > 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__ */ Regards, Bin
Hi Padmarao, On Thu, Dec 10, 2020 at 6:33 PM Bin Meng <bmeng.cn@gmail.com> wrote: > > Hi Padmarao, > > On Thu, Dec 3, 2020 at 4:44 AM Padmarao Begari > <padmarao.begari@microchip.com> wrote: > > > > Enable 32-bit or 64-bit DMA in the macb driver based on the macb > > compatible string of the device tree node. > > > > Signed-off-by: Padmarao Begari <padmarao.begari@microchip.com> > > Reviewed-by: Anup Patel <anup.patel@wdc.com> > > --- > > drivers/net/macb.c | 131 +++++++++++++++++++++++++++++++++++++++------ > > drivers/net/macb.h | 6 +++ > > 2 files changed, 120 insertions(+), 17 deletions(-) > > > > diff --git a/drivers/net/macb.c b/drivers/net/macb.c > > index b80a259ff7..e7c93d4747 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)) > > @@ -133,6 +142,7 @@ struct macb_device { > > #endif > > phy_interface_t phy_interface; > > #endif > > + unsigned short hw_dma_cap; > > }; > > > > struct macb_config { > > @@ -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->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->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->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->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->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->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->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->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->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->hw_dma_cap & HW_DMA_CAP_64B) > > + dmacfg |= GEM_BIT(ADDR64); Does GEM on PolarFire not support 32-bit DMA address? I believe in U-Boot we can only get 32-bit address. > > + > > 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->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->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->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 */ > > @@ -1225,10 +1311,11 @@ static int macb_eth_probe(struct udevice *dev) > > struct eth_pdata *pdata = dev_get_platdata(dev); > > struct macb_device *macb = dev_get_priv(dev); > > const char *phy_mode; > > + const char *compatible; > > 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) { > > @@ -1236,6 +1323,15 @@ static int macb_eth_probe(struct udevice *dev) > > return -EINVAL; > > } > > > > + compatible = dev_read_prop(dev, "compatible", NULL); > > + > > + if (compatible) { > > + if (!strcmp(compatible, "microchip,mpfs-mss-gem")) > > + macb->hw_dma_cap = HW_DMA_CAP_64B; > > + else > > + macb->hw_dma_cap = HW_DMA_CAP_32B; > > + } > > + > > macb->regs = (void *)pdata->iobase; > > > > macb->is_big_endian = (cpu_to_be32(0x12345678) == 0x12345678); > > @@ -1324,6 +1420,7 @@ 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" }, > > Can we make the hw_dma_cap part of the .data (struct macb_config), like: > > static const struct macb_config default_gem_config = { > .dma_burst_length = 16, > .hw_dma_cap = HW_DMA_CAP_32B, > .clk_init = NULL, > }; > Regards, Bin
Hi Bin, On Thu, Dec 10, 2020 at 4:08 PM Bin Meng <bmeng.cn@gmail.com> wrote: > Hi Padmarao, > > On Thu, Dec 10, 2020 at 6:33 PM Bin Meng <bmeng.cn@gmail.com> wrote: > > > > Hi Padmarao, > > > > On Thu, Dec 3, 2020 at 4:44 AM Padmarao Begari > > <padmarao.begari@microchip.com> wrote: > > > > > > Enable 32-bit or 64-bit DMA in the macb driver based on the macb > > > compatible string of the device tree node. > > > > > > Signed-off-by: Padmarao Begari <padmarao.begari@microchip.com> > > > Reviewed-by: Anup Patel <anup.patel@wdc.com> > > > --- > > > drivers/net/macb.c | 131 +++++++++++++++++++++++++++++++++++++++------ > > > drivers/net/macb.h | 6 +++ > > > 2 files changed, 120 insertions(+), 17 deletions(-) > > > > > > diff --git a/drivers/net/macb.c b/drivers/net/macb.c > > > index b80a259ff7..e7c93d4747 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)) > > > @@ -133,6 +142,7 @@ struct macb_device { > > > #endif > > > phy_interface_t phy_interface; > > > #endif > > > + unsigned short hw_dma_cap; > > > }; > > > > > > struct macb_config { > > > @@ -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->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->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->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->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->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->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->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->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->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->hw_dma_cap & HW_DMA_CAP_64B) > > > + dmacfg |= GEM_BIT(ADDR64); > > Does GEM on PolarFire not support 32-bit DMA address? I believe in > U-Boot we can only get 32-bit address. > > > > + > > > 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->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->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->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 */ > > > @@ -1225,10 +1311,11 @@ static int macb_eth_probe(struct udevice *dev) > > > struct eth_pdata *pdata = dev_get_platdata(dev); > > > struct macb_device *macb = dev_get_priv(dev); > > > const char *phy_mode; > > > + const char *compatible; > > > 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) { > > > @@ -1236,6 +1323,15 @@ static int macb_eth_probe(struct udevice *dev) > > > return -EINVAL; > > > } > > > > > > + compatible = dev_read_prop(dev, "compatible", NULL); > > > + > > > + if (compatible) { > > > + if (!strcmp(compatible, "microchip,mpfs-mss-gem")) > > > + macb->hw_dma_cap = HW_DMA_CAP_64B; > > > + else > > > + macb->hw_dma_cap = HW_DMA_CAP_32B; > > > + } > > > + > > > macb->regs = (void *)pdata->iobase; > > > > > > macb->is_big_endian = (cpu_to_be32(0x12345678) == 0x12345678); > > > @@ -1324,6 +1420,7 @@ 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" }, > > > > Can we make the hw_dma_cap part of the .data (struct macb_config), like: > > > > static const struct macb_config default_gem_config = { > > .dma_burst_length = 16, > > .hw_dma_cap = HW_DMA_CAP_32B, > > .clk_init = NULL, > > }; > > > > Yes, we can use hw_dma_cap in struct macb_config #define HW_DMA_CAP_32B 0 #define HW_DMA_CAP_64B 1 Can we check 64-bit DMA condition like: if (macb->config->hw_dma_cap) or if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) Which one will be used in the driver? Regards Padmarao Regards, > Bin >
Hi Bin, On Thu, Dec 10, 2020 at 4:08 PM Bin Meng <bmeng.cn@gmail.com> wrote: > Hi Padmarao, > > On Thu, Dec 10, 2020 at 6:33 PM Bin Meng <bmeng.cn@gmail.com> wrote: > > > > Hi Padmarao, > > > > On Thu, Dec 3, 2020 at 4:44 AM Padmarao Begari > > <padmarao.begari@microchip.com> wrote: > > > > > > Enable 32-bit or 64-bit DMA in the macb driver based on the macb > > > compatible string of the device tree node. > > > > > > Signed-off-by: Padmarao Begari <padmarao.begari@microchip.com> > > > Reviewed-by: Anup Patel <anup.patel@wdc.com> > > > --- > > > drivers/net/macb.c | 131 +++++++++++++++++++++++++++++++++++++++------ > > > drivers/net/macb.h | 6 +++ > > > 2 files changed, 120 insertions(+), 17 deletions(-) > > > > > > diff --git a/drivers/net/macb.c b/drivers/net/macb.c > > > index b80a259ff7..e7c93d4747 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)) > > > @@ -133,6 +142,7 @@ struct macb_device { > > > #endif > > > phy_interface_t phy_interface; > > > #endif > > > + unsigned short hw_dma_cap; > > > }; > > > > > > struct macb_config { > > > @@ -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->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->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->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->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->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->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->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->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->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->hw_dma_cap & HW_DMA_CAP_64B) > > > + dmacfg |= GEM_BIT(ADDR64); > > Does GEM on PolarFire not support 32-bit DMA address? I believe in > U-Boot we can only get 32-bit address. > > Yes, it's not work when I tested with 32-bit DMA. Regards Padmarao > > > + > > > 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->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->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->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 */ > > > @@ -1225,10 +1311,11 @@ static int macb_eth_probe(struct udevice *dev) > > > struct eth_pdata *pdata = dev_get_platdata(dev); > > > struct macb_device *macb = dev_get_priv(dev); > > > const char *phy_mode; > > > + const char *compatible; > > > 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) { > > > @@ -1236,6 +1323,15 @@ static int macb_eth_probe(struct udevice *dev) > > > return -EINVAL; > > > } > > > > > > + compatible = dev_read_prop(dev, "compatible", NULL); > > > + > > > + if (compatible) { > > > + if (!strcmp(compatible, "microchip,mpfs-mss-gem")) > > > + macb->hw_dma_cap = HW_DMA_CAP_64B; > > > + else > > > + macb->hw_dma_cap = HW_DMA_CAP_32B; > > > + } > > > + > > > macb->regs = (void *)pdata->iobase; > > > > > > macb->is_big_endian = (cpu_to_be32(0x12345678) == 0x12345678); > > > @@ -1324,6 +1420,7 @@ 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" }, > > > > Can we make the hw_dma_cap part of the .data (struct macb_config), like: > > > > static const struct macb_config default_gem_config = { > > .dma_burst_length = 16, > > .hw_dma_cap = HW_DMA_CAP_32B, > > .clk_init = NULL, > > }; > > > > Regards, > Bin >
Hi Padmarao, On Fri, Dec 11, 2020 at 4:49 PM Padmarao Begari <padmarao.b@gmail.com> wrote: > > Hi Bin, > > On Thu, Dec 10, 2020 at 4:08 PM Bin Meng <bmeng.cn@gmail.com> wrote: >> >> Hi Padmarao, >> >> On Thu, Dec 10, 2020 at 6:33 PM Bin Meng <bmeng.cn@gmail.com> wrote: >> > >> > Hi Padmarao, >> > >> > On Thu, Dec 3, 2020 at 4:44 AM Padmarao Begari >> > <padmarao.begari@microchip.com> wrote: >> > > >> > > Enable 32-bit or 64-bit DMA in the macb driver based on the macb >> > > compatible string of the device tree node. >> > > >> > > Signed-off-by: Padmarao Begari <padmarao.begari@microchip.com> >> > > Reviewed-by: Anup Patel <anup.patel@wdc.com> >> > > --- >> > > drivers/net/macb.c | 131 +++++++++++++++++++++++++++++++++++++++------ >> > > drivers/net/macb.h | 6 +++ >> > > 2 files changed, 120 insertions(+), 17 deletions(-) >> > > >> > > diff --git a/drivers/net/macb.c b/drivers/net/macb.c >> > > index b80a259ff7..e7c93d4747 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)) >> > > @@ -133,6 +142,7 @@ struct macb_device { >> > > #endif >> > > phy_interface_t phy_interface; >> > > #endif >> > > + unsigned short hw_dma_cap; >> > > }; >> > > >> > > struct macb_config { >> > > @@ -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->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->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->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->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->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->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->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->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->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->hw_dma_cap & HW_DMA_CAP_64B) >> > > + dmacfg |= GEM_BIT(ADDR64); >> >> Does GEM on PolarFire not support 32-bit DMA address? I believe in >> U-Boot we can only get 32-bit address. >> > > Yes, it's not work when I tested with 32-bit DMA. Okay, then this explains why 64-bit DMA patch is needed. Is this a bug of the GEM IP integrated in the PolarFire? Could you please write something in the commit message to clarify? That would be helpful. Thanks! Regards, Bin
Hi Bin, On Fri, Dec 11, 2020 at 2:59 PM Bin Meng <bmeng.cn@gmail.com> wrote: > Hi Padmarao, > > On Fri, Dec 11, 2020 at 4:49 PM Padmarao Begari <padmarao.b@gmail.com> > wrote: > > > > Hi Bin, > > > > On Thu, Dec 10, 2020 at 4:08 PM Bin Meng <bmeng.cn@gmail.com> wrote: > >> > >> Hi Padmarao, > >> > >> On Thu, Dec 10, 2020 at 6:33 PM Bin Meng <bmeng.cn@gmail.com> wrote: > >> > > >> > Hi Padmarao, > >> > > >> > On Thu, Dec 3, 2020 at 4:44 AM Padmarao Begari > >> > <padmarao.begari@microchip.com> wrote: > >> > > > >> > > Enable 32-bit or 64-bit DMA in the macb driver based on the macb > >> > > compatible string of the device tree node. > >> > > > >> > > Signed-off-by: Padmarao Begari <padmarao.begari@microchip.com> > >> > > Reviewed-by: Anup Patel <anup.patel@wdc.com> > >> > > --- > >> > > drivers/net/macb.c | 131 > +++++++++++++++++++++++++++++++++++++++------ > >> > > drivers/net/macb.h | 6 +++ > >> > > 2 files changed, 120 insertions(+), 17 deletions(-) > >> > > > >> > > diff --git a/drivers/net/macb.c b/drivers/net/macb.c > >> > > index b80a259ff7..e7c93d4747 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)) > >> > > @@ -133,6 +142,7 @@ struct macb_device { > >> > > #endif > >> > > phy_interface_t phy_interface; > >> > > #endif > >> > > + unsigned short hw_dma_cap; > >> > > }; > >> > > > >> > > struct macb_config { > >> > > @@ -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->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->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->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->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->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->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->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->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->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->hw_dma_cap & HW_DMA_CAP_64B) > >> > > + dmacfg |= GEM_BIT(ADDR64); > >> > >> Does GEM on PolarFire not support 32-bit DMA address? I believe in > >> U-Boot we can only get 32-bit address. > >> > > > > Yes, it's not work when I tested with 32-bit DMA. > > Okay, then this explains why 64-bit DMA patch is needed. Is this a bug > of the GEM IP integrated in the PolarFire? > Could you please write something in the commit message to clarify? > That would be helpful. Thanks! No, it's not a bug, The PolarFire SoC Memory Protection Unit(MPU) gives the 64-bit DMA access with GEM, the MPU transactions on the AXI bus is 64-bit not 32-bit. Regards Padmarao > Regards, > Bin >
Hi Padmarao, On Fri, Dec 11, 2020 at 8:07 PM Padmarao Begari <padmarao.b@gmail.com> wrote: > > Hi Bin, > > On Fri, Dec 11, 2020 at 2:59 PM Bin Meng <bmeng.cn@gmail.com> wrote: >> >> Hi Padmarao, >> >> On Fri, Dec 11, 2020 at 4:49 PM Padmarao Begari <padmarao.b@gmail.com> wrote: >> > >> > Hi Bin, >> > >> > On Thu, Dec 10, 2020 at 4:08 PM Bin Meng <bmeng.cn@gmail.com> wrote: >> >> >> >> Hi Padmarao, >> >> >> >> On Thu, Dec 10, 2020 at 6:33 PM Bin Meng <bmeng.cn@gmail.com> wrote: >> >> > >> >> > Hi Padmarao, >> >> > >> >> > On Thu, Dec 3, 2020 at 4:44 AM Padmarao Begari >> >> > <padmarao.begari@microchip.com> wrote: >> >> > > >> >> > > Enable 32-bit or 64-bit DMA in the macb driver based on the macb >> >> > > compatible string of the device tree node. >> >> > > >> >> > > Signed-off-by: Padmarao Begari <padmarao.begari@microchip.com> >> >> > > Reviewed-by: Anup Patel <anup.patel@wdc.com> >> >> > > --- >> >> > > drivers/net/macb.c | 131 +++++++++++++++++++++++++++++++++++++++------ >> >> > > drivers/net/macb.h | 6 +++ >> >> > > 2 files changed, 120 insertions(+), 17 deletions(-) >> >> > > >> >> > > diff --git a/drivers/net/macb.c b/drivers/net/macb.c >> >> > > index b80a259ff7..e7c93d4747 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)) >> >> > > @@ -133,6 +142,7 @@ struct macb_device { >> >> > > #endif >> >> > > phy_interface_t phy_interface; >> >> > > #endif >> >> > > + unsigned short hw_dma_cap; >> >> > > }; >> >> > > >> >> > > struct macb_config { >> >> > > @@ -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->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->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->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->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->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->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->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->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->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->hw_dma_cap & HW_DMA_CAP_64B) >> >> > > + dmacfg |= GEM_BIT(ADDR64); >> >> >> >> Does GEM on PolarFire not support 32-bit DMA address? I believe in >> >> U-Boot we can only get 32-bit address. >> >> >> > >> > Yes, it's not work when I tested with 32-bit DMA. >> >> Okay, then this explains why 64-bit DMA patch is needed. Is this a bug >> of the GEM IP integrated in the PolarFire? >> Could you please write something in the commit message to clarify? >> That would be helpful. Thanks! > > > No, it's not a bug, The PolarFire SoC Memory Protection Unit(MPU) gives the 64-bit DMA access with GEM, the MPU transactions on the AXI bus is 64-bit not 32-bit. This sounds like a GEM IP integration configuration issue on PolarFire. Regards, Bin
On Fri, Dec 11, 2020 at 3:27 PM Bin Meng <bmeng.cn@gmail.com> wrote: > > Hi Padmarao, > > On Fri, Dec 11, 2020 at 8:07 PM Padmarao Begari <padmarao.b@gmail.com> wrote: > > > > Hi Bin, > > > > On Fri, Dec 11, 2020 at 2:59 PM Bin Meng <bmeng.cn@gmail.com> wrote: > >> > >> Hi Padmarao, > >> > >> On Fri, Dec 11, 2020 at 4:49 PM Padmarao Begari <padmarao.b@gmail.com> wrote: > >> > > >> > Hi Bin, > >> > > >> > On Thu, Dec 10, 2020 at 4:08 PM Bin Meng <bmeng.cn@gmail.com> wrote: > >> >> > >> >> Hi Padmarao, > >> >> > >> >> On Thu, Dec 10, 2020 at 6:33 PM Bin Meng <bmeng.cn@gmail.com> wrote: > >> >> > > >> >> > Hi Padmarao, > >> >> > > >> >> > On Thu, Dec 3, 2020 at 4:44 AM Padmarao Begari > >> >> > <padmarao.begari@microchip.com> wrote: > >> >> > > > >> >> > > Enable 32-bit or 64-bit DMA in the macb driver based on the macb > >> >> > > compatible string of the device tree node. > >> >> > > > >> >> > > Signed-off-by: Padmarao Begari <padmarao.begari@microchip.com> > >> >> > > Reviewed-by: Anup Patel <anup.patel@wdc.com> > >> >> > > --- > >> >> > > drivers/net/macb.c | 131 +++++++++++++++++++++++++++++++++++++++------ > >> >> > > drivers/net/macb.h | 6 +++ > >> >> > > 2 files changed, 120 insertions(+), 17 deletions(-) > >> >> > > > >> >> > > diff --git a/drivers/net/macb.c b/drivers/net/macb.c > >> >> > > index b80a259ff7..e7c93d4747 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)) > >> >> > > @@ -133,6 +142,7 @@ struct macb_device { > >> >> > > #endif > >> >> > > phy_interface_t phy_interface; > >> >> > > #endif > >> >> > > + unsigned short hw_dma_cap; > >> >> > > }; > >> >> > > > >> >> > > struct macb_config { > >> >> > > @@ -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->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->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->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->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->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->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->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->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->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->hw_dma_cap & HW_DMA_CAP_64B) > >> >> > > + dmacfg |= GEM_BIT(ADDR64); > >> >> > >> >> Does GEM on PolarFire not support 32-bit DMA address? I believe in > >> >> U-Boot we can only get 32-bit address. > >> >> > >> > > >> > Yes, it's not work when I tested with 32-bit DMA. > >> > >> Okay, then this explains why 64-bit DMA patch is needed. Is this a bug > >> of the GEM IP integrated in the PolarFire? > >> Could you please write something in the commit message to clarify? > >> That would be helpful. Thanks! > > > > > > No, it's not a bug, The PolarFire SoC Memory Protection Unit(MPU) gives the 64-bit DMA access with GEM, the MPU transactions on the AXI bus is 64-bit not 32-bit. > > This sounds like a GEM IP integration configuration issue on PolarFire. Actually, I also stumbled upon a situation where I needed to use 64bit addressing on MACB because IOMMU bits I had to add to the address. It didn't end up as a patch, but it make sense to support it although U-boot wil provide lower addresses. > > Regards, > Bin
diff --git a/drivers/net/macb.c b/drivers/net/macb.c index b80a259ff7..e7c93d4747 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)) @@ -133,6 +142,7 @@ struct macb_device { #endif phy_interface_t phy_interface; #endif + unsigned short hw_dma_cap; }; struct macb_config { @@ -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->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->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->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->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->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->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->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->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->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->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->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->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->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 */ @@ -1225,10 +1311,11 @@ static int macb_eth_probe(struct udevice *dev) struct eth_pdata *pdata = dev_get_platdata(dev); struct macb_device *macb = dev_get_priv(dev); const char *phy_mode; + const char *compatible; 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) { @@ -1236,6 +1323,15 @@ static int macb_eth_probe(struct udevice *dev) return -EINVAL; } + compatible = dev_read_prop(dev, "compatible", NULL); + + if (compatible) { + if (!strcmp(compatible, "microchip,mpfs-mss-gem")) + macb->hw_dma_cap = HW_DMA_CAP_64B; + else + macb->hw_dma_cap = HW_DMA_CAP_32B; + } + macb->regs = (void *)pdata->iobase; macb->is_big_endian = (cpu_to_be32(0x12345678) == 0x12345678); @@ -1324,6 +1420,7 @@ 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" }, { } }; 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__ */