* [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