mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [For master PATCH 0/7] macb: more fixes + gem (gigabit support)
@ 2013-02-08  9:07 Jean-Christophe PLAGNIOL-VILLARD
  2013-02-08  9:18 ` [PATCH 1/7] macb: call macb_init at probe explecitly Jean-Christophe PLAGNIOL-VILLARD
                   ` (3 more replies)
  0 siblings, 4 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-02-08  9:07 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre

HI,

	This patch serie fixe more issue on the macb and add the GEM support
	(gigabit support) present on Atmel sama5d3x as example

	The IP version is detected as in linux

	we now share more code with the kernel and will help to maintain the
	driver

	tesed on at91 macb & gem

The following changes since commit 15c5fa0467b20c05e9ebea36e049764054a7e308:

  macb: drop non used define (2013-02-08 16:55:16 +0800)

are available in the git repository at:

  git://git.jcrosoft.org/barebox.git delivery/macb

for you to fetch changes up to b7058953abdd014b9626b22d868fb29c1c563514:

  macb: add cadence Gigabit GEM support (2013-02-08 16:55:41 +0800)

----------------------------------------------------------------
Jean-Christophe PLAGNIOL-VILLARD (7):
      macb: call macb_init at probe explecitly
      macb: sync remaining define with linux
      macb: use the macro as in linux for tx/rx buffer ring size
      macb: enable Tramsmit and Receive at open
      macb: reset the IP at init
      macb: fix tx ring size
      macb: add cadence Gigabit GEM support

 drivers/net/macb.c |  394 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------
 drivers/net/macb.h |  179 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 466 insertions(+), 107 deletions(-)

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/7] macb: call macb_init at probe explecitly
  2013-02-08  9:07 [For master PATCH 0/7] macb: more fixes + gem (gigabit support) Jean-Christophe PLAGNIOL-VILLARD
@ 2013-02-08  9:18 ` Jean-Christophe PLAGNIOL-VILLARD
  2013-02-08  9:18   ` [PATCH 2/7] macb: sync remaining define with linux Jean-Christophe PLAGNIOL-VILLARD
                     ` (5 more replies)
  2013-02-08 10:24 ` [For master PATCH 0/7] macb: more fixes + gem (gigabit support) Nicolas Ferre
                   ` (2 subsequent siblings)
  3 siblings, 6 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-02-08  9:18 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre

as eth_device init is planning for remove and we need the init before register
the mdio bus

Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/net/macb.c |    8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 2eba2a5..3aec0c4 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -241,9 +241,8 @@ static int macb_open(struct eth_device *edev)
 			       macb->interface);
 }
 
-static int macb_init(struct eth_device *edev)
+static void macb_init(struct macb_device *macb)
 {
-	struct macb_device *macb = edev->priv;
 	unsigned long paddr, val = 0;
 	int i;
 
@@ -284,8 +283,6 @@ static int macb_init(struct eth_device *edev)
 
 	/* Enable TX and RX */
 	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE));
-
-	return 0;
 }
 
 static void macb_halt(struct eth_device *edev)
@@ -423,7 +420,6 @@ static int macb_probe(struct device_d *dev)
 
 	macb->dev = dev;
 
-	edev->init = macb_init;
 	edev->open = macb_open;
 	edev->send = macb_send;
 	edev->recv = macb_recv;
@@ -474,6 +470,8 @@ static int macb_probe(struct device_d *dev)
 
 	macb_writel(macb, NCFGR, ncfgr);
 
+	macb_init(macb);
+
 	mdiobus_register(&macb->miibus);
 	eth_register(edev);
 
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 2/7] macb: sync remaining define with linux
  2013-02-08  9:18 ` [PATCH 1/7] macb: call macb_init at probe explecitly Jean-Christophe PLAGNIOL-VILLARD
@ 2013-02-08  9:18   ` Jean-Christophe PLAGNIOL-VILLARD
  2013-02-08  9:18   ` [PATCH 3/7] macb: use the macro as in linux for tx/rx buffer ring size Jean-Christophe PLAGNIOL-VILLARD
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-02-08  9:18 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre

Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/net/macb.c |   71 ++++++++++++++++------------------------------------
 drivers/net/macb.h |   70 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 92 insertions(+), 49 deletions(-)

diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 3aec0c4..4dc873d 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -56,29 +56,6 @@
 #define CFG_MACB_TX_TIMEOUT		1000
 #define CFG_MACB_AUTONEG_TIMEOUT	5000000
 
-struct macb_dma_desc {
-	u32	addr;
-	u32	ctrl;
-};
-
-#define RXADDR_USED		0x00000001
-#define RXADDR_WRAP		0x00000002
-
-#define RXBUF_FRMLEN_MASK	0x00000fff
-#define RXBUF_FRAME_START	0x00004000
-#define RXBUF_FRAME_END		0x00008000
-#define RXBUF_TYPEID_MATCH	0x00400000
-#define RXBUF_BROADCAST		0x80000000
-
-#define TXBUF_FRMLEN_MASK	0x000007ff
-#define TXBUF_FRAME_END		0x00008000
-#define TXBUF_NOCRC		0x00010000
-#define TXBUF_EXHAUSTED		0x08000000
-#define TXBUF_UNDERRUN		0x10000000
-#define TXBUF_MAXRETRY		0x20000000
-#define TXBUF_WRAP		0x40000000
-#define TXBUF_USED		0x80000000
-
 struct macb_device {
 	void			__iomem *regs;
 
@@ -111,8 +88,8 @@ static int macb_send(struct eth_device *edev, void *packet,
 
 	dev_dbg(macb->dev, "%s\n", __func__);
 
-	ctrl = length & TXBUF_FRMLEN_MASK;
-	ctrl |= TXBUF_FRAME_END | TXBUF_WRAP;
+	ctrl = MACB_BF(TX_FRMLEN, length);
+	ctrl |= MACB_BIT(TX_LAST) | MACB_BIT(TX_WRAP);
 
 	macb->tx_ring[0].ctrl = ctrl;
 	macb->tx_ring[0].addr = (ulong)packet;
@@ -121,13 +98,13 @@ static int macb_send(struct eth_device *edev, void *packet,
 	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
 
 	ret = wait_on_timeout(100 * MSECOND,
-		!(macb->tx_ring[0].ctrl & TXBUF_USED));
+		!(macb->tx_ring[0].ctrl & MACB_BIT(TX_USED)));
 
 	ctrl = macb->tx_ring[0].ctrl;
 
-	if (ctrl & TXBUF_UNDERRUN)
+	if (ctrl & MACB_BIT(TX_UNDERRUN))
 		dev_err(macb->dev, "TX underrun\n");
-	if (ctrl & TXBUF_EXHAUSTED)
+	if (ctrl & MACB_BIT(TX_BUF_EXHAUSTED))
 		dev_err(macb->dev, "TX buffers exhausted in mid frame\n");
 	if (ret)
 		dev_err(macb->dev,"TX timeout\n");
@@ -144,14 +121,14 @@ static void reclaim_rx_buffers(struct macb_device *macb,
 
 	i = macb->rx_tail;
 	while (i > new_tail) {
-		macb->rx_ring[i].addr &= ~RXADDR_USED;
+		macb->rx_ring[i].addr &= ~MACB_BIT(RX_USED);
 		i++;
 		if (i > CFG_MACB_RX_RING_SIZE)
 			i = 0;
 	}
 
 	while (i < new_tail) {
-		macb->rx_ring[i].addr &= ~RXADDR_USED;
+		macb->rx_ring[i].addr &= ~MACB_BIT(RX_USED);
 		i++;
 	}
 
@@ -171,19 +148,19 @@ static int macb_recv(struct eth_device *edev)
 	dev_dbg(macb->dev, "%s\n", __func__);
 
 	for (;;) {
-		if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED))
+		if (!(macb->rx_ring[rx_tail].addr & MACB_BIT(RX_USED)))
 			return -1;
 
 		status = macb->rx_ring[rx_tail].ctrl;
-		if (status & RXBUF_FRAME_START) {
+		if (status & MACB_BIT(RX_SOF)) {
 			if (rx_tail != macb->rx_tail)
 				reclaim_rx_buffers(macb, rx_tail);
 			wrapped = 0;
 		}
 
-		if (status & RXBUF_FRAME_END) {
+		if (status & MACB_BIT(RX_EOF)) {
 			buffer = macb->rx_buffer + 128 * macb->rx_tail;
-			length = status & RXBUF_FRMLEN_MASK;
+			length = MACB_BFEXT(RX_FRMLEN, status);
 			if (wrapped) {
 				unsigned int headlen, taillen;
 
@@ -257,14 +234,14 @@ static void macb_init(struct macb_device *macb)
 	paddr = (ulong)macb->rx_buffer;
 	for (i = 0; i < CFG_MACB_RX_RING_SIZE; i++) {
 		if (i == (CFG_MACB_RX_RING_SIZE - 1))
-			paddr |= RXADDR_WRAP;
+			paddr |= MACB_BIT(RX_WRAP);
 		macb->rx_ring[i].addr = paddr;
 		macb->rx_ring[i].ctrl = 0;
 		paddr += 128;
 	}
 
 	macb->tx_ring[0].addr = 0;
-	macb->tx_ring[0].ctrl = TXBUF_USED | TXBUF_WRAP;
+	macb->tx_ring[0].ctrl = MACB_BIT(TX_USED) | MACB_BIT(TX_WRAP);
 
 	macb->rx_tail = macb->tx_tail = 0;
 
@@ -308,7 +285,6 @@ static int macb_phy_read(struct mii_bus *bus, int addr, int reg)
 	struct macb_device *macb = bus->priv;
 
 	unsigned long netctl;
-	unsigned long netstat;
 	unsigned long frame;
 	int value;
 	uint64_t start;
@@ -319,21 +295,20 @@ static int macb_phy_read(struct mii_bus *bus, int addr, int reg)
 	netctl |= MACB_BIT(MPE);
 	macb_writel(macb, NCR, netctl);
 
-	frame = (MACB_BF(SOF, 1)
-		 | MACB_BF(RW, 2)
+	frame = (MACB_BF(SOF, MACB_MAN_SOF)
+		 | MACB_BF(RW, MACB_MAN_READ)
 		 | MACB_BF(PHYA, addr)
 		 | MACB_BF(REGA, reg)
-		 | MACB_BF(CODE, 2));
+		 | MACB_BF(CODE, MACB_MAN_CODE));
 	macb_writel(macb, MAN, frame);
 
 	start = get_time_ns();
 	do {
-		netstat = macb_readl(macb, NSR);
 		if (is_timeout(start, SECOND)) {
 			dev_err(macb->dev, "phy read timed out\n");
 			return -1;
 		}
-	} while (!(netstat & MACB_BIT(IDLE)));
+	} while (!MACB_BFEXT(IDLE, macb_readl(macb, NSR)));
 
 	frame = macb_readl(macb, MAN);
 	value = MACB_BFEXT(DATA, frame);
@@ -349,7 +324,6 @@ static int macb_phy_write(struct mii_bus *bus, int addr, int reg, u16 value)
 {
 	struct macb_device *macb = bus->priv;
 	unsigned long netctl;
-	unsigned long netstat;
 	unsigned long frame;
 
 	dev_dbg(macb->dev, "%s\n", __func__);
@@ -358,17 +332,16 @@ static int macb_phy_write(struct mii_bus *bus, int addr, int reg, u16 value)
 	netctl |= MACB_BIT(MPE);
 	macb_writel(macb, NCR, netctl);
 
-	frame = (MACB_BF(SOF, 1)
-		 | MACB_BF(RW, 1)
+	frame = (MACB_BF(SOF, MACB_MAN_SOF)
+		 | MACB_BF(RW, MACB_MAN_WRITE)
 		 | MACB_BF(PHYA, addr)
 		 | MACB_BF(REGA, reg)
-		 | MACB_BF(CODE, 2)
+		 | MACB_BF(CODE, MACB_MAN_CODE)
 		 | MACB_BF(DATA, value));
 	macb_writel(macb, MAN, frame);
 
-	do {
-		netstat = macb_readl(macb, NSR);
-	} while (!(netstat & MACB_BIT(IDLE)));
+	while (!MACB_BFEXT(IDLE, macb_readl(macb, NSR)))
+		;
 
 	netctl = macb_readl(macb, NCR);
 	netctl &= ~MACB_BIT(MPE);
diff --git a/drivers/net/macb.h b/drivers/net/macb.h
index 5d9c534..8dd5a87 100644
--- a/drivers/net/macb.h
+++ b/drivers/net/macb.h
@@ -268,4 +268,74 @@
 #define macb_writel(port,reg,value)			\
 	__raw_writel((value), (port)->regs + MACB_##reg)
 
+/**
+ * struct macb_dma_desc - Hardware DMA descriptor
+ * @addr: DMA address of data buffer
+ * @ctrl: Control and status bits
+ */
+struct macb_dma_desc {
+	u32	addr;
+	u32	ctrl;
+};
+
+/* DMA descriptor bitfields */
+#define MACB_RX_USED_OFFSET			0
+#define MACB_RX_USED_SIZE			1
+#define MACB_RX_WRAP_OFFSET			1
+#define MACB_RX_WRAP_SIZE			1
+#define MACB_RX_WADDR_OFFSET			2
+#define MACB_RX_WADDR_SIZE			30
+
+#define MACB_RX_FRMLEN_OFFSET			0
+#define MACB_RX_FRMLEN_SIZE			12
+#define MACB_RX_OFFSET_OFFSET			12
+#define MACB_RX_OFFSET_SIZE			2
+#define MACB_RX_SOF_OFFSET			14
+#define MACB_RX_SOF_SIZE			1
+#define MACB_RX_EOF_OFFSET			15
+#define MACB_RX_EOF_SIZE			1
+#define MACB_RX_CFI_OFFSET			16
+#define MACB_RX_CFI_SIZE			1
+#define MACB_RX_VLAN_PRI_OFFSET			17
+#define MACB_RX_VLAN_PRI_SIZE			3
+#define MACB_RX_PRI_TAG_OFFSET			20
+#define MACB_RX_PRI_TAG_SIZE			1
+#define MACB_RX_VLAN_TAG_OFFSET			21
+#define MACB_RX_VLAN_TAG_SIZE			1
+#define MACB_RX_TYPEID_MATCH_OFFSET		22
+#define MACB_RX_TYPEID_MATCH_SIZE		1
+#define MACB_RX_SA4_MATCH_OFFSET		23
+#define MACB_RX_SA4_MATCH_SIZE			1
+#define MACB_RX_SA3_MATCH_OFFSET		24
+#define MACB_RX_SA3_MATCH_SIZE			1
+#define MACB_RX_SA2_MATCH_OFFSET		25
+#define MACB_RX_SA2_MATCH_SIZE			1
+#define MACB_RX_SA1_MATCH_OFFSET		26
+#define MACB_RX_SA1_MATCH_SIZE			1
+#define MACB_RX_EXT_MATCH_OFFSET		28
+#define MACB_RX_EXT_MATCH_SIZE			1
+#define MACB_RX_UHASH_MATCH_OFFSET		29
+#define MACB_RX_UHASH_MATCH_SIZE		1
+#define MACB_RX_MHASH_MATCH_OFFSET		30
+#define MACB_RX_MHASH_MATCH_SIZE		1
+#define MACB_RX_BROADCAST_OFFSET		31
+#define MACB_RX_BROADCAST_SIZE			1
+
+#define MACB_TX_FRMLEN_OFFSET			0
+#define MACB_TX_FRMLEN_SIZE			11
+#define MACB_TX_LAST_OFFSET			15
+#define MACB_TX_LAST_SIZE			1
+#define MACB_TX_NOCRC_OFFSET			16
+#define MACB_TX_NOCRC_SIZE			1
+#define MACB_TX_BUF_EXHAUSTED_OFFSET		27
+#define MACB_TX_BUF_EXHAUSTED_SIZE		1
+#define MACB_TX_UNDERRUN_OFFSET			28
+#define MACB_TX_UNDERRUN_SIZE			1
+#define MACB_TX_ERROR_OFFSET			29
+#define MACB_TX_ERROR_SIZE			1
+#define MACB_TX_WRAP_OFFSET			30
+#define MACB_TX_WRAP_SIZE			1
+#define MACB_TX_USED_OFFSET			31
+#define MACB_TX_USED_SIZE			1
+
 #endif /* __DRIVERS_MACB_H__ */
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 3/7] macb: use the macro as in linux for tx/rx buffer ring size
  2013-02-08  9:18 ` [PATCH 1/7] macb: call macb_init at probe explecitly Jean-Christophe PLAGNIOL-VILLARD
  2013-02-08  9:18   ` [PATCH 2/7] macb: sync remaining define with linux Jean-Christophe PLAGNIOL-VILLARD
@ 2013-02-08  9:18   ` Jean-Christophe PLAGNIOL-VILLARD
  2013-02-08  9:18   ` [PATCH 4/7] macb: enable Tramsmit and Receive at open Jean-Christophe PLAGNIOL-VILLARD
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-02-08  9:18 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre

Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/net/macb.c |   33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 4dc873d..962a889 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -51,10 +51,12 @@
 
 #include "macb.h"
 
-#define CFG_MACB_RX_BUFFER_SIZE		4096
-#define CFG_MACB_RX_RING_SIZE		(CFG_MACB_RX_BUFFER_SIZE / 128)
-#define CFG_MACB_TX_TIMEOUT		1000
-#define CFG_MACB_AUTONEG_TIMEOUT	5000000
+#define MACB_RX_BUFFER_SIZE	128
+#define RX_BUFFER_MULTIPLE	64  /* bytes */
+#define RX_RING_SIZE		32 /* must be power of 2 */
+#define RX_RING_BYTES		(sizeof(struct macb_dma_desc) * RX_RING_SIZE)
+
+#define TX_RING_BYTES		(sizeof(struct macb_dma_desc))
 
 struct macb_device {
 	void			__iomem *regs;
@@ -123,7 +125,7 @@ static void reclaim_rx_buffers(struct macb_device *macb,
 	while (i > new_tail) {
 		macb->rx_ring[i].addr &= ~MACB_BIT(RX_USED);
 		i++;
-		if (i > CFG_MACB_RX_RING_SIZE)
+		if (i > RX_RING_SIZE)
 			i = 0;
 	}
 
@@ -159,12 +161,12 @@ static int macb_recv(struct eth_device *edev)
 		}
 
 		if (status & MACB_BIT(RX_EOF)) {
-			buffer = macb->rx_buffer + 128 * macb->rx_tail;
+			buffer = macb->rx_buffer + MACB_RX_BUFFER_SIZE * macb->rx_tail;
 			length = MACB_BFEXT(RX_FRMLEN, status);
 			if (wrapped) {
 				unsigned int headlen, taillen;
 
-				headlen = 128 * (CFG_MACB_RX_RING_SIZE
+				headlen = MACB_RX_BUFFER_SIZE * (RX_RING_SIZE
 						 - macb->rx_tail);
 				taillen = length - headlen;
 				memcpy((void *)NetRxPackets[0],
@@ -175,11 +177,11 @@ static int macb_recv(struct eth_device *edev)
 			}
 
 			net_receive(buffer, length);
-			if (++rx_tail >= CFG_MACB_RX_RING_SIZE)
+			if (++rx_tail >= RX_RING_SIZE)
 				rx_tail = 0;
 			reclaim_rx_buffers(macb, rx_tail);
 		} else {
-			if (++rx_tail >= CFG_MACB_RX_RING_SIZE) {
+			if (++rx_tail >= RX_RING_SIZE) {
 				wrapped = 1;
 				rx_tail = 0;
 			}
@@ -232,13 +234,12 @@ static void macb_init(struct macb_device *macb)
 
 	/* initialize DMA descriptors */
 	paddr = (ulong)macb->rx_buffer;
-	for (i = 0; i < CFG_MACB_RX_RING_SIZE; i++) {
-		if (i == (CFG_MACB_RX_RING_SIZE - 1))
-			paddr |= MACB_BIT(RX_WRAP);
+	for (i = 0; i < RX_RING_SIZE; i++) {
 		macb->rx_ring[i].addr = paddr;
 		macb->rx_ring[i].ctrl = 0;
-		paddr += 128;
+		paddr += MACB_RX_BUFFER_SIZE;
 	}
+	macb->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
 
 	macb->tx_ring[0].addr = 0;
 	macb->tx_ring[0].ctrl = MACB_BIT(TX_USED) | MACB_BIT(TX_WRAP);
@@ -414,9 +415,9 @@ static int macb_probe(struct device_d *dev)
 
 	macb->phy_flags = pdata->phy_flags;
 
-	macb->rx_buffer = dma_alloc_coherent(CFG_MACB_RX_BUFFER_SIZE);
-	macb->rx_ring = dma_alloc_coherent(CFG_MACB_RX_RING_SIZE * sizeof(struct macb_dma_desc));
-	macb->tx_ring = dma_alloc_coherent(sizeof(struct macb_dma_desc));
+	macb->rx_buffer = dma_alloc_coherent(MACB_RX_BUFFER_SIZE * RX_RING_SIZE);
+	macb->rx_ring = dma_alloc_coherent(RX_RING_BYTES);
+	macb->tx_ring = dma_alloc_coherent(TX_RING_BYTES);
 
 	macb->regs = dev_request_mem_region(dev, 0);
 
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 4/7] macb: enable Tramsmit and Receive at open
  2013-02-08  9:18 ` [PATCH 1/7] macb: call macb_init at probe explecitly Jean-Christophe PLAGNIOL-VILLARD
  2013-02-08  9:18   ` [PATCH 2/7] macb: sync remaining define with linux Jean-Christophe PLAGNIOL-VILLARD
  2013-02-08  9:18   ` [PATCH 3/7] macb: use the macro as in linux for tx/rx buffer ring size Jean-Christophe PLAGNIOL-VILLARD
@ 2013-02-08  9:18   ` Jean-Christophe PLAGNIOL-VILLARD
  2013-02-08  9:18   ` [PATCH 5/7] macb: reset the IP at init Jean-Christophe PLAGNIOL-VILLARD
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-02-08  9:18 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre

Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/net/macb.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 962a889..3026507 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -214,6 +214,9 @@ static int macb_open(struct eth_device *edev)
 
 	dev_dbg(macb->dev, "%s\n", __func__);
 
+	/* Enable TX and RX */
+	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE));
+
 	/* Obtain the PHY's address/id */
 	return phy_device_connect(edev, &macb->miibus, macb->phy_addr,
 			       macb_adjust_link, macb->phy_flags,
@@ -259,8 +262,6 @@ static void macb_init(struct macb_device *macb)
 #endif
 	macb_writel(macb, USRIO, val);
 
-	/* Enable TX and RX */
-	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE));
 }
 
 static void macb_halt(struct eth_device *edev)
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 5/7] macb: reset the IP at init
  2013-02-08  9:18 ` [PATCH 1/7] macb: call macb_init at probe explecitly Jean-Christophe PLAGNIOL-VILLARD
                     ` (2 preceding siblings ...)
  2013-02-08  9:18   ` [PATCH 4/7] macb: enable Tramsmit and Receive at open Jean-Christophe PLAGNIOL-VILLARD
@ 2013-02-08  9:18   ` Jean-Christophe PLAGNIOL-VILLARD
  2013-02-08  9:18   ` [PATCH 6/7] macb: fix tx ring size Jean-Christophe PLAGNIOL-VILLARD
  2013-02-08  9:18   ` [PATCH 7/7] macb: add cadence Gigabit GEM support Jean-Christophe PLAGNIOL-VILLARD
  5 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-02-08  9:18 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre

Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/net/macb.c |   23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 3026507..d6b60aa 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -374,6 +374,23 @@ static int macb_set_ethaddr(struct eth_device *edev, unsigned char *adr)
 	return 0;
 }
 
+static void macb_reset_hw(struct macb_device *bp)
+{
+	/* Disable RX and TX forcefully */
+	macb_writel(bp, NCR, 0);
+
+	/* Clear the stats registers (XXX: Update stats first?) */
+	macb_writel(bp, NCR, MACB_BIT(CLRSTAT));
+
+	/* Clear all status flags */
+	macb_writel(bp, TSR, -1);
+	macb_writel(bp, RSR, -1);
+
+	/* Disable all interrupts */
+	macb_writel(bp, IDR, -1);
+	macb_readl(bp, ISR);
+}
+
 static int macb_probe(struct device_d *dev)
 {
 	struct eth_device *edev;
@@ -433,6 +450,9 @@ static int macb_probe(struct device_d *dev)
 	}
 
 	clk_enable(pclk);
+
+	macb_reset_hw(macb);
+
 	macb_hz = clk_get_rate(pclk);
 	if (macb_hz < 20000000)
 		ncfgr = MACB_BF(CLK, MACB_CLK_DIV8);
@@ -443,6 +463,9 @@ static int macb_probe(struct device_d *dev)
 	else
 		ncfgr = MACB_BF(CLK, MACB_CLK_DIV64);
 
+
+	ncfgr |= MACB_BIT(PAE);		/* PAuse Enable */
+	ncfgr |= MACB_BIT(DRFCS);	/* Discard Rx FCS */
 	macb_writel(macb, NCFGR, ncfgr);
 
 	macb_init(macb);
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 6/7] macb: fix tx ring size
  2013-02-08  9:18 ` [PATCH 1/7] macb: call macb_init at probe explecitly Jean-Christophe PLAGNIOL-VILLARD
                     ` (3 preceding siblings ...)
  2013-02-08  9:18   ` [PATCH 5/7] macb: reset the IP at init Jean-Christophe PLAGNIOL-VILLARD
@ 2013-02-08  9:18   ` Jean-Christophe PLAGNIOL-VILLARD
  2013-02-08 12:20     ` Alexander Aring
  2013-02-11 16:33     ` Sascha Hauer
  2013-02-08  9:18   ` [PATCH 7/7] macb: add cadence Gigabit GEM support Jean-Christophe PLAGNIOL-VILLARD
  5 siblings, 2 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-02-08  9:18 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre

the mininal tx ring size is 2 as if one we wrap on the same descriptor
and can cause IP lock on GEM (gigabit version) this is always the case

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/net/macb.c |   50 ++++++++++++++++++++++++++++++++++----------------
 1 file changed, 34 insertions(+), 16 deletions(-)

diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index d6b60aa..3a65af7 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -53,15 +53,17 @@
 
 #define MACB_RX_BUFFER_SIZE	128
 #define RX_BUFFER_MULTIPLE	64  /* bytes */
-#define RX_RING_SIZE		32 /* must be power of 2 */
-#define RX_RING_BYTES		(sizeof(struct macb_dma_desc) * RX_RING_SIZE)
+#define RX_NB_PACKET		10
+#define TX_RING_SIZE		2 /* must be power of 2 */
 
-#define TX_RING_BYTES		(sizeof(struct macb_dma_desc))
+#define RX_RING_BYTES(bp)	(sizeof(struct macb_dma_desc) * bp->rx_ring_size)
+#define TX_RING_BYTES		(sizeof(struct macb_dma_desc) * TX_RING_SIZE)
 
 struct macb_device {
 	void			__iomem *regs;
 
 	unsigned int		rx_tail;
+	unsigned int		tx_head;
 	unsigned int		tx_tail;
 
 	void			*rx_buffer;
@@ -86,23 +88,36 @@ static int macb_send(struct eth_device *edev, void *packet,
 {
 	struct macb_device *macb = edev->priv;
 	unsigned long ctrl;
-	int ret;
-
-	dev_dbg(macb->dev, "%s\n", __func__);
+	int ret = 0;
+	uint64_t start;
+	unsigned int tx_head = macb->tx_head;
 
 	ctrl = MACB_BF(TX_FRMLEN, length);
-	ctrl |= MACB_BIT(TX_LAST) | MACB_BIT(TX_WRAP);
+	ctrl |= MACB_BIT(TX_LAST);
 
-	macb->tx_ring[0].ctrl = ctrl;
-	macb->tx_ring[0].addr = (ulong)packet;
+	if (tx_head == (TX_RING_SIZE - 1)) {
+		ctrl |= MACB_BIT(TX_WRAP);
+		macb->tx_head = 0;
+	} else {
+		macb->tx_head++;
+	}
+
+	macb->tx_ring[tx_head].ctrl = ctrl;
+	macb->tx_ring[tx_head].addr = (ulong)packet;
 	barrier();
 	dma_flush_range((ulong) packet, (ulong)packet + length);
 	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
 
-	ret = wait_on_timeout(100 * MSECOND,
-		!(macb->tx_ring[0].ctrl & MACB_BIT(TX_USED)));
-
-	ctrl = macb->tx_ring[0].ctrl;
+	start = get_time_ns();
+	ret = -ETIMEDOUT;
+	do {
+		barrier();
+		ctrl = macb->tx_ring[0].ctrl;
+		if (ctrl & MACB_BIT(TX_USED)) {
+			ret = 0;
+			break;
+		}
+	} while (!is_timeout(start, 100 * MSECOND));
 
 	if (ctrl & MACB_BIT(TX_UNDERRUN))
 		dev_err(macb->dev, "TX underrun\n");
@@ -244,10 +259,13 @@ static void macb_init(struct macb_device *macb)
 	}
 	macb->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
 
-	macb->tx_ring[0].addr = 0;
-	macb->tx_ring[0].ctrl = MACB_BIT(TX_USED) | MACB_BIT(TX_WRAP);
+	for (i = 0; i < TX_RING_SIZE; i++) {
+		macb->tx_ring[i].addr = 0;
+		macb->tx_ring[i].ctrl = MACB_BIT(TX_USED);
+	}
+	macb->tx_ring[TX_RING_SIZE - 1].addr |= MACB_BIT(TX_WRAP);
 
-	macb->rx_tail = macb->tx_tail = 0;
+	macb->rx_tail = macb->tx_head = macb->tx_tail = 0;
 
 	macb_writel(macb, RBQP, (ulong)macb->rx_ring);
 	macb_writel(macb, TBQP, (ulong)macb->tx_ring);
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 7/7] macb: add cadence Gigabit GEM support
  2013-02-08  9:18 ` [PATCH 1/7] macb: call macb_init at probe explecitly Jean-Christophe PLAGNIOL-VILLARD
                     ` (4 preceding siblings ...)
  2013-02-08  9:18   ` [PATCH 6/7] macb: fix tx ring size Jean-Christophe PLAGNIOL-VILLARD
@ 2013-02-08  9:18   ` Jean-Christophe PLAGNIOL-VILLARD
  5 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-02-08  9:18 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre

based on the kernel code
detect it via IP version

In the GEM we can use a full packet buffer for receive but the buffer size
need to be 64bit size aligned.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/net/macb.c |  246 +++++++++++++++++++++++++++++++++++++++++++---------
 drivers/net/macb.h |  109 ++++++++++++++++++++++-
 2 files changed, 315 insertions(+), 40 deletions(-)

diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 3a65af7..0cfad05 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -71,8 +71,12 @@ struct macb_device {
 	struct macb_dma_desc	*rx_ring;
 	struct macb_dma_desc	*tx_ring;
 
+	int			rx_buffer_size;
+	int			rx_ring_size;
+
 	int			phy_addr;
 
+	struct clk		*pclk;
 	const struct device_d	*dev;
 	struct eth_device	netdev;
 
@@ -81,8 +85,20 @@ struct macb_device {
 	struct mii_bus	miibus;
 
 	unsigned int		phy_flags;
+
+	bool			is_gem;
 };
 
+static inline bool macb_is_gem(struct macb_device *macb)
+{
+	return macb->is_gem;
+}
+
+static inline bool read_is_gem(struct macb_device *macb)
+{
+	return MACB_BFEXT(IDNUM, macb_readl(macb, MID)) == 0x2;
+}
+
 static int macb_send(struct eth_device *edev, void *packet,
 		     int length)
 {
@@ -140,7 +156,7 @@ static void reclaim_rx_buffers(struct macb_device *macb,
 	while (i > new_tail) {
 		macb->rx_ring[i].addr &= ~MACB_BIT(RX_USED);
 		i++;
-		if (i > RX_RING_SIZE)
+		if (i > macb->rx_ring_size)
 			i = 0;
 	}
 
@@ -153,6 +169,37 @@ static void reclaim_rx_buffers(struct macb_device *macb,
 	macb->rx_tail = new_tail;
 }
 
+static int gem_recv(struct eth_device *edev)
+{
+	struct macb_device *macb = edev->priv;
+	unsigned int rx_tail = macb->rx_tail;
+	void *buffer;
+	int length;
+	u32 status;
+
+	dev_dbg(macb->dev, "%s\n", __func__);
+
+	for (;;) {
+		barrier();
+		if (!(macb->rx_ring[rx_tail].addr & MACB_BIT(RX_USED)))
+			return -1;
+
+		barrier();
+		status = macb->rx_ring[rx_tail].ctrl;
+		length = MACB_BFEXT(RX_FRMLEN, status);
+		if (status & MACB_BIT(RX_SOF)) {
+			buffer = macb->rx_buffer + macb->rx_buffer_size * macb->rx_tail;
+			net_receive(buffer, length);
+			macb->rx_ring[rx_tail].ctrl &= ~MACB_BIT(RX_USED);
+			barrier();
+		}
+		rx_tail++;
+		macb->rx_tail++;
+	}
+
+	return 0;
+}
+
 static int macb_recv(struct eth_device *edev)
 {
 	struct macb_device *macb = edev->priv;
@@ -176,12 +223,12 @@ static int macb_recv(struct eth_device *edev)
 		}
 
 		if (status & MACB_BIT(RX_EOF)) {
-			buffer = macb->rx_buffer + MACB_RX_BUFFER_SIZE * macb->rx_tail;
+			buffer = macb->rx_buffer + macb->rx_buffer_size * macb->rx_tail;
 			length = MACB_BFEXT(RX_FRMLEN, status);
 			if (wrapped) {
 				unsigned int headlen, taillen;
 
-				headlen = MACB_RX_BUFFER_SIZE * (RX_RING_SIZE
+				headlen = macb->rx_buffer_size * (macb->rx_ring_size
 						 - macb->rx_tail);
 				taillen = length - headlen;
 				memcpy((void *)NetRxPackets[0],
@@ -192,11 +239,11 @@ static int macb_recv(struct eth_device *edev)
 			}
 
 			net_receive(buffer, length);
-			if (++rx_tail >= RX_RING_SIZE)
+			if (++rx_tail >= macb->rx_ring_size)
 				rx_tail = 0;
 			reclaim_rx_buffers(macb, rx_tail);
 		} else {
-			if (++rx_tail >= RX_RING_SIZE) {
+			if (++rx_tail >= macb->rx_ring_size) {
 				wrapped = 1;
 				rx_tail = 0;
 			}
@@ -214,13 +261,17 @@ static void macb_adjust_link(struct eth_device *edev)
 
 	reg = macb_readl(macb, NCFGR);
 	reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
+	if (macb_is_gem(macb))
+		reg &= ~GEM_BIT(GBE);
 
 	if (edev->phydev->duplex)
 		reg |= MACB_BIT(FD);
 	if (edev->phydev->speed == SPEED_100)
 		reg |= MACB_BIT(SPD);
+	if (edev->phydev->speed == SPEED_1000)
+		reg |= GEM_BIT(GBE);
 
-	macb_writel(macb, NCFGR, reg);
+	macb_or_gem_writel(macb, NCFGR, reg);
 }
 
 static int macb_open(struct eth_device *edev)
@@ -238,6 +289,29 @@ static int macb_open(struct eth_device *edev)
 			       macb->interface);
 }
 
+/*
+ * Configure the receive DMA engine
+ * - use the correct receive buffer size
+ * - set the possibility to use INCR16 bursts
+ *   (if not supported by FIFO, it will fallback to default)
+ * - set both rx/tx packet buffers to full memory size
+ * - set discard rx packets if no DMA resource
+ * These are configurable parameters for GEM.
+ */
+static void macb_configure_dma(struct macb_device *bp)
+{
+	u32 dmacfg;
+
+	if (macb_is_gem(bp)) {
+		dmacfg = gem_readl(bp, DMACFG) & ~GEM_BF(RXBS, -1L);
+		dmacfg |= GEM_BF(RXBS, bp->rx_buffer_size / RX_BUFFER_MULTIPLE);
+		dmacfg |= GEM_BF(FBLDO, 16);
+		dmacfg |= GEM_BIT(TXPBMS) | GEM_BF(RXBMS, -1L);
+		dmacfg |= GEM_BIT(DDRP);
+		gem_writel(bp, DMACFG, dmacfg);
+	}
+}
+
 static void macb_init(struct macb_device *macb)
 {
 	unsigned long paddr, val = 0;
@@ -252,12 +326,12 @@ static void macb_init(struct macb_device *macb)
 
 	/* initialize DMA descriptors */
 	paddr = (ulong)macb->rx_buffer;
-	for (i = 0; i < RX_RING_SIZE; i++) {
+	for (i = 0; i < macb->rx_ring_size; i++) {
 		macb->rx_ring[i].addr = paddr;
 		macb->rx_ring[i].ctrl = 0;
-		paddr += MACB_RX_BUFFER_SIZE;
+		paddr += macb->rx_buffer_size;
 	}
-	macb->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
+	macb->rx_ring[macb->rx_ring_size - 1].addr |= MACB_BIT(RX_WRAP);
 
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		macb->tx_ring[i].addr = 0;
@@ -267,18 +341,29 @@ static void macb_init(struct macb_device *macb)
 
 	macb->rx_tail = macb->tx_head = macb->tx_tail = 0;
 
+	macb_configure_dma(macb);
+
 	macb_writel(macb, RBQP, (ulong)macb->rx_ring);
 	macb_writel(macb, TBQP, (ulong)macb->tx_ring);
 
-	if (macb->interface == PHY_INTERFACE_MODE_RMII)
-		val |= MACB_BIT(RMII);
-	else
-		val &= ~MACB_BIT(RMII);
+	switch(macb->interface) {
+	case PHY_INTERFACE_MODE_RGMII:
+		val = GEM_BIT(RGMII);
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		if (IS_ENABLED(CONFIG_ARCH_AT91))
+			val = MACB_BIT(RMII) | MACB_BIT(CLKEN);
+		else
+			val = 0;
+		break;
+	default:
+		if (IS_ENABLED(CONFIG_ARCH_AT91))
+			val = MACB_BIT(CLKEN);
+		else
+			val = MACB_BIT(MII);
+	}
 
-#if defined(CONFIG_ARCH_AT91)
-	val |= MACB_BIT(CLKEN);
-#endif
-	macb_writel(macb, USRIO, val);
+	macb_or_gem_writel(macb, USRIO, val);
 
 }
 
@@ -386,12 +471,75 @@ static int macb_set_ethaddr(struct eth_device *edev, unsigned char *adr)
 	dev_dbg(macb->dev, "%s\n", __func__);
 
 	/* set hardware address */
-	macb_writel(macb, SA1B, adr[0] | adr[1] << 8 | adr[2] << 16 | adr[3] << 24);
-	macb_writel(macb, SA1T, adr[4] | adr[5] << 8);
+	macb_or_gem_writel(macb, SA1B, adr[0] | adr[1] << 8 | adr[2] << 16 | adr[3] << 24);
+	macb_or_gem_writel(macb, SA1T, adr[4] | adr[5] << 8);
 
 	return 0;
 }
 
+static u32 gem_mdc_clk_div(struct macb_device *bp)
+{
+	u32 config;
+	unsigned long pclk_hz = clk_get_rate(bp->pclk);
+
+	if (pclk_hz <= 20000000)
+		config = GEM_BF(CLK, GEM_CLK_DIV8);
+	else if (pclk_hz <= 40000000)
+		config = GEM_BF(CLK, GEM_CLK_DIV16);
+	else if (pclk_hz <= 80000000)
+		config = GEM_BF(CLK, GEM_CLK_DIV32);
+	else if (pclk_hz <= 120000000)
+		config = GEM_BF(CLK, GEM_CLK_DIV48);
+	else if (pclk_hz <= 160000000)
+		config = GEM_BF(CLK, GEM_CLK_DIV64);
+	else
+		config = GEM_BF(CLK, GEM_CLK_DIV96);
+
+	return config;
+}
+
+static u32 macb_mdc_clk_div(struct macb_device *bp)
+{
+	u32 config;
+	unsigned long pclk_hz;
+
+	if (macb_is_gem(bp))
+		return gem_mdc_clk_div(bp);
+
+	pclk_hz = clk_get_rate(bp->pclk);
+	if (pclk_hz <= 20000000)
+		config = MACB_BF(CLK, MACB_CLK_DIV8);
+	else if (pclk_hz <= 40000000)
+		config = MACB_BF(CLK, MACB_CLK_DIV16);
+	else if (pclk_hz <= 80000000)
+		config = MACB_BF(CLK, MACB_CLK_DIV32);
+	else
+		config = MACB_BF(CLK, MACB_CLK_DIV64);
+
+	return config;
+}
+
+/*
+ * Get the DMA bus width field of the network configuration register that we
+ * should program.  We find the width from decoding the design configuration
+ * register to find the maximum supported data bus width.
+ */
+static u32 macb_dbw(struct macb_device *bp)
+{
+	if (!macb_is_gem(bp))
+		return 0;
+
+	switch (GEM_BFEXT(DBWDEF, gem_readl(bp, DCFG1))) {
+	case 4:
+		return GEM_BF(DBW, GEM_DBW128);
+	case 2:
+		return GEM_BF(DBW, GEM_DBW64);
+	case 1:
+	default:
+		return GEM_BF(DBW, GEM_DBW32);
+	}
+}
+
 static void macb_reset_hw(struct macb_device *bp)
 {
 	/* Disable RX and TX forcefully */
@@ -409,14 +557,35 @@ static void macb_reset_hw(struct macb_device *bp)
 	macb_readl(bp, ISR);
 }
 
+static void macb_init_rx_buffer_size(struct macb_device *bp, size_t size)
+{
+	if (!macb_is_gem(bp)) {
+		bp->rx_buffer_size = MACB_RX_BUFFER_SIZE;
+		bp->rx_ring_size = roundup(RX_NB_PACKET * PKTSIZE / MACB_RX_BUFFER_SIZE, 2);
+	} else {
+		bp->rx_buffer_size = size;
+		bp->rx_ring_size = RX_NB_PACKET;
+
+		if (bp->rx_buffer_size % RX_BUFFER_MULTIPLE) {
+			dev_dbg(bp->dev,
+				    "RX buffer must be multiple of %d bytes, expanding\n",
+				    RX_BUFFER_MULTIPLE);
+			bp->rx_buffer_size =
+				roundup(bp->rx_buffer_size, RX_BUFFER_MULTIPLE);
+		}
+		bp->rx_buffer = dma_alloc_coherent(bp->rx_buffer_size * bp->rx_ring_size);
+	}
+
+	dev_dbg(bp->dev, "[%d] rx_buffer_size [%d]\n",
+		   size, bp->rx_buffer_size);
+}
+
 static int macb_probe(struct device_d *dev)
 {
 	struct eth_device *edev;
 	struct macb_device *macb;
-	unsigned long macb_hz;
 	u32 ncfgr;
 	struct at91_ether_platform_data *pdata;
-	struct clk *pclk;
 
 	if (!dev->platform_data) {
 		dev_err(dev, "macb: no platform_data\n");
@@ -432,7 +601,6 @@ static int macb_probe(struct device_d *dev)
 
 	edev->open = macb_open;
 	edev->send = macb_send;
-	edev->recv = macb_recv;
 	edev->halt = macb_halt;
 	edev->get_ethaddr = pdata->get_ethaddr ? pdata->get_ethaddr : macb_get_ethaddr;
 	edev->set_ethaddr = macb_set_ethaddr;
@@ -451,8 +619,9 @@ static int macb_probe(struct device_d *dev)
 
 	macb->phy_flags = pdata->phy_flags;
 
-	macb->rx_buffer = dma_alloc_coherent(MACB_RX_BUFFER_SIZE * RX_RING_SIZE);
-	macb->rx_ring = dma_alloc_coherent(RX_RING_BYTES);
+	macb_init_rx_buffer_size(macb, PKTSIZE);
+	macb->rx_buffer = dma_alloc_coherent(macb->rx_buffer_size * macb->rx_ring_size);
+	macb->rx_ring = dma_alloc_coherent(RX_RING_BYTES(macb));
 	macb->tx_ring = dma_alloc_coherent(TX_RING_BYTES);
 
 	macb->regs = dev_request_mem_region(dev, 0);
@@ -461,29 +630,25 @@ static int macb_probe(struct device_d *dev)
 	 * Do some basic initialization so that we at least can talk
 	 * to the PHY
 	 */
-	pclk = clk_get(dev, "macb_clk");
-	if (IS_ERR(pclk)) {
+	macb->pclk = clk_get(dev, "macb_clk");
+	if (IS_ERR(macb->pclk)) {
 		dev_err(dev, "no macb_clk\n");
-		return PTR_ERR(pclk);
+		return PTR_ERR(macb->pclk);
 	}
 
-	clk_enable(pclk);
-
-	macb_reset_hw(macb);
+	clk_enable(macb->pclk);
 
-	macb_hz = clk_get_rate(pclk);
-	if (macb_hz < 20000000)
-		ncfgr = MACB_BF(CLK, MACB_CLK_DIV8);
-	else if (macb_hz < 40000000)
-		ncfgr = MACB_BF(CLK, MACB_CLK_DIV16);
-	else if (macb_hz < 80000000)
-		ncfgr = MACB_BF(CLK, MACB_CLK_DIV32);
+	if (macb_is_gem(macb))
+		edev->recv = gem_recv;
 	else
-		ncfgr = MACB_BF(CLK, MACB_CLK_DIV64);
-
+		edev->recv = macb_recv;
+	macb->is_gem = read_is_gem(macb);
 
+	macb_reset_hw(macb);
+	ncfgr = macb_mdc_clk_div(macb);
 	ncfgr |= MACB_BIT(PAE);		/* PAuse Enable */
 	ncfgr |= MACB_BIT(DRFCS);	/* Discard Rx FCS */
+	ncfgr |= macb_dbw(macb);
 	macb_writel(macb, NCFGR, ncfgr);
 
 	macb_init(macb);
@@ -491,6 +656,9 @@ static int macb_probe(struct device_d *dev)
 	mdiobus_register(&macb->miibus);
 	eth_register(edev);
 
+	dev_info(dev, "Cadence %s at 0x%p\n",
+		macb_is_gem(macb) ? "GEM" : "MACB", macb->regs);
+
 	return 0;
 }
 
diff --git a/drivers/net/macb.h b/drivers/net/macb.h
index 8dd5a87..cadd561 100644
--- a/drivers/net/macb.h
+++ b/drivers/net/macb.h
@@ -67,6 +67,24 @@
 #define MACB_TPQ				0x00bc
 #define MACB_USRIO				0x00c0
 #define MACB_WOL				0x00c4
+#define MACB_MID				0x00fc
+
+/* GEM register offsets. */
+#define GEM_NCFGR				0x0004
+#define GEM_USRIO				0x000c
+#define GEM_DMACFG				0x0010
+#define GEM_HRB					0x0080
+#define GEM_HRT					0x0084
+#define GEM_SA1B				0x0088
+#define GEM_SA1T				0x008C
+#define GEM_OTX					0x0100
+#define GEM_DCFG1				0x0280
+#define GEM_DCFG2				0x0284
+#define GEM_DCFG3				0x0288
+#define GEM_DCFG4				0x028c
+#define GEM_DCFG5				0x0290
+#define GEM_DCFG6				0x0294
+#define GEM_DCFG7				0x0298
 
 /* Bitfields in NCR */
 #define MACB_LB_OFFSET				0
@@ -134,6 +152,34 @@
 #define MACB_IRXFCS_OFFSET			19
 #define MACB_IRXFCS_SIZE			1
 
+/* GEM specific NCFGR bitfields. */
+#define GEM_GBE_OFFSET				10
+#define GEM_GBE_SIZE				1
+#define GEM_CLK_OFFSET				18
+#define GEM_CLK_SIZE				3
+#define GEM_DBW_OFFSET				21
+#define GEM_DBW_SIZE				2
+
+/* Constants for data bus width. */
+#define GEM_DBW32				0
+#define GEM_DBW64				1
+#define GEM_DBW128				2
+
+/* Bitfields in DMACFG. */
+#define GEM_FBLDO_OFFSET			0
+#define GEM_FBLDO_SIZE				5
+#define GEM_RXBMS_OFFSET			8
+#define GEM_RXBMS_SIZE				2
+#define GEM_TXPBMS_OFFSET			10
+#define GEM_TXPBMS_SIZE				1
+#define GEM_TXCOEN_OFFSET			11
+#define GEM_TXCOEN_SIZE				1
+#define GEM_RXBS_OFFSET				16
+#define GEM_RXBS_SIZE				8
+#define GEM_DDRP_OFFSET				24
+#define GEM_DDRP_SIZE				1
+
+
 /* Bitfields in NSR */
 #define MACB_NSR_LINK_OFFSET			0
 #define MACB_NSR_LINK_SIZE			1
@@ -208,7 +254,7 @@
 #define MACB_SOF_OFFSET				30
 #define MACB_SOF_SIZE				2
 
-/* Bitfields in USRIO */
+/* Bitfields in USRIO (AVR32) */
 #define MACB_MII_OFFSET				0
 #define MACB_MII_SIZE				1
 #define MACB_EAM_OFFSET				1
@@ -221,6 +267,8 @@
 /* Bitfields in USRIO (AT91) */
 #define MACB_RMII_OFFSET			0
 #define MACB_RMII_SIZE				1
+#define GEM_RGMII_OFFSET			0	/* GEM gigabit mode */
+#define GEM_RGMII_SIZE				1
 #define MACB_CLKEN_OFFSET			1
 #define MACB_CLKEN_SIZE				1
 
@@ -236,12 +284,30 @@
 #define MACB_WOL_MTI_OFFSET			19
 #define MACB_WOL_MTI_SIZE			1
 
+/* Bitfields in MID */
+#define MACB_IDNUM_OFFSET			16
+#define MACB_IDNUM_SIZE				16
+#define MACB_REV_OFFSET				0
+#define MACB_REV_SIZE				16
+
+/* Bitfields in DCFG1. */
+#define GEM_DBWDEF_OFFSET			25
+#define GEM_DBWDEF_SIZE				3
+
 /* Constants for CLK */
 #define MACB_CLK_DIV8				0
 #define MACB_CLK_DIV16				1
 #define MACB_CLK_DIV32				2
 #define MACB_CLK_DIV64				3
 
+/* GEM specific constants for CLK. */
+#define GEM_CLK_DIV8				0
+#define GEM_CLK_DIV16				1
+#define GEM_CLK_DIV32				2
+#define GEM_CLK_DIV48				3
+#define GEM_CLK_DIV64				4
+#define GEM_CLK_DIV96				5
+
 /* Constants for MAN register */
 #define MACB_MAN_SOF				1
 #define MACB_MAN_WRITE				1
@@ -262,11 +328,52 @@
 		    << MACB_##name##_OFFSET))		\
 	 | MACB_BF(name,value))
 
+#define GEM_BIT(name)					\
+	(1 << GEM_##name##_OFFSET)
+#define GEM_BF(name, value)				\
+	(((value) & ((1 << GEM_##name##_SIZE) - 1))	\
+	 << GEM_##name##_OFFSET)
+#define GEM_BFEXT(name, value)\
+	(((value) >> GEM_##name##_OFFSET)		\
+	 & ((1 << GEM_##name##_SIZE) - 1))
+#define GEM_BFINS(name, value, old)			\
+	(((old) & ~(((1 << GEM_##name##_SIZE) - 1)	\
+		    << GEM_##name##_OFFSET))		\
+	 | GEM_BF(name, value))
+
 /* Register access macros */
 #define macb_readl(port,reg)				\
 	__raw_readl((port)->regs + MACB_##reg)
 #define macb_writel(port,reg,value)			\
 	__raw_writel((value), (port)->regs + MACB_##reg)
+#define gem_readl(port, reg)				\
+	__raw_readl((port)->regs + GEM_##reg)
+#define gem_writel(port, reg, value)			\
+	__raw_writel((value), (port)->regs + GEM_##reg)
+
+/*
+ * Conditional GEM/MACB macros.  These perform the operation to the correct
+ * register dependent on whether the device is a GEM or a MACB.  For registers
+ * and bitfields that are common across both devices, use macb_{read,write}l
+ * to avoid the cost of the conditional.
+ */
+#define macb_or_gem_writel(__bp, __reg, __value) \
+	({ \
+		if (macb_is_gem((__bp))) \
+			gem_writel((__bp), __reg, __value); \
+		else \
+			macb_writel((__bp), __reg, __value); \
+	})
+
+#define macb_or_gem_readl(__bp, __reg) \
+	({ \
+		u32 __v; \
+		if (macb_is_gem((__bp))) \
+			__v = gem_readl((__bp), __reg); \
+		else \
+			__v = macb_readl((__bp), __reg); \
+		__v; \
+	})
 
 /**
  * struct macb_dma_desc - Hardware DMA descriptor
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [For master PATCH 0/7] macb: more fixes + gem (gigabit support)
  2013-02-08  9:07 [For master PATCH 0/7] macb: more fixes + gem (gigabit support) Jean-Christophe PLAGNIOL-VILLARD
  2013-02-08  9:18 ` [PATCH 1/7] macb: call macb_init at probe explecitly Jean-Christophe PLAGNIOL-VILLARD
@ 2013-02-08 10:24 ` Nicolas Ferre
  2013-02-11  8:35 ` Sascha Hauer
  2013-02-11 16:57 ` [PATCH 6/7 v2] macb: fix tx ring size Jean-Christophe PLAGNIOL-VILLARD
  3 siblings, 0 replies; 16+ messages in thread
From: Nicolas Ferre @ 2013-02-08 10:24 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On 02/08/2013 10:07 AM, Jean-Christophe PLAGNIOL-VILLARD :
> HI,
> 
> 	This patch serie fixe more issue on the macb and add the GEM support
> 	(gigabit support) present on Atmel sama5d3x as example
> 
> 	The IP version is detected as in linux
> 
> 	we now share more code with the kernel and will help to maintain the
> 	driver
> 
> 	tesed on at91 macb & gem


You can add to the whole patch series:

Tested-by: Nicolas Ferre <nicolas.ferre@atmel.com>


> 
> The following changes since commit 15c5fa0467b20c05e9ebea36e049764054a7e308:
> 
>   macb: drop non used define (2013-02-08 16:55:16 +0800)
> 
> are available in the git repository at:
> 
>   git://git.jcrosoft.org/barebox.git delivery/macb
> 
> for you to fetch changes up to b7058953abdd014b9626b22d868fb29c1c563514:
> 
>   macb: add cadence Gigabit GEM support (2013-02-08 16:55:41 +0800)
> 
> ----------------------------------------------------------------
> Jean-Christophe PLAGNIOL-VILLARD (7):
>       macb: call macb_init at probe explecitly
>       macb: sync remaining define with linux
>       macb: use the macro as in linux for tx/rx buffer ring size
>       macb: enable Tramsmit and Receive at open
>       macb: reset the IP at init
>       macb: fix tx ring size
>       macb: add cadence Gigabit GEM support
> 
>  drivers/net/macb.c |  394 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------
>  drivers/net/macb.h |  179 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 466 insertions(+), 107 deletions(-)
> 
> Best Regards,
> J.
> 
> 


-- 
Nicolas Ferre

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 6/7] macb: fix tx ring size
  2013-02-08  9:18   ` [PATCH 6/7] macb: fix tx ring size Jean-Christophe PLAGNIOL-VILLARD
@ 2013-02-08 12:20     ` Alexander Aring
  2013-02-08 13:36       ` Jean-Christophe PLAGNIOL-VILLARD
  2013-02-11 16:33     ` Sascha Hauer
  1 sibling, 1 reply; 16+ messages in thread
From: Alexander Aring @ 2013-02-08 12:20 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox, Nicolas Ferre

Hi,

On Fri, Feb 08, 2013 at 10:18:49AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> the mininal tx ring size is 2 as if one we wrap on the same descriptor
> and can cause IP lock on GEM (gigabit version) this is always the case
> 
> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> ---
>  drivers/net/macb.c |   50 ++++++++++++++++++++++++++++++++++----------------
>  1 file changed, 34 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/net/macb.c b/drivers/net/macb.c
> index d6b60aa..3a65af7 100644
> --- a/drivers/net/macb.c
> +++ b/drivers/net/macb.c
> @@ -53,15 +53,17 @@
>  
>  #define MACB_RX_BUFFER_SIZE	128
>  #define RX_BUFFER_MULTIPLE	64  /* bytes */
> -#define RX_RING_SIZE		32 /* must be power of 2 */
> -#define RX_RING_BYTES		(sizeof(struct macb_dma_desc) * RX_RING_SIZE)
> +#define RX_NB_PACKET		10
> +#define TX_RING_SIZE		2 /* must be power of 2 */
>  
> -#define TX_RING_BYTES		(sizeof(struct macb_dma_desc))
> +#define RX_RING_BYTES(bp)	(sizeof(struct macb_dma_desc) * bp->rx_ring_size)
> +#define TX_RING_BYTES		(sizeof(struct macb_dma_desc) * TX_RING_SIZE)
>  
>  struct macb_device {
>  	void			__iomem *regs;
>  
>  	unsigned int		rx_tail;
> +	unsigned int		tx_head;
>  	unsigned int		tx_tail;
>  
>  	void			*rx_buffer;
> @@ -86,23 +88,36 @@ static int macb_send(struct eth_device *edev, void *packet,
>  {
>  	struct macb_device *macb = edev->priv;
>  	unsigned long ctrl;
> -	int ret;
> -
> -	dev_dbg(macb->dev, "%s\n", __func__);
> +	int ret = 0;
> +	uint64_t start;
> +	unsigned int tx_head = macb->tx_head;
>  
>  	ctrl = MACB_BF(TX_FRMLEN, length);
> -	ctrl |= MACB_BIT(TX_LAST) | MACB_BIT(TX_WRAP);
> +	ctrl |= MACB_BIT(TX_LAST);
>  
> -	macb->tx_ring[0].ctrl = ctrl;
> -	macb->tx_ring[0].addr = (ulong)packet;
> +	if (tx_head == (TX_RING_SIZE - 1)) {
> +		ctrl |= MACB_BIT(TX_WRAP);
> +		macb->tx_head = 0;
> +	} else {
> +		macb->tx_head++;
> +	}
> +
> +	macb->tx_ring[tx_head].ctrl = ctrl;
> +	macb->tx_ring[tx_head].addr = (ulong)packet;
>  	barrier();
>  	dma_flush_range((ulong) packet, (ulong)packet + length);
>  	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
>  
> -	ret = wait_on_timeout(100 * MSECOND,
> -		!(macb->tx_ring[0].ctrl & MACB_BIT(TX_USED)));
> -
> -	ctrl = macb->tx_ring[0].ctrl;
> +	start = get_time_ns();
> +	ret = -ETIMEDOUT;

Is this ret ever used?

> +	do {
> +		barrier();
> +		ctrl = macb->tx_ring[0].ctrl;
> +		if (ctrl & MACB_BIT(TX_USED)) {
> +			ret = 0;
> +			break;
> +		}
> +	} while (!is_timeout(start, 100 * MSECOND));
>  
>  	if (ctrl & MACB_BIT(TX_UNDERRUN))
>  		dev_err(macb->dev, "TX underrun\n");
> @@ -244,10 +259,13 @@ static void macb_init(struct macb_device *macb)
>  	}
>  	macb->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
>  
> -	macb->tx_ring[0].addr = 0;
> -	macb->tx_ring[0].ctrl = MACB_BIT(TX_USED) | MACB_BIT(TX_WRAP);
> +	for (i = 0; i < TX_RING_SIZE; i++) {
> +		macb->tx_ring[i].addr = 0;
> +		macb->tx_ring[i].ctrl = MACB_BIT(TX_USED);
> +	}
> +	macb->tx_ring[TX_RING_SIZE - 1].addr |= MACB_BIT(TX_WRAP);
>  
> -	macb->rx_tail = macb->tx_tail = 0;
> +	macb->rx_tail = macb->tx_head = macb->tx_tail = 0;
>  
>  	macb_writel(macb, RBQP, (ulong)macb->rx_ring);
>  	macb_writel(macb, TBQP, (ulong)macb->tx_ring);
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 6/7] macb: fix tx ring size
  2013-02-08 12:20     ` Alexander Aring
@ 2013-02-08 13:36       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-02-08 13:36 UTC (permalink / raw)
  To: Alexander Aring; +Cc: barebox, Nicolas Ferre

On 13:20 Fri 08 Feb     , Alexander Aring wrote:
> Hi,
> 
> On Fri, Feb 08, 2013 at 10:18:49AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > the mininal tx ring size is 2 as if one we wrap on the same descriptor
> > and can cause IP lock on GEM (gigabit version) this is always the case
> > 
> > Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> > Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> > ---
> >  drivers/net/macb.c |   50 ++++++++++++++++++++++++++++++++++----------------
> >  1 file changed, 34 insertions(+), 16 deletions(-)
> > 
> > diff --git a/drivers/net/macb.c b/drivers/net/macb.c
> > index d6b60aa..3a65af7 100644
> > --- a/drivers/net/macb.c
> > +++ b/drivers/net/macb.c
> > @@ -53,15 +53,17 @@
> >  
> >  #define MACB_RX_BUFFER_SIZE	128
> >  #define RX_BUFFER_MULTIPLE	64  /* bytes */
> > -#define RX_RING_SIZE		32 /* must be power of 2 */
> > -#define RX_RING_BYTES		(sizeof(struct macb_dma_desc) * RX_RING_SIZE)
> > +#define RX_NB_PACKET		10
> > +#define TX_RING_SIZE		2 /* must be power of 2 */
> >  
> > -#define TX_RING_BYTES		(sizeof(struct macb_dma_desc))
> > +#define RX_RING_BYTES(bp)	(sizeof(struct macb_dma_desc) * bp->rx_ring_size)
> > +#define TX_RING_BYTES		(sizeof(struct macb_dma_desc) * TX_RING_SIZE)
> >  
> >  struct macb_device {
> >  	void			__iomem *regs;
> >  
> >  	unsigned int		rx_tail;
> > +	unsigned int		tx_head;
> >  	unsigned int		tx_tail;
> >  
> >  	void			*rx_buffer;
> > @@ -86,23 +88,36 @@ static int macb_send(struct eth_device *edev, void *packet,
> >  {
> >  	struct macb_device *macb = edev->priv;
> >  	unsigned long ctrl;
> > -	int ret;
> > -
> > -	dev_dbg(macb->dev, "%s\n", __func__);
> > +	int ret = 0;
> > +	uint64_t start;
> > +	unsigned int tx_head = macb->tx_head;
> >  
> >  	ctrl = MACB_BF(TX_FRMLEN, length);
> > -	ctrl |= MACB_BIT(TX_LAST) | MACB_BIT(TX_WRAP);
> > +	ctrl |= MACB_BIT(TX_LAST);
> >  
> > -	macb->tx_ring[0].ctrl = ctrl;
> > -	macb->tx_ring[0].addr = (ulong)packet;
> > +	if (tx_head == (TX_RING_SIZE - 1)) {
> > +		ctrl |= MACB_BIT(TX_WRAP);
> > +		macb->tx_head = 0;
> > +	} else {
> > +		macb->tx_head++;
> > +	}
> > +
> > +	macb->tx_ring[tx_head].ctrl = ctrl;
> > +	macb->tx_ring[tx_head].addr = (ulong)packet;
> >  	barrier();
> >  	dma_flush_range((ulong) packet, (ulong)packet + length);
> >  	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
> >  
> > -	ret = wait_on_timeout(100 * MSECOND,
> > -		!(macb->tx_ring[0].ctrl & MACB_BIT(TX_USED)));
> > -
> > -	ctrl = macb->tx_ring[0].ctrl;
> > +	start = get_time_ns();
> > +	ret = -ETIMEDOUT;
> 
> Is this ret ever used?
for sure we return it if we timeout

this is the ret of the send

Best Regards,
J.
> 
> > +	do {
> > +		barrier();
> > +		ctrl = macb->tx_ring[0].ctrl;
> > +		if (ctrl & MACB_BIT(TX_USED)) {
> > +			ret = 0;
> > +			break;
> > +		}
> > +	} while (!is_timeout(start, 100 * MSECOND));
> >  
> >  	if (ctrl & MACB_BIT(TX_UNDERRUN))
> >  		dev_err(macb->dev, "TX underrun\n");
> > @@ -244,10 +259,13 @@ static void macb_init(struct macb_device *macb)
> >  	}
> >  	macb->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
> >  
> > -	macb->tx_ring[0].addr = 0;
> > -	macb->tx_ring[0].ctrl = MACB_BIT(TX_USED) | MACB_BIT(TX_WRAP);
> > +	for (i = 0; i < TX_RING_SIZE; i++) {
> > +		macb->tx_ring[i].addr = 0;
> > +		macb->tx_ring[i].ctrl = MACB_BIT(TX_USED);
> > +	}
> > +	macb->tx_ring[TX_RING_SIZE - 1].addr |= MACB_BIT(TX_WRAP);
> >  
> > -	macb->rx_tail = macb->tx_tail = 0;
> > +	macb->rx_tail = macb->tx_head = macb->tx_tail = 0;
> >  
> >  	macb_writel(macb, RBQP, (ulong)macb->rx_ring);
> >  	macb_writel(macb, TBQP, (ulong)macb->tx_ring);
> > -- 
> > 1.7.10.4
> > 
> > 
> > _______________________________________________
> > barebox mailing list
> > barebox@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/barebox

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [For master PATCH 0/7] macb: more fixes + gem (gigabit support)
  2013-02-08  9:07 [For master PATCH 0/7] macb: more fixes + gem (gigabit support) Jean-Christophe PLAGNIOL-VILLARD
  2013-02-08  9:18 ` [PATCH 1/7] macb: call macb_init at probe explecitly Jean-Christophe PLAGNIOL-VILLARD
  2013-02-08 10:24 ` [For master PATCH 0/7] macb: more fixes + gem (gigabit support) Nicolas Ferre
@ 2013-02-11  8:35 ` Sascha Hauer
  2013-02-11 16:57 ` [PATCH 6/7 v2] macb: fix tx ring size Jean-Christophe PLAGNIOL-VILLARD
  3 siblings, 0 replies; 16+ messages in thread
From: Sascha Hauer @ 2013-02-11  8:35 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox, Nicolas Ferre

On Fri, Feb 08, 2013 at 10:07:39AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> HI,
> 
> 	This patch serie fixe more issue on the macb and add the GEM support
> 	(gigabit support) present on Atmel sama5d3x as example
> 
> 	The IP version is detected as in linux
> 
> 	we now share more code with the kernel and will help to maintain the
> 	driver
> 
> 	tesed on at91 macb & gem
> 
> The following changes since commit 15c5fa0467b20c05e9ebea36e049764054a7e308:
> 
>   macb: drop non used define (2013-02-08 16:55:16 +0800)
> 
> are available in the git repository at:
> 
>   git://git.jcrosoft.org/barebox.git delivery/macb

Applied, thanks

Sascha

> 
> for you to fetch changes up to b7058953abdd014b9626b22d868fb29c1c563514:
> 
>   macb: add cadence Gigabit GEM support (2013-02-08 16:55:41 +0800)
> 
> ----------------------------------------------------------------
> Jean-Christophe PLAGNIOL-VILLARD (7):
>       macb: call macb_init at probe explecitly
>       macb: sync remaining define with linux
>       macb: use the macro as in linux for tx/rx buffer ring size
>       macb: enable Tramsmit and Receive at open
>       macb: reset the IP at init
>       macb: fix tx ring size
>       macb: add cadence Gigabit GEM support
> 
>  drivers/net/macb.c |  394 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------
>  drivers/net/macb.h |  179 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 466 insertions(+), 107 deletions(-)
> 
> Best Regards,
> J.
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 6/7] macb: fix tx ring size
  2013-02-08  9:18   ` [PATCH 6/7] macb: fix tx ring size Jean-Christophe PLAGNIOL-VILLARD
  2013-02-08 12:20     ` Alexander Aring
@ 2013-02-11 16:33     ` Sascha Hauer
  2013-02-11 16:52       ` Jean-Christophe PLAGNIOL-VILLARD
  1 sibling, 1 reply; 16+ messages in thread
From: Sascha Hauer @ 2013-02-11 16:33 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox, Nicolas Ferre

On Fri, Feb 08, 2013 at 10:18:49AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> the mininal tx ring size is 2 as if one we wrap on the same descriptor
> and can cause IP lock on GEM (gigabit version) this is always the case
> 
> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> ---
>  drivers/net/macb.c |   50 ++++++++++++++++++++++++++++++++++----------------
>  1 file changed, 34 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/net/macb.c b/drivers/net/macb.c
> index d6b60aa..3a65af7 100644
> --- a/drivers/net/macb.c
> +++ b/drivers/net/macb.c
> @@ -53,15 +53,17 @@
>  
>  #define MACB_RX_BUFFER_SIZE	128
>  #define RX_BUFFER_MULTIPLE	64  /* bytes */
> -#define RX_RING_SIZE		32 /* must be power of 2 */

This removes RX_RING_SIZE...

> @@ -244,10 +259,13 @@ static void macb_init(struct macb_device *macb)
>  	}
>  	macb->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);

But not its users.

Dropped.

Sascha

>  
> -	macb->tx_ring[0].addr = 0;
> -	macb->tx_ring[0].ctrl = MACB_BIT(TX_USED) | MACB_BIT(TX_WRAP);
> +	for (i = 0; i < TX_RING_SIZE; i++) {
> +		macb->tx_ring[i].addr = 0;
> +		macb->tx_ring[i].ctrl = MACB_BIT(TX_USED);
> +	}
> +	macb->tx_ring[TX_RING_SIZE - 1].addr |= MACB_BIT(TX_WRAP);
>  
> -	macb->rx_tail = macb->tx_tail = 0;
> +	macb->rx_tail = macb->tx_head = macb->tx_tail = 0;
>  
>  	macb_writel(macb, RBQP, (ulong)macb->rx_ring);
>  	macb_writel(macb, TBQP, (ulong)macb->tx_ring);
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 6/7] macb: fix tx ring size
  2013-02-11 16:33     ` Sascha Hauer
@ 2013-02-11 16:52       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-02-11 16:52 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox, Nicolas Ferre

On 17:33 Mon 11 Feb     , Sascha Hauer wrote:
> On Fri, Feb 08, 2013 at 10:18:49AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > the mininal tx ring size is 2 as if one we wrap on the same descriptor
> > and can cause IP lock on GEM (gigabit version) this is always the case
> > 
> > Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> > Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> > ---
> >  drivers/net/macb.c |   50 ++++++++++++++++++++++++++++++++++----------------
> >  1 file changed, 34 insertions(+), 16 deletions(-)
> > 
> > diff --git a/drivers/net/macb.c b/drivers/net/macb.c
> > index d6b60aa..3a65af7 100644
> > --- a/drivers/net/macb.c
> > +++ b/drivers/net/macb.c
> > @@ -53,15 +53,17 @@
> >  
> >  #define MACB_RX_BUFFER_SIZE	128
> >  #define RX_BUFFER_MULTIPLE	64  /* bytes */
> > -#define RX_RING_SIZE		32 /* must be power of 2 */
> 
> This removes RX_RING_SIZE...

I miss split the patch with gem

I resend it

Best Regards,
J.

> 
> > @@ -244,10 +259,13 @@ static void macb_init(struct macb_device *macb)
> >  	}
> >  	macb->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
> 
> But not its users.
> 
> Dropped.
> 
> Sascha
> 
> >  
> > -	macb->tx_ring[0].addr = 0;
> > -	macb->tx_ring[0].ctrl = MACB_BIT(TX_USED) | MACB_BIT(TX_WRAP);
> > +	for (i = 0; i < TX_RING_SIZE; i++) {
> > +		macb->tx_ring[i].addr = 0;
> > +		macb->tx_ring[i].ctrl = MACB_BIT(TX_USED);
> > +	}
> > +	macb->tx_ring[TX_RING_SIZE - 1].addr |= MACB_BIT(TX_WRAP);
> >  
> > -	macb->rx_tail = macb->tx_tail = 0;
> > +	macb->rx_tail = macb->tx_head = macb->tx_tail = 0;
> >  
> >  	macb_writel(macb, RBQP, (ulong)macb->rx_ring);
> >  	macb_writel(macb, TBQP, (ulong)macb->tx_ring);
> > -- 
> > 1.7.10.4
> > 
> > 
> > _______________________________________________
> > barebox mailing list
> > barebox@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/barebox
> > 
> 
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 6/7 v2] macb: fix tx ring size
  2013-02-08  9:07 [For master PATCH 0/7] macb: more fixes + gem (gigabit support) Jean-Christophe PLAGNIOL-VILLARD
                   ` (2 preceding siblings ...)
  2013-02-11  8:35 ` Sascha Hauer
@ 2013-02-11 16:57 ` Jean-Christophe PLAGNIOL-VILLARD
  2013-02-11 16:57   ` [PATCH 7/7 v2] macb: add cadence Gigabit GEM support Jean-Christophe PLAGNIOL-VILLARD
  3 siblings, 1 reply; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-02-11 16:57 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre

the mininal tx ring size is 2 as if one we wrap on the same descriptor
and can cause IP lock on GEM (gigabit version) this is always the case

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/net/macb.c |   48 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 33 insertions(+), 15 deletions(-)

diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index d6b60aa..9040e4e 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -54,14 +54,16 @@
 #define MACB_RX_BUFFER_SIZE	128
 #define RX_BUFFER_MULTIPLE	64  /* bytes */
 #define RX_RING_SIZE		32 /* must be power of 2 */
-#define RX_RING_BYTES		(sizeof(struct macb_dma_desc) * RX_RING_SIZE)
+#define TX_RING_SIZE		2 /* must be power of 2 */
 
-#define TX_RING_BYTES		(sizeof(struct macb_dma_desc))
+#define RX_RING_BYTES		(sizeof(struct macb_dma_desc) * RX_RING_SIZE)
+#define TX_RING_BYTES		(sizeof(struct macb_dma_desc) * TX_RING_SIZE)
 
 struct macb_device {
 	void			__iomem *regs;
 
 	unsigned int		rx_tail;
+	unsigned int		tx_head;
 	unsigned int		tx_tail;
 
 	void			*rx_buffer;
@@ -86,23 +88,36 @@ static int macb_send(struct eth_device *edev, void *packet,
 {
 	struct macb_device *macb = edev->priv;
 	unsigned long ctrl;
-	int ret;
-
-	dev_dbg(macb->dev, "%s\n", __func__);
+	int ret = 0;
+	uint64_t start;
+	unsigned int tx_head = macb->tx_head;
 
 	ctrl = MACB_BF(TX_FRMLEN, length);
-	ctrl |= MACB_BIT(TX_LAST) | MACB_BIT(TX_WRAP);
+	ctrl |= MACB_BIT(TX_LAST);
+
+	if (tx_head == (TX_RING_SIZE - 1)) {
+		ctrl |= MACB_BIT(TX_WRAP);
+		macb->tx_head = 0;
+	} else {
+		macb->tx_head++;
+	}
 
-	macb->tx_ring[0].ctrl = ctrl;
-	macb->tx_ring[0].addr = (ulong)packet;
+	macb->tx_ring[tx_head].ctrl = ctrl;
+	macb->tx_ring[tx_head].addr = (ulong)packet;
 	barrier();
 	dma_flush_range((ulong) packet, (ulong)packet + length);
 	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
 
-	ret = wait_on_timeout(100 * MSECOND,
-		!(macb->tx_ring[0].ctrl & MACB_BIT(TX_USED)));
-
-	ctrl = macb->tx_ring[0].ctrl;
+	start = get_time_ns();
+	ret = -ETIMEDOUT;
+	do {
+		barrier();
+		ctrl = macb->tx_ring[0].ctrl;
+		if (ctrl & MACB_BIT(TX_USED)) {
+			ret = 0;
+			break;
+		}
+	} while (!is_timeout(start, 100 * MSECOND));
 
 	if (ctrl & MACB_BIT(TX_UNDERRUN))
 		dev_err(macb->dev, "TX underrun\n");
@@ -244,10 +259,13 @@ static void macb_init(struct macb_device *macb)
 	}
 	macb->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
 
-	macb->tx_ring[0].addr = 0;
-	macb->tx_ring[0].ctrl = MACB_BIT(TX_USED) | MACB_BIT(TX_WRAP);
+	for (i = 0; i < TX_RING_SIZE; i++) {
+		macb->tx_ring[i].addr = 0;
+		macb->tx_ring[i].ctrl = MACB_BIT(TX_USED);
+	}
+	macb->tx_ring[TX_RING_SIZE - 1].addr |= MACB_BIT(TX_WRAP);
 
-	macb->rx_tail = macb->tx_tail = 0;
+	macb->rx_tail = macb->tx_head = macb->tx_tail = 0;
 
 	macb_writel(macb, RBQP, (ulong)macb->rx_ring);
 	macb_writel(macb, TBQP, (ulong)macb->tx_ring);
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 7/7 v2] macb: add cadence Gigabit GEM support
  2013-02-11 16:57 ` [PATCH 6/7 v2] macb: fix tx ring size Jean-Christophe PLAGNIOL-VILLARD
@ 2013-02-11 16:57   ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-02-11 16:57 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre

based on the kernel code
detect it via IP version

In the GEM we can use a full packet buffer for receive but the buffer size
need to be 64bit size aligned.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/net/macb.c |  250 +++++++++++++++++++++++++++++++++++++++++++---------
 drivers/net/macb.h |  109 ++++++++++++++++++++++-
 2 files changed, 317 insertions(+), 42 deletions(-)

diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 9040e4e..0cfad05 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -53,10 +53,10 @@
 
 #define MACB_RX_BUFFER_SIZE	128
 #define RX_BUFFER_MULTIPLE	64  /* bytes */
-#define RX_RING_SIZE		32 /* must be power of 2 */
+#define RX_NB_PACKET		10
 #define TX_RING_SIZE		2 /* must be power of 2 */
 
-#define RX_RING_BYTES		(sizeof(struct macb_dma_desc) * RX_RING_SIZE)
+#define RX_RING_BYTES(bp)	(sizeof(struct macb_dma_desc) * bp->rx_ring_size)
 #define TX_RING_BYTES		(sizeof(struct macb_dma_desc) * TX_RING_SIZE)
 
 struct macb_device {
@@ -71,8 +71,12 @@ struct macb_device {
 	struct macb_dma_desc	*rx_ring;
 	struct macb_dma_desc	*tx_ring;
 
+	int			rx_buffer_size;
+	int			rx_ring_size;
+
 	int			phy_addr;
 
+	struct clk		*pclk;
 	const struct device_d	*dev;
 	struct eth_device	netdev;
 
@@ -81,8 +85,20 @@ struct macb_device {
 	struct mii_bus	miibus;
 
 	unsigned int		phy_flags;
+
+	bool			is_gem;
 };
 
+static inline bool macb_is_gem(struct macb_device *macb)
+{
+	return macb->is_gem;
+}
+
+static inline bool read_is_gem(struct macb_device *macb)
+{
+	return MACB_BFEXT(IDNUM, macb_readl(macb, MID)) == 0x2;
+}
+
 static int macb_send(struct eth_device *edev, void *packet,
 		     int length)
 {
@@ -140,7 +156,7 @@ static void reclaim_rx_buffers(struct macb_device *macb,
 	while (i > new_tail) {
 		macb->rx_ring[i].addr &= ~MACB_BIT(RX_USED);
 		i++;
-		if (i > RX_RING_SIZE)
+		if (i > macb->rx_ring_size)
 			i = 0;
 	}
 
@@ -153,6 +169,37 @@ static void reclaim_rx_buffers(struct macb_device *macb,
 	macb->rx_tail = new_tail;
 }
 
+static int gem_recv(struct eth_device *edev)
+{
+	struct macb_device *macb = edev->priv;
+	unsigned int rx_tail = macb->rx_tail;
+	void *buffer;
+	int length;
+	u32 status;
+
+	dev_dbg(macb->dev, "%s\n", __func__);
+
+	for (;;) {
+		barrier();
+		if (!(macb->rx_ring[rx_tail].addr & MACB_BIT(RX_USED)))
+			return -1;
+
+		barrier();
+		status = macb->rx_ring[rx_tail].ctrl;
+		length = MACB_BFEXT(RX_FRMLEN, status);
+		if (status & MACB_BIT(RX_SOF)) {
+			buffer = macb->rx_buffer + macb->rx_buffer_size * macb->rx_tail;
+			net_receive(buffer, length);
+			macb->rx_ring[rx_tail].ctrl &= ~MACB_BIT(RX_USED);
+			barrier();
+		}
+		rx_tail++;
+		macb->rx_tail++;
+	}
+
+	return 0;
+}
+
 static int macb_recv(struct eth_device *edev)
 {
 	struct macb_device *macb = edev->priv;
@@ -176,12 +223,12 @@ static int macb_recv(struct eth_device *edev)
 		}
 
 		if (status & MACB_BIT(RX_EOF)) {
-			buffer = macb->rx_buffer + MACB_RX_BUFFER_SIZE * macb->rx_tail;
+			buffer = macb->rx_buffer + macb->rx_buffer_size * macb->rx_tail;
 			length = MACB_BFEXT(RX_FRMLEN, status);
 			if (wrapped) {
 				unsigned int headlen, taillen;
 
-				headlen = MACB_RX_BUFFER_SIZE * (RX_RING_SIZE
+				headlen = macb->rx_buffer_size * (macb->rx_ring_size
 						 - macb->rx_tail);
 				taillen = length - headlen;
 				memcpy((void *)NetRxPackets[0],
@@ -192,11 +239,11 @@ static int macb_recv(struct eth_device *edev)
 			}
 
 			net_receive(buffer, length);
-			if (++rx_tail >= RX_RING_SIZE)
+			if (++rx_tail >= macb->rx_ring_size)
 				rx_tail = 0;
 			reclaim_rx_buffers(macb, rx_tail);
 		} else {
-			if (++rx_tail >= RX_RING_SIZE) {
+			if (++rx_tail >= macb->rx_ring_size) {
 				wrapped = 1;
 				rx_tail = 0;
 			}
@@ -214,13 +261,17 @@ static void macb_adjust_link(struct eth_device *edev)
 
 	reg = macb_readl(macb, NCFGR);
 	reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
+	if (macb_is_gem(macb))
+		reg &= ~GEM_BIT(GBE);
 
 	if (edev->phydev->duplex)
 		reg |= MACB_BIT(FD);
 	if (edev->phydev->speed == SPEED_100)
 		reg |= MACB_BIT(SPD);
+	if (edev->phydev->speed == SPEED_1000)
+		reg |= GEM_BIT(GBE);
 
-	macb_writel(macb, NCFGR, reg);
+	macb_or_gem_writel(macb, NCFGR, reg);
 }
 
 static int macb_open(struct eth_device *edev)
@@ -238,6 +289,29 @@ static int macb_open(struct eth_device *edev)
 			       macb->interface);
 }
 
+/*
+ * Configure the receive DMA engine
+ * - use the correct receive buffer size
+ * - set the possibility to use INCR16 bursts
+ *   (if not supported by FIFO, it will fallback to default)
+ * - set both rx/tx packet buffers to full memory size
+ * - set discard rx packets if no DMA resource
+ * These are configurable parameters for GEM.
+ */
+static void macb_configure_dma(struct macb_device *bp)
+{
+	u32 dmacfg;
+
+	if (macb_is_gem(bp)) {
+		dmacfg = gem_readl(bp, DMACFG) & ~GEM_BF(RXBS, -1L);
+		dmacfg |= GEM_BF(RXBS, bp->rx_buffer_size / RX_BUFFER_MULTIPLE);
+		dmacfg |= GEM_BF(FBLDO, 16);
+		dmacfg |= GEM_BIT(TXPBMS) | GEM_BF(RXBMS, -1L);
+		dmacfg |= GEM_BIT(DDRP);
+		gem_writel(bp, DMACFG, dmacfg);
+	}
+}
+
 static void macb_init(struct macb_device *macb)
 {
 	unsigned long paddr, val = 0;
@@ -252,12 +326,12 @@ static void macb_init(struct macb_device *macb)
 
 	/* initialize DMA descriptors */
 	paddr = (ulong)macb->rx_buffer;
-	for (i = 0; i < RX_RING_SIZE; i++) {
+	for (i = 0; i < macb->rx_ring_size; i++) {
 		macb->rx_ring[i].addr = paddr;
 		macb->rx_ring[i].ctrl = 0;
-		paddr += MACB_RX_BUFFER_SIZE;
+		paddr += macb->rx_buffer_size;
 	}
-	macb->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
+	macb->rx_ring[macb->rx_ring_size - 1].addr |= MACB_BIT(RX_WRAP);
 
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		macb->tx_ring[i].addr = 0;
@@ -267,18 +341,29 @@ static void macb_init(struct macb_device *macb)
 
 	macb->rx_tail = macb->tx_head = macb->tx_tail = 0;
 
+	macb_configure_dma(macb);
+
 	macb_writel(macb, RBQP, (ulong)macb->rx_ring);
 	macb_writel(macb, TBQP, (ulong)macb->tx_ring);
 
-	if (macb->interface == PHY_INTERFACE_MODE_RMII)
-		val |= MACB_BIT(RMII);
-	else
-		val &= ~MACB_BIT(RMII);
+	switch(macb->interface) {
+	case PHY_INTERFACE_MODE_RGMII:
+		val = GEM_BIT(RGMII);
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		if (IS_ENABLED(CONFIG_ARCH_AT91))
+			val = MACB_BIT(RMII) | MACB_BIT(CLKEN);
+		else
+			val = 0;
+		break;
+	default:
+		if (IS_ENABLED(CONFIG_ARCH_AT91))
+			val = MACB_BIT(CLKEN);
+		else
+			val = MACB_BIT(MII);
+	}
 
-#if defined(CONFIG_ARCH_AT91)
-	val |= MACB_BIT(CLKEN);
-#endif
-	macb_writel(macb, USRIO, val);
+	macb_or_gem_writel(macb, USRIO, val);
 
 }
 
@@ -386,12 +471,75 @@ static int macb_set_ethaddr(struct eth_device *edev, unsigned char *adr)
 	dev_dbg(macb->dev, "%s\n", __func__);
 
 	/* set hardware address */
-	macb_writel(macb, SA1B, adr[0] | adr[1] << 8 | adr[2] << 16 | adr[3] << 24);
-	macb_writel(macb, SA1T, adr[4] | adr[5] << 8);
+	macb_or_gem_writel(macb, SA1B, adr[0] | adr[1] << 8 | adr[2] << 16 | adr[3] << 24);
+	macb_or_gem_writel(macb, SA1T, adr[4] | adr[5] << 8);
 
 	return 0;
 }
 
+static u32 gem_mdc_clk_div(struct macb_device *bp)
+{
+	u32 config;
+	unsigned long pclk_hz = clk_get_rate(bp->pclk);
+
+	if (pclk_hz <= 20000000)
+		config = GEM_BF(CLK, GEM_CLK_DIV8);
+	else if (pclk_hz <= 40000000)
+		config = GEM_BF(CLK, GEM_CLK_DIV16);
+	else if (pclk_hz <= 80000000)
+		config = GEM_BF(CLK, GEM_CLK_DIV32);
+	else if (pclk_hz <= 120000000)
+		config = GEM_BF(CLK, GEM_CLK_DIV48);
+	else if (pclk_hz <= 160000000)
+		config = GEM_BF(CLK, GEM_CLK_DIV64);
+	else
+		config = GEM_BF(CLK, GEM_CLK_DIV96);
+
+	return config;
+}
+
+static u32 macb_mdc_clk_div(struct macb_device *bp)
+{
+	u32 config;
+	unsigned long pclk_hz;
+
+	if (macb_is_gem(bp))
+		return gem_mdc_clk_div(bp);
+
+	pclk_hz = clk_get_rate(bp->pclk);
+	if (pclk_hz <= 20000000)
+		config = MACB_BF(CLK, MACB_CLK_DIV8);
+	else if (pclk_hz <= 40000000)
+		config = MACB_BF(CLK, MACB_CLK_DIV16);
+	else if (pclk_hz <= 80000000)
+		config = MACB_BF(CLK, MACB_CLK_DIV32);
+	else
+		config = MACB_BF(CLK, MACB_CLK_DIV64);
+
+	return config;
+}
+
+/*
+ * Get the DMA bus width field of the network configuration register that we
+ * should program.  We find the width from decoding the design configuration
+ * register to find the maximum supported data bus width.
+ */
+static u32 macb_dbw(struct macb_device *bp)
+{
+	if (!macb_is_gem(bp))
+		return 0;
+
+	switch (GEM_BFEXT(DBWDEF, gem_readl(bp, DCFG1))) {
+	case 4:
+		return GEM_BF(DBW, GEM_DBW128);
+	case 2:
+		return GEM_BF(DBW, GEM_DBW64);
+	case 1:
+	default:
+		return GEM_BF(DBW, GEM_DBW32);
+	}
+}
+
 static void macb_reset_hw(struct macb_device *bp)
 {
 	/* Disable RX and TX forcefully */
@@ -409,14 +557,35 @@ static void macb_reset_hw(struct macb_device *bp)
 	macb_readl(bp, ISR);
 }
 
+static void macb_init_rx_buffer_size(struct macb_device *bp, size_t size)
+{
+	if (!macb_is_gem(bp)) {
+		bp->rx_buffer_size = MACB_RX_BUFFER_SIZE;
+		bp->rx_ring_size = roundup(RX_NB_PACKET * PKTSIZE / MACB_RX_BUFFER_SIZE, 2);
+	} else {
+		bp->rx_buffer_size = size;
+		bp->rx_ring_size = RX_NB_PACKET;
+
+		if (bp->rx_buffer_size % RX_BUFFER_MULTIPLE) {
+			dev_dbg(bp->dev,
+				    "RX buffer must be multiple of %d bytes, expanding\n",
+				    RX_BUFFER_MULTIPLE);
+			bp->rx_buffer_size =
+				roundup(bp->rx_buffer_size, RX_BUFFER_MULTIPLE);
+		}
+		bp->rx_buffer = dma_alloc_coherent(bp->rx_buffer_size * bp->rx_ring_size);
+	}
+
+	dev_dbg(bp->dev, "[%d] rx_buffer_size [%d]\n",
+		   size, bp->rx_buffer_size);
+}
+
 static int macb_probe(struct device_d *dev)
 {
 	struct eth_device *edev;
 	struct macb_device *macb;
-	unsigned long macb_hz;
 	u32 ncfgr;
 	struct at91_ether_platform_data *pdata;
-	struct clk *pclk;
 
 	if (!dev->platform_data) {
 		dev_err(dev, "macb: no platform_data\n");
@@ -432,7 +601,6 @@ static int macb_probe(struct device_d *dev)
 
 	edev->open = macb_open;
 	edev->send = macb_send;
-	edev->recv = macb_recv;
 	edev->halt = macb_halt;
 	edev->get_ethaddr = pdata->get_ethaddr ? pdata->get_ethaddr : macb_get_ethaddr;
 	edev->set_ethaddr = macb_set_ethaddr;
@@ -451,8 +619,9 @@ static int macb_probe(struct device_d *dev)
 
 	macb->phy_flags = pdata->phy_flags;
 
-	macb->rx_buffer = dma_alloc_coherent(MACB_RX_BUFFER_SIZE * RX_RING_SIZE);
-	macb->rx_ring = dma_alloc_coherent(RX_RING_BYTES);
+	macb_init_rx_buffer_size(macb, PKTSIZE);
+	macb->rx_buffer = dma_alloc_coherent(macb->rx_buffer_size * macb->rx_ring_size);
+	macb->rx_ring = dma_alloc_coherent(RX_RING_BYTES(macb));
 	macb->tx_ring = dma_alloc_coherent(TX_RING_BYTES);
 
 	macb->regs = dev_request_mem_region(dev, 0);
@@ -461,29 +630,25 @@ static int macb_probe(struct device_d *dev)
 	 * Do some basic initialization so that we at least can talk
 	 * to the PHY
 	 */
-	pclk = clk_get(dev, "macb_clk");
-	if (IS_ERR(pclk)) {
+	macb->pclk = clk_get(dev, "macb_clk");
+	if (IS_ERR(macb->pclk)) {
 		dev_err(dev, "no macb_clk\n");
-		return PTR_ERR(pclk);
+		return PTR_ERR(macb->pclk);
 	}
 
-	clk_enable(pclk);
-
-	macb_reset_hw(macb);
+	clk_enable(macb->pclk);
 
-	macb_hz = clk_get_rate(pclk);
-	if (macb_hz < 20000000)
-		ncfgr = MACB_BF(CLK, MACB_CLK_DIV8);
-	else if (macb_hz < 40000000)
-		ncfgr = MACB_BF(CLK, MACB_CLK_DIV16);
-	else if (macb_hz < 80000000)
-		ncfgr = MACB_BF(CLK, MACB_CLK_DIV32);
+	if (macb_is_gem(macb))
+		edev->recv = gem_recv;
 	else
-		ncfgr = MACB_BF(CLK, MACB_CLK_DIV64);
-
+		edev->recv = macb_recv;
+	macb->is_gem = read_is_gem(macb);
 
+	macb_reset_hw(macb);
+	ncfgr = macb_mdc_clk_div(macb);
 	ncfgr |= MACB_BIT(PAE);		/* PAuse Enable */
 	ncfgr |= MACB_BIT(DRFCS);	/* Discard Rx FCS */
+	ncfgr |= macb_dbw(macb);
 	macb_writel(macb, NCFGR, ncfgr);
 
 	macb_init(macb);
@@ -491,6 +656,9 @@ static int macb_probe(struct device_d *dev)
 	mdiobus_register(&macb->miibus);
 	eth_register(edev);
 
+	dev_info(dev, "Cadence %s at 0x%p\n",
+		macb_is_gem(macb) ? "GEM" : "MACB", macb->regs);
+
 	return 0;
 }
 
diff --git a/drivers/net/macb.h b/drivers/net/macb.h
index 8dd5a87..cadd561 100644
--- a/drivers/net/macb.h
+++ b/drivers/net/macb.h
@@ -67,6 +67,24 @@
 #define MACB_TPQ				0x00bc
 #define MACB_USRIO				0x00c0
 #define MACB_WOL				0x00c4
+#define MACB_MID				0x00fc
+
+/* GEM register offsets. */
+#define GEM_NCFGR				0x0004
+#define GEM_USRIO				0x000c
+#define GEM_DMACFG				0x0010
+#define GEM_HRB					0x0080
+#define GEM_HRT					0x0084
+#define GEM_SA1B				0x0088
+#define GEM_SA1T				0x008C
+#define GEM_OTX					0x0100
+#define GEM_DCFG1				0x0280
+#define GEM_DCFG2				0x0284
+#define GEM_DCFG3				0x0288
+#define GEM_DCFG4				0x028c
+#define GEM_DCFG5				0x0290
+#define GEM_DCFG6				0x0294
+#define GEM_DCFG7				0x0298
 
 /* Bitfields in NCR */
 #define MACB_LB_OFFSET				0
@@ -134,6 +152,34 @@
 #define MACB_IRXFCS_OFFSET			19
 #define MACB_IRXFCS_SIZE			1
 
+/* GEM specific NCFGR bitfields. */
+#define GEM_GBE_OFFSET				10
+#define GEM_GBE_SIZE				1
+#define GEM_CLK_OFFSET				18
+#define GEM_CLK_SIZE				3
+#define GEM_DBW_OFFSET				21
+#define GEM_DBW_SIZE				2
+
+/* Constants for data bus width. */
+#define GEM_DBW32				0
+#define GEM_DBW64				1
+#define GEM_DBW128				2
+
+/* Bitfields in DMACFG. */
+#define GEM_FBLDO_OFFSET			0
+#define GEM_FBLDO_SIZE				5
+#define GEM_RXBMS_OFFSET			8
+#define GEM_RXBMS_SIZE				2
+#define GEM_TXPBMS_OFFSET			10
+#define GEM_TXPBMS_SIZE				1
+#define GEM_TXCOEN_OFFSET			11
+#define GEM_TXCOEN_SIZE				1
+#define GEM_RXBS_OFFSET				16
+#define GEM_RXBS_SIZE				8
+#define GEM_DDRP_OFFSET				24
+#define GEM_DDRP_SIZE				1
+
+
 /* Bitfields in NSR */
 #define MACB_NSR_LINK_OFFSET			0
 #define MACB_NSR_LINK_SIZE			1
@@ -208,7 +254,7 @@
 #define MACB_SOF_OFFSET				30
 #define MACB_SOF_SIZE				2
 
-/* Bitfields in USRIO */
+/* Bitfields in USRIO (AVR32) */
 #define MACB_MII_OFFSET				0
 #define MACB_MII_SIZE				1
 #define MACB_EAM_OFFSET				1
@@ -221,6 +267,8 @@
 /* Bitfields in USRIO (AT91) */
 #define MACB_RMII_OFFSET			0
 #define MACB_RMII_SIZE				1
+#define GEM_RGMII_OFFSET			0	/* GEM gigabit mode */
+#define GEM_RGMII_SIZE				1
 #define MACB_CLKEN_OFFSET			1
 #define MACB_CLKEN_SIZE				1
 
@@ -236,12 +284,30 @@
 #define MACB_WOL_MTI_OFFSET			19
 #define MACB_WOL_MTI_SIZE			1
 
+/* Bitfields in MID */
+#define MACB_IDNUM_OFFSET			16
+#define MACB_IDNUM_SIZE				16
+#define MACB_REV_OFFSET				0
+#define MACB_REV_SIZE				16
+
+/* Bitfields in DCFG1. */
+#define GEM_DBWDEF_OFFSET			25
+#define GEM_DBWDEF_SIZE				3
+
 /* Constants for CLK */
 #define MACB_CLK_DIV8				0
 #define MACB_CLK_DIV16				1
 #define MACB_CLK_DIV32				2
 #define MACB_CLK_DIV64				3
 
+/* GEM specific constants for CLK. */
+#define GEM_CLK_DIV8				0
+#define GEM_CLK_DIV16				1
+#define GEM_CLK_DIV32				2
+#define GEM_CLK_DIV48				3
+#define GEM_CLK_DIV64				4
+#define GEM_CLK_DIV96				5
+
 /* Constants for MAN register */
 #define MACB_MAN_SOF				1
 #define MACB_MAN_WRITE				1
@@ -262,11 +328,52 @@
 		    << MACB_##name##_OFFSET))		\
 	 | MACB_BF(name,value))
 
+#define GEM_BIT(name)					\
+	(1 << GEM_##name##_OFFSET)
+#define GEM_BF(name, value)				\
+	(((value) & ((1 << GEM_##name##_SIZE) - 1))	\
+	 << GEM_##name##_OFFSET)
+#define GEM_BFEXT(name, value)\
+	(((value) >> GEM_##name##_OFFSET)		\
+	 & ((1 << GEM_##name##_SIZE) - 1))
+#define GEM_BFINS(name, value, old)			\
+	(((old) & ~(((1 << GEM_##name##_SIZE) - 1)	\
+		    << GEM_##name##_OFFSET))		\
+	 | GEM_BF(name, value))
+
 /* Register access macros */
 #define macb_readl(port,reg)				\
 	__raw_readl((port)->regs + MACB_##reg)
 #define macb_writel(port,reg,value)			\
 	__raw_writel((value), (port)->regs + MACB_##reg)
+#define gem_readl(port, reg)				\
+	__raw_readl((port)->regs + GEM_##reg)
+#define gem_writel(port, reg, value)			\
+	__raw_writel((value), (port)->regs + GEM_##reg)
+
+/*
+ * Conditional GEM/MACB macros.  These perform the operation to the correct
+ * register dependent on whether the device is a GEM or a MACB.  For registers
+ * and bitfields that are common across both devices, use macb_{read,write}l
+ * to avoid the cost of the conditional.
+ */
+#define macb_or_gem_writel(__bp, __reg, __value) \
+	({ \
+		if (macb_is_gem((__bp))) \
+			gem_writel((__bp), __reg, __value); \
+		else \
+			macb_writel((__bp), __reg, __value); \
+	})
+
+#define macb_or_gem_readl(__bp, __reg) \
+	({ \
+		u32 __v; \
+		if (macb_is_gem((__bp))) \
+			__v = gem_readl((__bp), __reg); \
+		else \
+			__v = macb_readl((__bp), __reg); \
+		__v; \
+	})
 
 /**
  * struct macb_dma_desc - Hardware DMA descriptor
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2013-02-11 16:59 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-08  9:07 [For master PATCH 0/7] macb: more fixes + gem (gigabit support) Jean-Christophe PLAGNIOL-VILLARD
2013-02-08  9:18 ` [PATCH 1/7] macb: call macb_init at probe explecitly Jean-Christophe PLAGNIOL-VILLARD
2013-02-08  9:18   ` [PATCH 2/7] macb: sync remaining define with linux Jean-Christophe PLAGNIOL-VILLARD
2013-02-08  9:18   ` [PATCH 3/7] macb: use the macro as in linux for tx/rx buffer ring size Jean-Christophe PLAGNIOL-VILLARD
2013-02-08  9:18   ` [PATCH 4/7] macb: enable Tramsmit and Receive at open Jean-Christophe PLAGNIOL-VILLARD
2013-02-08  9:18   ` [PATCH 5/7] macb: reset the IP at init Jean-Christophe PLAGNIOL-VILLARD
2013-02-08  9:18   ` [PATCH 6/7] macb: fix tx ring size Jean-Christophe PLAGNIOL-VILLARD
2013-02-08 12:20     ` Alexander Aring
2013-02-08 13:36       ` Jean-Christophe PLAGNIOL-VILLARD
2013-02-11 16:33     ` Sascha Hauer
2013-02-11 16:52       ` Jean-Christophe PLAGNIOL-VILLARD
2013-02-08  9:18   ` [PATCH 7/7] macb: add cadence Gigabit GEM support Jean-Christophe PLAGNIOL-VILLARD
2013-02-08 10:24 ` [For master PATCH 0/7] macb: more fixes + gem (gigabit support) Nicolas Ferre
2013-02-11  8:35 ` Sascha Hauer
2013-02-11 16:57 ` [PATCH 6/7 v2] macb: fix tx ring size Jean-Christophe PLAGNIOL-VILLARD
2013-02-11 16:57   ` [PATCH 7/7 v2] macb: add cadence Gigabit GEM support Jean-Christophe PLAGNIOL-VILLARD

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox