devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6]  Add CPU Frequency scaling support on Armada 37xx
@ 2017-12-01 11:25 Gregory CLEMENT
  2017-12-01 11:25 ` [PATCH 1/6] dt-bindings: marvell: Add documentation for the North Bridge PM " Gregory CLEMENT
                   ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Gregory CLEMENT @ 2017-12-01 11:25 UTC (permalink / raw)
  To: Rafael J. Wysocki, Viresh Kumar, linux-pm-u79uwXL29TY76Z2rM5mHXA
  Cc: Jason Cooper, Andrew Lunn, Sebastian Hesselbarth,
	Gregory CLEMENT, Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Thomas Petazzoni,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Antoine Tenart, Miquèl Raynal, Nadav Haklai, Victor Gu,
	Marcin Wojtas, Wilson Ding, Hua Jing, Neta Zur Hershkovits,
	Evan Wang

Hi,

This series adds the CPU Frequency support on Armada 37xx using
DVFS. It is based on the initial work of Evan Wang and Victor Gu.

DVFS control is done by a set of registers from the North Bridge Power
Management block. The binding for this block is documented in patch 1.

While adding a new cpufreq driver I found that the Kconfig and
Makefile were no more in order, so it is fixed by patch 2 and 3.

The 4th patch is just about updating the MAINTAINERS file with the new
driver.

The next patch is the real purpose of the series. The main goal of
this driver is to setup the CPU load level in the hardware to
associate them to CPU frequencies and register a standard cpufreq
driver. Note that the hardware also capable of doing AVS (Adaptive
Voltage Scaling), by associating a voltage on each level beside the
CPU frequency. However, this support is not yet ready, so it is not
part of this series.

Finally, the last patch is for arm-soc the arm-soc subsystem through
mvebu and update the device tree to support the CPU frequency scaling.

An update on the CPU clock driver is needed in order to take into
account the DVFS setting. It's the purpose of an other series already
sent, but is no dependencies between the series (for building or at
runtime).

Thanks,

Gregory

Gregory CLEMENT (6):
  dt-bindings: marvell: Add documentation for the North Bridge PM on
    Armada 37xx
  cpufreq: ARM: sort the Kconfig menu
  cpufreq: sort the drivers in ARM part
  MAINTAINERS: add new entries for Armada 37xx cpufreq driver
  cpufreq: Add DVFS support for Armada 37xx
  arm64: dts: marvell: armada-37xx: add nodes allowing cpufreq support

 .../bindings/arm/marvell/armada-37xx.txt           |  19 ++
 MAINTAINERS                                        |   1 +
 arch/arm64/boot/dts/marvell/armada-372x.dtsi       |   1 +
 arch/arm64/boot/dts/marvell/armada-37xx.dtsi       |   7 +
 drivers/cpufreq/Kconfig.arm                        |  89 ++++----
 drivers/cpufreq/Makefile                           |   9 +-
 drivers/cpufreq/armada-37xx-cpufreq.c              | 241 +++++++++++++++++++++
 7 files changed, 322 insertions(+), 45 deletions(-)
 create mode 100644 drivers/cpufreq/armada-37xx-cpufreq.c

-- 
2.15.0

--
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] 15+ messages in thread

* [PATCH 1/6] dt-bindings: marvell: Add documentation for the North Bridge PM on Armada 37xx
  2017-12-01 11:25 [PATCH 0/6] Add CPU Frequency scaling support on Armada 37xx Gregory CLEMENT
@ 2017-12-01 11:25 ` Gregory CLEMENT
  2017-12-04 21:47   ` Rob Herring
  2017-12-01 11:25 ` [PATCH 2/6] cpufreq: ARM: sort the Kconfig menu Gregory CLEMENT
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Gregory CLEMENT @ 2017-12-01 11:25 UTC (permalink / raw)
  To: Rafael J. Wysocki, Viresh Kumar, linux-pm
  Cc: Jason Cooper, Andrew Lunn, Sebastian Hesselbarth,
	Gregory CLEMENT, Rob Herring, devicetree, Thomas Petazzoni,
	linux-arm-kernel, Antoine Tenart, Miquèl Raynal,
	Nadav Haklai, Victor Gu, Marcin Wojtas, Wilson Ding, Hua Jing,
	Neta Zur Hershkovits, Evan Wang

Extend the documentation of the Armada 37xx SoC with the the North
Bridge Power Management component.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 .../devicetree/bindings/arm/marvell/armada-37xx.txt   | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt b/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt
index 51336e5fc761..7ad9830d9177 100644
--- a/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt
@@ -14,3 +14,22 @@ following property before the previous one:
 Example:
 
 compatible = "marvell,armada-3720-db", "marvell,armada3720", "marvell,armada3710";
+
+
+Power management
+----------------
+
+For power management (particularly DVFS and AVS), the North Bridge
+Power Management component is needed:
+
+Required properties:
+- compatible     : should contain "marvell,armada-3700-nb-pm", "syscon";
+- reg            : the register start and length for the North Bridge
+		    Power Management
+
+Example:
+
+nb_pm: nb_pm@14000 {
+	compatible = "marvell,armada-3700-nb-pm", "syscon";
+	reg = <0x14000 0x60>;
+}
-- 
2.15.0

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

* [PATCH 2/6] cpufreq: ARM: sort the Kconfig menu
  2017-12-01 11:25 [PATCH 0/6] Add CPU Frequency scaling support on Armada 37xx Gregory CLEMENT
  2017-12-01 11:25 ` [PATCH 1/6] dt-bindings: marvell: Add documentation for the North Bridge PM " Gregory CLEMENT
@ 2017-12-01 11:25 ` Gregory CLEMENT
  2017-12-04  8:41   ` Viresh Kumar
  2017-12-01 11:25 ` [PATCH 3/6] cpufreq: sort the drivers in ARM part Gregory CLEMENT
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Gregory CLEMENT @ 2017-12-01 11:25 UTC (permalink / raw)
  To: Rafael J. Wysocki, Viresh Kumar, linux-pm
  Cc: Jason Cooper, Andrew Lunn, Sebastian Hesselbarth,
	Gregory CLEMENT, Rob Herring, devicetree, Thomas Petazzoni,
	linux-arm-kernel, Antoine Tenart, Miquèl Raynal,
	Nadav Haklai, Victor Gu, Marcin Wojtas, Wilson Ding, Hua Jing,
	Neta Zur Hershkovits, Evan Wang

Group all the related big LITTLE configuration together and sort the
other entries in alphabetic order.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 drivers/cpufreq/Kconfig.arm | 82 ++++++++++++++++++++++-----------------------
 1 file changed, 41 insertions(+), 41 deletions(-)

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index bdce4488ded1..17625115c67f 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -2,6 +2,23 @@
 # ARM CPU Frequency scaling drivers
 #
 
+config ACPI_CPPC_CPUFREQ
+	tristate "CPUFreq driver based on the ACPI CPPC spec"
+	depends on ACPI_PROCESSOR
+	select ACPI_CPPC_LIB
+	default n
+	help
+	  This adds a CPUFreq driver which uses CPPC methods
+	  as described in the ACPIv5.1 spec. CPPC stands for
+	  Collaborative Processor Performance Controls. It
+	  is based on an abstract continuous scale of CPU
+	  performance values which allows the remote power
+	  processor to flexibly optimize for power and
+	  performance. CPPC relies on power management firmware
+	  support for its operation.
+
+	  If in doubt, say N.
+
 # big LITTLE core layer and glue drivers
 config ARM_BIG_LITTLE_CPUFREQ
 	tristate "Generic ARM big LITTLE CPUfreq driver"
@@ -12,6 +29,30 @@ config ARM_BIG_LITTLE_CPUFREQ
 	help
 	  This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
 
+config ARM_DT_BL_CPUFREQ
+	tristate "Generic probing via DT for ARM big LITTLE CPUfreq driver"
+	depends on ARM_BIG_LITTLE_CPUFREQ && OF
+	help
+	  This enables probing via DT for Generic CPUfreq driver for ARM
+	  big.LITTLE platform. This gets frequency tables from DT.
+
+config ARM_VEXPRESS_SPC_CPUFREQ
+        tristate "Versatile Express SPC based CPUfreq driver"
+	depends on ARM_BIG_LITTLE_CPUFREQ && ARCH_VEXPRESS_SPC
+        help
+          This add the CPUfreq driver support for Versatile Express
+	  big.LITTLE platforms using SPC for power management.
+
+config ARM_SCPI_CPUFREQ
+        tristate "SCPI based CPUfreq driver"
+	depends on ARM_BIG_LITTLE_CPUFREQ && ARM_SCPI_PROTOCOL && COMMON_CLK_SCPI
+        help
+	  This adds the CPUfreq driver support for ARM big.LITTLE platforms
+	  using SCPI protocol for CPU power management.
+
+	  This driver uses SCPI Message Protocol driver to interact with the
+	  firmware providing the CPU DVFS functionality.
+
 config ARM_BRCMSTB_AVS_CPUFREQ
 	tristate "Broadcom STB AVS CPUfreq driver"
 	depends on ARCH_BRCMSTB || COMPILE_TEST
@@ -33,20 +74,6 @@ config ARM_BRCMSTB_AVS_CPUFREQ_DEBUG
 
 	  If in doubt, say N.
 
-config ARM_DT_BL_CPUFREQ
-	tristate "Generic probing via DT for ARM big LITTLE CPUfreq driver"
-	depends on ARM_BIG_LITTLE_CPUFREQ && OF
-	help
-	  This enables probing via DT for Generic CPUfreq driver for ARM
-	  big.LITTLE platform. This gets frequency tables from DT.
-
-config ARM_VEXPRESS_SPC_CPUFREQ
-        tristate "Versatile Express SPC based CPUfreq driver"
-	depends on ARM_BIG_LITTLE_CPUFREQ && ARCH_VEXPRESS_SPC
-        help
-          This add the CPUfreq driver support for Versatile Express
-	  big.LITTLE platforms using SPC for power management.
-
 config ARM_EXYNOS5440_CPUFREQ
 	tristate "SAMSUNG EXYNOS5440"
 	depends on SOC_EXYNOS5440
@@ -205,16 +232,6 @@ config ARM_SA1100_CPUFREQ
 config ARM_SA1110_CPUFREQ
 	bool
 
-config ARM_SCPI_CPUFREQ
-        tristate "SCPI based CPUfreq driver"
-	depends on ARM_BIG_LITTLE_CPUFREQ && ARM_SCPI_PROTOCOL && COMMON_CLK_SCPI
-        help
-	  This adds the CPUfreq driver support for ARM big.LITTLE platforms
-	  using SCPI protocol for CPU power management.
-
-	  This driver uses SCPI Message Protocol driver to interact with the
-	  firmware providing the CPU DVFS functionality.
-
 config ARM_SPEAR_CPUFREQ
 	bool "SPEAr CPUFreq support"
 	depends on PLAT_SPEAR
@@ -275,20 +292,3 @@ config ARM_PXA2xx_CPUFREQ
 	  This add the CPUFreq driver support for Intel PXA2xx SOCs.
 
 	  If in doubt, say N.
-
-config ACPI_CPPC_CPUFREQ
-	tristate "CPUFreq driver based on the ACPI CPPC spec"
-	depends on ACPI_PROCESSOR
-	select ACPI_CPPC_LIB
-	default n
-	help
-	  This adds a CPUFreq driver which uses CPPC methods
-	  as described in the ACPIv5.1 spec. CPPC stands for
-	  Collaborative Processor Performance Controls. It
-	  is based on an abstract continuous scale of CPU
-	  performance values which allows the remote power
-	  processor to flexibly optimize for power and
-	  performance. CPPC relies on power management firmware
-	  support for its operation.
-
-	  If in doubt, say N.
-- 
2.15.0

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

* [PATCH 3/6] cpufreq: sort the drivers in ARM part
  2017-12-01 11:25 [PATCH 0/6] Add CPU Frequency scaling support on Armada 37xx Gregory CLEMENT
  2017-12-01 11:25 ` [PATCH 1/6] dt-bindings: marvell: Add documentation for the North Bridge PM " Gregory CLEMENT
  2017-12-01 11:25 ` [PATCH 2/6] cpufreq: ARM: sort the Kconfig menu Gregory CLEMENT
@ 2017-12-01 11:25 ` Gregory CLEMENT
  2017-12-04  9:18   ` Viresh Kumar
       [not found] ` <20171201112508.14121-1-gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Gregory CLEMENT @ 2017-12-01 11:25 UTC (permalink / raw)
  To: Rafael J. Wysocki, Viresh Kumar, linux-pm
  Cc: Jason Cooper, Andrew Lunn, Sebastian Hesselbarth,
	Gregory CLEMENT, Rob Herring, devicetree, Thomas Petazzoni,
	linux-arm-kernel, Antoine Tenart, Miquèl Raynal,
	Nadav Haklai, Victor Gu, Marcin Wojtas, Wilson Ding, Hua Jing,
	Neta Zur Hershkovits, Evan Wang

Keep the driver files alphabetically sorted.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 drivers/cpufreq/Makefile | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 812f9e0d01a3..d762e76887e7 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -53,22 +53,24 @@ obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ)	+= arm_big_little.o
 obj-$(CONFIG_ARM_DT_BL_CPUFREQ)		+= arm_big_little_dt.o
 
 obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ)	+= brcmstb-avs-cpufreq.o
+obj-$(CONFIG_ACPI_CPPC_CPUFREQ)		+= cppc_cpufreq.o
 obj-$(CONFIG_ARCH_DAVINCI)		+= davinci-cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ)	+= exynos5440-cpufreq.o
 obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ)	+= highbank-cpufreq.o
 obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)		+= imx6q-cpufreq.o
 obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ)	+= kirkwood-cpufreq.o
 obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ)	+= mediatek-cpufreq.o
+obj-$(CONFIG_MACH_MVEBU_V7)		+= mvebu-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)	+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)	+= pxa2xx-cpufreq.o
 obj-$(CONFIG_PXA3xx)			+= pxa3xx-cpufreq.o
-obj-$(CONFIG_ARM_S3C24XX_CPUFREQ)	+= s3c24xx-cpufreq.o
-obj-$(CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS) += s3c24xx-cpufreq-debugfs.o
 obj-$(CONFIG_ARM_S3C2410_CPUFREQ)	+= s3c2410-cpufreq.o
 obj-$(CONFIG_ARM_S3C2412_CPUFREQ)	+= s3c2412-cpufreq.o
 obj-$(CONFIG_ARM_S3C2416_CPUFREQ)	+= s3c2416-cpufreq.o
 obj-$(CONFIG_ARM_S3C2440_CPUFREQ)	+= s3c2440-cpufreq.o
 obj-$(CONFIG_ARM_S3C64XX_CPUFREQ)	+= s3c64xx-cpufreq.o
+obj-$(CONFIG_ARM_S3C24XX_CPUFREQ)	+= s3c24xx-cpufreq.o
+obj-$(CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS) += s3c24xx-cpufreq-debugfs.o
 obj-$(CONFIG_ARM_S5PV210_CPUFREQ)	+= s5pv210-cpufreq.o
 obj-$(CONFIG_ARM_SA1100_CPUFREQ)	+= sa1100-cpufreq.o
 obj-$(CONFIG_ARM_SA1110_CPUFREQ)	+= sa1110-cpufreq.o
@@ -81,8 +83,6 @@ obj-$(CONFIG_ARM_TEGRA124_CPUFREQ)	+= tegra124-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA186_CPUFREQ)	+= tegra186-cpufreq.o
 obj-$(CONFIG_ARM_TI_CPUFREQ)		+= ti-cpufreq.o
 obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ)	+= vexpress-spc-cpufreq.o
-obj-$(CONFIG_ACPI_CPPC_CPUFREQ) += cppc_cpufreq.o
-obj-$(CONFIG_MACH_MVEBU_V7)		+= mvebu-cpufreq.o
 
 
 ##################################################################################
-- 
2.15.0

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

* [PATCH 4/6] MAINTAINERS: add new entries for Armada 37xx cpufreq driver
       [not found] ` <20171201112508.14121-1-gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
@ 2017-12-01 11:25   ` Gregory CLEMENT
  0 siblings, 0 replies; 15+ messages in thread
From: Gregory CLEMENT @ 2017-12-01 11:25 UTC (permalink / raw)
  To: Rafael J. Wysocki, Viresh Kumar, linux-pm-u79uwXL29TY76Z2rM5mHXA
  Cc: Jason Cooper, Andrew Lunn, Sebastian Hesselbarth,
	Gregory CLEMENT, Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Thomas Petazzoni,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Antoine Tenart, Miquèl Raynal, Nadav Haklai, Victor Gu,
	Marcin Wojtas, Wilson Ding, Hua Jing, Neta Zur Hershkovits,
	Evan Wang

This new driver belongs to the mvebu family, update the MAINTAINER file
to document it.

Signed-off-by: Gregory CLEMENT <gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index aa71ab52fd76..98dcee849481 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1582,6 +1582,7 @@ F:	arch/arm/boot/dts/kirkwood*
 F:	arch/arm/configs/mvebu_*_defconfig
 F:	arch/arm/mach-mvebu/
 F:	arch/arm64/boot/dts/marvell/armada*
+F:	drivers/cpufreq/armada-37xx-cpufreq.c
 F:	drivers/cpufreq/mvebu-cpufreq.c
 F:	drivers/irqchip/irq-armada-370-xp.c
 F:	drivers/irqchip/irq-mvebu-*
-- 
2.15.0

--
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] 15+ messages in thread

* [PATCH 5/6] cpufreq: Add DVFS support for Armada 37xx
  2017-12-01 11:25 [PATCH 0/6] Add CPU Frequency scaling support on Armada 37xx Gregory CLEMENT
                   ` (3 preceding siblings ...)
       [not found] ` <20171201112508.14121-1-gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
@ 2017-12-01 11:25 ` Gregory CLEMENT
  2017-12-05  5:54   ` Viresh Kumar
  2017-12-01 11:25 ` [PATCH 6/6] arm64: dts: marvell: armada-37xx: add nodes allowing cpufreq support Gregory CLEMENT
  5 siblings, 1 reply; 15+ messages in thread
From: Gregory CLEMENT @ 2017-12-01 11:25 UTC (permalink / raw)
  To: Rafael J. Wysocki, Viresh Kumar, linux-pm
  Cc: Jason Cooper, Andrew Lunn, Sebastian Hesselbarth,
	Gregory CLEMENT, Rob Herring, devicetree, Thomas Petazzoni,
	linux-arm-kernel, Antoine Tenart, Miquèl Raynal,
	Nadav Haklai, Victor Gu, Marcin Wojtas, Wilson Ding, Hua Jing,
	Neta Zur Hershkovits, Evan Wang

This patch adds DVFS support for the Armada 37xx SoCs

There are up to four CPU frequency loads for Armada 37xx controlled by
the hardware.

This driver associates the CPU load level to a frequency, then the
hardware will switch while selecting a load level.

The hardware also can associate a voltage for each level (AVS support)
but it is not yet supported

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 drivers/cpufreq/Kconfig.arm           |   7 +
 drivers/cpufreq/Makefile              |   1 +
 drivers/cpufreq/armada-37xx-cpufreq.c | 241 ++++++++++++++++++++++++++++++++++
 3 files changed, 249 insertions(+)
 create mode 100644 drivers/cpufreq/armada-37xx-cpufreq.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 17625115c67f..3018ff0d068f 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -19,6 +19,13 @@ config ACPI_CPPC_CPUFREQ
 
 	  If in doubt, say N.
 
+config ARM_ARMADA_37XX_CPUFREQ
+	tristate "Armada 37xx CPUFreq support"
+	depends on ARCH_MVEBU
+	help
+	  This adds the CPUFreq driver support for Marvell Armada 37xx SoCs.
+	  The Armada 37xx PMU supports 4 frequency and VDD levels.
+
 # big LITTLE core layer and glue drivers
 config ARM_BIG_LITTLE_CPUFREQ
 	tristate "Generic ARM big LITTLE CPUfreq driver"
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index d762e76887e7..e07715ce8844 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ)	+= arm_big_little.o
 # LITTLE drivers, so that it is probed last.
 obj-$(CONFIG_ARM_DT_BL_CPUFREQ)		+= arm_big_little_dt.o
 
+obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ)	+= armada-37xx-cpufreq.o
 obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ)	+= brcmstb-avs-cpufreq.o
 obj-$(CONFIG_ACPI_CPPC_CPUFREQ)		+= cppc_cpufreq.o
 obj-$(CONFIG_ARCH_DAVINCI)		+= davinci-cpufreq.o
diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c
new file mode 100644
index 000000000000..40c9a744cc6e
--- /dev/null
+++ b/drivers/cpufreq/armada-37xx-cpufreq.c
@@ -0,0 +1,241 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * CPU frequency scaling support for Armada 37xx platform.
+ *
+ * Copyright (C) 2017 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+/* Power management in North Bridge register set */
+#define ARMADA_37XX_NB_L0L1	0x18
+#define ARMADA_37XX_NB_L2L3	0x1C
+#define		ARMADA_37XX_NB_TBG_DIV_OFF	13
+#define		ARMADA_37XX_NB_TBG_DIV_MASK	0x7
+#define		ARMADA_37XX_NB_CLK_SEL_OFF	11
+#define		ARMADA_37XX_NB_CLK_SEL_MASK	0x1
+#define		ARMADA_37XX_NB_CLK_SEL_TBG      0x1
+#define		ARMADA_37XX_NB_TBG_SEL_OFF	9
+#define		ARMADA_37XX_NB_TBG_SEL_MASK	0x3
+#define		ARMADA_37XX_NB_VDD_SEL_OFF	6
+#define		ARMADA_37XX_NB_VDD_SEL_MASK	0x3
+#define		ARMADA_37XX_NB_CONFIG_SHIFT	16
+#define ARMADA_37XX_NB_DYN_MOD	0x24
+#define		ARMADA_37XX_NB_CLK_SEL_EN	BIT(26)
+#define		ARMADA_37XX_NB_TBG_EN		BIT(28)
+#define		ARMADA_37XX_NB_DIV_EN		BIT(29)
+#define		ARMADA_37XX_NB_VDD_EN		BIT(30)
+#define		ARMADA_37XX_NB_DFS_EN		BIT(31)
+#define ARMADA_37XX_NB_CPU_LOAD	0x30
+#define		ARMADA_37XX_NB_CPU_LOAD_MASK	0x3
+#define		ARMADA_37XX_DVFS_LOAD_0		0
+#define		ARMADA_37XX_DVFS_LOAD_1		1
+#define		ARMADA_37XX_DVFS_LOAD_2		2
+#define		ARMADA_37XX_DVFS_LOAD_3		3
+
+/*
+ * On Armada 37xx the Power management manages 4 level of CPU load,
+ * each level can be associated with a CPU clock source, a CPU
+ * divider, a VDD level, etc...
+ */
+#define LOAD_LEVEL_NR	4
+
+struct armada_37xx_dvfs {
+	u32 cpu_freq_max;
+	u8 divider[LOAD_LEVEL_NR];
+};
+
+static struct armada_37xx_dvfs armada_37xx_dvfs[] = {
+	{.cpu_freq_max = 1200*1000*1000, .divider = {1, 2, 4, 6} },
+	{.cpu_freq_max = 1000*1000*1000, .divider = {1, 2, 4, 5} },
+	{.cpu_freq_max = 800*1000*1000,  .divider = {1, 2, 3, 4} },
+	{.cpu_freq_max = 600*1000*1000,  .divider = {2, 4, 5, 6} },
+};
+
+static struct armada_37xx_dvfs *armada_37xx_cpu_freq_info_get(u32 freq)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(armada_37xx_dvfs); i++) {
+		if (freq == armada_37xx_dvfs[i].cpu_freq_max)
+			return &armada_37xx_dvfs[i];
+	}
+
+	pr_err("Unsupported CPU frequency %d MHz\n", freq/1000000);
+	return NULL;
+}
+
+/*
+ * Setup the four level managed by the hardware. Once the four level
+ * will be configured then the DVFS will be enabled.
+ */
+static void __init armada37xx_cpufreq_dvfs_setup(struct regmap *base,
+						 struct clk *clk, u8 *divider)
+{
+	int load_level;
+	struct clk *parent;
+
+	for (load_level = 0; load_level < LOAD_LEVEL_NR; load_level++) {
+		unsigned int reg, mask,  val, offset = 0;
+
+		if (load_level <= ARMADA_37XX_DVFS_LOAD_1)
+			reg = ARMADA_37XX_NB_L0L1;
+		else
+			reg = ARMADA_37XX_NB_L2L3;
+
+		if (load_level ==  ARMADA_37XX_DVFS_LOAD_0 ||
+		    load_level ==  ARMADA_37XX_DVFS_LOAD_2)
+			offset += ARMADA_37XX_NB_CONFIG_SHIFT;
+
+		/* Set cpu clock source, for all the level we use TBG */
+		val = ARMADA_37XX_NB_CLK_SEL_TBG << ARMADA_37XX_NB_CLK_SEL_OFF;
+		mask = (ARMADA_37XX_NB_CLK_SEL_MASK
+			<< ARMADA_37XX_NB_CLK_SEL_OFF);
+
+		/*
+		 * Set cpu divider based on the pre-computed array in
+		 * order to have balanced step.
+		 */
+		val |= divider[load_level] << ARMADA_37XX_NB_TBG_DIV_OFF;
+		mask |= (ARMADA_37XX_NB_TBG_DIV_MASK
+			<< ARMADA_37XX_NB_TBG_DIV_OFF);
+
+		/* Set VDD divider which is actually the load level. */
+		val |= load_level << ARMADA_37XX_NB_VDD_SEL_OFF;
+		mask |= (ARMADA_37XX_NB_VDD_SEL_MASK
+			<< ARMADA_37XX_NB_VDD_SEL_OFF);
+
+		val <<= offset;
+		mask <<= offset;
+
+		regmap_update_bits(base, reg, mask, val);
+	}
+
+	/*
+	 * Set cpu clock source, for all the level we keep the same
+	 * clock source that the one already configured. For this one
+	 * we need to use the clock framework
+	 */
+	parent = clk_get_parent(clk);
+	clk_set_parent(clk, parent);
+}
+
+static void __init armada37xx_cpufreq_disable_dvfs(struct regmap *base)
+{
+	unsigned int reg = ARMADA_37XX_NB_DYN_MOD,
+		mask = ARMADA_37XX_NB_DFS_EN;
+
+	regmap_update_bits(base, reg, mask, 0);
+}
+
+static void __init armada37xx_cpufreq_enable_dvfs(struct regmap *base)
+{
+	unsigned int val, reg = ARMADA_37XX_NB_CPU_LOAD,
+		mask = ARMADA_37XX_NB_CPU_LOAD_MASK;
+
+	/* Start with the highest load (0) */
+	val = ARMADA_37XX_DVFS_LOAD_0;
+	regmap_update_bits(base, reg, mask, val);
+
+	/* Now enable DVFS for the CPUs */
+	reg = ARMADA_37XX_NB_DYN_MOD;
+	mask =	ARMADA_37XX_NB_CLK_SEL_EN | ARMADA_37XX_NB_TBG_EN |
+		ARMADA_37XX_NB_DIV_EN | ARMADA_37XX_NB_VDD_EN |
+		ARMADA_37XX_NB_DFS_EN;
+
+	regmap_update_bits(base, reg, mask, mask);
+}
+
+static int __init armada37xx_cpufreq_driver_init(void)
+{
+	struct armada_37xx_dvfs *dvfs;
+	struct platform_device *pdev;
+	unsigned int cur_frequency;
+	struct regmap *nb_pm_base;
+	struct device *cpu_dev;
+	int load_level, ret;
+	struct clk *clk;
+
+	nb_pm_base =
+		syscon_regmap_lookup_by_compatible("marvell,armada-3700-nb-pm");
+
+	if (IS_ERR(nb_pm_base))
+		return -ENODEV;
+
+	/* Before doing any configuration on the DVFS first, disable it */
+	armada37xx_cpufreq_disable_dvfs(nb_pm_base);
+
+	/*
+	 * On CPU 0 register the operating points supported (which are
+	 * the nominal CPU frequency and full integer divisions of
+	 * it).
+	 */
+	cpu_dev = get_cpu_device(0);
+	if (!cpu_dev) {
+		dev_err(cpu_dev, "Cannot get CPU\n");
+		return -ENODEV;
+	}
+
+	clk = clk_get(cpu_dev, 0);
+	if (IS_ERR(clk)) {
+		dev_err(cpu_dev, "Cannot get clock for CPU0\n");
+		return PTR_ERR(clk);
+	}
+
+	/* Get nominal (current) CPU frequency */
+	cur_frequency = clk_get_rate(clk);
+	if (!cur_frequency) {
+		dev_err(cpu_dev, "Failed to get clock rate for CPU\n");
+		return -EINVAL;
+	}
+
+	dvfs = armada_37xx_cpu_freq_info_get(cur_frequency);
+	if (!dvfs)
+		return -EINVAL;
+
+	armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider);
+
+	/*
+	 * In case of a failure of dev_pm_opp_add(), we don't bother
+	 * with cleaning up the registered OPP (there's no function to
+	 * do so), and simply cancel the registration of the cpufreq
+	 * device.
+	 */
+	for (load_level = ARMADA_37XX_DVFS_LOAD_0; load_level < LOAD_LEVEL_NR;
+	     load_level++) {
+		unsigned long freq = dvfs->divider[load_level];
+
+		ret = dev_pm_opp_add(cpu_dev, freq, 0);
+		if (ret)
+			return ret;
+	}
+
+	/* Now that everything is setup, enable the DVFS at hardware level */
+	armada37xx_cpufreq_enable_dvfs(nb_pm_base);
+
+	pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+
+	return PTR_ERR_OR_ZERO(pdev);
+}
+/* late_initcall, to guarantee the driver is loaded after A37xx clock driver */
+late_initcall(armada37xx_cpufreq_driver_init);
+
+MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
+MODULE_DESCRIPTION("Armada 37xx cpufreq driver");
+MODULE_LICENSE("GPL");
-- 
2.15.0

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

* [PATCH 6/6] arm64: dts: marvell: armada-37xx: add nodes allowing cpufreq support
  2017-12-01 11:25 [PATCH 0/6] Add CPU Frequency scaling support on Armada 37xx Gregory CLEMENT
                   ` (4 preceding siblings ...)
  2017-12-01 11:25 ` [PATCH 5/6] cpufreq: Add DVFS support for Armada 37xx Gregory CLEMENT
@ 2017-12-01 11:25 ` Gregory CLEMENT
  5 siblings, 0 replies; 15+ messages in thread
From: Gregory CLEMENT @ 2017-12-01 11:25 UTC (permalink / raw)
  To: Rafael J. Wysocki, Viresh Kumar, linux-pm
  Cc: Jason Cooper, Andrew Lunn, Sebastian Hesselbarth,
	Gregory CLEMENT, Rob Herring, devicetree, Thomas Petazzoni,
	linux-arm-kernel, Antoine Tenart, Miquèl Raynal,
	Nadav Haklai, Victor Gu, Marcin Wojtas, Wilson Ding, Hua Jing,
	Neta Zur Hershkovits, Evan Wang

In order to be able to use cpu freq, we need to associate a clock to each
CPU and to expose the power management registers.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm64/boot/dts/marvell/armada-372x.dtsi | 1 +
 arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 7 +++++++
 2 files changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/marvell/armada-372x.dtsi b/arch/arm64/boot/dts/marvell/armada-372x.dtsi
index 59d7557d3b1b..2554e0baea6b 100644
--- a/arch/arm64/boot/dts/marvell/armada-372x.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-372x.dtsi
@@ -56,6 +56,7 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a53","arm,armv8";
 			reg = <0x1>;
+			clocks = <&nb_periph_clk 16>;
 			enable-method = "psci";
 		};
 	};
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index 90c26d616a54..6e51ed54d75c 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -65,6 +65,7 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a53", "arm,armv8";
 			reg = <0>;
+			clocks = <&nb_periph_clk 16>;
 			enable-method = "psci";
 		};
 	};
@@ -234,6 +235,12 @@
 				};
 			};
 
+			nb_pm: nb_pm@14000 {
+				compatible = "marvell,armada-3700-nb-pm",
+					     "syscon";
+				reg = <0x14000 0x60>;
+			};
+
 			pinctrl_sb: pinctrl@18800 {
 				compatible = "marvell,armada3710-sb-pinctrl",
 					     "syscon", "simple-mfd";
-- 
2.15.0

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

* Re: [PATCH 2/6] cpufreq: ARM: sort the Kconfig menu
  2017-12-01 11:25 ` [PATCH 2/6] cpufreq: ARM: sort the Kconfig menu Gregory CLEMENT
@ 2017-12-04  8:41   ` Viresh Kumar
  2017-12-06 11:52     ` Gregory CLEMENT
  0 siblings, 1 reply; 15+ messages in thread
From: Viresh Kumar @ 2017-12-04  8:41 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Rafael J. Wysocki, linux-pm, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Rob Herring, devicetree, Thomas Petazzoni,
	linux-arm-kernel, Antoine Tenart, Miquèl Raynal,
	Nadav Haklai, Victor Gu, Marcin Wojtas, Wilson Ding, Hua Jing,
	Neta Zur Hershkovits, Evan Wang

On 01-12-17, 12:25, Gregory CLEMENT wrote:
> +config ARM_VEXPRESS_SPC_CPUFREQ
> +        tristate "Versatile Express SPC based CPUfreq driver"
> +	depends on ARM_BIG_LITTLE_CPUFREQ && ARCH_VEXPRESS_SPC
> +        help
> +          This add the CPUfreq driver support for Versatile Express
> +	  big.LITTLE platforms using SPC for power management.
> +
> +config ARM_SCPI_CPUFREQ

The order of above two must be reversed ?

-- 
viresh

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

* Re: [PATCH 3/6] cpufreq: sort the drivers in ARM part
  2017-12-01 11:25 ` [PATCH 3/6] cpufreq: sort the drivers in ARM part Gregory CLEMENT
@ 2017-12-04  9:18   ` Viresh Kumar
  2017-12-06 12:09     ` Gregory CLEMENT
  0 siblings, 1 reply; 15+ messages in thread
From: Viresh Kumar @ 2017-12-04  9:18 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Rafael J. Wysocki, linux-pm, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Rob Herring, devicetree, Thomas Petazzoni,
	linux-arm-kernel, Antoine Tenart, Miquèl Raynal,
	Nadav Haklai, Victor Gu, Marcin Wojtas, Wilson Ding, Hua Jing,
	Neta Zur Hershkovits, Evan Wang

On 01-12-17, 12:25, Gregory CLEMENT wrote:
> Keep the driver files alphabetically sorted.
> 
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
>  drivers/cpufreq/Makefile | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
> index 812f9e0d01a3..d762e76887e7 100644
> --- a/drivers/cpufreq/Makefile
> +++ b/drivers/cpufreq/Makefile
> @@ -53,22 +53,24 @@ obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ)	+= arm_big_little.o
>  obj-$(CONFIG_ARM_DT_BL_CPUFREQ)		+= arm_big_little_dt.o
>  
>  obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ)	+= brcmstb-avs-cpufreq.o
> +obj-$(CONFIG_ACPI_CPPC_CPUFREQ)		+= cppc_cpufreq.o

Shouldn't we add them in ascending order of the whole config name and not just
CPPC_CPUFREQ ?

-- 
viresh

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

* Re: [PATCH 1/6] dt-bindings: marvell: Add documentation for the North Bridge PM on Armada 37xx
  2017-12-01 11:25 ` [PATCH 1/6] dt-bindings: marvell: Add documentation for the North Bridge PM " Gregory CLEMENT
@ 2017-12-04 21:47   ` Rob Herring
  2017-12-06 11:51     ` Gregory CLEMENT
  0 siblings, 1 reply; 15+ messages in thread
From: Rob Herring @ 2017-12-04 21:47 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Rafael J. Wysocki, Viresh Kumar, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, devicetree, Thomas Petazzoni,
	linux-arm-kernel, Antoine Tenart, Miquèl Raynal,
	Nadav Haklai, Victor Gu, Marcin Wojtas, Wilson Ding, Hua Jing,
	Neta Zur Hershkovits, Evan Wang

On Fri, Dec 01, 2017 at 12:25:03PM +0100, Gregory CLEMENT wrote:
> Extend the documentation of the Armada 37xx SoC with the the North
> Bridge Power Management component.
> 
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
>  .../devicetree/bindings/arm/marvell/armada-37xx.txt   | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt b/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt
> index 51336e5fc761..7ad9830d9177 100644
> --- a/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt
> +++ b/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt
> @@ -14,3 +14,22 @@ following property before the previous one:
>  Example:
>  
>  compatible = "marvell,armada-3720-db", "marvell,armada3720", "marvell,armada3710";
> +
> +
> +Power management
> +----------------
> +
> +For power management (particularly DVFS and AVS), the North Bridge
> +Power Management component is needed:
> +
> +Required properties:
> +- compatible     : should contain "marvell,armada-3700-nb-pm", "syscon";
> +- reg            : the register start and length for the North Bridge
> +		    Power Management
> +
> +Example:
> +
> +nb_pm: nb_pm@14000 {

Don't use underscore in node or property names. "syscon" is a better 
choice here.

> +	compatible = "marvell,armada-3700-nb-pm", "syscon";
> +	reg = <0x14000 0x60>;
> +}
> -- 
> 2.15.0
> 

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

* Re: [PATCH 5/6] cpufreq: Add DVFS support for Armada 37xx
  2017-12-01 11:25 ` [PATCH 5/6] cpufreq: Add DVFS support for Armada 37xx Gregory CLEMENT
@ 2017-12-05  5:54   ` Viresh Kumar
  2017-12-06 12:24     ` Gregory CLEMENT
  0 siblings, 1 reply; 15+ messages in thread
From: Viresh Kumar @ 2017-12-05  5:54 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Rafael J. Wysocki, linux-pm, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Rob Herring, devicetree, Thomas Petazzoni,
	linux-arm-kernel, Antoine Tenart, Miquèl Raynal,
	Nadav Haklai, Victor Gu, Marcin Wojtas, Wilson Ding, Hua Jing,
	Neta Zur Hershkovits, Evan Wang

On 01-12-17, 12:25, Gregory CLEMENT wrote:
> This patch adds DVFS support for the Armada 37xx SoCs
> 
> There are up to four CPU frequency loads for Armada 37xx controlled by
> the hardware.
> 
> This driver associates the CPU load level to a frequency, then the
> hardware will switch while selecting a load level.
> 
> The hardware also can associate a voltage for each level (AVS support)
> but it is not yet supported
> 
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
>  drivers/cpufreq/Kconfig.arm           |   7 +
>  drivers/cpufreq/Makefile              |   1 +
>  drivers/cpufreq/armada-37xx-cpufreq.c | 241 ++++++++++++++++++++++++++++++++++
>  3 files changed, 249 insertions(+)
>  create mode 100644 drivers/cpufreq/armada-37xx-cpufreq.c
> 
> diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
> index 17625115c67f..3018ff0d068f 100644
> --- a/drivers/cpufreq/Kconfig.arm
> +++ b/drivers/cpufreq/Kconfig.arm
> @@ -19,6 +19,13 @@ config ACPI_CPPC_CPUFREQ
>  
>  	  If in doubt, say N.
>  
> +config ARM_ARMADA_37XX_CPUFREQ
> +	tristate "Armada 37xx CPUFreq support"
> +	depends on ARCH_MVEBU
> +	help
> +	  This adds the CPUFreq driver support for Marvell Armada 37xx SoCs.
> +	  The Armada 37xx PMU supports 4 frequency and VDD levels.
> +
>  # big LITTLE core layer and glue drivers
>  config ARM_BIG_LITTLE_CPUFREQ
>  	tristate "Generic ARM big LITTLE CPUfreq driver"
> diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
> index d762e76887e7..e07715ce8844 100644
> --- a/drivers/cpufreq/Makefile
> +++ b/drivers/cpufreq/Makefile
> @@ -52,6 +52,7 @@ obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ)	+= arm_big_little.o
>  # LITTLE drivers, so that it is probed last.
>  obj-$(CONFIG_ARM_DT_BL_CPUFREQ)		+= arm_big_little_dt.o
>  
> +obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ)	+= armada-37xx-cpufreq.o
>  obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ)	+= brcmstb-avs-cpufreq.o
>  obj-$(CONFIG_ACPI_CPPC_CPUFREQ)		+= cppc_cpufreq.o
>  obj-$(CONFIG_ARCH_DAVINCI)		+= davinci-cpufreq.o
> diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c
> new file mode 100644
> index 000000000000..40c9a744cc6e
> --- /dev/null
> +++ b/drivers/cpufreq/armada-37xx-cpufreq.c
> @@ -0,0 +1,241 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * CPU frequency scaling support for Armada 37xx platform.
> + *
> + * Copyright (C) 2017 Marvell
> + *
> + * Gregory CLEMENT <gregory.clement@free-electrons.com>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/cpu.h>
> +#include <linux/cpufreq.h>
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_opp.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +
> +/* Power management in North Bridge register set */
> +#define ARMADA_37XX_NB_L0L1	0x18
> +#define ARMADA_37XX_NB_L2L3	0x1C
> +#define		ARMADA_37XX_NB_TBG_DIV_OFF	13
> +#define		ARMADA_37XX_NB_TBG_DIV_MASK	0x7
> +#define		ARMADA_37XX_NB_CLK_SEL_OFF	11
> +#define		ARMADA_37XX_NB_CLK_SEL_MASK	0x1
> +#define		ARMADA_37XX_NB_CLK_SEL_TBG      0x1
> +#define		ARMADA_37XX_NB_TBG_SEL_OFF	9
> +#define		ARMADA_37XX_NB_TBG_SEL_MASK	0x3
> +#define		ARMADA_37XX_NB_VDD_SEL_OFF	6
> +#define		ARMADA_37XX_NB_VDD_SEL_MASK	0x3
> +#define		ARMADA_37XX_NB_CONFIG_SHIFT	16

Looks like you have added tabs after #define as well? Perhaps a space
is good enough there.

> +#define ARMADA_37XX_NB_DYN_MOD	0x24
> +#define		ARMADA_37XX_NB_CLK_SEL_EN	BIT(26)
> +#define		ARMADA_37XX_NB_TBG_EN		BIT(28)
> +#define		ARMADA_37XX_NB_DIV_EN		BIT(29)
> +#define		ARMADA_37XX_NB_VDD_EN		BIT(30)
> +#define		ARMADA_37XX_NB_DFS_EN		BIT(31)
> +#define ARMADA_37XX_NB_CPU_LOAD	0x30
> +#define		ARMADA_37XX_NB_CPU_LOAD_MASK	0x3
> +#define		ARMADA_37XX_DVFS_LOAD_0		0
> +#define		ARMADA_37XX_DVFS_LOAD_1		1
> +#define		ARMADA_37XX_DVFS_LOAD_2		2
> +#define		ARMADA_37XX_DVFS_LOAD_3		3
> +
> +/*
> + * On Armada 37xx the Power management manages 4 level of CPU load,
> + * each level can be associated with a CPU clock source, a CPU
> + * divider, a VDD level, etc...
> + */
> +#define LOAD_LEVEL_NR	4
> +
> +struct armada_37xx_dvfs {
> +	u32 cpu_freq_max;
> +	u8 divider[LOAD_LEVEL_NR];
> +};
> +
> +static struct armada_37xx_dvfs armada_37xx_dvfs[] = {
> +	{.cpu_freq_max = 1200*1000*1000, .divider = {1, 2, 4, 6} },
> +	{.cpu_freq_max = 1000*1000*1000, .divider = {1, 2, 4, 5} },
> +	{.cpu_freq_max = 800*1000*1000,  .divider = {1, 2, 3, 4} },
> +	{.cpu_freq_max = 600*1000*1000,  .divider = {2, 4, 5, 6} },
> +};
> +
> +static struct armada_37xx_dvfs *armada_37xx_cpu_freq_info_get(u32 freq)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(armada_37xx_dvfs); i++) {
> +		if (freq == armada_37xx_dvfs[i].cpu_freq_max)
> +			return &armada_37xx_dvfs[i];
> +	}
> +
> +	pr_err("Unsupported CPU frequency %d MHz\n", freq/1000000);
> +	return NULL;
> +}
> +
> +/*
> + * Setup the four level managed by the hardware. Once the four level
> + * will be configured then the DVFS will be enabled.
> + */
> +static void __init armada37xx_cpufreq_dvfs_setup(struct regmap *base,
> +						 struct clk *clk, u8 *divider)
> +{
> +	int load_level;
> +	struct clk *parent;
> +
> +	for (load_level = 0; load_level < LOAD_LEVEL_NR; load_level++) {
> +		unsigned int reg, mask,  val, offset = 0;
> +
> +		if (load_level <= ARMADA_37XX_DVFS_LOAD_1)
> +			reg = ARMADA_37XX_NB_L0L1;
> +		else
> +			reg = ARMADA_37XX_NB_L2L3;
> +
> +		if (load_level ==  ARMADA_37XX_DVFS_LOAD_0 ||
> +		    load_level ==  ARMADA_37XX_DVFS_LOAD_2)
> +			offset += ARMADA_37XX_NB_CONFIG_SHIFT;
> +
> +		/* Set cpu clock source, for all the level we use TBG */
> +		val = ARMADA_37XX_NB_CLK_SEL_TBG << ARMADA_37XX_NB_CLK_SEL_OFF;
> +		mask = (ARMADA_37XX_NB_CLK_SEL_MASK
> +			<< ARMADA_37XX_NB_CLK_SEL_OFF);
> +
> +		/*
> +		 * Set cpu divider based on the pre-computed array in
> +		 * order to have balanced step.
> +		 */
> +		val |= divider[load_level] << ARMADA_37XX_NB_TBG_DIV_OFF;
> +		mask |= (ARMADA_37XX_NB_TBG_DIV_MASK
> +			<< ARMADA_37XX_NB_TBG_DIV_OFF);
> +
> +		/* Set VDD divider which is actually the load level. */
> +		val |= load_level << ARMADA_37XX_NB_VDD_SEL_OFF;
> +		mask |= (ARMADA_37XX_NB_VDD_SEL_MASK
> +			<< ARMADA_37XX_NB_VDD_SEL_OFF);
> +
> +		val <<= offset;
> +		mask <<= offset;
> +
> +		regmap_update_bits(base, reg, mask, val);
> +	}
> +
> +	/*
> +	 * Set cpu clock source, for all the level we keep the same
> +	 * clock source that the one already configured. For this one
> +	 * we need to use the clock framework
> +	 */
> +	parent = clk_get_parent(clk);
> +	clk_set_parent(clk, parent);
> +}
> +
> +static void __init armada37xx_cpufreq_disable_dvfs(struct regmap *base)
> +{
> +	unsigned int reg = ARMADA_37XX_NB_DYN_MOD,
> +		mask = ARMADA_37XX_NB_DFS_EN;
> +
> +	regmap_update_bits(base, reg, mask, 0);
> +}
> +
> +static void __init armada37xx_cpufreq_enable_dvfs(struct regmap *base)
> +{
> +	unsigned int val, reg = ARMADA_37XX_NB_CPU_LOAD,
> +		mask = ARMADA_37XX_NB_CPU_LOAD_MASK;
> +
> +	/* Start with the highest load (0) */
> +	val = ARMADA_37XX_DVFS_LOAD_0;
> +	regmap_update_bits(base, reg, mask, val);
> +
> +	/* Now enable DVFS for the CPUs */
> +	reg = ARMADA_37XX_NB_DYN_MOD;
> +	mask =	ARMADA_37XX_NB_CLK_SEL_EN | ARMADA_37XX_NB_TBG_EN |
> +		ARMADA_37XX_NB_DIV_EN | ARMADA_37XX_NB_VDD_EN |
> +		ARMADA_37XX_NB_DFS_EN;
> +
> +	regmap_update_bits(base, reg, mask, mask);
> +}
> +
> +static int __init armada37xx_cpufreq_driver_init(void)
> +{
> +	struct armada_37xx_dvfs *dvfs;
> +	struct platform_device *pdev;
> +	unsigned int cur_frequency;
> +	struct regmap *nb_pm_base;
> +	struct device *cpu_dev;
> +	int load_level, ret;
> +	struct clk *clk;
> +
> +	nb_pm_base =
> +		syscon_regmap_lookup_by_compatible("marvell,armada-3700-nb-pm");
> +
> +	if (IS_ERR(nb_pm_base))
> +		return -ENODEV;
> +
> +	/* Before doing any configuration on the DVFS first, disable it */
> +	armada37xx_cpufreq_disable_dvfs(nb_pm_base);
> +
> +	/*
> +	 * On CPU 0 register the operating points supported (which are
> +	 * the nominal CPU frequency and full integer divisions of
> +	 * it).
> +	 */
> +	cpu_dev = get_cpu_device(0);
> +	if (!cpu_dev) {
> +		dev_err(cpu_dev, "Cannot get CPU\n");
> +		return -ENODEV;
> +	}
> +
> +	clk = clk_get(cpu_dev, 0);
> +	if (IS_ERR(clk)) {
> +		dev_err(cpu_dev, "Cannot get clock for CPU0\n");
> +		return PTR_ERR(clk);
> +	}
> +
> +	/* Get nominal (current) CPU frequency */
> +	cur_frequency = clk_get_rate(clk);
> +	if (!cur_frequency) {
> +		dev_err(cpu_dev, "Failed to get clock rate for CPU\n");
> +		return -EINVAL;
> +	}
> +
> +	dvfs = armada_37xx_cpu_freq_info_get(cur_frequency);
> +	if (!dvfs)
> +		return -EINVAL;
> +
> +	armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider);
> +
> +	/*
> +	 * In case of a failure of dev_pm_opp_add(), we don't bother
> +	 * with cleaning up the registered OPP (there's no function to
> +	 * do so),

What do you mean by the comment within ()? We do have
dev_pm_opp_remove() helper.

> and simply cancel the registration of the cpufreq
> +	 * device.
> +	 */
> +	for (load_level = ARMADA_37XX_DVFS_LOAD_0; load_level < LOAD_LEVEL_NR;
> +	     load_level++) {
> +		unsigned long freq = dvfs->divider[load_level];
> +
> +		ret = dev_pm_opp_add(cpu_dev, freq, 0);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	/* Now that everything is setup, enable the DVFS at hardware level */
> +	armada37xx_cpufreq_enable_dvfs(nb_pm_base);
> +
> +	pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
> +
> +	return PTR_ERR_OR_ZERO(pdev);
> +}
> +/* late_initcall, to guarantee the driver is loaded after A37xx clock driver */
> +late_initcall(armada37xx_cpufreq_driver_init);
> +
> +MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
> +MODULE_DESCRIPTION("Armada 37xx cpufreq driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.15.0

-- 
viresh

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

* Re: [PATCH 1/6] dt-bindings: marvell: Add documentation for the North Bridge PM on Armada 37xx
  2017-12-04 21:47   ` Rob Herring
@ 2017-12-06 11:51     ` Gregory CLEMENT
  0 siblings, 0 replies; 15+ messages in thread
From: Gregory CLEMENT @ 2017-12-06 11:51 UTC (permalink / raw)
  To: Rob Herring
  Cc: Rafael J. Wysocki, Viresh Kumar, linux-pm-u79uwXL29TY76Z2rM5mHXA,
	Jason Cooper, Andrew Lunn, Sebastian Hesselbarth,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Thomas Petazzoni,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Antoine Tenart, Miquèl Raynal, Nadav Haklai, Victor Gu,
	Marcin Wojtas, Wilson Ding, Hua Jing, Neta Zur Hershkovits,
	Evan Wang

Hi Rob,
 
 On lun., déc. 04 2017, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:

> On Fri, Dec 01, 2017 at 12:25:03PM +0100, Gregory CLEMENT wrote:
>> Extend the documentation of the Armada 37xx SoC with the the North
>> Bridge Power Management component.
>> 
>> Signed-off-by: Gregory CLEMENT <gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
>> ---
>>  .../devicetree/bindings/arm/marvell/armada-37xx.txt   | 19 +++++++++++++++++++
>>  1 file changed, 19 insertions(+)
>> 
>> diff --git a/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt b/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt
>> index 51336e5fc761..7ad9830d9177 100644
>> --- a/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt
>> +++ b/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt
>> @@ -14,3 +14,22 @@ following property before the previous one:
>>  Example:
>>  
>>  compatible = "marvell,armada-3720-db", "marvell,armada3720", "marvell,armada3710";
>> +
>> +
>> +Power management
>> +----------------
>> +
>> +For power management (particularly DVFS and AVS), the North Bridge
>> +Power Management component is needed:
>> +
>> +Required properties:
>> +- compatible     : should contain "marvell,armada-3700-nb-pm", "syscon";
>> +- reg            : the register start and length for the North Bridge
>> +		    Power Management
>> +
>> +Example:
>> +
>> +nb_pm: nb_pm@14000 {
>
> Don't use underscore in node or property names. "syscon" is a better 
> choice here.

OK I will change this.

Thanks,

Gregory

>
>> +	compatible = "marvell,armada-3700-nb-pm", "syscon";
>> +	reg = <0x14000 0x60>;
>> +}
>> -- 
>> 2.15.0
>> 

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
--
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] 15+ messages in thread

* Re: [PATCH 2/6] cpufreq: ARM: sort the Kconfig menu
  2017-12-04  8:41   ` Viresh Kumar
@ 2017-12-06 11:52     ` Gregory CLEMENT
  0 siblings, 0 replies; 15+ messages in thread
From: Gregory CLEMENT @ 2017-12-06 11:52 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Thomas Petazzoni, Andrew Lunn, Jason Cooper, linux-pm,
	Antoine Tenart, Rafael J. Wysocki, Evan Wang, Nadav Haklai,
	devicetree, Rob Herring, Neta Zur Hershkovits,
	Miquèl Raynal, Victor Gu, Hua Jing, Marcin Wojtas,
	Wilson Ding, linux-arm-kernel, Sebastian Hesselbarth

Hi Viresh,
 
 On lun., déc. 04 2017, Viresh Kumar <viresh.kumar@linaro.org> wrote:

> On 01-12-17, 12:25, Gregory CLEMENT wrote:
>> +config ARM_VEXPRESS_SPC_CPUFREQ
>> +        tristate "Versatile Express SPC based CPUfreq driver"
>> +	depends on ARM_BIG_LITTLE_CPUFREQ && ARCH_VEXPRESS_SPC
>> +        help
>> +          This add the CPUfreq driver support for Versatile Express
>> +	  big.LITTLE platforms using SPC for power management.
>> +
>> +config ARM_SCPI_CPUFREQ
>
> The order of above two must be reversed ?

Right, I will fix it.

Thanks,

Gregory


>
> -- 
> viresh

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 3/6] cpufreq: sort the drivers in ARM part
  2017-12-04  9:18   ` Viresh Kumar
@ 2017-12-06 12:09     ` Gregory CLEMENT
  0 siblings, 0 replies; 15+ messages in thread
From: Gregory CLEMENT @ 2017-12-06 12:09 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, linux-pm, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Rob Herring, devicetree, Thomas Petazzoni,
	linux-arm-kernel, Antoine Tenart, Miquèl Raynal,
	Nadav Haklai, Victor Gu, Marcin Wojtas, Wilson Ding, Hua Jing,
	Neta Zur Hershkovits, Evan Wang

Hi Viresh,
 
 On lun., déc. 04 2017, Viresh Kumar <viresh.kumar@linaro.org> wrote:

> On 01-12-17, 12:25, Gregory CLEMENT wrote:
>> Keep the driver files alphabetically sorted.
>> 
>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>> ---
>>  drivers/cpufreq/Makefile | 8 ++++----
>>  1 file changed, 4 insertions(+), 4 deletions(-)
>> 
>> diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
>> index 812f9e0d01a3..d762e76887e7 100644
>> --- a/drivers/cpufreq/Makefile
>> +++ b/drivers/cpufreq/Makefile
>> @@ -53,22 +53,24 @@ obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ)	+= arm_big_little.o
>>  obj-$(CONFIG_ARM_DT_BL_CPUFREQ)		+= arm_big_little_dt.o
>>  
>>  obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ)	+= brcmstb-avs-cpufreq.o
>> +obj-$(CONFIG_ACPI_CPPC_CPUFREQ)		+= cppc_cpufreq.o
>
> Shouldn't we add them in ascending order of the whole config name and not just
> CPPC_CPUFREQ ?

Here it is the object name that are sorted not the CONFIG_ name. So
cppc_cpufreq comes after brcmstb-avs-cpufreq.

Thanks,

Gregory

>
> -- 
> viresh

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 5/6] cpufreq: Add DVFS support for Armada 37xx
  2017-12-05  5:54   ` Viresh Kumar
@ 2017-12-06 12:24     ` Gregory CLEMENT
  0 siblings, 0 replies; 15+ messages in thread
From: Gregory CLEMENT @ 2017-12-06 12:24 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, linux-pm, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Rob Herring, devicetree, Thomas Petazzoni,
	linux-arm-kernel, Antoine Tenart, Miquèl Raynal,
	Nadav Haklai, Victor Gu, Marcin Wojtas, Wilson Ding, Hua Jing,
	Neta Zur Hershkovits, Evan Wang

Hi Viresh,
 
 On mar., déc. 05 2017, Viresh Kumar <viresh.kumar@linaro.org> wrote:

> On 01-12-17, 12:25, Gregory CLEMENT wrote:
>> This patch adds DVFS support for the Armada 37xx SoCs
>> 
>> There are up to four CPU frequency loads for Armada 37xx controlled by
>> the hardware.
>> 
>> This driver associates the CPU load level to a frequency, then the
>> hardware will switch while selecting a load level.
>> 
>> The hardware also can associate a voltage for each level (AVS support)
>> but it is not yet supported
>> 
>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>> ---
>>  drivers/cpufreq/Kconfig.arm           |   7 +
>>  drivers/cpufreq/Makefile              |   1 +
>>  drivers/cpufreq/armada-37xx-cpufreq.c | 241 ++++++++++++++++++++++++++++++++++
>>  3 files changed, 249 insertions(+)
>>  create mode 100644 drivers/cpufreq/armada-37xx-cpufreq.c
>> 
>> diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
>> index 17625115c67f..3018ff0d068f 100644
>> --- a/drivers/cpufreq/Kconfig.arm
>> +++ b/drivers/cpufreq/Kconfig.arm
>> @@ -19,6 +19,13 @@ config ACPI_CPPC_CPUFREQ
>>  
>>  	  If in doubt, say N.
>>  
>> +config ARM_ARMADA_37XX_CPUFREQ
>> +	tristate "Armada 37xx CPUFreq support"
>> +	depends on ARCH_MVEBU
>> +	help
>> +	  This adds the CPUFreq driver support for Marvell Armada 37xx SoCs.
>> +	  The Armada 37xx PMU supports 4 frequency and VDD levels.
>> +
>>  # big LITTLE core layer and glue drivers
>>  config ARM_BIG_LITTLE_CPUFREQ
>>  	tristate "Generic ARM big LITTLE CPUfreq driver"
>> diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
>> index d762e76887e7..e07715ce8844 100644
>> --- a/drivers/cpufreq/Makefile
>> +++ b/drivers/cpufreq/Makefile
>> @@ -52,6 +52,7 @@ obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ)	+= arm_big_little.o
>>  # LITTLE drivers, so that it is probed last.
>>  obj-$(CONFIG_ARM_DT_BL_CPUFREQ)		+= arm_big_little_dt.o
>>  
>> +obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ)	+= armada-37xx-cpufreq.o
>>  obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ)	+= brcmstb-avs-cpufreq.o
>>  obj-$(CONFIG_ACPI_CPPC_CPUFREQ)		+= cppc_cpufreq.o
>>  obj-$(CONFIG_ARCH_DAVINCI)		+= davinci-cpufreq.o
>> diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c
>> new file mode 100644
>> index 000000000000..40c9a744cc6e
>> --- /dev/null
>> +++ b/drivers/cpufreq/armada-37xx-cpufreq.c
>> @@ -0,0 +1,241 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * CPU frequency scaling support for Armada 37xx platform.
>> + *
>> + * Copyright (C) 2017 Marvell
>> + *
>> + * Gregory CLEMENT <gregory.clement@free-electrons.com>
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/cpu.h>
>> +#include <linux/cpufreq.h>
>> +#include <linux/err.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/io.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/module.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_device.h>
>> +#include <linux/of_irq.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pm_opp.h>
>> +#include <linux/regmap.h>
>> +#include <linux/slab.h>
>> +
>> +/* Power management in North Bridge register set */
>> +#define ARMADA_37XX_NB_L0L1	0x18
>> +#define ARMADA_37XX_NB_L2L3	0x1C
>> +#define		ARMADA_37XX_NB_TBG_DIV_OFF	13
>> +#define		ARMADA_37XX_NB_TBG_DIV_MASK	0x7
>> +#define		ARMADA_37XX_NB_CLK_SEL_OFF	11
>> +#define		ARMADA_37XX_NB_CLK_SEL_MASK	0x1
>> +#define		ARMADA_37XX_NB_CLK_SEL_TBG      0x1
>> +#define		ARMADA_37XX_NB_TBG_SEL_OFF	9
>> +#define		ARMADA_37XX_NB_TBG_SEL_MASK	0x3
>> +#define		ARMADA_37XX_NB_VDD_SEL_OFF	6
>> +#define		ARMADA_37XX_NB_VDD_SEL_MASK	0x3
>> +#define		ARMADA_37XX_NB_CONFIG_SHIFT	16
>
> Looks like you have added tabs after #define as well? Perhaps a space
> is good enough there.

OK

>
>> +#define ARMADA_37XX_NB_DYN_MOD	0x24
>> +#define		ARMADA_37XX_NB_CLK_SEL_EN	BIT(26)
>> +#define		ARMADA_37XX_NB_TBG_EN		BIT(28)
>> +#define		ARMADA_37XX_NB_DIV_EN		BIT(29)
>> +#define		ARMADA_37XX_NB_VDD_EN		BIT(30)
>> +#define		ARMADA_37XX_NB_DFS_EN		BIT(31)
>> +#define ARMADA_37XX_NB_CPU_LOAD	0x30
>> +#define		ARMADA_37XX_NB_CPU_LOAD_MASK	0x3
>> +#define		ARMADA_37XX_DVFS_LOAD_0		0
>> +#define		ARMADA_37XX_DVFS_LOAD_1		1
>> +#define		ARMADA_37XX_DVFS_LOAD_2		2
>> +#define		ARMADA_37XX_DVFS_LOAD_3		3
>> +
>> +/*
>> + * On Armada 37xx the Power management manages 4 level of CPU load,
>> + * each level can be associated with a CPU clock source, a CPU
>> + * divider, a VDD level, etc...
>> + */
>> +#define LOAD_LEVEL_NR	4
>> +
>> +struct armada_37xx_dvfs {
>> +	u32 cpu_freq_max;
>> +	u8 divider[LOAD_LEVEL_NR];
>> +};
>> +
>> +static struct armada_37xx_dvfs armada_37xx_dvfs[] = {
>> +	{.cpu_freq_max = 1200*1000*1000, .divider = {1, 2, 4, 6} },
>> +	{.cpu_freq_max = 1000*1000*1000, .divider = {1, 2, 4, 5} },
>> +	{.cpu_freq_max = 800*1000*1000,  .divider = {1, 2, 3, 4} },
>> +	{.cpu_freq_max = 600*1000*1000,  .divider = {2, 4, 5, 6} },
>> +};
>> +
>> +static struct armada_37xx_dvfs *armada_37xx_cpu_freq_info_get(u32 freq)
>> +{
>> +	int i;
>> +
>> +	for (i = 0; i < ARRAY_SIZE(armada_37xx_dvfs); i++) {
>> +		if (freq == armada_37xx_dvfs[i].cpu_freq_max)
>> +			return &armada_37xx_dvfs[i];
>> +	}
>> +
>> +	pr_err("Unsupported CPU frequency %d MHz\n", freq/1000000);
>> +	return NULL;
>> +}
>> +
>> +/*
>> + * Setup the four level managed by the hardware. Once the four level
>> + * will be configured then the DVFS will be enabled.
>> + */
>> +static void __init armada37xx_cpufreq_dvfs_setup(struct regmap *base,
>> +						 struct clk *clk, u8 *divider)
>> +{
>> +	int load_level;
>> +	struct clk *parent;
>> +
>> +	for (load_level = 0; load_level < LOAD_LEVEL_NR; load_level++) {
>> +		unsigned int reg, mask,  val, offset = 0;
>> +
>> +		if (load_level <= ARMADA_37XX_DVFS_LOAD_1)
>> +			reg = ARMADA_37XX_NB_L0L1;
>> +		else
>> +			reg = ARMADA_37XX_NB_L2L3;
>> +
>> +		if (load_level ==  ARMADA_37XX_DVFS_LOAD_0 ||
>> +		    load_level ==  ARMADA_37XX_DVFS_LOAD_2)
>> +			offset += ARMADA_37XX_NB_CONFIG_SHIFT;
>> +
>> +		/* Set cpu clock source, for all the level we use TBG */
>> +		val = ARMADA_37XX_NB_CLK_SEL_TBG << ARMADA_37XX_NB_CLK_SEL_OFF;
>> +		mask = (ARMADA_37XX_NB_CLK_SEL_MASK
>> +			<< ARMADA_37XX_NB_CLK_SEL_OFF);
>> +
>> +		/*
>> +		 * Set cpu divider based on the pre-computed array in
>> +		 * order to have balanced step.
>> +		 */
>> +		val |= divider[load_level] << ARMADA_37XX_NB_TBG_DIV_OFF;
>> +		mask |= (ARMADA_37XX_NB_TBG_DIV_MASK
>> +			<< ARMADA_37XX_NB_TBG_DIV_OFF);
>> +
>> +		/* Set VDD divider which is actually the load level. */
>> +		val |= load_level << ARMADA_37XX_NB_VDD_SEL_OFF;
>> +		mask |= (ARMADA_37XX_NB_VDD_SEL_MASK
>> +			<< ARMADA_37XX_NB_VDD_SEL_OFF);
>> +
>> +		val <<= offset;
>> +		mask <<= offset;
>> +
>> +		regmap_update_bits(base, reg, mask, val);
>> +	}
>> +
>> +	/*
>> +	 * Set cpu clock source, for all the level we keep the same
>> +	 * clock source that the one already configured. For this one
>> +	 * we need to use the clock framework
>> +	 */
>> +	parent = clk_get_parent(clk);
>> +	clk_set_parent(clk, parent);
>> +}
>> +
>> +static void __init armada37xx_cpufreq_disable_dvfs(struct regmap *base)
>> +{
>> +	unsigned int reg = ARMADA_37XX_NB_DYN_MOD,
>> +		mask = ARMADA_37XX_NB_DFS_EN;
>> +
>> +	regmap_update_bits(base, reg, mask, 0);
>> +}
>> +
>> +static void __init armada37xx_cpufreq_enable_dvfs(struct regmap *base)
>> +{
>> +	unsigned int val, reg = ARMADA_37XX_NB_CPU_LOAD,
>> +		mask = ARMADA_37XX_NB_CPU_LOAD_MASK;
>> +
>> +	/* Start with the highest load (0) */
>> +	val = ARMADA_37XX_DVFS_LOAD_0;
>> +	regmap_update_bits(base, reg, mask, val);
>> +
>> +	/* Now enable DVFS for the CPUs */
>> +	reg = ARMADA_37XX_NB_DYN_MOD;
>> +	mask =	ARMADA_37XX_NB_CLK_SEL_EN | ARMADA_37XX_NB_TBG_EN |
>> +		ARMADA_37XX_NB_DIV_EN | ARMADA_37XX_NB_VDD_EN |
>> +		ARMADA_37XX_NB_DFS_EN;
>> +
>> +	regmap_update_bits(base, reg, mask, mask);
>> +}
>> +
>> +static int __init armada37xx_cpufreq_driver_init(void)
>> +{
>> +	struct armada_37xx_dvfs *dvfs;
>> +	struct platform_device *pdev;
>> +	unsigned int cur_frequency;
>> +	struct regmap *nb_pm_base;
>> +	struct device *cpu_dev;
>> +	int load_level, ret;
>> +	struct clk *clk;
>> +
>> +	nb_pm_base =
>> +		syscon_regmap_lookup_by_compatible("marvell,armada-3700-nb-pm");
>> +
>> +	if (IS_ERR(nb_pm_base))
>> +		return -ENODEV;
>> +
>> +	/* Before doing any configuration on the DVFS first, disable it */
>> +	armada37xx_cpufreq_disable_dvfs(nb_pm_base);
>> +
>> +	/*
>> +	 * On CPU 0 register the operating points supported (which are
>> +	 * the nominal CPU frequency and full integer divisions of
>> +	 * it).
>> +	 */
>> +	cpu_dev = get_cpu_device(0);
>> +	if (!cpu_dev) {
>> +		dev_err(cpu_dev, "Cannot get CPU\n");
>> +		return -ENODEV;
>> +	}
>> +
>> +	clk = clk_get(cpu_dev, 0);
>> +	if (IS_ERR(clk)) {
>> +		dev_err(cpu_dev, "Cannot get clock for CPU0\n");
>> +		return PTR_ERR(clk);
>> +	}
>> +
>> +	/* Get nominal (current) CPU frequency */
>> +	cur_frequency = clk_get_rate(clk);
>> +	if (!cur_frequency) {
>> +		dev_err(cpu_dev, "Failed to get clock rate for CPU\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	dvfs = armada_37xx_cpu_freq_info_get(cur_frequency);
>> +	if (!dvfs)
>> +		return -EINVAL;
>> +
>> +	armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider);
>> +
>> +	/*
>> +	 * In case of a failure of dev_pm_opp_add(), we don't bother
>> +	 * with cleaning up the registered OPP (there's no function to
>> +	 * do so),
>
> What do you mean by the comment within ()? We do have
> dev_pm_opp_remove() helper.

Actually it was a copy and paste from an other driver, I didn't check it
this was still true.
So the original comment was added in July 2014 and the
dev_pm_opp_remove() helpers was added few months later
in Nov 2014.

I will fix it and also in the other driver mvebu-cpufreq.c.

Thanks,

Gregory



>
>> and simply cancel the registration of the cpufreq
>> +	 * device.
>> +	 */
>> +	for (load_level = ARMADA_37XX_DVFS_LOAD_0; load_level < LOAD_LEVEL_NR;
>> +	     load_level++) {
>> +		unsigned long freq = dvfs->divider[load_level];
>> +
>> +		ret = dev_pm_opp_add(cpu_dev, freq, 0);
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
>> +	/* Now that everything is setup, enable the DVFS at hardware level */
>> +	armada37xx_cpufreq_enable_dvfs(nb_pm_base);
>> +
>> +	pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
>> +
>> +	return PTR_ERR_OR_ZERO(pdev);
>> +}
>> +/* late_initcall, to guarantee the driver is loaded after A37xx clock driver */
>> +late_initcall(armada37xx_cpufreq_driver_init);
>> +
>> +MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
>> +MODULE_DESCRIPTION("Armada 37xx cpufreq driver");
>> +MODULE_LICENSE("GPL");
>> -- 
>> 2.15.0
>
> -- 
> viresh

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

end of thread, other threads:[~2017-12-06 12:24 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-01 11:25 [PATCH 0/6] Add CPU Frequency scaling support on Armada 37xx Gregory CLEMENT
2017-12-01 11:25 ` [PATCH 1/6] dt-bindings: marvell: Add documentation for the North Bridge PM " Gregory CLEMENT
2017-12-04 21:47   ` Rob Herring
2017-12-06 11:51     ` Gregory CLEMENT
2017-12-01 11:25 ` [PATCH 2/6] cpufreq: ARM: sort the Kconfig menu Gregory CLEMENT
2017-12-04  8:41   ` Viresh Kumar
2017-12-06 11:52     ` Gregory CLEMENT
2017-12-01 11:25 ` [PATCH 3/6] cpufreq: sort the drivers in ARM part Gregory CLEMENT
2017-12-04  9:18   ` Viresh Kumar
2017-12-06 12:09     ` Gregory CLEMENT
     [not found] ` <20171201112508.14121-1-gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2017-12-01 11:25   ` [PATCH 4/6] MAINTAINERS: add new entries for Armada 37xx cpufreq driver Gregory CLEMENT
2017-12-01 11:25 ` [PATCH 5/6] cpufreq: Add DVFS support for Armada 37xx Gregory CLEMENT
2017-12-05  5:54   ` Viresh Kumar
2017-12-06 12:24     ` Gregory CLEMENT
2017-12-01 11:25 ` [PATCH 6/6] arm64: dts: marvell: armada-37xx: add nodes allowing cpufreq support Gregory CLEMENT

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).