softrst.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * Copyright (c) 2006-2024 RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-11-26 GuEe-GUI first version
  9. */
  10. struct rockchip_softrst
  11. {
  12. void *regs;
  13. int num_per_reg;
  14. rt_uint8_t flags;
  15. struct rt_spinlock lock;
  16. };
  17. static rt_err_t rockchip_softrst_assert(struct rt_reset_control *rstc)
  18. {
  19. int bank, offset;
  20. struct rockchip_softrst *softrst = rstc->rstcer->priv;
  21. bank = rstc->id / softrst->num_per_reg;
  22. offset = rstc->id % softrst->num_per_reg;
  23. if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK)
  24. {
  25. HWREG32(softrst->regs + (bank * 4)) = RT_BIT(offset) | (RT_BIT(offset) << 16);
  26. }
  27. else
  28. {
  29. rt_uint32_t reg;
  30. rt_ubase_t level;
  31. level = rt_spin_lock_irqsave(&softrst->lock);
  32. reg = HWREG32(softrst->regs + (bank * 4));
  33. HWREG32(softrst->regs + (bank * 4)) = reg | RT_BIT(offset);
  34. rt_spin_unlock_irqrestore(&softrst->lock, level);
  35. }
  36. return RT_EOK;
  37. }
  38. static rt_err_t rockchip_softrst_deassert(struct rt_reset_control *rstc)
  39. {
  40. int bank, offset;
  41. struct rockchip_softrst *softrst = rstc->rstcer->priv;
  42. bank = rstc->id / softrst->num_per_reg;
  43. offset = rstc->id % softrst->num_per_reg;
  44. if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK)
  45. {
  46. HWREG32(softrst->regs + (bank * 4)) = (RT_BIT(offset) << 16);
  47. }
  48. else
  49. {
  50. rt_uint32_t reg;
  51. rt_ubase_t level;
  52. level = rt_spin_lock_irqsave(&softrst->lock);
  53. reg = HWREG32(softrst->regs + (bank * 4));
  54. HWREG32(softrst->regs + (bank * 4)) = reg & ~RT_BIT(offset);
  55. rt_spin_unlock_irqrestore(&softrst->lock, level);
  56. }
  57. return RT_EOK;
  58. }
  59. static const struct rt_reset_control_ops rockchip_softrst_ops =
  60. {
  61. .assert = rockchip_softrst_assert,
  62. .deassert = rockchip_softrst_deassert,
  63. };
  64. static rt_err_t rk_register_softrst(struct rt_reset_controller *rstcer,
  65. struct rt_ofw_node *np, void *regs, rt_uint8_t flags)
  66. {
  67. rt_err_t err;
  68. struct rockchip_softrst *softrst = rt_calloc(1, sizeof(*softrst));
  69. if (!softrst)
  70. {
  71. return -RT_ENOMEM;
  72. }
  73. rstcer->priv = softrst;
  74. rt_spin_lock_init(&softrst->lock);
  75. softrst->regs = regs;
  76. softrst->flags = flags;
  77. softrst->num_per_reg = (flags & ROCKCHIP_SOFTRST_HIWORD_MASK) ? 16 : 32;
  78. rstcer->ofw_node = np;
  79. rstcer->ops = &rockchip_softrst_ops;
  80. if ((err = rt_reset_controller_register(rstcer)))
  81. {
  82. rt_free(softrst);
  83. }
  84. return err;
  85. }