kirkwood-pm.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Power Management driver for Marvell Kirkwood SoCs
  4. *
  5. * Copyright (C) 2013 Ezequiel Garcia <ezequiel@free-electrons.com>
  6. * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
  7. */
  8. #include <linux/kernel.h>
  9. #include <linux/suspend.h>
  10. #include <linux/io.h>
  11. #include "kirkwood.h"
  12. #include "kirkwood-pm.h"
  13. static void __iomem *ddr_operation_base;
  14. static void __iomem *memory_pm_ctrl;
  15. static void kirkwood_low_power(void)
  16. {
  17. u32 mem_pm_ctrl;
  18. mem_pm_ctrl = readl(memory_pm_ctrl);
  19. /* Set peripherals to low-power mode */
  20. writel_relaxed(~0, memory_pm_ctrl);
  21. /* Set DDR in self-refresh */
  22. writel_relaxed(0x7, ddr_operation_base);
  23. /*
  24. * Set CPU in wait-for-interrupt state.
  25. * This disables the CPU core clocks,
  26. * the array clocks, and also the L2 controller.
  27. */
  28. cpu_do_idle();
  29. writel_relaxed(mem_pm_ctrl, memory_pm_ctrl);
  30. }
  31. static int kirkwood_suspend_enter(suspend_state_t state)
  32. {
  33. switch (state) {
  34. case PM_SUSPEND_STANDBY:
  35. kirkwood_low_power();
  36. break;
  37. default:
  38. return -EINVAL;
  39. }
  40. return 0;
  41. }
  42. static int kirkwood_pm_valid_standby(suspend_state_t state)
  43. {
  44. return state == PM_SUSPEND_STANDBY;
  45. }
  46. static const struct platform_suspend_ops kirkwood_suspend_ops = {
  47. .enter = kirkwood_suspend_enter,
  48. .valid = kirkwood_pm_valid_standby,
  49. };
  50. void __init kirkwood_pm_init(void)
  51. {
  52. ddr_operation_base = ioremap(DDR_OPERATION_BASE, 4);
  53. memory_pm_ctrl = ioremap(MEMORY_PM_CTRL_PHYS, 4);
  54. suspend_set_ops(&kirkwood_suspend_ops);
  55. }