bcm53xx: add initial support for ARM based BCM47XX and BCM53XX SoCs

This was only tested on a Netgear R6250, but it could also work on
other devices when the correct images are generated.
It is only possible to boot into a ram disk, no Ethernet, Wifi, flash,
USB is supported.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>

SVN-Revision: 37268
This commit is contained in:
Hauke Mehrtens 2013-07-12 13:46:27 +00:00
parent 92961e0917
commit 9e9261a718
15 changed files with 1428 additions and 0 deletions

View file

@ -0,0 +1,29 @@
#
# Copyright (C) 2013 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
ARCH:=arm
BOARD:=bcm53xx
BOARDNAME:=Broadcom BCM47xx/53xx with ARM CPU
FEATURES:=squashfs usb pci pcie gpio
MAINTAINER:=Hauke Mehrtens <hauke@hauke-m.de>
LINUX_VERSION:=3.10
include $(INCLUDE_DIR)/target.mk
define Target/Description
Build firmware images for Broadcom based BCM47xx/53xx routers with ARM CPU, *not* MIPS.
endef
CFLAGS:=-Os -pipe -mtune=cortex-a9 -march=armv7-a -mfpu=vfp -mfloat-abi=softfp
KERNELNAME:="zImage dtbs"
DEFAULT_PACKAGES +=
$(eval $(call BuildTarget))

View file

@ -0,0 +1,207 @@
CONFIG_ALIGNMENT_TRAP=y
# CONFIG_ARCH_BCM is not set
CONFIG_ARCH_BCM53XX=y
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
CONFIG_ARCH_HAS_TICK_BROADCAST=y
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
CONFIG_ARCH_MULTIPLATFORM=y
# CONFIG_ARCH_MULTI_CPU_AUTO is not set
# CONFIG_ARCH_MULTI_V6 is not set
CONFIG_ARCH_MULTI_V6_V7=y
CONFIG_ARCH_MULTI_V7=y
# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
CONFIG_ARCH_NR_GPIO=0
# CONFIG_ARCH_OMAP2PLUS is not set
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
# CONFIG_ARCH_SUNXI is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_ARCH_VIRT is not set
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
# CONFIG_ARCH_WM8850 is not set
CONFIG_ARM=y
CONFIG_ARM_APPENDED_DTB=y
# CONFIG_ARM_ATAG_DTB_COMPAT is not set
# CONFIG_ARM_CPU_SUSPEND is not set
# CONFIG_ARM_ERRATA_430973 is not set
# CONFIG_ARM_ERRATA_643719 is not set
# CONFIG_ARM_ERRATA_720789 is not set
# CONFIG_ARM_ERRATA_754322 is not set
# CONFIG_ARM_ERRATA_754327 is not set
# CONFIG_ARM_ERRATA_764369 is not set
# CONFIG_ARM_ERRATA_798181 is not set
CONFIG_ARM_GIC=y
CONFIG_ARM_GLOBAL_TIMER=y
CONFIG_ARM_L1_CACHE_SHIFT=6
CONFIG_ARM_L1_CACHE_SHIFT_6=y
# CONFIG_ARM_LPAE is not set
CONFIG_ARM_NR_BANKS=8
CONFIG_ARM_PATCH_PHYS_VIRT=y
CONFIG_ARM_THUMB=y
# CONFIG_ARM_THUMBEE is not set
CONFIG_ARM_VIRT_EXT=y
CONFIG_ATAGS=y
CONFIG_AUTO_ZRELADDR=y
CONFIG_BCMA=y
CONFIG_BCMA_BLOCKIO=y
CONFIG_BCMA_DEBUG=y
CONFIG_BCMA_DRIVER_GMAC_CMN=y
CONFIG_BCMA_HOST_SOC=y
CONFIG_BGMAC=y
# CONFIG_CACHE_L2X0 is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_CLKDEV_LOOKUP=y
CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
CONFIG_CLKSRC_OF=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_COMMON_CLK=y
CONFIG_CPU_32v6K=y
CONFIG_CPU_32v7=y
CONFIG_CPU_ABRT_EV7=y
# CONFIG_CPU_BPREDICT_DISABLE is not set
CONFIG_CPU_CACHE_V7=y
CONFIG_CPU_CACHE_VIPT=y
CONFIG_CPU_COPY_V6=y
CONFIG_CPU_CP15=y
CONFIG_CPU_CP15_MMU=y
CONFIG_CPU_HAS_ASID=y
# CONFIG_CPU_ICACHE_DISABLE is not set
CONFIG_CPU_PABRT_V7=y
CONFIG_CPU_RMAP=y
CONFIG_CPU_TLB_V7=y
CONFIG_CPU_V7=y
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_DEBUG_BCM53XX=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_LL=y
CONFIG_DEBUG_LL_INCLUDE="debug/bcm53xx.S"
CONFIG_DEBUG_UNCOMPRESS=y
CONFIG_DEBUG_USER=y
CONFIG_DTC=y
CONFIG_EARLY_PRINTK=y
CONFIG_FRAME_POINTER=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IO=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GPIO_DEVRES=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
CONFIG_HAVE_AOUT=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_HAVE_ARCH_PFN_VALID=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_ARM_SCU=y
CONFIG_HAVE_ARM_TWD=y
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
CONFIG_HAVE_BPF_JIT=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_HAVE_CONTEXT_TRACKING=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_DMA_CONTIGUOUS=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_GENERIC_DMA_COHERENT=y
CONFIG_HAVE_GENERIC_HARDIRQS=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_NET_DSA=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_HAVE_PROC_CPU=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_SMP=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_UID16=y
CONFIG_HZ_PERIODIC=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_WORK=y
CONFIG_KTIME_SCALAR=y
CONFIG_LOCAL_TIMERS=y
# CONFIG_MCPM is not set
CONFIG_MDIO_BOARDINFO=y
CONFIG_MODULES_USE_ELF_REL=y
# CONFIG_MPCORE_WATCHDOG is not set
CONFIG_MTD_OF_PARTS=y
# CONFIG_MTD_PHYSMAP_OF is not set
CONFIG_MULTI_IRQ_HANDLER=y
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_NEED_DMA_MAP_STATE=y
# CONFIG_NET_IP_TUNNEL is not set
CONFIG_NR_CPUS=4
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_DEVICE=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_IRQ=y
CONFIG_OF_MDIO=y
CONFIG_OF_MTD=y
CONFIG_OF_NET=y
CONFIG_OLD_SIGACTION=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_PAGE_OFFSET=0xC0000000
# CONFIG_PCI_SYSCALL is not set
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PHYLIB=y
# CONFIG_PREEMPT_RCU is not set
CONFIG_RCU_STALL_COMMON=y
# CONFIG_RCU_USER_QS is not set
CONFIG_RFS_ACCEL=y
CONFIG_RPS=y
CONFIG_SCHED_HRTICK=y
# CONFIG_SCSI_DMA is not set
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SMP=y
CONFIG_SMP_ON_UP=y
CONFIG_SPARSE_IRQ=y
CONFIG_STOP_MACHINE=y
# CONFIG_SWP_EMULATE is not set
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
# CONFIG_TEGRA_HOST1X is not set
# CONFIG_THUMB2_KERNEL is not set
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TREE_RCU=y
CONFIG_UID16=y
CONFIG_UIDGID_CONVERTED=y
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
# CONFIG_USB_ARCH_HAS_EHCI is not set
# CONFIG_USB_ARCH_HAS_OHCI is not set
# CONFIG_USB_ARCH_HAS_XHCI is not set
CONFIG_USE_GENERIC_SMP_HELPERS=y
CONFIG_USE_OF=y
CONFIG_VECTORS_BASE=0xffff0000
# CONFIG_VFP is not set
# CONFIG_XEN is not set
CONFIG_XPS=y
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_BCJ=y
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZONE_DMA_FLAG=0

View file

@ -0,0 +1,56 @@
#
# Copyright (C) 2013 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/image.mk
define Image/Prepare
rm -f $(KDIR)/fs_mark
echo -ne '\xde\xad\xc0\xde' > $(KDIR)/fs_mark
$(call prepare_generic_squashfs,$(KDIR)/fs_mark)
endef
define Image/Build/Initramfs
$(call Image/Build/Initramfs/Chk,bcm5301-netgear-r6250,U12H245T00_NETGEAR,2,initramfs)
endef
define Image/Build/Initramfs/Chk
$(call Image/Build/Initramfs/DTB,$(1))
$(STAGING_DIR_HOST)/bin/mkchkimg -o $(BIN_DIR)/openwrt-$(1)-$(4).chk -k $(KDIR)/$(IMG_PREFIX)-$(4)-$(1).trx -b $(2) -r $(3)
endef
define Image/Build/Initramfs/DTB
$(call Image/Build/DTB,zImage-initramfs,$(1))
$(STAGING_DIR_HOST)/bin/trx -o $(KDIR)/$(IMG_PREFIX)-initramfs-$(1).trx \
-f $(KDIR)/zImage-initramfs-$(1).lzma
endef
define Image/Build/squashfs/DTB
$(call Image/Build/DTB,zImage,$(1))
$(STAGING_DIR_HOST)/bin/trx -o $(KDIR)/$(IMG_PREFIX)-squashfs-$(1).trx \
-f $(KDIR)/zImage-$(1).lzma \
-a 1024 -f $(KDIR)/root.squashfs -a 0x10000 -A $(KDIR)/fs_mark
endef
define Image/Build/squashfs/Chk
$(call Image/Build/squashfs/DTB,$(1))
$(STAGING_DIR_HOST)/bin/mkchkimg -o $(BIN_DIR)/openwrt-$(1)-$(4).chk -k $(KDIR)/$(IMG_PREFIX)-$(4)-$(1).trx -b $(2) -r $(3)
endef
define Image/Build/DTB
rm -f $(KDIR)/$(1)-$(2).lzma
rm -f $(KDIR)/$(1)-$(2).dts
cat $(KDIR)/$(1) $(LINUX_DIR)/arch/$(ARCH)/boot/dts/$(2).dtb > $(KDIR)/$(1)-$(2).dts;
$(STAGING_DIR_HOST)/bin/lzma e $(KDIR)/$(1)-$(2).dts $(KDIR)/$(1)-$(2).lzma -d16
endef
define Image/Build
$(call Image/Build/$(1),$(1))
$(call Image/Build/squashfs/Chk,bcm5301-netgear-r6250,U12H245T00_NETGEAR,2,squashfs)
endef
$(eval $(call BuildImage))

View file

@ -0,0 +1,421 @@
From 403eb25e5ae7a2169d8c1eae9df4162815e7c3ba Mon Sep 17 00:00:00 2001
From: Stuart Menefy <stuart.menefy at>
Date: Wed, 26 Jun 2013 11:48:38 +0000
Subject: [PATCH 01/17] clocksource:arm_global_timer: Add ARM global timer
support.
This is a simple driver for the global timer module found in the Cortex
A9-MP cores from revision r1p0 onwards. This should be able to perform
the functions of the system timer and the local timer in an SMP system.
The global timer has the following features:
The global timer is a 64-bit incrementing counter with an
auto-incrementing feature. It continues incrementing after sending
interrupts. The global timer is memory mapped in the private memory
region.
The global timer is accessible to all Cortex-A9 processors in the
cluster. Each Cortex-A9 processor has a private 64-bit comparator that
is used to assert a private interrupt when the global timer has reached
the comparator value. All the Cortex-A9 processors in a design use the
banked ID, ID27, for this interrupt. ID27 is sent to the Interrupt
Controller as a Private Peripheral Interrupt. The global timer is
clocked by PERIPHCLK.
Signed-off-by: Stuart Menefy <stuart.menefy@st.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Rob Herring <robherring2@gmail.com>
CC: Linus Walleij <linus.walleij@linaro.org>
CC: Will Deacon <will.deacon@arm.com>
CC: Thomas Gleixner <tglx@linutronix.de>
---
.../devicetree/bindings/arm/global_timer.txt | 21 ++
drivers/clocksource/Kconfig | 13 +
drivers/clocksource/Makefile | 1 +
drivers/clocksource/arm_global_timer.c | 325 ++++++++++++++++++++
4 files changed, 360 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/global_timer.txt
create mode 100644 drivers/clocksource/arm_global_timer.c
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/global_timer.txt
@@ -0,0 +1,21 @@
+
+* ARM Global Timer
+ Cortex-A9 are often associated with a per-core Global timer.
+
+** Timer node required properties:
+
+- compatible : Should be "arm,cortex-a9-global-timer"
+ Driver supports versions r2p0 and above.
+
+- interrupts : One interrupt to each core
+
+- reg : Specify the base address and the size of the GT timer
+ register window.
+
+Example:
+
+ timer@2c000600 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x2c000600 0x20>;
+ interrupts = <1 13 0xf01>;
+ };
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -67,6 +67,19 @@ config ARM_ARCH_TIMER
bool
select CLKSRC_OF if OF
+config ARM_GLOBAL_TIMER
+ bool
+ select CLKSRC_OF if OF
+ help
+ This options enables support for the ARM global timer unit
+
+config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+ bool
+ depends on ARM_GLOBAL_TIMER
+ default y
+ help
+ Use ARM global timer clock source as sched_clock
+
config CLKSRC_METAG_GENERIC
def_bool y if METAG
help
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -28,4 +28,5 @@ obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exyno
obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o
obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
+obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o
--- /dev/null
+++ b/drivers/clocksource/arm_global_timer.c
@@ -0,0 +1,325 @@
+/*
+ * drivers/clocksource/arm_global_timer.c
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Stuart Menefy <stuart.menefy@st.com>
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * 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/init.h>
+#include <linux/interrupt.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/cpu.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+
+#include <asm/sched_clock.h>
+#include <asm/cputype.h>
+
+#define GT_COUNTER0 0x00
+#define GT_COUNTER1 0x04
+
+#define GT_CONTROL 0x08
+#define GT_CONTROL_TIMER_ENABLE BIT(0) /* this bit is NOT banked */
+#define GT_CONTROL_COMP_ENABLE BIT(1) /* banked */
+#define GT_CONTROL_IRQ_ENABLE BIT(2) /* banked */
+#define GT_CONTROL_AUTO_INC BIT(3) /* banked */
+
+#define GT_INT_STATUS 0x0c
+#define GT_INT_STATUS_EVENT_FLAG BIT(0)
+
+#define GT_COMP0 0x10
+#define GT_COMP1 0x14
+#define GT_AUTO_INC 0x18
+
+/*
+ * We are expecting to be clocked by the ARM peripheral clock.
+ *
+ * Note: it is assumed we are using a prescaler value of zero, so this is
+ * the units for all operations.
+ */
+static void __iomem *gt_base;
+static unsigned long gt_clk_rate;
+static int gt_ppi;
+static struct clock_event_device __percpu *gt_evt;
+
+/*
+ * To get the value from the Global Timer Counter register proceed as follows:
+ * 1. Read the upper 32-bit timer counter register
+ * 2. Read the lower 32-bit timer counter register
+ * 3. Read the upper 32-bit timer counter register again. If the value is
+ * different to the 32-bit upper value read previously, go back to step 2.
+ * Otherwise the 64-bit timer counter value is correct.
+ */
+static u64 gt_counter_read(void)
+{
+ u64 counter;
+ u32 lower;
+ u32 upper, old_upper;
+
+ upper = readl_relaxed(gt_base + GT_COUNTER1);
+ do {
+ old_upper = upper;
+ lower = readl_relaxed(gt_base + GT_COUNTER0);
+ upper = readl_relaxed(gt_base + GT_COUNTER1);
+ } while (upper != old_upper);
+
+ counter = upper;
+ counter <<= 32;
+ counter |= lower;
+ return counter;
+}
+
+/**
+ * To ensure that updates to comparator value register do not set the
+ * Interrupt Status Register proceed as follows:
+ * 1. Clear the Comp Enable bit in the Timer Control Register.
+ * 2. Write the lower 32-bit Comparator Value Register.
+ * 3. Write the upper 32-bit Comparator Value Register.
+ * 4. Set the Comp Enable bit and, if necessary, the IRQ enable bit.
+ */
+static void gt_compare_set(unsigned long delta, int periodic)
+{
+ u64 counter = gt_counter_read();
+ unsigned long ctrl = readl(gt_base + GT_CONTROL);
+
+ counter += delta;
+ ctrl &= ~(GT_CONTROL_COMP_ENABLE | GT_CONTROL_IRQ_ENABLE);
+
+ writel(ctrl, gt_base + GT_CONTROL);
+ writel(lower_32_bits(counter), gt_base + GT_COMP0);
+ writel(upper_32_bits(counter), gt_base + GT_COMP1);
+
+ if (periodic) {
+ writel(delta, gt_base + GT_AUTO_INC);
+ ctrl |= GT_CONTROL_AUTO_INC;
+ }
+
+ ctrl |= GT_CONTROL_COMP_ENABLE | GT_CONTROL_IRQ_ENABLE;
+ writel(ctrl, gt_base + GT_CONTROL);
+}
+
+static void gt_clockevent_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *clk)
+{
+ unsigned long ctrl;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ gt_compare_set(DIV_ROUND_CLOSEST(gt_clk_rate, HZ), 1);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ ctrl = readl(gt_base + GT_CONTROL);
+ ctrl &= ~(GT_CONTROL_COMP_ENABLE |
+ GT_CONTROL_IRQ_ENABLE | GT_CONTROL_AUTO_INC);
+ writel(ctrl, gt_base + GT_CONTROL);
+ break;
+ default:
+ break;
+ }
+}
+
+static int gt_clockevent_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ gt_compare_set(evt, 0);
+ return 0;
+}
+
+static irqreturn_t gt_clockevent_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ if (readl_relaxed(gt_base + GT_INT_STATUS) &
+ GT_INT_STATUS_EVENT_FLAG) {
+ /**
+ * ERRATA 740657( Global Timer can send 2 interrupts for
+ * the same event in single-shot mode)
+ * Workaround:
+ * Either disable single-shot mode.
+ * Or
+ * Modify the Interrupt Handler to avoid the
+ * offending sequence. This is achieved by clearing
+ * the Global Timer flag _after_ having incremented
+ * the Comparator register value to a higher value.
+ */
+ if (!(readl_relaxed(gt_base + GT_CONTROL) &
+ GT_CONTROL_AUTO_INC))
+ gt_compare_set(ULONG_MAX, 0);
+
+ writel_relaxed(GT_INT_STATUS_EVENT_FLAG,
+ gt_base + GT_INT_STATUS);
+
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static int __cpuinit gt_clockevents_init(struct clock_event_device *clk)
+{
+ int cpu = smp_processor_id();
+
+ clk->name = "arm_global_timer";
+ clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+ clk->set_mode = gt_clockevent_set_mode;
+ clk->set_next_event = gt_clockevent_set_next_event;
+ clk->cpumask = cpumask_of(cpu);
+ clk->rating = 300;
+ clk->irq = gt_ppi;
+ clockevents_config_and_register(clk, gt_clk_rate,
+ 1, 0xffffffff);
+ enable_percpu_irq(clk->irq, IRQ_TYPE_NONE);
+ return 0;
+}
+
+static void gt_clockevents_stop(struct clock_event_device *clk)
+{
+ gt_clockevent_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
+ disable_percpu_irq(clk->irq);
+}
+
+static cycle_t gt_clocksource_read(struct clocksource *cs)
+{
+ return gt_counter_read();
+}
+
+static struct clocksource gt_clocksource = {
+ .name = "arm_global_timer",
+ .rating = 300,
+ .read = gt_clocksource_read,
+ .mask = CLOCKSOURCE_MASK(64),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+#ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+static u32 notrace gt_sched_clock_read(void)
+{
+ return gt_counter_read();
+}
+#endif
+
+static void __init gt_clocksource_init(void)
+{
+ writel(0, gt_base + GT_CONTROL);
+ writel(0, gt_base + GT_COUNTER0);
+ writel(0, gt_base + GT_COUNTER1);
+ /* enables timer on all the cores */
+ writel(GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
+
+#ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+ setup_sched_clock(gt_sched_clock_read, 32, gt_clk_rate);
+#endif
+ clocksource_register_hz(&gt_clocksource, gt_clk_rate);
+}
+
+static int __cpuinit gt_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_STARTING:
+ gt_clockevents_init(this_cpu_ptr(gt_evt));
+ break;
+ case CPU_DYING:
+ gt_clockevents_stop(this_cpu_ptr(gt_evt));
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+static struct notifier_block gt_cpu_nb __cpuinitdata = {
+ .notifier_call = gt_cpu_notify,
+};
+
+static void __init global_timer_of_register(struct device_node *np)
+{
+ struct clk *gt_clk;
+ int err = 0;
+
+ /*
+ * In r2p0 the comparators for each processor with the global timer
+ * fire when the timer value is greater than or equal to. In previous
+ * revisions the comparators fired when the timer value was equal to.
+ */
+ if ((read_cpuid_id() & 0xf0000f) < 0x200000) {
+ pr_warn("global-timer: non support for this cpu version.\n");
+ return;
+ }
+
+ gt_ppi = irq_of_parse_and_map(np, 0);
+ if (!gt_ppi) {
+ pr_warn("global-timer: unable to parse irq\n");
+ return;
+ }
+
+ gt_base = of_iomap(np, 0);
+ if (!gt_base) {
+ pr_warn("global-timer: invalid base address\n");
+ return;
+ }
+
+ gt_clk = of_clk_get(np, 0);
+ if (!IS_ERR(gt_clk)) {
+ err = clk_prepare_enable(gt_clk);
+ if (err)
+ goto out_unmap;
+ } else {
+ pr_warn("global-timer: clk not found\n");
+ err = -EINVAL;
+ goto out_unmap;
+ }
+
+ gt_clk_rate = clk_get_rate(gt_clk);
+ gt_evt = alloc_percpu(struct clock_event_device);
+ if (!gt_evt) {
+ pr_warn("global-timer: can't allocate memory\n");
+ err = -ENOMEM;
+ goto out_clk;
+ }
+
+ err = request_percpu_irq(gt_ppi, gt_clockevent_interrupt,
+ "gt", gt_evt);
+ if (err) {
+ pr_warn("global-timer: can't register interrupt %d (%d)\n",
+ gt_ppi, err);
+ goto out_free;
+ }
+
+ err = register_cpu_notifier(&gt_cpu_nb);
+ if (err) {
+ pr_warn("global-timer: unable to register cpu notifier.\n");
+ goto out_irq;
+ }
+
+ /* Immediately configure the timer on the boot CPU */
+ gt_clocksource_init();
+ gt_clockevents_init(this_cpu_ptr(gt_evt));
+
+ return;
+
+out_irq:
+ free_percpu_irq(gt_ppi, gt_evt);
+out_free:
+ free_percpu(gt_evt);
+out_clk:
+ clk_disable_unprepare(gt_clk);
+out_unmap:
+ iounmap(gt_base);
+ WARN(err, "ARM Global timer register failed (%d)\n", err);
+}
+
+/* Only tested on r2p2 and r3p0 */
+CLOCKSOURCE_OF_DECLARE(arm_gt, "arm,cortex-a9-global-timer",
+ global_timer_of_register);

View file

@ -0,0 +1,307 @@
From 6c55b7f2fe06eb01f4ca6dad35d54c6e2ecbff25 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Sat, 29 Jun 2013 22:06:43 +0200
Subject: [PATCH 08/17] bcm53xx: initial support for the BCM5301/BCM470X SoC
with ARM CPU
This patch adds support for the BCM5301/BCM470X SoCs with an ARM CPU.
Currently just booting to a shell is working and nothing else, no
Ethernet, wifi, flash, ...
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
arch/arm/Kconfig | 2 +
arch/arm/Kconfig.debug | 5 ++
arch/arm/Makefile | 1 +
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/bcm5301-netgear-r6250.dts | 20 +++++++
arch/arm/boot/dts/bcm5301.dtsi | 83 +++++++++++++++++++++++++++
arch/arm/include/debug/bcm53xx.S | 19 ++++++
arch/arm/mach-bcm53xx/Kconfig | 15 +++++
arch/arm/mach-bcm53xx/Makefile | 1 +
arch/arm/mach-bcm53xx/bcm53xx.c | 69 ++++++++++++++++++++++
10 files changed, 216 insertions(+)
create mode 100644 arch/arm/boot/dts/bcm5301-netgear-r6250.dts
create mode 100644 arch/arm/boot/dts/bcm5301.dtsi
create mode 100644 arch/arm/include/debug/bcm53xx.S
create mode 100644 arch/arm/mach-bcm53xx/Kconfig
create mode 100644 arch/arm/mach-bcm53xx/Makefile
create mode 100644 arch/arm/mach-bcm53xx/bcm53xx.c
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -922,6 +922,8 @@ source "arch/arm/mach-bcm/Kconfig"
source "arch/arm/mach-bcm2835/Kconfig"
+source "arch/arm/mach-bcm53xx/Kconfig"
+
source "arch/arm/mach-clps711x/Kconfig"
source "arch/arm/mach-cns3xxx/Kconfig"
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -93,6 +93,10 @@ choice
bool "Kernel low-level debugging on BCM2835 PL011 UART"
depends on ARCH_BCM2835
+ config DEBUG_BCM53XX
+ bool "Kernel low-level debugging on BCM53XX UART1"
+ depends on ARCH_BCM53XX
+
config DEBUG_CLPS711X_UART1
bool "Kernel low-level debugging messages via UART1"
depends on ARCH_CLPS711X
@@ -620,6 +624,7 @@ endchoice
config DEBUG_LL_INCLUDE
string
default "debug/bcm2835.S" if DEBUG_BCM2835
+ default "debug/bcm53xx.S" if DEBUG_BCM53XX
default "debug/cns3xxx.S" if DEBUG_CNS3XXX
default "debug/exynos.S" if DEBUG_EXYNOS_UART
default "debug/highbank.S" if DEBUG_HIGHBANK_UART
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -145,6 +145,7 @@ textofs-$(CONFIG_ARCH_MSM8960) := 0x0020
machine-$(CONFIG_ARCH_AT91) += at91
machine-$(CONFIG_ARCH_BCM) += bcm
machine-$(CONFIG_ARCH_BCM2835) += bcm2835
+machine-$(CONFIG_ARCH_BCM53XX) += bcm53xx
machine-$(CONFIG_ARCH_CLPS711X) += clps711x
machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx
machine-$(CONFIG_ARCH_DAVINCI) += davinci
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -209,6 +209,7 @@ dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07
wm8650-mid.dtb \
wm8850-w70v2.dtb
dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb
+dtb-$(CONFIG_ARCH_BCM53XX) += bcm5301-netgear-r6250.dtb
targets += dtbs
targets += $(dtb-y)
--- /dev/null
+++ b/arch/arm/boot/dts/bcm5301-netgear-r6250.dts
@@ -0,0 +1,20 @@
+/*
+ * Broadcom BCM47XX / BCM53XX arm platform code.
+ *
+ * Copyright 2013 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+/dts-v1/;
+
+/include/ "bcm5301.dtsi"
+
+/ {
+ model = "Netgear R6250 V1 (BCM4708)";
+ compatible = "netgear,r6250v1", "brcm,bcm5301";
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+};
--- /dev/null
+++ b/arch/arm/boot/dts/bcm5301.dtsi
@@ -0,0 +1,83 @@
+/*
+ * Broadcom BCM47XX / BCM53XX ARM platform code.
+ *
+ * Copyright 2013 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "brcm,bcm5301";
+ model = "BCM5301/BCM4707/BCM4708/BCM4709 SoC";
+ interrupt-parent = <&gic>;
+
+ chosen {
+ bootargs = "console=ttyS0,115200 earlyprintk debug vmalloc=64M";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ };
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk_periph: periph {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <400000000>;
+ };
+ };
+
+ uart@18000300 {
+ compatible = "ns16550";
+ reg = <0x18000300 0x100>;
+ interrupts = <0 85 4>;
+ clock-frequency = <100000000>;
+ };
+
+ uart@18000400 {
+ compatible = "ns16550";
+ reg = <0x18000400 0x100>;
+ interrupts = <0 85 4>;
+ clock-frequency = <100000000>;
+ };
+
+ gic: interrupt-controller@19021000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x19021000 0x1000>,
+ <0x19020100 0x100>;
+ };
+
+ timer@19020200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x19020200 0x100>;
+ interrupts = <1 11 0xf04>;
+ clocks = <&clk_periph>;
+ #clock-cells = <0>;
+ };
+
+ local-timer@19020200 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x19020600 0x100>;
+ interrupts = <1 13 0xf04>;
+ };
+};
--- /dev/null
+++ b/arch/arm/include/debug/bcm53xx.S
@@ -0,0 +1,19 @@
+/*
+ * Macros used for EARLY_PRINTK, in low-level UART debug console
+ *
+ * Copyright 2013 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#define BCM53XX_UART1_PHYS 0x18000300
+#define BCM53XX_UART1_VIRT 0xf1000300
+#define BCM53XX_UART1_SH 0
+
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =BCM53XX_UART1_PHYS @ MMU off, Physical
+ ldr \rv, =BCM53XX_UART1_VIRT @ MMU on, Virtual
+ .endm
+
+#define UART_SHIFT BCM53XX_UART1_SH
+#include <asm/hardware/debug-8250.S>
--- /dev/null
+++ b/arch/arm/mach-bcm53xx/Kconfig
@@ -0,0 +1,15 @@
+config ARCH_BCM53XX
+ bool "Broadcom BCM47XX / BCM53XX ARM SoC"
+ select CPU_V7
+ select ARM_GIC
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if LOCAL_TIMERS
+ select HAVE_SMP
+ select HAVE_CLK
+ select LOCAL_TIMERS if SMP
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS_BUILD
+ select GENERIC_CLOCKEVENTS
+ select ARM_GLOBAL_TIMER
+ help
+ Support for Broadcom BCM47XX and BCM53XX SoCs with ARM CPU cores.
--- /dev/null
+++ b/arch/arm/mach-bcm53xx/Makefile
@@ -0,0 +1 @@
+obj-y += bcm53xx.o
--- /dev/null
+++ b/arch/arm/mach-bcm53xx/bcm53xx.c
@@ -0,0 +1,69 @@
+/*
+ * Broadcom BCM47XX / BCM53XX ARM platform code.
+ *
+ * Copyright 2013 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/irqchip.h>
+#include <linux/clocksource.h>
+#include <linux/clk-provider.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/smp_scu.h>
+#include <asm/signal.h>
+
+static int bcm53xx_abort_handler(unsigned long addr, unsigned int fsr,
+ struct pt_regs *regs)
+{
+ /*
+ * These happen for no good reason
+ * possibly left over from CFE
+ */
+ pr_warn("External imprecise Data abort at addr=%#lx, fsr=%#x ignored.\n",
+ addr, fsr);
+
+ /* Returning non-zero causes fault display and panic */
+ return 0;
+}
+
+static void bcm53xx_aborts_enable(void)
+{
+ /* Install our hook */
+ hook_fault_code(16 + 6, bcm53xx_abort_handler, SIGBUS, 0,
+ "imprecise external abort");
+}
+
+static void __init bcm53xx_timer_init(void)
+{
+ of_clk_init(NULL);
+ clocksource_of_init();
+}
+
+void __init bcm53xx_map_io(void)
+{
+ debug_ll_io_init();
+ bcm53xx_aborts_enable();
+}
+
+static void __init bcm53xx_dt_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char const *bcm53xx_dt_compat[] = {
+ "brcm,bcm5301",
+ "netgear,r6250v1",
+ NULL,
+};
+
+DT_MACHINE_START(BCM53XX, "BCM53XX")
+ .init_machine = bcm53xx_dt_init,
+ .map_io = bcm53xx_map_io,
+ .init_irq = irqchip_init,
+ .init_time = bcm53xx_timer_init,
+ .dt_compat = bcm53xx_dt_compat,
+MACHINE_END

View file

@ -0,0 +1,99 @@
From d16de2a4ffeaf62fb3d838365a29b80f330bffe0 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Thu, 4 Jul 2013 22:26:58 +0200
Subject: [PATCH 09/17] bcma: register bcma as device tree driver
This driver is used by the bcm53xx ARM SoC code.Now it is possible to
give the address of the chipcommon core in device tree.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/bcma/host_soc.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 73 insertions(+)
--- a/drivers/bcma/host_soc.c
+++ b/drivers/bcma/host_soc.c
@@ -7,6 +7,9 @@
#include "bcma_private.h"
#include "scan.h"
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
#include <linux/bcma/bcma.h>
#include <linux/bcma/bcma_soc.h>
@@ -181,3 +184,73 @@ int __init bcma_host_soc_register(struct
return err;
}
+
+#ifdef CONFIG_OF
+static int bcma_host_soc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct bcma_bus *bus;
+ int err;
+
+ /* Alloc */
+ bus = kzalloc(sizeof(*bus), GFP_KERNEL);
+ if (!bus)
+ return -ENOMEM;
+
+ /* Map MMIO */
+ err = -ENOMEM;
+ bus->mmio = of_iomap(np, 0);
+ if (!bus->mmio)
+ goto err_kfree_bus;
+
+ /* Host specific */
+ bus->hosttype = BCMA_HOSTTYPE_SOC;
+ bus->ops = &bcma_host_soc_ops;
+
+
+ /* Register */
+ err = bcma_bus_register(bus);
+ if (err)
+ goto err_unmap_mmio;
+
+ platform_set_drvdata(pdev, bus);
+
+ return err;
+
+err_unmap_mmio:
+ iounmap(bus->mmio);
+err_kfree_bus:
+ kfree(bus);
+ return err;
+}
+
+static int bcma_host_soc_remove(struct platform_device *pdev)
+{
+ struct bcma_bus *bus = platform_get_drvdata(pdev);
+
+ bcma_bus_unregister(bus);
+ iounmap(bus->mmio);
+ kfree(bus);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id bcma_host_soc_of_match[] = {
+ { .compatible = "brcm,bus-aix", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, bcma_host_soc_of_match);
+
+static struct platform_driver bcma_host_soc_driver = {
+ .driver = {
+ .name = "bcma-host-soc",
+ .owner = THIS_MODULE,
+ .of_match_table = bcma_host_soc_of_match,
+ },
+ .probe = bcma_host_soc_probe,
+ .remove = bcma_host_soc_remove,
+};
+module_platform_driver(bcma_host_soc_driver);
+#endif /* CONFIG_OF */

View file

@ -0,0 +1,57 @@
From 6fe4f63b017c3c0a7caa73d01fab23874ca0ed97 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Thu, 4 Jul 2013 22:29:48 +0200
Subject: [PATCH 10/17] bcma: add some more core names
These cores were found on a BCM4708 (chipid 53010), this is a ARM SoC
with two Cortex A9 cores.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/bcma/scan.c | 12 ++++++++++++
include/linux/bcma/bcma.h | 12 ++++++++++++
2 files changed, 24 insertions(+)
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -32,6 +32,18 @@ static const struct bcma_device_id_name
{ BCMA_CORE_4706_CHIPCOMMON, "BCM4706 ChipCommon" },
{ BCMA_CORE_4706_SOC_RAM, "BCM4706 SOC RAM" },
{ BCMA_CORE_4706_MAC_GBIT, "BCM4706 GBit MAC" },
+ { BCMA_CORE_PCIEG2, "PCIe Gen 2" },
+ { BCMA_CORE_DMA, "DMA" },
+ { BCMA_CORE_SDIO3, "SDIO3" },
+ { BCMA_CORE_USB20, "USB 2.0" },
+ { BCMA_CORE_USB30, "USB 3.0" },
+ { BCMA_CORE_A9JTAG, "ARM Cortex A9 JTAG" },
+ { BCMA_CORE_DDR23, "Denali DDR2/DDR3 memory controller" },
+ { BCMA_CORE_ROM, "ROM" },
+ { BCMA_CORE_NAND, "NAND flash controller" },
+ { BCMA_CORE_QSPI, "SPI flash controller" },
+ { BCMA_CORE_CHIPCOMMON_B, "Chipcommon B" },
+ { BCMA_CORE_ARMCA9, "ARM Cortex A9 core (ihost)" },
{ BCMA_CORE_AMEMC, "AMEMC (DDR)" },
{ BCMA_CORE_ALTA, "ALTA (I2S)" },
{ BCMA_CORE_INVALID, "Invalid" },
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -72,7 +72,19 @@ struct bcma_host_ops {
/* Core-ID values. */
#define BCMA_CORE_OOB_ROUTER 0x367 /* Out of band */
#define BCMA_CORE_4706_CHIPCOMMON 0x500
+#define BCMA_CORE_PCIEG2 0x501
+#define BCMA_CORE_DMA 0x502
+#define BCMA_CORE_SDIO3 0x503
+#define BCMA_CORE_USB20 0x504
+#define BCMA_CORE_USB30 0x505
+#define BCMA_CORE_A9JTAG 0x506
+#define BCMA_CORE_DDR23 0x507
+#define BCMA_CORE_ROM 0x508
+#define BCMA_CORE_NAND 0x509
+#define BCMA_CORE_QSPI 0x50A
+#define BCMA_CORE_CHIPCOMMON_B 0x50B /* ChipcommonB core */
#define BCMA_CORE_4706_SOC_RAM 0x50E
+#define BCMA_CORE_ARMCA9 0x510
#define BCMA_CORE_4706_MAC_GBIT 0x52D
#define BCMA_CORE_AMEMC 0x52E /* DDR1/2 memory controller core */
#define BCMA_CORE_ALTA 0x534 /* I2S core */

View file

@ -0,0 +1,33 @@
From b5f4430c100a4d7b526426db46b76add728f45d4 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Thu, 4 Jul 2013 22:35:22 +0200
Subject: [PATCH 11/17] bcma: make it possible to select SoC support without
mips
To make it possible to use the SoC host interface with ARM SoCs do not
depend on the MIPS driver any more.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/bcma/Kconfig | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -35,8 +35,14 @@ config BCMA_DRIVER_PCI_HOSTMODE
PCI core hostmode operation (external PCI bus).
config BCMA_HOST_SOC
- bool
- depends on BCMA_DRIVER_MIPS
+ bool "Support for BCMA in a SoC"
+ depends on BCMA
+ help
+ Host interface for a Broadcom AIX bus directly mapped into
+ the memory. This only works with the Broadcom SoCs from the
+ BCM47XX line.
+
+ If unsure, say N
config BCMA_DRIVER_MIPS
bool "BCMA Broadcom MIPS core driver"

View file

@ -0,0 +1,24 @@
From 5b9be5e1e3c368466e482c7dbb2cf6b890614b39 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Thu, 4 Jul 2013 22:37:13 +0200
Subject: [PATCH 12/17] bcm53xx: register bcma bus
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
arch/arm/boot/dts/bcm5301.dtsi | 5 +++++
1 file changed, 5 insertions(+)
--- a/arch/arm/boot/dts/bcm5301.dtsi
+++ b/arch/arm/boot/dts/bcm5301.dtsi
@@ -67,6 +67,11 @@
<0x19020100 0x100>;
};
+ bus@18000000 {
+ compatible = "brcm,bus-aix";
+ reg = <0x18000000 0x1000>;
+ };
+
timer@19020200 {
compatible = "arm,cortex-a9-global-timer";
reg = <0x19020200 0x100>;

View file

@ -0,0 +1,26 @@
From fda36440e95ef9adbd7955b069248d1d807a85b1 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Thu, 4 Jul 2013 22:48:25 +0200
Subject: [PATCH 13/17] bcma: add constants for new ARM based SoCs
These are the chipIDs of some ARM based SoCs from the BCM47xx line.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
include/linux/bcma/bcma.h | 5 +++++
1 file changed, 5 insertions(+)
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -188,6 +188,11 @@ struct bcma_host_ops {
#define BCMA_PKG_ID_BCM5357 11
#define BCMA_CHIP_ID_BCM53572 53572
#define BCMA_PKG_ID_BCM47188 9
+#define BCMA_CHIP_ID_BCM4707 53010
+#define BCMA_PKG_ID_BCM4707 1
+#define BCMA_PKG_ID_BCM4708 2
+#define BCMA_PKG_ID_BCM4709 0
+#define BCMA_CHIP_ID_BCM53018 53018
/* Board types (on PCI usually equals to the subsystem dev id) */
/* BCM4313 */

View file

@ -0,0 +1,21 @@
From e2e1b185afd86a047e1f2db405c61ae4e43c0f29 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Thu, 4 Jul 2013 22:49:14 +0200
Subject: [PATCH 14/17] bcma: return correct error code when bus can failed
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/bcma/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -218,7 +218,7 @@ int bcma_bus_register(struct bcma_bus *b
err = bcma_bus_scan(bus);
if (err) {
bcma_err(bus, "Failed to scan: %d\n", err);
- return -1;
+ return err;
}
/* Early init CC core */

View file

@ -0,0 +1,83 @@
From 8204277ed0f4aeb7bb38d0d5f39d9ebcced92576 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Fri, 5 Jul 2013 00:24:38 +0200
Subject: [PATCH 15/17] bcma: fix handling of big addrl
The return value of bcma_erom_get_addr_desc() is a unsigned value and it
could wrap around in the two complement writing.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/bcma/scan.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -213,7 +213,7 @@ static s32 bcma_erom_get_mst_port(struct
return ent;
}
-static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr,
+static u32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr,
u32 type, u8 port)
{
u32 addrl, addrh, sizel, sizeh = 0;
@@ -225,7 +225,7 @@ static s32 bcma_erom_get_addr_desc(struc
((ent & SCAN_ADDR_TYPE) != type) ||
(((ent & SCAN_ADDR_PORT) >> SCAN_ADDR_PORT_SHIFT) != port)) {
bcma_erom_push_ent(eromptr);
- return -EINVAL;
+ return (u32)-EINVAL;
}
addrl = ent & SCAN_ADDR_ADDR;
@@ -273,7 +273,7 @@ static int bcma_get_next_core(struct bcm
struct bcma_device_id *match, int core_num,
struct bcma_device *core)
{
- s32 tmp;
+ u32 tmp;
u8 i, j;
s32 cia, cib;
u8 ports[2], wrappers[2];
@@ -351,11 +351,11 @@ static int bcma_get_next_core(struct bcm
* the main register space for the core
*/
tmp = bcma_erom_get_addr_desc(bus, eromptr, SCAN_ADDR_TYPE_SLAVE, 0);
- if (tmp <= 0) {
+ if (tmp == 0 || IS_ERR_VALUE(tmp)) {
/* Try again to see if it is a bridge */
tmp = bcma_erom_get_addr_desc(bus, eromptr,
SCAN_ADDR_TYPE_BRIDGE, 0);
- if (tmp <= 0) {
+ if (tmp == 0 || IS_ERR_VALUE(tmp)) {
return -EILSEQ;
} else {
bcma_info(bus, "Bridge found\n");
@@ -369,7 +369,7 @@ static int bcma_get_next_core(struct bcm
for (j = 0; ; j++) {
tmp = bcma_erom_get_addr_desc(bus, eromptr,
SCAN_ADDR_TYPE_SLAVE, i);
- if (tmp < 0) {
+ if (IS_ERR_VALUE(tmp)) {
/* no more entries for port _i_ */
/* pr_debug("erom: slave port %d "
* "has %d descriptors\n", i, j); */
@@ -386,7 +386,7 @@ static int bcma_get_next_core(struct bcm
for (j = 0; ; j++) {
tmp = bcma_erom_get_addr_desc(bus, eromptr,
SCAN_ADDR_TYPE_MWRAP, i);
- if (tmp < 0) {
+ if (IS_ERR_VALUE(tmp)) {
/* no more entries for port _i_ */
/* pr_debug("erom: master wrapper %d "
* "has %d descriptors\n", i, j); */
@@ -404,7 +404,7 @@ static int bcma_get_next_core(struct bcm
for (j = 0; ; j++) {
tmp = bcma_erom_get_addr_desc(bus, eromptr,
SCAN_ADDR_TYPE_SWRAP, i + hack);
- if (tmp < 0) {
+ if (IS_ERR_VALUE(tmp)) {
/* no more entries for port _i_ */
/* pr_debug("erom: master wrapper %d "
* has %d descriptors\n", i, j); */

View file

@ -0,0 +1,22 @@
From 0cf467765b64f6dc60f95c890cdb1641ae1d9390 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Wed, 10 Jul 2013 17:54:33 +0200
Subject: [PATCH 16/17] bgmac: bgmac depends on phylib
bgmac is using functions from phylib, add the dependency.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/net/ethernet/broadcom/Kconfig | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/net/ethernet/broadcom/Kconfig
+++ b/drivers/net/ethernet/broadcom/Kconfig
@@ -133,6 +133,7 @@ config BNX2X_SRIOV
config BGMAC
tristate "BCMA bus GBit core support"
depends on BCMA_HOST_SOC && HAS_DMA
+ select PHYLIB
---help---
This driver supports GBit MAC and BCM4706 GBit MAC cores on BCMA bus.
They can be found on BCM47xx SoCs and provide gigabit ethernet.

View file

@ -0,0 +1,25 @@
From a0c7d2569ed39b8b0d90a431d80babc0f5f1f864 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Wed, 10 Jul 2013 17:55:34 +0200
Subject: [PATCH 17/17] bgmac: make bgmac work on systems without nvram
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/net/ethernet/broadcom/bgmac.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
@@ -16,7 +16,11 @@
#include <linux/phy.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
+#ifdef CONFIG_BCM47XX
#include <bcm47xx_nvram.h>
+#else
+#define bcm47xx_nvram_getenv(a, b, c) -1
+#endif
static const struct bcma_device_id bgmac_bcma_tbl[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS),

View file

@ -0,0 +1,18 @@
#
# Copyright (C) 2013 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
define Profile/Generic
NAME:=Broadcom SoC, BCM43xx WiFi (b43, default)
endef
define Profile/Generic/Description
Package set compatible with hardware any Broadcom BCM47xx or BCM535x
SoC with a ARM CPU like the BCM4707, BCM4708, BCM4709, BCM53010
endef
$(eval $(call Profile,Generic))