[PATCH] pxa978:align c2 code with open soruce

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Wenzeng Chen <wzch@xxxxxxxxxxx>

VPF/CPU mode/CP15 saved and restored by open source code
L2$ controller/debug register/performance monitor saved
and restored by our own code.

Change-Id: I5bd5209d1ca6ca79e9bba30c48b677934fd5f205
Signed-off-by: Wenzeng Chen <wzch@xxxxxxxxxxx>
---
 arch/arm/mach-pxa/ca9_asm.S                |  541 ++++------------------------
 arch/arm/mach-pxa/cmd_ca9_idle.c           |   79 +++--
 arch/arm/mach-pxa/dvfm.c                   |    3 -
 arch/arm/mach-pxa/include/mach/ca9_asm.h   |   12 +-
 arch/arm/mach-pxa/include/mach/ca9_regs.h  |   82 -----
 arch/arm/mach-pxa/include/mach/pxa95x_pm.h |   10 +-
 arch/arm/mach-pxa/mspm_idle.c              |    8 +-
 arch/arm/mach-pxa/pxa95x_pm.c              |   27 +-
 8 files changed, 142 insertions(+), 620 deletions(-)
 delete mode 100644 arch/arm/mach-pxa/include/mach/ca9_regs.h

diff --git a/arch/arm/mach-pxa/ca9_asm.S b/arch/arm/mach-pxa/ca9_asm.S
index 62bad28..dc74715 100644
--- a/arch/arm/mach-pxa/ca9_asm.S
+++ b/arch/arm/mach-pxa/ca9_asm.S
@@ -1,15 +1,8 @@
-#define PWRMODE_REG	0x40f40080
-
-#define mode_usr	0x10
-#define mode_fiq	0x11
-#define mode_irq	0x12
-#define mode_svc	0x13
-#define mode_abt	0x17
-#define mode_und	0x1b
-#define mode_sys	0x1f
-
-
-
+#include <asm/hardware/cache-l2x0.h>
+#define PXA978_L2CACHE_BASE		0x58120000
+#define OSCR_PHY_ADDR			0x40A00010
+#define OSCR_VIRTUAL_ADDR		0xF2A00010
+#define POWER_MODE_BASE		0x40F40080
 	.global dump_cop_regs
 dump_cop_regs:
 	stmfd	sp!, {r4-r12,lr}
@@ -68,137 +61,18 @@ dump_cop_regs:
 
 	ldmfd	sp!,{r4-r12,pc}
 
-	.global save_pl310
-save_pl310:
-	stmfd	sp!, {r4-r12,lr}   @r0 context, r1 pl310 virtual address
-	ldr   r2,   [r1, #0x100]			@ control
-	str   r2,  [r0]
-	ldr   r2,  [r1, #0x104]			@aux_control
-	str   r2,  [r0, #4]
-	ldr   r2,  [r1, #0x108]			@tag_ram_control
-	str   r2,  [r0, #8]
-	ldr   r2,  [r1, #0x10C]			@data_ram_control
-	str   r2,  [r0, #12]
-	ldr   r2,  [r1, #0x200]			@ev_counter_ctrl
-	str   r2,  [r0, #16]
-	ldr   r2,  [r1, #0x204]			@ev_counter1_cfg
-	str   r2,  [r0, #20]
-	ldr   r2,  [r1, #0x208]			@ev_counter0_cfg
-	str   r2,  [r0, #24]
-	ldr   r2,  [r1, #0x20C]			@ev_counter1
-	str   r2,  [r0, #28]
-	ldr   r2,  [r1, #0x210]			@ev_counter0
-	str   r2,  [r0, #32]
-	ldr   r2,  [r1, #0x214]			@int_mask
-	str   r2,  [r0, #36]
-	ldr   r2,  [r1, #0x950]			@lock_line_en
-	str   r2,  [r0, #40]
-
-	mov r2, r0
-	mov r3, #0
-LOOP1:
-	add r4, r3, #288			@lockdown_reg
-	add r3, r3, #1
-	cmp r3, #8
-	add r5, r1,r4, lsl #3
-	ldr  r6, [r5]
-	ldr  r4, [r5, #4]
-	str  r6,  [r2, #44]
-	str  r4,  [r2, #48]
-	add r2, r2,#8
-	bne LOOP1
-	ldr   r2,  [r1, #0xF40]		@debug_ctrl
-	str   r2,  [r0, #120]
-	ldr   r2,  [r1, #0xF60]		@prefetch_ctrl
-	str   r2,  [r0, #124]
-	ldr   r2,  [r1, #0xF80]		@power_ctrl
-	str   r2,  [r0, #128]
-	add r1, r0, #132  		@ the size of pl310_context
-	@.extern flushL2VaRange	@ we call clean all before WFI, so this one is uncessary
-	@bl	flushL2VaRange
-	ldmfd	 sp!, {r4-r12,pc}
-
-	.global restore_pl310
-restore_pl310:
-	@r0 context, r1 pl310 virtual address
-	ldr r3, [r1, #0x100]		@control
-	cmp r3, #0
-	beq restore_reg
-	mov r3, #0
-	str  r3, [r1, #0x730]            @cache sync
+	.global pxa978_enter_c1
+pxa978_enter_c1:
 	dsb
-	str  r3, [r1, #0x100] 		@control
-restore_reg:
-	ldr r3, [r0, #4]			@aux control
-	str r3, [r1, #0x104]
-	ldr r3, [r0, #8]			@tag_ram_control
-	str r3, [r1, #0x108]
-	ldr r3, [r0, #12]			@data_ram_control
-	str r3, [r1, #0x10C]
-	ldr r3, [r0, #16]			@ev_counter_ctrl
-	str r3, [r1, #0x200]
-	ldr r3, [r0, #20]			@ev_counter1_cfg
-	str r3, [r1, #0x204]
-	ldr r3, [r0, #24]			@ev_counter0_cfg
-	str r3, [r1, #0x208]
-	ldr r3, [r0, #28]			@ev_counter1
-	str r3, [r1, #0x20C]
-	ldr r3, [r0, #32]			@ev_counter0
-	str r3, [r1, #0x210]
-	ldr r3, [r0, #36]			@int_mask
-	str r3, [r1, #0x214]
-	ldr r3, [r0, #40]			@lock_line_en
-	str r3, [r1, #0x950]
-	mov r3, #0
-	mov r5, r0
-LOOP2:
-	add r4, r3, #288		@lockdown_reg
-	ldr r6, [r5, #44]
-	ldr r7, [r5, #48]
-	add r3, r3, #1
-	add r8, r1, r4, lsl #3
-	cmp r3, #8
-	str r6, [r8]
-	str r7, [r8, #4]
-	add r5, r5, #8
-	bne LOOP2
-	ldr r3, [r0, #120]		@debug_ctrl
-	str r3, [r1, #0xF40]
-	ldr r3, [r0, #124]		@prefetch_ctrl
-	str r3, [r1, #0xF60]
-	ldr r3, [r0, #128]		@power_ctrl
-	str r3, [r1, #0xF80]
-	dsb
-	mov r4, r0
-	mov r5, r1
-	cmp r2, #0
-	.extern invalidL2All
-	blne	invalidL2All
-	ldr r3, [r4]
-	str r3, [r5, #0x100]
-	dsb
-	pop  {r4-r12,pc}
-
-	.global ca9_enter_c2_wrapper
-ca9_enter_c2_wrapper:
-	push {r4-r12,lr}
-	mov  r4,r0
-	mov  r5,r1
-	mov  r6,r2
-	mov  r7,r3
-	bl	 save_pl310
-	mov  r0, r7
-	bl	 ca9_enter_c2
-	mov  r0, r4
-	mov  r1, r5
-	mov  r2, r6
-	b restore_pl310
-
-	.global ca9_enter_c2
-ca9_enter_c2:
-	stmfd	sp!, {r4-r12,lr}
-	@ align: [13..0]=0
+	wfi
+	bx	lr
 
+	.global pxa978_cpu_suspend
+pxa978_cpu_suspend:
+	cmp	r2, #0x0
+	beq	pxa978_enter_c1
+	mov 	r6, r1		@l2c base address virtual
+	mov	r7, r3		@PWR_MODE
 	mov	r2, r0, lsr #14
 	mov	r2, r2, lsl #14
 @ copy reset handler to SRAM
@@ -206,262 +80,75 @@ ca9_enter_c2:
 	ldrd	r0, [r3]
 	strd	r0, [r2]
 
-	adr	r0, ca9_c2_restore
-	bl	VirtualToPhysical @ modified r0,r1
+	adr	r0, pxa978_c2_restore
+	bl	VirtualToPhysical 	@ modified r0,r1
 	str	r0, [r2, #0x08]
 
 	add	r0, r2, #0x10
 	mov	r5, r0
-	bl	VirtualToPhysical @ modified r0,r1
+	bl	VirtualToPhysical 	@ modified r0,r1
 	str	r0, [r2, #0x0c]
 	mov	r0, r5
-
-@ Save CPU registers
-	cps	#mode_abt
-	mrs	r1, spsr
-	stm	r0!,{r1,sp,lr}
-	cps	#mode_und
-	mrs	r1, spsr
-	stm	r0!,{r1,sp,lr}
-	cps	#mode_sys
-	stm	r0!,{sp,lr}
-	cps	#mode_irq
-	mrs	r1, spsr
-	stm	r0!,{r1,sp,lr}
-	cps	#mode_fiq
-	mrs	r1, spsr
-	stm	r0!,{r1,r8-r12,sp,lr}
-	cps	#mode_svc
-	mrs	r1,spsr
-	stm	r0!,{r1,sp} @ others will be restored from stack when exiting
-	bic	r1, r1, #0x1f @ clear mode
-	orr	r1, r1, #mode_usr
-	msr	spsr, r1
-	stm	r0,{sp,lr}^	@ fetch user mode regs as spsr is set to user mode
-	add	r0,r0,#8	@ Cannot use base register update in stm above
-	@ don't restore svc mode spsr as we won't need it until restored later
-@ Save cp15
-	mrc	p15,2,r1,c0,c0,0	@ CSSELR
-	mrc	p15,0,r2,c1,c0,1	@ ACTLR
-	mrc	p15,0,r3,c1,c0,0	@ SCTLR
-	mrc	p15,0,r4,c1,c0,2	@ CPACR
-	stm	r0!, {r1-r4}
-
-	mrc p15,0,r1,c1,c0,0   @ SCTLR	 disable L1 cache
-	bic r1, r1, #0x1000
-	bic r1, r1, #0x0004
-	mcr p15,0,r1,c1,c0,0
-
-	mrc	p15,0,r1,c12,c0,0	@ VBAR
-	mrc	p15,0,r2,c2,c0,0	@ TTBR0
-	mrc	p15,0,r3,c2,c0,1	@ TTBR1
-	mrc	p15,0,r4,c2,c0,2	@ TTBCR
-	stm	r0!, {r1-r4}
-
-	mrc	p15,0,r1,c3,c0,0	@ DACR
-	mrc	p15,0,r2,c7,c4,0	@ PAR
-	mrc	p15,0,r3,c10,c2,0	@ PRRR
-	mrc	p15,0,r4,c10,c2,1	@ NMRR
-	stm	r0!, {r1-r4}
-
-	@ TBD:    CP15 registers 9 and 11
-	mrc	p15,0,r1,c13,c0,1	@ CONTEXTIDR
-	mrc	p15,0,r2,c13,c0,2	@ TPIDRURW
-	mrc	p15,0,r3,c13,c0,3	@ TPIDRURO
-	mrc	p15,0,r4,c13,c0,4	@ TPIDRPRW
-	stm	r0!, {r1-r4}
-
-	@ Adding new coop regs ASTODO
-	mrc	p15,0,r1,c12,c0,1	@ MVBAR
-	mrc	p15,5,r2,c15,c5,2	@ Main TLB VA register
-	mrc	p15,5,r3,c15,c6,2	@ Main TLB PA register
-	mrc	p15,5,r4,c15,c7,2	@ Main TLB Attribute
-	stm	r0!, {r1-r4}
-
-	@ Adding new coop regs ASTODO
-	mrc	p15,0,r1,c1,c1,0	@ SCRd
-	mrc	p15,0,r2,c1,c1,1	@ SDERc
-	mrc	p15,0,r3,c1,c1,2	@ NSACR
-	mrc	p15,0,r4,c1,c1,3	@ VCR
-	stm	r0!, {r1-r4}
-
-	@ Adding new coop regs ASTODO
-	mrc	p15,0,r1,c10,c0,0	@ TLB Lockdown Register
-	mrc	p15,0,r2,c12,c1,1	@ Virtualization Interrupt Register
-	mrc	p15,0,r3,c13,c0,0	@ FCSEIDR
-	mrc	p15,0,r4,c13,c0,1	@ CONTEXTIDR
-	stm	r0!, {r1-r4}
-
-	mrc	p15,0,r1,c15,c0,0	@ power control reg
-	str	r1, [r0], #4
-	mrc	p15,0,r1,c0,c0,0	@ Read Main ID Register
-	ubfx	r1, r1, #20, #4		@ Extract major version number
-	cmp	r3, #2
-	blt	savenople		@ PLE only possible in r2p0 onwards
-	mrc	p15,0,r1,c11,c0,0	@ Read PLE IDR
-	cmp	r3, #0
-	beq	savenople		@ No PLE present
-
-	mrc	p15,0,r1,c11,c1,0	@ Read PLE UAR
-	mrc	p15,0,r2,c11,c1,1	@ Read PLE PCR
-	stm	r0!, {r1, r2}
-savenople:
-@ Clean and invalidate L1 D-cache: this does not survive C2
-@	.extern cleanAndInvalidateCache
-@	bl	cleanAndInvalidateCache
-
-@	v7_flush_dcache_all corrupts r0-r7, r9-r11
-	.extern v7_flush_dcache_all
-	push	{r0-r7,r9-r11}
-	bl	v7_flush_dcache_all
-	pop		{r0-r7,r9-r11}
-
-	.extern v7_flush_icache_all
-	bl v7_flush_icache_all
-	@ Clean L2 areas that will be used on restore before L2 is reenabled
-	@mov	r0, sp
-	@add r1, r0, #0x40 @ actually 9 regs saved on stack
-	@.extern flushL2VaRange
-	@bl	flushL2VaRange
-	@mmu page table may in L2 cache,  it is diffcult to get page table addr
-	@so we clean all L2 cache as a temp WR
-	.extern cleanL2VaRange
-	bl	cleanL2VaRange
-@ C2 entry
+save_pl310:
+	ldr	r1, [r6, #L2X0_CTRL]
+	ldr 	r2, [r6, #L2X0_AUX_CTRL]
+	ldr 	r3, [r6, #L2X0_TAG_LATENCY_CTRL]
+	ldr 	r4, [r6, #L2X0_DATA_LATENCY_CTRL]
+	stm 	r0!,{r1-r4}
+	ldr 	r1, [r6, #L2X0_PREFETCH_CTRL]
+	ldr 	r2, [r6, #L2X0_POWER_CTRL]
+	stm 	r0!,{r1-r2}
+/*C2 entry*/
 	dsb
 	wfi
-@ in case a wakeup is pending, CPU will fall through without being reset!
+/*in case a wakeup is pending, CPU will fall through without being reset!*/
  .align 5
-	mov	r0, r5 @ setup the saved register base and restore as usual
-	ldr r8, =0xf2e0011c
-	mov r9, #0x2000
-	str r9, [r8]
-	mov r5, #0x1
+	mov	r0, r5 	@ setup the saved register base and restore as usual
+	ldr	r1, =OSCR_VIRTUAL_ADDR
 	b set_l2_redundency
-@ return here from reset chunk
-ca9_c2_restore:
+/*return here from reset chunk*/
+pxa978_c2_restore:
+	ldr	r6, =PXA978_L2CACHE_BASE
+	ldr 	r1, =OSCR_PHY_ADDR
+	ldr	r2, =POWER_MODE_BASE
+	ldr	r7, [r2]
+	and	r7, r7, #0x40
 set_l2_redundency:
-@	mov r2, #0xC3	@60usec
+	mov	r2, #0xC3		@60usec
 @	mov r2, #0x140
-@	orr r2, #0x5	@100usec
-	mov r2, #0x790
-	orr r2, #0xE 	@600usec
-
-	cmp r5, #0x1
-	bne no_mmu
-	ldr r1,=0xf2a00010
+@	orr r2, #0x5		@100usec
+@	mov r2, #0x790
+@	orr r2, #0xE 		@600usec
 	ldr r3, [r1]
-	b loop
-
-no_mmu:
-	ldr r1,=0x40a00010
-	ldr r3, [r1]
-	b loop
 loop:
 	ldr r4, [r1]
 	sub r4, r4, r3
 	cmp r4, r2
 	ble loop
-	cps	#mode_abt
-	ldm	r0!,{r1,sp,lr}
-	msr	spsr, r1
-	cps	#mode_und
-	ldm	r0!,{r1,sp,lr}
-	msr	spsr, r1
-	cps	#mode_sys
-	ldm	r0!,{sp,lr}
-	msr	spsr, r1
-	cps	#mode_irq
-	ldm	r0!,{r1,sp,lr}
-	msr	spsr, r1
-	cps	#mode_fiq
-	ldm	r0!,{r1,r8-r12,sp,lr}
-	msr	spsr, r1
-	cps	#mode_svc
-	ldm	r0!,{r1,sp} @ others will be restored from stack when exiting
-	mov	r2, r1
-	bic	r1, r1, #0x1f @ clear mode
-	orr	r1, r1, #mode_usr
-	msr	spsr, r1
-	ldm	r0,{sp,lr}^	@ set user mode regs as spsr is set to user mode
-	add	r0,r0,#8	@ cannot use base register update in ldm above
-	msr	spsr, r2	@ now restore the svc mode spsr
-@ Restore cp15
-	ldm	r0!, {r1-r4}
-	mcr	p15,2,r1,c0,c0,0	@ CSSELR
-	mcr	p15,0,r2,c1,c0,1	@ ACTLR
-	@ mcr	p15,0,r3,c1,c0,0	@ SCTLR
-	mov	r5, r3			@ keep until ready to enable MMU
-	mcr	p15,0,r4,c1,c0,2	@ CPACR
-
-	ldm	r0!, {r1-r4}
-	mcr	p15,0,r1,c12,c0,0	@ VBAR
-	mcr	p15,0,r2,c2,c0,0	@ TTBR0
-	mcr	p15,0,r3,c2,c0,1	@ TTBR1
-	mcr	p15,0,r4,c2,c0,2	@ TTBCR
-
-	ldm	r0!, {r1-r4}
-	mcr	p15,0,r1,c3,c0,0	@ DACR
-	mcr	p15,0,r2,c7,c4,0	@ PAR
-	mcr	p15,0,r3,c10,c2,0	@ PRRR
-	mcr	p15,0,r4,c10,c2,1	@ NMRR
-
-	@ TBD:    CP15 registers 9 and 11
-	ldm	r0!, {r1-r4}
-	mcr	p15,0,r1,c13,c0,1	@ CONTEXTIDR
-	mcr	p15,0,r2,c13,c0,2	@ TPIDRURW
-	mcr	p15,0,r3,c13,c0,3	@ TPIDRURO
-	mcr	p15,0,r4,c13,c0,4	@ TPIDRPRW
-
-	@ Adding new coop regs ASTODO
-	ldm	r0!, {r1-r4}
-	mcr	p15,0,r1,c12,c0,1	@ MVBAR
-	mcr	p15,5,r2,c15,c5,2	@ Main TLB VA register
-	mcr	p15,5,r3,c15,c6,2	@ Main TLB PA register
-	mcr	p15,5,r4,c15,c7,2	@ Main TLB Attribute
-
-	@ Adding new coop regs ASTODO
-	ldm	r0!, {r1-r4}
-	mcr	p15,0,r1,c1,c1,0	@ SCRd
-	mcr	p15,0,r2,c1,c1,1	@ SDERc
-	mcr	p15,0,r3,c1,c1,2	@ NSACR
-	mcr	p15,0,r4,c1,c1,3	@ VCR
-
-	@ Adding new coop regs ASTODO
-	ldm	r0!, {r1-r4}
-	mrc	p15,0,r1,c10,c0,0	@ TLB Lockdown Register
-	mrc	p15,0,r2,c12,c1,1	@ Virtualization Interrupt Register
-	mrc	p15,0,r3,c13,c0,0	@ FCSEIDR
-	mrc	p15,0,r4,c13,c0,1	@ CONTEXTIDR
-
-	@ others
-	ldr	r1, [r0], #4
-	mcr	p15,0,r1,c15,c0,0	@ power control reg
-	mrc	p15,0,r1,c0,c0,0	@ Read Main ID Register
-	ubfx	r1, r1, #20, #4		@ Extract major version number
-	cmp	r3, #2
-	blt	restorenople		@ PLE only possible in r2p0 onwards
-	mrc	p15,0,r1,c11,c0,0	@ Read PLE IDR
-	cmp	r3, #0
-	beq	restorenople		@ No PLE present
-
-	ldm	r0!, {r1, r2}
-	mcr	p15,0,r1,c11,c1,0	@ set PLE UAR
-	mcr	p15,0,r2,c11,c1,1	@ set PLE PCR
-restorenople:
-	@ Enable MMU now
-	ldr	r0, return_addr		@ this addr is with MMU on
-	b	cont
-.align 5
-cont:
-	mcr	p15,0,r5,c1,c0,0	@ SCTLR
-	bx	r0
-return_on_exit:
-	ldmfd	sp!,{r4-r12,pc}
-return_addr:
-	.long	return_on_exit
-
-@ reset handler for C2 exit
+	cmp 	r7, #0
+	beq	restore_pl310
+pl310_inv_all:
+	mov	r1, #0xFF
+	str 	r1, [r6, #L2X0_INV_WAY]
+inv_wait:
+	ldr	r2, [r6,#L2X0_INV_WAY]
+	and 	r2, r2, r1
+	cmp 	r2, #0
+	bne	inv_wait
+	str	r2, [r6, #L2X0_CACHE_SYNC]
+restore_pl310:
+	ldm 	r0!, {r2-r5}
+	str	r3, [r6, #L2X0_AUX_CTRL]
+	str	r4, [r6, #L2X0_TAG_LATENCY_CTRL]
+	str	r5, [r6, #L2X0_DATA_LATENCY_CTRL]
+	ldm 	r0!, {r3-r4}
+	str	r3, [r6, #L2X0_PREFETCH_CTRL]
+	str	r4, [r6, #L2X0_POWER_CTRL]
+	mov	r2, #1
+	str	r2, [r6, #L2X0_CTRL]		@enable L2$
+	b cpu_resume
+
+/*reset handler for C2 exit */
 reset_chunk:
 	ldr	r0, c2_data
 	ldr	pc, c2_restore
@@ -483,94 +170,6 @@ VirtualToPhysical:
 	orr	r0, r0, r1
 	bx	lr
 
-	.fpu    neon
-/* See arch/arm/include/asm/vfp.h */
-#define FPEXC		cr8
-#define FPSCR		cr1
-#define MVFR0		cr7
-	.macro  VMRS, rd, sysreg, cond
-	MRC\cond        p10, 7, \rd, \sysreg, cr0, 0    @ FMRX  \rd, \sysreg
-	.endm
-
-	.macro  VMSR, sysreg, rd, cond
-	MCR\cond        p10, 7, \rd, \sysreg, cr0, 0    @ FMXR  \sysreg, \rd
-	.endm
-
-	.global save_vfp
-save_vfp:
-        @ FPU state save/restore.
-        @ FPSID,MVFR0 and MVFR1 don't get serialized/saved (Read Only).
-	MRC	p15,0,r3,c1,c0,2	@ CPACR allows CP10 and CP11 access
-	ORR	r2,r3,#0xF00000
-	MCR	p15,0,r2,c1,c0,2
-	ISB
-	MRC	p15,0,r2,c1,c0,2
-	AND	r2,r2,#0xF00000
-	CMP	r2,#0xF00000
-	BEQ	L000
-	MOVS	r2, #0
-	@ Override to 0 to indicate that no FPU is present
-	@	STR     r2,[r11,#DM_VFP]		; TODO: autodetect VFP in C!!
-	B	L001
-
-L000:	@	Save configuration registers and enable.
-	VMRS	r12,FPEXC
-	STR	r12,[r0],#4		@ Save the FPEXC
-        @ Enable FPU access to save/restore the other registers.
-	LDR	r2,=0x40000000
-	VMSR	FPEXC,r2
-	VMRS	r2,FPSCR
-	STR	r2,[r0],#4		@ Save the FPSCR
-        @ Store the VFP-D16 registers.
-	VSTM	r0!, {D0-D15}
-        @ Check for Advanced SIMD/VFP-D32 support
-	VMRS	r2,MVFR0
-	AND	r2,r2,#0xF		@ extract the A_SIMD bitfield
-	CMP	r2, #0x2
-	BLT	L001
-        @ Store the Advanced SIMD/VFP-D32 additional registers.
-	VSTM	r0!, {D16-D31}
-
-		@ IMPLEMENTATION DEFINED: save any subarchitecture defined state
-		@ NOTE: Don't change the order of the FPEXC and CPACR restores
-	VMSR	FPEXC,r10         @ Restore the original En bit of FPU.
-L001:
-	MCR	p15,0,r3,c1,c0,2 @ Restore the original CPACR value.
-	BX	lr
-
-	.global restore_vfp
-restore_vfp:
-	@ FPU state save/restore. Obviously FPSID,MVFR0 and MVFR1 don't get
-	@ serialized (RO).
-	@ Modify CPACR to allow CP10 and CP11 access
-	MRC	p15,0,r2,c1,c0,2
-	ORR	r2,r2,#0x00F00000
-	MCR	p15,0,r2,c1,c0,2
-	@ Enable FPU access to save/restore the rest of registers.
-	LDR	r2,=0x40000000
-	VMSR	FPEXC, r2
-	@ Recover FPEXC and FPSCR. These will be restored later.
-	LDM	r0!,{r3,r12}
-	@ Restore the VFP-D16 registers.
-	VLDM	r0!, {D0-D15}
-	@ Check for Advanced SIMD/VFP-D32 support
-	VMRS	r2, MVFR0
-	AND	r2,r2,#0xF		@ extract the A_SIMD bitfield
-	CMP	r2, #0x2
-	BLT	L0000
-
-	@ Store the Advanced SIMD/VFP-D32 additional registers.
-	VLDM	r0!, {D16-D31}
-
-	@ IMPLEMENTATION DEFINED: restore any subarchitecture defined state
-
-L0000:	@ Restore configuration registers and enable.
-	@ Restore FPSCR _before_ FPEXC since FPEXC could disable FPU
-	@ and make setting FPSCR unpredictable.
-	VMSR	FPSCR,r12
-	VMSR	FPEXC,r3		@ Restore FPEXC after FPSCR
-	BX	lr
-
 	.global save_performance_monitors
 save_performance_monitors:
 	PUSH	{r4, r8, r9, r10}
@@ -690,8 +289,8 @@ L40:	MCR	p15,0,r1,c9,c12,0	@ clear the PMCR global enable bit
 	POP	{r4-r5, r8-r10, pc}
 
 	@ Debug: see DDI0388F, 10.2.1
-	.global save_ca9_debug
-save_ca9_debug:
+	.global save_pxa978_debug
+save_pxa978_debug:
 @	push	{r4}
 	push	{r1-r4}
 	mrc	p14, 0, r1, c0, c6, 0
@@ -731,8 +330,8 @@ save_ca9_debug:
 @	pop	{r4}
 	pop	{r1-r4}
 	bx	lr
-	.global restore_ca9_debug
-restore_ca9_debug:
+	.global restore_pxa978_debug
+restore_pxa978_debug:
 @	push	{r4}
 	push	{r1-r4}
 	ldm	r0!,{r1-r4}
diff --git a/arch/arm/mach-pxa/cmd_ca9_idle.c b/arch/arm/mach-pxa/cmd_ca9_idle.c
index 992d9e1..3849da9 100644
--- a/arch/arm/mach-pxa/cmd_ca9_idle.c
+++ b/arch/arm/mach-pxa/cmd_ca9_idle.c
@@ -17,12 +17,17 @@
  *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  */
-
 #include <mach/ca9_asm.h>
-#include <mach/ca9_regs.h>
-#include <mach/pxa95x_pm.h>
 #include <asm/outercache.h>
+#include <linux/suspend.h>
+#include <asm/cacheflush.h>
+#include <asm/suspend.h>
+#include <linux/cpu_pm.h>
+#include <mach/pxa95x_pm.h>
+#include <asm/io.h>
 #include <mach/pxa3xx-regs.h>
+#include <linux/delay.h>
+
 /* Part of the code based on the below ARM code and modified */
 /*
  * Copyright (C) 2008-2010 ARM Limited
@@ -44,43 +49,53 @@
  *		misrepresented as being the original software.
  * 3. This notice may not be removed or altered from any source distribution.
  */
-
-#define __nop() do { asm volatile ("nop" : : : "memory"); } while (0)
-
-void flushL2VaRange(phys_addr_t start, phys_addr_t end)
+#define PWRMODE_L2_DIS_IN_C2 0x40
+static int pxa978_suspend_finish(unsigned int core_mode)
 {
-	outer_flush_range(VirtualToPhysical(start), VirtualToPhysical(end));
+	unsigned int power_mode = PWRMODE;
+	if (power_mode & PWRMODE_L2_DIS_IN_C2) {
+		/* In L2$ non-retentive mode, two option:
+		 *1. clean all before c2, inv all after c2
+		 *2. flush all before c2
+		 *but we mush use the first one. for after power on, L2 is
+		 *in an unpredicatable state of all data, tag, status bit
+		 */
+		/*this will actually call clean_all() */
+		outer_clean_range(0, 0xFFFFFFFF);
+	}
+	pxa978_cpu_suspend(get_c2_sram_base(), pl310_membase, core_mode,
+			   power_mode & PWRMODE_L2_DIS_IN_C2);
+	return 0;
 }
 
-void cleanL2VaRange(phys_addr_t start, phys_addr_t end)
+void c2_address_unremap(void)
 {
-	/*actually this will clean all because the range > L2 cache size*/
-	outer_clean_range(0, 0x10000000);
+	__raw_writel(0, remap_c2_reg);
 }
-void invalidL2All(void)
+
+void c2_address_remap(void)
 {
-	outer_inv_all();
+	unsigned c2_addr = VirtualToPhysical(get_c2_sram_base());
+	__raw_writel(((c2_addr >> 13) | 1) & 0x1FFF, remap_c2_reg);
 }
 
-#define PWRMODE_L2_DIS_IN_C2 0x40
-
-void ca9_enter_idle(unsigned int pwrmode, unsigned int sramaddr, unsigned int l2c_base_address)
+void pxa978_pm_enter(unsigned int core_mode)
 {
-	struct pl310_context pl310;
-	unsigned int remap_addr = VirtualToPhysical(sramaddr);
-	unsigned int pmu_context[PMU_DATA_SIZE/sizeof(unsigned int)];
-	unsigned int vfp_context[VFP_DATA_SIZE/sizeof(unsigned int)];
-	unsigned int debug_context[DEBUG_DATA_SIZE/sizeof(unsigned int)];
-	/* Remap 0 physical to SRAM so reset will runs the C2 restore code */
-	*remap_c2_reg = ((remap_addr>>13)|1)&0x1fff;
-	save_vfp((unsigned int *)&vfp_context);
-	save_ca9_debug((unsigned int *)&debug_context);
-	save_performance_monitors((unsigned int *)&pmu_context);
-
-	ca9_enter_c2_wrapper(&pl310, l2c_base_address, pwrmode & PWRMODE_L2_DIS_IN_C2, sramaddr);
+	unsigned int debug_context[DEBUG_DATA_SIZE / sizeof(unsigned int)];
+	unsigned int pmu_context[PMU_DATA_SIZE / sizeof(unsigned int)];
+	if (core_mode == PWRDM_POWER_C2) {
+		c2_address_remap();
+		save_pxa978_debug((unsigned int *)&debug_context);
+		save_performance_monitors((unsigned int *)&pmu_context);
+		cpu_pm_enter();
+		cpu_suspend(core_mode, pxa978_suspend_finish);
+	} else	if (core_mode == PWRDM_POWER_C1)
+		pxa978_suspend_finish(core_mode);
 
-	restore_performance_monitors((unsigned int *)&pmu_context);
-	restore_ca9_debug((unsigned int *)&debug_context);
-	restore_vfp((unsigned int *)&vfp_context);
-	*remap_c2_reg = 0;
+	if (core_mode == PWRDM_POWER_C2) {
+		cpu_pm_exit();
+		restore_performance_monitors((unsigned int *)&pmu_context);
+		restore_pxa978_debug((unsigned int *)&debug_context);
+		c2_address_unremap();
+	}
 }
diff --git a/arch/arm/mach-pxa/dvfm.c b/arch/arm/mach-pxa/dvfm.c
index 90d8517..ed76ba1 100644
--- a/arch/arm/mach-pxa/dvfm.c
+++ b/arch/arm/mach-pxa/dvfm.c
@@ -285,14 +285,11 @@ static ssize_t dvfm_c2_allow_store(struct sys_device *sys_dev,
 	return len;
 }
 
-extern unsigned int *remap_c2_reg;
-
 static ssize_t dvfm_c2_allow_show(struct sys_device *sys_dev,
 			  struct sysdev_attribute *attr, char *buf)
 {
 	unsigned int len;
 	printk("\n [%s] c2_allow = %d", __func__, c2_allow);
-	printk("\n [%s] REMAP reg = 0x%x, value = 0x%x", __func__, remap_c2_reg, *remap_c2_reg);
 	return len;
 }
 SYSDEV_ATTR(c2_allow, 0644, dvfm_c2_allow_show, dvfm_c2_allow_store);
diff --git a/arch/arm/mach-pxa/include/mach/ca9_asm.h b/arch/arm/mach-pxa/include/mach/ca9_asm.h
index 350daa9..db3e354 100644
--- a/arch/arm/mach-pxa/include/mach/ca9_asm.h
+++ b/arch/arm/mach-pxa/include/mach/ca9_asm.h
@@ -1,21 +1,17 @@
-
 unsigned VirtualToPhysical(unsigned);
 /*-----------------------------------------------------------------*/
 #define PMU_DATA_SIZE               128
 void save_performance_monitors(unsigned int *pointer);
 void restore_performance_monitors(unsigned int *pointer);
 /*-----------------------------------------------------------------*/
-#define VFP_DATA_SIZE               288
-void save_vfp(unsigned int *pointer);
-void restore_vfp(unsigned int *pointer);
-/*-----------------------------------------------------------------*/
 #define DEBUG_DATA_SIZE               128
-void save_ca9_debug(unsigned int *pointer);
-void restore_ca9_debug(unsigned int *pointer);
+void save_pxa978_debug(unsigned int *pointer);
+void restore_pxa978_debug(unsigned int *pointer);
 /*-----------------------------------------------------------------*/
 /* Critical registers saved/restored inside one assembly function.
 sramaddr[13..0]=0 is enforced.
 These registers are saved in SRAM at the given address,
 right after the reset vector code. Aproximae size: 0xc0 bytes.
 */
-void ca9_enter_c2_wrapper(struct pl310_context *pl310, unsigned l2c_base_address, unsigned pwrmode, unsigned sramaddr);
+void pxa978_cpu_suspend(unsigned int sramaddr, unsigned int l2c_base_address,
+			unsigned int core_mode, unsigned int pwrmode);
diff --git a/arch/arm/mach-pxa/include/mach/ca9_regs.h b/arch/arm/mach-pxa/include/mach/ca9_regs.h
deleted file mode 100644
index b259185..0000000
--- a/arch/arm/mach-pxa/include/mach/ca9_regs.h
+++ /dev/null
@@ -1,82 +0,0 @@
-
-#include <linux/kernel.h>
-
-#define L2310_ADDR_START 0x58120000
-#define L2310_ADDR_END	 0x58120FFF
-
-struct lockdown_regs {
-	unsigned int d, i;
-};
-
-struct pl310_registers {
-	const unsigned cache_id;
-	const unsigned cache_type;
-	char padding1[0x0F8];
-	volatile unsigned control;
-	volatile unsigned aux_control;
-	volatile unsigned tag_ram_control;
-	volatile unsigned data_ram_control;
-	char padding2[0x0F0];
-	volatile unsigned ev_counter_ctrl;
-	volatile unsigned ev_counter1_cfg;
-	volatile unsigned ev_counter0_cfg;
-	volatile unsigned ev_counter1;
-	volatile unsigned ev_counter0;
-	volatile unsigned int_mask;
-	const volatile unsigned int_mask_status;
-	const volatile unsigned int_raw_status;
-	volatile unsigned int_clear;
-	char padding3[0x50C];
-	volatile unsigned cache_sync;
-	char padding4[0x03C];
-	volatile unsigned inv_pa;
-	char padding5[0x008];
-	volatile unsigned inv_way;
-	char padding6[0x030];
-	volatile unsigned clean_pa;
-	char padding7[0x004];
-	volatile unsigned clean_index;
-	volatile unsigned clean_way;
-	char padding8[0x030];
-	volatile unsigned clean_inv_pa;
-	char padding9[0x004];
-	volatile unsigned clean_inv_index;
-	volatile unsigned clean_inv_way;
-	char paddinga[0x100];
-	volatile struct lockdown_regs lockdown[8];
-	char paddingb[0x010];
-	volatile unsigned lock_line_en;
-	volatile unsigned unlock_way;
-	char paddingc[0x2A8];
-	volatile unsigned addr_filtering_start;
-	volatile unsigned addr_filtering_end;
-	char paddingd[0x338];
-	volatile unsigned debug_ctrl;
-	char paddinge[0x01C];
-	volatile unsigned prefetch_ctrl;
-	char paddingf[0x01C];
-	volatile unsigned power_ctrl;
-	unsigned int *memset;
-};
-
-
-struct pl310_context {
-	unsigned int control;
-	unsigned int aux_control;
-	unsigned int tag_ram_control;
-	unsigned int data_ram_control;
-	unsigned int ev_counter_ctrl;
-	unsigned int ev_counter1_cfg;
-	unsigned int ev_counter0_cfg;
-	unsigned int ev_counter1;
-	unsigned int ev_counter0;
-	unsigned int int_mask;
-	unsigned int lock_line_en;
-	struct lockdown_regs lockdown[8];
-	unsigned int unlock_way;
-	unsigned int addr_filtering_start;
-	unsigned int addr_filtering_end;
-	unsigned int debug_ctrl;
-	unsigned int prefetch_ctrl;
-	unsigned int power_ctrl;
-};
diff --git a/arch/arm/mach-pxa/include/mach/pxa95x_pm.h b/arch/arm/mach-pxa/include/mach/pxa95x_pm.h
index 7163df6..642bab1 100644
--- a/arch/arm/mach-pxa/include/mach/pxa95x_pm.h
+++ b/arch/arm/mach-pxa/include/mach/pxa95x_pm.h
@@ -371,6 +371,11 @@
 #define SleepState_end			(SleepState_flushFunc + WORD_SIZE)
 #define SleepState_size			(SleepState_end - SleepState_begin)
 
+/*pxa978 core power mode*/
+#define PWRDM_POWER_C1		0x0
+#define PWRDM_POWER_C2		0x1
+
+
 #ifndef __ASSEMBLY__
 
 typedef struct {
@@ -565,6 +570,7 @@ struct pxa95x_peripheral_wakeup_ops {
 	int (*cmwdt) (pm_wakeup_src_t src, int enable);
 };
 extern unsigned int *remap_c2_reg;
+extern unsigned int  *pl310_membase;
 
 #define GC_PWR_ENABLE		(1)
 #define GC_PWR_DISABLE		(0)
@@ -578,8 +584,8 @@ extern unsigned int pm_core_pwdn(unsigned int powerState);
 extern unsigned int pm_enter_cgm_deepidle(unsigned int);
 extern int pxa95x_query_gwsr(int);
 extern u32 get_mipi_reference_control(void);
-extern void ca9_enter_idle(unsigned int pwrmode, unsigned int sramaddr, unsigned int l2c_base_address);
-
+extern unsigned int get_c2_sram_base(void);
+extern void pxa978_pm_enter(unsigned int save_mode);
 #endif
 #endif
 #endif
diff --git a/arch/arm/mach-pxa/mspm_idle.c b/arch/arm/mach-pxa/mspm_idle.c
index 79ad678..e1750e4 100644
--- a/arch/arm/mach-pxa/mspm_idle.c
+++ b/arch/arm/mach-pxa/mspm_idle.c
@@ -32,7 +32,6 @@
 #include <mach/regs-ost.h>
 #include <mach/pxa95x_dvfm.h>
 #include <mach/mspm_prof.h>
-#include <mach/ca9_regs.h>
 #ifdef CONFIG_ISPT
 #include <mach/pxa_ispt.h>
 #endif
@@ -120,15 +119,12 @@ static unsigned int pm_enter_deepidle(unsigned int x)
 	BUG_ON(1);
 }
 #endif
-extern unsigned int get_sram_base(void);
-extern struct pl310_registers pl310_regs;
 extern unsigned int c2_allow;
 static void pxa95x_cpu_idle(void)
 {
 	unsigned int c1_enter_time, c1_exit_time, pollreg;
 	struct op_info *info = NULL;
 	int op;
-	unsigned int sram_base = get_sram_base();
 	static unsigned int counter, counter2;
 	DVFMLPMGlobalCount.D0C1_Enter_count++;
 	op = dvfm_get_op(&info);
@@ -151,14 +147,14 @@ static void pxa95x_cpu_idle(void)
 	mipsram_disable_counter();
 #endif
 	if (cpu_is_pxa978()) {
-		if (sram_base && c2_allow) {
+		if (c2_allow) {
 			PWRMODE = 0x0;
 			PWRMODE = (PXA978_PM_S0D0CG | PXA95x_PM_I_Q_BIT);
 			do {
 				pollreg = PWRMODE;
 			} while (pollreg !=
 					(PXA978_PM_S0D0CG | PXA95x_PM_I_Q_BIT));
-			ca9_enter_idle(pollreg, sram_base + 0x8000, (unsigned int)pl310_regs.memset);
+			pxa978_pm_enter(PWRDM_POWER_C2);
 			counter++;
 			if (counter == 10000) {
 				counter2++;
diff --git a/arch/arm/mach-pxa/pxa95x_pm.c b/arch/arm/mach-pxa/pxa95x_pm.c
index 9935840..e3e599f 100644
--- a/arch/arm/mach-pxa/pxa95x_pm.c
+++ b/arch/arm/mach-pxa/pxa95x_pm.c
@@ -34,7 +34,6 @@
 #include <mach/mfp-pxa3xx.h>
 #include <mach/gpio.h>
 #include <mach/debug_pm.h>
-#include <mach/ca9_regs.h>
 #ifdef CONFIG_ISPT
 #include <mach/pxa_ispt.h>
 #endif
@@ -54,7 +53,6 @@
 /* mtd.h declares another DEBUG macro definition */
 #undef DEBUG
 #include <linux/mtd/mtd.h>
-
 /* The first 32KB is reserved and can't be accessed by kernel.
  * This restrict is only valid on BootROM V2.
  */
@@ -187,8 +185,8 @@ EXPORT_SYMBOL(dmc_membase);
 unsigned char __iomem *ost_membase;
 EXPORT_SYMBOL(ost_membase);
 unsigned char __iomem *pm_membase;
-
-unsigned int *remap_c2_reg;
+unsigned int __iomem *pl310_membase;
+unsigned int __iomem *remap_c2_reg;
 
 extern void pxa95x_cpu_sleep(unsigned int, unsigned int);
 extern void pxa95x_cpu_resume(void);
@@ -458,8 +456,6 @@ static void pxa95x_gpio_restore(struct gpio_regs *context)
 	GFER2 = context->gfer2;
 	GFER3 = context->gfer3;
 }
-
-struct pl310_registers pl310_regs;
 static void pxa95x_sysbus_init(struct pxa95x_pm_regs *context)
 {
 	context->smc.membase = ioremap(SMC_START, SMC_END - SMC_START + 1);
@@ -477,9 +473,7 @@ static void pxa95x_sysbus_init(struct pxa95x_pm_regs *context)
 	 */
 	context->data_pool = (unsigned char *)0xC0000000;
 	if (cpu_is_pxa978()) {
-		pl310_regs.memset = ioremap(L2310_ADDR_START, L2310_ADDR_END - L2310_ADDR_START + 1);
-		printk(KERN_DEBUG "pl310_regs.memset = 0x%lx, Start: 0x%lx END: 0x%lx\n",
-						pl310_regs.memset, L2310_ADDR_START, L2310_ADDR_END);
+		pl310_membase = ioremap(0x58120000, 0x1000);
 	}
 }
 
@@ -1249,6 +1243,11 @@ unsigned int get_sram_base(void)
 		| VLSCR_LVL3_SINGLE_RAIL | VLSCR_LVL0_SINGLE_RAIL \
 		| VLSCR_VCT0_LVL0_REMAP_MASK | VLSCR_VCT0_LVL1_REMAP_MASK \
 		| VLSCR_VCT0_LVL2_REMAP_MASK | VLSCR_VCT0_LVL3_REMAP_MASK)
+unsigned int get_c2_sram_base(void)
+{
+	return (unsigned int) (pxa95x_pm_regs.sram_map + 0x8000);
+}
+
 void enter_lowpower_mode(int state)
 {
 	unsigned int start_tick = 0, end_tick = 0;
@@ -1342,9 +1341,7 @@ void enter_lowpower_mode(int state)
 					vlscr &= ~(VLSCR_SINGLE_RAIL_MASK);
 					vlscr |= (VLSCR_D1_VALUE);
 					VLSCR = vlscr;
-
-					ca9_enter_idle(pollreg, sram + 0x8000,
-							(u32)pl310_regs.memset);
+					pxa978_pm_enter(PWRDM_POWER_C2);
 				} else {
 					pxa95x_cpu_standby(sram + 0x8000,
 							sram + 0xa000 - 4,
@@ -1454,9 +1451,8 @@ void enter_lowpower_mode(int state)
 					vlscr &= ~(VLSCR_SINGLE_RAIL_MASK);
 					vlscr |= (VLSCR_D2_VALUE);
 					VLSCR = vlscr;
+					pxa978_pm_enter(PWRDM_POWER_C2);
 
-					ca9_enter_idle(pollreg, sram + 0x8000,
-							(u32)pl310_regs.memset);
 				} else {
 					pxa95x_cpu_standby(sram + 0x8000,
 							sram + 0xa000 - 4,
@@ -1619,8 +1615,7 @@ void enter_lowpower_mode(int state)
 			   */
 			sram = (unsigned int) pxa95x_pm_regs.sram_map;
 			if (cpu_is_pxa978()) {
-				ca9_enter_idle(pollreg, sram + 0x8000,
-						(u32)pl310_regs.memset);
+				pxa978_pm_enter(PWRDM_POWER_C2);
 			} else {
 				if (cur_op < 2)
 					pm_enter_cgm_deepidle
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux