reset-sunxi.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  2. /*
  3. * Copyright (C) 2018 Amarula Solutions.
  4. * Author: Jagan Teki <jagan@amarulasolutions.com>
  5. */
  6. #include <common.h>
  7. #include <dm.h>
  8. #include <errno.h>
  9. #include <log.h>
  10. #include <malloc.h>
  11. #include <reset-uclass.h>
  12. #include <asm/io.h>
  13. #include <clk/sunxi.h>
  14. #include <linux/bitops.h>
  15. #include <linux/log2.h>
  16. static const struct ccu_reset *plat_to_reset(struct ccu_plat *plat,
  17. unsigned long id)
  18. {
  19. return &plat->desc->resets[id];
  20. }
  21. static int sunxi_reset_request(struct reset_ctl *reset_ctl)
  22. {
  23. struct ccu_plat *plat = dev_get_plat(reset_ctl->dev);
  24. debug("%s: (RST#%ld)\n", __func__, reset_ctl->id);
  25. if (reset_ctl->id >= plat->desc->num_resets)
  26. return -EINVAL;
  27. return 0;
  28. }
  29. static int sunxi_set_reset(struct reset_ctl *reset_ctl, bool on)
  30. {
  31. struct ccu_plat *plat = dev_get_plat(reset_ctl->dev);
  32. const struct ccu_reset *reset = plat_to_reset(plat, reset_ctl->id);
  33. u32 reg;
  34. if (!(reset->flags & CCU_RST_F_IS_VALID)) {
  35. printf("%s: (RST#%ld) unhandled\n", __func__, reset_ctl->id);
  36. return 0;
  37. }
  38. debug("%s: (RST#%ld) off#0x%x, BIT(%d)\n", __func__,
  39. reset_ctl->id, reset->off, ilog2(reset->bit));
  40. reg = readl(plat->base + reset->off);
  41. if (on)
  42. reg |= reset->bit;
  43. else
  44. reg &= ~reset->bit;
  45. writel(reg, plat->base + reset->off);
  46. return 0;
  47. }
  48. static int sunxi_reset_assert(struct reset_ctl *reset_ctl)
  49. {
  50. return sunxi_set_reset(reset_ctl, false);
  51. }
  52. static int sunxi_reset_deassert(struct reset_ctl *reset_ctl)
  53. {
  54. return sunxi_set_reset(reset_ctl, true);
  55. }
  56. struct reset_ops sunxi_reset_ops = {
  57. .request = sunxi_reset_request,
  58. .rst_assert = sunxi_reset_assert,
  59. .rst_deassert = sunxi_reset_deassert,
  60. };
  61. U_BOOT_DRIVER(sunxi_reset) = {
  62. .name = "sunxi_reset",
  63. .id = UCLASS_RESET,
  64. .ops = &sunxi_reset_ops,
  65. };