diff --git a/arch/arm/include/debug/brcmstb.S b/arch/arm/include/debug/brcmstb.S index 52aaed2b936f..c826f15d2f80 100644 --- a/arch/arm/include/debug/brcmstb.S +++ b/arch/arm/include/debug/brcmstb.S @@ -58,6 +58,7 @@ /* Check SUN_TOP_CTRL base */ ldr \rp, =SUN_TOP_CTRL_BASE @ load SUN_TOP_CTRL PA ldr \rv, [\rp, #0] @ get register contents +ARM_BE8( rev \rv, \rv ) and \rv, \rv, #0xffffff00 @ strip revision bits [7:0] /* Chip specific detection starts here */ @@ -98,11 +99,13 @@ .endm .macro store, rd, rx:vararg +ARM_BE8( rev \rd, \rd ) str \rd, \rx .endm .macro load, rd, rx:vararg ldr \rd, \rx +ARM_BE8( rev \rd, \rd ) .endm .macro senduart,rd,rx diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile index 980f5850097c..62a59008c5a8 100644 --- a/arch/arm/mach-bcm/Makefile +++ b/arch/arm/mach-bcm/Makefile @@ -43,6 +43,11 @@ endif # BCM2835 obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o +ifeq ($(CONFIG_ARCH_BCM2835),y) +ifeq ($(CONFIG_ARM),y) +obj-$(CONFIG_SMP) += platsmp.o +endif +endif # BCM5301X obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c index 0c1edfc98696..8cff865ace04 100644 --- a/arch/arm/mach-bcm/board_bcm2835.c +++ b/arch/arm/mach-bcm/board_bcm2835.c @@ -15,15 +15,11 @@ #include #include #include -#include #include #include -static void __init bcm2835_init(void) -{ - bcm2835_init_clocks(); -} +#include "platsmp.h" static const char * const bcm2835_compat[] = { #ifdef CONFIG_ARCH_MULTI_V6 @@ -31,11 +27,12 @@ static const char * const bcm2835_compat[] = { #endif #ifdef CONFIG_ARCH_MULTI_V7 "brcm,bcm2836", + "brcm,bcm2837", #endif NULL }; DT_MACHINE_START(BCM2835, "BCM2835") - .init_machine = bcm2835_init, - .dt_compat = bcm2835_compat + .dt_compat = bcm2835_compat, + .smp = smp_ops(bcm2836_smp_ops), MACHINE_END diff --git a/arch/arm/mach-bcm/platsmp.c b/arch/arm/mach-bcm/platsmp.c index 9e3f275934eb..7d954830eb57 100644 --- a/arch/arm/mach-bcm/platsmp.c +++ b/arch/arm/mach-bcm/platsmp.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -287,6 +288,38 @@ out: return ret; } +static int bcm2836_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + void __iomem *intc_base; + struct device_node *dn; + char *name; + + name = "brcm,bcm2836-l1-intc"; + dn = of_find_compatible_node(NULL, NULL, name); + if (!dn) { + pr_err("unable to find intc node\n"); + return -ENODEV; + } + + intc_base = of_iomap(dn, 0); + of_node_put(dn); + + if (!intc_base) { + pr_err("unable to remap intc base register\n"); + return -ENOMEM; + } + + writel(virt_to_phys(secondary_startup), + intc_base + LOCAL_MAILBOX3_SET0 + 16 * cpu); + + dsb(sy); + sev(); + + iounmap(intc_base); + + return 0; +} + static const struct smp_operations kona_smp_ops __initconst = { .smp_prepare_cpus = bcm_smp_prepare_cpus, .smp_boot_secondary = kona_boot_secondary, @@ -305,3 +338,8 @@ static const struct smp_operations nsp_smp_ops __initconst = { .smp_boot_secondary = nsp_boot_secondary, }; CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops); + +const struct smp_operations bcm2836_smp_ops __initconst = { + .smp_boot_secondary = bcm2836_boot_secondary, +}; +CPU_METHOD_OF_DECLARE(bcm_smp_bcm2836, "brcm,bcm2836-smp", &bcm2836_smp_ops); diff --git a/arch/arm/mach-bcm/platsmp.h b/arch/arm/mach-bcm/platsmp.h new file mode 100644 index 000000000000..b8b8b3fa350d --- /dev/null +++ b/arch/arm/mach-bcm/platsmp.h @@ -0,0 +1,10 @@ +/* + * Copyright (C) 2017 Stefan Wahren + * + * 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 version 2. + * + */ + +extern const struct smp_operations bcm2836_smp_ops; diff --git a/drivers/clk/bcm/clk-bcm2835-aux.c b/drivers/clk/bcm/clk-bcm2835-aux.c index bd750cf2238d..77e276d61702 100644 --- a/drivers/clk/bcm/clk-bcm2835-aux.c +++ b/drivers/clk/bcm/clk-bcm2835-aux.c @@ -14,7 +14,6 @@ #include #include -#include #include #include #include diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 58ce6af8452d..44301a3d9963 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -416,35 +415,6 @@ static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base, return regdump ? 0 : -ENOMEM; } -/* - * These are fixed clocks. They're probably not all root clocks and it may - * be possible to turn them on and off but until this is mapped out better - * it's the only way they can be used. - */ -void __init bcm2835_init_clocks(void) -{ - struct clk_hw *hw; - int ret; - - hw = clk_hw_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 126000000); - if (IS_ERR(hw)) - pr_err("apb_pclk not registered\n"); - - hw = clk_hw_register_fixed_rate(NULL, "uart0_pclk", NULL, 0, 3000000); - if (IS_ERR(hw)) - pr_err("uart0_pclk not registered\n"); - ret = clk_hw_register_clkdev(hw, NULL, "20201000.uart"); - if (ret) - pr_err("uart0_pclk alias not registered\n"); - - hw = clk_hw_register_fixed_rate(NULL, "uart1_pclk", NULL, 0, 125000000); - if (IS_ERR(hw)) - pr_err("uart1_pclk not registered\n"); - ret = clk_hw_register_clkdev(hw, NULL, "20215000.uart"); - if (ret) - pr_err("uart1_pclk alias not registered\n"); -} - struct bcm2835_pll_data { const char *name; u32 cm_ctrl_reg; diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c index dc8c1e3eafe7..667b9e14b032 100644 --- a/drivers/irqchip/irq-bcm2836.c +++ b/drivers/irqchip/irq-bcm2836.c @@ -19,63 +19,10 @@ #include #include #include +#include + #include -#define LOCAL_CONTROL 0x000 -#define LOCAL_PRESCALER 0x008 - -/* - * The low 2 bits identify the CPU that the GPU IRQ goes to, and the - * next 2 bits identify the CPU that the GPU FIQ goes to. - */ -#define LOCAL_GPU_ROUTING 0x00c -/* When setting bits 0-3, enables PMU interrupts on that CPU. */ -#define LOCAL_PM_ROUTING_SET 0x010 -/* When setting bits 0-3, disables PMU interrupts on that CPU. */ -#define LOCAL_PM_ROUTING_CLR 0x014 -/* - * The low 4 bits of this are the CPU's timer IRQ enables, and the - * next 4 bits are the CPU's timer FIQ enables (which override the IRQ - * bits). - */ -#define LOCAL_TIMER_INT_CONTROL0 0x040 -/* - * The low 4 bits of this are the CPU's per-mailbox IRQ enables, and - * the next 4 bits are the CPU's per-mailbox FIQ enables (which - * override the IRQ bits). - */ -#define LOCAL_MAILBOX_INT_CONTROL0 0x050 -/* - * The CPU's interrupt status register. Bits are defined by the the - * LOCAL_IRQ_* bits below. - */ -#define LOCAL_IRQ_PENDING0 0x060 -/* Same status bits as above, but for FIQ. */ -#define LOCAL_FIQ_PENDING0 0x070 -/* - * Mailbox write-to-set bits. There are 16 mailboxes, 4 per CPU, and - * these bits are organized by mailbox number and then CPU number. We - * use mailbox 0 for IPIs. The mailbox's interrupt is raised while - * any bit is set. - */ -#define LOCAL_MAILBOX0_SET0 0x080 -#define LOCAL_MAILBOX3_SET0 0x08c -/* Mailbox write-to-clear bits. */ -#define LOCAL_MAILBOX0_CLR0 0x0c0 -#define LOCAL_MAILBOX3_CLR0 0x0cc - -#define LOCAL_IRQ_CNTPSIRQ 0 -#define LOCAL_IRQ_CNTPNSIRQ 1 -#define LOCAL_IRQ_CNTHPIRQ 2 -#define LOCAL_IRQ_CNTVIRQ 3 -#define LOCAL_IRQ_MAILBOX0 4 -#define LOCAL_IRQ_MAILBOX1 5 -#define LOCAL_IRQ_MAILBOX2 6 -#define LOCAL_IRQ_MAILBOX3 7 -#define LOCAL_IRQ_GPU_FAST 8 -#define LOCAL_IRQ_PMU_FAST 9 -#define LAST_IRQ LOCAL_IRQ_PMU_FAST - struct bcm2836_arm_irqchip_intc { struct irq_domain *domain; void __iomem *base; @@ -215,24 +162,6 @@ static int bcm2836_cpu_dying(unsigned int cpu) cpu); return 0; } - -#ifdef CONFIG_ARM -static int __init bcm2836_smp_boot_secondary(unsigned int cpu, - struct task_struct *idle) -{ - unsigned long secondary_startup_phys = - (unsigned long)virt_to_phys((void *)secondary_startup); - - writel(secondary_startup_phys, - intc.base + LOCAL_MAILBOX3_SET0 + 16 * cpu); - - return 0; -} - -static const struct smp_operations bcm2836_smp_ops __initconst = { - .smp_boot_secondary = bcm2836_smp_boot_secondary, -}; -#endif #endif static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = { @@ -249,10 +178,6 @@ bcm2836_arm_irqchip_smp_init(void) bcm2836_cpu_dying); set_smp_cross_call(bcm2836_arm_irqchip_send_ipi); - -#ifdef CONFIG_ARM - smp_set_ops(&bcm2836_smp_ops); -#endif #endif } diff --git a/include/linux/clk/bcm2835.h b/include/linux/clk/bcm2835.h deleted file mode 100644 index aa937f6c17da..000000000000 --- a/include/linux/clk/bcm2835.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2010 Broadcom - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __LINUX_CLK_BCM2835_H_ -#define __LINUX_CLK_BCM2835_H_ - -void __init bcm2835_init_clocks(void); - -#endif diff --git a/include/linux/irqchip/irq-bcm2836.h b/include/linux/irqchip/irq-bcm2836.h new file mode 100644 index 000000000000..218a6e1b18d8 --- /dev/null +++ b/include/linux/irqchip/irq-bcm2836.h @@ -0,0 +1,70 @@ +/* + * Root interrupt controller for the BCM2836 (Raspberry Pi 2). + * + * Copyright 2015 Broadcom + * + * 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. + */ + +#define LOCAL_CONTROL 0x000 +#define LOCAL_PRESCALER 0x008 + +/* + * The low 2 bits identify the CPU that the GPU IRQ goes to, and the + * next 2 bits identify the CPU that the GPU FIQ goes to. + */ +#define LOCAL_GPU_ROUTING 0x00c +/* When setting bits 0-3, enables PMU interrupts on that CPU. */ +#define LOCAL_PM_ROUTING_SET 0x010 +/* When setting bits 0-3, disables PMU interrupts on that CPU. */ +#define LOCAL_PM_ROUTING_CLR 0x014 +/* + * The low 4 bits of this are the CPU's timer IRQ enables, and the + * next 4 bits are the CPU's timer FIQ enables (which override the IRQ + * bits). + */ +#define LOCAL_TIMER_INT_CONTROL0 0x040 +/* + * The low 4 bits of this are the CPU's per-mailbox IRQ enables, and + * the next 4 bits are the CPU's per-mailbox FIQ enables (which + * override the IRQ bits). + */ +#define LOCAL_MAILBOX_INT_CONTROL0 0x050 +/* + * The CPU's interrupt status register. Bits are defined by the the + * LOCAL_IRQ_* bits below. + */ +#define LOCAL_IRQ_PENDING0 0x060 +/* Same status bits as above, but for FIQ. */ +#define LOCAL_FIQ_PENDING0 0x070 +/* + * Mailbox write-to-set bits. There are 16 mailboxes, 4 per CPU, and + * these bits are organized by mailbox number and then CPU number. We + * use mailbox 0 for IPIs. The mailbox's interrupt is raised while + * any bit is set. + */ +#define LOCAL_MAILBOX0_SET0 0x080 +#define LOCAL_MAILBOX3_SET0 0x08c +/* Mailbox write-to-clear bits. */ +#define LOCAL_MAILBOX0_CLR0 0x0c0 +#define LOCAL_MAILBOX3_CLR0 0x0cc + +#define LOCAL_IRQ_CNTPSIRQ 0 +#define LOCAL_IRQ_CNTPNSIRQ 1 +#define LOCAL_IRQ_CNTHPIRQ 2 +#define LOCAL_IRQ_CNTVIRQ 3 +#define LOCAL_IRQ_MAILBOX0 4 +#define LOCAL_IRQ_MAILBOX1 5 +#define LOCAL_IRQ_MAILBOX2 6 +#define LOCAL_IRQ_MAILBOX3 7 +#define LOCAL_IRQ_GPU_FAST 8 +#define LOCAL_IRQ_PMU_FAST 9 +#define LAST_IRQ LOCAL_IRQ_PMU_FAST