0001
0002
0003
0004
0005 #include <linux/linkage.h>
0006 #include <asm/assembler.h>
0007
0008 #define MAX_LOOP_COUNT 1000
0009
0010
0011 #define SDR_CTRLGRP_LOWPWREQ_ADDR 0x54
0012 #define SDR_CTRLGRP_LOWPWRACK_ADDR 0x58
0013
0014
0015 #define SELFRSHREQ_POS 3
0016 #define SELFRSHREQ_MASK 0x8
0017
0018 #define SELFRFSHACK_POS 1
0019 #define SELFRFSHACK_MASK 0x2
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 .arch armv7-a
0033 .text
0034 .align 3
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 ENTRY(socfpga_sdram_self_refresh)
0048
0049 mrc p15, 0, r2, c15, c0, 0
0050 orr r2, r2, #1
0051 mcr p15, 0, r2, c15, c0, 0
0052
0053
0054 ldr r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR]
0055 orr r2, r2, #SELFRSHREQ_MASK
0056 str r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR]
0057
0058
0059 mov r3, #0
0060 while_ack_0:
0061 ldr r2, [r0, #SDR_CTRLGRP_LOWPWRACK_ADDR]
0062 and r2, r2, #SELFRFSHACK_MASK
0063 cmp r2, #SELFRFSHACK_MASK
0064 beq ack_1
0065
0066 add r3, #1
0067 cmp r3, #MAX_LOOP_COUNT
0068 bne while_ack_0
0069
0070 ack_1:
0071 mov r1, r3
0072
0073
0074
0075
0076
0077 isb
0078
0079
0080
0081
0082
0083
0084 dsb
0085 dmb
0086
0087 wfi
0088
0089
0090 ldr r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR]
0091 bic r2, r2, #SELFRSHREQ_MASK
0092 str r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR]
0093
0094
0095 mov r3, #0
0096 while_ack_1:
0097 ldr r2, [r0, #SDR_CTRLGRP_LOWPWRACK_ADDR]
0098 and r2, r2, #SELFRFSHACK_MASK
0099 cmp r2, #SELFRFSHACK_MASK
0100 bne ack_0
0101
0102 add r3, #1
0103 cmp r3, #MAX_LOOP_COUNT
0104 bne while_ack_1
0105
0106 ack_0:
0107
0108
0109
0110
0111
0112 mov r3, r3, lsl #16
0113 add r1, r1, r3
0114
0115
0116 mrc p15, 0, r2, c15, c0, 0
0117 bic r2, r2, #1
0118 mcr p15, 0, r2, c15, c0, 0
0119
0120 mov r0, r1 @ return value
0121 bx lr @ return
0122
0123 ENDPROC(socfpga_sdram_self_refresh)
0124 ENTRY(socfpga_sdram_self_refresh_sz)
0125 .word . - socfpga_sdram_self_refresh