at91-reset.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /*
  2. * Atmel AT91 SAM9 & SAMA5 SoCs reset code
  3. *
  4. * Copyright (C) 2007 Atmel Corporation.
  5. * Copyright (C) BitBox Ltd 2010
  6. * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcosoft.com>
  7. * Copyright (C) 2014 Free Electrons
  8. *
  9. * This file is licensed under the terms of the GNU General Public
  10. * License version 2. This program is licensed "as is" without any
  11. * warranty of any kind, whether express or implied.
  12. */
  13. #include <linux/clk.h>
  14. #include <linux/io.h>
  15. #include <linux/module.h>
  16. #include <linux/of_address.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/reboot.h>
  19. #include <soc/at91/at91sam9_ddrsdr.h>
  20. #include <soc/at91/at91sam9_sdramc.h>
  21. #define AT91_RSTC_CR 0x00 /* Reset Controller Control Register */
  22. #define AT91_RSTC_PROCRST BIT(0) /* Processor Reset */
  23. #define AT91_RSTC_PERRST BIT(2) /* Peripheral Reset */
  24. #define AT91_RSTC_EXTRST BIT(3) /* External Reset */
  25. #define AT91_RSTC_KEY (0xa5 << 24) /* KEY Password */
  26. #define AT91_RSTC_SR 0x04 /* Reset Controller Status Register */
  27. #define AT91_RSTC_URSTS BIT(0) /* User Reset Status */
  28. #define AT91_RSTC_RSTTYP GENMASK(10, 8) /* Reset Type */
  29. #define AT91_RSTC_NRSTL BIT(16) /* NRST Pin Level */
  30. #define AT91_RSTC_SRCMP BIT(17) /* Software Reset Command in Progress */
  31. #define AT91_RSTC_MR 0x08 /* Reset Controller Mode Register */
  32. #define AT91_RSTC_URSTEN BIT(0) /* User Reset Enable */
  33. #define AT91_RSTC_URSTASYNC BIT(2) /* User Reset Asynchronous Control */
  34. #define AT91_RSTC_URSTIEN BIT(4) /* User Reset Interrupt Enable */
  35. #define AT91_RSTC_ERSTL GENMASK(11, 8) /* External Reset Length */
  36. enum reset_type {
  37. RESET_TYPE_GENERAL = 0,
  38. RESET_TYPE_WAKEUP = 1,
  39. RESET_TYPE_WATCHDOG = 2,
  40. RESET_TYPE_SOFTWARE = 3,
  41. RESET_TYPE_USER = 4,
  42. RESET_TYPE_CPU_FAIL = 6,
  43. RESET_TYPE_XTAL_FAIL = 7,
  44. RESET_TYPE_ULP2 = 8,
  45. };
  46. struct at91_reset {
  47. void __iomem *rstc_base;
  48. void __iomem *ramc_base[2];
  49. struct clk *sclk;
  50. struct notifier_block nb;
  51. u32 args;
  52. u32 ramc_lpr;
  53. };
  54. /*
  55. * unless the SDRAM is cleanly shutdown before we hit the
  56. * reset register it can be left driving the data bus and
  57. * killing the chance of a subsequent boot from NAND
  58. */
  59. static int at91_reset(struct notifier_block *this, unsigned long mode,
  60. void *cmd)
  61. {
  62. struct at91_reset *reset = container_of(this, struct at91_reset, nb);
  63. asm volatile(
  64. /* Align to cache lines */
  65. ".balign 32\n\t"
  66. /* Disable SDRAM0 accesses */
  67. " tst %0, #0\n\t"
  68. " beq 1f\n\t"
  69. " str %3, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
  70. /* Power down SDRAM0 */
  71. " str %4, [%0, %6]\n\t"
  72. /* Disable SDRAM1 accesses */
  73. "1: tst %1, #0\n\t"
  74. " beq 2f\n\t"
  75. " strne %3, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
  76. /* Power down SDRAM1 */
  77. " strne %4, [%1, %6]\n\t"
  78. /* Reset CPU */
  79. "2: str %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t"
  80. " b .\n\t"
  81. :
  82. : "r" (reset->ramc_base[0]),
  83. "r" (reset->ramc_base[1]),
  84. "r" (reset->rstc_base),
  85. "r" (1),
  86. "r" cpu_to_le32(AT91_DDRSDRC_LPCB_POWER_DOWN),
  87. "r" (reset->args),
  88. "r" (reset->ramc_lpr)
  89. : "r4");
  90. return NOTIFY_DONE;
  91. }
  92. static void __init at91_reset_status(struct platform_device *pdev,
  93. void __iomem *base)
  94. {
  95. const char *reason;
  96. u32 reg = readl(base + AT91_RSTC_SR);
  97. switch ((reg & AT91_RSTC_RSTTYP) >> 8) {
  98. case RESET_TYPE_GENERAL:
  99. reason = "general reset";
  100. break;
  101. case RESET_TYPE_WAKEUP:
  102. reason = "wakeup";
  103. break;
  104. case RESET_TYPE_WATCHDOG:
  105. reason = "watchdog reset";
  106. break;
  107. case RESET_TYPE_SOFTWARE:
  108. reason = "software reset";
  109. break;
  110. case RESET_TYPE_USER:
  111. reason = "user reset";
  112. break;
  113. case RESET_TYPE_CPU_FAIL:
  114. reason = "CPU clock failure detection";
  115. break;
  116. case RESET_TYPE_XTAL_FAIL:
  117. reason = "32.768 kHz crystal failure detection";
  118. break;
  119. case RESET_TYPE_ULP2:
  120. reason = "ULP2 reset";
  121. break;
  122. default:
  123. reason = "unknown reset";
  124. break;
  125. }
  126. dev_info(&pdev->dev, "Starting after %s\n", reason);
  127. }
  128. static const struct of_device_id at91_ramc_of_match[] = {
  129. {
  130. .compatible = "atmel,at91sam9260-sdramc",
  131. .data = (void *)AT91_SDRAMC_LPR,
  132. },
  133. {
  134. .compatible = "atmel,at91sam9g45-ddramc",
  135. .data = (void *)AT91_DDRSDRC_LPR,
  136. },
  137. { /* sentinel */ }
  138. };
  139. static const struct of_device_id at91_reset_of_match[] = {
  140. {
  141. .compatible = "atmel,at91sam9260-rstc",
  142. .data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PERRST |
  143. AT91_RSTC_PROCRST),
  144. },
  145. {
  146. .compatible = "atmel,at91sam9g45-rstc",
  147. .data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PERRST |
  148. AT91_RSTC_PROCRST)
  149. },
  150. {
  151. .compatible = "atmel,sama5d3-rstc",
  152. .data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PERRST |
  153. AT91_RSTC_PROCRST)
  154. },
  155. {
  156. .compatible = "atmel,samx7-rstc",
  157. .data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PROCRST)
  158. },
  159. {
  160. .compatible = "microchip,sam9x60-rstc",
  161. .data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PROCRST)
  162. },
  163. { /* sentinel */ }
  164. };
  165. MODULE_DEVICE_TABLE(of, at91_reset_of_match);
  166. static int __init at91_reset_probe(struct platform_device *pdev)
  167. {
  168. const struct of_device_id *match;
  169. struct at91_reset *reset;
  170. struct device_node *np;
  171. int ret, idx = 0;
  172. reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
  173. if (!reset)
  174. return -ENOMEM;
  175. reset->rstc_base = of_iomap(pdev->dev.of_node, 0);
  176. if (!reset->rstc_base) {
  177. dev_err(&pdev->dev, "Could not map reset controller address\n");
  178. return -ENODEV;
  179. }
  180. if (!of_device_is_compatible(pdev->dev.of_node, "atmel,sama5d3-rstc")) {
  181. /* we need to shutdown the ddr controller, so get ramc base */
  182. for_each_matching_node_and_match(np, at91_ramc_of_match, &match) {
  183. reset->ramc_lpr = (u32)match->data;
  184. reset->ramc_base[idx] = of_iomap(np, 0);
  185. if (!reset->ramc_base[idx]) {
  186. dev_err(&pdev->dev, "Could not map ram controller address\n");
  187. of_node_put(np);
  188. return -ENODEV;
  189. }
  190. idx++;
  191. }
  192. }
  193. match = of_match_node(at91_reset_of_match, pdev->dev.of_node);
  194. reset->nb.notifier_call = at91_reset;
  195. reset->nb.priority = 192;
  196. reset->args = (u32)match->data;
  197. reset->sclk = devm_clk_get(&pdev->dev, NULL);
  198. if (IS_ERR(reset->sclk))
  199. return PTR_ERR(reset->sclk);
  200. ret = clk_prepare_enable(reset->sclk);
  201. if (ret) {
  202. dev_err(&pdev->dev, "Could not enable slow clock\n");
  203. return ret;
  204. }
  205. platform_set_drvdata(pdev, reset);
  206. if (of_device_is_compatible(pdev->dev.of_node, "microchip,sam9x60-rstc")) {
  207. u32 val = readl(reset->rstc_base + AT91_RSTC_MR);
  208. writel(AT91_RSTC_KEY | AT91_RSTC_URSTASYNC | val,
  209. reset->rstc_base + AT91_RSTC_MR);
  210. }
  211. ret = register_restart_handler(&reset->nb);
  212. if (ret) {
  213. clk_disable_unprepare(reset->sclk);
  214. return ret;
  215. }
  216. at91_reset_status(pdev, reset->rstc_base);
  217. return 0;
  218. }
  219. static int __exit at91_reset_remove(struct platform_device *pdev)
  220. {
  221. struct at91_reset *reset = platform_get_drvdata(pdev);
  222. unregister_restart_handler(&reset->nb);
  223. clk_disable_unprepare(reset->sclk);
  224. return 0;
  225. }
  226. static struct platform_driver at91_reset_driver = {
  227. .remove = __exit_p(at91_reset_remove),
  228. .driver = {
  229. .name = "at91-reset",
  230. .of_match_table = at91_reset_of_match,
  231. },
  232. };
  233. module_platform_driver_probe(at91_reset_driver, at91_reset_probe);
  234. MODULE_AUTHOR("Atmel Corporation");
  235. MODULE_DESCRIPTION("Reset driver for Atmel SoCs");
  236. MODULE_LICENSE("GPL v2");