summaryrefslogtreecommitdiff
path: root/arch/arm/mach-mx5/mx50_wfi.S
blob: a3bf20dd7e6abbe714360dc6ca6dc51872f406dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <linux/linkage.h>

/*
 *  mx50_wait
 *
 *  Idle the processor (eg, wait for interrupt).
 *  Make sure DDR is in self-refresh.
 *  IRQs are already disabled.
 */
ENTRY(mx50_wait)
    stmfd   sp!, {r3,r4,r5,r6,r7,r8,r9,r10,r11}     @ Save registers

    mov    r6, r0                       @save CCM address
    mov    r5, r1                       @save DataBahn address
    mov    r7, r2                       @save sys_clk usecount

    /*
     * Make sure the DDR is self-refresh, before setting the clock bits.
     */

     /* Step 2: Poll the CKE_STATUS bit. */
LoopCKE0:
    /* Wait for CKE = 0 */
    ldr     r0,[r5, #0xfc]
    and     r0, r0, #0x10000
    ldr     r2, =0x10000
    cmp     r0, r2
    beq     LoopCKE0

    /* Check if Databahn is in SYNC or ASYNC mode. */
    ldr      r4, [r5, #0xdc]
    and     r4, r4, #0x30000
    cmp    r4, #0x30000
    beq     Sync_mode

    /* Set the DDR_CLKGATE to 0x1. */
    ldr      r0, [r6, #0x98]
    bic     r0, r0, #0x80000000
    str     r0, [r6, #0x98]

    .long     0xe320f003              @ Opcode for WFI

    /* Set the DDR_CLKGATE to 0x3. */
    ldr      r0, [r6, #0x98]
    orr     r0, r0, #0xC0000000
    str     r0, [r6, #0x98]
    b       Wfi_Done

Sync_mode:
    /* If usecount of sys_clk is greater than 0, donot gate it. */
    cmp    r7, #0
    bgt    do_wfi

    /* Check if PLL1 is sourcing SYS_CLK. */
    ldr     r5, [r6, #0x90]
    and    r5, r0, #0x1
    cmp   r5, #0x1
    beq    pll1_source

    /* Set the SYS_XTAL_CLKGATE to 0x1. */
    ldr      r0, [r6, #0x94]
    bic     r0, r0, #0x80000000
    str     r0, [r6, #0x94]

    /* Set the SYS_XTAL_DIV to 0xF (1.6MHz) to reduce power.
     * since this clock is not gated when ARM is in WFI.
     */

    ldr      r0, [r6, #0x94]
    orr      r0, r0, #0x3c0
    str      r0, [r6, #0x94]

    b       do_wfi
pll1_source:
    /* Set the SYS_PLL_CLKGATE to 0x1. */
    ldr      r0, [r6, #0x94]
    bic     r0, r0, #0x40000000
    str     r0, [r6, #0x94]

do_wfi:
    .long     0xe320f003              @ Opcode for WFI

    cmp    r7, #0
    bgt     Wfi_Done

     cmp    r5, #1
     beq    pll1_source1
    /* Set the SYS_XTAL_DIV to 24MHz.*/
    ldr      r0, [r6, #0x94]
    bic      r0, r0, #0x3c0
    orr      r0, r0, #0x40
    str      r0, [r6, #0x94]

    /* Set the SYS_XTAL_CLKGATE to 0x3. */
    ldr      r0, [r6, #0x94]
    orr     r0, r0, #0xC0000000
    str     r0, [r6, #0x94]
    b       Wfi_Done

pll1_source1:
    /* Set the SYS_PLL_CLKGATE to 0x3. */
    ldr      r0, [r6, #0x94]
    orr     r0, r0, #0x30000000
    str     r0, [r6, #0x94]

Wfi_Done:
    /* Restore registers */
    ldmfd sp!, {r3,r4,r5,r6,r7,r8,r9,r10,r11}
    mov     pc, lr

    .type   mx50_do_wait, #object
ENTRY(mx50_do_wait)
    .word   mx50_wait
    .size    mx50_wait, . - mx50_wait