From: Jonas Gorski Date: Tue, 31 Jul 2012 14:27:31 +0000 (+0000) Subject: bcm63xx: update enetswitch driver X-Git-Tag: reboot~13244 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=94d257a851201a119ecf862e4f6012f7768de25d;p=oweals%2Fopenwrt.git bcm63xx: update enetswitch driver Update enetswith driver with latest fixes and additions. Signed-off-by: Jonas Gorski SVN-Revision: 32921 --- diff --git a/target/linux/brcm63xx/patches-3.3/416-bcm63xx_enet-fix-lockup-on-BCM6328.patch b/target/linux/brcm63xx/patches-3.3/416-bcm63xx_enet-fix-lockup-on-BCM6328.patch deleted file mode 100644 index b0f55e0866..0000000000 --- a/target/linux/brcm63xx/patches-3.3/416-bcm63xx_enet-fix-lockup-on-BCM6328.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 37d151859e09d09a950ad3ae615db1903bcc59d3 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Sun, 13 Nov 2011 14:59:37 +0100 -Subject: [PATCH 43/79] bcm63xx_enet: fix lockup on BCM6328 - -BCM6328 locks up on a maxburst size of 16, reduce it to 8 for BCM6328 and -BCM6368. - -Signed-off-by: Jonas Gorski ---- - drivers/net/ethernet/broadcom/bcm63xx_enet.c | 14 ++++++++------ - drivers/net/ethernet/broadcom/bcm63xx_enet.h | 4 ++++ - 2 files changed, 12 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c -+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c -@@ -261,7 +261,6 @@ static int bcm_enet_refill_rx(struct net - if (!skb) - break; - priv->rx_skb[desc_idx] = skb; -- - p = dma_map_single(&priv->pdev->dev, skb->data, - priv->rx_skb_size, - DMA_FROM_DEVICE); -@@ -995,9 +994,9 @@ static int bcm_enet_open(struct net_devi - enet_writel(priv, priv->hw_mtu, ENET_TXMAXLEN_REG); - - /* set dma maximum burst len */ -- enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, -+ enet_dmac_writel(priv, priv->dma_maxburst, - ENETDMAC_MAXBURST_REG(priv->rx_chan)); -- enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, -+ enet_dmac_writel(priv, priv->dma_maxburst, - ENETDMAC_MAXBURST_REG(priv->tx_chan)); - - /* set correct transmit fifo watermark */ -@@ -1593,7 +1592,7 @@ static int compute_hw_mtu(struct bcm_ene - * it's appended - */ - priv->rx_skb_size = ALIGN(actual_mtu + ETH_FCS_LEN, -- BCMENET_DMA_MAXBURST * 4); -+ priv->dma_maxburst * 4); - return 0; - } - -@@ -1700,6 +1699,8 @@ static int __devinit bcm_enet_probe(stru - return -ENOMEM; - priv = netdev_priv(dev); - -+ priv->dma_maxburst = bcm_enet_is_sw(priv) ? -+ BCMENETSW_DMA_MAXBURST : BCMENET_DMA_MAXBURST; - ret = compute_hw_mtu(priv, dev->mtu); - if (ret) - goto out; -@@ -2263,9 +2264,9 @@ static int bcm_enetsw_open(struct net_de - enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG(priv->tx_chan)); - - /* set dma maximum burst len */ -- enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, -+ enet_dmac_writel(priv, priv->dma_maxburst, - ENETDMAC_MAXBURST_REG(priv->rx_chan)); -- enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, -+ enet_dmac_writel(priv, priv->dma_maxburst, - ENETDMAC_MAXBURST_REG(priv->tx_chan)); - - /* set flow control low/high threshold to 1/3 / 2/3 */ -@@ -2727,6 +2728,7 @@ static int __devinit bcm_enetsw_probe(st - priv->irq_tx = irq_tx; - priv->rx_ring_size = BCMENET_DEF_RX_DESC; - priv->tx_ring_size = BCMENET_DEF_TX_DESC; -+ priv->dma_maxburst = BCMENETSW_DMA_MAXBURST; - - pd = pdev->dev.platform_data; - if (pd) { ---- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h -+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h -@@ -17,6 +17,7 @@ - - /* maximum burst len for dma (4 bytes unit) */ - #define BCMENET_DMA_MAXBURST 16 -+#define BCMENETSW_DMA_MAXBURST 8 - - /* tx transmit threshold (4 bytes unit), fifo is 256 bytes, the value - * must be low enough so that a DMA transfer of above burst length can -@@ -280,6 +281,9 @@ struct bcm_enet_priv { - /* number of dma desc in tx ring */ - int tx_ring_size; - -+ /* maximum dma burst size */ -+ int dma_maxburst; -+ - /* cpu view of rx dma ring */ - struct bcm_enet_desc *tx_desc_cpu; - diff --git a/target/linux/brcm63xx/patches-3.3/416-bcm63xx_enet-reset-port-link-state-in-bcm_enetsw_ope.patch b/target/linux/brcm63xx/patches-3.3/416-bcm63xx_enet-reset-port-link-state-in-bcm_enetsw_ope.patch new file mode 100644 index 0000000000..6d8e5a72db --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/416-bcm63xx_enet-reset-port-link-state-in-bcm_enetsw_ope.patch @@ -0,0 +1,28 @@ +From 6d5c5bb13db3fd8e3dd0b82742b3957f41a4a3ac Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Thu, 24 May 2012 20:38:58 +0200 +Subject: [PATCH] bcm63xx_enet: reset port link state in bcm_enetsw_open + +bcm_enetsw_open disables all ports, but does not reset their link state. +This results in connected ports staying disabled after a ifdown/ifup +cycle, since bcm_enetsw_phy_poll only enables them if their current state +is different from the stored link state. + +Fix this by also resetting the port link state. + +Signed-off-by: Jonas Gorski +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -2213,6 +2213,8 @@ static int bcm_enetsw_open(struct net_de + enetsw_writeb(priv, ENETSW_PTCTRL_RXDIS_MASK | + ENETSW_PTCTRL_TXDIS_MASK, + ENETSW_PTCTRL_REG(i)); ++ ++ priv->sw_port_link[i] = 0; + } + + /* reset mib */ diff --git a/target/linux/brcm63xx/patches-3.3/417-MIPS-BCM63XX-add-support-for-BCM6328-in-bcm_enetsw.patch b/target/linux/brcm63xx/patches-3.3/417-MIPS-BCM63XX-add-support-for-BCM6328-in-bcm_enetsw.patch deleted file mode 100644 index cf77679d24..0000000000 --- a/target/linux/brcm63xx/patches-3.3/417-MIPS-BCM63XX-add-support-for-BCM6328-in-bcm_enetsw.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 44e21f4c7c556573fff0432f7846086763df3455 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Tue, 14 Jun 2011 21:14:39 +0200 -Subject: [PATCH 44/79] MIPS: BCM63XX: add support for BCM6328 in bcm_enetsw - -Signed-off-by: Jonas Gorski ---- - arch/mips/bcm63xx/clk.c | 34 +++++++++++++++++++------- - arch/mips/bcm63xx/dev-enet.c | 4 +-- - drivers/net/ethernet/broadcom/bcm63xx_enet.h | 2 +- - 3 files changed, 28 insertions(+), 12 deletions(-) - ---- a/arch/mips/bcm63xx/clk.c -+++ b/arch/mips/bcm63xx/clk.c -@@ -118,21 +118,37 @@ static struct clk clk_ephy = { - */ - static void enetsw_set(struct clk *clk, int enable) - { -- if (!BCMCPU_IS_6368()) -+ u32 mask; -+ -+ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6368()) - return; -- bcm_hwclock_set(CKCTL_6368_ROBOSW_EN | -- CKCTL_6368_SWPKT_USB_EN | -- CKCTL_6368_SWPKT_SAR_EN, enable); -+ -+ if (BCMCPU_IS_6328()) -+ mask = CKCTL_6328_ROBOSW_EN; -+ else -+ mask = CKCTL_6368_ROBOSW_EN | CKCTL_6368_SWPKT_USB_EN | -+ CKCTL_6368_SWPKT_SAR_EN; -+ -+ bcm_hwclock_set(mask, enable); - if (enable) { -+ u32 reg; - u32 val; - -+ if (BCMCPU_IS_6328()) { -+ reg = PERF_SOFTRESET_6328_REG; -+ mask = SOFTRESET_6328_ENETSW_MASK; -+ } else { -+ reg = PERF_SOFTRESET_6368_REG; -+ mask = SOFTRESET_6368_ENETSW_MASK; -+ } -+ - /* reset switch core afer clock change */ -- val = bcm_perf_readl(PERF_SOFTRESET_6368_REG); -- val &= ~SOFTRESET_6368_ENETSW_MASK; -- bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); -+ val = bcm_perf_readl(reg); -+ val &= ~mask; -+ bcm_perf_writel(val, reg); - msleep(10); -- val |= SOFTRESET_6368_ENETSW_MASK; -- bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); -+ val |= mask; -+ bcm_perf_writel(val, reg); - msleep(10); - } - } ---- a/arch/mips/bcm63xx/dev-enet.c -+++ b/arch/mips/bcm63xx/dev-enet.c -@@ -141,7 +141,7 @@ static int __init register_shared(void) - shared_res[0].end = shared_res[0].start; - shared_res[0].end += (RSET_ENETDMA_SIZE) - 1; - -- if (BCMCPU_IS_6368()) -+ if (BCMCPU_IS_6328() || BCMCPU_IS_6368()) - chan_count = 32; - else - chan_count = 16; -@@ -224,7 +224,7 @@ bcm63xx_enetsw_register(const struct bcm - { - int ret; - -- if (!BCMCPU_IS_6368()) -+ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6368()) - return -ENODEV; - - ret = register_shared(); ---- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h -+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h -@@ -368,7 +368,7 @@ struct bcm_enet_priv { - - static inline int bcm_enet_is_sw(struct bcm_enet_priv *priv) - { -- if (BCMCPU_IS_6368()) -+ if (BCMCPU_IS_6328() || BCMCPU_IS_6368()) - return 1; - else - return 0; diff --git a/target/linux/brcm63xx/patches-3.3/417-bcm63xx_enet-don-t-overwrite-settings-when-setting-d.patch b/target/linux/brcm63xx/patches-3.3/417-bcm63xx_enet-don-t-overwrite-settings-when-setting-d.patch new file mode 100644 index 0000000000..407c8169ec --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/417-bcm63xx_enet-don-t-overwrite-settings-when-setting-d.patch @@ -0,0 +1,20 @@ +From e79bc74f76361020d820ed4611d28f70ebd845ca Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Tue, 10 Jul 2012 10:44:09 +0200 +Subject: [PATCH 34/84] bcm63xx_enet: don't overwrite settings when setting duplex on force + +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -2333,7 +2333,7 @@ static int bcm_enetsw_open(struct net_de + } + + if (port->force_duplex_full) +- override = ENETSW_IMPOV_FDX_MASK; ++ override |= ENETSW_IMPOV_FDX_MASK; + + + enetsw_writeb(priv, override, ENETSW_PORTOV_REG(i)); diff --git a/target/linux/brcm63xx/patches-3.3/418-MIPS-BCM63XX-add-HS-SPI-platform-device-and-register.patch b/target/linux/brcm63xx/patches-3.3/418-MIPS-BCM63XX-add-HS-SPI-platform-device-and-register.patch deleted file mode 100644 index 5b25344671..0000000000 --- a/target/linux/brcm63xx/patches-3.3/418-MIPS-BCM63XX-add-HS-SPI-platform-device-and-register.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 56be5a2d7e08faa7bb306faaf352ac4e6ac52c01 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Sat, 12 Nov 2011 12:18:26 +0100 -Subject: [PATCH 26/60] MIPS: BCM63XX: add HS SPI platform device and register it - -Signed-off-by: Jonas Gorski ---- - arch/mips/bcm63xx/Makefile | 5 +- - arch/mips/bcm63xx/boards/board_bcm963xx.c | 2 + - arch/mips/bcm63xx/dev-hsspi.c | 57 ++++++++++++++++++++ - .../include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h | 20 +++++++ - 4 files changed, 82 insertions(+), 2 deletions(-) - create mode 100644 arch/mips/bcm63xx/dev-hsspi.c - create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h - ---- a/arch/mips/bcm63xx/Makefile -+++ b/arch/mips/bcm63xx/Makefile -@@ -1,6 +1,7 @@ - obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ -- dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o dev-rng.o \ -- dev-spi.o dev-uart.o dev-usb-ehci.o dev-usb-ohci.o dev-wdt.o -+ dev-dsp.o dev-enet.o dev-flash.o dev-hsspi.o dev-pcmcia.o \ -+ dev-rng.o dev-spi.o dev-uart.o dev-usb-ehci.o \ -+ dev-usb-ohci.o dev-wdt.o - obj-$(CONFIG_EARLY_PRINTK) += early_printk.o - - obj-y += boards/ ---- a/arch/mips/bcm63xx/boards/board_bcm963xx.c -+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -945,6 +946,7 @@ int __init board_register_devices(void) - pr_err(PFX "failed to register fallback SPROM\n"); - } - #endif -+ bcm63xx_hsspi_register(); - - bcm63xx_spi_register(); - ---- /dev/null -+++ b/arch/mips/bcm63xx/dev-hsspi.c -@@ -0,0 +1,57 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2012 Jonas Gorski -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+static struct resource spi_resources[] = { -+ { -+ .start = -1, /* filled at runtime */ -+ .end = -1, /* filled at runtime */ -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .start = -1, /* filled at runtime */ -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static struct bcm63xx_hsspi_pdata spi_pdata = { -+ .bus_num = 0, -+}; -+ -+static struct platform_device bcm63xx_hsspi_device = { -+ .name = "bcm63xx-hsspi", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(spi_resources), -+ .resource = spi_resources, -+ .dev = { -+ .platform_data = &spi_pdata, -+ }, -+}; -+ -+int __init bcm63xx_hsspi_register(void) -+{ -+ -+ if (!BCMCPU_IS_6328()) -+ return -ENODEV; -+ -+ spi_resources[0].start = bcm63xx_regset_address(RSET_HSSPI); -+ spi_resources[0].end = spi_resources[0].start; -+ spi_resources[0].end += RSET_HSSPI_SIZE - 1; -+ spi_resources[1].start = bcm63xx_get_irq_number(IRQ_HSSPI); -+ -+ spi_pdata.speed_hz = HSSPI_PLL_HZ_6328; -+ -+ return platform_device_register(&bcm63xx_hsspi_device); -+} ---- /dev/null -+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h -@@ -0,0 +1,20 @@ -+#ifndef BCM63XX_DEV_HSSPI_H -+#define BCM63XX_DEV_HSSPI_H -+ -+#include -+#include -+#include -+ -+int __init bcm63xx_hsspi_register(void); -+ -+struct bcm63xx_hsspi_pdata { -+ int bus_num; -+ u32 speed_hz; -+}; -+ -+#define bcm_hsspi_readl(o) bcm_rset_readl(RSET_HSSPI, (o)) -+#define bcm_hsspi_writel(v, o) bcm_rset_writel(RSET_HSSPI, (v), (o)) -+ -+#define HSSPI_PLL_HZ_6328 133333333 -+ -+#endif /* BCM63XX_DEV_HSSPI_H */ diff --git a/target/linux/brcm63xx/patches-3.3/418-bcm63xx_enet-store-the-number-of-ports-instead-of-ha.patch b/target/linux/brcm63xx/patches-3.3/418-bcm63xx_enet-store-the-number-of-ports-instead-of-ha.patch new file mode 100644 index 0000000000..232668b7c9 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/418-bcm63xx_enet-store-the-number-of-ports-instead-of-ha.patch @@ -0,0 +1,98 @@ +From efe31ec8fca92162fc21630611971345014a81a0 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Tue, 10 Jul 2012 10:39:30 +0200 +Subject: [PATCH 33/84] bcm63xx_enet: store the number of ports instead of hardcoding them + +This will be needed for devices with a different number of ports +--- + arch/mips/bcm63xx/dev-enet.c | 2 ++ + .../include/asm/mach-bcm63xx/bcm63xx_dev_enet.h | 2 ++ + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 9 +++++---- + drivers/net/ethernet/broadcom/bcm63xx_enet.h | 1 + + 4 files changed, 10 insertions(+), 4 deletions(-) + +--- a/arch/mips/bcm63xx/dev-enet.c ++++ b/arch/mips/bcm63xx/dev-enet.c +@@ -239,6 +239,8 @@ bcm63xx_enetsw_register(const struct bcm + + memcpy(bcm63xx_enetsw_device.dev.platform_data, pd, sizeof (*pd)); + ++ enetsw_pd.num_ports = ENETSW_PORTS_6368; ++ + ret = platform_device_register(&bcm63xx_enetsw_device); + if (ret) + return ret; +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h +@@ -43,6 +43,7 @@ struct bcm63xx_enet_platform_data { + * on board ethernet switch platform data + */ + #define ENETSW_MAX_PORT 6 ++#define ENETSW_PORTS_6368 6 /* 4 FE PHY + 2 RGMII */ + + struct bcm63xx_enetsw_port { + int used; +@@ -58,6 +59,7 @@ struct bcm63xx_enetsw_port { + + struct bcm63xx_enetsw_platform_data { + char mac_addr[ETH_ALEN]; ++ int num_ports; + struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT]; + }; + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -2041,7 +2041,7 @@ static void swphy_poll_timer(unsigned lo + struct bcm_enet_priv *priv = (struct bcm_enet_priv *)data; + unsigned int i; + +- for (i = 0; i < ARRAY_SIZE(priv->used_ports); i++) { ++ for (i = 0; i < priv->num_ports; i++) { + struct bcm63xx_enetsw_port *port; + int val, j, up, advertise, lpa, lpa2, speed, duplex, media; + u8 override; +@@ -2207,7 +2207,7 @@ static int bcm_enetsw_open(struct net_de + priv->rx_curr_desc = 0; + + /* disable all ports */ +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < priv->num_ports; i++) { + enetsw_writeb(priv, ENETSW_PORTOV_ENABLE_MASK, + ENETSW_PORTOV_REG(i)); + enetsw_writeb(priv, ENETSW_PTCTRL_RXDIS_MASK | +@@ -2303,7 +2303,7 @@ static int bcm_enetsw_open(struct net_de + /* + * apply override config for bypass_link ports here. + */ +- for (i = 0; i < ARRAY_SIZE(priv->used_ports); i++) { ++ for (i = 0; i < priv->num_ports; i++) { + struct bcm63xx_enetsw_port *port; + u8 override; + port = &priv->used_ports[i]; +@@ -2447,7 +2447,7 @@ static int bcm_enetsw_phy_is_external(st + { + int i; + +- for (i = 0; i < (int)ARRAY_SIZE(priv->used_ports); ++i) { ++ for (i = 0; i < priv->num_ports; ++i) { + if (!priv->used_ports[i].used) + continue; + if (priv->used_ports[i].phy_id == phy_id) +@@ -2735,6 +2735,7 @@ static int __devinit bcm_enetsw_probe(st + memcpy(dev->dev_addr, pd->mac_addr, ETH_ALEN); + memcpy(priv->used_ports, pd->used_ports, + sizeof (pd->used_ports)); ++ priv->num_ports = pd->num_ports; + } + + ret = compute_hw_mtu(priv, dev->mtu); +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h +@@ -354,6 +354,7 @@ struct bcm_enet_priv { + unsigned int hw_mtu; + + /* port mapping for switch devices */ ++ int num_ports; + struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT]; + int sw_port_link[ENETSW_MAX_PORT]; + diff --git a/target/linux/brcm63xx/patches-3.3/419-SPI-MIPS-BCM63XX-Add-HS-SPI-driver.patch b/target/linux/brcm63xx/patches-3.3/419-SPI-MIPS-BCM63XX-Add-HS-SPI-driver.patch deleted file mode 100644 index 739c2c60f7..0000000000 --- a/target/linux/brcm63xx/patches-3.3/419-SPI-MIPS-BCM63XX-Add-HS-SPI-driver.patch +++ /dev/null @@ -1,481 +0,0 @@ -From 4b27423676485d05bcd6fc6f3809164fb8f9d22d Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Sat, 12 Nov 2011 12:19:55 +0100 -Subject: [PATCH 30/60] SPI: MIPS: BCM63XX: Add HSSPI driver - -Add a driver for the High Speed SPI controller found on newer BCM63XX SoCs. - -Signed-off-by: Jonas Gorski ---- - .../include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h | 2 + - drivers/spi/Kconfig | 7 + - drivers/spi/Makefile | 1 + - drivers/spi/spi-bcm63xx-hsspi.c | 427 ++++++++++++++++++++ - 4 files changed, 437 insertions(+), 0 deletions(-) - create mode 100644 drivers/spi/spi-bcm63xx-hsspi.c - ---- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h -+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h -@@ -17,4 +17,6 @@ struct bcm63xx_hsspi_pdata { - - #define HSSPI_PLL_HZ_6328 133333333 - -+#define HSSPI_BUFFER_LEN 512 -+ - #endif /* BCM63XX_DEV_HSSPI_H */ ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -100,6 +100,13 @@ config SPI_BCM63XX - help - Enable support for the SPI controller on the Broadcom BCM63xx SoCs. - -+config SPI_BCM63XX_HSSPI -+ tristate "Broadcom BCM63XX HS SPI controller driver" -+ depends on BCM63XX -+ help -+ This enables support for the High Speed SPI controller present on -+ newer Broadcom BCM63XX SoCs. -+ - config SPI_BITBANG - tristate "Utilities for Bitbanging SPI masters" - help ---- a/drivers/spi/Makefile -+++ b/drivers/spi/Makefile -@@ -15,6 +15,7 @@ obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o - obj-$(CONFIG_SPI_ATH79) += spi-ath79.o - obj-$(CONFIG_SPI_AU1550) += spi-au1550.o - obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o -+obj-$(CONFIG_SPI_BCM63XX_HSSPI) += spi-bcm63xx-hsspi.o - obj-$(CONFIG_SPI_BFIN) += spi-bfin5xx.o - obj-$(CONFIG_SPI_BFIN_SPORT) += spi-bfin-sport.o - obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o ---- /dev/null -+++ b/drivers/spi/spi-bcm63xx-hsspi.c -@@ -0,0 +1,427 @@ -+/* -+ * Broadcom BCM63XX High Speed SPI Controller driver -+ * -+ * Copyright 2000-2010 Broadcom Corporation -+ * Copyright 2012 Jonas Gorski -+ * -+ * Licensed under the GNU/GPL. See COPYING for details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define HSSPI_OP_CODE_SHIFT 13 -+#define HSSPI_OP_SLEEP (0 << HSSPI_OP_CODE_SHIFT) -+#define HSSPI_OP_READ_WRITE (1 << HSSPI_OP_CODE_SHIFT) -+#define HSSPI_OP_WRITE (2 << HSSPI_OP_CODE_SHIFT) -+#define HSSPI_OP_READ (3 << HSSPI_OP_CODE_SHIFT) -+ -+#define HSSPI_MAX_PREPEND_LEN 15 -+ -+#define HSSPI_MAX_SYNC_CLOCK 30000000 -+ -+struct bcm63xx_hsspi { -+ struct completion done; -+ struct spi_transfer *curr_trans; -+ -+ struct platform_device *pdev; -+ struct clk *clk; -+ void __iomem *regs; -+ u8 __iomem *fifo; -+ -+ u32 speed_hz; -+ int irq; -+}; -+ -+static void bcm63xx_hsspi_set_clk(struct bcm63xx_hsspi *bs, int hz, -+ int profile) -+{ -+ u32 reg; -+ -+ reg = DIV_ROUND_UP(2048, DIV_ROUND_UP(bs->speed_hz, hz)); -+ bcm_hsspi_writel(CLK_CTRL_ACCUM_RST_ON_LOOP | reg, -+ HSSPI_PROFILE_CLK_CTRL_REG(profile)); -+ -+ reg = bcm_hsspi_readl(HSSPI_PROFILE_SIGNAL_CTRL_REG(profile)); -+ if (hz > HSSPI_MAX_SYNC_CLOCK) -+ reg |= SIGNAL_CTRL_ASYNC_INPUT_PATH; -+ else -+ reg &= ~SIGNAL_CTRL_ASYNC_INPUT_PATH; -+ bcm_hsspi_writel(reg, HSSPI_PROFILE_SIGNAL_CTRL_REG(profile)); -+} -+ -+static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, -+ struct spi_transfer *t1, -+ struct spi_transfer *t2) -+{ -+ struct bcm63xx_hsspi *bs = spi_master_get_devdata(spi->master); -+ u8 chip_select = spi->chip_select; -+ u16 opcode = 0; -+ int len, prepend_size = 0; -+ -+ init_completion(&bs->done); -+ -+ bs->curr_trans = t2 ? t2 : t1; -+ bcm63xx_hsspi_set_clk(bs, bs->curr_trans->speed_hz, chip_select); -+ -+ if (t2 && !t2->tx_buf) -+ prepend_size = t1->len; -+ -+ bcm_hsspi_writel(prepend_size << MODE_CTRL_PREPENDBYTE_CNT_SHIFT | -+ 2 << MODE_CTRL_MULTIDATA_WR_STRT_SHIFT | -+ 2 << MODE_CTRL_MULTIDATA_RD_STRT_SHIFT | 0xff, -+ HSSPI_PROFILE_MODE_CTRL_REG(chip_select)); -+ -+ if (t1->rx_buf && t1->tx_buf) -+ opcode = HSSPI_OP_READ_WRITE; -+ else if (t1->rx_buf || (t2 && t2->rx_buf)) -+ opcode = HSSPI_OP_READ; -+ else if (t1->tx_buf) -+ opcode = HSSPI_OP_WRITE; -+ -+ if (opcode == HSSPI_OP_READ && t2) -+ len = t2->len; -+ else -+ len = t1->len; -+ -+ if (t1->tx_buf) { -+ memcpy_toio(bs->fifo + 2, t1->tx_buf, t1->len); -+ if (t2 && t2->tx_buf) { -+ memcpy_toio(bs->fifo + 2 + t1->len, -+ t2->tx_buf, t2->len); -+ len += t2->len; -+ } -+ } -+ -+ opcode |= len; -+ memcpy_toio(bs->fifo, &opcode, sizeof(opcode)); -+ -+ /* enable interrupt */ -+ bcm_hsspi_writel(HSSPI_PING0_CMD_DONE, HSSPI_INT_MASK_REG); -+ -+ /* start the transfer */ -+ bcm_hsspi_writel(chip_select << PINGPONG_CMD_SS_SHIFT | -+ chip_select << PINGPONG_CMD_PROFILE_SHIFT | -+ PINGPONG_COMMAND_START_NOW, -+ HSSPI_PINGPONG_COMMAND_REG(0)); -+ -+ if (wait_for_completion_timeout(&bs->done, HZ) == 0) { -+ dev_err(&bs->pdev->dev, "transfer timed out!\n"); -+ return -ETIMEDOUT; -+ } -+ -+ return t1->len + (t2 ? t2->len : 0); -+} -+ -+static int bcm63xx_hsspi_setup(struct spi_device *spi) -+{ -+ u32 reg; -+ -+ if (spi->bits_per_word != 8) -+ return -EINVAL; -+ -+ if (spi->max_speed_hz == 0) -+ return -EINVAL; -+ -+ reg = bcm_hsspi_readl(HSSPI_PROFILE_SIGNAL_CTRL_REG(spi->chip_select)); -+ reg &= ~(SIGNAL_CTRL_LAUNCH_RISING | SIGNAL_CTRL_LATCH_RISING); -+ if (spi->mode & SPI_CPHA) -+ reg |= SIGNAL_CTRL_LAUNCH_RISING; -+ else -+ reg |= SIGNAL_CTRL_LATCH_RISING; -+ bcm_hsspi_writel(reg, HSSPI_PROFILE_SIGNAL_CTRL_REG(spi->chip_select)); -+ -+ return 0; -+} -+ -+static int bcm63xx_hsspi_transfer_one(struct spi_master *master, -+ struct spi_message *msg) -+{ -+ struct spi_transfer *t, *prev = NULL; -+ struct spi_device *spi = msg->spi; -+ u32 reg; -+ int ret = -EINVAL; -+ int len = 0; -+ -+ /* check if we are able to make these transfers */ -+ list_for_each_entry(t, &msg->transfers, transfer_list) { -+ if (!t->tx_buf && !t->rx_buf) -+ goto out; -+ -+ if (t->speed_hz == 0) -+ t->speed_hz = spi->max_speed_hz; -+ -+ if (t->speed_hz > spi->max_speed_hz) -+ goto out; -+ -+ if (t->len > HSSPI_BUFFER_LEN) -+ goto out; -+ -+ /* -+ * This controller does not support keeping the chip select -+ * active between transfers. -+ * This logic currently supports combining: -+ * write then read with no cs_change (e.g. m25p80 RDSR) -+ * write then write with no cs_change (e.g. m25p80 PP) -+ */ -+ if (prev && prev->tx_buf && !prev->cs_change && !t->cs_change) { -+ /* -+ * reject if we have to combine two tx transfers and -+ * their combined length is bigger than the buffer -+ */ -+ if (prev->tx_buf && t->tx_buf && -+ (prev->len + t->len) > HSSPI_BUFFER_LEN) -+ goto out; -+ /* -+ * reject if we need write more than 15 bytes in read -+ * then write. -+ */ -+ if (prev->tx_buf && t->rx_buf && -+ prev->len > HSSPI_MAX_PREPEND_LEN) -+ goto out; -+ } -+ -+ } -+ -+ /* setup clock polarity */ -+ reg = bcm_hsspi_readl(HSSPI_GLOBAL_CTRL_REG); -+ reg &= ~GLOBAL_CTRL_CLK_POLARITY; -+ if (spi->mode & SPI_CPOL) -+ reg |= GLOBAL_CTRL_CLK_POLARITY; -+ bcm_hsspi_writel(reg, HSSPI_GLOBAL_CTRL_REG); -+ -+ list_for_each_entry(t, &msg->transfers, transfer_list) { -+ if (prev && prev->tx_buf && !prev->cs_change && !t->cs_change) { -+ /* combine write with following transfer */ -+ ret = bcm63xx_hsspi_do_txrx(msg->spi, prev, t); -+ if (ret < 0) -+ goto out; -+ -+ len += ret; -+ prev = NULL; -+ continue; -+ } -+ -+ /* write the previous pending transfer */ -+ if (prev != NULL) { -+ ret = bcm63xx_hsspi_do_txrx(msg->spi, prev, NULL); -+ if (ret < 0) -+ goto out; -+ -+ len += ret; -+ } -+ -+ prev = t; -+ } -+ -+ /* do last pending transfer */ -+ if (prev != NULL) { -+ ret = bcm63xx_hsspi_do_txrx(msg->spi, prev, NULL); -+ if (ret < 0) -+ goto out; -+ len += ret; -+ } -+ -+ msg->actual_length = len; -+ ret = 0; -+out: -+ msg->status = ret; -+ spi_finalize_current_message(master); -+ return 0; -+} -+ -+static irqreturn_t bcm63xx_hsspi_interrupt(int irq, void *dev_id) -+{ -+ struct spi_master *master = (struct spi_master *)dev_id; -+ struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); -+ -+ if (bcm_hsspi_readl(HSSPI_INT_STATUS_MASKED_REG) == 0) -+ return IRQ_NONE; -+ -+ bcm_hsspi_writel(HSSPI_INT_CLEAR_ALL, HSSPI_INT_STATUS_REG); -+ bcm_hsspi_writel(0, HSSPI_INT_MASK_REG); -+ -+ if (bs->curr_trans && bs->curr_trans->rx_buf) -+ memcpy_fromio(bs->curr_trans->rx_buf, bs->fifo, -+ bs->curr_trans->len); -+ complete(&bs->done); -+ -+ return IRQ_HANDLED; -+} -+ -+static int __devinit bcm63xx_hsspi_probe(struct platform_device *pdev) -+{ -+ -+ struct spi_master *master; -+ struct bcm63xx_hsspi *bs; -+ struct resource *res_mem; -+ void __iomem *regs; -+ struct device *dev = &pdev->dev; -+ struct bcm63xx_hsspi_pdata *pdata = pdev->dev.platform_data; -+ struct clk *clk; -+ int irq; -+ int ret; -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ dev_err(dev, "no irq\n"); -+ return -ENXIO; -+ } -+ -+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ regs = devm_request_and_ioremap(dev, res_mem); -+ if (!regs) { -+ dev_err(dev, "unable to ioremap regs\n"); -+ return -ENXIO; -+ } -+ -+ clk = clk_get(dev, "hsspi"); -+ -+ if (IS_ERR(clk)) { -+ ret = PTR_ERR(clk); -+ goto out_release; -+ } -+ -+ clk_prepare_enable(clk); -+ -+ master = spi_alloc_master(&pdev->dev, sizeof(*bs)); -+ if (!master) { -+ ret = -ENOMEM; -+ goto out_disable_clk; -+ } -+ -+ bs = spi_master_get_devdata(master); -+ bs->pdev = pdev; -+ bs->clk = clk; -+ bs->regs = regs; -+ -+ master->bus_num = pdata->bus_num; -+ master->num_chipselect = 8; -+ master->setup = bcm63xx_hsspi_setup; -+ master->transfer_one_message = bcm63xx_hsspi_transfer_one; -+ master->mode_bits = SPI_CPOL | SPI_CPHA; -+ -+ bs->speed_hz = pdata->speed_hz; -+ bs->fifo = (u8 __iomem *)(bs->regs + HSSPI_FIFO_REG(0)); -+ -+ platform_set_drvdata(pdev, master); -+ -+ bs->curr_trans = NULL; -+ -+ /* Initialize the hardware */ -+ bcm_hsspi_writel(0, HSSPI_INT_MASK_REG); -+ -+ /* clean up any pending interrupts */ -+ bcm_hsspi_writel(HSSPI_INT_CLEAR_ALL, HSSPI_INT_STATUS_REG); -+ -+ bcm_hsspi_writel(bcm_hsspi_readl(HSSPI_GLOBAL_CTRL_REG) | -+ GLOBAL_CTRL_CLK_GATE_SSOFF, -+ HSSPI_GLOBAL_CTRL_REG); -+ -+ ret = devm_request_irq(dev, irq, bcm63xx_hsspi_interrupt, IRQF_SHARED, -+ pdev->name, master); -+ -+ if (ret) -+ goto out_put_master; -+ -+ /* register and we are done */ -+ ret = spi_register_master(master); -+ if (ret) -+ goto out_free_irq; -+ -+ return 0; -+ -+out_free_irq: -+ devm_free_irq(dev, bs->irq, master); -+out_put_master: -+ spi_master_put(master); -+out_disable_clk: -+ clk_disable_unprepare(clk); -+ clk_put(clk); -+out_release: -+ devm_ioremap_release(dev, regs); -+ -+ return ret; -+} -+ -+ -+static int __exit bcm63xx_hsspi_remove(struct platform_device *pdev) -+{ -+ struct spi_master *master = platform_get_drvdata(pdev); -+ struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); -+ -+ spi_unregister_master(master); -+ -+ /* reset the hardware and block queue progress */ -+ bcm_hsspi_writel(0, HSSPI_INT_MASK_REG); -+ clk_disable_unprepare(bs->clk); -+ clk_put(bs->clk); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int bcm63xx_hsspi_suspend(struct platform_device *pdev, -+ pm_message_t mesg) -+{ -+ struct spi_master *master = platform_get_drvdata(pdev); -+ struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); -+ -+ spi_master_suspend(master); -+ clk_disable(bs->clk); -+ -+ return 0; -+} -+ -+static int bcm63xx_hsspi_resume(struct platform_device *pdev) -+{ -+ struct spi_master *master = platform_get_drvdata(pdev); -+ struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); -+ -+ clk_enable(bs->clk); -+ spi_master_resume(master); -+ -+ return 0; -+} -+ -+static const struct dev_pm_ops bcm63xx_hsspi_pm_ops = { -+ .suspend = bcm63xx_hsspi_suspend, -+ .resume = bcm63xx_hsspi_resume, -+}; -+ -+#define BCM63XX_HSSPI_PM_OPS (&bcm63xx_hsspi_pm_ops) -+#else -+#define BCM63XX_HSSPI_PM_OPS NULL -+#endif -+ -+ -+ -+static struct platform_driver bcm63xx_hsspi_driver = { -+ .driver = { -+ .name = "bcm63xx-hsspi", -+ .owner = THIS_MODULE, -+ .pm = BCM63XX_HSSPI_PM_OPS, -+ }, -+ .probe = bcm63xx_hsspi_probe, -+ .remove = __exit_p(bcm63xx_hsspi_remove), -+}; -+ -+module_platform_driver(bcm63xx_hsspi_driver); -+ -+MODULE_ALIAS("platform:bcm63xx_hsspi"); -+MODULE_DESCRIPTION("Broadcom BCM63xx HS SPI Controller driver"); -+MODULE_AUTHOR("Jonas Gorski "); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/brcm63xx/patches-3.3/419-bcm63xx_enet-store-is_sw-in-a-variable-instead-of-ch.patch b/target/linux/brcm63xx/patches-3.3/419-bcm63xx_enet-store-is_sw-in-a-variable-instead-of-ch.patch new file mode 100644 index 0000000000..6f73477ab3 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/419-bcm63xx_enet-store-is_sw-in-a-variable-instead-of-ch.patch @@ -0,0 +1,73 @@ +From ef581388c45dbc48f7bbe050e87deb1e3c63a698 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Tue, 10 Jul 2012 10:52:02 +0200 +Subject: [PATCH 35/84] bcm63xx_enet: store is_sw in a variable instead of checking the cpuid + +Reduces the number of changes needed for making enetsw work on new +chips. +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 7 +++++-- + drivers/net/ethernet/broadcom/bcm63xx_enet.h | 10 ++-------- + 2 files changed, 7 insertions(+), 10 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -364,7 +364,7 @@ static int bcm_enet_receive_queue(struct + } + + /* recycle packet if it's marked as bad */ +- if (!bcm_enet_is_sw(priv) && ++ if (!priv->enet_is_sw && + unlikely(len_stat & DMADESC_ERR_MASK)) { + dev->stats.rx_errors++; + +@@ -597,7 +597,7 @@ static int bcm_enet_start_xmit(struct sk + } + + /* pad small packets sent on a switch device */ +- if (bcm_enet_is_sw(priv) && skb->len < 64) { ++ if (priv->enet_is_sw && skb->len < 64) { + int needed = 64 - skb->len; + char *data; + +@@ -1700,6 +1700,8 @@ static int __devinit bcm_enet_probe(stru + return -ENOMEM; + priv = netdev_priv(dev); + ++ priv->enet_is_sw = false; ++ + ret = compute_hw_mtu(priv, dev->mtu); + if (ret) + goto out; +@@ -2725,6 +2727,7 @@ static int __devinit bcm_enetsw_probe(st + memset(priv, 0, sizeof(*priv)); + + /* initialize default and fetch platform data */ ++ priv->enet_is_sw = true; + priv->irq_rx = irq_rx; + priv->irq_tx = irq_tx; + priv->rx_ring_size = BCMENET_DEF_RX_DESC; +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h +@@ -353,6 +353,8 @@ struct bcm_enet_priv { + /* maximum hardware transmit/receive size */ + unsigned int hw_mtu; + ++ bool enet_is_sw; ++ + /* port mapping for switch devices */ + int num_ports; + struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT]; +@@ -363,12 +365,4 @@ struct bcm_enet_priv { + spinlock_t enetsw_mdio_lock; + }; + +-static inline int bcm_enet_is_sw(struct bcm_enet_priv *priv) +-{ +- if (BCMCPU_IS_6368()) +- return 1; +- else +- return 0; +-} +- + #endif /* ! BCM63XX_ENET_H_ */ diff --git a/target/linux/brcm63xx/patches-3.3/420-BCM63XX-allow-enetsw-without-tx-irq.patch b/target/linux/brcm63xx/patches-3.3/420-BCM63XX-allow-enetsw-without-tx-irq.patch new file mode 100644 index 0000000000..6396b626df --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/420-BCM63XX-allow-enetsw-without-tx-irq.patch @@ -0,0 +1,69 @@ +From 625894c377ba266c0044675b53f05d65db6355b6 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Sun, 8 Jul 2012 13:07:52 +0200 +Subject: [PATCH 38/84] BCM63XX: allow enetsw without tx irq + +--- + arch/mips/bcm63xx/dev-enet.c | 2 ++ + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 18 +++++++++++------- + 2 files changed, 13 insertions(+), 7 deletions(-) + +--- a/arch/mips/bcm63xx/dev-enet.c ++++ b/arch/mips/bcm63xx/dev-enet.c +@@ -236,6 +236,8 @@ bcm63xx_enetsw_register(const struct bcm + enetsw_res[0].end += RSET_ENETSW_SIZE - 1; + enetsw_res[1].start = bcm63xx_get_irq_number(IRQ_ENETSW_RXDMA0); + enetsw_res[2].start = bcm63xx_get_irq_number(IRQ_ENETSW_TXDMA0); ++ if (!enetsw_res[2].start) ++ enetsw_res[2].start = -1; + + memcpy(bcm63xx_enetsw_device.dev.platform_data, pd, sizeof (*pd)); + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -2151,10 +2151,12 @@ static int bcm_enetsw_open(struct net_de + if (ret) + goto out_freeirq; + +- ret = request_irq(priv->irq_tx, bcm_enet_isr_dma, +- IRQF_DISABLED, dev->name, dev); +- if (ret) +- goto out_freeirq_rx; ++ if (priv->irq_tx != -1) { ++ ret = request_irq(priv->irq_tx, bcm_enet_isr_dma, ++ IRQF_DISABLED, dev->name, dev); ++ if (ret) ++ goto out_freeirq_rx; ++ } + + /* allocate rx dma ring */ + size = priv->rx_ring_size * sizeof(struct bcm_enet_desc); +@@ -2376,7 +2378,8 @@ out_free_rx_ring: + priv->rx_desc_cpu, priv->rx_desc_dma); + + out_freeirq_tx: +- free_irq(priv->irq_tx, dev); ++ if (priv->irq_tx != -1) ++ free_irq(priv->irq_tx, dev); + + out_freeirq_rx: + free_irq(priv->irq_rx, dev); +@@ -2433,7 +2436,8 @@ static int bcm_enetsw_stop(struct net_de + priv->rx_desc_cpu, priv->rx_desc_dma); + dma_free_coherent(kdev, priv->tx_desc_alloc_size, + priv->tx_desc_cpu, priv->tx_desc_dma); +- free_irq(priv->irq_tx, dev); ++ if (priv->irq_tx != -1) ++ free_irq(priv->irq_tx, dev); + free_irq(priv->irq_rx, dev); + + return 0; +@@ -2716,7 +2720,7 @@ static int __devinit bcm_enetsw_probe(st + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq_rx = platform_get_irq(pdev, 0); + irq_tx = platform_get_irq(pdev, 1); +- if (!res_mem || irq_rx < 0 || irq_tx < 0) ++ if (!res_mem || irq_rx < 0) + return -ENODEV; + + ret = 0; diff --git a/target/linux/brcm63xx/patches-3.3/420-MIPS-BCM63XX-Register-SPI-flash-if-present.patch b/target/linux/brcm63xx/patches-3.3/420-MIPS-BCM63XX-Register-SPI-flash-if-present.patch deleted file mode 100644 index 49bbdf916b..0000000000 --- a/target/linux/brcm63xx/patches-3.3/420-MIPS-BCM63XX-Register-SPI-flash-if-present.patch +++ /dev/null @@ -1,102 +0,0 @@ -From d135d94b3d1fe599d13e7198d5f502912d694c13 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Sun, 3 Jul 2011 15:00:38 +0200 -Subject: [PATCH 29/60] MIPS: BCM63XX: Register SPI flash if present - -Signed-off-by: Jonas Gorski ---- - arch/mips/bcm63xx/dev-flash.c | 33 +++++++++++++++++++- - arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 2 + - 2 files changed, 33 insertions(+), 2 deletions(-) - ---- a/arch/mips/bcm63xx/dev-flash.c -+++ b/arch/mips/bcm63xx/dev-flash.c -@@ -16,9 +16,12 @@ - #include - #include - #include -+#include -+#include - - #include - #include -+#include - #include - #include - -@@ -55,6 +58,21 @@ static struct platform_device mtd_dev = - }, - }; - -+static struct flash_platform_data bcm63xx_flash_data = { -+ .part_probe_types = bcm63xx_part_types, -+}; -+ -+static struct spi_board_info bcm63xx_spi_flash_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .mode = 0, -+ .max_speed_hz = 781000, -+ .modalias = "m25p80", -+ .platform_data = &bcm63xx_flash_data, -+ }, -+}; -+ - static int __init bcm63xx_detect_flash_type(void) - { - u32 val; -@@ -62,6 +80,11 @@ static int __init bcm63xx_detect_flash_t - switch (bcm63xx_get_cpu_id()) { - case BCM6328_CPU_ID: - val = bcm_misc_readl(MISC_STRAPBUS_6328_REG); -+ if (val & STRAPBUS_6328_HSSPI_CLK_FAST) -+ bcm63xx_spi_flash_info[0].max_speed_hz = 33333334; -+ else -+ bcm63xx_spi_flash_info[0].max_speed_hz = 16666667; -+ - if (val & STRAPBUS_6328_BOOT_SEL_SERIAL) - return BCM63XX_FLASH_TYPE_SERIAL; - else -@@ -79,6 +102,9 @@ static int __init bcm63xx_detect_flash_t - return BCM63XX_FLASH_TYPE_SERIAL; - case BCM6368_CPU_ID: - val = bcm_gpio_readl(GPIO_STRAPBUS_REG); -+ if (val & STRAPBUS_6368_SPI_CLK_FAST) -+ bcm63xx_spi_flash_info[0].max_speed_hz = 20000000; -+ - switch (val & STRAPBUS_6368_BOOT_SEL_MASK) { - case STRAPBUS_6368_BOOT_SEL_NAND: - return BCM63XX_FLASH_TYPE_NAND; -@@ -110,8 +136,11 @@ int __init bcm63xx_flash_register(void) - - return platform_device_register(&mtd_dev); - case BCM63XX_FLASH_TYPE_SERIAL: -- pr_warn("unsupported serial flash detected\n"); -- return -ENODEV; -+ if (BCMCPU_IS_6328()) -+ bcm63xx_flash_data.max_transfer_len = HSSPI_BUFFER_LEN; -+ -+ return spi_register_board_info(bcm63xx_spi_flash_info, -+ ARRAY_SIZE(bcm63xx_spi_flash_info)); - case BCM63XX_FLASH_TYPE_NAND: - pr_warn("unsupported NAND flash detected\n"); - return -ENODEV; ---- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h -+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h -@@ -555,6 +555,7 @@ - #define GPIO_STRAPBUS_REG 0x40 - #define STRAPBUS_6358_BOOT_SEL_PARALLEL (1 << 1) - #define STRAPBUS_6358_BOOT_SEL_SERIAL (0 << 1) -+#define STRAPBUS_6368_SPI_CLK_FAST (1 << 6) - #define STRAPBUS_6368_BOOT_SEL_MASK 0x3 - #define STRAPBUS_6368_BOOT_SEL_NAND 0 - #define STRAPBUS_6368_BOOT_SEL_SERIAL 1 -@@ -1227,6 +1228,7 @@ - #define SERDES_PCIE_EXD_EN (1 << 15) - - #define MISC_STRAPBUS_6328_REG 0x240 -+#define STRAPBUS_6328_HSSPI_CLK_FAST (1 << 4) - #define STRAPBUS_6328_FCVO_SHIFT 7 - #define STRAPBUS_6328_FCVO_MASK (0x1f << STRAPBUS_6328_FCVO_SHIFT) - #define STRAPBUS_6328_BOOT_SEL_SERIAL (1 << 28) diff --git a/target/linux/brcm63xx/patches-3.3/421-BCM63XX-use-port-id-for-deciding-external-phy.patch b/target/linux/brcm63xx/patches-3.3/421-BCM63XX-use-port-id-for-deciding-external-phy.patch new file mode 100644 index 0000000000..da7013d8ff --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/421-BCM63XX-use-port-id-for-deciding-external-phy.patch @@ -0,0 +1,87 @@ +From 85e4551e033df7cb043e93042661fc1e58799efa Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Sun, 8 Jul 2012 15:36:23 +0200 +Subject: [PATCH 52/84] BCM63XX: use port id for deciding external phy + +Ports 0-3 always use the internal phy, while 4+ always need an external +phy to work. +--- + .../include/asm/mach-bcm63xx/bcm63xx_dev_enet.h | 3 ++- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 15 ++++++++------- + drivers/net/ethernet/broadcom/bcm63xx_enet.h | 5 +++++ + 3 files changed, 15 insertions(+), 8 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h +@@ -45,9 +45,10 @@ struct bcm63xx_enet_platform_data { + #define ENETSW_MAX_PORT 6 + #define ENETSW_PORTS_6368 6 /* 4 FE PHY + 2 RGMII */ + ++#define ENETSW_RGMII_PORT0 4 ++ + struct bcm63xx_enetsw_port { + int used; +- int external_phy; + int phy_id; + + int bypass_link; +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -2046,6 +2046,7 @@ static void swphy_poll_timer(unsigned lo + for (i = 0; i < priv->num_ports; i++) { + struct bcm63xx_enetsw_port *port; + int val, j, up, advertise, lpa, lpa2, speed, duplex, media; ++ int external_phy = bcm_enet_port_is_rgmii(i); + u8 override; + + port = &priv->used_ports[i]; +@@ -2057,7 +2058,7 @@ static void swphy_poll_timer(unsigned lo + + /* dummy read to clear */ + for (j = 0; j < 2; j++) +- val = bcmenet_sw_mdio_read(priv, port->external_phy, ++ val = bcmenet_sw_mdio_read(priv, external_phy, + port->phy_id, MII_BMSR); + + if (val == 0xffff) +@@ -2081,14 +2082,14 @@ static void swphy_poll_timer(unsigned lo + continue; + } + +- advertise = bcmenet_sw_mdio_read(priv, port->external_phy, ++ advertise = bcmenet_sw_mdio_read(priv, external_phy, + port->phy_id, MII_ADVERTISE); + +- lpa = bcmenet_sw_mdio_read(priv, port->external_phy, +- port->phy_id, MII_LPA); ++ lpa = bcmenet_sw_mdio_read(priv, external_phy, port->phy_id, ++ MII_LPA); + +- lpa2 = bcmenet_sw_mdio_read(priv, port->external_phy, +- port->phy_id, MII_STAT1000); ++ lpa2 = bcmenet_sw_mdio_read(priv, external_phy, port->phy_id, ++ MII_STAT1000); + + /* figure out media and duplex from advertise and LPA values */ + media = mii_nway_result(lpa & advertise); +@@ -2457,7 +2458,7 @@ static int bcm_enetsw_phy_is_external(st + if (!priv->used_ports[i].used) + continue; + if (priv->used_ports[i].phy_id == phy_id) +- return priv->used_ports[i].external_phy; ++ return bcm_enet_port_is_rgmii(i); + } + + printk_once(KERN_WARNING "bcm63xx_enet: could not find a used port " +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h +@@ -365,4 +365,9 @@ struct bcm_enet_priv { + spinlock_t enetsw_mdio_lock; + }; + ++static inline int bcm_enet_port_is_rgmii(int portid) ++{ ++ return portid >= ENETSW_RGMII_PORT0; ++} ++ + #endif /* ! BCM63XX_ENET_H_ */ diff --git a/target/linux/brcm63xx/patches-3.3/421-MIPS-BCM63XX-move-nvram-related-functions-into-their.patch b/target/linux/brcm63xx/patches-3.3/421-MIPS-BCM63XX-move-nvram-related-functions-into-their.patch deleted file mode 100644 index ff2a831d84..0000000000 --- a/target/linux/brcm63xx/patches-3.3/421-MIPS-BCM63XX-move-nvram-related-functions-into-their.patch +++ /dev/null @@ -1,351 +0,0 @@ -From 5b753c1d01c6af23d7d37d37d9de30da8a971084 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Sat, 12 May 2012 22:51:08 +0200 -Subject: [PATCH 60/79] MIPS: BCM63XX: move nvram related functions into their - own file - -Signed-off-by: Jonas Gorski ---- - arch/mips/bcm63xx/Makefile | 6 +- - arch/mips/bcm63xx/boards/board_bcm963xx.c | 74 +++-------------- - arch/mips/bcm63xx/nvram.c | 84 ++++++++++++++++++++ - arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h | 34 ++++++++ - .../mips/include/asm/mach-bcm63xx/board_bcm963xx.h | 17 ---- - 5 files changed, 134 insertions(+), 81 deletions(-) - create mode 100644 arch/mips/bcm63xx/nvram.c - create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h - ---- a/arch/mips/bcm63xx/Makefile -+++ b/arch/mips/bcm63xx/Makefile -@@ -1,6 +1,6 @@ --obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ -- dev-dsp.o dev-enet.o dev-flash.o dev-hsspi.o dev-pcmcia.o \ -- dev-rng.o dev-spi.o dev-uart.o dev-usb-ehci.o \ -+obj-y += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o setup.o \ -+ timer.o dev-dsp.o dev-enet.o dev-flash.o dev-hsspi.o \ -+ dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o dev-usb-ehci.o \ - dev-usb-ohci.o dev-wdt.o - obj-$(CONFIG_EARLY_PRINTK) += early_printk.o - ---- a/arch/mips/bcm63xx/boards/board_bcm963xx.c -+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -41,8 +42,6 @@ - #define CFE_OFFSET_64K 0x10000 - #define CFE_OFFSET_128K 0x20000 - --static struct bcm963xx_nvram nvram; --static unsigned int mac_addr_used; - static struct board_info board; - - /* -@@ -696,50 +695,16 @@ const char *board_get_name(void) - return board.name; - } - --/* -- * register & return a new board mac address -- */ --static int board_get_mac_address(u8 *mac) --{ -- u8 *p; -- int count; -- -- if (mac_addr_used >= nvram.mac_addr_count) { -- printk(KERN_ERR PFX "not enough mac address\n"); -- return -ENODEV; -- } -- -- memcpy(mac, nvram.mac_addr_base, ETH_ALEN); -- p = mac + ETH_ALEN - 1; -- count = mac_addr_used; -- -- while (count--) { -- do { -- (*p)++; -- if (*p != 0) -- break; -- p--; -- } while (p != mac); -- } -- -- if (p == mac) { -- printk(KERN_ERR PFX "unable to fetch mac address\n"); -- return -ENODEV; -- } -- -- mac_addr_used++; -- return 0; --} -- - static void __init boardid_fixup(u8 *boot_addr) - { - struct bcm_tag *tag = (struct bcm_tag *)(boot_addr + CFE_OFFSET_64K); -+ char *board_name = (char *)bcm63xx_nvram_get_name(); - - /* check if bcm_tag is at 64k offset */ -- if (strncmp(nvram.name, tag->boardid, BOARDID_LEN) != 0) { -+ if (strncmp(board_name, tag->boardid, BOARDID_LEN) != 0) { - /* else try 128k */ - tag = (struct bcm_tag *)(boot_addr + CFE_OFFSET_128K); -- if (strncmp(nvram.name, tag->boardid, BOARDID_LEN) != 0) { -+ if (strncmp(board_name, tag->boardid, BOARDID_LEN) != 0) { - /* No tag found */ - printk(KERN_DEBUG "No bcm_tag found!\n"); - return; -@@ -749,9 +714,9 @@ static void __init boardid_fixup(u8 *boo - if (tag->information1[0] != '+') - return; - -- strncpy(nvram.name, &tag->information1[1], BOARDID_LEN); -+ strncpy(board_name, &tag->information1[1], BOARDID_LEN); - -- printk(KERN_INFO "Overriding boardid with '%s'\n", nvram.name); -+ printk(KERN_INFO "Overriding boardid with '%s'\n", board_name); - } - - /* -@@ -759,9 +724,10 @@ static void __init boardid_fixup(u8 *boo - */ - void __init board_prom_init(void) - { -- unsigned int check_len, i; -- u8 *boot_addr, *cfe, *p; -+ unsigned int i; -+ u8 *boot_addr, *cfe; - char cfe_version[32]; -+ char *board_name; - u32 val; - - /* read base address of boot chip select (0) -@@ -786,32 +752,19 @@ void __init board_prom_init(void) - strcpy(cfe_version, "unknown"); - printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); - -- /* extract nvram data */ -- memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram)); -- -- /* check checksum before using data */ -- if (nvram.version <= 4) -- check_len = offsetof(struct bcm963xx_nvram, checksum_old); -- else -- check_len = sizeof(nvram); -- val = 0; -- p = (u8 *)&nvram; -- while (check_len--) -- val += *p; -- if (val) { -- printk(KERN_ERR PFX "invalid nvram checksum\n"); -+ if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) - return; -- } - - if (strcmp(cfe_version, "unknown") != 0) { - /* cfe present */ - boardid_fixup(boot_addr); - } - -+ board_name = bcm63xx_nvram_get_name(); - /* find board by name */ - for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { -- if (strncmp(nvram.name, bcm963xx_boards[i]->name, -- sizeof(nvram.name))) -+ if (strncmp(board_name, bcm963xx_boards[i]->name, -+ BCM63XX_NVRAM_NAMELEN)) - continue; - /* copy, board desc array is marked initdata */ - memcpy(&board, bcm963xx_boards[i], sizeof(board)); -@@ -821,7 +774,7 @@ void __init board_prom_init(void) - /* bail out if board is not found, will complain later */ - if (!board.name[0]) { - char name[17]; -- memcpy(name, nvram.name, 16); -+ memcpy(name, board_name, 16); - name[16] = 0; - printk(KERN_ERR PFX "unknown bcm963xx board: %s\n", - name); -@@ -914,15 +867,15 @@ int __init board_register_devices(void) - bcm63xx_pcmcia_register(); - - if (board.has_enet0 && -- !board_get_mac_address(board.enet0.mac_addr)) -+ !bcm63xx_nvram_get_mac_address(board.enet0.mac_addr)) - bcm63xx_enet_register(0, &board.enet0); - - if (board.has_enet1 && -- !board_get_mac_address(board.enet1.mac_addr)) -+ !bcm63xx_nvram_get_mac_address(board.enet1.mac_addr)) - bcm63xx_enet_register(1, &board.enet1); - - if (board.has_enetsw && -- !board_get_mac_address(board.enetsw.mac_addr)) -+ !bcm63xx_nvram_get_mac_address(board.enetsw.mac_addr)) - bcm63xx_enetsw_register(&board.enetsw); - - if (board.has_ehci0) -@@ -938,7 +891,7 @@ int __init board_register_devices(void) - * do this after registering enet devices - */ - #ifdef CONFIG_SSB_PCIHOST -- if (!board_get_mac_address(bcm63xx_sprom.il0mac)) { -+ if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) { - memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); - memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); - if (ssb_arch_register_fallback_sprom( ---- /dev/null -+++ b/arch/mips/bcm63xx/nvram.c -@@ -0,0 +1,84 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2012 Jonas Gorski -+ */ -+ -+#define pr_fmt(fmt) "bcm63xx_nvram: " fmt -+ -+#include -+#include -+#include -+ -+#include -+ -+static struct bcm963xx_nvram nvram; -+static int mac_addr_used; -+ -+int __init bcm63xx_nvram_init(void *addr) -+{ -+ unsigned int check_len; -+ u8 *p; -+ u32 val; -+ -+ /* extract nvram data */ -+ memcpy(&nvram, addr, sizeof(nvram)); -+ -+ /* check checksum before using data */ -+ if (nvram.version <= 4) -+ check_len = offsetof(struct bcm963xx_nvram, checksum_old); -+ else -+ check_len = sizeof(nvram); -+ val = 0; -+ p = (u8 *)&nvram; -+ -+ while (check_len--) -+ val += *p; -+ if (val) { -+ pr_err("invalid nvram checksum\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+u8 *bcm63xx_nvram_get_name(void) -+{ -+ return nvram.name; -+} -+EXPORT_SYMBOL(bcm63xx_nvram_get_name); -+ -+int bcm63xx_nvram_get_mac_address(u8 *mac) -+{ -+ u8 *p; -+ int count; -+ -+ if (mac_addr_used >= nvram.mac_addr_count) { -+ pr_err("not enough mac address\n"); -+ return -ENODEV; -+ } -+ -+ memcpy(mac, nvram.mac_addr_base, ETH_ALEN); -+ p = mac + ETH_ALEN - 1; -+ count = mac_addr_used; -+ -+ while (count--) { -+ do { -+ (*p)++; -+ if (*p != 0) -+ break; -+ p--; -+ } while (p != mac); -+ } -+ -+ if (p == mac) { -+ pr_err("unable to fetch mac address\n"); -+ return -ENODEV; -+ } -+ -+ mac_addr_used++; -+ return 0; -+} -+EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address); ---- /dev/null -+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h -@@ -0,0 +1,34 @@ -+#ifndef BCM63XX_NVRAM_H -+#define BCM63XX_NVRAM_H -+ -+#include -+ -+#define BCM63XX_NVRAM_NAMELEN 16 -+ -+/* -+ * nvram structure -+ */ -+struct bcm963xx_nvram { -+ u32 version; -+ u8 reserved1[256]; -+ u8 name[BCM63XX_NVRAM_NAMELEN]; -+ u32 main_tp_number; -+ u32 psi_size; -+ u32 mac_addr_count; -+ u8 mac_addr_base[ETH_ALEN]; -+ u8 reserved2[2]; -+ u32 checksum_old; -+ u8 reserved3[720]; -+ u32 checksum_high; -+}; -+ -+int __init bcm63xx_nvram_init(void *); -+ -+u8 *bcm63xx_nvram_get_name(void); -+ -+/* -+ * register & return a new board mac address -+ */ -+int bcm63xx_nvram_get_mac_address(u8 *mac); -+ -+#endif /* BCM63XX_NVRAM_H */ ---- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h -+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h -@@ -15,23 +15,6 @@ - #define BCM963XX_NVRAM_OFFSET 0x580 - - /* -- * nvram structure -- */ --struct bcm963xx_nvram { -- u32 version; -- u8 reserved1[256]; -- u8 name[16]; -- u32 main_tp_number; -- u32 psi_size; -- u32 mac_addr_count; -- u8 mac_addr_base[6]; -- u8 reserved2[2]; -- u32 checksum_old; -- u8 reserved3[720]; -- u32 checksum_high; --}; -- --/* - * board definition - */ - struct board_info { diff --git a/target/linux/brcm63xx/patches-3.3/422-MIPS-BCM63XX-export-PSI-size-from-nvram.patch b/target/linux/brcm63xx/patches-3.3/422-MIPS-BCM63XX-export-PSI-size-from-nvram.patch deleted file mode 100644 index 34966b27f1..0000000000 --- a/target/linux/brcm63xx/patches-3.3/422-MIPS-BCM63XX-export-PSI-size-from-nvram.patch +++ /dev/null @@ -1,44 +0,0 @@ -From ffbeb183bf0e9e12fd607c5352f48420c32f588f Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Sat, 12 May 2012 23:04:17 +0200 -Subject: [PATCH 61/79] MIPS: BCM63XX: export PSI size from nvram - -Signed-off-by: Jonas Gorski ---- - arch/mips/bcm63xx/nvram.c | 11 +++++++++++ - arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h | 2 ++ - 2 files changed, 13 insertions(+) - ---- a/arch/mips/bcm63xx/nvram.c -+++ b/arch/mips/bcm63xx/nvram.c -@@ -14,6 +14,8 @@ - - #include - -+#define BCM63XX_DEFAULT_PSI_SIZE 64 -+ - static struct bcm963xx_nvram nvram; - static int mac_addr_used; - -@@ -82,3 +84,12 @@ int bcm63xx_nvram_get_mac_address(u8 *ma - return 0; - } - EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address); -+ -+int bcm63xx_nvram_get_psi_size(void) -+{ -+ if (nvram.psi_size > 0) -+ return nvram.psi_size; -+ -+ return BCM63XX_DEFAULT_PSI_SIZE; -+} -+EXPORT_SYMBOL(bcm63xx_nvram_get_psi_size); ---- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h -+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h -@@ -31,4 +31,6 @@ u8 *bcm63xx_nvram_get_name(void); - */ - int bcm63xx_nvram_get_mac_address(u8 *mac); - -+int bcm63xx_nvram_get_psi_size(void); -+ - #endif /* BCM63XX_NVRAM_H */ diff --git a/target/linux/brcm63xx/patches-3.3/422-bcm63xx_enet-enable-rgmii-clock-on-external-ports.patch b/target/linux/brcm63xx/patches-3.3/422-bcm63xx_enet-enable-rgmii-clock-on-external-ports.patch new file mode 100644 index 0000000000..b71e1dc369 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/422-bcm63xx_enet-enable-rgmii-clock-on-external-ports.patch @@ -0,0 +1,53 @@ +From d8237d704fc25eb2fc25ef4403608b78c6a6d4be Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Sun, 15 Jul 2012 20:08:57 +0200 +Subject: [PATCH 54/81] bcm63xx_enet: enable rgmii clock on external ports + +--- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 13 +++++++++++++ + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 12 ++++++++++++ + 2 files changed, 25 insertions(+), 0 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -779,6 +779,19 @@ + #define ENETSW_PORTOV_FDX_MASK (1 << 1) + #define ENETSW_PORTOV_LINKUP_MASK (1 << 0) + ++/* Port RGMII control register */ ++#define ENETSW_RGMII_CTRL_REG(x) (0x60 + (x)) ++#define ENETSW_RGMII_CTRL_GMII_CLK_EN (1 << 7) ++#define ENETSW_RGMII_CTRL_MII_OVERRIDE_EN (1 << 6) ++#define ENETSW_RGMII_CTRL_MII_MODE_MASK (3 << 4) ++#define ENETSW_RGMII_CTRL_RGMII_MODE (0 << 4) ++#define ENETSW_RGMII_CTRL_MII_MODE (1 << 4) ++#define ENETSW_RGMII_CTRL_RVMII_MODE (2 << 4) ++#define ENETSW_RGMII_CTRL_TIMING_SEL_EN (1 << 0) ++ ++/* Port RGMII timing register */ ++#define ENETSW_RGMII_TIMING_REG(x) (0x68 + (x)) ++ + /* MDIO control register */ + #define ENETSW_MDIOC_REG (0xb0) + #define ENETSW_MDIOC_EXT_MASK (1 << 16) +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -2222,6 +2222,18 @@ static int bcm_enetsw_open(struct net_de + priv->sw_port_link[i] = 0; + } + ++ /* enable external ports */ ++ for (i = ENETSW_RGMII_PORT0; i < priv->num_ports; i++) { ++ u8 rgmii_ctrl; ++ ++ if (!priv->used_ports[i].used) ++ continue; ++ ++ rgmii_ctrl = enetsw_readb(priv, ENETSW_RGMII_CTRL_REG(i)); ++ rgmii_ctrl |= ENETSW_RGMII_CTRL_GMII_CLK_EN; ++ enetsw_writeb(priv, rgmii_ctrl, ENETSW_RGMII_CTRL_REG(i)); ++ } ++ + /* reset mib */ + val = enetsw_readb(priv, ENETSW_GMCR_REG); + val |= ENETSW_GMCR_RST_MIB_MASK; diff --git a/target/linux/brcm63xx/patches-3.3/423-MTD-bcm63xxpart-use-nvram-for-PSI-size.patch b/target/linux/brcm63xx/patches-3.3/423-MTD-bcm63xxpart-use-nvram-for-PSI-size.patch deleted file mode 100644 index 5ca6f47970..0000000000 --- a/target/linux/brcm63xx/patches-3.3/423-MTD-bcm63xxpart-use-nvram-for-PSI-size.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 658afad639a9456e1bb6fe5bba0032f3c0c3f699 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Tue, 1 May 2012 14:10:39 +0200 -Subject: [PATCH 62/79] MTD: bcm63xxpart: use nvram for PSI size - ---- - drivers/mtd/bcm63xxpart.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/mtd/bcm63xxpart.c -+++ b/drivers/mtd/bcm63xxpart.c -@@ -32,6 +32,7 @@ - #include - #include - -+#include - #include - #include - -@@ -90,7 +91,8 @@ static int bcm63xx_parse_cfe_partitions( - BCM63XX_CFE_BLOCK_SIZE); - - cfelen = cfe_erasesize; -- nvramlen = cfe_erasesize; -+ nvramlen = bcm63xx_nvram_get_psi_size() * 1024; -+ nvramlen = roundup(nvramlen, cfe_erasesize); - - /* Allocate memory for buffer */ - buf = vmalloc(sizeof(struct bcm_tag)); diff --git a/target/linux/brcm63xx/patches-3.3/423-bcm63xx_enet-fix-lockup-on-BCM6328.patch b/target/linux/brcm63xx/patches-3.3/423-bcm63xx_enet-fix-lockup-on-BCM6328.patch new file mode 100644 index 0000000000..4306ce753e --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/423-bcm63xx_enet-fix-lockup-on-BCM6328.patch @@ -0,0 +1,93 @@ +From 382a0b0dc4cbd0e0fbfd6c2d132e972c3d1245b0 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Sun, 13 Nov 2011 14:59:37 +0100 +Subject: [PATCH 39/84] bcm63xx_enet: fix lockup on BCM6328 + +BCM6328 locks up on a maxburst size of 16, reduce it to 8 for BCM6328 and +BCM6368. + +Signed-off-by: Jonas Gorski +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 13 +++++++------ + drivers/net/ethernet/broadcom/bcm63xx_enet.h | 4 ++++ + 2 files changed, 11 insertions(+), 6 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -261,7 +261,6 @@ static int bcm_enet_refill_rx(struct net + if (!skb) + break; + priv->rx_skb[desc_idx] = skb; +- + p = dma_map_single(&priv->pdev->dev, skb->data, + priv->rx_skb_size, + DMA_FROM_DEVICE); +@@ -995,9 +994,9 @@ static int bcm_enet_open(struct net_devi + enet_writel(priv, priv->hw_mtu, ENET_TXMAXLEN_REG); + + /* set dma maximum burst len */ +- enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, ++ enet_dmac_writel(priv, priv->dma_maxburst, + ENETDMAC_MAXBURST_REG(priv->rx_chan)); +- enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, ++ enet_dmac_writel(priv, priv->dma_maxburst, + ENETDMAC_MAXBURST_REG(priv->tx_chan)); + + /* set correct transmit fifo watermark */ +@@ -1593,7 +1592,7 @@ static int compute_hw_mtu(struct bcm_ene + * it's appended + */ + priv->rx_skb_size = ALIGN(actual_mtu + ETH_FCS_LEN, +- BCMENET_DMA_MAXBURST * 4); ++ priv->dma_maxburst * 4); + return 0; + } + +@@ -1701,6 +1700,7 @@ static int __devinit bcm_enet_probe(stru + priv = netdev_priv(dev); + + priv->enet_is_sw = false; ++ priv->dma_maxburst = BCMENET_DMA_MAXBURST; + + ret = compute_hw_mtu(priv, dev->mtu); + if (ret) +@@ -2282,9 +2282,9 @@ static int bcm_enetsw_open(struct net_de + enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG(priv->tx_chan)); + + /* set dma maximum burst len */ +- enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, ++ enet_dmac_writel(priv, priv->dma_maxburst, + ENETDMAC_MAXBURST_REG(priv->rx_chan)); +- enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, ++ enet_dmac_writel(priv, priv->dma_maxburst, + ENETDMAC_MAXBURST_REG(priv->tx_chan)); + + /* set flow control low/high threshold to 1/3 / 2/3 */ +@@ -2749,6 +2749,7 @@ static int __devinit bcm_enetsw_probe(st + priv->irq_tx = irq_tx; + priv->rx_ring_size = BCMENET_DEF_RX_DESC; + priv->tx_ring_size = BCMENET_DEF_TX_DESC; ++ priv->dma_maxburst = BCMENETSW_DMA_MAXBURST; + + pd = pdev->dev.platform_data; + if (pd) { +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h +@@ -17,6 +17,7 @@ + + /* maximum burst len for dma (4 bytes unit) */ + #define BCMENET_DMA_MAXBURST 16 ++#define BCMENETSW_DMA_MAXBURST 8 + + /* tx transmit threshold (4 bytes unit), fifo is 256 bytes, the value + * must be low enough so that a DMA transfer of above burst length can +@@ -280,6 +281,9 @@ struct bcm_enet_priv { + /* number of dma desc in tx ring */ + int tx_ring_size; + ++ /* maximum dma burst size */ ++ int dma_maxburst; ++ + /* cpu view of rx dma ring */ + struct bcm_enet_desc *tx_desc_cpu; + diff --git a/target/linux/brcm63xx/patches-3.3/424-MIPS-BCM63XX-add-support-for-BCM6328-in-bcm_enetsw.patch b/target/linux/brcm63xx/patches-3.3/424-MIPS-BCM63XX-add-support-for-BCM6328-in-bcm_enetsw.patch new file mode 100644 index 0000000000..e665249c5e --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/424-MIPS-BCM63XX-add-support-for-BCM6328-in-bcm_enetsw.patch @@ -0,0 +1,103 @@ +From f1c1bfa89cdac76a215d0e21161da9f8f8373437 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Tue, 14 Jun 2011 21:14:39 +0200 +Subject: [PATCH 40/84] MIPS: BCM63XX: add support for BCM6328 in bcm_enetsw + +Signed-off-by: Jonas Gorski +--- + arch/mips/bcm63xx/clk.c | 34 ++++++++++++++----- + arch/mips/bcm63xx/dev-enet.c | 9 +++-- + .../include/asm/mach-bcm63xx/bcm63xx_dev_enet.h | 1 + + 3 files changed, 32 insertions(+), 12 deletions(-) + +--- a/arch/mips/bcm63xx/clk.c ++++ b/arch/mips/bcm63xx/clk.c +@@ -118,21 +118,37 @@ static struct clk clk_ephy = { + */ + static void enetsw_set(struct clk *clk, int enable) + { +- if (!BCMCPU_IS_6368()) ++ u32 mask; ++ ++ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6368()) + return; +- bcm_hwclock_set(CKCTL_6368_ROBOSW_EN | +- CKCTL_6368_SWPKT_USB_EN | +- CKCTL_6368_SWPKT_SAR_EN, enable); ++ ++ if (BCMCPU_IS_6328()) ++ mask = CKCTL_6328_ROBOSW_EN; ++ else ++ mask = CKCTL_6368_ROBOSW_EN | CKCTL_6368_SWPKT_USB_EN | ++ CKCTL_6368_SWPKT_SAR_EN; ++ ++ bcm_hwclock_set(mask, enable); + if (enable) { ++ u32 reg; + u32 val; + ++ if (BCMCPU_IS_6328()) { ++ reg = PERF_SOFTRESET_6328_REG; ++ mask = SOFTRESET_6328_ENETSW_MASK; ++ } else { ++ reg = PERF_SOFTRESET_6368_REG; ++ mask = SOFTRESET_6368_ENETSW_MASK; ++ } ++ + /* reset switch core afer clock change */ +- val = bcm_perf_readl(PERF_SOFTRESET_6368_REG); +- val &= ~SOFTRESET_6368_ENETSW_MASK; +- bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); ++ val = bcm_perf_readl(reg); ++ val &= ~mask; ++ bcm_perf_writel(val, reg); + msleep(10); +- val |= SOFTRESET_6368_ENETSW_MASK; +- bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); ++ val |= mask; ++ bcm_perf_writel(val, reg); + msleep(10); + } + } +--- a/arch/mips/bcm63xx/dev-enet.c ++++ b/arch/mips/bcm63xx/dev-enet.c +@@ -141,7 +141,7 @@ static int __init register_shared(void) + shared_res[0].end = shared_res[0].start; + shared_res[0].end += (RSET_ENETDMA_SIZE) - 1; + +- if (BCMCPU_IS_6368()) ++ if (BCMCPU_IS_6328() || BCMCPU_IS_6368()) + chan_count = 32; + else + chan_count = 16; +@@ -224,7 +224,7 @@ bcm63xx_enetsw_register(const struct bcm + { + int ret; + +- if (!BCMCPU_IS_6368()) ++ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6368()) + return -ENODEV; + + ret = register_shared(); +@@ -241,7 +241,10 @@ bcm63xx_enetsw_register(const struct bcm + + memcpy(bcm63xx_enetsw_device.dev.platform_data, pd, sizeof (*pd)); + +- enetsw_pd.num_ports = ENETSW_PORTS_6368; ++ if (BCMCPU_IS_6328()) ++ enetsw_pd.num_ports = ENETSW_PORTS_6328; ++ else if (BCMCPU_IS_6368()) ++ enetsw_pd.num_ports = ENETSW_PORTS_6368; + + ret = platform_device_register(&bcm63xx_enetsw_device); + if (ret) +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h +@@ -43,6 +43,7 @@ struct bcm63xx_enet_platform_data { + * on board ethernet switch platform data + */ + #define ENETSW_MAX_PORT 6 ++#define ENETSW_PORTS_6328 5 /* 4 FE PHY + 1 RGMII */ + #define ENETSW_PORTS_6368 6 /* 4 FE PHY + 2 RGMII */ + + #define ENETSW_RGMII_PORT0 4 diff --git a/target/linux/brcm63xx/patches-3.3/424-MTD-physmap-allow-passing-pp_data.patch b/target/linux/brcm63xx/patches-3.3/424-MTD-physmap-allow-passing-pp_data.patch deleted file mode 100644 index f869911d54..0000000000 --- a/target/linux/brcm63xx/patches-3.3/424-MTD-physmap-allow-passing-pp_data.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 266c506f4b262bd6aba0776a03d82c98e65d9906 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Tue, 1 May 2012 17:32:36 +0200 -Subject: [PATCH 63/79] MTD: physmap: allow passing pp_data - ---- - drivers/mtd/maps/physmap.c | 4 +++- - include/linux/mtd/physmap.h | 1 + - 2 files changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/mtd/maps/physmap.c -+++ b/drivers/mtd/maps/physmap.c -@@ -84,6 +84,7 @@ static int physmap_flash_probe(struct pl - { - struct physmap_flash_data *physmap_data; - struct physmap_flash_info *info; -+ struct mtd_part_parser_data *pp_data; - const char **probe_type; - const char **part_types; - int err = 0; -@@ -173,8 +174,9 @@ static int physmap_flash_probe(struct pl - goto err_out; - - part_types = physmap_data->part_probe_types ? : part_probe_types; -+ pp_data = physmap_data->pp_data ? physmap_data->pp_data : NULL; - -- mtd_device_parse_register(info->cmtd, part_types, 0, -+ mtd_device_parse_register(info->cmtd, part_types, pp_data, - physmap_data->parts, physmap_data->nr_parts); - return 0; - ---- a/include/linux/mtd/physmap.h -+++ b/include/linux/mtd/physmap.h -@@ -32,6 +32,7 @@ struct physmap_flash_data { - char *probe_type; - struct mtd_partition *parts; - const char **part_probe_types; -+ struct mtd_part_parser_data *pp_data; - }; - - #endif /* __LINUX_MTD_PHYSMAP__ */ diff --git a/target/linux/brcm63xx/patches-3.3/425-BCM63XX-allow-providing-fixup-data-in-board-data.patch b/target/linux/brcm63xx/patches-3.3/425-BCM63XX-allow-providing-fixup-data-in-board-data.patch deleted file mode 100644 index c79c3fe9af..0000000000 --- a/target/linux/brcm63xx/patches-3.3/425-BCM63XX-allow-providing-fixup-data-in-board-data.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 5131195413b62df73dfd394fea272830ea8c4e1a Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Thu, 3 May 2012 14:40:03 +0200 -Subject: [PATCH 67/80] BCM63XX: allow providing fixup data in board data - ---- - arch/mips/bcm63xx/boards/board_bcm963xx.c | 10 +++++++++- - arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h | 10 ++++++++++ - 2 files changed, 19 insertions(+), 1 deletion(-) - ---- a/arch/mips/bcm63xx/boards/board_bcm963xx.c -+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - - #define PFX "board_bcm963xx: " - -@@ -856,6 +857,7 @@ int __init board_register_devices(void) - { - int button_count = 0; - int led_count = 0; -+ int i; - - if (board.has_uart0) - bcm63xx_uart_register(0); -@@ -891,7 +893,8 @@ int __init board_register_devices(void) - * do this after registering enet devices - */ - #ifdef CONFIG_SSB_PCIHOST -- if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) { -+ if (!board.has_caldata && -+ !bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) { - memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); - memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); - if (ssb_arch_register_fallback_sprom( -@@ -931,5 +934,9 @@ int __init board_register_devices(void) - platform_device_register(&bcm63xx_gpio_keys_device); - } - -+ /* register any fixups */ -+ for (i = 0; i < board.has_caldata; i++) -+ pci_enable_ath9k_fixup(board.caldata[i].slot, board.caldata[i].caldata_offset); -+ - return 0; - } ---- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h -+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h -@@ -7,6 +7,7 @@ - #include - #include - #include -+#include - - /* - * flash mapping -@@ -14,6 +15,11 @@ - #define BCM963XX_CFE_VERSION_OFFSET 0x570 - #define BCM963XX_NVRAM_OFFSET 0x580 - -+struct ath9k_caldata { -+ unsigned int slot; -+ u32 caldata_offset; -+}; -+ - /* - * board definition - */ -@@ -32,6 +38,10 @@ struct board_info { - unsigned int has_dsp:1; - unsigned int has_uart0:1; - unsigned int has_uart1:1; -+ unsigned int has_caldata:2; -+ -+ /* wifi calibration data config */ -+ struct ath9k_caldata caldata[2]; - - /* ethernet config */ - struct bcm63xx_enet_platform_data enet0; diff --git a/target/linux/brcm63xx/patches-3.3/425-MIPS-BCM63XX-add-HS-SPI-platform-device-and-register.patch b/target/linux/brcm63xx/patches-3.3/425-MIPS-BCM63XX-add-HS-SPI-platform-device-and-register.patch new file mode 100644 index 0000000000..5b25344671 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/425-MIPS-BCM63XX-add-HS-SPI-platform-device-and-register.patch @@ -0,0 +1,128 @@ +From 56be5a2d7e08faa7bb306faaf352ac4e6ac52c01 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Sat, 12 Nov 2011 12:18:26 +0100 +Subject: [PATCH 26/60] MIPS: BCM63XX: add HS SPI platform device and register it + +Signed-off-by: Jonas Gorski +--- + arch/mips/bcm63xx/Makefile | 5 +- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 2 + + arch/mips/bcm63xx/dev-hsspi.c | 57 ++++++++++++++++++++ + .../include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h | 20 +++++++ + 4 files changed, 82 insertions(+), 2 deletions(-) + create mode 100644 arch/mips/bcm63xx/dev-hsspi.c + create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h + +--- a/arch/mips/bcm63xx/Makefile ++++ b/arch/mips/bcm63xx/Makefile +@@ -1,6 +1,7 @@ + obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ +- dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o dev-rng.o \ +- dev-spi.o dev-uart.o dev-usb-ehci.o dev-usb-ohci.o dev-wdt.o ++ dev-dsp.o dev-enet.o dev-flash.o dev-hsspi.o dev-pcmcia.o \ ++ dev-rng.o dev-spi.o dev-uart.o dev-usb-ehci.o \ ++ dev-usb-ohci.o dev-wdt.o + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o + + obj-y += boards/ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -945,6 +946,7 @@ int __init board_register_devices(void) + pr_err(PFX "failed to register fallback SPROM\n"); + } + #endif ++ bcm63xx_hsspi_register(); + + bcm63xx_spi_register(); + +--- /dev/null ++++ b/arch/mips/bcm63xx/dev-hsspi.c +@@ -0,0 +1,57 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2012 Jonas Gorski ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++static struct resource spi_resources[] = { ++ { ++ .start = -1, /* filled at runtime */ ++ .end = -1, /* filled at runtime */ ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = -1, /* filled at runtime */ ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct bcm63xx_hsspi_pdata spi_pdata = { ++ .bus_num = 0, ++}; ++ ++static struct platform_device bcm63xx_hsspi_device = { ++ .name = "bcm63xx-hsspi", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(spi_resources), ++ .resource = spi_resources, ++ .dev = { ++ .platform_data = &spi_pdata, ++ }, ++}; ++ ++int __init bcm63xx_hsspi_register(void) ++{ ++ ++ if (!BCMCPU_IS_6328()) ++ return -ENODEV; ++ ++ spi_resources[0].start = bcm63xx_regset_address(RSET_HSSPI); ++ spi_resources[0].end = spi_resources[0].start; ++ spi_resources[0].end += RSET_HSSPI_SIZE - 1; ++ spi_resources[1].start = bcm63xx_get_irq_number(IRQ_HSSPI); ++ ++ spi_pdata.speed_hz = HSSPI_PLL_HZ_6328; ++ ++ return platform_device_register(&bcm63xx_hsspi_device); ++} +--- /dev/null ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h +@@ -0,0 +1,20 @@ ++#ifndef BCM63XX_DEV_HSSPI_H ++#define BCM63XX_DEV_HSSPI_H ++ ++#include ++#include ++#include ++ ++int __init bcm63xx_hsspi_register(void); ++ ++struct bcm63xx_hsspi_pdata { ++ int bus_num; ++ u32 speed_hz; ++}; ++ ++#define bcm_hsspi_readl(o) bcm_rset_readl(RSET_HSSPI, (o)) ++#define bcm_hsspi_writel(v, o) bcm_rset_writel(RSET_HSSPI, (v), (o)) ++ ++#define HSSPI_PLL_HZ_6328 133333333 ++ ++#endif /* BCM63XX_DEV_HSSPI_H */ diff --git a/target/linux/brcm63xx/patches-3.3/426-MTD-m25p80-allow-passing-pp_data.patch b/target/linux/brcm63xx/patches-3.3/426-MTD-m25p80-allow-passing-pp_data.patch deleted file mode 100644 index bda48079e0..0000000000 --- a/target/linux/brcm63xx/patches-3.3/426-MTD-m25p80-allow-passing-pp_data.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 7f17dfe9009beb07a3de0e380932a725293829df Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Tue, 1 May 2012 17:33:03 +0200 -Subject: [PATCH 64/79] MTD: m25p80: allow passing pp_data - ---- - drivers/mtd/devices/m25p80.c | 3 +++ - include/linux/spi/flash.h | 2 ++ - 2 files changed, 5 insertions(+) - ---- a/drivers/mtd/devices/m25p80.c -+++ b/drivers/mtd/devices/m25p80.c -@@ -886,6 +886,9 @@ static int __devinit m25p_probe(struct s - dev_warn(&spi->dev, "unrecognized id %s\n", data->type); - } - -+ if (data && data->pp_data) -+ memcpy(&ppdata, data->pp_data, sizeof(ppdata)); -+ - info = (void *)id->driver_data; - - if (info->jedec_id) { ---- a/include/linux/spi/flash.h -+++ b/include/linux/spi/flash.h -@@ -12,6 +12,7 @@ struct mtd_part_parser_data; - * with chips that can't be queried for JEDEC or other IDs - * @part_probe_types: optional list of MTD parser names to use for - * partitioning -+ * @pp_data: optional partition parser data. - * - * @max_transfer_len: option maximum read/write length limitation for - * SPI controllers not able to transfer any length commands. -@@ -30,6 +31,7 @@ struct flash_platform_data { - char *type; - - const char **part_probe_types; -+ struct mtd_part_parser_data *pp_data; - - unsigned int max_transfer_len; - /* we'll likely add more ... use JEDEC IDs, etc */ diff --git a/target/linux/brcm63xx/patches-3.3/426-SPI-MIPS-BCM63XX-Add-HS-SPI-driver.patch b/target/linux/brcm63xx/patches-3.3/426-SPI-MIPS-BCM63XX-Add-HS-SPI-driver.patch new file mode 100644 index 0000000000..739c2c60f7 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/426-SPI-MIPS-BCM63XX-Add-HS-SPI-driver.patch @@ -0,0 +1,481 @@ +From 4b27423676485d05bcd6fc6f3809164fb8f9d22d Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Sat, 12 Nov 2011 12:19:55 +0100 +Subject: [PATCH 30/60] SPI: MIPS: BCM63XX: Add HSSPI driver + +Add a driver for the High Speed SPI controller found on newer BCM63XX SoCs. + +Signed-off-by: Jonas Gorski +--- + .../include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h | 2 + + drivers/spi/Kconfig | 7 + + drivers/spi/Makefile | 1 + + drivers/spi/spi-bcm63xx-hsspi.c | 427 ++++++++++++++++++++ + 4 files changed, 437 insertions(+), 0 deletions(-) + create mode 100644 drivers/spi/spi-bcm63xx-hsspi.c + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h +@@ -17,4 +17,6 @@ struct bcm63xx_hsspi_pdata { + + #define HSSPI_PLL_HZ_6328 133333333 + ++#define HSSPI_BUFFER_LEN 512 ++ + #endif /* BCM63XX_DEV_HSSPI_H */ +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -100,6 +100,13 @@ config SPI_BCM63XX + help + Enable support for the SPI controller on the Broadcom BCM63xx SoCs. + ++config SPI_BCM63XX_HSSPI ++ tristate "Broadcom BCM63XX HS SPI controller driver" ++ depends on BCM63XX ++ help ++ This enables support for the High Speed SPI controller present on ++ newer Broadcom BCM63XX SoCs. ++ + config SPI_BITBANG + tristate "Utilities for Bitbanging SPI masters" + help +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -15,6 +15,7 @@ obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o + obj-$(CONFIG_SPI_ATH79) += spi-ath79.o + obj-$(CONFIG_SPI_AU1550) += spi-au1550.o + obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o ++obj-$(CONFIG_SPI_BCM63XX_HSSPI) += spi-bcm63xx-hsspi.o + obj-$(CONFIG_SPI_BFIN) += spi-bfin5xx.o + obj-$(CONFIG_SPI_BFIN_SPORT) += spi-bfin-sport.o + obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o +--- /dev/null ++++ b/drivers/spi/spi-bcm63xx-hsspi.c +@@ -0,0 +1,427 @@ ++/* ++ * Broadcom BCM63XX High Speed SPI Controller driver ++ * ++ * Copyright 2000-2010 Broadcom Corporation ++ * Copyright 2012 Jonas Gorski ++ * ++ * Licensed under the GNU/GPL. See COPYING for details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define HSSPI_OP_CODE_SHIFT 13 ++#define HSSPI_OP_SLEEP (0 << HSSPI_OP_CODE_SHIFT) ++#define HSSPI_OP_READ_WRITE (1 << HSSPI_OP_CODE_SHIFT) ++#define HSSPI_OP_WRITE (2 << HSSPI_OP_CODE_SHIFT) ++#define HSSPI_OP_READ (3 << HSSPI_OP_CODE_SHIFT) ++ ++#define HSSPI_MAX_PREPEND_LEN 15 ++ ++#define HSSPI_MAX_SYNC_CLOCK 30000000 ++ ++struct bcm63xx_hsspi { ++ struct completion done; ++ struct spi_transfer *curr_trans; ++ ++ struct platform_device *pdev; ++ struct clk *clk; ++ void __iomem *regs; ++ u8 __iomem *fifo; ++ ++ u32 speed_hz; ++ int irq; ++}; ++ ++static void bcm63xx_hsspi_set_clk(struct bcm63xx_hsspi *bs, int hz, ++ int profile) ++{ ++ u32 reg; ++ ++ reg = DIV_ROUND_UP(2048, DIV_ROUND_UP(bs->speed_hz, hz)); ++ bcm_hsspi_writel(CLK_CTRL_ACCUM_RST_ON_LOOP | reg, ++ HSSPI_PROFILE_CLK_CTRL_REG(profile)); ++ ++ reg = bcm_hsspi_readl(HSSPI_PROFILE_SIGNAL_CTRL_REG(profile)); ++ if (hz > HSSPI_MAX_SYNC_CLOCK) ++ reg |= SIGNAL_CTRL_ASYNC_INPUT_PATH; ++ else ++ reg &= ~SIGNAL_CTRL_ASYNC_INPUT_PATH; ++ bcm_hsspi_writel(reg, HSSPI_PROFILE_SIGNAL_CTRL_REG(profile)); ++} ++ ++static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, ++ struct spi_transfer *t1, ++ struct spi_transfer *t2) ++{ ++ struct bcm63xx_hsspi *bs = spi_master_get_devdata(spi->master); ++ u8 chip_select = spi->chip_select; ++ u16 opcode = 0; ++ int len, prepend_size = 0; ++ ++ init_completion(&bs->done); ++ ++ bs->curr_trans = t2 ? t2 : t1; ++ bcm63xx_hsspi_set_clk(bs, bs->curr_trans->speed_hz, chip_select); ++ ++ if (t2 && !t2->tx_buf) ++ prepend_size = t1->len; ++ ++ bcm_hsspi_writel(prepend_size << MODE_CTRL_PREPENDBYTE_CNT_SHIFT | ++ 2 << MODE_CTRL_MULTIDATA_WR_STRT_SHIFT | ++ 2 << MODE_CTRL_MULTIDATA_RD_STRT_SHIFT | 0xff, ++ HSSPI_PROFILE_MODE_CTRL_REG(chip_select)); ++ ++ if (t1->rx_buf && t1->tx_buf) ++ opcode = HSSPI_OP_READ_WRITE; ++ else if (t1->rx_buf || (t2 && t2->rx_buf)) ++ opcode = HSSPI_OP_READ; ++ else if (t1->tx_buf) ++ opcode = HSSPI_OP_WRITE; ++ ++ if (opcode == HSSPI_OP_READ && t2) ++ len = t2->len; ++ else ++ len = t1->len; ++ ++ if (t1->tx_buf) { ++ memcpy_toio(bs->fifo + 2, t1->tx_buf, t1->len); ++ if (t2 && t2->tx_buf) { ++ memcpy_toio(bs->fifo + 2 + t1->len, ++ t2->tx_buf, t2->len); ++ len += t2->len; ++ } ++ } ++ ++ opcode |= len; ++ memcpy_toio(bs->fifo, &opcode, sizeof(opcode)); ++ ++ /* enable interrupt */ ++ bcm_hsspi_writel(HSSPI_PING0_CMD_DONE, HSSPI_INT_MASK_REG); ++ ++ /* start the transfer */ ++ bcm_hsspi_writel(chip_select << PINGPONG_CMD_SS_SHIFT | ++ chip_select << PINGPONG_CMD_PROFILE_SHIFT | ++ PINGPONG_COMMAND_START_NOW, ++ HSSPI_PINGPONG_COMMAND_REG(0)); ++ ++ if (wait_for_completion_timeout(&bs->done, HZ) == 0) { ++ dev_err(&bs->pdev->dev, "transfer timed out!\n"); ++ return -ETIMEDOUT; ++ } ++ ++ return t1->len + (t2 ? t2->len : 0); ++} ++ ++static int bcm63xx_hsspi_setup(struct spi_device *spi) ++{ ++ u32 reg; ++ ++ if (spi->bits_per_word != 8) ++ return -EINVAL; ++ ++ if (spi->max_speed_hz == 0) ++ return -EINVAL; ++ ++ reg = bcm_hsspi_readl(HSSPI_PROFILE_SIGNAL_CTRL_REG(spi->chip_select)); ++ reg &= ~(SIGNAL_CTRL_LAUNCH_RISING | SIGNAL_CTRL_LATCH_RISING); ++ if (spi->mode & SPI_CPHA) ++ reg |= SIGNAL_CTRL_LAUNCH_RISING; ++ else ++ reg |= SIGNAL_CTRL_LATCH_RISING; ++ bcm_hsspi_writel(reg, HSSPI_PROFILE_SIGNAL_CTRL_REG(spi->chip_select)); ++ ++ return 0; ++} ++ ++static int bcm63xx_hsspi_transfer_one(struct spi_master *master, ++ struct spi_message *msg) ++{ ++ struct spi_transfer *t, *prev = NULL; ++ struct spi_device *spi = msg->spi; ++ u32 reg; ++ int ret = -EINVAL; ++ int len = 0; ++ ++ /* check if we are able to make these transfers */ ++ list_for_each_entry(t, &msg->transfers, transfer_list) { ++ if (!t->tx_buf && !t->rx_buf) ++ goto out; ++ ++ if (t->speed_hz == 0) ++ t->speed_hz = spi->max_speed_hz; ++ ++ if (t->speed_hz > spi->max_speed_hz) ++ goto out; ++ ++ if (t->len > HSSPI_BUFFER_LEN) ++ goto out; ++ ++ /* ++ * This controller does not support keeping the chip select ++ * active between transfers. ++ * This logic currently supports combining: ++ * write then read with no cs_change (e.g. m25p80 RDSR) ++ * write then write with no cs_change (e.g. m25p80 PP) ++ */ ++ if (prev && prev->tx_buf && !prev->cs_change && !t->cs_change) { ++ /* ++ * reject if we have to combine two tx transfers and ++ * their combined length is bigger than the buffer ++ */ ++ if (prev->tx_buf && t->tx_buf && ++ (prev->len + t->len) > HSSPI_BUFFER_LEN) ++ goto out; ++ /* ++ * reject if we need write more than 15 bytes in read ++ * then write. ++ */ ++ if (prev->tx_buf && t->rx_buf && ++ prev->len > HSSPI_MAX_PREPEND_LEN) ++ goto out; ++ } ++ ++ } ++ ++ /* setup clock polarity */ ++ reg = bcm_hsspi_readl(HSSPI_GLOBAL_CTRL_REG); ++ reg &= ~GLOBAL_CTRL_CLK_POLARITY; ++ if (spi->mode & SPI_CPOL) ++ reg |= GLOBAL_CTRL_CLK_POLARITY; ++ bcm_hsspi_writel(reg, HSSPI_GLOBAL_CTRL_REG); ++ ++ list_for_each_entry(t, &msg->transfers, transfer_list) { ++ if (prev && prev->tx_buf && !prev->cs_change && !t->cs_change) { ++ /* combine write with following transfer */ ++ ret = bcm63xx_hsspi_do_txrx(msg->spi, prev, t); ++ if (ret < 0) ++ goto out; ++ ++ len += ret; ++ prev = NULL; ++ continue; ++ } ++ ++ /* write the previous pending transfer */ ++ if (prev != NULL) { ++ ret = bcm63xx_hsspi_do_txrx(msg->spi, prev, NULL); ++ if (ret < 0) ++ goto out; ++ ++ len += ret; ++ } ++ ++ prev = t; ++ } ++ ++ /* do last pending transfer */ ++ if (prev != NULL) { ++ ret = bcm63xx_hsspi_do_txrx(msg->spi, prev, NULL); ++ if (ret < 0) ++ goto out; ++ len += ret; ++ } ++ ++ msg->actual_length = len; ++ ret = 0; ++out: ++ msg->status = ret; ++ spi_finalize_current_message(master); ++ return 0; ++} ++ ++static irqreturn_t bcm63xx_hsspi_interrupt(int irq, void *dev_id) ++{ ++ struct spi_master *master = (struct spi_master *)dev_id; ++ struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); ++ ++ if (bcm_hsspi_readl(HSSPI_INT_STATUS_MASKED_REG) == 0) ++ return IRQ_NONE; ++ ++ bcm_hsspi_writel(HSSPI_INT_CLEAR_ALL, HSSPI_INT_STATUS_REG); ++ bcm_hsspi_writel(0, HSSPI_INT_MASK_REG); ++ ++ if (bs->curr_trans && bs->curr_trans->rx_buf) ++ memcpy_fromio(bs->curr_trans->rx_buf, bs->fifo, ++ bs->curr_trans->len); ++ complete(&bs->done); ++ ++ return IRQ_HANDLED; ++} ++ ++static int __devinit bcm63xx_hsspi_probe(struct platform_device *pdev) ++{ ++ ++ struct spi_master *master; ++ struct bcm63xx_hsspi *bs; ++ struct resource *res_mem; ++ void __iomem *regs; ++ struct device *dev = &pdev->dev; ++ struct bcm63xx_hsspi_pdata *pdata = pdev->dev.platform_data; ++ struct clk *clk; ++ int irq; ++ int ret; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ dev_err(dev, "no irq\n"); ++ return -ENXIO; ++ } ++ ++ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ regs = devm_request_and_ioremap(dev, res_mem); ++ if (!regs) { ++ dev_err(dev, "unable to ioremap regs\n"); ++ return -ENXIO; ++ } ++ ++ clk = clk_get(dev, "hsspi"); ++ ++ if (IS_ERR(clk)) { ++ ret = PTR_ERR(clk); ++ goto out_release; ++ } ++ ++ clk_prepare_enable(clk); ++ ++ master = spi_alloc_master(&pdev->dev, sizeof(*bs)); ++ if (!master) { ++ ret = -ENOMEM; ++ goto out_disable_clk; ++ } ++ ++ bs = spi_master_get_devdata(master); ++ bs->pdev = pdev; ++ bs->clk = clk; ++ bs->regs = regs; ++ ++ master->bus_num = pdata->bus_num; ++ master->num_chipselect = 8; ++ master->setup = bcm63xx_hsspi_setup; ++ master->transfer_one_message = bcm63xx_hsspi_transfer_one; ++ master->mode_bits = SPI_CPOL | SPI_CPHA; ++ ++ bs->speed_hz = pdata->speed_hz; ++ bs->fifo = (u8 __iomem *)(bs->regs + HSSPI_FIFO_REG(0)); ++ ++ platform_set_drvdata(pdev, master); ++ ++ bs->curr_trans = NULL; ++ ++ /* Initialize the hardware */ ++ bcm_hsspi_writel(0, HSSPI_INT_MASK_REG); ++ ++ /* clean up any pending interrupts */ ++ bcm_hsspi_writel(HSSPI_INT_CLEAR_ALL, HSSPI_INT_STATUS_REG); ++ ++ bcm_hsspi_writel(bcm_hsspi_readl(HSSPI_GLOBAL_CTRL_REG) | ++ GLOBAL_CTRL_CLK_GATE_SSOFF, ++ HSSPI_GLOBAL_CTRL_REG); ++ ++ ret = devm_request_irq(dev, irq, bcm63xx_hsspi_interrupt, IRQF_SHARED, ++ pdev->name, master); ++ ++ if (ret) ++ goto out_put_master; ++ ++ /* register and we are done */ ++ ret = spi_register_master(master); ++ if (ret) ++ goto out_free_irq; ++ ++ return 0; ++ ++out_free_irq: ++ devm_free_irq(dev, bs->irq, master); ++out_put_master: ++ spi_master_put(master); ++out_disable_clk: ++ clk_disable_unprepare(clk); ++ clk_put(clk); ++out_release: ++ devm_ioremap_release(dev, regs); ++ ++ return ret; ++} ++ ++ ++static int __exit bcm63xx_hsspi_remove(struct platform_device *pdev) ++{ ++ struct spi_master *master = platform_get_drvdata(pdev); ++ struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); ++ ++ spi_unregister_master(master); ++ ++ /* reset the hardware and block queue progress */ ++ bcm_hsspi_writel(0, HSSPI_INT_MASK_REG); ++ clk_disable_unprepare(bs->clk); ++ clk_put(bs->clk); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int bcm63xx_hsspi_suspend(struct platform_device *pdev, ++ pm_message_t mesg) ++{ ++ struct spi_master *master = platform_get_drvdata(pdev); ++ struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); ++ ++ spi_master_suspend(master); ++ clk_disable(bs->clk); ++ ++ return 0; ++} ++ ++static int bcm63xx_hsspi_resume(struct platform_device *pdev) ++{ ++ struct spi_master *master = platform_get_drvdata(pdev); ++ struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); ++ ++ clk_enable(bs->clk); ++ spi_master_resume(master); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops bcm63xx_hsspi_pm_ops = { ++ .suspend = bcm63xx_hsspi_suspend, ++ .resume = bcm63xx_hsspi_resume, ++}; ++ ++#define BCM63XX_HSSPI_PM_OPS (&bcm63xx_hsspi_pm_ops) ++#else ++#define BCM63XX_HSSPI_PM_OPS NULL ++#endif ++ ++ ++ ++static struct platform_driver bcm63xx_hsspi_driver = { ++ .driver = { ++ .name = "bcm63xx-hsspi", ++ .owner = THIS_MODULE, ++ .pm = BCM63XX_HSSPI_PM_OPS, ++ }, ++ .probe = bcm63xx_hsspi_probe, ++ .remove = __exit_p(bcm63xx_hsspi_remove), ++}; ++ ++module_platform_driver(bcm63xx_hsspi_driver); ++ ++MODULE_ALIAS("platform:bcm63xx_hsspi"); ++MODULE_DESCRIPTION("Broadcom BCM63xx HS SPI Controller driver"); ++MODULE_AUTHOR("Jonas Gorski "); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/brcm63xx/patches-3.3/427-MIPS-BCM63XX-Register-SPI-flash-if-present.patch b/target/linux/brcm63xx/patches-3.3/427-MIPS-BCM63XX-Register-SPI-flash-if-present.patch new file mode 100644 index 0000000000..f3bf2cd33f --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/427-MIPS-BCM63XX-Register-SPI-flash-if-present.patch @@ -0,0 +1,102 @@ +From d135d94b3d1fe599d13e7198d5f502912d694c13 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Sun, 3 Jul 2011 15:00:38 +0200 +Subject: [PATCH 29/60] MIPS: BCM63XX: Register SPI flash if present + +Signed-off-by: Jonas Gorski +--- + arch/mips/bcm63xx/dev-flash.c | 33 +++++++++++++++++++- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 2 + + 2 files changed, 33 insertions(+), 2 deletions(-) + +--- a/arch/mips/bcm63xx/dev-flash.c ++++ b/arch/mips/bcm63xx/dev-flash.c +@@ -16,9 +16,12 @@ + #include + #include + #include ++#include ++#include + + #include + #include ++#include + #include + #include + +@@ -55,6 +58,21 @@ static struct platform_device mtd_dev = + }, + }; + ++static struct flash_platform_data bcm63xx_flash_data = { ++ .part_probe_types = bcm63xx_part_types, ++}; ++ ++static struct spi_board_info bcm63xx_spi_flash_info[] = { ++ { ++ .bus_num = 0, ++ .chip_select = 0, ++ .mode = 0, ++ .max_speed_hz = 781000, ++ .modalias = "m25p80", ++ .platform_data = &bcm63xx_flash_data, ++ }, ++}; ++ + static int __init bcm63xx_detect_flash_type(void) + { + u32 val; +@@ -62,6 +80,11 @@ static int __init bcm63xx_detect_flash_t + switch (bcm63xx_get_cpu_id()) { + case BCM6328_CPU_ID: + val = bcm_misc_readl(MISC_STRAPBUS_6328_REG); ++ if (val & STRAPBUS_6328_HSSPI_CLK_FAST) ++ bcm63xx_spi_flash_info[0].max_speed_hz = 33333334; ++ else ++ bcm63xx_spi_flash_info[0].max_speed_hz = 16666667; ++ + if (val & STRAPBUS_6328_BOOT_SEL_SERIAL) + return BCM63XX_FLASH_TYPE_SERIAL; + else +@@ -79,6 +102,9 @@ static int __init bcm63xx_detect_flash_t + return BCM63XX_FLASH_TYPE_SERIAL; + case BCM6368_CPU_ID: + val = bcm_gpio_readl(GPIO_STRAPBUS_REG); ++ if (val & STRAPBUS_6368_SPI_CLK_FAST) ++ bcm63xx_spi_flash_info[0].max_speed_hz = 20000000; ++ + switch (val & STRAPBUS_6368_BOOT_SEL_MASK) { + case STRAPBUS_6368_BOOT_SEL_NAND: + return BCM63XX_FLASH_TYPE_NAND; +@@ -110,8 +136,11 @@ int __init bcm63xx_flash_register(void) + + return platform_device_register(&mtd_dev); + case BCM63XX_FLASH_TYPE_SERIAL: +- pr_warn("unsupported serial flash detected\n"); +- return -ENODEV; ++ if (BCMCPU_IS_6328()) ++ bcm63xx_flash_data.max_transfer_len = HSSPI_BUFFER_LEN; ++ ++ return spi_register_board_info(bcm63xx_spi_flash_info, ++ ARRAY_SIZE(bcm63xx_spi_flash_info)); + case BCM63XX_FLASH_TYPE_NAND: + pr_warn("unsupported NAND flash detected\n"); + return -ENODEV; +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -555,6 +555,7 @@ + #define GPIO_STRAPBUS_REG 0x40 + #define STRAPBUS_6358_BOOT_SEL_PARALLEL (1 << 1) + #define STRAPBUS_6358_BOOT_SEL_SERIAL (0 << 1) ++#define STRAPBUS_6368_SPI_CLK_FAST (1 << 6) + #define STRAPBUS_6368_BOOT_SEL_MASK 0x3 + #define STRAPBUS_6368_BOOT_SEL_NAND 0 + #define STRAPBUS_6368_BOOT_SEL_SERIAL 1 +@@ -1240,6 +1241,7 @@ + #define SERDES_PCIE_EXD_EN (1 << 15) + + #define MISC_STRAPBUS_6328_REG 0x240 ++#define STRAPBUS_6328_HSSPI_CLK_FAST (1 << 4) + #define STRAPBUS_6328_FCVO_SHIFT 7 + #define STRAPBUS_6328_FCVO_MASK (0x1f << STRAPBUS_6328_FCVO_SHIFT) + #define STRAPBUS_6328_BOOT_SEL_SERIAL (1 << 28) diff --git a/target/linux/brcm63xx/patches-3.3/427-MIPS-BCM63XX-store-the-flash-type-in-global-variable.patch b/target/linux/brcm63xx/patches-3.3/427-MIPS-BCM63XX-store-the-flash-type-in-global-variable.patch deleted file mode 100644 index 6e5cdbe840..0000000000 --- a/target/linux/brcm63xx/patches-3.3/427-MIPS-BCM63XX-store-the-flash-type-in-global-variable.patch +++ /dev/null @@ -1,109 +0,0 @@ -From f888824d352df894ab721a5ca067b0313500efe7 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Thu, 3 May 2012 12:17:54 +0200 -Subject: [PATCH 38/59] MIPS: BCM63XX: store the flash type in global variable - ---- - arch/mips/bcm63xx/dev-flash.c | 36 +++++++++++++------ - .../include/asm/mach-bcm63xx/bcm63xx_dev_flash.h | 2 + - 2 files changed, 26 insertions(+), 12 deletions(-) - ---- a/arch/mips/bcm63xx/dev-flash.c -+++ b/arch/mips/bcm63xx/dev-flash.c -@@ -25,6 +25,8 @@ - #include - #include - -+int bcm63xx_attached_flash = -1; -+ - static struct mtd_partition mtd_partitions[] = { - { - .name = "cfe", -@@ -86,20 +88,23 @@ static int __init bcm63xx_detect_flash_t - bcm63xx_spi_flash_info[0].max_speed_hz = 16666667; - - if (val & STRAPBUS_6328_BOOT_SEL_SERIAL) -- return BCM63XX_FLASH_TYPE_SERIAL; -+ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_SERIAL; - else -- return BCM63XX_FLASH_TYPE_NAND; -+ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_NAND; -+ break; - case BCM6338_CPU_ID: - case BCM6345_CPU_ID: - case BCM6348_CPU_ID: - /* no way to auto detect so assume parallel */ -- return BCM63XX_FLASH_TYPE_PARALLEL; -+ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_PARALLEL; -+ break; - case BCM6358_CPU_ID: - val = bcm_gpio_readl(GPIO_STRAPBUS_REG); - if (val & STRAPBUS_6358_BOOT_SEL_PARALLEL) -- return BCM63XX_FLASH_TYPE_PARALLEL; -+ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_PARALLEL; - else -- return BCM63XX_FLASH_TYPE_SERIAL; -+ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_SERIAL; -+ break; - case BCM6368_CPU_ID: - val = bcm_gpio_readl(GPIO_STRAPBUS_REG); - if (val & STRAPBUS_6368_SPI_CLK_FAST) -@@ -107,25 +112,32 @@ static int __init bcm63xx_detect_flash_t - - switch (val & STRAPBUS_6368_BOOT_SEL_MASK) { - case STRAPBUS_6368_BOOT_SEL_NAND: -- return BCM63XX_FLASH_TYPE_NAND; -+ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_NAND; -+ break; - case STRAPBUS_6368_BOOT_SEL_SERIAL: -- return BCM63XX_FLASH_TYPE_SERIAL; -+ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_SERIAL; -+ break; - case STRAPBUS_6368_BOOT_SEL_PARALLEL: -- return BCM63XX_FLASH_TYPE_PARALLEL; -+ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_PARALLEL; -+ break; -+ default: -+ return -EINVAL; - } - default: - return -EINVAL; - } -+ -+ return 0; - } - - int __init bcm63xx_flash_register(void) - { -- int flash_type; - u32 val; - -- flash_type = bcm63xx_detect_flash_type(); - -- switch (flash_type) { -+ bcm63xx_detect_flash_type(); -+ -+ switch (bcm63xx_attached_flash) { - case BCM63XX_FLASH_TYPE_PARALLEL: - /* read base address of boot chip select (0) */ - val = bcm_mpi_readl(MPI_CSBASE_REG(0)); -@@ -146,7 +158,7 @@ int __init bcm63xx_flash_register(void) - return -ENODEV; - default: - pr_err("flash detection failed for BCM%x: %d\n", -- bcm63xx_get_cpu_id(), flash_type); -+ bcm63xx_get_cpu_id(), bcm63xx_attached_flash); - return -ENODEV; - } - } ---- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h -+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h -@@ -7,6 +7,8 @@ enum { - BCM63XX_FLASH_TYPE_NAND, - }; - -+extern int bcm63xx_attached_flash; -+ - int __init bcm63xx_flash_register(void); - - #endif /* __BCM63XX_FLASH_H */ diff --git a/target/linux/brcm63xx/patches-3.3/428-BCM63XX-add-a-fixup-for-ath9k-devices.patch b/target/linux/brcm63xx/patches-3.3/428-BCM63XX-add-a-fixup-for-ath9k-devices.patch deleted file mode 100644 index a3b30e4443..0000000000 --- a/target/linux/brcm63xx/patches-3.3/428-BCM63XX-add-a-fixup-for-ath9k-devices.patch +++ /dev/null @@ -1,227 +0,0 @@ -From fb6f6f58db9ae9cf27ab01f5f09cfbc5c078a7b8 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Thu, 3 May 2012 14:36:11 +0200 -Subject: [PATCH 66/80] BCM63XX: add a fixup for ath9k devices - ---- - arch/mips/bcm63xx/Makefile | 2 +- - arch/mips/bcm63xx/pci-ath9k-fixup.c | 190 ++++++++++++++++++++ - .../include/asm/mach-bcm63xx/pci_ath9k_fixup.h | 7 + - 3 files changed, 198 insertions(+), 1 deletion(-) - create mode 100644 arch/mips/bcm63xx/pci-ath9k-fixup.c - create mode 100644 arch/mips/include/asm/mach-bcm63xx/pci_ath9k_fixup.h - ---- a/arch/mips/bcm63xx/Makefile -+++ b/arch/mips/bcm63xx/Makefile -@@ -1,7 +1,7 @@ - obj-y += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o setup.o \ - timer.o dev-dsp.o dev-enet.o dev-flash.o dev-hsspi.o \ - dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o dev-usb-ehci.o \ -- dev-usb-ohci.o dev-wdt.o -+ dev-usb-ohci.o dev-wdt.o pci-ath9k-fixup.o - obj-$(CONFIG_EARLY_PRINTK) += early_printk.o - - obj-y += boards/ ---- /dev/null -+++ b/arch/mips/bcm63xx/pci-ath9k-fixup.c -@@ -0,0 +1,190 @@ -+/* -+ * Broadcom BCM63XX Ath9k EEPROM fixup helper. -+ * -+ * Copytight (C) 2012 Jonas Gorski -+ * -+ * Based on -+ * -+ * Atheros AP94 reference board PCI initialization -+ * -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct ath9k_fixup { -+ unsigned slot; -+ u8 mac[ETH_ALEN]; -+ struct ath9k_platform_data pdata; -+}; -+ -+static int ath9k_num_fixups; -+static struct ath9k_fixup ath9k_fixups[2] = { -+ { -+ .slot = 255, -+ .pdata = { -+ .led_pin = -1, -+ }, -+ }, -+ { -+ .slot = 255, -+ .pdata = { -+ .led_pin = -1, -+ }, -+ }, -+}; -+ -+static u16 *bcm63xx_read_eeprom(u16 *eeprom, u32 offset) -+{ -+ u32 addr; -+ -+ if (BCMCPU_IS_6328()) { -+ addr = 0x18000000; -+ } else { -+ addr = bcm_mpi_readl(MPI_CSBASE_REG(0)); -+ addr &= MPI_CSBASE_BASE_MASK; -+ } -+ -+ switch (bcm63xx_attached_flash) { -+ case BCM63XX_FLASH_TYPE_PARALLEL: -+ memcpy(eeprom, (void *)KSEG1ADDR(addr + offset), ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16)); -+ return eeprom; -+ case BCM63XX_FLASH_TYPE_SERIAL: -+ /* the first megabyte is memory mapped */ -+ if (offset < 0x100000) { -+ memcpy(eeprom, (void *)KSEG1ADDR(addr + offset), ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16)); -+ return eeprom; -+ } -+ -+ if (BCMCPU_IS_6328()) { -+ /* we can change the memory mapped megabyte */ -+ bcm_hsspi_writel(offset & 0xf00000, 0x18); -+ memcpy(eeprom, (void *)KSEG1ADDR(addr + (offset & 0xfffff)), ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16)); -+ bcm_hsspi_writel(0, 0x18); -+ return eeprom; -+ } -+ /* can't do anything here without talking to the SPI controller. */ -+ case BCM63XX_FLASH_TYPE_NAND: -+ default: -+ return NULL; -+ } -+} -+ -+static void ath9k_pci_fixup(struct pci_dev *dev) -+{ -+ void __iomem *mem; -+ struct ath9k_platform_data *pdata = NULL; -+ u16 *cal_data = NULL; -+ u16 cmd; -+ u32 bar0; -+ u32 val; -+ unsigned i; -+ -+ for (i = 0; i < ath9k_num_fixups; i++) { -+ if (ath9k_fixups[i].slot != PCI_SLOT(dev->devfn)) -+ continue; -+ -+ cal_data = ath9k_fixups[i].pdata.eeprom_data; -+ pdata = &ath9k_fixups[i].pdata; -+ break; -+ } -+ -+ if (cal_data == NULL) -+ return; -+ -+ if (*cal_data != 0xa55a) { -+ pr_err("pci %s: invalid calibration data\n", pci_name(dev)); -+ return; -+ } -+ -+ pr_info("pci %s: fixup device configuration\n", pci_name(dev)); -+ -+ switch (bcm63xx_get_cpu_id()) { -+ case BCM6328_CPU_ID: -+ val = BCM_PCIE_MEM_BASE_PA; -+ break; -+ case BCM6348_CPU_ID: -+ case BCM6358_CPU_ID: -+ case BCM6368_CPU_ID: -+ val = BCM_PCI_MEM_BASE_PA; -+ break; -+ default: -+ BUG(); -+ } -+ -+ mem = ioremap(val, 0x10000); -+ if (!mem) { -+ pr_err("pci %s: ioremap error\n", pci_name(dev)); -+ return; -+ } -+ -+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); -+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, val); -+ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+ -+ /* set offset to first reg address */ -+ cal_data += 3; -+ while(*cal_data != 0xffff) { -+ u32 reg; -+ reg = *cal_data++; -+ val = *cal_data++; -+ val |= (*cal_data++) << 16; -+ -+ writel(val, mem + reg); -+ udelay(100); -+ } -+ -+ pci_read_config_dword(dev, PCI_VENDOR_ID, &val); -+ dev->vendor = val & 0xffff; -+ dev->device = (val >> 16) & 0xffff; -+ -+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &val); -+ dev->revision = val & 0xff; -+ dev->class = val >> 8; /* upper 3 bytes */ -+ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+ -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0); -+ -+ iounmap(mem); -+ -+ dev->dev.platform_data = pdata; -+} -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup); -+ -+void __init pci_enable_ath9k_fixup(unsigned slot, u32 offset) -+{ -+ if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups)) -+ return; -+ -+ ath9k_fixups[ath9k_num_fixups].slot = slot; -+ -+ if (!bcm63xx_read_eeprom(ath9k_fixups[ath9k_num_fixups].pdata.eeprom_data, offset)) -+ return; -+ -+ if (bcm63xx_nvram_get_mac_address(ath9k_fixups[ath9k_num_fixups].mac)) -+ return; -+ -+ ath9k_fixups[ath9k_num_fixups].pdata.macaddr = ath9k_fixups[ath9k_num_fixups].mac; -+ ath9k_num_fixups++; -+} ---- /dev/null -+++ b/arch/mips/include/asm/mach-bcm63xx/pci_ath9k_fixup.h -@@ -0,0 +1,7 @@ -+#ifndef _PCI_ATH9K_FIXUP -+#define _PCI_ATH9K_FIXUP -+ -+ -+void pci_enable_ath9k_fixup(unsigned slot, u32 offset) __init; -+ -+#endif /* _PCI_ATH9K_FIXUP */ diff --git a/target/linux/brcm63xx/patches-3.3/428-MIPS-BCM63XX-move-nvram-related-functions-into-their.patch b/target/linux/brcm63xx/patches-3.3/428-MIPS-BCM63XX-move-nvram-related-functions-into-their.patch new file mode 100644 index 0000000000..ff2a831d84 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/428-MIPS-BCM63XX-move-nvram-related-functions-into-their.patch @@ -0,0 +1,351 @@ +From 5b753c1d01c6af23d7d37d37d9de30da8a971084 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Sat, 12 May 2012 22:51:08 +0200 +Subject: [PATCH 60/79] MIPS: BCM63XX: move nvram related functions into their + own file + +Signed-off-by: Jonas Gorski +--- + arch/mips/bcm63xx/Makefile | 6 +- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 74 +++-------------- + arch/mips/bcm63xx/nvram.c | 84 ++++++++++++++++++++ + arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h | 34 ++++++++ + .../mips/include/asm/mach-bcm63xx/board_bcm963xx.h | 17 ---- + 5 files changed, 134 insertions(+), 81 deletions(-) + create mode 100644 arch/mips/bcm63xx/nvram.c + create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h + +--- a/arch/mips/bcm63xx/Makefile ++++ b/arch/mips/bcm63xx/Makefile +@@ -1,6 +1,6 @@ +-obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ +- dev-dsp.o dev-enet.o dev-flash.o dev-hsspi.o dev-pcmcia.o \ +- dev-rng.o dev-spi.o dev-uart.o dev-usb-ehci.o \ ++obj-y += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o setup.o \ ++ timer.o dev-dsp.o dev-enet.o dev-flash.o dev-hsspi.o \ ++ dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o dev-usb-ehci.o \ + dev-usb-ohci.o dev-wdt.o + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o + +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -41,8 +42,6 @@ + #define CFE_OFFSET_64K 0x10000 + #define CFE_OFFSET_128K 0x20000 + +-static struct bcm963xx_nvram nvram; +-static unsigned int mac_addr_used; + static struct board_info board; + + /* +@@ -696,50 +695,16 @@ const char *board_get_name(void) + return board.name; + } + +-/* +- * register & return a new board mac address +- */ +-static int board_get_mac_address(u8 *mac) +-{ +- u8 *p; +- int count; +- +- if (mac_addr_used >= nvram.mac_addr_count) { +- printk(KERN_ERR PFX "not enough mac address\n"); +- return -ENODEV; +- } +- +- memcpy(mac, nvram.mac_addr_base, ETH_ALEN); +- p = mac + ETH_ALEN - 1; +- count = mac_addr_used; +- +- while (count--) { +- do { +- (*p)++; +- if (*p != 0) +- break; +- p--; +- } while (p != mac); +- } +- +- if (p == mac) { +- printk(KERN_ERR PFX "unable to fetch mac address\n"); +- return -ENODEV; +- } +- +- mac_addr_used++; +- return 0; +-} +- + static void __init boardid_fixup(u8 *boot_addr) + { + struct bcm_tag *tag = (struct bcm_tag *)(boot_addr + CFE_OFFSET_64K); ++ char *board_name = (char *)bcm63xx_nvram_get_name(); + + /* check if bcm_tag is at 64k offset */ +- if (strncmp(nvram.name, tag->boardid, BOARDID_LEN) != 0) { ++ if (strncmp(board_name, tag->boardid, BOARDID_LEN) != 0) { + /* else try 128k */ + tag = (struct bcm_tag *)(boot_addr + CFE_OFFSET_128K); +- if (strncmp(nvram.name, tag->boardid, BOARDID_LEN) != 0) { ++ if (strncmp(board_name, tag->boardid, BOARDID_LEN) != 0) { + /* No tag found */ + printk(KERN_DEBUG "No bcm_tag found!\n"); + return; +@@ -749,9 +714,9 @@ static void __init boardid_fixup(u8 *boo + if (tag->information1[0] != '+') + return; + +- strncpy(nvram.name, &tag->information1[1], BOARDID_LEN); ++ strncpy(board_name, &tag->information1[1], BOARDID_LEN); + +- printk(KERN_INFO "Overriding boardid with '%s'\n", nvram.name); ++ printk(KERN_INFO "Overriding boardid with '%s'\n", board_name); + } + + /* +@@ -759,9 +724,10 @@ static void __init boardid_fixup(u8 *boo + */ + void __init board_prom_init(void) + { +- unsigned int check_len, i; +- u8 *boot_addr, *cfe, *p; ++ unsigned int i; ++ u8 *boot_addr, *cfe; + char cfe_version[32]; ++ char *board_name; + u32 val; + + /* read base address of boot chip select (0) +@@ -786,32 +752,19 @@ void __init board_prom_init(void) + strcpy(cfe_version, "unknown"); + printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); + +- /* extract nvram data */ +- memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram)); +- +- /* check checksum before using data */ +- if (nvram.version <= 4) +- check_len = offsetof(struct bcm963xx_nvram, checksum_old); +- else +- check_len = sizeof(nvram); +- val = 0; +- p = (u8 *)&nvram; +- while (check_len--) +- val += *p; +- if (val) { +- printk(KERN_ERR PFX "invalid nvram checksum\n"); ++ if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) + return; +- } + + if (strcmp(cfe_version, "unknown") != 0) { + /* cfe present */ + boardid_fixup(boot_addr); + } + ++ board_name = bcm63xx_nvram_get_name(); + /* find board by name */ + for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { +- if (strncmp(nvram.name, bcm963xx_boards[i]->name, +- sizeof(nvram.name))) ++ if (strncmp(board_name, bcm963xx_boards[i]->name, ++ BCM63XX_NVRAM_NAMELEN)) + continue; + /* copy, board desc array is marked initdata */ + memcpy(&board, bcm963xx_boards[i], sizeof(board)); +@@ -821,7 +774,7 @@ void __init board_prom_init(void) + /* bail out if board is not found, will complain later */ + if (!board.name[0]) { + char name[17]; +- memcpy(name, nvram.name, 16); ++ memcpy(name, board_name, 16); + name[16] = 0; + printk(KERN_ERR PFX "unknown bcm963xx board: %s\n", + name); +@@ -914,15 +867,15 @@ int __init board_register_devices(void) + bcm63xx_pcmcia_register(); + + if (board.has_enet0 && +- !board_get_mac_address(board.enet0.mac_addr)) ++ !bcm63xx_nvram_get_mac_address(board.enet0.mac_addr)) + bcm63xx_enet_register(0, &board.enet0); + + if (board.has_enet1 && +- !board_get_mac_address(board.enet1.mac_addr)) ++ !bcm63xx_nvram_get_mac_address(board.enet1.mac_addr)) + bcm63xx_enet_register(1, &board.enet1); + + if (board.has_enetsw && +- !board_get_mac_address(board.enetsw.mac_addr)) ++ !bcm63xx_nvram_get_mac_address(board.enetsw.mac_addr)) + bcm63xx_enetsw_register(&board.enetsw); + + if (board.has_ehci0) +@@ -938,7 +891,7 @@ int __init board_register_devices(void) + * do this after registering enet devices + */ + #ifdef CONFIG_SSB_PCIHOST +- if (!board_get_mac_address(bcm63xx_sprom.il0mac)) { ++ if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) { + memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); + memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); + if (ssb_arch_register_fallback_sprom( +--- /dev/null ++++ b/arch/mips/bcm63xx/nvram.c +@@ -0,0 +1,84 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2012 Jonas Gorski ++ */ ++ ++#define pr_fmt(fmt) "bcm63xx_nvram: " fmt ++ ++#include ++#include ++#include ++ ++#include ++ ++static struct bcm963xx_nvram nvram; ++static int mac_addr_used; ++ ++int __init bcm63xx_nvram_init(void *addr) ++{ ++ unsigned int check_len; ++ u8 *p; ++ u32 val; ++ ++ /* extract nvram data */ ++ memcpy(&nvram, addr, sizeof(nvram)); ++ ++ /* check checksum before using data */ ++ if (nvram.version <= 4) ++ check_len = offsetof(struct bcm963xx_nvram, checksum_old); ++ else ++ check_len = sizeof(nvram); ++ val = 0; ++ p = (u8 *)&nvram; ++ ++ while (check_len--) ++ val += *p; ++ if (val) { ++ pr_err("invalid nvram checksum\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++u8 *bcm63xx_nvram_get_name(void) ++{ ++ return nvram.name; ++} ++EXPORT_SYMBOL(bcm63xx_nvram_get_name); ++ ++int bcm63xx_nvram_get_mac_address(u8 *mac) ++{ ++ u8 *p; ++ int count; ++ ++ if (mac_addr_used >= nvram.mac_addr_count) { ++ pr_err("not enough mac address\n"); ++ return -ENODEV; ++ } ++ ++ memcpy(mac, nvram.mac_addr_base, ETH_ALEN); ++ p = mac + ETH_ALEN - 1; ++ count = mac_addr_used; ++ ++ while (count--) { ++ do { ++ (*p)++; ++ if (*p != 0) ++ break; ++ p--; ++ } while (p != mac); ++ } ++ ++ if (p == mac) { ++ pr_err("unable to fetch mac address\n"); ++ return -ENODEV; ++ } ++ ++ mac_addr_used++; ++ return 0; ++} ++EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address); +--- /dev/null ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h +@@ -0,0 +1,34 @@ ++#ifndef BCM63XX_NVRAM_H ++#define BCM63XX_NVRAM_H ++ ++#include ++ ++#define BCM63XX_NVRAM_NAMELEN 16 ++ ++/* ++ * nvram structure ++ */ ++struct bcm963xx_nvram { ++ u32 version; ++ u8 reserved1[256]; ++ u8 name[BCM63XX_NVRAM_NAMELEN]; ++ u32 main_tp_number; ++ u32 psi_size; ++ u32 mac_addr_count; ++ u8 mac_addr_base[ETH_ALEN]; ++ u8 reserved2[2]; ++ u32 checksum_old; ++ u8 reserved3[720]; ++ u32 checksum_high; ++}; ++ ++int __init bcm63xx_nvram_init(void *); ++ ++u8 *bcm63xx_nvram_get_name(void); ++ ++/* ++ * register & return a new board mac address ++ */ ++int bcm63xx_nvram_get_mac_address(u8 *mac); ++ ++#endif /* BCM63XX_NVRAM_H */ +--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h ++++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h +@@ -15,23 +15,6 @@ + #define BCM963XX_NVRAM_OFFSET 0x580 + + /* +- * nvram structure +- */ +-struct bcm963xx_nvram { +- u32 version; +- u8 reserved1[256]; +- u8 name[16]; +- u32 main_tp_number; +- u32 psi_size; +- u32 mac_addr_count; +- u8 mac_addr_base[6]; +- u8 reserved2[2]; +- u32 checksum_old; +- u8 reserved3[720]; +- u32 checksum_high; +-}; +- +-/* + * board definition + */ + struct board_info { diff --git a/target/linux/brcm63xx/patches-3.3/429-MIPS-BCM63XX-export-PSI-size-from-nvram.patch b/target/linux/brcm63xx/patches-3.3/429-MIPS-BCM63XX-export-PSI-size-from-nvram.patch new file mode 100644 index 0000000000..34966b27f1 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/429-MIPS-BCM63XX-export-PSI-size-from-nvram.patch @@ -0,0 +1,44 @@ +From ffbeb183bf0e9e12fd607c5352f48420c32f588f Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Sat, 12 May 2012 23:04:17 +0200 +Subject: [PATCH 61/79] MIPS: BCM63XX: export PSI size from nvram + +Signed-off-by: Jonas Gorski +--- + arch/mips/bcm63xx/nvram.c | 11 +++++++++++ + arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h | 2 ++ + 2 files changed, 13 insertions(+) + +--- a/arch/mips/bcm63xx/nvram.c ++++ b/arch/mips/bcm63xx/nvram.c +@@ -14,6 +14,8 @@ + + #include + ++#define BCM63XX_DEFAULT_PSI_SIZE 64 ++ + static struct bcm963xx_nvram nvram; + static int mac_addr_used; + +@@ -82,3 +84,12 @@ int bcm63xx_nvram_get_mac_address(u8 *ma + return 0; + } + EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address); ++ ++int bcm63xx_nvram_get_psi_size(void) ++{ ++ if (nvram.psi_size > 0) ++ return nvram.psi_size; ++ ++ return BCM63XX_DEFAULT_PSI_SIZE; ++} ++EXPORT_SYMBOL(bcm63xx_nvram_get_psi_size); +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h +@@ -31,4 +31,6 @@ u8 *bcm63xx_nvram_get_name(void); + */ + int bcm63xx_nvram_get_mac_address(u8 *mac); + ++int bcm63xx_nvram_get_psi_size(void); ++ + #endif /* BCM63XX_NVRAM_H */ diff --git a/target/linux/brcm63xx/patches-3.3/429-MTD-bcm63xxpart-allow-passing-a-caldata-offset.patch b/target/linux/brcm63xx/patches-3.3/429-MTD-bcm63xxpart-allow-passing-a-caldata-offset.patch deleted file mode 100644 index 681bab2488..0000000000 --- a/target/linux/brcm63xx/patches-3.3/429-MTD-bcm63xxpart-allow-passing-a-caldata-offset.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 8ab86c5dc38ad4de1442e50e0adbc354d9184d71 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Tue, 1 May 2012 14:38:41 +0200 -Subject: [PATCH 68/79] MTD: bcm63xxpart: allow passing a caldata offset - -Allow bcm63xxpart to receive a caldata offset if calibration data is -contained in flash. ---- - drivers/mtd/bcm63xxpart.c | 47 ++++++++++++++++++++++++++++++++++++++-- - include/linux/mtd/partitions.h | 2 ++ - 2 files changed, 47 insertions(+), 2 deletions(-) - ---- a/drivers/mtd/bcm63xxpart.c -+++ b/drivers/mtd/bcm63xxpart.c -@@ -80,6 +80,8 @@ static int bcm63xx_parse_cfe_partitions( - unsigned int rootfslen, kernellen, sparelen, totallen; - unsigned int cfelen, nvramlen; - unsigned int cfe_erasesize; -+ unsigned int caldatalen1 = 0, caldataaddr1 = 0; -+ unsigned int caldatalen2 = 0, caldataaddr2 = 0; - int i; - u32 computed_crc; - bool rootfs_first = false; -@@ -94,6 +96,23 @@ static int bcm63xx_parse_cfe_partitions( - nvramlen = bcm63xx_nvram_get_psi_size() * 1024; - nvramlen = roundup(nvramlen, cfe_erasesize); - -+ if (data) { -+ if (data->caldata[0]) { -+ caldatalen1 = cfe_erasesize; -+ caldataaddr1 = rounddown(data->caldata[0], -+ cfe_erasesize); -+ } -+ if (data->caldata[1]) { -+ caldatalen2 = cfe_erasesize; -+ caldataaddr2 = rounddown(data->caldata[1], -+ cfe_erasesize); -+ } -+ if (caldataaddr1 == caldataaddr2) { -+ caldataaddr2 = 0; -+ caldatalen2 = 0; -+ } -+ } -+ - /* Allocate memory for buffer */ - buf = vmalloc(sizeof(struct bcm_tag)); - if (!buf) -@@ -144,7 +163,7 @@ static int bcm63xx_parse_cfe_partitions( - rootfsaddr = 0; - spareaddr = cfelen; - } -- sparelen = master->size - spareaddr - nvramlen; -+ sparelen = master->size - spareaddr - nvramlen - caldatalen1 - caldatalen2; - - /* Determine number of partitions */ - if (rootfslen > 0) -@@ -153,6 +172,12 @@ static int bcm63xx_parse_cfe_partitions( - if (kernellen > 0) - nrparts++; - -+ if (caldatalen1 > 0) -+ nrparts++; -+ -+ if (caldatalen2 > 0) -+ nrparts++; -+ - /* Ask kernel for more memory */ - parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); - if (!parts) { -@@ -190,6 +215,23 @@ static int bcm63xx_parse_cfe_partitions( - curpart++; - } - -+ if (caldatalen1 > 0) { -+ if (caldatalen2 > 0) -+ parts[curpart].name = "cal_data1"; -+ else -+ parts[curpart].name = "cal_data"; -+ parts[curpart].offset = caldataaddr1; -+ parts[curpart].size = caldatalen1; -+ curpart++; -+ } -+ -+ if (caldatalen2 > 0) { -+ parts[curpart].name = "cal_data2"; -+ parts[curpart].offset = caldataaddr2; -+ parts[curpart].size = caldatalen2; -+ curpart++; -+ } -+ - parts[curpart].name = "nvram"; - parts[curpart].offset = master->size - nvramlen; - parts[curpart].size = nvramlen; -@@ -198,7 +240,8 @@ static int bcm63xx_parse_cfe_partitions( - /* Global partition "linux" to make easy firmware upgrade */ - parts[curpart].name = "linux"; - parts[curpart].offset = cfelen; -- parts[curpart].size = master->size - cfelen - nvramlen; -+ parts[curpart].size = master->size - cfelen - nvramlen -+ - caldatalen1 - caldatalen2; - - for (i = 0; i < nrparts; i++) - pr_info("Partition %d is %s offset %llx and length %llx\n", i, ---- a/include/linux/mtd/partitions.h -+++ b/include/linux/mtd/partitions.h -@@ -58,10 +58,12 @@ struct device_node; - /** - * struct mtd_part_parser_data - used to pass data to MTD partition parsers. - * @origin: for RedBoot, start address of MTD device -+ * @caldata: for CFE, start address of wifi calibration data - * @of_node: for OF parsers, device node containing partitioning information - */ - struct mtd_part_parser_data { - unsigned long origin; -+ unsigned long caldata[2]; - struct device_node *of_node; - }; - diff --git a/target/linux/brcm63xx/patches-3.3/430-MIPS-BCM63XX-pass-caldata-info-to-flash.patch b/target/linux/brcm63xx/patches-3.3/430-MIPS-BCM63XX-pass-caldata-info-to-flash.patch deleted file mode 100644 index 2c7368477e..0000000000 --- a/target/linux/brcm63xx/patches-3.3/430-MIPS-BCM63XX-pass-caldata-info-to-flash.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 977f8a30103b9c4992cab8f49357fe0d4274004f Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Thu, 3 May 2012 14:55:26 +0200 -Subject: [PATCH 69/80] MIPS: BCM63XX: pass caldata info to flash - ---- - arch/mips/bcm63xx/boards/board_bcm963xx.c | 2 +- - arch/mips/bcm63xx/dev-flash.c | 9 ++++++++- - arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h | 4 +++- - 3 files changed, 12 insertions(+), 3 deletions(-) - ---- a/arch/mips/bcm63xx/boards/board_bcm963xx.c -+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c -@@ -912,7 +912,7 @@ int __init board_register_devices(void) - if (board.num_spis) - spi_register_board_info(board.spis, board.num_spis); - -- bcm63xx_flash_register(); -+ bcm63xx_flash_register(board.has_caldata, board.caldata); - - /* count number of LEDs defined by this device */ - while (led_count < ARRAY_SIZE(board.leds) && board.leds[led_count].name) ---- a/arch/mips/bcm63xx/dev-flash.c -+++ b/arch/mips/bcm63xx/dev-flash.c -@@ -35,12 +35,15 @@ static struct mtd_partition mtd_partitio - } - }; - -+static struct mtd_part_parser_data bcm63xx_parser_data; -+ - static const char *bcm63xx_part_types[] = { "bcm63xxpart", "RedBoot", NULL }; - - static struct physmap_flash_data flash_data = { - .width = 2, - .parts = mtd_partitions, - .part_probe_types = bcm63xx_part_types, -+ .pp_data = &bcm63xx_parser_data, - }; - - static struct resource mtd_resources[] = { -@@ -62,6 +65,7 @@ static struct platform_device mtd_dev = - - static struct flash_platform_data bcm63xx_flash_data = { - .part_probe_types = bcm63xx_part_types, -+ .pp_data = &bcm63xx_parser_data, - }; - - static struct spi_board_info bcm63xx_spi_flash_info[] = { -@@ -130,10 +134,13 @@ static int __init bcm63xx_detect_flash_t - return 0; - } - --int __init bcm63xx_flash_register(void) -+int __init bcm63xx_flash_register(int num_caldata, struct ath9k_caldata *caldata) - { - u32 val; -+ unsigned int i; - -+ for (i = 0; i < num_caldata; i++) -+ bcm63xx_parser_data.caldata[i] = caldata[i].caldata_offset; - - bcm63xx_detect_flash_type(); - ---- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h -+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h -@@ -1,6 +1,8 @@ - #ifndef __BCM63XX_FLASH_H - #define __BCM63XX_FLASH_H - -+#include -+ - enum { - BCM63XX_FLASH_TYPE_PARALLEL, - BCM63XX_FLASH_TYPE_SERIAL, -@@ -9,6 +11,6 @@ enum { - - extern int bcm63xx_attached_flash; - --int __init bcm63xx_flash_register(void); -+int __init bcm63xx_flash_register(int num_caldata, struct ath9k_caldata *caldata); - - #endif /* __BCM63XX_FLASH_H */ diff --git a/target/linux/brcm63xx/patches-3.3/430-MTD-bcm63xxpart-use-nvram-for-PSI-size.patch b/target/linux/brcm63xx/patches-3.3/430-MTD-bcm63xxpart-use-nvram-for-PSI-size.patch new file mode 100644 index 0000000000..5ca6f47970 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/430-MTD-bcm63xxpart-use-nvram-for-PSI-size.patch @@ -0,0 +1,29 @@ +From 658afad639a9456e1bb6fe5bba0032f3c0c3f699 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Tue, 1 May 2012 14:10:39 +0200 +Subject: [PATCH 62/79] MTD: bcm63xxpart: use nvram for PSI size + +--- + drivers/mtd/bcm63xxpart.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/bcm63xxpart.c ++++ b/drivers/mtd/bcm63xxpart.c +@@ -32,6 +32,7 @@ + #include + #include + ++#include + #include + #include + +@@ -90,7 +91,8 @@ static int bcm63xx_parse_cfe_partitions( + BCM63XX_CFE_BLOCK_SIZE); + + cfelen = cfe_erasesize; +- nvramlen = cfe_erasesize; ++ nvramlen = bcm63xx_nvram_get_psi_size() * 1024; ++ nvramlen = roundup(nvramlen, cfe_erasesize); + + /* Allocate memory for buffer */ + buf = vmalloc(sizeof(struct bcm_tag)); diff --git a/target/linux/brcm63xx/patches-3.3/431-MTD-physmap-allow-passing-pp_data.patch b/target/linux/brcm63xx/patches-3.3/431-MTD-physmap-allow-passing-pp_data.patch new file mode 100644 index 0000000000..f869911d54 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/431-MTD-physmap-allow-passing-pp_data.patch @@ -0,0 +1,41 @@ +From 266c506f4b262bd6aba0776a03d82c98e65d9906 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Tue, 1 May 2012 17:32:36 +0200 +Subject: [PATCH 63/79] MTD: physmap: allow passing pp_data + +--- + drivers/mtd/maps/physmap.c | 4 +++- + include/linux/mtd/physmap.h | 1 + + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/maps/physmap.c ++++ b/drivers/mtd/maps/physmap.c +@@ -84,6 +84,7 @@ static int physmap_flash_probe(struct pl + { + struct physmap_flash_data *physmap_data; + struct physmap_flash_info *info; ++ struct mtd_part_parser_data *pp_data; + const char **probe_type; + const char **part_types; + int err = 0; +@@ -173,8 +174,9 @@ static int physmap_flash_probe(struct pl + goto err_out; + + part_types = physmap_data->part_probe_types ? : part_probe_types; ++ pp_data = physmap_data->pp_data ? physmap_data->pp_data : NULL; + +- mtd_device_parse_register(info->cmtd, part_types, 0, ++ mtd_device_parse_register(info->cmtd, part_types, pp_data, + physmap_data->parts, physmap_data->nr_parts); + return 0; + +--- a/include/linux/mtd/physmap.h ++++ b/include/linux/mtd/physmap.h +@@ -32,6 +32,7 @@ struct physmap_flash_data { + char *probe_type; + struct mtd_partition *parts; + const char **part_probe_types; ++ struct mtd_part_parser_data *pp_data; + }; + + #endif /* __LINUX_MTD_PHYSMAP__ */ diff --git a/target/linux/brcm63xx/patches-3.3/431-bcm63xx_enet-reset-port-link-state-in-bcm_enetsw_ope.patch b/target/linux/brcm63xx/patches-3.3/431-bcm63xx_enet-reset-port-link-state-in-bcm_enetsw_ope.patch deleted file mode 100644 index e1e048c093..0000000000 --- a/target/linux/brcm63xx/patches-3.3/431-bcm63xx_enet-reset-port-link-state-in-bcm_enetsw_ope.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 6d5c5bb13db3fd8e3dd0b82742b3957f41a4a3ac Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Thu, 24 May 2012 20:38:58 +0200 -Subject: [PATCH] bcm63xx_enet: reset port link state in bcm_enetsw_open - -bcm_enetsw_open disables all ports, but does not reset their link state. -This results in connected ports staying disabled after a ifdown/ifup -cycle, since bcm_enetsw_phy_poll only enables them if their current state -is different from the stored link state. - -Fix this by also resetting the port link state. - -Signed-off-by: Jonas Gorski ---- - drivers/net/ethernet/broadcom/bcm63xx_enet.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c -+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c -@@ -2214,6 +2214,8 @@ static int bcm_enetsw_open(struct net_de - enetsw_writeb(priv, ENETSW_PTCTRL_RXDIS_MASK | - ENETSW_PTCTRL_TXDIS_MASK, - ENETSW_PTCTRL_REG(i)); -+ -+ priv->sw_port_link[i] = 0; - } - - /* reset mib */ diff --git a/target/linux/brcm63xx/patches-3.3/432-BCM63XX-allow-providing-fixup-data-in-board-data.patch b/target/linux/brcm63xx/patches-3.3/432-BCM63XX-allow-providing-fixup-data-in-board-data.patch new file mode 100644 index 0000000000..c79c3fe9af --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/432-BCM63XX-allow-providing-fixup-data-in-board-data.patch @@ -0,0 +1,81 @@ +From 5131195413b62df73dfd394fea272830ea8c4e1a Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Thu, 3 May 2012 14:40:03 +0200 +Subject: [PATCH 67/80] BCM63XX: allow providing fixup data in board data + +--- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 10 +++++++++- + arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h | 10 ++++++++++ + 2 files changed, 19 insertions(+), 1 deletion(-) + +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + #define PFX "board_bcm963xx: " + +@@ -856,6 +857,7 @@ int __init board_register_devices(void) + { + int button_count = 0; + int led_count = 0; ++ int i; + + if (board.has_uart0) + bcm63xx_uart_register(0); +@@ -891,7 +893,8 @@ int __init board_register_devices(void) + * do this after registering enet devices + */ + #ifdef CONFIG_SSB_PCIHOST +- if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) { ++ if (!board.has_caldata && ++ !bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) { + memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); + memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); + if (ssb_arch_register_fallback_sprom( +@@ -931,5 +934,9 @@ int __init board_register_devices(void) + platform_device_register(&bcm63xx_gpio_keys_device); + } + ++ /* register any fixups */ ++ for (i = 0; i < board.has_caldata; i++) ++ pci_enable_ath9k_fixup(board.caldata[i].slot, board.caldata[i].caldata_offset); ++ + return 0; + } +--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h ++++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + + /* + * flash mapping +@@ -14,6 +15,11 @@ + #define BCM963XX_CFE_VERSION_OFFSET 0x570 + #define BCM963XX_NVRAM_OFFSET 0x580 + ++struct ath9k_caldata { ++ unsigned int slot; ++ u32 caldata_offset; ++}; ++ + /* + * board definition + */ +@@ -32,6 +38,10 @@ struct board_info { + unsigned int has_dsp:1; + unsigned int has_uart0:1; + unsigned int has_uart1:1; ++ unsigned int has_caldata:2; ++ ++ /* wifi calibration data config */ ++ struct ath9k_caldata caldata[2]; + + /* ethernet config */ + struct bcm63xx_enet_platform_data enet0; diff --git a/target/linux/brcm63xx/patches-3.3/433-MTD-m25p80-allow-passing-pp_data.patch b/target/linux/brcm63xx/patches-3.3/433-MTD-m25p80-allow-passing-pp_data.patch new file mode 100644 index 0000000000..bda48079e0 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/433-MTD-m25p80-allow-passing-pp_data.patch @@ -0,0 +1,40 @@ +From 7f17dfe9009beb07a3de0e380932a725293829df Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Tue, 1 May 2012 17:33:03 +0200 +Subject: [PATCH 64/79] MTD: m25p80: allow passing pp_data + +--- + drivers/mtd/devices/m25p80.c | 3 +++ + include/linux/spi/flash.h | 2 ++ + 2 files changed, 5 insertions(+) + +--- a/drivers/mtd/devices/m25p80.c ++++ b/drivers/mtd/devices/m25p80.c +@@ -886,6 +886,9 @@ static int __devinit m25p_probe(struct s + dev_warn(&spi->dev, "unrecognized id %s\n", data->type); + } + ++ if (data && data->pp_data) ++ memcpy(&ppdata, data->pp_data, sizeof(ppdata)); ++ + info = (void *)id->driver_data; + + if (info->jedec_id) { +--- a/include/linux/spi/flash.h ++++ b/include/linux/spi/flash.h +@@ -12,6 +12,7 @@ struct mtd_part_parser_data; + * with chips that can't be queried for JEDEC or other IDs + * @part_probe_types: optional list of MTD parser names to use for + * partitioning ++ * @pp_data: optional partition parser data. + * + * @max_transfer_len: option maximum read/write length limitation for + * SPI controllers not able to transfer any length commands. +@@ -30,6 +31,7 @@ struct flash_platform_data { + char *type; + + const char **part_probe_types; ++ struct mtd_part_parser_data *pp_data; + + unsigned int max_transfer_len; + /* we'll likely add more ... use JEDEC IDs, etc */ diff --git a/target/linux/brcm63xx/patches-3.3/434-MIPS-BCM63XX-store-the-flash-type-in-global-variable.patch b/target/linux/brcm63xx/patches-3.3/434-MIPS-BCM63XX-store-the-flash-type-in-global-variable.patch new file mode 100644 index 0000000000..6e5cdbe840 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/434-MIPS-BCM63XX-store-the-flash-type-in-global-variable.patch @@ -0,0 +1,109 @@ +From f888824d352df894ab721a5ca067b0313500efe7 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Thu, 3 May 2012 12:17:54 +0200 +Subject: [PATCH 38/59] MIPS: BCM63XX: store the flash type in global variable + +--- + arch/mips/bcm63xx/dev-flash.c | 36 +++++++++++++------ + .../include/asm/mach-bcm63xx/bcm63xx_dev_flash.h | 2 + + 2 files changed, 26 insertions(+), 12 deletions(-) + +--- a/arch/mips/bcm63xx/dev-flash.c ++++ b/arch/mips/bcm63xx/dev-flash.c +@@ -25,6 +25,8 @@ + #include + #include + ++int bcm63xx_attached_flash = -1; ++ + static struct mtd_partition mtd_partitions[] = { + { + .name = "cfe", +@@ -86,20 +88,23 @@ static int __init bcm63xx_detect_flash_t + bcm63xx_spi_flash_info[0].max_speed_hz = 16666667; + + if (val & STRAPBUS_6328_BOOT_SEL_SERIAL) +- return BCM63XX_FLASH_TYPE_SERIAL; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_SERIAL; + else +- return BCM63XX_FLASH_TYPE_NAND; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_NAND; ++ break; + case BCM6338_CPU_ID: + case BCM6345_CPU_ID: + case BCM6348_CPU_ID: + /* no way to auto detect so assume parallel */ +- return BCM63XX_FLASH_TYPE_PARALLEL; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_PARALLEL; ++ break; + case BCM6358_CPU_ID: + val = bcm_gpio_readl(GPIO_STRAPBUS_REG); + if (val & STRAPBUS_6358_BOOT_SEL_PARALLEL) +- return BCM63XX_FLASH_TYPE_PARALLEL; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_PARALLEL; + else +- return BCM63XX_FLASH_TYPE_SERIAL; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_SERIAL; ++ break; + case BCM6368_CPU_ID: + val = bcm_gpio_readl(GPIO_STRAPBUS_REG); + if (val & STRAPBUS_6368_SPI_CLK_FAST) +@@ -107,25 +112,32 @@ static int __init bcm63xx_detect_flash_t + + switch (val & STRAPBUS_6368_BOOT_SEL_MASK) { + case STRAPBUS_6368_BOOT_SEL_NAND: +- return BCM63XX_FLASH_TYPE_NAND; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_NAND; ++ break; + case STRAPBUS_6368_BOOT_SEL_SERIAL: +- return BCM63XX_FLASH_TYPE_SERIAL; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_SERIAL; ++ break; + case STRAPBUS_6368_BOOT_SEL_PARALLEL: +- return BCM63XX_FLASH_TYPE_PARALLEL; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_PARALLEL; ++ break; ++ default: ++ return -EINVAL; + } + default: + return -EINVAL; + } ++ ++ return 0; + } + + int __init bcm63xx_flash_register(void) + { +- int flash_type; + u32 val; + +- flash_type = bcm63xx_detect_flash_type(); + +- switch (flash_type) { ++ bcm63xx_detect_flash_type(); ++ ++ switch (bcm63xx_attached_flash) { + case BCM63XX_FLASH_TYPE_PARALLEL: + /* read base address of boot chip select (0) */ + val = bcm_mpi_readl(MPI_CSBASE_REG(0)); +@@ -146,7 +158,7 @@ int __init bcm63xx_flash_register(void) + return -ENODEV; + default: + pr_err("flash detection failed for BCM%x: %d\n", +- bcm63xx_get_cpu_id(), flash_type); ++ bcm63xx_get_cpu_id(), bcm63xx_attached_flash); + return -ENODEV; + } + } +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h +@@ -7,6 +7,8 @@ enum { + BCM63XX_FLASH_TYPE_NAND, + }; + ++extern int bcm63xx_attached_flash; ++ + int __init bcm63xx_flash_register(void); + + #endif /* __BCM63XX_FLASH_H */ diff --git a/target/linux/brcm63xx/patches-3.3/435-BCM63XX-add-a-fixup-for-ath9k-devices.patch b/target/linux/brcm63xx/patches-3.3/435-BCM63XX-add-a-fixup-for-ath9k-devices.patch new file mode 100644 index 0000000000..a3b30e4443 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/435-BCM63XX-add-a-fixup-for-ath9k-devices.patch @@ -0,0 +1,227 @@ +From fb6f6f58db9ae9cf27ab01f5f09cfbc5c078a7b8 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Thu, 3 May 2012 14:36:11 +0200 +Subject: [PATCH 66/80] BCM63XX: add a fixup for ath9k devices + +--- + arch/mips/bcm63xx/Makefile | 2 +- + arch/mips/bcm63xx/pci-ath9k-fixup.c | 190 ++++++++++++++++++++ + .../include/asm/mach-bcm63xx/pci_ath9k_fixup.h | 7 + + 3 files changed, 198 insertions(+), 1 deletion(-) + create mode 100644 arch/mips/bcm63xx/pci-ath9k-fixup.c + create mode 100644 arch/mips/include/asm/mach-bcm63xx/pci_ath9k_fixup.h + +--- a/arch/mips/bcm63xx/Makefile ++++ b/arch/mips/bcm63xx/Makefile +@@ -1,7 +1,7 @@ + obj-y += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o setup.o \ + timer.o dev-dsp.o dev-enet.o dev-flash.o dev-hsspi.o \ + dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o dev-usb-ehci.o \ +- dev-usb-ohci.o dev-wdt.o ++ dev-usb-ohci.o dev-wdt.o pci-ath9k-fixup.o + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o + + obj-y += boards/ +--- /dev/null ++++ b/arch/mips/bcm63xx/pci-ath9k-fixup.c +@@ -0,0 +1,190 @@ ++/* ++ * Broadcom BCM63XX Ath9k EEPROM fixup helper. ++ * ++ * Copytight (C) 2012 Jonas Gorski ++ * ++ * Based on ++ * ++ * Atheros AP94 reference board PCI initialization ++ * ++ * Copyright (C) 2009-2010 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct ath9k_fixup { ++ unsigned slot; ++ u8 mac[ETH_ALEN]; ++ struct ath9k_platform_data pdata; ++}; ++ ++static int ath9k_num_fixups; ++static struct ath9k_fixup ath9k_fixups[2] = { ++ { ++ .slot = 255, ++ .pdata = { ++ .led_pin = -1, ++ }, ++ }, ++ { ++ .slot = 255, ++ .pdata = { ++ .led_pin = -1, ++ }, ++ }, ++}; ++ ++static u16 *bcm63xx_read_eeprom(u16 *eeprom, u32 offset) ++{ ++ u32 addr; ++ ++ if (BCMCPU_IS_6328()) { ++ addr = 0x18000000; ++ } else { ++ addr = bcm_mpi_readl(MPI_CSBASE_REG(0)); ++ addr &= MPI_CSBASE_BASE_MASK; ++ } ++ ++ switch (bcm63xx_attached_flash) { ++ case BCM63XX_FLASH_TYPE_PARALLEL: ++ memcpy(eeprom, (void *)KSEG1ADDR(addr + offset), ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16)); ++ return eeprom; ++ case BCM63XX_FLASH_TYPE_SERIAL: ++ /* the first megabyte is memory mapped */ ++ if (offset < 0x100000) { ++ memcpy(eeprom, (void *)KSEG1ADDR(addr + offset), ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16)); ++ return eeprom; ++ } ++ ++ if (BCMCPU_IS_6328()) { ++ /* we can change the memory mapped megabyte */ ++ bcm_hsspi_writel(offset & 0xf00000, 0x18); ++ memcpy(eeprom, (void *)KSEG1ADDR(addr + (offset & 0xfffff)), ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16)); ++ bcm_hsspi_writel(0, 0x18); ++ return eeprom; ++ } ++ /* can't do anything here without talking to the SPI controller. */ ++ case BCM63XX_FLASH_TYPE_NAND: ++ default: ++ return NULL; ++ } ++} ++ ++static void ath9k_pci_fixup(struct pci_dev *dev) ++{ ++ void __iomem *mem; ++ struct ath9k_platform_data *pdata = NULL; ++ u16 *cal_data = NULL; ++ u16 cmd; ++ u32 bar0; ++ u32 val; ++ unsigned i; ++ ++ for (i = 0; i < ath9k_num_fixups; i++) { ++ if (ath9k_fixups[i].slot != PCI_SLOT(dev->devfn)) ++ continue; ++ ++ cal_data = ath9k_fixups[i].pdata.eeprom_data; ++ pdata = &ath9k_fixups[i].pdata; ++ break; ++ } ++ ++ if (cal_data == NULL) ++ return; ++ ++ if (*cal_data != 0xa55a) { ++ pr_err("pci %s: invalid calibration data\n", pci_name(dev)); ++ return; ++ } ++ ++ pr_info("pci %s: fixup device configuration\n", pci_name(dev)); ++ ++ switch (bcm63xx_get_cpu_id()) { ++ case BCM6328_CPU_ID: ++ val = BCM_PCIE_MEM_BASE_PA; ++ break; ++ case BCM6348_CPU_ID: ++ case BCM6358_CPU_ID: ++ case BCM6368_CPU_ID: ++ val = BCM_PCI_MEM_BASE_PA; ++ break; ++ default: ++ BUG(); ++ } ++ ++ mem = ioremap(val, 0x10000); ++ if (!mem) { ++ pr_err("pci %s: ioremap error\n", pci_name(dev)); ++ return; ++ } ++ ++ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); ++ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); ++ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, val); ++ ++ pci_read_config_word(dev, PCI_COMMAND, &cmd); ++ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; ++ pci_write_config_word(dev, PCI_COMMAND, cmd); ++ ++ /* set offset to first reg address */ ++ cal_data += 3; ++ while(*cal_data != 0xffff) { ++ u32 reg; ++ reg = *cal_data++; ++ val = *cal_data++; ++ val |= (*cal_data++) << 16; ++ ++ writel(val, mem + reg); ++ udelay(100); ++ } ++ ++ pci_read_config_dword(dev, PCI_VENDOR_ID, &val); ++ dev->vendor = val & 0xffff; ++ dev->device = (val >> 16) & 0xffff; ++ ++ pci_read_config_dword(dev, PCI_CLASS_REVISION, &val); ++ dev->revision = val & 0xff; ++ dev->class = val >> 8; /* upper 3 bytes */ ++ ++ pci_read_config_word(dev, PCI_COMMAND, &cmd); ++ cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); ++ pci_write_config_word(dev, PCI_COMMAND, cmd); ++ ++ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0); ++ ++ iounmap(mem); ++ ++ dev->dev.platform_data = pdata; ++} ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup); ++ ++void __init pci_enable_ath9k_fixup(unsigned slot, u32 offset) ++{ ++ if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups)) ++ return; ++ ++ ath9k_fixups[ath9k_num_fixups].slot = slot; ++ ++ if (!bcm63xx_read_eeprom(ath9k_fixups[ath9k_num_fixups].pdata.eeprom_data, offset)) ++ return; ++ ++ if (bcm63xx_nvram_get_mac_address(ath9k_fixups[ath9k_num_fixups].mac)) ++ return; ++ ++ ath9k_fixups[ath9k_num_fixups].pdata.macaddr = ath9k_fixups[ath9k_num_fixups].mac; ++ ath9k_num_fixups++; ++} +--- /dev/null ++++ b/arch/mips/include/asm/mach-bcm63xx/pci_ath9k_fixup.h +@@ -0,0 +1,7 @@ ++#ifndef _PCI_ATH9K_FIXUP ++#define _PCI_ATH9K_FIXUP ++ ++ ++void pci_enable_ath9k_fixup(unsigned slot, u32 offset) __init; ++ ++#endif /* _PCI_ATH9K_FIXUP */ diff --git a/target/linux/brcm63xx/patches-3.3/436-MTD-bcm63xxpart-allow-passing-a-caldata-offset.patch b/target/linux/brcm63xx/patches-3.3/436-MTD-bcm63xxpart-allow-passing-a-caldata-offset.patch new file mode 100644 index 0000000000..681bab2488 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/436-MTD-bcm63xxpart-allow-passing-a-caldata-offset.patch @@ -0,0 +1,118 @@ +From 8ab86c5dc38ad4de1442e50e0adbc354d9184d71 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Tue, 1 May 2012 14:38:41 +0200 +Subject: [PATCH 68/79] MTD: bcm63xxpart: allow passing a caldata offset + +Allow bcm63xxpart to receive a caldata offset if calibration data is +contained in flash. +--- + drivers/mtd/bcm63xxpart.c | 47 ++++++++++++++++++++++++++++++++++++++-- + include/linux/mtd/partitions.h | 2 ++ + 2 files changed, 47 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/bcm63xxpart.c ++++ b/drivers/mtd/bcm63xxpart.c +@@ -80,6 +80,8 @@ static int bcm63xx_parse_cfe_partitions( + unsigned int rootfslen, kernellen, sparelen, totallen; + unsigned int cfelen, nvramlen; + unsigned int cfe_erasesize; ++ unsigned int caldatalen1 = 0, caldataaddr1 = 0; ++ unsigned int caldatalen2 = 0, caldataaddr2 = 0; + int i; + u32 computed_crc; + bool rootfs_first = false; +@@ -94,6 +96,23 @@ static int bcm63xx_parse_cfe_partitions( + nvramlen = bcm63xx_nvram_get_psi_size() * 1024; + nvramlen = roundup(nvramlen, cfe_erasesize); + ++ if (data) { ++ if (data->caldata[0]) { ++ caldatalen1 = cfe_erasesize; ++ caldataaddr1 = rounddown(data->caldata[0], ++ cfe_erasesize); ++ } ++ if (data->caldata[1]) { ++ caldatalen2 = cfe_erasesize; ++ caldataaddr2 = rounddown(data->caldata[1], ++ cfe_erasesize); ++ } ++ if (caldataaddr1 == caldataaddr2) { ++ caldataaddr2 = 0; ++ caldatalen2 = 0; ++ } ++ } ++ + /* Allocate memory for buffer */ + buf = vmalloc(sizeof(struct bcm_tag)); + if (!buf) +@@ -144,7 +163,7 @@ static int bcm63xx_parse_cfe_partitions( + rootfsaddr = 0; + spareaddr = cfelen; + } +- sparelen = master->size - spareaddr - nvramlen; ++ sparelen = master->size - spareaddr - nvramlen - caldatalen1 - caldatalen2; + + /* Determine number of partitions */ + if (rootfslen > 0) +@@ -153,6 +172,12 @@ static int bcm63xx_parse_cfe_partitions( + if (kernellen > 0) + nrparts++; + ++ if (caldatalen1 > 0) ++ nrparts++; ++ ++ if (caldatalen2 > 0) ++ nrparts++; ++ + /* Ask kernel for more memory */ + parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); + if (!parts) { +@@ -190,6 +215,23 @@ static int bcm63xx_parse_cfe_partitions( + curpart++; + } + ++ if (caldatalen1 > 0) { ++ if (caldatalen2 > 0) ++ parts[curpart].name = "cal_data1"; ++ else ++ parts[curpart].name = "cal_data"; ++ parts[curpart].offset = caldataaddr1; ++ parts[curpart].size = caldatalen1; ++ curpart++; ++ } ++ ++ if (caldatalen2 > 0) { ++ parts[curpart].name = "cal_data2"; ++ parts[curpart].offset = caldataaddr2; ++ parts[curpart].size = caldatalen2; ++ curpart++; ++ } ++ + parts[curpart].name = "nvram"; + parts[curpart].offset = master->size - nvramlen; + parts[curpart].size = nvramlen; +@@ -198,7 +240,8 @@ static int bcm63xx_parse_cfe_partitions( + /* Global partition "linux" to make easy firmware upgrade */ + parts[curpart].name = "linux"; + parts[curpart].offset = cfelen; +- parts[curpart].size = master->size - cfelen - nvramlen; ++ parts[curpart].size = master->size - cfelen - nvramlen ++ - caldatalen1 - caldatalen2; + + for (i = 0; i < nrparts; i++) + pr_info("Partition %d is %s offset %llx and length %llx\n", i, +--- a/include/linux/mtd/partitions.h ++++ b/include/linux/mtd/partitions.h +@@ -58,10 +58,12 @@ struct device_node; + /** + * struct mtd_part_parser_data - used to pass data to MTD partition parsers. + * @origin: for RedBoot, start address of MTD device ++ * @caldata: for CFE, start address of wifi calibration data + * @of_node: for OF parsers, device node containing partitioning information + */ + struct mtd_part_parser_data { + unsigned long origin; ++ unsigned long caldata[2]; + struct device_node *of_node; + }; + diff --git a/target/linux/brcm63xx/patches-3.3/437-MIPS-BCM63XX-pass-caldata-info-to-flash.patch b/target/linux/brcm63xx/patches-3.3/437-MIPS-BCM63XX-pass-caldata-info-to-flash.patch new file mode 100644 index 0000000000..2c7368477e --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/437-MIPS-BCM63XX-pass-caldata-info-to-flash.patch @@ -0,0 +1,82 @@ +From 977f8a30103b9c4992cab8f49357fe0d4274004f Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Thu, 3 May 2012 14:55:26 +0200 +Subject: [PATCH 69/80] MIPS: BCM63XX: pass caldata info to flash + +--- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 2 +- + arch/mips/bcm63xx/dev-flash.c | 9 ++++++++- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h | 4 +++- + 3 files changed, 12 insertions(+), 3 deletions(-) + +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -912,7 +912,7 @@ int __init board_register_devices(void) + if (board.num_spis) + spi_register_board_info(board.spis, board.num_spis); + +- bcm63xx_flash_register(); ++ bcm63xx_flash_register(board.has_caldata, board.caldata); + + /* count number of LEDs defined by this device */ + while (led_count < ARRAY_SIZE(board.leds) && board.leds[led_count].name) +--- a/arch/mips/bcm63xx/dev-flash.c ++++ b/arch/mips/bcm63xx/dev-flash.c +@@ -35,12 +35,15 @@ static struct mtd_partition mtd_partitio + } + }; + ++static struct mtd_part_parser_data bcm63xx_parser_data; ++ + static const char *bcm63xx_part_types[] = { "bcm63xxpart", "RedBoot", NULL }; + + static struct physmap_flash_data flash_data = { + .width = 2, + .parts = mtd_partitions, + .part_probe_types = bcm63xx_part_types, ++ .pp_data = &bcm63xx_parser_data, + }; + + static struct resource mtd_resources[] = { +@@ -62,6 +65,7 @@ static struct platform_device mtd_dev = + + static struct flash_platform_data bcm63xx_flash_data = { + .part_probe_types = bcm63xx_part_types, ++ .pp_data = &bcm63xx_parser_data, + }; + + static struct spi_board_info bcm63xx_spi_flash_info[] = { +@@ -130,10 +134,13 @@ static int __init bcm63xx_detect_flash_t + return 0; + } + +-int __init bcm63xx_flash_register(void) ++int __init bcm63xx_flash_register(int num_caldata, struct ath9k_caldata *caldata) + { + u32 val; ++ unsigned int i; + ++ for (i = 0; i < num_caldata; i++) ++ bcm63xx_parser_data.caldata[i] = caldata[i].caldata_offset; + + bcm63xx_detect_flash_type(); + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h +@@ -1,6 +1,8 @@ + #ifndef __BCM63XX_FLASH_H + #define __BCM63XX_FLASH_H + ++#include ++ + enum { + BCM63XX_FLASH_TYPE_PARALLEL, + BCM63XX_FLASH_TYPE_SERIAL, +@@ -9,6 +11,6 @@ enum { + + extern int bcm63xx_attached_flash; + +-int __init bcm63xx_flash_register(void); ++int __init bcm63xx_flash_register(int num_caldata, struct ath9k_caldata *caldata); + + #endif /* __BCM63XX_FLASH_H */ diff --git a/target/linux/brcm63xx/patches-3.3/520-bcm63xx-add-support-for-96368MVWG-board.patch b/target/linux/brcm63xx/patches-3.3/520-bcm63xx-add-support-for-96368MVWG-board.patch index d23861ba35..b2b58a19f0 100644 --- a/target/linux/brcm63xx/patches-3.3/520-bcm63xx-add-support-for-96368MVWG-board.patch +++ b/target/linux/brcm63xx/patches-3.3/520-bcm63xx-add-support-for-96368MVWG-board.patch @@ -10,7 +10,7 @@ Subject: [PATCH 32/63] bcm63xx: add support for 96368MVWG board. --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c -@@ -2015,6 +2015,80 @@ static struct board_info __initdata boar +@@ -2015,6 +2015,78 @@ static struct board_info __initdata boar #endif /* @@ -42,14 +42,12 @@ Subject: [PATCH 32/63] bcm63xx: add support for 96368MVWG board. + [4] = { + .used = 1, + .phy_id = 0x12, -+ .external_phy = 1, + .name = "port0", + }, + + [5] = { + .used = 1, + .phy_id = 0x11, -+ .external_phy = 1, + .name = "port3", + }, + }, @@ -91,7 +89,7 @@ Subject: [PATCH 32/63] bcm63xx: add support for 96368MVWG board. * all boards */ static const struct board_info __initdata *bcm963xx_boards[] = { -@@ -2063,6 +2137,10 @@ static const struct board_info __initdat +@@ -2063,6 +2135,10 @@ static const struct board_info __initdat &board_HW553, &board_spw303v, #endif @@ -102,7 +100,7 @@ Subject: [PATCH 32/63] bcm63xx: add support for 96368MVWG board. }; static void __init nb4_nvram_fixup(void) -@@ -2244,12 +2322,25 @@ void __init board_prom_init(void) +@@ -2244,12 +2320,25 @@ void __init board_prom_init(void) bcm63xx_pci_enabled = 1; if (BCMCPU_IS_6348()) val |= GPIO_MODE_6348_G2_PCI; diff --git a/target/linux/brcm63xx/patches-3.3/521-bcm63xx-add-support-for-96368MVNgr-board.patch b/target/linux/brcm63xx/patches-3.3/521-bcm63xx-add-support-for-96368MVNgr-board.patch index 19002f1fdb..62f70aa2de 100644 --- a/target/linux/brcm63xx/patches-3.3/521-bcm63xx-add-support-for-96368MVNgr-board.patch +++ b/target/linux/brcm63xx/patches-3.3/521-bcm63xx-add-support-for-96368MVNgr-board.patch @@ -9,7 +9,7 @@ Subject: [PATCH 33/63] bcm63xx: add support for 96368MVNgr board. --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c -@@ -2086,6 +2086,72 @@ static struct board_info __initdata boar +@@ -2084,6 +2084,72 @@ static struct board_info __initdata boar .has_ohci0 = 1, .has_ehci0 = 1, }; @@ -82,7 +82,7 @@ Subject: [PATCH 33/63] bcm63xx: add support for 96368MVNgr board. #endif /* -@@ -2140,6 +2206,7 @@ static const struct board_info __initdat +@@ -2138,6 +2204,7 @@ static const struct board_info __initdat #ifdef CONFIG_BCM63XX_CPU_6368 &board_96368mvwg, diff --git a/target/linux/brcm63xx/patches-3.3/522-MIPS-BCM63XX-add-96328avng-reference-board.patch b/target/linux/brcm63xx/patches-3.3/522-MIPS-BCM63XX-add-96328avng-reference-board.patch index 29bbf82af3..f75e18891c 100644 --- a/target/linux/brcm63xx/patches-3.3/522-MIPS-BCM63XX-add-96328avng-reference-board.patch +++ b/target/linux/brcm63xx/patches-3.3/522-MIPS-BCM63XX-add-96328avng-reference-board.patch @@ -90,7 +90,7 @@ Subject: [PATCH] MIPS: BCM63XX: add 96328avng reference board * known 6338 boards */ #ifdef CONFIG_BCM63XX_CPU_6338 -@@ -2158,6 +2232,9 @@ static struct board_info __initdata boar +@@ -2156,6 +2230,9 @@ static struct board_info __initdata boar * all boards */ static const struct board_info __initdata *bcm963xx_boards[] = { diff --git a/target/linux/brcm63xx/patches-3.3/523-MIPS-BCM63XX-add-963281TAN-reference-board.patch b/target/linux/brcm63xx/patches-3.3/523-MIPS-BCM63XX-add-963281TAN-reference-board.patch index 604515b7d2..e2970960fc 100644 --- a/target/linux/brcm63xx/patches-3.3/523-MIPS-BCM63XX-add-963281TAN-reference-board.patch +++ b/target/linux/brcm63xx/patches-3.3/523-MIPS-BCM63XX-add-963281TAN-reference-board.patch @@ -86,7 +86,7 @@ Subject: [PATCH] MIPS: BCM63XX: add 963281TAN reference board #endif /* -@@ -2234,6 +2304,7 @@ static struct board_info __initdata boar +@@ -2232,6 +2302,7 @@ static struct board_info __initdata boar static const struct board_info __initdata *bcm963xx_boards[] = { #ifdef CONFIG_BCM63XX_CPU_6328 &board_96328avng, diff --git a/target/linux/brcm63xx/patches-3.3/524-board_dsl_274xb_rev_f.patch b/target/linux/brcm63xx/patches-3.3/524-board_dsl_274xb_rev_f.patch index 52b083207d..99fcb0f4c7 100644 --- a/target/linux/brcm63xx/patches-3.3/524-board_dsl_274xb_rev_f.patch +++ b/target/linux/brcm63xx/patches-3.3/524-board_dsl_274xb_rev_f.patch @@ -120,7 +120,7 @@ Subject: [PATCH 70/79] MIPS: BCM63XX: Add board definition for D-Link #endif /* -@@ -2305,6 +2408,7 @@ static const struct board_info __initdat +@@ -2303,6 +2406,7 @@ static const struct board_info __initdat #ifdef CONFIG_BCM63XX_CPU_6328 &board_96328avng, &board_963281TAN, diff --git a/target/linux/brcm63xx/patches-3.3/525-board_96348w3.patch b/target/linux/brcm63xx/patches-3.3/525-board_96348w3.patch index ffce6fc14a..367ec97821 100644 --- a/target/linux/brcm63xx/patches-3.3/525-board_96348w3.patch +++ b/target/linux/brcm63xx/patches-3.3/525-board_96348w3.patch @@ -58,7 +58,7 @@ #endif /* -@@ -2438,6 +2489,7 @@ static const struct board_info __initdat +@@ -2436,6 +2487,7 @@ static const struct board_info __initdat &board_ct536_ct5621, &board_96348A_122, &board_CPVA502plus, diff --git a/target/linux/brcm63xx/patches-3.3/526-board_CT6373-1.patch b/target/linux/brcm63xx/patches-3.3/526-board_CT6373-1.patch index effd9f6d95..50d8535f54 100644 --- a/target/linux/brcm63xx/patches-3.3/526-board_CT6373-1.patch +++ b/target/linux/brcm63xx/patches-3.3/526-board_CT6373-1.patch @@ -126,7 +126,7 @@ static struct board_info __initdata board_HW553 = { .name = "HW553", .expected_cpu_id = 0x6358, -@@ -2504,6 +2616,7 @@ static const struct board_info __initdat +@@ -2502,6 +2614,7 @@ static const struct board_info __initdat &board_nb4_ser_r2, &board_nb4_fxc_r1, &board_nb4_fxc_r2, diff --git a/target/linux/brcm63xx/patches-3.3/527-board_dva-g3810bn-tl-1.patch b/target/linux/brcm63xx/patches-3.3/527-board_dva-g3810bn-tl-1.patch index 034626c8a4..6e764e3f70 100644 --- a/target/linux/brcm63xx/patches-3.3/527-board_dva-g3810bn-tl-1.patch +++ b/target/linux/brcm63xx/patches-3.3/527-board_dva-g3810bn-tl-1.patch @@ -72,7 +72,7 @@ #endif /* -@@ -2619,6 +2684,7 @@ static const struct board_info __initdat +@@ -2617,6 +2682,7 @@ static const struct board_info __initdat &board_ct6373_1, &board_HW553, &board_spw303v, diff --git a/target/linux/brcm63xx/patches-3.3/801-ssb_export_fallback_sprom.patch b/target/linux/brcm63xx/patches-3.3/801-ssb_export_fallback_sprom.patch index 5794fa72e6..3802cfce55 100644 --- a/target/linux/brcm63xx/patches-3.3/801-ssb_export_fallback_sprom.patch +++ b/target/linux/brcm63xx/patches-3.3/801-ssb_export_fallback_sprom.patch @@ -8,7 +8,7 @@ #include #include #include -@@ -2831,7 +2832,7 @@ static void __init nb4_nvram_fixup(void) +@@ -2829,7 +2830,7 @@ static void __init nb4_nvram_fixup(void) * bcm4318 WLAN work */ #ifdef CONFIG_SSB_PCIHOST @@ -17,7 +17,7 @@ .revision = 0x02, .board_rev = 0x17, .country_code = 0x0, -@@ -2851,6 +2852,7 @@ static struct ssb_sprom bcm63xx_sprom = +@@ -2849,6 +2850,7 @@ static struct ssb_sprom bcm63xx_sprom = .boardflags_lo = 0x2848, .boardflags_hi = 0x0000, };