diff mbox series

[U-Boot,1/2] net: zynq_gem: Added 64-bit addressing support

Message ID 1543229859-15003-1-git-send-email-siva.durga.paladugu@xilinx.com
State Accepted
Commit 9a7799f4f4426e690d8c5ab69e6ac34e51029036
Delegated to: Michal Simek
Headers show
Series [U-Boot,1/2] net: zynq_gem: Added 64-bit addressing support | expand

Commit Message

Siva Durga Prasad Paladugu Nov. 26, 2018, 10:57 a.m. UTC
From: Vipul Kumar <vipul.kumar@xilinx.com>

This patch adds 64-bit addressing support for zynq gem.
This means it can perform send and receive operations on
64-bit address buffers.

Signed-off-by: Vipul Kumar <vipul.kumar@xilinx.com>
Signed-off-by: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
 drivers/net/zynq_gem.c | 63 ++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 54 insertions(+), 9 deletions(-)

Comments

Michal Simek Dec. 3, 2018, 3:21 p.m. UTC | #1
On 26. 11. 18 11:57, Siva Durga Prasad Paladugu wrote:
> From: Vipul Kumar <vipul.kumar@xilinx.com>
> 
> This patch adds 64-bit addressing support for zynq gem.
> This means it can perform send and receive operations on
> 64-bit address buffers.
> 
> Signed-off-by: Vipul Kumar <vipul.kumar@xilinx.com>
> Signed-off-by: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> ---
>  drivers/net/zynq_gem.c | 63 ++++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 54 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
> index bc33126..ee528db 100644
> --- a/drivers/net/zynq_gem.c
> +++ b/drivers/net/zynq_gem.c
> @@ -86,10 +86,17 @@ DECLARE_GLOBAL_DATA_PTR;
>  /* Set with binary 00011000 to use 1536 byte(1*max length frame/buffer) */
>  #define ZYNQ_GEM_DMACR_RXBUF		0x00180000
>  
> +#if defined(CONFIG_PHYS_64BIT)
> +# define ZYNQ_GEM_DMA_BUS_WIDTH		BIT(30) /* 64 bit bus */
> +#else
> +# define ZYNQ_GEM_DMA_BUS_WIDTH		(0 << 30) /* 32 bit bus */
> +#endif
> +
>  #define ZYNQ_GEM_DMACR_INIT		(ZYNQ_GEM_DMACR_BLENGTH | \
>  					ZYNQ_GEM_DMACR_RXSIZE | \
>  					ZYNQ_GEM_DMACR_TXSIZE | \
> -					ZYNQ_GEM_DMACR_RXBUF)
> +					ZYNQ_GEM_DMACR_RXBUF | \
> +					ZYNQ_GEM_DMA_BUS_WIDTH)
>  
>  #define ZYNQ_GEM_TSR_DONE		0x00000020 /* Tx done mask */
>  
> @@ -147,12 +154,20 @@ struct zynq_gem_regs {
>  	u32 transmit_q1_ptr; /* 0x440 - Transmit priority queue 1 */
>  	u32 reserved8[15];
>  	u32 receive_q1_ptr; /* 0x480 - Receive priority queue 1 */
> +	u32 reserved10[17];
> +	u32 upper_txqbase; /* 0x4C8 - Upper tx_q base addr */
> +	u32 reserved11[2];
> +	u32 upper_rxqbase; /* 0x4D4 - Upper rx_q base addr */
>  };
>  
>  /* BD descriptors */
>  struct emac_bd {
>  	u32 addr; /* Next descriptor pointer */
>  	u32 status;
> +#if defined(CONFIG_PHYS_64BIT)
> +	u32 addr_hi;
> +	u32 reserved;
> +#endif
>  };
>  
>  #define RX_BUF 32
> @@ -390,13 +405,21 @@ static int zynq_gem_init(struct udevice *dev)
>  		for (i = 0; i < RX_BUF; i++) {
>  			priv->rx_bd[i].status = 0xF0000000;
>  			priv->rx_bd[i].addr =
> -					((ulong)(priv->rxbuffers) +
> -							(i * PKTSIZE_ALIGN));
> -		}
> +					(lower_32_bits((ulong)(priv->rxbuffers)
> +							+ (i * PKTSIZE_ALIGN)));
> +#if defined(CONFIG_PHYS_64BIT)
> +			priv->rx_bd[i].addr_hi =
> +					(upper_32_bits((ulong)(priv->rxbuffers)
> +							+ (i * PKTSIZE_ALIGN)));
> +#endif
> +	}
>  		/* WRAP bit to last BD */
>  		priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
>  		/* Write RxBDs to IP */
> -		writel((ulong)priv->rx_bd, &regs->rxqbase);
> +		writel(lower_32_bits((ulong)priv->rx_bd), &regs->rxqbase);
> +#if defined(CONFIG_PHYS_64BIT)
> +		writel(upper_32_bits((ulong)priv->rx_bd), &regs->upper_rxqbase);
> +#endif
>  
>  		/* Setup for DMA Configuration register */
>  		writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);
> @@ -406,12 +429,18 @@ static int zynq_gem_init(struct udevice *dev)
>  
>  		/* Disable the second priority queue */
>  		dummy_tx_bd->addr = 0;
> +#if defined(CONFIG_PHYS_64BIT)
> +		dummy_tx_bd->addr_hi = 0;
> +#endif
>  		dummy_tx_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
>  				ZYNQ_GEM_TXBUF_LAST_MASK|
>  				ZYNQ_GEM_TXBUF_USED_MASK;
>  
>  		dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK |
>  				ZYNQ_GEM_RXBUF_NEW_MASK;
> +#if defined(CONFIG_PHYS_64BIT)
> +		dummy_rx_bd->addr_hi = 0;
> +#endif
>  		dummy_rx_bd->status = 0;
>  
>  		writel((ulong)dummy_tx_bd, &regs->transmit_q1_ptr);
> @@ -485,7 +514,8 @@ static int zynq_gem_init(struct udevice *dev)
>  
>  static int zynq_gem_send(struct udevice *dev, void *ptr, int len)
>  {
> -	u32 addr, size;
> +	dma_addr_t addr;
> +	u32 size;
>  	struct zynq_gem_priv *priv = dev_get_priv(dev);
>  	struct zynq_gem_regs *regs = priv->iobase;
>  	struct emac_bd *current_bd = &priv->tx_bd[1];
> @@ -493,17 +523,26 @@ static int zynq_gem_send(struct udevice *dev, void *ptr, int len)
>  	/* Setup Tx BD */
>  	memset(priv->tx_bd, 0, sizeof(struct emac_bd));
>  
> -	priv->tx_bd->addr = (ulong)ptr;
> +	priv->tx_bd->addr = lower_32_bits((ulong)ptr);
> +#if defined(CONFIG_PHYS_64BIT)
> +	priv->tx_bd->addr_hi = upper_32_bits((ulong)ptr);
> +#endif
>  	priv->tx_bd->status = (len & ZYNQ_GEM_TXBUF_FRMLEN_MASK) |
>  			       ZYNQ_GEM_TXBUF_LAST_MASK;
>  	/* Dummy descriptor to mark it as the last in descriptor chain */
>  	current_bd->addr = 0x0;
> +#if defined(CONFIG_PHYS_64BIT)
> +	current_bd->addr_hi = 0x0;
> +#endif
>  	current_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
>  			     ZYNQ_GEM_TXBUF_LAST_MASK|
>  			     ZYNQ_GEM_TXBUF_USED_MASK;
>  
>  	/* setup BD */
> -	writel((ulong)priv->tx_bd, &regs->txqbase);
> +	writel(lower_32_bits((ulong)priv->tx_bd), &regs->txqbase);
> +#if defined(CONFIG_PHYS_64BIT)
> +	writel(upper_32_bits((ulong)priv->tx_bd), &regs->upper_txqbase);
> +#endif
>  
>  	addr = (ulong) ptr;
>  	addr &= ~(ARCH_DMA_MINALIGN - 1);
> @@ -531,7 +570,7 @@ static int zynq_gem_send(struct udevice *dev, void *ptr, int len)
>  static int zynq_gem_recv(struct udevice *dev, int flags, uchar **packetp)
>  {
>  	int frame_len;
> -	u32 addr;
> +	dma_addr_t addr;
>  	struct zynq_gem_priv *priv = dev_get_priv(dev);
>  	struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current];
>  
> @@ -550,8 +589,14 @@ static int zynq_gem_recv(struct udevice *dev, int flags, uchar **packetp)
>  		return -1;
>  	}
>  
> +#if defined(CONFIG_PHYS_64BIT)
> +	addr = (dma_addr_t)((current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK)
> +		      | ((dma_addr_t)current_bd->addr_hi << 32));
> +#else
>  	addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK;
> +#endif
>  	addr &= ~(ARCH_DMA_MINALIGN - 1);
> +
>  	*packetp = (uchar *)(uintptr_t)addr;
>  
>  	return frame_len;
> 

Applied both.

M
diff mbox series

Patch

diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index bc33126..ee528db 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -86,10 +86,17 @@  DECLARE_GLOBAL_DATA_PTR;
 /* Set with binary 00011000 to use 1536 byte(1*max length frame/buffer) */
 #define ZYNQ_GEM_DMACR_RXBUF		0x00180000
 
+#if defined(CONFIG_PHYS_64BIT)
+# define ZYNQ_GEM_DMA_BUS_WIDTH		BIT(30) /* 64 bit bus */
+#else
+# define ZYNQ_GEM_DMA_BUS_WIDTH		(0 << 30) /* 32 bit bus */
+#endif
+
 #define ZYNQ_GEM_DMACR_INIT		(ZYNQ_GEM_DMACR_BLENGTH | \
 					ZYNQ_GEM_DMACR_RXSIZE | \
 					ZYNQ_GEM_DMACR_TXSIZE | \
-					ZYNQ_GEM_DMACR_RXBUF)
+					ZYNQ_GEM_DMACR_RXBUF | \
+					ZYNQ_GEM_DMA_BUS_WIDTH)
 
 #define ZYNQ_GEM_TSR_DONE		0x00000020 /* Tx done mask */
 
@@ -147,12 +154,20 @@  struct zynq_gem_regs {
 	u32 transmit_q1_ptr; /* 0x440 - Transmit priority queue 1 */
 	u32 reserved8[15];
 	u32 receive_q1_ptr; /* 0x480 - Receive priority queue 1 */
+	u32 reserved10[17];
+	u32 upper_txqbase; /* 0x4C8 - Upper tx_q base addr */
+	u32 reserved11[2];
+	u32 upper_rxqbase; /* 0x4D4 - Upper rx_q base addr */
 };
 
 /* BD descriptors */
 struct emac_bd {
 	u32 addr; /* Next descriptor pointer */
 	u32 status;
+#if defined(CONFIG_PHYS_64BIT)
+	u32 addr_hi;
+	u32 reserved;
+#endif
 };
 
 #define RX_BUF 32
@@ -390,13 +405,21 @@  static int zynq_gem_init(struct udevice *dev)
 		for (i = 0; i < RX_BUF; i++) {
 			priv->rx_bd[i].status = 0xF0000000;
 			priv->rx_bd[i].addr =
-					((ulong)(priv->rxbuffers) +
-							(i * PKTSIZE_ALIGN));
-		}
+					(lower_32_bits((ulong)(priv->rxbuffers)
+							+ (i * PKTSIZE_ALIGN)));
+#if defined(CONFIG_PHYS_64BIT)
+			priv->rx_bd[i].addr_hi =
+					(upper_32_bits((ulong)(priv->rxbuffers)
+							+ (i * PKTSIZE_ALIGN)));
+#endif
+	}
 		/* WRAP bit to last BD */
 		priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
 		/* Write RxBDs to IP */
-		writel((ulong)priv->rx_bd, &regs->rxqbase);
+		writel(lower_32_bits((ulong)priv->rx_bd), &regs->rxqbase);
+#if defined(CONFIG_PHYS_64BIT)
+		writel(upper_32_bits((ulong)priv->rx_bd), &regs->upper_rxqbase);
+#endif
 
 		/* Setup for DMA Configuration register */
 		writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);
@@ -406,12 +429,18 @@  static int zynq_gem_init(struct udevice *dev)
 
 		/* Disable the second priority queue */
 		dummy_tx_bd->addr = 0;
+#if defined(CONFIG_PHYS_64BIT)
+		dummy_tx_bd->addr_hi = 0;
+#endif
 		dummy_tx_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
 				ZYNQ_GEM_TXBUF_LAST_MASK|
 				ZYNQ_GEM_TXBUF_USED_MASK;
 
 		dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK |
 				ZYNQ_GEM_RXBUF_NEW_MASK;
+#if defined(CONFIG_PHYS_64BIT)
+		dummy_rx_bd->addr_hi = 0;
+#endif
 		dummy_rx_bd->status = 0;
 
 		writel((ulong)dummy_tx_bd, &regs->transmit_q1_ptr);
@@ -485,7 +514,8 @@  static int zynq_gem_init(struct udevice *dev)
 
 static int zynq_gem_send(struct udevice *dev, void *ptr, int len)
 {
-	u32 addr, size;
+	dma_addr_t addr;
+	u32 size;
 	struct zynq_gem_priv *priv = dev_get_priv(dev);
 	struct zynq_gem_regs *regs = priv->iobase;
 	struct emac_bd *current_bd = &priv->tx_bd[1];
@@ -493,17 +523,26 @@  static int zynq_gem_send(struct udevice *dev, void *ptr, int len)
 	/* Setup Tx BD */
 	memset(priv->tx_bd, 0, sizeof(struct emac_bd));
 
-	priv->tx_bd->addr = (ulong)ptr;
+	priv->tx_bd->addr = lower_32_bits((ulong)ptr);
+#if defined(CONFIG_PHYS_64BIT)
+	priv->tx_bd->addr_hi = upper_32_bits((ulong)ptr);
+#endif
 	priv->tx_bd->status = (len & ZYNQ_GEM_TXBUF_FRMLEN_MASK) |
 			       ZYNQ_GEM_TXBUF_LAST_MASK;
 	/* Dummy descriptor to mark it as the last in descriptor chain */
 	current_bd->addr = 0x0;
+#if defined(CONFIG_PHYS_64BIT)
+	current_bd->addr_hi = 0x0;
+#endif
 	current_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
 			     ZYNQ_GEM_TXBUF_LAST_MASK|
 			     ZYNQ_GEM_TXBUF_USED_MASK;
 
 	/* setup BD */
-	writel((ulong)priv->tx_bd, &regs->txqbase);
+	writel(lower_32_bits((ulong)priv->tx_bd), &regs->txqbase);
+#if defined(CONFIG_PHYS_64BIT)
+	writel(upper_32_bits((ulong)priv->tx_bd), &regs->upper_txqbase);
+#endif
 
 	addr = (ulong) ptr;
 	addr &= ~(ARCH_DMA_MINALIGN - 1);
@@ -531,7 +570,7 @@  static int zynq_gem_send(struct udevice *dev, void *ptr, int len)
 static int zynq_gem_recv(struct udevice *dev, int flags, uchar **packetp)
 {
 	int frame_len;
-	u32 addr;
+	dma_addr_t addr;
 	struct zynq_gem_priv *priv = dev_get_priv(dev);
 	struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current];
 
@@ -550,8 +589,14 @@  static int zynq_gem_recv(struct udevice *dev, int flags, uchar **packetp)
 		return -1;
 	}
 
+#if defined(CONFIG_PHYS_64BIT)
+	addr = (dma_addr_t)((current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK)
+		      | ((dma_addr_t)current_bd->addr_hi << 32));
+#else
 	addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK;
+#endif
 	addr &= ~(ARCH_DMA_MINALIGN - 1);
+
 	*packetp = (uchar *)(uintptr_t)addr;
 
 	return frame_len;