self-refresh.S 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (C) 2014-2015 Altera Corporation. All rights reserved.
  4. */
  5. #include <linux/linkage.h>
  6. #include <asm/assembler.h>
  7. #define MAX_LOOP_COUNT 1000
  8. /* Register offset */
  9. #define SDR_CTRLGRP_LOWPWREQ_ADDR 0x54
  10. #define SDR_CTRLGRP_LOWPWRACK_ADDR 0x58
  11. /* Bitfield positions */
  12. #define SELFRSHREQ_POS 3
  13. #define SELFRSHREQ_MASK 0x8
  14. #define SELFRFSHACK_POS 1
  15. #define SELFRFSHACK_MASK 0x2
  16. /*
  17. * This code assumes that when the bootloader configured
  18. * the sdram controller for the DDR on the board it
  19. * configured the following fields depending on the DDR
  20. * vendor/configuration:
  21. *
  22. * sdr.ctrlcfg.lowpwreq.selfrfshmask
  23. * sdr.ctrlcfg.lowpwrtiming.clkdisablecycles
  24. * sdr.ctrlcfg.dramtiming4.selfrfshexit
  25. */
  26. .arch armv7-a
  27. .text
  28. .align 3
  29. /*
  30. * socfpga_sdram_self_refresh
  31. *
  32. * r0 : sdr_ctl_base_addr
  33. * r1 : temp storage of return value
  34. * r2 : temp storage of register values
  35. * r3 : loop counter
  36. *
  37. * return value: lower 16 bits: loop count going into self refresh
  38. * upper 16 bits: loop count exiting self refresh
  39. */
  40. ENTRY(socfpga_sdram_self_refresh)
  41. /* Enable dynamic clock gating in the Power Control Register. */
  42. mrc p15, 0, r2, c15, c0, 0
  43. orr r2, r2, #1
  44. mcr p15, 0, r2, c15, c0, 0
  45. /* Enable self refresh: set sdr.ctrlgrp.lowpwreq.selfrshreq = 1 */
  46. ldr r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR]
  47. orr r2, r2, #SELFRSHREQ_MASK
  48. str r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR]
  49. /* Poll until sdr.ctrlgrp.lowpwrack.selfrfshack == 1 or hit max loops */
  50. mov r3, #0
  51. while_ack_0:
  52. ldr r2, [r0, #SDR_CTRLGRP_LOWPWRACK_ADDR]
  53. and r2, r2, #SELFRFSHACK_MASK
  54. cmp r2, #SELFRFSHACK_MASK
  55. beq ack_1
  56. add r3, #1
  57. cmp r3, #MAX_LOOP_COUNT
  58. bne while_ack_0
  59. ack_1:
  60. mov r1, r3
  61. /*
  62. * Execute an ISB instruction to ensure that all of the
  63. * CP15 register changes have been committed.
  64. */
  65. isb
  66. /*
  67. * Execute a barrier instruction to ensure that all cache,
  68. * TLB and branch predictor maintenance operations issued
  69. * by any CPU in the cluster have completed.
  70. */
  71. dsb
  72. dmb
  73. wfi
  74. /* Disable self-refresh: set sdr.ctrlgrp.lowpwreq.selfrshreq = 0 */
  75. ldr r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR]
  76. bic r2, r2, #SELFRSHREQ_MASK
  77. str r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR]
  78. /* Poll until sdr.ctrlgrp.lowpwrack.selfrfshack == 0 or hit max loops */
  79. mov r3, #0
  80. while_ack_1:
  81. ldr r2, [r0, #SDR_CTRLGRP_LOWPWRACK_ADDR]
  82. and r2, r2, #SELFRFSHACK_MASK
  83. cmp r2, #SELFRFSHACK_MASK
  84. bne ack_0
  85. add r3, #1
  86. cmp r3, #MAX_LOOP_COUNT
  87. bne while_ack_1
  88. ack_0:
  89. /*
  90. * Prepare return value:
  91. * Shift loop count for exiting self refresh into upper 16 bits.
  92. * Leave loop count for requesting self refresh in lower 16 bits.
  93. */
  94. mov r3, r3, lsl #16
  95. add r1, r1, r3
  96. /* Disable dynamic clock gating in the Power Control Register. */
  97. mrc p15, 0, r2, c15, c0, 0
  98. bic r2, r2, #1
  99. mcr p15, 0, r2, c15, c0, 0
  100. mov r0, r1 @ return value
  101. bx lr @ return
  102. ENDPROC(socfpga_sdram_self_refresh)
  103. ENTRY(socfpga_sdram_self_refresh_sz)
  104. .word . - socfpga_sdram_self_refresh