diff options
| author | Santosh Shilimkar <santosh.shilimkar@ti.com> | 2012-05-09 20:38:35 +0530 | 
|---|---|---|
| committer | Santosh Shilimkar <santosh.shilimkar@ti.com> | 2012-07-09 19:14:39 +0530 | 
| commit | 247c445c0fbd52c77e497ff5bfcf0dceb8afea8d (patch) | |
| tree | 3334a9cd1b573fa5d447cf0876e8904d21aef105 | |
| parent | e17933c2c0173ec19aa2450e4be79b7adfd52224 (diff) | |
| download | olio-linux-3.10-247c445c0fbd52c77e497ff5bfcf0dceb8afea8d.tar.xz olio-linux-3.10-247c445c0fbd52c77e497ff5bfcf0dceb8afea8d.zip | |
ARM: OMAP5: Add the WakeupGen IP updates
OMAP4 and OMAP5 share same WakeupGen IP with below few udpates on OMAP5.
- Additional 32 interrupt support is added w.r.t OMAP4 design.
- The AUX CORE boot registers are now made accessible from non-secure SW.
- SAR offset are changed and PTMSYNC* registers are removed from SAR.
Patch updates the WakeupGen code accordingly.
Signed-off-by: R Sricharan <r.sricharan@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
| -rw-r--r-- | arch/arm/mach-omap2/include/mach/omap-wakeupgen.h | 7 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/omap-hotplug.c | 24 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/omap-smp.c | 19 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/omap-wakeupgen.c | 114 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/omap4-sar-layout.h | 12 | 
5 files changed, 143 insertions, 33 deletions
| diff --git a/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h index 548de90b58c..b0fd16f5c39 100644 --- a/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h +++ b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h @@ -11,15 +11,20 @@  #ifndef OMAP_ARCH_WAKEUPGEN_H  #define OMAP_ARCH_WAKEUPGEN_H +/* OMAP4 and OMAP5 has same base address */ +#define OMAP_WKUPGEN_BASE			0x48281000 +  #define OMAP_WKG_CONTROL_0			0x00  #define OMAP_WKG_ENB_A_0			0x10  #define OMAP_WKG_ENB_B_0			0x14  #define OMAP_WKG_ENB_C_0			0x18  #define OMAP_WKG_ENB_D_0			0x1c +#define OMAP_WKG_ENB_E_0			0x20  #define OMAP_WKG_ENB_A_1			0x410  #define OMAP_WKG_ENB_B_1			0x414  #define OMAP_WKG_ENB_C_1			0x418  #define OMAP_WKG_ENB_D_1			0x41c +#define OMAP_WKG_ENB_E_1			0x420  #define OMAP_AUX_CORE_BOOT_0			0x800  #define OMAP_AUX_CORE_BOOT_1			0x804  #define OMAP_PTMSYNCREQ_MASK			0xc00 @@ -28,4 +33,6 @@  #define OMAP_TIMESTAMPCYCLEHI			0xc0c  extern int __init omap_wakeupgen_init(void); +extern void __iomem *omap_get_wakeupgen_base(void); +extern int omap_secure_apis_support(void);  #endif diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c index 56c345b8b93..414083b427d 100644 --- a/arch/arm/mach-omap2/omap-hotplug.c +++ b/arch/arm/mach-omap2/omap-hotplug.c @@ -17,8 +17,10 @@  #include <linux/kernel.h>  #include <linux/errno.h>  #include <linux/smp.h> +#include <linux/io.h>  #include <asm/cacheflush.h> +#include <mach/omap-wakeupgen.h>  #include "common.h" @@ -35,7 +37,8 @@ int platform_cpu_kill(unsigned int cpu)   */  void __ref platform_cpu_die(unsigned int cpu)  { -	unsigned int this_cpu; +	unsigned int boot_cpu = 0; +	void __iomem *base = omap_get_wakeupgen_base();  	flush_cache_all();  	dsb(); @@ -43,16 +46,27 @@ void __ref platform_cpu_die(unsigned int cpu)  	/*  	 * we're ready for shutdown now, so do it  	 */ -	if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0) -		pr_err("Secure clear status failed\n"); +	if (omap_secure_apis_support()) { +		if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0) +			pr_err("Secure clear status failed\n"); +	} else { +		__raw_writel(0, base + OMAP_AUX_CORE_BOOT_0); +	} +  	for (;;) {  		/*  		 * Enter into low power state  		 */  		omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF); -		this_cpu = smp_processor_id(); -		if (omap_read_auxcoreboot0() == this_cpu) { + +		if (omap_secure_apis_support()) +			boot_cpu = omap_read_auxcoreboot0(); +		else +			boot_cpu = +				__raw_readl(base + OMAP_AUX_CORE_BOOT_0) >> 5; + +		if (boot_cpu == smp_processor_id()) {  			/*  			 * OK, proper wakeup, we're done  			 */ diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index deffbf1c962..badfe398038 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -26,6 +26,8 @@  #include <mach/hardware.h>  #include <mach/omap-secure.h> +#include <mach/omap-wakeupgen.h> +#include <asm/cputype.h>  #include "iomap.h"  #include "common.h" @@ -73,6 +75,8 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)  {  	static struct clockdomain *cpu1_clkdm;  	static bool booted; +	void __iomem *base = omap_get_wakeupgen_base(); +  	/*  	 * Set synchronisation state between this boot processor  	 * and the secondary one @@ -85,7 +89,11 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)  	 * the AuxCoreBoot1 register is updated with cpu state  	 * A barrier is added to ensure that write buffer is drained  	 */ -	omap_modify_auxcoreboot0(0x200, 0xfffffdff); +	if (omap_secure_apis_support()) +		omap_modify_auxcoreboot0(0x200, 0xfffffdff); +	else +		__raw_writel(0x20, base + OMAP_AUX_CORE_BOOT_0); +  	flush_cache_all();  	smp_wmb(); @@ -124,13 +132,20 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)  static void __init wakeup_secondary(void)  { +	void __iomem *base = omap_get_wakeupgen_base(); +  	/*  	 * Write the address of secondary startup routine into the  	 * AuxCoreBoot1 where ROM code will jump and start executing  	 * on secondary core once out of WFE  	 * A barrier is added to ensure that write buffer is drained  	 */ -	omap_auxcoreboot_addr(virt_to_phys(omap_secondary_startup)); +	if (omap_secure_apis_support()) +		omap_auxcoreboot_addr(virt_to_phys(omap_secondary_startup)); +	else +		__raw_writel(virt_to_phys(omap5_secondary_startup), +						base + OMAP_AUX_CORE_BOOT_1); +  	smp_wmb();  	/* diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index d811c779035..05fdebfaa19 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -33,18 +33,23 @@  #include "omap4-sar-layout.h"  #include "common.h" -#define NR_REG_BANKS		4 -#define MAX_IRQS		128 +#define MAX_NR_REG_BANKS	5 +#define MAX_IRQS		160  #define WKG_MASK_ALL		0x00000000  #define WKG_UNMASK_ALL		0xffffffff  #define CPU_ENA_OFFSET		0x400  #define CPU0_ID			0x0  #define CPU1_ID			0x1 +#define OMAP4_NR_BANKS		4 +#define OMAP4_NR_IRQS		128  static void __iomem *wakeupgen_base;  static void __iomem *sar_base;  static DEFINE_SPINLOCK(wakeupgen_lock);  static unsigned int irq_target_cpu[NR_IRQS]; +static unsigned int irq_banks = MAX_NR_REG_BANKS; +static unsigned int max_irqs = MAX_IRQS; +static unsigned int omap_secure_apis;  /*   * Static helper functions. @@ -146,13 +151,13 @@ static void wakeupgen_unmask(struct irq_data *d)  }  #ifdef CONFIG_HOTPLUG_CPU -static DEFINE_PER_CPU(u32 [NR_REG_BANKS], irqmasks); +static DEFINE_PER_CPU(u32 [MAX_NR_REG_BANKS], irqmasks);  static void _wakeupgen_save_masks(unsigned int cpu)  {  	u8 i; -	for (i = 0; i < NR_REG_BANKS; i++) +	for (i = 0; i < irq_banks; i++)  		per_cpu(irqmasks, cpu)[i] = wakeupgen_readl(i, cpu);  } @@ -160,7 +165,7 @@ static void _wakeupgen_restore_masks(unsigned int cpu)  {  	u8 i; -	for (i = 0; i < NR_REG_BANKS; i++) +	for (i = 0; i < irq_banks; i++)  		wakeupgen_writel(per_cpu(irqmasks, cpu)[i], i, cpu);  } @@ -168,7 +173,7 @@ static void _wakeupgen_set_all(unsigned int cpu, unsigned int reg)  {  	u8 i; -	for (i = 0; i < NR_REG_BANKS; i++) +	for (i = 0; i < irq_banks; i++)  		wakeupgen_writel(reg, i, cpu);  } @@ -196,25 +201,14 @@ static void wakeupgen_irqmask_all(unsigned int cpu, unsigned int set)  #endif  #ifdef CONFIG_CPU_PM -/* - * Save WakeupGen interrupt context in SAR BANK3. Restore is done by - * ROM code. WakeupGen IP is integrated along with GIC to manage the - * interrupt wakeups from CPU low power states. It manages - * masking/unmasking of Shared peripheral interrupts(SPI). So the - * interrupt enable/disable control should be in sync and consistent - * at WakeupGen and GIC so that interrupts are not lost. - */ -static void irq_save_context(void) +static inline void omap4_irq_save_context(void)  {  	u32 i, val;  	if (omap_rev() == OMAP4430_REV_ES1_0)  		return; -	if (!sar_base) -		sar_base = omap4_get_sar_ram_base(); - -	for (i = 0; i < NR_REG_BANKS; i++) { +	for (i = 0; i < irq_banks; i++) {  		/* Save the CPUx interrupt mask for IRQ 0 to 127 */  		val = wakeupgen_readl(i, 0);  		sar_writel(val, WAKEUPGENENB_OFFSET_CPU0, i); @@ -254,6 +248,53 @@ static void irq_save_context(void)  	val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET);  	val |= SAR_BACKUP_STATUS_WAKEUPGEN;  	__raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET); + +} + +static inline void omap5_irq_save_context(void) +{ +	u32 i, val; + +	for (i = 0; i < irq_banks; i++) { +		/* Save the CPUx interrupt mask for IRQ 0 to 159 */ +		val = wakeupgen_readl(i, 0); +		sar_writel(val, OMAP5_WAKEUPGENENB_OFFSET_CPU0, i); +		val = wakeupgen_readl(i, 1); +		sar_writel(val, OMAP5_WAKEUPGENENB_OFFSET_CPU1, i); +		sar_writel(0x0, OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU0, i); +		sar_writel(0x0, OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU1, i); +	} + +	/* Save AuxBoot* registers */ +	val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); +	__raw_writel(val, sar_base + OMAP5_AUXCOREBOOT0_OFFSET); +	val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); +	__raw_writel(val, sar_base + OMAP5_AUXCOREBOOT1_OFFSET); + +	/* Set the Backup Bit Mask status */ +	val = __raw_readl(sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET); +	val |= SAR_BACKUP_STATUS_WAKEUPGEN; +	__raw_writel(val, sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET); + +} + +/* + * Save WakeupGen interrupt context in SAR BANK3. Restore is done by + * ROM code. WakeupGen IP is integrated along with GIC to manage the + * interrupt wakeups from CPU low power states. It manages + * masking/unmasking of Shared peripheral interrupts(SPI). So the + * interrupt enable/disable control should be in sync and consistent + * at WakeupGen and GIC so that interrupts are not lost. + */ +static void irq_save_context(void) +{ +	if (!sar_base) +		sar_base = omap4_get_sar_ram_base(); + +	if (soc_is_omap54xx()) +		omap5_irq_save_context(); +	else +		omap4_irq_save_context();  }  /* @@ -262,9 +303,14 @@ static void irq_save_context(void)  static void irq_sar_clear(void)  {  	u32 val; -	val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET); +	u32 offset = SAR_BACKUP_STATUS_OFFSET; + +	if (soc_is_omap54xx()) +		offset = OMAP5_SAR_BACKUP_STATUS_OFFSET; + +	val = __raw_readl(sar_base + offset);  	val &= ~SAR_BACKUP_STATUS_WAKEUPGEN; -	__raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET); +	__raw_writel(val, sar_base + offset);  }  /* @@ -336,13 +382,25 @@ static struct notifier_block irq_notifier_block = {  static void __init irq_pm_init(void)  { -	cpu_pm_register_notifier(&irq_notifier_block); +	/* FIXME: Remove this when MPU OSWR support is added */ +	if (!soc_is_omap54xx()) +		cpu_pm_register_notifier(&irq_notifier_block);  }  #else  static void __init irq_pm_init(void)  {}  #endif +void __iomem *omap_get_wakeupgen_base(void) +{ +	return wakeupgen_base; +} + +int omap_secure_apis_support(void) +{ +	return omap_secure_apis; +} +  /*   * Initialise the wakeupgen module.   */ @@ -358,12 +416,18 @@ int __init omap_wakeupgen_init(void)  	}  	/* Static mapping, never released */ -	wakeupgen_base = ioremap(OMAP44XX_WKUPGEN_BASE, SZ_4K); +	wakeupgen_base = ioremap(OMAP_WKUPGEN_BASE, SZ_4K);  	if (WARN_ON(!wakeupgen_base))  		return -ENOMEM; +	if (cpu_is_omap44xx()) { +		irq_banks = OMAP4_NR_BANKS; +		max_irqs = OMAP4_NR_IRQS; +		omap_secure_apis = 1; +	} +  	/* Clear all IRQ bitmasks at wakeupGen level */ -	for (i = 0; i < NR_REG_BANKS; i++) { +	for (i = 0; i < irq_banks; i++) {  		wakeupgen_writel(0, i, CPU0_ID);  		wakeupgen_writel(0, i, CPU1_ID);  	} @@ -382,7 +446,7 @@ int __init omap_wakeupgen_init(void)  	 */  	/* Associate all the IRQs to boot CPU like GIC init does. */ -	for (i = 0; i < NR_IRQS; i++) +	for (i = 0; i < max_irqs; i++)  		irq_target_cpu[i] = boot_cpu;  	irq_hotplug_init(); diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h index fe5b545ad44..e170fe803b0 100644 --- a/arch/arm/mach-omap2/omap4-sar-layout.h +++ b/arch/arm/mach-omap2/omap4-sar-layout.h @@ -12,7 +12,7 @@  #define OMAP_ARCH_OMAP4_SAR_LAYOUT_H  /* - * SAR BANK offsets from base address OMAP44XX_SAR_RAM_BASE + * SAR BANK offsets from base address OMAP44XX/54XX_SAR_RAM_BASE   */  #define SAR_BANK1_OFFSET		0x0000  #define SAR_BANK2_OFFSET		0x1000 @@ -47,4 +47,14 @@  #define PTMSYNCREQ_EN_OFFSET			(SAR_BANK3_OFFSET + 0x6d0)  #define SAR_BACKUP_STATUS_WAKEUPGEN		0x10 +/* WakeUpGen save restore offset from OMAP54XX_SAR_RAM_BASE */ +#define OMAP5_WAKEUPGENENB_OFFSET_CPU0		(SAR_BANK3_OFFSET + 0x8d4) +#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU0	(SAR_BANK3_OFFSET + 0x8e8) +#define OMAP5_WAKEUPGENENB_OFFSET_CPU1		(SAR_BANK3_OFFSET + 0x8fc) +#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU1	(SAR_BANK3_OFFSET + 0x910) +#define OMAP5_AUXCOREBOOT0_OFFSET		(SAR_BANK3_OFFSET + 0x924) +#define OMAP5_AUXCOREBOOT1_OFFSET		(SAR_BANK3_OFFSET + 0x928) +#define OMAP5_AMBA_IF_MODE_OFFSET		(SAR_BANK3_OFFSET + 0x92c) +#define OMAP5_SAR_BACKUP_STATUS_OFFSET		(SAR_BANK3_OFFSET + 0x800) +  #endif |