0001
0002
0003
0004
0005
0006 #include <linux/linkage.h>
0007
0008 #include <soc/tegra/flowctrl.h>
0009 #include <soc/tegra/fuse.h>
0010
0011 #include <asm/asm-offsets.h>
0012 #include <asm/assembler.h>
0013 #include <asm/cache.h>
0014
0015 #include "irammap.h"
0016 #include "sleep.h"
0017
0018 #define EMC_CFG 0xc
0019 #define EMC_ADR_CFG 0x10
0020 #define EMC_TIMING_CONTROL 0x28
0021 #define EMC_NOP 0xdc
0022 #define EMC_SELF_REF 0xe0
0023 #define EMC_MRW 0xe8
0024 #define EMC_FBIO_CFG5 0x104
0025 #define EMC_AUTO_CAL_CONFIG 0x2a4
0026 #define EMC_AUTO_CAL_INTERVAL 0x2a8
0027 #define EMC_AUTO_CAL_STATUS 0x2ac
0028 #define EMC_REQ_CTRL 0x2b0
0029 #define EMC_CFG_DIG_DLL 0x2bc
0030 #define EMC_EMC_STATUS 0x2b4
0031 #define EMC_ZCAL_INTERVAL 0x2e0
0032 #define EMC_ZQ_CAL 0x2ec
0033 #define EMC_XM2VTTGENPADCTRL 0x310
0034 #define EMC_XM2VTTGENPADCTRL2 0x314
0035
0036 #define PMC_CTRL 0x0
0037 #define PMC_CTRL_SIDE_EFFECT_LP0 (1 << 14)
0038
0039 #define PMC_PLLP_WB0_OVERRIDE 0xf8
0040 #define PMC_IO_DPD_REQ 0x1b8
0041 #define PMC_IO_DPD_STATUS 0x1bc
0042
0043 #define CLK_RESET_CCLK_BURST 0x20
0044 #define CLK_RESET_CCLK_DIVIDER 0x24
0045 #define CLK_RESET_SCLK_BURST 0x28
0046 #define CLK_RESET_SCLK_DIVIDER 0x2c
0047
0048 #define CLK_RESET_PLLC_BASE 0x80
0049 #define CLK_RESET_PLLC_MISC 0x8c
0050 #define CLK_RESET_PLLM_BASE 0x90
0051 #define CLK_RESET_PLLM_MISC 0x9c
0052 #define CLK_RESET_PLLP_BASE 0xa0
0053 #define CLK_RESET_PLLP_MISC 0xac
0054 #define CLK_RESET_PLLA_BASE 0xb0
0055 #define CLK_RESET_PLLA_MISC 0xbc
0056 #define CLK_RESET_PLLX_BASE 0xe0
0057 #define CLK_RESET_PLLX_MISC 0xe4
0058 #define CLK_RESET_PLLX_MISC3 0x518
0059 #define CLK_RESET_PLLX_MISC3_IDDQ 3
0060 #define CLK_RESET_PLLM_MISC_IDDQ 5
0061 #define CLK_RESET_PLLC_MISC_IDDQ 26
0062 #define CLK_RESET_PLLP_RESHIFT 0x528
0063 #define CLK_RESET_PLLP_RESHIFT_DEFAULT 0x3b
0064 #define CLK_RESET_PLLP_RESHIFT_ENABLE 0x3
0065
0066 #define CLK_RESET_CLK_SOURCE_MSELECT 0x3b4
0067
0068 #define MSELECT_CLKM (0x3 << 30)
0069
0070 #define LOCK_DELAY 50
0071
0072 #define TEGRA30_POWER_HOTPLUG_SHUTDOWN (1 << 27)
0073
0074 #define PLLA_STORE_MASK (1 << 0)
0075 #define PLLC_STORE_MASK (1 << 1)
0076 #define PLLM_STORE_MASK (1 << 2)
0077 #define PLLP_STORE_MASK (1 << 3)
0078 #define PLLX_STORE_MASK (1 << 4)
0079 #define PLLM_PMC_STORE_MASK (1 << 5)
0080
0081 .macro emc_device_mask, rd, base
0082 ldr \rd, [\base, #EMC_ADR_CFG]
0083 tst \rd, #0x1
0084 moveq \rd, #(0x1 << 8) @ just 1 device
0085 movne \rd, #(0x3 << 8) @ 2 devices
0086 .endm
0087
0088 .macro emc_timing_update, rd, base
0089 mov \rd, #1
0090 str \rd, [\base, #EMC_TIMING_CONTROL]
0091 1001:
0092 ldr \rd, [\base, #EMC_EMC_STATUS]
0093 tst \rd, #(0x1<<23) @ wait EMC_STATUS_TIMING_UPDATE_STALLED is clear
0094 bne 1001b
0095 .endm
0096
0097 .macro test_pll_state, rd, test_mask
0098 ldr \rd, tegra_pll_state
0099 tst \rd, #\test_mask
0100 .endm
0101
0102 .macro store_pll_state, rd, tmp, r_car_base, pll_base, pll_mask
0103 ldr \rd, [\r_car_base, #\pll_base]
0104 tst \rd, #(1 << 30)
0105 ldr \rd, tegra_pll_state
0106 biceq \rd, \rd, #\pll_mask
0107 orrne \rd, \rd, #\pll_mask
0108 adr \tmp, tegra_pll_state
0109 str \rd, [\tmp]
0110 .endm
0111
0112 .macro store_pllm_pmc_state, rd, tmp, pmc_base
0113 ldr \rd, [\pmc_base, #PMC_PLLP_WB0_OVERRIDE]
0114 tst \rd, #(1 << 12)
0115 ldr \rd, tegra_pll_state
0116 biceq \rd, \rd, #PLLM_PMC_STORE_MASK
0117 orrne \rd, \rd, #PLLM_PMC_STORE_MASK
0118 adr \tmp, tegra_pll_state
0119 str \rd, [\tmp]
0120 .endm
0121
0122 .macro pllm_pmc_enable, rd, pmc_base
0123 test_pll_state \rd, PLLM_PMC_STORE_MASK
0124
0125 ldrne \rd, [\pmc_base, #PMC_PLLP_WB0_OVERRIDE]
0126 orrne \rd, \rd, #(1 << 12)
0127 strne \rd, [\pmc_base, #PMC_PLLP_WB0_OVERRIDE]
0128 .endm
0129
0130 .macro pll_enable, rd, r_car_base, pll_base, pll_misc, test_mask
0131 test_pll_state \rd, \test_mask
0132 beq 1f
0133
0134 ldr \rd, [\r_car_base, #\pll_base]
0135 tst \rd, #(1 << 30)
0136 orreq \rd, \rd, #(1 << 30)
0137 streq \rd, [\r_car_base, #\pll_base]
0138
0139 .if \pll_misc
0140 ldr \rd, [\r_car_base, #\pll_misc]
0141 bic \rd, \rd, #(1 << 18)
0142 str \rd, [\r_car_base, #\pll_misc]
0143 ldr \rd, [\r_car_base, #\pll_misc]
0144 ldr \rd, [\r_car_base, #\pll_misc]
0145 orr \rd, \rd, #(1 << 18)
0146 str \rd, [\r_car_base, #\pll_misc]
0147 .endif
0148 1:
0149 .endm
0150
0151 .macro pll_locked, rd, r_car_base, pll_base, test_mask
0152 test_pll_state \rd, \test_mask
0153 beq 2f
0154 1:
0155 ldr \rd, [\r_car_base, #\pll_base]
0156 tst \rd, #(1 << 27)
0157 beq 1b
0158 2:
0159 .endm
0160
0161 .macro pll_iddq_exit, rd, car, iddq, iddq_bit
0162 ldr \rd, [\car, #\iddq]
0163 bic \rd, \rd, #(1<<\iddq_bit)
0164 str \rd, [\car, #\iddq]
0165 .endm
0166
0167 .macro pll_iddq_entry, rd, car, iddq, iddq_bit
0168 ldr \rd, [\car, #\iddq]
0169 orr \rd, \rd, #(1<<\iddq_bit)
0170 str \rd, [\car, #\iddq]
0171 .endm
0172
0173 #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
0174
0175
0176
0177
0178
0179
0180 ENTRY(tegra30_hotplug_shutdown)
0181
0182 mov r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN
0183 bl tegra30_cpu_shutdown
0184 ret lr @ should never get here
0185 ENDPROC(tegra30_hotplug_shutdown)
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 ENTRY(tegra30_cpu_shutdown)
0197 cpu_id r3
0198 tegra_get_soc_id TEGRA_APB_MISC_VIRT, r10
0199 cmp r10, #TEGRA30
0200 bne _no_cpu0_chk @ It's not Tegra30
0201
0202 cmp r3, #0
0203 reteq lr @ Must never be called for CPU 0
0204 _no_cpu0_chk:
0205
0206 ldr r12, =TEGRA_FLOW_CTRL_VIRT
0207 cpu_to_csr_reg r1, r3
0208 add r1, r1, r12 @ virtual CSR address for this CPU
0209 cpu_to_halt_reg r2, r3
0210 add r2, r2, r12 @ virtual HALT_EVENTS address for this CPU
0211
0212
0213
0214
0215
0216 movw r12, \
0217 FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | \
0218 FLOW_CTRL_CSR_ENABLE
0219 cmp r10, #TEGRA30
0220 moveq r4, #(1 << 4) @ wfe bitmap
0221 movne r4, #(1 << 8) @ wfi bitmap
0222 ARM( orr r12, r12, r4, lsl r3 )
0223 THUMB( lsl r4, r4, r3 )
0224 THUMB( orr r12, r12, r4 )
0225 str r12, [r1]
0226
0227
0228 mov r3, #0x400
0229 delay_1:
0230 subs r3, r3, #1 @ delay as a part of wfe war.
0231 bge delay_1;
0232 cpsid a @ disable imprecise aborts.
0233 ldr r3, [r1] @ read CSR
0234 str r3, [r1] @ clear CSR
0235
0236 tst r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN
0237 beq flow_ctrl_setting_for_lp2
0238
0239
0240 mov r3, #FLOW_CTRL_WAITEVENT @ For hotplug
0241 b flow_ctrl_done
0242 flow_ctrl_setting_for_lp2:
0243
0244 cmp r10, #TEGRA30
0245 moveq r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT @ For LP2
0246 movne r3, #FLOW_CTRL_WAITEVENT
0247 orrne r3, r3, #FLOW_CTRL_HALT_GIC_IRQ
0248 orrne r3, r3, #FLOW_CTRL_HALT_GIC_FIQ
0249 flow_ctrl_done:
0250 cmp r10, #TEGRA30
0251 str r3, [r2]
0252 ldr r0, [r2]
0253 b wfe_war
0254
0255 __cpu_reset_again:
0256 dsb
0257 .align 5
0258 wfeeq @ CPU should be power gated here
0259 wfine
0260 wfe_war:
0261 b __cpu_reset_again
0262
0263
0264
0265
0266
0267 .rept 38
0268 nop
0269 .endr
0270 b . @ should never get here
0271
0272 ENDPROC(tegra30_cpu_shutdown)
0273 #endif
0274
0275 #ifdef CONFIG_PM_SLEEP
0276
0277
0278
0279
0280
0281
0282 ENTRY(tegra30_sleep_core_finish)
0283 mov r4, r0
0284
0285 mov r0, #TEGRA_FLUSH_CACHE_ALL
0286 bl tegra_disable_clean_inv_dcache
0287 mov r0, r4
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297 mov32 r4, TEGRA_PMC_BASE
0298 mov32 r5, TEGRA_CLK_RESET_BASE
0299 mov32 r6, TEGRA_FLOW_CTRL_BASE
0300 mov32 r7, TEGRA_TMRUS_BASE
0301
0302 mov32 r3, tegra_shut_off_mmu
0303 add r3, r3, r0
0304
0305 mov32 r0, tegra30_tear_down_core
0306 mov32 r1, tegra30_iram_start
0307 sub r0, r0, r1
0308 mov32 r1, TEGRA_IRAM_LPx_RESUME_AREA
0309 add r0, r0, r1
0310
0311 ret r3
0312 ENDPROC(tegra30_sleep_core_finish)
0313
0314
0315
0316
0317
0318
0319 ENTRY(tegra30_pm_secondary_cpu_suspend)
0320 mov r7, lr
0321
0322
0323 mov r0, #TEGRA_FLUSH_CACHE_LOUIS
0324 bl tegra_disable_clean_inv_dcache
0325
0326
0327 mov r0, #0 @ power mode flags (!hotplug)
0328 bl tegra30_cpu_shutdown
0329 mov r0, #1 @ never return here
0330 ret r7
0331 ENDPROC(tegra30_pm_secondary_cpu_suspend)
0332
0333
0334
0335
0336
0337
0338 ENTRY(tegra30_tear_down_cpu)
0339 mov32 r6, TEGRA_FLOW_CTRL_BASE
0340
0341 b tegra30_enter_sleep
0342 ENDPROC(tegra30_tear_down_cpu)
0343
0344
0345 .align L1_CACHE_SHIFT
0346 .globl tegra30_iram_start
0347 tegra30_iram_start:
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362 ENTRY(tegra30_lp1_reset)
0363
0364
0365
0366
0367
0368 mov32 r0, TEGRA_CLK_RESET_BASE
0369
0370 mov r1, #(1 << 28)
0371 str r1, [r0, #CLK_RESET_SCLK_BURST]
0372 str r1, [r0, #CLK_RESET_CCLK_BURST]
0373 mov r1, #0
0374 str r1, [r0, #CLK_RESET_CCLK_DIVIDER]
0375 str r1, [r0, #CLK_RESET_SCLK_DIVIDER]
0376
0377 tegra_get_soc_id TEGRA_APB_MISC_BASE, r10
0378 cmp r10, #TEGRA30
0379 beq _no_pll_iddq_exit
0380
0381 pll_iddq_exit r1, r0, CLK_RESET_PLLM_MISC, CLK_RESET_PLLM_MISC_IDDQ
0382 pll_iddq_exit r1, r0, CLK_RESET_PLLC_MISC, CLK_RESET_PLLC_MISC_IDDQ
0383 pll_iddq_exit r1, r0, CLK_RESET_PLLX_MISC3, CLK_RESET_PLLX_MISC3_IDDQ
0384
0385 mov32 r7, TEGRA_TMRUS_BASE
0386 ldr r1, [r7]
0387 add r1, r1, #2
0388 wait_until r1, r7, r3
0389
0390
0391 mov32 r2, TEGRA_PMC_BASE
0392 pllm_pmc_enable r1, r2
0393
0394 pll_enable r1, r0, CLK_RESET_PLLM_BASE, 0, PLLM_STORE_MASK
0395 pll_enable r1, r0, CLK_RESET_PLLC_BASE, 0, PLLC_STORE_MASK
0396 pll_enable r1, r0, CLK_RESET_PLLX_BASE, 0, PLLX_STORE_MASK
0397
0398 b _pll_m_c_x_done
0399
0400 _no_pll_iddq_exit:
0401
0402 mov32 r2, TEGRA_PMC_BASE
0403 pllm_pmc_enable r1, r2
0404
0405 pll_enable r1, r0, CLK_RESET_PLLM_BASE, CLK_RESET_PLLM_MISC, PLLM_STORE_MASK
0406 pll_enable r1, r0, CLK_RESET_PLLC_BASE, CLK_RESET_PLLC_MISC, PLLC_STORE_MASK
0407
0408 _pll_m_c_x_done:
0409 pll_enable r1, r0, CLK_RESET_PLLP_BASE, CLK_RESET_PLLP_MISC, PLLP_STORE_MASK
0410 pll_enable r1, r0, CLK_RESET_PLLA_BASE, CLK_RESET_PLLA_MISC, PLLA_STORE_MASK
0411
0412 pll_locked r1, r0, CLK_RESET_PLLM_BASE, PLLM_STORE_MASK
0413 pll_locked r1, r0, CLK_RESET_PLLP_BASE, PLLP_STORE_MASK
0414 pll_locked r1, r0, CLK_RESET_PLLA_BASE, PLLA_STORE_MASK
0415 pll_locked r1, r0, CLK_RESET_PLLC_BASE, PLLC_STORE_MASK
0416
0417
0418
0419
0420
0421
0422 tegra_get_soc_id TEGRA_APB_MISC_BASE, r1
0423 cmp r1, #TEGRA30
0424 beq 1f
0425
0426 pll_locked r1, r0, CLK_RESET_PLLX_BASE, PLLX_STORE_MASK
0427
0428 ldr r1, [r0, #CLK_RESET_PLLP_BASE]
0429 bic r1, r1, #(1<<31) @ disable PllP bypass
0430 str r1, [r0, #CLK_RESET_PLLP_BASE]
0431
0432 mov r1, #CLK_RESET_PLLP_RESHIFT_DEFAULT
0433 str r1, [r0, #CLK_RESET_PLLP_RESHIFT]
0434 1:
0435
0436 mov32 r7, TEGRA_TMRUS_BASE
0437 ldr r1, [r7]
0438 add r1, r1, #LOCK_DELAY
0439 wait_until r1, r7, r3
0440
0441 adr r5, tegra_sdram_pad_save
0442
0443 ldr r4, [r5, #0x18] @ restore CLK_SOURCE_MSELECT
0444 str r4, [r0, #CLK_RESET_CLK_SOURCE_MSELECT]
0445
0446 ldr r4, [r5, #0x1C] @ restore SCLK_BURST
0447 str r4, [r0, #CLK_RESET_SCLK_BURST]
0448
0449 movw r4, #:lower16:((1 << 28) | (0x4)) @ burst policy is PLLP
0450 movt r4, #:upper16:((1 << 28) | (0x4))
0451 str r4, [r0, #CLK_RESET_CCLK_BURST]
0452
0453
0454 ldr r1, [r5, #0x14] @ PMC_IO_DPD_STATUS
0455 mvn r1, r1
0456 bic r1, r1, #(1 << 31)
0457 orr r1, r1, #(1 << 30)
0458 str r1, [r2, #PMC_IO_DPD_REQ] @ DPD_OFF
0459
0460 cmp r10, #TEGRA30
0461 movweq r0, #:lower16:TEGRA_EMC_BASE @ r0 reserved for emc base
0462 movteq r0, #:upper16:TEGRA_EMC_BASE
0463 cmp r10, #TEGRA114
0464 movweq r0, #:lower16:TEGRA_EMC0_BASE
0465 movteq r0, #:upper16:TEGRA_EMC0_BASE
0466 cmp r10, #TEGRA124
0467 movweq r0, #:lower16:TEGRA124_EMC_BASE
0468 movteq r0, #:upper16:TEGRA124_EMC_BASE
0469
0470 exit_self_refresh:
0471 ldr r1, [r5, #0xC] @ restore EMC_XM2VTTGENPADCTRL
0472 str r1, [r0, #EMC_XM2VTTGENPADCTRL]
0473 ldr r1, [r5, #0x10] @ restore EMC_XM2VTTGENPADCTRL2
0474 str r1, [r0, #EMC_XM2VTTGENPADCTRL2]
0475 ldr r1, [r5, #0x8] @ restore EMC_AUTO_CAL_INTERVAL
0476 str r1, [r0, #EMC_AUTO_CAL_INTERVAL]
0477
0478
0479 ldr r1, [r0, #EMC_CFG_DIG_DLL]
0480 orr r1, r1, #(1 << 30) @ set DLL_RESET
0481 str r1, [r0, #EMC_CFG_DIG_DLL]
0482
0483 emc_timing_update r1, r0
0484
0485 cmp r10, #TEGRA114
0486 movweq r1, #:lower16:TEGRA_EMC1_BASE
0487 movteq r1, #:upper16:TEGRA_EMC1_BASE
0488 cmpeq r0, r1
0489
0490 ldr r1, [r0, #EMC_AUTO_CAL_CONFIG]
0491 orr r1, r1, #(1 << 31) @ set AUTO_CAL_ACTIVE
0492 orreq r1, r1, #(1 << 27) @ set slave mode for channel 1
0493 str r1, [r0, #EMC_AUTO_CAL_CONFIG]
0494
0495 emc_wait_auto_cal_onetime:
0496 ldr r1, [r0, #EMC_AUTO_CAL_STATUS]
0497 tst r1, #(1 << 31) @ wait until AUTO_CAL_ACTIVE is cleared
0498 bne emc_wait_auto_cal_onetime
0499
0500 ldr r1, [r0, #EMC_CFG]
0501 bic r1, r1, #(1 << 31) @ disable DRAM_CLK_STOP_PD
0502 str r1, [r0, #EMC_CFG]
0503
0504 mov r1, #0
0505 str r1, [r0, #EMC_SELF_REF] @ take DRAM out of self refresh
0506 mov r1, #1
0507 cmp r10, #TEGRA30
0508 streq r1, [r0, #EMC_NOP]
0509 streq r1, [r0, #EMC_NOP]
0510
0511 emc_device_mask r1, r0
0512
0513 exit_selfrefresh_loop:
0514 ldr r2, [r0, #EMC_EMC_STATUS]
0515 ands r2, r2, r1
0516 bne exit_selfrefresh_loop
0517
0518 lsr r1, r1, #8 @ devSel, bit0:dev0, bit1:dev1
0519
0520 mov32 r7, TEGRA_TMRUS_BASE
0521 ldr r2, [r0, #EMC_FBIO_CFG5]
0522
0523 and r2, r2, #3 @ check DRAM_TYPE
0524 cmp r2, #2
0525 beq emc_lpddr2
0526
0527
0528 mov32 r2, 0x80000011 @ DEV_SELECTION=2, LENGTH=LONG, CMD=1
0529 str r2, [r0, #EMC_ZQ_CAL]
0530 ldr r2, [r7]
0531 add r2, r2, #10
0532 wait_until r2, r7, r3
0533
0534 tst r1, #2
0535 beq zcal_done
0536
0537
0538 mov32 r2, 0x40000011 @ DEV_SELECTION=1, LENGTH=LONG, CMD=1
0539 str r2, [r0, #EMC_ZQ_CAL]
0540 ldr r2, [r7]
0541 add r2, r2, #10
0542 wait_until r2, r7, r3
0543 b zcal_done
0544
0545 emc_lpddr2:
0546
0547 mov32 r2, 0x800A00AB @ DEV_SELECTION=2, MA=10, OP=0xAB
0548 str r2, [r0, #EMC_MRW]
0549 ldr r2, [r7]
0550 add r2, r2, #1
0551 wait_until r2, r7, r3
0552
0553 tst r1, #2
0554 beq zcal_done
0555
0556
0557 mov32 r2, 0x400A00AB @ DEV_SELECTION=1, MA=10, OP=0xAB
0558 str r2, [r0, #EMC_MRW]
0559 ldr r2, [r7]
0560 add r2, r2, #1
0561 wait_until r2, r7, r3
0562
0563 zcal_done:
0564 mov r1, #0 @ unstall all transactions
0565 str r1, [r0, #EMC_REQ_CTRL]
0566 ldr r1, [r5, #0x4] @ restore EMC_ZCAL_INTERVAL
0567 str r1, [r0, #EMC_ZCAL_INTERVAL]
0568 ldr r1, [r5, #0x0] @ restore EMC_CFG
0569 str r1, [r0, #EMC_CFG]
0570
0571 emc_timing_update r1, r0
0572
0573
0574 cmp r10, #TEGRA114
0575 bne __no_dual_emc_chanl
0576 mov32 r1, TEGRA_EMC1_BASE
0577 cmp r0, r1
0578 movne r0, r1
0579 addne r5, r5, #0x20
0580 bne exit_self_refresh
0581 __no_dual_emc_chanl:
0582
0583 mov32 r0, TEGRA_PMC_BASE
0584 ldr r0, [r0, #PMC_SCRATCH41]
0585 ret r0 @ jump to tegra_resume
0586 ENDPROC(tegra30_lp1_reset)
0587
0588 .align L1_CACHE_SHIFT
0589 tegra30_sdram_pad_address:
0590 .word TEGRA_EMC_BASE + EMC_CFG @0x0
0591 .word TEGRA_EMC_BASE + EMC_ZCAL_INTERVAL @0x4
0592 .word TEGRA_EMC_BASE + EMC_AUTO_CAL_INTERVAL @0x8
0593 .word TEGRA_EMC_BASE + EMC_XM2VTTGENPADCTRL @0xc
0594 .word TEGRA_EMC_BASE + EMC_XM2VTTGENPADCTRL2 @0x10
0595 .word TEGRA_PMC_BASE + PMC_IO_DPD_STATUS @0x14
0596 .word TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT @0x18
0597 .word TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST @0x1c
0598 tegra30_sdram_pad_address_end:
0599
0600 tegra114_sdram_pad_address:
0601 .word TEGRA_EMC0_BASE + EMC_CFG @0x0
0602 .word TEGRA_EMC0_BASE + EMC_ZCAL_INTERVAL @0x4
0603 .word TEGRA_EMC0_BASE + EMC_AUTO_CAL_INTERVAL @0x8
0604 .word TEGRA_EMC0_BASE + EMC_XM2VTTGENPADCTRL @0xc
0605 .word TEGRA_EMC0_BASE + EMC_XM2VTTGENPADCTRL2 @0x10
0606 .word TEGRA_PMC_BASE + PMC_IO_DPD_STATUS @0x14
0607 .word TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT @0x18
0608 .word TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST @0x1c
0609 .word TEGRA_EMC1_BASE + EMC_CFG @0x20
0610 .word TEGRA_EMC1_BASE + EMC_ZCAL_INTERVAL @0x24
0611 .word TEGRA_EMC1_BASE + EMC_AUTO_CAL_INTERVAL @0x28
0612 .word TEGRA_EMC1_BASE + EMC_XM2VTTGENPADCTRL @0x2c
0613 .word TEGRA_EMC1_BASE + EMC_XM2VTTGENPADCTRL2 @0x30
0614 tegra114_sdram_pad_adress_end:
0615
0616 tegra124_sdram_pad_address:
0617 .word TEGRA124_EMC_BASE + EMC_CFG @0x0
0618 .word TEGRA124_EMC_BASE + EMC_ZCAL_INTERVAL @0x4
0619 .word TEGRA124_EMC_BASE + EMC_AUTO_CAL_INTERVAL @0x8
0620 .word TEGRA124_EMC_BASE + EMC_XM2VTTGENPADCTRL @0xc
0621 .word TEGRA124_EMC_BASE + EMC_XM2VTTGENPADCTRL2 @0x10
0622 .word TEGRA_PMC_BASE + PMC_IO_DPD_STATUS @0x14
0623 .word TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT @0x18
0624 .word TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST @0x1c
0625 tegra124_sdram_pad_address_end:
0626
0627 tegra30_sdram_pad_size:
0628 .word tegra30_sdram_pad_address_end - tegra30_sdram_pad_address
0629
0630 tegra114_sdram_pad_size:
0631 .word tegra114_sdram_pad_adress_end - tegra114_sdram_pad_address
0632
0633 .type tegra_sdram_pad_save, %object
0634 tegra_sdram_pad_save:
0635 .rept (tegra114_sdram_pad_adress_end - tegra114_sdram_pad_address) / 4
0636 .long 0
0637 .endr
0638
0639 tegra_pll_state:
0640 .word 0x0
0641
0642
0643
0644
0645
0646
0647
0648 tegra30_tear_down_core:
0649 bl tegra30_sdram_self_refresh
0650 bl tegra30_switch_cpu_to_clk32k
0651 b tegra30_enter_sleep
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664 tegra30_switch_cpu_to_clk32k:
0665
0666
0667
0668
0669 mov r0, #(1 << 28)
0670 str r0, [r5, #CLK_RESET_SCLK_BURST]
0671
0672 ldr r1, [r7]
0673 add r1, r1, #2
0674 wait_until r1, r7, r9
0675 str r0, [r5, #CLK_RESET_CCLK_BURST]
0676 mov r0, #0
0677 str r0, [r5, #CLK_RESET_CCLK_DIVIDER]
0678 str r0, [r5, #CLK_RESET_SCLK_DIVIDER]
0679
0680
0681 ldr r0, [r5, #CLK_RESET_CLK_SOURCE_MSELECT]
0682 orr r0, r0, #MSELECT_CLKM
0683 str r0, [r5, #CLK_RESET_CLK_SOURCE_MSELECT]
0684
0685
0686 ldr r1, [r7]
0687 add r1, r1, #2
0688 wait_until r1, r7, r9
0689
0690
0691 store_pll_state r0, r1, r5, CLK_RESET_PLLA_BASE, PLLA_STORE_MASK
0692 store_pll_state r0, r1, r5, CLK_RESET_PLLC_BASE, PLLC_STORE_MASK
0693 store_pll_state r0, r1, r5, CLK_RESET_PLLM_BASE, PLLM_STORE_MASK
0694 store_pll_state r0, r1, r5, CLK_RESET_PLLP_BASE, PLLP_STORE_MASK
0695 store_pll_state r0, r1, r5, CLK_RESET_PLLX_BASE, PLLX_STORE_MASK
0696 store_pllm_pmc_state r0, r1, r4
0697
0698
0699 ldr r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
0700 bic r0, r0, #(1 << 12)
0701 str r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
0702
0703
0704 tegra_get_soc_id TEGRA_APB_MISC_BASE, r1
0705 cmp r1, #TEGRA30
0706 ldr r0, [r5, #CLK_RESET_PLLP_BASE]
0707 orrne r0, r0, #(1 << 31) @ enable PllP bypass on fast cluster
0708 bic r0, r0, #(1 << 30)
0709 str r0, [r5, #CLK_RESET_PLLP_BASE]
0710 beq 1f
0711 mov r0, #CLK_RESET_PLLP_RESHIFT_ENABLE
0712 str r0, [r5, #CLK_RESET_PLLP_RESHIFT]
0713 1:
0714 ldr r0, [r5, #CLK_RESET_PLLA_BASE]
0715 bic r0, r0, #(1 << 30)
0716 str r0, [r5, #CLK_RESET_PLLA_BASE]
0717 ldr r0, [r5, #CLK_RESET_PLLC_BASE]
0718 bic r0, r0, #(1 << 30)
0719 str r0, [r5, #CLK_RESET_PLLC_BASE]
0720 ldr r0, [r5, #CLK_RESET_PLLX_BASE]
0721 bic r0, r0, #(1 << 30)
0722 str r0, [r5, #CLK_RESET_PLLX_BASE]
0723
0724 cmp r10, #TEGRA30
0725 beq _no_pll_in_iddq
0726 pll_iddq_entry r1, r5, CLK_RESET_PLLX_MISC3, CLK_RESET_PLLX_MISC3_IDDQ
0727 _no_pll_in_iddq:
0728
0729
0730
0731
0732
0733
0734 mov r0, #(1 << 24)
0735 str r0, [r5, #CLK_RESET_SCLK_BURST]
0736
0737 ret lr
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747 tegra30_enter_sleep:
0748 cpu_id r1
0749
0750 cpu_to_csr_reg r2, r1
0751 ldr r0, [r6, r2]
0752 orr r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
0753 orr r0, r0, #FLOW_CTRL_CSR_ENABLE
0754 str r0, [r6, r2]
0755
0756 tegra_get_soc_id TEGRA_APB_MISC_BASE, r10
0757 cmp r10, #TEGRA30
0758 mov r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT
0759 orreq r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ
0760 orrne r0, r0, #FLOW_CTRL_HALT_LIC_IRQ | FLOW_CTRL_HALT_LIC_FIQ
0761
0762 cpu_to_halt_reg r2, r1
0763 str r0, [r6, r2]
0764 dsb
0765 ldr r0, [r6, r2]
0766
0767 cmp r10, #TEGRA30
0768 halted:
0769 isb
0770 dsb
0771 wfine
0772 wfeeq
0773
0774
0775 b halted
0776
0777
0778
0779
0780
0781
0782
0783
0784
0785
0786
0787
0788 tegra30_sdram_self_refresh:
0789
0790 adr r8, tegra_sdram_pad_save
0791 tegra_get_soc_id TEGRA_APB_MISC_BASE, r10
0792 cmp r10, #TEGRA30
0793 adreq r2, tegra30_sdram_pad_address
0794 ldreq r3, tegra30_sdram_pad_size
0795 cmp r10, #TEGRA114
0796 adreq r2, tegra114_sdram_pad_address
0797 ldreq r3, tegra114_sdram_pad_size
0798 cmp r10, #TEGRA124
0799 adreq r2, tegra124_sdram_pad_address
0800 ldreq r3, tegra30_sdram_pad_size
0801
0802 mov r9, #0
0803
0804 padsave:
0805 ldr r0, [r2, r9] @ r0 is the addr in the pad_address
0806
0807 ldr r1, [r0]
0808 str r1, [r8, r9] @ save the content of the addr
0809
0810 add r9, r9, #4
0811 cmp r3, r9
0812 bne padsave
0813 padsave_done:
0814
0815 dsb
0816
0817 cmp r10, #TEGRA30
0818 ldreq r0, =TEGRA_EMC_BASE @ r0 reserved for emc base addr
0819 cmp r10, #TEGRA114
0820 ldreq r0, =TEGRA_EMC0_BASE
0821 cmp r10, #TEGRA124
0822 ldreq r0, =TEGRA124_EMC_BASE
0823
0824 enter_self_refresh:
0825 cmp r10, #TEGRA30
0826 mov r1, #0
0827 str r1, [r0, #EMC_ZCAL_INTERVAL]
0828 str r1, [r0, #EMC_AUTO_CAL_INTERVAL]
0829 ldr r1, [r0, #EMC_CFG]
0830 bic r1, r1, #(1 << 28)
0831 bicne r1, r1, #(1 << 29)
0832 str r1, [r0, #EMC_CFG] @ disable DYN_SELF_REF
0833
0834 emc_timing_update r1, r0
0835
0836 ldr r1, [r7]
0837 add r1, r1, #5
0838 wait_until r1, r7, r2
0839
0840 emc_wait_auto_cal:
0841 ldr r1, [r0, #EMC_AUTO_CAL_STATUS]
0842 tst r1, #(1 << 31) @ wait until AUTO_CAL_ACTIVE is cleared
0843 bne emc_wait_auto_cal
0844
0845 mov r1, #3
0846 str r1, [r0, #EMC_REQ_CTRL] @ stall incoming DRAM requests
0847
0848 emcidle:
0849 ldr r1, [r0, #EMC_EMC_STATUS]
0850 tst r1, #4
0851 beq emcidle
0852
0853 mov r1, #1
0854 str r1, [r0, #EMC_SELF_REF]
0855
0856 emc_device_mask r1, r0
0857
0858 emcself:
0859 ldr r2, [r0, #EMC_EMC_STATUS]
0860 and r2, r2, r1
0861 cmp r2, r1
0862 bne emcself @ loop until DDR in self-refresh
0863
0864
0865 ldr r1, [r0, #EMC_XM2VTTGENPADCTRL]
0866 mov32 r2, 0xF8F8FFFF @ clear XM2VTTGEN_DRVUP and XM2VTTGEN_DRVDN
0867 and r1, r1, r2
0868 str r1, [r0, #EMC_XM2VTTGENPADCTRL]
0869 ldr r1, [r0, #EMC_XM2VTTGENPADCTRL2]
0870 cmp r10, #TEGRA30
0871 orreq r1, r1, #7 @ set E_NO_VTTGEN
0872 orrne r1, r1, #0x3f
0873 str r1, [r0, #EMC_XM2VTTGENPADCTRL2]
0874
0875 emc_timing_update r1, r0
0876
0877
0878 cmp r10, #TEGRA114
0879 bne no_dual_emc_chanl
0880 mov32 r1, TEGRA_EMC1_BASE
0881 cmp r0, r1
0882 movne r0, r1
0883 bne enter_self_refresh
0884 no_dual_emc_chanl:
0885
0886 ldr r1, [r4, #PMC_CTRL]
0887 tst r1, #PMC_CTRL_SIDE_EFFECT_LP0
0888 bne pmc_io_dpd_skip
0889
0890
0891
0892
0893 mov32 r1, 0x8EC00000
0894 str r1, [r4, #PMC_IO_DPD_REQ]
0895 pmc_io_dpd_skip:
0896
0897 dsb
0898
0899 ret lr
0900
0901 .ltorg
0902
0903 .align L1_CACHE_SHIFT
0904 .global tegra30_iram_end
0905 tegra30_iram_end:
0906 b .
0907 #endif