1/* 2 * linux/arch/arm/mach-omap3/sram.S 3 * 4 * Omap3 specific functions that need to be run in internal SRAM 5 * 6 * Copyright (C) 2004, 2007, 2008 Texas Instruments, Inc. 7 * Copyright (C) 2008 Nokia Corporation 8 * 9 * Rajendra Nayak <rnayak@ti.com> 10 * Richard Woodruff <r-woodruff2@ti.com> 11 * Paul Walmsley 12 * 13 * This program is free software; you can redistribute it and/or 14 * modify it under the terms of the GNU General Public License as 15 * published by the Free Software Foundation; either version 2 of 16 * the License, or (at your option) any later version. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the 21 * GNU General Public License for more details. 22 * 23 * You should have received a copy of the GNU General Public License 24 * along with this program; if not, write to the Free Software 25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 26 * MA 02111-1307 USA 27 */ 28#include <linux/linkage.h> 29 30#include <asm/assembler.h> 31 32#include "soc.h" 33#include "iomap.h" 34#include "sdrc.h" 35#include "cm3xxx.h" 36 37/* 38 * This file needs be built unconditionally as ARM to interoperate correctly 39 * with non-Thumb-2-capable firmware. 40 */ 41 .arm 42 43 .text 44 45/* r1 parameters */ 46#define SDRC_NO_UNLOCK_DLL 0x0 47#define SDRC_UNLOCK_DLL 0x1 48 49/* SDRC_DLLA_CTRL bit settings */ 50#define FIXEDDELAY_SHIFT 24 51#define FIXEDDELAY_MASK (0xff << FIXEDDELAY_SHIFT) 52#define DLLIDLE_MASK 0x4 53 54/* 55 * SDRC_DLLA_CTRL default values: TI hardware team indicates that 56 * FIXEDDELAY should be initialized to 0xf. This apparently was 57 * empirically determined during process testing, so no derivation 58 * was provided. 59 */ 60#define FIXEDDELAY_DEFAULT (0x0f << FIXEDDELAY_SHIFT) 61 62/* SDRC_DLLA_STATUS bit settings */ 63#define LOCKSTATUS_MASK 0x4 64 65/* SDRC_POWER bit settings */ 66#define SRFRONIDLEREQ_MASK 0x40 67 68/* CM_IDLEST1_CORE bit settings */ 69#define ST_SDRC_MASK 0x2 70 71/* CM_ICLKEN1_CORE bit settings */ 72#define EN_SDRC_MASK 0x2 73 74/* CM_CLKSEL1_PLL bit settings */ 75#define CORE_DPLL_CLKOUT_DIV_SHIFT 0x1b 76 77/* 78 * omap3_sram_configure_core_dpll - change DPLL3 M2 divider 79 * 80 * Params passed in registers: 81 * r0 = new M2 divider setting (only 1 and 2 supported right now) 82 * r1 = unlock SDRC DLL? (1 = yes, 0 = no). Only unlock DLL for 83 * SDRC rates < 83MHz 84 * r2 = number of MPU cycles to wait for SDRC to stabilize after 85 * reprogramming the SDRC when switching to a slower MPU speed 86 * r3 = increasing SDRC rate? (1 = yes, 0 = no) 87 * 88 * Params passed via the stack. The needed params will be copied in SRAM 89 * before use by the code in SRAM (SDRAM is not accessible during SDRC 90 * reconfiguration): 91 * new SDRC_RFR_CTRL_0 register contents 92 * new SDRC_ACTIM_CTRL_A_0 register contents 93 * new SDRC_ACTIM_CTRL_B_0 register contents 94 * new SDRC_MR_0 register value 95 * new SDRC_RFR_CTRL_1 register contents 96 * new SDRC_ACTIM_CTRL_A_1 register contents 97 * new SDRC_ACTIM_CTRL_B_1 register contents 98 * new SDRC_MR_1 register value 99 * 100 * If the param SDRC_RFR_CTRL_1 is 0, the parameters are not programmed into 101 * the SDRC CS1 registers 102 * 103 * NOTE: This code no longer attempts to program the SDRC AC timing and MR 104 * registers. This is because the code currently cannot ensure that all 105 * L3 initiators (e.g., sDMA, IVA, DSS DISPC, etc.) are not accessing the 106 * SDRAM when the registers are written. If the registers are changed while 107 * an initiator is accessing SDRAM, memory can be corrupted and/or the SDRC 108 * may enter an unpredictable state. In the future, the intent is to 109 * re-enable this code in cases where we can ensure that no initiators are 110 * touching the SDRAM. Until that time, users who know that their use case 111 * can satisfy the above requirement can enable the CONFIG_OMAP3_SDRC_AC_TIMING 112 * option. 113 * 114 * Richard Woodruff notes that any changes to this code must be carefully 115 * audited and tested to ensure that they don't cause a TLB miss while 116 * the SDRAM is inaccessible. Such a situation will crash the system 117 * since it will cause the ARM MMU to attempt to walk the page tables. 118 * These crashes may be intermittent. 119 */ 120 .align 3 121ENTRY(omap3_sram_configure_core_dpll) 122 stmfd sp!, {r1-r12, lr} @ store regs to stack 123 124 @ pull the extra args off the stack 125 @ and store them in SRAM 126 127/* 128 * PC-relative stores are deprecated in ARMv7 and lead to undefined behaviour 129 * in Thumb-2: use a r7 as a base instead. 130 * Be careful not to clobber r7 when maintaing this file. 131 */ 132 THUMB( adr r7, omap3_sram_configure_core_dpll ) 133 .macro strtext Rt:req, label:req 134 ARM( str \Rt, \label ) 135 THUMB( str \Rt, [r7, \label - omap3_sram_configure_core_dpll] ) 136 .endm 137 138 ldr r4, [sp, #52] 139 strtext r4, omap_sdrc_rfr_ctrl_0_val 140 ldr r4, [sp, #56] 141 strtext r4, omap_sdrc_actim_ctrl_a_0_val 142 ldr r4, [sp, #60] 143 strtext r4, omap_sdrc_actim_ctrl_b_0_val 144 ldr r4, [sp, #64] 145 strtext r4, omap_sdrc_mr_0_val 146 ldr r4, [sp, #68] 147 strtext r4, omap_sdrc_rfr_ctrl_1_val 148 cmp r4, #0 @ if SDRC_RFR_CTRL_1 is 0, 149 beq skip_cs1_params @ do not use cs1 params 150 ldr r4, [sp, #72] 151 strtext r4, omap_sdrc_actim_ctrl_a_1_val 152 ldr r4, [sp, #76] 153 strtext r4, omap_sdrc_actim_ctrl_b_1_val 154 ldr r4, [sp, #80] 155 strtext r4, omap_sdrc_mr_1_val 156skip_cs1_params: 157 mrc p15, 0, r8, c1, c0, 0 @ read ctrl register 158 bic r10, r8, #0x800 @ clear Z-bit, disable branch prediction 159 mcr p15, 0, r10, c1, c0, 0 @ write ctrl register 160 dsb @ flush buffered writes to interconnect 161 isb @ prevent speculative exec past here 162 cmp r3, #1 @ if increasing SDRC clk rate, 163 bleq configure_sdrc @ program the SDRC regs early (for RFR) 164 cmp r1, #SDRC_UNLOCK_DLL @ set the intended DLL state 165 bleq unlock_dll 166 blne lock_dll 167 bl sdram_in_selfrefresh @ put SDRAM in self refresh, idle SDRC 168 bl configure_core_dpll @ change the DPLL3 M2 divider 169 mov r12, r2 170 bl wait_clk_stable @ wait for SDRC to stabilize 171 bl enable_sdrc @ take SDRC out of idle 172 cmp r1, #SDRC_UNLOCK_DLL @ wait for DLL status to change 173 bleq wait_dll_unlock 174 blne wait_dll_lock 175 cmp r3, #1 @ if increasing SDRC clk rate, 176 beq return_to_sdram @ return to SDRAM code, otherwise, 177 bl configure_sdrc @ reprogram SDRC regs now 178return_to_sdram: 179 mcr p15, 0, r8, c1, c0, 0 @ restore ctrl register 180 isb @ prevent speculative exec past here 181 mov r0, #0 @ return value 182 ldmfd sp!, {r1-r12, pc} @ restore regs and return 183unlock_dll: 184 ldr r11, omap3_sdrc_dlla_ctrl 185 ldr r12, [r11] 186 bic r12, r12, #FIXEDDELAY_MASK 187 orr r12, r12, #FIXEDDELAY_DEFAULT 188 orr r12, r12, #DLLIDLE_MASK 189 str r12, [r11] @ (no OCP barrier needed) 190 bx lr 191lock_dll: 192 ldr r11, omap3_sdrc_dlla_ctrl 193 ldr r12, [r11] 194 bic r12, r12, #DLLIDLE_MASK 195 str r12, [r11] @ (no OCP barrier needed) 196 bx lr 197sdram_in_selfrefresh: 198 ldr r11, omap3_sdrc_power @ read the SDRC_POWER register 199 ldr r12, [r11] @ read the contents of SDRC_POWER 200 mov r9, r12 @ keep a copy of SDRC_POWER bits 201 orr r12, r12, #SRFRONIDLEREQ_MASK @ enable self refresh on idle 202 str r12, [r11] @ write back to SDRC_POWER register 203 ldr r12, [r11] @ posted-write barrier for SDRC 204idle_sdrc: 205 ldr r11, omap3_cm_iclken1_core @ read the CM_ICLKEN1_CORE reg 206 ldr r12, [r11] 207 bic r12, r12, #EN_SDRC_MASK @ disable iclk bit for SDRC 208 str r12, [r11] 209wait_sdrc_idle: 210 ldr r11, omap3_cm_idlest1_core 211 ldr r12, [r11] 212 and r12, r12, #ST_SDRC_MASK @ check for SDRC idle 213 cmp r12, #ST_SDRC_MASK 214 bne wait_sdrc_idle 215 bx lr 216configure_core_dpll: 217 ldr r11, omap3_cm_clksel1_pll 218 ldr r12, [r11] 219 ldr r10, core_m2_mask_val @ modify m2 for core dpll 220 and r12, r12, r10 221 orr r12, r12, r0, lsl #CORE_DPLL_CLKOUT_DIV_SHIFT 222 str r12, [r11] 223 ldr r12, [r11] @ posted-write barrier for CM 224 bx lr 225wait_clk_stable: 226 subs r12, r12, #1 227 bne wait_clk_stable 228 bx lr 229enable_sdrc: 230 ldr r11, omap3_cm_iclken1_core 231 ldr r12, [r11] 232 orr r12, r12, #EN_SDRC_MASK @ enable iclk bit for SDRC 233 str r12, [r11] 234wait_sdrc_idle1: 235 ldr r11, omap3_cm_idlest1_core 236 ldr r12, [r11] 237 and r12, r12, #ST_SDRC_MASK 238 cmp r12, #0 239 bne wait_sdrc_idle1 240restore_sdrc_power_val: 241 ldr r11, omap3_sdrc_power 242 str r9, [r11] @ restore SDRC_POWER, no barrier needed 243 bx lr 244wait_dll_lock: 245 ldr r11, omap3_sdrc_dlla_status 246 ldr r12, [r11] 247 and r12, r12, #LOCKSTATUS_MASK 248 cmp r12, #LOCKSTATUS_MASK 249 bne wait_dll_lock 250 bx lr 251wait_dll_unlock: 252 ldr r11, omap3_sdrc_dlla_status 253 ldr r12, [r11] 254 and r12, r12, #LOCKSTATUS_MASK 255 cmp r12, #0x0 256 bne wait_dll_unlock 257 bx lr 258configure_sdrc: 259 ldr r12, omap_sdrc_rfr_ctrl_0_val @ fetch value from SRAM 260 ldr r11, omap3_sdrc_rfr_ctrl_0 @ fetch addr from SRAM 261 str r12, [r11] @ store 262#ifdef CONFIG_OMAP3_SDRC_AC_TIMING 263 ldr r12, omap_sdrc_actim_ctrl_a_0_val 264 ldr r11, omap3_sdrc_actim_ctrl_a_0 265 str r12, [r11] 266 ldr r12, omap_sdrc_actim_ctrl_b_0_val 267 ldr r11, omap3_sdrc_actim_ctrl_b_0 268 str r12, [r11] 269 ldr r12, omap_sdrc_mr_0_val 270 ldr r11, omap3_sdrc_mr_0 271 str r12, [r11] 272#endif 273 ldr r12, omap_sdrc_rfr_ctrl_1_val 274 cmp r12, #0 @ if SDRC_RFR_CTRL_1 is 0, 275 beq skip_cs1_prog @ do not program cs1 params 276 ldr r11, omap3_sdrc_rfr_ctrl_1 277 str r12, [r11] 278#ifdef CONFIG_OMAP3_SDRC_AC_TIMING 279 ldr r12, omap_sdrc_actim_ctrl_a_1_val 280 ldr r11, omap3_sdrc_actim_ctrl_a_1 281 str r12, [r11] 282 ldr r12, omap_sdrc_actim_ctrl_b_1_val 283 ldr r11, omap3_sdrc_actim_ctrl_b_1 284 str r12, [r11] 285 ldr r12, omap_sdrc_mr_1_val 286 ldr r11, omap3_sdrc_mr_1 287 str r12, [r11] 288#endif 289skip_cs1_prog: 290 ldr r12, [r11] @ posted-write barrier for SDRC 291 bx lr 292 293 .align 294omap3_sdrc_power: 295 .word OMAP34XX_SDRC_REGADDR(SDRC_POWER) 296omap3_cm_clksel1_pll: 297 .word OMAP34XX_CM_REGADDR(PLL_MOD, CM_CLKSEL1) 298omap3_cm_idlest1_core: 299 .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST) 300omap3_cm_iclken1_core: 301 .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_ICLKEN1) 302 303omap3_sdrc_rfr_ctrl_0: 304 .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_0) 305omap3_sdrc_rfr_ctrl_1: 306 .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_1) 307omap3_sdrc_actim_ctrl_a_0: 308 .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_0) 309omap3_sdrc_actim_ctrl_a_1: 310 .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_1) 311omap3_sdrc_actim_ctrl_b_0: 312 .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_0) 313omap3_sdrc_actim_ctrl_b_1: 314 .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_1) 315omap3_sdrc_mr_0: 316 .word OMAP34XX_SDRC_REGADDR(SDRC_MR_0) 317omap3_sdrc_mr_1: 318 .word OMAP34XX_SDRC_REGADDR(SDRC_MR_1) 319omap_sdrc_rfr_ctrl_0_val: 320 .word 0xDEADBEEF 321omap_sdrc_rfr_ctrl_1_val: 322 .word 0xDEADBEEF 323omap_sdrc_actim_ctrl_a_0_val: 324 .word 0xDEADBEEF 325omap_sdrc_actim_ctrl_a_1_val: 326 .word 0xDEADBEEF 327omap_sdrc_actim_ctrl_b_0_val: 328 .word 0xDEADBEEF 329omap_sdrc_actim_ctrl_b_1_val: 330 .word 0xDEADBEEF 331omap_sdrc_mr_0_val: 332 .word 0xDEADBEEF 333omap_sdrc_mr_1_val: 334 .word 0xDEADBEEF 335 336omap3_sdrc_dlla_status: 337 .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS) 338omap3_sdrc_dlla_ctrl: 339 .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL) 340core_m2_mask_val: 341 .word 0x07FFFFFF 342ENDPROC(omap3_sram_configure_core_dpll) 343 344ENTRY(omap3_sram_configure_core_dpll_sz) 345 .word . - omap3_sram_configure_core_dpll 346 347