net: dwc: xgmac: Allow DMA buffers above 4GB
Currently, Synopsis xgmac driver only works if DMA region is under 4GB. This change enables the DMA buffers allocations above 4GB memory regions. Signed-off-by: Nikunj Kela <nikunj.kela@sima.ai>
This commit is contained in:
@@ -45,6 +45,7 @@
|
|||||||
#include <asm/gpio.h>
|
#include <asm/gpio.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
#include "dwc_eth_xgmac.h"
|
#include "dwc_eth_xgmac.h"
|
||||||
|
|
||||||
static void *xgmac_alloc_descs(struct xgmac_priv *xgmac, unsigned int num)
|
static void *xgmac_alloc_descs(struct xgmac_priv *xgmac, unsigned int num)
|
||||||
@@ -457,7 +458,7 @@ static int xgmac_start(struct udevice *dev)
|
|||||||
int ret, i;
|
int ret, i;
|
||||||
u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl;
|
u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl;
|
||||||
ulong last_rx_desc;
|
ulong last_rx_desc;
|
||||||
ulong desc_pad;
|
ulong desc_pad, address;
|
||||||
|
|
||||||
struct xgmac_desc *tx_desc = NULL;
|
struct xgmac_desc *tx_desc = NULL;
|
||||||
struct xgmac_desc *rx_desc = NULL;
|
struct xgmac_desc *rx_desc = NULL;
|
||||||
@@ -702,8 +703,11 @@ static int xgmac_start(struct udevice *dev)
|
|||||||
for (i = 0; i < XGMAC_DESCRIPTORS_RX; i++) {
|
for (i = 0; i < XGMAC_DESCRIPTORS_RX; i++) {
|
||||||
rx_desc = (struct xgmac_desc *)xgmac_get_desc(xgmac, i, true);
|
rx_desc = (struct xgmac_desc *)xgmac_get_desc(xgmac, i, true);
|
||||||
|
|
||||||
rx_desc->des0 = (uintptr_t)(xgmac->rx_dma_buf +
|
address = (uintptr_t)(xgmac->rx_dma_buf +
|
||||||
(i * XGMAC_MAX_PACKET_SIZE));
|
(i * XGMAC_MAX_PACKET_SIZE));
|
||||||
|
|
||||||
|
rx_desc->des0 = lower_32_bits(address);
|
||||||
|
rx_desc->des1 = upper_32_bits(address);
|
||||||
rx_desc->des3 = XGMAC_DESC3_OWN;
|
rx_desc->des3 = XGMAC_DESC3_OWN;
|
||||||
/* Flush the cache to the memory */
|
/* Flush the cache to the memory */
|
||||||
mb();
|
mb();
|
||||||
@@ -713,13 +717,17 @@ static int xgmac_start(struct udevice *dev)
|
|||||||
XGMAC_MAX_PACKET_SIZE);
|
XGMAC_MAX_PACKET_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
writel(0, &xgmac->dma_regs->ch0_txdesc_list_haddress);
|
address = (ulong)xgmac_get_desc(xgmac, 0, false);
|
||||||
writel((ulong)xgmac_get_desc(xgmac, 0, false),
|
writel(upper_32_bits(address),
|
||||||
|
&xgmac->dma_regs->ch0_txdesc_list_haddress);
|
||||||
|
writel(lower_32_bits(address),
|
||||||
&xgmac->dma_regs->ch0_txdesc_list_address);
|
&xgmac->dma_regs->ch0_txdesc_list_address);
|
||||||
writel(XGMAC_DESCRIPTORS_TX - 1,
|
writel(XGMAC_DESCRIPTORS_TX - 1,
|
||||||
&xgmac->dma_regs->ch0_txdesc_ring_length);
|
&xgmac->dma_regs->ch0_txdesc_ring_length);
|
||||||
writel(0, &xgmac->dma_regs->ch0_rxdesc_list_haddress);
|
address = (ulong)xgmac_get_desc(xgmac, 0, true);
|
||||||
writel((ulong)xgmac_get_desc(xgmac, 0, true),
|
writel(upper_32_bits(address),
|
||||||
|
&xgmac->dma_regs->ch0_rxdesc_list_haddress);
|
||||||
|
writel(lower_32_bits(address),
|
||||||
&xgmac->dma_regs->ch0_rxdesc_list_address);
|
&xgmac->dma_regs->ch0_rxdesc_list_address);
|
||||||
writel(XGMAC_DESCRIPTORS_RX - 1,
|
writel(XGMAC_DESCRIPTORS_RX - 1,
|
||||||
&xgmac->dma_regs->ch0_rxdesc_ring_length);
|
&xgmac->dma_regs->ch0_rxdesc_ring_length);
|
||||||
@@ -844,8 +852,8 @@ static int xgmac_send(struct udevice *dev, void *packet, int length)
|
|||||||
xgmac->tx_desc_idx++;
|
xgmac->tx_desc_idx++;
|
||||||
xgmac->tx_desc_idx %= XGMAC_DESCRIPTORS_TX;
|
xgmac->tx_desc_idx %= XGMAC_DESCRIPTORS_TX;
|
||||||
|
|
||||||
tx_desc->des0 = (ulong)xgmac->tx_dma_buf;
|
tx_desc->des0 = lower_32_bits((ulong)xgmac->tx_dma_buf);
|
||||||
tx_desc->des1 = 0;
|
tx_desc->des1 = upper_32_bits((ulong)xgmac->tx_dma_buf);
|
||||||
tx_desc->des2 = length;
|
tx_desc->des2 = length;
|
||||||
/*
|
/*
|
||||||
* Make sure that if HW sees the _OWN write below, it will see all the
|
* Make sure that if HW sees the _OWN write below, it will see all the
|
||||||
@@ -901,6 +909,7 @@ static int xgmac_free_pkt(struct udevice *dev, uchar *packet, int length)
|
|||||||
u32 idx, idx_mask = xgmac->desc_per_cacheline - 1;
|
u32 idx, idx_mask = xgmac->desc_per_cacheline - 1;
|
||||||
uchar *packet_expected;
|
uchar *packet_expected;
|
||||||
struct xgmac_desc *rx_desc;
|
struct xgmac_desc *rx_desc;
|
||||||
|
ulong address;
|
||||||
|
|
||||||
debug("%s(packet=%p, length=%d)\n", __func__, packet, length);
|
debug("%s(packet=%p, length=%d)\n", __func__, packet, length);
|
||||||
|
|
||||||
@@ -920,13 +929,15 @@ static int xgmac_free_pkt(struct udevice *dev, uchar *packet, int length)
|
|||||||
idx++) {
|
idx++) {
|
||||||
rx_desc = xgmac_get_desc(xgmac, idx, true);
|
rx_desc = xgmac_get_desc(xgmac, idx, true);
|
||||||
rx_desc->des0 = 0;
|
rx_desc->des0 = 0;
|
||||||
|
rx_desc->des1 = 0;
|
||||||
/* Flush the cache to the memory */
|
/* Flush the cache to the memory */
|
||||||
mb();
|
mb();
|
||||||
xgmac->config->ops->xgmac_flush_desc(rx_desc);
|
xgmac->config->ops->xgmac_flush_desc(rx_desc);
|
||||||
xgmac->config->ops->xgmac_inval_buffer(packet, length);
|
xgmac->config->ops->xgmac_inval_buffer(packet, length);
|
||||||
rx_desc->des0 = (u32)(ulong)(xgmac->rx_dma_buf +
|
address = (ulong)(xgmac->rx_dma_buf +
|
||||||
(idx * XGMAC_MAX_PACKET_SIZE));
|
(idx * XGMAC_MAX_PACKET_SIZE));
|
||||||
rx_desc->des1 = 0;
|
rx_desc->des0 = lower_32_bits(address);
|
||||||
|
rx_desc->des1 = upper_32_bits(address);
|
||||||
rx_desc->des2 = 0;
|
rx_desc->des2 = 0;
|
||||||
/*
|
/*
|
||||||
* Make sure that if HW sees the _OWN write below,
|
* Make sure that if HW sees the _OWN write below,
|
||||||
|
Reference in New Issue
Block a user