Re: [PATCH 1/4] ARM: sun9i: Support SMP on A80 with Multi-Cluster Power Management (MCPM)

2017-07-25 Thread Chen-Yu Tsai
On Tue, Jul 25, 2017 at 10:40 PM, Maxime Ripard
 wrote:
> On Tue, Jul 25, 2017 at 04:29:52PM +0800, Chen-Yu Tsai wrote:
>>  default ARCH_SUNXI
>> On Tue, Jul 25, 2017 at 3:47 PM, Maxime Ripard
>>  wrote:
>> > Hi Chen-Yu,
>> >
>> > On Tue, Jul 25, 2017 at 01:09:16PM +0800, Chen-Yu Tsai wrote:
>> >> The A80 is a big.LITTLE SoC with 1 cluster of 4 Cortex-A7s and
>> >> 1 cluster of 4 Cortex-A15s.
>> >>
>> >> This patch adds support to bring up the second cluster and thus all
>> >> cores using the common MCPM code. Core/cluster power down has not
>> >> been implemented, thus CPU hotplugging and big.LITTLE switcher is
>> >> not supported.
>> >>
>> >> Signed-off-by: Chen-Yu Tsai 
>> >> ---
>> >>  arch/arm/mach-sunxi/Kconfig  |  10 ++
>> >>  arch/arm/mach-sunxi/Makefile |   1 +
>> >>  arch/arm/mach-sunxi/mcpm.c   | 391 
>> >> +++
>> >>  3 files changed, 402 insertions(+)
>> >>  create mode 100644 arch/arm/mach-sunxi/mcpm.c
>> >>
>> >> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
>> >> index 58153cdf025b..177380548d99 100644
>> >> --- a/arch/arm/mach-sunxi/Kconfig
>> >> +++ b/arch/arm/mach-sunxi/Kconfig
>> >> @@ -47,5 +47,15 @@ config MACH_SUN9I
>> >>   bool "Allwinner (sun9i) SoCs support"
>> >>   default ARCH_SUNXI
>> >>   select ARM_GIC
>> >> + imply MCPM
>> >> +
>> >> +config SUN9I_A80_MCPM
>> >> + bool "Allwinner A80 Multi-Cluster PM support"
>> >> + depends on MCPM && MACH_SUN9I
>> >> + default MACH_SUN9I
>> >> + select ARM_CCI400_PORT_CTRL
>> >> + help
>> >> +   This is needed to provide CPU and cluster power management
>> >> +   on Allwinner A80 implementing big.LITTLE.
>> >
>> > Do we really need an option for that? we don't provide the option to
>> > disable the CPU SMP operations for the rest of the SoCs.
>>
>> It was an option as it also required MCPM and CCI400 support to be built.
>> We could hide it. Or, using mach-hisi as a reference, we could do:
>>
>> config MACH_SUN9I
>> default ARCH_SUNXI
>> select ARM_GIC
>> select MCPM if SMP
>> select ARM_CCI400_PORT_CTRL if SMP
>>
>> and in the Makefile:
>>
>> obj-$(CONFIG_MCPM) += sun9i-mcpm.o
>
> I guess a hidden option would work for me.

I kind of prefer mach-hisi's solution though.

>
>> >> +#define SUNXI_CPUS_PER_CLUSTER   4
>> >> +#define SUNXI_NR_CLUSTERS2
>> >> +
>> >> +#define SUN9I_A80_A15_CLUSTER1
>> >
>> > Don't we have a way to derive that from the DT ?
>>
>> Indeed we can.
>>
>> It would be slighty more complicated though:
>>
>> node = of_cpu_device_node_get(cluster * SUNXI_CPUS_PER_CLUSTER + cpu);
>> if (of_device_is_compatible(node, "arm,cortex-a15")) {
>> ...
>> }
>
> There's no helper to create that map?

Are you referring to the topology map? That one only stores topology,
not what type of cores they are. The CPU capacity part doesn't either.
It only stores the results.

> We'll use it for A83T too, so the complexity will be reduced anyway.

I'll just put it in a helper function.

[...]

>> >
>> > It looks mostly good, and I would replace the sunxi by sun9i, and call
>> > that file sun9i-mcpm.c
>>
>> I was hoping to reuse the file for the A83T, so it was sunxi-mcpm.c
>> or just mcpm. Most of the stuff is similiar, except the A83T has two
>> revisions and one of them has two gate/power bits swapped. :(
>
> Hmmm, that's true.
>
> What about just mcpm then?

Works for me. I don't need to change anything. :)

ChenYu


Re: [PATCH 1/4] ARM: sun9i: Support SMP on A80 with Multi-Cluster Power Management (MCPM)

2017-07-25 Thread Chen-Yu Tsai
On Tue, Jul 25, 2017 at 10:40 PM, Maxime Ripard
 wrote:
> On Tue, Jul 25, 2017 at 04:29:52PM +0800, Chen-Yu Tsai wrote:
>>  default ARCH_SUNXI
>> On Tue, Jul 25, 2017 at 3:47 PM, Maxime Ripard
>>  wrote:
>> > Hi Chen-Yu,
>> >
>> > On Tue, Jul 25, 2017 at 01:09:16PM +0800, Chen-Yu Tsai wrote:
>> >> The A80 is a big.LITTLE SoC with 1 cluster of 4 Cortex-A7s and
>> >> 1 cluster of 4 Cortex-A15s.
>> >>
>> >> This patch adds support to bring up the second cluster and thus all
>> >> cores using the common MCPM code. Core/cluster power down has not
>> >> been implemented, thus CPU hotplugging and big.LITTLE switcher is
>> >> not supported.
>> >>
>> >> Signed-off-by: Chen-Yu Tsai 
>> >> ---
>> >>  arch/arm/mach-sunxi/Kconfig  |  10 ++
>> >>  arch/arm/mach-sunxi/Makefile |   1 +
>> >>  arch/arm/mach-sunxi/mcpm.c   | 391 
>> >> +++
>> >>  3 files changed, 402 insertions(+)
>> >>  create mode 100644 arch/arm/mach-sunxi/mcpm.c
>> >>
>> >> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
>> >> index 58153cdf025b..177380548d99 100644
>> >> --- a/arch/arm/mach-sunxi/Kconfig
>> >> +++ b/arch/arm/mach-sunxi/Kconfig
>> >> @@ -47,5 +47,15 @@ config MACH_SUN9I
>> >>   bool "Allwinner (sun9i) SoCs support"
>> >>   default ARCH_SUNXI
>> >>   select ARM_GIC
>> >> + imply MCPM
>> >> +
>> >> +config SUN9I_A80_MCPM
>> >> + bool "Allwinner A80 Multi-Cluster PM support"
>> >> + depends on MCPM && MACH_SUN9I
>> >> + default MACH_SUN9I
>> >> + select ARM_CCI400_PORT_CTRL
>> >> + help
>> >> +   This is needed to provide CPU and cluster power management
>> >> +   on Allwinner A80 implementing big.LITTLE.
>> >
>> > Do we really need an option for that? we don't provide the option to
>> > disable the CPU SMP operations for the rest of the SoCs.
>>
>> It was an option as it also required MCPM and CCI400 support to be built.
>> We could hide it. Or, using mach-hisi as a reference, we could do:
>>
>> config MACH_SUN9I
>> default ARCH_SUNXI
>> select ARM_GIC
>> select MCPM if SMP
>> select ARM_CCI400_PORT_CTRL if SMP
>>
>> and in the Makefile:
>>
>> obj-$(CONFIG_MCPM) += sun9i-mcpm.o
>
> I guess a hidden option would work for me.

I kind of prefer mach-hisi's solution though.

>
>> >> +#define SUNXI_CPUS_PER_CLUSTER   4
>> >> +#define SUNXI_NR_CLUSTERS2
>> >> +
>> >> +#define SUN9I_A80_A15_CLUSTER1
>> >
>> > Don't we have a way to derive that from the DT ?
>>
>> Indeed we can.
>>
>> It would be slighty more complicated though:
>>
>> node = of_cpu_device_node_get(cluster * SUNXI_CPUS_PER_CLUSTER + cpu);
>> if (of_device_is_compatible(node, "arm,cortex-a15")) {
>> ...
>> }
>
> There's no helper to create that map?

Are you referring to the topology map? That one only stores topology,
not what type of cores they are. The CPU capacity part doesn't either.
It only stores the results.

> We'll use it for A83T too, so the complexity will be reduced anyway.

I'll just put it in a helper function.

[...]

>> >
>> > It looks mostly good, and I would replace the sunxi by sun9i, and call
>> > that file sun9i-mcpm.c
>>
>> I was hoping to reuse the file for the A83T, so it was sunxi-mcpm.c
>> or just mcpm. Most of the stuff is similiar, except the A83T has two
>> revisions and one of them has two gate/power bits swapped. :(
>
> Hmmm, that's true.
>
> What about just mcpm then?

Works for me. I don't need to change anything. :)

ChenYu


Re: [PATCH 1/4] ARM: sun9i: Support SMP on A80 with Multi-Cluster Power Management (MCPM)

2017-07-25 Thread Maxime Ripard
On Tue, Jul 25, 2017 at 04:29:52PM +0800, Chen-Yu Tsai wrote:
>  default ARCH_SUNXI
> On Tue, Jul 25, 2017 at 3:47 PM, Maxime Ripard
>  wrote:
> > Hi Chen-Yu,
> >
> > On Tue, Jul 25, 2017 at 01:09:16PM +0800, Chen-Yu Tsai wrote:
> >> The A80 is a big.LITTLE SoC with 1 cluster of 4 Cortex-A7s and
> >> 1 cluster of 4 Cortex-A15s.
> >>
> >> This patch adds support to bring up the second cluster and thus all
> >> cores using the common MCPM code. Core/cluster power down has not
> >> been implemented, thus CPU hotplugging and big.LITTLE switcher is
> >> not supported.
> >>
> >> Signed-off-by: Chen-Yu Tsai 
> >> ---
> >>  arch/arm/mach-sunxi/Kconfig  |  10 ++
> >>  arch/arm/mach-sunxi/Makefile |   1 +
> >>  arch/arm/mach-sunxi/mcpm.c   | 391 
> >> +++
> >>  3 files changed, 402 insertions(+)
> >>  create mode 100644 arch/arm/mach-sunxi/mcpm.c
> >>
> >> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> >> index 58153cdf025b..177380548d99 100644
> >> --- a/arch/arm/mach-sunxi/Kconfig
> >> +++ b/arch/arm/mach-sunxi/Kconfig
> >> @@ -47,5 +47,15 @@ config MACH_SUN9I
> >>   bool "Allwinner (sun9i) SoCs support"
> >>   default ARCH_SUNXI
> >>   select ARM_GIC
> >> + imply MCPM
> >> +
> >> +config SUN9I_A80_MCPM
> >> + bool "Allwinner A80 Multi-Cluster PM support"
> >> + depends on MCPM && MACH_SUN9I
> >> + default MACH_SUN9I
> >> + select ARM_CCI400_PORT_CTRL
> >> + help
> >> +   This is needed to provide CPU and cluster power management
> >> +   on Allwinner A80 implementing big.LITTLE.
> >
> > Do we really need an option for that? we don't provide the option to
> > disable the CPU SMP operations for the rest of the SoCs.
> 
> It was an option as it also required MCPM and CCI400 support to be built.
> We could hide it. Or, using mach-hisi as a reference, we could do:
> 
> config MACH_SUN9I
> default ARCH_SUNXI
> select ARM_GIC
> select MCPM if SMP
> select ARM_CCI400_PORT_CTRL if SMP
> 
> and in the Makefile:
> 
> obj-$(CONFIG_MCPM) += sun9i-mcpm.o

I guess a hidden option would work for me.

> >> +#define SUNXI_CPUS_PER_CLUSTER   4
> >> +#define SUNXI_NR_CLUSTERS2
> >> +
> >> +#define SUN9I_A80_A15_CLUSTER1
> >
> > Don't we have a way to derive that from the DT ?
> 
> Indeed we can.
> 
> It would be slighty more complicated though:
> 
> node = of_cpu_device_node_get(cluster * SUNXI_CPUS_PER_CLUSTER + cpu);
> if (of_device_is_compatible(node, "arm,cortex-a15")) {
> ...
> }

There's no helper to create that map?

We'll use it for A83T too, so the complexity will be reduced anyway.

> >
> >> +#define CPUCFG_CX_CTRL_REG0(c)   (0x10 * (c))
> >> +#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE(n)BIT(n)
> >> +#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE_ALL   0xf
> >> +#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A7BIT(4)
> >> +#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A15   BIT(0)
> >> +#define CPUCFG_CX_CTRL_REG1(c)   (0x10 * (c) + 0x4)
> >> +#define CPUCFG_CX_CTRL_REG1_ACINACTM BIT(0)
> >> +#define CPUCFG_CX_RST_CTRL(c)(0x80 + 0x4 * (c))
> >> +#define CPUCFG_CX_RST_CTRL_DBG_SOC_RST   BIT(24)
> >> +#define CPUCFG_CX_RST_CTRL_ETM_RST(n)BIT(20 + (n))
> >> +#define CPUCFG_CX_RST_CTRL_ETM_RST_ALL   (0xf << 20)
> >> +#define CPUCFG_CX_RST_CTRL_DBG_RST(n)BIT(16 + (n))
> >> +#define CPUCFG_CX_RST_CTRL_DBG_RST_ALL   (0xf << 16)
> >> +#define CPUCFG_CX_RST_CTRL_H_RST BIT(12)
> >> +#define CPUCFG_CX_RST_CTRL_L2_RSTBIT(8)
> >> +#define CPUCFG_CX_RST_CTRL_CX_RST(n) BIT(4 + (n))
> >> +#define CPUCFG_CX_RST_CTRL_CORE_RST(n)   BIT(n)
> >> +
> >> +#define PRCM_CPU_PO_RST_CTRL(c)  (0x4 + 0x4 * (c))
> >> +#define PRCM_CPU_PO_RST_CTRL_CORE(n) BIT(n)
> >> +#define PRCM_CPU_PO_RST_CTRL_CORE_ALL0xf
> >> +#define PRCM_PWROFF_GATING_REG(c)(0x100 + 0x4 * (c))
> >> +#define PRCM_PWROFF_GATING_REG_CLUSTER   BIT(4)
> >> +#define PRCM_PWROFF_GATING_REG_CORE(n)   BIT(n)
> >> +#define PRCM_PWR_SWITCH_REG(c, cpu)  (0x140 + 0x10 * (c) + 0x4 * (cpu))
> >> +#define PRCM_CPU_SOFT_ENTRY_REG  0x164
> >> +
> >> +static void __iomem *cpucfg_base;
> >> +static void __iomem *prcm_base;
> >> +
> >> +static int sunxi_cpu_power_switch_set(unsigned int cpu, unsigned int 
> >> cluster,
> >> +   bool enable)
> >> +{
> >> + u32 reg;
> >> +
> >> + /* control sequence from Allwinner A80 user manual v1.2 PRCM section 
> >> */
> >> + reg = readl(prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
> >> + if (enable) {
> >> + if (reg == 0x00) {
> >> + pr_debug("power clamp for cluster %u cpu %u already 
> >> open\n",
> >> +  cluster, cpu);
> >> + return 0;
> >> + }

Re: [PATCH 1/4] ARM: sun9i: Support SMP on A80 with Multi-Cluster Power Management (MCPM)

2017-07-25 Thread Maxime Ripard
On Tue, Jul 25, 2017 at 04:29:52PM +0800, Chen-Yu Tsai wrote:
>  default ARCH_SUNXI
> On Tue, Jul 25, 2017 at 3:47 PM, Maxime Ripard
>  wrote:
> > Hi Chen-Yu,
> >
> > On Tue, Jul 25, 2017 at 01:09:16PM +0800, Chen-Yu Tsai wrote:
> >> The A80 is a big.LITTLE SoC with 1 cluster of 4 Cortex-A7s and
> >> 1 cluster of 4 Cortex-A15s.
> >>
> >> This patch adds support to bring up the second cluster and thus all
> >> cores using the common MCPM code. Core/cluster power down has not
> >> been implemented, thus CPU hotplugging and big.LITTLE switcher is
> >> not supported.
> >>
> >> Signed-off-by: Chen-Yu Tsai 
> >> ---
> >>  arch/arm/mach-sunxi/Kconfig  |  10 ++
> >>  arch/arm/mach-sunxi/Makefile |   1 +
> >>  arch/arm/mach-sunxi/mcpm.c   | 391 
> >> +++
> >>  3 files changed, 402 insertions(+)
> >>  create mode 100644 arch/arm/mach-sunxi/mcpm.c
> >>
> >> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> >> index 58153cdf025b..177380548d99 100644
> >> --- a/arch/arm/mach-sunxi/Kconfig
> >> +++ b/arch/arm/mach-sunxi/Kconfig
> >> @@ -47,5 +47,15 @@ config MACH_SUN9I
> >>   bool "Allwinner (sun9i) SoCs support"
> >>   default ARCH_SUNXI
> >>   select ARM_GIC
> >> + imply MCPM
> >> +
> >> +config SUN9I_A80_MCPM
> >> + bool "Allwinner A80 Multi-Cluster PM support"
> >> + depends on MCPM && MACH_SUN9I
> >> + default MACH_SUN9I
> >> + select ARM_CCI400_PORT_CTRL
> >> + help
> >> +   This is needed to provide CPU and cluster power management
> >> +   on Allwinner A80 implementing big.LITTLE.
> >
> > Do we really need an option for that? we don't provide the option to
> > disable the CPU SMP operations for the rest of the SoCs.
> 
> It was an option as it also required MCPM and CCI400 support to be built.
> We could hide it. Or, using mach-hisi as a reference, we could do:
> 
> config MACH_SUN9I
> default ARCH_SUNXI
> select ARM_GIC
> select MCPM if SMP
> select ARM_CCI400_PORT_CTRL if SMP
> 
> and in the Makefile:
> 
> obj-$(CONFIG_MCPM) += sun9i-mcpm.o

I guess a hidden option would work for me.

> >> +#define SUNXI_CPUS_PER_CLUSTER   4
> >> +#define SUNXI_NR_CLUSTERS2
> >> +
> >> +#define SUN9I_A80_A15_CLUSTER1
> >
> > Don't we have a way to derive that from the DT ?
> 
> Indeed we can.
> 
> It would be slighty more complicated though:
> 
> node = of_cpu_device_node_get(cluster * SUNXI_CPUS_PER_CLUSTER + cpu);
> if (of_device_is_compatible(node, "arm,cortex-a15")) {
> ...
> }

There's no helper to create that map?

We'll use it for A83T too, so the complexity will be reduced anyway.

> >
> >> +#define CPUCFG_CX_CTRL_REG0(c)   (0x10 * (c))
> >> +#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE(n)BIT(n)
> >> +#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE_ALL   0xf
> >> +#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A7BIT(4)
> >> +#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A15   BIT(0)
> >> +#define CPUCFG_CX_CTRL_REG1(c)   (0x10 * (c) + 0x4)
> >> +#define CPUCFG_CX_CTRL_REG1_ACINACTM BIT(0)
> >> +#define CPUCFG_CX_RST_CTRL(c)(0x80 + 0x4 * (c))
> >> +#define CPUCFG_CX_RST_CTRL_DBG_SOC_RST   BIT(24)
> >> +#define CPUCFG_CX_RST_CTRL_ETM_RST(n)BIT(20 + (n))
> >> +#define CPUCFG_CX_RST_CTRL_ETM_RST_ALL   (0xf << 20)
> >> +#define CPUCFG_CX_RST_CTRL_DBG_RST(n)BIT(16 + (n))
> >> +#define CPUCFG_CX_RST_CTRL_DBG_RST_ALL   (0xf << 16)
> >> +#define CPUCFG_CX_RST_CTRL_H_RST BIT(12)
> >> +#define CPUCFG_CX_RST_CTRL_L2_RSTBIT(8)
> >> +#define CPUCFG_CX_RST_CTRL_CX_RST(n) BIT(4 + (n))
> >> +#define CPUCFG_CX_RST_CTRL_CORE_RST(n)   BIT(n)
> >> +
> >> +#define PRCM_CPU_PO_RST_CTRL(c)  (0x4 + 0x4 * (c))
> >> +#define PRCM_CPU_PO_RST_CTRL_CORE(n) BIT(n)
> >> +#define PRCM_CPU_PO_RST_CTRL_CORE_ALL0xf
> >> +#define PRCM_PWROFF_GATING_REG(c)(0x100 + 0x4 * (c))
> >> +#define PRCM_PWROFF_GATING_REG_CLUSTER   BIT(4)
> >> +#define PRCM_PWROFF_GATING_REG_CORE(n)   BIT(n)
> >> +#define PRCM_PWR_SWITCH_REG(c, cpu)  (0x140 + 0x10 * (c) + 0x4 * (cpu))
> >> +#define PRCM_CPU_SOFT_ENTRY_REG  0x164
> >> +
> >> +static void __iomem *cpucfg_base;
> >> +static void __iomem *prcm_base;
> >> +
> >> +static int sunxi_cpu_power_switch_set(unsigned int cpu, unsigned int 
> >> cluster,
> >> +   bool enable)
> >> +{
> >> + u32 reg;
> >> +
> >> + /* control sequence from Allwinner A80 user manual v1.2 PRCM section 
> >> */
> >> + reg = readl(prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
> >> + if (enable) {
> >> + if (reg == 0x00) {
> >> + pr_debug("power clamp for cluster %u cpu %u already 
> >> open\n",
> >> +  cluster, cpu);
> >> + return 0;
> >> + }
> >> +
> >> + writel(0xff, prcm_base 

Re: [PATCH 1/4] ARM: sun9i: Support SMP on A80 with Multi-Cluster Power Management (MCPM)

2017-07-25 Thread icenowy

在 2017-07-25 16:29,Chen-Yu Tsai 写道:

default ARCH_SUNXI
On Tue, Jul 25, 2017 at 3:47 PM, Maxime Ripard
 wrote:

Hi Chen-Yu,

On Tue, Jul 25, 2017 at 01:09:16PM +0800, Chen-Yu Tsai wrote:

The A80 is a big.LITTLE SoC with 1 cluster of 4 Cortex-A7s and
1 cluster of 4 Cortex-A15s.

This patch adds support to bring up the second cluster and thus all
cores using the common MCPM code. Core/cluster power down has not
been implemented, thus CPU hotplugging and big.LITTLE switcher is
not supported.

Signed-off-by: Chen-Yu Tsai 
---
 arch/arm/mach-sunxi/Kconfig  |  10 ++
 arch/arm/mach-sunxi/Makefile |   1 +
 arch/arm/mach-sunxi/mcpm.c   | 391 
+++

 3 files changed, 402 insertions(+)
 create mode 100644 arch/arm/mach-sunxi/mcpm.c

diff --git a/arch/arm/mach-sunxi/Kconfig 
b/arch/arm/mach-sunxi/Kconfig

index 58153cdf025b..177380548d99 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -47,5 +47,15 @@ config MACH_SUN9I
  bool "Allwinner (sun9i) SoCs support"
  default ARCH_SUNXI
  select ARM_GIC
+ imply MCPM
+
+config SUN9I_A80_MCPM
+ bool "Allwinner A80 Multi-Cluster PM support"
+ depends on MCPM && MACH_SUN9I
+ default MACH_SUN9I
+ select ARM_CCI400_PORT_CTRL
+ help
+   This is needed to provide CPU and cluster power management
+   on Allwinner A80 implementing big.LITTLE.


Do we really need an option for that? we don't provide the option to
disable the CPU SMP operations for the rest of the SoCs.


It was an option as it also required MCPM and CCI400 support to be 
built.

We could hide it. Or, using mach-hisi as a reference, we could do:


I think a hidden config option is a proper way, as we can then select
this config option in MACH_SUN8I when introducing A83T support.



config MACH_SUN9I
default ARCH_SUNXI
select ARM_GIC
select MCPM if SMP
select ARM_CCI400_PORT_CTRL if SMP

and in the Makefile:

obj-$(CONFIG_MCPM) += sun9i-mcpm.o




 endif
diff --git a/arch/arm/mach-sunxi/Makefile 
b/arch/arm/mach-sunxi/Makefile

index 27b168f121a1..e8558912c714 100644
--- a/arch/arm/mach-sunxi/Makefile
+++ b/arch/arm/mach-sunxi/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
 obj-$(CONFIG_SMP) += platsmp.o
+obj-$(CONFIG_SUN9I_A80_MCPM) += mcpm.o
diff --git a/arch/arm/mach-sunxi/mcpm.c b/arch/arm/mach-sunxi/mcpm.c
new file mode 100644
index ..4b6e1d6ae379
--- /dev/null
+++ b/arch/arm/mach-sunxi/mcpm.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2015 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai 
+ *
+ * arch/arm/mach-sunxi/mcpm.c
+ *
+ * Based on arch/arm/mach-exynos/mcpm-exynos.c and Allwinner code
+ *
+ * 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.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define SUNXI_CPUS_PER_CLUSTER   4
+#define SUNXI_NR_CLUSTERS2
+
+#define SUN9I_A80_A15_CLUSTER1


Don't we have a way to derive that from the DT ?


Indeed we can.

It would be slighty more complicated though:

node = of_cpu_device_node_get(cluster * SUNXI_CPUS_PER_CLUSTER + cpu);
if (of_device_is_compatible(node, "arm,cortex-a15")) {
...
}




+#define CPUCFG_CX_CTRL_REG0(c)   (0x10 * (c))
+#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE(n)BIT(n)
+#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE_ALL   0xf
+#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A7BIT(4)
+#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A15   BIT(0)
+#define CPUCFG_CX_CTRL_REG1(c)   (0x10 * (c) + 0x4)
+#define CPUCFG_CX_CTRL_REG1_ACINACTM BIT(0)
+#define CPUCFG_CX_RST_CTRL(c)(0x80 + 0x4 * (c))
+#define CPUCFG_CX_RST_CTRL_DBG_SOC_RST   BIT(24)
+#define CPUCFG_CX_RST_CTRL_ETM_RST(n)BIT(20 + (n))
+#define CPUCFG_CX_RST_CTRL_ETM_RST_ALL   (0xf << 20)
+#define CPUCFG_CX_RST_CTRL_DBG_RST(n)BIT(16 + (n))
+#define CPUCFG_CX_RST_CTRL_DBG_RST_ALL   (0xf << 16)
+#define CPUCFG_CX_RST_CTRL_H_RST BIT(12)
+#define CPUCFG_CX_RST_CTRL_L2_RSTBIT(8)
+#define CPUCFG_CX_RST_CTRL_CX_RST(n) BIT(4 + (n))
+#define CPUCFG_CX_RST_CTRL_CORE_RST(n)   BIT(n)
+
+#define PRCM_CPU_PO_RST_CTRL(c)  (0x4 + 0x4 * (c))
+#define PRCM_CPU_PO_RST_CTRL_CORE(n) BIT(n)
+#define PRCM_CPU_PO_RST_CTRL_CORE_ALL0xf
+#define PRCM_PWROFF_GATING_REG(c)(0x100 + 0x4 * (c))
+#define PRCM_PWROFF_GATING_REG_CLUSTER   BIT(4)
+#define PRCM_PWROFF_GATING_REG_CORE(n)   BIT(n)
+#define PRCM_PWR_SWITCH_REG(c, cpu)  (0x140 + 0x10 * (c) + 0x4 * 
(cpu))

+#define PRCM_CPU_SOFT_ENTRY_REG  0x164
+
+static void __iomem *cpucfg_base;
+static void __iomem *prcm_base;
+
+static int sunxi_cpu_power_switch_set(unsigned int cpu, unsigned int 
cluster,

+ 

Re: [PATCH 1/4] ARM: sun9i: Support SMP on A80 with Multi-Cluster Power Management (MCPM)

2017-07-25 Thread icenowy

在 2017-07-25 16:29,Chen-Yu Tsai 写道:

default ARCH_SUNXI
On Tue, Jul 25, 2017 at 3:47 PM, Maxime Ripard
 wrote:

Hi Chen-Yu,

On Tue, Jul 25, 2017 at 01:09:16PM +0800, Chen-Yu Tsai wrote:

The A80 is a big.LITTLE SoC with 1 cluster of 4 Cortex-A7s and
1 cluster of 4 Cortex-A15s.

This patch adds support to bring up the second cluster and thus all
cores using the common MCPM code. Core/cluster power down has not
been implemented, thus CPU hotplugging and big.LITTLE switcher is
not supported.

Signed-off-by: Chen-Yu Tsai 
---
 arch/arm/mach-sunxi/Kconfig  |  10 ++
 arch/arm/mach-sunxi/Makefile |   1 +
 arch/arm/mach-sunxi/mcpm.c   | 391 
+++

 3 files changed, 402 insertions(+)
 create mode 100644 arch/arm/mach-sunxi/mcpm.c

diff --git a/arch/arm/mach-sunxi/Kconfig 
b/arch/arm/mach-sunxi/Kconfig

index 58153cdf025b..177380548d99 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -47,5 +47,15 @@ config MACH_SUN9I
  bool "Allwinner (sun9i) SoCs support"
  default ARCH_SUNXI
  select ARM_GIC
+ imply MCPM
+
+config SUN9I_A80_MCPM
+ bool "Allwinner A80 Multi-Cluster PM support"
+ depends on MCPM && MACH_SUN9I
+ default MACH_SUN9I
+ select ARM_CCI400_PORT_CTRL
+ help
+   This is needed to provide CPU and cluster power management
+   on Allwinner A80 implementing big.LITTLE.


Do we really need an option for that? we don't provide the option to
disable the CPU SMP operations for the rest of the SoCs.


It was an option as it also required MCPM and CCI400 support to be 
built.

We could hide it. Or, using mach-hisi as a reference, we could do:


I think a hidden config option is a proper way, as we can then select
this config option in MACH_SUN8I when introducing A83T support.



config MACH_SUN9I
default ARCH_SUNXI
select ARM_GIC
select MCPM if SMP
select ARM_CCI400_PORT_CTRL if SMP

and in the Makefile:

obj-$(CONFIG_MCPM) += sun9i-mcpm.o




 endif
diff --git a/arch/arm/mach-sunxi/Makefile 
b/arch/arm/mach-sunxi/Makefile

index 27b168f121a1..e8558912c714 100644
--- a/arch/arm/mach-sunxi/Makefile
+++ b/arch/arm/mach-sunxi/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
 obj-$(CONFIG_SMP) += platsmp.o
+obj-$(CONFIG_SUN9I_A80_MCPM) += mcpm.o
diff --git a/arch/arm/mach-sunxi/mcpm.c b/arch/arm/mach-sunxi/mcpm.c
new file mode 100644
index ..4b6e1d6ae379
--- /dev/null
+++ b/arch/arm/mach-sunxi/mcpm.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2015 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai 
+ *
+ * arch/arm/mach-sunxi/mcpm.c
+ *
+ * Based on arch/arm/mach-exynos/mcpm-exynos.c and Allwinner code
+ *
+ * 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.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define SUNXI_CPUS_PER_CLUSTER   4
+#define SUNXI_NR_CLUSTERS2
+
+#define SUN9I_A80_A15_CLUSTER1


Don't we have a way to derive that from the DT ?


Indeed we can.

It would be slighty more complicated though:

node = of_cpu_device_node_get(cluster * SUNXI_CPUS_PER_CLUSTER + cpu);
if (of_device_is_compatible(node, "arm,cortex-a15")) {
...
}




+#define CPUCFG_CX_CTRL_REG0(c)   (0x10 * (c))
+#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE(n)BIT(n)
+#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE_ALL   0xf
+#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A7BIT(4)
+#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A15   BIT(0)
+#define CPUCFG_CX_CTRL_REG1(c)   (0x10 * (c) + 0x4)
+#define CPUCFG_CX_CTRL_REG1_ACINACTM BIT(0)
+#define CPUCFG_CX_RST_CTRL(c)(0x80 + 0x4 * (c))
+#define CPUCFG_CX_RST_CTRL_DBG_SOC_RST   BIT(24)
+#define CPUCFG_CX_RST_CTRL_ETM_RST(n)BIT(20 + (n))
+#define CPUCFG_CX_RST_CTRL_ETM_RST_ALL   (0xf << 20)
+#define CPUCFG_CX_RST_CTRL_DBG_RST(n)BIT(16 + (n))
+#define CPUCFG_CX_RST_CTRL_DBG_RST_ALL   (0xf << 16)
+#define CPUCFG_CX_RST_CTRL_H_RST BIT(12)
+#define CPUCFG_CX_RST_CTRL_L2_RSTBIT(8)
+#define CPUCFG_CX_RST_CTRL_CX_RST(n) BIT(4 + (n))
+#define CPUCFG_CX_RST_CTRL_CORE_RST(n)   BIT(n)
+
+#define PRCM_CPU_PO_RST_CTRL(c)  (0x4 + 0x4 * (c))
+#define PRCM_CPU_PO_RST_CTRL_CORE(n) BIT(n)
+#define PRCM_CPU_PO_RST_CTRL_CORE_ALL0xf
+#define PRCM_PWROFF_GATING_REG(c)(0x100 + 0x4 * (c))
+#define PRCM_PWROFF_GATING_REG_CLUSTER   BIT(4)
+#define PRCM_PWROFF_GATING_REG_CORE(n)   BIT(n)
+#define PRCM_PWR_SWITCH_REG(c, cpu)  (0x140 + 0x10 * (c) + 0x4 * 
(cpu))

+#define PRCM_CPU_SOFT_ENTRY_REG  0x164
+
+static void __iomem *cpucfg_base;
+static void __iomem *prcm_base;
+
+static int sunxi_cpu_power_switch_set(unsigned int cpu, unsigned int 
cluster,

+   bool enable)
+{
+ u32 reg;
+

Re: [PATCH 1/4] ARM: sun9i: Support SMP on A80 with Multi-Cluster Power Management (MCPM)

2017-07-25 Thread Chen-Yu Tsai
 default ARCH_SUNXI
On Tue, Jul 25, 2017 at 3:47 PM, Maxime Ripard
 wrote:
> Hi Chen-Yu,
>
> On Tue, Jul 25, 2017 at 01:09:16PM +0800, Chen-Yu Tsai wrote:
>> The A80 is a big.LITTLE SoC with 1 cluster of 4 Cortex-A7s and
>> 1 cluster of 4 Cortex-A15s.
>>
>> This patch adds support to bring up the second cluster and thus all
>> cores using the common MCPM code. Core/cluster power down has not
>> been implemented, thus CPU hotplugging and big.LITTLE switcher is
>> not supported.
>>
>> Signed-off-by: Chen-Yu Tsai 
>> ---
>>  arch/arm/mach-sunxi/Kconfig  |  10 ++
>>  arch/arm/mach-sunxi/Makefile |   1 +
>>  arch/arm/mach-sunxi/mcpm.c   | 391 
>> +++
>>  3 files changed, 402 insertions(+)
>>  create mode 100644 arch/arm/mach-sunxi/mcpm.c
>>
>> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
>> index 58153cdf025b..177380548d99 100644
>> --- a/arch/arm/mach-sunxi/Kconfig
>> +++ b/arch/arm/mach-sunxi/Kconfig
>> @@ -47,5 +47,15 @@ config MACH_SUN9I
>>   bool "Allwinner (sun9i) SoCs support"
>>   default ARCH_SUNXI
>>   select ARM_GIC
>> + imply MCPM
>> +
>> +config SUN9I_A80_MCPM
>> + bool "Allwinner A80 Multi-Cluster PM support"
>> + depends on MCPM && MACH_SUN9I
>> + default MACH_SUN9I
>> + select ARM_CCI400_PORT_CTRL
>> + help
>> +   This is needed to provide CPU and cluster power management
>> +   on Allwinner A80 implementing big.LITTLE.
>
> Do we really need an option for that? we don't provide the option to
> disable the CPU SMP operations for the rest of the SoCs.

It was an option as it also required MCPM and CCI400 support to be built.
We could hide it. Or, using mach-hisi as a reference, we could do:

config MACH_SUN9I
default ARCH_SUNXI
select ARM_GIC
select MCPM if SMP
select ARM_CCI400_PORT_CTRL if SMP

and in the Makefile:

obj-$(CONFIG_MCPM) += sun9i-mcpm.o

>
>>  endif
>> diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
>> index 27b168f121a1..e8558912c714 100644
>> --- a/arch/arm/mach-sunxi/Makefile
>> +++ b/arch/arm/mach-sunxi/Makefile
>> @@ -1,2 +1,3 @@
>>  obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
>>  obj-$(CONFIG_SMP) += platsmp.o
>> +obj-$(CONFIG_SUN9I_A80_MCPM) += mcpm.o
>> diff --git a/arch/arm/mach-sunxi/mcpm.c b/arch/arm/mach-sunxi/mcpm.c
>> new file mode 100644
>> index ..4b6e1d6ae379
>> --- /dev/null
>> +++ b/arch/arm/mach-sunxi/mcpm.c
>> @@ -0,0 +1,391 @@
>> +/*
>> + * Copyright (c) 2015 Chen-Yu Tsai
>> + *
>> + * Chen-Yu Tsai 
>> + *
>> + * arch/arm/mach-sunxi/mcpm.c
>> + *
>> + * Based on arch/arm/mach-exynos/mcpm-exynos.c and Allwinner code
>> + *
>> + * 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.
>> + */
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#define SUNXI_CPUS_PER_CLUSTER   4
>> +#define SUNXI_NR_CLUSTERS2
>> +
>> +#define SUN9I_A80_A15_CLUSTER1
>
> Don't we have a way to derive that from the DT ?

Indeed we can.

It would be slighty more complicated though:

node = of_cpu_device_node_get(cluster * SUNXI_CPUS_PER_CLUSTER + cpu);
if (of_device_is_compatible(node, "arm,cortex-a15")) {
...
}

>
>> +#define CPUCFG_CX_CTRL_REG0(c)   (0x10 * (c))
>> +#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE(n)BIT(n)
>> +#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE_ALL   0xf
>> +#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A7BIT(4)
>> +#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A15   BIT(0)
>> +#define CPUCFG_CX_CTRL_REG1(c)   (0x10 * (c) + 0x4)
>> +#define CPUCFG_CX_CTRL_REG1_ACINACTM BIT(0)
>> +#define CPUCFG_CX_RST_CTRL(c)(0x80 + 0x4 * (c))
>> +#define CPUCFG_CX_RST_CTRL_DBG_SOC_RST   BIT(24)
>> +#define CPUCFG_CX_RST_CTRL_ETM_RST(n)BIT(20 + (n))
>> +#define CPUCFG_CX_RST_CTRL_ETM_RST_ALL   (0xf << 20)
>> +#define CPUCFG_CX_RST_CTRL_DBG_RST(n)BIT(16 + (n))
>> +#define CPUCFG_CX_RST_CTRL_DBG_RST_ALL   (0xf << 16)
>> +#define CPUCFG_CX_RST_CTRL_H_RST BIT(12)
>> +#define CPUCFG_CX_RST_CTRL_L2_RSTBIT(8)
>> +#define CPUCFG_CX_RST_CTRL_CX_RST(n) BIT(4 + (n))
>> +#define CPUCFG_CX_RST_CTRL_CORE_RST(n)   BIT(n)
>> +
>> +#define PRCM_CPU_PO_RST_CTRL(c)  (0x4 + 0x4 * (c))
>> +#define PRCM_CPU_PO_RST_CTRL_CORE(n) BIT(n)
>> +#define PRCM_CPU_PO_RST_CTRL_CORE_ALL0xf
>> +#define PRCM_PWROFF_GATING_REG(c)(0x100 + 0x4 * (c))
>> +#define PRCM_PWROFF_GATING_REG_CLUSTER   BIT(4)
>> +#define PRCM_PWROFF_GATING_REG_CORE(n)   BIT(n)
>> +#define PRCM_PWR_SWITCH_REG(c, cpu)  (0x140 + 0x10 * (c) + 0x4 * (cpu))
>> +#define PRCM_CPU_SOFT_ENTRY_REG  0x164
>> +
>> +static void 

Re: [PATCH 1/4] ARM: sun9i: Support SMP on A80 with Multi-Cluster Power Management (MCPM)

2017-07-25 Thread Chen-Yu Tsai
 default ARCH_SUNXI
On Tue, Jul 25, 2017 at 3:47 PM, Maxime Ripard
 wrote:
> Hi Chen-Yu,
>
> On Tue, Jul 25, 2017 at 01:09:16PM +0800, Chen-Yu Tsai wrote:
>> The A80 is a big.LITTLE SoC with 1 cluster of 4 Cortex-A7s and
>> 1 cluster of 4 Cortex-A15s.
>>
>> This patch adds support to bring up the second cluster and thus all
>> cores using the common MCPM code. Core/cluster power down has not
>> been implemented, thus CPU hotplugging and big.LITTLE switcher is
>> not supported.
>>
>> Signed-off-by: Chen-Yu Tsai 
>> ---
>>  arch/arm/mach-sunxi/Kconfig  |  10 ++
>>  arch/arm/mach-sunxi/Makefile |   1 +
>>  arch/arm/mach-sunxi/mcpm.c   | 391 
>> +++
>>  3 files changed, 402 insertions(+)
>>  create mode 100644 arch/arm/mach-sunxi/mcpm.c
>>
>> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
>> index 58153cdf025b..177380548d99 100644
>> --- a/arch/arm/mach-sunxi/Kconfig
>> +++ b/arch/arm/mach-sunxi/Kconfig
>> @@ -47,5 +47,15 @@ config MACH_SUN9I
>>   bool "Allwinner (sun9i) SoCs support"
>>   default ARCH_SUNXI
>>   select ARM_GIC
>> + imply MCPM
>> +
>> +config SUN9I_A80_MCPM
>> + bool "Allwinner A80 Multi-Cluster PM support"
>> + depends on MCPM && MACH_SUN9I
>> + default MACH_SUN9I
>> + select ARM_CCI400_PORT_CTRL
>> + help
>> +   This is needed to provide CPU and cluster power management
>> +   on Allwinner A80 implementing big.LITTLE.
>
> Do we really need an option for that? we don't provide the option to
> disable the CPU SMP operations for the rest of the SoCs.

It was an option as it also required MCPM and CCI400 support to be built.
We could hide it. Or, using mach-hisi as a reference, we could do:

config MACH_SUN9I
default ARCH_SUNXI
select ARM_GIC
select MCPM if SMP
select ARM_CCI400_PORT_CTRL if SMP

and in the Makefile:

obj-$(CONFIG_MCPM) += sun9i-mcpm.o

>
>>  endif
>> diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
>> index 27b168f121a1..e8558912c714 100644
>> --- a/arch/arm/mach-sunxi/Makefile
>> +++ b/arch/arm/mach-sunxi/Makefile
>> @@ -1,2 +1,3 @@
>>  obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
>>  obj-$(CONFIG_SMP) += platsmp.o
>> +obj-$(CONFIG_SUN9I_A80_MCPM) += mcpm.o
>> diff --git a/arch/arm/mach-sunxi/mcpm.c b/arch/arm/mach-sunxi/mcpm.c
>> new file mode 100644
>> index ..4b6e1d6ae379
>> --- /dev/null
>> +++ b/arch/arm/mach-sunxi/mcpm.c
>> @@ -0,0 +1,391 @@
>> +/*
>> + * Copyright (c) 2015 Chen-Yu Tsai
>> + *
>> + * Chen-Yu Tsai 
>> + *
>> + * arch/arm/mach-sunxi/mcpm.c
>> + *
>> + * Based on arch/arm/mach-exynos/mcpm-exynos.c and Allwinner code
>> + *
>> + * 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.
>> + */
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#define SUNXI_CPUS_PER_CLUSTER   4
>> +#define SUNXI_NR_CLUSTERS2
>> +
>> +#define SUN9I_A80_A15_CLUSTER1
>
> Don't we have a way to derive that from the DT ?

Indeed we can.

It would be slighty more complicated though:

node = of_cpu_device_node_get(cluster * SUNXI_CPUS_PER_CLUSTER + cpu);
if (of_device_is_compatible(node, "arm,cortex-a15")) {
...
}

>
>> +#define CPUCFG_CX_CTRL_REG0(c)   (0x10 * (c))
>> +#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE(n)BIT(n)
>> +#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE_ALL   0xf
>> +#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A7BIT(4)
>> +#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A15   BIT(0)
>> +#define CPUCFG_CX_CTRL_REG1(c)   (0x10 * (c) + 0x4)
>> +#define CPUCFG_CX_CTRL_REG1_ACINACTM BIT(0)
>> +#define CPUCFG_CX_RST_CTRL(c)(0x80 + 0x4 * (c))
>> +#define CPUCFG_CX_RST_CTRL_DBG_SOC_RST   BIT(24)
>> +#define CPUCFG_CX_RST_CTRL_ETM_RST(n)BIT(20 + (n))
>> +#define CPUCFG_CX_RST_CTRL_ETM_RST_ALL   (0xf << 20)
>> +#define CPUCFG_CX_RST_CTRL_DBG_RST(n)BIT(16 + (n))
>> +#define CPUCFG_CX_RST_CTRL_DBG_RST_ALL   (0xf << 16)
>> +#define CPUCFG_CX_RST_CTRL_H_RST BIT(12)
>> +#define CPUCFG_CX_RST_CTRL_L2_RSTBIT(8)
>> +#define CPUCFG_CX_RST_CTRL_CX_RST(n) BIT(4 + (n))
>> +#define CPUCFG_CX_RST_CTRL_CORE_RST(n)   BIT(n)
>> +
>> +#define PRCM_CPU_PO_RST_CTRL(c)  (0x4 + 0x4 * (c))
>> +#define PRCM_CPU_PO_RST_CTRL_CORE(n) BIT(n)
>> +#define PRCM_CPU_PO_RST_CTRL_CORE_ALL0xf
>> +#define PRCM_PWROFF_GATING_REG(c)(0x100 + 0x4 * (c))
>> +#define PRCM_PWROFF_GATING_REG_CLUSTER   BIT(4)
>> +#define PRCM_PWROFF_GATING_REG_CORE(n)   BIT(n)
>> +#define PRCM_PWR_SWITCH_REG(c, cpu)  (0x140 + 0x10 * (c) + 0x4 * (cpu))
>> +#define PRCM_CPU_SOFT_ENTRY_REG  0x164
>> +
>> +static void __iomem *cpucfg_base;
>> +static void __iomem *prcm_base;
>> +
>> 

Re: [PATCH 1/4] ARM: sun9i: Support SMP on A80 with Multi-Cluster Power Management (MCPM)

2017-07-25 Thread Maxime Ripard
Hi Chen-Yu,

On Tue, Jul 25, 2017 at 01:09:16PM +0800, Chen-Yu Tsai wrote:
> The A80 is a big.LITTLE SoC with 1 cluster of 4 Cortex-A7s and
> 1 cluster of 4 Cortex-A15s.
> 
> This patch adds support to bring up the second cluster and thus all
> cores using the common MCPM code. Core/cluster power down has not
> been implemented, thus CPU hotplugging and big.LITTLE switcher is
> not supported.
> 
> Signed-off-by: Chen-Yu Tsai 
> ---
>  arch/arm/mach-sunxi/Kconfig  |  10 ++
>  arch/arm/mach-sunxi/Makefile |   1 +
>  arch/arm/mach-sunxi/mcpm.c   | 391 
> +++
>  3 files changed, 402 insertions(+)
>  create mode 100644 arch/arm/mach-sunxi/mcpm.c
> 
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index 58153cdf025b..177380548d99 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -47,5 +47,15 @@ config MACH_SUN9I
>   bool "Allwinner (sun9i) SoCs support"
>   default ARCH_SUNXI
>   select ARM_GIC
> + imply MCPM
> +
> +config SUN9I_A80_MCPM
> + bool "Allwinner A80 Multi-Cluster PM support"
> + depends on MCPM && MACH_SUN9I
> + default MACH_SUN9I
> + select ARM_CCI400_PORT_CTRL
> + help
> +   This is needed to provide CPU and cluster power management
> +   on Allwinner A80 implementing big.LITTLE.

Do we really need an option for that? we don't provide the option to
disable the CPU SMP operations for the rest of the SoCs.

>  endif
> diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
> index 27b168f121a1..e8558912c714 100644
> --- a/arch/arm/mach-sunxi/Makefile
> +++ b/arch/arm/mach-sunxi/Makefile
> @@ -1,2 +1,3 @@
>  obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
>  obj-$(CONFIG_SMP) += platsmp.o
> +obj-$(CONFIG_SUN9I_A80_MCPM) += mcpm.o
> diff --git a/arch/arm/mach-sunxi/mcpm.c b/arch/arm/mach-sunxi/mcpm.c
> new file mode 100644
> index ..4b6e1d6ae379
> --- /dev/null
> +++ b/arch/arm/mach-sunxi/mcpm.c
> @@ -0,0 +1,391 @@
> +/*
> + * Copyright (c) 2015 Chen-Yu Tsai
> + *
> + * Chen-Yu Tsai 
> + *
> + * arch/arm/mach-sunxi/mcpm.c
> + *
> + * Based on arch/arm/mach-exynos/mcpm-exynos.c and Allwinner code
> + *
> + * 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.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +
> +#define SUNXI_CPUS_PER_CLUSTER   4
> +#define SUNXI_NR_CLUSTERS2
> + 
> +#define SUN9I_A80_A15_CLUSTER1

Don't we have a way to derive that from the DT ?

> +#define CPUCFG_CX_CTRL_REG0(c)   (0x10 * (c))
> +#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE(n)BIT(n)
> +#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE_ALL   0xf
> +#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A7BIT(4)
> +#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A15   BIT(0)
> +#define CPUCFG_CX_CTRL_REG1(c)   (0x10 * (c) + 0x4)
> +#define CPUCFG_CX_CTRL_REG1_ACINACTM BIT(0)
> +#define CPUCFG_CX_RST_CTRL(c)(0x80 + 0x4 * (c))
> +#define CPUCFG_CX_RST_CTRL_DBG_SOC_RST   BIT(24)
> +#define CPUCFG_CX_RST_CTRL_ETM_RST(n)BIT(20 + (n))
> +#define CPUCFG_CX_RST_CTRL_ETM_RST_ALL   (0xf << 20)
> +#define CPUCFG_CX_RST_CTRL_DBG_RST(n)BIT(16 + (n))
> +#define CPUCFG_CX_RST_CTRL_DBG_RST_ALL   (0xf << 16)
> +#define CPUCFG_CX_RST_CTRL_H_RST BIT(12)
> +#define CPUCFG_CX_RST_CTRL_L2_RSTBIT(8)
> +#define CPUCFG_CX_RST_CTRL_CX_RST(n) BIT(4 + (n))
> +#define CPUCFG_CX_RST_CTRL_CORE_RST(n)   BIT(n)
> +
> +#define PRCM_CPU_PO_RST_CTRL(c)  (0x4 + 0x4 * (c))
> +#define PRCM_CPU_PO_RST_CTRL_CORE(n) BIT(n)
> +#define PRCM_CPU_PO_RST_CTRL_CORE_ALL0xf
> +#define PRCM_PWROFF_GATING_REG(c)(0x100 + 0x4 * (c))
> +#define PRCM_PWROFF_GATING_REG_CLUSTER   BIT(4)
> +#define PRCM_PWROFF_GATING_REG_CORE(n)   BIT(n)
> +#define PRCM_PWR_SWITCH_REG(c, cpu)  (0x140 + 0x10 * (c) + 0x4 * (cpu))
> +#define PRCM_CPU_SOFT_ENTRY_REG  0x164
> +
> +static void __iomem *cpucfg_base;
> +static void __iomem *prcm_base;
> +
> +static int sunxi_cpu_power_switch_set(unsigned int cpu, unsigned int cluster,
> +   bool enable)
> +{
> + u32 reg;
> +
> + /* control sequence from Allwinner A80 user manual v1.2 PRCM section */
> + reg = readl(prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
> + if (enable) {
> + if (reg == 0x00) {
> + pr_debug("power clamp for cluster %u cpu %u already 
> open\n",
> +  cluster, cpu);
> + return 0;
> + }
> +
> + writel(0xff, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
> + udelay(10);
> + writel(0xfe, prcm_base + 

Re: [PATCH 1/4] ARM: sun9i: Support SMP on A80 with Multi-Cluster Power Management (MCPM)

2017-07-25 Thread Maxime Ripard
Hi Chen-Yu,

On Tue, Jul 25, 2017 at 01:09:16PM +0800, Chen-Yu Tsai wrote:
> The A80 is a big.LITTLE SoC with 1 cluster of 4 Cortex-A7s and
> 1 cluster of 4 Cortex-A15s.
> 
> This patch adds support to bring up the second cluster and thus all
> cores using the common MCPM code. Core/cluster power down has not
> been implemented, thus CPU hotplugging and big.LITTLE switcher is
> not supported.
> 
> Signed-off-by: Chen-Yu Tsai 
> ---
>  arch/arm/mach-sunxi/Kconfig  |  10 ++
>  arch/arm/mach-sunxi/Makefile |   1 +
>  arch/arm/mach-sunxi/mcpm.c   | 391 
> +++
>  3 files changed, 402 insertions(+)
>  create mode 100644 arch/arm/mach-sunxi/mcpm.c
> 
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index 58153cdf025b..177380548d99 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -47,5 +47,15 @@ config MACH_SUN9I
>   bool "Allwinner (sun9i) SoCs support"
>   default ARCH_SUNXI
>   select ARM_GIC
> + imply MCPM
> +
> +config SUN9I_A80_MCPM
> + bool "Allwinner A80 Multi-Cluster PM support"
> + depends on MCPM && MACH_SUN9I
> + default MACH_SUN9I
> + select ARM_CCI400_PORT_CTRL
> + help
> +   This is needed to provide CPU and cluster power management
> +   on Allwinner A80 implementing big.LITTLE.

Do we really need an option for that? we don't provide the option to
disable the CPU SMP operations for the rest of the SoCs.

>  endif
> diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
> index 27b168f121a1..e8558912c714 100644
> --- a/arch/arm/mach-sunxi/Makefile
> +++ b/arch/arm/mach-sunxi/Makefile
> @@ -1,2 +1,3 @@
>  obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
>  obj-$(CONFIG_SMP) += platsmp.o
> +obj-$(CONFIG_SUN9I_A80_MCPM) += mcpm.o
> diff --git a/arch/arm/mach-sunxi/mcpm.c b/arch/arm/mach-sunxi/mcpm.c
> new file mode 100644
> index ..4b6e1d6ae379
> --- /dev/null
> +++ b/arch/arm/mach-sunxi/mcpm.c
> @@ -0,0 +1,391 @@
> +/*
> + * Copyright (c) 2015 Chen-Yu Tsai
> + *
> + * Chen-Yu Tsai 
> + *
> + * arch/arm/mach-sunxi/mcpm.c
> + *
> + * Based on arch/arm/mach-exynos/mcpm-exynos.c and Allwinner code
> + *
> + * 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.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +
> +#define SUNXI_CPUS_PER_CLUSTER   4
> +#define SUNXI_NR_CLUSTERS2
> + 
> +#define SUN9I_A80_A15_CLUSTER1

Don't we have a way to derive that from the DT ?

> +#define CPUCFG_CX_CTRL_REG0(c)   (0x10 * (c))
> +#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE(n)BIT(n)
> +#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE_ALL   0xf
> +#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A7BIT(4)
> +#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A15   BIT(0)
> +#define CPUCFG_CX_CTRL_REG1(c)   (0x10 * (c) + 0x4)
> +#define CPUCFG_CX_CTRL_REG1_ACINACTM BIT(0)
> +#define CPUCFG_CX_RST_CTRL(c)(0x80 + 0x4 * (c))
> +#define CPUCFG_CX_RST_CTRL_DBG_SOC_RST   BIT(24)
> +#define CPUCFG_CX_RST_CTRL_ETM_RST(n)BIT(20 + (n))
> +#define CPUCFG_CX_RST_CTRL_ETM_RST_ALL   (0xf << 20)
> +#define CPUCFG_CX_RST_CTRL_DBG_RST(n)BIT(16 + (n))
> +#define CPUCFG_CX_RST_CTRL_DBG_RST_ALL   (0xf << 16)
> +#define CPUCFG_CX_RST_CTRL_H_RST BIT(12)
> +#define CPUCFG_CX_RST_CTRL_L2_RSTBIT(8)
> +#define CPUCFG_CX_RST_CTRL_CX_RST(n) BIT(4 + (n))
> +#define CPUCFG_CX_RST_CTRL_CORE_RST(n)   BIT(n)
> +
> +#define PRCM_CPU_PO_RST_CTRL(c)  (0x4 + 0x4 * (c))
> +#define PRCM_CPU_PO_RST_CTRL_CORE(n) BIT(n)
> +#define PRCM_CPU_PO_RST_CTRL_CORE_ALL0xf
> +#define PRCM_PWROFF_GATING_REG(c)(0x100 + 0x4 * (c))
> +#define PRCM_PWROFF_GATING_REG_CLUSTER   BIT(4)
> +#define PRCM_PWROFF_GATING_REG_CORE(n)   BIT(n)
> +#define PRCM_PWR_SWITCH_REG(c, cpu)  (0x140 + 0x10 * (c) + 0x4 * (cpu))
> +#define PRCM_CPU_SOFT_ENTRY_REG  0x164
> +
> +static void __iomem *cpucfg_base;
> +static void __iomem *prcm_base;
> +
> +static int sunxi_cpu_power_switch_set(unsigned int cpu, unsigned int cluster,
> +   bool enable)
> +{
> + u32 reg;
> +
> + /* control sequence from Allwinner A80 user manual v1.2 PRCM section */
> + reg = readl(prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
> + if (enable) {
> + if (reg == 0x00) {
> + pr_debug("power clamp for cluster %u cpu %u already 
> open\n",
> +  cluster, cpu);
> + return 0;
> + }
> +
> + writel(0xff, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
> + udelay(10);
> + writel(0xfe, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
> +   

[PATCH 1/4] ARM: sun9i: Support SMP on A80 with Multi-Cluster Power Management (MCPM)

2017-07-24 Thread Chen-Yu Tsai
The A80 is a big.LITTLE SoC with 1 cluster of 4 Cortex-A7s and
1 cluster of 4 Cortex-A15s.

This patch adds support to bring up the second cluster and thus all
cores using the common MCPM code. Core/cluster power down has not
been implemented, thus CPU hotplugging and big.LITTLE switcher is
not supported.

Signed-off-by: Chen-Yu Tsai 
---
 arch/arm/mach-sunxi/Kconfig  |  10 ++
 arch/arm/mach-sunxi/Makefile |   1 +
 arch/arm/mach-sunxi/mcpm.c   | 391 +++
 3 files changed, 402 insertions(+)
 create mode 100644 arch/arm/mach-sunxi/mcpm.c

diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 58153cdf025b..177380548d99 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -47,5 +47,15 @@ config MACH_SUN9I
bool "Allwinner (sun9i) SoCs support"
default ARCH_SUNXI
select ARM_GIC
+   imply MCPM
+
+config SUN9I_A80_MCPM
+   bool "Allwinner A80 Multi-Cluster PM support"
+   depends on MCPM && MACH_SUN9I
+   default MACH_SUN9I
+   select ARM_CCI400_PORT_CTRL
+   help
+ This is needed to provide CPU and cluster power management
+ on Allwinner A80 implementing big.LITTLE.
 
 endif
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
index 27b168f121a1..e8558912c714 100644
--- a/arch/arm/mach-sunxi/Makefile
+++ b/arch/arm/mach-sunxi/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
 obj-$(CONFIG_SMP) += platsmp.o
+obj-$(CONFIG_SUN9I_A80_MCPM) += mcpm.o
diff --git a/arch/arm/mach-sunxi/mcpm.c b/arch/arm/mach-sunxi/mcpm.c
new file mode 100644
index ..4b6e1d6ae379
--- /dev/null
+++ b/arch/arm/mach-sunxi/mcpm.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2015 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai 
+ *
+ * arch/arm/mach-sunxi/mcpm.c
+ *
+ * Based on arch/arm/mach-exynos/mcpm-exynos.c and Allwinner code
+ *
+ * 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.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define SUNXI_CPUS_PER_CLUSTER 4
+#define SUNXI_NR_CLUSTERS  2
+
+#define SUN9I_A80_A15_CLUSTER  1
+
+#define CPUCFG_CX_CTRL_REG0(c) (0x10 * (c))
+#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE(n)  BIT(n)
+#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE_ALL 0xf
+#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A7  BIT(4)
+#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A15 BIT(0)
+#define CPUCFG_CX_CTRL_REG1(c) (0x10 * (c) + 0x4)
+#define CPUCFG_CX_CTRL_REG1_ACINACTM   BIT(0)
+#define CPUCFG_CX_RST_CTRL(c)  (0x80 + 0x4 * (c))
+#define CPUCFG_CX_RST_CTRL_DBG_SOC_RST BIT(24)
+#define CPUCFG_CX_RST_CTRL_ETM_RST(n)  BIT(20 + (n))
+#define CPUCFG_CX_RST_CTRL_ETM_RST_ALL (0xf << 20)
+#define CPUCFG_CX_RST_CTRL_DBG_RST(n)  BIT(16 + (n))
+#define CPUCFG_CX_RST_CTRL_DBG_RST_ALL (0xf << 16)
+#define CPUCFG_CX_RST_CTRL_H_RST   BIT(12)
+#define CPUCFG_CX_RST_CTRL_L2_RST  BIT(8)
+#define CPUCFG_CX_RST_CTRL_CX_RST(n)   BIT(4 + (n))
+#define CPUCFG_CX_RST_CTRL_CORE_RST(n) BIT(n)
+
+#define PRCM_CPU_PO_RST_CTRL(c)(0x4 + 0x4 * (c))
+#define PRCM_CPU_PO_RST_CTRL_CORE(n)   BIT(n)
+#define PRCM_CPU_PO_RST_CTRL_CORE_ALL  0xf
+#define PRCM_PWROFF_GATING_REG(c)  (0x100 + 0x4 * (c))
+#define PRCM_PWROFF_GATING_REG_CLUSTER BIT(4)
+#define PRCM_PWROFF_GATING_REG_CORE(n) BIT(n)
+#define PRCM_PWR_SWITCH_REG(c, cpu)(0x140 + 0x10 * (c) + 0x4 * (cpu))
+#define PRCM_CPU_SOFT_ENTRY_REG0x164
+
+static void __iomem *cpucfg_base;
+static void __iomem *prcm_base;
+
+static int sunxi_cpu_power_switch_set(unsigned int cpu, unsigned int cluster,
+ bool enable)
+{
+   u32 reg;
+
+   /* control sequence from Allwinner A80 user manual v1.2 PRCM section */
+   reg = readl(prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+   if (enable) {
+   if (reg == 0x00) {
+   pr_debug("power clamp for cluster %u cpu %u already 
open\n",
+cluster, cpu);
+   return 0;
+   }
+
+   writel(0xff, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+   udelay(10);
+   writel(0xfe, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+   udelay(10);
+   writel(0xf8, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+   udelay(10);
+   writel(0xf0, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+   udelay(10);
+   writel(0x00, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+   udelay(10);
+   } else {
+   writel(0xff, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+   udelay(10);
+   }
+
+   return 0;
+}
+
+static int 

[PATCH 1/4] ARM: sun9i: Support SMP on A80 with Multi-Cluster Power Management (MCPM)

2017-07-24 Thread Chen-Yu Tsai
The A80 is a big.LITTLE SoC with 1 cluster of 4 Cortex-A7s and
1 cluster of 4 Cortex-A15s.

This patch adds support to bring up the second cluster and thus all
cores using the common MCPM code. Core/cluster power down has not
been implemented, thus CPU hotplugging and big.LITTLE switcher is
not supported.

Signed-off-by: Chen-Yu Tsai 
---
 arch/arm/mach-sunxi/Kconfig  |  10 ++
 arch/arm/mach-sunxi/Makefile |   1 +
 arch/arm/mach-sunxi/mcpm.c   | 391 +++
 3 files changed, 402 insertions(+)
 create mode 100644 arch/arm/mach-sunxi/mcpm.c

diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 58153cdf025b..177380548d99 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -47,5 +47,15 @@ config MACH_SUN9I
bool "Allwinner (sun9i) SoCs support"
default ARCH_SUNXI
select ARM_GIC
+   imply MCPM
+
+config SUN9I_A80_MCPM
+   bool "Allwinner A80 Multi-Cluster PM support"
+   depends on MCPM && MACH_SUN9I
+   default MACH_SUN9I
+   select ARM_CCI400_PORT_CTRL
+   help
+ This is needed to provide CPU and cluster power management
+ on Allwinner A80 implementing big.LITTLE.
 
 endif
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
index 27b168f121a1..e8558912c714 100644
--- a/arch/arm/mach-sunxi/Makefile
+++ b/arch/arm/mach-sunxi/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
 obj-$(CONFIG_SMP) += platsmp.o
+obj-$(CONFIG_SUN9I_A80_MCPM) += mcpm.o
diff --git a/arch/arm/mach-sunxi/mcpm.c b/arch/arm/mach-sunxi/mcpm.c
new file mode 100644
index ..4b6e1d6ae379
--- /dev/null
+++ b/arch/arm/mach-sunxi/mcpm.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2015 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai 
+ *
+ * arch/arm/mach-sunxi/mcpm.c
+ *
+ * Based on arch/arm/mach-exynos/mcpm-exynos.c and Allwinner code
+ *
+ * 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.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define SUNXI_CPUS_PER_CLUSTER 4
+#define SUNXI_NR_CLUSTERS  2
+
+#define SUN9I_A80_A15_CLUSTER  1
+
+#define CPUCFG_CX_CTRL_REG0(c) (0x10 * (c))
+#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE(n)  BIT(n)
+#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE_ALL 0xf
+#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A7  BIT(4)
+#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A15 BIT(0)
+#define CPUCFG_CX_CTRL_REG1(c) (0x10 * (c) + 0x4)
+#define CPUCFG_CX_CTRL_REG1_ACINACTM   BIT(0)
+#define CPUCFG_CX_RST_CTRL(c)  (0x80 + 0x4 * (c))
+#define CPUCFG_CX_RST_CTRL_DBG_SOC_RST BIT(24)
+#define CPUCFG_CX_RST_CTRL_ETM_RST(n)  BIT(20 + (n))
+#define CPUCFG_CX_RST_CTRL_ETM_RST_ALL (0xf << 20)
+#define CPUCFG_CX_RST_CTRL_DBG_RST(n)  BIT(16 + (n))
+#define CPUCFG_CX_RST_CTRL_DBG_RST_ALL (0xf << 16)
+#define CPUCFG_CX_RST_CTRL_H_RST   BIT(12)
+#define CPUCFG_CX_RST_CTRL_L2_RST  BIT(8)
+#define CPUCFG_CX_RST_CTRL_CX_RST(n)   BIT(4 + (n))
+#define CPUCFG_CX_RST_CTRL_CORE_RST(n) BIT(n)
+
+#define PRCM_CPU_PO_RST_CTRL(c)(0x4 + 0x4 * (c))
+#define PRCM_CPU_PO_RST_CTRL_CORE(n)   BIT(n)
+#define PRCM_CPU_PO_RST_CTRL_CORE_ALL  0xf
+#define PRCM_PWROFF_GATING_REG(c)  (0x100 + 0x4 * (c))
+#define PRCM_PWROFF_GATING_REG_CLUSTER BIT(4)
+#define PRCM_PWROFF_GATING_REG_CORE(n) BIT(n)
+#define PRCM_PWR_SWITCH_REG(c, cpu)(0x140 + 0x10 * (c) + 0x4 * (cpu))
+#define PRCM_CPU_SOFT_ENTRY_REG0x164
+
+static void __iomem *cpucfg_base;
+static void __iomem *prcm_base;
+
+static int sunxi_cpu_power_switch_set(unsigned int cpu, unsigned int cluster,
+ bool enable)
+{
+   u32 reg;
+
+   /* control sequence from Allwinner A80 user manual v1.2 PRCM section */
+   reg = readl(prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+   if (enable) {
+   if (reg == 0x00) {
+   pr_debug("power clamp for cluster %u cpu %u already 
open\n",
+cluster, cpu);
+   return 0;
+   }
+
+   writel(0xff, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+   udelay(10);
+   writel(0xfe, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+   udelay(10);
+   writel(0xf8, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+   udelay(10);
+   writel(0xf0, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+   udelay(10);
+   writel(0x00, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+   udelay(10);
+   } else {
+   writel(0xff, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+   udelay(10);
+   }
+
+   return 0;
+}
+
+static int sunxi_cpu_powerup(unsigned int cpu,