Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (c) 2012, NVIDIA Corporation. All rights reserved.
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) /* enter LP0 when CPU pwr gated */
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 /* safety delay after lock is detected */
0071 
0072 #define TEGRA30_POWER_HOTPLUG_SHUTDOWN  (1 << 27) /* Hotplug shutdown */
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     /* Enable lock detector */
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  * tegra30_hotplug_shutdown(void)
0176  *
0177  * Powergates the current CPU.
0178  * Should never return.
0179  */
0180 ENTRY(tegra30_hotplug_shutdown)
0181     /* Powergate this CPU */
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  * tegra30_cpu_shutdown(unsigned long flags)
0189  *
0190  * Puts the current CPU in wait-for-event mode on the flow controller
0191  * and powergates it -- flags (in R0) indicate the request type.
0192  *
0193  * r10 = SoC ID
0194  * corrupts r0-r4, r10-r12
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      * Clear this CPU's "event" and "interrupt" flags and power gate
0214      * it when halting but not before it is in the "WFE" state.
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     /* Halt this CPU. */
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     /* flow controller set up for hotplug */
0240     mov r3, #FLOW_CTRL_WAITEVENT        @ For hotplug
0241     b   flow_ctrl_done
0242 flow_ctrl_setting_for_lp2:
0243     /* flow controller set up for LP2 */
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      * 38 nop's, which fills rest of wfe cache line and
0265      * 4 more cachelines with nop
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  * tegra30_sleep_core_finish(unsigned long v2p)
0278  *
0279  * Enters suspend in LP0 or LP1 by turning off the MMU and jumping to
0280  * tegra30_tear_down_core in IRAM
0281  */
0282 ENTRY(tegra30_sleep_core_finish)
0283     mov r4, r0
0284     /* Flush, disable the L1 data cache and exit SMP */
0285     mov r0, #TEGRA_FLUSH_CACHE_ALL
0286     bl  tegra_disable_clean_inv_dcache
0287     mov r0, r4
0288 
0289     /*
0290      * Preload all the address literals that are needed for the
0291      * CPU power-gating process, to avoid loading from SDRAM which
0292      * are not supported once SDRAM is put into self-refresh.
0293      * LP0 / LP1 use physical address, since the MMU needs to be
0294      * disabled before putting SDRAM into self-refresh to avoid
0295      * memory access due to page table walks.
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  * tegra30_pm_secondary_cpu_suspend(unsigned long unused_arg)
0316  *
0317  * Enters LP2 on secondary CPU by exiting coherency and powergating the CPU.
0318  */
0319 ENTRY(tegra30_pm_secondary_cpu_suspend)
0320     mov r7, lr
0321 
0322     /* Flush and disable the L1 data cache */
0323     mov     r0, #TEGRA_FLUSH_CACHE_LOUIS
0324     bl  tegra_disable_clean_inv_dcache
0325 
0326     /* Powergate this CPU. */
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  * tegra30_tear_down_cpu
0335  *
0336  * Switches the CPU to enter sleep.
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 /* START OF ROUTINES COPIED TO IRAM */
0345     .align L1_CACHE_SHIFT
0346     .globl tegra30_iram_start
0347 tegra30_iram_start:
0348 
0349 /*
0350  * tegra30_lp1_reset
0351  *
0352  * reset vector for LP1 restore; copied into IRAM during suspend.
0353  * Brings the system back up to a safe staring point (SDRAM out of
0354  * self-refresh, PLLC, PLLM and PLLP reenabled, CPU running on PLLX,
0355  * system clock running on the same PLL that it suspended at), and
0356  * jumps to tegra_resume to restore virtual addressing.
0357  * The physical address of tegra_resume expected to be stored in
0358  * PMC_SCRATCH41.
0359  *
0360  * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_LPx_RESUME_AREA.
0361  */
0362 ENTRY(tegra30_lp1_reset)
0363     /*
0364      * The CPU and system bus are running at 32KHz and executing from
0365      * IRAM when this code is executed; immediately switch to CLKM and
0366      * enable PLLP, PLLM, PLLC, PLLA and PLLX.
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     /* enable PLLM via PMC */
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     /* enable PLLM via PMC */
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      * CPUFreq driver could select other PLL for CPU. PLLX will be
0419      * enabled by the Tegra30 CLK driver on an as-needed basis, see
0420      * tegra30_cpu_clock_resume().
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     /* Restore pad power state to normal */
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     /* Relock DLL */
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     /* Issue a ZQ_CAL for dev0 - DDR3 */
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     /* Issue a ZQ_CAL for dev1 - DDR3 */
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     /* Issue a ZQ_CAL for dev0 - LPDDR2 */
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     /* Issue a ZQ_CAL for dev0 - LPDDR2 */
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     /* Tegra114 had dual EMC channel, now config the other one */
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  * tegra30_tear_down_core
0644  *
0645  * copied into and executed from IRAM
0646  * puts memory in self-refresh for LP0 and LP1
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  * tegra30_switch_cpu_to_clk32k
0655  *
0656  * In LP0 and LP1 all PLLs will be turned off. Switching the CPU and System CLK
0657  * to the 32KHz clock.
0658  * r4 = TEGRA_PMC_BASE
0659  * r5 = TEGRA_CLK_RESET_BASE
0660  * r6 = TEGRA_FLOW_CTRL_BASE
0661  * r7 = TEGRA_TMRUS_BASE
0662  * r10= SoC ID
0663  */
0664 tegra30_switch_cpu_to_clk32k:
0665     /*
0666      * start by jumping to CLKM to safely disable PLLs, then jump to
0667      * CLKS.
0668      */
0669     mov r0, #(1 << 28)
0670     str r0, [r5, #CLK_RESET_SCLK_BURST]
0671     /* 2uS delay delay between changing SCLK and CCLK */
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     /* switch the clock source of mselect to be CLK_M */
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     /* 2uS delay delay between changing SCLK and disabling PLLs */
0686     ldr r1, [r7]
0687     add r1, r1, #2
0688     wait_until r1, r7, r9
0689 
0690     /* store enable-state of PLLs */
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     /* disable PLLM via PMC in LP1 */
0699     ldr r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
0700     bic r0, r0, #(1 << 12)
0701     str r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
0702 
0703     /* disable PLLP, PLLA, PLLC and PLLX */
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      * Switch to clk_s (32KHz); bits 28:31=0
0731      * Enable burst on CPU IRQ; bit 24=1
0732      * Set IRQ burst clock source to clk_m; bits 10:8=0
0733      */
0734     mov r0, #(1 << 24)
0735     str r0, [r5, #CLK_RESET_SCLK_BURST]
0736 
0737     ret lr
0738 
0739 /*
0740  * tegra30_enter_sleep
0741  *
0742  * uses flow controller to enter sleep state
0743  * executes from IRAM with SDRAM in selfrefresh when target state is LP0 or LP1
0744  * executes from SDRAM with target state is LP2
0745  * r6 = TEGRA_FLOW_CTRL_BASE
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] /* memory barrier */
0766 
0767     cmp r10, #TEGRA30
0768 halted:
0769     isb
0770     dsb
0771     wfine   /* CPU should be power gated here */
0772     wfeeq
0773 
0774     /* !!!FIXME!!! Implement halt failure handler */
0775     b   halted
0776 
0777 /*
0778  * tegra30_sdram_self_refresh
0779  *
0780  * called with MMU off and caches disabled
0781  * must be executed from IRAM
0782  * r4 = TEGRA_PMC_BASE
0783  * r5 = TEGRA_CLK_RESET_BASE
0784  * r6 = TEGRA_FLOW_CTRL_BASE
0785  * r7 = TEGRA_TMRUS_BASE
0786  * r10= SoC ID
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     /* Put VTTGEN in the lowest power mode */
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     /* Tegra114 had dual EMC channel, now config the other one */
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      * Put DDR_DATA, DISC_ADDR_CMD, DDR_ADDR_CMD, POP_ADDR_CMD, POP_CLK
0891      * and COMP in the lowest power mode when LP1.
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 /* dummy symbol for end of IRAM */
0903     .align L1_CACHE_SHIFT
0904     .global tegra30_iram_end
0905 tegra30_iram_end:
0906     b   .
0907 #endif