reset.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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/init.h>
  17. #include <linux/io.h>
  18. #include <linux/cpumask.h>
  19. #include <linux/bitops.h>
  20. #include <asm/cacheflush.h>
  21. #include <asm/hardware/cache-l2x0.h>
  22. #include <mach/iomap.h>
  23. #include <mach/irammap.h>
  24. #include "reset.h"
  25. #include "fuse.h"
  26. #define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \
  27. TEGRA_IRAM_RESET_HANDLER_OFFSET)
  28. static bool is_enabled;
  29. static void tegra_cpu_reset_handler_enable(void)
  30. {
  31. void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE);
  32. void __iomem *evp_cpu_reset =
  33. IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE + 0x100);
  34. void __iomem *sb_ctrl = IO_ADDRESS(TEGRA_SB_BASE);
  35. u32 reg;
  36. BUG_ON(is_enabled);
  37. BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);
  38. memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
  39. tegra_cpu_reset_handler_size);
  40. /*
  41. * NOTE: This must be the one and only write to the EVP CPU reset
  42. * vector in the entire system.
  43. */
  44. writel(TEGRA_IRAM_RESET_BASE + tegra_cpu_reset_handler_offset,
  45. evp_cpu_reset);
  46. wmb();
  47. reg = readl(evp_cpu_reset);
  48. /*
  49. * Prevent further modifications to the physical reset vector.
  50. * NOTE: Has no effect on chips prior to Tegra30.
  51. */
  52. if (tegra_chip_id != TEGRA20) {
  53. reg = readl(sb_ctrl);
  54. reg |= 2;
  55. writel(reg, sb_ctrl);
  56. wmb();
  57. }
  58. is_enabled = true;
  59. }
  60. void __init tegra_cpu_reset_handler_init(void)
  61. {
  62. #ifdef CONFIG_SMP
  63. __tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] =
  64. *((u32 *)cpu_present_mask);
  65. __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_SECONDARY] =
  66. virt_to_phys((void *)tegra_secondary_startup);
  67. #endif
  68. tegra_cpu_reset_handler_enable();
  69. }