Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * arch/arm/mach-tegra/reset.c
0004  *
0005  * Copyright (C) 2011,2012 NVIDIA Corporation.
0006  */
0007 
0008 #include <linux/bitops.h>
0009 #include <linux/cpumask.h>
0010 #include <linux/init.h>
0011 #include <linux/io.h>
0012 
0013 #include <linux/firmware/trusted_foundations.h>
0014 
0015 #include <soc/tegra/fuse.h>
0016 
0017 #include <asm/cacheflush.h>
0018 #include <asm/firmware.h>
0019 #include <asm/hardware/cache-l2x0.h>
0020 
0021 #include "iomap.h"
0022 #include "irammap.h"
0023 #include "reset.h"
0024 #include "sleep.h"
0025 
0026 #define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \
0027                 TEGRA_IRAM_RESET_HANDLER_OFFSET)
0028 
0029 static bool is_enabled;
0030 
0031 static void __init tegra_cpu_reset_handler_set(const u32 reset_address)
0032 {
0033     void __iomem *evp_cpu_reset =
0034         IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE + 0x100);
0035     void __iomem *sb_ctrl = IO_ADDRESS(TEGRA_SB_BASE);
0036     u32 reg;
0037 
0038     /*
0039      * NOTE: This must be the one and only write to the EVP CPU reset
0040      *       vector in the entire system.
0041      */
0042     writel(reset_address, evp_cpu_reset);
0043     wmb();
0044     reg = readl(evp_cpu_reset);
0045 
0046     /*
0047      * Prevent further modifications to the physical reset vector.
0048      *  NOTE: Has no effect on chips prior to Tegra30.
0049      */
0050     reg = readl(sb_ctrl);
0051     reg |= 2;
0052     writel(reg, sb_ctrl);
0053     wmb();
0054 }
0055 
0056 static void __init tegra_cpu_reset_handler_enable(void)
0057 {
0058     void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE);
0059     const u32 reset_address = TEGRA_IRAM_RESET_BASE +
0060                         tegra_cpu_reset_handler_offset;
0061     int err;
0062 
0063     BUG_ON(is_enabled);
0064     BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);
0065 
0066     memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
0067             tegra_cpu_reset_handler_size);
0068 
0069     err = call_firmware_op(set_cpu_boot_addr, 0, reset_address);
0070     switch (err) {
0071     case -ENOSYS:
0072         tegra_cpu_reset_handler_set(reset_address);
0073         fallthrough;
0074     case 0:
0075         is_enabled = true;
0076         break;
0077     default:
0078         pr_crit("Cannot set CPU reset handler: %d\n", err);
0079         BUG();
0080     }
0081 }
0082 
0083 void __init tegra_cpu_reset_handler_init(void)
0084 {
0085     __tegra_cpu_reset_handler_data[TEGRA_RESET_TF_PRESENT] =
0086         trusted_foundations_registered();
0087 
0088 #ifdef CONFIG_SMP
0089     __tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] =
0090         *((u32 *)cpu_possible_mask);
0091     __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_SECONDARY] =
0092         __pa_symbol((void *)secondary_startup);
0093 #endif
0094 
0095 #ifdef CONFIG_PM_SLEEP
0096     __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP1] =
0097         TEGRA_IRAM_LPx_RESUME_AREA;
0098     __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP2] =
0099         __pa_symbol((void *)tegra_resume);
0100 #endif
0101 
0102     tegra_cpu_reset_handler_enable();
0103 }