bcm63xx: remove 3.3 support

3.6 is tested enough to be considered stable.

Signed-off-by: Jonas Gorski <jogo@openwrt.org>

SVN-Revision: 35009
This commit is contained in:
Jonas Gorski 2013-01-04 14:47:43 +00:00
parent 3b7882e775
commit 10fc07daac
143 changed files with 0 additions and 17373 deletions

View file

@ -1,159 +0,0 @@
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
CONFIG_ARCH_DISCARD_MEMBLOCK=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_AUDIT=y
CONFIG_AUDIT_GENERIC=y
CONFIG_BCM63XX=y
CONFIG_BCM63XX_CPU_6328=y
CONFIG_BCM63XX_CPU_6338=y
CONFIG_BCM63XX_CPU_6345=y
CONFIG_BCM63XX_CPU_6348=y
CONFIG_BCM63XX_CPU_6358=y
CONFIG_BCM63XX_CPU_6362=y
CONFIG_BCM63XX_CPU_6368=y
CONFIG_BCM63XX_ENET=y
CONFIG_BCM63XX_PHY=y
CONFIG_BCM63XX_WDT=y
CONFIG_BOARD_BCM963XX=y
# CONFIG_BOARD_LIVEBOX is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_CEVT_R4K=y
CONFIG_CEVT_R4K_LIB=y
CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=squashfs,jffs2 noinitrd console=ttyS0,115200"
CONFIG_CMDLINE_BOOL=y
# CONFIG_CMDLINE_OVERRIDE is not set
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_CPU_HAS_PREFETCH=y
CONFIG_CPU_HAS_SYNC=y
CONFIG_CPU_MIPS32=y
CONFIG_CPU_MIPS32_R1=y
CONFIG_CPU_MIPSR1=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
CONFIG_CRAMFS=y
CONFIG_CSRC_R4K=y
CONFIG_CSRC_R4K_LIB=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_EARLY_PRINTK=y
CONFIG_ELF_CORE=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_74X164=y
CONFIG_GPIO_DEVICE=y
CONFIG_GPIO_SYSFS=y
# CONFIG_HAMRADIO is not set
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_HAVE_GENERIC_HARDIRQS=y
CONFIG_HAVE_IDE=y
CONFIG_HAVE_IRQ_WORK=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_HW_HAS_PCI=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_BCM63XX=y
CONFIG_HZ=250
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
CONFIG_IMAGE_CMDLINE_HACK=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_IRQ_CPU=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_KEXEC=y
CONFIG_LEDS_GPIO=y
CONFIG_M25PXX_USE_FAST_READ=y
CONFIG_MDIO_BOARDINFO=y
CONFIG_MIPS=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
# CONFIG_MIPS_MACHINE is not set
CONFIG_MIPS_MT_DISABLED=y
CONFIG_MODULE_FORCE_LOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MTD_BCM63XX_PARTS=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_BE_BYTE_SWAP=y
# CONFIG_MTD_CFI_GEOMETRY is not set
# CONFIG_MTD_CFI_NOSWAP is not set
CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_M25P80=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_PER_CPU_KM=y
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_PCI=y
# CONFIG_PCIEAER is not set
CONFIG_PCIEPORTBUS=y
CONFIG_PCI_DOMAINS=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PHYLIB=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
# CONFIG_PREEMPT_RCU is not set
CONFIG_RELAY=y
CONFIG_RTL8366_SMI=y
CONFIG_RTL8367_PHY=y
# CONFIG_SCSI_DMA is not set
# CONFIG_SERIAL_8250 is not set
CONFIG_SERIAL_BCM63XX=y
CONFIG_SERIAL_BCM63XX_CONSOLE=y
CONFIG_SPI=y
# CONFIG_SPI_BCM63XX is not set
CONFIG_SPI_BCM63XX_HSSPI=y
CONFIG_SPI_BITBANG=y
CONFIG_SPI_GPIO=y
CONFIG_SPI_MASTER=y
CONFIG_SQUASHFS_EMBEDDED=y
CONFIG_SSB=y
CONFIG_SSB_B43_PCI_BRIDGE=y
CONFIG_SSB_BLOCKIO=y
# CONFIG_SSB_DRIVER_MIPS is not set
CONFIG_SSB_DRIVER_PCICORE=y
CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
CONFIG_SSB_PCIHOST=y
CONFIG_SSB_PCIHOST_POSSIBLE=y
CONFIG_SSB_SPROM=y
CONFIG_SWAP_IO_SPACE=y
CONFIG_SWCONFIG=y
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
CONFIG_SYS_HAS_EARLY_PRINTK=y
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_USB_ARCH_HAS_XHCI=y
CONFIG_USB_SUPPORT=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_WATCHDOG_NOWAYOUT=y
CONFIG_ZONE_DMA_FLAG=0

View file

@ -1,36 +0,0 @@
From cbcfe65e357666106c3c6250baf9c5ce33f3e3e3 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Wed, 25 Jan 2012 17:39:53 +0100
Subject: [PATCH 03/63] MIPS: BCM63XX: fix platform_devices id
There is only one watchdog and VoIP DSP platform devices per board, use
-1 as the platform_device id accordingly.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/bcm63xx/dev-dsp.c | 2 +-
arch/mips/bcm63xx/dev-wdt.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
--- a/arch/mips/bcm63xx/dev-dsp.c
+++ b/arch/mips/bcm63xx/dev-dsp.c
@@ -31,7 +31,7 @@ static struct resource voip_dsp_resource
static struct platform_device bcm63xx_voip_dsp_device = {
.name = "bcm63xx-voip-dsp",
- .id = 0,
+ .id = -1,
.num_resources = ARRAY_SIZE(voip_dsp_resources),
.resource = voip_dsp_resources,
};
--- a/arch/mips/bcm63xx/dev-wdt.c
+++ b/arch/mips/bcm63xx/dev-wdt.c
@@ -21,7 +21,7 @@ static struct resource wdt_resources[] =
static struct platform_device bcm63xx_wdt_device = {
.name = "bcm63xx-wdt",
- .id = 0,
+ .id = -1,
.num_resources = ARRAY_SIZE(wdt_resources),
.resource = wdt_resources,
};

View file

@ -1,93 +0,0 @@
From db1cc4ee366bf0528fcb8b4afa65dec915d98889 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Wed, 25 Jan 2012 17:39:55 +0100
Subject: [PATCH 04/63] MIPS: BCM63XX: be consistent in clock bits enable naming
Remove the _CLK suffix from the BCM6368 clock bits definitions to be
consistent with what is already present.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/bcm63xx/clk.c | 6 ++--
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 36 ++++++++++----------
2 files changed, 21 insertions(+), 21 deletions(-)
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -120,7 +120,7 @@ static void enetsw_set(struct clk *clk,
{
if (!BCMCPU_IS_6368())
return;
- bcm_hwclock_set(CKCTL_6368_ROBOSW_CLK_EN |
+ bcm_hwclock_set(CKCTL_6368_ROBOSW_EN |
CKCTL_6368_SWPKT_USB_EN |
CKCTL_6368_SWPKT_SAR_EN, enable);
if (enable) {
@@ -163,7 +163,7 @@ static void usbh_set(struct clk *clk, in
if (BCMCPU_IS_6348())
bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
else if (BCMCPU_IS_6368())
- bcm_hwclock_set(CKCTL_6368_USBH_CLK_EN, enable);
+ bcm_hwclock_set(CKCTL_6368_USBH_EN, enable);
}
static struct clk clk_usbh = {
@@ -199,7 +199,7 @@ static void xtm_set(struct clk *clk, int
if (!BCMCPU_IS_6368())
return;
- bcm_hwclock_set(CKCTL_6368_SAR_CLK_EN |
+ bcm_hwclock_set(CKCTL_6368_SAR_EN |
CKCTL_6368_SWPKT_SAR_EN, enable);
if (enable) {
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -90,29 +90,29 @@
#define CKCTL_6368_PHYMIPS_EN (1 << 6)
#define CKCTL_6368_SWPKT_USB_EN (1 << 7)
#define CKCTL_6368_SWPKT_SAR_EN (1 << 8)
-#define CKCTL_6368_SPI_CLK_EN (1 << 9)
-#define CKCTL_6368_USBD_CLK_EN (1 << 10)
-#define CKCTL_6368_SAR_CLK_EN (1 << 11)
-#define CKCTL_6368_ROBOSW_CLK_EN (1 << 12)
-#define CKCTL_6368_UTOPIA_CLK_EN (1 << 13)
-#define CKCTL_6368_PCM_CLK_EN (1 << 14)
-#define CKCTL_6368_USBH_CLK_EN (1 << 15)
+#define CKCTL_6368_SPI_EN (1 << 9)
+#define CKCTL_6368_USBD_EN (1 << 10)
+#define CKCTL_6368_SAR_EN (1 << 11)
+#define CKCTL_6368_ROBOSW_EN (1 << 12)
+#define CKCTL_6368_UTOPIA_EN (1 << 13)
+#define CKCTL_6368_PCM_EN (1 << 14)
+#define CKCTL_6368_USBH_EN (1 << 15)
#define CKCTL_6368_DISABLE_GLESS_EN (1 << 16)
-#define CKCTL_6368_NAND_CLK_EN (1 << 17)
-#define CKCTL_6368_IPSEC_CLK_EN (1 << 17)
+#define CKCTL_6368_NAND_EN (1 << 17)
+#define CKCTL_6368_IPSEC_EN (1 << 17)
#define CKCTL_6368_ALL_SAFE_EN (CKCTL_6368_SWPKT_USB_EN | \
CKCTL_6368_SWPKT_SAR_EN | \
- CKCTL_6368_SPI_CLK_EN | \
- CKCTL_6368_USBD_CLK_EN | \
- CKCTL_6368_SAR_CLK_EN | \
- CKCTL_6368_ROBOSW_CLK_EN | \
- CKCTL_6368_UTOPIA_CLK_EN | \
- CKCTL_6368_PCM_CLK_EN | \
- CKCTL_6368_USBH_CLK_EN | \
+ CKCTL_6368_SPI_EN | \
+ CKCTL_6368_USBD_EN | \
+ CKCTL_6368_SAR_EN | \
+ CKCTL_6368_ROBOSW_EN | \
+ CKCTL_6368_UTOPIA_EN | \
+ CKCTL_6368_PCM_EN | \
+ CKCTL_6368_USBH_EN | \
CKCTL_6368_DISABLE_GLESS_EN | \
- CKCTL_6368_NAND_CLK_EN | \
- CKCTL_6368_IPSEC_CLK_EN)
+ CKCTL_6368_NAND_EN | \
+ CKCTL_6368_IPSEC_EN)
/* System PLL Control register */
#define PERF_SYS_PLL_CTL_REG 0x8

View file

@ -1,68 +0,0 @@
From 04456614952a9a848192253439b4e361f0321cb5 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Wed, 25 Jan 2012 17:39:51 +0100
Subject: [PATCH 05/63] MIPS: BCM63XX: add IRQ_SPI and CPU specific SPI IRQ values
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -478,6 +478,7 @@ static inline unsigned long bcm63xx_regs
*/
enum bcm63xx_irq {
IRQ_TIMER = 0,
+ IRQ_SPI,
IRQ_UART0,
IRQ_UART1,
IRQ_DSL,
@@ -509,6 +510,7 @@ enum bcm63xx_irq {
* 6338 irqs
*/
#define BCM_6338_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
+#define BCM_6338_SPI_IRQ (IRQ_INTERNAL_BASE + 1)
#define BCM_6338_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
#define BCM_6338_UART1_IRQ 0
#define BCM_6338_DSL_IRQ (IRQ_INTERNAL_BASE + 5)
@@ -539,6 +541,7 @@ enum bcm63xx_irq {
* 6345 irqs
*/
#define BCM_6345_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
+#define BCM_6345_SPI_IRQ 0
#define BCM_6345_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
#define BCM_6345_UART1_IRQ 0
#define BCM_6345_DSL_IRQ (IRQ_INTERNAL_BASE + 3)
@@ -569,6 +572,7 @@ enum bcm63xx_irq {
* 6348 irqs
*/
#define BCM_6348_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
+#define BCM_6348_SPI_IRQ (IRQ_INTERNAL_BASE + 1)
#define BCM_6348_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
#define BCM_6348_UART1_IRQ 0
#define BCM_6348_DSL_IRQ (IRQ_INTERNAL_BASE + 4)
@@ -599,6 +603,7 @@ enum bcm63xx_irq {
* 6358 irqs
*/
#define BCM_6358_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
+#define BCM_6358_SPI_IRQ (IRQ_INTERNAL_BASE + 1)
#define BCM_6358_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
#define BCM_6358_UART1_IRQ (IRQ_INTERNAL_BASE + 3)
#define BCM_6358_DSL_IRQ (IRQ_INTERNAL_BASE + 29)
@@ -638,6 +643,7 @@ enum bcm63xx_irq {
#define BCM_6368_HIGH_IRQ_BASE (IRQ_INTERNAL_BASE + 32)
#define BCM_6368_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
+#define BCM_6368_SPI_IRQ (IRQ_INTERNAL_BASE + 1)
#define BCM_6368_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
#define BCM_6368_UART1_IRQ (IRQ_INTERNAL_BASE + 3)
#define BCM_6368_DSL_IRQ (IRQ_INTERNAL_BASE + 4)
@@ -677,6 +683,7 @@ extern const int *bcm63xx_irqs;
#define __GEN_CPU_IRQ_TABLE(__cpu) \
[IRQ_TIMER] = BCM_## __cpu ##_TIMER_IRQ, \
+ [IRQ_SPI] = BCM_## __cpu ##_SPI_IRQ, \
[IRQ_UART0] = BCM_## __cpu ##_UART0_IRQ, \
[IRQ_UART1] = BCM_## __cpu ##_UART1_IRQ, \
[IRQ_DSL] = BCM_## __cpu ##_DSL_IRQ, \

View file

@ -1,21 +0,0 @@
From bfd78dda2ad5afb4434ebe99c05528614065bdb1 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Wed, 25 Jan 2012 17:39:56 +0100
Subject: [PATCH 06/63] MIPS: BCM63XX: define BCM6358 SPI base address
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -289,7 +289,7 @@ enum bcm63xx_regs_set {
#define BCM_6358_UART0_BASE (0xfffe0100)
#define BCM_6358_UART1_BASE (0xfffe0120)
#define BCM_6358_GPIO_BASE (0xfffe0080)
-#define BCM_6358_SPI_BASE (0xdeadbeef)
+#define BCM_6358_SPI_BASE (0xfffe0800)
#define BCM_6358_SPI2_BASE (0xfffe0800)
#define BCM_6358_UDC0_BASE (0xfffe0800)
#define BCM_6358_OHCI0_BASE (0xfffe1400)

View file

@ -1,26 +0,0 @@
From 9b990ee00f70bdd6a731dbe264d5acb453a6c5e2 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Wed, 25 Jan 2012 17:39:57 +0100
Subject: [PATCH 07/63] MIPS: BCM63XX: add BCM6368 SPI clock mask
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/bcm63xx/clk.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -181,9 +181,11 @@ static void spi_set(struct clk *clk, int
mask = CKCTL_6338_SPI_EN;
else if (BCMCPU_IS_6348())
mask = CKCTL_6348_SPI_EN;
- else
- /* BCMCPU_IS_6358 */
+ else if (BCMCPU_IS_6358())
mask = CKCTL_6358_SPI_EN;
+ else
+ /* BCMCPU_IS_6368 */
+ mask = CKCTL_6368_SPI_EN;
bcm_hwclock_set(mask, enable);
}

View file

@ -1,26 +0,0 @@
From 16ba44545156e4e7cc1e812ad93e562ce92fd74c Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Wed, 25 Jan 2012 17:40:00 +0100
Subject: [PATCH 08/63] MIPS: BCM63XX: define SPI register sizes.
There are two distinct sizes for the SPI register depending on the SoC
generation (6338 & 6348 vs 6358 & 6368).
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -135,6 +135,10 @@ enum bcm63xx_regs_set {
#define RSET_DSL_LMEM_SIZE (64 * 1024 * 4)
#define RSET_DSL_SIZE 4096
#define RSET_WDT_SIZE 12
+#define BCM_6338_RSET_SPI_SIZE 64
+#define BCM_6348_RSET_SPI_SIZE 64
+#define BCM_6358_RSET_SPI_SIZE 1804
+#define BCM_6368_RSET_SPI_SIZE 1804
#define RSET_ENET_SIZE 2048
#define RSET_ENETDMA_SIZE 2048
#define RSET_ENETSW_SIZE 65536

View file

@ -1,83 +0,0 @@
From 32511e7dfab9b9cabe2772e3f5430559294a8d1c Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Wed, 25 Jan 2012 17:40:01 +0100
Subject: [PATCH 09/63] MIPS: BCM63XX: remove SPI2 register
This register was introduced with the support of the BCM6368 CPU in the idea
that its internal layout was different from the other CPUs SPI controller.
The controller is actually the same as the one present on BCM6358 so we can
remove this register and use the usual SPI register instead.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 10 +---------
1 files changed, 1 insertions(+), 9 deletions(-)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -102,7 +102,6 @@ enum bcm63xx_regs_set {
RSET_UART1,
RSET_GPIO,
RSET_SPI,
- RSET_SPI2,
RSET_UDC0,
RSET_OHCI0,
RSET_OHCI_PRIV,
@@ -166,7 +165,6 @@ enum bcm63xx_regs_set {
#define BCM_6338_UART1_BASE (0xdeadbeef)
#define BCM_6338_GPIO_BASE (0xfffe0400)
#define BCM_6338_SPI_BASE (0xfffe0c00)
-#define BCM_6338_SPI2_BASE (0xdeadbeef)
#define BCM_6338_UDC0_BASE (0xdeadbeef)
#define BCM_6338_USBDMA_BASE (0xfffe2400)
#define BCM_6338_OHCI0_BASE (0xdeadbeef)
@@ -210,7 +208,6 @@ enum bcm63xx_regs_set {
#define BCM_6345_UART1_BASE (0xdeadbeef)
#define BCM_6345_GPIO_BASE (0xfffe0400)
#define BCM_6345_SPI_BASE (0xdeadbeef)
-#define BCM_6345_SPI2_BASE (0xdeadbeef)
#define BCM_6345_UDC0_BASE (0xdeadbeef)
#define BCM_6345_USBDMA_BASE (0xfffe2800)
#define BCM_6345_ENET0_BASE (0xfffe1800)
@@ -253,7 +250,6 @@ enum bcm63xx_regs_set {
#define BCM_6348_UART1_BASE (0xdeadbeef)
#define BCM_6348_GPIO_BASE (0xfffe0400)
#define BCM_6348_SPI_BASE (0xfffe0c00)
-#define BCM_6348_SPI2_BASE (0xdeadbeef)
#define BCM_6348_UDC0_BASE (0xfffe1000)
#define BCM_6348_OHCI0_BASE (0xfffe1b00)
#define BCM_6348_OHCI_PRIV_BASE (0xfffe1c00)
@@ -294,7 +290,6 @@ enum bcm63xx_regs_set {
#define BCM_6358_UART1_BASE (0xfffe0120)
#define BCM_6358_GPIO_BASE (0xfffe0080)
#define BCM_6358_SPI_BASE (0xfffe0800)
-#define BCM_6358_SPI2_BASE (0xfffe0800)
#define BCM_6358_UDC0_BASE (0xfffe0800)
#define BCM_6358_OHCI0_BASE (0xfffe1400)
#define BCM_6358_OHCI_PRIV_BASE (0xdeadbeef)
@@ -335,8 +330,7 @@ enum bcm63xx_regs_set {
#define BCM_6368_UART0_BASE (0xb0000100)
#define BCM_6368_UART1_BASE (0xb0000120)
#define BCM_6368_GPIO_BASE (0xb0000080)
-#define BCM_6368_SPI_BASE (0xdeadbeef)
-#define BCM_6368_SPI2_BASE (0xb0000800)
+#define BCM_6368_SPI_BASE (0xb0000800)
#define BCM_6368_UDC0_BASE (0xdeadbeef)
#define BCM_6368_OHCI0_BASE (0xb0001600)
#define BCM_6368_OHCI_PRIV_BASE (0xdeadbeef)
@@ -383,7 +377,6 @@ extern const unsigned long *bcm63xx_regs
__GEN_RSET_BASE(__cpu, UART1) \
__GEN_RSET_BASE(__cpu, GPIO) \
__GEN_RSET_BASE(__cpu, SPI) \
- __GEN_RSET_BASE(__cpu, SPI2) \
__GEN_RSET_BASE(__cpu, UDC0) \
__GEN_RSET_BASE(__cpu, OHCI0) \
__GEN_RSET_BASE(__cpu, OHCI_PRIV) \
@@ -422,7 +415,6 @@ extern const unsigned long *bcm63xx_regs
[RSET_UART1] = BCM_## __cpu ##_UART1_BASE, \
[RSET_GPIO] = BCM_## __cpu ##_GPIO_BASE, \
[RSET_SPI] = BCM_## __cpu ##_SPI_BASE, \
- [RSET_SPI2] = BCM_## __cpu ##_SPI2_BASE, \
[RSET_UDC0] = BCM_## __cpu ##_UDC0_BASE, \
[RSET_OHCI0] = BCM_## __cpu ##_OHCI0_BASE, \
[RSET_OHCI_PRIV] = BCM_## __cpu ##_OHCI_PRIV_BASE, \

View file

@ -1,140 +0,0 @@
From 81f9e7d6aa1dde65483387ba9e9823ef44f90435 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Wed, 25 Jan 2012 17:40:03 +0100
Subject: [PATCH 10/63] MIPS: BCM63XX: define internal registers offsets of the SPI controller
BCM6338, BCM6348, BCM6358 and BCM6368 basically use the same SPI controller
though the internal registers are shuffled, which still allows a common
driver to drive that IP block.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 119 +++++++++++++++++++++
1 files changed, 119 insertions(+), 0 deletions(-)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -973,4 +973,123 @@
#define M2M_SRCID_REG(x) ((x) * 0x40 + 0x14)
#define M2M_DSTID_REG(x) ((x) * 0x40 + 0x18)
+/*************************************************************************
+ * _REG relative to RSET_SPI
+ *************************************************************************/
+
+/* BCM 6338 SPI core */
+#define SPI_6338_CMD 0x00 /* 16-bits register */
+#define SPI_6338_INT_STATUS 0x02
+#define SPI_6338_INT_MASK_ST 0x03
+#define SPI_6338_INT_MASK 0x04
+#define SPI_6338_ST 0x05
+#define SPI_6338_CLK_CFG 0x06
+#define SPI_6338_FILL_BYTE 0x07
+#define SPI_6338_MSG_TAIL 0x09
+#define SPI_6338_RX_TAIL 0x0b
+#define SPI_6338_MSG_CTL 0x40
+#define SPI_6338_MSG_DATA 0x41
+#define SPI_6338_MSG_DATA_SIZE 0x3f
+#define SPI_6338_RX_DATA 0x80
+#define SPI_6338_RX_DATA_SIZE 0x3f
+
+/* BCM 6348 SPI core */
+#define SPI_6348_CMD 0x00 /* 16-bits register */
+#define SPI_6348_INT_STATUS 0x02
+#define SPI_6348_INT_MASK_ST 0x03
+#define SPI_6348_INT_MASK 0x04
+#define SPI_6348_ST 0x05
+#define SPI_6348_CLK_CFG 0x06
+#define SPI_6348_FILL_BYTE 0x07
+#define SPI_6348_MSG_TAIL 0x09
+#define SPI_6348_RX_TAIL 0x0b
+#define SPI_6348_MSG_CTL 0x40
+#define SPI_6348_MSG_DATA 0x41
+#define SPI_6348_MSG_DATA_SIZE 0x3f
+#define SPI_6348_RX_DATA 0x80
+#define SPI_6348_RX_DATA_SIZE 0x3f
+
+/* BCM 6358 SPI core */
+#define SPI_6358_MSG_CTL 0x00 /* 16-bits register */
+#define SPI_6358_MSG_DATA 0x02
+#define SPI_6358_MSG_DATA_SIZE 0x21e
+#define SPI_6358_RX_DATA 0x400
+#define SPI_6358_RX_DATA_SIZE 0x220
+#define SPI_6358_CMD 0x700 /* 16-bits register */
+#define SPI_6358_INT_STATUS 0x702
+#define SPI_6358_INT_MASK_ST 0x703
+#define SPI_6358_INT_MASK 0x704
+#define SPI_6358_ST 0x705
+#define SPI_6358_CLK_CFG 0x706
+#define SPI_6358_FILL_BYTE 0x707
+#define SPI_6358_MSG_TAIL 0x709
+#define SPI_6358_RX_TAIL 0x70B
+
+/* BCM 6358 SPI core */
+#define SPI_6368_MSG_CTL 0x00 /* 16-bits register */
+#define SPI_6368_MSG_DATA 0x02
+#define SPI_6368_MSG_DATA_SIZE 0x21e
+#define SPI_6368_RX_DATA 0x400
+#define SPI_6368_RX_DATA_SIZE 0x220
+#define SPI_6368_CMD 0x700 /* 16-bits register */
+#define SPI_6368_INT_STATUS 0x702
+#define SPI_6368_INT_MASK_ST 0x703
+#define SPI_6368_INT_MASK 0x704
+#define SPI_6368_ST 0x705
+#define SPI_6368_CLK_CFG 0x706
+#define SPI_6368_FILL_BYTE 0x707
+#define SPI_6368_MSG_TAIL 0x709
+#define SPI_6368_RX_TAIL 0x70B
+
+/* Shared SPI definitions */
+
+/* Message configuration */
+#define SPI_FD_RW 0x00
+#define SPI_HD_W 0x01
+#define SPI_HD_R 0x02
+#define SPI_BYTE_CNT_SHIFT 0
+#define SPI_MSG_TYPE_SHIFT 14
+
+/* Command */
+#define SPI_CMD_NOOP 0x00
+#define SPI_CMD_SOFT_RESET 0x01
+#define SPI_CMD_HARD_RESET 0x02
+#define SPI_CMD_START_IMMEDIATE 0x03
+#define SPI_CMD_COMMAND_SHIFT 0
+#define SPI_CMD_COMMAND_MASK 0x000f
+#define SPI_CMD_DEVICE_ID_SHIFT 4
+#define SPI_CMD_PREPEND_BYTE_CNT_SHIFT 8
+#define SPI_CMD_ONE_BYTE_SHIFT 11
+#define SPI_CMD_ONE_WIRE_SHIFT 12
+#define SPI_DEV_ID_0 0
+#define SPI_DEV_ID_1 1
+#define SPI_DEV_ID_2 2
+#define SPI_DEV_ID_3 3
+
+/* Interrupt mask */
+#define SPI_INTR_CMD_DONE 0x01
+#define SPI_INTR_RX_OVERFLOW 0x02
+#define SPI_INTR_TX_UNDERFLOW 0x04
+#define SPI_INTR_TX_OVERFLOW 0x08
+#define SPI_INTR_RX_UNDERFLOW 0x10
+#define SPI_INTR_CLEAR_ALL 0x1f
+
+/* Status */
+#define SPI_RX_EMPTY 0x02
+#define SPI_CMD_BUSY 0x04
+#define SPI_SERIAL_BUSY 0x08
+
+/* Clock configuration */
+#define SPI_CLK_20MHZ 0x00
+#define SPI_CLK_0_391MHZ 0x01
+#define SPI_CLK_0_781MHZ 0x02 /* default */
+#define SPI_CLK_1_563MHZ 0x03
+#define SPI_CLK_3_125MHZ 0x04
+#define SPI_CLK_6_250MHZ 0x05
+#define SPI_CLK_12_50MHZ 0x06
+#define SPI_CLK_MASK 0x07
+#define SPI_SSOFFTIME_MASK 0x38
+#define SPI_SSOFFTIME_SHIFT 3
+#define SPI_BYTE_SWAP 0x80
+
#endif /* BCM63XX_REGS_H_ */

View file

@ -1,243 +0,0 @@
From af84327888c7081662a6b949754fc54d32a50503 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Wed, 25 Jan 2012 17:40:04 +0100
Subject: [PATCH 11/63] MIPS: BCM63XX: add stub to register the SPI platform driver
This patch adds the necessary stub to register the SPI platform driver.
Since the registers are shuffled between the 4 BCM63xx CPUs supported by
this SPI driver we also need to generate the internal register layout and
export this layout for the driver to use it properly.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/bcm63xx/Makefile | 3 +-
arch/mips/bcm63xx/dev-spi.c | 119 ++++++++++++++++++++
.../include/asm/mach-bcm63xx/bcm63xx_dev_spi.h | 89 +++++++++++++++
3 files changed, 210 insertions(+), 1 deletions(-)
create mode 100644 arch/mips/bcm63xx/dev-spi.c
create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h
--- a/arch/mips/bcm63xx/Makefile
+++ b/arch/mips/bcm63xx/Makefile
@@ -1,5 +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-pcmcia.o dev-uart.o dev-wdt.o
+ dev-dsp.o dev-enet.o dev-pcmcia.o dev-spi.o dev-uart.o \
+ dev-wdt.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += boards/
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-spi.c
@@ -0,0 +1,119 @@
+/*
+ * 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) 2009-2011 Florian Fainelli <florian@openwrt.org>
+ * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_spi.h>
+#include <bcm63xx_regs.h>
+
+#ifdef BCMCPU_RUNTIME_DETECT
+/*
+ * register offsets
+ */
+static const unsigned long bcm6338_regs_spi[] = {
+ __GEN_SPI_REGS_TABLE(6338)
+};
+
+static const unsigned long bcm6348_regs_spi[] = {
+ __GEN_SPI_REGS_TABLE(6348)
+};
+
+static const unsigned long bcm6358_regs_spi[] = {
+ __GEN_SPI_REGS_TABLE(6358)
+};
+
+static const unsigned long bcm6368_regs_spi[] = {
+ __GEN_SPI_REGS_TABLE(6368)
+};
+
+const unsigned long *bcm63xx_regs_spi;
+EXPORT_SYMBOL(bcm63xx_regs_spi);
+
+static __init void bcm63xx_spi_regs_init(void)
+{
+ if (BCMCPU_IS_6338())
+ bcm63xx_regs_spi = bcm6338_regs_spi;
+ if (BCMCPU_IS_6348())
+ bcm63xx_regs_spi = bcm6348_regs_spi;
+ if (BCMCPU_IS_6358())
+ bcm63xx_regs_spi = bcm6358_regs_spi;
+ if (BCMCPU_IS_6368())
+ bcm63xx_regs_spi = bcm6368_regs_spi;
+}
+#else
+static __init void bcm63xx_spi_regs_init(void) { }
+#endif
+
+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_spi_pdata spi_pdata = {
+ .bus_num = 0,
+ .num_chipselect = 8,
+};
+
+static struct platform_device bcm63xx_spi_device = {
+ .name = "bcm63xx-spi",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(spi_resources),
+ .resource = spi_resources,
+ .dev = {
+ .platform_data = &spi_pdata,
+ },
+};
+
+int __init bcm63xx_spi_register(void)
+{
+ struct clk *periph_clk;
+
+ if (BCMCPU_IS_6345())
+ return -ENODEV;
+
+ periph_clk = clk_get(NULL, "periph");
+ if (IS_ERR(periph_clk)) {
+ pr_err("unable to get periph clock\n");
+ return -ENODEV;
+ }
+
+ /* Set bus frequency */
+ spi_pdata.speed_hz = clk_get_rate(periph_clk);
+
+ spi_resources[0].start = bcm63xx_regset_address(RSET_SPI);
+ spi_resources[0].end = spi_resources[0].start;
+ spi_resources[1].start = bcm63xx_get_irq_number(IRQ_SPI);
+
+ if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
+ spi_resources[0].end += BCM_6338_RSET_SPI_SIZE - 1;
+ spi_pdata.fifo_size = SPI_6338_MSG_DATA_SIZE;
+ }
+
+ if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
+ spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1;
+ spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE;
+ }
+
+ bcm63xx_spi_regs_init();
+
+ return platform_device_register(&bcm63xx_spi_device);
+}
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h
@@ -0,0 +1,89 @@
+#ifndef BCM63XX_DEV_SPI_H
+#define BCM63XX_DEV_SPI_H
+
+#include <linux/types.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+
+int __init bcm63xx_spi_register(void);
+
+struct bcm63xx_spi_pdata {
+ unsigned int fifo_size;
+ int bus_num;
+ int num_chipselect;
+ u32 speed_hz;
+};
+
+enum bcm63xx_regs_spi {
+ SPI_CMD,
+ SPI_INT_STATUS,
+ SPI_INT_MASK_ST,
+ SPI_INT_MASK,
+ SPI_ST,
+ SPI_CLK_CFG,
+ SPI_FILL_BYTE,
+ SPI_MSG_TAIL,
+ SPI_RX_TAIL,
+ SPI_MSG_CTL,
+ SPI_MSG_DATA,
+ SPI_RX_DATA,
+};
+
+#define __GEN_SPI_RSET_BASE(__cpu, __rset) \
+ case SPI_## __rset: \
+ return SPI_## __cpu ##_## __rset;
+
+#define __GEN_SPI_RSET(__cpu) \
+ switch (reg) { \
+ __GEN_SPI_RSET_BASE(__cpu, CMD) \
+ __GEN_SPI_RSET_BASE(__cpu, INT_STATUS) \
+ __GEN_SPI_RSET_BASE(__cpu, INT_MASK_ST) \
+ __GEN_SPI_RSET_BASE(__cpu, INT_MASK) \
+ __GEN_SPI_RSET_BASE(__cpu, ST) \
+ __GEN_SPI_RSET_BASE(__cpu, CLK_CFG) \
+ __GEN_SPI_RSET_BASE(__cpu, FILL_BYTE) \
+ __GEN_SPI_RSET_BASE(__cpu, MSG_TAIL) \
+ __GEN_SPI_RSET_BASE(__cpu, RX_TAIL) \
+ __GEN_SPI_RSET_BASE(__cpu, MSG_CTL) \
+ __GEN_SPI_RSET_BASE(__cpu, MSG_DATA) \
+ __GEN_SPI_RSET_BASE(__cpu, RX_DATA) \
+ }
+
+#define __GEN_SPI_REGS_TABLE(__cpu) \
+ [SPI_CMD] = SPI_## __cpu ##_CMD, \
+ [SPI_INT_STATUS] = SPI_## __cpu ##_INT_STATUS, \
+ [SPI_INT_MASK_ST] = SPI_## __cpu ##_INT_MASK_ST, \
+ [SPI_INT_MASK] = SPI_## __cpu ##_INT_MASK, \
+ [SPI_ST] = SPI_## __cpu ##_ST, \
+ [SPI_CLK_CFG] = SPI_## __cpu ##_CLK_CFG, \
+ [SPI_FILL_BYTE] = SPI_## __cpu ##_FILL_BYTE, \
+ [SPI_MSG_TAIL] = SPI_## __cpu ##_MSG_TAIL, \
+ [SPI_RX_TAIL] = SPI_## __cpu ##_RX_TAIL, \
+ [SPI_MSG_CTL] = SPI_## __cpu ##_MSG_CTL, \
+ [SPI_MSG_DATA] = SPI_## __cpu ##_MSG_DATA, \
+ [SPI_RX_DATA] = SPI_## __cpu ##_RX_DATA,
+
+static inline unsigned long bcm63xx_spireg(enum bcm63xx_regs_spi reg)
+{
+#ifdef BCMCPU_RUNTIME_DETECT
+ extern const unsigned long *bcm63xx_regs_spi;
+
+ return bcm63xx_regs_spi[reg];
+#else
+#ifdef CONFIG_BCM63XX_CPU_6338
+ __GEN_SPI_RSET(6338)
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6348
+ __GEN_SPI_RSET(6348)
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6358
+ __GEN_SPI_RSET(6358)
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6368
+ __GEN_SPI_RSET(6368)
+#endif
+#endif
+ return 0;
+}
+
+#endif /* BCM63XX_DEV_SPI_H */

View file

@ -1,29 +0,0 @@
From fab0cbda27ab2400d6a461bf144007a0d5337527 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Wed, 25 Jan 2012 17:40:05 +0100
Subject: [PATCH 12/63] MIPS: BCM63XX: make board setup code register the spi platform device
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/bcm63xx/boards/board_bcm963xx.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -25,6 +25,7 @@
#include <bcm63xx_dev_enet.h>
#include <bcm63xx_dev_dsp.h>
#include <bcm63xx_dev_pcmcia.h>
+#include <bcm63xx_dev_spi.h>
#include <board_bcm963xx.h>
#define PFX "board_bcm963xx: "
@@ -890,6 +891,8 @@ int __init board_register_devices(void)
}
#endif
+ bcm63xx_spi_register();
+
/* read base address of boot chip select (0) */
val = bcm_mpi_readl(MPI_CSBASE_REG(0));
val &= MPI_CSBASE_BASE_MASK;

View file

@ -1,532 +0,0 @@
From 5f592b818a2c5731bb12137e7cffc3aa6e24ee5a Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Wed, 1 Feb 2012 09:14:09 +0000
Subject: [PATCH 13/63] spi: add Broadcom BCM63xx SPI controller driver
This patch adds support for the SPI controller found on the Broadcom BCM63xx
SoCs.
Signed-off-by: Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
Signed-off-by: Florian Fainelli <florian@openwrt.org>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/spi/Kconfig | 6 +
drivers/spi/Makefile | 1 +
drivers/spi/spi-bcm63xx.c | 486 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 493 insertions(+), 0 deletions(-)
create mode 100644 drivers/spi/spi-bcm63xx.c
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -94,6 +94,12 @@ config SPI_AU1550
If you say yes to this option, support will be included for the
PSC SPI controller found on Au1550, Au1200 and Au1300 series.
+config SPI_BCM63XX
+ tristate "Broadcom BCM63xx SPI controller"
+ depends on BCM63XX
+ help
+ Enable support for the SPI controller on the Broadcom BCM63xx SoCs.
+
config SPI_BITBANG
tristate "Utilities for Bitbanging SPI masters"
help
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_SPI_ALTERA) += spi-altera.
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_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.c
@@ -0,0 +1,486 @@
+/*
+ * Broadcom BCM63xx SPI controller support
+ *
+ * Copyright (C) 2009-2011 Florian Fainelli <florian@openwrt.org>
+ * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/spi/spi.h>
+#include <linux/completion.h>
+#include <linux/err.h>
+
+#include <bcm63xx_dev_spi.h>
+
+#define PFX KBUILD_MODNAME
+#define DRV_VER "0.1.2"
+
+struct bcm63xx_spi {
+ spinlock_t lock;
+ int stopping;
+ struct completion done;
+
+ void __iomem *regs;
+ int irq;
+
+ /* Platform data */
+ u32 speed_hz;
+ unsigned fifo_size;
+
+ /* Data buffers */
+ const unsigned char *tx_ptr;
+ unsigned char *rx_ptr;
+
+ /* data iomem */
+ u8 __iomem *tx_io;
+ const u8 __iomem *rx_io;
+
+ int remaining_bytes;
+
+ struct clk *clk;
+ struct platform_device *pdev;
+};
+
+static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs,
+ unsigned int offset)
+{
+ return bcm_readb(bs->regs + bcm63xx_spireg(offset));
+}
+
+static inline u16 bcm_spi_readw(struct bcm63xx_spi *bs,
+ unsigned int offset)
+{
+ return bcm_readw(bs->regs + bcm63xx_spireg(offset));
+}
+
+static inline void bcm_spi_writeb(struct bcm63xx_spi *bs,
+ u8 value, unsigned int offset)
+{
+ bcm_writeb(value, bs->regs + bcm63xx_spireg(offset));
+}
+
+static inline void bcm_spi_writew(struct bcm63xx_spi *bs,
+ u16 value, unsigned int offset)
+{
+ bcm_writew(value, bs->regs + bcm63xx_spireg(offset));
+}
+
+static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = {
+ { 20000000, SPI_CLK_20MHZ },
+ { 12500000, SPI_CLK_12_50MHZ },
+ { 6250000, SPI_CLK_6_250MHZ },
+ { 3125000, SPI_CLK_3_125MHZ },
+ { 1563000, SPI_CLK_1_563MHZ },
+ { 781000, SPI_CLK_0_781MHZ },
+ { 391000, SPI_CLK_0_391MHZ }
+};
+
+static int bcm63xx_spi_setup_transfer(struct spi_device *spi,
+ struct spi_transfer *t)
+{
+ struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
+ u8 bits_per_word;
+ u8 clk_cfg, reg;
+ u32 hz;
+ int i;
+
+ bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word;
+ hz = (t) ? t->speed_hz : spi->max_speed_hz;
+ if (bits_per_word != 8) {
+ dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
+ __func__, bits_per_word);
+ return -EINVAL;
+ }
+
+ if (spi->chip_select > spi->master->num_chipselect) {
+ dev_err(&spi->dev, "%s, unsupported slave %d\n",
+ __func__, spi->chip_select);
+ return -EINVAL;
+ }
+
+ /* Find the closest clock configuration */
+ for (i = 0; i < SPI_CLK_MASK; i++) {
+ if (hz >= bcm63xx_spi_freq_table[i][0]) {
+ clk_cfg = bcm63xx_spi_freq_table[i][1];
+ break;
+ }
+ }
+
+ /* No matching configuration found, default to lowest */
+ if (i == SPI_CLK_MASK)
+ clk_cfg = SPI_CLK_0_391MHZ;
+
+ /* clear existing clock configuration bits of the register */
+ reg = bcm_spi_readb(bs, SPI_CLK_CFG);
+ reg &= ~SPI_CLK_MASK;
+ reg |= clk_cfg;
+
+ bcm_spi_writeb(bs, reg, SPI_CLK_CFG);
+ dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n",
+ clk_cfg, hz);
+
+ return 0;
+}
+
+/* the spi->mode bits understood by this driver: */
+#define MODEBITS (SPI_CPOL | SPI_CPHA)
+
+static int bcm63xx_spi_setup(struct spi_device *spi)
+{
+ struct bcm63xx_spi *bs;
+ int ret;
+
+ bs = spi_master_get_devdata(spi->master);
+
+ if (bs->stopping)
+ return -ESHUTDOWN;
+
+ if (!spi->bits_per_word)
+ spi->bits_per_word = 8;
+
+ if (spi->mode & ~MODEBITS) {
+ dev_err(&spi->dev, "%s, unsupported mode bits %x\n",
+ __func__, spi->mode & ~MODEBITS);
+ return -EINVAL;
+ }
+
+ ret = bcm63xx_spi_setup_transfer(spi, NULL);
+ if (ret < 0) {
+ dev_err(&spi->dev, "setup: unsupported mode bits %x\n",
+ spi->mode & ~MODEBITS);
+ return ret;
+ }
+
+ dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec/bit\n",
+ __func__, spi->mode & MODEBITS, spi->bits_per_word, 0);
+
+ return 0;
+}
+
+/* Fill the TX FIFO with as many bytes as possible */
+static void bcm63xx_spi_fill_tx_fifo(struct bcm63xx_spi *bs)
+{
+ u8 size;
+
+ /* Fill the Tx FIFO with as many bytes as possible */
+ size = bs->remaining_bytes < bs->fifo_size ? bs->remaining_bytes :
+ bs->fifo_size;
+ memcpy_toio(bs->tx_io, bs->tx_ptr, size);
+ bs->remaining_bytes -= size;
+}
+
+static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
+{
+ struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
+ u16 msg_ctl;
+ u16 cmd;
+
+ dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
+ t->tx_buf, t->rx_buf, t->len);
+
+ /* Transmitter is inhibited */
+ bs->tx_ptr = t->tx_buf;
+ bs->rx_ptr = t->rx_buf;
+ init_completion(&bs->done);
+
+ if (t->tx_buf) {
+ bs->remaining_bytes = t->len;
+ bcm63xx_spi_fill_tx_fifo(bs);
+ }
+
+ /* Enable the command done interrupt which
+ * we use to determine completion of a command */
+ bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
+
+ /* Fill in the Message control register */
+ msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);
+
+ if (t->rx_buf && t->tx_buf)
+ msg_ctl |= (SPI_FD_RW << SPI_MSG_TYPE_SHIFT);
+ else if (t->rx_buf)
+ msg_ctl |= (SPI_HD_R << SPI_MSG_TYPE_SHIFT);
+ else if (t->tx_buf)
+ msg_ctl |= (SPI_HD_W << SPI_MSG_TYPE_SHIFT);
+
+ bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL);
+
+ /* Issue the transfer */
+ cmd = SPI_CMD_START_IMMEDIATE;
+ cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
+ cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
+ bcm_spi_writew(bs, cmd, SPI_CMD);
+ wait_for_completion(&bs->done);
+
+ /* Disable the CMD_DONE interrupt */
+ bcm_spi_writeb(bs, 0, SPI_INT_MASK);
+
+ return t->len - bs->remaining_bytes;
+}
+
+static int bcm63xx_transfer(struct spi_device *spi, struct spi_message *m)
+{
+ struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
+ struct spi_transfer *t;
+ int ret = 0;
+
+ if (unlikely(list_empty(&m->transfers)))
+ return -EINVAL;
+
+ if (bs->stopping)
+ return -ESHUTDOWN;
+
+ list_for_each_entry(t, &m->transfers, transfer_list) {
+ ret += bcm63xx_txrx_bufs(spi, t);
+ }
+
+ m->complete(m->context);
+
+ return ret;
+}
+
+/* This driver supports single master mode only. Hence
+ * CMD_DONE is the only interrupt we care about
+ */
+static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)
+{
+ struct spi_master *master = (struct spi_master *)dev_id;
+ struct bcm63xx_spi *bs = spi_master_get_devdata(master);
+ u8 intr;
+ u16 cmd;
+
+ /* Read interupts and clear them immediately */
+ intr = bcm_spi_readb(bs, SPI_INT_STATUS);
+ bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
+ bcm_spi_writeb(bs, 0, SPI_INT_MASK);
+
+ /* A tansfer completed */
+ if (intr & SPI_INTR_CMD_DONE) {
+ u8 rx_tail;
+
+ rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
+
+ /* Read out all the data */
+ if (rx_tail)
+ memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail);
+
+ /* See if there is more data to send */
+ if (bs->remaining_bytes > 0) {
+ bcm63xx_spi_fill_tx_fifo(bs);
+
+ /* Start the transfer */
+ bcm_spi_writew(bs, SPI_HD_W << SPI_MSG_TYPE_SHIFT,
+ SPI_MSG_CTL);
+ cmd = bcm_spi_readw(bs, SPI_CMD);
+ cmd |= SPI_CMD_START_IMMEDIATE;
+ cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
+ bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
+ bcm_spi_writew(bs, cmd, SPI_CMD);
+ } else {
+ complete(&bs->done);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+
+static int __devinit bcm63xx_spi_probe(struct platform_device *pdev)
+{
+ struct resource *r;
+ struct device *dev = &pdev->dev;
+ struct bcm63xx_spi_pdata *pdata = pdev->dev.platform_data;
+ int irq;
+ struct spi_master *master;
+ struct clk *clk;
+ struct bcm63xx_spi *bs;
+ int ret;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ dev_err(dev, "no iomem\n");
+ ret = -ENXIO;
+ goto out;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(dev, "no irq\n");
+ ret = -ENXIO;
+ goto out;
+ }
+
+ clk = clk_get(dev, "spi");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "no clock for device\n");
+ ret = PTR_ERR(clk);
+ goto out;
+ }
+
+ master = spi_alloc_master(dev, sizeof(*bs));
+ if (!master) {
+ dev_err(dev, "out of memory\n");
+ ret = -ENOMEM;
+ goto out_clk;
+ }
+
+ bs = spi_master_get_devdata(master);
+ init_completion(&bs->done);
+
+ platform_set_drvdata(pdev, master);
+ bs->pdev = pdev;
+
+ if (!devm_request_mem_region(&pdev->dev, r->start,
+ resource_size(r), PFX)) {
+ dev_err(dev, "iomem request failed\n");
+ ret = -ENXIO;
+ goto out_err;
+ }
+
+ bs->regs = devm_ioremap_nocache(&pdev->dev, r->start,
+ resource_size(r));
+ if (!bs->regs) {
+ dev_err(dev, "unable to ioremap regs\n");
+ ret = -ENOMEM;
+ goto out_err;
+ }
+
+ bs->irq = irq;
+ bs->clk = clk;
+ bs->fifo_size = pdata->fifo_size;
+
+ ret = devm_request_irq(&pdev->dev, irq, bcm63xx_spi_interrupt, 0,
+ pdev->name, master);
+ if (ret) {
+ dev_err(dev, "unable to request irq\n");
+ goto out_err;
+ }
+
+ master->bus_num = pdata->bus_num;
+ master->num_chipselect = pdata->num_chipselect;
+ master->setup = bcm63xx_spi_setup;
+ master->transfer = bcm63xx_transfer;
+ bs->speed_hz = pdata->speed_hz;
+ bs->stopping = 0;
+ bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
+ bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA));
+ spin_lock_init(&bs->lock);
+
+ /* Initialize hardware */
+ clk_enable(bs->clk);
+ bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
+
+ /* register and we are done */
+ ret = spi_register_master(master);
+ if (ret) {
+ dev_err(dev, "spi register failed\n");
+ goto out_clk_disable;
+ }
+
+ dev_info(dev, "at 0x%08x (irq %d, FIFOs size %d) v%s\n",
+ r->start, irq, bs->fifo_size, DRV_VER);
+
+ return 0;
+
+out_clk_disable:
+ clk_disable(clk);
+out_err:
+ platform_set_drvdata(pdev, NULL);
+ spi_master_put(master);
+out_clk:
+ clk_put(clk);
+out:
+ return ret;
+}
+
+static int __devexit bcm63xx_spi_remove(struct platform_device *pdev)
+{
+ struct spi_master *master = platform_get_drvdata(pdev);
+ struct bcm63xx_spi *bs = spi_master_get_devdata(master);
+
+ /* reset spi block */
+ bcm_spi_writeb(bs, 0, SPI_INT_MASK);
+ spin_lock(&bs->lock);
+ bs->stopping = 1;
+
+ /* HW shutdown */
+ clk_disable(bs->clk);
+ clk_put(bs->clk);
+
+ spin_unlock(&bs->lock);
+ platform_set_drvdata(pdev, 0);
+ spi_unregister_master(master);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int bcm63xx_spi_suspend(struct device *dev)
+{
+ struct spi_master *master =
+ platform_get_drvdata(to_platform_device(dev));
+ struct bcm63xx_spi *bs = spi_master_get_devdata(master);
+
+ clk_disable(bs->clk);
+
+ return 0;
+}
+
+static int bcm63xx_spi_resume(struct device *dev)
+{
+ struct spi_master *master =
+ platform_get_drvdata(to_platform_device(dev));
+ struct bcm63xx_spi *bs = spi_master_get_devdata(master);
+
+ clk_enable(bs->clk);
+
+ return 0;
+}
+
+static const struct dev_pm_ops bcm63xx_spi_pm_ops = {
+ .suspend = bcm63xx_spi_suspend,
+ .resume = bcm63xx_spi_resume,
+};
+
+#define BCM63XX_SPI_PM_OPS (&bcm63xx_spi_pm_ops)
+#else
+#define BCM63XX_SPI_PM_OPS NULL
+#endif
+
+static struct platform_driver bcm63xx_spi_driver = {
+ .driver = {
+ .name = "bcm63xx-spi",
+ .owner = THIS_MODULE,
+ .pm = BCM63XX_SPI_PM_OPS,
+ },
+ .probe = bcm63xx_spi_probe,
+ .remove = __devexit_p(bcm63xx_spi_remove),
+};
+
+module_platform_driver(bcm63xx_spi_driver);
+
+MODULE_ALIAS("platform:bcm63xx_spi");
+MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
+MODULE_AUTHOR("Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>");
+MODULE_DESCRIPTION("Broadcom BCM63xx SPI Controller driver");
+MODULE_LICENSE("GPL");

View file

@ -1,101 +0,0 @@
From a73c2d9dc7ea0d14fbf48db48e783d123162f5c3 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Thu, 19 Apr 2012 13:15:57 +0200
Subject: [PATCH] mtd: bcm63xxpart: handle Broadcom partition order
The original Broadcom partition order has the root fs in front of the
kernel, which resulted in miscalculated partition sizes.
Detect when such an image is on the flash and also reorder the partitions
accordingly.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Acked-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@linux.intel.com>
---
drivers/mtd/bcm63xxpart.c | 41 ++++++++++++++++++++++++++++++-----------
1 file changed, 30 insertions(+), 11 deletions(-)
--- a/drivers/mtd/bcm63xxpart.c
+++ b/drivers/mtd/bcm63xxpart.c
@@ -4,7 +4,7 @@
* Copyright © 2006-2008 Florian Fainelli <florian@openwrt.org>
* Mike Albon <malbon@openwrt.org>
* Copyright © 2009-2010 Daniel Dickinson <openwrt@cshore.neomailbox.net>
- * Copyright © 2011 Jonas Gorski <jonas.gorski@gmail.com>
+ * Copyright © 2011-2012 Jonas Gorski <jonas.gorski@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -82,6 +82,7 @@ static int bcm63xx_parse_cfe_partitions(
int namelen = 0;
int i;
u32 computed_crc;
+ bool rootfs_first = false;
if (bcm63xx_detect_cfe(master))
return -EINVAL;
@@ -109,6 +110,7 @@ static int bcm63xx_parse_cfe_partitions(
char *boardid = &(buf->board_id[0]);
char *tagversion = &(buf->tag_version[0]);
+ sscanf(buf->flash_image_start, "%u", &rootfsaddr);
sscanf(buf->kernel_address, "%u", &kerneladdr);
sscanf(buf->kernel_length, "%u", &kernellen);
sscanf(buf->total_length, "%u", &totallen);
@@ -117,10 +119,19 @@ static int bcm63xx_parse_cfe_partitions(
tagversion, boardid);
kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE;
- rootfsaddr = kerneladdr + kernellen;
+ rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE;
spareaddr = roundup(totallen, master->erasesize) + cfelen;
sparelen = master->size - spareaddr - nvramlen;
- rootfslen = spareaddr - rootfsaddr;
+
+ if (rootfsaddr < kerneladdr) {
+ /* default Broadcom layout */
+ rootfslen = kerneladdr - rootfsaddr;
+ rootfs_first = true;
+ } else {
+ /* OpenWrt layout */
+ rootfsaddr = kerneladdr + kernellen;
+ rootfslen = spareaddr - rootfsaddr;
+ }
} else {
pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n",
buf->header_crc, computed_crc);
@@ -156,18 +167,26 @@ static int bcm63xx_parse_cfe_partitions(
curpart++;
if (kernellen > 0) {
- parts[curpart].name = "kernel";
- parts[curpart].offset = kerneladdr;
- parts[curpart].size = kernellen;
+ int kernelpart = curpart;
+
+ if (rootfslen > 0 && rootfs_first)
+ kernelpart++;
+ parts[kernelpart].name = "kernel";
+ parts[kernelpart].offset = kerneladdr;
+ parts[kernelpart].size = kernellen;
curpart++;
}
if (rootfslen > 0) {
- parts[curpart].name = "rootfs";
- parts[curpart].offset = rootfsaddr;
- parts[curpart].size = rootfslen;
- if (sparelen > 0)
- parts[curpart].size += sparelen;
+ int rootfspart = curpart;
+
+ if (kernellen > 0 && rootfs_first)
+ rootfspart--;
+ parts[rootfspart].name = "rootfs";
+ parts[rootfspart].offset = rootfsaddr;
+ parts[rootfspart].size = rootfslen;
+ if (sparelen > 0 && !rootfs_first)
+ parts[rootfspart].size += sparelen;
curpart++;
}

View file

@ -1,289 +0,0 @@
From cde4384e1037c15e5dd04c68d19c75798b6281dd Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Fri, 20 Apr 2012 15:37:33 +0200
Subject: [PATCH] spi/bcm63xx: convert to the pump message infrastructure
This patch converts the bcm63xx SPI driver to use the SPI infrastructure
pump message queue. Since we were previously sleeping in the SPI
driver's transfer() function (which is not allowed) this is now fixed as well.
To complete that conversion a certain number of changes have been made:
- the transfer len is split into multiple hardware transfers in case its
size is bigger than the hardware FIFO size
- the FIFO refill is no longer done in the interrupt context, which was a
bad idea leading to quick interrupt handler re-entrancy
Tested-by: Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
Signed-off-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/spi/spi-bcm63xx.c | 149 +++++++++++++++++++++++++++------------------
1 file changed, 89 insertions(+), 60 deletions(-)
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -1,7 +1,7 @@
/*
* Broadcom BCM63xx SPI controller support
*
- * Copyright (C) 2009-2011 Florian Fainelli <florian@openwrt.org>
+ * Copyright (C) 2009-2012 Florian Fainelli <florian@openwrt.org>
* Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
*
* This program is free software; you can redistribute it and/or
@@ -30,6 +30,8 @@
#include <linux/spi/spi.h>
#include <linux/completion.h>
#include <linux/err.h>
+#include <linux/workqueue.h>
+#include <linux/pm_runtime.h>
#include <bcm63xx_dev_spi.h>
@@ -96,17 +98,12 @@ static const unsigned bcm63xx_spi_freq_t
{ 391000, SPI_CLK_0_391MHZ }
};
-static int bcm63xx_spi_setup_transfer(struct spi_device *spi,
- struct spi_transfer *t)
+static int bcm63xx_spi_check_transfer(struct spi_device *spi,
+ struct spi_transfer *t)
{
- struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
u8 bits_per_word;
- u8 clk_cfg, reg;
- u32 hz;
- int i;
bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word;
- hz = (t) ? t->speed_hz : spi->max_speed_hz;
if (bits_per_word != 8) {
dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
__func__, bits_per_word);
@@ -119,6 +116,19 @@ static int bcm63xx_spi_setup_transfer(st
return -EINVAL;
}
+ return 0;
+}
+
+static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
+ struct spi_transfer *t)
+{
+ struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
+ u32 hz;
+ u8 clk_cfg, reg;
+ int i;
+
+ hz = (t) ? t->speed_hz : spi->max_speed_hz;
+
/* Find the closest clock configuration */
for (i = 0; i < SPI_CLK_MASK; i++) {
if (hz >= bcm63xx_spi_freq_table[i][0]) {
@@ -139,8 +149,6 @@ static int bcm63xx_spi_setup_transfer(st
bcm_spi_writeb(bs, reg, SPI_CLK_CFG);
dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n",
clk_cfg, hz);
-
- return 0;
}
/* the spi->mode bits understood by this driver: */
@@ -165,7 +173,7 @@ static int bcm63xx_spi_setup(struct spi_
return -EINVAL;
}
- ret = bcm63xx_spi_setup_transfer(spi, NULL);
+ ret = bcm63xx_spi_check_transfer(spi, NULL);
if (ret < 0) {
dev_err(&spi->dev, "setup: unsupported mode bits %x\n",
spi->mode & ~MODEBITS);
@@ -190,28 +198,29 @@ static void bcm63xx_spi_fill_tx_fifo(str
bs->remaining_bytes -= size;
}
-static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
+static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi,
+ struct spi_transfer *t)
{
struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
u16 msg_ctl;
u16 cmd;
+ /* Disable the CMD_DONE interrupt */
+ bcm_spi_writeb(bs, 0, SPI_INT_MASK);
+
dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
t->tx_buf, t->rx_buf, t->len);
/* Transmitter is inhibited */
bs->tx_ptr = t->tx_buf;
bs->rx_ptr = t->rx_buf;
- init_completion(&bs->done);
if (t->tx_buf) {
bs->remaining_bytes = t->len;
bcm63xx_spi_fill_tx_fifo(bs);
}
- /* Enable the command done interrupt which
- * we use to determine completion of a command */
- bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
+ init_completion(&bs->done);
/* Fill in the Message control register */
msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);
@@ -230,33 +239,76 @@ static int bcm63xx_txrx_bufs(struct spi_
cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
bcm_spi_writew(bs, cmd, SPI_CMD);
- wait_for_completion(&bs->done);
- /* Disable the CMD_DONE interrupt */
- bcm_spi_writeb(bs, 0, SPI_INT_MASK);
+ /* Enable the CMD_DONE interrupt */
+ bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
return t->len - bs->remaining_bytes;
}
-static int bcm63xx_transfer(struct spi_device *spi, struct spi_message *m)
+static int bcm63xx_spi_prepare_transfer(struct spi_master *master)
{
- struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
- struct spi_transfer *t;
- int ret = 0;
+ struct bcm63xx_spi *bs = spi_master_get_devdata(master);
- if (unlikely(list_empty(&m->transfers)))
- return -EINVAL;
+ pm_runtime_get_sync(&bs->pdev->dev);
- if (bs->stopping)
- return -ESHUTDOWN;
+ return 0;
+}
+
+static int bcm63xx_spi_unprepare_transfer(struct spi_master *master)
+{
+ struct bcm63xx_spi *bs = spi_master_get_devdata(master);
+
+ pm_runtime_put(&bs->pdev->dev);
+
+ return 0;
+}
+
+static int bcm63xx_spi_transfer_one(struct spi_master *master,
+ struct spi_message *m)
+{
+ struct bcm63xx_spi *bs = spi_master_get_devdata(master);
+ struct spi_transfer *t;
+ struct spi_device *spi = m->spi;
+ int status = 0;
+ unsigned int timeout = 0;
list_for_each_entry(t, &m->transfers, transfer_list) {
- ret += bcm63xx_txrx_bufs(spi, t);
- }
+ unsigned int len = t->len;
+ u8 rx_tail;
- m->complete(m->context);
+ status = bcm63xx_spi_check_transfer(spi, t);
+ if (status < 0)
+ goto exit;
+
+ /* configure adapter for a new transfer */
+ bcm63xx_spi_setup_transfer(spi, t);
+
+ while (len) {
+ /* send the data */
+ len -= bcm63xx_txrx_bufs(spi, t);
+
+ timeout = wait_for_completion_timeout(&bs->done, HZ);
+ if (!timeout) {
+ status = -ETIMEDOUT;
+ goto exit;
+ }
+
+ /* read out all data */
+ rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
+
+ /* Read out all the data */
+ if (rx_tail)
+ memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail);
+ }
+
+ m->actual_length += t->len;
+ }
+exit:
+ m->status = status;
+ spi_finalize_current_message(master);
- return ret;
+ return 0;
}
/* This driver supports single master mode only. Hence
@@ -267,39 +319,15 @@ static irqreturn_t bcm63xx_spi_interrupt
struct spi_master *master = (struct spi_master *)dev_id;
struct bcm63xx_spi *bs = spi_master_get_devdata(master);
u8 intr;
- u16 cmd;
/* Read interupts and clear them immediately */
intr = bcm_spi_readb(bs, SPI_INT_STATUS);
bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
bcm_spi_writeb(bs, 0, SPI_INT_MASK);
- /* A tansfer completed */
- if (intr & SPI_INTR_CMD_DONE) {
- u8 rx_tail;
-
- rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
-
- /* Read out all the data */
- if (rx_tail)
- memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail);
-
- /* See if there is more data to send */
- if (bs->remaining_bytes > 0) {
- bcm63xx_spi_fill_tx_fifo(bs);
-
- /* Start the transfer */
- bcm_spi_writew(bs, SPI_HD_W << SPI_MSG_TYPE_SHIFT,
- SPI_MSG_CTL);
- cmd = bcm_spi_readw(bs, SPI_CMD);
- cmd |= SPI_CMD_START_IMMEDIATE;
- cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
- bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
- bcm_spi_writew(bs, cmd, SPI_CMD);
- } else {
- complete(&bs->done);
- }
- }
+ /* A transfer completed */
+ if (intr & SPI_INTR_CMD_DONE)
+ complete(&bs->done);
return IRQ_HANDLED;
}
@@ -345,7 +373,6 @@ static int __devinit bcm63xx_spi_probe(s
}
bs = spi_master_get_devdata(master);
- init_completion(&bs->done);
platform_set_drvdata(pdev, master);
bs->pdev = pdev;
@@ -379,7 +406,9 @@ static int __devinit bcm63xx_spi_probe(s
master->bus_num = pdata->bus_num;
master->num_chipselect = pdata->num_chipselect;
master->setup = bcm63xx_spi_setup;
- master->transfer = bcm63xx_transfer;
+ master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer;
+ master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer;
+ master->transfer_one_message = bcm63xx_spi_transfer_one;
bs->speed_hz = pdata->speed_hz;
bs->stopping = 0;
bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));

View file

@ -1,68 +0,0 @@
From 1e41dc0ee2f3807328db95e4f87ff1333245190f Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Fri, 20 Apr 2012 15:37:34 +0200
Subject: [PATCH] spi/bcm63xx: don't use the stopping state
We do not need to use a flag to indicate if the master driver is stopping
it is sufficient to perform spi master unregistering in the platform
driver's remove function.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/spi/spi-bcm63xx.c | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -39,8 +39,6 @@
#define DRV_VER "0.1.2"
struct bcm63xx_spi {
- spinlock_t lock;
- int stopping;
struct completion done;
void __iomem *regs;
@@ -161,9 +159,6 @@ static int bcm63xx_spi_setup(struct spi_
bs = spi_master_get_devdata(spi->master);
- if (bs->stopping)
- return -ESHUTDOWN;
-
if (!spi->bits_per_word)
spi->bits_per_word = 8;
@@ -410,10 +405,8 @@ static int __devinit bcm63xx_spi_probe(s
master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer;
master->transfer_one_message = bcm63xx_spi_transfer_one;
bs->speed_hz = pdata->speed_hz;
- bs->stopping = 0;
bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA));
- spin_lock_init(&bs->lock);
/* Initialize hardware */
clk_enable(bs->clk);
@@ -447,18 +440,16 @@ static int __devexit bcm63xx_spi_remove(
struct spi_master *master = platform_get_drvdata(pdev);
struct bcm63xx_spi *bs = spi_master_get_devdata(master);
+ spi_unregister_master(master);
+
/* reset spi block */
bcm_spi_writeb(bs, 0, SPI_INT_MASK);
- spin_lock(&bs->lock);
- bs->stopping = 1;
/* HW shutdown */
clk_disable(bs->clk);
clk_put(bs->clk);
- spin_unlock(&bs->lock);
platform_set_drvdata(pdev, 0);
- spi_unregister_master(master);
return 0;
}

View file

@ -1,24 +0,0 @@
From 88a3a255a510ed193bf0cc35424761c3c9247586 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Fri, 20 Apr 2012 15:37:35 +0200
Subject: [PATCH] spi/bcm63xx: set master driver mode_bits.
We were not properly advertising the MODE bits supported by this driver, fix
that.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/spi/spi-bcm63xx.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -404,6 +404,7 @@ static int __devinit bcm63xx_spi_probe(s
master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer;
master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer;
master->transfer_one_message = bcm63xx_spi_transfer_one;
+ master->mode_bits = MODEBITS;
bs->speed_hz = pdata->speed_hz;
bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA));

View file

@ -1,128 +0,0 @@
--- a/arch/mips/bcm63xx/dev-spi.c
+++ b/arch/mips/bcm63xx/dev-spi.c
@@ -106,11 +106,15 @@ int __init bcm63xx_spi_register(void)
if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
spi_resources[0].end += BCM_6338_RSET_SPI_SIZE - 1;
spi_pdata.fifo_size = SPI_6338_MSG_DATA_SIZE;
+ spi_pdata.msg_type_shift = SPI_6338_MSG_TYPE_SHIFT;
+ spi_pdata.msg_ctl_width = SPI_6338_MSG_CTL_WIDTH;
}
if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1;
spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE;
+ spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT;
+ spi_pdata.msg_ctl_width = SPI_6358_MSG_CTL_WIDTH;
}
bcm63xx_spi_regs_init();
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h
@@ -9,6 +9,8 @@ int __init bcm63xx_spi_register(void);
struct bcm63xx_spi_pdata {
unsigned int fifo_size;
+ unsigned int msg_type_shift;
+ unsigned int msg_ctl_width;
int bus_num;
int num_chipselect;
u32 speed_hz;
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -987,7 +987,8 @@
#define SPI_6338_FILL_BYTE 0x07
#define SPI_6338_MSG_TAIL 0x09
#define SPI_6338_RX_TAIL 0x0b
-#define SPI_6338_MSG_CTL 0x40
+#define SPI_6338_MSG_CTL 0x40 /* 8-bits register */
+#define SPI_6338_MSG_CTL_WIDTH 8
#define SPI_6338_MSG_DATA 0x41
#define SPI_6338_MSG_DATA_SIZE 0x3f
#define SPI_6338_RX_DATA 0x80
@@ -1003,7 +1004,8 @@
#define SPI_6348_FILL_BYTE 0x07
#define SPI_6348_MSG_TAIL 0x09
#define SPI_6348_RX_TAIL 0x0b
-#define SPI_6348_MSG_CTL 0x40
+#define SPI_6348_MSG_CTL 0x40 /* 8-bits register */
+#define SPI_6348_MSG_CTL_WIDTH 8
#define SPI_6348_MSG_DATA 0x41
#define SPI_6348_MSG_DATA_SIZE 0x3f
#define SPI_6348_RX_DATA 0x80
@@ -1011,6 +1013,7 @@
/* BCM 6358 SPI core */
#define SPI_6358_MSG_CTL 0x00 /* 16-bits register */
+#define SPI_6358_MSG_CTL_WIDTH 16
#define SPI_6358_MSG_DATA 0x02
#define SPI_6358_MSG_DATA_SIZE 0x21e
#define SPI_6358_RX_DATA 0x400
@@ -1027,6 +1030,7 @@
/* BCM 6358 SPI core */
#define SPI_6368_MSG_CTL 0x00 /* 16-bits register */
+#define SPI_6368_MSG_CTL_WIDTH 16
#define SPI_6368_MSG_DATA 0x02
#define SPI_6368_MSG_DATA_SIZE 0x21e
#define SPI_6368_RX_DATA 0x400
@@ -1048,7 +1052,10 @@
#define SPI_HD_W 0x01
#define SPI_HD_R 0x02
#define SPI_BYTE_CNT_SHIFT 0
-#define SPI_MSG_TYPE_SHIFT 14
+#define SPI_6338_MSG_TYPE_SHIFT 6
+#define SPI_6348_MSG_TYPE_SHIFT 6
+#define SPI_6358_MSG_TYPE_SHIFT 14
+#define SPI_6368_MSG_TYPE_SHIFT 14
/* Command */
#define SPI_CMD_NOOP 0x00
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -47,6 +47,8 @@ struct bcm63xx_spi {
/* Platform data */
u32 speed_hz;
unsigned fifo_size;
+ unsigned int msg_type_shift;
+ unsigned int msg_ctl_width;
/* Data buffers */
const unsigned char *tx_ptr;
@@ -221,13 +223,24 @@ static unsigned int bcm63xx_txrx_bufs(st
msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);
if (t->rx_buf && t->tx_buf)
- msg_ctl |= (SPI_FD_RW << SPI_MSG_TYPE_SHIFT);
+ msg_ctl |= (SPI_FD_RW << bs->msg_type_shift);
else if (t->rx_buf)
- msg_ctl |= (SPI_HD_R << SPI_MSG_TYPE_SHIFT);
+ msg_ctl |= (SPI_HD_R << bs->msg_type_shift);
else if (t->tx_buf)
- msg_ctl |= (SPI_HD_W << SPI_MSG_TYPE_SHIFT);
+ msg_ctl |= (SPI_HD_W << bs->msg_type_shift);
- bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL);
+ switch (bs->msg_ctl_width) {
+ case 8:
+ bcm_spi_writeb(bs, msg_ctl, SPI_MSG_CTL);
+ break;
+ case 16:
+ bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL);
+ break;
+ default:
+ dev_err(&spi->dev, "unknown MSG_CTL width: %d\n",
+ bs->msg_ctl_width);
+ return 0;
+ }
/* Issue the transfer */
cmd = SPI_CMD_START_IMMEDIATE;
@@ -406,6 +419,8 @@ static int __devinit bcm63xx_spi_probe(s
master->transfer_one_message = bcm63xx_spi_transfer_one;
master->mode_bits = MODEBITS;
bs->speed_hz = pdata->speed_hz;
+ bs->msg_type_shift = pdata->msg_type_shift;
+ bs->msg_ctl_width = pdata->msg_ctl_width;
bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA));

View file

@ -1,23 +0,0 @@
From 41ee87b6ddd525fab54e21ede506f2084bcabed3 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Wed, 25 Jan 2012 17:39:52 +0100
Subject: [PATCH 14/63] MIPS: BCM63XX: fix BCM6368 IPSec clock bit
The IPsec clock bit is 18 and not 17.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -99,7 +99,7 @@
#define CKCTL_6368_USBH_EN (1 << 15)
#define CKCTL_6368_DISABLE_GLESS_EN (1 << 16)
#define CKCTL_6368_NAND_EN (1 << 17)
-#define CKCTL_6368_IPSEC_EN (1 << 17)
+#define CKCTL_6368_IPSEC_EN (1 << 18)
#define CKCTL_6368_ALL_SAFE_EN (CKCTL_6368_SWPKT_USB_EN | \
CKCTL_6368_SWPKT_SAR_EN | \

View file

@ -1,48 +0,0 @@
From 0fec0136456ce214ea4df6b8ff3b3728befc816a Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Tue, 31 Jan 2012 15:12:22 +0100
Subject: [PATCH 3/6] MIPS: BCM63XX: add support for "ipsec" clock
This module is only available on BCM6368 so far and does not require
resetting the block.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
Cc: linux-mips@linux-mips.org
Cc: mpm@selenic.com
Cc: herbert@gondor.apana.org.au
Patchwork: https://patchwork.linux-mips.org/patch/3324/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
---
arch/mips/bcm63xx/clk.c | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -224,6 +224,18 @@ static struct clk clk_xtm = {
};
/*
+ * IPsec clock
+ */
+static void ipsec_set(struct clk *clk, int enable)
+{
+ bcm_hwclock_set(CKCTL_6368_IPSEC_EN, enable);
+}
+
+static struct clk clk_ipsec = {
+ .set = ipsec_set,
+};
+
+/*
* Internal peripheral clock
*/
static struct clk clk_periph = {
@@ -280,6 +292,8 @@ struct clk *clk_get(struct device *dev,
return &clk_periph;
if (BCMCPU_IS_6358() && !strcmp(id, "pcm"))
return &clk_pcm;
+ if (BCMCPU_IS_6368() && !strcmp(id, "ipsec"))
+ return &clk_ipsec;
return ERR_PTR(-ENOENT);
}

View file

@ -1,113 +0,0 @@
From 357761c423c0f9e4af4aafe85be7889dc36f3584 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Tue, 31 Jan 2012 15:12:23 +0100
Subject: [PATCH 4/6] MIPS: BCM63XX: add RNG peripheral definitions
Signed-off-by: Florian Fainelli <florian@openwrt.org>
Cc: linux-mips@linux-mips.org
Cc: mpm@selenic.com
Cc: herbert@gondor.apana.org.au
Patchwork: https://patchwork.linux-mips.org/patch/3326/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
---
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 9 +++++++++
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 14 ++++++++++++++
2 files changed, 23 insertions(+), 0 deletions(-)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -129,6 +129,7 @@ enum bcm63xx_regs_set {
RSET_PCMDMA,
RSET_PCMDMAC,
RSET_PCMDMAS,
+ RSET_RNG
};
#define RSET_DSL_LMEM_SIZE (64 * 1024 * 4)
@@ -152,6 +153,7 @@ enum bcm63xx_regs_set {
#define RSET_XTMDMA_SIZE 256
#define RSET_XTMDMAC_SIZE(chans) (16 * (chans))
#define RSET_XTMDMAS_SIZE(chans) (16 * (chans))
+#define RSET_RNG_SIZE 20
/*
* 6338 register sets base address
@@ -195,6 +197,7 @@ enum bcm63xx_regs_set {
#define BCM_6338_PCMDMA_BASE (0xdeadbeef)
#define BCM_6338_PCMDMAC_BASE (0xdeadbeef)
#define BCM_6338_PCMDMAS_BASE (0xdeadbeef)
+#define BCM_6338_RNG_BASE (0xdeadbeef)
/*
* 6345 register sets base address
@@ -238,6 +241,7 @@ enum bcm63xx_regs_set {
#define BCM_6345_PCMDMA_BASE (0xdeadbeef)
#define BCM_6345_PCMDMAC_BASE (0xdeadbeef)
#define BCM_6345_PCMDMAS_BASE (0xdeadbeef)
+#define BCM_6345_RNG_BASE (0xdeadbeef)
/*
* 6348 register sets base address
@@ -278,6 +282,7 @@ enum bcm63xx_regs_set {
#define BCM_6348_PCMDMA_BASE (0xdeadbeef)
#define BCM_6348_PCMDMAC_BASE (0xdeadbeef)
#define BCM_6348_PCMDMAS_BASE (0xdeadbeef)
+#define BCM_6348_RNG_BASE (0xdeadbeef)
/*
* 6358 register sets base address
@@ -318,6 +323,7 @@ enum bcm63xx_regs_set {
#define BCM_6358_PCMDMA_BASE (0xfffe1800)
#define BCM_6358_PCMDMAC_BASE (0xfffe1900)
#define BCM_6358_PCMDMAS_BASE (0xfffe1a00)
+#define BCM_6358_RNG_BASE (0xdeadbeef)
/*
@@ -359,6 +365,7 @@ enum bcm63xx_regs_set {
#define BCM_6368_PCMDMA_BASE (0xb0005800)
#define BCM_6368_PCMDMAC_BASE (0xb0005a00)
#define BCM_6368_PCMDMAS_BASE (0xb0005c00)
+#define BCM_6368_RNG_BASE (0xb0004180)
extern const unsigned long *bcm63xx_regs_base;
@@ -404,6 +411,7 @@ extern const unsigned long *bcm63xx_regs
__GEN_RSET_BASE(__cpu, PCMDMA) \
__GEN_RSET_BASE(__cpu, PCMDMAC) \
__GEN_RSET_BASE(__cpu, PCMDMAS) \
+ __GEN_RSET_BASE(__cpu, RNG) \
}
#define __GEN_CPU_REGS_TABLE(__cpu) \
@@ -442,6 +450,7 @@ extern const unsigned long *bcm63xx_regs
[RSET_PCMDMA] = BCM_## __cpu ##_PCMDMA_BASE, \
[RSET_PCMDMAC] = BCM_## __cpu ##_PCMDMAC_BASE, \
[RSET_PCMDMAS] = BCM_## __cpu ##_PCMDMAS_BASE, \
+ [RSET_RNG] = BCM_## __cpu ##_RNG_BASE, \
static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -974,6 +974,20 @@
#define M2M_DSTID_REG(x) ((x) * 0x40 + 0x18)
/*************************************************************************
+ * _REG relative to RSET_RNG
+ *************************************************************************/
+
+#define RNG_CTRL 0x00
+#define RNG_EN (1 << 0)
+
+#define RNG_STAT 0x04
+#define RNG_AVAIL_MASK (0xff000000)
+
+#define RNG_DATA 0x08
+#define RNG_THRES 0x0c
+#define RNG_MASK 0x10
+
+/*************************************************************************
* _REG relative to RSET_SPI
*************************************************************************/

View file

@ -1,71 +0,0 @@
From 79fed26f65c22e0d67c9523f7a374f0585bd2803 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Tue, 31 Jan 2012 15:12:24 +0100
Subject: [PATCH 5/6] MIPS: BCM63XX: add RNG driver platform_device stub
Signed-off-by: Florian Fainelli <florian@openwrt.org>
Cc: linux-mips@linux-mips.org
Cc: mpm@selenic.com
Cc: herbert@gondor.apana.org.au
Patchwork: https://patchwork.linux-mips.org/patch/3325/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
---
arch/mips/bcm63xx/Makefile | 4 ++--
arch/mips/bcm63xx/dev-rng.c | 40 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+), 2 deletions(-)
create mode 100644 arch/mips/bcm63xx/dev-rng.c
--- 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-pcmcia.o dev-spi.o dev-uart.o \
- dev-wdt.o
+ dev-dsp.o dev-enet.o dev-pcmcia.o dev-rng.o dev-spi.o \
+ dev-uart.o dev-wdt.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += boards/
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-rng.c
@@ -0,0 +1,40 @@
+/*
+ * 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) 2011 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_cpu.h>
+
+static struct resource rng_resources[] = {
+ {
+ .start = -1, /* filled at runtime */
+ .end = -1, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bcm63xx_rng_device = {
+ .name = "bcm63xx-rng",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(rng_resources),
+ .resource = rng_resources,
+};
+
+int __init bcm63xx_rng_register(void)
+{
+ if (!BCMCPU_IS_6368())
+ return -ENODEV;
+
+ rng_resources[0].start = bcm63xx_regset_address(RSET_RNG);
+ rng_resources[0].end = rng_resources[0].start;
+ rng_resources[0].end += RSET_RNG_SIZE - 1;
+
+ return platform_device_register(&bcm63xx_rng_device);
+}
+arch_initcall(bcm63xx_rng_register);

View file

@ -1,229 +0,0 @@
From 1cfc5c76c5f48359716bd804daef2f2f7554fb4a Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Tue, 31 Jan 2012 15:12:25 +0100
Subject: [PATCH 6/6] hw_random: add Broadcom BCM63xx RNG driver
Signed-off-by: Florian Fainelli <florian@openwrt.org>
Cc: linux-mips@linux-mips.org
Cc: mpm@selenic.com
Cc: herbert@gondor.apana.org.au
Patchwork: https://patchwork.linux-mips.org/patch/3327/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
---
drivers/char/hw_random/Kconfig | 14 +++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/bcm63xx-rng.c | 175 ++++++++++++++++++++++++++++++++++
3 files changed, 190 insertions(+), 0 deletions(-)
create mode 100644 drivers/char/hw_random/bcm63xx-rng.c
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -73,6 +73,20 @@ config HW_RANDOM_ATMEL
If unsure, say Y.
+config HW_RANDOM_BCM63XX
+ tristate "Broadcom BCM63xx Random Number Generator support"
+ depends on HW_RANDOM && BCM63XX
+ default HW_RANDOM
+ ---help---
+ This driver provides kernel-side support for the Random Number
+ Generator hardware found on the Broadcom BCM63xx SoCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bcm63xx-rng
+
+ If unusure, say Y.
+
+
config HW_RANDOM_GEODE
tristate "AMD Geode HW Random Number Generator support"
depends on HW_RANDOM && X86_32 && PCI
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += ti
obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o
obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o
obj-$(CONFIG_HW_RANDOM_ATMEL) += atmel-rng.o
+obj-$(CONFIG_HW_RANDOM_BCM63XX) += bcm63xx-rng.o
obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
obj-$(CONFIG_HW_RANDOM_N2RNG) += n2-rng.o
n2-rng-y := n2-drv.o n2-asm.o
--- /dev/null
+++ b/drivers/char/hw_random/bcm63xx-rng.c
@@ -0,0 +1,175 @@
+/*
+ * Broadcom BCM63xx Random Number Generator support
+ *
+ * Copyright (C) 2011, Florian Fainelli <florian@openwrt.org>
+ * Copyright (C) 2009, Broadcom Corporation
+ *
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/hw_random.h>
+
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+
+struct bcm63xx_rng_priv {
+ struct clk *clk;
+ void __iomem *regs;
+};
+
+#define to_rng_priv(rng) ((struct bcm63xx_rng_priv *)rng->priv)
+
+static int bcm63xx_rng_init(struct hwrng *rng)
+{
+ struct bcm63xx_rng_priv *priv = to_rng_priv(rng);
+ u32 val;
+
+ val = bcm_readl(priv->regs + RNG_CTRL);
+ val |= RNG_EN;
+ bcm_writel(val, priv->regs + RNG_CTRL);
+
+ return 0;
+}
+
+static void bcm63xx_rng_cleanup(struct hwrng *rng)
+{
+ struct bcm63xx_rng_priv *priv = to_rng_priv(rng);
+ u32 val;
+
+ val = bcm_readl(priv->regs + RNG_CTRL);
+ val &= ~RNG_EN;
+ bcm_writel(val, priv->regs + RNG_CTRL);
+}
+
+static int bcm63xx_rng_data_present(struct hwrng *rng, int wait)
+{
+ struct bcm63xx_rng_priv *priv = to_rng_priv(rng);
+
+ return bcm_readl(priv->regs + RNG_STAT) & RNG_AVAIL_MASK;
+}
+
+static int bcm63xx_rng_data_read(struct hwrng *rng, u32 *data)
+{
+ struct bcm63xx_rng_priv *priv = to_rng_priv(rng);
+
+ *data = bcm_readl(priv->regs + RNG_DATA);
+
+ return 4;
+}
+
+static int __init bcm63xx_rng_probe(struct platform_device *pdev)
+{
+ struct resource *r;
+ struct clk *clk;
+ int ret;
+ struct bcm63xx_rng_priv *priv;
+ struct hwrng *rng;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ dev_err(&pdev->dev, "no iomem resource\n");
+ ret = -ENXIO;
+ goto out;
+ }
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ dev_err(&pdev->dev, "no memory for private structure\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ rng = kzalloc(sizeof(*rng), GFP_KERNEL);
+ if (!rng) {
+ dev_err(&pdev->dev, "no memory for rng structure\n");
+ ret = -ENOMEM;
+ goto out_free_priv;
+ }
+
+ platform_set_drvdata(pdev, rng);
+ rng->priv = (unsigned long)priv;
+ rng->name = pdev->name;
+ rng->init = bcm63xx_rng_init;
+ rng->cleanup = bcm63xx_rng_cleanup;
+ rng->data_present = bcm63xx_rng_data_present;
+ rng->data_read = bcm63xx_rng_data_read;
+
+ clk = clk_get(&pdev->dev, "ipsec");
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "no clock for device\n");
+ ret = PTR_ERR(clk);
+ goto out_free_rng;
+ }
+
+ priv->clk = clk;
+
+ if (!devm_request_mem_region(&pdev->dev, r->start,
+ resource_size(r), pdev->name)) {
+ dev_err(&pdev->dev, "request mem failed");
+ ret = -ENOMEM;
+ goto out_free_rng;
+ }
+
+ priv->regs = devm_ioremap_nocache(&pdev->dev, r->start,
+ resource_size(r));
+ if (!priv->regs) {
+ dev_err(&pdev->dev, "ioremap failed");
+ ret = -ENOMEM;
+ goto out_free_rng;
+ }
+
+ clk_enable(clk);
+
+ ret = hwrng_register(rng);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register rng device\n");
+ goto out_clk_disable;
+ }
+
+ dev_info(&pdev->dev, "registered RNG driver\n");
+
+ return 0;
+
+out_clk_disable:
+ clk_disable(clk);
+out_free_rng:
+ platform_set_drvdata(pdev, NULL);
+ kfree(rng);
+out_free_priv:
+ kfree(priv);
+out:
+ return ret;
+}
+
+static int __devexit bcm63xx_rng_remove(struct platform_device *pdev)
+{
+ struct hwrng *rng = platform_get_drvdata(pdev);
+ struct bcm63xx_rng_priv *priv = to_rng_priv(rng);
+
+ hwrng_unregister(rng);
+ clk_disable(priv->clk);
+ kfree(priv);
+ kfree(rng);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver bcm63xx_rng_driver = {
+ .probe = bcm63xx_rng_probe,
+ .remove = __devexit_p(bcm63xx_rng_remove),
+ .driver = {
+ .name = "bcm63xx-rng",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(bcm63xx_rng_driver);
+
+MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
+MODULE_DESCRIPTION("Broadcom BCM63xx RNG driver");
+MODULE_LICENSE("GPL");

View file

@ -1,202 +0,0 @@
From bfe47f0f68b5f7a3a92d07266cba58b188fe10e7 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Tue, 12 Jun 2012 10:23:38 +0200
Subject: [PATCH 1/8] MIPS: BCM63XX: Move flash registration out of board_bcm963xx.c
board_bcm963xx.c is already large enough.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: Maxime Bizon <mbizon@freebox.fr>
Cc: Florian Fainelli <florian@openwrt.org>
Cc: Kevin Cernekee <cernekee@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/3952/
Reviewed-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
---
arch/mips/bcm63xx/Makefile | 4 +-
arch/mips/bcm63xx/boards/board_bcm963xx.c | 49 +-------------
arch/mips/bcm63xx/dev-flash.c | 69 ++++++++++++++++++++
.../include/asm/mach-bcm63xx/bcm63xx_dev_flash.h | 6 ++
4 files changed, 79 insertions(+), 49 deletions(-)
create mode 100644 arch/mips/bcm63xx/dev-flash.c
create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.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-pcmcia.o dev-rng.o dev-spi.o \
- dev-uart.o dev-wdt.o
+ dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o dev-rng.o \
+ dev-spi.o dev-uart.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
@@ -11,9 +11,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
#include <linux/ssb/ssb.h>
#include <asm/addrspace.h>
#include <bcm63xx_board.h>
@@ -24,6 +21,7 @@
#include <bcm63xx_dev_pci.h>
#include <bcm63xx_dev_enet.h>
#include <bcm63xx_dev_dsp.h>
+#include <bcm63xx_dev_flash.h>
#include <bcm63xx_dev_pcmcia.h>
#include <bcm63xx_dev_spi.h>
#include <board_bcm963xx.h>
@@ -809,40 +807,6 @@ void __init board_setup(void)
panic("unexpected CPU for bcm963xx board");
}
-static struct mtd_partition mtd_partitions[] = {
- {
- .name = "cfe",
- .offset = 0x0,
- .size = 0x40000,
- }
-};
-
-static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL };
-
-static struct physmap_flash_data flash_data = {
- .width = 2,
- .nr_parts = ARRAY_SIZE(mtd_partitions),
- .parts = mtd_partitions,
- .part_probe_types = bcm63xx_part_types,
-};
-
-static struct resource mtd_resources[] = {
- {
- .start = 0, /* filled at runtime */
- .end = 0, /* filled at runtime */
- .flags = IORESOURCE_MEM,
- }
-};
-
-static struct platform_device mtd_dev = {
- .name = "physmap-flash",
- .resource = mtd_resources,
- .num_resources = ARRAY_SIZE(mtd_resources),
- .dev = {
- .platform_data = &flash_data,
- },
-};
-
static struct gpio_led_platform_data bcm63xx_led_data;
static struct platform_device bcm63xx_gpio_leds = {
@@ -856,8 +820,6 @@ static struct platform_device bcm63xx_gp
*/
int __init board_register_devices(void)
{
- u32 val;
-
if (board.has_uart0)
bcm63xx_uart_register(0);
@@ -893,14 +855,7 @@ int __init board_register_devices(void)
bcm63xx_spi_register();
- /* read base address of boot chip select (0) */
- val = bcm_mpi_readl(MPI_CSBASE_REG(0));
- val &= MPI_CSBASE_BASE_MASK;
-
- mtd_resources[0].start = val;
- mtd_resources[0].end = 0x1FFFFFFF;
-
- platform_device_register(&mtd_dev);
+ bcm63xx_flash_register();
bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
bcm63xx_led_data.leds = board.leds;
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-flash.c
@@ -0,0 +1,69 @@
+/*
+ * Broadcom BCM63xx flash registration
+ *
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_flash.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+
+static struct mtd_partition mtd_partitions[] = {
+ {
+ .name = "cfe",
+ .offset = 0x0,
+ .size = 0x40000,
+ }
+};
+
+static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL };
+
+static struct physmap_flash_data flash_data = {
+ .width = 2,
+ .parts = mtd_partitions,
+ .part_probe_types = bcm63xx_part_types,
+};
+
+static struct resource mtd_resources[] = {
+ {
+ .start = 0, /* filled at runtime */
+ .end = 0, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device mtd_dev = {
+ .name = "physmap-flash",
+ .resource = mtd_resources,
+ .num_resources = ARRAY_SIZE(mtd_resources),
+ .dev = {
+ .platform_data = &flash_data,
+ },
+};
+
+int __init bcm63xx_flash_register(void)
+{
+ u32 val;
+
+ /* read base address of boot chip select (0) */
+ val = bcm_mpi_readl(MPI_CSBASE_REG(0));
+ val &= MPI_CSBASE_BASE_MASK;
+
+ mtd_resources[0].start = val;
+ mtd_resources[0].end = 0x1FFFFFFF;
+
+ return platform_device_register(&mtd_dev);
+}
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h
@@ -0,0 +1,6 @@
+#ifndef __BCM63XX_FLASH_H
+#define __BCM63XX_FLASH_H
+
+int __init bcm63xx_flash_register(void);
+
+#endif /* __BCM63XX_FLASH_H */

View file

@ -1,137 +0,0 @@
From 0c921d542eb4359791cffd1737bf45184f6ae352 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Tue, 12 Jun 2012 10:23:39 +0200
Subject: [PATCH 2/8] MIPS: BCM63XX: Add flash type detection
On BCM6358 and BCM6368 the attached flash type is exposed through a
bootstrapping register. Use it for auto detecting the flash type on
those and default to parallel flash for earlier SoCs.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: Maxime Bizon <mbizon@freebox.fr>
Cc: Florian Fainelli <florian@openwrt.org>
Cc: Kevin Cernekee <cernekee@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/3954/
Reviewed-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
---
arch/mips/bcm63xx/dev-flash.c | 60 ++++++++++++++++++--
.../include/asm/mach-bcm63xx/bcm63xx_dev_flash.h | 6 ++
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 9 +++
3 files changed, 69 insertions(+), 6 deletions(-)
--- a/arch/mips/bcm63xx/dev-flash.c
+++ b/arch/mips/bcm63xx/dev-flash.c
@@ -7,6 +7,7 @@
*
* Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
* Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
+ * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
*/
#include <linux/init.h>
@@ -54,16 +55,63 @@ static struct platform_device mtd_dev =
},
};
-int __init bcm63xx_flash_register(void)
+static int __init bcm63xx_detect_flash_type(void)
{
u32 val;
- /* read base address of boot chip select (0) */
- val = bcm_mpi_readl(MPI_CSBASE_REG(0));
- val &= MPI_CSBASE_BASE_MASK;
+ switch (bcm63xx_get_cpu_id()) {
+ 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;
+ case BCM6358_CPU_ID:
+ val = bcm_gpio_readl(GPIO_STRAPBUS_REG);
+ if (val & STRAPBUS_6358_BOOT_SEL_PARALLEL)
+ return BCM63XX_FLASH_TYPE_PARALLEL;
+ else
+ return BCM63XX_FLASH_TYPE_SERIAL;
+ case BCM6368_CPU_ID:
+ val = bcm_gpio_readl(GPIO_STRAPBUS_REG);
+ switch (val & STRAPBUS_6368_BOOT_SEL_MASK) {
+ case STRAPBUS_6368_BOOT_SEL_NAND:
+ return BCM63XX_FLASH_TYPE_NAND;
+ case STRAPBUS_6368_BOOT_SEL_SERIAL:
+ return BCM63XX_FLASH_TYPE_SERIAL;
+ case STRAPBUS_6368_BOOT_SEL_PARALLEL:
+ return BCM63XX_FLASH_TYPE_PARALLEL;
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+int __init bcm63xx_flash_register(void)
+{
+ int flash_type;
+ u32 val;
- mtd_resources[0].start = val;
- mtd_resources[0].end = 0x1FFFFFFF;
+ flash_type = bcm63xx_detect_flash_type();
- return platform_device_register(&mtd_dev);
+ switch (flash_type) {
+ case BCM63XX_FLASH_TYPE_PARALLEL:
+ /* read base address of boot chip select (0) */
+ val = bcm_mpi_readl(MPI_CSBASE_REG(0));
+ val &= MPI_CSBASE_BASE_MASK;
+
+ mtd_resources[0].start = val;
+ mtd_resources[0].end = 0x1FFFFFFF;
+
+ return platform_device_register(&mtd_dev);
+ case BCM63XX_FLASH_TYPE_SERIAL:
+ pr_warn("unsupported serial flash detected\n");
+ return -ENODEV;
+ case BCM63XX_FLASH_TYPE_NAND:
+ pr_warn("unsupported NAND flash detected\n");
+ return -ENODEV;
+ default:
+ pr_err("flash detection failed for BCM%x: %d\n",
+ bcm63xx_get_cpu_id(), flash_type);
+ return -ENODEV;
+ }
}
--- 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,12 @@
#ifndef __BCM63XX_FLASH_H
#define __BCM63XX_FLASH_H
+enum {
+ BCM63XX_FLASH_TYPE_PARALLEL,
+ BCM63XX_FLASH_TYPE_SERIAL,
+ BCM63XX_FLASH_TYPE_NAND,
+};
+
int __init bcm63xx_flash_register(void);
#endif /* __BCM63XX_FLASH_H */
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -507,6 +507,15 @@
#define GPIO_BASEMODE_6368_MASK 0x7
/* those bits must be kept as read in gpio basemode register*/
+#define GPIO_STRAPBUS_REG 0x40
+#define STRAPBUS_6358_BOOT_SEL_PARALLEL (1 << 1)
+#define STRAPBUS_6358_BOOT_SEL_SERIAL (0 << 1)
+#define STRAPBUS_6368_BOOT_SEL_MASK 0x3
+#define STRAPBUS_6368_BOOT_SEL_NAND 0
+#define STRAPBUS_6368_BOOT_SEL_SERIAL 1
+#define STRAPBUS_6368_BOOT_SEL_PARALLEL 3
+
+
/*************************************************************************
* _REG relative to RSET_ENET
*************************************************************************/

View file

@ -1,53 +0,0 @@
From a9168d99658bd050e49afc06880d140e2fc2c231 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Tue, 12 Jun 2012 10:23:40 +0200
Subject: [PATCH 3/8] MIPS: BCM63XX: Use the Chip ID register for identifying the SoC
Newer BCM63XX SoCs use virtually the same CPU ID, differing only in the
revision bits. But since they all have the Chip ID register at the same
location, we can use that to identify the SoC we are running on.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: Maxime Bizon <mbizon@freebox.fr>
Cc: Florian Fainelli <florian@openwrt.org>
Cc: Kevin Cernekee <cernekee@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/3955/
Reviewed-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
---
arch/mips/bcm63xx/cpu.c | 20 ++++++++++++--------
1 files changed, 12 insertions(+), 8 deletions(-)
--- a/arch/mips/bcm63xx/cpu.c
+++ b/arch/mips/bcm63xx/cpu.c
@@ -228,17 +228,21 @@ void __init bcm63xx_cpu_init(void)
bcm63xx_irqs = bcm6345_irqs;
break;
case CPU_BMIPS4350:
- switch (read_c0_prid() & 0xf0) {
- case 0x10:
+ if ((read_c0_prid() & 0xf0) == 0x10) {
expected_cpu_id = BCM6358_CPU_ID;
bcm63xx_regs_base = bcm6358_regs_base;
bcm63xx_irqs = bcm6358_irqs;
- break;
- case 0x30:
- expected_cpu_id = BCM6368_CPU_ID;
- bcm63xx_regs_base = bcm6368_regs_base;
- bcm63xx_irqs = bcm6368_irqs;
- break;
+ } else {
+ /* all newer chips have the same chip id location */
+ u16 chip_id = bcm_readw(BCM_6368_PERF_BASE);
+
+ switch (chip_id) {
+ case BCM6368_CPU_ID:
+ expected_cpu_id = BCM6368_CPU_ID;
+ bcm63xx_regs_base = bcm6368_regs_base;
+ bcm63xx_irqs = bcm6368_irqs;
+ break;
+ }
}
break;
}

View file

@ -1,590 +0,0 @@
From 8f9ed2e5502ed3ba3d4c89678cb44f43ccd5b9e0 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Wed, 13 Jun 2012 16:46:54 +0100
Subject: [PATCH 4/8] MIPS: BCM63XX: Add basic BCM6328 support
This includes CPU speed, memory size detection and working UART, but
lacking the appropriate drivers, no support for attached flash.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: Maxime Bizon <mbizon@freebox.fr>
Cc: Florian Fainelli <florian@openwrt.org>
Cc: Kevin Cernekee <cernekee@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/3951/
Reviewed-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
---
arch/mips/bcm63xx/Kconfig | 3 +
arch/mips/bcm63xx/boards/board_bcm963xx.c | 12 ++-
arch/mips/bcm63xx/cpu.c | 43 ++++++++
arch/mips/bcm63xx/dev-flash.c | 6 +
arch/mips/bcm63xx/dev-spi.c | 2 +-
arch/mips/bcm63xx/irq.c | 21 ++++
arch/mips/bcm63xx/prom.c | 4 +-
arch/mips/bcm63xx/setup.c | 13 ++-
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 111 ++++++++++++++++++++-
arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h | 2 +
arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h | 2 +
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 54 ++++++++++
arch/mips/include/asm/mach-bcm63xx/ioremap.h | 1 +
13 files changed, 265 insertions(+), 9 deletions(-)
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -1,6 +1,9 @@
menu "CPU support"
depends on BCM63XX
+config BCM63XX_CPU_6328
+ bool "support 6328 CPU"
+
config BCM63XX_CPU_6338
bool "support 6338 CPU"
select HW_HAS_PCI
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -708,9 +708,15 @@ void __init board_prom_init(void)
char cfe_version[32];
u32 val;
- /* read base address of boot chip select (0) */
- val = bcm_mpi_readl(MPI_CSBASE_REG(0));
- val &= MPI_CSBASE_BASE_MASK;
+ /* read base address of boot chip select (0)
+ * 6328 does not have MPI but boots from a fixed address
+ */
+ if (BCMCPU_IS_6328())
+ val = 0x18000000;
+ else {
+ val = bcm_mpi_readl(MPI_CSBASE_REG(0));
+ val &= MPI_CSBASE_BASE_MASK;
+ }
boot_addr = (u8 *)KSEG1ADDR(val);
/* dump cfe version */
--- a/arch/mips/bcm63xx/cpu.c
+++ b/arch/mips/bcm63xx/cpu.c
@@ -29,6 +29,14 @@ static u16 bcm63xx_cpu_rev;
static unsigned int bcm63xx_cpu_freq;
static unsigned int bcm63xx_memory_size;
+static const unsigned long bcm6328_regs_base[] = {
+ __GEN_CPU_REGS_TABLE(6328)
+};
+
+static const int bcm6328_irqs[] = {
+ __GEN_CPU_IRQ_TABLE(6328)
+};
+
static const unsigned long bcm6338_regs_base[] = {
__GEN_CPU_REGS_TABLE(6338)
};
@@ -99,6 +107,33 @@ unsigned int bcm63xx_get_memory_size(voi
static unsigned int detect_cpu_clock(void)
{
switch (bcm63xx_get_cpu_id()) {
+ case BCM6328_CPU_ID:
+ {
+ unsigned int tmp, mips_pll_fcvo;
+
+ tmp = bcm_misc_readl(MISC_STRAPBUS_6328_REG);
+ mips_pll_fcvo = (tmp & STRAPBUS_6328_FCVO_MASK)
+ >> STRAPBUS_6328_FCVO_SHIFT;
+
+ switch (mips_pll_fcvo) {
+ case 0x12:
+ case 0x14:
+ case 0x19:
+ return 160000000;
+ case 0x1c:
+ return 192000000;
+ case 0x13:
+ case 0x15:
+ return 200000000;
+ case 0x1a:
+ return 384000000;
+ case 0x16:
+ return 400000000;
+ default:
+ return 320000000;
+ }
+
+ }
case BCM6338_CPU_ID:
/* BCM6338 has a fixed 240 Mhz frequency */
return 240000000;
@@ -170,6 +205,9 @@ static unsigned int detect_memory_size(v
unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0;
u32 val;
+ if (BCMCPU_IS_6328())
+ return bcm_ddr_readl(DDR_CSEND_REG) << 24;
+
if (BCMCPU_IS_6345()) {
val = bcm_sdram_readl(SDRAM_MBASE_REG);
return (val * 8 * 1024 * 1024);
@@ -237,6 +275,11 @@ void __init bcm63xx_cpu_init(void)
u16 chip_id = bcm_readw(BCM_6368_PERF_BASE);
switch (chip_id) {
+ case BCM6328_CPU_ID:
+ expected_cpu_id = BCM6328_CPU_ID;
+ bcm63xx_regs_base = bcm6328_regs_base;
+ bcm63xx_irqs = bcm6328_irqs;
+ break;
case BCM6368_CPU_ID:
expected_cpu_id = BCM6368_CPU_ID;
bcm63xx_regs_base = bcm6368_regs_base;
--- a/arch/mips/bcm63xx/dev-flash.c
+++ b/arch/mips/bcm63xx/dev-flash.c
@@ -60,6 +60,12 @@ static int __init bcm63xx_detect_flash_t
u32 val;
switch (bcm63xx_get_cpu_id()) {
+ case BCM6328_CPU_ID:
+ val = bcm_misc_readl(MISC_STRAPBUS_6328_REG);
+ if (val & STRAPBUS_6328_BOOT_SEL_SERIAL)
+ return BCM63XX_FLASH_TYPE_SERIAL;
+ else
+ return BCM63XX_FLASH_TYPE_NAND;
case BCM6338_CPU_ID:
case BCM6345_CPU_ID:
case BCM6348_CPU_ID:
--- a/arch/mips/bcm63xx/dev-spi.c
+++ b/arch/mips/bcm63xx/dev-spi.c
@@ -87,7 +87,7 @@ int __init bcm63xx_spi_register(void)
{
struct clk *periph_clk;
- if (BCMCPU_IS_6345())
+ if (BCMCPU_IS_6328() || BCMCPU_IS_6345())
return -ENODEV;
periph_clk = clk_get(NULL, "periph");
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -27,6 +27,17 @@ static void __internal_irq_unmask_32(uns
static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused;
#ifndef BCMCPU_RUNTIME_DETECT
+#ifdef CONFIG_BCM63XX_CPU_6328
+#define irq_stat_reg PERF_IRQSTAT_6328_REG
+#define irq_mask_reg PERF_IRQMASK_6328_REG
+#define irq_bits 64
+#define is_ext_irq_cascaded 1
+#define ext_irq_start (BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE)
+#define ext_irq_end (BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE)
+#define ext_irq_count 4
+#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6328
+#define ext_irq_cfg_reg2 0
+#endif
#ifdef CONFIG_BCM63XX_CPU_6338
#define irq_stat_reg PERF_IRQSTAT_6338_REG
#define irq_mask_reg PERF_IRQMASK_6338_REG
@@ -118,6 +129,16 @@ static void bcm63xx_init_irq(void)
irq_mask_addr = bcm63xx_regset_address(RSET_PERF);
switch (bcm63xx_get_cpu_id()) {
+ case BCM6328_CPU_ID:
+ irq_stat_addr += PERF_IRQSTAT_6328_REG;
+ irq_mask_addr += PERF_IRQMASK_6328_REG;
+ irq_bits = 64;
+ ext_irq_count = 4;
+ is_ext_irq_cascaded = 1;
+ ext_irq_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE;
+ ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE;
+ ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328;
+ break;
case BCM6338_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6338_REG;
irq_mask_addr += PERF_IRQMASK_6338_REG;
--- a/arch/mips/bcm63xx/prom.c
+++ b/arch/mips/bcm63xx/prom.c
@@ -26,7 +26,9 @@ void __init prom_init(void)
bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG);
/* disable all hardware blocks clock for now */
- if (BCMCPU_IS_6338())
+ if (BCMCPU_IS_6328())
+ mask = CKCTL_6328_ALL_SAFE_EN;
+ else if (BCMCPU_IS_6338())
mask = CKCTL_6338_ALL_SAFE_EN;
else if (BCMCPU_IS_6345())
mask = CKCTL_6345_ALL_SAFE_EN;
--- a/arch/mips/bcm63xx/setup.c
+++ b/arch/mips/bcm63xx/setup.c
@@ -68,6 +68,9 @@ void bcm63xx_machine_reboot(void)
/* mask and clear all external irq */
switch (bcm63xx_get_cpu_id()) {
+ case BCM6328_CPU_ID:
+ perf_regs[0] = PERF_EXTIRQ_CFG_REG_6328;
+ break;
case BCM6338_CPU_ID:
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6338;
break;
@@ -95,9 +98,13 @@ void bcm63xx_machine_reboot(void)
bcm6348_a1_reboot();
printk(KERN_INFO "triggering watchdog soft-reset...\n");
- reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG);
- reg |= SYS_PLL_SOFT_RESET;
- bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG);
+ if (BCMCPU_IS_6328()) {
+ bcm_wdt_writel(1, WDT_SOFTRESET_REG);
+ } else {
+ reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG);
+ reg |= SYS_PLL_SOFT_RESET;
+ bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG);
+ }
while (1)
;
}
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -9,6 +9,7 @@
* compile time if only one CPU support is enabled (idea stolen from
* arm mach-types)
*/
+#define BCM6328_CPU_ID 0x6328
#define BCM6338_CPU_ID 0x6338
#define BCM6345_CPU_ID 0x6345
#define BCM6348_CPU_ID 0x6348
@@ -20,6 +21,19 @@ u16 __bcm63xx_get_cpu_id(void);
u16 bcm63xx_get_cpu_rev(void);
unsigned int bcm63xx_get_cpu_freq(void);
+#ifdef CONFIG_BCM63XX_CPU_6328
+# ifdef bcm63xx_get_cpu_id
+# undef bcm63xx_get_cpu_id
+# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
+# define BCMCPU_RUNTIME_DETECT
+# else
+# define bcm63xx_get_cpu_id() BCM6328_CPU_ID
+# endif
+# define BCMCPU_IS_6328() (bcm63xx_get_cpu_id() == BCM6328_CPU_ID)
+#else
+# define BCMCPU_IS_6328() (0)
+#endif
+
#ifdef CONFIG_BCM63XX_CPU_6338
# ifdef bcm63xx_get_cpu_id
# undef bcm63xx_get_cpu_id
@@ -129,7 +143,8 @@ enum bcm63xx_regs_set {
RSET_PCMDMA,
RSET_PCMDMAC,
RSET_PCMDMAS,
- RSET_RNG
+ RSET_RNG,
+ RSET_MISC
};
#define RSET_DSL_LMEM_SIZE (64 * 1024 * 4)
@@ -156,6 +171,49 @@ enum bcm63xx_regs_set {
#define RSET_RNG_SIZE 20
/*
+ * 6328 register sets base address
+ */
+#define BCM_6328_DSL_LMEM_BASE (0xdeadbeef)
+#define BCM_6328_PERF_BASE (0xb0000000)
+#define BCM_6328_TIMER_BASE (0xb0000040)
+#define BCM_6328_WDT_BASE (0xb000005c)
+#define BCM_6328_UART0_BASE (0xb0000100)
+#define BCM_6328_UART1_BASE (0xb0000120)
+#define BCM_6328_GPIO_BASE (0xb0000080)
+#define BCM_6328_SPI_BASE (0xdeadbeef)
+#define BCM_6328_UDC0_BASE (0xdeadbeef)
+#define BCM_6328_USBDMA_BASE (0xdeadbeef)
+#define BCM_6328_OHCI0_BASE (0xdeadbeef)
+#define BCM_6328_OHCI_PRIV_BASE (0xdeadbeef)
+#define BCM_6328_USBH_PRIV_BASE (0xdeadbeef)
+#define BCM_6328_MPI_BASE (0xdeadbeef)
+#define BCM_6328_PCMCIA_BASE (0xdeadbeef)
+#define BCM_6328_SDRAM_REGS_BASE (0xdeadbeef)
+#define BCM_6328_DSL_BASE (0xb0001900)
+#define BCM_6328_UBUS_BASE (0xdeadbeef)
+#define BCM_6328_ENET0_BASE (0xdeadbeef)
+#define BCM_6328_ENET1_BASE (0xdeadbeef)
+#define BCM_6328_ENETDMA_BASE (0xb000d800)
+#define BCM_6328_ENETDMAC_BASE (0xb000da00)
+#define BCM_6328_ENETDMAS_BASE (0xb000dc00)
+#define BCM_6328_ENETSW_BASE (0xb0e00000)
+#define BCM_6328_EHCI0_BASE (0x10002500)
+#define BCM_6328_SDRAM_BASE (0xdeadbeef)
+#define BCM_6328_MEMC_BASE (0xdeadbeef)
+#define BCM_6328_DDR_BASE (0xb0003000)
+#define BCM_6328_M2M_BASE (0xdeadbeef)
+#define BCM_6328_ATM_BASE (0xdeadbeef)
+#define BCM_6328_XTM_BASE (0xdeadbeef)
+#define BCM_6328_XTMDMA_BASE (0xb000b800)
+#define BCM_6328_XTMDMAC_BASE (0xdeadbeef)
+#define BCM_6328_XTMDMAS_BASE (0xdeadbeef)
+#define BCM_6328_PCM_BASE (0xb000a800)
+#define BCM_6328_PCMDMA_BASE (0xdeadbeef)
+#define BCM_6328_PCMDMAC_BASE (0xdeadbeef)
+#define BCM_6328_PCMDMAS_BASE (0xdeadbeef)
+#define BCM_6328_RNG_BASE (0xdeadbeef)
+#define BCM_6328_MISC_BASE (0xb0001800)
+/*
* 6338 register sets base address
*/
#define BCM_6338_DSL_LMEM_BASE (0xfff00000)
@@ -198,6 +256,7 @@ enum bcm63xx_regs_set {
#define BCM_6338_PCMDMAC_BASE (0xdeadbeef)
#define BCM_6338_PCMDMAS_BASE (0xdeadbeef)
#define BCM_6338_RNG_BASE (0xdeadbeef)
+#define BCM_6338_MISC_BASE (0xdeadbeef)
/*
* 6345 register sets base address
@@ -242,6 +301,7 @@ enum bcm63xx_regs_set {
#define BCM_6345_PCMDMAC_BASE (0xdeadbeef)
#define BCM_6345_PCMDMAS_BASE (0xdeadbeef)
#define BCM_6345_RNG_BASE (0xdeadbeef)
+#define BCM_6345_MISC_BASE (0xdeadbeef)
/*
* 6348 register sets base address
@@ -283,6 +343,7 @@ enum bcm63xx_regs_set {
#define BCM_6348_PCMDMAC_BASE (0xdeadbeef)
#define BCM_6348_PCMDMAS_BASE (0xdeadbeef)
#define BCM_6348_RNG_BASE (0xdeadbeef)
+#define BCM_6348_MISC_BASE (0xdeadbeef)
/*
* 6358 register sets base address
@@ -324,6 +385,7 @@ enum bcm63xx_regs_set {
#define BCM_6358_PCMDMAC_BASE (0xfffe1900)
#define BCM_6358_PCMDMAS_BASE (0xfffe1a00)
#define BCM_6358_RNG_BASE (0xdeadbeef)
+#define BCM_6358_MISC_BASE (0xdeadbeef)
/*
@@ -366,6 +428,7 @@ enum bcm63xx_regs_set {
#define BCM_6368_PCMDMAC_BASE (0xb0005a00)
#define BCM_6368_PCMDMAS_BASE (0xb0005c00)
#define BCM_6368_RNG_BASE (0xb0004180)
+#define BCM_6368_MISC_BASE (0xdeadbeef)
extern const unsigned long *bcm63xx_regs_base;
@@ -412,6 +475,7 @@ extern const unsigned long *bcm63xx_regs
__GEN_RSET_BASE(__cpu, PCMDMAC) \
__GEN_RSET_BASE(__cpu, PCMDMAS) \
__GEN_RSET_BASE(__cpu, RNG) \
+ __GEN_RSET_BASE(__cpu, MISC) \
}
#define __GEN_CPU_REGS_TABLE(__cpu) \
@@ -451,6 +515,7 @@ extern const unsigned long *bcm63xx_regs
[RSET_PCMDMAC] = BCM_## __cpu ##_PCMDMAC_BASE, \
[RSET_PCMDMAS] = BCM_## __cpu ##_PCMDMAS_BASE, \
[RSET_RNG] = BCM_## __cpu ##_RNG_BASE, \
+ [RSET_MISC] = BCM_## __cpu ##_MISC_BASE, \
static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
@@ -458,6 +523,9 @@ static inline unsigned long bcm63xx_regs
#ifdef BCMCPU_RUNTIME_DETECT
return bcm63xx_regs_base[set];
#else
+#ifdef CONFIG_BCM63XX_CPU_6328
+ __GEN_RSET(6328)
+#endif
#ifdef CONFIG_BCM63XX_CPU_6338
__GEN_RSET(6338)
#endif
@@ -512,6 +580,47 @@ enum bcm63xx_irq {
};
/*
+ * 6328 irqs
+ */
+#define BCM_6328_HIGH_IRQ_BASE (IRQ_INTERNAL_BASE + 32)
+
+#define BCM_6328_TIMER_IRQ (IRQ_INTERNAL_BASE + 31)
+#define BCM_6328_SPI_IRQ 0
+#define BCM_6328_UART0_IRQ (IRQ_INTERNAL_BASE + 28)
+#define BCM_6328_UART1_IRQ (BCM_6328_HIGH_IRQ_BASE + 7)
+#define BCM_6328_DSL_IRQ (IRQ_INTERNAL_BASE + 4)
+#define BCM_6328_UDC0_IRQ 0
+#define BCM_6328_ENET0_IRQ 0
+#define BCM_6328_ENET1_IRQ 0
+#define BCM_6328_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12)
+#define BCM_6328_OHCI0_IRQ (IRQ_INTERNAL_BASE + 9)
+#define BCM_6328_EHCI0_IRQ (IRQ_INTERNAL_BASE + 10)
+#define BCM_6328_PCMCIA_IRQ 0
+#define BCM_6328_ENET0_RXDMA_IRQ 0
+#define BCM_6328_ENET0_TXDMA_IRQ 0
+#define BCM_6328_ENET1_RXDMA_IRQ 0
+#define BCM_6328_ENET1_TXDMA_IRQ 0
+#define BCM_6328_PCI_IRQ (IRQ_INTERNAL_BASE + 23)
+#define BCM_6328_ATM_IRQ 0
+#define BCM_6328_ENETSW_RXDMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 0)
+#define BCM_6328_ENETSW_RXDMA1_IRQ (BCM_6328_HIGH_IRQ_BASE + 1)
+#define BCM_6328_ENETSW_RXDMA2_IRQ (BCM_6328_HIGH_IRQ_BASE + 2)
+#define BCM_6328_ENETSW_RXDMA3_IRQ (BCM_6328_HIGH_IRQ_BASE + 3)
+#define BCM_6328_ENETSW_TXDMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 4)
+#define BCM_6328_ENETSW_TXDMA1_IRQ (BCM_6328_HIGH_IRQ_BASE + 5)
+#define BCM_6328_ENETSW_TXDMA2_IRQ (BCM_6328_HIGH_IRQ_BASE + 6)
+#define BCM_6328_ENETSW_TXDMA3_IRQ (BCM_6328_HIGH_IRQ_BASE + 7)
+#define BCM_6328_XTM_IRQ (BCM_6328_HIGH_IRQ_BASE + 31)
+#define BCM_6328_XTM_DMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 11)
+
+#define BCM_6328_PCM_DMA0_IRQ (IRQ_INTERNAL_BASE + 2)
+#define BCM_6328_PCM_DMA1_IRQ (IRQ_INTERNAL_BASE + 3)
+#define BCM_6328_EXT_IRQ0 (IRQ_INTERNAL_BASE + 24)
+#define BCM_6328_EXT_IRQ1 (IRQ_INTERNAL_BASE + 25)
+#define BCM_6328_EXT_IRQ2 (IRQ_INTERNAL_BASE + 26)
+#define BCM_6328_EXT_IRQ3 (IRQ_INTERNAL_BASE + 27)
+
+/*
* 6338 irqs
*/
#define BCM_6338_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
@@ -8,6 +8,8 @@ int __init bcm63xx_gpio_init(void);
static inline unsigned long bcm63xx_gpio_count(void)
{
switch (bcm63xx_get_cpu_id()) {
+ case BCM6328_CPU_ID:
+ return 32;
case BCM6358_CPU_ID:
return 40;
case BCM6338_CPU_ID:
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
@@ -91,5 +91,7 @@
#define bcm_memc_writel(v, o) bcm_rset_writel(RSET_MEMC, (v), (o))
#define bcm_ddr_readl(o) bcm_rset_readl(RSET_DDR, (o))
#define bcm_ddr_writel(v, o) bcm_rset_writel(RSET_DDR, (v), (o))
+#define bcm_misc_readl(o) bcm_rset_readl(RSET_MISC, (o))
+#define bcm_misc_writel(v, o) bcm_rset_writel(RSET_MISC, (v), (o))
#endif /* ! BCM63XX_IO_H_ */
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -15,6 +15,30 @@
/* Clock Control register */
#define PERF_CKCTL_REG 0x4
+#define CKCTL_6328_PHYMIPS_EN (1 << 0)
+#define CKCTL_6328_ADSL_QPROC_EN (1 << 1)
+#define CKCTL_6328_ADSL_AFE_EN (1 << 2)
+#define CKCTL_6328_ADSL_EN (1 << 3)
+#define CKCTL_6328_MIPS_EN (1 << 4)
+#define CKCTL_6328_SAR_EN (1 << 5)
+#define CKCTL_6328_PCM_EN (1 << 6)
+#define CKCTL_6328_USBD_EN (1 << 7)
+#define CKCTL_6328_USBH_EN (1 << 8)
+#define CKCTL_6328_HSSPI_EN (1 << 9)
+#define CKCTL_6328_PCIE_EN (1 << 10)
+#define CKCTL_6328_ROBOSW_EN (1 << 11)
+
+#define CKCTL_6328_ALL_SAFE_EN (CKCTL_6328_PHYMIPS_EN | \
+ CKCTL_6328_ADSL_QPROC_EN | \
+ CKCTL_6328_ADSL_AFE_EN | \
+ CKCTL_6328_ADSL_EN | \
+ CKCTL_6328_SAR_EN | \
+ CKCTL_6328_PCM_EN | \
+ CKCTL_6328_USBD_EN | \
+ CKCTL_6328_USBH_EN | \
+ CKCTL_6328_ROBOSW_EN | \
+ CKCTL_6328_PCIE_EN)
+
#define CKCTL_6338_ADSLPHY_EN (1 << 0)
#define CKCTL_6338_MPI_EN (1 << 1)
#define CKCTL_6338_DRAM_EN (1 << 2)
@@ -119,6 +143,7 @@
#define SYS_PLL_SOFT_RESET 0x1
/* Interrupt Mask register */
+#define PERF_IRQMASK_6328_REG 0x20
#define PERF_IRQMASK_6338_REG 0xc
#define PERF_IRQMASK_6345_REG 0xc
#define PERF_IRQMASK_6348_REG 0xc
@@ -126,6 +151,7 @@
#define PERF_IRQMASK_6368_REG 0x20
/* Interrupt Status register */
+#define PERF_IRQSTAT_6328_REG 0x28
#define PERF_IRQSTAT_6338_REG 0x10
#define PERF_IRQSTAT_6345_REG 0x10
#define PERF_IRQSTAT_6348_REG 0x10
@@ -133,6 +159,7 @@
#define PERF_IRQSTAT_6368_REG 0x28
/* External Interrupt Configuration register */
+#define PERF_EXTIRQ_CFG_REG_6328 0x18
#define PERF_EXTIRQ_CFG_REG_6338 0x14
#define PERF_EXTIRQ_CFG_REG_6348 0x14
#define PERF_EXTIRQ_CFG_REG_6358 0x14
@@ -162,8 +189,21 @@
/* Soft Reset register */
#define PERF_SOFTRESET_REG 0x28
+#define PERF_SOFTRESET_6328_REG 0x10
#define PERF_SOFTRESET_6368_REG 0x10
+#define SOFTRESET_6328_SPI_MASK (1 << 0)
+#define SOFTRESET_6328_EPHY_MASK (1 << 1)
+#define SOFTRESET_6328_SAR_MASK (1 << 2)
+#define SOFTRESET_6328_ENETSW_MASK (1 << 3)
+#define SOFTRESET_6328_USBS_MASK (1 << 4)
+#define SOFTRESET_6328_USBH_MASK (1 << 5)
+#define SOFTRESET_6328_PCM_MASK (1 << 6)
+#define SOFTRESET_6328_PCIE_CORE_MASK (1 << 7)
+#define SOFTRESET_6328_PCIE_MASK (1 << 8)
+#define SOFTRESET_6328_PCIE_EXT_MASK (1 << 9)
+#define SOFTRESET_6328_PCIE_HARD_MASK (1 << 10)
+
#define SOFTRESET_6338_SPI_MASK (1 << 0)
#define SOFTRESET_6338_ENET_MASK (1 << 2)
#define SOFTRESET_6338_USBH_MASK (1 << 3)
@@ -307,6 +347,8 @@
/* Watchdog reset length register */
#define WDT_RSTLEN_REG 0x8
+/* Watchdog soft reset register (BCM6328 only) */
+#define WDT_SOFTRESET_REG 0xc
/*************************************************************************
* _REG relative to RSET_UARTx
@@ -933,6 +975,8 @@
* _REG relative to RSET_DDR
*************************************************************************/
+#define DDR_CSEND_REG 0x8
+
#define DDR_DMIPSPLLCFG_REG 0x18
#define DMIPSPLLCFG_M1_SHIFT 0
#define DMIPSPLLCFG_M1_MASK (0xff << DMIPSPLLCFG_M1_SHIFT)
@@ -1122,4 +1166,14 @@
#define SPI_SSOFFTIME_SHIFT 3
#define SPI_BYTE_SWAP 0x80
+/*************************************************************************
+ * _REG relative to RSET_MISC
+ *************************************************************************/
+
+#define MISC_STRAPBUS_6328_REG 0x240
+#define STRAPBUS_6328_FCVO_SHIFT 7
+#define STRAPBUS_6328_FCVO_MASK (0x1f << STRAPBUS_6328_FCVO_SHIFT)
+#define STRAPBUS_6328_BOOT_SEL_SERIAL (1 << 28)
+#define STRAPBUS_6328_BOOT_SEL_NAND (0 << 28)
+
#endif /* BCM63XX_REGS_H_ */
--- a/arch/mips/include/asm/mach-bcm63xx/ioremap.h
+++ b/arch/mips/include/asm/mach-bcm63xx/ioremap.h
@@ -18,6 +18,7 @@ static inline int is_bcm63xx_internal_re
if (offset >= 0xfff00000)
return 1;
break;
+ case BCM6328_CPU_ID:
case BCM6368_CPU_ID:
if (offset >= 0xb0000000 && offset < 0xb1000000)
return 1;

View file

@ -1,61 +0,0 @@
From b8420b9150fa03fcdfacd32e8c5ad286e208d5e9 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Wed, 13 Jun 2012 16:48:02 +0100
Subject: [PATCH 5/8] MIPS: BCM63XX: Move the PCI initialization into its own function
Also make the cpu check a bit more explicit.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: Maxime Bizon <mbizon@freebox.fr>
Cc: Florian Fainelli <florian@openwrt.org>
Cc: Kevin Cernekee <cernekee@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/3953/
Reviewed-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
---
arch/mips/pci/pci-bcm63xx.c | 25 +++++++++++++++++--------
1 files changed, 17 insertions(+), 8 deletions(-)
--- a/arch/mips/pci/pci-bcm63xx.c
+++ b/arch/mips/pci/pci-bcm63xx.c
@@ -94,17 +94,10 @@ static void bcm63xx_int_cfg_writel(u32 v
void __iomem *pci_iospace_start;
-static int __init bcm63xx_pci_init(void)
+static int __init bcm63xx_register_pci(void)
{
unsigned int mem_size;
u32 val;
-
- if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358() && !BCMCPU_IS_6368())
- return -ENODEV;
-
- if (!bcm63xx_pci_enabled)
- return -ENODEV;
-
/*
* configuration access are done through IO space, remap 4
* first bytes to access it from CPU.
@@ -221,4 +214,20 @@ static int __init bcm63xx_pci_init(void)
return 0;
}
+
+static int __init bcm63xx_pci_init(void)
+{
+ if (!bcm63xx_pci_enabled)
+ return -ENODEV;
+
+ switch (bcm63xx_get_cpu_id()) {
+ case BCM6348_CPU_ID:
+ case BCM6358_CPU_ID:
+ case BCM6368_CPU_ID:
+ return bcm63xx_register_pci();
+ default:
+ return -ENODEV;
+ }
+}
+
arch_initcall(bcm63xx_pci_init);

View file

@ -1,427 +0,0 @@
From 45655e79f84e35c13b8964b961d804e64b3aca91 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Wed, 13 Jun 2012 17:07:13 +0100
Subject: [PATCH 6/8] MIPS: BCM63XX: Add PCIe Support for BCM6328
Add support for the PCIe port found on BCM6328.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: Maxime Bizon <mbizon@freebox.fr>
Cc: Florian Fainelli <florian@openwrt.org>
Cc: Kevin Cernekee <cernekee@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/3956/
Reviewed-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
---
arch/mips/bcm63xx/Kconfig | 1 +
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 9 ++
arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h | 6 +
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 54 ++++++++++
arch/mips/pci/ops-bcm63xx.c | 61 +++++++++++
arch/mips/pci/pci-bcm63xx.c | 112 +++++++++++++++++++++
arch/mips/pci/pci-bcm63xx.h | 5 +
7 files changed, 248 insertions(+), 0 deletions(-)
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -3,6 +3,7 @@ menu "CPU support"
config BCM63XX_CPU_6328
bool "support 6328 CPU"
+ select HW_HAS_PCI
config BCM63XX_CPU_6338
bool "support 6338 CPU"
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -122,6 +122,7 @@ enum bcm63xx_regs_set {
RSET_USBH_PRIV,
RSET_MPI,
RSET_PCMCIA,
+ RSET_PCIE,
RSET_DSL,
RSET_ENET0,
RSET_ENET1,
@@ -188,6 +189,7 @@ enum bcm63xx_regs_set {
#define BCM_6328_USBH_PRIV_BASE (0xdeadbeef)
#define BCM_6328_MPI_BASE (0xdeadbeef)
#define BCM_6328_PCMCIA_BASE (0xdeadbeef)
+#define BCM_6328_PCIE_BASE (0xb0e40000)
#define BCM_6328_SDRAM_REGS_BASE (0xdeadbeef)
#define BCM_6328_DSL_BASE (0xb0001900)
#define BCM_6328_UBUS_BASE (0xdeadbeef)
@@ -232,6 +234,7 @@ enum bcm63xx_regs_set {
#define BCM_6338_USBH_PRIV_BASE (0xdeadbeef)
#define BCM_6338_MPI_BASE (0xfffe3160)
#define BCM_6338_PCMCIA_BASE (0xdeadbeef)
+#define BCM_6338_PCIE_BASE (0xdeadbeef)
#define BCM_6338_SDRAM_REGS_BASE (0xfffe3100)
#define BCM_6338_DSL_BASE (0xfffe1000)
#define BCM_6338_UBUS_BASE (0xdeadbeef)
@@ -279,6 +282,7 @@ enum bcm63xx_regs_set {
#define BCM_6345_ENETSW_BASE (0xdeadbeef)
#define BCM_6345_PCMCIA_BASE (0xfffe2028)
#define BCM_6345_MPI_BASE (0xfffe2000)
+#define BCM_6345_PCIE_BASE (0xdeadbeef)
#define BCM_6345_OHCI0_BASE (0xfffe2100)
#define BCM_6345_OHCI_PRIV_BASE (0xfffe2200)
#define BCM_6345_USBH_PRIV_BASE (0xdeadbeef)
@@ -320,6 +324,7 @@ enum bcm63xx_regs_set {
#define BCM_6348_USBH_PRIV_BASE (0xdeadbeef)
#define BCM_6348_MPI_BASE (0xfffe2000)
#define BCM_6348_PCMCIA_BASE (0xfffe2054)
+#define BCM_6348_PCIE_BASE (0xdeadbeef)
#define BCM_6348_SDRAM_REGS_BASE (0xfffe2300)
#define BCM_6348_M2M_BASE (0xfffe2800)
#define BCM_6348_DSL_BASE (0xfffe3000)
@@ -362,6 +367,7 @@ enum bcm63xx_regs_set {
#define BCM_6358_USBH_PRIV_BASE (0xfffe1500)
#define BCM_6358_MPI_BASE (0xfffe1000)
#define BCM_6358_PCMCIA_BASE (0xfffe1054)
+#define BCM_6358_PCIE_BASE (0xdeadbeef)
#define BCM_6358_SDRAM_REGS_BASE (0xfffe2300)
#define BCM_6358_M2M_BASE (0xdeadbeef)
#define BCM_6358_DSL_BASE (0xfffe3000)
@@ -405,6 +411,7 @@ enum bcm63xx_regs_set {
#define BCM_6368_USBH_PRIV_BASE (0xb0001700)
#define BCM_6368_MPI_BASE (0xb0001000)
#define BCM_6368_PCMCIA_BASE (0xb0001054)
+#define BCM_6368_PCIE_BASE (0xdeadbeef)
#define BCM_6368_SDRAM_REGS_BASE (0xdeadbeef)
#define BCM_6368_M2M_BASE (0xdeadbeef)
#define BCM_6368_DSL_BASE (0xdeadbeef)
@@ -453,6 +460,7 @@ extern const unsigned long *bcm63xx_regs
__GEN_RSET_BASE(__cpu, USBH_PRIV) \
__GEN_RSET_BASE(__cpu, MPI) \
__GEN_RSET_BASE(__cpu, PCMCIA) \
+ __GEN_RSET_BASE(__cpu, PCIE) \
__GEN_RSET_BASE(__cpu, DSL) \
__GEN_RSET_BASE(__cpu, ENET0) \
__GEN_RSET_BASE(__cpu, ENET1) \
@@ -493,6 +501,7 @@ extern const unsigned long *bcm63xx_regs
[RSET_USBH_PRIV] = BCM_## __cpu ##_USBH_PRIV_BASE, \
[RSET_MPI] = BCM_## __cpu ##_MPI_BASE, \
[RSET_PCMCIA] = BCM_## __cpu ##_PCMCIA_BASE, \
+ [RSET_PCIE] = BCM_## __cpu ##_PCIE_BASE, \
[RSET_DSL] = BCM_## __cpu ##_DSL_BASE, \
[RSET_ENET0] = BCM_## __cpu ##_ENET0_BASE, \
[RSET_ENET1] = BCM_## __cpu ##_ENET1_BASE, \
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
@@ -40,6 +40,10 @@
#define BCM_CB_MEM_END_PA (BCM_CB_MEM_BASE_PA + \
BCM_CB_MEM_SIZE - 1)
+#define BCM_PCIE_MEM_BASE_PA 0x10f00000
+#define BCM_PCIE_MEM_SIZE (16 * 1024 * 1024)
+#define BCM_PCIE_MEM_END_PA (BCM_PCIE_MEM_BASE_PA + \
+ BCM_PCIE_MEM_SIZE - 1)
/*
* Internal registers are accessed through KSEG3
@@ -85,6 +89,8 @@
#define bcm_mpi_writel(v, o) bcm_rset_writel(RSET_MPI, (v), (o))
#define bcm_pcmcia_readl(o) bcm_rset_readl(RSET_PCMCIA, (o))
#define bcm_pcmcia_writel(v, o) bcm_rset_writel(RSET_PCMCIA, (v), (o))
+#define bcm_pcie_readl(o) bcm_rset_readl(RSET_PCIE, (o))
+#define bcm_pcie_writel(v, o) bcm_rset_writel(RSET_PCIE, (v), (o))
#define bcm_sdram_readl(o) bcm_rset_readl(RSET_SDRAM, (o))
#define bcm_sdram_writel(v, o) bcm_rset_writel(RSET_SDRAM, (v), (o))
#define bcm_memc_readl(o) bcm_rset_readl(RSET_MEMC, (o))
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -1169,6 +1169,9 @@
/*************************************************************************
* _REG relative to RSET_MISC
*************************************************************************/
+#define MISC_SERDES_CTRL_REG 0x0
+#define SERDES_PCIE_EN (1 << 0)
+#define SERDES_PCIE_EXD_EN (1 << 15)
#define MISC_STRAPBUS_6328_REG 0x240
#define STRAPBUS_6328_FCVO_SHIFT 7
@@ -1176,4 +1179,55 @@
#define STRAPBUS_6328_BOOT_SEL_SERIAL (1 << 28)
#define STRAPBUS_6328_BOOT_SEL_NAND (0 << 28)
+/*************************************************************************
+ * _REG relative to RSET_PCIE
+ *************************************************************************/
+
+#define PCIE_CONFIG2_REG 0x408
+#define CONFIG2_BAR1_SIZE_EN 1
+#define CONFIG2_BAR1_SIZE_MASK 0xf
+
+#define PCIE_IDVAL3_REG 0x43c
+#define IDVAL3_CLASS_CODE_MASK 0xffffff
+#define IDVAL3_SUBCLASS_SHIFT 8
+#define IDVAL3_CLASS_SHIFT 16
+
+#define PCIE_DLSTATUS_REG 0x1048
+#define DLSTATUS_PHYLINKUP (1 << 13)
+
+#define PCIE_BRIDGE_OPT1_REG 0x2820
+#define OPT1_RD_BE_OPT_EN (1 << 7)
+#define OPT1_RD_REPLY_BE_FIX_EN (1 << 9)
+#define OPT1_PCIE_BRIDGE_HOLE_DET_EN (1 << 11)
+#define OPT1_L1_INT_STATUS_MASK_POL (1 << 12)
+
+#define PCIE_BRIDGE_OPT2_REG 0x2824
+#define OPT2_UBUS_UR_DECODE_DIS (1 << 2)
+#define OPT2_TX_CREDIT_CHK_EN (1 << 4)
+#define OPT2_CFG_TYPE1_BD_SEL (1 << 7)
+#define OPT2_CFG_TYPE1_BUS_NO_SHIFT 16
+#define OPT2_CFG_TYPE1_BUS_NO_MASK (0xff << OPT2_CFG_TYPE1_BUS_NO_SHIFT)
+
+#define PCIE_BRIDGE_BAR0_BASEMASK_REG 0x2828
+#define PCIE_BRIDGE_BAR1_BASEMASK_REG 0x2830
+#define BASEMASK_REMAP_EN (1 << 0)
+#define BASEMASK_SWAP_EN (1 << 1)
+#define BASEMASK_MASK_SHIFT 4
+#define BASEMASK_MASK_MASK (0xfff << BASEMASK_MASK_SHIFT)
+#define BASEMASK_BASE_SHIFT 20
+#define BASEMASK_BASE_MASK (0xfff << BASEMASK_BASE_SHIFT)
+
+#define PCIE_BRIDGE_BAR0_REBASE_ADDR_REG 0x282c
+#define PCIE_BRIDGE_BAR1_REBASE_ADDR_REG 0x2834
+#define REBASE_ADDR_BASE_SHIFT 20
+#define REBASE_ADDR_BASE_MASK (0xfff << REBASE_ADDR_BASE_SHIFT)
+
+#define PCIE_BRIDGE_RC_INT_MASK_REG 0x2854
+#define PCIE_RC_INT_A (1 << 0)
+#define PCIE_RC_INT_B (1 << 1)
+#define PCIE_RC_INT_C (1 << 2)
+#define PCIE_RC_INT_D (1 << 3)
+
+#define PCIE_DEVICE_OFFSET 0x8000
+
#endif /* BCM63XX_REGS_H_ */
--- a/arch/mips/pci/ops-bcm63xx.c
+++ b/arch/mips/pci/ops-bcm63xx.c
@@ -465,3 +465,64 @@ static void bcm63xx_fixup(struct pci_dev
DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm63xx_fixup);
#endif
+
+static int bcm63xx_pcie_can_access(struct pci_bus *bus, int devfn)
+{
+ switch (bus->number) {
+ case PCIE_BUS_BRIDGE:
+ return (PCI_SLOT(devfn) == 0);
+ case PCIE_BUS_DEVICE:
+ if (PCI_SLOT(devfn) == 0)
+ return bcm_pcie_readl(PCIE_DLSTATUS_REG)
+ & DLSTATUS_PHYLINKUP;
+ default:
+ return false;
+ }
+}
+
+static int bcm63xx_pcie_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ u32 data;
+ u32 reg = where & ~3;
+
+ if (!bcm63xx_pcie_can_access(bus, devfn))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if (bus->number == PCIE_BUS_DEVICE)
+ reg += PCIE_DEVICE_OFFSET;
+
+ data = bcm_pcie_readl(reg);
+
+ *val = postprocess_read(data, where, size);
+
+ return PCIBIOS_SUCCESSFUL;
+
+}
+
+static int bcm63xx_pcie_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 data;
+ u32 reg = where & ~3;
+
+ if (!bcm63xx_pcie_can_access(bus, devfn))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if (bus->number == PCIE_BUS_DEVICE)
+ reg += PCIE_DEVICE_OFFSET;
+
+
+ data = bcm_pcie_readl(reg);
+
+ data = preprocess_write(data, val, where, size);
+ bcm_pcie_writel(data, reg);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+struct pci_ops bcm63xx_pcie_ops = {
+ .read = bcm63xx_pcie_read,
+ .write = bcm63xx_pcie_write
+};
--- a/arch/mips/pci/pci-bcm63xx.c
+++ b/arch/mips/pci/pci-bcm63xx.c
@@ -10,6 +10,7 @@
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/delay.h>
#include <asm/bootinfo.h>
#include "pci-bcm63xx.h"
@@ -71,6 +72,26 @@ struct pci_controller bcm63xx_cb_control
};
#endif
+static struct resource bcm_pcie_mem_resource = {
+ .name = "bcm63xx PCIe memory space",
+ .start = BCM_PCIE_MEM_BASE_PA,
+ .end = BCM_PCIE_MEM_END_PA,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource bcm_pcie_io_resource = {
+ .name = "bcm63xx PCIe IO space",
+ .start = 0,
+ .end = 0,
+ .flags = 0,
+};
+
+struct pci_controller bcm63xx_pcie_controller = {
+ .pci_ops = &bcm63xx_pcie_ops,
+ .io_resource = &bcm_pcie_io_resource,
+ .mem_resource = &bcm_pcie_mem_resource,
+};
+
static u32 bcm63xx_int_cfg_readl(u32 reg)
{
u32 tmp;
@@ -94,6 +115,95 @@ static void bcm63xx_int_cfg_writel(u32 v
void __iomem *pci_iospace_start;
+static void __init bcm63xx_reset_pcie(void)
+{
+ u32 val;
+
+ /* enable clock */
+ val = bcm_perf_readl(PERF_CKCTL_REG);
+ val |= CKCTL_6328_PCIE_EN;
+ bcm_perf_writel(val, PERF_CKCTL_REG);
+
+ /* enable SERDES */
+ val = bcm_misc_readl(MISC_SERDES_CTRL_REG);
+ val |= SERDES_PCIE_EN | SERDES_PCIE_EXD_EN;
+ bcm_misc_writel(val, MISC_SERDES_CTRL_REG);
+
+ /* reset the PCIe core */
+ val = bcm_perf_readl(PERF_SOFTRESET_6328_REG);
+
+ val &= ~SOFTRESET_6328_PCIE_MASK;
+ val &= ~SOFTRESET_6328_PCIE_CORE_MASK;
+ val &= ~SOFTRESET_6328_PCIE_HARD_MASK;
+ val &= ~SOFTRESET_6328_PCIE_EXT_MASK;
+ bcm_perf_writel(val, PERF_SOFTRESET_6328_REG);
+ mdelay(10);
+
+ val |= SOFTRESET_6328_PCIE_MASK;
+ val |= SOFTRESET_6328_PCIE_CORE_MASK;
+ val |= SOFTRESET_6328_PCIE_HARD_MASK;
+ bcm_perf_writel(val, PERF_SOFTRESET_6328_REG);
+ mdelay(10);
+
+ val |= SOFTRESET_6328_PCIE_EXT_MASK;
+ bcm_perf_writel(val, PERF_SOFTRESET_6328_REG);
+ mdelay(200);
+}
+
+static int __init bcm63xx_register_pcie(void)
+{
+ u32 val;
+
+ bcm63xx_reset_pcie();
+
+ /* configure the PCIe bridge */
+ val = bcm_pcie_readl(PCIE_BRIDGE_OPT1_REG);
+ val |= OPT1_RD_BE_OPT_EN;
+ val |= OPT1_RD_REPLY_BE_FIX_EN;
+ val |= OPT1_PCIE_BRIDGE_HOLE_DET_EN;
+ val |= OPT1_L1_INT_STATUS_MASK_POL;
+ bcm_pcie_writel(val, PCIE_BRIDGE_OPT1_REG);
+
+ /* setup the interrupts */
+ val = bcm_pcie_readl(PCIE_BRIDGE_RC_INT_MASK_REG);
+ val |= PCIE_RC_INT_A | PCIE_RC_INT_B | PCIE_RC_INT_C | PCIE_RC_INT_D;
+ bcm_pcie_writel(val, PCIE_BRIDGE_RC_INT_MASK_REG);
+
+ val = bcm_pcie_readl(PCIE_BRIDGE_OPT2_REG);
+ /* enable credit checking and error checking */
+ val |= OPT2_TX_CREDIT_CHK_EN;
+ val |= OPT2_UBUS_UR_DECODE_DIS;
+
+ /* set device bus/func for the pcie device */
+ val |= (PCIE_BUS_DEVICE << OPT2_CFG_TYPE1_BUS_NO_SHIFT);
+ val |= OPT2_CFG_TYPE1_BD_SEL;
+ bcm_pcie_writel(val, PCIE_BRIDGE_OPT2_REG);
+
+ /* setup class code as bridge */
+ val = bcm_pcie_readl(PCIE_IDVAL3_REG);
+ val &= ~IDVAL3_CLASS_CODE_MASK;
+ val |= (PCI_CLASS_BRIDGE_PCI << IDVAL3_SUBCLASS_SHIFT);
+ bcm_pcie_writel(val, PCIE_IDVAL3_REG);
+
+ /* disable bar1 size */
+ val = bcm_pcie_readl(PCIE_CONFIG2_REG);
+ val &= ~CONFIG2_BAR1_SIZE_MASK;
+ bcm_pcie_writel(val, PCIE_CONFIG2_REG);
+
+ /* set bar0 to little endian */
+ val = (BCM_PCIE_MEM_BASE_PA >> 20) << BASEMASK_BASE_SHIFT;
+ val |= (BCM_PCIE_MEM_BASE_PA >> 20) << BASEMASK_MASK_SHIFT;
+ val |= BASEMASK_REMAP_EN;
+ bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_BASEMASK_REG);
+
+ val = (BCM_PCIE_MEM_BASE_PA >> 20) << REBASE_ADDR_BASE_SHIFT;
+ bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_REBASE_ADDR_REG);
+
+ register_pci_controller(&bcm63xx_pcie_controller);
+
+ return 0;
+}
+
static int __init bcm63xx_register_pci(void)
{
unsigned int mem_size;
@@ -221,6 +331,8 @@ static int __init bcm63xx_pci_init(void)
return -ENODEV;
switch (bcm63xx_get_cpu_id()) {
+ case BCM6328_CPU_ID:
+ return bcm63xx_register_pcie();
case BCM6348_CPU_ID:
case BCM6358_CPU_ID:
case BCM6368_CPU_ID:
--- a/arch/mips/pci/pci-bcm63xx.h
+++ b/arch/mips/pci/pci-bcm63xx.h
@@ -13,11 +13,16 @@
*/
#define CARDBUS_PCI_IDSEL 0x8
+
+#define PCIE_BUS_BRIDGE 0
+#define PCIE_BUS_DEVICE 1
+
/*
* defined in ops-bcm63xx.c
*/
extern struct pci_ops bcm63xx_pci_ops;
extern struct pci_ops bcm63xx_cb_ops;
+extern struct pci_ops bcm63xx_pcie_ops;
/*
* defined in pci-bcm63xx.c

View file

@ -1,28 +0,0 @@
From 4831929b8c37aa866afca1498001c939377e5a67 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Wed, 13 Jun 2012 17:07:16 +0100
Subject: [PATCH 7/8] MIPS: Expose PCIe drivers for MIPS
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: Maxime Bizon <mbizon@freebox.fr>
Cc: Florian Fainelli <florian@openwrt.org>
Cc: Kevin Cernekee <cernekee@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/3957/
Reviewed-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
---
arch/mips/Kconfig | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2392,6 +2392,8 @@ config PCI_DOMAINS
source "drivers/pci/Kconfig"
+source "drivers/pci/pcie/Kconfig"
+
#
# ISA support is now enabled via select. Too many systems still have the one
# or other ISA chip on the board that users don't know about so don't expect

View file

@ -1,34 +0,0 @@
[PATCH] MIPS: BCM63XX: fix BCM6345 clock bits shifting
BCM6345 has an intermediate 16-bits wide test control register between the
peripheral identifier function, and its clock control register is only 16-bits
wide contrary to other platforms where it is 32-bits wide. By shifting all
clocks bits by 16-bits to the left we ensure they get written to the proper
clock control register, without adding specific BCM6345 handling in the clock
code.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -53,13 +53,13 @@
CKCTL_6338_SAR_EN | \
CKCTL_6338_SPI_EN)
-#define CKCTL_6345_CPU_EN (1 << 0)
-#define CKCTL_6345_BUS_EN (1 << 1)
-#define CKCTL_6345_EBI_EN (1 << 2)
-#define CKCTL_6345_UART_EN (1 << 3)
-#define CKCTL_6345_ADSLPHY_EN (1 << 4)
-#define CKCTL_6345_ENET_EN (1 << 7)
-#define CKCTL_6345_USBH_EN (1 << 8)
+#define CKCTL_6345_CPU_EN (1 << 16)
+#define CKCTL_6345_BUS_EN (1 << 17)
+#define CKCTL_6345_EBI_EN (1 << 18)
+#define CKCTL_6345_UART_EN (1 << 19)
+#define CKCTL_6345_ADSLPHY_EN (1 << 20)
+#define CKCTL_6345_ENET_EN (1 << 23)
+#define CKCTL_6345_USBH_EN (1 << 24)
#define CKCTL_6345_ALL_SAFE_EN (CKCTL_6345_ENET_EN | \
CKCTL_6345_USBH_EN | \

View file

@ -1,41 +0,0 @@
From a183d93bf0c6f9219ef1dd6e4948edf81c57ea3b Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Thu, 2 Feb 2012 09:27:58 +0100
Subject: [PATCH] MIPS: BCM63XX: add missing include for bcm63xx_gpio.h
bcm63xx_gpio.h uses macros defined in bcm63xx_cpu.h without including it,
leading to the following build failure:
CC [M] drivers/mmc/core/cd-gpio.o
In file included from arch/mips/include/asm/mach-bcm63xx/gpio.h:4:0,
from arch/mips/include/asm/gpio.h:4,
from include/linux/gpio.h:30,
from drivers/mmc/core/cd-gpio.c:12:
arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h: In function 'bcm63xx_gpio_count':
arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h:10:2: error: implicit declaration of function 'bcm63xx_get_cpu_id'
arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h:11:7: error: 'BCM6358_CPU_ID' undeclared (first use in this function)
arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h:11:7: note: each undeclared identifier is reported only once for each function it appears in
arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h:13:7: error: 'BCM6338_CPU_ID' undeclared (first use in this function)
arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h:15:7: error: 'BCM6345_CPU_ID' undeclared (first use in this function)
arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h:17:7: error: 'BCM6368_CPU_ID' undeclared (first use in this function)
arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h:19:7: error: 'BCM6348_CPU_ID' undeclared (first use in this function)
make[7]: *** [drivers/mmc/core/cd-gpio.o] Error 1
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
@@ -2,6 +2,7 @@
#define BCM63XX_GPIO_H
#include <linux/init.h>
+#include <bcm63xx_cpu.h>
int __init bcm63xx_gpio_init(void);

View file

@ -1,41 +0,0 @@
From 2962bbe9cc807549c0705551c5b7be47e34e3fac Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Mon, 30 Apr 2012 09:32:56 +0200
Subject: [PATCH 20/79] MTD: bcm63xxpart: remove unused variable
namelen is never used, so drop it.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
drivers/mtd/bcm63xxpart.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
--- a/drivers/mtd/bcm63xxpart.c
+++ b/drivers/mtd/bcm63xxpart.c
@@ -79,7 +79,6 @@ static int bcm63xx_parse_cfe_partitions(
unsigned int rootfsaddr, kerneladdr, spareaddr;
unsigned int rootfslen, kernellen, sparelen, totallen;
unsigned int cfelen, nvramlen;
- int namelen = 0;
int i;
u32 computed_crc;
bool rootfs_first = false;
@@ -143,15 +142,11 @@ static int bcm63xx_parse_cfe_partitions(
}
/* Determine number of partitions */
- namelen = 8;
- if (rootfslen > 0) {
+ if (rootfslen > 0)
nrparts++;
- namelen += 6;
- }
- if (kernellen > 0) {
+
+ if (kernellen > 0)
nrparts++;
- namelen += 6;
- }
/* Ask kernel for more memory */
parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);

View file

@ -1,33 +0,0 @@
From fd2ab39f22af4176eb3d23acbc4d1218cf835065 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Tue, 8 May 2012 09:47:32 +0200
Subject: [PATCH 21/79] MTD: bcm63xxpart: merge sparelen calculation
The length of the spare part is calculated the same way in both branches
so move to a common place.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
drivers/mtd/bcm63xxpart.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/mtd/bcm63xxpart.c
+++ b/drivers/mtd/bcm63xxpart.c
@@ -120,7 +120,6 @@ static int bcm63xx_parse_cfe_partitions(
kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE;
rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE;
spareaddr = roundup(totallen, master->erasesize) + cfelen;
- sparelen = master->size - spareaddr - nvramlen;
if (rootfsaddr < kerneladdr) {
/* default Broadcom layout */
@@ -138,8 +137,8 @@ static int bcm63xx_parse_cfe_partitions(
rootfslen = 0;
rootfsaddr = 0;
spareaddr = cfelen;
- sparelen = master->size - cfelen - nvramlen;
}
+ sparelen = master->size - spareaddr - nvramlen;
/* Determine number of partitions */
if (rootfslen > 0)

View file

@ -1,49 +0,0 @@
From 465f1b3ff24dbf3bec43dce344a7bc2640e05ffc Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Tue, 8 May 2012 09:53:07 +0200
Subject: [PATCH 22/79] MTD: bcm63xxpart: make fixed part length calculation
more generic
The CFE does not use 4K sectors even if the flash supports it, so
for the fixed partitions like CFE itself or NVRAM the erase block
size is always 64k or bigger.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
drivers/mtd/bcm63xxpart.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
--- a/drivers/mtd/bcm63xxpart.c
+++ b/drivers/mtd/bcm63xxpart.c
@@ -37,8 +37,7 @@
#define BCM63XX_EXTENDED_SIZE 0xBFC00000 /* Extended flash address */
-#define BCM63XX_MIN_CFE_SIZE 0x10000 /* always at least 64KiB */
-#define BCM63XX_MIN_NVRAM_SIZE 0x10000 /* always at least 64KiB */
+#define BCM63XX_CFE_BLOCK_SIZE 0x10000 /* always at least 64KiB */
#define BCM63XX_CFE_MAGIC_OFFSET 0x4e0
@@ -79,6 +78,7 @@ static int bcm63xx_parse_cfe_partitions(
unsigned int rootfsaddr, kerneladdr, spareaddr;
unsigned int rootfslen, kernellen, sparelen, totallen;
unsigned int cfelen, nvramlen;
+ unsigned int cfe_erasesize;
int i;
u32 computed_crc;
bool rootfs_first = false;
@@ -86,8 +86,11 @@ static int bcm63xx_parse_cfe_partitions(
if (bcm63xx_detect_cfe(master))
return -EINVAL;
- cfelen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_CFE_SIZE);
- nvramlen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_NVRAM_SIZE);
+ cfe_erasesize = max_t(uint32_t, master->erasesize,
+ BCM63XX_CFE_BLOCK_SIZE);
+
+ cfelen = cfe_erasesize;
+ nvramlen = cfe_erasesize;
/* Allocate memory for buffer */
buf = vmalloc(sizeof(struct bcm_tag));

View file

@ -1,26 +0,0 @@
From d5173b2c806f4039679b001f1b55a3c245afdf68 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Tue, 8 May 2012 10:02:13 +0200
Subject: [PATCH 23/79] MTD: bcm63xxpart: move the last curpart++ to its
correct place
The line belongs above the comment, not below it.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
drivers/mtd/bcm63xxpart.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/mtd/bcm63xxpart.c
+++ b/drivers/mtd/bcm63xxpart.c
@@ -190,9 +190,9 @@ static int bcm63xx_parse_cfe_partitions(
parts[curpart].name = "nvram";
parts[curpart].offset = master->size - nvramlen;
parts[curpart].size = nvramlen;
+ curpart++;
/* Global partition "linux" to make easy firmware upgrade */
- curpart++;
parts[curpart].name = "linux";
parts[curpart].offset = cfelen;
parts[curpart].size = master->size - cfelen - nvramlen;

View file

@ -1,27 +0,0 @@
From 55aa355612ce55dc1943f116ea49e795a098b60c Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Tue, 8 May 2012 10:03:27 +0200
Subject: [PATCH 24/79] MTD: bcm63xxpart: use correct printk format for
partitions
Use ll to be able to remove the casts.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
drivers/mtd/bcm63xxpart.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
--- a/drivers/mtd/bcm63xxpart.c
+++ b/drivers/mtd/bcm63xxpart.c
@@ -198,9 +198,8 @@ static int bcm63xx_parse_cfe_partitions(
parts[curpart].size = master->size - cfelen - nvramlen;
for (i = 0; i < nrparts; i++)
- pr_info("Partition %d is %s offset %lx and length %lx\n", i,
- parts[i].name, (long unsigned int)(parts[i].offset),
- (long unsigned int)(parts[i].size));
+ pr_info("Partition %d is %s offset %llx and length %llx\n", i,
+ parts[i].name, parts[i].offset, parts[i].size);
pr_info("Spare partition is offset %x and length %x\n", spareaddr,
sparelen);

View file

@ -1,20 +0,0 @@
--- a/drivers/watchdog/bcm63xx_wdt.c
+++ b/drivers/watchdog/bcm63xx_wdt.c
@@ -301,7 +301,7 @@ static void bcm63xx_wdt_shutdown(struct
bcm63xx_wdt_pause();
}
-static struct platform_driver bcm63xx_wdt = {
+static struct platform_driver bcm63xx_wdt_driver = {
.probe = bcm63xx_wdt_probe,
.remove = __devexit_p(bcm63xx_wdt_remove),
.shutdown = bcm63xx_wdt_shutdown,
@@ -311,7 +311,7 @@ static struct platform_driver bcm63xx_wd
}
};
-module_platform_driver(bcm63xx_wdt);
+module_platform_driver(bcm63xx_wdt_driver);
MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>");
MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");

View file

@ -1,26 +0,0 @@
From 960e1ef3c5b2d69a4a5a6984b6408d65221dd86c Mon Sep 17 00:00:00 2001
From: Kevin Cernekee <cernekee@gmail.com>
Date: Sat, 23 Jun 2012 04:14:55 +0000
Subject: [PATCH 06/81] MIPS: BCM63XX: Fix USB IRQ definitions for 6328
OHCI/EHCI are in the high (second) word. Not currently used by any
driver.
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -602,8 +602,8 @@ enum bcm63xx_irq {
#define BCM_6328_ENET0_IRQ 0
#define BCM_6328_ENET1_IRQ 0
#define BCM_6328_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12)
-#define BCM_6328_OHCI0_IRQ (IRQ_INTERNAL_BASE + 9)
-#define BCM_6328_EHCI0_IRQ (IRQ_INTERNAL_BASE + 10)
+#define BCM_6328_OHCI0_IRQ (BCM_6328_HIGH_IRQ_BASE + 9)
+#define BCM_6328_EHCI0_IRQ (BCM_6328_HIGH_IRQ_BASE + 10)
#define BCM_6328_PCMCIA_IRQ 0
#define BCM_6328_ENET0_RXDMA_IRQ 0
#define BCM_6328_ENET0_TXDMA_IRQ 0

View file

@ -1,62 +0,0 @@
From 21bb8141c205ae48d331787debb6b272add90ac7 Mon Sep 17 00:00:00 2001
From: Kevin Cernekee <cernekee@gmail.com>
Date: Sat, 23 Jun 2012 04:14:54 +0000
Subject: [PATCH 05/81] MIPS: BCM63XX: Add register definitions for USBD
dependencies
The USB 2.0 device depends on some functionality in other blocks, such
as GPIO and USBH. Add those register definitions here.
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 6 +++---
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 8 ++++++++
2 files changed, 11 insertions(+), 3 deletions(-)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -184,9 +184,9 @@ enum bcm63xx_regs_set {
#define BCM_6328_SPI_BASE (0xdeadbeef)
#define BCM_6328_UDC0_BASE (0xdeadbeef)
#define BCM_6328_USBDMA_BASE (0xdeadbeef)
-#define BCM_6328_OHCI0_BASE (0xdeadbeef)
+#define BCM_6328_OHCI0_BASE (0xb0002600)
#define BCM_6328_OHCI_PRIV_BASE (0xdeadbeef)
-#define BCM_6328_USBH_PRIV_BASE (0xdeadbeef)
+#define BCM_6328_USBH_PRIV_BASE (0xb0002700)
#define BCM_6328_MPI_BASE (0xdeadbeef)
#define BCM_6328_PCMCIA_BASE (0xdeadbeef)
#define BCM_6328_PCIE_BASE (0xb0e40000)
@@ -199,7 +199,7 @@ enum bcm63xx_regs_set {
#define BCM_6328_ENETDMAC_BASE (0xb000da00)
#define BCM_6328_ENETDMAS_BASE (0xb000dc00)
#define BCM_6328_ENETSW_BASE (0xb0e00000)
-#define BCM_6328_EHCI0_BASE (0x10002500)
+#define BCM_6328_EHCI0_BASE (0xb0002500)
#define BCM_6328_SDRAM_BASE (0xdeadbeef)
#define BCM_6328_MEMC_BASE (0xdeadbeef)
#define BCM_6328_DDR_BASE (0xb0003000)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -543,6 +543,12 @@
#define GPIO_MODE_6368_SPI_SSN5 (1 << 31)
+#define GPIO_PINMUX_OTHR_REG 0x24
+#define GPIO_PINMUX_OTHR_6328_USB_SHIFT 12
+#define GPIO_PINMUX_OTHR_6328_USB_MASK (3 << GPIO_PINMUX_OTHR_6328_USB_SHIFT)
+#define GPIO_PINMUX_OTHR_6328_USB_HOST (1 << GPIO_PINMUX_OTHR_6328_USB_SHIFT)
+#define GPIO_PINMUX_OTHR_6328_USB_DEV (2 << GPIO_PINMUX_OTHR_6328_USB_SHIFT)
+
#define GPIO_BASEMODE_6368_REG 0x38
#define GPIO_BASEMODE_6368_UART2 0x1
#define GPIO_BASEMODE_6368_GPIO 0x0
@@ -770,6 +776,8 @@
#define USBH_PRIV_SWAP_6358_REG 0x0
#define USBH_PRIV_SWAP_6368_REG 0x1c
+#define USBH_PRIV_SWAP_USBD_SHIFT 6
+#define USBH_PRIV_SWAP_USBD_MASK (1 << USBH_PRIV_SWAP_USBD_SHIFT)
#define USBH_PRIV_SWAP_EHCI_ENDN_SHIFT 4
#define USBH_PRIV_SWAP_EHCI_ENDN_MASK (1 << USBH_PRIV_SWAP_EHCI_ENDN_SHIFT)
#define USBH_PRIV_SWAP_EHCI_DATA_SHIFT 3

View file

@ -1,29 +0,0 @@
From fbef4dff80be6254e36ab5b9c655d248a3991ded Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Sat, 24 Nov 2012 12:08:22 +0100
Subject: [PATCH 3.7] spi/bcm63xx: fix transfer bits_per_words check
Transfers often do not have bits_per_words set, so use the spi device's
bits_per_words in this case.
This fixes the driver rejecting valid transfers e.g. generated by
spi_write() or spi_read().
Cc: stable@vger.kernel.org
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
drivers/spi/spi-bcm63xx.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -103,7 +103,8 @@ static int bcm63xx_spi_check_transfer(st
{
u8 bits_per_word;
- bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word;
+ bits_per_word = (t && t->bits_per_word) ?
+ t->bits_per_word : spi->bits_per_word;
if (bits_per_word != 8) {
dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
__func__, bits_per_word);

View file

@ -1,279 +0,0 @@
From 0f2ae1e1282ff64f74a5e36f7da874f94911225e Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Wed, 14 Nov 2012 22:22:33 +0100
Subject: [PATCH] spi/bcm63xx: fix multi transfer messages
The BCM63XX SPI controller does not support keeping CS asserted after
sending its buffer. This breaks common usages like spi_write_then_read,
where it is expected to be kept active during the whole transfers.
Work around this by combining the transfers into one if the buffer
allows. For spi_write_then_read, use the prepend byte feature to write
to "prepend" the write if it is less than 15 bytes, allowing the whole
fifo size for the read.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
Tested on a SPI conntected switch which required keeping CS active between
the register read command and reading the register contents.
Based on Mark's spi/next.
Not sure if this is stable material, as it's quite invasive.
drivers/spi/spi-bcm63xx.c | 172 ++++++++++++++++++++++++++++++---------------
1 file changed, 117 insertions(+), 55 deletions(-)
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -38,6 +38,8 @@
#define PFX KBUILD_MODNAME
#define DRV_VER "0.1.2"
+#define BCM63XX_SPI_MAX_PREPEND 15
+
struct bcm63xx_spi {
struct completion done;
@@ -50,16 +52,10 @@ struct bcm63xx_spi {
unsigned int msg_type_shift;
unsigned int msg_ctl_width;
- /* Data buffers */
- const unsigned char *tx_ptr;
- unsigned char *rx_ptr;
-
/* data iomem */
u8 __iomem *tx_io;
const u8 __iomem *rx_io;
- int remaining_bytes;
-
struct clk *clk;
struct platform_device *pdev;
};
@@ -184,50 +180,60 @@ static int bcm63xx_spi_setup(struct spi_
return 0;
}
-/* Fill the TX FIFO with as many bytes as possible */
-static void bcm63xx_spi_fill_tx_fifo(struct bcm63xx_spi *bs)
-{
- u8 size;
-
- /* Fill the Tx FIFO with as many bytes as possible */
- size = bs->remaining_bytes < bs->fifo_size ? bs->remaining_bytes :
- bs->fifo_size;
- memcpy_toio(bs->tx_io, bs->tx_ptr, size);
- bs->remaining_bytes -= size;
-}
-
static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi,
- struct spi_transfer *t)
+ struct spi_transfer *first,
+ unsigned int n_transfers)
{
struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
u16 msg_ctl;
u16 cmd;
+ unsigned int i, timeout, total_len = 0, prepend_len = 0, len = 0;
+ struct spi_transfer *t = first;
+ u8 rx_tail;
+ bool do_rx = false;
+ bool do_tx = false;
/* Disable the CMD_DONE interrupt */
bcm_spi_writeb(bs, 0, SPI_INT_MASK);
- dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
- t->tx_buf, t->rx_buf, t->len);
+ if (n_transfers > 1 && t->tx_buf && t->len <= BCM63XX_SPI_MAX_PREPEND)
+ prepend_len = t->len;
+
+ /* prepare the buffer */
+ for (i = 0; i < n_transfers; i++) {
+ if (t->tx_buf) {
+ do_tx = true;
+ memcpy_toio(bs->tx_io + total_len, t->tx_buf, t->len);
+
+ /* don't prepend more than one tx */
+ if (t != first)
+ prepend_len = 0;
+ }
+
+ if (t->rx_buf) {
+ do_rx = true;
+ if (t == first)
+ prepend_len = 0;
+ }
- /* Transmitter is inhibited */
- bs->tx_ptr = t->tx_buf;
- bs->rx_ptr = t->rx_buf;
-
- if (t->tx_buf) {
- bs->remaining_bytes = t->len;
- bcm63xx_spi_fill_tx_fifo(bs);
+ total_len += t->len;
+
+ t = list_entry(t->transfer_list.next, struct spi_transfer,
+ transfer_list);
}
+ len = total_len - prepend_len;
+
init_completion(&bs->done);
/* Fill in the Message control register */
- msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);
+ msg_ctl = (len << SPI_BYTE_CNT_SHIFT);
- if (t->rx_buf && t->tx_buf)
+ if (do_rx && do_tx && prepend_len == 0)
msg_ctl |= (SPI_FD_RW << bs->msg_type_shift);
- else if (t->rx_buf)
+ else if (do_rx)
msg_ctl |= (SPI_HD_R << bs->msg_type_shift);
- else if (t->tx_buf)
+ else if (do_tx)
msg_ctl |= (SPI_HD_W << bs->msg_type_shift);
switch (bs->msg_ctl_width) {
@@ -245,14 +251,41 @@ static unsigned int bcm63xx_txrx_bufs(st
/* Issue the transfer */
cmd = SPI_CMD_START_IMMEDIATE;
- cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
+ cmd |= (prepend_len << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
bcm_spi_writew(bs, cmd, SPI_CMD);
/* Enable the CMD_DONE interrupt */
bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
- return t->len - bs->remaining_bytes;
+ timeout = wait_for_completion_timeout(&bs->done, HZ);
+ if (!timeout)
+ return -ETIMEDOUT;
+
+ /* read out all data */
+ rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
+
+ if (do_rx && rx_tail != len)
+ return -EINVAL;
+
+ if (!rx_tail)
+ return total_len;
+
+ len = 0;
+ t = first;
+ /* Read out all the data */
+ for (i = 0; i < n_transfers; i++) {
+ if (t->rx_buf)
+ memcpy_fromio(t->rx_buf, bs->rx_io + len, t->len);
+
+ if (t != first || prepend_len == 0)
+ len += t->len;
+
+ t = list_entry(t->transfer_list.next, struct spi_transfer,
+ transfer_list);
+ }
+
+ return total_len;
}
static int bcm63xx_spi_prepare_transfer(struct spi_master *master)
@@ -277,42 +310,71 @@ static int bcm63xx_spi_transfer_one(stru
struct spi_message *m)
{
struct bcm63xx_spi *bs = spi_master_get_devdata(master);
- struct spi_transfer *t;
+ struct spi_transfer *t, *first = NULL;
struct spi_device *spi = m->spi;
int status = 0;
- unsigned int timeout = 0;
+ unsigned int n_transfers = 0, total_len = 0;
+ bool can_use_prepend = false;
+ /*
+ * This SPI controller does not support keeping CS active after a
+ * transfer, so we need to combine the transfers into one until we may
+ * deassert CS.
+ */
list_for_each_entry(t, &m->transfers, transfer_list) {
- unsigned int len = t->len;
- u8 rx_tail;
-
status = bcm63xx_spi_check_transfer(spi, t);
if (status < 0)
goto exit;
- /* configure adapter for a new transfer */
- bcm63xx_spi_setup_transfer(spi, t);
+ if (!first)
+ first = t;
- while (len) {
- /* send the data */
- len -= bcm63xx_txrx_bufs(spi, t);
-
- timeout = wait_for_completion_timeout(&bs->done, HZ);
- if (!timeout) {
- status = -ETIMEDOUT;
- goto exit;
- }
+ n_transfers++;
+ total_len += t->len;
+
+ if (n_transfers == 2 && !first->rx_buf && !t->tx_buf &&
+ first->len <= BCM63XX_SPI_MAX_PREPEND)
+ can_use_prepend = true;
+ else if (can_use_prepend && t->tx_buf)
+ can_use_prepend = false;
+
+ if ((can_use_prepend &&
+ total_len > (bs->fifo_size + BCM63XX_SPI_MAX_PREPEND)) ||
+ (!can_use_prepend && total_len > bs->fifo_size)) {
+ status = -EINVAL;
+ goto exit;
+ }
- /* read out all data */
- rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
+ /* all transfers have to be made at the same speed */
+ if (t->speed_hz != first->speed_hz) {
+ status = -EINVAL;
+ goto exit;
+ }
- /* Read out all the data */
- if (rx_tail)
- memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail);
+ /* CS will be deasserted directly after the transfer */
+ if (t->delay_usecs) {
+ status = -EINVAL;
+ goto exit;
}
- m->actual_length += t->len;
+ if (t->cs_change ||
+ list_is_last(&t->transfer_list, &m->transfers)) {
+ /* configure adapter for a new transfer */
+ bcm63xx_spi_setup_transfer(spi, first);
+
+ status = bcm63xx_txrx_bufs(spi, first, n_transfers);
+ if (status < 0)
+ goto exit;
+
+ m->actual_length += status;
+ first = NULL;
+ status = 0;
+ n_transfers = 0;
+ total_len = 0;
+ can_use_prepend = false;
+ }
}
+
exit:
m->status = status;
spi_finalize_current_message(master);

View file

@ -1,38 +0,0 @@
From 3f650fc30aa0badf9d02842ce396cea3eef2eeaa Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Fri, 1 Jul 2011 23:16:47 +0200
Subject: [PATCH 49/79] SPI: Allow specifying the parsers for SPI flash
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
include/linux/spi/flash.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/include/linux/spi/flash.h
+++ b/include/linux/spi/flash.h
@@ -2,7 +2,7 @@
#define LINUX_SPI_FLASH_H
struct mtd_partition;
-
+struct mtd_part_parser_data;
/**
* struct flash_platform_data: board-specific flash data
* @name: optional flash device name (eg, as used with mtdparts=)
@@ -10,6 +10,8 @@ struct mtd_partition;
* @nr_parts: number of mtd_partitions for static partitoning
* @type: optional flash device type (e.g. m25p80 vs m25p64), for use
* 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
*
* Board init code (in arch/.../mach-xxx/board-yyy.c files) can
* provide information about SPI flash parts (such as DataFlash) to
@@ -25,6 +27,7 @@ struct flash_platform_data {
char *type;
+ const char **part_probe_types;
/* we'll likely add more ... use JEDEC IDs, etc */
};

View file

@ -1,23 +0,0 @@
From c7c3c338cb25d7f55ddb3f6bfbf3572758ca3896 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Thu, 10 Nov 2011 16:53:08 +0100
Subject: [PATCH 50/79] MTD: DEVICES: m25p80: use parsers if provided in flash
platform data
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
drivers/mtd/devices/m25p80.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -986,7 +986,8 @@ static int __devinit m25p_probe(struct s
/* partitions should match sector boundaries; and it may be good to
* use readonly partitions for writeprotected sectors (BP2..BP0).
*/
- return mtd_device_parse_register(&flash->mtd, NULL, &ppdata,
+ return mtd_device_parse_register(&flash->mtd,
+ data ? data->part_probe_types : NULL, &ppdata,
data ? data->parts : NULL,
data ? data->nr_parts : 0);
}

View file

@ -1,92 +0,0 @@
From 5fb4e8d7287ac8fcb33aae8b1e9e22c5a3c392bd Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Thu, 10 Nov 2011 17:33:40 +0100
Subject: [PATCH 51/79] MTD: DEVICES: m25p80: add support for limiting reads
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
drivers/mtd/devices/m25p80.c | 29 +++++++++++++++++++++++++++--
include/linux/spi/flash.h | 4 ++++
2 files changed, 31 insertions(+), 2 deletions(-)
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -100,6 +100,7 @@ struct m25p {
u16 addr_width;
u8 erase_opcode;
u8 *command;
+ int max_transfer_len;
};
static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
@@ -346,10 +347,9 @@ static int m25p80_erase(struct mtd_info
* Read an address range from the flash chip. The address range
* may be any size provided it is within the physical boundaries.
*/
-static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
+static int __m25p80_read(struct m25p *flash, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
- struct m25p *flash = mtd_to_m25p(mtd);
struct spi_transfer t[2];
struct spi_message m;
@@ -408,6 +408,28 @@ static int m25p80_read(struct mtd_info *
return 0;
}
+static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ struct m25p *flash = mtd_to_m25p(mtd);
+ size_t off;
+ size_t read_len = flash->max_transfer_len;
+ size_t part_len;
+ int ret = 0;
+
+ if (!read_len)
+ return __m25p80_read(flash, from, len, retlen, buf);
+
+ *retlen = 0;
+
+ for (off = 0; off < len && !ret; off += read_len) {
+ ret = __m25p80_read(flash, from + off, min(len - off, read_len),
+ &part_len, buf + off);
+ *retlen += part_len;
+ }
+
+ return ret;
+}
/*
* Write an address range to the flash chip. Data must be written in
* FLASH_PAGESIZE chunks. The address range may be any size provided
@@ -897,6 +919,9 @@ static int __devinit m25p_probe(struct s
return -ENOMEM;
}
+ if (data)
+ flash->max_transfer_len = data->max_transfer_len;
+
flash->spi = spi;
mutex_init(&flash->lock);
dev_set_drvdata(&spi->dev, flash);
--- a/include/linux/spi/flash.h
+++ b/include/linux/spi/flash.h
@@ -13,6 +13,8 @@ struct mtd_part_parser_data;
* @part_probe_types: optional list of MTD parser names to use for
* partitioning
*
+ * @max_transfer_len: option maximum read/write length limitation for
+ * SPI controllers not able to transfer any length commands.
* Board init code (in arch/.../mach-xxx/board-yyy.c files) can
* provide information about SPI flash parts (such as DataFlash) to
* help set up the device and its appropriate default partitioning.
@@ -28,6 +30,8 @@ struct flash_platform_data {
char *type;
const char **part_probe_types;
+
+ unsigned int max_transfer_len;
/* we'll likely add more ... use JEDEC IDs, etc */
};

View file

@ -1,116 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -12,6 +12,8 @@
#include <linux/string.h>
#include <linux/platform_device.h>
#include <linux/ssb/ssb.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
#include <asm/addrspace.h>
#include <bcm63xx_board.h>
#include <bcm63xx_cpu.h>
@@ -28,6 +30,9 @@
#define PFX "board_bcm963xx: "
+#define BCM963XX_KEYS_POLL_INTERVAL 20
+#define BCM963XX_KEYS_DEBOUNCE_INTERVAL (BCM963XX_KEYS_POLL_INTERVAL * 3)
+
static struct bcm963xx_nvram nvram;
static unsigned int mac_addr_used;
static struct board_info board;
@@ -293,6 +298,16 @@ static struct board_info __initdata boar
.active_low = 1,
},
},
+ .buttons = {
+ {
+ .desc = "reset",
+ .gpio = 33,
+ .active_low = 1,
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL,
+ },
+ },
};
static struct board_info __initdata board_96348gw = {
@@ -351,6 +366,16 @@ static struct board_info __initdata boar
.active_low = 1,
},
},
+ .buttons = {
+ {
+ .desc = "reset",
+ .gpio = 36,
+ .active_low = 1,
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL,
+ },
+ },
};
static struct board_info __initdata board_FAST2404 = {
@@ -821,11 +846,23 @@ static struct platform_device bcm63xx_gp
.dev.platform_data = &bcm63xx_led_data,
};
+static struct gpio_keys_platform_data bcm63xx_gpio_keys_data = {
+ .poll_interval = BCM963XX_KEYS_POLL_INTERVAL,
+};
+
+static struct platform_device bcm63xx_gpio_keys_device = {
+ .name = "gpio-keys-polled",
+ .id = 0,
+ .dev.platform_data = &bcm63xx_gpio_keys_data,
+};
+
/*
* third stage init callback, register all board devices.
*/
int __init board_register_devices(void)
{
+ int button_count = 0;
+
if (board.has_uart0)
bcm63xx_uart_register(0);
@@ -868,5 +905,16 @@ int __init board_register_devices(void)
platform_device_register(&bcm63xx_gpio_leds);
+ /* count number of BUTTONs defined by this device */
+ while (button_count < ARRAY_SIZE(board.buttons) && board.buttons[button_count].desc)
+ button_count++;
+
+ if (button_count) {
+ bcm63xx_gpio_keys_data.nbuttons = button_count;
+ bcm63xx_gpio_keys_data.buttons = board.buttons;
+
+ platform_device_register(&bcm63xx_gpio_keys_device);
+ }
+
return 0;
}
--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -3,6 +3,7 @@
#include <linux/types.h>
#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
#include <linux/leds.h>
#include <bcm63xx_dev_enet.h>
#include <bcm63xx_dev_dsp.h>
@@ -57,6 +58,9 @@ struct board_info {
/* GPIO LEDs */
struct gpio_led leds[5];
+
+ /* Buttons */
+ struct gpio_keys_button buttons[4];
};
#endif /* ! BOARD_BCM963XX_H_ */

View file

@ -1,41 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -862,6 +862,7 @@ static struct platform_device bcm63xx_gp
int __init board_register_devices(void)
{
int button_count = 0;
+ int led_count = 0;
if (board.has_uart0)
bcm63xx_uart_register(0);
@@ -900,10 +901,16 @@ int __init board_register_devices(void)
bcm63xx_flash_register();
- bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
- bcm63xx_led_data.leds = board.leds;
+ /* count number of LEDs defined by this device */
+ while (led_count < ARRAY_SIZE(board.leds) && board.leds[led_count].name)
+ led_count++;
+
+ if (led_count) {
+ bcm63xx_led_data.num_leds = led_count;
+ bcm63xx_led_data.leds = board.leds;
- platform_device_register(&bcm63xx_gpio_leds);
+ platform_device_register(&bcm63xx_gpio_leds);
+ }
/* count number of BUTTONs defined by this device */
while (button_count < ARRAY_SIZE(board.buttons) && board.buttons[button_count].desc)
--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -57,7 +57,7 @@ struct board_info {
struct bcm63xx_dsp_platform_data dsp;
/* GPIO LEDs */
- struct gpio_led leds[5];
+ struct gpio_led leds[14];
/* Buttons */
struct gpio_keys_button buttons[4];

View file

@ -1,25 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -899,6 +899,9 @@ int __init board_register_devices(void)
bcm63xx_spi_register();
+ if (board.num_devs)
+ platform_add_devices(board.devs, board.num_devs);
+
bcm63xx_flash_register();
/* count number of LEDs defined by this device */
--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -61,6 +61,10 @@ struct board_info {
/* Buttons */
struct gpio_keys_button buttons[4];
+
+ /* Additional platform devices */
+ struct platform_device **devs;
+ unsigned int num_devs;
};
#endif /* ! BOARD_BCM963XX_H_ */

View file

@ -1,33 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -14,6 +14,7 @@
#include <linux/ssb/ssb.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
+#include <linux/spi/spi.h>
#include <asm/addrspace.h>
#include <bcm63xx_board.h>
#include <bcm63xx_cpu.h>
@@ -902,6 +903,9 @@ int __init board_register_devices(void)
if (board.num_devs)
platform_add_devices(board.devs, board.num_devs);
+ if (board.num_spis)
+ spi_register_board_info(board.spis, board.num_spis);
+
bcm63xx_flash_register();
/* count number of LEDs defined by this device */
--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -65,6 +65,10 @@ struct board_info {
/* Additional platform devices */
struct platform_device **devs;
unsigned int num_devs;
+
+ /* Additional platform devices */
+ struct spi_board_info *spis;
+ unsigned int num_spis;
};
#endif /* ! BOARD_BCM963XX_H_ */

View file

@ -1,61 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -28,12 +28,16 @@
#include <bcm63xx_dev_pcmcia.h>
#include <bcm63xx_dev_spi.h>
#include <board_bcm963xx.h>
+#include <linux/bcm963xx_tag.h>
#define PFX "board_bcm963xx: "
#define BCM963XX_KEYS_POLL_INTERVAL 20
#define BCM963XX_KEYS_DEBOUNCE_INTERVAL (BCM963XX_KEYS_POLL_INTERVAL * 3)
+#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;
@@ -724,6 +728,29 @@ static int board_get_mac_address(u8 *mac
return 0;
}
+static void __init boardid_fixup(u8 *boot_addr)
+{
+ struct bcm_tag *tag = (struct bcm_tag *)(boot_addr + CFE_OFFSET_64K);
+
+ /* check if bcm_tag is at 64k offset */
+ if (strncmp(nvram.name, tag->board_id, BOARDID_LEN) != 0) {
+ /* else try 128k */
+ tag = (struct bcm_tag *)(boot_addr + CFE_OFFSET_128K);
+ if (strncmp(nvram.name, tag->board_id, BOARDID_LEN) != 0) {
+ /* No tag found */
+ printk(KERN_DEBUG "No bcm_tag found!\n");
+ return;
+ }
+ }
+ /* check if we should override the boardid */
+ if (tag->information1[0] != '+')
+ return;
+
+ strncpy(nvram.name, &tag->information1[1], BOARDID_LEN);
+
+ printk(KERN_INFO "Overriding boardid with '%s'\n", nvram.name);
+}
+
/*
* early init callback, read nvram data from flash and checksum it
*/
@@ -771,6 +798,11 @@ void __init board_prom_init(void)
return;
}
+ if (strcmp(cfe_version, "unknown") != 0) {
+ /* cfe present */
+ boardid_fixup(boot_addr);
+ }
+
/* find board by name */
for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
if (strncmp(nvram.name, bcm963xx_boards[i]->name,

View file

@ -1,96 +0,0 @@
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -56,8 +56,8 @@ static void __internal_irq_unmask_64(uns
#define is_ext_irq_cascaded 0
#define ext_irq_start 0
#define ext_irq_end 0
-#define ext_irq_count 0
-#define ext_irq_cfg_reg1 0
+#define ext_irq_count 4
+#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6345
#define ext_irq_cfg_reg2 0
#endif
#ifdef CONFIG_BCM63XX_CPU_6348
@@ -143,11 +143,15 @@ static void bcm63xx_init_irq(void)
irq_stat_addr += PERF_IRQSTAT_6338_REG;
irq_mask_addr += PERF_IRQMASK_6338_REG;
irq_bits = 32;
+ ext_irq_count = 4;
+ ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338;
break;
case BCM6345_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6345_REG;
irq_mask_addr += PERF_IRQMASK_6345_REG;
irq_bits = 32;
+ ext_irq_count = 4;
+ ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345;
break;
case BCM6348_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6348_REG;
@@ -434,7 +438,8 @@ static int bcm63xx_external_irq_set_type
reg = bcm_perf_readl(regaddr);
irq %= 4;
- if (BCMCPU_IS_6348()) {
+ switch (bcm63xx_get_cpu_id()) {
+ case BCM6348_CPU_ID:
if (levelsense)
reg |= EXTIRQ_CFG_LEVELSENSE_6348(irq);
else
@@ -447,9 +452,12 @@ static int bcm63xx_external_irq_set_type
reg |= EXTIRQ_CFG_BOTHEDGE_6348(irq);
else
reg &= ~EXTIRQ_CFG_BOTHEDGE_6348(irq);
- }
+ break;
- if (BCMCPU_IS_6338() || BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
+ case BCM6338_CPU_ID:
+ case BCM6345_CPU_ID:
+ case BCM6358_CPU_ID:
+ case BCM6368_CPU_ID:
if (levelsense)
reg |= EXTIRQ_CFG_LEVELSENSE(irq);
else
@@ -462,6 +470,9 @@ static int bcm63xx_external_irq_set_type
reg |= EXTIRQ_CFG_BOTHEDGE(irq);
else
reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
+ break;
+ default:
+ BUG();
}
bcm_perf_writel(reg, regaddr);
--- a/arch/mips/bcm63xx/setup.c
+++ b/arch/mips/bcm63xx/setup.c
@@ -74,6 +74,9 @@ void bcm63xx_machine_reboot(void)
case BCM6338_CPU_ID:
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6338;
break;
+ case BCM6345_CPU_ID:
+ perf_regs[0] = PERF_EXTIRQ_CFG_REG_6345;
+ break;
case BCM6348_CPU_ID:
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6348;
break;
@@ -83,6 +86,9 @@ void bcm63xx_machine_reboot(void)
}
for (i = 0; i < 2; i++) {
+ if (!perf_regs[i])
+ break;
+
reg = bcm_perf_readl(perf_regs[i]);
if (BCMCPU_IS_6348()) {
reg &= ~EXTIRQ_CFG_MASK_ALL_6348;
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -161,6 +161,7 @@
/* External Interrupt Configuration register */
#define PERF_EXTIRQ_CFG_REG_6328 0x18
#define PERF_EXTIRQ_CFG_REG_6338 0x14
+#define PERF_EXTIRQ_CFG_REG_6345 0x14
#define PERF_EXTIRQ_CFG_REG_6348 0x14
#define PERF_EXTIRQ_CFG_REG_6358 0x14
#define PERF_EXTIRQ_CFG_REG_6368 0x18

View file

@ -1,23 +0,0 @@
From a7d2622b6614fdca504c074a0cd307d5a1165c30 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Tue, 8 May 2012 09:39:01 +0200
Subject: [PATCH 04/59] Revert "MIPS: BCM63XX: Call board_register_device from device_initcall()"
This commit causes a race between PCI scan and SSB fallback SPROM handler
registration, causing the wifi to not work on slower systems. The only
subsystem touched from board_register_device is platform device
registration, which should be safe as an arch init call.
This reverts commit d64ed7ada2f689d2c62af1892ca55e47d3653e36.
---
arch/mips/bcm63xx/setup.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
--- a/arch/mips/bcm63xx/setup.c
+++ b/arch/mips/bcm63xx/setup.c
@@ -157,4 +157,4 @@ int __init bcm63xx_register_devices(void
return board_register_devices();
}
-device_initcall(bcm63xx_register_devices);
+arch_initcall(bcm63xx_register_devices);

View file

@ -1,22 +0,0 @@
From c110865541e2d3782c412af9d48c016de5a64d9c Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Tue, 14 Jun 2011 21:14:39 +0200
Subject: [PATCH 42/79] MIPS: BCM63XX: allow second UART on BCM6328
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
arch/mips/bcm63xx/dev-uart.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/arch/mips/bcm63xx/dev-uart.c
+++ b/arch/mips/bcm63xx/dev-uart.c
@@ -54,7 +54,8 @@ int __init bcm63xx_uart_register(unsigne
if (id >= ARRAY_SIZE(bcm63xx_uart_devices))
return -ENODEV;
- if (id == 1 && (!BCMCPU_IS_6358() && !BCMCPU_IS_6368()))
+ if (id == 1 && !BCMCPU_IS_6328() && !BCMCPU_IS_6358() &&
+ !BCMCPU_IS_6368())
return -ENODEV;
if (id == 0) {

View file

@ -1,48 +0,0 @@
From 5aeb6273a610f8aab090b3499827177eb41311ba Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Sat, 12 Nov 2011 12:19:09 +0100
Subject: [PATCH 53/79] MIPS: BCM63XX: expose the HS SPI clock
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
arch/mips/bcm63xx/clk.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -194,6 +194,26 @@ static struct clk clk_spi = {
};
/*
+ * SPI clock
+ */
+static void hsspi_set(struct clk *clk, int enable)
+{
+ u32 mask;
+
+ if (BCMCPU_IS_6328())
+ mask = CKCTL_6328_HSSPI_EN;
+ else
+ return;
+
+ bcm_hwclock_set(mask, enable);
+}
+
+static struct clk clk_hsspi = {
+ .set = hsspi_set,
+};
+
+
+/*
* XTM clock
*/
static void xtm_set(struct clk *clk, int enable)
@@ -286,6 +306,8 @@ struct clk *clk_get(struct device *dev,
return &clk_usbh;
if (!strcmp(id, "spi"))
return &clk_spi;
+ if (!strcmp(id, "hsspi"))
+ return &clk_hsspi;
if (!strcmp(id, "xtm"))
return &clk_xtm;
if (!strcmp(id, "periph"))

View file

@ -1,211 +0,0 @@
From 70f970222bc1096689ae1bffeb9ed09a7c4bed07 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Sat, 12 Nov 2011 12:19:55 +0100
Subject: [PATCH 28/60] MIPS: BCM63XX: add HSSPI register definitions
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 18 ++++++++
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 47 +++++++++++++++++++++
2 files changed, 65 insertions(+), 0 deletions(-)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -116,6 +116,7 @@ enum bcm63xx_regs_set {
RSET_UART1,
RSET_GPIO,
RSET_SPI,
+ RSET_HSSPI,
RSET_UDC0,
RSET_OHCI0,
RSET_OHCI_PRIV,
@@ -159,6 +160,7 @@ enum bcm63xx_regs_set {
#define RSET_ENETDMA_SIZE 2048
#define RSET_ENETSW_SIZE 65536
#define RSET_UART_SIZE 24
+#define RSET_HSSPI_SIZE 1536
#define RSET_UDC_SIZE 256
#define RSET_OHCI_SIZE 256
#define RSET_EHCI_SIZE 256
@@ -182,6 +184,7 @@ enum bcm63xx_regs_set {
#define BCM_6328_UART1_BASE (0xb0000120)
#define BCM_6328_GPIO_BASE (0xb0000080)
#define BCM_6328_SPI_BASE (0xdeadbeef)
+#define BCM_6328_HSSPI_BASE (0xb0001000)
#define BCM_6328_UDC0_BASE (0xdeadbeef)
#define BCM_6328_USBDMA_BASE (0xdeadbeef)
#define BCM_6328_OHCI0_BASE (0xb0002600)
@@ -227,6 +230,7 @@ enum bcm63xx_regs_set {
#define BCM_6338_UART1_BASE (0xdeadbeef)
#define BCM_6338_GPIO_BASE (0xfffe0400)
#define BCM_6338_SPI_BASE (0xfffe0c00)
+#define BCM_6338_HSSPI_BASE (0xdeadbeef)
#define BCM_6338_UDC0_BASE (0xdeadbeef)
#define BCM_6338_USBDMA_BASE (0xfffe2400)
#define BCM_6338_OHCI0_BASE (0xdeadbeef)
@@ -273,6 +277,7 @@ enum bcm63xx_regs_set {
#define BCM_6345_UART1_BASE (0xdeadbeef)
#define BCM_6345_GPIO_BASE (0xfffe0400)
#define BCM_6345_SPI_BASE (0xdeadbeef)
+#define BCM_6345_HSSPI_BASE (0xdeadbeef)
#define BCM_6345_UDC0_BASE (0xdeadbeef)
#define BCM_6345_USBDMA_BASE (0xfffe2800)
#define BCM_6345_ENET0_BASE (0xfffe1800)
@@ -318,6 +323,7 @@ enum bcm63xx_regs_set {
#define BCM_6348_UART1_BASE (0xdeadbeef)
#define BCM_6348_GPIO_BASE (0xfffe0400)
#define BCM_6348_SPI_BASE (0xfffe0c00)
+#define BCM_6348_HSSPI_BASE (0xdeadbeef)
#define BCM_6348_UDC0_BASE (0xfffe1000)
#define BCM_6348_OHCI0_BASE (0xfffe1b00)
#define BCM_6348_OHCI_PRIV_BASE (0xfffe1c00)
@@ -361,6 +367,7 @@ enum bcm63xx_regs_set {
#define BCM_6358_UART1_BASE (0xfffe0120)
#define BCM_6358_GPIO_BASE (0xfffe0080)
#define BCM_6358_SPI_BASE (0xfffe0800)
+#define BCM_6358_HSSPI_BASE (0xdeadbeef)
#define BCM_6358_UDC0_BASE (0xfffe0800)
#define BCM_6358_OHCI0_BASE (0xfffe1400)
#define BCM_6358_OHCI_PRIV_BASE (0xdeadbeef)
@@ -405,6 +412,7 @@ enum bcm63xx_regs_set {
#define BCM_6368_UART1_BASE (0xb0000120)
#define BCM_6368_GPIO_BASE (0xb0000080)
#define BCM_6368_SPI_BASE (0xb0000800)
+#define BCM_6368_HSSPI_BASE (0xdeadbeef)
#define BCM_6368_UDC0_BASE (0xdeadbeef)
#define BCM_6368_OHCI0_BASE (0xb0001600)
#define BCM_6368_OHCI_PRIV_BASE (0xdeadbeef)
@@ -454,6 +462,7 @@ extern const unsigned long *bcm63xx_regs
__GEN_RSET_BASE(__cpu, UART1) \
__GEN_RSET_BASE(__cpu, GPIO) \
__GEN_RSET_BASE(__cpu, SPI) \
+ __GEN_RSET_BASE(__cpu, HSSPI) \
__GEN_RSET_BASE(__cpu, UDC0) \
__GEN_RSET_BASE(__cpu, OHCI0) \
__GEN_RSET_BASE(__cpu, OHCI_PRIV) \
@@ -495,6 +504,7 @@ extern const unsigned long *bcm63xx_regs
[RSET_UART1] = BCM_## __cpu ##_UART1_BASE, \
[RSET_GPIO] = BCM_## __cpu ##_GPIO_BASE, \
[RSET_SPI] = BCM_## __cpu ##_SPI_BASE, \
+ [RSET_HSSPI] = BCM_## __cpu ##_HSSPI_BASE, \
[RSET_UDC0] = BCM_## __cpu ##_UDC0_BASE, \
[RSET_OHCI0] = BCM_## __cpu ##_OHCI0_BASE, \
[RSET_OHCI_PRIV] = BCM_## __cpu ##_OHCI_PRIV_BASE, \
@@ -567,6 +577,7 @@ enum bcm63xx_irq {
IRQ_ENET0,
IRQ_ENET1,
IRQ_ENET_PHY,
+ IRQ_HSSPI,
IRQ_OHCI0,
IRQ_EHCI0,
IRQ_ENET0_RXDMA,
@@ -602,6 +613,7 @@ enum bcm63xx_irq {
#define BCM_6328_ENET0_IRQ 0
#define BCM_6328_ENET1_IRQ 0
#define BCM_6328_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12)
+#define BCM_6328_HSSPI_IRQ (IRQ_INTERNAL_BASE + 29)
#define BCM_6328_OHCI0_IRQ (BCM_6328_HIGH_IRQ_BASE + 9)
#define BCM_6328_EHCI0_IRQ (BCM_6328_HIGH_IRQ_BASE + 10)
#define BCM_6328_PCMCIA_IRQ 0
@@ -640,6 +652,7 @@ enum bcm63xx_irq {
#define BCM_6338_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
#define BCM_6338_ENET1_IRQ 0
#define BCM_6338_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9)
+#define BCM_6338_HSSPI_IRQ 0
#define BCM_6338_OHCI0_IRQ 0
#define BCM_6338_EHCI0_IRQ 0
#define BCM_6338_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 15)
@@ -671,6 +684,7 @@ enum bcm63xx_irq {
#define BCM_6345_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
#define BCM_6345_ENET1_IRQ 0
#define BCM_6345_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12)
+#define BCM_6345_HSSPI_IRQ 0
#define BCM_6345_OHCI0_IRQ 0
#define BCM_6345_EHCI0_IRQ 0
#define BCM_6345_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 13 + 1)
@@ -702,6 +716,7 @@ enum bcm63xx_irq {
#define BCM_6348_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
#define BCM_6348_ENET1_IRQ (IRQ_INTERNAL_BASE + 7)
#define BCM_6348_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9)
+#define BCM_6348_HSSPI_IRQ 0
#define BCM_6348_OHCI0_IRQ (IRQ_INTERNAL_BASE + 12)
#define BCM_6348_EHCI0_IRQ 0
#define BCM_6348_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 20)
@@ -733,6 +748,7 @@ enum bcm63xx_irq {
#define BCM_6358_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
#define BCM_6358_ENET1_IRQ (IRQ_INTERNAL_BASE + 6)
#define BCM_6358_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9)
+#define BCM_6358_HSSPI_IRQ 0
#define BCM_6358_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5)
#define BCM_6358_EHCI0_IRQ (IRQ_INTERNAL_BASE + 10)
#define BCM_6358_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 15)
@@ -773,6 +789,7 @@ enum bcm63xx_irq {
#define BCM_6368_ENET0_IRQ 0
#define BCM_6368_ENET1_IRQ 0
#define BCM_6368_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 15)
+#define BCM_6368_HSSPI_IRQ 0
#define BCM_6368_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5)
#define BCM_6368_EHCI0_IRQ (IRQ_INTERNAL_BASE + 7)
#define BCM_6368_PCMCIA_IRQ 0
@@ -813,6 +830,7 @@ extern const int *bcm63xx_irqs;
[IRQ_ENET0] = BCM_## __cpu ##_ENET0_IRQ, \
[IRQ_ENET1] = BCM_## __cpu ##_ENET1_IRQ, \
[IRQ_ENET_PHY] = BCM_## __cpu ##_ENET_PHY_IRQ, \
+ [IRQ_HSSPI] = BCM_## __cpu ##_HSSPI_IRQ, \
[IRQ_OHCI0] = BCM_## __cpu ##_OHCI0_IRQ, \
[IRQ_EHCI0] = BCM_## __cpu ##_EHCI0_IRQ, \
[IRQ_ENET0_RXDMA] = BCM_## __cpu ##_ENET0_RXDMA_IRQ, \
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -1239,4 +1239,51 @@
#define PCIE_DEVICE_OFFSET 0x8000
+/*************************************************************************
+ * _REG relative to RSET_HSSPI
+ *************************************************************************/
+
+#define HSSPI_GLOBAL_CTRL_REG 0x0
+#define GLOBAL_CTRL_CLK_POLARITY (1 << 17)
+#define GLOBAL_CTRL_CLK_GATE_SSOFF (1 << 16)
+
+#define HSSPI_GLOBAL_EXT_TRIGGER_REG 0x4
+
+#define HSSPI_INT_STATUS_REG 0x8
+#define HSSPI_INT_STATUS_MASKED_REG 0xc
+#define HSSPI_INT_MASK_REG 0x10
+
+#define HSSPI_PING0_CMD_DONE (1 << 0)
+
+#define HSSPI_INT_CLEAR_ALL 0xff001f1f
+
+#define HSSPI_PINGPONG_COMMAND_REG(x) (0x80 + (x) * 0x40)
+#define PINGPONG_CMD_COMMAND_MASK 0xf
+#define PINGPONG_COMMAND_NOOP 0
+#define PINGPONG_COMMAND_START_NOW 1
+#define PINGPONG_COMMAND_START_TRIGGER 2
+#define PINGPONG_COMMAND_HALT 3
+#define PINGPONG_COMMAND_FLUSH 4
+#define PINGPONG_CMD_PROFILE_SHIFT 8
+#define PINGPONG_CMD_SS_SHIFT 12
+
+#define HSSPI_PINGPONG_STATUS_REG(x) (0x84 + (x) * 0x40)
+
+#define HSSPI_PROFILE_CLK_CTRL_REG(x) (0x100 + (x) * 0x20)
+#define CLK_CTRL_ACCUM_RST_ON_LOOP (1 << 15)
+
+#define HSSPI_PROFILE_SIGNAL_CTRL_REG(x) (0x104 + (x) * 0x20)
+#define SIGNAL_CTRL_LATCH_RISING (1 << 12)
+#define SIGNAL_CTRL_LAUNCH_RISING (1 << 13)
+#define SIGNAL_CTRL_ASYNC_INPUT_PATH (1 << 16)
+
+#define HSSPI_PROFILE_MODE_CTRL_REG(x) (0x108 + (x) * 0x20)
+#define MODE_CTRL_MULTIDATA_RD_STRT_SHIFT 8
+#define MODE_CTRL_MULTIDATA_WR_STRT_SHIFT 12
+#define MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT 16
+#define MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT 18
+#define MODE_CTRL_PREPENDBYTE_CNT_SHIFT 24
+
+#define HSSPI_FIFO_REG(x) (0x200 + (x) * 0x200)
+
#endif /* BCM63XX_REGS_H_ */

View file

@ -1,267 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -61,28 +61,28 @@ static struct board_info __initdata boar
.leds = {
{
- .name = "adsl",
+ .name = "96338GW:green:adsl",
.gpio = 3,
.active_low = 1,
},
{
- .name = "ses",
+ .name = "96338GW:green:ses",
.gpio = 5,
.active_low = 1,
},
{
- .name = "ppp-fail",
+ .name = "96338GW:green:ppp-fail",
.gpio = 4,
.active_low = 1,
},
{
- .name = "power",
+ .name = "96338GW:green:power",
.gpio = 0,
.active_low = 1,
.default_trigger = "default-on",
},
{
- .name = "stop",
+ .name = "96338GW:green:stop",
.gpio = 1,
.active_low = 1,
}
@@ -102,28 +102,28 @@ static struct board_info __initdata boar
.leds = {
{
- .name = "adsl",
+ .name = "96338W:green:adsl",
.gpio = 3,
.active_low = 1,
},
{
- .name = "ses",
+ .name = "96338W:green:ses",
.gpio = 5,
.active_low = 1,
},
{
- .name = "ppp-fail",
+ .name = "96338W:green:ppp-fail",
.gpio = 4,
.active_low = 1,
},
{
- .name = "power",
+ .name = "96338W:green:power",
.gpio = 0,
.active_low = 1,
.default_trigger = "default-on",
},
{
- .name = "stop",
+ .name = "96338W:green:stop",
.gpio = 1,
.active_low = 1,
},
@@ -162,29 +162,29 @@ static struct board_info __initdata boar
.leds = {
{
- .name = "adsl-fail",
+ .name = "96348R:green:adsl-fail",
.gpio = 2,
.active_low = 1,
},
{
- .name = "ppp",
+ .name = "96348R:green:ppp",
.gpio = 3,
.active_low = 1,
},
{
- .name = "ppp-fail",
+ .name = "96348R:green:ppp-fail",
.gpio = 4,
.active_low = 1,
},
{
- .name = "power",
+ .name = "96348R:green:power",
.gpio = 0,
.active_low = 1,
.default_trigger = "default-on",
},
{
- .name = "stop",
+ .name = "96348R:green:stop",
.gpio = 1,
.active_low = 1,
},
@@ -223,28 +223,28 @@ static struct board_info __initdata boar
.leds = {
{
- .name = "adsl-fail",
+ .name = "96348GW-10:green:adsl-fail",
.gpio = 2,
.active_low = 1,
},
{
- .name = "ppp",
+ .name = "96348GW-10:green:ppp",
.gpio = 3,
.active_low = 1,
},
{
- .name = "ppp-fail",
+ .name = "96348GW-10:green:ppp-fail",
.gpio = 4,
.active_low = 1,
},
{
- .name = "power",
+ .name = "96348GW-10:green:power",
.gpio = 0,
.active_low = 1,
.default_trigger = "default-on",
},
{
- .name = "stop",
+ .name = "96348GW-10:green:stop",
.gpio = 1,
.active_low = 1,
},
@@ -277,28 +277,28 @@ static struct board_info __initdata boar
.leds = {
{
- .name = "adsl-fail",
+ .name = "96348GW-11:green:adsl-fail",
.gpio = 2,
.active_low = 1,
},
{
- .name = "ppp",
+ .name = "96348GW-11:green:ppp",
.gpio = 3,
.active_low = 1,
},
{
- .name = "ppp-fail",
+ .name = "96348GW-11:green:ppp-fail",
.gpio = 4,
.active_low = 1,
},
{
- .name = "power",
+ .name = "96348GW-11:green:power",
.gpio = 0,
.active_low = 1,
.default_trigger = "default-on",
},
{
- .name = "stop",
+ .name = "96348GW-11:green:stop",
.gpio = 1,
.active_low = 1,
},
@@ -345,28 +345,28 @@ static struct board_info __initdata boar
.leds = {
{
- .name = "adsl-fail",
+ .name = "96348GW:green:adsl-fail",
.gpio = 2,
.active_low = 1,
},
{
- .name = "ppp",
+ .name = "96348GW:green:ppp",
.gpio = 3,
.active_low = 1,
},
{
- .name = "ppp-fail",
+ .name = "96348GW:green:ppp-fail",
.gpio = 4,
.active_low = 1,
},
{
- .name = "power",
+ .name = "96348GW:green:power",
.gpio = 0,
.active_low = 1,
.default_trigger = "default-on",
},
{
- .name = "stop",
+ .name = "96348GW:green:stop",
.gpio = 1,
.active_low = 1,
},
@@ -498,27 +498,27 @@ static struct board_info __initdata boar
.leds = {
{
- .name = "adsl-fail",
+ .name = "96358VW:green:adsl-fail",
.gpio = 15,
.active_low = 1,
},
{
- .name = "ppp",
+ .name = "96358VW:green:ppp",
.gpio = 22,
.active_low = 1,
},
{
- .name = "ppp-fail",
+ .name = "96358VW:green:ppp-fail",
.gpio = 23,
.active_low = 1,
},
{
- .name = "power",
+ .name = "96358VW:green:power",
.gpio = 4,
.default_trigger = "default-on",
},
{
- .name = "stop",
+ .name = "96358VW:green:stop",
.gpio = 5,
},
},
@@ -550,22 +550,22 @@ static struct board_info __initdata boar
.leds = {
{
- .name = "adsl",
+ .name = "96358VW2:green:adsl",
.gpio = 22,
.active_low = 1,
},
{
- .name = "ppp-fail",
+ .name = "96358VW2:green:ppp-fail",
.gpio = 23,
},
{
- .name = "power",
+ .name = "96358VW2:green:power",
.gpio = 5,
.active_low = 1,
.default_trigger = "default-on",
},
{
- .name = "stop",
+ .name = "96358VW2:green:stop",
.gpio = 4,
.active_low = 1,
},

View file

@ -1,26 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -777,6 +777,8 @@ void __init board_prom_init(void)
if (!memcmp(cfe, "cfe-v", 5))
snprintf(cfe_version, sizeof(cfe_version), "%u.%u.%u-%u.%u",
cfe[5], cfe[6], cfe[7], cfe[8], cfe[9]);
+ else if (!memcmp(cfe, "cfe-", 4))
+ snprintf(cfe_version, 16, "%s", (char *) &cfe[4]);
else
strcpy(cfe_version, "unknown");
printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
--- a/drivers/mtd/bcm63xxpart.c
+++ b/drivers/mtd/bcm63xxpart.c
@@ -54,10 +54,10 @@ static int bcm63xx_detect_cfe(struct mtd
if (ret)
return ret;
- if (strncmp("cfe-v", buf, 5) == 0)
+ if (strncmp("cfe-", buf, 4) == 0)
return 0;
- /* very old CFE's do not have the cfe-v string, so check for magic */
+ /* very old CFE's do not have the cfe- string, so check for magic */
ret = mtd_read(master, BCM63XX_CFE_MAGIC_OFFSET, 8, &retlen,
(void *)buf);
buf[retlen] = 0;

View file

@ -1,497 +0,0 @@
From 27ebbb819b1f92d52309276b29b7a56e362e5c4d Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Mon, 21 Nov 2011 00:48:52 +0100
Subject: [PATCH 54/84] MIPS: BCM63XX: add basic BCM6362 support
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
arch/mips/bcm63xx/Kconfig | 4 +
arch/mips/bcm63xx/boards/board_bcm963xx.c | 2 +-
arch/mips/bcm63xx/cpu.c | 52 ++++++++-
arch/mips/bcm63xx/irq.c | 19 +++
arch/mips/bcm63xx/prom.c | 2 +
arch/mips/bcm63xx/setup.c | 3 +
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 139 +++++++++++++++++++++
arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h | 2 +
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 59 +++++++++
arch/mips/include/asm/mach-bcm63xx/ioremap.h | 1 +
10 files changed, 281 insertions(+), 2 deletions(-)
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -25,6 +25,10 @@ config BCM63XX_CPU_6358
bool "support 6358 CPU"
select HW_HAS_PCI
+config BCM63XX_CPU_6362
+ bool "support 6362 CPU"
+ select HW_HAS_PCI
+
config BCM63XX_CPU_6368
bool "support 6368 CPU"
select HW_HAS_PCI
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -764,7 +764,7 @@ void __init board_prom_init(void)
/* read base address of boot chip select (0)
* 6328 does not have MPI but boots from a fixed address
*/
- if (BCMCPU_IS_6328())
+ if (BCMCPU_IS_6328() || BCMCPU_IS_6362())
val = 0x18000000;
else {
val = bcm_mpi_readl(MPI_CSBASE_REG(0));
--- a/arch/mips/bcm63xx/cpu.c
+++ b/arch/mips/bcm63xx/cpu.c
@@ -71,6 +71,15 @@ static const int bcm6358_irqs[] = {
};
+static const unsigned long bcm6362_regs_base[] = {
+ __GEN_CPU_REGS_TABLE(6362)
+};
+
+static const int bcm6362_irqs[] = {
+ __GEN_CPU_IRQ_TABLE(6362)
+
+};
+
static const unsigned long bcm6368_regs_base[] = {
__GEN_CPU_REGS_TABLE(6368)
};
@@ -169,6 +178,42 @@ static unsigned int detect_cpu_clock(voi
return (16 * 1000000 * n1 * n2) / m1;
}
+ case BCM6362_CPU_ID:
+ {
+ unsigned int tmp, mips_pll_fcvo;
+
+ tmp = bcm_misc_readl(MISC_STRAPBUS_6362_REG);
+ mips_pll_fcvo = (tmp & STRAPBUS_6362_FCVO_MASK)
+ >> STRAPBUS_6362_FCVO_SHIFT;
+ switch (mips_pll_fcvo) {
+ case 0x03:
+ case 0x0b:
+ case 0x13:
+ case 0x1b:
+ return 240000000;
+ case 0x04:
+ case 0x0c:
+ case 0x14:
+ case 0x1c:
+ return 160000000;
+ case 0x05:
+ case 0x0e:
+ case 0x16:
+ case 0x1e:
+ case 0x1f:
+ return 400000000;
+ case 0x06:
+ return 440000000;
+ case 0x07:
+ case 0x17:
+ return 384000000;
+ case 0x15:
+ case 0x1d:
+ return 200000000;
+ default:
+ return 320000000;
+ }
+ }
case BCM6368_CPU_ID:
{
unsigned int tmp, p1, p2, ndiv, m1;
@@ -205,7 +250,7 @@ static unsigned int detect_memory_size(v
unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0;
u32 val;
- if (BCMCPU_IS_6328())
+ if (BCMCPU_IS_6328() || BCMCPU_IS_6362())
return bcm_ddr_readl(DDR_CSEND_REG) << 24;
if (BCMCPU_IS_6345()) {
@@ -280,6 +325,11 @@ void __init bcm63xx_cpu_init(void)
bcm63xx_regs_base = bcm6328_regs_base;
bcm63xx_irqs = bcm6328_irqs;
break;
+ case BCM6362_CPU_ID:
+ expected_cpu_id = BCM6362_CPU_ID;
+ bcm63xx_regs_base = bcm6362_regs_base;
+ bcm63xx_irqs = bcm6362_irqs;
+ break;
case BCM6368_CPU_ID:
expected_cpu_id = BCM6368_CPU_ID;
bcm63xx_regs_base = bcm6368_regs_base;
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -82,6 +82,14 @@ static void __internal_irq_unmask_64(uns
#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6358
#define ext_irq_cfg_reg2 0
#endif
+#ifdef CONFIG_BCM63XX_CPU_6362
+#define irq_stat_reg PERF_IRQSTAT_6362_REG
+#define irq_mask_reg PERF_IRQMASK_6362_REG
+#define irq_bits 64
+#define is_ext_irq_cascaded 1
+#define ext_irq_start (BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE)
+#define ext_irq_end (BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE)
+#endif
#ifdef CONFIG_BCM63XX_CPU_6368
#define irq_stat_reg PERF_IRQSTAT_6368_REG
#define irq_mask_reg PERF_IRQMASK_6368_REG
@@ -170,6 +178,16 @@ static void bcm63xx_init_irq(void)
ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358;
break;
+ case BCM6362_CPU_ID:
+ irq_stat_addr += PERF_IRQSTAT_6362_REG;
+ irq_mask_addr += PERF_IRQMASK_6362_REG;
+ irq_bits = 64;
+ ext_irq_count = 4;
+ is_ext_irq_cascaded = 1;
+ ext_irq_start = BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE;
+ ext_irq_end = BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE;
+ ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6362;
+ break;
case BCM6368_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6368_REG;
irq_mask_addr += PERF_IRQMASK_6368_REG;
@@ -457,6 +475,7 @@ static int bcm63xx_external_irq_set_type
case BCM6338_CPU_ID:
case BCM6345_CPU_ID:
case BCM6358_CPU_ID:
+ case BCM6362_CPU_ID:
case BCM6368_CPU_ID:
if (levelsense)
reg |= EXTIRQ_CFG_LEVELSENSE(irq);
--- a/arch/mips/bcm63xx/prom.c
+++ b/arch/mips/bcm63xx/prom.c
@@ -36,6 +36,8 @@ void __init prom_init(void)
mask = CKCTL_6348_ALL_SAFE_EN;
else if (BCMCPU_IS_6358())
mask = CKCTL_6358_ALL_SAFE_EN;
+ else if (BCMCPU_IS_6362())
+ mask = CKCTL_6362_ALL_SAFE_EN;
else if (BCMCPU_IS_6368())
mask = CKCTL_6368_ALL_SAFE_EN;
else
--- a/arch/mips/bcm63xx/setup.c
+++ b/arch/mips/bcm63xx/setup.c
@@ -83,6 +83,9 @@ void bcm63xx_machine_reboot(void)
case BCM6358_CPU_ID:
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6358;
break;
+ case BCM6362_CPU_ID:
+ perf_regs[0] = PERF_EXTIRQ_CFG_REG_6362;
+ break;
}
for (i = 0; i < 2; i++) {
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -14,6 +14,7 @@
#define BCM6345_CPU_ID 0x6345
#define BCM6348_CPU_ID 0x6348
#define BCM6358_CPU_ID 0x6358
+#define BCM6362_CPU_ID 0x6362
#define BCM6368_CPU_ID 0x6368
void __init bcm63xx_cpu_init(void);
@@ -86,6 +87,20 @@ unsigned int bcm63xx_get_cpu_freq(void);
# define BCMCPU_IS_6358() (0)
#endif
+#ifdef CONFIG_BCM63XX_CPU_6362
+# ifdef bcm63xx_get_cpu_id
+# undef bcm63xx_get_cpu_id
+# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
+# define BCMCPU_RUNTIME_DETECT
+# else
+# define bcm63xx_get_cpu_id() BCM6362_CPU_ID
+# endif
+# define BCMCPU_IS_6362() (bcm63xx_get_cpu_id() == BCM6362_CPU_ID)
+#else
+# define BCMCPU_IS_6362() (0)
+#endif
+
+
#ifdef CONFIG_BCM63XX_CPU_6368
# ifdef bcm63xx_get_cpu_id
# undef bcm63xx_get_cpu_id
@@ -402,6 +417,62 @@ enum bcm63xx_regs_set {
/*
+ * 6362 register sets base address
+ */
+#define BCM_6362_DSL_LMEM_BASE (0xdeadbeef)
+#define BCM_6362_PERF_BASE (0xb0000000)
+#define BCM_6362_TIMER_BASE (0xb0000040)
+#define BCM_6362_WDT_BASE (0xb000005c)
+#define BCM_6362_UART0_BASE (0xb0000100)
+#define BCM_6362_UART1_BASE (0xb0000120)
+#define BCM_6362_GPIO_BASE (0xb0000080)
+#define BCM_6362_SPI_BASE (0xb0000800)
+#define BCM_6362_HSSPI_BASE (0xb0001000)
+#define BCM_6362_UDC0_BASE (0xdeadbeef)
+#define BCM_6362_USBDMA_BASE (0xb000c000)
+#define BCM_6362_OHCI0_BASE (0xb0002600)
+#define BCM_6362_OHCI_PRIV_BASE (0xdeadbeef)
+#define BCM_6362_USBH_PRIV_BASE (0xb0002700)
+#define BCM_6362_USBD_BASE (0xb0002400)
+#define BCM_6362_MPI_BASE (0xdeadbeef)
+#define BCM_6362_PCMCIA_BASE (0xdeadbeef)
+#define BCM_6362_PCIE_BASE (0xb0e40000)
+#define BCM_6362_SDRAM_REGS_BASE (0xdeadbeef)
+#define BCM_6362_DSL_BASE (0xdeadbeef)
+#define BCM_6362_UBUS_BASE (0xdeadbeef)
+#define BCM_6362_ENET0_BASE (0xdeadbeef)
+#define BCM_6362_ENET1_BASE (0xdeadbeef)
+#define BCM_6362_ENETDMA_BASE (0xb000d800)
+#define BCM_6362_ENETDMAC_BASE (0xb000da00)
+#define BCM_6362_ENETDMAS_BASE (0xb000dc00)
+#define BCM_6362_ENETSW_BASE (0xb0e00000)
+#define BCM_6362_EHCI0_BASE (0xb0002500)
+#define BCM_6362_SDRAM_BASE (0xdeadbeef)
+#define BCM_6362_MEMC_BASE (0xdeadbeef)
+#define BCM_6362_DDR_BASE (0xb0003000)
+#define BCM_6362_M2M_BASE (0xdeadbeef)
+#define BCM_6362_ATM_BASE (0xdeadbeef)
+#define BCM_6362_XTM_BASE (0xb0007800)
+#define BCM_6362_XTMDMA_BASE (0xb000b800)
+#define BCM_6362_XTMDMAC_BASE (0xdeadbeef)
+#define BCM_6362_XTMDMAS_BASE (0xdeadbeef)
+#define BCM_6362_PCM_BASE (0xb000a800)
+#define BCM_6362_PCMDMA_BASE (0xdeadbeef)
+#define BCM_6362_PCMDMAC_BASE (0xdeadbeef)
+#define BCM_6362_PCMDMAS_BASE (0xdeadbeef)
+#define BCM_6362_RNG_BASE (0xdeadbeef)
+#define BCM_6362_MISC_BASE (0xb0001800)
+
+#define BCM_6362_NAND_REG_BASE (0xb0000200)
+#define BCM_6362_NAND_CACHE_BASE (0xb0000600)
+#define BCM_6362_LED_BASE (0xb0001900)
+#define BCM_6362_IPSEC_BASE (0xb0002800)
+#define BCM_6362_IPSEC_DMA_BASE (0xb000d000)
+#define BCM_6362_WLAN_CHIPCOMMON_BASE (0xb0004000)
+#define BCM_6362_WLAN_D11_BASE (0xb0005000)
+#define BCM_6362_WLAN_SHIM_BASE (0xb0007000)
+
+/*
* 6368 register sets base address
*/
#define BCM_6368_DSL_LMEM_BASE (0xdeadbeef)
@@ -557,6 +628,9 @@ static inline unsigned long bcm63xx_regs
#ifdef CONFIG_BCM63XX_CPU_6358
__GEN_RSET(6358)
#endif
+#ifdef CONFIG_BCM63XX_CPU_6362
+ __GEN_RSET(6362)
+#endif
#ifdef CONFIG_BCM63XX_CPU_6368
__GEN_RSET(6368)
#endif
@@ -777,6 +851,71 @@ enum bcm63xx_irq {
#define BCM_6358_EXT_IRQ3 (IRQ_INTERNAL_BASE + 28)
/*
+ * 6362 irqs
+ */
+#define BCM_6362_HIGH_IRQ_BASE (IRQ_INTERNAL_BASE + 32)
+
+#define BCM_6362_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
+#define BCM_6362_SPI_IRQ (IRQ_INTERNAL_BASE + 2)
+#define BCM_6362_UART0_IRQ (IRQ_INTERNAL_BASE + 3)
+#define BCM_6362_UART1_IRQ (IRQ_INTERNAL_BASE + 4)
+#define BCM_6362_DSL_IRQ (IRQ_INTERNAL_BASE + 28)
+#define BCM_6362_UDC0_IRQ 0
+#define BCM_6362_ENET0_IRQ 0
+#define BCM_6362_ENET1_IRQ 0
+#define BCM_6362_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 14)
+#define BCM_6362_HSSPI_IRQ (IRQ_INTERNAL_BASE + 5)
+#define BCM_6362_OHCI0_IRQ (IRQ_INTERNAL_BASE + 9)
+#define BCM_6362_EHCI0_IRQ (IRQ_INTERNAL_BASE + 10)
+#define BCM_6362_USBD_IRQ (IRQ_INTERNAL_BASE + 11)
+#define BCM_6362_USBD_RXDMA0_IRQ (IRQ_INTERNAL_BASE + 20)
+#define BCM_6362_USBD_TXDMA0_IRQ (IRQ_INTERNAL_BASE + 21)
+#define BCM_6362_USBD_RXDMA1_IRQ (IRQ_INTERNAL_BASE + 22)
+#define BCM_6362_USBD_TXDMA1_IRQ (IRQ_INTERNAL_BASE + 23)
+#define BCM_6362_USBD_RXDMA2_IRQ (IRQ_INTERNAL_BASE + 24)
+#define BCM_6362_USBD_TXDMA2_IRQ (IRQ_INTERNAL_BASE + 25)
+#define BCM_6362_PCMCIA_IRQ 0
+#define BCM_6362_ENET0_RXDMA_IRQ 0
+#define BCM_6362_ENET0_TXDMA_IRQ 0
+#define BCM_6362_ENET1_RXDMA_IRQ 0
+#define BCM_6362_ENET1_TXDMA_IRQ 0
+#define BCM_6362_PCI_IRQ (IRQ_INTERNAL_BASE + 30)
+#define BCM_6362_ATM_IRQ 0
+#define BCM_6362_ENETSW_RXDMA0_IRQ (BCM_6362_HIGH_IRQ_BASE + 0)
+#define BCM_6362_ENETSW_RXDMA1_IRQ (BCM_6362_HIGH_IRQ_BASE + 1)
+#define BCM_6362_ENETSW_RXDMA2_IRQ (BCM_6362_HIGH_IRQ_BASE + 2)
+#define BCM_6362_ENETSW_RXDMA3_IRQ (BCM_6362_HIGH_IRQ_BASE + 3)
+#define BCM_6362_ENETSW_TXDMA0_IRQ 0
+#define BCM_6362_ENETSW_TXDMA1_IRQ 0
+#define BCM_6362_ENETSW_TXDMA2_IRQ 0
+#define BCM_6362_ENETSW_TXDMA3_IRQ 0
+#define BCM_6362_XTM_IRQ 0
+#define BCM_6362_XTM_DMA0_IRQ (BCM_6362_HIGH_IRQ_BASE + 12)
+
+#define BCM_6362_RING_OSC_IRQ (IRQ_INTERNAL_BASE + 1)
+#define BCM_6362_WLAN_GPIO_IRQ (IRQ_INTERNAL_BASE + 6)
+#define BCM_6362_WLAN_IRQ (IRQ_INTERNAL_BASE + 7)
+#define BCM_6362_IPSEC_IRQ (IRQ_INTERNAL_BASE + 8)
+#define BCM_6362_NAND_IRQ (IRQ_INTERNAL_BASE + 12)
+#define BCM_6362_PCM_IRQ (IRQ_INTERNAL_BASE + 13)
+#define BCM_6362_DG_IRQ (IRQ_INTERNAL_BASE + 15)
+#define BCM_6362_EPHY_ENERGY0_IRQ (IRQ_INTERNAL_BASE + 16)
+#define BCM_6362_EPHY_ENERGY1_IRQ (IRQ_INTERNAL_BASE + 17)
+#define BCM_6362_EPHY_ENERGY2_IRQ (IRQ_INTERNAL_BASE + 18)
+#define BCM_6362_EPHY_ENERGY3_IRQ (IRQ_INTERNAL_BASE + 19)
+#define BCM_6362_IPSEC_DMA0_IRQ (IRQ_INTERNAL_BASE + 26)
+#define BCM_6362_IPSEC_DMA1_IRQ (IRQ_INTERNAL_BASE + 27)
+#define BCM_6362_FAP0_IRQ (IRQ_INTERNAL_BASE + 29)
+#define BCM_6362_PCM_DMA0_IRQ (BCM_6362_HIGH_IRQ_BASE + 4)
+#define BCM_6362_PCM_DMA1_IRQ (BCM_6362_HIGH_IRQ_BASE + 5)
+#define BCM_6362_DECT0_IRQ (BCM_6362_HIGH_IRQ_BASE + 6)
+#define BCM_6362_DECT1_IRQ (BCM_6362_HIGH_IRQ_BASE + 7)
+#define BCM_6362_EXT_IRQ0 (BCM_6362_HIGH_IRQ_BASE + 8)
+#define BCM_6362_EXT_IRQ1 (BCM_6362_HIGH_IRQ_BASE + 9)
+#define BCM_6362_EXT_IRQ2 (BCM_6362_HIGH_IRQ_BASE + 10)
+#define BCM_6362_EXT_IRQ3 (BCM_6362_HIGH_IRQ_BASE + 11)
+
+/*
* 6368 irqs
*/
#define BCM_6368_HIGH_IRQ_BASE (IRQ_INTERNAL_BASE + 32)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
@@ -17,6 +17,8 @@ static inline unsigned long bcm63xx_gpio
return 8;
case BCM6345_CPU_ID:
return 16;
+ case BCM6362_CPU_ID:
+ return 48;
case BCM6368_CPU_ID:
return 38;
case BCM6348_CPU_ID:
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -107,6 +107,39 @@
CKCTL_6358_USBSU_EN | \
CKCTL_6358_EPHY_EN)
+#define CKCTL_6362_ADSL_QPROC_EN (1 << 1)
+#define CKCTL_6362_ADSL_AFE_EN (1 << 2)
+#define CKCTL_6362_ADSL_EN (1 << 3)
+#define CKCTL_6362_MIPS_EN (1 << 4)
+#define CKCTL_6362_WLAN_OCP_EN (1 << 5)
+#define CKCTL_6362_SWPKT_USB_EN (1 << 7)
+#define CKCTL_6362_SWPKT_SAR_EN (1 << 8)
+#define CKCTL_6362_SAR_EN (1 << 9)
+#define CKCTL_6362_ROBOSW_EN (1 << 10)
+#define CKCTL_6362_PCM_EN (1 << 11)
+#define CKCTL_6362_USBD_EN (1 << 12)
+#define CKCTL_6362_USBH_EN (1 << 13)
+#define CKCTL_6362_IPSEC_EN (1 << 14)
+#define CKCTL_6362_SPI_EN (1 << 15)
+#define CKCTL_6362_HSSPI_EN (1 << 16)
+#define CKCTL_6362_PCIE_EN (1 << 17)
+#define CKCTL_6362_FAP_EN (1 << 18)
+#define CKCTL_6362_PHYMIPS_EN (1 << 19)
+#define CKCTL_6362_NAND_EN (1 << 20)
+
+#define CKCTL_6362_ALL_SAFE_EN (CKCTL_6362_PHYMIPS_EN | \
+ CKCTL_6362_ADSL_QPROC_EN | \
+ CKCTL_6362_ADSL_AFE_EN | \
+ CKCTL_6362_ADSL_EN | \
+ CKCTL_6362_SAR_EN | \
+ CKCTL_6362_PCM_EN | \
+ CKCTL_6362_IPSEC_EN | \
+ CKCTL_6362_USBD_EN | \
+ CKCTL_6362_USBH_EN | \
+ CKCTL_6362_ROBOSW_EN | \
+ CKCTL_6362_PCIE_EN)
+
+
#define CKCTL_6368_VDSL_QPROC_EN (1 << 2)
#define CKCTL_6368_VDSL_AFE_EN (1 << 3)
#define CKCTL_6368_VDSL_BONDING_EN (1 << 4)
@@ -148,6 +181,7 @@
#define PERF_IRQMASK_6345_REG 0xc
#define PERF_IRQMASK_6348_REG 0xc
#define PERF_IRQMASK_6358_REG 0xc
+#define PERF_IRQMASK_6362_REG 0x20
#define PERF_IRQMASK_6368_REG 0x20
/* Interrupt Status register */
@@ -156,6 +190,7 @@
#define PERF_IRQSTAT_6345_REG 0x10
#define PERF_IRQSTAT_6348_REG 0x10
#define PERF_IRQSTAT_6358_REG 0x10
+#define PERF_IRQSTAT_6362_REG 0x28
#define PERF_IRQSTAT_6368_REG 0x28
/* External Interrupt Configuration register */
@@ -164,6 +199,7 @@
#define PERF_EXTIRQ_CFG_REG_6345 0x14
#define PERF_EXTIRQ_CFG_REG_6348 0x14
#define PERF_EXTIRQ_CFG_REG_6358 0x14
+#define PERF_EXTIRQ_CFG_REG_6362 0x18
#define PERF_EXTIRQ_CFG_REG_6368 0x18
#define PERF_EXTIRQ_CFG_REG2_6368 0x1c
@@ -191,6 +227,7 @@
/* Soft Reset register */
#define PERF_SOFTRESET_REG 0x28
#define PERF_SOFTRESET_6328_REG 0x10
+#define PERF_SOFTRESET_6362_REG 0x10
#define PERF_SOFTRESET_6368_REG 0x10
#define SOFTRESET_6328_SPI_MASK (1 << 0)
@@ -244,6 +281,22 @@
SOFTRESET_6348_ACLC_MASK | \
SOFTRESET_6348_ADSLMIPSPLL_MASK)
+#define SOFTRESET_6362_SPI_MASK (1 << 0)
+#define SOFTRESET_6362_IPSEC_MASK (1 << 1)
+#define SOFTRESET_6362_EPHY_MASK (1 << 2)
+#define SOFTRESET_6362_SAR_MASK (1 << 3)
+#define SOFTRESET_6362_ENETSW_MASK (1 << 4)
+#define SOFTRESET_6362_USBS_MASK (1 << 5)
+#define SOFTRESET_6362_USBH_MASK (1 << 6)
+#define SOFTRESET_6362_PCM_MASK (1 << 7)
+#define SOFTRESET_6362_PCIE_CORE_MASK (1 << 8)
+#define SOFTRESET_6362_PCIE_MASK (1 << 9)
+#define SOFTRESET_6362_PCIE_EXT_MASK (1 << 10)
+#define SOFTRESET_6362_WLAN_SHIM_MASK (1 << 11)
+#define SOFTRESET_6362_DDR_PHY_MASK (1 << 12)
+#define SOFTRESET_6362_FAP_MASK (1 << 13)
+#define SOFTRESET_6362_WLAN_UBUS_MASK (1 << 14)
+
#define SOFTRESET_6368_SPI_MASK (1 << 0)
#define SOFTRESET_6368_MPI_MASK (1 << 3)
#define SOFTRESET_6368_EPHY_MASK (1 << 6)
@@ -1182,6 +1235,12 @@
#define SERDES_PCIE_EN (1 << 0)
#define SERDES_PCIE_EXD_EN (1 << 15)
+#define MISC_STRAPBUS_6362_REG 0x14
+#define STRAPBUS_6362_FCVO_SHIFT 1
+#define STRAPBUS_6362_FCVO_MASK (0x1f << STRAPBUS_6362_FCVO_SHIFT)
+#define STRAPBUS_6362_BOOT_SEL_SERIAL (1 << 15)
+#define STRAPBUS_6362_BOOT_SEL_NAND (0 << 15)
+
#define MISC_STRAPBUS_6328_REG 0x240
#define STRAPBUS_6328_FCVO_SHIFT 7
#define STRAPBUS_6328_FCVO_MASK (0x1f << STRAPBUS_6328_FCVO_SHIFT)
--- a/arch/mips/include/asm/mach-bcm63xx/ioremap.h
+++ b/arch/mips/include/asm/mach-bcm63xx/ioremap.h
@@ -19,6 +19,7 @@ static inline int is_bcm63xx_internal_re
return 1;
break;
case BCM6328_CPU_ID:
+ case BCM6362_CPU_ID:
case BCM6368_CPU_ID:
if (offset >= 0xb0000000 && offset < 0xb1000000)
return 1;

View file

@ -1,110 +0,0 @@
From e49546bf3f255f028d0877ceeb7ed6466fe37d8a Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Mon, 21 Nov 2011 00:53:26 +0100
Subject: [PATCH 56/84] MIPS: BCM63XX: enable pcie for BCM6362
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 3 +-
arch/mips/pci/pci-bcm63xx.c | 57 +++++++++++++++------
2 files changed, 44 insertions(+), 16 deletions(-)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -1231,7 +1231,8 @@
/*************************************************************************
* _REG relative to RSET_MISC
*************************************************************************/
-#define MISC_SERDES_CTRL_REG 0x0
+#define MISC_SERDES_CTRL_6328_REG 0x0
+#define MISC_SERDES_CTRL_6362_REG 0x4
#define SERDES_PCIE_EN (1 << 0)
#define SERDES_PCIE_EXD_EN (1 << 15)
--- a/arch/mips/pci/pci-bcm63xx.c
+++ b/arch/mips/pci/pci-bcm63xx.c
@@ -118,35 +118,61 @@ void __iomem *pci_iospace_start;
static void __init bcm63xx_reset_pcie(void)
{
u32 val;
+ u32 reg;
+ u32 mask;
/* enable clock */
+
+ if (BCMCPU_IS_6328())
+ mask = CKCTL_6328_PCIE_EN;
+ else
+ mask = CKCTL_6362_PCIE_EN;
+
val = bcm_perf_readl(PERF_CKCTL_REG);
- val |= CKCTL_6328_PCIE_EN;
+ val |= mask;
bcm_perf_writel(val, PERF_CKCTL_REG);
/* enable SERDES */
- val = bcm_misc_readl(MISC_SERDES_CTRL_REG);
+
+ if (BCMCPU_IS_6328())
+ reg = MISC_SERDES_CTRL_6328_REG;
+ else
+ reg = MISC_SERDES_CTRL_6362_REG;
+
+ val = bcm_misc_readl(reg);
val |= SERDES_PCIE_EN | SERDES_PCIE_EXD_EN;
- bcm_misc_writel(val, MISC_SERDES_CTRL_REG);
+ bcm_misc_writel(val, reg);
/* reset the PCIe core */
- val = bcm_perf_readl(PERF_SOFTRESET_6328_REG);
+ if (BCMCPU_IS_6328()) {
+ reg = PERF_SOFTRESET_6328_REG;
+ mask = SOFTRESET_6328_PCIE_MASK | SOFTRESET_6328_PCIE_CORE_MASK
+ | SOFTRESET_6328_PCIE_HARD_MASK;
+ } else {
+ reg = PERF_SOFTRESET_6362_REG;
+ mask = SOFTRESET_6362_PCIE_MASK | SOFTRESET_6362_PCIE_CORE_MASK;
+ }
+ val = bcm_perf_readl(reg);
+ val &= ~mask;
+
+ if (BCMCPU_IS_6328())
+ val &= ~SOFTRESET_6328_PCIE_EXT_MASK;
+ else
+ val &= ~SOFTRESET_6362_PCIE_EXT_MASK;
- val &= ~SOFTRESET_6328_PCIE_MASK;
- val &= ~SOFTRESET_6328_PCIE_CORE_MASK;
- val &= ~SOFTRESET_6328_PCIE_HARD_MASK;
- val &= ~SOFTRESET_6328_PCIE_EXT_MASK;
- bcm_perf_writel(val, PERF_SOFTRESET_6328_REG);
+ bcm_perf_writel(val, reg);
mdelay(10);
- val |= SOFTRESET_6328_PCIE_MASK;
- val |= SOFTRESET_6328_PCIE_CORE_MASK;
- val |= SOFTRESET_6328_PCIE_HARD_MASK;
- bcm_perf_writel(val, PERF_SOFTRESET_6328_REG);
+ val |= mask;
+ bcm_perf_writel(val, reg);
mdelay(10);
- val |= SOFTRESET_6328_PCIE_EXT_MASK;
- bcm_perf_writel(val, PERF_SOFTRESET_6328_REG);
+ if (BCMCPU_IS_6328())
+ val |= SOFTRESET_6328_PCIE_EXT_MASK;
+ else
+ val |= SOFTRESET_6362_PCIE_EXT_MASK;
+
+ bcm_perf_writel(val, reg);
mdelay(200);
}
@@ -332,6 +358,7 @@ static int __init bcm63xx_pci_init(void)
switch (bcm63xx_get_cpu_id()) {
case BCM6328_CPU_ID:
+ case BCM6362_CPU_ID:
return bcm63xx_register_pcie();
case BCM6348_CPU_ID:
case BCM6358_CPU_ID:

View file

@ -1,234 +0,0 @@
From 7b510c5754d3c46e1287803f51e8ecb177414438 Mon Sep 17 00:00:00 2001
From: Maxime Bizon <mbizon@freebox.fr>
Date: Fri, 10 Jun 2011 19:14:30 +0200
Subject: [PATCH 23/63] ohci: add driver for bcm63xx integrated controller.
---
drivers/usb/host/Kconfig | 9 ++
drivers/usb/host/ohci-bcm63xx.c | 175 +++++++++++++++++++++++++++++++++++++++
drivers/usb/host/ohci-hcd.c | 5 +
drivers/usb/host/ohci.h | 2 +-
4 files changed, 190 insertions(+), 1 deletions(-)
create mode 100644 drivers/usb/host/ohci-bcm63xx.c
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -296,6 +296,15 @@ config USB_OHCI_HCD
To compile this driver as a module, choose M here: the
module will be called ohci-hcd.
+config USB_OHCI_BCM63XX
+ bool "Support for Broadcom 63xx on-chip OHCI USB controller"
+ depends on USB_OHCI_HCD && BCM63XX
+ select USB_OHCI_BIG_ENDIAN_DESC
+ select USB_OHCI_BIG_ENDIAN_MMIO
+ ---help---
+ Enables support for the on-chip OHCI controller on
+ BCM63XX chips.
+
config USB_OHCI_HCD_OMAP1
bool "OHCI support for OMAP1/2 chips"
depends on USB_OHCI_HCD && (ARCH_OMAP1 || ARCH_OMAP2)
--- /dev/null
+++ b/drivers/usb/host/ohci-bcm63xx.c
@@ -0,0 +1,175 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+
+static struct clk *usb_host_clock;
+
+static int __devinit ohci_bcm63xx_start(struct usb_hcd *hcd)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ int ret;
+
+ ohci->num_ports = 1;
+
+ ret = ohci_init(ohci);
+ if (ret < 0)
+ return ret;
+
+ /* FIXME: autodetected port 2 is shared with USB slave */
+
+ ret = ohci_run(ohci);
+ if (ret < 0) {
+ err("can't start %s", hcd->self.bus_name);
+ ohci_stop(hcd);
+ return ret;
+ }
+ return 0;
+}
+
+static const struct hc_driver ohci_bcm63xx_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "BCM63XX integrated OHCI controller",
+ .hcd_priv_size = sizeof(struct ohci_hcd),
+
+ .irq = ohci_irq,
+ .flags = HCD_USB11 | HCD_MEMORY,
+ .start = ohci_bcm63xx_start,
+ .stop = ohci_stop,
+ .shutdown = ohci_shutdown,
+ .urb_enqueue = ohci_urb_enqueue,
+ .urb_dequeue = ohci_urb_dequeue,
+ .endpoint_disable = ohci_endpoint_disable,
+ .get_frame_number = ohci_get_frame,
+ .hub_status_data = ohci_hub_status_data,
+ .hub_control = ohci_hub_control,
+ .start_port_reset = ohci_start_port_reset,
+};
+
+static int __devinit ohci_hcd_bcm63xx_drv_probe(struct platform_device *pdev)
+{
+ struct resource *res_mem;
+ struct usb_hcd *hcd;
+ struct ohci_hcd *ohci;
+ struct clk *clk;
+ u32 reg;
+ int ret, irq;
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (!res_mem || irq < 0)
+ return -ENODEV;
+
+ /* enable USB host clock */
+ clk = clk_get(&pdev->dev, "usbh");
+ if (IS_ERR(clk))
+ return -ENODEV;
+
+ clk_enable(clk);
+ usb_host_clock = clk;
+ msleep(100);
+
+ if (BCMCPU_IS_6348())
+ bcm_rset_writel(RSET_OHCI_PRIV, 0, OHCI_PRIV_REG);
+ else if (BCMCPU_IS_6358()) {
+ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6358_REG);
+ reg &= ~USBH_PRIV_SWAP_OHCI_ENDN_MASK;
+ reg |= USBH_PRIV_SWAP_OHCI_DATA_MASK;
+ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SWAP_6358_REG);
+ /*
+ * The magic value comes for the original vendor BSP
+ * and is needed for USB to work. Datasheet does not
+ * help, so the magic value is used as-is.
+ */
+ bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020,
+ USBH_PRIV_TEST_6358_REG);
+
+ } else if (BCMCPU_IS_6368()) {
+ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG);
+ reg &= ~USBH_PRIV_SWAP_OHCI_ENDN_MASK;
+ reg |= USBH_PRIV_SWAP_OHCI_DATA_MASK;
+ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SWAP_6368_REG);
+
+ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SETUP_6368_REG);
+ reg |= USBH_PRIV_SETUP_IOC_MASK;
+ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SETUP_6368_REG);
+ }
+
+ hcd = usb_create_hcd(&ohci_bcm63xx_hc_driver, &pdev->dev, "bcm63xx");
+ if (!hcd)
+ return -ENOMEM;
+ hcd->rsrc_start = res_mem->start;
+ hcd->rsrc_len = res_mem->end - res_mem->start + 1;
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ pr_debug("request_mem_region failed\n");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs) {
+ pr_debug("ioremap failed\n");
+ ret = -EIO;
+ goto out1;
+ }
+
+ ohci = hcd_to_ohci(hcd);
+ ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC |
+ OHCI_QUIRK_FRAME_NO;
+ ohci_hcd_init(ohci);
+
+ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+ if (ret)
+ goto out2;
+
+ platform_set_drvdata(pdev, hcd);
+ return 0;
+
+out2:
+ iounmap(hcd->regs);
+out1:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+out:
+ usb_put_hcd(hcd);
+ return ret;
+}
+
+static int __devexit ohci_hcd_bcm63xx_drv_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd;
+
+ hcd = platform_get_drvdata(pdev);
+ usb_remove_hcd(hcd);
+ iounmap(hcd->regs);
+ usb_put_hcd(hcd);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ if (usb_host_clock) {
+ clk_disable(usb_host_clock);
+ clk_put(usb_host_clock);
+ }
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+static struct platform_driver ohci_hcd_bcm63xx_driver = {
+ .probe = ohci_hcd_bcm63xx_drv_probe,
+ .remove = __devexit_p(ohci_hcd_bcm63xx_drv_remove),
+ .shutdown = usb_hcd_platform_shutdown,
+ .driver = {
+ .name = "bcm63xx_ohci",
+ .owner = THIS_MODULE,
+ },
+};
+
+MODULE_ALIAS("platform:bcm63xx_ohci");
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1121,6 +1121,11 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ohci_xls_driver
#endif
+#ifdef CONFIG_USB_OHCI_BCM63XX
+#include "ohci-bcm63xx.c"
+#define PLATFORM_DRIVER ohci_hcd_bcm63xx_driver
+#endif
+
#if !defined(PCI_DRIVER) && \
!defined(PLATFORM_DRIVER) && \
!defined(OMAP1_PLATFORM_DRIVER) && \
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -652,7 +652,7 @@ static inline u32 hc32_to_cpup (const st
* some big-endian SOC implementations. Same thing happens with PSW access.
*/
-#ifdef CONFIG_PPC_MPC52xx
+#if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_BCM63XX)
#define big_endian_frame_no_quirk(ohci) (ohci->flags & OHCI_QUIRK_FRAME_NO)
#else
#define big_endian_frame_no_quirk(ohci) 0

View file

@ -1,143 +0,0 @@
From ab96f20ca1c3c8e7e5acd82d1e50823a5d572675 Mon Sep 17 00:00:00 2001
From: Maxime Bizon <mbizon@freebox.fr>
Date: Tue, 24 May 2011 21:47:41 +0200
Subject: [PATCH 24/63] MIPS: BCM63XX: register ohci device.
---
arch/mips/bcm63xx/Kconfig | 9 ++--
arch/mips/bcm63xx/Makefile | 2 +-
arch/mips/bcm63xx/boards/board_bcm963xx.c | 4 ++
arch/mips/bcm63xx/dev-usb-ohci.c | 50 ++++++++++++++++++++
.../asm/mach-bcm63xx/bcm63xx_dev_usb_ohci.h | 6 ++
5 files changed, 65 insertions(+), 6 deletions(-)
create mode 100644 arch/mips/bcm63xx/dev-usb-ohci.c
create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_ohci.h
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -8,22 +8,20 @@ config BCM63XX_CPU_6328
config BCM63XX_CPU_6338
bool "support 6338 CPU"
select HW_HAS_PCI
- select USB_ARCH_HAS_OHCI
- select USB_OHCI_BIG_ENDIAN_DESC
- select USB_OHCI_BIG_ENDIAN_MMIO
+ select USB_ARCH_HAS_OHCI if USB_SUPPORT
config BCM63XX_CPU_6345
bool "support 6345 CPU"
- select USB_OHCI_BIG_ENDIAN_DESC
- select USB_OHCI_BIG_ENDIAN_MMIO
config BCM63XX_CPU_6348
bool "support 6348 CPU"
select HW_HAS_PCI
+ select USB_ARCH_HAS_OHCI if USB_SUPPORT
config BCM63XX_CPU_6358
bool "support 6358 CPU"
select HW_HAS_PCI
+ select USB_ARCH_HAS_OHCI if USB_SUPPORT
config BCM63XX_CPU_6362
bool "support 6362 CPU"
@@ -32,6 +30,7 @@ config BCM63XX_CPU_6362
config BCM63XX_CPU_6368
bool "support 6368 CPU"
select HW_HAS_PCI
+ select USB_ARCH_HAS_OHCI if USB_SUPPORT
endmenu
source "arch/mips/bcm63xx/boards/Kconfig"
--- 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-pcmcia.o dev-rng.o \
- dev-spi.o dev-uart.o dev-wdt.o
+ dev-spi.o dev-uart.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
@@ -27,6 +27,7 @@
#include <bcm63xx_dev_flash.h>
#include <bcm63xx_dev_pcmcia.h>
#include <bcm63xx_dev_spi.h>
+#include <bcm63xx_dev_usb_ohci.h>
#include <board_bcm963xx.h>
#include <linux/bcm963xx_tag.h>
@@ -916,6 +917,9 @@ int __init board_register_devices(void)
!board_get_mac_address(board.enet1.mac_addr))
bcm63xx_enet_register(1, &board.enet1);
+ if (board.has_ohci0)
+ bcm63xx_ohci_register();
+
if (board.has_dsp)
bcm63xx_dsp_register(&board.dsp);
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-usb-ohci.c
@@ -0,0 +1,50 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_usb_ohci.h>
+
+static struct resource ohci_resources[] = {
+ {
+ .start = -1, /* filled at runtime */
+ .end = -1, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = -1, /* filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ohci_dmamask = ~(u32)0;
+
+static struct platform_device bcm63xx_ohci_device = {
+ .name = "bcm63xx_ohci",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(ohci_resources),
+ .resource = ohci_resources,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+int __init bcm63xx_ohci_register(void)
+{
+ if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358() && !BCMCPU_IS_6368())
+ return 0;
+
+ ohci_resources[0].start = bcm63xx_regset_address(RSET_OHCI0);
+ ohci_resources[0].end = ohci_resources[0].start;
+ ohci_resources[0].end += RSET_OHCI_SIZE - 1;
+ ohci_resources[1].start = bcm63xx_get_irq_number(IRQ_OHCI0);
+ return platform_device_register(&bcm63xx_ohci_device);
+}
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_ohci.h
@@ -0,0 +1,6 @@
+#ifndef BCM63XX_DEV_USB_OHCI_H_
+#define BCM63XX_DEV_USB_OHCI_H_
+
+int bcm63xx_ohci_register(void);
+
+#endif /* BCM63XX_DEV_USB_OHCI_H_ */

View file

@ -1,241 +0,0 @@
From db58271d5152aa1d3894fdef13ca04379139d5d9 Mon Sep 17 00:00:00 2001
From: Maxime Bizon <mbizon@freebox.fr>
Date: Fri, 10 Jun 2011 19:15:47 +0200
Subject: [PATCH 25/63] ehci: add driver for bcm63xx integrated controller.
---
drivers/usb/host/Kconfig | 10 ++-
drivers/usb/host/ehci-bcm63xx.c | 186 +++++++++++++++++++++++++++++++++++++++
drivers/usb/host/ehci-hcd.c | 5 +
3 files changed, 199 insertions(+), 1 deletions(-)
create mode 100644 drivers/usb/host/ehci-bcm63xx.c
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -106,7 +106,7 @@ config USB_EHCI_BIG_ENDIAN_MMIO
depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || \
ARCH_IXP4XX || XPS_USB_HCD_XILINX || \
PPC_MPC512x || CPU_CAVIUM_OCTEON || \
- PMC_MSP || SPARC_LEON)
+ PMC_MSP || SPARC_LEON || BCM63XX)
default y
config USB_EHCI_BIG_ENDIAN_DESC
@@ -129,6 +129,14 @@ config XPS_USB_HCD_XILINX
config USB_FSL_MPH_DR_OF
tristate
+config USB_EHCI_BCM63XX
+ bool "Support for Broadcom 63xx on-chip EHCI USB controller"
+ depends on USB_EHCI_HCD && BCM63XX
+ select USB_EHCI_BIG_ENDIAN_MMIO
+ ---help---
+ Enables support for the on-chip EHCI controller on
+ BCM6358 and later chips.
+
config USB_EHCI_FSL
bool "Support for Freescale PPC on-chip EHCI USB controller"
depends on USB_EHCI_HCD && FSL_SOC
--- /dev/null
+++ b/drivers/usb/host/ehci-bcm63xx.c
@@ -0,0 +1,186 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+
+static struct clk *usb_host_clock;
+
+static int ehci_bcm63xx_setup(struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ int retval;
+
+ retval = ehci_halt(ehci);
+ if (retval)
+ return retval;
+
+ retval = ehci_init(hcd);
+ if (retval)
+ return retval;
+
+ ehci_reset(ehci);
+ ehci_port_power(ehci, 0);
+
+ return retval;
+}
+
+
+static const struct hc_driver ehci_bcm63xx_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "BCM63XX integrated EHCI controller",
+ .hcd_priv_size = sizeof(struct ehci_hcd),
+
+ .irq = ehci_irq,
+ .flags = HCD_MEMORY | HCD_USB2,
+
+ .reset = ehci_bcm63xx_setup,
+ .start = ehci_run,
+ .stop = ehci_stop,
+ .shutdown = ehci_shutdown,
+
+ .urb_enqueue = ehci_urb_enqueue,
+ .urb_dequeue = ehci_urb_dequeue,
+ .endpoint_disable = ehci_endpoint_disable,
+
+ .get_frame_number = ehci_get_frame,
+
+ .hub_status_data = ehci_hub_status_data,
+ .hub_control = ehci_hub_control,
+ .bus_suspend = ehci_bus_suspend,
+ .bus_resume = ehci_bus_resume,
+ .relinquish_port = ehci_relinquish_port,
+ .port_handed_over = ehci_port_handed_over,
+};
+
+static int __devinit ehci_hcd_bcm63xx_drv_probe(struct platform_device *pdev)
+{
+ struct resource *res_mem;
+ struct usb_hcd *hcd;
+ struct ehci_hcd *ehci;
+ struct clk *clk;
+ u32 reg;
+ int ret, irq;
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);;
+ if (!res_mem || irq < 0)
+ return -ENODEV;
+
+ /* enable USB host clock */
+ clk = clk_get(&pdev->dev, "usbh");
+ if (IS_ERR(clk))
+ return -ENODEV;
+
+ clk_enable(clk);
+ usb_host_clock = clk;
+ msleep(100);
+
+ if (BCMCPU_IS_6358()) {
+ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6358_REG);
+ reg &= ~USBH_PRIV_SWAP_EHCI_DATA_MASK;
+ reg |= USBH_PRIV_SWAP_EHCI_ENDN_MASK;
+ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SWAP_6358_REG);
+
+ /*
+ * The magic value comes for the original vendor BSP
+ * and is needed for USB to work. Datasheet does not
+ * help, so the magic value is used as-is.
+ */
+ bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020,
+ USBH_PRIV_TEST_6358_REG);
+
+ } else if (BCMCPU_IS_6368()) {
+
+ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG);
+ reg &= ~USBH_PRIV_SWAP_EHCI_DATA_MASK;
+ reg |= USBH_PRIV_SWAP_EHCI_ENDN_MASK;
+ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SWAP_6368_REG);
+
+ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SETUP_6368_REG);
+ reg |= USBH_PRIV_SETUP_IOC_MASK;
+ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SETUP_6368_REG);
+ }
+
+ hcd = usb_create_hcd(&ehci_bcm63xx_hc_driver, &pdev->dev, "bcm63xx");
+ if (!hcd)
+ return -ENOMEM;
+ hcd->rsrc_start = res_mem->start;
+ hcd->rsrc_len = res_mem->end - res_mem->start + 1;
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ pr_debug("request_mem_region failed\n");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs) {
+ pr_debug("ioremap failed\n");
+ ret = -EIO;
+ goto out1;
+ }
+
+ ehci = hcd_to_ehci(hcd);
+ ehci->big_endian_mmio = 1;
+ ehci->big_endian_desc = 0;
+ ehci->caps = hcd->regs;
+ ehci->regs = hcd->regs +
+ HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
+ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+ ehci->sbrn = 0x20;
+ ehci->ignore_oc = 1;
+
+ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+ if (ret)
+ goto out2;
+
+ platform_set_drvdata(pdev, hcd);
+ return 0;
+
+out2:
+ iounmap(hcd->regs);
+out1:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+out:
+ usb_put_hcd(hcd);
+ return ret;
+}
+
+static int __devexit ehci_hcd_bcm63xx_drv_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd;
+
+ hcd = platform_get_drvdata(pdev);
+ usb_remove_hcd(hcd);
+ iounmap(hcd->regs);
+ usb_put_hcd(hcd);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ if (usb_host_clock) {
+ clk_disable(usb_host_clock);
+ clk_put(usb_host_clock);
+ }
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+static struct platform_driver ehci_hcd_bcm63xx_driver = {
+ .probe = ehci_hcd_bcm63xx_drv_probe,
+ .remove = __devexit_p(ehci_hcd_bcm63xx_drv_remove),
+ .shutdown = usb_hcd_platform_shutdown,
+ .driver = {
+ .name = "bcm63xx_ehci",
+ .owner = THIS_MODULE,
+ },
+};
+
+MODULE_ALIAS("platform:bcm63xx_ehci");
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1381,6 +1381,11 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ehci_mv_driver
#endif
+#ifdef CONFIG_USB_EHCI_BCM63XX
+#include "ehci-bcm63xx.c"
+#define PLATFORM_DRIVER ehci_hcd_bcm63xx_driver
+#endif
+
#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
!defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
!defined(XILINX_OF_PLATFORM_DRIVER)

View file

@ -1,125 +0,0 @@
From a2d78246e4cb45b5978fc682aad19c0fff0cd20d Mon Sep 17 00:00:00 2001
From: Maxime Bizon <mbizon@freebox.fr>
Date: Tue, 24 May 2011 21:50:33 +0200
Subject: [PATCH 26/63] MIPS: BCM63XX: register ehci device.
---
arch/mips/bcm63xx/Kconfig | 2 +
arch/mips/bcm63xx/Makefile | 2 +-
arch/mips/bcm63xx/boards/board_bcm963xx.c | 4 ++
arch/mips/bcm63xx/dev-usb-ehci.c | 50 ++++++++++++++++++++
.../asm/mach-bcm63xx/bcm63xx_dev_usb_ehci.h | 6 ++
5 files changed, 63 insertions(+), 1 deletions(-)
create mode 100644 arch/mips/bcm63xx/dev-usb-ehci.c
create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_ehci.h
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -22,6 +22,7 @@ config BCM63XX_CPU_6358
bool "support 6358 CPU"
select HW_HAS_PCI
select USB_ARCH_HAS_OHCI if USB_SUPPORT
+ select USB_ARCH_HAS_EHCI if USB_SUPPORT
config BCM63XX_CPU_6362
bool "support 6362 CPU"
@@ -31,6 +32,7 @@ config BCM63XX_CPU_6368
bool "support 6368 CPU"
select HW_HAS_PCI
select USB_ARCH_HAS_OHCI if USB_SUPPORT
+ select USB_ARCH_HAS_EHCI if USB_SUPPORT
endmenu
source "arch/mips/bcm63xx/boards/Kconfig"
--- 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-pcmcia.o dev-rng.o \
- dev-spi.o dev-uart.o dev-usb-ohci.o dev-wdt.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
@@ -28,6 +28,7 @@
#include <bcm63xx_dev_pcmcia.h>
#include <bcm63xx_dev_spi.h>
#include <bcm63xx_dev_usb_ohci.h>
+#include <bcm63xx_dev_usb_ehci.h>
#include <board_bcm963xx.h>
#include <linux/bcm963xx_tag.h>
@@ -917,6 +918,9 @@ int __init board_register_devices(void)
!board_get_mac_address(board.enet1.mac_addr))
bcm63xx_enet_register(1, &board.enet1);
+ if (board.has_ehci0)
+ bcm63xx_ehci_register();
+
if (board.has_ohci0)
bcm63xx_ohci_register();
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-usb-ehci.c
@@ -0,0 +1,50 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_usb_ehci.h>
+
+static struct resource ehci_resources[] = {
+ {
+ .start = -1, /* filled at runtime */
+ .end = -1, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = -1, /* filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ehci_dmamask = ~(u32)0;
+
+static struct platform_device bcm63xx_ehci_device = {
+ .name = "bcm63xx_ehci",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(ehci_resources),
+ .resource = ehci_resources,
+ .dev = {
+ .dma_mask = &ehci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+int __init bcm63xx_ehci_register(void)
+{
+ if (!BCMCPU_IS_6358() && !BCMCPU_IS_6368())
+ return 0;
+
+ ehci_resources[0].start = bcm63xx_regset_address(RSET_EHCI0);
+ ehci_resources[0].end = ehci_resources[0].start;
+ ehci_resources[0].end += RSET_EHCI_SIZE - 1;
+ ehci_resources[1].start = bcm63xx_get_irq_number(IRQ_EHCI0);
+ return platform_device_register(&bcm63xx_ehci_device);
+}
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_ehci.h
@@ -0,0 +1,6 @@
+#ifndef BCM63XX_DEV_USB_EHCI_H_
+#define BCM63XX_DEV_USB_EHCI_H_
+
+int bcm63xx_ehci_register(void);
+
+#endif /* BCM63XX_DEV_USB_EHCI_H_ */

View file

@ -1,65 +0,0 @@
From a4d005c91d403d9f3d0272db6cc46202c06ec774 Mon Sep 17 00:00:00 2001
From: Axel Gembe <ago@bastart.eu.org>
Date: Mon, 12 May 2008 18:54:09 +0200
Subject: [PATCH] bcm963xx: flashmap support
Signed-off-by: Axel Gembe <ago@bastart.eu.org>
---
arch/mips/bcm63xx/boards/board_bcm963xx.c | 19 +----------------
drivers/mtd/maps/bcm963xx-flash.c | 32 ++++++++++++++++++++++++----
drivers/mtd/redboot.c | 13 +++++++++--
3 files changed, 38 insertions(+), 26 deletions(-)
--- a/arch/mips/bcm63xx/dev-flash.c
+++ b/arch/mips/bcm63xx/dev-flash.c
@@ -30,7 +30,7 @@ static struct mtd_partition mtd_partitio
}
};
-static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL };
+static const char *bcm63xx_part_types[] = { "bcm63xxpart", "RedBoot", NULL };
static struct physmap_flash_data flash_data = {
.width = 2,
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -72,6 +72,7 @@ static int parse_redboot_partitions(stru
int nulllen = 0;
int numslots;
unsigned long offset;
+ unsigned long fis_origin = 0;
#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
static char nullstring[] = "unallocated";
#endif
@@ -178,6 +179,16 @@ static int parse_redboot_partitions(stru
goto out;
}
+ if (data && data->origin) {
+ fis_origin = data->origin;
+ } else {
+ for (i = 0; i < numslots; i++) {
+ if (!strncmp(buf[i].name, "RedBoot", 8)) {
+ fis_origin = (buf[i].flash_base & (master->size << 1) - 1);
+ }
+ }
+ }
+
for (i = 0; i < numslots; i++) {
struct fis_list *new_fl, **prev;
@@ -198,10 +209,10 @@ static int parse_redboot_partitions(stru
goto out;
}
new_fl->img = &buf[i];
- if (data && data->origin)
- buf[i].flash_base -= data->origin;
- else
- buf[i].flash_base &= master->size-1;
+ if (fis_origin)
+ buf[i].flash_base -= fis_origin;
+
+ buf[i].flash_base &= (master->size << 1) - 1;
/* I'm sure the JFFS2 code has done me permanent damage.
* I now think the following is _normal_

View file

@ -1,27 +0,0 @@
--- a/include/linux/bcm963xx_tag.h
+++ b/include/linux/bcm963xx_tag.h
@@ -85,8 +85,10 @@ struct bcm_tag {
__u32 rootfs_crc;
/* 224-227: CRC32 of kernel partition */
__u32 kernel_crc;
- /* 228-235: Unused at present */
- char reserved1[8];
+ /* 228-231: Image sequence number */
+ char image_sequence[4];
+ /* 222-235: Openwrt: real rootfs length */
+ __u32 real_rootfs_length;
/* 236-239: CRC32 of header excluding last 20 bytes */
__u32 header_crc;
/* 240-255: Unused at present */
--- a/drivers/mtd/bcm63xxpart.c
+++ b/drivers/mtd/bcm63xxpart.c
@@ -131,7 +131,8 @@ static int bcm63xx_parse_cfe_partitions(
} else {
/* OpenWrt layout */
rootfsaddr = kerneladdr + kernellen;
- rootfslen = spareaddr - rootfsaddr;
+ rootfslen = buf->real_rootfs_length;
+ spareaddr = rootfsaddr + rootfslen;
}
} else {
pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n",

View file

@ -1,11 +0,0 @@
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -1515,7 +1515,7 @@ static int compute_hw_mtu(struct bcm_ene
actual_mtu = mtu;
/* add ethernet header + vlan tag size */
- actual_mtu += VLAN_ETH_HLEN;
+ actual_mtu += VLAN_ETH_HLEN + VLAN_HLEN;
if (actual_mtu < 64 || actual_mtu > BCMENET_MAX_MTU)
return -EINVAL;

View file

@ -1,22 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -855,6 +855,8 @@ void __init board_prom_init(void)
if (BCMCPU_IS_6348())
val |= GPIO_MODE_6348_G3_EXT_MII |
GPIO_MODE_6348_G0_EXT_MII;
+ else if (BCMCPU_IS_6358())
+ val |= GPIO_MODE_6358_ENET1_MII_CLK_INV;
}
bcm_gpio_writel(val, GPIO_MODE_REG);
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -563,6 +563,8 @@
#define GPIO_MODE_6358_EXTRA_SPI_SS (1 << 7)
#define GPIO_MODE_6358_SERIAL_LED (1 << 10)
#define GPIO_MODE_6358_UTOPIA (1 << 12)
+#define GPIO_MODE_6358_ENET1_MII_CLK_INV (1 << 30)
+#define GPIO_MODE_6358_ENET0_MII_CLK_INV (1 << 31)
#define GPIO_MODE_6368_ANALOG_AFE_0 (1 << 0)
#define GPIO_MODE_6368_ANALOG_AFE_1 (1 << 1)

View file

@ -1,169 +0,0 @@
From b11218c750ab92cfab4408a0328f1b36ceec3f33 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Fri, 6 Jan 2012 12:24:18 +0100
Subject: [PATCH 19/63] NET: bcm63xx_enet: move phy_(dis)connect into probe/remove
Only connect/disconnect the phy during probe and remove, not during any
open/close. The phy seldom changes during the runtime, and disconnecting
the phy during close will prevent it from keeping any configuration over
a down/up cycle.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 84 +++++++++++++-------------
1 files changed, 41 insertions(+), 43 deletions(-)
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -784,10 +784,8 @@ static int bcm_enet_open(struct net_devi
struct bcm_enet_priv *priv;
struct sockaddr addr;
struct device *kdev;
- struct phy_device *phydev;
int i, ret;
unsigned int size;
- char phy_id[MII_BUS_ID_SIZE + 3];
void *p;
u32 val;
@@ -795,40 +793,10 @@ static int bcm_enet_open(struct net_devi
kdev = &priv->pdev->dev;
if (priv->has_phy) {
- /* connect to PHY */
- snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
- priv->mii_bus->id, priv->phy_id);
-
- phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link, 0,
- PHY_INTERFACE_MODE_MII);
-
- if (IS_ERR(phydev)) {
- dev_err(kdev, "could not attach to PHY\n");
- return PTR_ERR(phydev);
- }
-
- /* mask with MAC supported features */
- phydev->supported &= (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_MII);
- phydev->advertising = phydev->supported;
-
- if (priv->pause_auto && priv->pause_rx && priv->pause_tx)
- phydev->advertising |= SUPPORTED_Pause;
- else
- phydev->advertising &= ~SUPPORTED_Pause;
-
- dev_info(kdev, "attached PHY at address %d [%s]\n",
- phydev->addr, phydev->drv->name);
-
+ /* Reset state */
priv->old_link = 0;
priv->old_duplex = -1;
priv->old_pause = -1;
- priv->phydev = phydev;
}
/* mask all interrupts and request them */
@@ -838,7 +806,7 @@ static int bcm_enet_open(struct net_devi
ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev);
if (ret)
- goto out_phy_disconnect;
+ return ret;
ret = request_irq(priv->irq_rx, bcm_enet_isr_dma, IRQF_DISABLED,
dev->name, dev);
@@ -1025,9 +993,6 @@ out_freeirq_rx:
out_freeirq:
free_irq(dev->irq, dev);
-out_phy_disconnect:
- phy_disconnect(priv->phydev);
-
return ret;
}
@@ -1132,12 +1097,6 @@ static int bcm_enet_stop(struct net_devi
free_irq(priv->irq_rx, dev);
free_irq(dev->irq, dev);
- /* release phy */
- if (priv->has_phy) {
- phy_disconnect(priv->phydev);
- priv->phydev = NULL;
- }
-
return 0;
}
@@ -1714,6 +1673,8 @@ static int __devinit bcm_enet_probe(stru
/* MII bus registration */
if (priv->has_phy) {
+ struct phy_device *phydev;
+ char phy_id[MII_BUS_ID_SIZE + 3];
priv->mii_bus = mdiobus_alloc();
if (!priv->mii_bus) {
@@ -1750,6 +1711,38 @@ static int __devinit bcm_enet_probe(stru
dev_err(&pdev->dev, "unable to register mdio bus\n");
goto out_free_mdio;
}
+
+ /* connect to PHY */
+ snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
+ priv->mii_bus->id, priv->phy_id);
+
+ phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link, 0,
+ PHY_INTERFACE_MODE_MII);
+
+ if (IS_ERR(phydev)) {
+ dev_err(&pdev->dev, "could not attach to PHY\n");
+ goto out_unregister_mdio;
+ }
+
+ /* mask with MAC supported features */
+ phydev->supported &= (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_MII);
+ phydev->advertising = phydev->supported;
+
+ if (priv->pause_auto && priv->pause_rx && priv->pause_tx)
+ phydev->advertising |= SUPPORTED_Pause;
+ else
+ phydev->advertising &= ~SUPPORTED_Pause;
+
+ dev_info(&pdev->dev, "attached PHY at address %d [%s]\n",
+ phydev->addr, phydev->drv->name);
+
+ priv->phydev = phydev;
} else {
/* run platform code to initialize PHY device */
@@ -1795,6 +1788,9 @@ static int __devinit bcm_enet_probe(stru
return 0;
out_unregister_mdio:
+ if (priv->phydev)
+ phy_disconnect(priv->phydev);
+
if (priv->mii_bus) {
mdiobus_unregister(priv->mii_bus);
kfree(priv->mii_bus->irq);
@@ -1845,6 +1841,8 @@ static int __devexit bcm_enet_remove(str
enet_writel(priv, 0, ENET_MIISC_REG);
if (priv->has_phy) {
+ phy_disconnect(priv->phydev);
+ priv->phydev = NULL;
mdiobus_unregister(priv->mii_bus);
kfree(priv->mii_bus->irq);
mdiobus_free(priv->mii_bus);

View file

@ -1,40 +0,0 @@
From accc558f334662c8b16c121b4819931c028e8eb0 Mon Sep 17 00:00:00 2001
From: Maxime Bizon <mbizon@freebox.fr>
Date: Mon, 8 Jun 2009 16:12:10 +0200
Subject: [PATCH 27/63] bcm63xx_enet: implement reset_autoneg ethtool.
---
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 15 +++++++++++++++
1 files changed, 15 insertions(+), 0 deletions(-)
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -1290,6 +1290,20 @@ static void bcm_enet_get_ethtool_stats(s
mutex_unlock(&priv->mib_update_lock);
}
+static int bcm_enet_nway_reset(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+ if (priv->has_phy) {
+ if (!priv->phydev)
+ return -ENODEV;
+ return genphy_restart_aneg(priv->phydev);
+ }
+
+ return -EOPNOTSUPP;
+}
+
static int bcm_enet_get_settings(struct net_device *dev,
struct ethtool_cmd *cmd)
{
@@ -1432,6 +1446,7 @@ static const struct ethtool_ops bcm_enet
.get_strings = bcm_enet_get_strings,
.get_sset_count = bcm_enet_get_sset_count,
.get_ethtool_stats = bcm_enet_get_ethtool_stats,
+ .nway_reset = bcm_enet_nway_reset,
.get_settings = bcm_enet_get_settings,
.set_settings = bcm_enet_set_settings,
.get_drvinfo = bcm_enet_get_drvinfo,

View file

@ -1,69 +0,0 @@
From dbd9b51204aa4114756b8659e180139ef3878032 Mon Sep 17 00:00:00 2001
From: Maxime Bizon <mbizon@freebox.fr>
Date: Thu, 21 Jan 2010 17:28:36 +0100
Subject: [PATCH 28/63] bcm63xx_enet: use resource_size().
---
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 18 ++++++++----------
1 files changed, 8 insertions(+), 10 deletions(-)
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -1594,7 +1594,6 @@ static int __devinit bcm_enet_probe(stru
struct resource *res_mem, *res_irq, *res_irq_rx, *res_irq_tx;
struct mii_bus *bus;
const char *clk_name;
- unsigned int iomem_size;
int i, ret;
/* stop if shared driver failed, assume driver->probe will be
@@ -1619,13 +1618,13 @@ static int __devinit bcm_enet_probe(stru
if (ret)
goto out;
- iomem_size = resource_size(res_mem);
- if (!request_mem_region(res_mem->start, iomem_size, "bcm63xx_enet")) {
+ if (!request_mem_region(res_mem->start, resource_size(res_mem),
+ "bcm63xx_enet")) {
ret = -EBUSY;
goto out;
}
- priv->base = ioremap(res_mem->start, iomem_size);
+ priv->base = ioremap(res_mem->start, resource_size(res_mem));
if (priv->base == NULL) {
ret = -ENOMEM;
goto out_release_mem;
@@ -1831,7 +1830,7 @@ out_unmap:
iounmap(priv->base);
out_release_mem:
- release_mem_region(res_mem->start, iomem_size);
+ release_mem_region(res_mem->start, resource_size(res_mem));
out:
free_netdev(dev);
return ret;
@@ -1903,19 +1902,18 @@ struct platform_driver bcm63xx_enet_driv
static int __devinit bcm_enet_shared_probe(struct platform_device *pdev)
{
struct resource *res;
- unsigned int iomem_size;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;
- iomem_size = resource_size(res);
- if (!request_mem_region(res->start, iomem_size, "bcm63xx_enet_dma"))
+ if (!request_mem_region(res->start, resource_size(res),
+ "bcm63xx_enet_dma"))
return -EBUSY;
- bcm_enet_shared_base = ioremap(res->start, iomem_size);
+ bcm_enet_shared_base = ioremap(res->start, resource_size(res));
if (!bcm_enet_shared_base) {
- release_mem_region(res->start, iomem_size);
+ release_mem_region(res->start, resource_size(res));
return -ENOMEM;
}
return 0;

View file

@ -1,20 +0,0 @@
From fd15ecd10c95480be5635f8993b781fe3a1527c2 Mon Sep 17 00:00:00 2001
From: Maxime Bizon <mbizon@freebox.fr>
Date: Fri, 29 Apr 2011 16:54:50 +0200
Subject: [PATCH 29/63] bcm63xx_enet: disable clock when uninitializing device.
---
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -1870,6 +1870,8 @@ static int __devexit bcm_enet_remove(str
}
/* release device resources */
+ clk_disable(priv->mac_clk);
+ clk_put(priv->mac_clk);
iounmap(priv->base);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(res->start, resource_size(res));

View file

@ -1,381 +0,0 @@
From 305579c1f946ed1aa6c125252ace21c53d47c11d Mon Sep 17 00:00:00 2001
From: Maxime Bizon <mbizon@freebox.fr>
Date: Thu, 21 Jan 2010 17:50:54 +0100
Subject: [PATCH 30/63] bcm63xx_enet: split dma registers access.
---
arch/mips/bcm63xx/dev-enet.c | 23 +++-
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 4 +-
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 179 ++++++++++++++--------
3 files changed, 138 insertions(+), 68 deletions(-)
--- a/arch/mips/bcm63xx/dev-enet.c
+++ b/arch/mips/bcm63xx/dev-enet.c
@@ -19,6 +19,16 @@ static struct resource shared_res[] = {
.end = -1, /* filled at runtime */
.flags = IORESOURCE_MEM,
},
+ {
+ .start = -1, /* filled at runtime */
+ .end = -1, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = -1, /* filled at runtime */
+ .end = -1, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
};
static struct platform_device bcm63xx_enet_shared_device = {
@@ -110,10 +120,15 @@ int __init bcm63xx_enet_register(int uni
if (!shared_device_registered) {
shared_res[0].start = bcm63xx_regset_address(RSET_ENETDMA);
shared_res[0].end = shared_res[0].start;
- if (BCMCPU_IS_6338())
- shared_res[0].end += (RSET_ENETDMA_SIZE / 2) - 1;
- else
- shared_res[0].end += (RSET_ENETDMA_SIZE) - 1;
+ shared_res[0].end += (RSET_ENETDMA_SIZE) - 1;
+
+ shared_res[1].start = bcm63xx_regset_address(RSET_ENETDMAC);
+ shared_res[1].end = shared_res[1].start;
+ shared_res[1].end += RSET_ENETDMAC_SIZE(16) - 1;
+
+ shared_res[2].start = bcm63xx_regset_address(RSET_ENETDMAS);
+ shared_res[2].end = shared_res[2].start;
+ shared_res[2].end += RSET_ENETDMAS_SIZE(16) - 1;
ret = platform_device_register(&bcm63xx_enet_shared_device);
if (ret)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -172,7 +172,9 @@ enum bcm63xx_regs_set {
#define BCM_6358_RSET_SPI_SIZE 1804
#define BCM_6368_RSET_SPI_SIZE 1804
#define RSET_ENET_SIZE 2048
-#define RSET_ENETDMA_SIZE 2048
+#define RSET_ENETDMA_SIZE 256
+#define RSET_ENETDMAC_SIZE(chans) (16 * (chans))
+#define RSET_ENETDMAS_SIZE(chans) (16 * (chans))
#define RSET_ENETSW_SIZE 65536
#define RSET_UART_SIZE 24
#define RSET_HSSPI_SIZE 1536
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -41,8 +41,8 @@ static int copybreak __read_mostly = 128
module_param(copybreak, int, 0);
MODULE_PARM_DESC(copybreak, "Receive copy threshold");
-/* io memory shared between all devices */
-static void __iomem *bcm_enet_shared_base;
+/* io registers memory shared between all devices */
+static void __iomem *bcm_enet_shared_base[3];
/*
* io helpers to access mac registers
@@ -63,13 +63,35 @@ static inline void enet_writel(struct bc
*/
static inline u32 enet_dma_readl(struct bcm_enet_priv *priv, u32 off)
{
- return bcm_readl(bcm_enet_shared_base + off);
+ return bcm_readl(bcm_enet_shared_base[0] + off);
}
static inline void enet_dma_writel(struct bcm_enet_priv *priv,
u32 val, u32 off)
{
- bcm_writel(val, bcm_enet_shared_base + off);
+ bcm_writel(val, bcm_enet_shared_base[0] + off);
+}
+
+static inline u32 enet_dmac_readl(struct bcm_enet_priv *priv, u32 off)
+{
+ return bcm_readl(bcm_enet_shared_base[1] + off);
+}
+
+static inline void enet_dmac_writel(struct bcm_enet_priv *priv,
+ u32 val, u32 off)
+{
+ bcm_writel(val, bcm_enet_shared_base[1] + off);
+}
+
+static inline u32 enet_dmas_readl(struct bcm_enet_priv *priv, u32 off)
+{
+ return bcm_readl(bcm_enet_shared_base[2] + off);
+}
+
+static inline void enet_dmas_writel(struct bcm_enet_priv *priv,
+ u32 val, u32 off)
+{
+ bcm_writel(val, bcm_enet_shared_base[2] + off);
}
/*
@@ -353,8 +375,8 @@ static int bcm_enet_receive_queue(struct
bcm_enet_refill_rx(dev);
/* kick rx dma */
- enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
- ENETDMA_CHANCFG_REG(priv->rx_chan));
+ enet_dmac_writel(priv, ENETDMAC_CHANCFG_EN_MASK,
+ ENETDMAC_CHANCFG_REG(priv->rx_chan));
}
return processed;
@@ -429,10 +451,10 @@ static int bcm_enet_poll(struct napi_str
dev = priv->net_dev;
/* ack interrupts */
- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
- ENETDMA_IR_REG(priv->rx_chan));
- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
- ENETDMA_IR_REG(priv->tx_chan));
+ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
+ ENETDMAC_IR_REG(priv->rx_chan));
+ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
+ ENETDMAC_IR_REG(priv->tx_chan));
/* reclaim sent skb */
tx_work_done = bcm_enet_tx_reclaim(dev, 0);
@@ -451,10 +473,10 @@ static int bcm_enet_poll(struct napi_str
napi_complete(napi);
/* restore rx/tx interrupt */
- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
- ENETDMA_IRMASK_REG(priv->rx_chan));
- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
- ENETDMA_IRMASK_REG(priv->tx_chan));
+ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
+ ENETDMAC_IRMASK_REG(priv->rx_chan));
+ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
+ ENETDMAC_IRMASK_REG(priv->tx_chan));
return rx_work_done;
}
@@ -497,8 +519,8 @@ static irqreturn_t bcm_enet_isr_dma(int
priv = netdev_priv(dev);
/* mask rx/tx interrupts */
- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->rx_chan));
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->tx_chan));
napi_schedule(&priv->napi);
@@ -557,8 +579,8 @@ static int bcm_enet_start_xmit(struct sk
wmb();
/* kick tx dma */
- enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
- ENETDMA_CHANCFG_REG(priv->tx_chan));
+ enet_dmac_writel(priv, ENETDMAC_CHANCFG_EN_MASK,
+ ENETDMAC_CHANCFG_REG(priv->tx_chan));
/* stop queue if no more desc available */
if (!priv->tx_desc_count)
@@ -801,8 +823,8 @@ static int bcm_enet_open(struct net_devi
/* mask all interrupts and request them */
enet_writel(priv, 0, ENET_IRMASK_REG);
- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->rx_chan));
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->tx_chan));
ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev);
if (ret)
@@ -891,28 +913,28 @@ static int bcm_enet_open(struct net_devi
}
/* write rx & tx ring addresses */
- enet_dma_writel(priv, priv->rx_desc_dma,
- ENETDMA_RSTART_REG(priv->rx_chan));
- enet_dma_writel(priv, priv->tx_desc_dma,
- ENETDMA_RSTART_REG(priv->tx_chan));
+ enet_dmas_writel(priv, priv->rx_desc_dma,
+ ENETDMAS_RSTART_REG(priv->rx_chan));
+ enet_dmas_writel(priv, priv->tx_desc_dma,
+ ENETDMAS_RSTART_REG(priv->tx_chan));
/* clear remaining state ram for rx & tx channel */
- enet_dma_writel(priv, 0, ENETDMA_SRAM2_REG(priv->rx_chan));
- enet_dma_writel(priv, 0, ENETDMA_SRAM2_REG(priv->tx_chan));
- enet_dma_writel(priv, 0, ENETDMA_SRAM3_REG(priv->rx_chan));
- enet_dma_writel(priv, 0, ENETDMA_SRAM3_REG(priv->tx_chan));
- enet_dma_writel(priv, 0, ENETDMA_SRAM4_REG(priv->rx_chan));
- enet_dma_writel(priv, 0, ENETDMA_SRAM4_REG(priv->tx_chan));
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM2_REG(priv->rx_chan));
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM2_REG(priv->tx_chan));
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM3_REG(priv->rx_chan));
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM3_REG(priv->tx_chan));
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG(priv->rx_chan));
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG(priv->tx_chan));
/* set max rx/tx length */
enet_writel(priv, priv->hw_mtu, ENET_RXMAXLEN_REG);
enet_writel(priv, priv->hw_mtu, ENET_TXMAXLEN_REG);
/* set dma maximum burst len */
- enet_dma_writel(priv, BCMENET_DMA_MAXBURST,
- ENETDMA_MAXBURST_REG(priv->rx_chan));
- enet_dma_writel(priv, BCMENET_DMA_MAXBURST,
- ENETDMA_MAXBURST_REG(priv->tx_chan));
+ enet_dmac_writel(priv, BCMENET_DMA_MAXBURST,
+ ENETDMAC_MAXBURST_REG(priv->rx_chan));
+ enet_dmac_writel(priv, BCMENET_DMA_MAXBURST,
+ ENETDMAC_MAXBURST_REG(priv->tx_chan));
/* set correct transmit fifo watermark */
enet_writel(priv, BCMENET_TX_FIFO_TRESH, ENET_TXWMARK_REG);
@@ -930,26 +952,26 @@ static int bcm_enet_open(struct net_devi
val |= ENET_CTL_ENABLE_MASK;
enet_writel(priv, val, ENET_CTL_REG);
enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG);
- enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
- ENETDMA_CHANCFG_REG(priv->rx_chan));
+ enet_dmac_writel(priv, ENETDMAC_CHANCFG_EN_MASK,
+ ENETDMAC_CHANCFG_REG(priv->rx_chan));
/* watch "mib counters about to overflow" interrupt */
enet_writel(priv, ENET_IR_MIB, ENET_IR_REG);
enet_writel(priv, ENET_IR_MIB, ENET_IRMASK_REG);
/* watch "packet transferred" interrupt in rx and tx */
- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
- ENETDMA_IR_REG(priv->rx_chan));
- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
- ENETDMA_IR_REG(priv->tx_chan));
+ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
+ ENETDMAC_IR_REG(priv->rx_chan));
+ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
+ ENETDMAC_IR_REG(priv->tx_chan));
/* make sure we enable napi before rx interrupt */
napi_enable(&priv->napi);
- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
- ENETDMA_IRMASK_REG(priv->rx_chan));
- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
- ENETDMA_IRMASK_REG(priv->tx_chan));
+ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
+ ENETDMAC_IRMASK_REG(priv->rx_chan));
+ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
+ ENETDMAC_IRMASK_REG(priv->tx_chan));
if (priv->has_phy)
phy_start(priv->phydev);
@@ -1026,14 +1048,14 @@ static void bcm_enet_disable_dma(struct
{
int limit;
- enet_dma_writel(priv, 0, ENETDMA_CHANCFG_REG(chan));
+ enet_dmac_writel(priv, 0, ENETDMAC_CHANCFG_REG(chan));
limit = 1000;
do {
u32 val;
- val = enet_dma_readl(priv, ENETDMA_CHANCFG_REG(chan));
- if (!(val & ENETDMA_CHANCFG_EN_MASK))
+ val = enet_dmac_readl(priv, ENETDMAC_CHANCFG_REG(chan));
+ if (!(val & ENETDMAC_CHANCFG_EN_MASK))
break;
udelay(1);
} while (limit--);
@@ -1059,8 +1081,8 @@ static int bcm_enet_stop(struct net_devi
/* mask all interrupts */
enet_writel(priv, 0, ENET_IRMASK_REG);
- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->rx_chan));
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->tx_chan));
/* make sure no mib update is scheduled */
cancel_work_sync(&priv->mib_update_task);
@@ -1598,7 +1620,7 @@ static int __devinit bcm_enet_probe(stru
/* stop if shared driver failed, assume driver->probe will be
* called in the same order we register devices (correct ?) */
- if (!bcm_enet_shared_base)
+ if (!bcm_enet_shared_base[0])
return -ENODEV;
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1904,30 +1926,61 @@ struct platform_driver bcm63xx_enet_driv
static int __devinit bcm_enet_shared_probe(struct platform_device *pdev)
{
struct resource *res;
+ int ret, i, requested[3];
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENODEV;
+ memset(bcm_enet_shared_base, 0, sizeof (bcm_enet_shared_base));
+ memset(requested, 0, sizeof (requested));
- if (!request_mem_region(res->start, resource_size(res),
- "bcm63xx_enet_dma"))
- return -EBUSY;
+ for (i = 0; i < 3; i++) {
+ void __iomem *p;
- bcm_enet_shared_base = ioremap(res->start, resource_size(res));
- if (!bcm_enet_shared_base) {
- release_mem_region(res->start, resource_size(res));
- return -ENOMEM;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ if (!res) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (!request_mem_region(res->start, resource_size(res),
+ "bcm63xx_enet_dma")) {
+ ret = -EBUSY;
+ goto fail;
+ }
+ requested[i] = 0;
+
+ p = ioremap(res->start, resource_size(res));
+ if (!p) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ bcm_enet_shared_base[i] = p;
}
+
return 0;
+
+fail:
+ for (i = 0; i < 3; i++) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ if (!res)
+ continue;
+ if (bcm_enet_shared_base[i])
+ iounmap(bcm_enet_shared_base[i]);
+ if (requested[i])
+ release_mem_region(res->start, resource_size(res));
+ }
+ return ret;
}
static int __devexit bcm_enet_shared_remove(struct platform_device *pdev)
{
struct resource *res;
+ int i;
- iounmap(bcm_enet_shared_base);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, resource_size(res));
+ for (i = 0; i < 3; i++) {
+ iounmap(bcm_enet_shared_base[i]);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ release_mem_region(res->start, resource_size(res));
+ }
return 0;
}

View file

@ -1,28 +0,0 @@
From 6d5c5bb13db3fd8e3dd0b82742b3957f41a4a3ac Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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 <jonas.gorski@gmail.com>
---
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 */

View file

@ -1,20 +0,0 @@
From e79bc74f76361020d820ed4611d28f70ebd845ca Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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));

View file

@ -1,98 +0,0 @@
From efe31ec8fca92162fc21630611971345014a81a0 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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];

View file

@ -1,73 +0,0 @@
From ef581388c45dbc48f7bbe050e87deb1e3c63a698 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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_ */

View file

@ -1,69 +0,0 @@
From 625894c377ba266c0044675b53f05d65db6355b6 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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;

View file

@ -1,87 +0,0 @@
From 85e4551e033df7cb043e93042661fc1e58799efa Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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_ */

View file

@ -1,53 +0,0 @@
From d8237d704fc25eb2fc25ef4403608b78c6a6d4be Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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
@@ -838,6 +838,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;

View file

@ -1,93 +0,0 @@
From 382a0b0dc4cbd0e0fbfd6c2d132e972c3d1245b0 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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 <jonas.gorski@gmail.com>
---
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;

View file

@ -1,103 +0,0 @@
From f1c1bfa89cdac76a215d0e21161da9f8f8373437 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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 <jonas.gorski@gmail.com>
---
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

View file

@ -1,128 +0,0 @@
From 56be5a2d7e08faa7bb306faaf352ac4e6ac52c01 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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 <jonas.gorski@gmail.com>
---
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 <bcm63xx_dev_enet.h>
#include <bcm63xx_dev_dsp.h>
#include <bcm63xx_dev_flash.h>
+#include <bcm63xx_dev_hsspi.h>
#include <bcm63xx_dev_pcmcia.h>
#include <bcm63xx_dev_spi.h>
#include <bcm63xx_dev_usb_ohci.h>
@@ -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 <jonas.gorski@gmail.com>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_hsspi.h>
+#include <bcm63xx_regs.h>
+
+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 <linux/types.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+
+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 */

View file

@ -1,481 +0,0 @@
From 4b27423676485d05bcd6fc6f3809164fb8f9d22d Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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 <jonas.gorski@gmail.com>
---
.../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 <jonas.gorski@gmail.com>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/spi/spi.h>
+#include <linux/workqueue.h>
+
+#include <bcm63xx_regs.h>
+#include <bcm63xx_dev_hsspi.h>
+
+#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 <jonas.gorski@gmail.com>");
+MODULE_LICENSE("GPL");

View file

@ -1,102 +0,0 @@
From d135d94b3d1fe599d13e7198d5f502912d694c13 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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 <jonas.gorski@gmail.com>
---
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 <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
#include <bcm63xx_cpu.h>
#include <bcm63xx_dev_flash.h>
+#include <bcm63xx_dev_hsspi.h>
#include <bcm63xx_regs.h>
#include <bcm63xx_io.h>
@@ -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
@@ -614,6 +614,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
@@ -1308,6 +1309,7 @@
#define STRAPBUS_6362_BOOT_SEL_NAND (0 << 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)

View file

@ -1,50 +0,0 @@
From d9666553a10ea85ea64e3e8784a42167a1709ed5 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Mon, 21 Nov 2011 00:48:52 +0100
Subject: [PATCH 55/84] MIPS: BCM63XX: add flash detection for BCM6362
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
arch/mips/bcm63xx/dev-flash.c | 13 ++++++++++++-
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 1 +
2 files changed, 13 insertions(+), 1 deletions(-)
--- a/arch/mips/bcm63xx/dev-flash.c
+++ b/arch/mips/bcm63xx/dev-flash.c
@@ -100,6 +100,17 @@ static int __init bcm63xx_detect_flash_t
return BCM63XX_FLASH_TYPE_PARALLEL;
else
return BCM63XX_FLASH_TYPE_SERIAL;
+ case BCM6362_CPU_ID:
+ val = bcm_misc_readl(MISC_STRAPBUS_6362_REG);
+ if (val & STRAPBUS_6362_HSSPI_CLK_FAST)
+ bcm63xx_spi_flash_info[0].max_speed_hz = 50000000;
+ else
+ bcm63xx_spi_flash_info[0].max_speed_hz = 20000000;
+
+ if (val & STRAPBUS_6362_BOOT_SEL_SERIAL)
+ return BCM63XX_FLASH_TYPE_SERIAL;
+ else
+ return BCM63XX_FLASH_TYPE_NAND;
case BCM6368_CPU_ID:
val = bcm_gpio_readl(GPIO_STRAPBUS_REG);
if (val & STRAPBUS_6368_SPI_CLK_FAST)
@@ -136,7 +147,7 @@ int __init bcm63xx_flash_register(void)
return platform_device_register(&mtd_dev);
case BCM63XX_FLASH_TYPE_SERIAL:
- if (BCMCPU_IS_6328())
+ if (BCMCPU_IS_6328() || BCMCPU_IS_6362())
bcm63xx_flash_data.max_transfer_len = HSSPI_BUFFER_LEN;
return spi_register_board_info(bcm63xx_spi_flash_info,
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -1304,6 +1304,7 @@
#define MISC_STRAPBUS_6362_REG 0x14
#define STRAPBUS_6362_FCVO_SHIFT 1
+#define STRAPBUS_6362_HSSPI_CLK_FAST (1 << 13)
#define STRAPBUS_6362_FCVO_MASK (0x1f << STRAPBUS_6362_FCVO_SHIFT)
#define STRAPBUS_6362_BOOT_SEL_SERIAL (1 << 15)
#define STRAPBUS_6362_BOOT_SEL_NAND (0 << 15)

View file

@ -1,351 +0,0 @@
From 5b753c1d01c6af23d7d37d37d9de30da8a971084 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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 <jonas.gorski@gmail.com>
---
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 <bcm63xx_dev_uart.h>
#include <bcm63xx_regs.h>
#include <bcm63xx_io.h>
+#include <bcm63xx_nvram.h>
#include <bcm63xx_dev_pci.h>
#include <bcm63xx_dev_enet.h>
#include <bcm63xx_dev_dsp.h>
@@ -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->board_id, BOARDID_LEN) != 0) {
+ if (strncmp(board_name, tag->board_id, BOARDID_LEN) != 0) {
/* else try 128k */
tag = (struct bcm_tag *)(boot_addr + CFE_OFFSET_128K);
- if (strncmp(nvram.name, tag->board_id, BOARDID_LEN) != 0) {
+ if (strncmp(board_name, tag->board_id, 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 <jonas.gorski@gmail.com>
+ */
+
+#define pr_fmt(fmt) "bcm63xx_nvram: " fmt
+
+#include <linux/init.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
+
+#include <bcm63xx_nvram.h>
+
+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 <linux/if_ether.h>
+
+#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 {

View file

@ -1,44 +0,0 @@
From ffbeb183bf0e9e12fd607c5352f48420c32f588f Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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 <jonas.gorski@gmail.com>
---
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 <bcm63xx_nvram.h>
+#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 */

View file

@ -1,29 +0,0 @@
From 658afad639a9456e1bb6fe5bba0032f3c0c3f699 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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 <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+#include <asm/mach-bcm63xx/bcm63xx_nvram.h>
#include <linux/bcm963xx_tag.h>
#include <asm/mach-bcm63xx/board_bcm963xx.h>
@@ -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));

View file

@ -1,41 +0,0 @@
From 266c506f4b262bd6aba0776a03d82c98e65d9906 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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__ */

View file

@ -1,81 +0,0 @@
From 5131195413b62df73dfd394fea272830ea8c4e1a Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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 <bcm63xx_dev_usb_ehci.h>
#include <board_bcm963xx.h>
#include <linux/bcm963xx_tag.h>
+#include <pci_ath9k_fixup.h>
#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(
@@ -933,5 +936,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 <linux/leds.h>
#include <bcm63xx_dev_enet.h>
#include <bcm63xx_dev_dsp.h>
+#include <pci_ath9k_fixup.h>
/*
* 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;

View file

@ -1,40 +0,0 @@
From 7f17dfe9009beb07a3de0e380932a725293829df Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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
@@ -887,6 +887,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 */

View file

@ -1,122 +0,0 @@
From f888824d352df894ab721a5ca067b0313500efe7 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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 <bcm63xx_regs.h>
#include <bcm63xx_io.h>
+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 BCM6362_CPU_ID:
val = bcm_misc_readl(MISC_STRAPBUS_6362_REG);
if (val & STRAPBUS_6362_HSSPI_CLK_FAST)
@@ -108,9 +113,10 @@ static int __init bcm63xx_detect_flash_t
bcm63xx_spi_flash_info[0].max_speed_hz = 20000000;
if (val & STRAPBUS_6362_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 BCM6368_CPU_ID:
val = bcm_gpio_readl(GPIO_STRAPBUS_REG);
if (val & STRAPBUS_6368_SPI_CLK_FAST)
@@ -118,25 +124,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));
@@ -157,7 +170,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 */

View file

@ -1,227 +0,0 @@
From fb6f6f58db9ae9cf27ab01f5f09cfbc5c078a7b8 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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 <jonas.gorski@gmail.com>
+ *
+ * Based on
+ *
+ * Atheros AP94 reference board PCI initialization
+ *
+ * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * 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 <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/ath9k_platform.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_nvram.h>
+#include <bcm63xx_dev_pci.h>
+#include <bcm63xx_dev_flash.h>
+#include <bcm63xx_dev_hsspi.h>
+#include <pci_ath9k_fixup.h>
+
+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 */

View file

@ -1,118 +0,0 @@
From 8ab86c5dc38ad4de1442e50e0adbc354d9184d71 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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;
};

View file

@ -1,82 +0,0 @@
From 977f8a30103b9c4992cab8f49357fe0d4274004f Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
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[] = {
@@ -142,10 +146,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 <board_bcm963xx.h>
+
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 */

View file

@ -1,60 +0,0 @@
From 38c3f8d21da90f0833578a157e22ddabf4d576bd Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Sun, 12 Feb 2012 14:28:34 +0100
Subject: [PATCH 48/84] MIPS: BCM63XX: enable USB for BCM6328
The USB controller is the same as the one on BCM6368.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
arch/mips/bcm63xx/dev-usb-ehci.c | 2 +-
arch/mips/bcm63xx/dev-usb-ohci.c | 3 ++-
drivers/usb/host/ehci-bcm63xx.c | 2 +-
drivers/usb/host/ohci-bcm63xx.c | 2 +-
4 files changed, 5 insertions(+), 4 deletions(-)
--- a/arch/mips/bcm63xx/dev-usb-ehci.c
+++ b/arch/mips/bcm63xx/dev-usb-ehci.c
@@ -39,7 +39,7 @@ static struct platform_device bcm63xx_eh
int __init bcm63xx_ehci_register(void)
{
- if (!BCMCPU_IS_6358() && !BCMCPU_IS_6368())
+ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6358() && !BCMCPU_IS_6368())
return 0;
ehci_resources[0].start = bcm63xx_regset_address(RSET_EHCI0);
--- a/arch/mips/bcm63xx/dev-usb-ohci.c
+++ b/arch/mips/bcm63xx/dev-usb-ohci.c
@@ -39,7 +39,8 @@ static struct platform_device bcm63xx_oh
int __init bcm63xx_ohci_register(void)
{
- if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358() && !BCMCPU_IS_6368())
+ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6348() && !BCMCPU_IS_6358() &&
+ !BCMCPU_IS_6368())
return 0;
ohci_resources[0].start = bcm63xx_regset_address(RSET_OHCI0);
--- a/drivers/usb/host/ehci-bcm63xx.c
+++ b/drivers/usb/host/ehci-bcm63xx.c
@@ -99,7 +99,7 @@ static int __devinit ehci_hcd_bcm63xx_dr
bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020,
USBH_PRIV_TEST_6358_REG);
- } else if (BCMCPU_IS_6368()) {
+ } else if (BCMCPU_IS_6328() || BCMCPU_IS_6368()) {
reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG);
reg &= ~USBH_PRIV_SWAP_EHCI_DATA_MASK;
--- a/drivers/usb/host/ohci-bcm63xx.c
+++ b/drivers/usb/host/ohci-bcm63xx.c
@@ -94,7 +94,7 @@ static int __devinit ohci_hcd_bcm63xx_dr
bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020,
USBH_PRIV_TEST_6358_REG);
- } else if (BCMCPU_IS_6368()) {
+ } else if (BCMCPU_IS_6328() || BCMCPU_IS_6368()) {
reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG);
reg &= ~USBH_PRIV_SWAP_OHCI_ENDN_MASK;
reg |= USBH_PRIV_SWAP_OHCI_DATA_MASK;

View file

@ -1,56 +0,0 @@
From ed225910f0e062d9c28d5cf216f97b3cf457a8c5 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Mon, 21 Nov 2011 00:55:49 +0100
Subject: [PATCH 58/81] MIPS: BCM63XX: wire up the HS SPI controller for BCM6362
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
arch/mips/bcm63xx/clk.c | 2 ++
arch/mips/bcm63xx/dev-hsspi.c | 7 +++++--
.../include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h | 1 +
3 files changed, 8 insertions(+), 2 deletions(-)
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -218,6 +218,8 @@ static void hsspi_set(struct clk *clk, i
if (BCMCPU_IS_6328())
mask = CKCTL_6328_HSSPI_EN;
+ else if (BCMCPU_IS_6362())
+ mask = CKCTL_6362_HSSPI_EN;
else
return;
--- a/arch/mips/bcm63xx/dev-hsspi.c
+++ b/arch/mips/bcm63xx/dev-hsspi.c
@@ -43,7 +43,7 @@ static struct platform_device bcm63xx_hs
int __init bcm63xx_hsspi_register(void)
{
- if (!BCMCPU_IS_6328())
+ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6362())
return -ENODEV;
spi_resources[0].start = bcm63xx_regset_address(RSET_HSSPI);
@@ -51,7 +51,10 @@ int __init bcm63xx_hsspi_register(void)
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;
+ if (BCMCPU_IS_6328())
+ spi_pdata.speed_hz = HSSPI_PLL_HZ_6328;
+ else
+ spi_pdata.speed_hz = HSSPI_PLL_HZ;
return platform_device_register(&bcm63xx_hsspi_device);
}
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h
@@ -16,6 +16,7 @@ struct bcm63xx_hsspi_pdata {
#define bcm_hsspi_writel(v, o) bcm_rset_writel(RSET_HSSPI, (v), (o))
#define HSSPI_PLL_HZ_6328 133333333
+#define HSSPI_PLL_HZ 400000000
#define HSSPI_BUFFER_LEN 512

View file

@ -1,101 +0,0 @@
From eef84812bc7ffd590da6ad6b83bfeebaa43a7055 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Thu, 5 Jul 2012 21:19:20 +0200
Subject: [PATCH 58/84] MIPS: BCM63XX: enable SPI controller for BCM6362
---
arch/mips/bcm63xx/clk.c | 2 ++
arch/mips/bcm63xx/dev-spi.c | 11 ++++++++++-
.../include/asm/mach-bcm63xx/bcm63xx_dev_spi.h | 3 +++
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 16 ++++++++++++++++
4 files changed, 31 insertions(+), 1 deletions(-)
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -199,6 +199,8 @@ static void spi_set(struct clk *clk, int
mask = CKCTL_6348_SPI_EN;
else if (BCMCPU_IS_6358())
mask = CKCTL_6358_SPI_EN;
+ else if (BCMCPU_IS_6362())
+ mask = CKCTL_6362_SPI_EN;
else
/* BCMCPU_IS_6368 */
mask = CKCTL_6368_SPI_EN;
--- a/arch/mips/bcm63xx/dev-spi.c
+++ b/arch/mips/bcm63xx/dev-spi.c
@@ -34,6 +34,10 @@ static const unsigned long bcm6358_regs_
__GEN_SPI_REGS_TABLE(6358)
};
+static const unsigned long bcm6362_regs_spi[] = {
+ __GEN_SPI_REGS_TABLE(6362)
+};
+
static const unsigned long bcm6368_regs_spi[] = {
__GEN_SPI_REGS_TABLE(6368)
};
@@ -49,6 +53,8 @@ static __init void bcm63xx_spi_regs_init
bcm63xx_regs_spi = bcm6348_regs_spi;
if (BCMCPU_IS_6358())
bcm63xx_regs_spi = bcm6358_regs_spi;
+ if (BCMCPU_IS_6362())
+ bcm63xx_regs_spi = bcm6362_regs_spi;
if (BCMCPU_IS_6368())
bcm63xx_regs_spi = bcm6368_regs_spi;
}
@@ -99,6 +105,9 @@ int __init bcm63xx_spi_register(void)
/* Set bus frequency */
spi_pdata.speed_hz = clk_get_rate(periph_clk);
+ if (BCMCPU_IS_6362())
+ spi_pdata.bus_num = 1;
+
spi_resources[0].start = bcm63xx_regset_address(RSET_SPI);
spi_resources[0].end = spi_resources[0].start;
spi_resources[1].start = bcm63xx_get_irq_number(IRQ_SPI);
@@ -110,7 +119,7 @@ int __init bcm63xx_spi_register(void)
spi_pdata.msg_ctl_width = SPI_6338_MSG_CTL_WIDTH;
}
- if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
+ if (BCMCPU_IS_6358() || BCMCPU_IS_6362() || BCMCPU_IS_6368()) {
spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1;
spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE;
spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT;
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h
@@ -81,6 +81,9 @@ static inline unsigned long bcm63xx_spir
#ifdef CONFIG_BCM63XX_CPU_6358
__GEN_SPI_RSET(6358)
#endif
+#ifdef CONFIG_BCM63XX_CPU_6362
+ __GEN_SPI_RSET(6362)
+#endif
#ifdef CONFIG_BCM63XX_CPU_6368
__GEN_SPI_RSET(6368)
#endif
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -1223,6 +1223,22 @@
#define SPI_6358_MSG_TAIL 0x709
#define SPI_6358_RX_TAIL 0x70B
+/* BCM 6362 SPI core */
+#define SPI_6362_MSG_CTL 0x00 /* 16-bits register */
+#define SPI_6362_MSG_DATA 0x02
+#define SPI_6362_MSG_DATA_SIZE 0x21e
+#define SPI_6362_RX_DATA 0x400
+#define SPI_6362_RX_DATA_SIZE 0x220
+#define SPI_6362_CMD 0x700 /* 16-bits register */
+#define SPI_6362_INT_STATUS 0x702
+#define SPI_6362_INT_MASK_ST 0x703
+#define SPI_6362_INT_MASK 0x704
+#define SPI_6362_ST 0x705
+#define SPI_6362_CLK_CFG 0x706
+#define SPI_6362_FILL_BYTE 0x707
+#define SPI_6362_MSG_TAIL 0x709
+#define SPI_6362_RX_TAIL 0x70B
+
/* BCM 6358 SPI core */
#define SPI_6368_MSG_CTL 0x00 /* 16-bits register */
#define SPI_6368_MSG_CTL_WIDTH 16

View file

@ -1,84 +0,0 @@
From fb9e98936590637c26b66d60137a7b44b329a254 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Sun, 12 Feb 2012 14:40:56 +0100
Subject: [PATCH 59/84] MIPS: BCM63XX: enable USB for BCM6362
BCM6362 has the same USB controller as BCM6368.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
arch/mips/bcm63xx/Kconfig | 2 ++
arch/mips/bcm63xx/clk.c | 4 ++++
arch/mips/bcm63xx/dev-usb-ehci.c | 3 ++-
arch/mips/bcm63xx/dev-usb-ohci.c | 2 +-
drivers/usb/host/ehci-bcm63xx.c | 2 +-
drivers/usb/host/ohci-bcm63xx.c | 2 +-
6 files changed, 11 insertions(+), 4 deletions(-)
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -27,6 +27,8 @@ config BCM63XX_CPU_6358
config BCM63XX_CPU_6362
bool "support 6362 CPU"
select HW_HAS_PCI
+ select USB_ARCH_HAS_OHCI if USB_SUPPORT
+ select USB_ARCH_HAS_EHCI if USB_SUPPORT
config BCM63XX_CPU_6368
bool "support 6368 CPU"
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -178,6 +178,8 @@ static void usbh_set(struct clk *clk, in
{
if (BCMCPU_IS_6348())
bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
+ else if (BCMCPU_IS_6362())
+ bcm_hwclock_set(CKCTL_6362_USBH_EN, enable);
else if (BCMCPU_IS_6368())
bcm_hwclock_set(CKCTL_6368_USBH_EN, enable);
}
--- a/arch/mips/bcm63xx/dev-usb-ehci.c
+++ b/arch/mips/bcm63xx/dev-usb-ehci.c
@@ -39,7 +39,8 @@ static struct platform_device bcm63xx_eh
int __init bcm63xx_ehci_register(void)
{
- if (!BCMCPU_IS_6328() && !BCMCPU_IS_6358() && !BCMCPU_IS_6368())
+ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6358() && !BCMCPU_IS_6362() &&
+ !BCMCPU_IS_6368())
return 0;
ehci_resources[0].start = bcm63xx_regset_address(RSET_EHCI0);
--- a/arch/mips/bcm63xx/dev-usb-ohci.c
+++ b/arch/mips/bcm63xx/dev-usb-ohci.c
@@ -40,7 +40,7 @@ static struct platform_device bcm63xx_oh
int __init bcm63xx_ohci_register(void)
{
if (!BCMCPU_IS_6328() && !BCMCPU_IS_6348() && !BCMCPU_IS_6358() &&
- !BCMCPU_IS_6368())
+ !BCMCPU_IS_6362() && !BCMCPU_IS_6368())
return 0;
ohci_resources[0].start = bcm63xx_regset_address(RSET_OHCI0);
--- a/drivers/usb/host/ehci-bcm63xx.c
+++ b/drivers/usb/host/ehci-bcm63xx.c
@@ -99,7 +99,7 @@ static int __devinit ehci_hcd_bcm63xx_dr
bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020,
USBH_PRIV_TEST_6358_REG);
- } else if (BCMCPU_IS_6328() || BCMCPU_IS_6368()) {
+ } else if (BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_6368()) {
reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG);
reg &= ~USBH_PRIV_SWAP_EHCI_DATA_MASK;
--- a/drivers/usb/host/ohci-bcm63xx.c
+++ b/drivers/usb/host/ohci-bcm63xx.c
@@ -94,7 +94,7 @@ static int __devinit ohci_hcd_bcm63xx_dr
bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020,
USBH_PRIV_TEST_6358_REG);
- } else if (BCMCPU_IS_6328() || BCMCPU_IS_6368()) {
+ } else if (BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_6368()) {
reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG);
reg &= ~USBH_PRIV_SWAP_OHCI_ENDN_MASK;
reg |= USBH_PRIV_SWAP_OHCI_DATA_MASK;

View file

@ -1,77 +0,0 @@
From bf9d506bd144b95f8bb4127350ab2db5fba9c12e Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@gmail.com>
Date: Sun, 8 Jul 2012 21:07:12 +0200
Subject: [PATCH 60/84] MIPS: BCM63XX: enable enetsw for BCM6362
---
arch/mips/bcm63xx/clk.c | 7 ++++++-
arch/mips/bcm63xx/dev-enet.c | 6 ++++--
.../include/asm/mach-bcm63xx/bcm63xx_dev_enet.h | 1 +
3 files changed, 11 insertions(+), 3 deletions(-)
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -120,11 +120,13 @@ static void enetsw_set(struct clk *clk,
{
u32 mask;
- if (!BCMCPU_IS_6328() && !BCMCPU_IS_6368())
+ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6362() && !BCMCPU_IS_6368())
return;
if (BCMCPU_IS_6328())
mask = CKCTL_6328_ROBOSW_EN;
+ else if (BCMCPU_IS_6362())
+ mask = CKCTL_6362_ROBOSW_EN;
else
mask = CKCTL_6368_ROBOSW_EN | CKCTL_6368_SWPKT_USB_EN |
CKCTL_6368_SWPKT_SAR_EN;
@@ -137,6 +139,9 @@ static void enetsw_set(struct clk *clk,
if (BCMCPU_IS_6328()) {
reg = PERF_SOFTRESET_6328_REG;
mask = SOFTRESET_6328_ENETSW_MASK;
+ } else if (BCMCPU_IS_6362()) {
+ reg = PERF_SOFTRESET_6362_REG;
+ mask = SOFTRESET_6362_ENETSW_MASK;
} else {
reg = PERF_SOFTRESET_6368_REG;
mask = SOFTRESET_6368_ENETSW_MASK;
--- 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_6328() || BCMCPU_IS_6368())
+ if (BCMCPU_IS_6328() || BCMCPU_IS_6362() || 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_6328() && !BCMCPU_IS_6368())
+ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6362() && !BCMCPU_IS_6368())
return -ENODEV;
ret = register_shared();
@@ -243,6 +243,8 @@ bcm63xx_enetsw_register(const struct bcm
if (BCMCPU_IS_6328())
enetsw_pd.num_ports = ENETSW_PORTS_6328;
+ else if (BCMCPU_IS_6362())
+ enetsw_pd.num_ports = ENETSW_PORTS_6362;
else if (BCMCPU_IS_6368())
enetsw_pd.num_ports = ENETSW_PORTS_6368;
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h
@@ -44,6 +44,7 @@ struct bcm63xx_enet_platform_data {
*/
#define ENETSW_MAX_PORT 6
#define ENETSW_PORTS_6328 5 /* 4 FE PHY + 1 RGMII */
+#define ENETSW_PORTS_6362 6 /* 4 FE PHY + 2 RGMII */
#define ENETSW_PORTS_6368 6 /* 4 FE PHY + 2 RGMII */
#define ENETSW_RGMII_PORT0 4

Some files were not shown because too many files have changed in this diff Show more