All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 0/9] sunxi: sun5/7i: add the psci suspend function
@ 2016-10-06 14:33 Antoine Tenart
  2016-10-06 14:33 ` [U-Boot] [PATCH v2 1/9] ARM: add the ARM_GIC configuration option Antoine Tenart
                   ` (9 more replies)
  0 siblings, 10 replies; 13+ messages in thread
From: Antoine Tenart @ 2016-10-06 14:33 UTC (permalink / raw)
  To: u-boot

Hi all,

This series adds an implementation of the psci suspend function for both
sun5i and sun7i. This was tested on Nextthing's CHIP and on a A20, using
cpuidle in Linux. My tests showed a power consumption reduced by a factor
2 on the CHIP when the system was idle. It went from ~1W without cpuidle
enabled to ~0.45W.

The idea of this suspend function is to put the dram into self-refresh,
cut off some plls and to switch cpuclk to a source with a lower
frequency. Please note the sun7i implementation lacks some parts as
putting the ram into self-refresh and coming back from this state seems
a bit tricky. I made some tests but did not managed yet to have a stable
solution.

As the sun5i does not have a GIC, I needed to remove some code from the
generic psci code. To do this I added an ARM_GIC Kconfig option which
needs to be selected by each SoC having a GIC. I already added the
relevant lines for SoCs using the PSCI ARMv7 code. As this Kconfig
option is currently only used in the psci code, it should be safe to add
it even if all the SoCs having a GIC do not select it, as long as they
don't have psci functions.

Finally the series has a patch to add defines used by the psci code and
another patch to let sun5i SoCs boot the kernel in non-secure mode so
that it can call psci functions.

Thanks!

Antoine

Since v1:
  - Rebased on the latest master and updated the patches.
  - Fixed a compile warning I introduced in virt-v7.c
  - Added the missing ARM_GIC Kconfig options.
  - Fixed a commit message (removed 'HYP').

Antoine Tenart (9):
  ARM: add the ARM_GIC configuration option
  sunxi: select ARM_GIC for sun[6789]i
  ARM: select ARM_GIC for SoCs having a psci implementation
  exynos: select ARM_GIC for TARGET_ARNDALE
  tegra: select ARM_GIC for Tegra TK1s
  ARM: PSCI: protect GIC specific code with ARM_GIC
  sun5/7i: add an implementation of the psci suspend function
  sun5i: add defines used by the PSCI code
  sun5i: boot in non-secure mode by default

 arch/arm/Kconfig                              |  11 ++
 arch/arm/cpu/armv7/nonsec_virt.S              |   6 +
 arch/arm/cpu/armv7/sunxi/Makefile             |   9 +-
 arch/arm/cpu/armv7/sunxi/psci_suspend.c       | 175 ++++++++++++++++++++++++++
 arch/arm/cpu/armv7/virt-v7.c                  |  42 ++++---
 arch/arm/include/asm/arch-sunxi/clock_sun4i.h |   7 ++
 arch/arm/include/asm/arch-sunxi/dram_sun4i.h  |  11 ++
 arch/arm/mach-exynos/Kconfig                  |   1 +
 arch/arm/mach-tegra/tegra124/Kconfig          |   2 +
 board/sunxi/Kconfig                           |   9 ++
 include/configs/sun5i.h                       |   3 +
 11 files changed, 261 insertions(+), 15 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/sunxi/psci_suspend.c

-- 
2.10.1

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [U-Boot] [PATCH v2 1/9] ARM: add the ARM_GIC configuration option
  2016-10-06 14:33 [U-Boot] [PATCH v2 0/9] sunxi: sun5/7i: add the psci suspend function Antoine Tenart
@ 2016-10-06 14:33 ` Antoine Tenart
  2016-10-06 14:33 ` [U-Boot] [PATCH v2 2/9] sunxi: select ARM_GIC for sun[6789]i Antoine Tenart
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Antoine Tenart @ 2016-10-06 14:33 UTC (permalink / raw)
  To: u-boot

Some SoC does not have a GIC. Adds a configuration option to denote
this, allowing to remove code configuring the GIC when it's not
possible.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
 arch/arm/Kconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f55d5b2cd743..f361a47fc52f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -13,6 +13,9 @@ config DMA_ADDR_T_64BIT
 	bool
 	default y if ARM64
 
+config ARM_GIC
+	bool
+
 config HAS_VBAR
 	bool
 
-- 
2.10.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [U-Boot] [PATCH v2 2/9] sunxi: select ARM_GIC for sun[6789]i
  2016-10-06 14:33 [U-Boot] [PATCH v2 0/9] sunxi: sun5/7i: add the psci suspend function Antoine Tenart
  2016-10-06 14:33 ` [U-Boot] [PATCH v2 1/9] ARM: add the ARM_GIC configuration option Antoine Tenart
@ 2016-10-06 14:33 ` Antoine Tenart
  2016-10-06 14:33 ` [U-Boot] [PATCH v2 3/9] ARM: select ARM_GIC for SoCs having a psci implementation Antoine Tenart
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Antoine Tenart @ 2016-10-06 14:33 UTC (permalink / raw)
  To: u-boot

Select the newly introduced ARM_GIC option to the relevant sunxi
MACH configurations.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
 board/sunxi/Kconfig | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index b139d1c139a2..b8a34e4fbdf8 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -58,6 +58,7 @@ config MACH_SUN5I
 
 config MACH_SUN6I
 	bool "sun6i (Allwinner A31)"
+	select ARM_GIC
 	select CPU_V7
 	select CPU_V7_HAS_NONSEC
 	select CPU_V7_HAS_VIRT
@@ -68,6 +69,7 @@ config MACH_SUN6I
 
 config MACH_SUN7I
 	bool "sun7i (Allwinner A20)"
+	select ARM_GIC
 	select CPU_V7
 	select CPU_V7_HAS_NONSEC
 	select CPU_V7_HAS_VIRT
@@ -78,6 +80,7 @@ config MACH_SUN7I
 
 config MACH_SUN8I_A23
 	bool "sun8i (Allwinner A23)"
+	select ARM_GIC
 	select CPU_V7
 	select CPU_V7_HAS_NONSEC
 	select CPU_V7_HAS_VIRT
@@ -88,6 +91,7 @@ config MACH_SUN8I_A23
 
 config MACH_SUN8I_A33
 	bool "sun8i (Allwinner A33)"
+	select ARM_GIC
 	select CPU_V7
 	select CPU_V7_HAS_NONSEC
 	select CPU_V7_HAS_VIRT
@@ -98,12 +102,14 @@ config MACH_SUN8I_A33
 
 config MACH_SUN8I_A83T
 	bool "sun8i (Allwinner A83T)"
+	select ARM_GIC
 	select CPU_V7
 	select SUNXI_GEN_SUN6I
 	select SUPPORT_SPL
 
 config MACH_SUN8I_H3
 	bool "sun8i (Allwinner H3)"
+	select ARM_GIC
 	select CPU_V7
 	select CPU_V7_HAS_NONSEC
 	select CPU_V7_HAS_VIRT
@@ -114,6 +120,7 @@ config MACH_SUN8I_H3
 
 config MACH_SUN9I
 	bool "sun9i (Allwinner A80)"
+	select ARM_GIC
 	select CPU_V7
 	select SUNXI_GEN_SUN6I
 
-- 
2.10.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [U-Boot] [PATCH v2 3/9] ARM: select ARM_GIC for SoCs having a psci implementation
  2016-10-06 14:33 [U-Boot] [PATCH v2 0/9] sunxi: sun5/7i: add the psci suspend function Antoine Tenart
  2016-10-06 14:33 ` [U-Boot] [PATCH v2 1/9] ARM: add the ARM_GIC configuration option Antoine Tenart
  2016-10-06 14:33 ` [U-Boot] [PATCH v2 2/9] sunxi: select ARM_GIC for sun[6789]i Antoine Tenart
@ 2016-10-06 14:33 ` Antoine Tenart
  2016-10-06 14:33 ` [U-Boot] [PATCH v2 4/9] exynos: select ARM_GIC for TARGET_ARNDALE Antoine Tenart
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Antoine Tenart @ 2016-10-06 14:33 UTC (permalink / raw)
  To: u-boot

Select the newly introduced ARM_GIC option to the relevant MACH
configurations.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
 arch/arm/Kconfig | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f361a47fc52f..ed1a7d607dbe 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -316,6 +316,7 @@ config ARCH_BCM283X
 
 config TARGET_VEXPRESS_CA15_TC2
 	bool "Support vexpress_ca15_tc2"
+	select ARM_GIC
 	select CPU_V7
 	select CPU_V7_HAS_NONSEC
 	select CPU_V7_HAS_VIRT
@@ -402,14 +403,17 @@ config TARGET_BCM23550_W1D
 
 config TARGET_BCM28155_AP
 	bool "Support bcm28155_ap"
+	select ARM_GIC
 	select CPU_V7
 
 config TARGET_BCMCYGNUS
 	bool "Support bcmcygnus"
+	select ARM_GIC
 	select CPU_V7
 
 config TARGET_BCMNSP
 	bool "Support bcmnsp"
+	select ARM_GIC
 	select CPU_V7
 
 config ARCH_EXYNOS
@@ -452,6 +456,7 @@ config ARCH_MESON
 
 config ARCH_MX7
 	bool "Freescale MX7"
+	select ARM_GIC
 	select CPU_V7
 
 config ARCH_MX6
@@ -738,6 +743,7 @@ config TARGET_LS1012AFRDM
 
 config TARGET_LS1021AQDS
 	bool "Support ls1021aqds"
+	select ARM_GIC
 	select CPU_V7
 	select SUPPORT_SPL
 	select ARCH_LS1021A
@@ -746,6 +752,7 @@ config TARGET_LS1021AQDS
 
 config TARGET_LS1021ATWR
 	bool "Support ls1021atwr"
+	select ARM_GIC
 	select CPU_V7
 	select SUPPORT_SPL
 	select ARCH_LS1021A
@@ -810,6 +817,7 @@ config TARGET_COLIBRI_PXA270
 
 config ARCH_UNIPHIER
 	bool "Socionext UniPhier SoCs"
+	select ARM_GIC
 	select BLK
 	select CLK_UNIPHIER
 	select DM
-- 
2.10.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [U-Boot] [PATCH v2 4/9] exynos: select ARM_GIC for TARGET_ARNDALE
  2016-10-06 14:33 [U-Boot] [PATCH v2 0/9] sunxi: sun5/7i: add the psci suspend function Antoine Tenart
                   ` (2 preceding siblings ...)
  2016-10-06 14:33 ` [U-Boot] [PATCH v2 3/9] ARM: select ARM_GIC for SoCs having a psci implementation Antoine Tenart
@ 2016-10-06 14:33 ` Antoine Tenart
  2016-10-06 14:33 ` [U-Boot] [PATCH v2 5/9] tegra: select ARM_GIC for Tegra TK1s Antoine Tenart
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Antoine Tenart @ 2016-10-06 14:33 UTC (permalink / raw)
  To: u-boot

Select the newly introduced ARM_GIC option to the relevant configuration
which also have a psci implementation.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
 arch/arm/mach-exynos/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index ce2a16f95b02..f976d10eaee7 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -79,6 +79,7 @@ config TARGET_ODROID_XU3
 
 config TARGET_ARNDALE
 	bool "Exynos5250 Arndale board"
+	select ARM_GIC
 	select CPU_V7_HAS_NONSEC
 	select CPU_V7_HAS_VIRT
 	select SUPPORT_SPL
-- 
2.10.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [U-Boot] [PATCH v2 5/9] tegra: select ARM_GIC for Tegra TK1s
  2016-10-06 14:33 [U-Boot] [PATCH v2 0/9] sunxi: sun5/7i: add the psci suspend function Antoine Tenart
                   ` (3 preceding siblings ...)
  2016-10-06 14:33 ` [U-Boot] [PATCH v2 4/9] exynos: select ARM_GIC for TARGET_ARNDALE Antoine Tenart
@ 2016-10-06 14:33 ` Antoine Tenart
  2016-10-06 16:15   ` Stephen Warren
  2016-10-06 14:33 ` [U-Boot] [PATCH v2 6/9] ARM: PSCI: protect GIC specific code with ARM_GIC Antoine Tenart
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 13+ messages in thread
From: Antoine Tenart @ 2016-10-06 14:33 UTC (permalink / raw)
  To: u-boot

Select the newly introduced ARM_GIC option to the relevant configuration
which also have a psci implementation.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
 arch/arm/mach-tegra/tegra124/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/mach-tegra/tegra124/Kconfig b/arch/arm/mach-tegra/tegra124/Kconfig
index df7746228386..41d75bd2f321 100644
--- a/arch/arm/mach-tegra/tegra124/Kconfig
+++ b/arch/arm/mach-tegra/tegra124/Kconfig
@@ -6,12 +6,14 @@ choice
 
 config TARGET_JETSON_TK1
 	bool "NVIDIA Tegra124 Jetson TK1 board"
+	select ARM_GIC
 	select CPU_V7_HAS_NONSEC
 	select CPU_V7_HAS_VIRT
 	select ARCH_SUPPORT_PSCI
 
 config TARGET_CEI_TK1_SOM
 	bool "Colorado Engineering Inc Tegra124 TK1-som board"
+	select ARM_GIC
 	select CPU_V7_HAS_NONSEC if !SPL_BUILD
 	select CPU_V7_HAS_VIRT if !SPL_BUILD
 	help
-- 
2.10.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [U-Boot] [PATCH v2 6/9] ARM: PSCI: protect GIC specific code with ARM_GIC
  2016-10-06 14:33 [U-Boot] [PATCH v2 0/9] sunxi: sun5/7i: add the psci suspend function Antoine Tenart
                   ` (4 preceding siblings ...)
  2016-10-06 14:33 ` [U-Boot] [PATCH v2 5/9] tegra: select ARM_GIC for Tegra TK1s Antoine Tenart
@ 2016-10-06 14:33 ` Antoine Tenart
  2016-10-06 14:33 ` [U-Boot] [PATCH v2 7/9] sun5/7i: add an implementation of the psci suspend function Antoine Tenart
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Antoine Tenart @ 2016-10-06 14:33 UTC (permalink / raw)
  To: u-boot

Introducing the ARM_GIC configuration option, use it to only use GIC
specific code in ARM PSCI function when the SoC has a GIC.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
 arch/arm/cpu/armv7/nonsec_virt.S |  6 ++++++
 arch/arm/cpu/armv7/virt-v7.c     | 42 ++++++++++++++++++++++++++--------------
 2 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S
index 95ce9387b83e..2a11d2e83b80 100644
--- a/arch/arm/cpu/armv7/nonsec_virt.S
+++ b/arch/arm/cpu/armv7/nonsec_virt.S
@@ -164,6 +164,7 @@ ENDPROC(_smp_pen)
  * though, but we check this in C before calling this function.
  */
 ENTRY(_nonsec_init)
+#ifdef CONFIG_ARM_GIC
 	get_gicd_addr	r3
 
 	mvn	r1, #0				@ all bits to 1
@@ -175,6 +176,7 @@ ENTRY(_nonsec_init)
 	str	r1, [r3, #GICC_CTLR]		@ and clear all other bits
 	mov	r1, #0xff
 	str	r1, [r3, #GICC_PMR]		@ set priority mask register
+#endif
 
 	mrc	p15, 0, r0, c1, c1, 2
 	movw	r1, #0x3fff
@@ -200,7 +202,11 @@ ENTRY(_nonsec_init)
 	mcr	p15, 0, r1, c12, c0, 1		@ set MVBAR to secure vectors
 	isb
 
+#ifdef CONFIG_ARM_GIC
 	mov	r0, r3				@ return GICC address
+#else
+	mov	r0, #0
+#endif
 	bx	lr
 ENDPROC(_nonsec_init)
 
diff --git a/arch/arm/cpu/armv7/virt-v7.c b/arch/arm/cpu/armv7/virt-v7.c
index d33e5c61a9c2..a34305853a34 100644
--- a/arch/arm/cpu/armv7/virt-v7.c
+++ b/arch/arm/cpu/armv7/virt-v7.c
@@ -82,22 +82,11 @@ void __weak smp_kick_all_cpus(void)
 	kick_secondary_cpus_gic(gic_dist_addr);
 }
 
-__weak void psci_board_init(void)
-{
-}
-
-int armv7_init_nonsec(void)
+#ifdef CONFIG_ARM_GIC
+static int psci_gic_setup(void)
 {
-	unsigned int reg;
-	unsigned itlinesnr, i;
 	unsigned long gic_dist_addr;
-
-	/* check whether the CPU supports the security extensions */
-	reg = read_id_pfr1();
-	if ((reg & 0xF0) == 0) {
-		printf("nonsec: Security extensions not implemented.\n");
-		return -1;
-	}
+	unsigned itlinesnr, i;
 
 	/* the SCR register will be set directly in the monitor mode handler,
 	 * according to the spec one should not tinker with it in secure state
@@ -123,6 +112,31 @@ int armv7_init_nonsec(void)
 	for (i = 1; i <= itlinesnr; i++)
 		writel((unsigned)-1, gic_dist_addr + GICD_IGROUPRn + 4 * i);
 
+	return 0;
+}
+#endif
+
+__weak void psci_board_init(void)
+{
+}
+
+int armv7_init_nonsec(void)
+{
+	unsigned int reg;
+
+	/* check whether the CPU supports the security extensions */
+	reg = read_id_pfr1();
+	if ((reg & 0xF0) == 0) {
+		printf("nonsec: Security extensions not implemented.\n");
+		return -1;
+	}
+
+#ifdef CONFIG_ARM_GIC
+	int ret = psci_gic_setup();
+	if (ret)
+		return ret;
+#endif
+
 	psci_board_init();
 
 	/*
-- 
2.10.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [U-Boot] [PATCH v2 7/9] sun5/7i: add an implementation of the psci suspend function
  2016-10-06 14:33 [U-Boot] [PATCH v2 0/9] sunxi: sun5/7i: add the psci suspend function Antoine Tenart
                   ` (5 preceding siblings ...)
  2016-10-06 14:33 ` [U-Boot] [PATCH v2 6/9] ARM: PSCI: protect GIC specific code with ARM_GIC Antoine Tenart
@ 2016-10-06 14:33 ` Antoine Tenart
  2016-10-06 14:34 ` [U-Boot] [PATCH v2 8/9] sun5i: add defines used by the PSCI code Antoine Tenart
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Antoine Tenart @ 2016-10-06 14:33 UTC (permalink / raw)
  To: u-boot

Add the suspend psci function for sun5i and sun7i. When running on a
sun5i, this function put the ram into self-refresh, cut off some PLLs
and switch cpuclk to losc. When on a sun7i the suspend function
currently only cut off a few PLLs and switch cpuclk to osc24m. This
should be improved later.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
 arch/arm/cpu/armv7/sunxi/Makefile             |   9 +-
 arch/arm/cpu/armv7/sunxi/psci_suspend.c       | 175 ++++++++++++++++++++++++++
 arch/arm/include/asm/arch-sunxi/clock_sun4i.h |   7 ++
 arch/arm/include/asm/arch-sunxi/dram_sun4i.h  |  11 ++
 4 files changed, 201 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/cpu/armv7/sunxi/psci_suspend.c

diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
index b35b9df4a9d6..80667268a0fc 100644
--- a/arch/arm/cpu/armv7/sunxi/Makefile
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
@@ -13,7 +13,14 @@ obj-$(CONFIG_MACH_SUN6I)	+= tzpc.o
 obj-$(CONFIG_MACH_SUN8I_H3)	+= tzpc.o
 
 ifndef CONFIG_SPL_BUILD
-obj-$(CONFIG_ARMV7_PSCI)	+= psci.o
+ifdef CONFIG_ARMV7_PSCI
+obj-$(CONFIG_MACH_SUN6I)	+= psci.o
+obj-$(CONFIG_MACH_SUN7I)	+= psci.o
+obj-$(CONFIG_MACH_SUN8I)	+= psci.o
+
+obj-$(CONFIG_MACH_SUN5I)	+= psci_suspend.o
+obj-$(CONFIG_MACH_SUN7I)	+= psci_suspend.o
+endif
 endif
 
 ifdef CONFIG_SPL_BUILD
diff --git a/arch/arm/cpu/armv7/sunxi/psci_suspend.c b/arch/arm/cpu/armv7/sunxi/psci_suspend.c
new file mode 100644
index 000000000000..6526cb51cd1c
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/psci_suspend.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2016 Antoine Tenart <antoine.tenart@free-electrons.com>
+ *
+ * Based on Allwinner code.
+ * Copyright 2007-2012 (C) Allwinner Technology Co., Ltd.
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+#include <config.h>
+#include <common.h>
+
+#include <asm/arch/clock.h>
+#include <asm/arch/dram.h>
+#include <asm/armv7.h>
+#include <asm/io.h>
+#include <asm/psci.h>
+#include <asm/secure.h>
+#include <asm/system.h>
+
+#include <linux/bitops.h>
+
+#ifndef CONFIG_MACH_SUN7I
+static void __secure sunxi_enter_selfrefresh(struct sunxi_dram_reg *dram)
+{
+	int i;
+
+	/* disable all dram host ports */
+	for (i = 0; i < 32; i++)
+		clrbits_le32(&dram->hpcr[i], DRAM_HPCR_PORT_EN);
+
+	/* disable auto-refresh */
+	setbits_le32(&dram->drr, DRAM_DRR_AUTO_REFRESH_OFF);
+
+	/* precharge all commands */
+	clrsetbits_le32(&dram->dcr, DRAM_DCR_CMD_MASK,
+			DRAM_DCR_CMD_PRECHARGE_ALL | DRAM_DCR_CMD_EXEC);
+
+	/* enter into self-refresh */
+	clrsetbits_le32(&dram->dcr, DRAM_DCR_CMD_MASK,
+			DRAM_DCR_CMD_SELF_REFRESH | DRAM_DCR_CMD_EXEC);
+
+	/* disable ITM */
+	setbits_le32(&dram->ccr, DRAM_CCR_ITM_OFF);
+
+	/* disable DRAM clock */
+	clrbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
+
+	/* disable all DLLs */
+	for (i = 0; i < 5; i++)
+		clrsetbits_le32(&dram->dllcr[i],
+				DRAM_DLLCR_DISABLE | DRAM_DLLCR_NRESET,
+				DRAM_DLLCR_DISABLE);
+}
+
+static void __secure sunxi_enable_dll(struct sunxi_dram_reg *dram, u32 pll)
+{
+	clrsetbits_le32(&dram->dllcr[pll],
+			DRAM_DLLCR_DISABLE | DRAM_DLLCR_NRESET,
+			DRAM_DLLCR_DISABLE);
+
+	clrbits_le32(&dram->dllcr[pll],
+		     DRAM_DLLCR_DISABLE | DRAM_DLLCR_NRESET);
+
+	clrsetbits_le32(&dram->dllcr[pll],
+			DRAM_DLLCR_DISABLE | DRAM_DLLCR_NRESET,
+			DRAM_DLLCR_NRESET);
+}
+
+static void __secure sunxi_leave_selfrefresh(struct sunxi_dram_reg *dram)
+{
+	int i;
+
+	/* enable DLL0 */
+	sunxi_enable_dll(dram, 0);
+
+	/* enable DRAM clock */
+	setbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
+
+	/* enable all other DLLs */
+	for (i = 1; i < 5; i++)
+		sunxi_enable_dll(dram, i);
+
+	/* enable ITM */
+	clrbits_le32(&dram->ccr, DRAM_CCR_ITM_OFF);
+
+	/* leave self-refresh */
+	clrsetbits_le32(&dram->dcr, DRAM_DCR_CMD_MASK,
+			DRAM_DCR_CMD_EXIT | DRAM_DCR_CMD_EXEC);
+
+	/* manually refresh */
+	clrsetbits_le32(&dram->dcr, DRAM_DCR_CMD_MASK,
+			DRAM_DCR_CMD_REFRESH | DRAM_DCR_CMD_EXEC);
+
+	/* enable auto-refresh */
+	clrbits_le32(&dram->drr, DRAM_DRR_AUTO_REFRESH_OFF);
+
+	/* enable all host ports */
+	for (i = 0; i < 32; i++)
+		setbits_le32(&dram->hpcr[i], DRAM_HPCR_PORT_EN);
+}
+#else
+static void __secure sunxi_enter_selfrefresh(struct sunxi_dram_reg *dram)
+{
+}
+
+static void __secure sunxi_leave_selfrefresh(struct sunxi_dram_reg *dram)
+{
+}
+#endif
+
+static void __secure sunxi_clock_enter_suspend(struct sunxi_ccm_reg *ccm)
+{
+#ifndef CONFIG_MACH_SUN7I
+	/* gate off DRAM clock */
+	clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_DDR_CLK);
+#endif
+
+	/* switch cpuclk to osc24m */
+	clrsetbits_le32(&ccm->cpu_ahb_apb0_cfg, 0x3 << CPU_CLK_SRC_SHIFT,
+			CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT);
+
+	/* disable PLLs */
+	clrbits_le32(&ccm->pll1_cfg, CCM_PLL1_CTRL_EN);
+	clrbits_le32(&ccm->pll2_cfg, CCM_PLL2_CTRL_EN);
+	clrbits_le32(&ccm->pll3_cfg, CCM_PLL3_CTRL_EN);
+	clrbits_le32(&ccm->pll4_cfg, CCM_PLL4_CTRL_EN);
+	clrbits_le32(&ccm->pll7_cfg, CCM_PLL7_CTRL_EN);
+
+#ifndef CONFIG_MACH_SUN7I
+	/* switch cpuclk to losc */
+	clrbits_le32(&ccm->cpu_ahb_apb0_cfg, 0x3 << CPU_CLK_SRC_SHIFT);
+#endif
+}
+
+static void __secure sunxi_clock_leave_suspend(struct sunxi_ccm_reg *ccm)
+{
+#ifndef CONFIG_MACH_SUN7I
+	/* switch cpuclk to osc24m */
+	clrsetbits_le32(&ccm->cpu_ahb_apb0_cfg, 0x3 << CPU_CLK_SRC_SHIFT,
+			CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT);
+#endif
+
+	/* enable PLLs */
+	setbits_le32(&ccm->pll1_cfg, CCM_PLL1_CTRL_EN);
+	setbits_le32(&ccm->pll2_cfg, CCM_PLL2_CTRL_EN);
+	setbits_le32(&ccm->pll3_cfg, CCM_PLL3_CTRL_EN);
+	setbits_le32(&ccm->pll4_cfg, CCM_PLL4_CTRL_EN);
+	setbits_le32(&ccm->pll7_cfg, CCM_PLL7_CTRL_EN);
+
+	/* switch cpuclk to pll */
+	clrsetbits_le32(&ccm->cpu_ahb_apb0_cfg, 0x3 << CPU_CLK_SRC_SHIFT,
+			CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT);
+
+#ifndef CONFIG_MACH_SUN7I
+	/* gate on DRAM clock */
+	setbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_DDR_CLK);
+#endif
+}
+
+void __secure psci_cpu_suspend(void)
+{
+	struct sunxi_dram_reg *dram =
+			(struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+	sunxi_enter_selfrefresh(dram);
+	sunxi_clock_enter_suspend(ccm);
+
+	/* idle */
+	DSB;
+	wfi();
+
+	sunxi_clock_leave_suspend(ccm);
+	sunxi_leave_selfrefresh(dram);
+}
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
index d1c5ad0a739b..0e59781dcf8d 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
@@ -208,12 +208,17 @@ struct sunxi_ccm_reg {
 #define CCM_AHB_GATE_DLL (0x1 << 15)
 #define CCM_AHB_GATE_ACE (0x1 << 16)
 
+#define CCM_PLL1_CTRL_EN		(0x1 << 31)
+#define CCM_PLL2_CTRL_EN		(0x1 << 31)
+
 #define CCM_PLL3_CTRL_M_SHIFT		0
 #define CCM_PLL3_CTRL_M_MASK		(0x7f << CCM_PLL3_CTRL_M_SHIFT)
 #define CCM_PLL3_CTRL_M(n)		(((n) & 0x7f) << 0)
 #define CCM_PLL3_CTRL_INTEGER_MODE	(0x1 << 15)
 #define CCM_PLL3_CTRL_EN		(0x1 << 31)
 
+#define CCM_PLL4_CTRL_EN		(0x1 << 31)
+
 #define CCM_PLL5_CTRL_M(n) (((n) & 0x3) << 0)
 #define CCM_PLL5_CTRL_M_MASK CCM_PLL5_CTRL_M(0x3)
 #define CCM_PLL5_CTRL_M_X(n) ((n) - 1)
@@ -251,6 +256,8 @@ struct sunxi_ccm_reg {
 #define CCM_PLL6_CTRL_K_SHIFT		4
 #define CCM_PLL6_CTRL_K_MASK		(0x3 << CCM_PLL6_CTRL_K_SHIFT)
 
+#define CCM_PLL7_CTRL_EN (0x1 << 31)
+
 #define CCM_GPS_CTRL_RESET (0x1 << 0)
 #define CCM_GPS_CTRL_GATE (0x1 << 1)
 
diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun4i.h b/arch/arm/include/asm/arch-sunxi/dram_sun4i.h
index 139e3366a633..115d6697b94a 100644
--- a/arch/arm/include/asm/arch-sunxi/dram_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/dram_sun4i.h
@@ -130,6 +130,14 @@ struct dram_para {
 #define DRAM_DCR_MODE_SEQ 0x0
 #define DRAM_DCR_MODE_INTERLEAVE 0x1
 
+#define DRAM_DCR_CMD(n) ((n) << 27)
+#define DRAM_DCR_CMD_MASK DRAM_DCR_CMD(0xf)
+#define DRAM_DCR_CMD_SELF_REFRESH DRAM_DCR_CMD(0x2)
+#define DRAM_DCR_CMD_REFRESH DRAM_DCR_CMD(0x3)
+#define DRAM_DCR_CMD_PRECHARGE_ALL DRAM_DCR_CMD(0x5)
+#define DRAM_DCR_CMD_EXIT DRAM_DCR_CMD(0x7)
+#define DRAM_DCR_CMD_EXEC (0x1 << 31)
+
 #define DRAM_CSR_DTERR  (0x1 << 20)
 #define DRAM_CSR_DTIERR (0x1 << 21)
 #define DRAM_CSR_FAILED (DRAM_CSR_DTERR | DRAM_CSR_DTIERR)
@@ -137,6 +145,7 @@ struct dram_para {
 #define DRAM_DRR_TRFC(n) ((n) & 0xff)
 #define DRAM_DRR_TREFI(n) (((n) & 0xffff) << 8)
 #define DRAM_DRR_BURST(n) ((((n) - 1) & 0xf) << 24)
+#define DRAM_DRR_AUTO_REFRESH_OFF (0x1 << 31)
 
 #define DRAM_MCR_MODE_NORM(n) (((n) & 0x3) << 0)
 #define DRAM_MCR_MODE_NORM_MASK DRAM_MCR_MOD_NORM(0x3)
@@ -176,6 +185,8 @@ struct dram_para {
 
 #define DRAM_CSEL_MAGIC 0x16237495
 
+#define DRAM_HPCR_PORT_EN 0x1
+
 unsigned long dramc_init(struct dram_para *para);
 
 #endif /* _SUNXI_DRAM_SUN4I_H */
-- 
2.10.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [U-Boot] [PATCH v2 8/9] sun5i: add defines used by the PSCI code
  2016-10-06 14:33 [U-Boot] [PATCH v2 0/9] sunxi: sun5/7i: add the psci suspend function Antoine Tenart
                   ` (6 preceding siblings ...)
  2016-10-06 14:33 ` [U-Boot] [PATCH v2 7/9] sun5/7i: add an implementation of the psci suspend function Antoine Tenart
@ 2016-10-06 14:34 ` Antoine Tenart
  2016-10-06 14:34 ` [U-Boot] [PATCH v2 9/9] sun5i: boot in non-secure mode by default Antoine Tenart
  2016-10-07  8:52 ` [U-Boot] [PATCH v2 0/9] sunxi: sun5/7i: add the psci suspend function Hans de Goede
  9 siblings, 0 replies; 13+ messages in thread
From: Antoine Tenart @ 2016-10-06 14:34 UTC (permalink / raw)
  To: u-boot

The sun5i SoCs can take advantage of the newly introduce PSCI suspend
function. Add defines used by the PSCI code.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
 include/configs/sun5i.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/configs/sun5i.h b/include/configs/sun5i.h
index d2576599036a..86eeb847ac42 100644
--- a/include/configs/sun5i.h
+++ b/include/configs/sun5i.h
@@ -19,6 +19,9 @@
 
 #define CONFIG_SUNXI_USB_PHYS	2
 
+#define CONFIG_ARMV7_SECURE_BASE	SUNXI_SRAM_A1_BASE
+#define CONFIG_TIMER_CLK_FREQ		24000000
+
 /*
  * Include common sunxi configuration where most the settings are
  */
-- 
2.10.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [U-Boot] [PATCH v2 9/9] sun5i: boot in non-secure mode by default
  2016-10-06 14:33 [U-Boot] [PATCH v2 0/9] sunxi: sun5/7i: add the psci suspend function Antoine Tenart
                   ` (7 preceding siblings ...)
  2016-10-06 14:34 ` [U-Boot] [PATCH v2 8/9] sun5i: add defines used by the PSCI code Antoine Tenart
@ 2016-10-06 14:34 ` Antoine Tenart
  2016-10-07  8:52 ` [U-Boot] [PATCH v2 0/9] sunxi: sun5/7i: add the psci suspend function Hans de Goede
  9 siblings, 0 replies; 13+ messages in thread
From: Antoine Tenart @ 2016-10-06 14:34 UTC (permalink / raw)
  To: u-boot

sun5i now implements the psci suspend function. In order to be used by
the kernel, we should now boot in non-secure mode. Enable it by default.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
 board/sunxi/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index b8a34e4fbdf8..986ca84f6cd7 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -53,8 +53,10 @@ config MACH_SUN4I
 config MACH_SUN5I
 	bool "sun5i (Allwinner A13)"
 	select CPU_V7
+	select CPU_V7_HAS_NONSEC
 	select SUNXI_GEN_SUN4I
 	select SUPPORT_SPL
+	select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
 
 config MACH_SUN6I
 	bool "sun6i (Allwinner A31)"
-- 
2.10.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [U-Boot] [PATCH v2 5/9] tegra: select ARM_GIC for Tegra TK1s
  2016-10-06 14:33 ` [U-Boot] [PATCH v2 5/9] tegra: select ARM_GIC for Tegra TK1s Antoine Tenart
@ 2016-10-06 16:15   ` Stephen Warren
  2016-10-06 16:30     ` Antoine Tenart
  0 siblings, 1 reply; 13+ messages in thread
From: Stephen Warren @ 2016-10-06 16:15 UTC (permalink / raw)
  To: u-boot

On 10/06/2016 08:33 AM, Antoine Tenart wrote:
> Select the newly introduced ARM_GIC option to the relevant configuration
> which also have a psci implementation.

> diff --git a/arch/arm/mach-tegra/tegra124/Kconfig b/arch/arm/mach-tegra/tegra124/Kconfig

>  config TARGET_JETSON_TK1
>  	bool "NVIDIA Tegra124 Jetson TK1 board"
> +	select ARM_GIC
>  	select CPU_V7_HAS_NONSEC
>  	select CPU_V7_HAS_VIRT
>  	select ARCH_SUPPORT_PSCI
>
>  config TARGET_CEI_TK1_SOM
>  	bool "Colorado Engineering Inc Tegra124 TK1-som board"
> +	select ARM_GIC
>  	select CPU_V7_HAS_NONSEC if !SPL_BUILD
>  	select CPU_V7_HAS_VIRT if !SPL_BUILD
>  	help

This isn't correct; all Tegra variants have an ARM GIC; it's not 
board-specific. Shouldn't CONFIG_TEGRA or CONFIG_TEGRA_COMMON select 
ARM_GIC?

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [U-Boot] [PATCH v2 5/9] tegra: select ARM_GIC for Tegra TK1s
  2016-10-06 16:15   ` Stephen Warren
@ 2016-10-06 16:30     ` Antoine Tenart
  0 siblings, 0 replies; 13+ messages in thread
From: Antoine Tenart @ 2016-10-06 16:30 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

On Thu, Oct 06, 2016 at 10:15:06AM -0600, Stephen Warren wrote:
> On 10/06/2016 08:33 AM, Antoine Tenart wrote:
> >Select the newly introduced ARM_GIC option to the relevant configuration
> >which also have a psci implementation.
> 
> >diff --git a/arch/arm/mach-tegra/tegra124/Kconfig b/arch/arm/mach-tegra/tegra124/Kconfig
> 
> > config TARGET_JETSON_TK1
> > 	bool "NVIDIA Tegra124 Jetson TK1 board"
> >+	select ARM_GIC
> > 	select CPU_V7_HAS_NONSEC
> > 	select CPU_V7_HAS_VIRT
> > 	select ARCH_SUPPORT_PSCI
> >
> > config TARGET_CEI_TK1_SOM
> > 	bool "Colorado Engineering Inc Tegra124 TK1-som board"
> >+	select ARM_GIC
> > 	select CPU_V7_HAS_NONSEC if !SPL_BUILD
> > 	select CPU_V7_HAS_VIRT if !SPL_BUILD
> > 	help
> 
> This isn't correct; all Tegra variants have an ARM GIC; it's not
> board-specific. Shouldn't CONFIG_TEGRA or CONFIG_TEGRA_COMMON select
> ARM_GIC?

I focused on adding ARM_GIC for targets using PSCI, but I was hopping
for comments like this one :)

I'll move the ARM_GIC selection to CONFIG_TEGRA or CONFIG_TEGRA_COMMON
then.

Thanks!

Antoine

-- 
Antoine T?nart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20161006/b5aa5a44/attachment.sig>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [U-Boot] [PATCH v2 0/9] sunxi: sun5/7i: add the psci suspend function
  2016-10-06 14:33 [U-Boot] [PATCH v2 0/9] sunxi: sun5/7i: add the psci suspend function Antoine Tenart
                   ` (8 preceding siblings ...)
  2016-10-06 14:34 ` [U-Boot] [PATCH v2 9/9] sun5i: boot in non-secure mode by default Antoine Tenart
@ 2016-10-07  8:52 ` Hans de Goede
  9 siblings, 0 replies; 13+ messages in thread
From: Hans de Goede @ 2016-10-07  8:52 UTC (permalink / raw)
  To: u-boot

Hi Antoine,

On 06-10-16 16:33, Antoine Tenart wrote:
> Hi all,
>
> This series adds an implementation of the psci suspend function for both
> sun5i and sun7i. This was tested on Nextthing's CHIP and on a A20, using
> cpuidle in Linux. My tests showed a power consumption reduced by a factor
> 2 on the CHIP when the system was idle. It went from ~1W without cpuidle
> enabled to ~0.45W.
>
> The idea of this suspend function is to put the dram into self-refresh,
> cut off some plls and to switch cpuclk to a source with a lower
> frequency. Please note the sun7i implementation lacks some parts as
> putting the ram into self-refresh and coming back from this state seems
> a bit tricky. I made some tests but did not managed yet to have a stable
> solution.
>
> As the sun5i does not have a GIC, I needed to remove some code from the
> generic psci code. To do this I added an ARM_GIC Kconfig option which
> needs to be selected by each SoC having a GIC. I already added the
> relevant lines for SoCs using the PSCI ARMv7 code. As this Kconfig
> option is currently only used in the psci code, it should be safe to add
> it even if all the SoCs having a GIC do not select it, as long as they
> don't have psci functions.
>
> Finally the series has a patch to add defines used by the psci code and
> another patch to let sun5i SoCs boot the kernel in non-secure mode so
> that it can call psci functions.

While doing my laps in the swimming pool this morning I was thinking about
this patch set and I still have some questions.

Since this hooks into cpuidle in Linux, the kernel will call this as soon
as the system is idle, right?

But what happens then if some peripherals are still doing DMA? Have you
tried this on a CHIP with a LCD (or composite video out) attached ?

I would expect things to break when the system goes idle without the
screen being blanked, since the dram is then in self-refresh and
the display engine can no longer dma data from the framebuffer to
display.

Another example would be:

1) Something does a large(ish) mmc block write
2) mmc controller start-s dma sending data to the sdcard
3) sdcard blocks because it needs to do internal housekeeping
4) cpu goes idle -> dram goes into self refresh
5) sdcard is ready mmc-controller tries to dma data to write
to card, but dram is in self-refresh.

So unless I'm mistaken putting the dram in self-refresh when we still
have peripherals running and potentially doing dma, is a bad idea.

Regards,

Hans

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2016-10-07  8:52 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-06 14:33 [U-Boot] [PATCH v2 0/9] sunxi: sun5/7i: add the psci suspend function Antoine Tenart
2016-10-06 14:33 ` [U-Boot] [PATCH v2 1/9] ARM: add the ARM_GIC configuration option Antoine Tenart
2016-10-06 14:33 ` [U-Boot] [PATCH v2 2/9] sunxi: select ARM_GIC for sun[6789]i Antoine Tenart
2016-10-06 14:33 ` [U-Boot] [PATCH v2 3/9] ARM: select ARM_GIC for SoCs having a psci implementation Antoine Tenart
2016-10-06 14:33 ` [U-Boot] [PATCH v2 4/9] exynos: select ARM_GIC for TARGET_ARNDALE Antoine Tenart
2016-10-06 14:33 ` [U-Boot] [PATCH v2 5/9] tegra: select ARM_GIC for Tegra TK1s Antoine Tenart
2016-10-06 16:15   ` Stephen Warren
2016-10-06 16:30     ` Antoine Tenart
2016-10-06 14:33 ` [U-Boot] [PATCH v2 6/9] ARM: PSCI: protect GIC specific code with ARM_GIC Antoine Tenart
2016-10-06 14:33 ` [U-Boot] [PATCH v2 7/9] sun5/7i: add an implementation of the psci suspend function Antoine Tenart
2016-10-06 14:34 ` [U-Boot] [PATCH v2 8/9] sun5i: add defines used by the PSCI code Antoine Tenart
2016-10-06 14:34 ` [U-Boot] [PATCH v2 9/9] sun5i: boot in non-secure mode by default Antoine Tenart
2016-10-07  8:52 ` [U-Boot] [PATCH v2 0/9] sunxi: sun5/7i: add the psci suspend function Hans de Goede

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.