Re: [U-Boot] [PATCH v3 09/12] tegra124: Add PSCI support for Tegra124

2015-02-26 Thread Thierry Reding
On Wed, Feb 18, 2015 at 09:14:03AM +0100, Jan Kiszka wrote:
[...]
 +ENTRY(psci_cpu_off)
 + bl psci_cpu_off_common
 +
 + mrc p15, 0, r1, c0, c0, 5   @ MPIDR
 + and r1, r1, #7  @ number of CPUs in cluster
 +
 + get_csr_reg r1, r2, r3
 +
 + ldr r6, =TEGRA_FLOW_CTRL_BASE
 + mov r5, #(CSR_ENABLE)
 + add r5, r1, lsl #CSR_WAIT_WFI_SHIFT

This puts the wrong value into the WAIT_WFI field. The value of that
field is supposed to be a mask, not the index of the CPU. I've used this
to fix it:

mov r4, #(1  CSR_WAIT_WFI_SHIFT)
add r5, r4, lsl r1

With that fixed I see that with CPU hotplugging the power partition for
the CPU that's taken offline is gated. To verify:

# cat /sys/kernel/debug/powergate
# echo 0  /sys/devices/system/cpu/cpu1/online
# cat /sys/kernel/debug/powergate

Thierry


pgpFMehkmVUYA.pgp
Description: PGP signature
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH v3 09/12] tegra124: Add PSCI support for Tegra124

2015-02-26 Thread Thierry Reding
On Wed, Feb 18, 2015 at 09:14:03AM +0100, Jan Kiszka wrote:
[...]
 diff --git a/arch/arm/cpu/armv7/tegra124/ap.c 
 b/arch/arm/cpu/armv7/tegra124/ap.c
[...]
 +void ap_pm_init(void)
 +{
 + struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE;
 + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
 +
 + writel((u32)park_cpu, EXCEP_VECTOR_CPU_RESET_VECTOR);
 +
 + tegra_powergate_power_on(TEGRA_POWERGATE_CPU1);
 + tegra_powergate_power_on(TEGRA_POWERGATE_CPU2);
 + tegra_powergate_power_on(TEGRA_POWERGATE_CPU3);
 +
 + writel((2  CSR_WAIT_WFI_SHIFT) | CSR_ENABLE, flow-cpu1_csr);
 + writel((4  CSR_WAIT_WFI_SHIFT) | CSR_ENABLE, flow-cpu2_csr);
 + writel((8  CSR_WAIT_WFI_SHIFT) | CSR_ENABLE, flow-cpu3_csr);
 +
 + writel(EVENT_MODE_STOP, flow-halt_cpu1_events);
 + writel(EVENT_MODE_STOP, flow-halt_cpu2_events);
 + writel(EVENT_MODE_STOP, flow-halt_cpu3_events);
 +
 + while (readl(pmc-pmc_pwrgate_status)  ((1  TEGRA_POWERGATE_CPU1) |
 +   (1  TEGRA_POWERGATE_CPU2) |
 +   (1  TEGRA_POWERGATE_CPU3)))
 + /* wait */;
 +}

As discussed previously I don't quite understand why the sequence:

1) program CSR registers
2) program halt events
3) power on CPUs

does not work. Testing shows that PSCI will work with that sequence once
the kernel is loaded. However I can also confirm that U-Boot doesn't see
the power partition status updated to off, so I assume the partitions
will indeed still be powered on if we change the sequence.

So until we find out why that's happening I think it's safe to go with
the above sequence, since it does what we want. Perhaps add a comment
describing the ambiguity?

Also as a cosmetic cleanup, perhaps rather than checking the PMC power
gate status register you check bit 16 of each CPU's CSR register, which
should mirror the corresponding power gate status bit. That way you
don't need to access the PMC registers but restrict register accesses to
a single IP block in this code.

Thierry


pgpPDCiAgIFjD.pgp
Description: PGP signature
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH v3 09/12] tegra124: Add PSCI support for Tegra124

2015-02-26 Thread Jan Kiszka
On 2015-02-26 10:08, Thierry Reding wrote:
 On Wed, Feb 18, 2015 at 09:14:03AM +0100, Jan Kiszka wrote:
 [...]
 +ENTRY(psci_cpu_off)
 +bl psci_cpu_off_common
 +
 +mrc p15, 0, r1, c0, c0, 5   @ MPIDR
 +and r1, r1, #7  @ number of CPUs in cluster
 +
 +get_csr_reg r1, r2, r3
 +
 +ldr r6, =TEGRA_FLOW_CTRL_BASE
 +mov r5, #(CSR_ENABLE)
 +add r5, r1, lsl #CSR_WAIT_WFI_SHIFT
 
 This puts the wrong value into the WAIT_WFI field. The value of that
 field is supposed to be a mask, not the index of the CPU. I've used this
 to fix it:
 
   mov r4, #(1  CSR_WAIT_WFI_SHIFT)
   add r5, r4, lsl r1
 
 With that fixed I see that with CPU hotplugging the power partition for
 the CPU that's taken offline is gated. To verify:
 
   # cat /sys/kernel/debug/powergate
   # echo 0  /sys/devices/system/cpu/cpu1/online
   # cat /sys/kernel/debug/powergate

Ah, good catch. Will include your fix.

Jan

-- 
Siemens AG, Corporate Technology, CT RTC ITP SES-DE
Corporate Competence Center Embedded Linux
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


[U-Boot] [PATCH v3 09/12] tegra124: Add PSCI support for Tegra124

2015-02-18 Thread Jan Kiszka
This 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 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.

Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 arch/arm/cpu/armv7/Makefile   |   1 +
 arch/arm/cpu/armv7/tegra-common/Makefile  |   1 +
 arch/arm/cpu/armv7/tegra-common/psci.S| 101 ++
 arch/arm/cpu/armv7/tegra124/Makefile  |   7 +++
 arch/arm/cpu/armv7/tegra124/ap.c  |  44 +
 arch/arm/include/asm/arch-tegra124/flow.h |   5 ++
 6 files changed, 159 insertions(+)
 create mode 100644 arch/arm/cpu/armv7/tegra-common/psci.S
 create mode 100644 arch/arm/cpu/armv7/tegra124/Makefile
 create mode 100644 arch/arm/cpu/armv7/tegra124/ap.c

diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
index 409e6f5..616b6cc 100644
--- a/arch/arm/cpu/armv7/Makefile
+++ b/arch/arm/cpu/armv7/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_SOCFPGA) += socfpga/
 obj-$(if $(filter stv0991,$(SOC)),y) += stv0991/
 obj-$(CONFIG_ARCH_SUNXI) += sunxi/
 obj-$(CONFIG_TEGRA20) += tegra20/
+obj-$(CONFIG_TEGRA124) += tegra124/
 obj-$(CONFIG_U8500) += u8500/
 obj-$(CONFIG_ARCH_UNIPHIER) += uniphier/
 obj-$(CONFIG_VF610) += vf610/
diff --git a/arch/arm/cpu/armv7/tegra-common/Makefile 
b/arch/arm/cpu/armv7/tegra-common/Makefile
index 463c260..89355ca 100644
--- a/arch/arm/cpu/armv7/tegra-common/Makefile
+++ b/arch/arm/cpu/armv7/tegra-common/Makefile
@@ -7,4 +7,5 @@
 # SPDX-License-Identifier: GPL-2.0+
 #
 
+obj-$(CONFIG_ARMV7_PSCI) += psci.o
 obj-$(CONFIG_CMD_ENTERRCM) += cmd_enterrcm.o
diff --git a/arch/arm/cpu/armv7/tegra-common/psci.S 
b/arch/arm/cpu/armv7/tegra-common/psci.S
new file mode 100644
index 000..b7501fb
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra-common/psci.S
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2014, NVIDIA
+ * Copyright (C) 2015, Siemens AG
+ *
+ * Authors:
+ *  Thierry Reding tred...@nvidia.com
+ *  Jan Kiszka jan.kis...@siemens.com
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include linux/linkage.h
+#include asm/psci.h
+
+   .pushsection ._secure.text, ax
+   .arch_extension sec
+
+#define TEGRA_SB_CSR_0 0x6000c200
+#define NS_RST_VEC_WR_DIS  (1  1)
+
+#define TEGRA_RESET_EXCEPTION_VECTOR   0x6000f100
+
+#define TEGRA_FLOW_CTRL_BASE   0x60007000
+#define FLOW_CTRL_CPU_CSR  0x08
+#define CSR_ENABLE (1  0)
+#define CSR_IMMEDIATE_WAKE (1  3)
+#define CSR_WAIT_WFI_SHIFT 8
+#define FLOW_CTRL_CPU1_CSR 0x18
+
+@ converts CPU ID into FLOW_CTRL_CPUn_CSR offset
+.macro get_csr_reg cpu, ofs, tmp
+   cmp \cpu, #0@ CPU0?
+   lsl \tmp, \cpu, #3  @ multiple by 8 (register offset CPU1-3)
+   moveq   \ofs, #FLOW_CTRL_CPU_CSR
+   addne   \ofs, \tmp, #FLOW_CTRL_CPU1_CSR - 8
+.endm
+
+ENTRY(psci_arch_init)
+   mov r6, lr
+
+   mrc p15, 0, r5, c1, c1, 0   @ Read SCR
+   bic r5, r5, #1  @ Secure mode
+   mcr p15, 0, r5, c1, c1, 0   @ Write SCR
+   isb
+
+   @ lock reset vector
+   ldr r4, =TEGRA_SB_CSR_0
+   ldr r5, [r4]
+   orr r5, r5, #NS_RST_VEC_WR_DIS
+   str r5, [r4]
+
+   mrc p15, 0, r4, c0, c0, 5   @ MPIDR
+   and r4, r4, #7  @ number of CPUs in cluster
+   bl  psci_get_cpu_stack_top
+   mov sp, r5
+
+   bx  r6
+ENDPROC(psci_arch_init)
+
+ENTRY(psci_cpu_off)
+   bl psci_cpu_off_common
+
+   mrc p15, 0, r1, c0, c0, 5   @ MPIDR
+   and r1, r1, #7  @ number of CPUs in cluster
+
+   get_csr_reg r1, r2, r3
+
+   ldr r6, =TEGRA_FLOW_CTRL_BASE
+   mov r5, #(CSR_ENABLE)
+   add r5, r1, lsl #CSR_WAIT_WFI_SHIFT
+   str r5, [r6, r2]
+
+_loop: wfi
+   b   _loop
+ENDPROC(psci_cpu_off)
+
+ENTRY(psci_cpu_on)
+   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
+
+   ldr r6, =TEGRA_RESET_EXCEPTION_VECTOR
+   ldr r5, =psci_cpu_entry
+   str r5, [r6]
+
+   get_csr_reg r1, r2, r3
+
+   ldr r6, =TEGRA_FLOW_CTRL_BASE
+   mov r5, #(CSR_IMMEDIATE_WAKE | CSR_ENABLE)
+   str r5, [r6, r2]
+
+   mov r0, #ARM_PSCI_RET_SUCCESS   @ Return PSCI_RET_SUCCESS
+   pop {pc}
+ENDPROC(psci_cpu_on)
+
+   .globl psci_text_end
+psci_text_end:
+