src.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. * Copyright 2011 Freescale Semiconductor, Inc.
  3. * Copyright 2011 Linaro Ltd.
  4. *
  5. * The code contained herein is licensed under the GNU General Public
  6. * License. You may obtain a copy of the GNU General Public License
  7. * Version 2 or later at the following locations:
  8. *
  9. * http://www.opensource.org/licenses/gpl-license.html
  10. * http://www.gnu.org/copyleft/gpl.html
  11. */
  12. #include <linux/init.h>
  13. #include <linux/io.h>
  14. #include <linux/of.h>
  15. #include <linux/of_address.h>
  16. #include <linux/reset-controller.h>
  17. #include <linux/smp.h>
  18. #include <asm/smp_plat.h>
  19. #include "common.h"
  20. #define SRC_SCR 0x000
  21. #define SRC_GPR1 0x020
  22. #define BP_SRC_SCR_WARM_RESET_ENABLE 0
  23. #define BP_SRC_SCR_SW_GPU_RST 1
  24. #define BP_SRC_SCR_SW_VPU_RST 2
  25. #define BP_SRC_SCR_SW_IPU1_RST 3
  26. #define BP_SRC_SCR_SW_OPEN_VG_RST 4
  27. #define BP_SRC_SCR_SW_IPU2_RST 12
  28. #define BP_SRC_SCR_CORE1_RST 14
  29. #define BP_SRC_SCR_CORE1_ENABLE 22
  30. static void __iomem *src_base;
  31. static DEFINE_SPINLOCK(scr_lock);
  32. static const int sw_reset_bits[5] = {
  33. BP_SRC_SCR_SW_GPU_RST,
  34. BP_SRC_SCR_SW_VPU_RST,
  35. BP_SRC_SCR_SW_IPU1_RST,
  36. BP_SRC_SCR_SW_OPEN_VG_RST,
  37. BP_SRC_SCR_SW_IPU2_RST
  38. };
  39. static int imx_src_reset_module(struct reset_controller_dev *rcdev,
  40. unsigned long sw_reset_idx)
  41. {
  42. unsigned long timeout;
  43. unsigned long flags;
  44. int bit;
  45. u32 val;
  46. if (!src_base)
  47. return -ENODEV;
  48. if (sw_reset_idx >= ARRAY_SIZE(sw_reset_bits))
  49. return -EINVAL;
  50. bit = 1 << sw_reset_bits[sw_reset_idx];
  51. spin_lock_irqsave(&scr_lock, flags);
  52. val = readl_relaxed(src_base + SRC_SCR);
  53. val |= bit;
  54. writel_relaxed(val, src_base + SRC_SCR);
  55. spin_unlock_irqrestore(&scr_lock, flags);
  56. timeout = jiffies + msecs_to_jiffies(1000);
  57. while (readl(src_base + SRC_SCR) & bit) {
  58. if (time_after(jiffies, timeout))
  59. return -ETIME;
  60. cpu_relax();
  61. }
  62. return 0;
  63. }
  64. static const struct reset_control_ops imx_src_ops = {
  65. .reset = imx_src_reset_module,
  66. };
  67. static struct reset_controller_dev imx_reset_controller = {
  68. .ops = &imx_src_ops,
  69. .nr_resets = ARRAY_SIZE(sw_reset_bits),
  70. };
  71. void imx_enable_cpu(int cpu, bool enable)
  72. {
  73. u32 mask, val;
  74. cpu = cpu_logical_map(cpu);
  75. mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
  76. spin_lock(&scr_lock);
  77. val = readl_relaxed(src_base + SRC_SCR);
  78. val = enable ? val | mask : val & ~mask;
  79. val |= 1 << (BP_SRC_SCR_CORE1_RST + cpu - 1);
  80. writel_relaxed(val, src_base + SRC_SCR);
  81. spin_unlock(&scr_lock);
  82. }
  83. void imx_set_cpu_jump(int cpu, void *jump_addr)
  84. {
  85. cpu = cpu_logical_map(cpu);
  86. writel_relaxed(virt_to_phys(jump_addr),
  87. src_base + SRC_GPR1 + cpu * 8);
  88. }
  89. u32 imx_get_cpu_arg(int cpu)
  90. {
  91. cpu = cpu_logical_map(cpu);
  92. return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4);
  93. }
  94. void imx_set_cpu_arg(int cpu, u32 arg)
  95. {
  96. cpu = cpu_logical_map(cpu);
  97. writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4);
  98. }
  99. void __init imx_src_init(void)
  100. {
  101. struct device_node *np;
  102. u32 val;
  103. np = of_find_compatible_node(NULL, NULL, "fsl,imx51-src");
  104. if (!np)
  105. return;
  106. src_base = of_iomap(np, 0);
  107. WARN_ON(!src_base);
  108. imx_reset_controller.of_node = np;
  109. if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
  110. reset_controller_register(&imx_reset_controller);
  111. /*
  112. * force warm reset sources to generate cold reset
  113. * for a more reliable restart
  114. */
  115. spin_lock(&scr_lock);
  116. val = readl_relaxed(src_base + SRC_SCR);
  117. val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE);
  118. writel_relaxed(val, src_base + SRC_SCR);
  119. spin_unlock(&scr_lock);
  120. }