stm32mp1_reset.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /*
  2. * Copyright (c) 2018-2024, STMicroelectronics - All Rights Reserved
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <errno.h>
  7. #include <limits.h>
  8. #include <common/bl_common.h>
  9. #include <common/debug.h>
  10. #include <drivers/delay_timer.h>
  11. #include <drivers/st/stm32mp_reset.h>
  12. #include <lib/mmio.h>
  13. #include <lib/utils_def.h>
  14. #include <platform_def.h>
  15. static uint32_t id2reg_offset(unsigned int reset_id)
  16. {
  17. return ((reset_id & GENMASK(31, 5)) >> 5) * sizeof(uint32_t);
  18. }
  19. static uint8_t id2reg_bit_pos(unsigned int reset_id)
  20. {
  21. return (uint8_t)(reset_id & GENMASK(4, 0));
  22. }
  23. int stm32mp_reset_assert(uint32_t id, unsigned int to_us)
  24. {
  25. uint32_t offset = id2reg_offset(id);
  26. uint32_t bitmsk = BIT(id2reg_bit_pos(id));
  27. uintptr_t rcc_base = stm32mp_rcc_base();
  28. mmio_write_32(rcc_base + offset, bitmsk);
  29. if (to_us != 0U) {
  30. uint64_t timeout_ref = timeout_init_us(to_us);
  31. while ((mmio_read_32(rcc_base + offset) & bitmsk) == 0U) {
  32. if (timeout_elapsed(timeout_ref)) {
  33. return -ETIMEDOUT;
  34. }
  35. }
  36. }
  37. return 0;
  38. }
  39. int stm32mp_reset_deassert(uint32_t id, unsigned int to_us)
  40. {
  41. uint32_t offset = id2reg_offset(id) + RCC_RSTCLRR_OFFSET;
  42. uint32_t bitmsk = BIT(id2reg_bit_pos(id));
  43. uintptr_t rcc_base = stm32mp_rcc_base();
  44. mmio_write_32(rcc_base + offset, bitmsk);
  45. if (to_us != 0U) {
  46. uint64_t timeout_ref = timeout_init_us(to_us);
  47. while ((mmio_read_32(rcc_base + offset) & bitmsk) != 0U) {
  48. if (timeout_elapsed(timeout_ref)) {
  49. return -ETIMEDOUT;
  50. }
  51. }
  52. }
  53. return 0;
  54. }
  55. void __dead2 stm32mp_system_reset(void)
  56. {
  57. uintptr_t rcc_base = stm32mp_rcc_base();
  58. mmio_setbits_32(rcc_base + RCC_MP_GRSTCSETR,
  59. RCC_MP_GRSTCSETR_MPSYSRST);
  60. /* Loop in case system reset is not immediately caught */
  61. while (true) {
  62. wfi();
  63. }
  64. }