1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 #include <linux/linkage.h>
  11 #include <linux/clk/at91_pmc.h>
  12 #include "pm.h"
  13 #include "pm_data-offsets.h"
  14 
  15 #define SRAMC_SELF_FRESH_ACTIVE         0x01
  16 #define SRAMC_SELF_FRESH_EXIT           0x00
  17 
  18 pmc     .req    r0
  19 tmp1    .req    r4
  20 tmp2    .req    r5
  21 
  22 
  23 
  24 
  25         .macro wait_mckrdy
  26 1:      ldr     tmp1, [pmc, #AT91_PMC_SR]
  27         tst     tmp1, #AT91_PMC_MCKRDY
  28         beq     1b
  29         .endm
  30 
  31 
  32 
  33 
  34         .macro wait_moscrdy
  35 1:      ldr     tmp1, [pmc, #AT91_PMC_SR]
  36         tst     tmp1, #AT91_PMC_MOSCS
  37         beq     1b
  38         .endm
  39 
  40 
  41 
  42 
  43         .macro wait_moscsels
  44 1:      ldr     tmp1, [pmc, #AT91_PMC_SR]
  45         tst     tmp1, #AT91_PMC_MOSCSELS
  46         beq     1b
  47         .endm
  48 
  49 
  50 
  51 
  52         .macro at91_cpu_idle
  53 
  54 #if defined(CONFIG_CPU_V7)
  55         mov     tmp1, #AT91_PMC_PCK
  56         str     tmp1, [pmc, #AT91_PMC_SCDR]
  57 
  58         dsb
  59 
  60         wfi             @ Wait For Interrupt
  61 #else
  62         mcr     p15, 0, tmp1, c7, c0, 4
  63 #endif
  64 
  65         .endm
  66 
  67         .text
  68 
  69         .arm
  70 
  71 
  72 
  73 
  74 
  75 
  76 
  77         .align 3
  78 ENTRY(at91_pm_suspend_in_sram)
  79         
  80         stmfd   sp!, {r4 - r12, lr}
  81 
  82         
  83         mov     tmp1, #0
  84         mcr     p15, 0, tmp1, c7, c10, 4
  85 
  86         ldr     tmp1, [r0, #PM_DATA_PMC]
  87         str     tmp1, .pmc_base
  88         ldr     tmp1, [r0, #PM_DATA_RAMC0]
  89         str     tmp1, .sramc_base
  90         ldr     tmp1, [r0, #PM_DATA_RAMC1]
  91         str     tmp1, .sramc1_base
  92         ldr     tmp1, [r0, #PM_DATA_MEMCTRL]
  93         str     tmp1, .memtype
  94         ldr     tmp1, [r0, #PM_DATA_MODE]
  95         str     tmp1, .pm_mode
  96         
  97         ldr     tmp1, [r0, #PM_DATA_SHDWC]
  98         str     tmp1, .shdwc
  99         cmp     tmp1, #0
 100         ldrne   tmp2, [tmp1, #0]
 101         ldr     tmp1, [r0, #PM_DATA_SFRBU]
 102         str     tmp1, .sfr
 103         cmp     tmp1, #0
 104         ldrne   tmp2, [tmp1, #0x10]
 105 
 106         
 107         mov     r0, #SRAMC_SELF_FRESH_ACTIVE
 108         bl      at91_sramc_self_refresh
 109 
 110         ldr     r0, .pm_mode
 111         cmp     r0, #AT91_PM_STANDBY
 112         beq     standby
 113         cmp     r0, #AT91_PM_BACKUP
 114         beq     backup_mode
 115 
 116         bl      at91_ulp_mode
 117         b       exit_suspend
 118 
 119 standby:
 120         
 121         ldr     pmc, .pmc_base
 122         at91_cpu_idle
 123         b       exit_suspend
 124 
 125 backup_mode:
 126         bl      at91_backup_mode
 127         b       exit_suspend
 128 
 129 exit_suspend:
 130         
 131         mov     r0, #SRAMC_SELF_FRESH_EXIT
 132         bl      at91_sramc_self_refresh
 133 
 134         
 135         ldmfd   sp!, {r4 - r12, pc}
 136 ENDPROC(at91_pm_suspend_in_sram)
 137 
 138 ENTRY(at91_backup_mode)
 139         
 140         ldr     pmc, .pmc_base
 141         ldr     tmp1, [pmc, #AT91_PMC_MCKR]
 142         bic     tmp1, tmp1, #AT91_PMC_CSS
 143         str     tmp1, [pmc, #AT91_PMC_MCKR]
 144 
 145         wait_mckrdy
 146 
 147         
 148         ldr     r0, .sfr
 149         mov     tmp1, #0x1
 150         str     tmp1, [r0, #0x10]
 151 
 152         
 153         ldr     r0, .shdwc
 154         mov     tmp1, #0xA5000000
 155         add     tmp1, tmp1, #0x1
 156         str     tmp1, [r0, #0]
 157 ENDPROC(at91_backup_mode)
 158 
 159 .macro at91_pm_ulp0_mode
 160         ldr     pmc, .pmc_base
 161 
 162         
 163         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
 164         bic     tmp1, tmp1, #AT91_PMC_MOSCEN
 165         orr     tmp1, tmp1, #AT91_PMC_KEY
 166         str     tmp1, [pmc, #AT91_CKGR_MOR]
 167 
 168         
 169         ldr     tmp1, [pmc, #AT91_PMC_SR]
 170         str     tmp1, .saved_osc_status
 171         tst     tmp1, #AT91_PMC_MOSCRCS
 172         bne     1f
 173 
 174         
 175         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
 176         bic     tmp1, tmp1, #AT91_PMC_MOSCRCEN
 177         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
 178         orr     tmp1, tmp1, #AT91_PMC_KEY
 179         str     tmp1, [pmc, #AT91_CKGR_MOR]
 180 
 181         
 182 2:      ldr     tmp1, [pmc, #AT91_PMC_SR]
 183         tst     tmp1, #AT91_PMC_MOSCRCS
 184         bne     2b
 185 
 186         
 187 1:      at91_cpu_idle
 188 
 189         
 190         ldr     tmp1, .saved_osc_status
 191         tst     tmp1, #AT91_PMC_MOSCRCS
 192         beq     4f
 193 
 194         
 195         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
 196         orr     tmp1, tmp1, #AT91_PMC_MOSCRCEN
 197         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
 198         orr     tmp1, tmp1, #AT91_PMC_KEY
 199         str     tmp1, [pmc, #AT91_CKGR_MOR]
 200 
 201         
 202 3:      ldr     tmp1, [pmc, #AT91_PMC_SR]
 203         tst     tmp1, #AT91_PMC_MOSCRCS
 204         beq     3b
 205 
 206         
 207 4:      ldr     tmp1, [pmc, #AT91_CKGR_MOR]
 208         orr     tmp1, tmp1, #AT91_PMC_MOSCEN
 209         orr     tmp1, tmp1, #AT91_PMC_KEY
 210         str     tmp1, [pmc, #AT91_CKGR_MOR]
 211 
 212         wait_moscrdy
 213 .endm
 214 
 215 
 216 
 217 
 218 
 219 .macro at91_pm_ulp1_mode
 220         ldr     pmc, .pmc_base
 221 
 222         
 223         ldr     tmp1, [pmc, #AT91_PMC_SR]
 224         str     tmp1, .saved_osc_status
 225         tst     tmp1, #AT91_PMC_MOSCRCS
 226         bne     2f
 227 
 228         
 229         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
 230         orr     tmp1, tmp1, #AT91_PMC_MOSCRCEN
 231         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
 232         orr     tmp1, tmp1, #AT91_PMC_KEY
 233         str     tmp1, [pmc, #AT91_CKGR_MOR]
 234 
 235         
 236 1:      ldr     tmp1, [pmc, #AT91_PMC_SR]
 237         tst     tmp1, #AT91_PMC_MOSCRCS
 238         beq     1b
 239 
 240         
 241 2:      ldr     tmp1, [pmc, #AT91_CKGR_MOR]
 242         bic     tmp1, tmp1, #AT91_PMC_MOSCSEL
 243         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
 244         orr     tmp1, tmp1, #AT91_PMC_KEY
 245         str     tmp1, [pmc, #AT91_CKGR_MOR]
 246 
 247         wait_moscsels
 248 
 249         
 250         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
 251         bic     tmp1, tmp1, #AT91_PMC_MOSCEN
 252         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
 253         orr     tmp1, tmp1, #AT91_PMC_KEY
 254         str     tmp1, [pmc, #AT91_CKGR_MOR]
 255 
 256         
 257         ldr     tmp1, [pmc, #AT91_PMC_MCKR]
 258         bic     tmp1, tmp1, #AT91_PMC_CSS
 259         orr     tmp1, tmp1, #AT91_PMC_CSS_MAIN
 260         str     tmp1, [pmc, #AT91_PMC_MCKR]
 261 
 262         wait_mckrdy
 263 
 264         
 265         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
 266         orr     tmp1, tmp1, #AT91_PMC_WAITMODE
 267         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
 268         orr     tmp1, tmp1, #AT91_PMC_KEY
 269         str     tmp1, [pmc, #AT91_CKGR_MOR]
 270 
 271         wait_mckrdy
 272 
 273         
 274         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
 275         orr     tmp1, tmp1, #AT91_PMC_MOSCEN
 276         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
 277         orr     tmp1, tmp1, #AT91_PMC_KEY
 278         str     tmp1, [pmc, #AT91_CKGR_MOR]
 279 
 280         wait_moscrdy
 281 
 282         
 283         ldr     tmp1, [pmc, #AT91_PMC_MCKR]
 284         bic     tmp1, tmp1, #AT91_PMC_CSS
 285         str     tmp1, [pmc, #AT91_PMC_MCKR]
 286 
 287         wait_mckrdy
 288 
 289         
 290         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
 291         orr     tmp1, tmp1, #AT91_PMC_MOSCSEL
 292         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
 293         orr     tmp1, tmp1, #AT91_PMC_KEY
 294         str     tmp1, [pmc, #AT91_CKGR_MOR]
 295 
 296         wait_moscsels
 297 
 298         
 299         ldr     tmp1, [pmc, #AT91_PMC_MCKR]
 300         bic     tmp1, tmp1, #AT91_PMC_CSS
 301         orr     tmp1, tmp1, #AT91_PMC_CSS_MAIN
 302         str     tmp1, [pmc, #AT91_PMC_MCKR]
 303 
 304         wait_mckrdy
 305 
 306         
 307         ldr     tmp1, .saved_osc_status
 308         tst     tmp1, #AT91_PMC_MOSCRCS
 309         bne     3f
 310 
 311         
 312         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
 313         bic     tmp1, tmp1, #AT91_PMC_MOSCRCEN
 314         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
 315         orr     tmp1, tmp1, #AT91_PMC_KEY
 316         str     tmp1, [pmc, #AT91_CKGR_MOR]
 317 
 318         
 319 4:      ldr     tmp1, [pmc, #AT91_PMC_SR]
 320         tst     tmp1, #AT91_PMC_MOSCRCS
 321         bne     4b
 322 
 323 3:
 324 .endm
 325 
 326 ENTRY(at91_ulp_mode)
 327         ldr     pmc, .pmc_base
 328 
 329         
 330         ldr     tmp1, [pmc, #AT91_PMC_MCKR]
 331         str     tmp1, .saved_mckr
 332 
 333         
 334 
 335 
 336         bic     tmp1, tmp1, #AT91_PMC_CSS
 337         str     tmp1, [pmc, #AT91_PMC_MCKR]
 338 
 339         wait_mckrdy
 340 
 341         ldr     r0, .pm_mode
 342         cmp     r0, #AT91_PM_ULP1
 343         beq     ulp1_mode
 344 
 345         at91_pm_ulp0_mode
 346         b       ulp_exit
 347 
 348 ulp1_mode:
 349         at91_pm_ulp1_mode
 350         b       ulp_exit
 351 
 352 ulp_exit:
 353         ldr     pmc, .pmc_base
 354 
 355         
 356 
 357 
 358         ldr     tmp1, .saved_mckr
 359         str     tmp1, [pmc, #AT91_PMC_MCKR]
 360 
 361         wait_mckrdy
 362 
 363         mov     pc, lr
 364 ENDPROC(at91_ulp_mode)
 365 
 366 
 367 
 368 
 369 
 370 
 371 
 372 
 373 
 374 
 375 
 376 
 377 ENTRY(at91_sramc_self_refresh)
 378         ldr     r1, .memtype
 379         ldr     r2, .sramc_base
 380 
 381         cmp     r1, #AT91_MEMCTRL_MC
 382         bne     ddrc_sf
 383 
 384         
 385 
 386 
 387 
 388          
 389 
 390 
 391 
 392         tst     r0, #SRAMC_SELF_FRESH_ACTIVE
 393         beq     exit_sramc_sf
 394 
 395         
 396         mov     r3, #1
 397         str     r3, [r2, #AT91_MC_SDRAMC_SRR]
 398         b       exit_sramc_sf
 399 
 400 ddrc_sf:
 401         cmp     r1, #AT91_MEMCTRL_DDRSDR
 402         bne     sdramc_sf
 403 
 404         
 405 
 406 
 407         tst     r0, #SRAMC_SELF_FRESH_ACTIVE
 408         beq     ddrc_exit_sf
 409 
 410         
 411         ldr     r3, [r2, #AT91_DDRSDRC_MDR]
 412         str     r3, .saved_sam9_mdr
 413         bic     r3, r3, #~AT91_DDRSDRC_MD
 414         cmp     r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
 415         ldreq   r3, [r2, #AT91_DDRSDRC_MDR]
 416         biceq   r3, r3, #AT91_DDRSDRC_MD
 417         orreq   r3, r3, #AT91_DDRSDRC_MD_DDR2
 418         streq   r3, [r2, #AT91_DDRSDRC_MDR]
 419 
 420         
 421         ldr     r3, [r2, #AT91_DDRSDRC_LPR]
 422         str     r3, .saved_sam9_lpr
 423         bic     r3, r3, #AT91_DDRSDRC_LPCB
 424         orr     r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
 425         str     r3, [r2, #AT91_DDRSDRC_LPR]
 426 
 427         
 428         ldr     r2, .sramc1_base
 429         cmp     r2, #0
 430         beq     no_2nd_ddrc
 431 
 432         ldr     r3, [r2, #AT91_DDRSDRC_MDR]
 433         str     r3, .saved_sam9_mdr1
 434         bic     r3, r3, #~AT91_DDRSDRC_MD
 435         cmp     r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
 436         ldreq   r3, [r2, #AT91_DDRSDRC_MDR]
 437         biceq   r3, r3, #AT91_DDRSDRC_MD
 438         orreq   r3, r3, #AT91_DDRSDRC_MD_DDR2
 439         streq   r3, [r2, #AT91_DDRSDRC_MDR]
 440 
 441         
 442         ldr     r3, [r2, #AT91_DDRSDRC_LPR]
 443         str     r3, .saved_sam9_lpr1
 444         bic     r3, r3, #AT91_DDRSDRC_LPCB
 445         orr     r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
 446         str     r3, [r2, #AT91_DDRSDRC_LPR]
 447 
 448 no_2nd_ddrc:
 449         b       exit_sramc_sf
 450 
 451 ddrc_exit_sf:
 452         
 453         ldr     r3, .saved_sam9_mdr
 454         str     r3, [r2, #AT91_DDRSDRC_MDR]
 455         
 456         ldr     r3, .saved_sam9_lpr
 457         str     r3, [r2, #AT91_DDRSDRC_LPR]
 458 
 459         
 460         ldr     r2, .sramc1_base
 461         cmp     r2, #0
 462         ldrne   r3, .saved_sam9_mdr1
 463         strne   r3, [r2, #AT91_DDRSDRC_MDR]
 464         ldrne   r3, .saved_sam9_lpr1
 465         strne   r3, [r2, #AT91_DDRSDRC_LPR]
 466 
 467         b       exit_sramc_sf
 468 
 469         
 470 
 471 
 472 sdramc_sf:
 473         tst     r0, #SRAMC_SELF_FRESH_ACTIVE
 474         beq     sdramc_exit_sf
 475 
 476         
 477         ldr     r3, [r2, #AT91_SDRAMC_LPR]
 478         str     r3, .saved_sam9_lpr
 479         bic     r3, r3, #AT91_SDRAMC_LPCB
 480         orr     r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
 481         str     r3, [r2, #AT91_SDRAMC_LPR]
 482 
 483 sdramc_exit_sf:
 484         ldr     r3, .saved_sam9_lpr
 485         str     r3, [r2, #AT91_SDRAMC_LPR]
 486 
 487 exit_sramc_sf:
 488         mov     pc, lr
 489 ENDPROC(at91_sramc_self_refresh)
 490 
 491 .pmc_base:
 492         .word 0
 493 .sramc_base:
 494         .word 0
 495 .sramc1_base:
 496         .word 0
 497 .shdwc:
 498         .word 0
 499 .sfr:
 500         .word 0
 501 .memtype:
 502         .word 0
 503 .pm_mode:
 504         .word 0
 505 .saved_mckr:
 506         .word 0
 507 .saved_sam9_lpr:
 508         .word 0
 509 .saved_sam9_lpr1:
 510         .word 0
 511 .saved_sam9_mdr:
 512         .word 0
 513 .saved_sam9_mdr1:
 514         .word 0
 515 .saved_osc_status:
 516         .word 0
 517 
 518 ENTRY(at91_pm_suspend_in_sram_sz)
 519         .word .-at91_pm_suspend_in_sram