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

Archive Download this file



interactive