public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH RESEND v5 0/5] ARM: rockchip: add smp functionality
@ 2013-10-22 15:24 Heiko Stübner
  2013-10-22 15:25 ` [PATCH RESEND v5 1/5] misc: sram: add ability to limit used sram areas Heiko Stübner
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Heiko Stübner @ 2013-10-22 15:24 UTC (permalink / raw)
  To: linux-arm-kernel@lists.infradead.org
  Cc: arm, Grant Likely, Rob Herring, devicetree, Russell King,
	Philipp Zabel, linux-kernel, Greg Kroah-Hartman, Ulrich Prinz,
	Matt Sealey, Fabio Estevam

This series enables the use of the additional cores on Rockchip
Cortex-A9 SoCs.

To achieve this, add the scu, the needed sram and power-management-unit.

Tested on both a BQ Curie2 (rk3066a / dual core) and
on a Radxa Rock (rk3188 / quad core).

changes since v4:
- rebase on top of the recent rk3188 board support
- implement suggestion from Matt Sealey in moving the sram-limit from
  marking reserved regions to marking available regions - hopefully
  I got the usage right :-)
- remove __CPUINIT as suggested by Fabio Estevam

changes since v3:
- address comments from Rob Herring:
  - split the gathering of the reserve-data into a separate loop
  - spelling and style fixes
- first patch only included for reference, already part of the
  char-misc git tree

changes since v2:
- rework the sram allocation following the suggestion from Philipp Zabel

changes since v1:
- add reserved block feature for mmio-sram, to not use two logical
  sram nodes
- the sram content is kept intact while the device is running, so
  copying the trampoline is only needed once

Heiko Stuebner (5):
  misc: sram: add ability to limit used sram areas
  ARM: rockchip: add snoop-control-unit
  ARM: rockchip: add sram dt nodes and documentation
  ARM: rockchip: add power-management-unit dt node
  ARM: rockchip: add smp bringup code

 .../devicetree/bindings/arm/rockchip/pmu.txt       |   16 ++
 .../devicetree/bindings/arm/rockchip/smp-sram.txt  |   24 +++
 Documentation/devicetree/bindings/misc/sram.txt    |    8 +
 arch/arm/boot/dts/rk3066a.dtsi                     |    6 +
 arch/arm/boot/dts/rk3188.dtsi                      |    6 +
 arch/arm/boot/dts/rk3xxx.dtsi                      |   10 +
 arch/arm/mach-rockchip/Kconfig                     |    1 +
 arch/arm/mach-rockchip/Makefile                    |    1 +
 arch/arm/mach-rockchip/core.h                      |   22 +++
 arch/arm/mach-rockchip/headsmp.S                   |   30 ++++
 arch/arm/mach-rockchip/platsmp.c                   |  195 ++++++++++++++++++++
 arch/arm/mach-rockchip/rockchip.c                  |    2 +
 drivers/misc/sram.c                                |   51 ++++-
 13 files changed, 368 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/rockchip/pmu.txt
 create mode 100644 Documentation/devicetree/bindings/arm/rockchip/smp-sram.txt
 create mode 100644 arch/arm/mach-rockchip/core.h
 create mode 100644 arch/arm/mach-rockchip/headsmp.S
 create mode 100644 arch/arm/mach-rockchip/platsmp.c

-- 
1.7.10.4


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

* [PATCH RESEND v5 1/5] misc: sram: add ability to limit used sram areas
  2013-10-22 15:24 [PATCH RESEND v5 0/5] ARM: rockchip: add smp functionality Heiko Stübner
@ 2013-10-22 15:25 ` Heiko Stübner
  2013-10-22 15:26 ` [PATCH RESEND v5 2/5] ARM: rockchip: add snoop-control-unit Heiko Stübner
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Heiko Stübner @ 2013-10-22 15:25 UTC (permalink / raw)
  To: linux-arm-kernel@lists.infradead.org
  Cc: arm, Grant Likely, Rob Herring, devicetree, Russell King,
	Philipp Zabel, linux-kernel, Greg Kroah-Hartman, Ulrich Prinz,
	Matt Sealey, Fabio Estevam

Some SoCs need parts of their sram for special purposes. So while being part
of the peripheral, it should not be part of the genpool controlling the sram.

Therefore add an option available to keep arbitrary portions of the
sram from being part of the pool. If available is not present, all
sram is used.

Suggested-by: Rob Herring <robherring2@gmail.com>
move from marking reserved space to available space
Suggested-by: Matt Sealey <neko@bakuhatsu.net>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Ulrich Prinz <ulrich.prinz@googlemail.com>
---
 Documentation/devicetree/bindings/misc/sram.txt |    8 ++++
 drivers/misc/sram.c                             |   51 ++++++++++++++++++++---
 2 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/misc/sram.txt b/Documentation/devicetree/bindings/misc/sram.txt
index 4d0a00e..8be552f 100644
--- a/Documentation/devicetree/bindings/misc/sram.txt
+++ b/Documentation/devicetree/bindings/misc/sram.txt
@@ -8,9 +8,17 @@ Required properties:
 
 - reg : SRAM iomem address range
 
+Optional properties:
+
+- available: optional list of available chunks inside the sram that the
+  OS can use. Without available, the whole range is usable for the OS.
+  Format is <base size>, <base size>, ...; with base being relative to the
+  reg property base.
+
 Example:
 
 sram: sram@5c000000 {
 	compatible = "mmio-sram";
 	reg = <0x5c000000 0x40000>; /* 256 KiB SRAM at address 0x5c000000 */
+	available = <0x100 0x3ff00>;
 };
diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c
index afe66571..755e640 100644
--- a/drivers/misc/sram.c
+++ b/drivers/misc/sram.c
@@ -42,6 +42,8 @@ static int sram_probe(struct platform_device *pdev)
 	struct sram_dev *sram;
 	struct resource *res;
 	unsigned long size;
+	const __be32 *avail_list = NULL;
+	int avail_size = 0;
 	int ret;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -65,12 +67,49 @@ static int sram_probe(struct platform_device *pdev)
 	if (!sram->pool)
 		return -ENOMEM;
 
-	ret = gen_pool_add_virt(sram->pool, (unsigned long)virt_base,
-				res->start, size, -1);
-	if (ret < 0) {
-		if (sram->clk)
-			clk_disable_unprepare(sram->clk);
-		return ret;
+	if (pdev->dev.of_node) {
+		avail_list = of_get_property(pdev->dev.of_node,
+						"available",
+						&avail_size);
+		if (avail_list) {
+			avail_size /= sizeof(*avail_list);
+			if (!avail_size || avail_size % 2) {
+				dev_warn(&pdev->dev, "wrong number of arguments in available property\n");
+				avail_list = NULL;
+			}
+		}
+	}
+
+	if (!avail_list) {
+		ret = gen_pool_add_virt(sram->pool, (unsigned long)virt_base,
+					res->start, size, -1);
+		if (ret < 0) {
+			if (sram->clk)
+				clk_disable_unprepare(sram->clk);
+			return ret;
+		}
+	} else {
+		unsigned int astart;
+		unsigned int asize;
+		int i;
+
+		for (i = 0; i < avail_size; i += 2) {
+			/* get the next available block */
+			astart = be32_to_cpu(*avail_list++);
+			asize = be32_to_cpu(*avail_list++);
+
+			dev_dbg(&pdev->dev, "found available block 0x%x-0x%x\n",
+				 astart, astart + asize);
+
+			ret = gen_pool_add_virt(sram->pool,
+					(unsigned long)virt_base + astart,
+					res->start + astart, asize, -1);
+			if (ret < 0) {
+				if (sram->clk)
+					clk_disable_unprepare(sram->clk);
+				return ret;
+			}
+		}
 	}
 
 	platform_set_drvdata(pdev, sram);
-- 
1.7.10.4


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

* [PATCH RESEND v5 2/5] ARM: rockchip: add snoop-control-unit
  2013-10-22 15:24 [PATCH RESEND v5 0/5] ARM: rockchip: add smp functionality Heiko Stübner
  2013-10-22 15:25 ` [PATCH RESEND v5 1/5] misc: sram: add ability to limit used sram areas Heiko Stübner
@ 2013-10-22 15:26 ` Heiko Stübner
  2013-10-22 15:27 ` [PATCH RESEND v5 3/5] ARM: rockchip: add sram dt nodes and documentation Heiko Stübner
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Heiko Stübner @ 2013-10-22 15:26 UTC (permalink / raw)
  To: linux-arm-kernel@lists.infradead.org
  Cc: arm, Grant Likely, Rob Herring, devicetree, Russell King,
	Philipp Zabel, linux-kernel, Greg Kroah-Hartman, Ulrich Prinz,
	Matt Sealey, Fabio Estevam

This adds the device-node and config select to enable the
scu in all Rockchip Cortex-A9 SoCs.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Ulrich Prinz <ulrich.prinz@googlemail.com>
---
 arch/arm/boot/dts/rk3xxx.dtsi  |    5 +++++
 arch/arm/mach-rockchip/Kconfig |    1 +
 2 files changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
index 0fcbcfd..0a3d5b1 100644
--- a/arch/arm/boot/dts/rk3xxx.dtsi
+++ b/arch/arm/boot/dts/rk3xxx.dtsi
@@ -26,6 +26,11 @@
 		compatible = "simple-bus";
 		ranges;
 
+		scu@1013c000 {
+			compatible = "arm,cortex-a9-scu";
+			reg = <0x1013c000 0x100>;
+		};
+
 		gic: interrupt-controller@1013d000 {
 			compatible = "arm,cortex-a9-gic";
 			interrupt-controller;
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 6fef464..8700395 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -5,6 +5,7 @@ config ARCH_ROCKCHIP
 	select ARCH_REQUIRE_GPIOLIB
 	select ARM_GIC
 	select CACHE_L2X0
+	select HAVE_ARM_SCU
 	select HAVE_ARM_TWD if LOCAL_TIMERS
 	select HAVE_SMP
 	select LOCAL_TIMERS if SMP
-- 
1.7.10.4


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

* [PATCH RESEND v5 3/5] ARM: rockchip: add sram dt nodes and documentation
  2013-10-22 15:24 [PATCH RESEND v5 0/5] ARM: rockchip: add smp functionality Heiko Stübner
  2013-10-22 15:25 ` [PATCH RESEND v5 1/5] misc: sram: add ability to limit used sram areas Heiko Stübner
  2013-10-22 15:26 ` [PATCH RESEND v5 2/5] ARM: rockchip: add snoop-control-unit Heiko Stübner
@ 2013-10-22 15:27 ` Heiko Stübner
  2013-10-22 15:27 ` [PATCH RESEND v5 4/5] ARM: rockchip: add power-management-unit dt node Heiko Stübner
  2013-10-22 15:28 ` [PATCH RESEND v5 5/5] ARM: rockchip: add smp bringup code Heiko Stübner
  4 siblings, 0 replies; 6+ messages in thread
From: Heiko Stübner @ 2013-10-22 15:27 UTC (permalink / raw)
  To: linux-arm-kernel@lists.infradead.org
  Cc: arm, Grant Likely, Rob Herring, devicetree, Russell King,
	Philipp Zabel, linux-kernel, Greg Kroah-Hartman, Ulrich Prinz,
	Matt Sealey, Fabio Estevam

The Rockchip SoCs need a special part of their sram for bringup
of additional cores. Therefore also limit the public area when adding the
mmio-sram node to keep the sram driver from using this space.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Ulrich Prinz <ulrich.prinz@googlemail.com>
---
 .../devicetree/bindings/arm/rockchip/smp-sram.txt  |   24 ++++++++++++++++++++
 arch/arm/boot/dts/rk3066a.dtsi                     |    6 +++++
 arch/arm/boot/dts/rk3188.dtsi                      |    6 +++++
 3 files changed, 36 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/rockchip/smp-sram.txt

diff --git a/Documentation/devicetree/bindings/arm/rockchip/smp-sram.txt b/Documentation/devicetree/bindings/arm/rockchip/smp-sram.txt
new file mode 100644
index 0000000..0c88d06
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/rockchip/smp-sram.txt
@@ -0,0 +1,24 @@
+Rockchip SRAM for smp bringup:
+------------------------------
+
+Rockchip's smp-capable SoCs use the first part of the sram for the bringup
+of the cores. Once the core gets powered up it executes the code that is
+residing at the very beginning of the sram.
+
+Therefore the available space has to be limited to exclude this area using
+the available property of the sram node.
+
+Required node properties:
+- compatible : should contain both "rockchip,rk3066-sram", "mmio-sram"
+  so that the smp code can select the correct sram node.
+
+The rest of the properties should follow the generic mmio-sram discription
+found in ../../misc/sram.txt
+
+Example:
+
+	sram: sram@10080000 {
+		compatible = "rockchip,rk3066-sram", "mmio-sram";
+		reg = <0x10080000 0x10000>;
+		available = <0x50 0xffb0>;
+	};
diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi
index 2218c64..e91048b 100644
--- a/arch/arm/boot/dts/rk3066a.dtsi
+++ b/arch/arm/boot/dts/rk3066a.dtsi
@@ -64,6 +64,12 @@
 			clock-names = "timer", "pclk";
 		};
 
+		sram: sram@10080000 {
+			compatible = "rockchip,rk3066-sram", "mmio-sram";
+			reg = <0x10080000 0x10000>;
+			available = <0x50 0xffb0>;
+		};
+
 		pinctrl@20008000 {
 			compatible = "rockchip,rk3066a-pinctrl";
 			reg = <0x20008000 0x150>;
diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
index 1a26b03..a9885df 100644
--- a/arch/arm/boot/dts/rk3188.dtsi
+++ b/arch/arm/boot/dts/rk3188.dtsi
@@ -60,6 +60,12 @@
 			interrupts = <GIC_PPI 13 0xf04>;
 		};
 
+		sram: sram@10080000 {
+			compatible = "rockchip,rk3066-sram", "mmio-sram";
+			reg = <0x10080000 0x8000>;
+			available = <0x50 0x7fb0>;
+		};
+
 		pinctrl@20008000 {
 			compatible = "rockchip,rk3188-pinctrl";
 			reg = <0x20008000 0xa0>,
-- 
1.7.10.4


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

* [PATCH RESEND v5 4/5] ARM: rockchip: add power-management-unit dt node
  2013-10-22 15:24 [PATCH RESEND v5 0/5] ARM: rockchip: add smp functionality Heiko Stübner
                   ` (2 preceding siblings ...)
  2013-10-22 15:27 ` [PATCH RESEND v5 3/5] ARM: rockchip: add sram dt nodes and documentation Heiko Stübner
@ 2013-10-22 15:27 ` Heiko Stübner
  2013-10-22 15:28 ` [PATCH RESEND v5 5/5] ARM: rockchip: add smp bringup code Heiko Stübner
  4 siblings, 0 replies; 6+ messages in thread
From: Heiko Stübner @ 2013-10-22 15:27 UTC (permalink / raw)
  To: linux-arm-kernel@lists.infradead.org
  Cc: arm, Grant Likely, Rob Herring, devicetree, Russell King,
	Philipp Zabel, linux-kernel, Greg Kroah-Hartman, Ulrich Prinz,
	Matt Sealey, Fabio Estevam

The pmu is needed to bring up the cores during smp operations.
Therefore add a node and documentation for it.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Ulrich Prinz <ulrich.prinz@googlemail.com>
---
 Documentation/devicetree/bindings/arm/rockchip/pmu.txt |   16 ++++++++++++++++
 arch/arm/boot/dts/rk3xxx.dtsi                          |    5 +++++
 2 files changed, 21 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/rockchip/pmu.txt

diff --git a/Documentation/devicetree/bindings/arm/rockchip/pmu.txt b/Documentation/devicetree/bindings/arm/rockchip/pmu.txt
new file mode 100644
index 0000000..3ee9b42
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/rockchip/pmu.txt
@@ -0,0 +1,16 @@
+Rockchip power-management-unit:
+-------------------------------
+
+The pmu is used to turn off and on different power domains of the SoCs
+This includes the power to the CPU cores.
+
+Required node properties:
+- compatible value : = "rockchip,rk3066-pmu";
+- reg : physical base address and the size of the registers window
+
+Example:
+
+	pmu@20004000 {
+		compatible = "rockchip,rk3066-pmu";
+		reg = <0x20004000 0x100>;
+	};
diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
index 0a3d5b1..26e5a96 100644
--- a/arch/arm/boot/dts/rk3xxx.dtsi
+++ b/arch/arm/boot/dts/rk3xxx.dtsi
@@ -31,6 +31,11 @@
 			reg = <0x1013c000 0x100>;
 		};
 
+		pmu@20004000 {
+			compatible = "rockchip,rk3066-pmu";
+			reg = <0x20004000 0x100>;
+		};
+
 		gic: interrupt-controller@1013d000 {
 			compatible = "arm,cortex-a9-gic";
 			interrupt-controller;
-- 
1.7.10.4


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

* [PATCH RESEND v5 5/5] ARM: rockchip: add smp bringup code
  2013-10-22 15:24 [PATCH RESEND v5 0/5] ARM: rockchip: add smp functionality Heiko Stübner
                   ` (3 preceding siblings ...)
  2013-10-22 15:27 ` [PATCH RESEND v5 4/5] ARM: rockchip: add power-management-unit dt node Heiko Stübner
@ 2013-10-22 15:28 ` Heiko Stübner
  4 siblings, 0 replies; 6+ messages in thread
From: Heiko Stübner @ 2013-10-22 15:28 UTC (permalink / raw)
  To: linux-arm-kernel@lists.infradead.org
  Cc: arm, Grant Likely, Rob Herring, devicetree, Russell King,
	Philipp Zabel, linux-kernel, Greg Kroah-Hartman, Ulrich Prinz,
	Matt Sealey, Fabio Estevam

This adds the necessary smp-operations and startup code to use
additional cores on Rockchip SoCs.

We currently hog the power management unit in the smp code, as it is
necessary to control the power to the cpu core and nothing else is
currently using it, so a generic implementation can be done later.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Ulrich Prinz <ulrich.prinz@googlemail.com>
---
 arch/arm/mach-rockchip/Makefile   |    1 +
 arch/arm/mach-rockchip/core.h     |   22 +++++
 arch/arm/mach-rockchip/headsmp.S  |   30 ++++++
 arch/arm/mach-rockchip/platsmp.c  |  195 +++++++++++++++++++++++++++++++++++++
 arch/arm/mach-rockchip/rockchip.c |    2 +
 5 files changed, 252 insertions(+)
 create mode 100644 arch/arm/mach-rockchip/core.h
 create mode 100644 arch/arm/mach-rockchip/headsmp.S
 create mode 100644 arch/arm/mach-rockchip/platsmp.c

diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 1547d4f..4377a14 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip.o
+obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/mach-rockchip/core.h b/arch/arm/mach-rockchip/core.h
new file mode 100644
index 0000000..e2e7c9d
--- /dev/null
+++ b/arch/arm/mach-rockchip/core.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+extern char rockchip_secondary_trampoline;
+extern char rockchip_secondary_trampoline_end;
+
+extern unsigned long rockchip_boot_fn;
+extern void rockchip_secondary_startup(void);
+
+extern struct smp_operations rockchip_smp_ops;
diff --git a/arch/arm/mach-rockchip/headsmp.S b/arch/arm/mach-rockchip/headsmp.S
new file mode 100644
index 0000000..3dd72f7
--- /dev/null
+++ b/arch/arm/mach-rockchip/headsmp.S
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+ENTRY(rockchip_secondary_startup)
+	bl	v7_invalidate_l1
+	b	secondary_startup
+ENDPROC(rockchip_secondary_startup)
+
+ENTRY(rockchip_secondary_trampoline)
+	ldr	pc, 1f
+ENDPROC(rockchip_secondary_trampoline)
+	.globl	rockchip_boot_fn
+rockchip_boot_fn:
+1:	.space	4
+
+ENTRY(rockchip_secondary_trampoline_end)
diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c
new file mode 100644
index 0000000..5b3f69c
--- /dev/null
+++ b/arch/arm/mach-rockchip/platsmp.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_scu.h>
+#include <asm/smp_plat.h>
+#include <asm/mach/map.h>
+
+#include "core.h"
+
+static void __iomem *scu_base_addr;
+static void __iomem *sram_base_addr;
+static int ncores;
+
+/*
+ * temporary PMU handling
+ */
+
+#define PMU_PWRDN_CON		0x08
+#define PMU_PWRDN_ST		0x0c
+
+static void __iomem *pmu_base_addr;
+
+static inline bool pmu_power_domain_is_on(int pd)
+{
+	return !(readl_relaxed(pmu_base_addr + PMU_PWRDN_ST) & BIT(pd));
+}
+
+static void pmu_set_power_domain(int pd, bool on)
+{
+	u32 val = readl_relaxed(pmu_base_addr + PMU_PWRDN_CON);
+	if (on)
+		val &= ~BIT(pd);
+	else
+		val |=  BIT(pd);
+	writel(val, pmu_base_addr + PMU_PWRDN_CON);
+
+	while (pmu_power_domain_is_on(pd) != on) { }
+}
+
+/*
+ * Handling of CPU cores
+ */
+
+static int __cpuinit rockchip_boot_secondary(unsigned int cpu,
+					     struct task_struct *idle)
+{
+	if (!sram_base_addr || !pmu_base_addr) {
+		pr_err("%s: sram or pmu missing for cpu boot\n", __func__);
+		return -ENXIO;
+	}
+
+	if (cpu >= ncores) {
+		pr_err("%s: cpu %d outside maximum number of cpus %d\n",
+							__func__, cpu, ncores);
+		return -ENXIO;
+	}
+
+	/* start the core */
+	pmu_set_power_domain(0 + cpu, true);
+
+	return 0;
+}
+
+/**
+ * rockchip_smp_prepare_sram - populate necessary sram block
+ * Starting cores execute the code residing at the start of the on-chip sram
+ * after power-on. Therefore make sure, this sram region is reserved and
+ * big enough. After this check, copy the trampoline code that directs the
+ * core to the real startup code in ram into the sram-region.
+ * @node: mmio-sram device node
+ */
+static int __init rockchip_smp_prepare_sram(struct device_node *node)
+{
+	unsigned int trampoline_sz = &rockchip_secondary_trampoline_end -
+					    &rockchip_secondary_trampoline;
+	const __be32 *avail_list = NULL;
+	int avail_size;
+	int astart = -1;
+	unsigned int asize;
+	unsigned int i;
+
+	avail_list = of_get_property(node, "available",
+					&avail_size);
+	if (!avail_list) {
+		pr_err("%s: available property for sram missing\n",
+		       __func__);
+		return -ENOENT;
+	}
+
+	avail_size /= sizeof(*avail_list);
+	if (!avail_size || avail_size % 2) {
+		pr_err("%s: wrong number of arguments for available chunks\n",
+		       __func__);
+		return -EINVAL;
+	}
+
+	/* Check that the area for the trampoline is not generally available */
+	for (i = 0; i < avail_size; i += 2) {
+		/* get the next reserved block */
+		astart = be32_to_cpu(*avail_list++);
+		asize = be32_to_cpu(*avail_list++);
+
+		if (astart + asize < trampoline_sz) {
+			pr_err("%s: trampoline area in sram is not reserved\n",
+			       __func__);
+			return -EINVAL;
+		}
+	}
+
+	sram_base_addr = of_iomap(node, 0);
+
+	/* set the boot function for the sram code */
+	rockchip_boot_fn = virt_to_phys(rockchip_secondary_startup);
+
+	/* copy the trampoline to sram, that runs during startup of the core */
+	memcpy(sram_base_addr, &rockchip_secondary_trampoline, trampoline_sz);
+	flush_cache_all();
+	outer_clean_range(0, trampoline_sz);
+
+	dsb_sev();
+
+	return 0;
+}
+
+static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus)
+{
+	struct device_node *node;
+	unsigned int i;
+
+	node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+	if (!node) {
+		pr_err("%s: missing scu\n", __func__);
+		return;
+	}
+
+	scu_base_addr = of_iomap(node, 0);
+	if (!scu_base_addr) {
+		pr_err("%s: could not map scu registers\n", __func__);
+		return;
+	}
+
+	node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-sram");
+	if (!node) {
+		pr_err("%s: could not find sram dt node\n", __func__);
+		return;
+	}
+
+	if (rockchip_smp_prepare_sram(node))
+		return;
+
+	node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-pmu");
+	if (!node) {
+		pr_err("%s: could not find sram dt node\n", __func__);
+		return;
+	}
+
+	pmu_base_addr = of_iomap(node, 0);
+
+	/*
+	 * While the number of cpus is gathered from dt, also get the number
+	 * of cores from the scu to verify this value when booting the cores.
+	 */
+	ncores = scu_get_core_count(scu_base_addr);
+
+	scu_enable(scu_base_addr);
+
+	/* Make sure that all cores except the first are really off */
+	for (i = 1; i < ncores; i++)
+		pmu_set_power_domain(0 + i, false);
+}
+
+struct smp_operations rockchip_smp_ops __initdata = {
+	.smp_prepare_cpus	= rockchip_smp_prepare_cpus,
+	.smp_boot_secondary	= rockchip_boot_secondary,
+};
diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c
index 724d2d8..a0c1f19 100644
--- a/arch/arm/mach-rockchip/rockchip.c
+++ b/arch/arm/mach-rockchip/rockchip.c
@@ -24,6 +24,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/hardware/cache-l2x0.h>
+#include "core.h"
 
 static void __init rockchip_timer_init(void)
 {
@@ -46,6 +47,7 @@ static const char * const rockchip_board_dt_compat[] = {
 };
 
 DT_MACHINE_START(ROCKCHIP_DT, "Rockchip Cortex-A9 (Device Tree)")
+	.smp		= smp_ops(rockchip_smp_ops),
 	.init_machine	= rockchip_dt_init,
 	.init_time	= rockchip_timer_init,
 	.dt_compat	= rockchip_board_dt_compat,
-- 
1.7.10.4


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

end of thread, other threads:[~2013-10-22 15:28 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-22 15:24 [PATCH RESEND v5 0/5] ARM: rockchip: add smp functionality Heiko Stübner
2013-10-22 15:25 ` [PATCH RESEND v5 1/5] misc: sram: add ability to limit used sram areas Heiko Stübner
2013-10-22 15:26 ` [PATCH RESEND v5 2/5] ARM: rockchip: add snoop-control-unit Heiko Stübner
2013-10-22 15:27 ` [PATCH RESEND v5 3/5] ARM: rockchip: add sram dt nodes and documentation Heiko Stübner
2013-10-22 15:27 ` [PATCH RESEND v5 4/5] ARM: rockchip: add power-management-unit dt node Heiko Stübner
2013-10-22 15:28 ` [PATCH RESEND v5 5/5] ARM: rockchip: add smp bringup code Heiko Stübner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox