sleep34xx.S 19.2 KB
Newer Older
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
/*
 * (C) Copyright 2007
 * Texas Instruments
 * Karthik Dasu <karthik-dp@ti.com>
 *
 * (C) Copyright 2004
 * Texas Instruments, <www.ti.com>
 * Richard Woodruff <r-woodruff2@ti.com>
 *
 * 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., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */
#include <linux/linkage.h>
#include <asm/assembler.h>
27
#include <plat/sram.h>
28 29
#include <mach/io.h>

30 31
#include "cm2xxx_3xxx.h"
#include "prm2xxx_3xxx.h"
32
#include "sdrc.h"
33
#include "control.h"
34

35 36 37 38 39 40 41 42
/*
 * Registers access definitions
 */
#define SDRC_SCRATCHPAD_SEM_OFFS	0xc
#define SDRC_SCRATCHPAD_SEM_V	OMAP343X_SCRATCHPAD_REGADDR\
					(SDRC_SCRATCHPAD_SEM_OFFS)
#define PM_PREPWSTST_CORE_P	OMAP3430_PRM_BASE + CORE_MOD +\
					OMAP3430_PM_PREPWSTST
43
#define PM_PWSTCTRL_MPU_P	OMAP3430_PRM_BASE + MPU_MOD + OMAP2_PM_PWSTCTRL
44
#define CM_IDLEST1_CORE_V	OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST1)
45
#define CM_IDLEST_CKGEN_V	OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST)
46 47 48 49 50 51 52 53 54 55
#define SRAM_BASE_P		OMAP3_SRAM_PA
#define CONTROL_STAT		OMAP343X_CTRL_BASE + OMAP343X_CONTROL_STATUS
#define CONTROL_MEM_RTA_CTRL	(OMAP343X_CTRL_BASE +\
					OMAP36XX_CONTROL_MEM_RTA_CTRL)

/* Move this as correct place is available */
#define SCRATCHPAD_MEM_OFFS	0x310
#define SCRATCHPAD_BASE_P	(OMAP343X_CTRL_BASE +\
					OMAP343X_CONTROL_MEM_WKUP +\
					SCRATCHPAD_MEM_OFFS)
56
#define SDRC_POWER_V		OMAP34XX_SDRC_REGADDR(SDRC_POWER)
57 58 59 60 61 62 63
#define SDRC_SYSCONFIG_P	(OMAP343X_SDRC_BASE + SDRC_SYSCONFIG)
#define SDRC_MR_0_P		(OMAP343X_SDRC_BASE + SDRC_MR_0)
#define SDRC_EMR2_0_P		(OMAP343X_SDRC_BASE + SDRC_EMR2_0)
#define SDRC_MANUAL_0_P		(OMAP343X_SDRC_BASE + SDRC_MANUAL_0)
#define SDRC_MR_1_P		(OMAP343X_SDRC_BASE + SDRC_MR_1)
#define SDRC_EMR2_1_P		(OMAP343X_SDRC_BASE + SDRC_EMR2_1)
#define SDRC_MANUAL_1_P		(OMAP343X_SDRC_BASE + SDRC_MANUAL_1)
64 65
#define SDRC_DLLA_STATUS_V	OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
#define SDRC_DLLA_CTRL_V	OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
66

67 68 69 70 71
/*
 * This file needs be built unconditionally as ARM to interoperate correctly
 * with non-Thumb-2-capable firmware.
 */
	.arm
72 73 74

/*
 * API functions
75 76 77 78 79 80 81
 */

/*
 * The "get_*restore_pointer" functions are used to provide a
 * physical restore address where the ROM code jumps while waking
 * up from MPU OFF/OSWR state.
 * The restore pointer is stored into the scratchpad.
82
 */
83

84 85 86
	.text
/* Function call to get the restore pointer for resume from OFF */
ENTRY(get_restore_pointer)
J
Jean Pihet 已提交
87
	stmfd	sp!, {lr}	@ save registers on stack
88
	adr	r0, restore
J
Jean Pihet 已提交
89
	ldmfd	sp!, {pc}	@ restore regs and return
90 91
ENDPROC(get_restore_pointer)
	.align
92
ENTRY(get_restore_pointer_sz)
J
Jean Pihet 已提交
93
	.word	. - get_restore_pointer
J
Jean Pihet 已提交
94

95 96 97
	.text
/* Function call to get the restore pointer for 3630 resume from OFF */
ENTRY(get_omap3630_restore_pointer)
J
Jean Pihet 已提交
98
	stmfd	sp!, {lr}	@ save registers on stack
99
	adr	r0, restore_3630
J
Jean Pihet 已提交
100
	ldmfd	sp!, {pc}	@ restore regs and return
101 102
ENDPROC(get_omap3630_restore_pointer)
	.align
103
ENTRY(get_omap3630_restore_pointer_sz)
J
Jean Pihet 已提交
104
	.word	. - get_omap3630_restore_pointer
105

J
Jean Pihet 已提交
106 107 108 109 110 111
	.text
/* Function call to get the restore pointer for ES3 to resume from OFF */
ENTRY(get_es3_restore_pointer)
	stmfd	sp!, {lr}	@ save registers on stack
	adr	r0, restore_es3
	ldmfd	sp!, {pc}	@ restore regs and return
112 113
ENDPROC(get_es3_restore_pointer)
	.align
J
Jean Pihet 已提交
114 115 116
ENTRY(get_es3_restore_pointer_sz)
	.word	. - get_es3_restore_pointer

117 118 119
	.text
/*
 * L2 cache needs to be toggled for stable OFF mode functionality on 3630.
J
Jean Pihet 已提交
120
 * This function sets up a flag that will allow for this toggling to take
121
 * place on 3630. Hopefully some version in the future may not need this.
122 123
 */
ENTRY(enable_omap3630_toggle_l2_on_restore)
J
Jean Pihet 已提交
124
	stmfd	sp!, {lr}	@ save registers on stack
125 126
	/* Setup so that we will disable and enable l2 */
	mov	r1, #0x1
127 128
	adrl	r2, l2dis_3630	@ may be too distant for plain adr
	str	r1, [r2]
J
Jean Pihet 已提交
129
	ldmfd	sp!, {pc}	@ restore regs and return
130
ENDPROC(enable_omap3630_toggle_l2_on_restore)
131

J
Jean Pihet 已提交
132
	.text
133 134 135 136 137 138 139 140 141 142 143 144
/* Function to call rom code to save secure ram context */
ENTRY(save_secure_ram_context)
	stmfd	sp!, {r1-r12, lr}	@ save registers on stack
	adr	r3, api_params		@ r3 points to parameters
	str	r0, [r3,#0x4]		@ r0 has sdram address
	ldr	r12, high_mask
	and	r3, r3, r12
	ldr	r12, sram_phy_addr_mask
	orr	r3, r3, r12
	mov	r0, #25			@ set service ID for PPA
	mov	r12, r0			@ copy secure service ID in r12
	mov	r1, #0			@ set task id for ROM code in r1
145
	mov	r2, #4			@ set some flags in r2, r6
146
	mov	r6, #0xff
147 148
	dsb				@ data write barrier
	dmb				@ data memory barrier
149
	smc	#1			@ call SMI monitor (smi #1)
150 151 152 153 154
	nop
	nop
	nop
	nop
	ldmfd	sp!, {r1-r12, pc}
155
	.align
156 157 158 159 160 161
sram_phy_addr_mask:
	.word	SRAM_BASE_P
high_mask:
	.word	0xffff
api_params:
	.word	0x4, 0x0, 0x0, 0x1, 0x1
162
ENDPROC(save_secure_ram_context)
163 164 165
ENTRY(save_secure_ram_context_sz)
	.word	. - save_secure_ram_context

166 167 168 169 170 171
/*
 * ======================
 * == Idle entry point ==
 * ======================
 */

172 173 174
/*
 * Forces OMAP into idle state
 *
175 176 177 178
 * omap34xx_cpu_suspend() - This bit of code saves the CPU context if needed
 * and executes the WFI instruction. Calling WFI effectively changes the
 * power domains states to the desired target power states.
 *
179
 *
180
 * Notes:
J
Jean Pihet 已提交
181 182
 * - this code gets copied to internal SRAM at boot and after wake-up
 *   from OFF mode. The execution pointer in SRAM is _omap_sram_idle.
183 184 185
 * - when the OMAP wakes up it continues at different execution points
 *   depending on the low power mode (non-OFF vs OFF modes),
 *   cf. 'Resume path for xxx mode' comments.
186 187
 */
ENTRY(omap34xx_cpu_suspend)
J
Jean Pihet 已提交
188
	stmfd	sp!, {r0-r12, lr}	@ save registers on stack
189

190
	/*
191
	 * r0 contains CPU context save/restore pointer in sdram
192 193 194
	 * r1 contains information about saving context:
	 *   0 - No context lost
	 *   1 - Only L1 and logic lost
195 196
	 *   2 - Only L2 lost (Even L1 is retained we clean it along with L2)
	 *   3 - Both L1 and L2 lost and logic lost
197
	 */
198

199
	/* Directly jump to WFI is the context save is not required */
200
	cmp	r1, #0x0
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
	beq	omap3_do_wfi

	/* Otherwise fall through to the save context code */
save_context_wfi:
	mov	r8, r0			@ Store SDRAM address in r8
	mrc	p15, 0, r5, c1, c0, 1	@ Read Auxiliary Control Register
	mov	r4, #0x1		@ Number of parameters for restore call
	stmia	r8!, {r4-r5}		@ Push parameters for restore call
	mrc	p15, 1, r5, c9, c0, 2	@ Read L2 AUX ctrl register
	stmia	r8!, {r4-r5}		@ Push parameters for restore call

        /* Check what that target sleep state is from r1 */
	cmp	r1, #0x2		@ Only L2 lost, no need to save context
	beq	clean_caches

l1_logic_lost:
217 218 219
	mov	r4, sp			@ Store sp
	mrs	r5, spsr		@ Store spsr
	mov	r6, lr			@ Store lr
220
	stmia	r8!, {r4-r6}
221 222 223 224 225

	mrc	p15, 0, r4, c1, c0, 2	@ Coprocessor access control register
	mrc	p15, 0, r5, c2, c0, 0	@ TTBR0
	mrc	p15, 0, r6, c2, c0, 1	@ TTBR1
	mrc	p15, 0, r7, c2, c0, 2	@ TTBCR
226 227
	stmia	r8!, {r4-r7}

228 229 230 231 232 233 234 235 236 237
	mrc	p15, 0, r4, c3, c0, 0	@ Domain access Control Register
	mrc	p15, 0, r5, c10, c2, 0	@ PRRR
	mrc	p15, 0, r6, c10, c2, 1	@ NMRR
	stmia	r8!,{r4-r6}

	mrc	p15, 0, r4, c13, c0, 1	@ Context ID
	mrc	p15, 0, r5, c13, c0, 2	@ User r/w thread and process ID
	mrc	p15, 0, r6, c12, c0, 0	@ Secure or NS vector base address
	mrs	r7, cpsr		@ Store current cpsr
	stmia	r8!, {r4-r7}
238

239
	mrc	p15, 0, r4, c1, c0, 0	@ save control register
240 241 242 243 244 245 246 247 248 249
	stmia	r8!, {r4}

clean_caches:
	/*
	 * jump out to kernel flush routine
	 *  - reuse that code is better
	 *  - it executes in a cached space so is faster than refetch per-block
	 *  - should be faster and will change with kernel
	 *  - 'might' have to copy address, load and jump to it
	 */
J
Jean Pihet 已提交
250
	ldr	r1, kernel_flush
251 252 253 254 255 256 257 258 259 260 261 262
	blx	r1
	/*
	 * The kernel doesn't interwork: v7_flush_dcache_all in particluar will
	 * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled.
	 * This sequence switches back to ARM.  Note that .align may insert a
	 * nop: bx pc needs to be word-aligned in order to work.
	 */
 THUMB(	.thumb		)
 THUMB(	.align		)
 THUMB(	bx	pc	)
 THUMB(	nop		)
	.arm
263 264 265 266 267 268 269

omap3_do_wfi:
	ldr	r4, sdrc_power		@ read the SDRC_POWER register
	ldr	r5, [r4]		@ read the contents of SDRC_POWER
	orr	r5, r5, #0x40		@ enable self refresh on idle req
	str	r5, [r4]		@ write back to SDRC_POWER register

270
	/* Data memory barrier and Data sync barrier */
271 272
	dsb
	dmb
273

274 275 276 277 278
/*
 * ===================================
 * == WFI instruction => Enter idle ==
 * ===================================
 */
279 280
	wfi				@ wait for interrupt

281 282 283 284 285
/*
 * ===================================
 * == Resume path for non-OFF modes ==
 * ===================================
 */
286 287 288 289 290 291 292 293 294 295
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
296
	bl wait_sdrc_ok
297

298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
/*
 * ===================================
 * == Exit point from non-OFF modes ==
 * ===================================
 */
	ldmfd	sp!, {r0-r12, pc}	@ restore regs and return


/*
 * ==============================
 * == Resume path for OFF mode ==
 * ==============================
 */

/*
 * The restore_* functions are called by the ROM code
 *  when back from WFI in OFF mode.
 * Cf. the get_*restore_pointer functions.
 *
 *  restore_es3: applies to 34xx >= ES3.0
 *  restore_3630: applies to 36xx
 *  restore: common code for 3xxx
 */
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
restore_es3:
	ldr	r5, pm_prepwstst_core_p
	ldr	r4, [r5]
	and	r4, r4, #0x3
	cmp	r4, #0x0	@ Check if previous power state of CORE is OFF
	bne	restore
	adr	r0, es3_sdrc_fix
	ldr	r1, sram_base
	ldr	r2, es3_sdrc_fix_sz
	mov	r2, r2, ror #2
copy_to_sram:
	ldmia	r0!, {r3}	@ val = *src
	stmia	r1!, {r3}	@ *dst = val
	subs	r2, r2, #0x1	@ num_words--
	bne	copy_to_sram
	ldr	r1, sram_base
	blx	r1
338 339 340 341 342 343 344 345 346 347 348 349
	b	restore

restore_3630:
	ldr	r1, pm_prepwstst_core_p
	ldr	r2, [r1]
	and	r2, r2, #0x3
	cmp	r2, #0x0	@ Check if previous power state of CORE is OFF
	bne	restore
	/* Disable RTA before giving control */
	ldr	r1, control_mem_rta
	mov	r2, #OMAP36XX_RTA_DISABLE
	str	r2, [r1]
350 351 352

	/* Fall through to common code for the remaining logic */

353
restore:
J
Jean Pihet 已提交
354
	/*
355 356
	 * Check what was the reason for mpu reset and store the reason in r9:
	 *  0 - No context lost
J
Jean Pihet 已提交
357 358 359
	 *  1 - Only L1 and logic lost
	 *  2 - Only L2 lost - In this case, we wont be here
	 *  3 - Both L1 and L2 lost
360
	 */
J
Jean Pihet 已提交
361
	ldr	r1, pm_pwstctrl_mpu
362
	ldr	r2, [r1]
J
Jean Pihet 已提交
363 364 365
	and	r2, r2, #0x3
	cmp	r2, #0x0	@ Check if target power state was OFF or RET
	moveq	r9, #0x3	@ MPU OFF => L1 and L2 lost
366 367
	movne	r9, #0x1	@ Only L1 and L2 lost => avoid L2 invalidation
	bne	logic_l1_restore
368 369 370 371 372 373 374 375

	ldr	r0, l2dis_3630
	cmp	r0, #0x1	@ should we disable L2 on 3630?
	bne	skipl2dis
	mrc	p15, 0, r0, c1, c0, 1
	bic	r0, r0, #2	@ disable L2 cache
	mcr	p15, 0, r0, c1, c0, 1
skipl2dis:
376 377 378 379 380
	ldr	r0, control_stat
	ldr	r1, [r0]
	and	r1, #0x700
	cmp	r1, #0x300
	beq	l2_inv_gp
J
Jean Pihet 已提交
381 382 383 384
	mov	r0, #40			@ set service ID for PPA
	mov	r12, r0			@ copy secure Service ID in r12
	mov	r1, #0			@ set task id for ROM code in r1
	mov	r2, #4			@ set some flags in r2, r6
385 386
	mov	r6, #0xff
	adr	r3, l2_inv_api_params	@ r3 points to dummy parameters
387 388
	dsb				@ data write barrier
	dmb				@ data memory barrier
389
	smc	#1			@ call SMI monitor (smi #1)
390
	/* Write to Aux control register to set some bits */
J
Jean Pihet 已提交
391 392 393 394
	mov	r0, #42			@ set service ID for PPA
	mov	r12, r0			@ copy secure Service ID in r12
	mov	r1, #0			@ set task id for ROM code in r1
	mov	r2, #4			@ set some flags in r2, r6
395
	mov	r6, #0xff
396
	ldr	r4, scratchpad_base
J
Jean Pihet 已提交
397
	ldr	r3, [r4, #0xBC]		@ r3 points to parameters
398 399
	dsb				@ data write barrier
	dmb				@ data memory barrier
400
	smc	#1			@ call SMI monitor (smi #1)
401

402 403
#ifdef CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE
	/* Restore L2 aux control register */
J
Jean Pihet 已提交
404
					@ set service ID for PPA
405
	mov	r0, #CONFIG_OMAP3_L2_AUX_SECURE_SERVICE_SET_ID
J
Jean Pihet 已提交
406 407 408
	mov	r12, r0			@ copy service ID in r12
	mov	r1, #0			@ set task ID for ROM code in r1
	mov	r2, #4			@ set some flags in r2, r6
409 410 411
	mov	r6, #0xff
	ldr	r4, scratchpad_base
	ldr	r3, [r4, #0xBC]
J
Jean Pihet 已提交
412
	adds	r3, r3, #8		@ r3 points to parameters
413 414
	dsb				@ data write barrier
	dmb				@ data memory barrier
415
	smc	#1			@ call SMI monitor (smi #1)
416
#endif
417
	b	logic_l1_restore
J
Jean Pihet 已提交
418

419
	.align
420
l2_inv_api_params:
J
Jean Pihet 已提交
421
	.word	0x1, 0x00
422
l2_inv_gp:
423
	/* Execute smi to invalidate L2 cache */
J
Jean Pihet 已提交
424
	mov r12, #0x1			@ set up to invalidate L2
425
	smc	#0			@ Call SMI monitor (smieq)
426
	/* Write to Aux control register to set some bits */
427 428 429
	ldr	r4, scratchpad_base
	ldr	r3, [r4,#0xBC]
	ldr	r0, [r3,#4]
430
	mov	r12, #0x3
431
	smc	#0			@ Call SMI monitor (smieq)
432 433 434 435
	ldr	r4, scratchpad_base
	ldr	r3, [r4,#0xBC]
	ldr	r0, [r3,#12]
	mov	r12, #0x2
436
	smc	#0			@ Call SMI monitor (smieq)
437
logic_l1_restore:
438
	ldr	r1, l2dis_3630
J
Jean Pihet 已提交
439
	cmp	r1, #0x1		@ Test if L2 re-enable needed on 3630
440 441
	bne	skipl2reen
	mrc	p15, 0, r1, c1, c0, 1
J
Jean Pihet 已提交
442
	orr	r1, r1, #2		@ re-enable L2 cache
443 444
	mcr	p15, 0, r1, c1, c0, 1
skipl2reen:
445
	mov	r1, #0
J
Jean Pihet 已提交
446 447 448 449
	/*
	 * Invalidate all instruction caches to PoU
	 * and flush branch target cache
	 */
450 451 452 453
	mcr	p15, 0, r1, c7, c5, 0

	ldr	r4, scratchpad_base
	ldr	r3, [r4,#0xBC]
454
	adds	r3, r3, #16
455

456
	ldmia	r3!, {r4-r6}
457 458 459
	mov	sp, r4			@ Restore sp
	msr	spsr_cxsf, r5		@ Restore spsr
	mov	lr, r6			@ Restore lr
460

461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
	ldmia	r3!, {r4-r7}
	mcr	p15, 0, r4, c1, c0, 2	@ Coprocessor access Control Register
	mcr	p15, 0, r5, c2, c0, 0	@ TTBR0
	mcr	p15, 0, r6, c2, c0, 1	@ TTBR1
	mcr	p15, 0, r7, c2, c0, 2	@ TTBCR

	ldmia	r3!,{r4-r6}
	mcr	p15, 0, r4, c3, c0, 0	@ Domain access Control Register
	mcr	p15, 0, r5, c10, c2, 0	@ PRRR
	mcr	p15, 0, r6, c10, c2, 1	@ NMRR


	ldmia	r3!,{r4-r7}
	mcr	p15, 0, r4, c13, c0, 1	@ Context ID
	mcr	p15, 0, r5, c13, c0, 2	@ User r/w thread and process ID
	mrc	p15, 0, r6, c12, c0, 0	@ Secure or NS vector base address
	msr	cpsr, r7		@ store cpsr
478 479

	/* Enabling MMU here */
J
Jean Pihet 已提交
480 481
	mrc	p15, 0, r7, c2, c0, 2 	@ Read TTBRControl
	/* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1 */
482 483 484 485
	and	r7, #0x7
	cmp	r7, #0x0
	beq	usettbr0
ttbr_error:
J
Jean Pihet 已提交
486 487 488 489
	/*
	 * More work needs to be done to support N[0:2] value other than 0
	 * So looping here so that the error can be detected
	 */
490 491 492 493 494 495 496
	b	ttbr_error
usettbr0:
	mrc	p15, 0, r2, c2, c0, 0
	ldr	r5, ttbrbit_mask
	and	r2, r5
	mov	r4, pc
	ldr	r5, table_index_mask
J
Jean Pihet 已提交
497
	and	r4, r5			@ r4 = 31 to 20 bits of pc
498 499
	/* Extract the value to be written to table entry */
	ldr	r1, table_entry
J
Jean Pihet 已提交
500 501
	/* r1 has the value to be written to table entry*/
	add	r1, r1, r4
502 503
	/* Getting the address of table entry to modify */
	lsr	r4, #18
J
Jean Pihet 已提交
504 505
	/* r2 has the location which needs to be modified */
	add	r2, r4
506 507 508 509 510 511
	/* Storing previous entry of location being modified */
	ldr	r5, scratchpad_base
	ldr	r4, [r2]
	str	r4, [r5, #0xC0]
	/* Modify the table entry */
	str	r1, [r2]
J
Jean Pihet 已提交
512 513 514 515
	/*
	 * Storing address of entry being modified
	 * - will be restored after enabling MMU
	 */
516 517 518 519 520 521 522 523
	ldr	r5, scratchpad_base
	str	r2, [r5, #0xC4]

	mov	r0, #0
	mcr	p15, 0, r0, c7, c5, 4	@ Flush prefetch buffer
	mcr	p15, 0, r0, c7, c5, 6	@ Invalidate branch predictor array
	mcr	p15, 0, r0, c8, c5, 0	@ Invalidate instruction TLB
	mcr	p15, 0, r0, c8, c6, 0	@ Invalidate data TLB
J
Jean Pihet 已提交
524 525 526 527 528
	/*
	 * Restore control register. This enables the MMU.
	 * The caches and prediction are not enabled here, they
	 * will be enabled after restoring the MMU table entry.
	 */
529 530 531 532 533 534
	ldmia	r3!, {r4}
	/* Store previous value of control register in scratchpad */
	str	r4, [r5, #0xC8]
	ldr	r2, cache_pred_disable_mask
	and	r4, r2
	mcr	p15, 0, r4, c1, c0, 0
535 536 537 538
	dsb
	isb
	ldr     r0, =restoremmu_on
	bx      r0
539

540 541 542 543 544
/*
 * ==============================
 * == Exit point from OFF mode ==
 * ==============================
 */
545
restoremmu_on:
J
Jean Pihet 已提交
546
	ldmfd	sp!, {r0-r12, pc}	@ restore regs and return
547

J
Jean Pihet 已提交
548 549 550 551 552

/*
 * Internal functions
 */

553
/* This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0 */
J
Jean Pihet 已提交
554
	.text
555
	.align	3
J
Jean Pihet 已提交
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
ENTRY(es3_sdrc_fix)
	ldr	r4, sdrc_syscfg		@ get config addr
	ldr	r5, [r4]		@ get value
	tst	r5, #0x100		@ is part access blocked
	it	eq
	biceq	r5, r5, #0x100		@ clear bit if set
	str	r5, [r4]		@ write back change
	ldr	r4, sdrc_mr_0		@ get config addr
	ldr	r5, [r4]		@ get value
	str	r5, [r4]		@ write back change
	ldr	r4, sdrc_emr2_0		@ get config addr
	ldr	r5, [r4]		@ get value
	str	r5, [r4]		@ write back change
	ldr	r4, sdrc_manual_0	@ get config addr
	mov	r5, #0x2		@ autorefresh command
	str	r5, [r4]		@ kick off refreshes
	ldr	r4, sdrc_mr_1		@ get config addr
	ldr	r5, [r4]		@ get value
	str	r5, [r4]		@ write back change
	ldr	r4, sdrc_emr2_1		@ get config addr
	ldr	r5, [r4]		@ get value
	str	r5, [r4]		@ write back change
	ldr	r4, sdrc_manual_1	@ get config addr
	mov	r5, #0x2		@ autorefresh command
	str	r5, [r4]		@ kick off refreshes
	bx	lr

583
	.align
J
Jean Pihet 已提交
584 585 586 587 588 589 590 591 592 593 594 595 596 597
sdrc_syscfg:
	.word	SDRC_SYSCONFIG_P
sdrc_mr_0:
	.word	SDRC_MR_0_P
sdrc_emr2_0:
	.word	SDRC_EMR2_0_P
sdrc_manual_0:
	.word	SDRC_MANUAL_0_P
sdrc_mr_1:
	.word	SDRC_MR_1_P
sdrc_emr2_1:
	.word	SDRC_EMR2_1_P
sdrc_manual_1:
	.word	SDRC_MANUAL_1_P
598
ENDPROC(es3_sdrc_fix)
J
Jean Pihet 已提交
599 600 601
ENTRY(es3_sdrc_fix_sz)
	.word	. - es3_sdrc_fix

602 603 604 605 606 607 608 609 610 611
/*
 * This function implements the erratum ID i581 WA:
 *  SDRC state restore before accessing the SDRAM
 *
 * Only used at return from non-OFF mode. For OFF
 * mode the ROM code configures the SDRC and
 * the DPLL before calling the restore code directly
 * from DDR.
 */

612 613
/* Make sure SDRC accesses are ok */
wait_sdrc_ok:
614

J
Jean Pihet 已提交
615
/* DPLL3 must be locked before accessing the SDRC. Maybe the HW ensures this */
616 617 618 619 620 621
	ldr	r4, cm_idlest_ckgen
wait_dpll3_lock:
	ldr	r5, [r4]
	tst	r5, #1
	beq	wait_dpll3_lock

J
Jean Pihet 已提交
622
	ldr	r4, cm_idlest1_core
623
wait_sdrc_ready:
J
Jean Pihet 已提交
624 625 626
	ldr	r5, [r4]
	tst	r5, #0x2
	bne	wait_sdrc_ready
627
	/* allow DLL powerdown upon hw idle req */
J
Jean Pihet 已提交
628 629 630 631
	ldr	r4, sdrc_power
	ldr	r5, [r4]
	bic	r5, r5, #0x40
	str	r5, [r4]
632

633 634 635 636 637 638
/*
 * PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a
 * base instead.
 * Be careful not to clobber r7 when maintaing this code.
 */

J
Jean Pihet 已提交
639 640 641 642 643 644 645
is_dll_in_lock_mode:
	/* Is dll in lock mode? */
	ldr	r4, sdrc_dlla_ctrl
	ldr	r5, [r4]
	tst	r5, #0x4
	bxne	lr			@ Return if locked
	/* wait till dll locks */
646
	adr	r7, kick_counter
647 648 649
wait_dll_lock_timed:
	ldr	r4, wait_dll_lock_counter
	add	r4, r4, #1
650
	str	r4, [r7, #wait_dll_lock_counter - kick_counter]
651
	ldr	r4, sdrc_dlla_status
J
Jean Pihet 已提交
652 653
	/* Wait 20uS for lock */
	mov	r6, #8
654 655 656
wait_dll_lock:
	subs	r6, r6, #0x1
	beq	kick_dll
J
Jean Pihet 已提交
657 658 659 660 661
	ldr	r5, [r4]
	and	r5, r5, #0x4
	cmp	r5, #0x4
	bne	wait_dll_lock
	bx	lr			@ Return when locked
662

663 664 665 666 667
	/* disable/reenable DLL if not locked */
kick_dll:
	ldr	r4, sdrc_dlla_ctrl
	ldr	r5, [r4]
	mov	r6, r5
J
Jean Pihet 已提交
668
	bic	r6, #(1<<3)		@ disable dll
669 670
	str	r6, [r4]
	dsb
J
Jean Pihet 已提交
671
	orr	r6, r6, #(1<<3)		@ enable dll
672 673 674 675
	str	r6, [r4]
	dsb
	ldr	r4, kick_counter
	add	r4, r4, #1
676
	str	r4, [r7]		@ kick_counter
677 678
	b	wait_dll_lock_timed

679
	.align
680 681
cm_idlest1_core:
	.word	CM_IDLEST1_CORE_V
682 683
cm_idlest_ckgen:
	.word	CM_IDLEST_CKGEN_V
684 685 686 687
sdrc_dlla_status:
	.word	SDRC_DLLA_STATUS_V
sdrc_dlla_ctrl:
	.word	SDRC_DLLA_CTRL_V
688 689
pm_prepwstst_core_p:
	.word	PM_PREPWSTST_CORE_P
690 691 692 693
pm_pwstctrl_mpu:
	.word	PM_PWSTCTRL_MPU_P
scratchpad_base:
	.word	SCRATCHPAD_BASE_P
694 695
sram_base:
	.word	SRAM_BASE_P + 0x8000
696
sdrc_power:
J
Jean Pihet 已提交
697
	.word	SDRC_POWER_V
698 699 700 701 702 703 704 705
ttbrbit_mask:
	.word	0xFFFFC000
table_index_mask:
	.word	0xFFF00000
table_entry:
	.word	0x00000C02
cache_pred_disable_mask:
	.word	0xFFFFE7FB
706 707
control_stat:
	.word	CONTROL_STAT
708 709
control_mem_rta:
	.word	CONTROL_MEM_RTA_CTRL
710
kernel_flush:
J
Jean Pihet 已提交
711
	.word	v7_flush_dcache_all
712
l2dis_3630:
J
Jean Pihet 已提交
713
	.word	0
714 715 716 717 718 719 720 721
	/*
	 * When exporting to userspace while the counters are in SRAM,
	 * these 2 words need to be at the end to facilitate retrival!
	 */
kick_counter:
	.word	0
wait_dll_lock_counter:
	.word	0
722
ENDPROC(omap34xx_cpu_suspend)
723

724 725
ENTRY(omap34xx_cpu_suspend_sz)
	.word	. - omap34xx_cpu_suspend