Root/target/linux/lantiq/patches-3.0/0015-MIPS-lantiq-adds-etop-support-for-ase-ar9.patch

1From c7881d8d2b3aed9a90aa37dcf797328a9cfbe7b6 Mon Sep 17 00:00:00 2001
2From: John Crispin <blogic@openwrt.org>
3Date: Wed, 10 Aug 2011 15:32:16 +0200
4Subject: [PATCH 15/24] MIPS: lantiq: adds etop support for ase/ar9
5
6Extend the driver to handle the different DMA channel layout for AR9 and
7SoCs. The patch also adds support for the integrated PHY found on Amazon-SE
8and the gigabit switch found inside the AR9.
9
10Signed-off-by: John Crispin <blogic@openwrt.org>
11Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
12---
13 .../mips/include/asm/mach-lantiq/xway/lantiq_irq.h | 22 +---
14 .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 10 ++
15 arch/mips/lantiq/xway/devices.c | 11 +-
16 arch/mips/lantiq/xway/mach-easy50601.c | 5 +
17 drivers/net/lantiq_etop.c | 172 ++++++++++++++++++--
18 5 files changed, 180 insertions(+), 40 deletions(-)
19
20Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
21===================================================================
22--- linux-3.0.3.orig/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h 2011-10-04 20:05:23.000000000 +0200
23+++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h 2011-10-04 20:05:44.146312365 +0200
24@@ -40,26 +40,8 @@
25 
26 #define MIPS_CPU_TIMER_IRQ 7
27 
28-#define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0)
29-#define LTQ_DMA_CH1_INT (INT_NUM_IM2_IRL0 + 1)
30-#define LTQ_DMA_CH2_INT (INT_NUM_IM2_IRL0 + 2)
31-#define LTQ_DMA_CH3_INT (INT_NUM_IM2_IRL0 + 3)
32-#define LTQ_DMA_CH4_INT (INT_NUM_IM2_IRL0 + 4)
33-#define LTQ_DMA_CH5_INT (INT_NUM_IM2_IRL0 + 5)
34-#define LTQ_DMA_CH6_INT (INT_NUM_IM2_IRL0 + 6)
35-#define LTQ_DMA_CH7_INT (INT_NUM_IM2_IRL0 + 7)
36-#define LTQ_DMA_CH8_INT (INT_NUM_IM2_IRL0 + 8)
37-#define LTQ_DMA_CH9_INT (INT_NUM_IM2_IRL0 + 9)
38-#define LTQ_DMA_CH10_INT (INT_NUM_IM2_IRL0 + 10)
39-#define LTQ_DMA_CH11_INT (INT_NUM_IM2_IRL0 + 11)
40-#define LTQ_DMA_CH12_INT (INT_NUM_IM2_IRL0 + 25)
41-#define LTQ_DMA_CH13_INT (INT_NUM_IM2_IRL0 + 26)
42-#define LTQ_DMA_CH14_INT (INT_NUM_IM2_IRL0 + 27)
43-#define LTQ_DMA_CH15_INT (INT_NUM_IM2_IRL0 + 28)
44-#define LTQ_DMA_CH16_INT (INT_NUM_IM2_IRL0 + 29)
45-#define LTQ_DMA_CH17_INT (INT_NUM_IM2_IRL0 + 30)
46-#define LTQ_DMA_CH18_INT (INT_NUM_IM2_IRL0 + 16)
47-#define LTQ_DMA_CH19_INT (INT_NUM_IM2_IRL0 + 21)
48+#define LTQ_DMA_ETOP ((ltq_is_ase()) ? \
49+ (INT_NUM_IM3_IRL0) : (INT_NUM_IM2_IRL0))
50 
51 #define LTQ_PPE_MBOX_INT (INT_NUM_IM2_IRL0 + 24)
52 
53Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
54===================================================================
55--- linux-3.0.3.orig/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h 2011-10-04 20:05:23.000000000 +0200
56+++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h 2011-10-04 20:05:44.146312365 +0200
57@@ -80,6 +80,7 @@
58 #define LTQ_PMU_SIZE 0x1000
59 
60 #define PMU_DMA 0x0020
61+#define PMU_EPHY 0x0080
62 #define PMU_USB 0x8041
63 #define PMU_SPI 0x0100
64 #define PMU_LED 0x0800
65@@ -92,6 +93,10 @@
66 #define LTQ_ETOP_BASE_ADDR 0x1E180000
67 #define LTQ_ETOP_SIZE 0x40000
68 
69+/* GBIT - gigabit switch */
70+#define LTQ_GBIT_BASE_ADDR 0x1E108000
71+#define LTQ_GBIT_SIZE 0x200
72+
73 /* DMA */
74 #define LTQ_DMA_BASE_ADDR 0x1E104100
75 #define LTQ_DMA_SIZE 0x800
76@@ -148,6 +153,11 @@
77 extern void ltq_pmu_disable(unsigned int module);
78 extern void ltq_cgu_enable(unsigned int clk);
79 
80+static inline int ltq_is_ase(void)
81+{
82+ return (ltq_get_soc_type() == SOC_TYPE_AMAZON_SE);
83+}
84+
85 static inline int ltq_is_ar9(void)
86 {
87     return (ltq_get_soc_type() == SOC_TYPE_AR9);
88Index: linux-3.0.3/arch/mips/lantiq/xway/devices.c
89===================================================================
90--- linux-3.0.3.orig/arch/mips/lantiq/xway/devices.c 2011-10-04 20:03:54.000000000 +0200
91+++ linux-3.0.3/arch/mips/lantiq/xway/devices.c 2011-10-04 20:05:44.146312365 +0200
92@@ -79,18 +79,23 @@
93 }
94 
95 /* ethernet */
96-static struct resource ltq_etop_resources =
97- MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE);
98+static struct resource ltq_etop_resources[] = {
99+ MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE),
100+ MEM_RES("gbit", LTQ_GBIT_BASE_ADDR, LTQ_GBIT_SIZE),
101+};
102 
103 static struct platform_device ltq_etop = {
104     .name = "ltq_etop",
105- .resource = &ltq_etop_resources,
106+ .resource = ltq_etop_resources,
107     .num_resources = 1,
108 };
109 
110 void __init
111 ltq_register_etop(struct ltq_eth_data *eth)
112 {
113+ /* only register the gphy on socs that have one */
114+ if (ltq_is_ar9() | ltq_is_vr9())
115+ ltq_etop.num_resources = 2;
116     if (eth) {
117         ltq_etop.dev.platform_data = eth;
118         platform_device_register(&ltq_etop);
119Index: linux-3.0.3/drivers/net/lantiq_etop.c
120===================================================================
121--- linux-3.0.3.orig/drivers/net/lantiq_etop.c 2011-08-17 19:57:16.000000000 +0200
122+++ linux-3.0.3/drivers/net/lantiq_etop.c 2011-10-04 20:05:44.146312365 +0200
123@@ -34,6 +34,7 @@
124 #include <linux/init.h>
125 #include <linux/delay.h>
126 #include <linux/io.h>
127+#include <linux/dma-mapping.h>
128 
129 #include <asm/checksum.h>
130 
131@@ -69,10 +70,43 @@
132 #define ETOP_MII_REVERSE 0xe
133 #define ETOP_PLEN_UNDER 0x40
134 #define ETOP_CGEN 0x800
135+#define ETOP_CFG_MII0 0x01
136 
137-/* use 2 static channels for TX/RX */
138+#define LTQ_GBIT_MDIO_CTL 0xCC
139+#define LTQ_GBIT_MDIO_DATA 0xd0
140+#define LTQ_GBIT_GCTL0 0x68
141+#define LTQ_GBIT_PMAC_HD_CTL 0x8c
142+#define LTQ_GBIT_P0_CTL 0x4
143+#define LTQ_GBIT_PMAC_RX_IPG 0xa8
144+
145+#define PMAC_HD_CTL_AS (1 << 19)
146+#define PMAC_HD_CTL_RXSH (1 << 22)
147+
148+/* Switch Enable (0=disable, 1=enable) */
149+#define GCTL0_SE 0x80000000
150+/* Disable MDIO auto polling (0=disable, 1=enable) */
151+#define PX_CTL_DMDIO 0x00400000
152+
153+/* register information for the gbit's MDIO bus */
154+#define MDIO_XR9_REQUEST 0x00008000
155+#define MDIO_XR9_READ 0x00000800
156+#define MDIO_XR9_WRITE 0x00000400
157+#define MDIO_XR9_REG_MASK 0x1f
158+#define MDIO_XR9_ADDR_MASK 0x1f
159+#define MDIO_XR9_RD_MASK 0xffff
160+#define MDIO_XR9_REG_OFFSET 0
161+#define MDIO_XR9_ADDR_OFFSET 5
162+#define MDIO_XR9_WR_OFFSET 16
163+
164+/* the newer xway socks have a embedded 3/7 port gbit multiplexer */
165+#define ltq_has_gbit() (ltq_is_ar9() || ltq_is_vr9())
166+
167+/* use 2 static channels for TX/RX
168+ depending on the SoC we need to use different DMA channels for ethernet */
169 #define LTQ_ETOP_TX_CHANNEL 1
170-#define LTQ_ETOP_RX_CHANNEL 6
171+#define LTQ_ETOP_RX_CHANNEL ((ltq_is_ase()) ? (5) : \
172+ ((ltq_has_gbit()) ? (0) : (6)))
173+
174 #define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL)
175 #define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL)
176 
177@@ -81,9 +115,15 @@
178 #define ltq_etop_w32_mask(x, y, z) \
179         ltq_w32_mask(x, y, ltq_etop_membase + (z))
180 
181+#define ltq_gbit_r32(x) ltq_r32(ltq_gbit_membase + (x))
182+#define ltq_gbit_w32(x, y) ltq_w32(x, ltq_gbit_membase + (y))
183+#define ltq_gbit_w32_mask(x, y, z) \
184+ ltq_w32_mask(x, y, ltq_gbit_membase + (z))
185+
186 #define DRV_VERSION "1.0"
187 
188 static void __iomem *ltq_etop_membase;
189+static void __iomem *ltq_gbit_membase;
190 
191 struct ltq_etop_chan {
192     int idx;
193@@ -108,6 +148,9 @@
194     spinlock_t lock;
195 };
196 
197+static int ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr,
198+ int phy_reg, u16 phy_data);
199+
200 static int
201 ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
202 {
203@@ -209,7 +252,7 @@
204 ltq_etop_dma_irq(int irq, void *_priv)
205 {
206     struct ltq_etop_priv *priv = _priv;
207- int ch = irq - LTQ_DMA_CH0_INT;
208+ int ch = irq - LTQ_DMA_ETOP;
209 
210     napi_schedule(&priv->ch[ch].napi);
211     return IRQ_HANDLED;
212@@ -242,26 +285,66 @@
213             ltq_etop_free_channel(dev, &priv->ch[i]);
214 }
215 
216+static void
217+ltq_etop_gbit_init(void)
218+{
219+ ltq_pmu_enable(PMU_SWITCH);
220+
221+ ltq_gpio_request(42, 1, 0, 1, "MDIO");
222+ ltq_gpio_request(43, 1, 0, 1, "MDC");
223+
224+ ltq_gbit_w32_mask(0, GCTL0_SE, LTQ_GBIT_GCTL0);
225+ /** Disable MDIO auto polling mode */
226+ ltq_gbit_w32_mask(0, PX_CTL_DMDIO, LTQ_GBIT_P0_CTL);
227+ /* set 1522 packet size */
228+ ltq_gbit_w32_mask(0x300, 0, LTQ_GBIT_GCTL0);
229+ /* disable pmac & dmac headers */
230+ ltq_gbit_w32_mask(PMAC_HD_CTL_AS | PMAC_HD_CTL_RXSH, 0,
231+ LTQ_GBIT_PMAC_HD_CTL);
232+ /* Due to traffic halt when burst length 8,
233+ replace default IPG value with 0x3B */
234+ ltq_gbit_w32(0x3B, LTQ_GBIT_PMAC_RX_IPG);
235+}
236+
237 static int
238 ltq_etop_hw_init(struct net_device *dev)
239 {
240     struct ltq_etop_priv *priv = netdev_priv(dev);
241+ unsigned int mii_mode = priv->pldata->mii_mode;
242     int i;
243 
244     ltq_pmu_enable(PMU_PPE);
245 
246- switch (priv->pldata->mii_mode) {
247+ if (ltq_has_gbit()) {
248+ ltq_etop_gbit_init();
249+ }
250+
251+ switch (mii_mode) {
252+ case PHY_INTERFACE_MODE_RGMII:
253     case PHY_INTERFACE_MODE_RMII:
254         ltq_etop_w32_mask(ETOP_MII_MASK,
255             ETOP_MII_REVERSE, LTQ_ETOP_CFG);
256         break;
257 
258+ case PHY_INTERFACE_MODE_GMII:
259     case PHY_INTERFACE_MODE_MII:
260         ltq_etop_w32_mask(ETOP_MII_MASK,
261             ETOP_MII_NORMAL, LTQ_ETOP_CFG);
262         break;
263 
264     default:
265+ if (ltq_is_ase()) {
266+ ltq_pmu_enable(PMU_EPHY);
267+ /* disable external MII */
268+ ltq_etop_w32_mask(0, ETOP_CFG_MII0, LTQ_ETOP_CFG);
269+ /* enable clock for internal PHY */
270+ ltq_cgu_enable(CGU_EPHY);
271+ /* we need to write this magic to the internal phy to
272+ make it work */
273+ ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020);
274+ pr_info("Selected EPHY mode\n");
275+ break;
276+ }
277         netdev_err(dev, "unknown mii mode %d\n",
278             priv->pldata->mii_mode);
279         return -ENOTSUPP;
280@@ -273,7 +356,7 @@
281     ltq_dma_init_port(DMA_PORT_ETOP);
282 
283     for (i = 0; i < MAX_DMA_CHAN; i++) {
284- int irq = LTQ_DMA_CH0_INT + i;
285+ int irq = LTQ_DMA_ETOP + i;
286         struct ltq_etop_chan *ch = &priv->ch[i];
287 
288         ch->idx = ch->dma.nr = i;
289@@ -337,6 +420,39 @@
290 };
291 
292 static int
293+ltq_etop_mdio_wr_xr9(struct mii_bus *bus, int phy_addr,
294+ int phy_reg, u16 phy_data)
295+{
296+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_WRITE |
297+ (phy_data << MDIO_XR9_WR_OFFSET) |
298+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
299+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
300+
301+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
302+ ;
303+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
304+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
305+ ;
306+ return 0;
307+}
308+
309+static int
310+ltq_etop_mdio_rd_xr9(struct mii_bus *bus, int phy_addr, int phy_reg)
311+{
312+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_READ |
313+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
314+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
315+
316+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
317+ ;
318+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
319+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
320+ ;
321+ val = ltq_gbit_r32(LTQ_GBIT_MDIO_DATA) & MDIO_XR9_RD_MASK;
322+ return val;
323+}
324+
325+static int
326 ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
327 {
328     u32 val = MDIO_REQUEST |
329@@ -377,14 +493,11 @@
330 {
331     struct ltq_etop_priv *priv = netdev_priv(dev);
332     struct phy_device *phydev = NULL;
333- int phy_addr;
334 
335- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
336- if (priv->mii_bus->phy_map[phy_addr]) {
337- phydev = priv->mii_bus->phy_map[phy_addr];
338- break;
339- }
340- }
341+ if (ltq_is_ase())
342+ phydev = priv->mii_bus->phy_map[8];
343+ else
344+ phydev = priv->mii_bus->phy_map[0];
345 
346     if (!phydev) {
347         netdev_err(dev, "no PHY found\n");
348@@ -406,6 +519,9 @@
349                   | SUPPORTED_Autoneg
350                   | SUPPORTED_MII
351                   | SUPPORTED_TP);
352+ if (ltq_has_gbit())
353+ phydev->supported &= SUPPORTED_1000baseT_Half
354+ | SUPPORTED_1000baseT_Full;
355 
356     phydev->advertising = phydev->supported;
357     priv->phydev = phydev;
358@@ -431,8 +547,13 @@
359     }
360 
361     priv->mii_bus->priv = dev;
362- priv->mii_bus->read = ltq_etop_mdio_rd;
363- priv->mii_bus->write = ltq_etop_mdio_wr;
364+ if (ltq_has_gbit()) {
365+ priv->mii_bus->read = ltq_etop_mdio_rd_xr9;
366+ priv->mii_bus->write = ltq_etop_mdio_wr_xr9;
367+ } else {
368+ priv->mii_bus->read = ltq_etop_mdio_rd;
369+ priv->mii_bus->write = ltq_etop_mdio_wr;
370+ }
371     priv->mii_bus->name = "ltq_mii";
372     snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0);
373     priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
374@@ -522,9 +643,9 @@
375     struct ltq_etop_priv *priv = netdev_priv(dev);
376     struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1];
377     struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
378- int len;
379     unsigned long flags;
380     u32 byte_offset;
381+ int len;
382 
383     len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
384 
385@@ -698,7 +819,7 @@
386 {
387     struct net_device *dev;
388     struct ltq_etop_priv *priv;
389- struct resource *res;
390+ struct resource *res, *gbit_res;
391     int err;
392     int i;
393 
394@@ -726,6 +847,23 @@
395         goto err_out;
396     }
397 
398+ if (ltq_has_gbit()) {
399+ gbit_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
400+ if (!gbit_res) {
401+ dev_err(&pdev->dev, "failed to get gbit resource\n");
402+ err = -ENOENT;
403+ goto err_out;
404+ }
405+ ltq_gbit_membase = devm_ioremap_nocache(&pdev->dev,
406+ gbit_res->start, resource_size(gbit_res));
407+ if (!ltq_gbit_membase) {
408+ dev_err(&pdev->dev, "failed to remap gigabit switch %d\n",
409+ pdev->id);
410+ err = -ENOMEM;
411+ goto err_out;
412+ }
413+ }
414+
415     dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
416     strcpy(dev->name, "eth%d");
417     dev->netdev_ops = &ltq_eth_netdev_ops;
418

Archive Download this file



interactive