| /* |
| * linux/arch/arm/mach-mmp/reset.c |
| * |
| * Author: Neil Zhang <zhangwm@marvell.com> |
| * Copyright: (C) 2012 Marvell International Ltd. |
| * |
| * 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. |
| */ |
| |
| #include <linux/kernel.h> |
| #include <linux/smp.h> |
| #include <linux/cputype.h> |
| |
| #include <asm/io.h> |
| #include <asm/cacheflush.h> |
| #include <asm/mach/map.h> |
| #include <asm/mcpm.h> |
| |
| #include <soc/asr/addr-map.h> |
| |
| #include "reset.h" |
| |
| #define PMU_CC2_AP APMU_REG(0x0100) |
| #define CIU_WARM_RESET_VECTOR CIU_REG(0x00d8) |
| #define SW_SCRATCH CIU_REG(0x24) |
| |
| #define ASR1901_APMU_CORE_WAKEUP APMU_REG(0x012C) |
| |
| /* |
| * This function is called from boot_secondary to bootup the secondary cpu. |
| */ |
| #ifndef CONFIG_OPTEE |
| void mmp_cpu_power_up(unsigned int cpu, unsigned int cluster) |
| { |
| u32 tmp; |
| |
| BUG_ON(cpu == 0); |
| |
| tmp = readl(PMU_CC2_AP); |
| if (cpu_is_asr1901() || cpu_is_asr1906()) { |
| tmp = readl(ASR1901_APMU_CORE_WAKEUP); |
| if (!(tmp & ASR1901_CPU_CORE_WAKEUP(cpu))) { |
| /* Release secondary core from reset */ |
| tmp |= ASR1901_CPU_CORE_WAKEUP(cpu); |
| writel(tmp, ASR1901_APMU_CORE_WAKEUP); |
| } |
| } else if (cpu_is_pxa1088() || cpu_is_pxa1L88() || cpu_is_pxa1U88()) { |
| if (tmp & PXA1088_CPU_CORE_RST(cpu)) { |
| /* Release secondary core from reset */ |
| tmp &= ~(PXA1088_CPU_POR_RST(cpu) |
| | PXA1088_CPU_CORE_RST(cpu) | PXA1088_CPU_DBG_RST(cpu)); |
| writel(tmp, PMU_CC2_AP); |
| } |
| } else { |
| if (tmp & CPU_CORE_RST(cpu)) { |
| /* Release secondary core from reset */ |
| tmp &= ~(CPU_CORE_RST(cpu) |
| | CPU_DBG_RST(cpu) | CPU_WDOG_RST(cpu)); |
| writel(tmp, PMU_CC2_AP); |
| } |
| } |
| } |
| #endif |
| |
| int __init mmp_entry_vector_init(void) |
| { |
| |
| #if defined(CONFIG_CPU_PXA988) || defined(CONFIG_CPU_ASR1901) |
| |
| #ifndef CONFIG_OPTEE |
| writel(__pa(mcpm_entry_point), CIU_WARM_RESET_VECTOR); |
| #endif |
| |
| #endif |
| |
| #ifdef CONFIG_CPU_ASR18XX |
| writel(__pa(cpu_resume), CIU_WARM_RESET_VECTOR); |
| #endif |
| |
| return 0; |
| } |
| late_initcall(mmp_entry_vector_init); |