reset.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /*
  2. * (C) Copyright 2013 ASTRI
  3. *
  4. * See file CREDITS for list of people who contributed to this
  5. * project.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * version 2 as published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. */
  16. #include <common.h>
  17. #include <asm/io.h>
  18. /* WDT */
  19. #define WDT_CR 0x00
  20. #define WDT_PSR 0x04
  21. #define WDT_LDR 0x08
  22. #define WDT_VLR 0x0C
  23. #define WDT_ISR 0x10
  24. #define WDT_RCR 0x14
  25. #define WDT_TMR 0x18
  26. #define WDT_TCR 0x1C
  27. #define rSYS_SOFT_RSTNA 0x74
  28. #define rSYS_SOFT_RSTNB 0x78
  29. extern unsigned long ark_get_apb_clock(void);
  30. #define div_round_up(x, div) (((x) + (div) - 1) / (div))
  31. static void ark_wdt_reset(u32 timeout_ms)
  32. {
  33. u32 regbase = CONFIG_WATCHDOG_BASEADDR;
  34. u32 freq = ark_get_apb_clock();
  35. u32 count, divisor = 1;
  36. freq = div_round_up(freq, 128);
  37. count = timeout_ms * (u64)freq / 1000;
  38. if (count > 0xffff) {
  39. divisor = div_round_up(count, 0xffff);
  40. if (divisor > 0xffff) {
  41. printf("timeout %d too big\n", divisor);
  42. return;
  43. }
  44. }
  45. count = div_round_up(count, divisor);
  46. writel(0, regbase + WDT_CR);
  47. writel(divisor, regbase + WDT_PSR);
  48. writel(count, regbase + WDT_LDR);
  49. writel((0x3 << 4) | 3, regbase + WDT_CR);
  50. }
  51. static void ark1668e_softreset(void)
  52. {
  53. u32 sysregbase = 0xe4900000;
  54. writel(0, sysregbase + rSYS_SOFT_RSTNA);
  55. writel(0, sysregbase + rSYS_SOFT_RSTNB);
  56. }
  57. void reset_cpu(ulong addr)
  58. {
  59. /* TODO: Program the system controller to reset */
  60. #ifdef CONFIG_ARK1668EFAMILY
  61. ark_wdt_reset(2000);
  62. ark1668e_softreset();
  63. #else
  64. ark_wdt_reset(100);
  65. #endif
  66. /* loop for waiting reset */
  67. while(1);
  68. }