reset.c 2.4 KB

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