All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/6] This series adds SMP support for the MediaTek MT6580.
@ 2015-07-10  6:04   ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Russell King, Arnd Bergmann, Catalin Marinas,
	Heiko Stuebner, Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek
  Cc: loda.chou, jades.shih, scott.shu, wsd_upstream

This patchset adds support SMP on MediaTek MT6580 Cortex-A7 quad-core SoC.

This is based on v4.1-rc1 and following patch series:
(1) Yingjoe Chen's "Add SMP bringup support for mt65xx socs" [1]
(2) Mars Cheng's "Add mt6580 basic chip support" [2]
(3) Sascha Hauer's "Mediatek SCPSYS power domain support" [3]

The secondary cores are power off as default on MT6580, this change adds
a new enable-method to turn on power to the cores during booting process.

The System Power Manager (SPM) inside the SCPSYS is for the CPU MTCMOS
power domain control. Please check [3] for more information about SCPSYS.

[1] https://lkml.org/lkml/2015/5/16/33
[2] https://lkml.org/lkml/2015/7/7/122
[3] https://lkml.org/lkml/2015/6/9/172

Change in v2:
1. Rebase to 4.2-rc1
2. Fix using usleep() in atomic context
3. Put a timeout in cpu power on/off sequence
4. Fix some coding style

Scott Shu (6):
  Document: bindings: DT: Add SMP enable method for MT6580     SoC
    platform
  soc: Mediatek: Add SCPSYS CPU power domain driver
  ARM: mediatek: add smp bringup code for MT6580
  ARM: Mediatek: enable GPT6 on boot up to make arch timer     working
    for MT6580
  ARM: dts: mt6580: Add device nodes to the MT6580 dtsi file
  ARM: dts: mt6580: enable basic SMP bringup for MT6580

 Documentation/devicetree/bindings/arm/cpus.txt |   1 +
 arch/arm/boot/dts/mt6580.dtsi                  |  25 +++
 arch/arm/mach-mediatek/Makefile                |   2 +-
 arch/arm/mach-mediatek/generic.h               |  23 +++
 arch/arm/mach-mediatek/hotplug.c               | 267 +++++++++++++++++++++++++
 arch/arm/mach-mediatek/mediatek.c              |   4 +-
 arch/arm/mach-mediatek/platsmp.c               | 139 ++++++++++++-
 7 files changed, 458 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/mach-mediatek/generic.h
 create mode 100644 arch/arm/mach-mediatek/hotplug.c


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

* [PATCH v2 0/6] This series adds SMP support for the MediaTek MT6580.
@ 2015-07-10  6:04   ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Russell King, Arnd Bergmann, Catalin Marinas,
	Heiko Stuebner, Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: loda.chou-NuS5LvNUpcJWk0Htik3J/w,
	jades.shih-NuS5LvNUpcJWk0Htik3J/w,
	scott.shu-Re5JQEeQqe8AvxtiuMwx3w,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w

This patchset adds support SMP on MediaTek MT6580 Cortex-A7 quad-core SoC.

This is based on v4.1-rc1 and following patch series:
(1) Yingjoe Chen's "Add SMP bringup support for mt65xx socs" [1]
(2) Mars Cheng's "Add mt6580 basic chip support" [2]
(3) Sascha Hauer's "Mediatek SCPSYS power domain support" [3]

The secondary cores are power off as default on MT6580, this change adds
a new enable-method to turn on power to the cores during booting process.

The System Power Manager (SPM) inside the SCPSYS is for the CPU MTCMOS
power domain control. Please check [3] for more information about SCPSYS.

[1] https://lkml.org/lkml/2015/5/16/33
[2] https://lkml.org/lkml/2015/7/7/122
[3] https://lkml.org/lkml/2015/6/9/172

Change in v2:
1. Rebase to 4.2-rc1
2. Fix using usleep() in atomic context
3. Put a timeout in cpu power on/off sequence
4. Fix some coding style

Scott Shu (6):
  Document: bindings: DT: Add SMP enable method for MT6580     SoC
    platform
  soc: Mediatek: Add SCPSYS CPU power domain driver
  ARM: mediatek: add smp bringup code for MT6580
  ARM: Mediatek: enable GPT6 on boot up to make arch timer     working
    for MT6580
  ARM: dts: mt6580: Add device nodes to the MT6580 dtsi file
  ARM: dts: mt6580: enable basic SMP bringup for MT6580

 Documentation/devicetree/bindings/arm/cpus.txt |   1 +
 arch/arm/boot/dts/mt6580.dtsi                  |  25 +++
 arch/arm/mach-mediatek/Makefile                |   2 +-
 arch/arm/mach-mediatek/generic.h               |  23 +++
 arch/arm/mach-mediatek/hotplug.c               | 267 +++++++++++++++++++++++++
 arch/arm/mach-mediatek/mediatek.c              |   4 +-
 arch/arm/mach-mediatek/platsmp.c               | 139 ++++++++++++-
 7 files changed, 458 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/mach-mediatek/generic.h
 create mode 100644 arch/arm/mach-mediatek/hotplug.c

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

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

* [PATCH v2 0/6] This series adds SMP support for the MediaTek MT6580.
@ 2015-07-10  6:04   ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset adds support SMP on MediaTek MT6580 Cortex-A7 quad-core SoC.

This is based on v4.1-rc1 and following patch series:
(1) Yingjoe Chen's "Add SMP bringup support for mt65xx socs" [1]
(2) Mars Cheng's "Add mt6580 basic chip support" [2]
(3) Sascha Hauer's "Mediatek SCPSYS power domain support" [3]

The secondary cores are power off as default on MT6580, this change adds
a new enable-method to turn on power to the cores during booting process.

The System Power Manager (SPM) inside the SCPSYS is for the CPU MTCMOS
power domain control. Please check [3] for more information about SCPSYS.

[1] https://lkml.org/lkml/2015/5/16/33
[2] https://lkml.org/lkml/2015/7/7/122
[3] https://lkml.org/lkml/2015/6/9/172

Change in v2:
1. Rebase to 4.2-rc1
2. Fix using usleep() in atomic context
3. Put a timeout in cpu power on/off sequence
4. Fix some coding style

Scott Shu (6):
  Document: bindings: DT: Add SMP enable method for MT6580     SoC
    platform
  soc: Mediatek: Add SCPSYS CPU power domain driver
  ARM: mediatek: add smp bringup code for MT6580
  ARM: Mediatek: enable GPT6 on boot up to make arch timer     working
    for MT6580
  ARM: dts: mt6580: Add device nodes to the MT6580 dtsi file
  ARM: dts: mt6580: enable basic SMP bringup for MT6580

 Documentation/devicetree/bindings/arm/cpus.txt |   1 +
 arch/arm/boot/dts/mt6580.dtsi                  |  25 +++
 arch/arm/mach-mediatek/Makefile                |   2 +-
 arch/arm/mach-mediatek/generic.h               |  23 +++
 arch/arm/mach-mediatek/hotplug.c               | 267 +++++++++++++++++++++++++
 arch/arm/mach-mediatek/mediatek.c              |   4 +-
 arch/arm/mach-mediatek/platsmp.c               | 139 ++++++++++++-
 7 files changed, 458 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/mach-mediatek/generic.h
 create mode 100644 arch/arm/mach-mediatek/hotplug.c

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

* [PATCH v2 1/6] Document: bindings: DT: Add SMP enable method for MT6580 SoC platform
@ 2015-07-10  6:04     ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Russell King, Arnd Bergmann, Catalin Marinas,
	Heiko Stuebner, Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek
  Cc: loda.chou, jades.shih, scott.shu, wsd_upstream, Scott Shu

For MT6580 SoC platform, the secondary cores are in powered off state
as default, so compared with MT65xx series SoC, one new enable method
is needed. This method using the SPM (System Power Manager) inside
the SCPSYS to control the CPU power.

Signed-off-by: Scott Shu <scott.shu@mediatek.com>
---
 Documentation/devicetree/bindings/arm/cpus.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index be35054..eaee089 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -195,6 +195,7 @@ nodes to be present and contain the properties described below.
 			    "marvell,armada-380-smp"
 			    "marvell,armada-390-smp"
 			    "marvell,armada-xp-smp"
+			    "mediatek,mt6580-smp"
 			    "mediatek,mt65xx-smp"
 			    "mediatek,mt81xx-tz-smp"
 			    "qcom,gcc-msm8660"
-- 
1.8.1.1.dirty


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

* [PATCH v2 1/6] Document: bindings: DT: Add SMP enable method for MT6580 SoC platform
@ 2015-07-10  6:04     ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Russell King, Arnd Bergmann, Catalin Marinas,
	Heiko Stuebner, Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Scott Shu, scott.shu-Re5JQEeQqe8AvxtiuMwx3w,
	loda.chou-NuS5LvNUpcJWk0Htik3J/w,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w,
	jades.shih-NuS5LvNUpcJWk0Htik3J/w

For MT6580 SoC platform, the secondary cores are in powered off state
as default, so compared with MT65xx series SoC, one new enable method
is needed. This method using the SPM (System Power Manager) inside
the SCPSYS to control the CPU power.

Signed-off-by: Scott Shu <scott.shu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
 Documentation/devicetree/bindings/arm/cpus.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index be35054..eaee089 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -195,6 +195,7 @@ nodes to be present and contain the properties described below.
 			    "marvell,armada-380-smp"
 			    "marvell,armada-390-smp"
 			    "marvell,armada-xp-smp"
+			    "mediatek,mt6580-smp"
 			    "mediatek,mt65xx-smp"
 			    "mediatek,mt81xx-tz-smp"
 			    "qcom,gcc-msm8660"
-- 
1.8.1.1.dirty

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

* [PATCH v2 1/6] Document: bindings: DT: Add SMP enable method for MT6580 SoC platform
@ 2015-07-10  6:04     ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: linux-arm-kernel

For MT6580 SoC platform, the secondary cores are in powered off state
as default, so compared with MT65xx series SoC, one new enable method
is needed. This method using the SPM (System Power Manager) inside
the SCPSYS to control the CPU power.

Signed-off-by: Scott Shu <scott.shu@mediatek.com>
---
 Documentation/devicetree/bindings/arm/cpus.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index be35054..eaee089 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -195,6 +195,7 @@ nodes to be present and contain the properties described below.
 			    "marvell,armada-380-smp"
 			    "marvell,armada-390-smp"
 			    "marvell,armada-xp-smp"
+			    "mediatek,mt6580-smp"
 			    "mediatek,mt65xx-smp"
 			    "mediatek,mt81xx-tz-smp"
 			    "qcom,gcc-msm8660"
-- 
1.8.1.1.dirty

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

* [PATCH v2 2/6] soc: Mediatek: Add SCPSYS CPU power domain driver
@ 2015-07-10  6:04     ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Russell King, Arnd Bergmann, Catalin Marinas,
	Heiko Stuebner, Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek
  Cc: loda.chou, jades.shih, scott.shu, wsd_upstream, Scott Shu

This adds a CPU power domain driver for the Mediatek SCPSYS unit on
MT6580.

Signed-off-by: Scott Shu <scott.shu@mediatek.com>
---
 arch/arm/mach-mediatek/Makefile  |   2 +-
 arch/arm/mach-mediatek/generic.h |  23 ++++
 arch/arm/mach-mediatek/hotplug.c | 267 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 291 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-mediatek/generic.h
 create mode 100644 arch/arm/mach-mediatek/hotplug.c

diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
index 2116460..b2e4ef5 100644
--- a/arch/arm/mach-mediatek/Makefile
+++ b/arch/arm/mach-mediatek/Makefile
@@ -1,4 +1,4 @@
 ifeq ($(CONFIG_SMP),y)
-obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
+obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o hotplug.o
 endif
 obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
diff --git a/arch/arm/mach-mediatek/generic.h b/arch/arm/mach-mediatek/generic.h
new file mode 100644
index 0000000..376f183
--- /dev/null
+++ b/arch/arm/mach-mediatek/generic.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2015 Mediatek Inc.
+ * Author: Scott Shu <scott.shu@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+#ifndef __MACH_GENERIC_H
+#define __MACH_GENERIC_H
+
+#include <linux/kernel.h>
+
+int spm_cpu_mtcmos_init(void);
+int spm_cpu_mtcmos_on(int cpu);
+int spm_cpu_mtcmos_off(int cpu, bool wfi);
+
+#endif
diff --git a/arch/arm/mach-mediatek/hotplug.c b/arch/arm/mach-mediatek/hotplug.c
new file mode 100644
index 0000000..bd97f2e
--- /dev/null
+++ b/arch/arm/mach-mediatek/hotplug.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2015 Mediatek Inc.
+ * Author: Scott Shu <scott.shu@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+
+/* SCPSYS registers */
+#define SPM_POWERON_CONFIG_SET		0x0000
+
+#define SPM_CA7_CPU0_PWR_CON		0x0200
+#define SPM_CA7_CPU1_PWR_CON		0x0218
+#define SPM_CA7_CPU2_PWR_CON		0x021c
+#define SPM_CA7_CPU3_PWR_CON		0x0220
+
+#define SPM_CA7_CPU0_L1_PDN		0x025c
+#define SPM_CA7_CPU1_L1_PDN		0x0264
+#define SPM_CA7_CPU2_L1_PDN		0x026c
+#define SPM_CA7_CPU3_L1_PDN		0x0274
+
+#define SPM_PWR_STATUS			0x060c
+#define SPM_PWR_STATUS_2ND		0x0610
+#define SPM_SLEEP_TIMER_STA		0x0720
+
+/* bit definition in SPM_CA7_CPUx_PWR_CON */
+#define SRAM_ISOINT_B		BIT(6)
+#define SRAM_CKISO		BIT(5)
+#define PWR_CLK_DIS		BIT(4)
+#define PWR_ON_2ND		BIT(3)
+#define PWR_ON			BIT(2)
+#define PWR_ISO			BIT(1)
+#define PWR_RST_B		BIT(0)
+
+/* bit definition in SPM_CA7_CPUx_L1_PDN */
+#define L1_PDN_ACK		BIT(8)
+#define L1_PDN			BIT(0)
+
+#define MT6580_MAX_CPUS		4
+
+static DEFINE_SPINLOCK(spm_cpu_lock);
+
+void __iomem *spm_cpu_base;
+
+u32 spm_cpu_pwr_con[MT6580_MAX_CPUS] = {
+	SPM_CA7_CPU0_PWR_CON,
+	SPM_CA7_CPU1_PWR_CON,
+	SPM_CA7_CPU2_PWR_CON,
+	SPM_CA7_CPU3_PWR_CON,
+};
+
+u32 spm_cpu_l1_pdn[MT6580_MAX_CPUS] = {
+	SPM_CA7_CPU0_L1_PDN,
+	SPM_CA7_CPU1_L1_PDN,
+	SPM_CA7_CPU2_L1_PDN,
+	SPM_CA7_CPU3_L1_PDN,
+};
+
+#define SPM_REGWR_EN		BIT(0)
+#define SPM_PROJECT_CODE	0x0B16
+
+int spm_cpu_mtcmos_on(int cpu)
+{
+	unsigned long flags;
+	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
+	unsigned int temp;
+	int timeout = 10;
+	int ret = -ENOSYS;
+
+	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
+	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
+
+	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
+	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
+
+	spin_lock_irqsave(&spm_cpu_lock, flags);
+
+	/* Set PWR_ON */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_ON;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Wait for charging core power */
+	udelay(1);
+
+	/* Set PWR_ON_2ND */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_ON_2ND;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Wait for the power-ack */
+	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
+		(1U << (13 - cpu))) != (1U << (13 - cpu))) ||
+		((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
+		(1U << (13 - cpu))) != (1U << (13 - cpu)))) {
+		if (--timeout == 0)
+			goto fail;
+		udelay(1);
+	}
+
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_ISO;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* L1 power on */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
+	temp &= ~L1_PDN;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
+	timeout = 10;
+	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
+		L1_PDN_ACK) != 0) {
+		if (--timeout == 0)
+			goto fail;
+		udelay(1);
+	}
+
+	/* Wait for memory power ready */
+	udelay(1);
+
+	/* Set SRAM_ISOINT_B */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= SRAM_ISOINT_B;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear SRAM_CKISO */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~SRAM_CKISO;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear PWR_CLK_DIS */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_CLK_DIS;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Set PWR_RST_B to finish power on and reset sequences */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_RST_B;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	ret = 0;
+fail:
+	spin_unlock_irqrestore(&spm_cpu_lock, flags);
+
+	return ret;
+}
+
+int spm_cpu_mtcmos_off(int cpu, bool wfi)
+{
+	unsigned long flags;
+	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
+	unsigned int temp;
+	int timeout = 10;
+	int ret = -ENOSYS;
+
+	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
+	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
+
+	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
+	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
+
+	if (wfi) {
+		while ((readl_relaxed(spm_cpu_base + SPM_SLEEP_TIMER_STA) &
+			(1U << (16 + cpu))) == 0) {
+			if (--timeout == 0)
+				return ret;
+			udelay(1);
+		}
+	}
+
+	spin_lock_irqsave(&spm_cpu_lock, flags);
+
+	/* Set PWR_ISO */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_ISO;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Set SRAM_CKISO */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= SRAM_CKISO;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear SRAM_ISOINT_B */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~SRAM_ISOINT_B;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* L1 power off */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
+	temp |= L1_PDN;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
+	timeout = 10;
+	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
+		L1_PDN_ACK) != L1_PDN_ACK) {
+		if (--timeout == 0)
+			goto fail;
+		udelay(1);
+	}
+
+	/* Clear PWR_RST_B */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_RST_B;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Set PWR_CLK_DIS */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_CLK_DIS;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear PWR_ON */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_ON;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear PWR_ON_2ND */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_ON_2ND;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	timeout = 10;
+	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
+		(1U << (13 - cpu))) != 0) ||
+	       ((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
+		(1U << (13 - cpu))) != 0)) {
+		if (--timeout == 0)
+			goto fail;
+		udelay(1);
+	}
+
+	ret = 0;
+fail:
+	spin_unlock_irqrestore(&spm_cpu_lock, flags);
+
+	return ret;
+}
+
+int spm_cpu_mtcmos_init(void)
+{
+	struct device_node *node;
+
+	node = of_find_compatible_node(NULL, NULL, "mediatek,mt6580-scpsys");
+	if (!node) {
+		pr_err("Missing mt6580-scpsys node in the device tree\n");
+		return -ENODEV;
+	}
+
+	spm_cpu_base = of_iomap(node, 0);
+	if (!spm_cpu_base) {
+		pr_err("%s: Unable to map I/O memory\n", __func__);
+		return -ENODEV;
+	}
+
+	return 0;
+}
-- 
1.8.1.1.dirty


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

* [PATCH v2 2/6] soc: Mediatek: Add SCPSYS CPU power domain driver
@ 2015-07-10  6:04     ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Russell King, Arnd Bergmann, Catalin Marinas,
	Heiko Stuebner, Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: loda.chou-NuS5LvNUpcJWk0Htik3J/w,
	jades.shih-NuS5LvNUpcJWk0Htik3J/w,
	scott.shu-Re5JQEeQqe8AvxtiuMwx3w,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w, Scott Shu

This adds a CPU power domain driver for the Mediatek SCPSYS unit on
MT6580.

Signed-off-by: Scott Shu <scott.shu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
 arch/arm/mach-mediatek/Makefile  |   2 +-
 arch/arm/mach-mediatek/generic.h |  23 ++++
 arch/arm/mach-mediatek/hotplug.c | 267 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 291 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-mediatek/generic.h
 create mode 100644 arch/arm/mach-mediatek/hotplug.c

diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
index 2116460..b2e4ef5 100644
--- a/arch/arm/mach-mediatek/Makefile
+++ b/arch/arm/mach-mediatek/Makefile
@@ -1,4 +1,4 @@
 ifeq ($(CONFIG_SMP),y)
-obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
+obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o hotplug.o
 endif
 obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
diff --git a/arch/arm/mach-mediatek/generic.h b/arch/arm/mach-mediatek/generic.h
new file mode 100644
index 0000000..376f183
--- /dev/null
+++ b/arch/arm/mach-mediatek/generic.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2015 Mediatek Inc.
+ * Author: Scott Shu <scott.shu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+#ifndef __MACH_GENERIC_H
+#define __MACH_GENERIC_H
+
+#include <linux/kernel.h>
+
+int spm_cpu_mtcmos_init(void);
+int spm_cpu_mtcmos_on(int cpu);
+int spm_cpu_mtcmos_off(int cpu, bool wfi);
+
+#endif
diff --git a/arch/arm/mach-mediatek/hotplug.c b/arch/arm/mach-mediatek/hotplug.c
new file mode 100644
index 0000000..bd97f2e
--- /dev/null
+++ b/arch/arm/mach-mediatek/hotplug.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2015 Mediatek Inc.
+ * Author: Scott Shu <scott.shu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+
+/* SCPSYS registers */
+#define SPM_POWERON_CONFIG_SET		0x0000
+
+#define SPM_CA7_CPU0_PWR_CON		0x0200
+#define SPM_CA7_CPU1_PWR_CON		0x0218
+#define SPM_CA7_CPU2_PWR_CON		0x021c
+#define SPM_CA7_CPU3_PWR_CON		0x0220
+
+#define SPM_CA7_CPU0_L1_PDN		0x025c
+#define SPM_CA7_CPU1_L1_PDN		0x0264
+#define SPM_CA7_CPU2_L1_PDN		0x026c
+#define SPM_CA7_CPU3_L1_PDN		0x0274
+
+#define SPM_PWR_STATUS			0x060c
+#define SPM_PWR_STATUS_2ND		0x0610
+#define SPM_SLEEP_TIMER_STA		0x0720
+
+/* bit definition in SPM_CA7_CPUx_PWR_CON */
+#define SRAM_ISOINT_B		BIT(6)
+#define SRAM_CKISO		BIT(5)
+#define PWR_CLK_DIS		BIT(4)
+#define PWR_ON_2ND		BIT(3)
+#define PWR_ON			BIT(2)
+#define PWR_ISO			BIT(1)
+#define PWR_RST_B		BIT(0)
+
+/* bit definition in SPM_CA7_CPUx_L1_PDN */
+#define L1_PDN_ACK		BIT(8)
+#define L1_PDN			BIT(0)
+
+#define MT6580_MAX_CPUS		4
+
+static DEFINE_SPINLOCK(spm_cpu_lock);
+
+void __iomem *spm_cpu_base;
+
+u32 spm_cpu_pwr_con[MT6580_MAX_CPUS] = {
+	SPM_CA7_CPU0_PWR_CON,
+	SPM_CA7_CPU1_PWR_CON,
+	SPM_CA7_CPU2_PWR_CON,
+	SPM_CA7_CPU3_PWR_CON,
+};
+
+u32 spm_cpu_l1_pdn[MT6580_MAX_CPUS] = {
+	SPM_CA7_CPU0_L1_PDN,
+	SPM_CA7_CPU1_L1_PDN,
+	SPM_CA7_CPU2_L1_PDN,
+	SPM_CA7_CPU3_L1_PDN,
+};
+
+#define SPM_REGWR_EN		BIT(0)
+#define SPM_PROJECT_CODE	0x0B16
+
+int spm_cpu_mtcmos_on(int cpu)
+{
+	unsigned long flags;
+	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
+	unsigned int temp;
+	int timeout = 10;
+	int ret = -ENOSYS;
+
+	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
+	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
+
+	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
+	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
+
+	spin_lock_irqsave(&spm_cpu_lock, flags);
+
+	/* Set PWR_ON */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_ON;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Wait for charging core power */
+	udelay(1);
+
+	/* Set PWR_ON_2ND */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_ON_2ND;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Wait for the power-ack */
+	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
+		(1U << (13 - cpu))) != (1U << (13 - cpu))) ||
+		((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
+		(1U << (13 - cpu))) != (1U << (13 - cpu)))) {
+		if (--timeout == 0)
+			goto fail;
+		udelay(1);
+	}
+
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_ISO;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* L1 power on */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
+	temp &= ~L1_PDN;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
+	timeout = 10;
+	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
+		L1_PDN_ACK) != 0) {
+		if (--timeout == 0)
+			goto fail;
+		udelay(1);
+	}
+
+	/* Wait for memory power ready */
+	udelay(1);
+
+	/* Set SRAM_ISOINT_B */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= SRAM_ISOINT_B;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear SRAM_CKISO */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~SRAM_CKISO;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear PWR_CLK_DIS */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_CLK_DIS;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Set PWR_RST_B to finish power on and reset sequences */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_RST_B;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	ret = 0;
+fail:
+	spin_unlock_irqrestore(&spm_cpu_lock, flags);
+
+	return ret;
+}
+
+int spm_cpu_mtcmos_off(int cpu, bool wfi)
+{
+	unsigned long flags;
+	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
+	unsigned int temp;
+	int timeout = 10;
+	int ret = -ENOSYS;
+
+	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
+	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
+
+	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
+	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
+
+	if (wfi) {
+		while ((readl_relaxed(spm_cpu_base + SPM_SLEEP_TIMER_STA) &
+			(1U << (16 + cpu))) == 0) {
+			if (--timeout == 0)
+				return ret;
+			udelay(1);
+		}
+	}
+
+	spin_lock_irqsave(&spm_cpu_lock, flags);
+
+	/* Set PWR_ISO */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_ISO;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Set SRAM_CKISO */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= SRAM_CKISO;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear SRAM_ISOINT_B */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~SRAM_ISOINT_B;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* L1 power off */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
+	temp |= L1_PDN;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
+	timeout = 10;
+	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
+		L1_PDN_ACK) != L1_PDN_ACK) {
+		if (--timeout == 0)
+			goto fail;
+		udelay(1);
+	}
+
+	/* Clear PWR_RST_B */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_RST_B;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Set PWR_CLK_DIS */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_CLK_DIS;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear PWR_ON */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_ON;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear PWR_ON_2ND */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_ON_2ND;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	timeout = 10;
+	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
+		(1U << (13 - cpu))) != 0) ||
+	       ((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
+		(1U << (13 - cpu))) != 0)) {
+		if (--timeout == 0)
+			goto fail;
+		udelay(1);
+	}
+
+	ret = 0;
+fail:
+	spin_unlock_irqrestore(&spm_cpu_lock, flags);
+
+	return ret;
+}
+
+int spm_cpu_mtcmos_init(void)
+{
+	struct device_node *node;
+
+	node = of_find_compatible_node(NULL, NULL, "mediatek,mt6580-scpsys");
+	if (!node) {
+		pr_err("Missing mt6580-scpsys node in the device tree\n");
+		return -ENODEV;
+	}
+
+	spm_cpu_base = of_iomap(node, 0);
+	if (!spm_cpu_base) {
+		pr_err("%s: Unable to map I/O memory\n", __func__);
+		return -ENODEV;
+	}
+
+	return 0;
+}
-- 
1.8.1.1.dirty

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

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

* [PATCH v2 2/6] soc: Mediatek: Add SCPSYS CPU power domain driver
@ 2015-07-10  6:04     ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: linux-arm-kernel

This adds a CPU power domain driver for the Mediatek SCPSYS unit on
MT6580.

Signed-off-by: Scott Shu <scott.shu@mediatek.com>
---
 arch/arm/mach-mediatek/Makefile  |   2 +-
 arch/arm/mach-mediatek/generic.h |  23 ++++
 arch/arm/mach-mediatek/hotplug.c | 267 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 291 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-mediatek/generic.h
 create mode 100644 arch/arm/mach-mediatek/hotplug.c

diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
index 2116460..b2e4ef5 100644
--- a/arch/arm/mach-mediatek/Makefile
+++ b/arch/arm/mach-mediatek/Makefile
@@ -1,4 +1,4 @@
 ifeq ($(CONFIG_SMP),y)
-obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
+obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o hotplug.o
 endif
 obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
diff --git a/arch/arm/mach-mediatek/generic.h b/arch/arm/mach-mediatek/generic.h
new file mode 100644
index 0000000..376f183
--- /dev/null
+++ b/arch/arm/mach-mediatek/generic.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2015 Mediatek Inc.
+ * Author: Scott Shu <scott.shu@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+#ifndef __MACH_GENERIC_H
+#define __MACH_GENERIC_H
+
+#include <linux/kernel.h>
+
+int spm_cpu_mtcmos_init(void);
+int spm_cpu_mtcmos_on(int cpu);
+int spm_cpu_mtcmos_off(int cpu, bool wfi);
+
+#endif
diff --git a/arch/arm/mach-mediatek/hotplug.c b/arch/arm/mach-mediatek/hotplug.c
new file mode 100644
index 0000000..bd97f2e
--- /dev/null
+++ b/arch/arm/mach-mediatek/hotplug.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2015 Mediatek Inc.
+ * Author: Scott Shu <scott.shu@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+
+/* SCPSYS registers */
+#define SPM_POWERON_CONFIG_SET		0x0000
+
+#define SPM_CA7_CPU0_PWR_CON		0x0200
+#define SPM_CA7_CPU1_PWR_CON		0x0218
+#define SPM_CA7_CPU2_PWR_CON		0x021c
+#define SPM_CA7_CPU3_PWR_CON		0x0220
+
+#define SPM_CA7_CPU0_L1_PDN		0x025c
+#define SPM_CA7_CPU1_L1_PDN		0x0264
+#define SPM_CA7_CPU2_L1_PDN		0x026c
+#define SPM_CA7_CPU3_L1_PDN		0x0274
+
+#define SPM_PWR_STATUS			0x060c
+#define SPM_PWR_STATUS_2ND		0x0610
+#define SPM_SLEEP_TIMER_STA		0x0720
+
+/* bit definition in SPM_CA7_CPUx_PWR_CON */
+#define SRAM_ISOINT_B		BIT(6)
+#define SRAM_CKISO		BIT(5)
+#define PWR_CLK_DIS		BIT(4)
+#define PWR_ON_2ND		BIT(3)
+#define PWR_ON			BIT(2)
+#define PWR_ISO			BIT(1)
+#define PWR_RST_B		BIT(0)
+
+/* bit definition in SPM_CA7_CPUx_L1_PDN */
+#define L1_PDN_ACK		BIT(8)
+#define L1_PDN			BIT(0)
+
+#define MT6580_MAX_CPUS		4
+
+static DEFINE_SPINLOCK(spm_cpu_lock);
+
+void __iomem *spm_cpu_base;
+
+u32 spm_cpu_pwr_con[MT6580_MAX_CPUS] = {
+	SPM_CA7_CPU0_PWR_CON,
+	SPM_CA7_CPU1_PWR_CON,
+	SPM_CA7_CPU2_PWR_CON,
+	SPM_CA7_CPU3_PWR_CON,
+};
+
+u32 spm_cpu_l1_pdn[MT6580_MAX_CPUS] = {
+	SPM_CA7_CPU0_L1_PDN,
+	SPM_CA7_CPU1_L1_PDN,
+	SPM_CA7_CPU2_L1_PDN,
+	SPM_CA7_CPU3_L1_PDN,
+};
+
+#define SPM_REGWR_EN		BIT(0)
+#define SPM_PROJECT_CODE	0x0B16
+
+int spm_cpu_mtcmos_on(int cpu)
+{
+	unsigned long flags;
+	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
+	unsigned int temp;
+	int timeout = 10;
+	int ret = -ENOSYS;
+
+	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
+	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
+
+	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
+	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
+
+	spin_lock_irqsave(&spm_cpu_lock, flags);
+
+	/* Set PWR_ON */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_ON;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Wait for charging core power */
+	udelay(1);
+
+	/* Set PWR_ON_2ND */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_ON_2ND;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Wait for the power-ack */
+	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
+		(1U << (13 - cpu))) != (1U << (13 - cpu))) ||
+		((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
+		(1U << (13 - cpu))) != (1U << (13 - cpu)))) {
+		if (--timeout == 0)
+			goto fail;
+		udelay(1);
+	}
+
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_ISO;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* L1 power on */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
+	temp &= ~L1_PDN;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
+	timeout = 10;
+	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
+		L1_PDN_ACK) != 0) {
+		if (--timeout == 0)
+			goto fail;
+		udelay(1);
+	}
+
+	/* Wait for memory power ready */
+	udelay(1);
+
+	/* Set SRAM_ISOINT_B */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= SRAM_ISOINT_B;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear SRAM_CKISO */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~SRAM_CKISO;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear PWR_CLK_DIS */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_CLK_DIS;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Set PWR_RST_B to finish power on and reset sequences */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_RST_B;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	ret = 0;
+fail:
+	spin_unlock_irqrestore(&spm_cpu_lock, flags);
+
+	return ret;
+}
+
+int spm_cpu_mtcmos_off(int cpu, bool wfi)
+{
+	unsigned long flags;
+	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
+	unsigned int temp;
+	int timeout = 10;
+	int ret = -ENOSYS;
+
+	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
+	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
+
+	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
+	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
+
+	if (wfi) {
+		while ((readl_relaxed(spm_cpu_base + SPM_SLEEP_TIMER_STA) &
+			(1U << (16 + cpu))) == 0) {
+			if (--timeout == 0)
+				return ret;
+			udelay(1);
+		}
+	}
+
+	spin_lock_irqsave(&spm_cpu_lock, flags);
+
+	/* Set PWR_ISO */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_ISO;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Set SRAM_CKISO */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= SRAM_CKISO;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear SRAM_ISOINT_B */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~SRAM_ISOINT_B;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* L1 power off */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
+	temp |= L1_PDN;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
+	timeout = 10;
+	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
+		L1_PDN_ACK) != L1_PDN_ACK) {
+		if (--timeout == 0)
+			goto fail;
+		udelay(1);
+	}
+
+	/* Clear PWR_RST_B */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_RST_B;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Set PWR_CLK_DIS */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_CLK_DIS;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear PWR_ON */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_ON;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear PWR_ON_2ND */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_ON_2ND;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	timeout = 10;
+	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
+		(1U << (13 - cpu))) != 0) ||
+	       ((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
+		(1U << (13 - cpu))) != 0)) {
+		if (--timeout == 0)
+			goto fail;
+		udelay(1);
+	}
+
+	ret = 0;
+fail:
+	spin_unlock_irqrestore(&spm_cpu_lock, flags);
+
+	return ret;
+}
+
+int spm_cpu_mtcmos_init(void)
+{
+	struct device_node *node;
+
+	node = of_find_compatible_node(NULL, NULL, "mediatek,mt6580-scpsys");
+	if (!node) {
+		pr_err("Missing mt6580-scpsys node in the device tree\n");
+		return -ENODEV;
+	}
+
+	spm_cpu_base = of_iomap(node, 0);
+	if (!spm_cpu_base) {
+		pr_err("%s: Unable to map I/O memory\n", __func__);
+		return -ENODEV;
+	}
+
+	return 0;
+}
-- 
1.8.1.1.dirty

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

* [PATCH v2 3/6] ARM: mediatek: add smp bringup code for MT6580
@ 2015-07-10  6:04     ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Russell King, Arnd Bergmann, Catalin Marinas,
	Heiko Stuebner, Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek
  Cc: loda.chou, jades.shih, scott.shu, wsd_upstream, Scott Shu

Add support for cpu enable-method "mediatek,mt6580-smp" for booting
secondary CPUs on MT6580.

Signed-off-by: Scott Shu <scott.shu@mediatek.com>
---
 arch/arm/mach-mediatek/platsmp.c | 139 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 138 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c
index 12fefb3..7f5a5cfb 100644
--- a/arch/arm/mach-mediatek/platsmp.c
+++ b/arch/arm/mach-mediatek/platsmp.c
@@ -13,7 +13,6 @@
  * 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/io.h>
 #include <linux/memblock.h>
@@ -21,10 +20,15 @@
 #include <linux/of_address.h>
 #include <linux/string.h>
 #include <linux/threads.h>
+#include <linux/delay.h>
+#include <asm/cacheflush.h>
+#include "generic.h"
 
 #define MTK_MAX_CPU		8
 #define MTK_SMP_REG_SIZE	0x1000
 
+static DEFINE_SPINLOCK(boot_lock);
+
 struct mtk_smp_boot_info {
 	unsigned long smp_base;
 	unsigned int jump_reg;
@@ -57,6 +61,128 @@ static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
 static void __iomem *mtk_smp_base;
 static const struct mtk_smp_boot_info *mtk_smp_info;
 
+#ifdef CONFIG_HOTPLUG_CPU
+static int mt6580_cpu_kill(unsigned cpu)
+{
+	int ret;
+
+	ret = spm_cpu_mtcmos_off(cpu, 1);
+	if (ret < 0)
+		return 0;
+
+	return 1;
+}
+
+static void mt6580_cpu_die(unsigned int cpu)
+{
+	for (;;)
+		cpu_do_idle();
+}
+#endif
+
+static void write_pen_release(int val)
+{
+	pen_release = val;
+	/* Make sure this is visible to other CPUs */
+	smp_wmb();
+	sync_cache_w(&pen_release);
+}
+
+/*
+ * Refer common "pen" secondary release method
+ */
+static int mt6580_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	unsigned long timeout;
+	int ret;
+
+	/*
+	 * Set synchronisation state between this boot processor
+	 * and the secondary one
+	 */
+	spin_lock(&boot_lock);
+
+	/*
+	 * The secondary processor is waiting to be released from
+	 * the holding pen - release it, then wait for it to flag
+	 * that it has been released by resetting pen_release.
+	 *
+	 * Note that "pen_release" is the hardware CPU ID, whereas
+	 * "cpu" is Linux's internal ID.
+	 */
+	write_pen_release(cpu);
+
+	/*
+	 * CPU power on control by SPM
+	 */
+	ret = spm_cpu_mtcmos_on(cpu);
+	if (ret < 0) {
+		spin_unlock(&boot_lock);
+		return -ENOSYS;
+	}
+
+	timeout = jiffies + (1 * HZ);
+	while (time_before(jiffies, timeout)) {
+		/* Read barrier */
+		smp_rmb();
+
+		if (pen_release == -1)
+			break;
+
+		udelay(10);
+	}
+
+	/*
+	 * Now the secondary core is starting up let it run its
+	 * calibrations, then wait for it to finish
+	 */
+	spin_unlock(&boot_lock);
+
+	return (pen_release != -1 ? -ENOSYS : 0);
+}
+
+static void mt6580_secondary_init(unsigned int cpu)
+{
+	/*
+	 * Let the primary processor know we're out of the
+	 * pen, then head off into the C entry point
+	 */
+	write_pen_release(-1);
+
+	/*
+	 * Synchronise with the boot thread.
+	 */
+	spin_lock(&boot_lock);
+	spin_unlock(&boot_lock);
+}
+
+#define MT6580_INFRACFG_AO	0x10001000
+#define SW_ROM_PD		BIT(31)
+
+static void __init mt6580_smp_prepare_cpus(unsigned int max_cpus)
+{
+	static void __iomem *infracfg_ao_base;
+
+	infracfg_ao_base = ioremap(MT6580_INFRACFG_AO, 0x1000);
+
+	if (!infracfg_ao_base)
+		pr_err("%s: Unable to map I/O memory\n", __func__);
+
+	/* Enable bootrom power down mode */
+	writel_relaxed(readl(infracfg_ao_base + 0x804) | SW_ROM_PD,
+		       infracfg_ao_base + 0x804);
+
+	/* Write the address of slave startup into boot address
+	   register for bootrom power down mode */
+	writel_relaxed(virt_to_phys(secondary_startup_arm),
+		       infracfg_ao_base + 0x800);
+
+	iounmap(infracfg_ao_base);
+
+	/* Initial spm cpu mtcmos memory map */
+	spm_cpu_mtcmos_init();
+}
+
 static int mtk_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	if (!mtk_smp_base)
@@ -143,3 +269,14 @@ static struct smp_operations mt65xx_smp_ops __initdata = {
 	.smp_boot_secondary = mtk_boot_secondary,
 };
 CPU_METHOD_OF_DECLARE(mt65xx_smp, "mediatek,mt65xx-smp", &mt65xx_smp_ops);
+
+static struct smp_operations mt6580_smp_ops __initdata = {
+	.smp_prepare_cpus = mt6580_smp_prepare_cpus,
+	.smp_secondary_init = mt6580_secondary_init,
+	.smp_boot_secondary = mt6580_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+	.cpu_kill = mt6580_cpu_kill,
+	.cpu_die = mt6580_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(mt6580_smp, "mediatek,mt6580-smp", &mt6580_smp_ops);
-- 
1.8.1.1.dirty


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

* [PATCH v2 3/6] ARM: mediatek: add smp bringup code for MT6580
@ 2015-07-10  6:04     ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Russell King, Arnd Bergmann, Catalin Marinas,
	Heiko Stuebner, Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: loda.chou-NuS5LvNUpcJWk0Htik3J/w,
	jades.shih-NuS5LvNUpcJWk0Htik3J/w,
	scott.shu-Re5JQEeQqe8AvxtiuMwx3w,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w, Scott Shu

Add support for cpu enable-method "mediatek,mt6580-smp" for booting
secondary CPUs on MT6580.

Signed-off-by: Scott Shu <scott.shu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
 arch/arm/mach-mediatek/platsmp.c | 139 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 138 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c
index 12fefb3..7f5a5cfb 100644
--- a/arch/arm/mach-mediatek/platsmp.c
+++ b/arch/arm/mach-mediatek/platsmp.c
@@ -13,7 +13,6 @@
  * 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/io.h>
 #include <linux/memblock.h>
@@ -21,10 +20,15 @@
 #include <linux/of_address.h>
 #include <linux/string.h>
 #include <linux/threads.h>
+#include <linux/delay.h>
+#include <asm/cacheflush.h>
+#include "generic.h"
 
 #define MTK_MAX_CPU		8
 #define MTK_SMP_REG_SIZE	0x1000
 
+static DEFINE_SPINLOCK(boot_lock);
+
 struct mtk_smp_boot_info {
 	unsigned long smp_base;
 	unsigned int jump_reg;
@@ -57,6 +61,128 @@ static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
 static void __iomem *mtk_smp_base;
 static const struct mtk_smp_boot_info *mtk_smp_info;
 
+#ifdef CONFIG_HOTPLUG_CPU
+static int mt6580_cpu_kill(unsigned cpu)
+{
+	int ret;
+
+	ret = spm_cpu_mtcmos_off(cpu, 1);
+	if (ret < 0)
+		return 0;
+
+	return 1;
+}
+
+static void mt6580_cpu_die(unsigned int cpu)
+{
+	for (;;)
+		cpu_do_idle();
+}
+#endif
+
+static void write_pen_release(int val)
+{
+	pen_release = val;
+	/* Make sure this is visible to other CPUs */
+	smp_wmb();
+	sync_cache_w(&pen_release);
+}
+
+/*
+ * Refer common "pen" secondary release method
+ */
+static int mt6580_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	unsigned long timeout;
+	int ret;
+
+	/*
+	 * Set synchronisation state between this boot processor
+	 * and the secondary one
+	 */
+	spin_lock(&boot_lock);
+
+	/*
+	 * The secondary processor is waiting to be released from
+	 * the holding pen - release it, then wait for it to flag
+	 * that it has been released by resetting pen_release.
+	 *
+	 * Note that "pen_release" is the hardware CPU ID, whereas
+	 * "cpu" is Linux's internal ID.
+	 */
+	write_pen_release(cpu);
+
+	/*
+	 * CPU power on control by SPM
+	 */
+	ret = spm_cpu_mtcmos_on(cpu);
+	if (ret < 0) {
+		spin_unlock(&boot_lock);
+		return -ENOSYS;
+	}
+
+	timeout = jiffies + (1 * HZ);
+	while (time_before(jiffies, timeout)) {
+		/* Read barrier */
+		smp_rmb();
+
+		if (pen_release == -1)
+			break;
+
+		udelay(10);
+	}
+
+	/*
+	 * Now the secondary core is starting up let it run its
+	 * calibrations, then wait for it to finish
+	 */
+	spin_unlock(&boot_lock);
+
+	return (pen_release != -1 ? -ENOSYS : 0);
+}
+
+static void mt6580_secondary_init(unsigned int cpu)
+{
+	/*
+	 * Let the primary processor know we're out of the
+	 * pen, then head off into the C entry point
+	 */
+	write_pen_release(-1);
+
+	/*
+	 * Synchronise with the boot thread.
+	 */
+	spin_lock(&boot_lock);
+	spin_unlock(&boot_lock);
+}
+
+#define MT6580_INFRACFG_AO	0x10001000
+#define SW_ROM_PD		BIT(31)
+
+static void __init mt6580_smp_prepare_cpus(unsigned int max_cpus)
+{
+	static void __iomem *infracfg_ao_base;
+
+	infracfg_ao_base = ioremap(MT6580_INFRACFG_AO, 0x1000);
+
+	if (!infracfg_ao_base)
+		pr_err("%s: Unable to map I/O memory\n", __func__);
+
+	/* Enable bootrom power down mode */
+	writel_relaxed(readl(infracfg_ao_base + 0x804) | SW_ROM_PD,
+		       infracfg_ao_base + 0x804);
+
+	/* Write the address of slave startup into boot address
+	   register for bootrom power down mode */
+	writel_relaxed(virt_to_phys(secondary_startup_arm),
+		       infracfg_ao_base + 0x800);
+
+	iounmap(infracfg_ao_base);
+
+	/* Initial spm cpu mtcmos memory map */
+	spm_cpu_mtcmos_init();
+}
+
 static int mtk_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	if (!mtk_smp_base)
@@ -143,3 +269,14 @@ static struct smp_operations mt65xx_smp_ops __initdata = {
 	.smp_boot_secondary = mtk_boot_secondary,
 };
 CPU_METHOD_OF_DECLARE(mt65xx_smp, "mediatek,mt65xx-smp", &mt65xx_smp_ops);
+
+static struct smp_operations mt6580_smp_ops __initdata = {
+	.smp_prepare_cpus = mt6580_smp_prepare_cpus,
+	.smp_secondary_init = mt6580_secondary_init,
+	.smp_boot_secondary = mt6580_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+	.cpu_kill = mt6580_cpu_kill,
+	.cpu_die = mt6580_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(mt6580_smp, "mediatek,mt6580-smp", &mt6580_smp_ops);
-- 
1.8.1.1.dirty

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

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

* [PATCH v2 3/6] ARM: mediatek: add smp bringup code for MT6580
@ 2015-07-10  6:04     ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: linux-arm-kernel

Add support for cpu enable-method "mediatek,mt6580-smp" for booting
secondary CPUs on MT6580.

Signed-off-by: Scott Shu <scott.shu@mediatek.com>
---
 arch/arm/mach-mediatek/platsmp.c | 139 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 138 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c
index 12fefb3..7f5a5cfb 100644
--- a/arch/arm/mach-mediatek/platsmp.c
+++ b/arch/arm/mach-mediatek/platsmp.c
@@ -13,7 +13,6 @@
  * 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/io.h>
 #include <linux/memblock.h>
@@ -21,10 +20,15 @@
 #include <linux/of_address.h>
 #include <linux/string.h>
 #include <linux/threads.h>
+#include <linux/delay.h>
+#include <asm/cacheflush.h>
+#include "generic.h"
 
 #define MTK_MAX_CPU		8
 #define MTK_SMP_REG_SIZE	0x1000
 
+static DEFINE_SPINLOCK(boot_lock);
+
 struct mtk_smp_boot_info {
 	unsigned long smp_base;
 	unsigned int jump_reg;
@@ -57,6 +61,128 @@ static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
 static void __iomem *mtk_smp_base;
 static const struct mtk_smp_boot_info *mtk_smp_info;
 
+#ifdef CONFIG_HOTPLUG_CPU
+static int mt6580_cpu_kill(unsigned cpu)
+{
+	int ret;
+
+	ret = spm_cpu_mtcmos_off(cpu, 1);
+	if (ret < 0)
+		return 0;
+
+	return 1;
+}
+
+static void mt6580_cpu_die(unsigned int cpu)
+{
+	for (;;)
+		cpu_do_idle();
+}
+#endif
+
+static void write_pen_release(int val)
+{
+	pen_release = val;
+	/* Make sure this is visible to other CPUs */
+	smp_wmb();
+	sync_cache_w(&pen_release);
+}
+
+/*
+ * Refer common "pen" secondary release method
+ */
+static int mt6580_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	unsigned long timeout;
+	int ret;
+
+	/*
+	 * Set synchronisation state between this boot processor
+	 * and the secondary one
+	 */
+	spin_lock(&boot_lock);
+
+	/*
+	 * The secondary processor is waiting to be released from
+	 * the holding pen - release it, then wait for it to flag
+	 * that it has been released by resetting pen_release.
+	 *
+	 * Note that "pen_release" is the hardware CPU ID, whereas
+	 * "cpu" is Linux's internal ID.
+	 */
+	write_pen_release(cpu);
+
+	/*
+	 * CPU power on control by SPM
+	 */
+	ret = spm_cpu_mtcmos_on(cpu);
+	if (ret < 0) {
+		spin_unlock(&boot_lock);
+		return -ENOSYS;
+	}
+
+	timeout = jiffies + (1 * HZ);
+	while (time_before(jiffies, timeout)) {
+		/* Read barrier */
+		smp_rmb();
+
+		if (pen_release == -1)
+			break;
+
+		udelay(10);
+	}
+
+	/*
+	 * Now the secondary core is starting up let it run its
+	 * calibrations, then wait for it to finish
+	 */
+	spin_unlock(&boot_lock);
+
+	return (pen_release != -1 ? -ENOSYS : 0);
+}
+
+static void mt6580_secondary_init(unsigned int cpu)
+{
+	/*
+	 * Let the primary processor know we're out of the
+	 * pen, then head off into the C entry point
+	 */
+	write_pen_release(-1);
+
+	/*
+	 * Synchronise with the boot thread.
+	 */
+	spin_lock(&boot_lock);
+	spin_unlock(&boot_lock);
+}
+
+#define MT6580_INFRACFG_AO	0x10001000
+#define SW_ROM_PD		BIT(31)
+
+static void __init mt6580_smp_prepare_cpus(unsigned int max_cpus)
+{
+	static void __iomem *infracfg_ao_base;
+
+	infracfg_ao_base = ioremap(MT6580_INFRACFG_AO, 0x1000);
+
+	if (!infracfg_ao_base)
+		pr_err("%s: Unable to map I/O memory\n", __func__);
+
+	/* Enable bootrom power down mode */
+	writel_relaxed(readl(infracfg_ao_base + 0x804) | SW_ROM_PD,
+		       infracfg_ao_base + 0x804);
+
+	/* Write the address of slave startup into boot address
+	   register for bootrom power down mode */
+	writel_relaxed(virt_to_phys(secondary_startup_arm),
+		       infracfg_ao_base + 0x800);
+
+	iounmap(infracfg_ao_base);
+
+	/* Initial spm cpu mtcmos memory map */
+	spm_cpu_mtcmos_init();
+}
+
 static int mtk_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	if (!mtk_smp_base)
@@ -143,3 +269,14 @@ static struct smp_operations mt65xx_smp_ops __initdata = {
 	.smp_boot_secondary = mtk_boot_secondary,
 };
 CPU_METHOD_OF_DECLARE(mt65xx_smp, "mediatek,mt65xx-smp", &mt65xx_smp_ops);
+
+static struct smp_operations mt6580_smp_ops __initdata = {
+	.smp_prepare_cpus = mt6580_smp_prepare_cpus,
+	.smp_secondary_init = mt6580_secondary_init,
+	.smp_boot_secondary = mt6580_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+	.cpu_kill = mt6580_cpu_kill,
+	.cpu_die = mt6580_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(mt6580_smp, "mediatek,mt6580-smp", &mt6580_smp_ops);
-- 
1.8.1.1.dirty

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

* [PATCH v2 4/6] ARM: Mediatek: enable GPT6 on boot up to make arch timer working for MT6580
  2015-07-10  6:04   ` Scott Shu
  (?)
@ 2015-07-10  6:04     ` Scott Shu
  -1 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Russell King, Arnd Bergmann, Catalin Marinas,
	Heiko Stuebner, Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek
  Cc: loda.chou, jades.shih, scott.shu, wsd_upstream, Scott Shu

We enable GTP6 which ungates the arch timer clock.

Signed-off-by: Scott Shu <scott.shu@mediatek.com>
---
 arch/arm/mach-mediatek/mediatek.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c
index 6b38d67..469d332 100644
--- a/arch/arm/mach-mediatek/mediatek.c
+++ b/arch/arm/mach-mediatek/mediatek.c
@@ -28,7 +28,8 @@ static void __init mediatek_timer_init(void)
 {
 	void __iomem *gpt_base = 0;
 
-	if (of_machine_is_compatible("mediatek,mt6589") ||
+	if (of_machine_is_compatible("mediatek,mt6580") ||
+	    of_machine_is_compatible("mediatek,mt6589") ||
 	    of_machine_is_compatible("mediatek,mt8135") ||
 	    of_machine_is_compatible("mediatek,mt8127")) {
 		/* turn on GPT6 which ungates arch timer clocks */
@@ -46,6 +47,7 @@ static void __init mediatek_timer_init(void)
 };
 
 static const char * const mediatek_board_dt_compat[] = {
+	"mediatek,mt6580",
 	"mediatek,mt6589",
 	"mediatek,mt6592",
 	"mediatek,mt8127",
-- 
1.8.1.1.dirty


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

* [PATCH v2 4/6] ARM: Mediatek: enable GPT6 on boot up to make arch timer working for MT6580
@ 2015-07-10  6:04     ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Russell King, Arnd Bergmann, Catalin Marinas,
	Heiko Stuebner, Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek
  Cc: loda.chou, jades.shih, scott.shu, wsd_upstream, Scott Shu

We enable GTP6 which ungates the arch timer clock.

Signed-off-by: Scott Shu <scott.shu@mediatek.com>
---
 arch/arm/mach-mediatek/mediatek.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c
index 6b38d67..469d332 100644
--- a/arch/arm/mach-mediatek/mediatek.c
+++ b/arch/arm/mach-mediatek/mediatek.c
@@ -28,7 +28,8 @@ static void __init mediatek_timer_init(void)
 {
 	void __iomem *gpt_base = 0;
 
-	if (of_machine_is_compatible("mediatek,mt6589") ||
+	if (of_machine_is_compatible("mediatek,mt6580") ||
+	    of_machine_is_compatible("mediatek,mt6589") ||
 	    of_machine_is_compatible("mediatek,mt8135") ||
 	    of_machine_is_compatible("mediatek,mt8127")) {
 		/* turn on GPT6 which ungates arch timer clocks */
@@ -46,6 +47,7 @@ static void __init mediatek_timer_init(void)
 };
 
 static const char * const mediatek_board_dt_compat[] = {
+	"mediatek,mt6580",
 	"mediatek,mt6589",
 	"mediatek,mt6592",
 	"mediatek,mt8127",
-- 
1.8.1.1.dirty

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

* [PATCH v2 4/6] ARM: Mediatek: enable GPT6 on boot up to make arch timer working for MT6580
@ 2015-07-10  6:04     ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: linux-arm-kernel

We enable GTP6 which ungates the arch timer clock.

Signed-off-by: Scott Shu <scott.shu@mediatek.com>
---
 arch/arm/mach-mediatek/mediatek.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c
index 6b38d67..469d332 100644
--- a/arch/arm/mach-mediatek/mediatek.c
+++ b/arch/arm/mach-mediatek/mediatek.c
@@ -28,7 +28,8 @@ static void __init mediatek_timer_init(void)
 {
 	void __iomem *gpt_base = 0;
 
-	if (of_machine_is_compatible("mediatek,mt6589") ||
+	if (of_machine_is_compatible("mediatek,mt6580") ||
+	    of_machine_is_compatible("mediatek,mt6589") ||
 	    of_machine_is_compatible("mediatek,mt8135") ||
 	    of_machine_is_compatible("mediatek,mt8127")) {
 		/* turn on GPT6 which ungates arch timer clocks */
@@ -46,6 +47,7 @@ static void __init mediatek_timer_init(void)
 };
 
 static const char * const mediatek_board_dt_compat[] = {
+	"mediatek,mt6580",
 	"mediatek,mt6589",
 	"mediatek,mt6592",
 	"mediatek,mt8127",
-- 
1.8.1.1.dirty

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

* [PATCH v2 5/6] ARM: dts: mt6580: Add device nodes to the MT6580 dtsi file
  2015-07-10  6:04   ` Scott Shu
  (?)
@ 2015-07-10  6:04     ` Scott Shu
  -1 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Russell King, Arnd Bergmann, Catalin Marinas,
	Heiko Stuebner, Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek
  Cc: loda.chou, jades.shih, scott.shu, wsd_upstream, Scott Shu

This adds the SCPSYS device node to the MT6580 dtsi file.

Signed-off-by: Scott Shu <scott.shu@mediatek.com>
---
 arch/arm/boot/dts/mt6580.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/mt6580.dtsi b/arch/arm/boot/dts/mt6580.dtsi
index 09852cd..4a9df6a 100644
--- a/arch/arm/boot/dts/mt6580.dtsi
+++ b/arch/arm/boot/dts/mt6580.dtsi
@@ -74,6 +74,11 @@
 		};
 	};
 
+	scpsys: scpsys@10006000 {
+		compatible = "mediatek,mt6580-scpsys";
+		reg = <0x10006000 0x1000>;
+	};
+
 	timer: timer@10008000 {
 		compatible = "mediatek,mt6580-timer",
 			     "mediatek,mt6577-timer";
-- 
1.8.1.1.dirty


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

* [PATCH v2 5/6] ARM: dts: mt6580: Add device nodes to the MT6580 dtsi file
@ 2015-07-10  6:04     ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Russell King, Arnd Bergmann, Catalin Marinas,
	Heiko Stuebner, Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek
  Cc: loda.chou, jades.shih, scott.shu, wsd_upstream, Scott Shu

This adds the SCPSYS device node to the MT6580 dtsi file.

Signed-off-by: Scott Shu <scott.shu@mediatek.com>
---
 arch/arm/boot/dts/mt6580.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/mt6580.dtsi b/arch/arm/boot/dts/mt6580.dtsi
index 09852cd..4a9df6a 100644
--- a/arch/arm/boot/dts/mt6580.dtsi
+++ b/arch/arm/boot/dts/mt6580.dtsi
@@ -74,6 +74,11 @@
 		};
 	};
 
+	scpsys: scpsys@10006000 {
+		compatible = "mediatek,mt6580-scpsys";
+		reg = <0x10006000 0x1000>;
+	};
+
 	timer: timer@10008000 {
 		compatible = "mediatek,mt6580-timer",
 			     "mediatek,mt6577-timer";
-- 
1.8.1.1.dirty

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

* [PATCH v2 5/6] ARM: dts: mt6580: Add device nodes to the MT6580 dtsi file
@ 2015-07-10  6:04     ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: linux-arm-kernel

This adds the SCPSYS device node to the MT6580 dtsi file.

Signed-off-by: Scott Shu <scott.shu@mediatek.com>
---
 arch/arm/boot/dts/mt6580.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/mt6580.dtsi b/arch/arm/boot/dts/mt6580.dtsi
index 09852cd..4a9df6a 100644
--- a/arch/arm/boot/dts/mt6580.dtsi
+++ b/arch/arm/boot/dts/mt6580.dtsi
@@ -74,6 +74,11 @@
 		};
 	};
 
+	scpsys: scpsys at 10006000 {
+		compatible = "mediatek,mt6580-scpsys";
+		reg = <0x10006000 0x1000>;
+	};
+
 	timer: timer at 10008000 {
 		compatible = "mediatek,mt6580-timer",
 			     "mediatek,mt6577-timer";
-- 
1.8.1.1.dirty

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

* [PATCH v2 6/6] ARM: dts: mt6580: enable basic SMP bringup for MT6580
@ 2015-07-10  6:04     ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Russell King, Arnd Bergmann, Catalin Marinas,
	Heiko Stuebner, Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek
  Cc: loda.chou, jades.shih, scott.shu, wsd_upstream, Scott Shu

Add arch timer node to enable arch-timer support. MT6580 firmware
doesn't correctly setup arch-timer frequency and CNTVOFF, add
properties to workaround this.

This set cpu enable-method to enable SMP.

Signed-off-by: Scott Shu <scott.shu@mediatek.com>
---
 arch/arm/boot/dts/mt6580.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/mt6580.dtsi b/arch/arm/boot/dts/mt6580.dtsi
index 4a9df6a..ef577bd 100644
--- a/arch/arm/boot/dts/mt6580.dtsi
+++ b/arch/arm/boot/dts/mt6580.dtsi
@@ -25,26 +25,31 @@
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
+		enable-method = "mediatek,mt6580-smp";
 
 		cpu@0 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x0>;
+			clock-frequency = <1700000000>;
 		};
 		cpu@1 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x1>;
+			clock-frequency = <1700000000>;
 		};
 		cpu@2 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x2>;
+			clock-frequency = <1700000000>;
 		};
 		cpu@3 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x3>;
+			clock-frequency = <1700000000>;
 		};
 
 	};
@@ -74,6 +79,21 @@
 		};
 	};
 
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+				<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+				<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+				<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>;
+		clock-frequency = <13000000>;
+		arm,cpu-registers-not-fw-configured;
+	};
+
 	scpsys: scpsys@10006000 {
 		compatible = "mediatek,mt6580-scpsys";
 		reg = <0x10006000 0x1000>;
-- 
1.8.1.1.dirty


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

* [PATCH v2 6/6] ARM: dts: mt6580: enable basic SMP bringup for MT6580
@ 2015-07-10  6:04     ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Russell King, Arnd Bergmann, Catalin Marinas,
	Heiko Stuebner, Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Scott Shu, scott.shu-Re5JQEeQqe8AvxtiuMwx3w,
	loda.chou-NuS5LvNUpcJWk0Htik3J/w,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w,
	jades.shih-NuS5LvNUpcJWk0Htik3J/w

Add arch timer node to enable arch-timer support. MT6580 firmware
doesn't correctly setup arch-timer frequency and CNTVOFF, add
properties to workaround this.

This set cpu enable-method to enable SMP.

Signed-off-by: Scott Shu <scott.shu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
 arch/arm/boot/dts/mt6580.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/mt6580.dtsi b/arch/arm/boot/dts/mt6580.dtsi
index 4a9df6a..ef577bd 100644
--- a/arch/arm/boot/dts/mt6580.dtsi
+++ b/arch/arm/boot/dts/mt6580.dtsi
@@ -25,26 +25,31 @@
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
+		enable-method = "mediatek,mt6580-smp";
 
 		cpu@0 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x0>;
+			clock-frequency = <1700000000>;
 		};
 		cpu@1 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x1>;
+			clock-frequency = <1700000000>;
 		};
 		cpu@2 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x2>;
+			clock-frequency = <1700000000>;
 		};
 		cpu@3 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x3>;
+			clock-frequency = <1700000000>;
 		};
 
 	};
@@ -74,6 +79,21 @@
 		};
 	};
 
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+				<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+				<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+				<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>;
+		clock-frequency = <13000000>;
+		arm,cpu-registers-not-fw-configured;
+	};
+
 	scpsys: scpsys@10006000 {
 		compatible = "mediatek,mt6580-scpsys";
 		reg = <0x10006000 0x1000>;
-- 
1.8.1.1.dirty

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

* [PATCH v2 6/6] ARM: dts: mt6580: enable basic SMP bringup for MT6580
@ 2015-07-10  6:04     ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-10  6:04 UTC (permalink / raw)
  To: linux-arm-kernel

Add arch timer node to enable arch-timer support. MT6580 firmware
doesn't correctly setup arch-timer frequency and CNTVOFF, add
properties to workaround this.

This set cpu enable-method to enable SMP.

Signed-off-by: Scott Shu <scott.shu@mediatek.com>
---
 arch/arm/boot/dts/mt6580.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/mt6580.dtsi b/arch/arm/boot/dts/mt6580.dtsi
index 4a9df6a..ef577bd 100644
--- a/arch/arm/boot/dts/mt6580.dtsi
+++ b/arch/arm/boot/dts/mt6580.dtsi
@@ -25,26 +25,31 @@
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
+		enable-method = "mediatek,mt6580-smp";
 
 		cpu at 0 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x0>;
+			clock-frequency = <1700000000>;
 		};
 		cpu at 1 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x1>;
+			clock-frequency = <1700000000>;
 		};
 		cpu at 2 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x2>;
+			clock-frequency = <1700000000>;
 		};
 		cpu at 3 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x3>;
+			clock-frequency = <1700000000>;
 		};
 
 	};
@@ -74,6 +79,21 @@
 		};
 	};
 
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+				<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+				<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+				<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>;
+		clock-frequency = <13000000>;
+		arm,cpu-registers-not-fw-configured;
+	};
+
 	scpsys: scpsys at 10006000 {
 		compatible = "mediatek,mt6580-scpsys";
 		reg = <0x10006000 0x1000>;
-- 
1.8.1.1.dirty

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

* Re: [PATCH v2 2/6] soc: Mediatek: Add SCPSYS CPU power domain driver
@ 2015-07-10 14:31       ` Matthias Brugger
  0 siblings, 0 replies; 30+ messages in thread
From: Matthias Brugger @ 2015-07-10 14:31 UTC (permalink / raw)
  To: Scott Shu
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, Arnd Bergmann, Catalin Marinas, Heiko Stuebner,
	Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, loda.chou, jades.shih,
	scott.shu, wsd_upstream

On Friday, July 10, 2015 02:04:05 PM Scott Shu wrote:
> This adds a CPU power domain driver for the Mediatek SCPSYS unit on
> MT6580.
> 
> Signed-off-by: Scott Shu <scott.shu@mediatek.com>
> ---
>  arch/arm/mach-mediatek/Makefile  |   2 +-
>  arch/arm/mach-mediatek/generic.h |  23 ++++
>  arch/arm/mach-mediatek/hotplug.c | 267
> +++++++++++++++++++++++++++++++++++++++ 3 files changed, 291 insertions(+),
> 1 deletion(-)
>  create mode 100644 arch/arm/mach-mediatek/generic.h
>  create mode 100644 arch/arm/mach-mediatek/hotplug.c
> 
> diff --git a/arch/arm/mach-mediatek/Makefile
> b/arch/arm/mach-mediatek/Makefile index 2116460..b2e4ef5 100644
> --- a/arch/arm/mach-mediatek/Makefile
> +++ b/arch/arm/mach-mediatek/Makefile
> @@ -1,4 +1,4 @@
>  ifeq ($(CONFIG_SMP),y)
> -obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
> +obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o hotplug.o
>  endif
>  obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
> diff --git a/arch/arm/mach-mediatek/generic.h
> b/arch/arm/mach-mediatek/generic.h new file mode 100644
> index 0000000..376f183
> --- /dev/null
> +++ b/arch/arm/mach-mediatek/generic.h
> @@ -0,0 +1,23 @@
> +/*
> + * Copyright (c) 2015 Mediatek Inc.
> + * Author: Scott Shu <scott.shu@mediatek.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + */
> +#ifndef __MACH_GENERIC_H
> +#define __MACH_GENERIC_H
> +
> +#include <linux/kernel.h>
> +
> +int spm_cpu_mtcmos_init(void);
> +int spm_cpu_mtcmos_on(int cpu);
> +int spm_cpu_mtcmos_off(int cpu, bool wfi);
> +
> +#endif
> diff --git a/arch/arm/mach-mediatek/hotplug.c
> b/arch/arm/mach-mediatek/hotplug.c new file mode 100644
> index 0000000..bd97f2e
> --- /dev/null
> +++ b/arch/arm/mach-mediatek/hotplug.c
> @@ -0,0 +1,267 @@
> +/*
> + * Copyright (c) 2015 Mediatek Inc.
> + * Author: Scott Shu <scott.shu@mediatek.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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/init.h>
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/spinlock.h>
> +#include <linux/delay.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_address.h>
> +
> +/* SCPSYS registers */
> +#define SPM_POWERON_CONFIG_SET		0x0000
> +
> +#define SPM_CA7_CPU0_PWR_CON		0x0200
> +#define SPM_CA7_CPU1_PWR_CON		0x0218
> +#define SPM_CA7_CPU2_PWR_CON		0x021c
> +#define SPM_CA7_CPU3_PWR_CON		0x0220
> +
> +#define SPM_CA7_CPU0_L1_PDN		0x025c
> +#define SPM_CA7_CPU1_L1_PDN		0x0264
> +#define SPM_CA7_CPU2_L1_PDN		0x026c
> +#define SPM_CA7_CPU3_L1_PDN		0x0274
> +
> +#define SPM_PWR_STATUS			0x060c
> +#define SPM_PWR_STATUS_2ND		0x0610
> +#define SPM_SLEEP_TIMER_STA		0x0720
> +
> +/* bit definition in SPM_CA7_CPUx_PWR_CON */
> +#define SRAM_ISOINT_B		BIT(6)
> +#define SRAM_CKISO		BIT(5)
> +#define PWR_CLK_DIS		BIT(4)
> +#define PWR_ON_2ND		BIT(3)
> +#define PWR_ON			BIT(2)
> +#define PWR_ISO			BIT(1)
> +#define PWR_RST_B		BIT(0)
> +
> +/* bit definition in SPM_CA7_CPUx_L1_PDN */
> +#define L1_PDN_ACK		BIT(8)
> +#define L1_PDN			BIT(0)
> +
> +#define MT6580_MAX_CPUS		4
> +
> +static DEFINE_SPINLOCK(spm_cpu_lock);
> +
> +void __iomem *spm_cpu_base;
> +
> +u32 spm_cpu_pwr_con[MT6580_MAX_CPUS] = {
> +	SPM_CA7_CPU0_PWR_CON,
> +	SPM_CA7_CPU1_PWR_CON,
> +	SPM_CA7_CPU2_PWR_CON,
> +	SPM_CA7_CPU3_PWR_CON,
> +};
> +
> +u32 spm_cpu_l1_pdn[MT6580_MAX_CPUS] = {
> +	SPM_CA7_CPU0_L1_PDN,
> +	SPM_CA7_CPU1_L1_PDN,
> +	SPM_CA7_CPU2_L1_PDN,
> +	SPM_CA7_CPU3_L1_PDN,
> +};
> +
> +#define SPM_REGWR_EN		BIT(0)
> +#define SPM_PROJECT_CODE	0x0B16
> +
> +int spm_cpu_mtcmos_on(int cpu)
> +{
> +	unsigned long flags;
> +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> +	unsigned int temp;
> +	int timeout = 10;
> +	int ret = -ENOSYS;
> +
> +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> +
> +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> +
> +	spin_lock_irqsave(&spm_cpu_lock, flags);
> +
> +	/* Set PWR_ON */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= PWR_ON;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Wait for charging core power */
> +	udelay(1);
> +
> +	/* Set PWR_ON_2ND */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= PWR_ON_2ND;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Wait for the power-ack */
> +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> +		(1U << (13 - cpu))) != (1U << (13 - cpu))) ||
> +		((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> +		(1U << (13 - cpu))) != (1U << (13 - cpu)))) {
> +		if (--timeout == 0)
> +			goto fail;
> +		udelay(1);
> +	}
> +
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~PWR_ISO;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* L1 power on */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> +	temp &= ~L1_PDN;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> +	timeout = 10;
> +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> +		L1_PDN_ACK) != 0) {
> +		if (--timeout == 0)
> +			goto fail;
> +		udelay(1);
> +	}
> +
> +	/* Wait for memory power ready */
> +	udelay(1);
> +
> +	/* Set SRAM_ISOINT_B */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= SRAM_ISOINT_B;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Clear SRAM_CKISO */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~SRAM_CKISO;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Clear PWR_CLK_DIS */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~PWR_CLK_DIS;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Set PWR_RST_B to finish power on and reset sequences */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= PWR_RST_B;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	ret = 0;
> +fail:
> +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> +
> +	return ret;
> +}
> +
> +int spm_cpu_mtcmos_off(int cpu, bool wfi)
> +{
> +	unsigned long flags;
> +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> +	unsigned int temp;
> +	int timeout = 10;
> +	int ret = -ENOSYS;
> +
> +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> +
> +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> +
> +	if (wfi) {
> +		while ((readl_relaxed(spm_cpu_base + SPM_SLEEP_TIMER_STA) &
> +			(1U << (16 + cpu))) == 0) {
> +			if (--timeout == 0)
> +				return ret;
> +			udelay(1);
> +		}
> +	}
> +
> +	spin_lock_irqsave(&spm_cpu_lock, flags);
> +
> +	/* Set PWR_ISO */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= PWR_ISO;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Set SRAM_CKISO */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= SRAM_CKISO;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Clear SRAM_ISOINT_B */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~SRAM_ISOINT_B;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* L1 power off */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> +	temp |= L1_PDN;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> +	timeout = 10;
> +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> +		L1_PDN_ACK) != L1_PDN_ACK) {
> +		if (--timeout == 0)
> +			goto fail;
> +		udelay(1);
> +	}
> +
> +	/* Clear PWR_RST_B */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~PWR_RST_B;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Set PWR_CLK_DIS */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= PWR_CLK_DIS;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Clear PWR_ON */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~PWR_ON;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Clear PWR_ON_2ND */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~PWR_ON_2ND;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	timeout = 10;
> +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> +		(1U << (13 - cpu))) != 0) ||
> +	       ((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> +		(1U << (13 - cpu))) != 0)) {
> +		if (--timeout == 0)
> +			goto fail;
> +		udelay(1);
> +	}
> +
> +	ret = 0;
> +fail:
> +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> +
> +	return ret;
> +}
> +
> +int spm_cpu_mtcmos_init(void)
> +{
> +	struct device_node *node;
> +
> +	node = of_find_compatible_node(NULL, NULL, "mediatek,mt6580-scpsys");

This looks pretty much as if it should go in 
drivers/soc/mediatek/mtk-scpsys.c

AFAIR Sascha already mentioned that in v1.
Why do you want/need to implement this mach-mediatek?

Thanks,
Matthias

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

* Re: [PATCH v2 2/6] soc: Mediatek: Add SCPSYS CPU power domain driver
@ 2015-07-10 14:31       ` Matthias Brugger
  0 siblings, 0 replies; 30+ messages in thread
From: Matthias Brugger @ 2015-07-10 14:31 UTC (permalink / raw)
  To: Scott Shu
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, Arnd Bergmann, Catalin Marinas, Heiko Stuebner,
	Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	loda.chou-NuS5LvNUpcJWk0Htik3J/w,
	jades.shih-NuS5LvNUpcJWk0Htik3J/w,
	scott.shu-Re5JQEeQqe8AvxtiuMwx3w,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w

On Friday, July 10, 2015 02:04:05 PM Scott Shu wrote:
> This adds a CPU power domain driver for the Mediatek SCPSYS unit on
> MT6580.
> 
> Signed-off-by: Scott Shu <scott.shu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> ---
>  arch/arm/mach-mediatek/Makefile  |   2 +-
>  arch/arm/mach-mediatek/generic.h |  23 ++++
>  arch/arm/mach-mediatek/hotplug.c | 267
> +++++++++++++++++++++++++++++++++++++++ 3 files changed, 291 insertions(+),
> 1 deletion(-)
>  create mode 100644 arch/arm/mach-mediatek/generic.h
>  create mode 100644 arch/arm/mach-mediatek/hotplug.c
> 
> diff --git a/arch/arm/mach-mediatek/Makefile
> b/arch/arm/mach-mediatek/Makefile index 2116460..b2e4ef5 100644
> --- a/arch/arm/mach-mediatek/Makefile
> +++ b/arch/arm/mach-mediatek/Makefile
> @@ -1,4 +1,4 @@
>  ifeq ($(CONFIG_SMP),y)
> -obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
> +obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o hotplug.o
>  endif
>  obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
> diff --git a/arch/arm/mach-mediatek/generic.h
> b/arch/arm/mach-mediatek/generic.h new file mode 100644
> index 0000000..376f183
> --- /dev/null
> +++ b/arch/arm/mach-mediatek/generic.h
> @@ -0,0 +1,23 @@
> +/*
> + * Copyright (c) 2015 Mediatek Inc.
> + * Author: Scott Shu <scott.shu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + */
> +#ifndef __MACH_GENERIC_H
> +#define __MACH_GENERIC_H
> +
> +#include <linux/kernel.h>
> +
> +int spm_cpu_mtcmos_init(void);
> +int spm_cpu_mtcmos_on(int cpu);
> +int spm_cpu_mtcmos_off(int cpu, bool wfi);
> +
> +#endif
> diff --git a/arch/arm/mach-mediatek/hotplug.c
> b/arch/arm/mach-mediatek/hotplug.c new file mode 100644
> index 0000000..bd97f2e
> --- /dev/null
> +++ b/arch/arm/mach-mediatek/hotplug.c
> @@ -0,0 +1,267 @@
> +/*
> + * Copyright (c) 2015 Mediatek Inc.
> + * Author: Scott Shu <scott.shu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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/init.h>
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/spinlock.h>
> +#include <linux/delay.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_address.h>
> +
> +/* SCPSYS registers */
> +#define SPM_POWERON_CONFIG_SET		0x0000
> +
> +#define SPM_CA7_CPU0_PWR_CON		0x0200
> +#define SPM_CA7_CPU1_PWR_CON		0x0218
> +#define SPM_CA7_CPU2_PWR_CON		0x021c
> +#define SPM_CA7_CPU3_PWR_CON		0x0220
> +
> +#define SPM_CA7_CPU0_L1_PDN		0x025c
> +#define SPM_CA7_CPU1_L1_PDN		0x0264
> +#define SPM_CA7_CPU2_L1_PDN		0x026c
> +#define SPM_CA7_CPU3_L1_PDN		0x0274
> +
> +#define SPM_PWR_STATUS			0x060c
> +#define SPM_PWR_STATUS_2ND		0x0610
> +#define SPM_SLEEP_TIMER_STA		0x0720
> +
> +/* bit definition in SPM_CA7_CPUx_PWR_CON */
> +#define SRAM_ISOINT_B		BIT(6)
> +#define SRAM_CKISO		BIT(5)
> +#define PWR_CLK_DIS		BIT(4)
> +#define PWR_ON_2ND		BIT(3)
> +#define PWR_ON			BIT(2)
> +#define PWR_ISO			BIT(1)
> +#define PWR_RST_B		BIT(0)
> +
> +/* bit definition in SPM_CA7_CPUx_L1_PDN */
> +#define L1_PDN_ACK		BIT(8)
> +#define L1_PDN			BIT(0)
> +
> +#define MT6580_MAX_CPUS		4
> +
> +static DEFINE_SPINLOCK(spm_cpu_lock);
> +
> +void __iomem *spm_cpu_base;
> +
> +u32 spm_cpu_pwr_con[MT6580_MAX_CPUS] = {
> +	SPM_CA7_CPU0_PWR_CON,
> +	SPM_CA7_CPU1_PWR_CON,
> +	SPM_CA7_CPU2_PWR_CON,
> +	SPM_CA7_CPU3_PWR_CON,
> +};
> +
> +u32 spm_cpu_l1_pdn[MT6580_MAX_CPUS] = {
> +	SPM_CA7_CPU0_L1_PDN,
> +	SPM_CA7_CPU1_L1_PDN,
> +	SPM_CA7_CPU2_L1_PDN,
> +	SPM_CA7_CPU3_L1_PDN,
> +};
> +
> +#define SPM_REGWR_EN		BIT(0)
> +#define SPM_PROJECT_CODE	0x0B16
> +
> +int spm_cpu_mtcmos_on(int cpu)
> +{
> +	unsigned long flags;
> +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> +	unsigned int temp;
> +	int timeout = 10;
> +	int ret = -ENOSYS;
> +
> +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> +
> +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> +
> +	spin_lock_irqsave(&spm_cpu_lock, flags);
> +
> +	/* Set PWR_ON */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= PWR_ON;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Wait for charging core power */
> +	udelay(1);
> +
> +	/* Set PWR_ON_2ND */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= PWR_ON_2ND;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Wait for the power-ack */
> +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> +		(1U << (13 - cpu))) != (1U << (13 - cpu))) ||
> +		((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> +		(1U << (13 - cpu))) != (1U << (13 - cpu)))) {
> +		if (--timeout == 0)
> +			goto fail;
> +		udelay(1);
> +	}
> +
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~PWR_ISO;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* L1 power on */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> +	temp &= ~L1_PDN;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> +	timeout = 10;
> +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> +		L1_PDN_ACK) != 0) {
> +		if (--timeout == 0)
> +			goto fail;
> +		udelay(1);
> +	}
> +
> +	/* Wait for memory power ready */
> +	udelay(1);
> +
> +	/* Set SRAM_ISOINT_B */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= SRAM_ISOINT_B;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Clear SRAM_CKISO */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~SRAM_CKISO;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Clear PWR_CLK_DIS */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~PWR_CLK_DIS;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Set PWR_RST_B to finish power on and reset sequences */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= PWR_RST_B;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	ret = 0;
> +fail:
> +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> +
> +	return ret;
> +}
> +
> +int spm_cpu_mtcmos_off(int cpu, bool wfi)
> +{
> +	unsigned long flags;
> +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> +	unsigned int temp;
> +	int timeout = 10;
> +	int ret = -ENOSYS;
> +
> +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> +
> +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> +
> +	if (wfi) {
> +		while ((readl_relaxed(spm_cpu_base + SPM_SLEEP_TIMER_STA) &
> +			(1U << (16 + cpu))) == 0) {
> +			if (--timeout == 0)
> +				return ret;
> +			udelay(1);
> +		}
> +	}
> +
> +	spin_lock_irqsave(&spm_cpu_lock, flags);
> +
> +	/* Set PWR_ISO */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= PWR_ISO;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Set SRAM_CKISO */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= SRAM_CKISO;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Clear SRAM_ISOINT_B */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~SRAM_ISOINT_B;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* L1 power off */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> +	temp |= L1_PDN;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> +	timeout = 10;
> +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> +		L1_PDN_ACK) != L1_PDN_ACK) {
> +		if (--timeout == 0)
> +			goto fail;
> +		udelay(1);
> +	}
> +
> +	/* Clear PWR_RST_B */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~PWR_RST_B;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Set PWR_CLK_DIS */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= PWR_CLK_DIS;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Clear PWR_ON */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~PWR_ON;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Clear PWR_ON_2ND */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~PWR_ON_2ND;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	timeout = 10;
> +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> +		(1U << (13 - cpu))) != 0) ||
> +	       ((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> +		(1U << (13 - cpu))) != 0)) {
> +		if (--timeout == 0)
> +			goto fail;
> +		udelay(1);
> +	}
> +
> +	ret = 0;
> +fail:
> +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> +
> +	return ret;
> +}
> +
> +int spm_cpu_mtcmos_init(void)
> +{
> +	struct device_node *node;
> +
> +	node = of_find_compatible_node(NULL, NULL, "mediatek,mt6580-scpsys");

This looks pretty much as if it should go in 
drivers/soc/mediatek/mtk-scpsys.c

AFAIR Sascha already mentioned that in v1.
Why do you want/need to implement this mach-mediatek?

Thanks,
Matthias
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v2 2/6] soc: Mediatek: Add SCPSYS CPU power domain driver
@ 2015-07-10 14:31       ` Matthias Brugger
  0 siblings, 0 replies; 30+ messages in thread
From: Matthias Brugger @ 2015-07-10 14:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday, July 10, 2015 02:04:05 PM Scott Shu wrote:
> This adds a CPU power domain driver for the Mediatek SCPSYS unit on
> MT6580.
> 
> Signed-off-by: Scott Shu <scott.shu@mediatek.com>
> ---
>  arch/arm/mach-mediatek/Makefile  |   2 +-
>  arch/arm/mach-mediatek/generic.h |  23 ++++
>  arch/arm/mach-mediatek/hotplug.c | 267
> +++++++++++++++++++++++++++++++++++++++ 3 files changed, 291 insertions(+),
> 1 deletion(-)
>  create mode 100644 arch/arm/mach-mediatek/generic.h
>  create mode 100644 arch/arm/mach-mediatek/hotplug.c
> 
> diff --git a/arch/arm/mach-mediatek/Makefile
> b/arch/arm/mach-mediatek/Makefile index 2116460..b2e4ef5 100644
> --- a/arch/arm/mach-mediatek/Makefile
> +++ b/arch/arm/mach-mediatek/Makefile
> @@ -1,4 +1,4 @@
>  ifeq ($(CONFIG_SMP),y)
> -obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
> +obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o hotplug.o
>  endif
>  obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
> diff --git a/arch/arm/mach-mediatek/generic.h
> b/arch/arm/mach-mediatek/generic.h new file mode 100644
> index 0000000..376f183
> --- /dev/null
> +++ b/arch/arm/mach-mediatek/generic.h
> @@ -0,0 +1,23 @@
> +/*
> + * Copyright (c) 2015 Mediatek Inc.
> + * Author: Scott Shu <scott.shu@mediatek.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + */
> +#ifndef __MACH_GENERIC_H
> +#define __MACH_GENERIC_H
> +
> +#include <linux/kernel.h>
> +
> +int spm_cpu_mtcmos_init(void);
> +int spm_cpu_mtcmos_on(int cpu);
> +int spm_cpu_mtcmos_off(int cpu, bool wfi);
> +
> +#endif
> diff --git a/arch/arm/mach-mediatek/hotplug.c
> b/arch/arm/mach-mediatek/hotplug.c new file mode 100644
> index 0000000..bd97f2e
> --- /dev/null
> +++ b/arch/arm/mach-mediatek/hotplug.c
> @@ -0,0 +1,267 @@
> +/*
> + * Copyright (c) 2015 Mediatek Inc.
> + * Author: Scott Shu <scott.shu@mediatek.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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/init.h>
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/spinlock.h>
> +#include <linux/delay.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_address.h>
> +
> +/* SCPSYS registers */
> +#define SPM_POWERON_CONFIG_SET		0x0000
> +
> +#define SPM_CA7_CPU0_PWR_CON		0x0200
> +#define SPM_CA7_CPU1_PWR_CON		0x0218
> +#define SPM_CA7_CPU2_PWR_CON		0x021c
> +#define SPM_CA7_CPU3_PWR_CON		0x0220
> +
> +#define SPM_CA7_CPU0_L1_PDN		0x025c
> +#define SPM_CA7_CPU1_L1_PDN		0x0264
> +#define SPM_CA7_CPU2_L1_PDN		0x026c
> +#define SPM_CA7_CPU3_L1_PDN		0x0274
> +
> +#define SPM_PWR_STATUS			0x060c
> +#define SPM_PWR_STATUS_2ND		0x0610
> +#define SPM_SLEEP_TIMER_STA		0x0720
> +
> +/* bit definition in SPM_CA7_CPUx_PWR_CON */
> +#define SRAM_ISOINT_B		BIT(6)
> +#define SRAM_CKISO		BIT(5)
> +#define PWR_CLK_DIS		BIT(4)
> +#define PWR_ON_2ND		BIT(3)
> +#define PWR_ON			BIT(2)
> +#define PWR_ISO			BIT(1)
> +#define PWR_RST_B		BIT(0)
> +
> +/* bit definition in SPM_CA7_CPUx_L1_PDN */
> +#define L1_PDN_ACK		BIT(8)
> +#define L1_PDN			BIT(0)
> +
> +#define MT6580_MAX_CPUS		4
> +
> +static DEFINE_SPINLOCK(spm_cpu_lock);
> +
> +void __iomem *spm_cpu_base;
> +
> +u32 spm_cpu_pwr_con[MT6580_MAX_CPUS] = {
> +	SPM_CA7_CPU0_PWR_CON,
> +	SPM_CA7_CPU1_PWR_CON,
> +	SPM_CA7_CPU2_PWR_CON,
> +	SPM_CA7_CPU3_PWR_CON,
> +};
> +
> +u32 spm_cpu_l1_pdn[MT6580_MAX_CPUS] = {
> +	SPM_CA7_CPU0_L1_PDN,
> +	SPM_CA7_CPU1_L1_PDN,
> +	SPM_CA7_CPU2_L1_PDN,
> +	SPM_CA7_CPU3_L1_PDN,
> +};
> +
> +#define SPM_REGWR_EN		BIT(0)
> +#define SPM_PROJECT_CODE	0x0B16
> +
> +int spm_cpu_mtcmos_on(int cpu)
> +{
> +	unsigned long flags;
> +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> +	unsigned int temp;
> +	int timeout = 10;
> +	int ret = -ENOSYS;
> +
> +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> +
> +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> +
> +	spin_lock_irqsave(&spm_cpu_lock, flags);
> +
> +	/* Set PWR_ON */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= PWR_ON;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Wait for charging core power */
> +	udelay(1);
> +
> +	/* Set PWR_ON_2ND */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= PWR_ON_2ND;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Wait for the power-ack */
> +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> +		(1U << (13 - cpu))) != (1U << (13 - cpu))) ||
> +		((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> +		(1U << (13 - cpu))) != (1U << (13 - cpu)))) {
> +		if (--timeout == 0)
> +			goto fail;
> +		udelay(1);
> +	}
> +
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~PWR_ISO;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* L1 power on */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> +	temp &= ~L1_PDN;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> +	timeout = 10;
> +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> +		L1_PDN_ACK) != 0) {
> +		if (--timeout == 0)
> +			goto fail;
> +		udelay(1);
> +	}
> +
> +	/* Wait for memory power ready */
> +	udelay(1);
> +
> +	/* Set SRAM_ISOINT_B */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= SRAM_ISOINT_B;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Clear SRAM_CKISO */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~SRAM_CKISO;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Clear PWR_CLK_DIS */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~PWR_CLK_DIS;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Set PWR_RST_B to finish power on and reset sequences */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= PWR_RST_B;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	ret = 0;
> +fail:
> +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> +
> +	return ret;
> +}
> +
> +int spm_cpu_mtcmos_off(int cpu, bool wfi)
> +{
> +	unsigned long flags;
> +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> +	unsigned int temp;
> +	int timeout = 10;
> +	int ret = -ENOSYS;
> +
> +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> +
> +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> +
> +	if (wfi) {
> +		while ((readl_relaxed(spm_cpu_base + SPM_SLEEP_TIMER_STA) &
> +			(1U << (16 + cpu))) == 0) {
> +			if (--timeout == 0)
> +				return ret;
> +			udelay(1);
> +		}
> +	}
> +
> +	spin_lock_irqsave(&spm_cpu_lock, flags);
> +
> +	/* Set PWR_ISO */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= PWR_ISO;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Set SRAM_CKISO */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= SRAM_CKISO;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Clear SRAM_ISOINT_B */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~SRAM_ISOINT_B;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* L1 power off */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> +	temp |= L1_PDN;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> +	timeout = 10;
> +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> +		L1_PDN_ACK) != L1_PDN_ACK) {
> +		if (--timeout == 0)
> +			goto fail;
> +		udelay(1);
> +	}
> +
> +	/* Clear PWR_RST_B */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~PWR_RST_B;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Set PWR_CLK_DIS */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp |= PWR_CLK_DIS;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Clear PWR_ON */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~PWR_ON;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	/* Clear PWR_ON_2ND */
> +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> +	temp &= ~PWR_ON_2ND;
> +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> +
> +	timeout = 10;
> +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> +		(1U << (13 - cpu))) != 0) ||
> +	       ((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> +		(1U << (13 - cpu))) != 0)) {
> +		if (--timeout == 0)
> +			goto fail;
> +		udelay(1);
> +	}
> +
> +	ret = 0;
> +fail:
> +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> +
> +	return ret;
> +}
> +
> +int spm_cpu_mtcmos_init(void)
> +{
> +	struct device_node *node;
> +
> +	node = of_find_compatible_node(NULL, NULL, "mediatek,mt6580-scpsys");

This looks pretty much as if it should go in 
drivers/soc/mediatek/mtk-scpsys.c

AFAIR Sascha already mentioned that in v1.
Why do you want/need to implement this mach-mediatek?

Thanks,
Matthias

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

* Re: [PATCH v2 2/6] soc: Mediatek: Add SCPSYS CPU power domain driver
  2015-07-10 14:31       ` Matthias Brugger
  (?)
@ 2015-07-13  4:18         ` Scott Shu
  -1 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-13  4:18 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, Arnd Bergmann, Catalin Marinas, Heiko Stuebner,
	Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, loda.chou, jades.shih,
	scott.shu, wsd_upstream


For some platform, the code for controlling CPU power is located in
arch/arm/mach-xxxx. (i.e., mach-hisi and mach-qcom). The framework is
clear and easy to maintain. 	In addition, the code will be called in
very early stage during system boot up.Is the platform driver ready for
the moment?


On Fri, 2015-07-10 at 16:31 +0200, Matthias Brugger wrote:
> On Friday, July 10, 2015 02:04:05 PM Scott Shu wrote:
> > This adds a CPU power domain driver for the Mediatek SCPSYS unit on
> > MT6580.
> > 
> > Signed-off-by: Scott Shu <scott.shu@mediatek.com>
> > ---
> >  arch/arm/mach-mediatek/Makefile  |   2 +-
> >  arch/arm/mach-mediatek/generic.h |  23 ++++
> >  arch/arm/mach-mediatek/hotplug.c | 267
> > +++++++++++++++++++++++++++++++++++++++ 3 files changed, 291 insertions(+),
> > 1 deletion(-)
> >  create mode 100644 arch/arm/mach-mediatek/generic.h
> >  create mode 100644 arch/arm/mach-mediatek/hotplug.c
> > 
> > diff --git a/arch/arm/mach-mediatek/Makefile
> > b/arch/arm/mach-mediatek/Makefile index 2116460..b2e4ef5 100644
> > --- a/arch/arm/mach-mediatek/Makefile
> > +++ b/arch/arm/mach-mediatek/Makefile
> > @@ -1,4 +1,4 @@
> >  ifeq ($(CONFIG_SMP),y)
> > -obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
> > +obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o hotplug.o
> >  endif
> >  obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
> > diff --git a/arch/arm/mach-mediatek/generic.h
> > b/arch/arm/mach-mediatek/generic.h new file mode 100644
> > index 0000000..376f183
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/generic.h
> > @@ -0,0 +1,23 @@
> > +/*
> > + * Copyright (c) 2015 Mediatek Inc.
> > + * Author: Scott Shu <scott.shu@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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.
> > + */
> > +#ifndef __MACH_GENERIC_H
> > +#define __MACH_GENERIC_H
> > +
> > +#include <linux/kernel.h>
> > +
> > +int spm_cpu_mtcmos_init(void);
> > +int spm_cpu_mtcmos_on(int cpu);
> > +int spm_cpu_mtcmos_off(int cpu, bool wfi);
> > +
> > +#endif
> > diff --git a/arch/arm/mach-mediatek/hotplug.c
> > b/arch/arm/mach-mediatek/hotplug.c new file mode 100644
> > index 0000000..bd97f2e
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/hotplug.c
> > @@ -0,0 +1,267 @@
> > +/*
> > + * Copyright (c) 2015 Mediatek Inc.
> > + * Author: Scott Shu <scott.shu@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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/init.h>
> > +#include <linux/module.h>
> > +#include <linux/kernel.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/delay.h>
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_address.h>
> > +
> > +/* SCPSYS registers */
> > +#define SPM_POWERON_CONFIG_SET		0x0000
> > +
> > +#define SPM_CA7_CPU0_PWR_CON		0x0200
> > +#define SPM_CA7_CPU1_PWR_CON		0x0218
> > +#define SPM_CA7_CPU2_PWR_CON		0x021c
> > +#define SPM_CA7_CPU3_PWR_CON		0x0220
> > +
> > +#define SPM_CA7_CPU0_L1_PDN		0x025c
> > +#define SPM_CA7_CPU1_L1_PDN		0x0264
> > +#define SPM_CA7_CPU2_L1_PDN		0x026c
> > +#define SPM_CA7_CPU3_L1_PDN		0x0274
> > +
> > +#define SPM_PWR_STATUS			0x060c
> > +#define SPM_PWR_STATUS_2ND		0x0610
> > +#define SPM_SLEEP_TIMER_STA		0x0720
> > +
> > +/* bit definition in SPM_CA7_CPUx_PWR_CON */
> > +#define SRAM_ISOINT_B		BIT(6)
> > +#define SRAM_CKISO		BIT(5)
> > +#define PWR_CLK_DIS		BIT(4)
> > +#define PWR_ON_2ND		BIT(3)
> > +#define PWR_ON			BIT(2)
> > +#define PWR_ISO			BIT(1)
> > +#define PWR_RST_B		BIT(0)
> > +
> > +/* bit definition in SPM_CA7_CPUx_L1_PDN */
> > +#define L1_PDN_ACK		BIT(8)
> > +#define L1_PDN			BIT(0)
> > +
> > +#define MT6580_MAX_CPUS		4
> > +
> > +static DEFINE_SPINLOCK(spm_cpu_lock);
> > +
> > +void __iomem *spm_cpu_base;
> > +
> > +u32 spm_cpu_pwr_con[MT6580_MAX_CPUS] = {
> > +	SPM_CA7_CPU0_PWR_CON,
> > +	SPM_CA7_CPU1_PWR_CON,
> > +	SPM_CA7_CPU2_PWR_CON,
> > +	SPM_CA7_CPU3_PWR_CON,
> > +};
> > +
> > +u32 spm_cpu_l1_pdn[MT6580_MAX_CPUS] = {
> > +	SPM_CA7_CPU0_L1_PDN,
> > +	SPM_CA7_CPU1_L1_PDN,
> > +	SPM_CA7_CPU2_L1_PDN,
> > +	SPM_CA7_CPU3_L1_PDN,
> > +};
> > +
> > +#define SPM_REGWR_EN		BIT(0)
> > +#define SPM_PROJECT_CODE	0x0B16
> > +
> > +int spm_cpu_mtcmos_on(int cpu)
> > +{
> > +	unsigned long flags;
> > +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> > +	unsigned int temp;
> > +	int timeout = 10;
> > +	int ret = -ENOSYS;
> > +
> > +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> > +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> > +
> > +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> > +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> > +
> > +	spin_lock_irqsave(&spm_cpu_lock, flags);
> > +
> > +	/* Set PWR_ON */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ON;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Wait for charging core power */
> > +	udelay(1);
> > +
> > +	/* Set PWR_ON_2ND */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ON_2ND;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Wait for the power-ack */
> > +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> > +		(1U << (13 - cpu))) != (1U << (13 - cpu))) ||
> > +		((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> > +		(1U << (13 - cpu))) != (1U << (13 - cpu)))) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* L1 power on */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> > +	temp &= ~L1_PDN;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> > +	timeout = 10;
> > +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> > +		L1_PDN_ACK) != 0) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	/* Wait for memory power ready */
> > +	udelay(1);
> > +
> > +	/* Set SRAM_ISOINT_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= SRAM_ISOINT_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear SRAM_CKISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~SRAM_CKISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_CLK_DIS */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_CLK_DIS;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set PWR_RST_B to finish power on and reset sequences */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_RST_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	ret = 0;
> > +fail:
> > +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> > +
> > +	return ret;
> > +}
> > +
> > +int spm_cpu_mtcmos_off(int cpu, bool wfi)
> > +{
> > +	unsigned long flags;
> > +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> > +	unsigned int temp;
> > +	int timeout = 10;
> > +	int ret = -ENOSYS;
> > +
> > +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> > +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> > +
> > +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> > +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> > +
> > +	if (wfi) {
> > +		while ((readl_relaxed(spm_cpu_base + SPM_SLEEP_TIMER_STA) &
> > +			(1U << (16 + cpu))) == 0) {
> > +			if (--timeout == 0)
> > +				return ret;
> > +			udelay(1);
> > +		}
> > +	}
> > +
> > +	spin_lock_irqsave(&spm_cpu_lock, flags);
> > +
> > +	/* Set PWR_ISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set SRAM_CKISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= SRAM_CKISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear SRAM_ISOINT_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~SRAM_ISOINT_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* L1 power off */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> > +	temp |= L1_PDN;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> > +	timeout = 10;
> > +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> > +		L1_PDN_ACK) != L1_PDN_ACK) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	/* Clear PWR_RST_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_RST_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set PWR_CLK_DIS */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_CLK_DIS;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_ON */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ON;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_ON_2ND */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ON_2ND;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	timeout = 10;
> > +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> > +		(1U << (13 - cpu))) != 0) ||
> > +	       ((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> > +		(1U << (13 - cpu))) != 0)) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	ret = 0;
> > +fail:
> > +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> > +
> > +	return ret;
> > +}
> > +
> > +int spm_cpu_mtcmos_init(void)
> > +{
> > +	struct device_node *node;
> > +
> > +	node = of_find_compatible_node(NULL, NULL, "mediatek,mt6580-scpsys");
> 
> This looks pretty much as if it should go in 
> drivers/soc/mediatek/mtk-scpsys.c
> 
> AFAIR Sascha already mentioned that in v1.
> Why do you want/need to implement this mach-mediatek?
> 
> Thanks,
> Matthias



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

* Re: [PATCH v2 2/6] soc: Mediatek: Add SCPSYS CPU power domain driver
@ 2015-07-13  4:18         ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-13  4:18 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, Arnd Bergmann, Catalin Marinas, Heiko Stuebner,
	Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	loda.chou-NuS5LvNUpcJWk0Htik3J/w,
	jades.shih-NuS5LvNUpcJWk0Htik3J/w,
	scott.shu-Re5JQEeQqe8AvxtiuMwx3w,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w


For some platform, the code for controlling CPU power is located in
arch/arm/mach-xxxx. (i.e., mach-hisi and mach-qcom). The framework is
clear and easy to maintain. 	In addition, the code will be called in
very early stage during system boot up.Is the platform driver ready for
the moment?


On Fri, 2015-07-10 at 16:31 +0200, Matthias Brugger wrote:
> On Friday, July 10, 2015 02:04:05 PM Scott Shu wrote:
> > This adds a CPU power domain driver for the Mediatek SCPSYS unit on
> > MT6580.
> > 
> > Signed-off-by: Scott Shu <scott.shu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > ---
> >  arch/arm/mach-mediatek/Makefile  |   2 +-
> >  arch/arm/mach-mediatek/generic.h |  23 ++++
> >  arch/arm/mach-mediatek/hotplug.c | 267
> > +++++++++++++++++++++++++++++++++++++++ 3 files changed, 291 insertions(+),
> > 1 deletion(-)
> >  create mode 100644 arch/arm/mach-mediatek/generic.h
> >  create mode 100644 arch/arm/mach-mediatek/hotplug.c
> > 
> > diff --git a/arch/arm/mach-mediatek/Makefile
> > b/arch/arm/mach-mediatek/Makefile index 2116460..b2e4ef5 100644
> > --- a/arch/arm/mach-mediatek/Makefile
> > +++ b/arch/arm/mach-mediatek/Makefile
> > @@ -1,4 +1,4 @@
> >  ifeq ($(CONFIG_SMP),y)
> > -obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
> > +obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o hotplug.o
> >  endif
> >  obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
> > diff --git a/arch/arm/mach-mediatek/generic.h
> > b/arch/arm/mach-mediatek/generic.h new file mode 100644
> > index 0000000..376f183
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/generic.h
> > @@ -0,0 +1,23 @@
> > +/*
> > + * Copyright (c) 2015 Mediatek Inc.
> > + * Author: Scott Shu <scott.shu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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.
> > + */
> > +#ifndef __MACH_GENERIC_H
> > +#define __MACH_GENERIC_H
> > +
> > +#include <linux/kernel.h>
> > +
> > +int spm_cpu_mtcmos_init(void);
> > +int spm_cpu_mtcmos_on(int cpu);
> > +int spm_cpu_mtcmos_off(int cpu, bool wfi);
> > +
> > +#endif
> > diff --git a/arch/arm/mach-mediatek/hotplug.c
> > b/arch/arm/mach-mediatek/hotplug.c new file mode 100644
> > index 0000000..bd97f2e
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/hotplug.c
> > @@ -0,0 +1,267 @@
> > +/*
> > + * Copyright (c) 2015 Mediatek Inc.
> > + * Author: Scott Shu <scott.shu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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/init.h>
> > +#include <linux/module.h>
> > +#include <linux/kernel.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/delay.h>
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_address.h>
> > +
> > +/* SCPSYS registers */
> > +#define SPM_POWERON_CONFIG_SET		0x0000
> > +
> > +#define SPM_CA7_CPU0_PWR_CON		0x0200
> > +#define SPM_CA7_CPU1_PWR_CON		0x0218
> > +#define SPM_CA7_CPU2_PWR_CON		0x021c
> > +#define SPM_CA7_CPU3_PWR_CON		0x0220
> > +
> > +#define SPM_CA7_CPU0_L1_PDN		0x025c
> > +#define SPM_CA7_CPU1_L1_PDN		0x0264
> > +#define SPM_CA7_CPU2_L1_PDN		0x026c
> > +#define SPM_CA7_CPU3_L1_PDN		0x0274
> > +
> > +#define SPM_PWR_STATUS			0x060c
> > +#define SPM_PWR_STATUS_2ND		0x0610
> > +#define SPM_SLEEP_TIMER_STA		0x0720
> > +
> > +/* bit definition in SPM_CA7_CPUx_PWR_CON */
> > +#define SRAM_ISOINT_B		BIT(6)
> > +#define SRAM_CKISO		BIT(5)
> > +#define PWR_CLK_DIS		BIT(4)
> > +#define PWR_ON_2ND		BIT(3)
> > +#define PWR_ON			BIT(2)
> > +#define PWR_ISO			BIT(1)
> > +#define PWR_RST_B		BIT(0)
> > +
> > +/* bit definition in SPM_CA7_CPUx_L1_PDN */
> > +#define L1_PDN_ACK		BIT(8)
> > +#define L1_PDN			BIT(0)
> > +
> > +#define MT6580_MAX_CPUS		4
> > +
> > +static DEFINE_SPINLOCK(spm_cpu_lock);
> > +
> > +void __iomem *spm_cpu_base;
> > +
> > +u32 spm_cpu_pwr_con[MT6580_MAX_CPUS] = {
> > +	SPM_CA7_CPU0_PWR_CON,
> > +	SPM_CA7_CPU1_PWR_CON,
> > +	SPM_CA7_CPU2_PWR_CON,
> > +	SPM_CA7_CPU3_PWR_CON,
> > +};
> > +
> > +u32 spm_cpu_l1_pdn[MT6580_MAX_CPUS] = {
> > +	SPM_CA7_CPU0_L1_PDN,
> > +	SPM_CA7_CPU1_L1_PDN,
> > +	SPM_CA7_CPU2_L1_PDN,
> > +	SPM_CA7_CPU3_L1_PDN,
> > +};
> > +
> > +#define SPM_REGWR_EN		BIT(0)
> > +#define SPM_PROJECT_CODE	0x0B16
> > +
> > +int spm_cpu_mtcmos_on(int cpu)
> > +{
> > +	unsigned long flags;
> > +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> > +	unsigned int temp;
> > +	int timeout = 10;
> > +	int ret = -ENOSYS;
> > +
> > +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> > +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> > +
> > +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> > +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> > +
> > +	spin_lock_irqsave(&spm_cpu_lock, flags);
> > +
> > +	/* Set PWR_ON */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ON;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Wait for charging core power */
> > +	udelay(1);
> > +
> > +	/* Set PWR_ON_2ND */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ON_2ND;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Wait for the power-ack */
> > +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> > +		(1U << (13 - cpu))) != (1U << (13 - cpu))) ||
> > +		((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> > +		(1U << (13 - cpu))) != (1U << (13 - cpu)))) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* L1 power on */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> > +	temp &= ~L1_PDN;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> > +	timeout = 10;
> > +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> > +		L1_PDN_ACK) != 0) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	/* Wait for memory power ready */
> > +	udelay(1);
> > +
> > +	/* Set SRAM_ISOINT_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= SRAM_ISOINT_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear SRAM_CKISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~SRAM_CKISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_CLK_DIS */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_CLK_DIS;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set PWR_RST_B to finish power on and reset sequences */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_RST_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	ret = 0;
> > +fail:
> > +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> > +
> > +	return ret;
> > +}
> > +
> > +int spm_cpu_mtcmos_off(int cpu, bool wfi)
> > +{
> > +	unsigned long flags;
> > +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> > +	unsigned int temp;
> > +	int timeout = 10;
> > +	int ret = -ENOSYS;
> > +
> > +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> > +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> > +
> > +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> > +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> > +
> > +	if (wfi) {
> > +		while ((readl_relaxed(spm_cpu_base + SPM_SLEEP_TIMER_STA) &
> > +			(1U << (16 + cpu))) == 0) {
> > +			if (--timeout == 0)
> > +				return ret;
> > +			udelay(1);
> > +		}
> > +	}
> > +
> > +	spin_lock_irqsave(&spm_cpu_lock, flags);
> > +
> > +	/* Set PWR_ISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set SRAM_CKISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= SRAM_CKISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear SRAM_ISOINT_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~SRAM_ISOINT_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* L1 power off */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> > +	temp |= L1_PDN;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> > +	timeout = 10;
> > +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> > +		L1_PDN_ACK) != L1_PDN_ACK) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	/* Clear PWR_RST_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_RST_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set PWR_CLK_DIS */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_CLK_DIS;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_ON */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ON;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_ON_2ND */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ON_2ND;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	timeout = 10;
> > +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> > +		(1U << (13 - cpu))) != 0) ||
> > +	       ((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> > +		(1U << (13 - cpu))) != 0)) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	ret = 0;
> > +fail:
> > +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> > +
> > +	return ret;
> > +}
> > +
> > +int spm_cpu_mtcmos_init(void)
> > +{
> > +	struct device_node *node;
> > +
> > +	node = of_find_compatible_node(NULL, NULL, "mediatek,mt6580-scpsys");
> 
> This looks pretty much as if it should go in 
> drivers/soc/mediatek/mtk-scpsys.c
> 
> AFAIR Sascha already mentioned that in v1.
> Why do you want/need to implement this mach-mediatek?
> 
> Thanks,
> Matthias


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

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

* [PATCH v2 2/6] soc: Mediatek: Add SCPSYS CPU power domain driver
@ 2015-07-13  4:18         ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-13  4:18 UTC (permalink / raw)
  To: linux-arm-kernel


For some platform, the code for controlling CPU power is located in
arch/arm/mach-xxxx. (i.e., mach-hisi and mach-qcom). The framework is
clear and easy to maintain. 	In addition, the code will be called in
very early stage during system boot up.Is the platform driver ready for
the moment?


On Fri, 2015-07-10 at 16:31 +0200, Matthias Brugger wrote:
> On Friday, July 10, 2015 02:04:05 PM Scott Shu wrote:
> > This adds a CPU power domain driver for the Mediatek SCPSYS unit on
> > MT6580.
> > 
> > Signed-off-by: Scott Shu <scott.shu@mediatek.com>
> > ---
> >  arch/arm/mach-mediatek/Makefile  |   2 +-
> >  arch/arm/mach-mediatek/generic.h |  23 ++++
> >  arch/arm/mach-mediatek/hotplug.c | 267
> > +++++++++++++++++++++++++++++++++++++++ 3 files changed, 291 insertions(+),
> > 1 deletion(-)
> >  create mode 100644 arch/arm/mach-mediatek/generic.h
> >  create mode 100644 arch/arm/mach-mediatek/hotplug.c
> > 
> > diff --git a/arch/arm/mach-mediatek/Makefile
> > b/arch/arm/mach-mediatek/Makefile index 2116460..b2e4ef5 100644
> > --- a/arch/arm/mach-mediatek/Makefile
> > +++ b/arch/arm/mach-mediatek/Makefile
> > @@ -1,4 +1,4 @@
> >  ifeq ($(CONFIG_SMP),y)
> > -obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
> > +obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o hotplug.o
> >  endif
> >  obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
> > diff --git a/arch/arm/mach-mediatek/generic.h
> > b/arch/arm/mach-mediatek/generic.h new file mode 100644
> > index 0000000..376f183
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/generic.h
> > @@ -0,0 +1,23 @@
> > +/*
> > + * Copyright (c) 2015 Mediatek Inc.
> > + * Author: Scott Shu <scott.shu@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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.
> > + */
> > +#ifndef __MACH_GENERIC_H
> > +#define __MACH_GENERIC_H
> > +
> > +#include <linux/kernel.h>
> > +
> > +int spm_cpu_mtcmos_init(void);
> > +int spm_cpu_mtcmos_on(int cpu);
> > +int spm_cpu_mtcmos_off(int cpu, bool wfi);
> > +
> > +#endif
> > diff --git a/arch/arm/mach-mediatek/hotplug.c
> > b/arch/arm/mach-mediatek/hotplug.c new file mode 100644
> > index 0000000..bd97f2e
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/hotplug.c
> > @@ -0,0 +1,267 @@
> > +/*
> > + * Copyright (c) 2015 Mediatek Inc.
> > + * Author: Scott Shu <scott.shu@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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/init.h>
> > +#include <linux/module.h>
> > +#include <linux/kernel.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/delay.h>
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_address.h>
> > +
> > +/* SCPSYS registers */
> > +#define SPM_POWERON_CONFIG_SET		0x0000
> > +
> > +#define SPM_CA7_CPU0_PWR_CON		0x0200
> > +#define SPM_CA7_CPU1_PWR_CON		0x0218
> > +#define SPM_CA7_CPU2_PWR_CON		0x021c
> > +#define SPM_CA7_CPU3_PWR_CON		0x0220
> > +
> > +#define SPM_CA7_CPU0_L1_PDN		0x025c
> > +#define SPM_CA7_CPU1_L1_PDN		0x0264
> > +#define SPM_CA7_CPU2_L1_PDN		0x026c
> > +#define SPM_CA7_CPU3_L1_PDN		0x0274
> > +
> > +#define SPM_PWR_STATUS			0x060c
> > +#define SPM_PWR_STATUS_2ND		0x0610
> > +#define SPM_SLEEP_TIMER_STA		0x0720
> > +
> > +/* bit definition in SPM_CA7_CPUx_PWR_CON */
> > +#define SRAM_ISOINT_B		BIT(6)
> > +#define SRAM_CKISO		BIT(5)
> > +#define PWR_CLK_DIS		BIT(4)
> > +#define PWR_ON_2ND		BIT(3)
> > +#define PWR_ON			BIT(2)
> > +#define PWR_ISO			BIT(1)
> > +#define PWR_RST_B		BIT(0)
> > +
> > +/* bit definition in SPM_CA7_CPUx_L1_PDN */
> > +#define L1_PDN_ACK		BIT(8)
> > +#define L1_PDN			BIT(0)
> > +
> > +#define MT6580_MAX_CPUS		4
> > +
> > +static DEFINE_SPINLOCK(spm_cpu_lock);
> > +
> > +void __iomem *spm_cpu_base;
> > +
> > +u32 spm_cpu_pwr_con[MT6580_MAX_CPUS] = {
> > +	SPM_CA7_CPU0_PWR_CON,
> > +	SPM_CA7_CPU1_PWR_CON,
> > +	SPM_CA7_CPU2_PWR_CON,
> > +	SPM_CA7_CPU3_PWR_CON,
> > +};
> > +
> > +u32 spm_cpu_l1_pdn[MT6580_MAX_CPUS] = {
> > +	SPM_CA7_CPU0_L1_PDN,
> > +	SPM_CA7_CPU1_L1_PDN,
> > +	SPM_CA7_CPU2_L1_PDN,
> > +	SPM_CA7_CPU3_L1_PDN,
> > +};
> > +
> > +#define SPM_REGWR_EN		BIT(0)
> > +#define SPM_PROJECT_CODE	0x0B16
> > +
> > +int spm_cpu_mtcmos_on(int cpu)
> > +{
> > +	unsigned long flags;
> > +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> > +	unsigned int temp;
> > +	int timeout = 10;
> > +	int ret = -ENOSYS;
> > +
> > +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> > +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> > +
> > +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> > +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> > +
> > +	spin_lock_irqsave(&spm_cpu_lock, flags);
> > +
> > +	/* Set PWR_ON */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ON;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Wait for charging core power */
> > +	udelay(1);
> > +
> > +	/* Set PWR_ON_2ND */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ON_2ND;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Wait for the power-ack */
> > +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> > +		(1U << (13 - cpu))) != (1U << (13 - cpu))) ||
> > +		((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> > +		(1U << (13 - cpu))) != (1U << (13 - cpu)))) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* L1 power on */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> > +	temp &= ~L1_PDN;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> > +	timeout = 10;
> > +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> > +		L1_PDN_ACK) != 0) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	/* Wait for memory power ready */
> > +	udelay(1);
> > +
> > +	/* Set SRAM_ISOINT_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= SRAM_ISOINT_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear SRAM_CKISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~SRAM_CKISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_CLK_DIS */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_CLK_DIS;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set PWR_RST_B to finish power on and reset sequences */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_RST_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	ret = 0;
> > +fail:
> > +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> > +
> > +	return ret;
> > +}
> > +
> > +int spm_cpu_mtcmos_off(int cpu, bool wfi)
> > +{
> > +	unsigned long flags;
> > +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> > +	unsigned int temp;
> > +	int timeout = 10;
> > +	int ret = -ENOSYS;
> > +
> > +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> > +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> > +
> > +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> > +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> > +
> > +	if (wfi) {
> > +		while ((readl_relaxed(spm_cpu_base + SPM_SLEEP_TIMER_STA) &
> > +			(1U << (16 + cpu))) == 0) {
> > +			if (--timeout == 0)
> > +				return ret;
> > +			udelay(1);
> > +		}
> > +	}
> > +
> > +	spin_lock_irqsave(&spm_cpu_lock, flags);
> > +
> > +	/* Set PWR_ISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set SRAM_CKISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= SRAM_CKISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear SRAM_ISOINT_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~SRAM_ISOINT_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* L1 power off */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> > +	temp |= L1_PDN;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> > +	timeout = 10;
> > +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> > +		L1_PDN_ACK) != L1_PDN_ACK) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	/* Clear PWR_RST_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_RST_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set PWR_CLK_DIS */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_CLK_DIS;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_ON */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ON;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_ON_2ND */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ON_2ND;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	timeout = 10;
> > +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> > +		(1U << (13 - cpu))) != 0) ||
> > +	       ((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> > +		(1U << (13 - cpu))) != 0)) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	ret = 0;
> > +fail:
> > +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> > +
> > +	return ret;
> > +}
> > +
> > +int spm_cpu_mtcmos_init(void)
> > +{
> > +	struct device_node *node;
> > +
> > +	node = of_find_compatible_node(NULL, NULL, "mediatek,mt6580-scpsys");
> 
> This looks pretty much as if it should go in 
> drivers/soc/mediatek/mtk-scpsys.c
> 
> AFAIR Sascha already mentioned that in v1.
> Why do you want/need to implement this mach-mediatek?
> 
> Thanks,
> Matthias

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

* Re: [PATCH v2 2/6] soc: Mediatek: Add SCPSYS CPU power domain driver
  2015-07-10 14:31       ` Matthias Brugger
  (?)
@ 2015-07-18  2:23         ` Scott Shu
  -1 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-18  2:23 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, Arnd Bergmann, Catalin Marinas, Heiko Stuebner,
	Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, loda.chou, jades.shih,
	scott.shu, wsd_upstream

Hi Matthias,
Sascha hopes we can put CPU MTCMOS driver to his mtk-scpsys.c. We
understood but please let us describe our opinion.
(1) The code to initial CPU for SMP operation is in very early stage
during bring-up, the mtk-scpsys.c is not ready at the moment.

(2) The CPU MTCMOS driver may chip dependent, it’s more simple and easy
maintenance for us. 

(3) There are some precedents that locate the CPU power control under
arch/arm/mach-xxxx folder.

Please let us have more discussion about this.
Thanks a lot.
Scott

On Fri, 2015-07-10 at 16:31 +0200, Matthias Brugger wrote:
> On Friday, July 10, 2015 02:04:05 PM Scott Shu wrote:
> > This adds a CPU power domain driver for the Mediatek SCPSYS unit on
> > MT6580.
> > 
> > Signed-off-by: Scott Shu <scott.shu@mediatek.com>
> > ---
> >  arch/arm/mach-mediatek/Makefile  |   2 +-
> >  arch/arm/mach-mediatek/generic.h |  23 ++++
> >  arch/arm/mach-mediatek/hotplug.c | 267
> > +++++++++++++++++++++++++++++++++++++++ 3 files changed, 291 insertions(+),
> > 1 deletion(-)
> >  create mode 100644 arch/arm/mach-mediatek/generic.h
> >  create mode 100644 arch/arm/mach-mediatek/hotplug.c
> > 
> > diff --git a/arch/arm/mach-mediatek/Makefile
> > b/arch/arm/mach-mediatek/Makefile index 2116460..b2e4ef5 100644
> > --- a/arch/arm/mach-mediatek/Makefile
> > +++ b/arch/arm/mach-mediatek/Makefile
> > @@ -1,4 +1,4 @@
> >  ifeq ($(CONFIG_SMP),y)
> > -obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
> > +obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o hotplug.o
> >  endif
> >  obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
> > diff --git a/arch/arm/mach-mediatek/generic.h
> > b/arch/arm/mach-mediatek/generic.h new file mode 100644
> > index 0000000..376f183
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/generic.h
> > @@ -0,0 +1,23 @@
> > +/*
> > + * Copyright (c) 2015 Mediatek Inc.
> > + * Author: Scott Shu <scott.shu@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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.
> > + */
> > +#ifndef __MACH_GENERIC_H
> > +#define __MACH_GENERIC_H
> > +
> > +#include <linux/kernel.h>
> > +
> > +int spm_cpu_mtcmos_init(void);
> > +int spm_cpu_mtcmos_on(int cpu);
> > +int spm_cpu_mtcmos_off(int cpu, bool wfi);
> > +
> > +#endif
> > diff --git a/arch/arm/mach-mediatek/hotplug.c
> > b/arch/arm/mach-mediatek/hotplug.c new file mode 100644
> > index 0000000..bd97f2e
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/hotplug.c
> > @@ -0,0 +1,267 @@
> > +/*
> > + * Copyright (c) 2015 Mediatek Inc.
> > + * Author: Scott Shu <scott.shu@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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/init.h>
> > +#include <linux/module.h>
> > +#include <linux/kernel.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/delay.h>
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_address.h>
> > +
> > +/* SCPSYS registers */
> > +#define SPM_POWERON_CONFIG_SET		0x0000
> > +
> > +#define SPM_CA7_CPU0_PWR_CON		0x0200
> > +#define SPM_CA7_CPU1_PWR_CON		0x0218
> > +#define SPM_CA7_CPU2_PWR_CON		0x021c
> > +#define SPM_CA7_CPU3_PWR_CON		0x0220
> > +
> > +#define SPM_CA7_CPU0_L1_PDN		0x025c
> > +#define SPM_CA7_CPU1_L1_PDN		0x0264
> > +#define SPM_CA7_CPU2_L1_PDN		0x026c
> > +#define SPM_CA7_CPU3_L1_PDN		0x0274
> > +
> > +#define SPM_PWR_STATUS			0x060c
> > +#define SPM_PWR_STATUS_2ND		0x0610
> > +#define SPM_SLEEP_TIMER_STA		0x0720
> > +
> > +/* bit definition in SPM_CA7_CPUx_PWR_CON */
> > +#define SRAM_ISOINT_B		BIT(6)
> > +#define SRAM_CKISO		BIT(5)
> > +#define PWR_CLK_DIS		BIT(4)
> > +#define PWR_ON_2ND		BIT(3)
> > +#define PWR_ON			BIT(2)
> > +#define PWR_ISO			BIT(1)
> > +#define PWR_RST_B		BIT(0)
> > +
> > +/* bit definition in SPM_CA7_CPUx_L1_PDN */
> > +#define L1_PDN_ACK		BIT(8)
> > +#define L1_PDN			BIT(0)
> > +
> > +#define MT6580_MAX_CPUS		4
> > +
> > +static DEFINE_SPINLOCK(spm_cpu_lock);
> > +
> > +void __iomem *spm_cpu_base;
> > +
> > +u32 spm_cpu_pwr_con[MT6580_MAX_CPUS] = {
> > +	SPM_CA7_CPU0_PWR_CON,
> > +	SPM_CA7_CPU1_PWR_CON,
> > +	SPM_CA7_CPU2_PWR_CON,
> > +	SPM_CA7_CPU3_PWR_CON,
> > +};
> > +
> > +u32 spm_cpu_l1_pdn[MT6580_MAX_CPUS] = {
> > +	SPM_CA7_CPU0_L1_PDN,
> > +	SPM_CA7_CPU1_L1_PDN,
> > +	SPM_CA7_CPU2_L1_PDN,
> > +	SPM_CA7_CPU3_L1_PDN,
> > +};
> > +
> > +#define SPM_REGWR_EN		BIT(0)
> > +#define SPM_PROJECT_CODE	0x0B16
> > +
> > +int spm_cpu_mtcmos_on(int cpu)
> > +{
> > +	unsigned long flags;
> > +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> > +	unsigned int temp;
> > +	int timeout = 10;
> > +	int ret = -ENOSYS;
> > +
> > +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> > +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> > +
> > +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> > +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> > +
> > +	spin_lock_irqsave(&spm_cpu_lock, flags);
> > +
> > +	/* Set PWR_ON */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ON;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Wait for charging core power */
> > +	udelay(1);
> > +
> > +	/* Set PWR_ON_2ND */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ON_2ND;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Wait for the power-ack */
> > +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> > +		(1U << (13 - cpu))) != (1U << (13 - cpu))) ||
> > +		((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> > +		(1U << (13 - cpu))) != (1U << (13 - cpu)))) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* L1 power on */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> > +	temp &= ~L1_PDN;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> > +	timeout = 10;
> > +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> > +		L1_PDN_ACK) != 0) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	/* Wait for memory power ready */
> > +	udelay(1);
> > +
> > +	/* Set SRAM_ISOINT_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= SRAM_ISOINT_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear SRAM_CKISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~SRAM_CKISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_CLK_DIS */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_CLK_DIS;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set PWR_RST_B to finish power on and reset sequences */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_RST_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	ret = 0;
> > +fail:
> > +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> > +
> > +	return ret;
> > +}
> > +
> > +int spm_cpu_mtcmos_off(int cpu, bool wfi)
> > +{
> > +	unsigned long flags;
> > +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> > +	unsigned int temp;
> > +	int timeout = 10;
> > +	int ret = -ENOSYS;
> > +
> > +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> > +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> > +
> > +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> > +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> > +
> > +	if (wfi) {
> > +		while ((readl_relaxed(spm_cpu_base + SPM_SLEEP_TIMER_STA) &
> > +			(1U << (16 + cpu))) == 0) {
> > +			if (--timeout == 0)
> > +				return ret;
> > +			udelay(1);
> > +		}
> > +	}
> > +
> > +	spin_lock_irqsave(&spm_cpu_lock, flags);
> > +
> > +	/* Set PWR_ISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set SRAM_CKISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= SRAM_CKISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear SRAM_ISOINT_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~SRAM_ISOINT_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* L1 power off */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> > +	temp |= L1_PDN;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> > +	timeout = 10;
> > +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> > +		L1_PDN_ACK) != L1_PDN_ACK) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	/* Clear PWR_RST_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_RST_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set PWR_CLK_DIS */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_CLK_DIS;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_ON */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ON;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_ON_2ND */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ON_2ND;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	timeout = 10;
> > +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> > +		(1U << (13 - cpu))) != 0) ||
> > +	       ((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> > +		(1U << (13 - cpu))) != 0)) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	ret = 0;
> > +fail:
> > +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> > +
> > +	return ret;
> > +}
> > +
> > +int spm_cpu_mtcmos_init(void)
> > +{
> > +	struct device_node *node;
> > +
> > +	node = of_find_compatible_node(NULL, NULL, "mediatek,mt6580-scpsys");
> 
> This looks pretty much as if it should go in 
> drivers/soc/mediatek/mtk-scpsys.c
> 
> AFAIR Sascha already mentioned that in v1.
> Why do you want/need to implement this mach-mediatek?
> 
> Thanks,
> Matthias



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

* Re: [PATCH v2 2/6] soc: Mediatek: Add SCPSYS CPU power domain driver
@ 2015-07-18  2:23         ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-18  2:23 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, Arnd Bergmann, Catalin Marinas, Heiko Stuebner,
	Yingjoe Chen, Marc Carino, Lorenzo Pieralisi,
	Radha Mohan Chintakuntla, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	loda.chou-NuS5LvNUpcJWk0Htik3J/w,
	jades.shih-NuS5LvNUpcJWk0Htik3J/w,
	scott.shu-Re5JQEeQqe8AvxtiuMwx3w,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w

Hi Matthias,
Sascha hopes we can put CPU MTCMOS driver to his mtk-scpsys.c. We
understood but please let us describe our opinion.
(1) The code to initial CPU for SMP operation is in very early stage
during bring-up, the mtk-scpsys.c is not ready at the moment.

(2) The CPU MTCMOS driver may chip dependent, it’s more simple and easy
maintenance for us. 

(3) There are some precedents that locate the CPU power control under
arch/arm/mach-xxxx folder.

Please let us have more discussion about this.
Thanks a lot.
Scott

On Fri, 2015-07-10 at 16:31 +0200, Matthias Brugger wrote:
> On Friday, July 10, 2015 02:04:05 PM Scott Shu wrote:
> > This adds a CPU power domain driver for the Mediatek SCPSYS unit on
> > MT6580.
> > 
> > Signed-off-by: Scott Shu <scott.shu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > ---
> >  arch/arm/mach-mediatek/Makefile  |   2 +-
> >  arch/arm/mach-mediatek/generic.h |  23 ++++
> >  arch/arm/mach-mediatek/hotplug.c | 267
> > +++++++++++++++++++++++++++++++++++++++ 3 files changed, 291 insertions(+),
> > 1 deletion(-)
> >  create mode 100644 arch/arm/mach-mediatek/generic.h
> >  create mode 100644 arch/arm/mach-mediatek/hotplug.c
> > 
> > diff --git a/arch/arm/mach-mediatek/Makefile
> > b/arch/arm/mach-mediatek/Makefile index 2116460..b2e4ef5 100644
> > --- a/arch/arm/mach-mediatek/Makefile
> > +++ b/arch/arm/mach-mediatek/Makefile
> > @@ -1,4 +1,4 @@
> >  ifeq ($(CONFIG_SMP),y)
> > -obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
> > +obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o hotplug.o
> >  endif
> >  obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
> > diff --git a/arch/arm/mach-mediatek/generic.h
> > b/arch/arm/mach-mediatek/generic.h new file mode 100644
> > index 0000000..376f183
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/generic.h
> > @@ -0,0 +1,23 @@
> > +/*
> > + * Copyright (c) 2015 Mediatek Inc.
> > + * Author: Scott Shu <scott.shu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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.
> > + */
> > +#ifndef __MACH_GENERIC_H
> > +#define __MACH_GENERIC_H
> > +
> > +#include <linux/kernel.h>
> > +
> > +int spm_cpu_mtcmos_init(void);
> > +int spm_cpu_mtcmos_on(int cpu);
> > +int spm_cpu_mtcmos_off(int cpu, bool wfi);
> > +
> > +#endif
> > diff --git a/arch/arm/mach-mediatek/hotplug.c
> > b/arch/arm/mach-mediatek/hotplug.c new file mode 100644
> > index 0000000..bd97f2e
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/hotplug.c
> > @@ -0,0 +1,267 @@
> > +/*
> > + * Copyright (c) 2015 Mediatek Inc.
> > + * Author: Scott Shu <scott.shu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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/init.h>
> > +#include <linux/module.h>
> > +#include <linux/kernel.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/delay.h>
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_address.h>
> > +
> > +/* SCPSYS registers */
> > +#define SPM_POWERON_CONFIG_SET		0x0000
> > +
> > +#define SPM_CA7_CPU0_PWR_CON		0x0200
> > +#define SPM_CA7_CPU1_PWR_CON		0x0218
> > +#define SPM_CA7_CPU2_PWR_CON		0x021c
> > +#define SPM_CA7_CPU3_PWR_CON		0x0220
> > +
> > +#define SPM_CA7_CPU0_L1_PDN		0x025c
> > +#define SPM_CA7_CPU1_L1_PDN		0x0264
> > +#define SPM_CA7_CPU2_L1_PDN		0x026c
> > +#define SPM_CA7_CPU3_L1_PDN		0x0274
> > +
> > +#define SPM_PWR_STATUS			0x060c
> > +#define SPM_PWR_STATUS_2ND		0x0610
> > +#define SPM_SLEEP_TIMER_STA		0x0720
> > +
> > +/* bit definition in SPM_CA7_CPUx_PWR_CON */
> > +#define SRAM_ISOINT_B		BIT(6)
> > +#define SRAM_CKISO		BIT(5)
> > +#define PWR_CLK_DIS		BIT(4)
> > +#define PWR_ON_2ND		BIT(3)
> > +#define PWR_ON			BIT(2)
> > +#define PWR_ISO			BIT(1)
> > +#define PWR_RST_B		BIT(0)
> > +
> > +/* bit definition in SPM_CA7_CPUx_L1_PDN */
> > +#define L1_PDN_ACK		BIT(8)
> > +#define L1_PDN			BIT(0)
> > +
> > +#define MT6580_MAX_CPUS		4
> > +
> > +static DEFINE_SPINLOCK(spm_cpu_lock);
> > +
> > +void __iomem *spm_cpu_base;
> > +
> > +u32 spm_cpu_pwr_con[MT6580_MAX_CPUS] = {
> > +	SPM_CA7_CPU0_PWR_CON,
> > +	SPM_CA7_CPU1_PWR_CON,
> > +	SPM_CA7_CPU2_PWR_CON,
> > +	SPM_CA7_CPU3_PWR_CON,
> > +};
> > +
> > +u32 spm_cpu_l1_pdn[MT6580_MAX_CPUS] = {
> > +	SPM_CA7_CPU0_L1_PDN,
> > +	SPM_CA7_CPU1_L1_PDN,
> > +	SPM_CA7_CPU2_L1_PDN,
> > +	SPM_CA7_CPU3_L1_PDN,
> > +};
> > +
> > +#define SPM_REGWR_EN		BIT(0)
> > +#define SPM_PROJECT_CODE	0x0B16
> > +
> > +int spm_cpu_mtcmos_on(int cpu)
> > +{
> > +	unsigned long flags;
> > +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> > +	unsigned int temp;
> > +	int timeout = 10;
> > +	int ret = -ENOSYS;
> > +
> > +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> > +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> > +
> > +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> > +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> > +
> > +	spin_lock_irqsave(&spm_cpu_lock, flags);
> > +
> > +	/* Set PWR_ON */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ON;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Wait for charging core power */
> > +	udelay(1);
> > +
> > +	/* Set PWR_ON_2ND */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ON_2ND;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Wait for the power-ack */
> > +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> > +		(1U << (13 - cpu))) != (1U << (13 - cpu))) ||
> > +		((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> > +		(1U << (13 - cpu))) != (1U << (13 - cpu)))) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* L1 power on */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> > +	temp &= ~L1_PDN;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> > +	timeout = 10;
> > +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> > +		L1_PDN_ACK) != 0) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	/* Wait for memory power ready */
> > +	udelay(1);
> > +
> > +	/* Set SRAM_ISOINT_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= SRAM_ISOINT_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear SRAM_CKISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~SRAM_CKISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_CLK_DIS */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_CLK_DIS;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set PWR_RST_B to finish power on and reset sequences */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_RST_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	ret = 0;
> > +fail:
> > +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> > +
> > +	return ret;
> > +}
> > +
> > +int spm_cpu_mtcmos_off(int cpu, bool wfi)
> > +{
> > +	unsigned long flags;
> > +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> > +	unsigned int temp;
> > +	int timeout = 10;
> > +	int ret = -ENOSYS;
> > +
> > +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> > +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> > +
> > +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> > +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> > +
> > +	if (wfi) {
> > +		while ((readl_relaxed(spm_cpu_base + SPM_SLEEP_TIMER_STA) &
> > +			(1U << (16 + cpu))) == 0) {
> > +			if (--timeout == 0)
> > +				return ret;
> > +			udelay(1);
> > +		}
> > +	}
> > +
> > +	spin_lock_irqsave(&spm_cpu_lock, flags);
> > +
> > +	/* Set PWR_ISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set SRAM_CKISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= SRAM_CKISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear SRAM_ISOINT_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~SRAM_ISOINT_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* L1 power off */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> > +	temp |= L1_PDN;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> > +	timeout = 10;
> > +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> > +		L1_PDN_ACK) != L1_PDN_ACK) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	/* Clear PWR_RST_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_RST_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set PWR_CLK_DIS */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_CLK_DIS;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_ON */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ON;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_ON_2ND */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ON_2ND;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	timeout = 10;
> > +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> > +		(1U << (13 - cpu))) != 0) ||
> > +	       ((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> > +		(1U << (13 - cpu))) != 0)) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	ret = 0;
> > +fail:
> > +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> > +
> > +	return ret;
> > +}
> > +
> > +int spm_cpu_mtcmos_init(void)
> > +{
> > +	struct device_node *node;
> > +
> > +	node = of_find_compatible_node(NULL, NULL, "mediatek,mt6580-scpsys");
> 
> This looks pretty much as if it should go in 
> drivers/soc/mediatek/mtk-scpsys.c
> 
> AFAIR Sascha already mentioned that in v1.
> Why do you want/need to implement this mach-mediatek?
> 
> Thanks,
> Matthias


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

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

* [PATCH v2 2/6] soc: Mediatek: Add SCPSYS CPU power domain driver
@ 2015-07-18  2:23         ` Scott Shu
  0 siblings, 0 replies; 30+ messages in thread
From: Scott Shu @ 2015-07-18  2:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Matthias,
Sascha hopes we can put CPU MTCMOS driver to his mtk-scpsys.c. We
understood but please let us describe our opinion.
(1) The code to initial CPU for SMP operation is in very early stage
during bring-up, the mtk-scpsys.c is not ready at the moment.

(2) The CPU MTCMOS driver may chip dependent, it?s more simple and easy
maintenance for us. 

(3) There are some precedents that locate the CPU power control under
arch/arm/mach-xxxx folder.

Please let us have more discussion about this.
Thanks a lot.
Scott

On Fri, 2015-07-10 at 16:31 +0200, Matthias Brugger wrote:
> On Friday, July 10, 2015 02:04:05 PM Scott Shu wrote:
> > This adds a CPU power domain driver for the Mediatek SCPSYS unit on
> > MT6580.
> > 
> > Signed-off-by: Scott Shu <scott.shu@mediatek.com>
> > ---
> >  arch/arm/mach-mediatek/Makefile  |   2 +-
> >  arch/arm/mach-mediatek/generic.h |  23 ++++
> >  arch/arm/mach-mediatek/hotplug.c | 267
> > +++++++++++++++++++++++++++++++++++++++ 3 files changed, 291 insertions(+),
> > 1 deletion(-)
> >  create mode 100644 arch/arm/mach-mediatek/generic.h
> >  create mode 100644 arch/arm/mach-mediatek/hotplug.c
> > 
> > diff --git a/arch/arm/mach-mediatek/Makefile
> > b/arch/arm/mach-mediatek/Makefile index 2116460..b2e4ef5 100644
> > --- a/arch/arm/mach-mediatek/Makefile
> > +++ b/arch/arm/mach-mediatek/Makefile
> > @@ -1,4 +1,4 @@
> >  ifeq ($(CONFIG_SMP),y)
> > -obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
> > +obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o hotplug.o
> >  endif
> >  obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
> > diff --git a/arch/arm/mach-mediatek/generic.h
> > b/arch/arm/mach-mediatek/generic.h new file mode 100644
> > index 0000000..376f183
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/generic.h
> > @@ -0,0 +1,23 @@
> > +/*
> > + * Copyright (c) 2015 Mediatek Inc.
> > + * Author: Scott Shu <scott.shu@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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.
> > + */
> > +#ifndef __MACH_GENERIC_H
> > +#define __MACH_GENERIC_H
> > +
> > +#include <linux/kernel.h>
> > +
> > +int spm_cpu_mtcmos_init(void);
> > +int spm_cpu_mtcmos_on(int cpu);
> > +int spm_cpu_mtcmos_off(int cpu, bool wfi);
> > +
> > +#endif
> > diff --git a/arch/arm/mach-mediatek/hotplug.c
> > b/arch/arm/mach-mediatek/hotplug.c new file mode 100644
> > index 0000000..bd97f2e
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/hotplug.c
> > @@ -0,0 +1,267 @@
> > +/*
> > + * Copyright (c) 2015 Mediatek Inc.
> > + * Author: Scott Shu <scott.shu@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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/init.h>
> > +#include <linux/module.h>
> > +#include <linux/kernel.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/delay.h>
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_address.h>
> > +
> > +/* SCPSYS registers */
> > +#define SPM_POWERON_CONFIG_SET		0x0000
> > +
> > +#define SPM_CA7_CPU0_PWR_CON		0x0200
> > +#define SPM_CA7_CPU1_PWR_CON		0x0218
> > +#define SPM_CA7_CPU2_PWR_CON		0x021c
> > +#define SPM_CA7_CPU3_PWR_CON		0x0220
> > +
> > +#define SPM_CA7_CPU0_L1_PDN		0x025c
> > +#define SPM_CA7_CPU1_L1_PDN		0x0264
> > +#define SPM_CA7_CPU2_L1_PDN		0x026c
> > +#define SPM_CA7_CPU3_L1_PDN		0x0274
> > +
> > +#define SPM_PWR_STATUS			0x060c
> > +#define SPM_PWR_STATUS_2ND		0x0610
> > +#define SPM_SLEEP_TIMER_STA		0x0720
> > +
> > +/* bit definition in SPM_CA7_CPUx_PWR_CON */
> > +#define SRAM_ISOINT_B		BIT(6)
> > +#define SRAM_CKISO		BIT(5)
> > +#define PWR_CLK_DIS		BIT(4)
> > +#define PWR_ON_2ND		BIT(3)
> > +#define PWR_ON			BIT(2)
> > +#define PWR_ISO			BIT(1)
> > +#define PWR_RST_B		BIT(0)
> > +
> > +/* bit definition in SPM_CA7_CPUx_L1_PDN */
> > +#define L1_PDN_ACK		BIT(8)
> > +#define L1_PDN			BIT(0)
> > +
> > +#define MT6580_MAX_CPUS		4
> > +
> > +static DEFINE_SPINLOCK(spm_cpu_lock);
> > +
> > +void __iomem *spm_cpu_base;
> > +
> > +u32 spm_cpu_pwr_con[MT6580_MAX_CPUS] = {
> > +	SPM_CA7_CPU0_PWR_CON,
> > +	SPM_CA7_CPU1_PWR_CON,
> > +	SPM_CA7_CPU2_PWR_CON,
> > +	SPM_CA7_CPU3_PWR_CON,
> > +};
> > +
> > +u32 spm_cpu_l1_pdn[MT6580_MAX_CPUS] = {
> > +	SPM_CA7_CPU0_L1_PDN,
> > +	SPM_CA7_CPU1_L1_PDN,
> > +	SPM_CA7_CPU2_L1_PDN,
> > +	SPM_CA7_CPU3_L1_PDN,
> > +};
> > +
> > +#define SPM_REGWR_EN		BIT(0)
> > +#define SPM_PROJECT_CODE	0x0B16
> > +
> > +int spm_cpu_mtcmos_on(int cpu)
> > +{
> > +	unsigned long flags;
> > +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> > +	unsigned int temp;
> > +	int timeout = 10;
> > +	int ret = -ENOSYS;
> > +
> > +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> > +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> > +
> > +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> > +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> > +
> > +	spin_lock_irqsave(&spm_cpu_lock, flags);
> > +
> > +	/* Set PWR_ON */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ON;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Wait for charging core power */
> > +	udelay(1);
> > +
> > +	/* Set PWR_ON_2ND */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ON_2ND;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Wait for the power-ack */
> > +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> > +		(1U << (13 - cpu))) != (1U << (13 - cpu))) ||
> > +		((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> > +		(1U << (13 - cpu))) != (1U << (13 - cpu)))) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* L1 power on */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> > +	temp &= ~L1_PDN;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> > +	timeout = 10;
> > +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> > +		L1_PDN_ACK) != 0) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	/* Wait for memory power ready */
> > +	udelay(1);
> > +
> > +	/* Set SRAM_ISOINT_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= SRAM_ISOINT_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear SRAM_CKISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~SRAM_CKISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_CLK_DIS */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_CLK_DIS;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set PWR_RST_B to finish power on and reset sequences */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_RST_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	ret = 0;
> > +fail:
> > +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> > +
> > +	return ret;
> > +}
> > +
> > +int spm_cpu_mtcmos_off(int cpu, bool wfi)
> > +{
> > +	unsigned long flags;
> > +	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
> > +	unsigned int temp;
> > +	int timeout = 10;
> > +	int ret = -ENOSYS;
> > +
> > +	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
> > +	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
> > +
> > +	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
> > +	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
> > +
> > +	if (wfi) {
> > +		while ((readl_relaxed(spm_cpu_base + SPM_SLEEP_TIMER_STA) &
> > +			(1U << (16 + cpu))) == 0) {
> > +			if (--timeout == 0)
> > +				return ret;
> > +			udelay(1);
> > +		}
> > +	}
> > +
> > +	spin_lock_irqsave(&spm_cpu_lock, flags);
> > +
> > +	/* Set PWR_ISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_ISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set SRAM_CKISO */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= SRAM_CKISO;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear SRAM_ISOINT_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~SRAM_ISOINT_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* L1 power off */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
> > +	temp |= L1_PDN;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
> > +	timeout = 10;
> > +	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
> > +		L1_PDN_ACK) != L1_PDN_ACK) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	/* Clear PWR_RST_B */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_RST_B;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Set PWR_CLK_DIS */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp |= PWR_CLK_DIS;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_ON */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ON;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	/* Clear PWR_ON_2ND */
> > +	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
> > +	temp &= ~PWR_ON_2ND;
> > +	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
> > +
> > +	timeout = 10;
> > +	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
> > +		(1U << (13 - cpu))) != 0) ||
> > +	       ((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
> > +		(1U << (13 - cpu))) != 0)) {
> > +		if (--timeout == 0)
> > +			goto fail;
> > +		udelay(1);
> > +	}
> > +
> > +	ret = 0;
> > +fail:
> > +	spin_unlock_irqrestore(&spm_cpu_lock, flags);
> > +
> > +	return ret;
> > +}
> > +
> > +int spm_cpu_mtcmos_init(void)
> > +{
> > +	struct device_node *node;
> > +
> > +	node = of_find_compatible_node(NULL, NULL, "mediatek,mt6580-scpsys");
> 
> This looks pretty much as if it should go in 
> drivers/soc/mediatek/mtk-scpsys.c
> 
> AFAIR Sascha already mentioned that in v1.
> Why do you want/need to implement this mach-mediatek?
> 
> Thanks,
> Matthias

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

end of thread, other threads:[~2015-07-18  2:23 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <Scott Shu <scott.shu@gmail.com>
2015-07-10  6:04 ` [PATCH v2 0/6] This series adds SMP support for the MediaTek MT6580 Scott Shu
2015-07-10  6:04   ` Scott Shu
2015-07-10  6:04   ` Scott Shu
2015-07-10  6:04   ` [PATCH v2 1/6] Document: bindings: DT: Add SMP enable method for MT6580 SoC platform Scott Shu
2015-07-10  6:04     ` Scott Shu
2015-07-10  6:04     ` Scott Shu
2015-07-10  6:04   ` [PATCH v2 2/6] soc: Mediatek: Add SCPSYS CPU power domain driver Scott Shu
2015-07-10  6:04     ` Scott Shu
2015-07-10  6:04     ` Scott Shu
2015-07-10 14:31     ` Matthias Brugger
2015-07-10 14:31       ` Matthias Brugger
2015-07-10 14:31       ` Matthias Brugger
2015-07-13  4:18       ` Scott Shu
2015-07-13  4:18         ` Scott Shu
2015-07-13  4:18         ` Scott Shu
2015-07-18  2:23       ` Scott Shu
2015-07-18  2:23         ` Scott Shu
2015-07-18  2:23         ` Scott Shu
2015-07-10  6:04   ` [PATCH v2 3/6] ARM: mediatek: add smp bringup code for MT6580 Scott Shu
2015-07-10  6:04     ` Scott Shu
2015-07-10  6:04     ` Scott Shu
2015-07-10  6:04   ` [PATCH v2 4/6] ARM: Mediatek: enable GPT6 on boot up to make arch timer working " Scott Shu
2015-07-10  6:04     ` Scott Shu
2015-07-10  6:04     ` Scott Shu
2015-07-10  6:04   ` [PATCH v2 5/6] ARM: dts: mt6580: Add device nodes to the MT6580 dtsi file Scott Shu
2015-07-10  6:04     ` Scott Shu
2015-07-10  6:04     ` Scott Shu
2015-07-10  6:04   ` [PATCH v2 6/6] ARM: dts: mt6580: enable basic SMP bringup for MT6580 Scott Shu
2015-07-10  6:04     ` Scott Shu
2015-07-10  6:04     ` Scott Shu

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.