^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * (C) Copyright 2009, Texas Instruments, Inc. https://www.ti.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) /* replicated define because linux/bitops.h cannot be included in assembly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #define BIT(nr) (1 << (nr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/assembler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "psc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "ddr2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "clock.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /* Arbitrary, hardware currently does not update PHYRDY correctly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define PHYRDY_CYCLES 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* Assume 25 MHz speed for the cycle conversions since PLLs are bypassed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define PLL_BYPASS_CYCLES (PLL_BYPASS_TIME * 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define PLL_RESET_CYCLES (PLL_RESET_TIME * 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define PLL_LOCK_CYCLES (PLL_LOCK_TIME * 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define DEEPSLEEP_SLEEPENABLE_BIT BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) .arch armv5te
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Move DaVinci into deep sleep state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * Note: This code is copied to internal SRAM by PM code. When the DaVinci
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * wakes up it continues execution at the point it went to sleep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * Register Usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * r0: contains virtual base for DDR2 controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * r1: contains virtual base for DDR2 Power and Sleep controller (PSC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * r2: contains PSC number for DDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * r3: contains virtual base DDR2 PLL controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * r4: contains virtual address of the DEEPSLEEP register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) ENTRY(davinci_cpu_suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) stmfd sp!, {r0-r12, lr} @ save registers on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) ldr ip, CACHE_FLUSH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) blx ip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) ldmia r0, {r0-r4}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Switch DDR to self-refresh mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* calculate SDRCR address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) ldr ip, [r0, #DDR2_SDRCR_OFFSET]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) bic ip, ip, #DDR2_SRPD_BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) orr ip, ip, #DDR2_LPMODEN_BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) str ip, [r0, #DDR2_SDRCR_OFFSET]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) ldr ip, [r0, #DDR2_SDRCR_OFFSET]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) orr ip, ip, #DDR2_MCLKSTOPEN_BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) str ip, [r0, #DDR2_SDRCR_OFFSET]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) mov ip, #PHYRDY_CYCLES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 1: subs ip, ip, #0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) bne 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* Disable DDR2 LPSC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) mov r7, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) mov r0, #0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) bl davinci_ddr_psc_config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) mov r0, r7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* Disable clock to DDR PHY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ldr ip, [r3, #PLLDIV1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) bic ip, ip, #PLLDIV_EN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) str ip, [r3, #PLLDIV1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* Put the DDR PLL in bypass and power down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ldr ip, [r3, #PLLCTL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) bic ip, ip, #PLLCTL_PLLENSRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) bic ip, ip, #PLLCTL_PLLEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) str ip, [r3, #PLLCTL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* Wait for PLL to switch to bypass */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) mov ip, #PLL_BYPASS_CYCLES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) 2: subs ip, ip, #0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) bne 2b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* Power down the PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) ldr ip, [r3, #PLLCTL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) orr ip, ip, #PLLCTL_PLLPWRDN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) str ip, [r3, #PLLCTL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* Go to deep sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ldr ip, [r4]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) orr ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* System goes to sleep beyond after this instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) str ip, [r4]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* Wake up from sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* Clear sleep enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ldr ip, [r4]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) bic ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) str ip, [r4]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* initialize the DDR PLL controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* Put PLL in reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ldr ip, [r3, #PLLCTL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) bic ip, ip, #PLLCTL_PLLRST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) str ip, [r3, #PLLCTL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* Clear PLL power down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ldr ip, [r3, #PLLCTL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) bic ip, ip, #PLLCTL_PLLPWRDN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) str ip, [r3, #PLLCTL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) mov ip, #PLL_RESET_CYCLES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 3: subs ip, ip, #0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) bne 3b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* Bring PLL out of reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ldr ip, [r3, #PLLCTL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) orr ip, ip, #PLLCTL_PLLRST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) str ip, [r3, #PLLCTL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* Wait for PLL to lock (assume prediv = 1, 25MHz OSCIN) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) mov ip, #PLL_LOCK_CYCLES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 4: subs ip, ip, #0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) bne 4b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* Remove PLL from bypass mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ldr ip, [r3, #PLLCTL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) bic ip, ip, #PLLCTL_PLLENSRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) orr ip, ip, #PLLCTL_PLLEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) str ip, [r3, #PLLCTL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* Start 2x clock to DDR2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) ldr ip, [r3, #PLLDIV1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) orr ip, ip, #PLLDIV_EN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) str ip, [r3, #PLLDIV1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* Enable VCLK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* Enable DDR2 LPSC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) mov r7, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) mov r0, #0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) bl davinci_ddr_psc_config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) mov r0, r7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /* clear MCLKSTOPEN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ldr ip, [r0, #DDR2_SDRCR_OFFSET]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) bic ip, ip, #DDR2_MCLKSTOPEN_BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) str ip, [r0, #DDR2_SDRCR_OFFSET]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) ldr ip, [r0, #DDR2_SDRCR_OFFSET]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) bic ip, ip, #DDR2_LPMODEN_BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) str ip, [r0, #DDR2_SDRCR_OFFSET]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* Restore registers and return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ldmfd sp!, {r0-r12, pc}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ENDPROC(davinci_cpu_suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * Disables or Enables DDR2 LPSC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * Register Usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * r0: Enable or Disable LPSC r0 = 0x3 => Enable, r0 = 0x2 => Disable LPSC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * r1: contains virtual base for DDR2 Power and Sleep controller (PSC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * r2: contains PSC number for DDR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ENTRY(davinci_ddr_psc_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* Set next state in mdctl for DDR2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) mov r6, #MDCTL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) add r6, r6, r2, lsl #2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ldr ip, [r1, r6]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) bic ip, ip, #MDSTAT_STATE_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) orr ip, ip, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) str ip, [r1, r6]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* Enable the Power Domain Transition Command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) ldr ip, [r1, #PTCMD]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) orr ip, ip, #0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) str ip, [r1, #PTCMD]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* Check for Transition Complete (PTSTAT) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ptstat_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ldr ip, [r1, #PTSTAT]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) and ip, ip, #0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) cmp ip, #0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) bne ptstat_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* Check for DDR2 clock disable completion; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) mov r6, #MDSTAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) add r6, r6, r2, lsl #2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ddr2clk_stop_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ldr ip, [r1, r6]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) and ip, ip, #MDSTAT_STATE_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) cmp ip, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) bne ddr2clk_stop_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ENDPROC(davinci_ddr_psc_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) CACHE_FLUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #ifdef CONFIG_CPU_V6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .word v6_flush_kern_cache_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .word arm926_flush_kern_cache_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ENTRY(davinci_cpu_suspend_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .word . - davinci_cpu_suspend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ENDPROC(davinci_cpu_suspend_sz)