Add PSCI support for Jetson TK1/Tegra124 + CNTFRQ fix
Subsystems (4)
v4 cover Add PSCI support for Jetson TK1/Tegra124 + CNTFRQ fix
Changes in v4:
- rebased over master
- fixed a nasty bug in CTNFRQ setting that broke unrelated code
- fixed a bug in Tegra's psci_cpu_off that prevented powergating
- factored out armv7_get_cpu_id macro
- removed duplicate call to psci_arch_init
- addressed review comments regarding comments
- wait on initial CPU power-down using Flow Controller instead of PMC
Jan
Ian Campbell (3):
tegra124: Add more registers to struct mc_ctlr
jetson-tk1: Add PSCI configuration options and reserve secure code
tegra124: Reserve secure RAM using MC_SECURITY_CFG{0, 1}_0
Jan Kiszka (11):
sun7i: Remove duplicate call to psci_arch_init
ARM: Factor out armv7_get_cpu_id macro
ARM: Factor out reusable psci_cpu_off_common
ARM: Factor out reusable psci_cpu_entry
ARM: Factor out reusable psci_get_cpu_stack_top
ARM: Put target PC for PSCI CPU_ON on per-CPU stack
virt-dt: Allow reservation of secure region when in a RAM carveout
tegra: Make tegra_powergate_power_on public
tegra: Add ap_pm_init hook
tegra124: Add PSCI support for Tegra124
tegra: Set CNTFRQ for secondary CPUs
arch/arm/cpu/armv7/psci.S | 102 +++++++++++++++++++++++++ arch/arm/cpu/armv7/sunxi/psci.S | 112 +++++---------------------- arch/arm/cpu/armv7/virt-dt.c | 29 +++++++ arch/arm/cpu/armv7/virt-v7.c | 5 ++ arch/arm/include/asm/arch-tegra/ap.h | 5 ++ arch/arm/include/asm/arch-tegra/powergate.h | 1 + arch/arm/include/asm/arch-tegra124/flow.h | 6 ++ arch/arm/include/asm/arch-tegra124/mc.h | 35 ++++++++- arch/arm/include/asm/armv7.h | 1 + arch/arm/include/asm/macro.h | 7 ++ arch/arm/include/asm/system.h | 1 + arch/arm/lib/bootm-fdt.c | 5 ++ arch/arm/mach-tegra/Makefile | 4 + arch/arm/mach-tegra/ap.c | 15 ++++ arch/arm/mach-tegra/powergate.c | 2 +- arch/arm/mach-tegra/psci.S | 114 ++++++++++++++++++++++++++++ arch/arm/mach-tegra/tegra124/Kconfig | 2 + arch/arm/mach-tegra/tegra124/Makefile | 4 + arch/arm/mach-tegra/tegra124/ap.c | 55 ++++++++++++++ board/nvidia/common/board.c | 4 + include/configs/jetson-tk1.h | 5 ++ 21 files changed, 416 insertions(+), 98 deletions(-) create mode 100644 arch/arm/mach-tegra/psci.S create mode 100644 arch/arm/mach-tegra/tegra124/ap.c
Signature · 1 line
2.1.4
PATCH v4 1/14 sun7i: Remove duplicate call to psci_arch_init
This is already invoked a few cycles later in monitor mode by _secure_monitor. Drop it here, it serves no purpose.
--- arch/arm/cpu/armv7/sunxi/psci.S | 1 - 1 file changed, 1 deletion(-)
arch/arm/cpu/armv7/sunxi/psci.S +0 -1
@@ -254,7 +254,6 @@ _sunxi_cpu_entry: isb bl _nonsec_init - bl psci_arch_init adr r0, _target_pc ldr r0, [r0]
Signature · 1 line
2.1.4
PATCH v4 2/14 ARM: Factor out armv7_get_cpu_id macro
In reply to Jan KiszkaHandy for obtaining the ID of the current CPU. We will have more use cases.
--- arch/arm/cpu/armv7/sunxi/psci.S | 4 ++-- arch/arm/include/asm/macro.h | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-)
arch/arm/cpu/armv7/sunxi/psci.S +2 -2
@@ -19,6 +19,7 @@ #include <config.h> #include <asm/gic.h> +#include <asm/macro.h> #include <asm/psci.h> #include <asm/arch/cpu.h>
@@ -315,8 +316,7 @@ psci_arch_init: mcr p15, 0, r5, c1, c1, 0 @ Write SCR isb - mrc p15, 0, r4, c0, c0, 5 @ MPIDR - and r4, r4, #3 @ cpu number in cluster + armv7_get_cpu_id r4 mov r5, #0x400 @ 1kB of stack per CPU mul r4, r4, r5
arch/arm/include/asm/macro.h +7 -0
@@ -198,6 +198,13 @@ lr .req x30 .endm#endif +#else /* !CONFIG_ARM64 */ + +.macro armv7_get_cpu_id rn + mrc p15, 0, \rn, c0, c0, 5 /* read MPIDR */ + and \rn, \rn, #0xff /* return CPU ID in cluster */ +.endm +#endif /* CONFIG_ARM64 */ #endif /* __ASSEMBLY__ */
Signature · 1 line
2.1.4
PATCH v4 2/14 ARM: Factor out armv7_get_cpu_id macro
Quoted 45 lines · On Fri, 27 Feb 2015 13:28:01 +0000 Jan Kiszka <[email protected]> wrote:
Handy for obtaining the ID of the current CPU. We will have more use cases.
CC Marc Zyngier <[email protected]>Signed-off-by Jan Kiszka <[email protected]>--- arch/arm/cpu/armv7/sunxi/psci.S | 4 ++-- arch/arm/include/asm/macro.h | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-)(quoted diff) +0
-0
b/arch/arm/cpu/armv7/sunxi/psci.Sindex 9e898f2..0523217 100644arch/arm/cpu/armv7/sunxi/psci.S +2
-2@@ -19,6 +19,7 @@ #include <config.h> #include <asm/gic.h> +#include <asm/macro.h> #include <asm/psci.h> #include <asm/arch/cpu.h>@@ -315,8 +316,7 @@ psci_arch_init: mcr p15, 0, r5, c1, c1, 0 @ Write SCR isb - mrc p15, 0, r4, c0, c0, 5 @ MPIDR - and r4, r4, #3 @ cpu number in cluster + armv7_get_cpu_id r4 mov r5, #0x400 @ 1kB of stack per CPU mul r4, r4, r5(quoted diff) +0
-0
b/arch/arm/include/asm/macro.hindex 1c8c425..0bc925a 100644arch/arm/include/asm/macro.h +5
-0@@ -198,6 +198,13 @@ lr .req x30 .endm#endif +#else /* !CONFIG_ARM64 */ + +.macro armv7_get_cpu_id rn + mrc p15, 0, \rn, c0, c0, 5 /* read MPIDR */ + and \rn, \rn, #0xff /* return CPU ID
Quoted 3 lines
in cluster */
+.endm
+
How does this work in a multi-cluster situation? Or when you have sparse MPIDRs?
Thanks,
M.
Quoted 3 lines
#endif /*
CONFIG_ARM64*/#endif /*
__ASSEMBLY__*/
Signature · 1 line
Jazz is not dead. It just smells funny.
PATCH v4 2/14 ARM: Factor out armv7_get_cpu_id macro
Quoted 43 lines · Marc Zyngier
Quoted 40 lines · On Fri, 27 Feb 2015 13:28:01 +0000 Jan Kiszka <[email protected]> wrote:
Handy for obtaining the ID of the current CPU. We will have more use cases.
CC Marc Zyngier <[email protected]>Signed-off-by Jan Kiszka <[email protected]>--- arch/arm/cpu/armv7/sunxi/psci.S | 4 ++-- arch/arm/include/asm/macro.h | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-)(quoted diff) +0
-0
b/arch/arm/cpu/armv7/sunxi/psci.Sindex 9e898f2..0523217 100644arch/arm/cpu/armv7/sunxi/psci.S +2
-2@@ -19,6 +19,7 @@ #include <config.h> #include <asm/gic.h> +#include <asm/macro.h> #include <asm/psci.h> #include <asm/arch/cpu.h>@@ -315,8 +316,7 @@ psci_arch_init: mcr p15, 0, r5, c1, c1, 0 @ Write SCR isb - mrc p15, 0, r4, c0, c0, 5 @ MPIDR - and r4, r4, #3 @ cpu number in cluster + armv7_get_cpu_id r4 mov r5, #0x400 @ 1kB of stack per CPU mul r4, r4, r5(quoted diff) +0
-0
b/arch/arm/include/asm/macro.hindex 1c8c425..0bc925a 100644arch/arm/include/asm/macro.h +0
-0@@ -198,6 +198,13 @@ lr .req x30 .endm#endif
Quoted 11 lines
Quoted 8 lines
arch/arm/include/asm/macro.h +5
-0+#else /* !CONFIG_ARM64 */ + +.macro armv7_get_cpu_id rn + mrc p15, 0, \rn, c0, c0, 5 /* read MPIDR */ + and \rn, \rn, #0xff /* return CPU IDin cluster */
+.endm
+How does this work in a multi-cluster situation? Or when you have sparse MPIDRs?
I have no idea. That masking was stolen from your code.
The model we assume for PSCI is that there is no cluster and that we have enough per-cpu space for up to the maximum cpu ID obtained that way.
If you are concerned about signaling a false general applicability of that macro, I can fold it back into the callers or add some comments about restrictions. My plan was just to make the caller site a bit more readable.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT RTC ITP SES-DE Corporate Competence Center Embedded Linux
PATCH v4 2/14 ARM: Factor out armv7_get_cpu_id macro
Quoted 56 lines · Jan Kiszka
Quoted 43 lines · Marc Zyngier
Quoted 40 lines · On Fri, 27 Feb 2015 13:28:01 +0000 Jan Kiszka <[email protected]> wrote:
Handy for obtaining the ID of the current CPU. We will have more use cases.
CC Marc Zyngier <[email protected]>Signed-off-by Jan Kiszka <[email protected]>--- arch/arm/cpu/armv7/sunxi/psci.S | 4 ++-- arch/arm/include/asm/macro.h | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-)(quoted diff) +0
-0
b/arch/arm/cpu/armv7/sunxi/psci.Sindex 9e898f2..0523217 100644arch/arm/cpu/armv7/sunxi/psci.S +2
-2@@ -19,6 +19,7 @@ #include <config.h> #include <asm/gic.h> +#include <asm/macro.h> #include <asm/psci.h> #include <asm/arch/cpu.h>@@ -315,8 +316,7 @@ psci_arch_init: mcr p15, 0, r5, c1, c1, 0 @ Write SCR isb - mrc p15, 0, r4, c0, c0, 5 @ MPIDR - and r4, r4, #3 @ cpu number in cluster + armv7_get_cpu_id r4 mov r5, #0x400 @ 1kB of stack per CPU mul r4, r4, r5(quoted diff) +0
-0
b/arch/arm/include/asm/macro.hindex 1c8c425..0bc925a 100644arch/arm/include/asm/macro.h +0
-0@@ -198,6 +198,13 @@ lr .req x30 .endm#endif Quoted 11 lines
Quoted 8 lines
arch/arm/include/asm/macro.h +5
-0+#else /* !CONFIG_ARM64 */ + +.macro armv7_get_cpu_id rn + mrc p15, 0, \rn, c0, c0, 5 /* read MPIDR */ + and \rn, \rn, #0xff /* return CPU IDin cluster */
+.endm
+How does this work in a multi-cluster situation? Or when you have sparse MPIDRs?
Quoted 1 line
I have no idea. That masking was stolen from your code.
Well, it is perfectly correct in the context of the original code (single cluster, dense ID space), but is utterly wrong as a general implementation.
Quoted 2 lines
The model we assume for PSCI is that there is no cluster and that we have enough per-cpu space for up to the maximum cpu ID obtained that way.
I don't think you can rely on this assumption.
Quoted 4 lines
If you are concerned about signaling a false general applicability of that macro, I can fold it back into the callers or add some comments about restrictions. My plan was just to make the caller site a bit more readable.
I understand the concern, but making this a general macro is very misleading. Most systems with more than 4 cores will have clusters and a very sparse ID space, and these systems are quite common these days.
Computing a CPU number is not a simple task, specially in the absence of a discovery protocol (the Linux kernel relies on DT for that), so I'm afraid you have to either keep this on a per platform basis, or provide ways to override this macro.
Thanks,
M.
Signature · 1 line
Jazz is not dead. It just smells funny...
PATCH v4 2/14 ARM: Factor out armv7_get_cpu_id macro
Quoted 59 lines · Marc Zyngier
Quoted 56 lines · Jan Kiszka
Quoted 43 lines · Marc Zyngier
Quoted 40 lines · On Fri, 27 Feb 2015 13:28:01 +0000 Jan Kiszka <[email protected]> wrote:
Handy for obtaining the ID of the current CPU. We will have more use cases.
CC Marc Zyngier <[email protected]>Signed-off-by Jan Kiszka <[email protected]>--- arch/arm/cpu/armv7/sunxi/psci.S | 4 ++-- arch/arm/include/asm/macro.h | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-)(quoted diff) +0
-0
b/arch/arm/cpu/armv7/sunxi/psci.Sindex 9e898f2..0523217 100644arch/arm/cpu/armv7/sunxi/psci.S +2
-2@@ -19,6 +19,7 @@ #include <config.h> #include <asm/gic.h> +#include <asm/macro.h> #include <asm/psci.h> #include <asm/arch/cpu.h>@@ -315,8 +316,7 @@ psci_arch_init: mcr p15, 0, r5, c1, c1, 0 @ Write SCR isb - mrc p15, 0, r4, c0, c0, 5 @ MPIDR - and r4, r4, #3 @ cpu number in cluster + armv7_get_cpu_id r4 mov r5, #0x400 @ 1kB of stack per CPU mul r4, r4, r5(quoted diff) +0
-0
b/arch/arm/include/asm/macro.hindex 1c8c425..0bc925a 100644arch/arm/include/asm/macro.h +0
-0@@ -198,6 +198,13 @@ lr .req x30 .endm#endif Quoted 11 lines
Quoted 8 lines
arch/arm/include/asm/macro.h +5
-0+#else /* !CONFIG_ARM64 */ + +.macro armv7_get_cpu_id rn + mrc p15, 0, \rn, c0, c0, 5 /* read MPIDR */ + and \rn, \rn, #0xff /* return CPU IDin cluster */
+.endm
+How does this work in a multi-cluster situation? Or when you have sparse MPIDRs?
Quoted 1 line
I have no idea. That masking was stolen from your code.
Quoted 8 lines
Well, it is perfectly correct in the context of the original code (single cluster, dense ID space), but is utterly wrong as a general implementation.
Quoted 2 lines
The model we assume for PSCI is that there is no cluster and that we have enough per-cpu space for up to the maximum cpu ID obtained that way.
I don't think you can rely on this assumption.
We'll have to in order to share code, so this service has to help out.
Quoted 6 lines
Quoted 5 lines
If you are concerned about signaling a false general applicability of that macro, I can fold it back into the callers or add some comments about restrictions. My plan was just to make the caller site a bit more readable.
Quoted 8 lines
I understand the concern, but making this a general macro is very misleading. Most systems with more than 4 cores will have clusters and a very sparse ID space, and these systems are quite common these days.
Computing a CPU number is not a simple task, specially in the absence of a discovery protocol (the Linux kernel relies on DT for that), so I'm afraid you have to either keep this on a per platform basis, or provide ways to override this macro.
I'll make this another weak function. Unfolding won't work well because it should be used in common psci.S.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT RTC ITP SES-DE Corporate Competence Center Embedded Linux
PATCH v4 3/14 ARM: Factor out reusable psci_cpu_off_common
In reply to Jan KiszkaMove parts of sunxi's psci_cpu_off into psci_cpu_off_common, namely cache disabling and flushing, clrex and the disabling of SMP for the dying CPU. These steps are apparently generic for ARMv7 and will be reused for Tegra124 support.
--- arch/arm/cpu/armv7/psci.S | 71 +++++++++++++++++++++++++++++++++++++++++ arch/arm/cpu/armv7/sunxi/psci.S | 63 +----------------------------------- 2 files changed, 72 insertions(+), 62 deletions(-)
arch/arm/cpu/armv7/psci.S +71 -0
@@ -99,4 +99,75 @@ _smc_psci: pop {r4-r7, lr} movs pc, lr @ Return to the kernel +/* Imported from Linux kernel */ +LENTRY(v7_flush_dcache_all) + dmb @ ensure ordering with previous memory accesses + mrc p15, 1, r0, c0, c0, 1 @ read clidr + ands r3, r0, #0x7000000 @ extract loc from clidr + mov r3, r3, lsr #23 @ left align loc bit field + beq finished @ if loc is 0, then no need to clean + mov r10, #0 @ start clean at cache level 0 +flush_levels: + add r2, r10, r10, lsr #1 @ work out 3x current cache level + mov r1, r0, lsr r2 @ extract cache type bits from clidr + and r1, r1, #7 @ mask of the bits for current cache only + cmp r1, #2 @ see what cache we have at this level + blt skip @ skip if no cache, or just i-cache + mrs r9, cpsr @ make cssr&csidr read atomic + mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr + isb @ isb to sych the new cssr&csidr + mrc p15, 1, r1, c0, c0, 0 @ read the new csidr + msr cpsr_c, r9 + and r2, r1, #7 @ extract the length of the cache lines + add r2, r2, #4 @ add 4 (line length offset) + ldr r4, =0x3ff + ands r4, r4, r1, lsr #3 @ find maximum number on the way size + clz r5, r4 @ find bit position of way size increment + ldr r7, =0x7fff + ands r7, r7, r1, lsr #13 @ extract max number of the index size +loop1: + mov r9, r7 @ create working copy of max index +loop2: + orr r11, r10, r4, lsl r5 @ factor way and cache number into r11 + orr r11, r11, r9, lsl r2 @ factor index number into r11 + mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way + subs r9, r9, #1 @ decrement the index + bge loop2 + subs r4, r4, #1 @ decrement the way + bge loop1 +skip: + add r10, r10, #2 @ increment cache number + cmp r3, r10 + bgt flush_levels +finished: + mov r10, #0 @ swith back to cache level 0 + mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr + dsb st + isb + bx lr +ENDPROC(v7_flush_dcache_all) + +ENTRY(psci_cpu_off_common) + push {lr} + + mrc p15, 0, r0, c1, c0, 0 @ SCTLR + bic r0, r0, #(1 << 2) @ Clear C bit + mcr p15, 0, r0, c1, c0, 0 @ SCTLR + isb + dsb + + bl v7_flush_dcache_all + + clrex @ Why??? + + mrc p15, 0, r0, c1, c0, 1 @ ACTLR + bic r0, r0, #(1 << 6) @ Clear SMP bit + mcr p15, 0, r0, c1, c0, 1 @ ACTLR + isb + dsb + + pop {lr} + bx lr +ENDPROC(psci_cpu_off_common) + .popsection
arch/arm/cpu/armv7/sunxi/psci.S +1 -62
75 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH v4 3/14 ARM: Factor out reusable psci_cpu_off_common
Quoted 103 lines · On Fri, 27 Feb 2015 13:28:02 +0000 Jan Kiszka <[email protected]> wrote:
Move parts of sunxi's
psci_cpu_offintopsci_cpu_off_common, namely cache disabling and flushing, clrex and the disabling of SMP for the dying CPU. These steps are apparently generic for ARMv7 and will be reused for Tegra124 support.CC Marc Zyngier <[email protected]>Signed-off-by Jan Kiszka <[email protected]>--- arch/arm/cpu/armv7/psci.S | 71+++++++++++++++++++++++++++++++++++++++++
arch/arm/cpu/armv7/sunxi/psci.S| 63 +----------------------------------- 2 files changed, 72 insertions(+), 62 deletions(-)arch/arm/cpu/armv7/psci.S +0
-0@@ -99,4 +99,75 @@ _smc_psci: pop {r4-r7, lr} movs pc, lr @ Return to thekernel
arch/arm/cpu/armv7/psci.S +3
-0+/* Imported from Linux kernel */ +LENTRY(v7_flush_dcache_all) + dmb @ ensure orderingwith previous memory accesses
arch/arm/cpu/armv7/psci.S +2
-0+ mrc p15, 1, r0, c0, c0, 1 @ read clidr + ands r3, r0, #0x7000000 @ extract locfrom clidr
arch/arm/cpu/armv7/psci.S +1
-0+ mov r3, r3, lsr #23 @ leftalign loc bit field
arch/arm/cpu/armv7/psci.S +1
-0+ beq finished @ if loc is 0,then no need to clean
arch/arm/cpu/armv7/psci.S +1
-0+ mov r10, #0 @ startclean at cache level 0 +flush_levels:
arch/arm/cpu/armv7/psci.S +1
-0+ add r2, r10, r10, lsr #1 @ work out 3xcurrent cache level
arch/arm/cpu/armv7/psci.S +1
-0+ mov r1, r0, lsr r2 @ extractcache type bits from clidr
arch/arm/cpu/armv7/psci.S +1
-0+ and r1, r1, #7 @ mask of thebits for current cache only
arch/arm/cpu/armv7/psci.S +1
-0+ cmp r1, #2 @ see whatcache we have at this level
arch/arm/cpu/armv7/psci.S +1
-0+ blt skip @ skip if nocache, or just i-cache
arch/arm/cpu/armv7/psci.S +1
-0+ mrs r9, cpsr @ make cssr&csidrread atomic
arch/arm/cpu/armv7/psci.S +1
-0+ mcr p15, 2, r10, c0, c0, 0 @ selectcurrent cache level in cssr
arch/arm/cpu/armv7/psci.S +1
-0+ isb @ isb to sych thenew cssr&csidr
arch/arm/cpu/armv7/psci.S +1
-0+ mrc p15, 1, r1, c0, c0, 0 @ read thenew csidr
arch/arm/cpu/armv7/psci.S +2
-0+ msr cpsr_c, r9 + and r2, r1, #7 @ extract thelength of the cache lines
arch/arm/cpu/armv7/psci.S +1
-0+ add r2, r2, #4 @ add 4 (linelength offset)
arch/arm/cpu/armv7/psci.S +2
-0+ ldr r4, =0x3ff + ands r4, r4, r1, lsr #3 @ find maximumnumber on the way size
arch/arm/cpu/armv7/psci.S +1
-0+ clz r5, r4 @ find bitposition of way size increment
arch/arm/cpu/armv7/psci.S +2
-0+ ldr r7, =0x7fff + ands r7, r7, r1, lsr #13 @ extract maxnumber of the index size +loop1:
arch/arm/cpu/armv7/psci.S +1
-0+ mov r9, r7 @ createworking copy of max index +loop2:
arch/arm/cpu/armv7/psci.S +1
-0+ orr r11, r10, r4, lsl r5 @ factor wayand cache number into r11
arch/arm/cpu/armv7/psci.S +1
-0+ orr r11, r11, r9, lsl r2 @ factorindex number into r11
arch/arm/cpu/armv7/psci.S +1
-0+ mcr p15, 0, r11, c7, c14, 2 @ clean &invalidate by set/way
arch/arm/cpu/armv7/psci.S +1
-0+ subs r9, r9, #1 @ decrementthe index
arch/arm/cpu/armv7/psci.S +2
-0+ bge loop2 + subs r4, r4, #1 @ decrementthe way
arch/arm/cpu/armv7/psci.S +3
-0+ bge loop1 +skip: + add r10, r10, #2 @ incrementcache number
arch/arm/cpu/armv7/psci.S +4
-0+ cmp r3, r10 + bgt flush_levels +finished: + mov r10, #0 @ swithback to cache level 0
arch/arm/cpu/armv7/psci.S +1
-0+ mcr p15, 2, r10, c0, c0, 0 @ selectcurrent cache level in cssr
arch/arm/cpu/armv7/psci.S +13
-0+ dsb st + isb + bx lr +ENDPROC(v7_flush_dcache_all) + +ENTRY(psci_cpu_off_common) + push {lr} + + mrc p15, 0, r0, c1, c0, 0 @ SCTLR + bic r0, r0, #(1 << 2) @ Clear C bit + mcr p15, 0, r0, c1, c0, 0 @ SCTLR + isb + dsb
arch/arm/cpu/armv7/psci.S _smc_psci: · line 167
Quoted 10 lines
arch/arm/cpu/armv7/psci.S +10
-0+ + bl v7_flush_dcache_all + + clrex @ Why??? + + mrc p15, 0, r0, c1, c0, 1 @ ACTLR + bic r0, r0, #(1 << 6) @ Clear SMP bit + mcr p15, 0, r0, c1, c0, 1 @ ACTLR + isb + dsb
Same thing. Please turn this into something an implementation can override.
Quoted 112 lines
arch/arm/cpu/armv7/psci.S +5
-0+ + pop {lr} + bx lr +ENDPROC(psci_cpu_off_common) + .popsection(quoted diff) +0
-0
b/arch/arm/cpu/armv7/sunxi/psci.Sindex 0523217..bb3d4ef 100644arch/arm/cpu/armv7/sunxi/psci.S +0
-3@@ -200,53 +200,6 @@ psci_cpu_on: _target_pc: .word 0 -/* Imported from Linux kernel */ -v7_flush_dcache_all: - dmb @ ensure orderingwith previous memory accesses
arch/arm/cpu/armv7/sunxi/psci.S +0
-2- mrc p15, 1, r0, c0, c0, 1 @ read clidr - ands r3, r0, #0x7000000 @ extract locfrom clidr
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- mov r3, r3, lsr #23 @ leftalign loc bit field
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- beq finished @ if loc is 0,then no need to clean
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- mov r10, #0 @ startclean at cache level 0 -flush_levels:
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- add r2, r10, r10, lsr #1 @ work out 3xcurrent cache level
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- mov r1, r0, lsr r2 @ extractcache type bits from clidr
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- and r1, r1, #7 @ mask of thebits for current cache only
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- cmp r1, #2 @ see whatcache we have at this level
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- blt skip @ skip if nocache, or just i-cache
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- mrs r9, cpsr @ make cssr&csidrread atomic
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- mcr p15, 2, r10, c0, c0, 0 @ selectcurrent cache level in cssr
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- isb @ isb to sych thenew cssr&csidr
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- mrc p15, 1, r1, c0, c0, 0 @ read thenew csidr
arch/arm/cpu/armv7/sunxi/psci.S +0
-2- msr cpsr_c, r9 - and r2, r1, #7 @ extract thelength of the cache lines
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- add r2, r2, #4 @ add 4 (linelength offset)
arch/arm/cpu/armv7/sunxi/psci.S +0
-2- ldr r4, =0x3ff - ands r4, r4, r1, lsr #3 @ find maximumnumber on the way size
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- clz r5, r4 @ find bitposition of way size increment
arch/arm/cpu/armv7/sunxi/psci.S +0
-2- ldr r7, =0x7fff - ands r7, r7, r1, lsr #13 @ extract maxnumber of the index size -loop1:
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- mov r9, r7 @ createworking copy of max index -loop2:
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- orr r11, r10, r4, lsl r5 @ factor wayand cache number into r11
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- orr r11, r11, r9, lsl r2 @ factorindex number into r11
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- mcr p15, 0, r11, c7, c14, 2 @ clean &invalidate by set/way
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- subs r9, r9, #1 @ decrementthe index
arch/arm/cpu/armv7/sunxi/psci.S +0
-2- bge loop2 - subs r4, r4, #1 @ decrementthe way
arch/arm/cpu/armv7/sunxi/psci.S +0
-3- bge loop1 -skip: - add r10, r10, #2 @ incrementcache number
arch/arm/cpu/armv7/sunxi/psci.S +0
-4- cmp r3, r10 - bgt flush_levels -finished: - mov r10, #0 @ swithback to cache level 0
arch/arm/cpu/armv7/sunxi/psci.S +0
-1- mcr p15, 2, r10, c0, c0, 0 @ selectcurrent cache level in cssr
arch/arm/cpu/armv7/sunxi/psci.S +1
-19- dsb st - isb - bx lr - _sunxi_cpu_entry: @ Set SMP bit mrc p15, 0, r0, c1, c0, 1@@ -262,21 +215,7 @@ _sunxi_cpu_entry: .globl psci_cpu_off psci_cpu_off: - mrc p15, 0, r0, c1, c0, 0 @ SCTLR - bic r0, r0, #(1 << 2) @ Clear C bit - mcr p15, 0, r0, c1, c0, 0 @ SCTLR - isb - dsb - - bl v7_flush_dcache_all - - clrex @ Why??? - - mrc p15, 0, r0, c1, c0, 1 @ ACTLR - bic r0, r0, #(1 << 6) @ Clear SMP bit - mcr p15, 0, r0, c1, c0, 1 @ ACTLR - isb - dsb + bl psci_cpu_off_common @ Ask CPU0 to pull the rug... movw r0, #(GICD_BASE & 0xffff)
Signature · 1 line
Jazz is not dead. It just smells funny.
PATCH v4 4/14 ARM: Factor out reusable psci_cpu_entry
In reply to Jan Kiszka_sunxi_cpu_entry can be converted completely into a reusable psci_cpu_entry. Tegra124 will use it as well.
--- arch/arm/cpu/armv7/psci.S | 18 ++++++++++++++++++ arch/arm/cpu/armv7/sunxi/psci.S | 20 ++------------------ 2 files changed, 20 insertions(+), 18 deletions(-)
arch/arm/cpu/armv7/psci.S +18 -0
@@ -170,4 +170,22 @@ ENTRY(psci_cpu_off_common) bx lr ENDPROC(psci_cpu_off_common) +ENTRY(psci_cpu_entry) + @ Set SMP bit + mrc p15, 0, r0, c1, c0, 1 @ ACTLR + orr r0, r0, #(1 << 6) @ Set SMP bit + mcr p15, 0, r0, c1, c0, 1 @ ACTLR + isb + + bl _nonsec_init + + adr r0, _psci_target_pc + ldr r0, [r0] + b _do_nonsec_entry +ENDPROC(psci_cpu_entry) + +.globl _psci_target_pc +_psci_target_pc: + .word 0 + .popsection
arch/arm/cpu/armv7/sunxi/psci.S +2 -18
@@ -139,7 +139,7 @@ out: mcr p15, 0, r7, c1, c1, 0 @ r2 = target PC .globl psci_cpu_on psci_cpu_on: - adr r0, _target_pc + ldr r0, =_psci_target_pc str r2, [r0] dsb
@@ -151,7 +151,7 @@ psci_cpu_on: mov r4, #1 lsl r4, r4, r1 - adr r6, _sunxi_cpu_entry + ldr r6, =psci_cpu_entry str r6, [r0, #0x1a4] @ PRIVATE_REG (boot vector) @ Assert reset on target CPU
@@ -197,22 +197,6 @@ psci_cpu_on: mov r0, #ARM_PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS mov pc, lr -_target_pc: - .word 0 - -_sunxi_cpu_entry: - @ Set SMP bit - mrc p15, 0, r0, c1, c0, 1 - orr r0, r0, #0x40 - mcr p15, 0, r0, c1, c0, 1 - isb - - bl _nonsec_init - - adr r0, _target_pc - ldr r0, [r0] - b _do_nonsec_entry - .globl psci_cpu_off psci_cpu_off: bl psci_cpu_off_common
Signature · 1 line
2.1.4
PATCH v4 4/14 ARM: Factor out reusable psci_cpu_entry
Quoted 21 lines · On Fri, 27 Feb 2015 13:28:03 +0000 Jan Kiszka <[email protected]> wrote:
_sunxi_cpu_entrycan be converted completely into a reusablepsci_cpu_entry. Tegra124 will use it as well.CC Marc Zyngier <[email protected]>Signed-off-by Jan Kiszka <[email protected]>--- arch/arm/cpu/armv7/psci.S | 18 ++++++++++++++++++ arch/arm/cpu/armv7/sunxi/psci.S | 20 ++------------------ 2 files changed, 20 insertions(+), 18 deletions(-)arch/arm/cpu/armv7/psci.S +3
-0@@ -170,4 +170,22 @@ ENTRY(psci_cpu_off_common) bx lr ENDPROC(psci_cpu_off_common) +ENTRY(psci_cpu_entry) + @ Set SMP bit + mrc p15, 0, r0, c1, c0, 1 @ ACTLR
arch/arm/cpu/armv7/psci.S ENTRY(psci_cpu_off_common) · line 185
Quoted 10 lines
arch/arm/cpu/armv7/psci.S +10
-0+ orr r0, r0, #(1 << 6) @ Set SMP bit + mcr p15, 0, r0, c1, c0, 1 @ ACTLR + isb + + bl _nonsec_init + + adr r0, _psci_target_pc + ldr r0, [r0] + b _do_nonsec_entry +ENDPROC(psci_cpu_entry)
I'd add a *big* comment at the top of this. ACTLR is implementation dependent, and while sticking the SMP bit at this location is fairly common among ARM cores, it is by no mean a strong guarantee (this is not an architectural feature).
I'd recommend making it override-able.
Quoted 50 lines
arch/arm/cpu/armv7/psci.S +4
-0+.globl _psci_target_pc +_psci_target_pc: + .word 0 + .popsection(quoted diff) +0
-0
b/arch/arm/cpu/armv7/sunxi/psci.Sindex bb3d4ef..9ea3ce8 100644arch/arm/cpu/armv7/sunxi/psci.S +2
-2@@ -139,7 +139,7 @@ out: mcr p15, 0, r7, c1, c1, 0 @ r2 = target PC .globl psci_cpu_on psci_cpu_on: - adr r0, _target_pc + ldr r0, =_psci_target_pc str r2, [r0] dsb@@ -151,7 +151,7 @@ psci_cpu_on: mov r4, #1 lsl r4, r4, r1 - adr r6, _sunxi_cpu_entry + ldr r6, =psci_cpu_entry str r6, [r0, #0x1a4] @ PRIVATE_REG (boot vector) @ Assert reset on target CPU@@ -197,22 +197,6 @@ psci_cpu_on: mov r0, #ARM_PSCI_RET_SUCCESS @ Return
PSCI_RET_SUCCESSmov pc, lrarch/arm/cpu/armv7/sunxi/psci.S +0
-16-_target_pc: - .word 0 - -_sunxi_cpu_entry: - @ Set SMP bit - mrc p15, 0, r0, c1, c0, 1 - orr r0, r0, #0x40 - mcr p15, 0, r0, c1, c0, 1 - isb - - bl _nonsec_init - - adr r0, _target_pc - ldr r0, [r0] - b _do_nonsec_entry - .globl psci_cpu_off psci_cpu_off: bl psci_cpu_off_common
Signature · 1 line
Jazz is not dead. It just smells funny.
PATCH v4 4/14 ARM: Factor out reusable psci_cpu_entry
Quoted 19 lines · Marc Zyngier
arch/arm/cpu/armv7/psci.S ENTRY(psci_cpu_off_common) · line 185
Quoted 13 lines
arch/arm/cpu/armv7/psci.S +13
-0+ENTRY(psci_cpu_entry) + @ Set SMP bit + mrc p15, 0, r0, c1, c0, 1 @ ACTLR + orr r0, r0, #(1 << 6) @ Set SMP bit + mcr p15, 0, r0, c1, c0, 1 @ ACTLR + isb + + bl _nonsec_init + + adr r0, _psci_target_pc + ldr r0, [r0] + b _do_nonsec_entry +ENDPROC(psci_cpu_entry)I'd add a *big* comment at the top of this. ACTLR is implementation dependent, and while sticking the SMP bit at this location is fairly common among ARM cores, it is by no mean a strong guarantee (this is not an architectural feature).
Quoted 1 line
I'd recommend making it override-able.
Tom R has a series which does something along those lines:
https://patchwork.ozlabs.org/patch/431587/
I suppose it ought to be used here too one way or another.
Ian.
PATCH v4 5/14 ARM: Factor out reusable psci_get_cpu_stack_top
In reply to Jan KiszkaThis algorithm will be useful on Tegra as well, plus we will need it for making _psci_target_pc per-CPU.
--- arch/arm/cpu/armv7/psci.S | 14 ++++++++++++++ arch/arm/cpu/armv7/sunxi/psci.S | 17 +++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-)
arch/arm/cpu/armv7/psci.S +14 -0
@@ -170,6 +170,20 @@ ENTRY(psci_cpu_off_common) bx lr ENDPROC(psci_cpu_off_common) +@ expects CPU ID in r4 (will be overwritten) and returns stack top in r5 +ENTRY(psci_get_cpu_stack_top) + mov r5, #0x400 @ 1kB of stack per CPU + mul r4, r4, r5 + + ldr r5, =psci_text_end @ end of monitor text + add r5, r5, #0x2000 @ Skip two pages + lsr r5, r5, #12 @ Align to start of page + lsl r5, r5, #12 + sub r5, r5, r4 @ here's our stack! + + bx lr +ENDPROC(psci_get_cpu_stack_top) + ENTRY(psci_cpu_entry) @ Set SMP bit mrc p15, 0, r0, c1, c0, 1 @ ACTLR
arch/arm/cpu/armv7/sunxi/psci.S +7 -10
@@ -214,6 +214,8 @@ psci_cpu_off: .globl psci_arch_init psci_arch_init: + mov r6, lr + movw r4, #(GICD_BASE & 0xffff) movt r4, #(GICD_BASE >> 16)
@@ -240,16 +242,11 @@ psci_arch_init: isb armv7_get_cpu_id r4 - mov r5, #0x400 @ 1kB of stack per CPU - mul r4, r4, r5 - - adr r5, text_end @ end of text - add r5, r5, #0x2000 @ Skip two pages - lsr r5, r5, #12 @ Align to start of page - lsl r5, r5, #12 - sub sp, r5, r4 @ here's our stack! + bl psci_get_cpu_stack_top + mov sp, r5 - bx lr + bx r6 -text_end: + .globl psci_text_end +psci_text_end: .popsection
Signature · 1 line
2.1.4
PATCH v4 6/14 ARM: Put target PC for PSCI CPU_ON on per-CPU stack
In reply to Jan KiszkaUse a per-CPU variable for saving the target PC during CPU_ON operations. This allows us to run this service independently on targets that have more than 2 cores and also core-local power control.
--- arch/arm/cpu/armv7/psci.S | 11 +++++------ arch/arm/cpu/armv7/sunxi/psci.S | 9 ++++++--- 2 files changed, 11 insertions(+), 9 deletions(-)
arch/arm/cpu/armv7/psci.S +5 -6
@@ -17,6 +17,7 @@ #include <config.h> #include <linux/linkage.h> +#include <asm/macro.h> #include <asm/psci.h> .pushsection ._secure.text, "ax"
@@ -179,6 +180,7 @@ ENTRY(psci_get_cpu_stack_top) add r5, r5, #0x2000 @ Skip two pages lsr r5, r5, #12 @ Align to start of page lsl r5, r5, #12 + sub r5, r5, #4 @ reserve 1 word for target PC sub r5, r5, r4 @ here's our stack! bx lr
@@ -193,13 +195,10 @@ ENTRY(psci_cpu_entry) bl _nonsec_init - adr r0, _psci_target_pc - ldr r0, [r0] + armv7_get_cpu_id r4 + bl psci_get_cpu_stack_top + ldr r0, [r5] @ target PC at stack top b _do_nonsec_entry ENDPROC(psci_cpu_entry) -.globl _psci_target_pc -_psci_target_pc: - .word 0 - .popsection
arch/arm/cpu/armv7/sunxi/psci.S +6 -3
@@ -139,8 +139,11 @@ out: mcr p15, 0, r7, c1, c1, 0 @ r2 = target PC .globl psci_cpu_on psci_cpu_on: - ldr r0, =_psci_target_pc - str r2, [r0] + push {lr} + + mov r4, r1 + bl psci_get_cpu_stack_top @ get stack top of target CPU + str r2, [r5] @ store target PC at stack top dsb movw r0, #(SUN7I_CPUCFG_BASE & 0xffff)
@@ -195,7 +198,7 @@ psci_cpu_on: str r6, [r0, #0x1e4] mov r0, #ARM_PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS - mov pc, lr + pop {pc} .globl psci_cpu_off psci_cpu_off:
Signature · 1 line
2.1.4
PATCH v4 7/14 tegra124: Add more registers to struct mc_ctlr
In reply to Jan KiszkaFrom: Ian Campbell <[email protected]>
I will need mc_security_cfg0/1 in a future patch and I added the rest while debugging, so thought I might as well commit them.
--- arch/arm/include/asm/arch-tegra124/mc.h | 35 +++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-)
arch/arm/include/asm/arch-tegra124/mc.h +33 -2
@@ -35,9 +35,40 @@ struct mc_ctlr {u32 mc_emem_adr_cfg;/* offset 0x54 */ u32 mc_emem_adr_cfg_dev0;/* offset 0x58 */ u32 mc_emem_adr_cfg_dev1;/* offset 0x5C */ -u32 reserved3[12 ];/* offset 0x60 - 0x8C */ +u32 reserved3[4 ];/* offset 0x60 - 0x6C */ +u32 mc_security_cfg0;/* offset 0x70 */ +u32 mc_security_cfg1;/* offset 0x74 */ +u32 reserved4[6 ];/* offset 0x7C - 0x8C */ u32 mc_emem_arb_reserved[28 ];/* offset 0x90 - 0xFC */ -u32 reserved4[338 ];/* offset 0x100 - 0x644 */ +u32 reserved5[74 ];/* offset 0x100 - 0x224 */ +u32 mc_smmu_translation_enable_0;/* offset 0x228 */ +u32 mc_smmu_translation_enable_1;/* offset 0x22C */ +u32 mc_smmu_translation_enable_2;/* offset 0x230 */ +u32 mc_smmu_translation_enable_3;/* offset 0x234 */ +u32 mc_smmu_afi_asid;/* offset 0x238 */ +u32 mc_smmu_avpc_asid;/* offset 0x23C */ +u32 mc_smmu_dc_asid;/* offset 0x240 */ +u32 mc_smmu_dcb_asid;/* offset 0x244 */ +u32 reserved6[2 ];/* offset 0x248 - 0x24C */ +u32 mc_smmu_hc_asid;/* offset 0x250 */ +u32 mc_smmu_hda_asid;/* offset 0x254 */ +u32 mc_smmu_isp2_asid;/* offset 0x258 */ +u32 reserved7[2 ];/* offset 0x25C - 0x260 */ +u32 mc_smmu_msenc_asid;/* offset 0x264 */ +u32 mc_smmu_nv_asid;/* offset 0x268 */ +u32 mc_smmu_nv2_asid;/* offset 0x26C */ +u32 mc_smmu_ppcs_asid;/* offset 0x270 */ +u32 mc_smmu_sata_asid;/* offset 0x274 */ +u32 reserved8[1 ];/* offset 0x278 */ +u32 mc_smmu_vde_asid;/* offset 0x27C */ +u32 mc_smmu_vi_asid;/* offset 0x280 */ +u32 mc_smmu_vic_asid;/* offset 0x284 */ +u32 mc_smmu_xusb_host_asid;/* offset 0x288 */ +u32 mc_smmu_xusb_dev_asid;/* offset 0x28C */ +u32 reserved9[1 ];/* offset 0x290 */ +u32 mc_smmu_tsec_asid;/* offset 0x294 */ +u32 mc_smmu_ppcs1_asid;/* offset 0x298 */ +u32 reserved10[235 ];/* offset 0x29C - 0x644 */ u32 mc_video_protect_bom;/* offset 0x648 */ u32 mc_video_protect_size_mb;/* offset 0x64c */ u32 mc_video_protect_reg_ctrl;/* offset 0x650 */
Signature · 1 line
2.1.4
PATCH v4 8/14 virt-dt: Allow reservation of secure region when in a RAM carveout
In reply to Jan KiszkaIn this case the secure code lives in RAM, and hence the memory node in the device tree needs to be adjusted. This avoids that the OS will map and possibly access the reservation.
Add support for setting CONFIG_ARMV7_SECURE_RESERVE_SIZE to carve out such a region. We only support cutting off memory from the beginning or the end of a RAM bank as we do not want to increase their number (which would happen if punching a hole) for simplicity reasons
This will be used in a subsequent patch for Jetson-TK1.
--- arch/arm/cpu/armv7/virt-dt.c | 29 +++++++++++++++++++++++++++++ arch/arm/include/asm/armv7.h | 1 + arch/arm/lib/bootm-fdt.c | 5 +++++ 3 files changed, 35 insertions(+)
arch/arm/cpu/armv7/virt-dt.c +29 -0
@@ -16,6 +16,7 @@*/ #include <common.h> +#include <errno.h> #include <stdio_dev.h> #include <linux/ctype.h> #include <linux/types.h>
@@ -88,6 +89,34 @@ static int fdt_psci(void *fdt)return 0 ; } +int armv7_apply_memory_carveout (u64 *start,u64 *size) +{ +#ifdef CONFIG_ARMV7_SECURE_RESERVE_SIZE +if (*start + *size <CONFIG_ARMV7_SECURE_BASE || + *start >= (u64 )CONFIG_ARMV7_SECURE_BASE + +CONFIG_ARMV7_SECURE_RESERVE_SIZE ) +return 0 ; + +/* carveout must be at the beginning or the end of the bank */ +if (*start ==CONFIG_ARMV7_SECURE_BASE || + *start + *size == (u64 )CONFIG_ARMV7_SECURE_BASE + +CONFIG_ARMV7_SECURE_RESERVE_SIZE ) { +if (*size <CONFIG_ARMV7_SECURE_RESERVE_SIZE ) { +debug ("Secure monitor larger than RAM bank!?\n" ); +return -EINVAL ; + } + *size -=CONFIG_ARMV7_SECURE_RESERVE_SIZE ; +if (*start ==CONFIG_ARMV7_SECURE_BASE ) + *start +=CONFIG_ARMV7_SECURE_RESERVE_SIZE ; +return 0 ; + } +debug ("Secure monitor not located@beginning or end of RAM bank\n" ); +return -EINVAL ; +#else /* !CONFIG_ARMV7_SECURE_RESERVE_SIZE */ +return 0 ; +#endif +} +int armv7_update_dt (void *fdt) {if (!armv7_boot_nonsec ())
arch/arm/include/asm/armv7.h +1 -0
@@ -79,6 +79,7 @@ void v7_outer_cache_inval_range(u32 start, u32 end);#if defined(CONFIG_ARMV7_NONSEC ) || defined(CONFIG_ARMV7_VIRT )int armv7_init_nonsec (void ); +int armv7_apply_memory_carveout (u64 *start,u64 *size);int armv7_update_dt (void *fdt);bool armv7_boot_nonsec (void );
arch/arm/lib/bootm-fdt.c +5 -0
@@ -31,6 +31,11 @@ int arch_fixup_fdt(void *blob)for (bank =0 ; bank <CONFIG_NR_DRAM_BANKS ; bank++) { start[bank] = bd->bi_dram[bank].start; size[bank] = bd->bi_dram[bank].size; +#if defined(CONFIG_ARMV7_NONSEC ) || defined(CONFIG_ARMV7_VIRT ) + ret =armv7_apply_memory_carveout (&start[bank], &size[bank]); +if (ret) +return ret; +#endif } ret =fdt_fixup_memory_banks (blob, start, size,CONFIG_NR_DRAM_BANKS );
Signature · 1 line
2.1.4
PATCH v4 9/14 tegra: Make tegra_powergate_power_on public
In reply to Jan KiszkaWill be used for unpowergating CPUs.
--- arch/arm/include/asm/arch-tegra/powergate.h | 1 + arch/arm/mach-tegra/powergate.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
arch/arm/include/asm/arch-tegra/powergate.h +1 -0
@@ -33,6 +33,7 @@ enum tegra_powergate {int tegra_powergate_sequence_power_up (enum tegra_powergate id,enum periph_id periph); +int tegra_powergate_power_on (enum tegra_powergate id);int tegra_powergate_power_off (enum tegra_powergate id);#endif
arch/arm/mach-tegra/powergate.c +1 -1
@@ -44,7 +44,7 @@ static int tegra_powergate_set(enum tegra_powergate id, bool state)return -ETIMEDOUT ; } -static int tegra_powergate_power_on (enum tegra_powergate id) +int tegra_powergate_power_on (enum tegra_powergate id) {return tegra_powergate_set (id, true); }
Signature · 1 line
2.1.4
PATCH v4 10/14 tegra: Add ap_pm_init hook
In reply to Jan KiszkaThis function will be used to initialize CPU power management for Tegra SOCs. For now it does nothing.
--- arch/arm/include/asm/arch-tegra/ap.h | 5 +++++ board/nvidia/common/board.c | 4 ++++ 2 files changed, 9 insertions(+)
arch/arm/include/asm/arch-tegra/ap.h +5 -0
@@ -63,6 +63,11 @@ int tegra_get_chip(void);*/ int tegra_get_sku_info (void ); +/** +* Initialize power management for application processors +*/ +void ap_pm_init (void ); +/* Do any chip-specific cache config */ void config_cache (void );
board/nvidia/common/board.c +4 -0
@@ -21,6 +21,7 @@#include <asm/arch/pwm.h> #endif #include <asm/arch/tegra.h> +#include <asm/arch-tegra/ap.h> #include <asm/arch-tegra/board.h> #include <asm/arch-tegra/clk_rst.h> #include <asm/arch-tegra/pmc.h>
@@ -56,6 +57,7 @@ const struct tegra_sysinfo sysinfo = { CONFIG_TEGRA_BOARD_STRING }; +__weak void ap_pm_init (void ) {}__weak void pinmux_init (void ) {}__weak void pin_mux_usb (void ) {}__weak void pin_mux_spi (void ) {}
@@ -96,6 +98,8 @@ int board_init(void)clock_init ();clock_verify (); +ap_pm_init (); +#ifdef CONFIG_TEGRA_SPI pin_mux_spi ();#endif
Signature · 1 line
2.1.4
PATCH v4 11/14 tegra124: Add PSCI support for Tegra124
In reply to Jan KiszkaThis is based on Thierry Reding's work and uses Ian Campell's preparatory patches. It comes with full support for CPU_ON/OFF PSCI services. The algorithm used in this version for turning CPUs on and off was proposed by Peter De Schrijver and Thierry Reding in
http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/210881. It consists of first enabling CPU1..3 via the PMC, just to powergate them again with the help of the Flow Controller. Once the Flow Controller is in place, we can leave the PMC alone while processing CPU_ON and CPU_OFF PSCI requests.
--- arch/arm/include/asm/arch-tegra124/flow.h | 6 ++ arch/arm/mach-tegra/Makefile | 4 ++ arch/arm/mach-tegra/psci.S | 101 ++++++++++++++++++++++++++++++ arch/arm/mach-tegra/tegra124/Makefile | 4 ++ arch/arm/mach-tegra/tegra124/ap.c | 55 ++++++++++++++++ 5 files changed, 170 insertions(+) create mode 100644 arch/arm/mach-tegra/psci.S create mode 100644 arch/arm/mach-tegra/tegra124/ap.c
arch/arm/include/asm/arch-tegra124/flow.h +6 -0
@@ -37,4 +37,10 @@ struct flow_ctlr {/* FLOW_CTLR_CLUSTER_CONTROL_0 0x2c */ #define ACTIVE_LP (1 << 0) +/* CPUn_CSR_0 */ +#define CSR_ENABLE (1 << 0) +#define CSR_IMMEDIATE_WAKE (1 << 3) +#define CSR_WAIT_WFI_SHIFT 8 +#define CSR_PWR_OFF_STS (1 << 16) +#endif /* _TEGRA124_FLOW_H_ */
arch/arm/mach-tegra/Makefile +4 -0
@@ -25,6 +25,10 @@ obj-y += xusb-padctl.o obj-$(CONFIG_DISPLAY_CPUINFO) += sys_info.o obj-$(CONFIG_TEGRA124) += vpr.o +ifndef CONFIG_SPL_BUILD +obj-$(CONFIG_ARMV7_PSCI) += psci.o +endif + obj-$(CONFIG_TEGRA20) += tegra20/ obj-$(CONFIG_TEGRA30) += tegra30/ obj-$(CONFIG_TEGRA114) += tegra114/
arch/arm/mach-tegra/psci.S new file +101 -0
101 lines not on this page · raw message
arch/arm/mach-tegra/tegra124/Makefile +4 -0
@@ -11,3 +11,7 @@ obj-y += clock.o obj-y += funcmux.o obj-y += pinmux.o obj-y += xusb-padctl.o + +ifndef CONFIG_SPL_BUILD +obj-$(CONFIG_ARMV7_PSCI) += ap.o +endif
arch/arm/mach-tegra/tegra124/ap.c new file +55 -0
55 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH v4 12/14 jetson-tk1: Add PSCI configuration options and reserve secure code
In reply to Jan KiszkaFrom: Ian Campbell <[email protected]>
The secure world code is relocated to the MB just below the top of 4G, we reserve it in the FDT (by setting CONFIG_ARMV7_SECURE_RESERVE_SIZE) but it is not protected in h/w. See next patch.
--- arch/arm/mach-tegra/tegra124/Kconfig | 2 ++ include/configs/jetson-tk1.h | 5 +++++ 2 files changed, 7 insertions(+)
arch/arm/mach-tegra/tegra124/Kconfig +2 -0
@@ -5,6 +5,8 @@ choice config TARGET_JETSON_TK1 bool "NVIDIA Tegra124 Jetson TK1 board" + select CPU_V7_HAS_NONSEC if !SPL_BUILD + select CPU_V7_HAS_VIRT if !SPL_BUILD config TARGET_NYAN_BIG bool "Google/NVIDIA Nyan-big Chrombook"
include/configs/jetson-tk1.h +5 -0
@@ -81,4 +81,9 @@#include "tegra-common-usb-gadget.h" #include "tegra-common-post.h" +#define CONFIG_ARMV7_PSCI 1 +/* Reserve top 1M for secure RAM */ +#define CONFIG_ARMV7_SECURE_BASE 0xfff00000 +#define CONFIG_ARMV7_SECURE_RESERVE_SIZE 0x00100000 +#endif /* __CONFIG_H */
Signature · 1 line
2.1.4
PATCH v4 13/14 tegra124: Reserve secure RAM using MC_SECURITY_CFG{0, 1}_0
In reply to Jan KiszkaFrom: Ian Campbell <[email protected]>
These registers can be used to prevent non-secure world from accessing a megabyte aligned region of RAM, use them to protect the u-boot secure monitor code.
At first I tried to do this from s_init(), however this inexplicably causes u-boot's networking (e.g. DHCP) to fail, while networking under Linux was fine.
So instead I have added a new weak arch function protect_secure_section() called from relocate_secure_section() and reserved the region there. This is better overall since it defers the reservation until after the sec vs. non-sec decision (which can be influenced by an envvar) has been made when booting the os.
--- arch/arm/cpu/armv7/virt-v7.c | 5 +++++ arch/arm/include/asm/system.h | 1 + arch/arm/mach-tegra/ap.c | 15 +++++++++++++++ 3 files changed, 21 insertions(+)
arch/arm/cpu/armv7/virt-v7.c +5 -0
@@ -46,6 +46,10 @@ static unsigned long get_gicd_base_address(void)#endif } +/* Define a specific version of this function to enable any available +* hardware protections for the reserved region */ +void __weak protect_secure_section (void ) {} +static void relocate_secure_section (void ) {#ifdef CONFIG_ARMV7_SECURE_BASE
@@ -54,6 +58,7 @@ static void relocate_secure_section(void)memcpy ((void *)CONFIG_ARMV7_SECURE_BASE , __secure_start, sz);flush_dcache_range (CONFIG_ARMV7_SECURE_BASE ,CONFIG_ARMV7_SECURE_BASE + sz +1 ); +protect_secure_section ();invalidate_icache_all ();#endif }
arch/arm/include/asm/system.h +1 -0
@@ -77,6 +77,7 @@ void armv8_switch_to_el1(void);void gic_init (void );void gic_send_sgi (unsigned long sgino);void wait_for_wakeup (void ); +void protect_secure_region (void );void smp_kick_all_cpus (void );void flush_l3_cache (void );
arch/arm/mach-tegra/ap.c +15 -0
@@ -10,6 +10,7 @@#include <common.h> #include <asm/io.h> #include <asm/arch/gp_padctrl.h> +#include <asm/arch/mc.h> #include <asm/arch-tegra/ap.h> #include <asm/arch-tegra/clock.h> #include <asm/arch-tegra/fuse.h>
@@ -154,6 +155,20 @@ static void init_pmc_scratch(void)writel (odmdata, &pmc->pmc_scratch20); } +#ifdef CONFIG_ARMV7_SECURE_RESERVE_SIZE +void protect_secure_section (void ) +{ +struct mc_ctlr *mc = (struct mc_ctlr *)NV_PA_MC_BASE ; + +/* Must be MB aligned */ +BUILD_BUG_ON (CONFIG_ARMV7_SECURE_BASE &0xFFFFF ); +BUILD_BUG_ON (CONFIG_ARMV7_SECURE_RESERVE_SIZE &0xFFFFF ); + +writel (CONFIG_ARMV7_SECURE_BASE , &mc->mc_security_cfg0); +writel (CONFIG_ARMV7_SECURE_RESERVE_SIZE >>20 , &mc->mc_security_cfg1); +} +#endif +void s_init (void ) {/* Init PMC scratch memory */
Signature · 1 line
2.1.4
PATCH v4 14/14 tegra: Set CNTFRQ for secondary CPUs
In reply to Jan KiszkaWe only set CNTFRQ in arch_timer_init for the boot CPU. But this has to happen for all cores.
Fixing this resolves problems of KVM with emulating the generic timer/counter.
--- arch/arm/mach-tegra/psci.S | 13 +++++++++++++ 1 file changed, 13 insertions(+)
arch/arm/mach-tegra/psci.S +13 -0
@@ -51,12 +51,25 @@ ENTRY(psci_arch_init) str r5, [r4] armv7_get_cpu_id r4 + + adr r5, _sys_clock_freq + cmp r4, #0 + + mrceq p15, 0, r7, c14, c0, 0 @ read CNTFRQ from CPU0 + streq r7, [r5] + + ldrne r7, [r5] + mcrne p15, 0, r7, c14, c0, 0 @ write CNTFRQ to CPU1..3 + bl psci_get_cpu_stack_top mov sp, r5 bx r6 ENDPROC(psci_arch_init) +_sys_clock_freq: + .word 0 + ENTRY(psci_cpu_off) bl psci_cpu_off_common
Signature · 1 line
2.1.4
v4 cover Add PSCI support for Jetson TK1/Tegra124 + CNTFRQ fix
In reply to Jan KiszkaQuoted 1 line · Jan Kiszka
CC Ian Campbell <[email protected]>
I've been running with these on my Jetson (and booting Xen on top) just fine. So, FWIW:
Cheers,
Ian.
v4 cover Add PSCI support for Jetson TK1/Tegra124 + CNTFRQ fix
Quoted 8 lines · Ian Campbell
Quoted 1 line · Jan Kiszka
CC Ian Campbell <[email protected]>I've been running with these on my Jetson (and booting Xen on top) just fine. So, FWIW:
Tested-by Ian Campbell <[email protected]>
Great, thanks! I'll roll out v5 soon to address the pending review comments. Would be perfect if you could test that as well.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT RTC ITP SES-DE Corporate Competence Center Embedded Linux