0001
0002
0003
0004
0005
0006 #include <linux/linkage.h>
0007 #include <asm/assembler.h>
0008 #include <asm/asm-offsets.h>
0009 #include <asm/hardware/cache-l2x0.h>
0010 #include "hardware.h"
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #define PM_INFO_PBASE_OFFSET 0x0
0041 #define PM_INFO_RESUME_ADDR_OFFSET 0x4
0042 #define PM_INFO_DDR_TYPE_OFFSET 0x8
0043 #define PM_INFO_PM_INFO_SIZE_OFFSET 0xC
0044 #define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10
0045 #define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14
0046 #define PM_INFO_MX6Q_SRC_P_OFFSET 0x18
0047 #define PM_INFO_MX6Q_SRC_V_OFFSET 0x1C
0048 #define PM_INFO_MX6Q_IOMUXC_P_OFFSET 0x20
0049 #define PM_INFO_MX6Q_IOMUXC_V_OFFSET 0x24
0050 #define PM_INFO_MX6Q_CCM_P_OFFSET 0x28
0051 #define PM_INFO_MX6Q_CCM_V_OFFSET 0x2C
0052 #define PM_INFO_MX6Q_GPC_P_OFFSET 0x30
0053 #define PM_INFO_MX6Q_GPC_V_OFFSET 0x34
0054 #define PM_INFO_MX6Q_L2_P_OFFSET 0x38
0055 #define PM_INFO_MX6Q_L2_V_OFFSET 0x3C
0056 #define PM_INFO_MMDC_IO_NUM_OFFSET 0x40
0057 #define PM_INFO_MMDC_IO_VAL_OFFSET 0x44
0058
0059 #define MX6Q_SRC_GPR1 0x20
0060 #define MX6Q_SRC_GPR2 0x24
0061 #define MX6Q_MMDC_MAPSR 0x404
0062 #define MX6Q_MMDC_MPDGCTRL0 0x83c
0063 #define MX6Q_GPC_IMR1 0x08
0064 #define MX6Q_GPC_IMR2 0x0c
0065 #define MX6Q_GPC_IMR3 0x10
0066 #define MX6Q_GPC_IMR4 0x14
0067 #define MX6Q_CCM_CCR 0x0
0068
0069 .align 3
0070 .arm
0071
0072 .macro sync_l2_cache
0073
0074
0075 #ifdef CONFIG_CACHE_L2X0
0076 ldr r11, [r0, #PM_INFO_MX6Q_L2_V_OFFSET]
0077 teq r11, #0
0078 beq 6f
0079 mov r6, #0x0
0080 str r6, [r11, #L2X0_CACHE_SYNC]
0081 1:
0082 ldr r6, [r11, #L2X0_CACHE_SYNC]
0083 ands r6, r6, #0x1
0084 bne 1b
0085 6:
0086 #endif
0087
0088 .endm
0089
0090 .macro resume_mmdc
0091
0092
0093 cmp r5, #0x0
0094 ldreq r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
0095 ldrne r11, [r0, #PM_INFO_MX6Q_IOMUXC_P_OFFSET]
0096
0097 ldr r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
0098 ldr r7, =PM_INFO_MMDC_IO_VAL_OFFSET
0099 add r7, r7, r0
0100 1:
0101 ldr r8, [r7], #0x4
0102 ldr r9, [r7], #0x4
0103 str r9, [r11, r8]
0104 subs r6, r6, #0x1
0105 bne 1b
0106
0107 cmp r5, #0x0
0108 ldreq r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
0109 ldrne r11, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET]
0110
0111 cmp r3, #IMX_DDR_TYPE_LPDDR2
0112 bne 4f
0113
0114
0115 ldr r7, =MX6Q_MMDC_MPDGCTRL0
0116 ldr r6, [r11, r7]
0117 orr r6, r6, #(1 << 31)
0118 str r6, [r11, r7]
0119 2:
0120 ldr r6, [r11, r7]
0121 ands r6, r6, #(1 << 31)
0122 bne 2b
0123
0124
0125 ldr r6, [r11, r7]
0126 orr r6, r6, #(1 << 31)
0127 str r6, [r11, r7]
0128 3:
0129 ldr r6, [r11, r7]
0130 ands r6, r6, #(1 << 31)
0131 bne 3b
0132 4:
0133
0134 ldr r7, [r11, #MX6Q_MMDC_MAPSR]
0135 bic r7, r7, #(1 << 21)
0136 str r7, [r11, #MX6Q_MMDC_MAPSR]
0137 5:
0138 ldr r7, [r11, #MX6Q_MMDC_MAPSR]
0139 ands r7, r7, #(1 << 25)
0140 bne 5b
0141
0142
0143 ldr r7, [r11, #MX6Q_MMDC_MAPSR]
0144 bic r7, r7, #0x1
0145 str r7, [r11, #MX6Q_MMDC_MAPSR]
0146
0147 .endm
0148
0149 ENTRY(imx6_suspend)
0150 ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
0151 ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
0152 ldr r3, [r0, #PM_INFO_DDR_TYPE_OFFSET]
0153 ldr r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
0154
0155
0156
0157
0158
0159 ldr r6, =imx6_suspend
0160 ldr r7, =resume
0161 sub r7, r7, r6
0162 add r8, r1, r4
0163 add r9, r8, r7
0164
0165
0166
0167
0168
0169
0170 ldr r11, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
0171 ldr r6, [r11, #0x0]
0172 ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
0173 ldr r6, [r11, #0x0]
0174 ldr r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
0175 ldr r6, [r11, #0x0]
0176
0177
0178 ldr r11, [r0, #PM_INFO_MX6Q_SRC_V_OFFSET]
0179
0180 str r9, [r11, #MX6Q_SRC_GPR1]
0181 str r1, [r11, #MX6Q_SRC_GPR2]
0182
0183
0184 sync_l2_cache
0185
0186 ldr r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
0187
0188
0189
0190
0191 ldr r7, [r11, #MX6Q_MMDC_MAPSR]
0192 orr r7, r7, #0x1
0193 str r7, [r11, #MX6Q_MMDC_MAPSR]
0194
0195
0196 ldr r7, [r11, #MX6Q_MMDC_MAPSR]
0197 orr r7, r7, #(1 << 21)
0198 str r7, [r11, #MX6Q_MMDC_MAPSR]
0199
0200 poll_dvfs_set:
0201 ldr r7, [r11, #MX6Q_MMDC_MAPSR]
0202 ands r7, r7, #(1 << 25)
0203 beq poll_dvfs_set
0204
0205 ldr r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
0206 ldr r6, =0x0
0207 ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
0208 ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET
0209 add r8, r8, r0
0210
0211 cmp r3, #IMX_DDR_TYPE_LPDDR2
0212 subeq r7, r7, #0x3
0213 set_mmdc_io_lpm:
0214 ldr r9, [r8], #0x8
0215 str r6, [r11, r9]
0216 subs r7, r7, #0x1
0217 bne set_mmdc_io_lpm
0218
0219 cmp r3, #IMX_DDR_TYPE_LPDDR2
0220 bne set_mmdc_io_lpm_done
0221 ldr r6, =0x1000
0222 ldr r9, [r8], #0x8
0223 str r6, [r11, r9]
0224 ldr r9, [r8], #0x8
0225 str r6, [r11, r9]
0226 ldr r6, =0x80000
0227 ldr r9, [r8]
0228 str r6, [r11, r9]
0229 set_mmdc_io_lpm_done:
0230
0231
0232
0233
0234
0235
0236
0237
0238 ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
0239 ldr r6, [r11, #MX6Q_GPC_IMR1]
0240 ldr r7, [r11, #MX6Q_GPC_IMR2]
0241 ldr r8, [r11, #MX6Q_GPC_IMR3]
0242 ldr r9, [r11, #MX6Q_GPC_IMR4]
0243
0244 ldr r10, =0xffffffff
0245 str r10, [r11, #MX6Q_GPC_IMR1]
0246 str r10, [r11, #MX6Q_GPC_IMR2]
0247 str r10, [r11, #MX6Q_GPC_IMR3]
0248 str r10, [r11, #MX6Q_GPC_IMR4]
0249
0250
0251
0252
0253
0254
0255
0256 ldr r11, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
0257 ldr r10, [r11, #MX6Q_CCM_CCR]
0258 bic r10, r10, #(0x3f << 21)
0259 orr r10, r10, #(0x20 << 21)
0260 str r10, [r11, #MX6Q_CCM_CCR]
0261
0262
0263 ldr r10, [r11, #MX6Q_CCM_CCR]
0264 orr r10, r10, #(0x1 << 27)
0265 str r10, [r11, #MX6Q_CCM_CCR]
0266
0267
0268 ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
0269 str r6, [r11, #MX6Q_GPC_IMR1]
0270 str r7, [r11, #MX6Q_GPC_IMR2]
0271 str r8, [r11, #MX6Q_GPC_IMR3]
0272 str r9, [r11, #MX6Q_GPC_IMR4]
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284 ldr r6, =2000
0285 rbc_loop:
0286 subs r6, r6, #0x1
0287 bne rbc_loop
0288
0289
0290 wfi
0291 nop
0292 nop
0293 nop
0294 nop
0295
0296
0297
0298
0299
0300
0301 mov r5, #0x0
0302 resume_mmdc
0303
0304
0305 ret lr
0306
0307 resume:
0308
0309 mov r6, #0x0
0310 mcr p15, 0, r6, c7, c5, 0
0311 mcr p15, 0, r6, c7, c5, 6
0312
0313 mov r6, #0x1800
0314 mcr p15, 0, r6, c1, c0, 0
0315 isb
0316
0317
0318 ldr lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
0319
0320 ldr r11, [r0, #PM_INFO_MX6Q_SRC_P_OFFSET]
0321 mov r7, #0x0
0322 str r7, [r11, #MX6Q_SRC_GPR1]
0323 str r7, [r11, #MX6Q_SRC_GPR2]
0324
0325 ldr r3, [r0, #PM_INFO_DDR_TYPE_OFFSET]
0326 mov r5, #0x1
0327 resume_mmdc
0328
0329 ret lr
0330 ENDPROC(imx6_suspend)