pm.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /*
  2. * Zynq power management
  3. *
  4. * Copyright (C) 2012 - 2014 Xilinx
  5. *
  6. * Sören Brinkmann <soren.brinkmann@xilinx.com>
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #include <linux/io.h>
  22. #include <linux/of_address.h>
  23. #include <linux/of_device.h>
  24. #include "common.h"
  25. /* register offsets */
  26. #define DDRC_CTRL_REG1_OFFS 0x60
  27. #define DDRC_DRAM_PARAM_REG3_OFFS 0x20
  28. /* bitfields */
  29. #define DDRC_CLOCKSTOP_MASK BIT(23)
  30. #define DDRC_SELFREFRESH_MASK BIT(12)
  31. static void __iomem *ddrc_base;
  32. /**
  33. * zynq_pm_ioremap() - Create IO mappings
  34. * @comp: DT compatible string
  35. * Return: Pointer to the mapped memory or NULL.
  36. *
  37. * Remap the memory region for a compatible DT node.
  38. */
  39. static void __iomem *zynq_pm_ioremap(const char *comp)
  40. {
  41. struct device_node *np;
  42. void __iomem *base = NULL;
  43. np = of_find_compatible_node(NULL, NULL, comp);
  44. if (np) {
  45. base = of_iomap(np, 0);
  46. of_node_put(np);
  47. } else {
  48. pr_warn("%s: no compatible node found for '%s'\n", __func__,
  49. comp);
  50. }
  51. return base;
  52. }
  53. /**
  54. * zynq_pm_late_init() - Power management init
  55. *
  56. * Initialization of power management related features and infrastructure.
  57. */
  58. void __init zynq_pm_late_init(void)
  59. {
  60. u32 reg;
  61. ddrc_base = zynq_pm_ioremap("xlnx,zynq-ddrc-a05");
  62. if (!ddrc_base) {
  63. pr_warn("%s: Unable to map DDRC IO memory.\n", __func__);
  64. } else {
  65. /*
  66. * Enable DDRC clock stop feature. The HW takes care of
  67. * entering/exiting the correct mode depending
  68. * on activity state.
  69. */
  70. reg = readl(ddrc_base + DDRC_DRAM_PARAM_REG3_OFFS);
  71. reg |= DDRC_CLOCKSTOP_MASK;
  72. writel(reg, ddrc_base + DDRC_DRAM_PARAM_REG3_OFFS);
  73. }
  74. }