root/arch/arm/mach-tegra/reset.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tegra_cpu_reset_handler_set
  2. tegra_cpu_reset_handler_enable
  3. tegra_cpu_reset_handler_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * arch/arm/mach-tegra/reset.c
   4  *
   5  * Copyright (C) 2011,2012 NVIDIA Corporation.
   6  */
   7 
   8 #include <linux/bitops.h>
   9 #include <linux/cpumask.h>
  10 #include <linux/init.h>
  11 #include <linux/io.h>
  12 
  13 #include <linux/firmware/trusted_foundations.h>
  14 
  15 #include <soc/tegra/fuse.h>
  16 
  17 #include <asm/cacheflush.h>
  18 #include <asm/firmware.h>
  19 #include <asm/hardware/cache-l2x0.h>
  20 
  21 #include "iomap.h"
  22 #include "irammap.h"
  23 #include "reset.h"
  24 #include "sleep.h"
  25 
  26 #define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \
  27                                 TEGRA_IRAM_RESET_HANDLER_OFFSET)
  28 
  29 static bool is_enabled;
  30 
  31 static void __init tegra_cpu_reset_handler_set(const u32 reset_address)
  32 {
  33         void __iomem *evp_cpu_reset =
  34                 IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE + 0x100);
  35         void __iomem *sb_ctrl = IO_ADDRESS(TEGRA_SB_BASE);
  36         u32 reg;
  37 
  38         /*
  39          * NOTE: This must be the one and only write to the EVP CPU reset
  40          *       vector in the entire system.
  41          */
  42         writel(reset_address, evp_cpu_reset);
  43         wmb();
  44         reg = readl(evp_cpu_reset);
  45 
  46         /*
  47          * Prevent further modifications to the physical reset vector.
  48          *  NOTE: Has no effect on chips prior to Tegra30.
  49          */
  50         reg = readl(sb_ctrl);
  51         reg |= 2;
  52         writel(reg, sb_ctrl);
  53         wmb();
  54 }
  55 
  56 static void __init tegra_cpu_reset_handler_enable(void)
  57 {
  58         void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE);
  59         const u32 reset_address = TEGRA_IRAM_RESET_BASE +
  60                                                 tegra_cpu_reset_handler_offset;
  61         int err;
  62 
  63         BUG_ON(is_enabled);
  64         BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);
  65 
  66         memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
  67                         tegra_cpu_reset_handler_size);
  68 
  69         err = call_firmware_op(set_cpu_boot_addr, 0, reset_address);
  70         switch (err) {
  71         case -ENOSYS:
  72                 tegra_cpu_reset_handler_set(reset_address);
  73                 /* fall through */
  74         case 0:
  75                 is_enabled = true;
  76                 break;
  77         default:
  78                 pr_crit("Cannot set CPU reset handler: %d\n", err);
  79                 BUG();
  80         }
  81 }
  82 
  83 void __init tegra_cpu_reset_handler_init(void)
  84 {
  85         __tegra_cpu_reset_handler_data[TEGRA_RESET_TF_PRESENT] =
  86                 trusted_foundations_registered();
  87 
  88 #ifdef CONFIG_SMP
  89         __tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] =
  90                 *((u32 *)cpu_possible_mask);
  91         __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_SECONDARY] =
  92                 __pa_symbol((void *)secondary_startup);
  93 #endif
  94 
  95 #ifdef CONFIG_PM_SLEEP
  96         __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP1] =
  97                 TEGRA_IRAM_LPx_RESUME_AREA;
  98         __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP2] =
  99                 __pa_symbol((void *)tegra_resume);
 100 #endif
 101 
 102         tegra_cpu_reset_handler_enable();
 103 }

/* [<][>][^][v][top][bottom][index][help] */