Linux Audio

Check our new training course

Loading...
v6.13.7
  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
 29static bool is_enabled;
 30
 31static 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
 56static 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		fallthrough;
 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
 83void __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}
v6.8
  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
 29static bool is_enabled;
 30
 31static 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
 56static 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		fallthrough;
 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
 83void __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}