reset.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. * arch/arm/mach-tegra/reset.c
  3. *
  4. * Copyright (C) 2011,2012 NVIDIA Corporation.
  5. *
  6. * This software is licensed under the terms of the GNU General Public
  7. * License version 2, as published by the Free Software Foundation, and
  8. * may be copied, distributed, and modified under those terms.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. */
  16. #include <linux/bitops.h>
  17. #include <linux/cpumask.h>
  18. #include <linux/init.h>
  19. #include <linux/io.h>
  20. #include <soc/tegra/fuse.h>
  21. #include <asm/cacheflush.h>
  22. #include <asm/firmware.h>
  23. #include <asm/hardware/cache-l2x0.h>
  24. #include "iomap.h"
  25. #include "irammap.h"
  26. #include "reset.h"
  27. #include "sleep.h"
  28. #define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \
  29. TEGRA_IRAM_RESET_HANDLER_OFFSET)
  30. static bool is_enabled;
  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. * NOTE: This must be the one and only write to the EVP CPU reset
  39. * vector in the entire system.
  40. */
  41. writel(reset_address, evp_cpu_reset);
  42. wmb();
  43. reg = readl(evp_cpu_reset);
  44. /*
  45. * Prevent further modifications to the physical reset vector.
  46. * NOTE: Has no effect on chips prior to Tegra30.
  47. */
  48. reg = readl(sb_ctrl);
  49. reg |= 2;
  50. writel(reg, sb_ctrl);
  51. wmb();
  52. }
  53. static void __init tegra_cpu_reset_handler_enable(void)
  54. {
  55. void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE);
  56. const u32 reset_address = TEGRA_IRAM_RESET_BASE +
  57. tegra_cpu_reset_handler_offset;
  58. int err;
  59. BUG_ON(is_enabled);
  60. BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);
  61. memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
  62. tegra_cpu_reset_handler_size);
  63. err = call_firmware_op(set_cpu_boot_addr, 0, reset_address);
  64. switch (err) {
  65. case -ENOSYS:
  66. tegra_cpu_reset_handler_set(reset_address);
  67. /* pass-through */
  68. case 0:
  69. is_enabled = true;
  70. break;
  71. default:
  72. pr_crit("Cannot set CPU reset handler: %d\n", err);
  73. BUG();
  74. }
  75. }
  76. void __init tegra_cpu_reset_handler_init(void)
  77. {
  78. #ifdef CONFIG_SMP
  79. __tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] =
  80. *((u32 *)cpu_possible_mask);
  81. __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_SECONDARY] =
  82. virt_to_phys((void *)secondary_startup);
  83. #endif
  84. #ifdef CONFIG_PM_SLEEP
  85. __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP1] =
  86. TEGRA_IRAM_LPx_RESUME_AREA;
  87. __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP2] =
  88. virt_to_phys((void *)tegra_resume);
  89. #endif
  90. tegra_cpu_reset_handler_enable();
  91. }