linux/arch/arm/mach-tegra/sleep-tegra30.S
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2012, NVIDIA Corporation. All rights reserved.
   3 *
   4 * This program is free software; you can redistribute it and/or modify it
   5 * under the terms and conditions of the GNU General Public License,
   6 * version 2, as published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope it will be useful, but WITHOUT
   9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  11 * more details.
  12 *
  13 * You should have received a copy of the GNU General Public License
  14 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  15 */
  16
  17#include <linux/linkage.h>
  18
  19#include <soc/tegra/fuse.h>
  20
  21#include <asm/asm-offsets.h>
  22#include <asm/assembler.h>
  23#include <asm/cache.h>
  24
  25#include "flowctrl.h"
  26#include "irammap.h"
  27#include "sleep.h"
  28
  29#define EMC_CFG                         0xc
  30#define EMC_ADR_CFG                     0x10
  31#define EMC_TIMING_CONTROL              0x28
  32#define EMC_REFRESH                     0x70
  33#define EMC_NOP                         0xdc
  34#define EMC_SELF_REF                    0xe0
  35#define EMC_MRW                         0xe8
  36#define EMC_FBIO_CFG5                   0x104
  37#define EMC_AUTO_CAL_CONFIG             0x2a4
  38#define EMC_AUTO_CAL_INTERVAL           0x2a8
  39#define EMC_AUTO_CAL_STATUS             0x2ac
  40#define EMC_REQ_CTRL                    0x2b0
  41#define EMC_CFG_DIG_DLL                 0x2bc
  42#define EMC_EMC_STATUS                  0x2b4
  43#define EMC_ZCAL_INTERVAL               0x2e0
  44#define EMC_ZQ_CAL                      0x2ec
  45#define EMC_XM2VTTGENPADCTRL            0x310
  46#define EMC_XM2VTTGENPADCTRL2           0x314
  47
  48#define PMC_CTRL                        0x0
  49#define PMC_CTRL_SIDE_EFFECT_LP0 (1 << 14) /* enter LP0 when CPU pwr gated */
  50
  51#define PMC_PLLP_WB0_OVERRIDE           0xf8
  52#define PMC_IO_DPD_REQ                  0x1b8
  53#define PMC_IO_DPD_STATUS               0x1bc
  54
  55#define CLK_RESET_CCLK_BURST            0x20
  56#define CLK_RESET_CCLK_DIVIDER          0x24
  57#define CLK_RESET_SCLK_BURST            0x28
  58#define CLK_RESET_SCLK_DIVIDER          0x2c
  59
  60#define CLK_RESET_PLLC_BASE             0x80
  61#define CLK_RESET_PLLC_MISC             0x8c
  62#define CLK_RESET_PLLM_BASE             0x90
  63#define CLK_RESET_PLLM_MISC             0x9c
  64#define CLK_RESET_PLLP_BASE             0xa0
  65#define CLK_RESET_PLLP_MISC             0xac
  66#define CLK_RESET_PLLA_BASE             0xb0
  67#define CLK_RESET_PLLA_MISC             0xbc
  68#define CLK_RESET_PLLX_BASE             0xe0
  69#define CLK_RESET_PLLX_MISC             0xe4
  70#define CLK_RESET_PLLX_MISC3            0x518
  71#define CLK_RESET_PLLX_MISC3_IDDQ       3
  72#define CLK_RESET_PLLM_MISC_IDDQ        5
  73#define CLK_RESET_PLLC_MISC_IDDQ        26
  74
  75#define CLK_RESET_CLK_SOURCE_MSELECT    0x3b4
  76
  77#define MSELECT_CLKM                    (0x3 << 30)
  78
  79#define LOCK_DELAY 50 /* safety delay after lock is detected */
  80
  81#define TEGRA30_POWER_HOTPLUG_SHUTDOWN  (1 << 27) /* Hotplug shutdown */
  82
  83.macro emc_device_mask, rd, base
  84        ldr     \rd, [\base, #EMC_ADR_CFG]
  85        tst     \rd, #0x1
  86        moveq   \rd, #(0x1 << 8)                @ just 1 device
  87        movne   \rd, #(0x3 << 8)                @ 2 devices
  88.endm
  89
  90.macro emc_timing_update, rd, base
  91        mov     \rd, #1
  92        str     \rd, [\base, #EMC_TIMING_CONTROL]
  931001:
  94        ldr     \rd, [\base, #EMC_EMC_STATUS]
  95        tst     \rd, #(0x1<<23) @ wait EMC_STATUS_TIMING_UPDATE_STALLED is clear
  96        bne     1001b
  97.endm
  98
  99.macro pll_enable, rd, r_car_base, pll_base, pll_misc
 100        ldr     \rd, [\r_car_base, #\pll_base]
 101        tst     \rd, #(1 << 30)
 102        orreq   \rd, \rd, #(1 << 30)
 103        streq   \rd, [\r_car_base, #\pll_base]
 104        /* Enable lock detector */
 105        .if     \pll_misc
 106        ldr     \rd, [\r_car_base, #\pll_misc]
 107        bic     \rd, \rd, #(1 << 18)
 108        str     \rd, [\r_car_base, #\pll_misc]
 109        ldr     \rd, [\r_car_base, #\pll_misc]
 110        ldr     \rd, [\r_car_base, #\pll_misc]
 111        orr     \rd, \rd, #(1 << 18)
 112        str     \rd, [\r_car_base, #\pll_misc]
 113        .endif
 114.endm
 115
 116.macro pll_locked, rd, r_car_base, pll_base
 1171:
 118        ldr     \rd, [\r_car_base, #\pll_base]
 119        tst     \rd, #(1 << 27)
 120        beq     1b
 121.endm
 122
 123.macro pll_iddq_exit, rd, car, iddq, iddq_bit
 124        ldr     \rd, [\car, #\iddq]
 125        bic     \rd, \rd, #(1<<\iddq_bit)
 126        str     \rd, [\car, #\iddq]
 127.endm
 128
 129.macro pll_iddq_entry, rd, car, iddq, iddq_bit
 130        ldr     \rd, [\car, #\iddq]
 131        orr     \rd, \rd, #(1<<\iddq_bit)
 132        str     \rd, [\car, #\iddq]
 133.endm
 134
 135#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
 136/*
 137 * tegra30_hotplug_shutdown(void)
 138 *
 139 * Powergates the current CPU.
 140 * Should never return.
 141 */
 142ENTRY(tegra30_hotplug_shutdown)
 143        /* Powergate this CPU */
 144        mov     r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN
 145        bl      tegra30_cpu_shutdown
 146        ret     lr                      @ should never get here
 147ENDPROC(tegra30_hotplug_shutdown)
 148
 149/*
 150 * tegra30_cpu_shutdown(unsigned long flags)
 151 *
 152 * Puts the current CPU in wait-for-event mode on the flow controller
 153 * and powergates it -- flags (in R0) indicate the request type.
 154 *
 155 * r10 = SoC ID
 156 * corrupts r0-r4, r10-r12
 157 */
 158ENTRY(tegra30_cpu_shutdown)
 159        cpu_id  r3
 160        tegra_get_soc_id TEGRA_APB_MISC_VIRT, r10
 161        cmp     r10, #TEGRA30
 162        bne     _no_cpu0_chk    @ It's not Tegra30
 163
 164        cmp     r3, #0
 165        reteq   lr              @ Must never be called for CPU 0
 166_no_cpu0_chk:
 167
 168        ldr     r12, =TEGRA_FLOW_CTRL_VIRT
 169        cpu_to_csr_reg r1, r3
 170        add     r1, r1, r12     @ virtual CSR address for this CPU
 171        cpu_to_halt_reg r2, r3
 172        add     r2, r2, r12     @ virtual HALT_EVENTS address for this CPU
 173
 174        /*
 175         * Clear this CPU's "event" and "interrupt" flags and power gate
 176         * it when halting but not before it is in the "WFE" state.
 177         */
 178        movw    r12, \
 179                FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | \
 180                FLOW_CTRL_CSR_ENABLE
 181        cmp     r10, #TEGRA30
 182        moveq   r4, #(1 << 4)                   @ wfe bitmap
 183        movne   r4, #(1 << 8)                   @ wfi bitmap
 184 ARM(   orr     r12, r12, r4, lsl r3    )
 185 THUMB( lsl     r4, r4, r3              )
 186 THUMB( orr     r12, r12, r4            )
 187        str     r12, [r1]
 188
 189        /* Halt this CPU. */
 190        mov     r3, #0x400
 191delay_1:
 192        subs    r3, r3, #1                      @ delay as a part of wfe war.
 193        bge     delay_1;
 194        cpsid   a                               @ disable imprecise aborts.
 195        ldr     r3, [r1]                        @ read CSR
 196        str     r3, [r1]                        @ clear CSR
 197
 198        tst     r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN
 199        beq     flow_ctrl_setting_for_lp2
 200
 201        /* flow controller set up for hotplug */
 202        mov     r3, #FLOW_CTRL_WAITEVENT                @ For hotplug
 203        b       flow_ctrl_done
 204flow_ctrl_setting_for_lp2:
 205        /* flow controller set up for LP2 */
 206        cmp     r10, #TEGRA30
 207        moveq   r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT       @ For LP2
 208        movne   r3, #FLOW_CTRL_WAITEVENT
 209        orrne   r3, r3, #FLOW_CTRL_HALT_GIC_IRQ
 210        orrne   r3, r3, #FLOW_CTRL_HALT_GIC_FIQ
 211flow_ctrl_done:
 212        cmp     r10, #TEGRA30
 213        str     r3, [r2]
 214        ldr     r0, [r2]
 215        b       wfe_war
 216
 217__cpu_reset_again:
 218        dsb
 219        .align 5
 220        wfeeq                                   @ CPU should be power gated here
 221        wfine
 222wfe_war:
 223        b       __cpu_reset_again
 224
 225        /*
 226         * 38 nop's, which fills rest of wfe cache line and
 227         * 4 more cachelines with nop
 228         */
 229        .rept 38
 230        nop
 231        .endr
 232        b       .                               @ should never get here
 233
 234ENDPROC(tegra30_cpu_shutdown)
 235#endif
 236
 237#ifdef CONFIG_PM_SLEEP
 238/*
 239 * tegra30_sleep_core_finish(unsigned long v2p)
 240 *
 241 * Enters suspend in LP0 or LP1 by turning off the MMU and jumping to
 242 * tegra30_tear_down_core in IRAM
 243 */
 244ENTRY(tegra30_sleep_core_finish)
 245        mov     r4, r0
 246        /* Flush, disable the L1 data cache and exit SMP */
 247        mov     r0, #TEGRA_FLUSH_CACHE_ALL
 248        bl      tegra_disable_clean_inv_dcache
 249        mov     r0, r4
 250
 251        /*
 252         * Preload all the address literals that are needed for the
 253         * CPU power-gating process, to avoid loading from SDRAM which
 254         * are not supported once SDRAM is put into self-refresh.
 255         * LP0 / LP1 use physical address, since the MMU needs to be
 256         * disabled before putting SDRAM into self-refresh to avoid
 257         * memory access due to page table walks.
 258         */
 259        mov32   r4, TEGRA_PMC_BASE
 260        mov32   r5, TEGRA_CLK_RESET_BASE
 261        mov32   r6, TEGRA_FLOW_CTRL_BASE
 262        mov32   r7, TEGRA_TMRUS_BASE
 263
 264        mov32   r3, tegra_shut_off_mmu
 265        add     r3, r3, r0
 266
 267        mov32   r0, tegra30_tear_down_core
 268        mov32   r1, tegra30_iram_start
 269        sub     r0, r0, r1
 270        mov32   r1, TEGRA_IRAM_LPx_RESUME_AREA
 271        add     r0, r0, r1
 272
 273        ret     r3
 274ENDPROC(tegra30_sleep_core_finish)
 275
 276/*
 277 * tegra30_sleep_cpu_secondary_finish(unsigned long v2p)
 278 *
 279 * Enters LP2 on secondary CPU by exiting coherency and powergating the CPU.
 280 */
 281ENTRY(tegra30_sleep_cpu_secondary_finish)
 282        mov     r7, lr
 283
 284        /* Flush and disable the L1 data cache */
 285        mov     r0, #TEGRA_FLUSH_CACHE_LOUIS
 286        bl      tegra_disable_clean_inv_dcache
 287
 288        /* Powergate this CPU. */
 289        mov     r0, #0                          @ power mode flags (!hotplug)
 290        bl      tegra30_cpu_shutdown
 291        mov     r0, #1                          @ never return here
 292        ret     r7
 293ENDPROC(tegra30_sleep_cpu_secondary_finish)
 294
 295/*
 296 * tegra30_tear_down_cpu
 297 *
 298 * Switches the CPU to enter sleep.
 299 */
 300ENTRY(tegra30_tear_down_cpu)
 301        mov32   r6, TEGRA_FLOW_CTRL_BASE
 302
 303        b       tegra30_enter_sleep
 304ENDPROC(tegra30_tear_down_cpu)
 305
 306/* START OF ROUTINES COPIED TO IRAM */
 307        .align L1_CACHE_SHIFT
 308        .globl tegra30_iram_start
 309tegra30_iram_start:
 310
 311/*
 312 * tegra30_lp1_reset
 313 *
 314 * reset vector for LP1 restore; copied into IRAM during suspend.
 315 * Brings the system back up to a safe staring point (SDRAM out of
 316 * self-refresh, PLLC, PLLM and PLLP reenabled, CPU running on PLLX,
 317 * system clock running on the same PLL that it suspended at), and
 318 * jumps to tegra_resume to restore virtual addressing.
 319 * The physical address of tegra_resume expected to be stored in
 320 * PMC_SCRATCH41.
 321 *
 322 * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_LPx_RESUME_AREA.
 323 */
 324ENTRY(tegra30_lp1_reset)
 325        /*
 326         * The CPU and system bus are running at 32KHz and executing from
 327         * IRAM when this code is executed; immediately switch to CLKM and
 328         * enable PLLP, PLLM, PLLC, PLLA and PLLX.
 329         */
 330        mov32   r0, TEGRA_CLK_RESET_BASE
 331
 332        mov     r1, #(1 << 28)
 333        str     r1, [r0, #CLK_RESET_SCLK_BURST]
 334        str     r1, [r0, #CLK_RESET_CCLK_BURST]
 335        mov     r1, #0
 336        str     r1, [r0, #CLK_RESET_CCLK_DIVIDER]
 337        str     r1, [r0, #CLK_RESET_SCLK_DIVIDER]
 338
 339        tegra_get_soc_id TEGRA_APB_MISC_BASE, r10
 340        cmp     r10, #TEGRA30
 341        beq     _no_pll_iddq_exit
 342
 343        pll_iddq_exit r1, r0, CLK_RESET_PLLM_MISC, CLK_RESET_PLLM_MISC_IDDQ
 344        pll_iddq_exit r1, r0, CLK_RESET_PLLC_MISC, CLK_RESET_PLLC_MISC_IDDQ
 345        pll_iddq_exit r1, r0, CLK_RESET_PLLX_MISC3, CLK_RESET_PLLX_MISC3_IDDQ
 346
 347        mov32   r7, TEGRA_TMRUS_BASE
 348        ldr     r1, [r7]
 349        add     r1, r1, #2
 350        wait_until r1, r7, r3
 351
 352        /* enable PLLM via PMC */
 353        mov32   r2, TEGRA_PMC_BASE
 354        ldr     r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
 355        orr     r1, r1, #(1 << 12)
 356        str     r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
 357
 358        pll_enable r1, r0, CLK_RESET_PLLM_BASE, 0
 359        pll_enable r1, r0, CLK_RESET_PLLC_BASE, 0
 360        pll_enable r1, r0, CLK_RESET_PLLX_BASE, 0
 361
 362        b       _pll_m_c_x_done
 363
 364_no_pll_iddq_exit:
 365        /* enable PLLM via PMC */
 366        mov32   r2, TEGRA_PMC_BASE
 367        ldr     r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
 368        orr     r1, r1, #(1 << 12)
 369        str     r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
 370
 371        pll_enable r1, r0, CLK_RESET_PLLM_BASE, CLK_RESET_PLLM_MISC
 372        pll_enable r1, r0, CLK_RESET_PLLC_BASE, CLK_RESET_PLLC_MISC
 373        pll_enable r1, r0, CLK_RESET_PLLX_BASE, CLK_RESET_PLLX_MISC
 374
 375_pll_m_c_x_done:
 376        pll_enable r1, r0, CLK_RESET_PLLP_BASE, CLK_RESET_PLLP_MISC
 377        pll_enable r1, r0, CLK_RESET_PLLA_BASE, CLK_RESET_PLLA_MISC
 378
 379        pll_locked r1, r0, CLK_RESET_PLLM_BASE
 380        pll_locked r1, r0, CLK_RESET_PLLP_BASE
 381        pll_locked r1, r0, CLK_RESET_PLLA_BASE
 382        pll_locked r1, r0, CLK_RESET_PLLC_BASE
 383        pll_locked r1, r0, CLK_RESET_PLLX_BASE
 384
 385        mov32   r7, TEGRA_TMRUS_BASE
 386        ldr     r1, [r7]
 387        add     r1, r1, #LOCK_DELAY
 388        wait_until r1, r7, r3
 389
 390        adr     r5, tegra_sdram_pad_save
 391
 392        ldr     r4, [r5, #0x18]         @ restore CLK_SOURCE_MSELECT
 393        str     r4, [r0, #CLK_RESET_CLK_SOURCE_MSELECT]
 394
 395        ldr     r4, [r5, #0x1C]         @ restore SCLK_BURST
 396        str     r4, [r0, #CLK_RESET_SCLK_BURST]
 397
 398        cmp     r10, #TEGRA30
 399        movweq  r4, #:lower16:((1 << 28) | (0x8))       @ burst policy is PLLX
 400        movteq  r4, #:upper16:((1 << 28) | (0x8))
 401        movwne  r4, #:lower16:((1 << 28) | (0xe))
 402        movtne  r4, #:upper16:((1 << 28) | (0xe))
 403        str     r4, [r0, #CLK_RESET_CCLK_BURST]
 404
 405        /* Restore pad power state to normal */
 406        ldr     r1, [r5, #0x14]         @ PMC_IO_DPD_STATUS
 407        mvn     r1, r1
 408        bic     r1, r1, #(1 << 31)
 409        orr     r1, r1, #(1 << 30)
 410        str     r1, [r2, #PMC_IO_DPD_REQ]       @ DPD_OFF
 411
 412        cmp     r10, #TEGRA30
 413        movweq  r0, #:lower16:TEGRA_EMC_BASE    @ r0 reserved for emc base
 414        movteq  r0, #:upper16:TEGRA_EMC_BASE
 415        cmp     r10, #TEGRA114
 416        movweq  r0, #:lower16:TEGRA_EMC0_BASE
 417        movteq  r0, #:upper16:TEGRA_EMC0_BASE
 418        cmp     r10, #TEGRA124
 419        movweq  r0, #:lower16:TEGRA124_EMC_BASE
 420        movteq  r0, #:upper16:TEGRA124_EMC_BASE
 421
 422exit_self_refresh:
 423        ldr     r1, [r5, #0xC]          @ restore EMC_XM2VTTGENPADCTRL
 424        str     r1, [r0, #EMC_XM2VTTGENPADCTRL]
 425        ldr     r1, [r5, #0x10]         @ restore EMC_XM2VTTGENPADCTRL2
 426        str     r1, [r0, #EMC_XM2VTTGENPADCTRL2]
 427        ldr     r1, [r5, #0x8]          @ restore EMC_AUTO_CAL_INTERVAL
 428        str     r1, [r0, #EMC_AUTO_CAL_INTERVAL]
 429
 430        /* Relock DLL */
 431        ldr     r1, [r0, #EMC_CFG_DIG_DLL]
 432        orr     r1, r1, #(1 << 30)      @ set DLL_RESET
 433        str     r1, [r0, #EMC_CFG_DIG_DLL]
 434
 435        emc_timing_update r1, r0
 436
 437        cmp     r10, #TEGRA114
 438        movweq  r1, #:lower16:TEGRA_EMC1_BASE
 439        movteq  r1, #:upper16:TEGRA_EMC1_BASE
 440        cmpeq   r0, r1
 441
 442        ldr     r1, [r0, #EMC_AUTO_CAL_CONFIG]
 443        orr     r1, r1, #(1 << 31)      @ set AUTO_CAL_ACTIVE
 444        orreq   r1, r1, #(1 << 27)      @ set slave mode for channel 1
 445        str     r1, [r0, #EMC_AUTO_CAL_CONFIG]
 446
 447emc_wait_auto_cal_onetime:
 448        ldr     r1, [r0, #EMC_AUTO_CAL_STATUS]
 449        tst     r1, #(1 << 31)          @ wait until AUTO_CAL_ACTIVE is cleared
 450        bne     emc_wait_auto_cal_onetime
 451
 452        ldr     r1, [r0, #EMC_CFG]
 453        bic     r1, r1, #(1 << 31)      @ disable DRAM_CLK_STOP_PD
 454        str     r1, [r0, #EMC_CFG]
 455
 456        mov     r1, #0
 457        str     r1, [r0, #EMC_SELF_REF] @ take DRAM out of self refresh
 458        mov     r1, #1
 459        cmp     r10, #TEGRA30
 460        streq   r1, [r0, #EMC_NOP]
 461        streq   r1, [r0, #EMC_NOP]
 462        streq   r1, [r0, #EMC_REFRESH]
 463
 464        emc_device_mask r1, r0
 465
 466exit_selfrefresh_loop:
 467        ldr     r2, [r0, #EMC_EMC_STATUS]
 468        ands    r2, r2, r1
 469        bne     exit_selfrefresh_loop
 470
 471        lsr     r1, r1, #8              @ devSel, bit0:dev0, bit1:dev1
 472
 473        mov32   r7, TEGRA_TMRUS_BASE
 474        ldr     r2, [r0, #EMC_FBIO_CFG5]
 475
 476        and     r2, r2, #3              @ check DRAM_TYPE
 477        cmp     r2, #2
 478        beq     emc_lpddr2
 479
 480        /* Issue a ZQ_CAL for dev0 - DDR3 */
 481        mov32   r2, 0x80000011          @ DEV_SELECTION=2, LENGTH=LONG, CMD=1
 482        str     r2, [r0, #EMC_ZQ_CAL]
 483        ldr     r2, [r7]
 484        add     r2, r2, #10
 485        wait_until r2, r7, r3
 486
 487        tst     r1, #2
 488        beq     zcal_done
 489
 490        /* Issue a ZQ_CAL for dev1 - DDR3 */
 491        mov32   r2, 0x40000011          @ DEV_SELECTION=1, LENGTH=LONG, CMD=1
 492        str     r2, [r0, #EMC_ZQ_CAL]
 493        ldr     r2, [r7]
 494        add     r2, r2, #10
 495        wait_until r2, r7, r3
 496        b       zcal_done
 497
 498emc_lpddr2:
 499        /* Issue a ZQ_CAL for dev0 - LPDDR2 */
 500        mov32   r2, 0x800A00AB          @ DEV_SELECTION=2, MA=10, OP=0xAB
 501        str     r2, [r0, #EMC_MRW]
 502        ldr     r2, [r7]
 503        add     r2, r2, #1
 504        wait_until r2, r7, r3
 505
 506        tst     r1, #2
 507        beq     zcal_done
 508
 509        /* Issue a ZQ_CAL for dev0 - LPDDR2 */
 510        mov32   r2, 0x400A00AB          @ DEV_SELECTION=1, MA=10, OP=0xAB
 511        str     r2, [r0, #EMC_MRW]
 512        ldr     r2, [r7]
 513        add     r2, r2, #1
 514        wait_until r2, r7, r3
 515
 516zcal_done:
 517        mov     r1, #0                  @ unstall all transactions
 518        str     r1, [r0, #EMC_REQ_CTRL]
 519        ldr     r1, [r5, #0x4]          @ restore EMC_ZCAL_INTERVAL
 520        str     r1, [r0, #EMC_ZCAL_INTERVAL]
 521        ldr     r1, [r5, #0x0]          @ restore EMC_CFG
 522        str     r1, [r0, #EMC_CFG]
 523
 524        /* Tegra114 had dual EMC channel, now config the other one */
 525        cmp     r10, #TEGRA114
 526        bne     __no_dual_emc_chanl
 527        mov32   r1, TEGRA_EMC1_BASE
 528        cmp     r0, r1
 529        movne   r0, r1
 530        addne   r5, r5, #0x20
 531        bne     exit_self_refresh
 532__no_dual_emc_chanl:
 533
 534        mov32   r0, TEGRA_PMC_BASE
 535        ldr     r0, [r0, #PMC_SCRATCH41]
 536        ret     r0                      @ jump to tegra_resume
 537ENDPROC(tegra30_lp1_reset)
 538
 539        .align  L1_CACHE_SHIFT
 540tegra30_sdram_pad_address:
 541        .word   TEGRA_EMC_BASE + EMC_CFG                                @0x0
 542        .word   TEGRA_EMC_BASE + EMC_ZCAL_INTERVAL                      @0x4
 543        .word   TEGRA_EMC_BASE + EMC_AUTO_CAL_INTERVAL                  @0x8
 544        .word   TEGRA_EMC_BASE + EMC_XM2VTTGENPADCTRL                   @0xc
 545        .word   TEGRA_EMC_BASE + EMC_XM2VTTGENPADCTRL2                  @0x10
 546        .word   TEGRA_PMC_BASE + PMC_IO_DPD_STATUS                      @0x14
 547        .word   TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT     @0x18
 548        .word   TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST             @0x1c
 549tegra30_sdram_pad_address_end:
 550
 551tegra114_sdram_pad_address:
 552        .word   TEGRA_EMC0_BASE + EMC_CFG                               @0x0
 553        .word   TEGRA_EMC0_BASE + EMC_ZCAL_INTERVAL                     @0x4
 554        .word   TEGRA_EMC0_BASE + EMC_AUTO_CAL_INTERVAL                 @0x8
 555        .word   TEGRA_EMC0_BASE + EMC_XM2VTTGENPADCTRL                  @0xc
 556        .word   TEGRA_EMC0_BASE + EMC_XM2VTTGENPADCTRL2                 @0x10
 557        .word   TEGRA_PMC_BASE + PMC_IO_DPD_STATUS                      @0x14
 558        .word   TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT     @0x18
 559        .word   TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST             @0x1c
 560        .word   TEGRA_EMC1_BASE + EMC_CFG                               @0x20
 561        .word   TEGRA_EMC1_BASE + EMC_ZCAL_INTERVAL                     @0x24
 562        .word   TEGRA_EMC1_BASE + EMC_AUTO_CAL_INTERVAL                 @0x28
 563        .word   TEGRA_EMC1_BASE + EMC_XM2VTTGENPADCTRL                  @0x2c
 564        .word   TEGRA_EMC1_BASE + EMC_XM2VTTGENPADCTRL2                 @0x30
 565tegra114_sdram_pad_adress_end:
 566
 567tegra124_sdram_pad_address:
 568        .word   TEGRA124_EMC_BASE + EMC_CFG                             @0x0
 569        .word   TEGRA124_EMC_BASE + EMC_ZCAL_INTERVAL                   @0x4
 570        .word   TEGRA124_EMC_BASE + EMC_AUTO_CAL_INTERVAL               @0x8
 571        .word   TEGRA124_EMC_BASE + EMC_XM2VTTGENPADCTRL                @0xc
 572        .word   TEGRA124_EMC_BASE + EMC_XM2VTTGENPADCTRL2               @0x10
 573        .word   TEGRA_PMC_BASE + PMC_IO_DPD_STATUS                      @0x14
 574        .word   TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT     @0x18
 575        .word   TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST             @0x1c
 576tegra124_sdram_pad_address_end:
 577
 578tegra30_sdram_pad_size:
 579        .word   tegra30_sdram_pad_address_end - tegra30_sdram_pad_address
 580
 581tegra114_sdram_pad_size:
 582        .word   tegra114_sdram_pad_adress_end - tegra114_sdram_pad_address
 583
 584        .type   tegra_sdram_pad_save, %object
 585tegra_sdram_pad_save:
 586        .rept (tegra114_sdram_pad_adress_end - tegra114_sdram_pad_address) / 4
 587        .long   0
 588        .endr
 589
 590/*
 591 * tegra30_tear_down_core
 592 *
 593 * copied into and executed from IRAM
 594 * puts memory in self-refresh for LP0 and LP1
 595 */
 596tegra30_tear_down_core:
 597        bl      tegra30_sdram_self_refresh
 598        bl      tegra30_switch_cpu_to_clk32k
 599        b       tegra30_enter_sleep
 600
 601/*
 602 * tegra30_switch_cpu_to_clk32k
 603 *
 604 * In LP0 and LP1 all PLLs will be turned off. Switching the CPU and System CLK
 605 * to the 32KHz clock.
 606 * r4 = TEGRA_PMC_BASE
 607 * r5 = TEGRA_CLK_RESET_BASE
 608 * r6 = TEGRA_FLOW_CTRL_BASE
 609 * r7 = TEGRA_TMRUS_BASE
 610 * r10= SoC ID
 611 */
 612tegra30_switch_cpu_to_clk32k:
 613        /*
 614         * start by jumping to CLKM to safely disable PLLs, then jump to
 615         * CLKS.
 616         */
 617        mov     r0, #(1 << 28)
 618        str     r0, [r5, #CLK_RESET_SCLK_BURST]
 619        /* 2uS delay delay between changing SCLK and CCLK */
 620        ldr     r1, [r7]
 621        add     r1, r1, #2
 622        wait_until r1, r7, r9
 623        str     r0, [r5, #CLK_RESET_CCLK_BURST]
 624        mov     r0, #0
 625        str     r0, [r5, #CLK_RESET_CCLK_DIVIDER]
 626        str     r0, [r5, #CLK_RESET_SCLK_DIVIDER]
 627
 628        /* switch the clock source of mselect to be CLK_M */
 629        ldr     r0, [r5, #CLK_RESET_CLK_SOURCE_MSELECT]
 630        orr     r0, r0, #MSELECT_CLKM
 631        str     r0, [r5, #CLK_RESET_CLK_SOURCE_MSELECT]
 632
 633        /* 2uS delay delay between changing SCLK and disabling PLLs */
 634        ldr     r1, [r7]
 635        add     r1, r1, #2
 636        wait_until r1, r7, r9
 637
 638        /* disable PLLM via PMC in LP1 */
 639        ldr     r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
 640        bic     r0, r0, #(1 << 12)
 641        str     r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
 642
 643        /* disable PLLP, PLLA, PLLC and PLLX */
 644        ldr     r0, [r5, #CLK_RESET_PLLP_BASE]
 645        bic     r0, r0, #(1 << 30)
 646        str     r0, [r5, #CLK_RESET_PLLP_BASE]
 647        ldr     r0, [r5, #CLK_RESET_PLLA_BASE]
 648        bic     r0, r0, #(1 << 30)
 649        str     r0, [r5, #CLK_RESET_PLLA_BASE]
 650        ldr     r0, [r5, #CLK_RESET_PLLC_BASE]
 651        bic     r0, r0, #(1 << 30)
 652        str     r0, [r5, #CLK_RESET_PLLC_BASE]
 653        ldr     r0, [r5, #CLK_RESET_PLLX_BASE]
 654        bic     r0, r0, #(1 << 30)
 655        str     r0, [r5, #CLK_RESET_PLLX_BASE]
 656
 657        cmp     r10, #TEGRA30
 658        beq     _no_pll_in_iddq
 659        pll_iddq_entry r1, r5, CLK_RESET_PLLX_MISC3, CLK_RESET_PLLX_MISC3_IDDQ
 660_no_pll_in_iddq:
 661
 662        /* switch to CLKS */
 663        mov     r0, #0  /* brust policy = 32KHz */
 664        str     r0, [r5, #CLK_RESET_SCLK_BURST]
 665
 666        ret     lr
 667
 668/*
 669 * tegra30_enter_sleep
 670 *
 671 * uses flow controller to enter sleep state
 672 * executes from IRAM with SDRAM in selfrefresh when target state is LP0 or LP1
 673 * executes from SDRAM with target state is LP2
 674 * r6 = TEGRA_FLOW_CTRL_BASE
 675 */
 676tegra30_enter_sleep:
 677        cpu_id  r1
 678
 679        cpu_to_csr_reg  r2, r1
 680        ldr     r0, [r6, r2]
 681        orr     r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
 682        orr     r0, r0, #FLOW_CTRL_CSR_ENABLE
 683        str     r0, [r6, r2]
 684
 685        tegra_get_soc_id TEGRA_APB_MISC_BASE, r10
 686        cmp     r10, #TEGRA30
 687        mov     r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT
 688        orreq   r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ
 689        orrne   r0, r0, #FLOW_CTRL_HALT_LIC_IRQ | FLOW_CTRL_HALT_LIC_FIQ
 690
 691        cpu_to_halt_reg r2, r1
 692        str     r0, [r6, r2]
 693        dsb
 694        ldr     r0, [r6, r2] /* memory barrier */
 695
 696halted:
 697        isb
 698        dsb
 699        wfi     /* CPU should be power gated here */
 700
 701        /* !!!FIXME!!! Implement halt failure handler */
 702        b       halted
 703
 704/*
 705 * tegra30_sdram_self_refresh
 706 *
 707 * called with MMU off and caches disabled
 708 * must be executed from IRAM
 709 * r4 = TEGRA_PMC_BASE
 710 * r5 = TEGRA_CLK_RESET_BASE
 711 * r6 = TEGRA_FLOW_CTRL_BASE
 712 * r7 = TEGRA_TMRUS_BASE
 713 * r10= SoC ID
 714 */
 715tegra30_sdram_self_refresh:
 716
 717        adr     r8, tegra_sdram_pad_save
 718        tegra_get_soc_id TEGRA_APB_MISC_BASE, r10
 719        cmp     r10, #TEGRA30
 720        adreq   r2, tegra30_sdram_pad_address
 721        ldreq   r3, tegra30_sdram_pad_size
 722        cmp     r10, #TEGRA114
 723        adreq   r2, tegra114_sdram_pad_address
 724        ldreq   r3, tegra114_sdram_pad_size
 725        cmp     r10, #TEGRA124
 726        adreq   r2, tegra124_sdram_pad_address
 727        ldreq   r3, tegra30_sdram_pad_size
 728
 729        mov     r9, #0
 730
 731padsave:
 732        ldr     r0, [r2, r9]            @ r0 is the addr in the pad_address
 733
 734        ldr     r1, [r0]
 735        str     r1, [r8, r9]            @ save the content of the addr
 736
 737        add     r9, r9, #4
 738        cmp     r3, r9
 739        bne     padsave
 740padsave_done:
 741
 742        dsb
 743
 744        cmp     r10, #TEGRA30
 745        ldreq   r0, =TEGRA_EMC_BASE     @ r0 reserved for emc base addr
 746        cmp     r10, #TEGRA114
 747        ldreq   r0, =TEGRA_EMC0_BASE
 748        cmp     r10, #TEGRA124
 749        ldreq   r0, =TEGRA124_EMC_BASE
 750
 751enter_self_refresh:
 752        cmp     r10, #TEGRA30
 753        mov     r1, #0
 754        str     r1, [r0, #EMC_ZCAL_INTERVAL]
 755        str     r1, [r0, #EMC_AUTO_CAL_INTERVAL]
 756        ldr     r1, [r0, #EMC_CFG]
 757        bic     r1, r1, #(1 << 28)
 758        bicne   r1, r1, #(1 << 29)
 759        str     r1, [r0, #EMC_CFG]      @ disable DYN_SELF_REF
 760
 761        emc_timing_update r1, r0
 762
 763        ldr     r1, [r7]
 764        add     r1, r1, #5
 765        wait_until r1, r7, r2
 766
 767emc_wait_auto_cal:
 768        ldr     r1, [r0, #EMC_AUTO_CAL_STATUS]
 769        tst     r1, #(1 << 31)          @ wait until AUTO_CAL_ACTIVE is cleared
 770        bne     emc_wait_auto_cal
 771
 772        mov     r1, #3
 773        str     r1, [r0, #EMC_REQ_CTRL] @ stall incoming DRAM requests
 774
 775emcidle:
 776        ldr     r1, [r0, #EMC_EMC_STATUS]
 777        tst     r1, #4
 778        beq     emcidle
 779
 780        mov     r1, #1
 781        str     r1, [r0, #EMC_SELF_REF]
 782
 783        emc_device_mask r1, r0
 784
 785emcself:
 786        ldr     r2, [r0, #EMC_EMC_STATUS]
 787        and     r2, r2, r1
 788        cmp     r2, r1
 789        bne     emcself                 @ loop until DDR in self-refresh
 790
 791        /* Put VTTGEN in the lowest power mode */
 792        ldr     r1, [r0, #EMC_XM2VTTGENPADCTRL]
 793        mov32   r2, 0xF8F8FFFF  @ clear XM2VTTGEN_DRVUP and XM2VTTGEN_DRVDN
 794        and     r1, r1, r2
 795        str     r1, [r0, #EMC_XM2VTTGENPADCTRL]
 796        ldr     r1, [r0, #EMC_XM2VTTGENPADCTRL2]
 797        cmp     r10, #TEGRA30
 798        orreq   r1, r1, #7              @ set E_NO_VTTGEN
 799        orrne   r1, r1, #0x3f
 800        str     r1, [r0, #EMC_XM2VTTGENPADCTRL2]
 801
 802        emc_timing_update r1, r0
 803
 804        /* Tegra114 had dual EMC channel, now config the other one */
 805        cmp     r10, #TEGRA114
 806        bne     no_dual_emc_chanl
 807        mov32   r1, TEGRA_EMC1_BASE
 808        cmp     r0, r1
 809        movne   r0, r1
 810        bne     enter_self_refresh
 811no_dual_emc_chanl:
 812
 813        ldr     r1, [r4, #PMC_CTRL]
 814        tst     r1, #PMC_CTRL_SIDE_EFFECT_LP0
 815        bne     pmc_io_dpd_skip
 816        /*
 817         * Put DDR_DATA, DISC_ADDR_CMD, DDR_ADDR_CMD, POP_ADDR_CMD, POP_CLK
 818         * and COMP in the lowest power mode when LP1.
 819         */
 820        mov32   r1, 0x8EC00000
 821        str     r1, [r4, #PMC_IO_DPD_REQ]
 822pmc_io_dpd_skip:
 823
 824        dsb
 825
 826        ret     lr
 827
 828        .ltorg
 829/* dummy symbol for end of IRAM */
 830        .align L1_CACHE_SHIFT
 831        .global tegra30_iram_end
 832tegra30_iram_end:
 833        b       .
 834#endif
 835