reset-hsdk.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * HSDK SoC Reset Controller driver
  4. *
  5. * Copyright (C) 2019 Synopsys, Inc. All rights reserved.
  6. * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
  7. */
  8. #include <log.h>
  9. #include <asm/io.h>
  10. #include <common.h>
  11. #include <dm.h>
  12. #include <linux/bitops.h>
  13. #include <linux/iopoll.h>
  14. #include <reset-uclass.h>
  15. struct hsdk_rst {
  16. void __iomem *regs_ctl;
  17. void __iomem *regs_rst;
  18. };
  19. static const u32 rst_map[] = {
  20. BIT(16), /* APB_RST */
  21. BIT(17), /* AXI_RST */
  22. BIT(18), /* ETH_RST */
  23. BIT(19), /* USB_RST */
  24. BIT(20), /* SDIO_RST */
  25. BIT(21), /* HDMI_RST */
  26. BIT(22), /* GFX_RST */
  27. BIT(25), /* DMAC_RST */
  28. BIT(31), /* EBI_RST */
  29. };
  30. #define HSDK_MAX_RESETS ARRAY_SIZE(rst_map)
  31. #define CGU_SYS_RST_CTRL 0x0
  32. #define CGU_IP_SW_RESET 0x0
  33. #define CGU_IP_SW_RESET_DELAY_SHIFT 16
  34. #define CGU_IP_SW_RESET_DELAY_MASK GENMASK(31, CGU_IP_SW_RESET_DELAY_SHIFT)
  35. #define CGU_IP_SW_RESET_DELAY 0
  36. #define CGU_IP_SW_RESET_RESET BIT(0)
  37. #define SW_RESET_TIMEOUT 10000
  38. static void hsdk_reset_config(struct hsdk_rst *rst, unsigned long id)
  39. {
  40. writel(rst_map[id], rst->regs_ctl + CGU_SYS_RST_CTRL);
  41. }
  42. static int hsdk_reset_do(struct hsdk_rst *rst)
  43. {
  44. u32 reg;
  45. reg = readl(rst->regs_rst + CGU_IP_SW_RESET);
  46. reg &= ~CGU_IP_SW_RESET_DELAY_MASK;
  47. reg |= CGU_IP_SW_RESET_DELAY << CGU_IP_SW_RESET_DELAY_SHIFT;
  48. reg |= CGU_IP_SW_RESET_RESET;
  49. writel(reg, rst->regs_rst + CGU_IP_SW_RESET);
  50. /* wait till reset bit is back to 0 */
  51. return readl_poll_timeout(rst->regs_rst + CGU_IP_SW_RESET, reg,
  52. !(reg & CGU_IP_SW_RESET_RESET), SW_RESET_TIMEOUT);
  53. }
  54. static int hsdk_reset_reset(struct reset_ctl *rst_ctl)
  55. {
  56. struct udevice *dev = rst_ctl->dev;
  57. struct hsdk_rst *rst = dev_get_priv(dev);
  58. if (rst_ctl->id >= HSDK_MAX_RESETS)
  59. return -EINVAL;
  60. debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, rst_ctl,
  61. rst_ctl->dev, rst_ctl->id);
  62. hsdk_reset_config(rst, rst_ctl->id);
  63. return hsdk_reset_do(rst);
  64. }
  65. static int hsdk_reset_noop(struct reset_ctl *rst_ctl)
  66. {
  67. return 0;
  68. }
  69. static const struct reset_ops hsdk_reset_ops = {
  70. .request = hsdk_reset_noop,
  71. .rfree = hsdk_reset_noop,
  72. .rst_assert = hsdk_reset_noop,
  73. .rst_deassert = hsdk_reset_reset,
  74. };
  75. static const struct udevice_id hsdk_reset_dt_match[] = {
  76. { .compatible = "snps,hsdk-reset" },
  77. { },
  78. };
  79. static int hsdk_reset_probe(struct udevice *dev)
  80. {
  81. struct hsdk_rst *rst = dev_get_priv(dev);
  82. rst->regs_ctl = dev_remap_addr_index(dev, 0);
  83. if (!rst->regs_ctl)
  84. return -EINVAL;
  85. rst->regs_rst = dev_remap_addr_index(dev, 1);
  86. if (!rst->regs_rst)
  87. return -EINVAL;
  88. return 0;
  89. }
  90. U_BOOT_DRIVER(hsdk_reset) = {
  91. .name = "hsdk-reset",
  92. .id = UCLASS_RESET,
  93. .of_match = hsdk_reset_dt_match,
  94. .ops = &hsdk_reset_ops,
  95. .probe = hsdk_reset_probe,
  96. .priv_auto = sizeof(struct hsdk_rst),
  97. };