diff options
Diffstat (limited to 'arch/arm/mach-bcm')
| -rw-r--r-- | arch/arm/mach-bcm/Kconfig | 96 | ||||
| -rw-r--r-- | arch/arm/mach-bcm/Makefile | 25 | ||||
| -rw-r--r-- | arch/arm/mach-bcm/bcm_5301x.c | 56 | ||||
| -rw-r--r-- | arch/arm/mach-bcm/bcm_kona_smc.c | 136 | ||||
| -rw-r--r-- | arch/arm/mach-bcm/bcm_kona_smc.h | 52 | ||||
| -rw-r--r-- | arch/arm/mach-bcm/bcm_kona_smc_asm.S | 41 | ||||
| -rw-r--r-- | arch/arm/mach-bcm/board_bcm21664.c | 77 | ||||
| -rw-r--r-- | arch/arm/mach-bcm/board_bcm281xx.c | 86 | ||||
| -rw-r--r-- | arch/arm/mach-bcm/board_bcm2835.c | 137 | ||||
| -rw-r--r-- | arch/arm/mach-bcm/kona.c | 65 | ||||
| -rw-r--r-- | arch/arm/mach-bcm/kona_l2_cache.c | 47 | ||||
| -rw-r--r-- | arch/arm/mach-bcm/kona_l2_cache.h (renamed from arch/arm/mach-bcm/kona.h) | 11 | 
12 files changed, 570 insertions, 259 deletions
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index 69d67f714a2..41c839167e8 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -1,20 +1,90 @@ -config ARCH_BCM -	bool "Broadcom SoC" if ARCH_MULTI_V7 -	depends on MMU +menuconfig ARCH_BCM +	bool "Broadcom SoC Support" if ARCH_MULTI_V6_V7 +	help +	  This enables support for Broadcom ARM based SoC chips + +if ARCH_BCM + +config ARCH_BCM_MOBILE +	bool "Broadcom Mobile SoC Support" if ARCH_MULTI_V7  	select ARCH_REQUIRE_GPIOLIB  	select ARM_ERRATA_754322  	select ARM_ERRATA_764369 if SMP +	select ARM_ERRATA_775420  	select ARM_GIC -	select CPU_V7 -	select CLKSRC_OF -	select GENERIC_CLOCKEVENTS -	select GENERIC_TIME -	select GPIO_BCM -	select SPARSE_IRQ +	select GPIO_BCM_KONA  	select TICK_ONESHOT +	select HAVE_ARM_ARCH_TIMER +	select PINCTRL +	help +	  This enables support for systems based on Broadcom mobile SoCs. + +if ARCH_BCM_MOBILE + +menu "Broadcom Mobile SoC Selection" + +config ARCH_BCM_281XX +	bool "Broadcom BCM281XX SoC family" +	default y +	help +	  Enable support for the the BCM281XX family, which includes +	  BCM11130, BCM11140, BCM11351, BCM28145 and BCM28155 +	  variants. + +config ARCH_BCM_21664 +	bool "Broadcom BCM21664 SoC family" +	default y +	help +	  Enable support for the the BCM21664 family, which includes +	  BCM21663 and BCM21664 variants. + +config ARCH_BCM_MOBILE_L2_CACHE +	bool "Broadcom mobile SoC level 2 cache support" +	depends on (ARCH_BCM_281XX || ARCH_BCM_21664) +	default y +	select CACHE_L2X0 +	select ARCH_BCM_MOBILE_SMC + +config ARCH_BCM_MOBILE_SMC +	bool +	depends on ARCH_BCM_281XX || ARCH_BCM_21664 + +endmenu + +endif + +config ARCH_BCM2835 +	bool "Broadcom BCM2835 family" if ARCH_MULTI_V6 +	select ARCH_REQUIRE_GPIOLIB +	select ARM_AMBA +	select ARM_ERRATA_411920 +	select ARM_TIMER_SP804 +	select CLKSRC_OF +	select PINCTRL +	select PINCTRL_BCM2835 +	help +	  This enables support for the Broadcom BCM2835 SoC. This SoC is +	  used in the Raspberry Pi and Roku 2 devices. + +config ARCH_BCM_5301X +	bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7 +	select ARM_GIC  	select CACHE_L2X0 +	select HAVE_ARM_SCU if SMP +	select HAVE_ARM_TWD if SMP +	select ARM_GLOBAL_TIMER +	select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK  	help -	  This enables support for system based on Broadcom SoCs. -	  It currently supports the 'BCM281XX' family, which includes -	  BCM11130, BCM11140, BCM11351, BCM28145 and -	  BCM28155 variants. +	  Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores. + +	  This is a network SoC line mostly used in home routers and +	  wifi access points, it's internal name is Northstar. +	  This inclused the following SoC: BCM53010, BCM53011, BCM53012, +	  BCM53014, BCM53015, BCM53016, BCM53017, BCM53018, BCM4707, +	  BCM4708 and BCM4709. + +	  Do not confuse this with the BCM4760 which is a totally +	  different SoC or with the older BCM47XX and BCM53XX based +	  network SoC using a MIPS CPU, they are supported by arch/mips/bcm47xx + +endif diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile index e3d03033a7e..73129211497 100644 --- a/arch/arm/mach-bcm/Makefile +++ b/arch/arm/mach-bcm/Makefile @@ -1,5 +1,5 @@  # -# Copyright (C) 2012-2013 Broadcom Corporation +# Copyright (C) 2012-2014 Broadcom Corporation  #  # This program is free software; you can redistribute it and/or  # modify it under the terms of the GNU General Public License as @@ -10,6 +10,23 @@  # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  # GNU General Public License for more details. -obj-$(CONFIG_ARCH_BCM)		:= board_bcm281xx.o bcm_kona_smc.o bcm_kona_smc_asm.o kona.o -plus_sec := $(call as-instr,.arch_extension sec,+sec) -AFLAGS_bcm_kona_smc_asm.o	:=-Wa,-march=armv7-a$(plus_sec) +# BCM281XX +obj-$(CONFIG_ARCH_BCM_281XX)	+= board_bcm281xx.o + +# BCM21664 +obj-$(CONFIG_ARCH_BCM_21664)	+= board_bcm21664.o + +# BCM281XX and BCM21664 L2 cache control +obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona_l2_cache.o + +# Support for secure monitor traps +obj-$(CONFIG_ARCH_BCM_MOBILE_SMC) += bcm_kona_smc.o +ifeq ($(call as-instr,.arch_extension sec,as_has_sec),as_has_sec) +CFLAGS_bcm_kona_smc.o		+= -Wa,-march=armv7-a+sec -DREQUIRES_SEC +endif + +# BCM2835 +obj-$(CONFIG_ARCH_BCM2835)	+= board_bcm2835.o + +# BCM5301X +obj-$(CONFIG_ARCH_BCM_5301X)	+= bcm_5301x.o diff --git a/arch/arm/mach-bcm/bcm_5301x.c b/arch/arm/mach-bcm/bcm_5301x.c new file mode 100644 index 00000000000..e9bcbdbce55 --- /dev/null +++ b/arch/arm/mach-bcm/bcm_5301x.c @@ -0,0 +1,56 @@ +/* + * Broadcom BCM470X / BCM5301X ARM platform code. + * + * Copyright 2013 Hauke Mehrtens <hauke@hauke-m.de> + * + * Licensed under the GNU/GPL. See COPYING for details. + */ +#include <linux/of_platform.h> +#include <asm/hardware/cache-l2x0.h> + +#include <asm/mach/arch.h> +#include <asm/siginfo.h> +#include <asm/signal.h> + + +static bool first_fault = true; + +static int bcm5301x_abort_handler(unsigned long addr, unsigned int fsr, +				 struct pt_regs *regs) +{ +	if (fsr == 0x1c06 && first_fault) { +		first_fault = false; + +		/* +		 * These faults with code 0x1c06 happens for no good reason, +		 * possibly left over from the CFE boot loader. +		 */ +		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; +	} + +	/* Others should cause a fault */ +	return 1; +} + +static void __init bcm5301x_init_early(void) +{ +	/* Install our hook */ +	hook_fault_code(16 + 6, bcm5301x_abort_handler, SIGBUS, BUS_OBJERR, +			"imprecise external abort"); +} + +static const char __initconst *bcm5301x_dt_compat[] = { +	"brcm,bcm4708", +	NULL, +}; + +DT_MACHINE_START(BCM5301X, "BCM5301X") +	.l2c_aux_val	= 0, +	.l2c_aux_mask	= ~0, +	.init_early	= bcm5301x_init_early, +	.dt_compat	= bcm5301x_dt_compat, +MACHINE_END diff --git a/arch/arm/mach-bcm/bcm_kona_smc.c b/arch/arm/mach-bcm/bcm_kona_smc.c index 5e31e918f32..a55a7ecf146 100644 --- a/arch/arm/mach-bcm/bcm_kona_smc.c +++ b/arch/arm/mach-bcm/bcm_kona_smc.c @@ -21,11 +21,8 @@  #include "bcm_kona_smc.h" -struct secure_bridge_data { -	void __iomem *bounce;		/* virtual address */ -	u32 __iomem buffer_addr;	/* physical address */ -	int initialized; -} bridge_data; +static u32		bcm_smc_buffer_phys;	/* physical address */ +static void __iomem	*bcm_smc_buffer;	/* virtual address */  struct bcm_kona_smc_data {  	unsigned service_id; @@ -33,6 +30,7 @@ struct bcm_kona_smc_data {  	unsigned arg1;  	unsigned arg2;  	unsigned arg3; +	unsigned result;  };  static const struct of_device_id bcm_kona_smc_ids[] __initconst = { @@ -41,59 +39,125 @@ static const struct of_device_id bcm_kona_smc_ids[] __initconst = {  	{},  }; -/* Map in the bounce area */ +/* Map in the args buffer area */  int __init bcm_kona_smc_init(void)  {  	struct device_node *node; +	const __be32 *prop_val; +	u64 prop_size = 0; +	unsigned long buffer_size; +	u32 buffer_phys;  	/* Read buffer addr and size from the device tree node */  	node = of_find_matching_node(NULL, bcm_kona_smc_ids);  	if (!node)  		return -ENODEV; -	/* Don't care about size or flags of the DT node */ -	bridge_data.buffer_addr = -		be32_to_cpu(*of_get_address(node, 0, NULL, NULL)); -	BUG_ON(!bridge_data.buffer_addr); +	prop_val = of_get_address(node, 0, &prop_size, NULL); +	if (!prop_val) +		return -EINVAL; -	bridge_data.bounce = of_iomap(node, 0); -	BUG_ON(!bridge_data.bounce); +	/* We assume space for four 32-bit arguments */ +	if (prop_size < 4 * sizeof(u32) || prop_size > (u64)ULONG_MAX) +		return -EINVAL; +	buffer_size = (unsigned long)prop_size; -	bridge_data.initialized = 1; +	buffer_phys = be32_to_cpup(prop_val); +	if (!buffer_phys) +		return -EINVAL; + +	bcm_smc_buffer = ioremap(buffer_phys, buffer_size); +	if (!bcm_smc_buffer) +		return -ENOMEM; +	bcm_smc_buffer_phys = buffer_phys;  	pr_info("Kona Secure API initialized\n");  	return 0;  } +/* + * int bcm_kona_do_smc(u32 service_id, u32 buffer_addr) + * + * Only core 0 can run the secure monitor code.  If an "smc" request + * is initiated on a different core it must be redirected to core 0 + * for execution.  We rely on the caller to handle this. + * + * Each "smc" request supplies a service id and the address of a + * buffer containing parameters related to the service to be + * performed.  A flags value defines the behavior of the level 2 + * cache and interrupt handling while the secure monitor executes. + * + * Parameters to the "smc" request are passed in r4-r6 as follows: + *     r4	service id + *     r5	flags (SEC_ROM_*) + *     r6	physical address of buffer with other parameters + * + * Execution of an "smc" request produces two distinct results. + * + * First, the secure monitor call itself (regardless of the specific + * service request) can succeed, or can produce an error.  When an + * "smc" request completes this value is found in r12; it should + * always be SEC_EXIT_NORMAL. + * + * In addition, the particular service performed produces a result. + * The values that should be expected depend on the service.  We + * therefore return this value to the caller, so it can handle the + * request result appropriately.  This result value is found in r0 + * when the "smc" request completes. + */ +static int bcm_kona_do_smc(u32 service_id, u32 buffer_phys) +{ +	register u32 ip asm("ip");	/* Also called r12 */ +	register u32 r0 asm("r0"); +	register u32 r4 asm("r4"); +	register u32 r5 asm("r5"); +	register u32 r6 asm("r6"); + +	r4 = service_id; +	r5 = 0x3;		/* Keep IRQ and FIQ off in SM */ +	r6 = buffer_phys; + +	asm volatile ( +		/* Make sure we got the registers we want */ +		__asmeq("%0", "ip") +		__asmeq("%1", "r0") +		__asmeq("%2", "r4") +		__asmeq("%3", "r5") +		__asmeq("%4", "r6") +#ifdef REQUIRES_SEC +		".arch_extension sec\n" +#endif +		"	smc    #0\n" +		: "=r" (ip), "=r" (r0) +		: "r" (r4), "r" (r5), "r" (r6) +		: "r1", "r2", "r3", "r7", "lr"); + +	BUG_ON(ip != SEC_EXIT_NORMAL); + +	return r0; +} +  /* __bcm_kona_smc() should only run on CPU 0, with pre-emption disabled */  static void __bcm_kona_smc(void *info)  {  	struct bcm_kona_smc_data *data = info; -	u32 *args = bridge_data.bounce; -	int rc = 0; +	u32 *args = bcm_smc_buffer; -	/* Must run on CPU 0 */  	BUG_ON(smp_processor_id() != 0); +	BUG_ON(!args); -	/* Check map in the bounce area */ -	BUG_ON(!bridge_data.initialized); - -	/* Copy one 32 bit word into the bounce area */ -	args[0] = data->arg0; -	args[1] = data->arg1; -	args[2] = data->arg2; -	args[3] = data->arg3; +	/* Copy the four 32 bit argument values into the bounce area */ +	writel_relaxed(data->arg0, args++); +	writel_relaxed(data->arg1, args++); +	writel_relaxed(data->arg2, args++); +	writel(data->arg3, args);  	/* Flush caches for input data passed to Secure Monitor */ -	if (data->service_id != SSAPI_BRCM_START_VC_CORE) -		flush_cache_all(); - -	/* Trap into Secure Monitor */ -	rc = bcm_kona_smc_asm(data->service_id, bridge_data.buffer_addr); +	flush_cache_all(); -	if (rc != SEC_ROM_RET_OK) -		pr_err("Secure Monitor call failed (0x%x)!\n", rc); +	/* Trap into Secure Monitor and record the request result */ +	data->result = bcm_kona_do_smc(data->service_id, bcm_smc_buffer_phys);  }  unsigned bcm_kona_smc(unsigned service_id, unsigned arg0, unsigned arg1, @@ -106,17 +170,13 @@ unsigned bcm_kona_smc(unsigned service_id, unsigned arg0, unsigned arg1,  	data.arg1 = arg1;  	data.arg2 = arg2;  	data.arg3 = arg3; +	data.result = 0;  	/*  	 * Due to a limitation of the secure monitor, we must use the SMP  	 * infrastructure to forward all secure monitor calls to Core 0.  	 */ -	if (get_cpu() != 0) -		smp_call_function_single(0, __bcm_kona_smc, (void *)&data, 1); -	else -		__bcm_kona_smc(&data); +	smp_call_function_single(0, __bcm_kona_smc, &data, 1); -	put_cpu(); - -	return 0; +	return data.result;  } diff --git a/arch/arm/mach-bcm/bcm_kona_smc.h b/arch/arm/mach-bcm/bcm_kona_smc.h index d098a7e7674..2e29ec67e41 100644 --- a/arch/arm/mach-bcm/bcm_kona_smc.h +++ b/arch/arm/mach-bcm/bcm_kona_smc.h @@ -15,55 +15,12 @@  #define BCM_KONA_SMC_H  #include <linux/types.h> -#define FLAGS	(SEC_ROM_ICACHE_ENABLE_MASK | SEC_ROM_DCACHE_ENABLE_MASK | \ -			SEC_ROM_IRQ_ENABLE_MASK | SEC_ROM_FIQ_ENABLE_MASK) -/*! - * Definitions for IRQ & FIQ Mask for ARM - */ - -#define FIQ_IRQ_MASK						0xC0 -#define FIQ_MASK						0x40 -#define IRQ_MASK						0x80 - -/*! - * Secure Mode FLAGs - */ - -/* When set, enables ICache within the secure mode */ -#define SEC_ROM_ICACHE_ENABLE_MASK                        0x00000001 - -/* When set, enables DCache within the secure mode */ -#define SEC_ROM_DCACHE_ENABLE_MASK                        0x00000002 - -/* When set, enables IRQ within the secure mode */ -#define SEC_ROM_IRQ_ENABLE_MASK                           0x00000004 - -/* When set, enables FIQ within the secure mode */ -#define SEC_ROM_FIQ_ENABLE_MASK                           0x00000008 - -/* When set, enables Unified L2 cache within the secure mode */ -#define SEC_ROM_UL2_CACHE_ENABLE_MASK                     0x00000010 - -/* Broadcom Secure Service API Service IDs */ -#define SSAPI_DORMANT_ENTRY_SERV                          0x01000000 -#define SSAPI_PUBLIC_OTP_SERV                             0x01000001 -#define SSAPI_ENABLE_L2_CACHE                             0x01000002 -#define SSAPI_DISABLE_L2_CACHE                            0x01000003 -#define SSAPI_WRITE_SCU_STATUS                            0x01000004 -#define SSAPI_WRITE_PWR_GATE                              0x01000005 - -/* Broadcom Secure Service API Return Codes */ +/* Broadcom Secure Service API service IDs, return codes, and exit codes */ +#define SSAPI_ENABLE_L2_CACHE		0x01000002  #define SEC_ROM_RET_OK			0x00000001 -#define SEC_ROM_RET_FAIL		0x00000009 - -#define SSAPI_RET_FROM_INT_SERV		0x4  #define SEC_EXIT_NORMAL			0x1 -#define SSAPI_ROW_AES			0x0E000006 -#define SSAPI_BRCM_START_VC_CORE	0x0E000008 - -#ifndef	__ASSEMBLY__  extern int __init bcm_kona_smc_init(void);  extern unsigned bcm_kona_smc(unsigned service_id, @@ -72,9 +29,4 @@ extern unsigned bcm_kona_smc(unsigned service_id,  			     unsigned arg2,  			     unsigned arg3); -extern int bcm_kona_smc_asm(u32 service_id, -			    u32 buffer_addr); - -#endif	/* __ASSEMBLY__ */ -  #endif /* BCM_KONA_SMC_H */ diff --git a/arch/arm/mach-bcm/bcm_kona_smc_asm.S b/arch/arm/mach-bcm/bcm_kona_smc_asm.S deleted file mode 100644 index a1608480d60..00000000000 --- a/arch/arm/mach-bcm/bcm_kona_smc_asm.S +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2013 Broadcom Corporation - * - * 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. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - */ - -#include <linux/linkage.h> -#include "bcm_kona_smc.h" - -/* - * int bcm_kona_smc_asm(u32 service_id, u32 buffer_addr) - */ - -ENTRY(bcm_kona_smc_asm) -	stmfd	sp!, {r4-r12, lr} -	mov	r4, r0		@ service_id -	mov	r5, #3		@ Keep IRQ and FIQ off in SM -	/* -	 * Since interrupts are disabled in the open mode, we must keep -	 * interrupts disabled in secure mode by setting R5=0x3. If interrupts -	 * are enabled in open mode, we can set R5=0x0 to allow interrupts in -	 * secure mode.  If we did this, the secure monitor would return back -	 * control to the open mode to handle the interrupt prior to completing -	 * the secure service. If this happened, R12 would not be -	 * SEC_EXIT_NORMAL and we would need to call SMC again after resetting -	 * R5 (it gets clobbered by the secure monitor) and setting R4 to -	 * SSAPI_RET_FROM_INT_SERV to indicate that we want the secure monitor -	 * to finish up the previous uncompleted secure service. -	 */ -	mov	r6, r1		@ buffer_addr -	smc	#0 -	/* Check r12 for SEC_EXIT_NORMAL here if interrupts are enabled */ -	ldmfd	sp!, {r4-r12, pc} -ENDPROC(bcm_kona_smc_asm) diff --git a/arch/arm/mach-bcm/board_bcm21664.c b/arch/arm/mach-bcm/board_bcm21664.c new file mode 100644 index 00000000000..f0521cc0640 --- /dev/null +++ b/arch/arm/mach-bcm/board_bcm21664.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2014 Broadcom Corporation + * + * 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. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + +#include <linux/of_address.h> +#include <linux/of_platform.h> +#include <linux/io.h> + +#include <asm/mach/arch.h> + +#include "kona_l2_cache.h" + +#define RSTMGR_DT_STRING		"brcm,bcm21664-resetmgr" + +#define RSTMGR_REG_WR_ACCESS_OFFSET	0 +#define RSTMGR_REG_CHIP_SOFT_RST_OFFSET	4 + +#define RSTMGR_WR_PASSWORD		0xa5a5 +#define RSTMGR_WR_PASSWORD_SHIFT	8 +#define RSTMGR_WR_ACCESS_ENABLE		1 + +static void bcm21664_restart(enum reboot_mode mode, const char *cmd) +{ +	void __iomem *base; +	struct device_node *resetmgr; + +	resetmgr = of_find_compatible_node(NULL, NULL, RSTMGR_DT_STRING); +	if (!resetmgr) { +		pr_emerg("Couldn't find " RSTMGR_DT_STRING "\n"); +		return; +	} +	base = of_iomap(resetmgr, 0); +	if (!base) { +		pr_emerg("Couldn't map " RSTMGR_DT_STRING "\n"); +		return; +	} + +	/* +	 * A soft reset is triggered by writing a 0 to bit 0 of the soft reset +	 * register. To write to that register we must first write the password +	 * and the enable bit in the write access enable register. +	 */ +	writel((RSTMGR_WR_PASSWORD << RSTMGR_WR_PASSWORD_SHIFT) | +		RSTMGR_WR_ACCESS_ENABLE, +		base + RSTMGR_REG_WR_ACCESS_OFFSET); +	writel(0, base + RSTMGR_REG_CHIP_SOFT_RST_OFFSET); + +	/* Wait for reset */ +	while (1); +} + +static void __init bcm21664_init(void) +{ +	of_platform_populate(NULL, of_default_bus_match_table, NULL, +		&platform_bus); +	kona_l2_cache_init(); +} + +static const char * const bcm21664_dt_compat[] = { +	"brcm,bcm21664", +	NULL, +}; + +DT_MACHINE_START(BCM21664_DT, "BCM21664 Broadcom Application Processor") +	.init_machine = bcm21664_init, +	.restart = bcm21664_restart, +	.dt_compat = bcm21664_dt_compat, +MACHINE_END diff --git a/arch/arm/mach-bcm/board_bcm281xx.c b/arch/arm/mach-bcm/board_bcm281xx.c index 8d9f931164b..1ac59fc0cb1 100644 --- a/arch/arm/mach-bcm/board_bcm281xx.c +++ b/arch/arm/mach-bcm/board_bcm281xx.c @@ -1,5 +1,5 @@  /* - * Copyright (C) 2012-2013 Broadcom Corporation + * Copyright (C) 2012-2014 Broadcom Corporation   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License as @@ -11,65 +11,65 @@   * GNU General Public License for more details.   */ -#include <linux/of_platform.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/platform_device.h>  #include <linux/clocksource.h> +#include <linux/of_address.h> +#include <linux/of_platform.h>  #include <asm/mach/arch.h> -#include <asm/mach/time.h> -#include <asm/hardware/cache-l2x0.h> -#include "bcm_kona_smc.h" -#include "kona.h" +#include "kona_l2_cache.h" + +#define SECWDOG_OFFSET			0x00000000 +#define SECWDOG_RESERVED_MASK		0xe2000000 +#define SECWDOG_WD_LOAD_FLAG_MASK	0x10000000 +#define SECWDOG_EN_MASK			0x08000000 +#define SECWDOG_SRSTEN_MASK		0x04000000 +#define SECWDOG_CLKS_SHIFT		20 +#define SECWDOG_COUNT_SHIFT		0 -static int __init kona_l2_cache_init(void) +static void bcm281xx_restart(enum reboot_mode mode, const char *cmd)  { -	if (!IS_ENABLED(CONFIG_CACHE_L2X0)) -		return 0; +	uint32_t val; +	void __iomem *base; +	struct device_node *np_wdog; -	if (bcm_kona_smc_init() < 0) { -		pr_info("Kona secure API not available. Skipping L2 init\n"); -		return 0; +	np_wdog = of_find_compatible_node(NULL, NULL, "brcm,kona-wdt"); +	if (!np_wdog) { +		pr_emerg("Couldn't find brcm,kona-wdt\n"); +		return; +	} +	base = of_iomap(np_wdog, 0); +	if (!base) { +		pr_emerg("Couldn't map brcm,kona-wdt\n"); +		return;  	} -	bcm_kona_smc(SSAPI_ENABLE_L2_CACHE, 0, 0, 0, 0); - -	/* -	 * The aux_val and aux_mask have no effect since L2 cache is already -	 * enabled.  Pass 0s for aux_val and 1s for aux_mask for default value. -	 */ -	return l2x0_of_init(0, ~0); -} - -static void bcm_board_setup_restart(void) -{ -	struct device_node *np; +	/* Enable watchdog with short timeout (244us). */ +	val = readl(base + SECWDOG_OFFSET); +	val &= SECWDOG_RESERVED_MASK | SECWDOG_WD_LOAD_FLAG_MASK; +	val |= SECWDOG_EN_MASK | SECWDOG_SRSTEN_MASK | +		(0x15 << SECWDOG_CLKS_SHIFT) | +		(0x8 << SECWDOG_COUNT_SHIFT); +	writel(val, base + SECWDOG_OFFSET); -	np = of_find_compatible_node(NULL, NULL, "brcm,bcm11351"); -	if (np) { -		if (of_device_is_available(np)) -			bcm_kona_setup_restart(); -		of_node_put(np); -	} -	/* Restart setup for other boards goes here */ +	/* Wait for reset */ +	while (1);  } -static void __init board_init(void) +static void __init bcm281xx_init(void)  {  	of_platform_populate(NULL, of_default_bus_match_table, NULL,  		&platform_bus); - -	bcm_board_setup_restart();  	kona_l2_cache_init();  } -static const char * const bcm11351_dt_compat[] = { "brcm,bcm11351", NULL, }; +static const char * const bcm281xx_dt_compat[] = { +	"brcm,bcm11351",	/* Have to use the first number upstreamed */ +	NULL, +}; -DT_MACHINE_START(BCM11351_DT, "Broadcom Application Processor") -	.init_time = clocksource_of_init, -	.init_machine = board_init, -	.restart = bcm_kona_restart, -	.dt_compat = bcm11351_dt_compat, +DT_MACHINE_START(BCM281XX_DT, "BCM281xx Broadcom Application Processor") +	.init_machine = bcm281xx_init, +	.restart = bcm281xx_restart, +	.dt_compat = bcm281xx_dt_compat,  MACHINE_END diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c new file mode 100644 index 00000000000..70f2f3925f0 --- /dev/null +++ b/arch/arm/mach-bcm/board_bcm2835.c @@ -0,0 +1,137 @@ +/* + * 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. + */ + +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/irqchip.h> +#include <linux/of_address.h> +#include <linux/of_platform.h> +#include <linux/clk/bcm2835.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#define PM_RSTC				0x1c +#define PM_RSTS				0x20 +#define PM_WDOG				0x24 + +#define PM_PASSWORD			0x5a000000 +#define PM_RSTC_WRCFG_MASK		0x00000030 +#define PM_RSTC_WRCFG_FULL_RESET	0x00000020 +#define PM_RSTS_HADWRH_SET		0x00000040 + +#define BCM2835_PERIPH_PHYS	0x20000000 +#define BCM2835_PERIPH_VIRT	0xf0000000 +#define BCM2835_PERIPH_SIZE	SZ_16M + +static void __iomem *wdt_regs; + +/* + * The machine restart method can be called from an atomic context so we won't + * be able to ioremap the regs then. + */ +static void bcm2835_setup_restart(void) +{ +	struct device_node *np = of_find_compatible_node(NULL, NULL, +						"brcm,bcm2835-pm-wdt"); +	if (WARN(!np, "unable to setup watchdog restart")) +		return; + +	wdt_regs = of_iomap(np, 0); +	WARN(!wdt_regs, "failed to remap watchdog regs"); +} + +static void bcm2835_restart(enum reboot_mode mode, const char *cmd) +{ +	u32 val; + +	if (!wdt_regs) +		return; + +	/* use a timeout of 10 ticks (~150us) */ +	writel_relaxed(10 | PM_PASSWORD, wdt_regs + PM_WDOG); +	val = readl_relaxed(wdt_regs + PM_RSTC); +	val &= ~PM_RSTC_WRCFG_MASK; +	val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET; +	writel_relaxed(val, wdt_regs + PM_RSTC); + +	/* No sleeping, possibly atomic. */ +	mdelay(1); +} + +/* + * We can't really power off, but if we do the normal reset scheme, and + * indicate to bootcode.bin not to reboot, then most of the chip will be + * powered off. + */ +static void bcm2835_power_off(void) +{ +	u32 val; + +	/* +	 * We set the watchdog hard reset bit here to distinguish this reset +	 * from the normal (full) reset. bootcode.bin will not reboot after a +	 * hard reset. +	 */ +	val = readl_relaxed(wdt_regs + PM_RSTS); +	val &= ~PM_RSTC_WRCFG_MASK; +	val |= PM_PASSWORD | PM_RSTS_HADWRH_SET; +	writel_relaxed(val, wdt_regs + PM_RSTS); + +	/* Continue with normal reset mechanism */ +	bcm2835_restart(REBOOT_HARD, ""); +} + +static struct map_desc io_map __initdata = { +	.virtual = BCM2835_PERIPH_VIRT, +	.pfn = __phys_to_pfn(BCM2835_PERIPH_PHYS), +	.length = BCM2835_PERIPH_SIZE, +	.type = MT_DEVICE +}; + +static void __init bcm2835_map_io(void) +{ +	iotable_init(&io_map, 1); +} + +static void __init bcm2835_init(void) +{ +	int ret; + +	bcm2835_setup_restart(); +	if (wdt_regs) +		pm_power_off = bcm2835_power_off; + +	bcm2835_init_clocks(); + +	ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, +				   NULL); +	if (ret) { +		pr_err("of_platform_populate failed: %d\n", ret); +		BUG(); +	} +} + +static const char * const bcm2835_compat[] = { +	"brcm,bcm2835", +	NULL +}; + +DT_MACHINE_START(BCM2835, "BCM2835") +	.map_io = bcm2835_map_io, +	.init_irq = irqchip_init, +	.init_machine = bcm2835_init, +	.restart = bcm2835_restart, +	.dt_compat = bcm2835_compat +MACHINE_END diff --git a/arch/arm/mach-bcm/kona.c b/arch/arm/mach-bcm/kona.c deleted file mode 100644 index 6939d9017f6..00000000000 --- a/arch/arm/mach-bcm/kona.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2013 Broadcom Corporation - * - * 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. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - */ - -#include <linux/of_address.h> -#include <asm/io.h> - -#include "kona.h" - -static void __iomem *watchdog_base; - -void bcm_kona_setup_restart(void) -{ -	struct device_node *np_wdog; - -	/* -	 * The assumption is that whoever calls bcm_kona_setup_restart() -	 * also needs a Kona Watchdog Timer entry in Device Tree, i.e. we -	 * report an error if the DT entry is missing. -	 */ -	np_wdog = of_find_compatible_node(NULL, NULL, "brcm,kona-wdt"); -	if (!np_wdog) { -		pr_err("brcm,kona-wdt not found in DT, reboot disabled\n"); -		return; -	} -	watchdog_base = of_iomap(np_wdog, 0); -	WARN(!watchdog_base, "failed to map watchdog base"); -	of_node_put(np_wdog); -} - -#define SECWDOG_OFFSET			0x00000000 -#define SECWDOG_RESERVED_MASK		0xE2000000 -#define SECWDOG_WD_LOAD_FLAG_MASK	0x10000000 -#define SECWDOG_EN_MASK			0x08000000 -#define SECWDOG_SRSTEN_MASK		0x04000000 -#define SECWDOG_CLKS_SHIFT		20 -#define SECWDOG_LOCK_SHIFT		0 - -void bcm_kona_restart(enum reboot_mode mode, const char *cmd) -{ -	uint32_t val; - -	if (!watchdog_base) -		panic("Watchdog not mapped. Reboot failed.\n"); - -	/* Enable watchdog2 with very short timeout. */ -	val = readl(watchdog_base + SECWDOG_OFFSET); -	val &= SECWDOG_RESERVED_MASK | SECWDOG_WD_LOAD_FLAG_MASK; -	val |= SECWDOG_EN_MASK | SECWDOG_SRSTEN_MASK | -		(0x8 << SECWDOG_CLKS_SHIFT) | -		(0x8 << SECWDOG_LOCK_SHIFT); -	writel(val, watchdog_base + SECWDOG_OFFSET); - -	while (1) -		; -} diff --git a/arch/arm/mach-bcm/kona_l2_cache.c b/arch/arm/mach-bcm/kona_l2_cache.c new file mode 100644 index 00000000000..b31970377c2 --- /dev/null +++ b/arch/arm/mach-bcm/kona_l2_cache.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2012-2014 Broadcom Corporation + * + * 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. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + + +#include <linux/init.h> +#include <linux/printk.h> +#include <asm/hardware/cache-l2x0.h> + +#include "bcm_kona_smc.h" + +void __init kona_l2_cache_init(void) +{ +	unsigned int result; +	int ret; + +	ret = bcm_kona_smc_init(); +	if (ret) { +		pr_info("Secure API not available (%d). Skipping L2 init.\n", +			ret); +		return; +	} + +	result = bcm_kona_smc(SSAPI_ENABLE_L2_CACHE, 0, 0, 0, 0); +	if (result != SEC_ROM_RET_OK) { +		pr_err("Secure Monitor call failed (%u)! Skipping L2 init.\n", +			result); +		return; +	} + +	/* +	 * The aux_val and aux_mask have no effect since L2 cache is already +	 * enabled.  Pass 0s for aux_val and 1s for aux_mask for default value. +	 */ +	ret = l2x0_of_init(0, ~0); +	if (ret) +		pr_err("Couldn't enable L2 cache: %d\n", ret); +} diff --git a/arch/arm/mach-bcm/kona.h b/arch/arm/mach-bcm/kona_l2_cache.h index 291eca3e06f..46f84a95ab1 100644 --- a/arch/arm/mach-bcm/kona.h +++ b/arch/arm/mach-bcm/kona_l2_cache.h @@ -1,5 +1,5 @@  /* - * Copyright (C) 2013 Broadcom Corporation + * Copyright (C) 2012-2014 Broadcom Corporation   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License as @@ -11,7 +11,8 @@   * GNU General Public License for more details.   */ -#include <linux/reboot.h> - -void bcm_kona_setup_restart(void); -void bcm_kona_restart(enum reboot_mode mode, const char *cmd); +#ifdef CONFIG_ARCH_BCM_MOBILE_L2_CACHE +void	kona_l2_cache_init(void); +#else +#define kona_l2_cache_init() ((void)0) +#endif  | 
