diff options
Diffstat (limited to 'target/linux/lantiq/patches/0015-MIPS-lantiq-adds-etop-support-for-ase-ar9.patch')
-rw-r--r-- | target/linux/lantiq/patches/0015-MIPS-lantiq-adds-etop-support-for-ase-ar9.patch | 409 |
1 files changed, 0 insertions, 409 deletions
diff --git a/target/linux/lantiq/patches/0015-MIPS-lantiq-adds-etop-support-for-ase-ar9.patch b/target/linux/lantiq/patches/0015-MIPS-lantiq-adds-etop-support-for-ase-ar9.patch deleted file mode 100644 index 503c6bf78e..0000000000 --- a/target/linux/lantiq/patches/0015-MIPS-lantiq-adds-etop-support-for-ase-ar9.patch +++ /dev/null @@ -1,409 +0,0 @@ -From c7881d8d2b3aed9a90aa37dcf797328a9cfbe7b6 Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Wed, 10 Aug 2011 15:32:16 +0200 -Subject: [PATCH 15/24] MIPS: lantiq: adds etop support for ase/ar9 - -Extend the driver to handle the different DMA channel layout for AR9 and -SoCs. The patch also adds support for the integrated PHY found on Amazon-SE -and the gigabit switch found inside the AR9. - -Signed-off-by: John Crispin <blogic@openwrt.org> -Signed-off-by: Thomas Langer <thomas.langer@lantiq.com> ---- - .../mips/include/asm/mach-lantiq/xway/lantiq_irq.h | 22 +--- - .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 10 ++ - arch/mips/lantiq/xway/devices.c | 11 +- - arch/mips/lantiq/xway/mach-easy50601.c | 5 + - drivers/net/lantiq_etop.c | 172 ++++++++++++++++++-- - 5 files changed, 180 insertions(+), 40 deletions(-) - ---- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h -+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h -@@ -40,26 +40,8 @@ - - #define MIPS_CPU_TIMER_IRQ 7 - --#define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0) --#define LTQ_DMA_CH1_INT (INT_NUM_IM2_IRL0 + 1) --#define LTQ_DMA_CH2_INT (INT_NUM_IM2_IRL0 + 2) --#define LTQ_DMA_CH3_INT (INT_NUM_IM2_IRL0 + 3) --#define LTQ_DMA_CH4_INT (INT_NUM_IM2_IRL0 + 4) --#define LTQ_DMA_CH5_INT (INT_NUM_IM2_IRL0 + 5) --#define LTQ_DMA_CH6_INT (INT_NUM_IM2_IRL0 + 6) --#define LTQ_DMA_CH7_INT (INT_NUM_IM2_IRL0 + 7) --#define LTQ_DMA_CH8_INT (INT_NUM_IM2_IRL0 + 8) --#define LTQ_DMA_CH9_INT (INT_NUM_IM2_IRL0 + 9) --#define LTQ_DMA_CH10_INT (INT_NUM_IM2_IRL0 + 10) --#define LTQ_DMA_CH11_INT (INT_NUM_IM2_IRL0 + 11) --#define LTQ_DMA_CH12_INT (INT_NUM_IM2_IRL0 + 25) --#define LTQ_DMA_CH13_INT (INT_NUM_IM2_IRL0 + 26) --#define LTQ_DMA_CH14_INT (INT_NUM_IM2_IRL0 + 27) --#define LTQ_DMA_CH15_INT (INT_NUM_IM2_IRL0 + 28) --#define LTQ_DMA_CH16_INT (INT_NUM_IM2_IRL0 + 29) --#define LTQ_DMA_CH17_INT (INT_NUM_IM2_IRL0 + 30) --#define LTQ_DMA_CH18_INT (INT_NUM_IM2_IRL0 + 16) --#define LTQ_DMA_CH19_INT (INT_NUM_IM2_IRL0 + 21) -+#define LTQ_DMA_ETOP ((ltq_is_ase()) ? \ -+ (INT_NUM_IM3_IRL0) : (INT_NUM_IM2_IRL0)) - - #define LTQ_PPE_MBOX_INT (INT_NUM_IM2_IRL0 + 24) - ---- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -@@ -80,6 +80,7 @@ - #define LTQ_PMU_SIZE 0x1000 - - #define PMU_DMA 0x0020 -+#define PMU_EPHY 0x0080 - #define PMU_USB 0x8041 - #define PMU_SPI 0x0100 - #define PMU_LED 0x0800 -@@ -92,6 +93,10 @@ - #define LTQ_ETOP_BASE_ADDR 0x1E180000 - #define LTQ_ETOP_SIZE 0x40000 - -+/* GBIT - gigabit switch */ -+#define LTQ_GBIT_BASE_ADDR 0x1E108000 -+#define LTQ_GBIT_SIZE 0x200 -+ - /* DMA */ - #define LTQ_DMA_BASE_ADDR 0x1E104100 - #define LTQ_DMA_SIZE 0x800 -@@ -146,6 +151,11 @@ extern void ltq_pmu_enable(unsigned int - extern void ltq_pmu_disable(unsigned int module); - extern void ltq_cgu_enable(unsigned int clk); - -+static inline int ltq_is_ase(void) -+{ -+ return (ltq_get_soc_type() == SOC_TYPE_AMAZON_SE); -+} -+ - static inline int ltq_is_ar9(void) - { - return (ltq_get_soc_type() == SOC_TYPE_AR9); ---- a/arch/mips/lantiq/xway/devices.c -+++ b/arch/mips/lantiq/xway/devices.c -@@ -74,18 +74,23 @@ void __init ltq_register_ase_asc(void) - } - - /* ethernet */ --static struct resource ltq_etop_resources = -- MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE); -+static struct resource ltq_etop_resources[] = { -+ MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE), -+ MEM_RES("gbit", LTQ_GBIT_BASE_ADDR, LTQ_GBIT_SIZE), -+}; - - static struct platform_device ltq_etop = { - .name = "ltq_etop", -- .resource = <q_etop_resources, -+ .resource = ltq_etop_resources, - .num_resources = 1, - }; - - void __init - ltq_register_etop(struct ltq_eth_data *eth) - { -+ /* only register the gphy on socs that have one */ -+ if (ltq_is_ar9() | ltq_is_vr9()) -+ ltq_etop.num_resources = 2; - if (eth) { - ltq_etop.dev.platform_data = eth; - platform_device_register(<q_etop); ---- a/drivers/net/lantiq_etop.c -+++ b/drivers/net/lantiq_etop.c -@@ -34,6 +34,7 @@ - #include <linux/init.h> - #include <linux/delay.h> - #include <linux/io.h> -+#include <linux/dma-mapping.h> - - #include <asm/checksum.h> - -@@ -69,10 +70,43 @@ - #define ETOP_MII_REVERSE 0xe - #define ETOP_PLEN_UNDER 0x40 - #define ETOP_CGEN 0x800 -+#define ETOP_CFG_MII0 0x01 - --/* use 2 static channels for TX/RX */ -+#define LTQ_GBIT_MDIO_CTL 0xCC -+#define LTQ_GBIT_MDIO_DATA 0xd0 -+#define LTQ_GBIT_GCTL0 0x68 -+#define LTQ_GBIT_PMAC_HD_CTL 0x8c -+#define LTQ_GBIT_P0_CTL 0x4 -+#define LTQ_GBIT_PMAC_RX_IPG 0xa8 -+ -+#define PMAC_HD_CTL_AS (1 << 19) -+#define PMAC_HD_CTL_RXSH (1 << 22) -+ -+/* Switch Enable (0=disable, 1=enable) */ -+#define GCTL0_SE 0x80000000 -+/* Disable MDIO auto polling (0=disable, 1=enable) */ -+#define PX_CTL_DMDIO 0x00400000 -+ -+/* register information for the gbit's MDIO bus */ -+#define MDIO_XR9_REQUEST 0x00008000 -+#define MDIO_XR9_READ 0x00000800 -+#define MDIO_XR9_WRITE 0x00000400 -+#define MDIO_XR9_REG_MASK 0x1f -+#define MDIO_XR9_ADDR_MASK 0x1f -+#define MDIO_XR9_RD_MASK 0xffff -+#define MDIO_XR9_REG_OFFSET 0 -+#define MDIO_XR9_ADDR_OFFSET 5 -+#define MDIO_XR9_WR_OFFSET 16 -+ -+/* the newer xway socks have a embedded 3/7 port gbit multiplexer */ -+#define ltq_has_gbit() (ltq_is_ar9() || ltq_is_vr9()) -+ -+/* use 2 static channels for TX/RX -+ depending on the SoC we need to use different DMA channels for ethernet */ - #define LTQ_ETOP_TX_CHANNEL 1 --#define LTQ_ETOP_RX_CHANNEL 6 -+#define LTQ_ETOP_RX_CHANNEL ((ltq_is_ase()) ? (5) : \ -+ ((ltq_has_gbit()) ? (0) : (6))) -+ - #define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL) - #define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL) - -@@ -81,9 +115,15 @@ - #define ltq_etop_w32_mask(x, y, z) \ - ltq_w32_mask(x, y, ltq_etop_membase + (z)) - -+#define ltq_gbit_r32(x) ltq_r32(ltq_gbit_membase + (x)) -+#define ltq_gbit_w32(x, y) ltq_w32(x, ltq_gbit_membase + (y)) -+#define ltq_gbit_w32_mask(x, y, z) \ -+ ltq_w32_mask(x, y, ltq_gbit_membase + (z)) -+ - #define DRV_VERSION "1.0" - - static void __iomem *ltq_etop_membase; -+static void __iomem *ltq_gbit_membase; - - struct ltq_etop_chan { - int idx; -@@ -108,6 +148,9 @@ struct ltq_etop_priv { - spinlock_t lock; - }; - -+static int ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, -+ int phy_reg, u16 phy_data); -+ - static int - ltq_etop_alloc_skb(struct ltq_etop_chan *ch) - { -@@ -209,7 +252,7 @@ static irqreturn_t - ltq_etop_dma_irq(int irq, void *_priv) - { - struct ltq_etop_priv *priv = _priv; -- int ch = irq - LTQ_DMA_CH0_INT; -+ int ch = irq - LTQ_DMA_ETOP; - - napi_schedule(&priv->ch[ch].napi); - return IRQ_HANDLED; -@@ -242,26 +285,66 @@ ltq_etop_hw_exit(struct net_device *dev) - ltq_etop_free_channel(dev, &priv->ch[i]); - } - -+static void -+ltq_etop_gbit_init(void) -+{ -+ ltq_pmu_enable(PMU_SWITCH); -+ -+ ltq_gpio_request(42, 1, 0, 1, "MDIO"); -+ ltq_gpio_request(43, 1, 0, 1, "MDC"); -+ -+ ltq_gbit_w32_mask(0, GCTL0_SE, LTQ_GBIT_GCTL0); -+ /** Disable MDIO auto polling mode */ -+ ltq_gbit_w32_mask(0, PX_CTL_DMDIO, LTQ_GBIT_P0_CTL); -+ /* set 1522 packet size */ -+ ltq_gbit_w32_mask(0x300, 0, LTQ_GBIT_GCTL0); -+ /* disable pmac & dmac headers */ -+ ltq_gbit_w32_mask(PMAC_HD_CTL_AS | PMAC_HD_CTL_RXSH, 0, -+ LTQ_GBIT_PMAC_HD_CTL); -+ /* Due to traffic halt when burst length 8, -+ replace default IPG value with 0x3B */ -+ ltq_gbit_w32(0x3B, LTQ_GBIT_PMAC_RX_IPG); -+} -+ - static int - ltq_etop_hw_init(struct net_device *dev) - { - struct ltq_etop_priv *priv = netdev_priv(dev); -+ unsigned int mii_mode = priv->pldata->mii_mode; - int i; - - ltq_pmu_enable(PMU_PPE); - -- switch (priv->pldata->mii_mode) { -+ if (ltq_has_gbit()) { -+ ltq_etop_gbit_init(); -+ } -+ -+ switch (mii_mode) { -+ case PHY_INTERFACE_MODE_RGMII: - case PHY_INTERFACE_MODE_RMII: - ltq_etop_w32_mask(ETOP_MII_MASK, - ETOP_MII_REVERSE, LTQ_ETOP_CFG); - break; - -+ case PHY_INTERFACE_MODE_GMII: - case PHY_INTERFACE_MODE_MII: - ltq_etop_w32_mask(ETOP_MII_MASK, - ETOP_MII_NORMAL, LTQ_ETOP_CFG); - break; - - default: -+ if (ltq_is_ase()) { -+ ltq_pmu_enable(PMU_EPHY); -+ /* disable external MII */ -+ ltq_etop_w32_mask(0, ETOP_CFG_MII0, LTQ_ETOP_CFG); -+ /* enable clock for internal PHY */ -+ ltq_cgu_enable(CGU_EPHY); -+ /* we need to write this magic to the internal phy to -+ make it work */ -+ ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020); -+ pr_info("Selected EPHY mode\n"); -+ break; -+ } - netdev_err(dev, "unknown mii mode %d\n", - priv->pldata->mii_mode); - return -ENOTSUPP; -@@ -273,7 +356,7 @@ ltq_etop_hw_init(struct net_device *dev) - ltq_dma_init_port(DMA_PORT_ETOP); - - for (i = 0; i < MAX_DMA_CHAN; i++) { -- int irq = LTQ_DMA_CH0_INT + i; -+ int irq = LTQ_DMA_ETOP + i; - struct ltq_etop_chan *ch = &priv->ch[i]; - - ch->idx = ch->dma.nr = i; -@@ -337,6 +420,39 @@ static const struct ethtool_ops ltq_etop - }; - - static int -+ltq_etop_mdio_wr_xr9(struct mii_bus *bus, int phy_addr, -+ int phy_reg, u16 phy_data) -+{ -+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_WRITE | -+ (phy_data << MDIO_XR9_WR_OFFSET) | -+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) | -+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET); -+ -+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST) -+ ; -+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL); -+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST) -+ ; -+ return 0; -+} -+ -+static int -+ltq_etop_mdio_rd_xr9(struct mii_bus *bus, int phy_addr, int phy_reg) -+{ -+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_READ | -+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) | -+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET); -+ -+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST) -+ ; -+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL); -+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST) -+ ; -+ val = ltq_gbit_r32(LTQ_GBIT_MDIO_DATA) & MDIO_XR9_RD_MASK; -+ return val; -+} -+ -+static int - ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data) - { - u32 val = MDIO_REQUEST | -@@ -377,14 +493,11 @@ ltq_etop_mdio_probe(struct net_device *d - { - struct ltq_etop_priv *priv = netdev_priv(dev); - struct phy_device *phydev = NULL; -- int phy_addr; - -- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { -- if (priv->mii_bus->phy_map[phy_addr]) { -- phydev = priv->mii_bus->phy_map[phy_addr]; -- break; -- } -- } -+ if (ltq_is_ase()) -+ phydev = priv->mii_bus->phy_map[8]; -+ else -+ phydev = priv->mii_bus->phy_map[0]; - - if (!phydev) { - netdev_err(dev, "no PHY found\n"); -@@ -406,6 +519,9 @@ ltq_etop_mdio_probe(struct net_device *d - | SUPPORTED_Autoneg - | SUPPORTED_MII - | SUPPORTED_TP); -+ if (ltq_has_gbit()) -+ phydev->supported &= SUPPORTED_1000baseT_Half -+ | SUPPORTED_1000baseT_Full; - - phydev->advertising = phydev->supported; - priv->phydev = phydev; -@@ -431,8 +547,13 @@ ltq_etop_mdio_init(struct net_device *de - } - - priv->mii_bus->priv = dev; -- priv->mii_bus->read = ltq_etop_mdio_rd; -- priv->mii_bus->write = ltq_etop_mdio_wr; -+ if (ltq_has_gbit()) { -+ priv->mii_bus->read = ltq_etop_mdio_rd_xr9; -+ priv->mii_bus->write = ltq_etop_mdio_wr_xr9; -+ } else { -+ priv->mii_bus->read = ltq_etop_mdio_rd; -+ priv->mii_bus->write = ltq_etop_mdio_wr; -+ } - priv->mii_bus->name = "ltq_mii"; - snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0); - priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); -@@ -522,9 +643,9 @@ ltq_etop_tx(struct sk_buff *skb, struct - struct ltq_etop_priv *priv = netdev_priv(dev); - struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1]; - struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc]; -- int len; - unsigned long flags; - u32 byte_offset; -+ int len; - - len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; - -@@ -698,7 +819,7 @@ ltq_etop_probe(struct platform_device *p - { - struct net_device *dev; - struct ltq_etop_priv *priv; -- struct resource *res; -+ struct resource *res, *gbit_res; - int err; - int i; - -@@ -726,6 +847,23 @@ ltq_etop_probe(struct platform_device *p - goto err_out; - } - -+ if (ltq_has_gbit()) { -+ gbit_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ if (!gbit_res) { -+ dev_err(&pdev->dev, "failed to get gbit resource\n"); -+ err = -ENOENT; -+ goto err_out; -+ } -+ ltq_gbit_membase = devm_ioremap_nocache(&pdev->dev, -+ gbit_res->start, resource_size(gbit_res)); -+ if (!ltq_gbit_membase) { -+ dev_err(&pdev->dev, "failed to remap gigabit switch %d\n", -+ pdev->id); -+ err = -ENOMEM; -+ goto err_out; -+ } -+ } -+ - dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4); - strcpy(dev->name, "eth%d"); - dev->netdev_ops = <q_eth_netdev_ops; |