All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/4] Exynos Adaptive Supply Voltage support
       [not found] <CGME20191016145806eucas1p2d522901fc79e1ca6e03f1bb516a81370@eucas1p2.samsung.com>
@ 2019-10-16 14:57   ` Sylwester Nawrocki
  0 siblings, 0 replies; 28+ messages in thread
From: Sylwester Nawrocki @ 2019-10-16 14:57 UTC (permalink / raw)
  To: krzk, vireshk, robh+dt
  Cc: sboyd, roger.lu, linux-pm, linux-arm-kernel, linux-samsung-soc,
	devicetree, b.zolnierkie, m.szyprowski, Sylwester Nawrocki

This patch series adds ASV (Adaptive Supply Voltage) support
for Exynos SoCs. Previous version can be found at:
https://lore.kernel.org/linux-arm-kernel/20190917181322.GA683@bogus/t/

The first one is a patch for drivers/opp adding support for adjusting
OPP voltage at runtime [1], including my update to also handle OPP min/max
voltage.

The dt-bindings patch has been converted to YAML and needs to be aplied
to Rob's tree as it depends on a patch already applied there
("daa629cdba21 dt-bindings: arm: samsung: Convert Exynos Chipid bindings
to json-schema").

Already applied dts patches were dropped from the series.

The patch set is based on for-next branch,
git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git

Tested on Odroid XU3, XU3 Lite, XU4.

[1] "[PATCH v4 6/8] PM / OPP: Support adjusting OPP voltages at runtime"
    https://lore.kernel.org/linux-arm-kernel/1565703113-31479-7-git-send-email-andrew-sh.cheng@mediatek.com

Stephen Boyd (1):
  PM / OPP: Support adjusting OPP voltages at runtime

Sylwester Nawrocki (3):
  dt-bindings: arm: samsung: Update the CHIPID binding for ASV
  soc: samsung: Add Exynos Adaptive Supply Voltage driver
  ARM: EXYNOS: Enable exynos-asv driver for ARCH_EXYNOS

 .../bindings/arm/samsung/exynos-chipid.yaml   |  31 +-
 arch/arm/mach-exynos/Kconfig                  |   1 +
 drivers/opp/core.c                            |  69 +++
 drivers/soc/samsung/Kconfig                   |  10 +
 drivers/soc/samsung/Makefile                  |   3 +
 drivers/soc/samsung/exynos-asv.c              | 179 ++++++
 drivers/soc/samsung/exynos-asv.h              |  82 +++
 drivers/soc/samsung/exynos5422-asv.c          | 509 ++++++++++++++++++
 drivers/soc/samsung/exynos5422-asv.h          |  25 +
 include/linux/pm_opp.h                        |  13 +
 10 files changed, 919 insertions(+), 3 deletions(-)
 create mode 100644 drivers/soc/samsung/exynos-asv.c
 create mode 100644 drivers/soc/samsung/exynos-asv.h
 create mode 100644 drivers/soc/samsung/exynos5422-asv.c
 create mode 100644 drivers/soc/samsung/exynos5422-asv.h

--
2.17.1


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

* [PATCH v5 0/4] Exynos Adaptive Supply Voltage support
@ 2019-10-16 14:57   ` Sylwester Nawrocki
  0 siblings, 0 replies; 28+ messages in thread
From: Sylwester Nawrocki @ 2019-10-16 14:57 UTC (permalink / raw)
  To: krzk, vireshk, robh+dt
  Cc: devicetree, linux-samsung-soc, linux-pm, sboyd, b.zolnierkie,
	roger.lu, Sylwester Nawrocki, linux-arm-kernel, m.szyprowski

This patch series adds ASV (Adaptive Supply Voltage) support
for Exynos SoCs. Previous version can be found at:
https://lore.kernel.org/linux-arm-kernel/20190917181322.GA683@bogus/t/

The first one is a patch for drivers/opp adding support for adjusting
OPP voltage at runtime [1], including my update to also handle OPP min/max
voltage.

The dt-bindings patch has been converted to YAML and needs to be aplied
to Rob's tree as it depends on a patch already applied there
("daa629cdba21 dt-bindings: arm: samsung: Convert Exynos Chipid bindings
to json-schema").

Already applied dts patches were dropped from the series.

The patch set is based on for-next branch,
git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git

Tested on Odroid XU3, XU3 Lite, XU4.

[1] "[PATCH v4 6/8] PM / OPP: Support adjusting OPP voltages at runtime"
    https://lore.kernel.org/linux-arm-kernel/1565703113-31479-7-git-send-email-andrew-sh.cheng@mediatek.com

Stephen Boyd (1):
  PM / OPP: Support adjusting OPP voltages at runtime

Sylwester Nawrocki (3):
  dt-bindings: arm: samsung: Update the CHIPID binding for ASV
  soc: samsung: Add Exynos Adaptive Supply Voltage driver
  ARM: EXYNOS: Enable exynos-asv driver for ARCH_EXYNOS

 .../bindings/arm/samsung/exynos-chipid.yaml   |  31 +-
 arch/arm/mach-exynos/Kconfig                  |   1 +
 drivers/opp/core.c                            |  69 +++
 drivers/soc/samsung/Kconfig                   |  10 +
 drivers/soc/samsung/Makefile                  |   3 +
 drivers/soc/samsung/exynos-asv.c              | 179 ++++++
 drivers/soc/samsung/exynos-asv.h              |  82 +++
 drivers/soc/samsung/exynos5422-asv.c          | 509 ++++++++++++++++++
 drivers/soc/samsung/exynos5422-asv.h          |  25 +
 include/linux/pm_opp.h                        |  13 +
 10 files changed, 919 insertions(+), 3 deletions(-)
 create mode 100644 drivers/soc/samsung/exynos-asv.c
 create mode 100644 drivers/soc/samsung/exynos-asv.h
 create mode 100644 drivers/soc/samsung/exynos5422-asv.c
 create mode 100644 drivers/soc/samsung/exynos5422-asv.h

--
2.17.1


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

* [PATCH v5 1/4] PM / OPP: Support adjusting OPP voltages at runtime
       [not found]   ` <CGME20191016145810eucas1p1b31400c9b2e7f30cdf6deeb4ccee2788@eucas1p1.samsung.com>
@ 2019-10-16 14:57       ` Sylwester Nawrocki
  0 siblings, 0 replies; 28+ messages in thread
From: Sylwester Nawrocki @ 2019-10-16 14:57 UTC (permalink / raw)
  To: krzk, vireshk, robh+dt
  Cc: sboyd, roger.lu, linux-pm, linux-arm-kernel, linux-samsung-soc,
	devicetree, b.zolnierkie, m.szyprowski, Stephen Boyd,
	Sylwester Nawrocki

From: Stephen Boyd <sboyd@codeaurora.org>

On some SoCs the Adaptive Voltage Scaling (AVS) technique is
employed to optimize the operating voltage of a device. At a
given frequency, the hardware monitors dynamic factors and either
makes a suggestion for how much to adjust a voltage for the
current frequency, or it automatically adjusts the voltage
without software intervention. Add an API to the OPP library for
the former case, so that AVS type devices can update the voltages
for an OPP when the hardware determines the voltage should
change. The assumption is that drivers like CPUfreq or devfreq
will register for the OPP notifiers and adjust the voltage
according to suggestions that AVS makes.

This patch is derived from [1] submitted by Stephen.
[1] https://lore.kernel.org/patchwork/patch/599279/

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Roger Lu <roger.lu@mediatek.com>
[s.nawrocki@samsung.com: added handling of OPP min/max voltage]
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 drivers/opp/core.c     | 69 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/pm_opp.h | 13 ++++++++
 2 files changed, 82 insertions(+)

diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 3b7ffd0234e9..f38b3be85072 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -2112,6 +2112,75 @@ static int _opp_set_availability(struct device *dev, unsigned long freq,
 	return r;
 }

+/**
+ * dev_pm_opp_adjust_voltage() - helper to change the voltage of an OPP
+ * @dev:		device for which we do this operation
+ * @freq:		OPP frequency to adjust voltage of
+ * @u_volt:		new OPP target voltage
+ * @u_volt_min:		new OPP min voltage
+ * @u_volt_max:		new OPP max voltage
+ *
+ * Return: -EINVAL for bad pointers, -ENOMEM if no memory available for the
+ * copy operation, returns 0 if no modifcation was done OR modification was
+ * successful.
+ */
+int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
+			      unsigned long u_volt, unsigned long u_volt_min,
+			      unsigned long u_volt_max)
+
+{
+	struct opp_table *opp_table;
+	struct dev_pm_opp *tmp_opp, *opp = ERR_PTR(-ENODEV);
+	int r = 0;
+
+	/* Find the opp_table */
+	opp_table = _find_opp_table(dev);
+	if (IS_ERR(opp_table)) {
+		r = PTR_ERR(opp_table);
+		dev_warn(dev, "%s: Device OPP not found (%d)\n", __func__, r);
+		return r;
+	}
+
+	mutex_lock(&opp_table->lock);
+
+	/* Do we have the frequency? */
+	list_for_each_entry(tmp_opp, &opp_table->opp_list, node) {
+		if (tmp_opp->rate == freq) {
+			opp = tmp_opp;
+			break;
+		}
+	}
+
+	if (IS_ERR(opp)) {
+		r = PTR_ERR(opp);
+		goto adjust_unlock;
+	}
+
+	/* Is update really needed? */
+	if (opp->supplies->u_volt == u_volt)
+		goto adjust_unlock;
+
+	opp->supplies->u_volt = u_volt;
+	opp->supplies->u_volt_min = u_volt_min;
+	opp->supplies->u_volt_max = u_volt_max;
+
+	dev_pm_opp_get(opp);
+	mutex_unlock(&opp_table->lock);
+
+	/* Notify the voltage change of the OPP */
+	blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_ADJUST_VOLTAGE,
+				     opp);
+
+	dev_pm_opp_put(opp);
+	goto adjust_put_table;
+
+adjust_unlock:
+	mutex_unlock(&opp_table->lock);
+adjust_put_table:
+	dev_pm_opp_put_opp_table(opp_table);
+	return r;
+}
+
 /**
  * dev_pm_opp_enable() - Enable a specific OPP
  * @dev:	device for which we do this operation
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index b8197ab014f2..747861816f4f 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -22,6 +22,7 @@ struct opp_table;

 enum dev_pm_opp_event {
 	OPP_EVENT_ADD, OPP_EVENT_REMOVE, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE,
+	OPP_EVENT_ADJUST_VOLTAGE,
 };

 /**
@@ -113,6 +114,10 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq,
 void dev_pm_opp_remove(struct device *dev, unsigned long freq);
 void dev_pm_opp_remove_all_dynamic(struct device *dev);

+int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
+			      unsigned long u_volt, unsigned long u_volt_min,
+			      unsigned long u_volt_max);
+
 int dev_pm_opp_enable(struct device *dev, unsigned long freq);

 int dev_pm_opp_disable(struct device *dev, unsigned long freq);
@@ -242,6 +247,14 @@ static inline void dev_pm_opp_remove_all_dynamic(struct device *dev)
 {
 }

+static inline int
+dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
+			  unsigned long u_volt, unsigned long u_volt_min,
+			  unsigned long u_volt_max)
+{
+	return 0;
+}
+
 static inline int dev_pm_opp_enable(struct device *dev, unsigned long freq)
 {
 	return 0;
--
2.17.1


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

* [PATCH v5 1/4] PM / OPP: Support adjusting OPP voltages at runtime
@ 2019-10-16 14:57       ` Sylwester Nawrocki
  0 siblings, 0 replies; 28+ messages in thread
From: Sylwester Nawrocki @ 2019-10-16 14:57 UTC (permalink / raw)
  To: krzk, vireshk, robh+dt
  Cc: devicetree, linux-samsung-soc, linux-pm, sboyd, Stephen Boyd,
	b.zolnierkie, roger.lu, Sylwester Nawrocki, linux-arm-kernel,
	m.szyprowski

From: Stephen Boyd <sboyd@codeaurora.org>

On some SoCs the Adaptive Voltage Scaling (AVS) technique is
employed to optimize the operating voltage of a device. At a
given frequency, the hardware monitors dynamic factors and either
makes a suggestion for how much to adjust a voltage for the
current frequency, or it automatically adjusts the voltage
without software intervention. Add an API to the OPP library for
the former case, so that AVS type devices can update the voltages
for an OPP when the hardware determines the voltage should
change. The assumption is that drivers like CPUfreq or devfreq
will register for the OPP notifiers and adjust the voltage
according to suggestions that AVS makes.

This patch is derived from [1] submitted by Stephen.
[1] https://lore.kernel.org/patchwork/patch/599279/

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Roger Lu <roger.lu@mediatek.com>
[s.nawrocki@samsung.com: added handling of OPP min/max voltage]
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 drivers/opp/core.c     | 69 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/pm_opp.h | 13 ++++++++
 2 files changed, 82 insertions(+)

diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 3b7ffd0234e9..f38b3be85072 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -2112,6 +2112,75 @@ static int _opp_set_availability(struct device *dev, unsigned long freq,
 	return r;
 }

+/**
+ * dev_pm_opp_adjust_voltage() - helper to change the voltage of an OPP
+ * @dev:		device for which we do this operation
+ * @freq:		OPP frequency to adjust voltage of
+ * @u_volt:		new OPP target voltage
+ * @u_volt_min:		new OPP min voltage
+ * @u_volt_max:		new OPP max voltage
+ *
+ * Return: -EINVAL for bad pointers, -ENOMEM if no memory available for the
+ * copy operation, returns 0 if no modifcation was done OR modification was
+ * successful.
+ */
+int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
+			      unsigned long u_volt, unsigned long u_volt_min,
+			      unsigned long u_volt_max)
+
+{
+	struct opp_table *opp_table;
+	struct dev_pm_opp *tmp_opp, *opp = ERR_PTR(-ENODEV);
+	int r = 0;
+
+	/* Find the opp_table */
+	opp_table = _find_opp_table(dev);
+	if (IS_ERR(opp_table)) {
+		r = PTR_ERR(opp_table);
+		dev_warn(dev, "%s: Device OPP not found (%d)\n", __func__, r);
+		return r;
+	}
+
+	mutex_lock(&opp_table->lock);
+
+	/* Do we have the frequency? */
+	list_for_each_entry(tmp_opp, &opp_table->opp_list, node) {
+		if (tmp_opp->rate == freq) {
+			opp = tmp_opp;
+			break;
+		}
+	}
+
+	if (IS_ERR(opp)) {
+		r = PTR_ERR(opp);
+		goto adjust_unlock;
+	}
+
+	/* Is update really needed? */
+	if (opp->supplies->u_volt == u_volt)
+		goto adjust_unlock;
+
+	opp->supplies->u_volt = u_volt;
+	opp->supplies->u_volt_min = u_volt_min;
+	opp->supplies->u_volt_max = u_volt_max;
+
+	dev_pm_opp_get(opp);
+	mutex_unlock(&opp_table->lock);
+
+	/* Notify the voltage change of the OPP */
+	blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_ADJUST_VOLTAGE,
+				     opp);
+
+	dev_pm_opp_put(opp);
+	goto adjust_put_table;
+
+adjust_unlock:
+	mutex_unlock(&opp_table->lock);
+adjust_put_table:
+	dev_pm_opp_put_opp_table(opp_table);
+	return r;
+}
+
 /**
  * dev_pm_opp_enable() - Enable a specific OPP
  * @dev:	device for which we do this operation
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index b8197ab014f2..747861816f4f 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -22,6 +22,7 @@ struct opp_table;

 enum dev_pm_opp_event {
 	OPP_EVENT_ADD, OPP_EVENT_REMOVE, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE,
+	OPP_EVENT_ADJUST_VOLTAGE,
 };

 /**
@@ -113,6 +114,10 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq,
 void dev_pm_opp_remove(struct device *dev, unsigned long freq);
 void dev_pm_opp_remove_all_dynamic(struct device *dev);

+int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
+			      unsigned long u_volt, unsigned long u_volt_min,
+			      unsigned long u_volt_max);
+
 int dev_pm_opp_enable(struct device *dev, unsigned long freq);

 int dev_pm_opp_disable(struct device *dev, unsigned long freq);
@@ -242,6 +247,14 @@ static inline void dev_pm_opp_remove_all_dynamic(struct device *dev)
 {
 }

+static inline int
+dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
+			  unsigned long u_volt, unsigned long u_volt_min,
+			  unsigned long u_volt_max)
+{
+	return 0;
+}
+
 static inline int dev_pm_opp_enable(struct device *dev, unsigned long freq)
 {
 	return 0;
--
2.17.1


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

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

* [PATCH v5 2/4] dt-bindings: arm: samsung: Update the CHIPID binding for ASV
       [not found]   ` <CGME20191016145812eucas1p1a3cf3f44a2cff4c32a2270334630c4a2@eucas1p1.samsung.com>
@ 2019-10-16 14:57       ` Sylwester Nawrocki
  0 siblings, 0 replies; 28+ messages in thread
From: Sylwester Nawrocki @ 2019-10-16 14:57 UTC (permalink / raw)
  To: krzk, vireshk, robh+dt
  Cc: sboyd, roger.lu, linux-pm, linux-arm-kernel, linux-samsung-soc,
	devicetree, b.zolnierkie, m.szyprowski, Sylwester Nawrocki

This patch adds documentation of new optional "samsung,asv-bin"
property in the chipid device node and documents requirement of
"syscon" compatible string.  These additions are needed to support
Exynos ASV (Adaptive Supply Voltage) feature.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Depends on patch ("8d0daa4c89c9 dt-bindings: arm: samsung: Convert
Exynos Chipid bindings to json-schema") already applied to Rob's
dt/next.

Changes since v4:
 - converted to YAML

Changes since v3:
 - none

Changes since v2:
 - corrected patch summary line prefix, the patch moved in the
   sequence

Changes since v1 (RFC):
 - new patch

 .../bindings/arm/samsung/exynos-chipid.yaml   | 31 +++++++++++++++++--
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml b/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml
index 9c573ad7dc7d..df84d9e9f4c2 100644
--- a/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml
+++ b/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml
@@ -9,17 +9,42 @@ title: Samsung Exynos SoC series Chipid driver
 maintainers:
   - Krzysztof Kozlowski <krzk@kernel.org>

+# Custom select to avoid matching all nodes with 'syscon'
+select:
+  properties:
+    compatible:
+      contains:
+        const: samsung,exynos4210-chipid
+  required:
+    - compatible
+
 properties:
   compatible:
-    items:
-      - const: samsung,exynos4210-chipid
+    allOf:
+      - items:
+        - const: samsung,exynos4210-chipid
+        - const: syscon

   reg:
     maxItems: 1

+  samsung,asv-bin:
+    description:
+      Adaptive Supply Voltage bin selection. This can be used
+      to determine the ASV bin of an SoC if respective information
+      is missing in the CHIPID registers or in the OTP memory.
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - enum: [ 0, 1, 2, 3 ]
+
+required:
+  - compatible
+  - reg
+
 examples:
   - |
     chipid@10000000 {
-      compatible = "samsung,exynos4210-chipid";
+      compatible = "samsung,exynos4210-chipid", "syscon";
       reg = <0x10000000 0x100>;
+      samsung,asv-bin = <2>;
     };
--
2.17.1


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

* [PATCH v5 2/4] dt-bindings: arm: samsung: Update the CHIPID binding for ASV
@ 2019-10-16 14:57       ` Sylwester Nawrocki
  0 siblings, 0 replies; 28+ messages in thread
From: Sylwester Nawrocki @ 2019-10-16 14:57 UTC (permalink / raw)
  To: krzk, vireshk, robh+dt
  Cc: devicetree, linux-samsung-soc, linux-pm, sboyd, b.zolnierkie,
	roger.lu, Sylwester Nawrocki, linux-arm-kernel, m.szyprowski

This patch adds documentation of new optional "samsung,asv-bin"
property in the chipid device node and documents requirement of
"syscon" compatible string.  These additions are needed to support
Exynos ASV (Adaptive Supply Voltage) feature.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Depends on patch ("8d0daa4c89c9 dt-bindings: arm: samsung: Convert
Exynos Chipid bindings to json-schema") already applied to Rob's
dt/next.

Changes since v4:
 - converted to YAML

Changes since v3:
 - none

Changes since v2:
 - corrected patch summary line prefix, the patch moved in the
   sequence

Changes since v1 (RFC):
 - new patch

 .../bindings/arm/samsung/exynos-chipid.yaml   | 31 +++++++++++++++++--
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml b/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml
index 9c573ad7dc7d..df84d9e9f4c2 100644
--- a/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml
+++ b/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml
@@ -9,17 +9,42 @@ title: Samsung Exynos SoC series Chipid driver
 maintainers:
   - Krzysztof Kozlowski <krzk@kernel.org>

+# Custom select to avoid matching all nodes with 'syscon'
+select:
+  properties:
+    compatible:
+      contains:
+        const: samsung,exynos4210-chipid
+  required:
+    - compatible
+
 properties:
   compatible:
-    items:
-      - const: samsung,exynos4210-chipid
+    allOf:
+      - items:
+        - const: samsung,exynos4210-chipid
+        - const: syscon

   reg:
     maxItems: 1

+  samsung,asv-bin:
+    description:
+      Adaptive Supply Voltage bin selection. This can be used
+      to determine the ASV bin of an SoC if respective information
+      is missing in the CHIPID registers or in the OTP memory.
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - enum: [ 0, 1, 2, 3 ]
+
+required:
+  - compatible
+  - reg
+
 examples:
   - |
     chipid@10000000 {
-      compatible = "samsung,exynos4210-chipid";
+      compatible = "samsung,exynos4210-chipid", "syscon";
       reg = <0x10000000 0x100>;
+      samsung,asv-bin = <2>;
     };
--
2.17.1


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

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

* [PATCH v5 3/4] soc: samsung: Add Exynos Adaptive Supply Voltage driver
       [not found]   ` <CGME20191016145813eucas1p1623db169f1ee93f88cb2c75090804747@eucas1p1.samsung.com>
@ 2019-10-16 14:57       ` Sylwester Nawrocki
  0 siblings, 0 replies; 28+ messages in thread
From: Sylwester Nawrocki @ 2019-10-16 14:57 UTC (permalink / raw)
  To: krzk, vireshk, robh+dt
  Cc: sboyd, roger.lu, linux-pm, linux-arm-kernel, linux-samsung-soc,
	devicetree, b.zolnierkie, m.szyprowski, Sylwester Nawrocki

The Adaptive Supply Voltage (ASV) driver adjusts CPU cluster operating
points depending on exact revision of an SoC retrieved from the CHIPID
block or the OTP memory.  This allows for some power saving as for some
CPU clock frequencies we can lower CPU cluster's supply voltage comparing
to safe values common to all the SoC revisions.

This patch adds support for Exynos5422/5800 SoC, it is partially based
on code from https://github.com/hardkernel/linux repository,
branch odroidxu4-4.14.y, files: arch/arm/mach-exynos/exynos5422-asv.[ch].

Tested on Odroid XU3, XU4, XU3 Lite.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes since v4:
 - Fixed include guard in drivers/soc/samsung/exynos5422-asv.h

Changes since v3:
 - instead of removing/adding OPP use dedicated API to adjust OPP's
   voltage, only exynos_asv_update_cpu_opps() function has changed,
 - added a comment describing ASV tables at beginning of
   exynos5422-asv.c file.

Changes since v2:
 - use devm_kzalloc() in probe() to avoid memory leak,
 - removed leading spaces in exynos-chipid.h,
 - removed unneeded <linux/init.h> header inclusion,
 - dropped parentheses from exynos542_asv_parse_sg(),
 - updated Kconfig entry,
 - added const attribute to struct exynos_asv_susbsys::cpu_dt_compat.

Changes since v1 (RFC):
 - removed code for parsing the ASV OPP tables from DT, the ASV OPP tables
   moved to the driver,
 - converted to use the regmap API,
 - converted to normal platform driver.

 drivers/soc/samsung/Kconfig          |  10 +
 drivers/soc/samsung/Makefile         |   3 +
 drivers/soc/samsung/exynos-asv.c     | 179 ++++++++++
 drivers/soc/samsung/exynos-asv.h     |  82 +++++
 drivers/soc/samsung/exynos5422-asv.c | 509 +++++++++++++++++++++++++++
 drivers/soc/samsung/exynos5422-asv.h |  25 ++
 6 files changed, 808 insertions(+)
 create mode 100644 drivers/soc/samsung/exynos-asv.c
 create mode 100644 drivers/soc/samsung/exynos-asv.h
 create mode 100644 drivers/soc/samsung/exynos5422-asv.c
 create mode 100644 drivers/soc/samsung/exynos5422-asv.h

diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
index 33ad0de2de3c..27fc59bbb520 100644
--- a/drivers/soc/samsung/Kconfig
+++ b/drivers/soc/samsung/Kconfig
@@ -7,6 +7,16 @@ menuconfig SOC_SAMSUNG

 if SOC_SAMSUNG

+config EXYNOS_ASV
+	bool "Exynos Adaptive Supply Voltage support" if COMPILE_TEST
+	depends on (ARCH_EXYNOS && EXYNOS_CHIPID) || COMPILE_TEST
+	select EXYNOS_ASV_ARM if ARM && ARCH_EXYNOS
+
+# There is no need to enable these drivers for ARMv8
+config EXYNOS_ASV_ARM
+	bool "Exynos ASV ARMv7-specific driver extensions" if COMPILE_TEST
+	depends on EXYNOS_ASV
+
 config EXYNOS_CHIPID
 	bool "Exynos Chipid controller driver" if COMPILE_TEST
 	depends on ARCH_EXYNOS || COMPILE_TEST
diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
index 3b6a8797416c..edd1d6ea064d 100644
--- a/drivers/soc/samsung/Makefile
+++ b/drivers/soc/samsung/Makefile
@@ -1,5 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0

+obj-$(CONFIG_EXYNOS_ASV)	+= exynos-asv.o
+obj-$(CONFIG_EXYNOS_ASV_ARM)	+= exynos5422-asv.o
+
 obj-$(CONFIG_EXYNOS_CHIPID)	+= exynos-chipid.o
 obj-$(CONFIG_EXYNOS_PMU)	+= exynos-pmu.o

diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c
new file mode 100644
index 000000000000..c6f2e4f0dcc5
--- /dev/null
+++ b/drivers/soc/samsung/exynos-asv.c
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * Samsung Exynos SoC Adaptive Supply Voltage support
+ */
+
+#include <linux/cpu.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/regmap.h>
+#include <linux/soc/samsung/exynos-chipid.h>
+
+#include "exynos-asv.h"
+#include "exynos5422-asv.h"
+
+#define MHZ 1000000U
+
+static int exynos_asv_update_cpu_opps(struct exynos_asv *asv,
+				      struct device *cpu)
+{
+	struct exynos_asv_subsys *subsys = NULL;
+	struct dev_pm_opp *opp;
+	unsigned int opp_freq;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(asv->subsys); i++) {
+		if (of_device_is_compatible(cpu->of_node,
+					    asv->subsys[i].cpu_dt_compat)) {
+			subsys = &asv->subsys[i];
+			break;
+		}
+	}
+	if (!subsys)
+		return -EINVAL;
+
+	for (i = 0; i < subsys->table.num_rows; i++) {
+		unsigned int new_volt, volt;
+		int ret;
+
+		opp_freq = exynos_asv_opp_get_frequency(subsys, i);
+
+		opp = dev_pm_opp_find_freq_exact(cpu, opp_freq * MHZ, true);
+		if (IS_ERR(opp)) {
+			dev_info(asv->dev, "cpu%d opp%d, freq: %u missing\n",
+				 cpu->id, i, opp_freq);
+
+			continue;
+		}
+
+		volt = dev_pm_opp_get_voltage(opp);
+		new_volt = asv->opp_get_voltage(subsys, i, volt);
+		dev_pm_opp_put(opp);
+
+		if (new_volt == volt)
+			continue;
+
+		ret = dev_pm_opp_adjust_voltage(cpu, opp_freq * MHZ,
+						new_volt, new_volt, new_volt);
+		if (ret < 0)
+			dev_err(asv->dev,
+				"Failed to adjust OPP %u Hz/%u uV for cpu%d\n",
+				opp_freq, new_volt, cpu->id);
+		else
+			dev_dbg(asv->dev,
+				"Adjusted OPP %u Hz/%u -> %u uV, cpu%d\n",
+				opp_freq, volt, new_volt, cpu->id);
+	}
+
+	return 0;
+}
+
+static int exynos_asv_update_opps(struct exynos_asv *asv)
+{
+	struct opp_table *last_opp_table = NULL;
+	struct device *cpu;
+	int ret, cpuid;
+
+	for_each_possible_cpu(cpuid) {
+		struct opp_table *opp_table;
+
+		cpu = get_cpu_device(cpuid);
+		if (!cpu)
+			continue;
+
+		opp_table = dev_pm_opp_get_opp_table(cpu);
+		if (IS_ERR(opp_table))
+			continue;
+
+		if (!last_opp_table || opp_table != last_opp_table) {
+			last_opp_table = opp_table;
+
+			ret = exynos_asv_update_cpu_opps(asv, cpu);
+			if (ret < 0)
+				dev_err(asv->dev, "Couldn't udate OPPs for cpu%d\n",
+					cpuid);
+		}
+
+		dev_pm_opp_put_opp_table(opp_table);
+	}
+
+	return	0;
+}
+
+static int exynos_asv_probe(struct platform_device *pdev)
+{
+	int (*probe_func)(struct exynos_asv *asv);
+	struct exynos_asv *asv;
+	struct device *cpu_dev;
+	u32 product_id = 0;
+	int ret, i;
+
+	cpu_dev = get_cpu_device(0);
+	ret = dev_pm_opp_get_opp_count(cpu_dev);
+	if (ret < 0)
+		return -EPROBE_DEFER;
+
+	asv = devm_kzalloc(&pdev->dev, sizeof(*asv), GFP_KERNEL);
+	if (!asv)
+		return -ENOMEM;
+
+	asv->chipid_regmap = syscon_node_to_regmap(pdev->dev.of_node);
+	if (IS_ERR(asv->chipid_regmap)) {
+		dev_err(&pdev->dev, "Could not find syscon regmap\n");
+		return PTR_ERR(asv->chipid_regmap);
+	}
+
+	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);
+
+	switch (product_id & EXYNOS_MASK) {
+	case 0xE5422000:
+		probe_func = exynos5422_asv_init;
+		break;
+	default:
+		dev_err(&pdev->dev, "Unsupported product ID: %#x", product_id);
+		return -ENODEV;
+	}
+
+	ret = of_property_read_u32(pdev->dev.of_node, "samsung,asv-bin",
+				   &asv->of_bin);
+	if (ret < 0)
+		asv->of_bin = -EINVAL;
+
+	asv->dev = &pdev->dev;
+	dev_set_drvdata(&pdev->dev, asv);
+
+	for (i = 0; i < ARRAY_SIZE(asv->subsys); i++)
+		asv->subsys[i].asv = asv;
+
+	ret = probe_func(asv);
+	if (ret < 0)
+		return ret;
+
+	return exynos_asv_update_opps(asv);
+}
+
+static const struct of_device_id exynos_asv_of_device_ids[] = {
+	{ .compatible = "samsung,exynos4210-chipid" },
+	{}
+};
+
+static struct platform_driver exynos_asv_driver = {
+	.driver = {
+		.name = "exynos-asv",
+		.of_match_table = exynos_asv_of_device_ids,
+	},
+	.probe	= exynos_asv_probe,
+};
+module_platform_driver(exynos_asv_driver);
diff --git a/drivers/soc/samsung/exynos-asv.h b/drivers/soc/samsung/exynos-asv.h
new file mode 100644
index 000000000000..14b4fedf2ddd
--- /dev/null
+++ b/drivers/soc/samsung/exynos-asv.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * Samsung Exynos SoC Adaptive Supply Voltage support
+ */
+#ifndef __LINUX_SOC_EXYNOS_ASV_H
+#define __LINUX_SOC_EXYNOS_ASV_H
+
+enum {
+	EXYNOS_ASV_SUBSYS_ID_ARM,
+	EXYNOS_ASV_SUBSYS_ID_EGL = EXYNOS_ASV_SUBSYS_ID_ARM,
+	EXYNOS_ASV_SUBSYS_ID_KFC,
+	EXYNOS_ASV_SUBSYS_ID_INT,
+	EXYNOS_ASV_SUBSYS_ID_MIF,
+	EXYNOS_ASV_SUBSYS_ID_G3D,
+	EXYNOS_ASV_SUBSYS_ID_CAM,
+	EXYNOS_ASV_SUBSYS_ID_MAX
+};
+
+struct regmap;
+
+/* HPM, IDS values to select target group */
+struct asv_limit_entry {
+	unsigned int hpm;
+	unsigned int ids;
+};
+
+struct exynos_asv_table {
+	unsigned int num_rows;
+	unsigned int num_cols;
+	u32 *buf;
+};
+
+struct exynos_asv_subsys {
+	struct exynos_asv *asv;
+	const char *cpu_dt_compat;
+	int id;
+	struct exynos_asv_table table;
+
+	unsigned int base_volt;
+	unsigned int offset_volt_h;
+	unsigned int offset_volt_l;
+};
+
+struct exynos_asv {
+	struct device *dev;
+	struct regmap *chipid_regmap;
+	struct exynos_asv_subsys subsys[2];
+
+	int (*opp_get_voltage)(struct exynos_asv_subsys *subs, int level,
+			       unsigned int voltage);
+	unsigned int group;
+	unsigned int table;
+
+	/* True if SG fields from PKG_ID register should be used */
+	bool use_sg;
+	/* ASV bin read from DT */
+	int of_bin;
+};
+
+static inline u32 __asv_get_table_entry(struct exynos_asv_table *table,
+					unsigned int row, unsigned int col)
+{
+	return table->buf[row * (table->num_cols) + col];
+}
+
+static inline u32 exynos_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
+					unsigned int level, unsigned int group)
+{
+	return __asv_get_table_entry(&subsys->table, level, group + 1);
+}
+
+static inline u32 exynos_asv_opp_get_frequency(struct exynos_asv_subsys *subsys,
+					unsigned int level)
+{
+	return __asv_get_table_entry(&subsys->table, level, 0);
+}
+
+#endif /* __LINUX_SOC_EXYNOS_ASV_H */
diff --git a/drivers/soc/samsung/exynos5422-asv.c b/drivers/soc/samsung/exynos5422-asv.c
new file mode 100644
index 000000000000..7982f2ca0f11
--- /dev/null
+++ b/drivers/soc/samsung/exynos5422-asv.c
@@ -0,0 +1,509 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ *
+ * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
+ */
+
+#include <linux/bitrev.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/soc/samsung/exynos-chipid.h>
+#include <linux/slab.h>
+
+#include "exynos-asv.h"
+
+#define ASV_GROUPS_NUM		14
+#define ASV_ARM_DVFS_NUM	20
+#define ASV_ARM_BIN2_DVFS_NUM	17
+#define ASV_KFC_DVFS_NUM	14
+#define ASV_KFC_BIN2_DVFS_NUM	12
+
+/*
+ * This array is a set of 4 ASV data tables, first column of each ASV table
+ * contains frequency value in MHz and subsequent columns contain the CPU
+ * cluster's supply voltage values in uV.
+ * In order to create a set of OPPs for specific SoC revision one of the voltage
+ * columns (1...14) from one of the tables (0...3) is selected during
+ * initialization. There are separate ASV tables for the big (ARM) and little
+ * (KFC) CPU cluster. Only OPPs which are already defined in devicetree
+ * will be updated.
+ */
+
+static const u32 asv_arm_table[][ASV_ARM_DVFS_NUM][ASV_GROUPS_NUM + 1] = {
+{
+	/* ARM 0, 1 */
+	{ 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
+	  1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
+	{ 2000,    1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000,
+	  1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1900,    1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000,
+	  1162500, 1150000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+	{ 1800,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
+	  1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+	{ 1700,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
+	  1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
+	{ 1600,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
+	  1037500, 1025000, 1037500, 1025000, 1012500, 1000000, 987500 },
+	{ 1500,    1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
+	  1000000, 987500,  1000000, 987500,  975000,  962500,  950000 },
+	{ 1400,    1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+	  975000,  962500,  975000,  962500,  950000,  937500,  925000 },
+	{ 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
+	  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
+	{ 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
+	{ 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
+	  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* ARM 2 */
+	{ 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
+	  1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
+	{ 2000,    1312500, 1312500, 1312500, 1300000, 1275000, 1262500, 1250000,
+	  1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1900,    1262500, 1250000, 1250000, 1237500, 1212500, 1200000, 1187500,
+	  1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
+	{ 1800,    1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500,
+	  1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
+	{ 1700,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+	  1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
+	{ 1600,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+	  1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
+	{ 1500,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
+	{ 1400,    1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,
+	  987500,  975000,  987500,  975000,  962500,  950000,  937500 },
+	{ 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
+	  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
+	{ 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
+	{ 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
+	  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* ARM 3 */
+	{ 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
+	  1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
+	{ 2000,    1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000,
+	  1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1900,    1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500,
+	  1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
+	{ 1800,    1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500,
+	  1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
+	{ 1700,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+	  1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
+	{ 1600,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+	  1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
+	{ 1500,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
+	{ 1400,    1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,
+	  987500,  975000,  987500,  975000,  962500,  950000,  937500 },
+	{ 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
+	  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
+	{ 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
+	{ 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
+	  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* ARM bin 2 */
+	{ 1800,    1237500, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500,
+	  1150000, 1137500, 1150000, 1137500, 1125000, 1112500, 1100000 },
+	{ 1700,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
+	  1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+	{ 1600,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
+	  1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
+	{ 1500,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
+	  1037500, 1025000, 1037500, 1025000, 1012500, 1000000, 987500 },
+	{ 1400,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
+	{ 1300,    1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
+	  1000000, 987500,  1000000, 987500,  975000,  962500,  950000 },
+	{ 1200,    1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+	  975000,  962500,  975000,  962500,  950000,  937500,  925000 },
+	{ 1100,    1037500, 1025000, 1012500, 1000000, 987500,  975000,  962500,
+	  950000,  937500,  950000,  937500,  925000,  912500,  900000 },
+	{ 1000,    1012500, 1000000, 987500,  975000,  962500,  950000,  937500,
+	  925000,  912500,  925000,  912500,  900000,  900000,  900000 },
+	{ 900,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 800,     962500,  950000,  937500,  925000,  912500,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 700,     937500,  925000,  912500,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}
+};
+
+static const u32 asv_kfc_table[][ASV_KFC_DVFS_NUM][ASV_GROUPS_NUM + 1] = {
+{
+	/* KFC 0, 1 */
+	{ 1500000, 1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
+	  1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1400000, 1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
+	  1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+	{ 1300000, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
+	  1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+	{ 1200000, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+	  1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
+	{ 1100000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+	  1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
+	{ 1000000, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
+	{ 900000,  1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+	  975000,  962500,  950000,  937500,  925000,  912500,  900000 },
+	{ 800000,  1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  912500,  900000,  900000,  900000,  900000 },
+	{ 700000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600000,  950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* KFC 2 */
+	{ 1500,    1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
+	  1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1400,    1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
+	  1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+	{ 1300,    1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
+	  1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+	{ 1200,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+	  1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
+	{ 1100,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+	  1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
+	{ 1000,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
+	{ 900,     1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+	  975000,  962500,  950000,  937500,  925000,  912500,  900000 },
+	{ 800,     1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  912500,  900000,  900000,  900000,  900000 },
+	{ 700,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     912500,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* KFC 3 */
+	{ 1500,    1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
+	  1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1400,    1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
+	  1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+	{ 1300,    1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
+	  1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+	{ 1200,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+	  1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
+	{ 1100,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+	  1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
+	{ 1000,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
+	{ 900,     1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+	  975000,  962500,  950000,  937500,  925000,  912500,  900000 },
+	{ 800,     1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  912500,  900000,  900000,  900000,  900000 },
+	{ 700,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     912500,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* KFC bin 2 */
+	{ 1300,    1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000,
+	  1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500 },
+	{ 1200,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
+	  1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500 },
+	{ 1100,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
+	  1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000 },
+	{ 1000,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
+	  1037500, 1025000, 1012500, 1000000, 987500,  975000,  962500 },
+	{ 900,     1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
+	  1000000, 987500,  975000,  962500,  950000,  937500,  925000 },
+	{ 800,     1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
+	  962500,  950000,  937500,  925000,  912500,  900000,  900000 },
+	{ 700,     1012500, 1000000, 987500,  975000,  962500,  950000,  937500,
+	  925000,  912500,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     975000,  962500,  950000,  937500,  925000,  912500,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     937500,  925000,  912500,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}
+};
+
+static const struct asv_limit_entry __asv_limits[ASV_GROUPS_NUM] = {
+	{ 13, 55 },
+	{ 21, 65 },
+	{ 25, 69 },
+	{ 30, 72 },
+	{ 36, 74 },
+	{ 43, 76 },
+	{ 51, 78 },
+	{ 65, 80 },
+	{ 81, 82 },
+	{ 98, 84 },
+	{ 119, 87 },
+	{ 135, 89 },
+	{ 150, 92 },
+	{ 999, 999 },
+};
+
+static int exynos5422_asv_get_group(struct exynos_asv *asv)
+{
+	unsigned int pkgid_reg, auxi_reg;
+	int hpm, ids, i;
+
+	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PKG_ID, &pkgid_reg);
+	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_AUX_INFO, &auxi_reg);
+
+	if (asv->use_sg) {
+		u32 sga = (pkgid_reg >> EXYNOS5422_SG_A_OFFSET) &
+			   EXYNOS5422_SG_A_MASK;
+
+		u32 sgb = (pkgid_reg >> EXYNOS5422_SG_B_OFFSET) &
+			   EXYNOS5422_SG_B_MASK;
+
+		if ((pkgid_reg >> EXYNOS5422_SG_BSIGN_OFFSET) &
+		     EXYNOS5422_SG_BSIGN_MASK)
+			return sga + sgb;
+		else
+			return sga - sgb;
+	}
+
+	hpm = (auxi_reg >> EXYNOS5422_TMCB_OFFSET) & EXYNOS5422_TMCB_MASK;
+	ids = (pkgid_reg >> EXYNOS5422_IDS_OFFSET) & EXYNOS5422_IDS_MASK;
+
+	for (i = 0; i < ASV_GROUPS_NUM; i++) {
+		if (ids <= __asv_limits[i].ids)
+			break;
+		if (hpm <= __asv_limits[i].hpm)
+			break;
+	}
+	if (i < ASV_GROUPS_NUM)
+		return i;
+
+	return 0;
+}
+
+static int __asv_offset_voltage(unsigned int index)
+{
+	switch (index) {
+	case 1:
+		return 12500;
+	case 2:
+		return 50000;
+	case 3:
+		return 25000;
+	default:
+		return 0;
+	};
+}
+
+static void exynos5422_asv_offset_voltage_setup(struct exynos_asv *asv)
+{
+	struct exynos_asv_subsys *subsys;
+	unsigned int reg, value;
+
+	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_AUX_INFO, &reg);
+
+	/* ARM offset voltage setup */
+	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_ARM];
+
+	subsys->base_volt = 1000000;
+
+	value = (reg >> EXYNOS5422_ARM_UP_OFFSET) & EXYNOS5422_ARM_UP_MASK;
+	subsys->offset_volt_h = __asv_offset_voltage(value);
+
+	value = (reg >> EXYNOS5422_ARM_DN_OFFSET) & EXYNOS5422_ARM_DN_MASK;
+	subsys->offset_volt_l = __asv_offset_voltage(value);
+
+	/* KFC offset voltage setup */
+	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_KFC];
+
+	subsys->base_volt = 1000000;
+
+	value = (reg >> EXYNOS5422_KFC_UP_OFFSET) & EXYNOS5422_KFC_UP_MASK;
+	subsys->offset_volt_h = __asv_offset_voltage(value);
+
+	value = (reg >> EXYNOS5422_KFC_DN_OFFSET) & EXYNOS5422_KFC_DN_MASK;
+	subsys->offset_volt_l = __asv_offset_voltage(value);
+}
+
+static int exynos5422_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
+				int level, unsigned int volt)
+{
+	unsigned int asv_volt;
+
+	if (level >= subsys->table.num_rows)
+		return volt;
+
+	asv_volt = exynos_asv_opp_get_voltage(subsys, level,
+					      subsys->asv->group);
+
+	if (volt > subsys->base_volt)
+		asv_volt += subsys->offset_volt_h;
+	else
+		asv_volt += subsys->offset_volt_l;
+
+	return asv_volt;
+}
+
+static unsigned int exynos5422_asv_parse_table(struct exynos_asv *asv,
+				      unsigned int pkg_id)
+{
+	return (pkg_id >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
+}
+
+static bool exynos5422_asv_parse_bin2(struct exynos_asv *asv,
+				     unsigned int pkg_id)
+{
+	return (pkg_id >> EXYNOS5422_BIN2_OFFSET) & EXYNOS5422_BIN2_MASK;
+}
+
+static bool exynos5422_asv_parse_sg(struct exynos_asv *asv,
+					unsigned int pkg_id)
+{
+	return (pkg_id >> EXYNOS5422_USESG_OFFSET) & EXYNOS5422_USESG_MASK;
+}
+
+int exynos5422_asv_init(struct exynos_asv *asv)
+{
+	struct exynos_asv_subsys *subsys;
+	unsigned int table_index;
+	unsigned int pkg_id;
+	bool bin2;
+
+	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PKG_ID, &pkg_id);
+
+	if (asv->of_bin == 2) {
+		bin2 = true;
+		asv->use_sg = false;
+	} else {
+		asv->use_sg = exynos5422_asv_parse_sg(asv, pkg_id);
+		bin2 = exynos5422_asv_parse_bin2(asv, pkg_id);
+	}
+
+	asv->group = exynos5422_asv_get_group(asv);
+	asv->table = exynos5422_asv_parse_table(asv, pkg_id);
+
+	exynos5422_asv_offset_voltage_setup(asv);
+
+	if (bin2) {
+		table_index = 3;
+	} else {
+		if (asv->table == 2 || asv->table == 3)
+			table_index = asv->table - 1;
+		else
+			table_index = 0;
+	}
+
+	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_ARM];
+	subsys->cpu_dt_compat = "arm,cortex-a15";
+	if (bin2)
+		subsys->table.num_rows = ASV_ARM_BIN2_DVFS_NUM;
+	else
+		subsys->table.num_rows = ASV_ARM_DVFS_NUM;
+	subsys->table.num_cols = ASV_GROUPS_NUM + 1;
+	subsys->table.buf = (u32 *)asv_arm_table[table_index];
+
+	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_KFC];
+	subsys->cpu_dt_compat = "arm,cortex-a7";
+	if (bin2)
+		subsys->table.num_rows = ASV_KFC_BIN2_DVFS_NUM;
+	else
+		subsys->table.num_rows = ASV_KFC_DVFS_NUM;
+	subsys->table.num_cols = ASV_GROUPS_NUM + 1;
+	subsys->table.buf = (u32 *)asv_kfc_table[table_index];
+
+	asv->opp_get_voltage = exynos5422_asv_opp_get_voltage;
+
+	return 0;
+}
diff --git a/drivers/soc/samsung/exynos5422-asv.h b/drivers/soc/samsung/exynos5422-asv.h
new file mode 100644
index 000000000000..85218d2800fb
--- /dev/null
+++ b/drivers/soc/samsung/exynos5422-asv.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ *
+ * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
+ */
+
+#ifndef __LINUX_SOC_EXYNOS5422_ASV_H
+#define __LINUX_SOC_EXYNOS5422_ASV_H
+
+#include <linux/errno.h>
+
+struct exynos_asv;
+
+#ifdef CONFIG_EXYNOS_ASV_ARM
+int exynos5422_asv_init(struct exynos_asv *asv);
+#else
+static inline int exynos5422_asv_init(struct exynos_asv *asv)
+{
+	return -ENOTSUPP;
+}
+#endif
+
+#endif /* __LINUX_SOC_EXYNOS5422_ASV_H */
--
2.17.1


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

* [PATCH v5 3/4] soc: samsung: Add Exynos Adaptive Supply Voltage driver
@ 2019-10-16 14:57       ` Sylwester Nawrocki
  0 siblings, 0 replies; 28+ messages in thread
From: Sylwester Nawrocki @ 2019-10-16 14:57 UTC (permalink / raw)
  To: krzk, vireshk, robh+dt
  Cc: devicetree, linux-samsung-soc, linux-pm, sboyd, b.zolnierkie,
	roger.lu, Sylwester Nawrocki, linux-arm-kernel, m.szyprowski

The Adaptive Supply Voltage (ASV) driver adjusts CPU cluster operating
points depending on exact revision of an SoC retrieved from the CHIPID
block or the OTP memory.  This allows for some power saving as for some
CPU clock frequencies we can lower CPU cluster's supply voltage comparing
to safe values common to all the SoC revisions.

This patch adds support for Exynos5422/5800 SoC, it is partially based
on code from https://github.com/hardkernel/linux repository,
branch odroidxu4-4.14.y, files: arch/arm/mach-exynos/exynos5422-asv.[ch].

Tested on Odroid XU3, XU4, XU3 Lite.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes since v4:
 - Fixed include guard in drivers/soc/samsung/exynos5422-asv.h

Changes since v3:
 - instead of removing/adding OPP use dedicated API to adjust OPP's
   voltage, only exynos_asv_update_cpu_opps() function has changed,
 - added a comment describing ASV tables at beginning of
   exynos5422-asv.c file.

Changes since v2:
 - use devm_kzalloc() in probe() to avoid memory leak,
 - removed leading spaces in exynos-chipid.h,
 - removed unneeded <linux/init.h> header inclusion,
 - dropped parentheses from exynos542_asv_parse_sg(),
 - updated Kconfig entry,
 - added const attribute to struct exynos_asv_susbsys::cpu_dt_compat.

Changes since v1 (RFC):
 - removed code for parsing the ASV OPP tables from DT, the ASV OPP tables
   moved to the driver,
 - converted to use the regmap API,
 - converted to normal platform driver.

 drivers/soc/samsung/Kconfig          |  10 +
 drivers/soc/samsung/Makefile         |   3 +
 drivers/soc/samsung/exynos-asv.c     | 179 ++++++++++
 drivers/soc/samsung/exynos-asv.h     |  82 +++++
 drivers/soc/samsung/exynos5422-asv.c | 509 +++++++++++++++++++++++++++
 drivers/soc/samsung/exynos5422-asv.h |  25 ++
 6 files changed, 808 insertions(+)
 create mode 100644 drivers/soc/samsung/exynos-asv.c
 create mode 100644 drivers/soc/samsung/exynos-asv.h
 create mode 100644 drivers/soc/samsung/exynos5422-asv.c
 create mode 100644 drivers/soc/samsung/exynos5422-asv.h

diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
index 33ad0de2de3c..27fc59bbb520 100644
--- a/drivers/soc/samsung/Kconfig
+++ b/drivers/soc/samsung/Kconfig
@@ -7,6 +7,16 @@ menuconfig SOC_SAMSUNG

 if SOC_SAMSUNG

+config EXYNOS_ASV
+	bool "Exynos Adaptive Supply Voltage support" if COMPILE_TEST
+	depends on (ARCH_EXYNOS && EXYNOS_CHIPID) || COMPILE_TEST
+	select EXYNOS_ASV_ARM if ARM && ARCH_EXYNOS
+
+# There is no need to enable these drivers for ARMv8
+config EXYNOS_ASV_ARM
+	bool "Exynos ASV ARMv7-specific driver extensions" if COMPILE_TEST
+	depends on EXYNOS_ASV
+
 config EXYNOS_CHIPID
 	bool "Exynos Chipid controller driver" if COMPILE_TEST
 	depends on ARCH_EXYNOS || COMPILE_TEST
diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
index 3b6a8797416c..edd1d6ea064d 100644
--- a/drivers/soc/samsung/Makefile
+++ b/drivers/soc/samsung/Makefile
@@ -1,5 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0

+obj-$(CONFIG_EXYNOS_ASV)	+= exynos-asv.o
+obj-$(CONFIG_EXYNOS_ASV_ARM)	+= exynos5422-asv.o
+
 obj-$(CONFIG_EXYNOS_CHIPID)	+= exynos-chipid.o
 obj-$(CONFIG_EXYNOS_PMU)	+= exynos-pmu.o

diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c
new file mode 100644
index 000000000000..c6f2e4f0dcc5
--- /dev/null
+++ b/drivers/soc/samsung/exynos-asv.c
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * Samsung Exynos SoC Adaptive Supply Voltage support
+ */
+
+#include <linux/cpu.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/regmap.h>
+#include <linux/soc/samsung/exynos-chipid.h>
+
+#include "exynos-asv.h"
+#include "exynos5422-asv.h"
+
+#define MHZ 1000000U
+
+static int exynos_asv_update_cpu_opps(struct exynos_asv *asv,
+				      struct device *cpu)
+{
+	struct exynos_asv_subsys *subsys = NULL;
+	struct dev_pm_opp *opp;
+	unsigned int opp_freq;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(asv->subsys); i++) {
+		if (of_device_is_compatible(cpu->of_node,
+					    asv->subsys[i].cpu_dt_compat)) {
+			subsys = &asv->subsys[i];
+			break;
+		}
+	}
+	if (!subsys)
+		return -EINVAL;
+
+	for (i = 0; i < subsys->table.num_rows; i++) {
+		unsigned int new_volt, volt;
+		int ret;
+
+		opp_freq = exynos_asv_opp_get_frequency(subsys, i);
+
+		opp = dev_pm_opp_find_freq_exact(cpu, opp_freq * MHZ, true);
+		if (IS_ERR(opp)) {
+			dev_info(asv->dev, "cpu%d opp%d, freq: %u missing\n",
+				 cpu->id, i, opp_freq);
+
+			continue;
+		}
+
+		volt = dev_pm_opp_get_voltage(opp);
+		new_volt = asv->opp_get_voltage(subsys, i, volt);
+		dev_pm_opp_put(opp);
+
+		if (new_volt == volt)
+			continue;
+
+		ret = dev_pm_opp_adjust_voltage(cpu, opp_freq * MHZ,
+						new_volt, new_volt, new_volt);
+		if (ret < 0)
+			dev_err(asv->dev,
+				"Failed to adjust OPP %u Hz/%u uV for cpu%d\n",
+				opp_freq, new_volt, cpu->id);
+		else
+			dev_dbg(asv->dev,
+				"Adjusted OPP %u Hz/%u -> %u uV, cpu%d\n",
+				opp_freq, volt, new_volt, cpu->id);
+	}
+
+	return 0;
+}
+
+static int exynos_asv_update_opps(struct exynos_asv *asv)
+{
+	struct opp_table *last_opp_table = NULL;
+	struct device *cpu;
+	int ret, cpuid;
+
+	for_each_possible_cpu(cpuid) {
+		struct opp_table *opp_table;
+
+		cpu = get_cpu_device(cpuid);
+		if (!cpu)
+			continue;
+
+		opp_table = dev_pm_opp_get_opp_table(cpu);
+		if (IS_ERR(opp_table))
+			continue;
+
+		if (!last_opp_table || opp_table != last_opp_table) {
+			last_opp_table = opp_table;
+
+			ret = exynos_asv_update_cpu_opps(asv, cpu);
+			if (ret < 0)
+				dev_err(asv->dev, "Couldn't udate OPPs for cpu%d\n",
+					cpuid);
+		}
+
+		dev_pm_opp_put_opp_table(opp_table);
+	}
+
+	return	0;
+}
+
+static int exynos_asv_probe(struct platform_device *pdev)
+{
+	int (*probe_func)(struct exynos_asv *asv);
+	struct exynos_asv *asv;
+	struct device *cpu_dev;
+	u32 product_id = 0;
+	int ret, i;
+
+	cpu_dev = get_cpu_device(0);
+	ret = dev_pm_opp_get_opp_count(cpu_dev);
+	if (ret < 0)
+		return -EPROBE_DEFER;
+
+	asv = devm_kzalloc(&pdev->dev, sizeof(*asv), GFP_KERNEL);
+	if (!asv)
+		return -ENOMEM;
+
+	asv->chipid_regmap = syscon_node_to_regmap(pdev->dev.of_node);
+	if (IS_ERR(asv->chipid_regmap)) {
+		dev_err(&pdev->dev, "Could not find syscon regmap\n");
+		return PTR_ERR(asv->chipid_regmap);
+	}
+
+	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);
+
+	switch (product_id & EXYNOS_MASK) {
+	case 0xE5422000:
+		probe_func = exynos5422_asv_init;
+		break;
+	default:
+		dev_err(&pdev->dev, "Unsupported product ID: %#x", product_id);
+		return -ENODEV;
+	}
+
+	ret = of_property_read_u32(pdev->dev.of_node, "samsung,asv-bin",
+				   &asv->of_bin);
+	if (ret < 0)
+		asv->of_bin = -EINVAL;
+
+	asv->dev = &pdev->dev;
+	dev_set_drvdata(&pdev->dev, asv);
+
+	for (i = 0; i < ARRAY_SIZE(asv->subsys); i++)
+		asv->subsys[i].asv = asv;
+
+	ret = probe_func(asv);
+	if (ret < 0)
+		return ret;
+
+	return exynos_asv_update_opps(asv);
+}
+
+static const struct of_device_id exynos_asv_of_device_ids[] = {
+	{ .compatible = "samsung,exynos4210-chipid" },
+	{}
+};
+
+static struct platform_driver exynos_asv_driver = {
+	.driver = {
+		.name = "exynos-asv",
+		.of_match_table = exynos_asv_of_device_ids,
+	},
+	.probe	= exynos_asv_probe,
+};
+module_platform_driver(exynos_asv_driver);
diff --git a/drivers/soc/samsung/exynos-asv.h b/drivers/soc/samsung/exynos-asv.h
new file mode 100644
index 000000000000..14b4fedf2ddd
--- /dev/null
+++ b/drivers/soc/samsung/exynos-asv.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * Samsung Exynos SoC Adaptive Supply Voltage support
+ */
+#ifndef __LINUX_SOC_EXYNOS_ASV_H
+#define __LINUX_SOC_EXYNOS_ASV_H
+
+enum {
+	EXYNOS_ASV_SUBSYS_ID_ARM,
+	EXYNOS_ASV_SUBSYS_ID_EGL = EXYNOS_ASV_SUBSYS_ID_ARM,
+	EXYNOS_ASV_SUBSYS_ID_KFC,
+	EXYNOS_ASV_SUBSYS_ID_INT,
+	EXYNOS_ASV_SUBSYS_ID_MIF,
+	EXYNOS_ASV_SUBSYS_ID_G3D,
+	EXYNOS_ASV_SUBSYS_ID_CAM,
+	EXYNOS_ASV_SUBSYS_ID_MAX
+};
+
+struct regmap;
+
+/* HPM, IDS values to select target group */
+struct asv_limit_entry {
+	unsigned int hpm;
+	unsigned int ids;
+};
+
+struct exynos_asv_table {
+	unsigned int num_rows;
+	unsigned int num_cols;
+	u32 *buf;
+};
+
+struct exynos_asv_subsys {
+	struct exynos_asv *asv;
+	const char *cpu_dt_compat;
+	int id;
+	struct exynos_asv_table table;
+
+	unsigned int base_volt;
+	unsigned int offset_volt_h;
+	unsigned int offset_volt_l;
+};
+
+struct exynos_asv {
+	struct device *dev;
+	struct regmap *chipid_regmap;
+	struct exynos_asv_subsys subsys[2];
+
+	int (*opp_get_voltage)(struct exynos_asv_subsys *subs, int level,
+			       unsigned int voltage);
+	unsigned int group;
+	unsigned int table;
+
+	/* True if SG fields from PKG_ID register should be used */
+	bool use_sg;
+	/* ASV bin read from DT */
+	int of_bin;
+};
+
+static inline u32 __asv_get_table_entry(struct exynos_asv_table *table,
+					unsigned int row, unsigned int col)
+{
+	return table->buf[row * (table->num_cols) + col];
+}
+
+static inline u32 exynos_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
+					unsigned int level, unsigned int group)
+{
+	return __asv_get_table_entry(&subsys->table, level, group + 1);
+}
+
+static inline u32 exynos_asv_opp_get_frequency(struct exynos_asv_subsys *subsys,
+					unsigned int level)
+{
+	return __asv_get_table_entry(&subsys->table, level, 0);
+}
+
+#endif /* __LINUX_SOC_EXYNOS_ASV_H */
diff --git a/drivers/soc/samsung/exynos5422-asv.c b/drivers/soc/samsung/exynos5422-asv.c
new file mode 100644
index 000000000000..7982f2ca0f11
--- /dev/null
+++ b/drivers/soc/samsung/exynos5422-asv.c
@@ -0,0 +1,509 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ *
+ * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
+ */
+
+#include <linux/bitrev.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/soc/samsung/exynos-chipid.h>
+#include <linux/slab.h>
+
+#include "exynos-asv.h"
+
+#define ASV_GROUPS_NUM		14
+#define ASV_ARM_DVFS_NUM	20
+#define ASV_ARM_BIN2_DVFS_NUM	17
+#define ASV_KFC_DVFS_NUM	14
+#define ASV_KFC_BIN2_DVFS_NUM	12
+
+/*
+ * This array is a set of 4 ASV data tables, first column of each ASV table
+ * contains frequency value in MHz and subsequent columns contain the CPU
+ * cluster's supply voltage values in uV.
+ * In order to create a set of OPPs for specific SoC revision one of the voltage
+ * columns (1...14) from one of the tables (0...3) is selected during
+ * initialization. There are separate ASV tables for the big (ARM) and little
+ * (KFC) CPU cluster. Only OPPs which are already defined in devicetree
+ * will be updated.
+ */
+
+static const u32 asv_arm_table[][ASV_ARM_DVFS_NUM][ASV_GROUPS_NUM + 1] = {
+{
+	/* ARM 0, 1 */
+	{ 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
+	  1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
+	{ 2000,    1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000,
+	  1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1900,    1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000,
+	  1162500, 1150000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+	{ 1800,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
+	  1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+	{ 1700,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
+	  1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
+	{ 1600,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
+	  1037500, 1025000, 1037500, 1025000, 1012500, 1000000, 987500 },
+	{ 1500,    1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
+	  1000000, 987500,  1000000, 987500,  975000,  962500,  950000 },
+	{ 1400,    1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+	  975000,  962500,  975000,  962500,  950000,  937500,  925000 },
+	{ 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
+	  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
+	{ 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
+	{ 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
+	  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* ARM 2 */
+	{ 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
+	  1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
+	{ 2000,    1312500, 1312500, 1312500, 1300000, 1275000, 1262500, 1250000,
+	  1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1900,    1262500, 1250000, 1250000, 1237500, 1212500, 1200000, 1187500,
+	  1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
+	{ 1800,    1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500,
+	  1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
+	{ 1700,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+	  1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
+	{ 1600,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+	  1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
+	{ 1500,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
+	{ 1400,    1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,
+	  987500,  975000,  987500,  975000,  962500,  950000,  937500 },
+	{ 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
+	  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
+	{ 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
+	{ 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
+	  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* ARM 3 */
+	{ 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
+	  1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
+	{ 2000,    1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000,
+	  1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1900,    1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500,
+	  1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
+	{ 1800,    1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500,
+	  1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
+	{ 1700,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+	  1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
+	{ 1600,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+	  1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
+	{ 1500,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
+	{ 1400,    1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,
+	  987500,  975000,  987500,  975000,  962500,  950000,  937500 },
+	{ 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
+	  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
+	{ 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
+	{ 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
+	  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* ARM bin 2 */
+	{ 1800,    1237500, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500,
+	  1150000, 1137500, 1150000, 1137500, 1125000, 1112500, 1100000 },
+	{ 1700,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
+	  1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+	{ 1600,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
+	  1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
+	{ 1500,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
+	  1037500, 1025000, 1037500, 1025000, 1012500, 1000000, 987500 },
+	{ 1400,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
+	{ 1300,    1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
+	  1000000, 987500,  1000000, 987500,  975000,  962500,  950000 },
+	{ 1200,    1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+	  975000,  962500,  975000,  962500,  950000,  937500,  925000 },
+	{ 1100,    1037500, 1025000, 1012500, 1000000, 987500,  975000,  962500,
+	  950000,  937500,  950000,  937500,  925000,  912500,  900000 },
+	{ 1000,    1012500, 1000000, 987500,  975000,  962500,  950000,  937500,
+	  925000,  912500,  925000,  912500,  900000,  900000,  900000 },
+	{ 900,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 800,     962500,  950000,  937500,  925000,  912500,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 700,     937500,  925000,  912500,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}
+};
+
+static const u32 asv_kfc_table[][ASV_KFC_DVFS_NUM][ASV_GROUPS_NUM + 1] = {
+{
+	/* KFC 0, 1 */
+	{ 1500000, 1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
+	  1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1400000, 1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
+	  1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+	{ 1300000, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
+	  1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+	{ 1200000, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+	  1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
+	{ 1100000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+	  1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
+	{ 1000000, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
+	{ 900000,  1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+	  975000,  962500,  950000,  937500,  925000,  912500,  900000 },
+	{ 800000,  1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  912500,  900000,  900000,  900000,  900000 },
+	{ 700000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600000,  950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* KFC 2 */
+	{ 1500,    1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
+	  1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1400,    1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
+	  1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+	{ 1300,    1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
+	  1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+	{ 1200,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+	  1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
+	{ 1100,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+	  1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
+	{ 1000,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
+	{ 900,     1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+	  975000,  962500,  950000,  937500,  925000,  912500,  900000 },
+	{ 800,     1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  912500,  900000,  900000,  900000,  900000 },
+	{ 700,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     912500,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* KFC 3 */
+	{ 1500,    1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
+	  1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1400,    1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
+	  1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+	{ 1300,    1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
+	  1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+	{ 1200,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+	  1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
+	{ 1100,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+	  1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
+	{ 1000,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
+	{ 900,     1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+	  975000,  962500,  950000,  937500,  925000,  912500,  900000 },
+	{ 800,     1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  912500,  900000,  900000,  900000,  900000 },
+	{ 700,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     912500,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* KFC bin 2 */
+	{ 1300,    1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000,
+	  1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500 },
+	{ 1200,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
+	  1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500 },
+	{ 1100,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
+	  1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000 },
+	{ 1000,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
+	  1037500, 1025000, 1012500, 1000000, 987500,  975000,  962500 },
+	{ 900,     1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
+	  1000000, 987500,  975000,  962500,  950000,  937500,  925000 },
+	{ 800,     1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
+	  962500,  950000,  937500,  925000,  912500,  900000,  900000 },
+	{ 700,     1012500, 1000000, 987500,  975000,  962500,  950000,  937500,
+	  925000,  912500,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     975000,  962500,  950000,  937500,  925000,  912500,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     937500,  925000,  912500,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}
+};
+
+static const struct asv_limit_entry __asv_limits[ASV_GROUPS_NUM] = {
+	{ 13, 55 },
+	{ 21, 65 },
+	{ 25, 69 },
+	{ 30, 72 },
+	{ 36, 74 },
+	{ 43, 76 },
+	{ 51, 78 },
+	{ 65, 80 },
+	{ 81, 82 },
+	{ 98, 84 },
+	{ 119, 87 },
+	{ 135, 89 },
+	{ 150, 92 },
+	{ 999, 999 },
+};
+
+static int exynos5422_asv_get_group(struct exynos_asv *asv)
+{
+	unsigned int pkgid_reg, auxi_reg;
+	int hpm, ids, i;
+
+	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PKG_ID, &pkgid_reg);
+	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_AUX_INFO, &auxi_reg);
+
+	if (asv->use_sg) {
+		u32 sga = (pkgid_reg >> EXYNOS5422_SG_A_OFFSET) &
+			   EXYNOS5422_SG_A_MASK;
+
+		u32 sgb = (pkgid_reg >> EXYNOS5422_SG_B_OFFSET) &
+			   EXYNOS5422_SG_B_MASK;
+
+		if ((pkgid_reg >> EXYNOS5422_SG_BSIGN_OFFSET) &
+		     EXYNOS5422_SG_BSIGN_MASK)
+			return sga + sgb;
+		else
+			return sga - sgb;
+	}
+
+	hpm = (auxi_reg >> EXYNOS5422_TMCB_OFFSET) & EXYNOS5422_TMCB_MASK;
+	ids = (pkgid_reg >> EXYNOS5422_IDS_OFFSET) & EXYNOS5422_IDS_MASK;
+
+	for (i = 0; i < ASV_GROUPS_NUM; i++) {
+		if (ids <= __asv_limits[i].ids)
+			break;
+		if (hpm <= __asv_limits[i].hpm)
+			break;
+	}
+	if (i < ASV_GROUPS_NUM)
+		return i;
+
+	return 0;
+}
+
+static int __asv_offset_voltage(unsigned int index)
+{
+	switch (index) {
+	case 1:
+		return 12500;
+	case 2:
+		return 50000;
+	case 3:
+		return 25000;
+	default:
+		return 0;
+	};
+}
+
+static void exynos5422_asv_offset_voltage_setup(struct exynos_asv *asv)
+{
+	struct exynos_asv_subsys *subsys;
+	unsigned int reg, value;
+
+	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_AUX_INFO, &reg);
+
+	/* ARM offset voltage setup */
+	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_ARM];
+
+	subsys->base_volt = 1000000;
+
+	value = (reg >> EXYNOS5422_ARM_UP_OFFSET) & EXYNOS5422_ARM_UP_MASK;
+	subsys->offset_volt_h = __asv_offset_voltage(value);
+
+	value = (reg >> EXYNOS5422_ARM_DN_OFFSET) & EXYNOS5422_ARM_DN_MASK;
+	subsys->offset_volt_l = __asv_offset_voltage(value);
+
+	/* KFC offset voltage setup */
+	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_KFC];
+
+	subsys->base_volt = 1000000;
+
+	value = (reg >> EXYNOS5422_KFC_UP_OFFSET) & EXYNOS5422_KFC_UP_MASK;
+	subsys->offset_volt_h = __asv_offset_voltage(value);
+
+	value = (reg >> EXYNOS5422_KFC_DN_OFFSET) & EXYNOS5422_KFC_DN_MASK;
+	subsys->offset_volt_l = __asv_offset_voltage(value);
+}
+
+static int exynos5422_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
+				int level, unsigned int volt)
+{
+	unsigned int asv_volt;
+
+	if (level >= subsys->table.num_rows)
+		return volt;
+
+	asv_volt = exynos_asv_opp_get_voltage(subsys, level,
+					      subsys->asv->group);
+
+	if (volt > subsys->base_volt)
+		asv_volt += subsys->offset_volt_h;
+	else
+		asv_volt += subsys->offset_volt_l;
+
+	return asv_volt;
+}
+
+static unsigned int exynos5422_asv_parse_table(struct exynos_asv *asv,
+				      unsigned int pkg_id)
+{
+	return (pkg_id >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
+}
+
+static bool exynos5422_asv_parse_bin2(struct exynos_asv *asv,
+				     unsigned int pkg_id)
+{
+	return (pkg_id >> EXYNOS5422_BIN2_OFFSET) & EXYNOS5422_BIN2_MASK;
+}
+
+static bool exynos5422_asv_parse_sg(struct exynos_asv *asv,
+					unsigned int pkg_id)
+{
+	return (pkg_id >> EXYNOS5422_USESG_OFFSET) & EXYNOS5422_USESG_MASK;
+}
+
+int exynos5422_asv_init(struct exynos_asv *asv)
+{
+	struct exynos_asv_subsys *subsys;
+	unsigned int table_index;
+	unsigned int pkg_id;
+	bool bin2;
+
+	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PKG_ID, &pkg_id);
+
+	if (asv->of_bin == 2) {
+		bin2 = true;
+		asv->use_sg = false;
+	} else {
+		asv->use_sg = exynos5422_asv_parse_sg(asv, pkg_id);
+		bin2 = exynos5422_asv_parse_bin2(asv, pkg_id);
+	}
+
+	asv->group = exynos5422_asv_get_group(asv);
+	asv->table = exynos5422_asv_parse_table(asv, pkg_id);
+
+	exynos5422_asv_offset_voltage_setup(asv);
+
+	if (bin2) {
+		table_index = 3;
+	} else {
+		if (asv->table == 2 || asv->table == 3)
+			table_index = asv->table - 1;
+		else
+			table_index = 0;
+	}
+
+	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_ARM];
+	subsys->cpu_dt_compat = "arm,cortex-a15";
+	if (bin2)
+		subsys->table.num_rows = ASV_ARM_BIN2_DVFS_NUM;
+	else
+		subsys->table.num_rows = ASV_ARM_DVFS_NUM;
+	subsys->table.num_cols = ASV_GROUPS_NUM + 1;
+	subsys->table.buf = (u32 *)asv_arm_table[table_index];
+
+	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_KFC];
+	subsys->cpu_dt_compat = "arm,cortex-a7";
+	if (bin2)
+		subsys->table.num_rows = ASV_KFC_BIN2_DVFS_NUM;
+	else
+		subsys->table.num_rows = ASV_KFC_DVFS_NUM;
+	subsys->table.num_cols = ASV_GROUPS_NUM + 1;
+	subsys->table.buf = (u32 *)asv_kfc_table[table_index];
+
+	asv->opp_get_voltage = exynos5422_asv_opp_get_voltage;
+
+	return 0;
+}
diff --git a/drivers/soc/samsung/exynos5422-asv.h b/drivers/soc/samsung/exynos5422-asv.h
new file mode 100644
index 000000000000..85218d2800fb
--- /dev/null
+++ b/drivers/soc/samsung/exynos5422-asv.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ *
+ * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
+ */
+
+#ifndef __LINUX_SOC_EXYNOS5422_ASV_H
+#define __LINUX_SOC_EXYNOS5422_ASV_H
+
+#include <linux/errno.h>
+
+struct exynos_asv;
+
+#ifdef CONFIG_EXYNOS_ASV_ARM
+int exynos5422_asv_init(struct exynos_asv *asv);
+#else
+static inline int exynos5422_asv_init(struct exynos_asv *asv)
+{
+	return -ENOTSUPP;
+}
+#endif
+
+#endif /* __LINUX_SOC_EXYNOS5422_ASV_H */
--
2.17.1


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

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

* [PATCH v5 4/4] ARM: EXYNOS: Enable exynos-asv driver for ARCH_EXYNOS
       [not found]   ` <CGME20191016145814eucas1p10d50d438abb850fd82f622122b223196@eucas1p1.samsung.com>
@ 2019-10-16 14:57       ` Sylwester Nawrocki
  0 siblings, 0 replies; 28+ messages in thread
From: Sylwester Nawrocki @ 2019-10-16 14:57 UTC (permalink / raw)
  To: krzk, vireshk, robh+dt
  Cc: sboyd, roger.lu, linux-pm, linux-arm-kernel, linux-samsung-soc,
	devicetree, b.zolnierkie, m.szyprowski, Sylwester Nawrocki

Enable exynos-asv driver for Exynos 32-bit SoCs.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes since v1 (RFC):
 - none

 arch/arm/mach-exynos/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 9dab1f50a02f..4ef56571145b 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -13,6 +13,7 @@ menuconfig ARCH_EXYNOS
 	select ARM_AMBA
 	select ARM_GIC
 	select COMMON_CLK_SAMSUNG
+	select EXYNOS_ASV
 	select EXYNOS_CHIPID
 	select EXYNOS_THERMAL
 	select EXYNOS_PMU
--
2.17.1


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

* [PATCH v5 4/4] ARM: EXYNOS: Enable exynos-asv driver for ARCH_EXYNOS
@ 2019-10-16 14:57       ` Sylwester Nawrocki
  0 siblings, 0 replies; 28+ messages in thread
From: Sylwester Nawrocki @ 2019-10-16 14:57 UTC (permalink / raw)
  To: krzk, vireshk, robh+dt
  Cc: devicetree, linux-samsung-soc, linux-pm, sboyd, b.zolnierkie,
	roger.lu, Sylwester Nawrocki, linux-arm-kernel, m.szyprowski

Enable exynos-asv driver for Exynos 32-bit SoCs.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes since v1 (RFC):
 - none

 arch/arm/mach-exynos/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 9dab1f50a02f..4ef56571145b 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -13,6 +13,7 @@ menuconfig ARCH_EXYNOS
 	select ARM_AMBA
 	select ARM_GIC
 	select COMMON_CLK_SAMSUNG
+	select EXYNOS_ASV
 	select EXYNOS_CHIPID
 	select EXYNOS_THERMAL
 	select EXYNOS_PMU
--
2.17.1


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

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

* Re: [PATCH v5 2/4] dt-bindings: arm: samsung: Update the CHIPID binding for ASV
  2019-10-16 14:57       ` Sylwester Nawrocki
@ 2019-10-16 16:16         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2019-10-16 16:16 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: vireshk, robh+dt, sboyd, roger.lu, linux-pm, linux-arm-kernel,
	linux-samsung-soc, devicetree,
	Bartłomiej Żołnierkiewicz, Marek Szyprowski

On Wed, 16 Oct 2019 at 17:58, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> This patch adds documentation of new optional "samsung,asv-bin"
> property in the chipid device node and documents requirement of
> "syscon" compatible string.  These additions are needed to support
> Exynos ASV (Adaptive Supply Voltage) feature.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
> Depends on patch ("8d0daa4c89c9 dt-bindings: arm: samsung: Convert
> Exynos Chipid bindings to json-schema") already applied to Rob's
> dt/next.
>
> Changes since v4:
>  - converted to YAML
>
> Changes since v3:
>  - none
>
> Changes since v2:
>  - corrected patch summary line prefix, the patch moved in the
>    sequence
>
> Changes since v1 (RFC):
>  - new patch
>
>  .../bindings/arm/samsung/exynos-chipid.yaml   | 31 +++++++++++++++++--
>  1 file changed, 28 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml b/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml
> index 9c573ad7dc7d..df84d9e9f4c2 100644
> --- a/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml
> +++ b/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml
> @@ -9,17 +9,42 @@ title: Samsung Exynos SoC series Chipid driver
>  maintainers:
>    - Krzysztof Kozlowski <krzk@kernel.org>
>
> +# Custom select to avoid matching all nodes with 'syscon'
> +select:
> +  properties:
> +    compatible:
> +      contains:
> +        const: samsung,exynos4210-chipid
> +  required:
> +    - compatible
> +
>  properties:
>    compatible:
> -    items:
> -      - const: samsung,exynos4210-chipid
> +    allOf:

I think it was my mistake to use allOf in other Exynos bindings. It
should not be needed.

Rest looks good so with allOf removal:
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

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

* Re: [PATCH v5 2/4] dt-bindings: arm: samsung: Update the CHIPID binding for ASV
@ 2019-10-16 16:16         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2019-10-16 16:16 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: devicetree, linux-samsung-soc, linux-pm, sboyd, vireshk,
	Bartłomiej Żołnierkiewicz, roger.lu, robh+dt,
	linux-arm-kernel, Marek Szyprowski

On Wed, 16 Oct 2019 at 17:58, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> This patch adds documentation of new optional "samsung,asv-bin"
> property in the chipid device node and documents requirement of
> "syscon" compatible string.  These additions are needed to support
> Exynos ASV (Adaptive Supply Voltage) feature.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
> Depends on patch ("8d0daa4c89c9 dt-bindings: arm: samsung: Convert
> Exynos Chipid bindings to json-schema") already applied to Rob's
> dt/next.
>
> Changes since v4:
>  - converted to YAML
>
> Changes since v3:
>  - none
>
> Changes since v2:
>  - corrected patch summary line prefix, the patch moved in the
>    sequence
>
> Changes since v1 (RFC):
>  - new patch
>
>  .../bindings/arm/samsung/exynos-chipid.yaml   | 31 +++++++++++++++++--
>  1 file changed, 28 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml b/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml
> index 9c573ad7dc7d..df84d9e9f4c2 100644
> --- a/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml
> +++ b/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml
> @@ -9,17 +9,42 @@ title: Samsung Exynos SoC series Chipid driver
>  maintainers:
>    - Krzysztof Kozlowski <krzk@kernel.org>
>
> +# Custom select to avoid matching all nodes with 'syscon'
> +select:
> +  properties:
> +    compatible:
> +      contains:
> +        const: samsung,exynos4210-chipid
> +  required:
> +    - compatible
> +
>  properties:
>    compatible:
> -    items:
> -      - const: samsung,exynos4210-chipid
> +    allOf:

I think it was my mistake to use allOf in other Exynos bindings. It
should not be needed.

Rest looks good so with allOf removal:
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

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

* Re: [PATCH v5 1/4] PM / OPP: Support adjusting OPP voltages at runtime
  2019-10-16 14:57       ` Sylwester Nawrocki
@ 2019-10-17  6:42         ` Viresh Kumar
  -1 siblings, 0 replies; 28+ messages in thread
From: Viresh Kumar @ 2019-10-17  6:42 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: krzk, vireshk, robh+dt, sboyd, roger.lu, linux-pm,
	linux-arm-kernel, linux-samsung-soc, devicetree, b.zolnierkie,
	m.szyprowski, Stephen Boyd

On 16-10-19, 16:57, Sylwester Nawrocki wrote:
> From: Stephen Boyd <sboyd@codeaurora.org>
> 
> On some SoCs the Adaptive Voltage Scaling (AVS) technique is
> employed to optimize the operating voltage of a device. At a
> given frequency, the hardware monitors dynamic factors and either
> makes a suggestion for how much to adjust a voltage for the
> current frequency, or it automatically adjusts the voltage
> without software intervention. Add an API to the OPP library for
> the former case, so that AVS type devices can update the voltages
> for an OPP when the hardware determines the voltage should
> change. The assumption is that drivers like CPUfreq or devfreq
> will register for the OPP notifiers and adjust the voltage
> according to suggestions that AVS makes.
> 
> This patch is derived from [1] submitted by Stephen.
> [1] https://lore.kernel.org/patchwork/patch/599279/
> 
> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> Signed-off-by: Roger Lu <roger.lu@mediatek.com>
> [s.nawrocki@samsung.com: added handling of OPP min/max voltage]
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  drivers/opp/core.c     | 69 ++++++++++++++++++++++++++++++++++++++++++
>  include/linux/pm_opp.h | 13 ++++++++
>  2 files changed, 82 insertions(+)

Applied. Thanks.

-- 
viresh

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

* Re: [PATCH v5 1/4] PM / OPP: Support adjusting OPP voltages at runtime
@ 2019-10-17  6:42         ` Viresh Kumar
  0 siblings, 0 replies; 28+ messages in thread
From: Viresh Kumar @ 2019-10-17  6:42 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: devicetree, linux-samsung-soc, linux-pm, sboyd, vireshk,
	b.zolnierkie, roger.lu, krzk, robh+dt, Stephen Boyd,
	linux-arm-kernel, m.szyprowski

On 16-10-19, 16:57, Sylwester Nawrocki wrote:
> From: Stephen Boyd <sboyd@codeaurora.org>
> 
> On some SoCs the Adaptive Voltage Scaling (AVS) technique is
> employed to optimize the operating voltage of a device. At a
> given frequency, the hardware monitors dynamic factors and either
> makes a suggestion for how much to adjust a voltage for the
> current frequency, or it automatically adjusts the voltage
> without software intervention. Add an API to the OPP library for
> the former case, so that AVS type devices can update the voltages
> for an OPP when the hardware determines the voltage should
> change. The assumption is that drivers like CPUfreq or devfreq
> will register for the OPP notifiers and adjust the voltage
> according to suggestions that AVS makes.
> 
> This patch is derived from [1] submitted by Stephen.
> [1] https://lore.kernel.org/patchwork/patch/599279/
> 
> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> Signed-off-by: Roger Lu <roger.lu@mediatek.com>
> [s.nawrocki@samsung.com: added handling of OPP min/max voltage]
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  drivers/opp/core.c     | 69 ++++++++++++++++++++++++++++++++++++++++++
>  include/linux/pm_opp.h | 13 ++++++++
>  2 files changed, 82 insertions(+)

Applied. Thanks.

-- 
viresh

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

* Re: [PATCH v5 2/4] dt-bindings: arm: samsung: Update the CHIPID binding for ASV
  2019-10-16 16:16         ` Krzysztof Kozlowski
@ 2019-10-17  9:03           ` Sylwester Nawrocki
  -1 siblings, 0 replies; 28+ messages in thread
From: Sylwester Nawrocki @ 2019-10-17  9:03 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: devicetree, linux-samsung-soc, linux-pm, sboyd, vireshk,
	Bartłomiej Żołnierkiewicz, roger.lu, robh+dt,
	linux-arm-kernel, Marek Szyprowski

On 10/16/19 18:16, Krzysztof Kozlowski wrote:
>> --- a/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml
>> +++ b/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml
>> @@ -9,17 +9,42 @@ title: Samsung Exynos SoC series Chipid driver

BTW, I think we should rename the above title to talk about IP block/device
rather than driver, e.g.

-SAMSUNG Exynos SoCs Chipid driver.
+SAMSUNG Exynos SoC series CHIPID subsystem

>> +# Custom select to avoid matching all nodes with 'syscon'
>> +select:
>> +  properties:
>> +    compatible:
>> +      contains:
>> +        const: samsung,exynos4210-chipid
>> +  required:
>> +    - compatible
>> +
>>  properties:
>>    compatible:
>> -    items:
>> -      - const: samsung,exynos4210-chipid
>> +    allOf:
>
> I think it was my mistake to use allOf in other Exynos bindings. It
> should not be needed.

Indeed it seems to work well without allOf, I was wondering why we
needed the custom select above AND allOf.

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

* Re: [PATCH v5 2/4] dt-bindings: arm: samsung: Update the CHIPID binding for ASV
@ 2019-10-17  9:03           ` Sylwester Nawrocki
  0 siblings, 0 replies; 28+ messages in thread
From: Sylwester Nawrocki @ 2019-10-17  9:03 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: devicetree, linux-samsung-soc,
	Bartłomiej Żołnierkiewicz, sboyd, vireshk,
	linux-pm, roger.lu, robh+dt, linux-arm-kernel, Marek Szyprowski

On 10/16/19 18:16, Krzysztof Kozlowski wrote:
>> --- a/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml
>> +++ b/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.yaml
>> @@ -9,17 +9,42 @@ title: Samsung Exynos SoC series Chipid driver

BTW, I think we should rename the above title to talk about IP block/device
rather than driver, e.g.

-SAMSUNG Exynos SoCs Chipid driver.
+SAMSUNG Exynos SoC series CHIPID subsystem

>> +# Custom select to avoid matching all nodes with 'syscon'
>> +select:
>> +  properties:
>> +    compatible:
>> +      contains:
>> +        const: samsung,exynos4210-chipid
>> +  required:
>> +    - compatible
>> +
>>  properties:
>>    compatible:
>> -    items:
>> -      - const: samsung,exynos4210-chipid
>> +    allOf:
>
> I think it was my mistake to use allOf in other Exynos bindings. It
> should not be needed.

Indeed it seems to work well without allOf, I was wondering why we
needed the custom select above AND allOf.

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

* Re: [PATCH v5 1/4] PM / OPP: Support adjusting OPP voltages at runtime
  2019-10-17  6:42         ` Viresh Kumar
@ 2019-10-21 11:23           ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2019-10-21 11:23 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Sylwester Nawrocki, vireshk, robh+dt, sboyd, roger.lu, linux-pm,
	linux-arm-kernel, linux-samsung-soc, devicetree, b.zolnierkie,
	m.szyprowski, Stephen Boyd

On Thu, Oct 17, 2019 at 12:12:58PM +0530, Viresh Kumar wrote:
> On 16-10-19, 16:57, Sylwester Nawrocki wrote:
> > From: Stephen Boyd <sboyd@codeaurora.org>
> > 
> > On some SoCs the Adaptive Voltage Scaling (AVS) technique is
> > employed to optimize the operating voltage of a device. At a
> > given frequency, the hardware monitors dynamic factors and either
> > makes a suggestion for how much to adjust a voltage for the
> > current frequency, or it automatically adjusts the voltage
> > without software intervention. Add an API to the OPP library for
> > the former case, so that AVS type devices can update the voltages
> > for an OPP when the hardware determines the voltage should
> > change. The assumption is that drivers like CPUfreq or devfreq
> > will register for the OPP notifiers and adjust the voltage
> > according to suggestions that AVS makes.
> > 
> > This patch is derived from [1] submitted by Stephen.
> > [1] https://lore.kernel.org/patchwork/patch/599279/
> > 
> > Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> > Signed-off-by: Roger Lu <roger.lu@mediatek.com>
> > [s.nawrocki@samsung.com: added handling of OPP min/max voltage]
> > Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> > ---
> >  drivers/opp/core.c     | 69 ++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/pm_opp.h | 13 ++++++++
> >  2 files changed, 82 insertions(+)
> 
> Applied. Thanks.

Hi Viresh,

Can you provide a stable tag with this patch so I can take soc/samsung
driver?

Best regards,
Krzysztof


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

* Re: [PATCH v5 1/4] PM / OPP: Support adjusting OPP voltages at runtime
@ 2019-10-21 11:23           ` Krzysztof Kozlowski
  0 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2019-10-21 11:23 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: devicetree, linux-samsung-soc, linux-pm, sboyd, vireshk,
	b.zolnierkie, roger.lu, robh+dt, Sylwester Nawrocki,
	Stephen Boyd, linux-arm-kernel, m.szyprowski

On Thu, Oct 17, 2019 at 12:12:58PM +0530, Viresh Kumar wrote:
> On 16-10-19, 16:57, Sylwester Nawrocki wrote:
> > From: Stephen Boyd <sboyd@codeaurora.org>
> > 
> > On some SoCs the Adaptive Voltage Scaling (AVS) technique is
> > employed to optimize the operating voltage of a device. At a
> > given frequency, the hardware monitors dynamic factors and either
> > makes a suggestion for how much to adjust a voltage for the
> > current frequency, or it automatically adjusts the voltage
> > without software intervention. Add an API to the OPP library for
> > the former case, so that AVS type devices can update the voltages
> > for an OPP when the hardware determines the voltage should
> > change. The assumption is that drivers like CPUfreq or devfreq
> > will register for the OPP notifiers and adjust the voltage
> > according to suggestions that AVS makes.
> > 
> > This patch is derived from [1] submitted by Stephen.
> > [1] https://lore.kernel.org/patchwork/patch/599279/
> > 
> > Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> > Signed-off-by: Roger Lu <roger.lu@mediatek.com>
> > [s.nawrocki@samsung.com: added handling of OPP min/max voltage]
> > Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> > ---
> >  drivers/opp/core.c     | 69 ++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/pm_opp.h | 13 ++++++++
> >  2 files changed, 82 insertions(+)
> 
> Applied. Thanks.

Hi Viresh,

Can you provide a stable tag with this patch so I can take soc/samsung
driver?

Best regards,
Krzysztof


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

* Re: [PATCH v5 1/4] PM / OPP: Support adjusting OPP voltages at runtime
  2019-10-21 11:23           ` Krzysztof Kozlowski
@ 2019-10-22  2:23             ` Viresh Kumar
  -1 siblings, 0 replies; 28+ messages in thread
From: Viresh Kumar @ 2019-10-22  2:23 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Sylwester Nawrocki, vireshk, robh+dt, sboyd, roger.lu, linux-pm,
	linux-arm-kernel, linux-samsung-soc, devicetree, b.zolnierkie,
	m.szyprowski, Stephen Boyd

On 21-10-19, 13:23, Krzysztof Kozlowski wrote:
> On Thu, Oct 17, 2019 at 12:12:58PM +0530, Viresh Kumar wrote:
> > On 16-10-19, 16:57, Sylwester Nawrocki wrote:
> > > From: Stephen Boyd <sboyd@codeaurora.org>
> > > 
> > > On some SoCs the Adaptive Voltage Scaling (AVS) technique is
> > > employed to optimize the operating voltage of a device. At a
> > > given frequency, the hardware monitors dynamic factors and either
> > > makes a suggestion for how much to adjust a voltage for the
> > > current frequency, or it automatically adjusts the voltage
> > > without software intervention. Add an API to the OPP library for
> > > the former case, so that AVS type devices can update the voltages
> > > for an OPP when the hardware determines the voltage should
> > > change. The assumption is that drivers like CPUfreq or devfreq
> > > will register for the OPP notifiers and adjust the voltage
> > > according to suggestions that AVS makes.
> > > 
> > > This patch is derived from [1] submitted by Stephen.
> > > [1] https://lore.kernel.org/patchwork/patch/599279/
> > > 
> > > Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> > > Signed-off-by: Roger Lu <roger.lu@mediatek.com>
> > > [s.nawrocki@samsung.com: added handling of OPP min/max voltage]
> > > Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> > > ---
> > >  drivers/opp/core.c     | 69 ++++++++++++++++++++++++++++++++++++++++++
> > >  include/linux/pm_opp.h | 13 ++++++++
> > >  2 files changed, 82 insertions(+)
> > 
> > Applied. Thanks.
> 
> Hi Viresh,
> 
> Can you provide a stable tag with this patch so I can take soc/samsung
> driver?

opp-5.4-support-adjust-voltages

-- 
viresh

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

* Re: [PATCH v5 1/4] PM / OPP: Support adjusting OPP voltages at runtime
@ 2019-10-22  2:23             ` Viresh Kumar
  0 siblings, 0 replies; 28+ messages in thread
From: Viresh Kumar @ 2019-10-22  2:23 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: devicetree, linux-samsung-soc, linux-pm, sboyd, vireshk,
	b.zolnierkie, roger.lu, robh+dt, Sylwester Nawrocki,
	Stephen Boyd, linux-arm-kernel, m.szyprowski

On 21-10-19, 13:23, Krzysztof Kozlowski wrote:
> On Thu, Oct 17, 2019 at 12:12:58PM +0530, Viresh Kumar wrote:
> > On 16-10-19, 16:57, Sylwester Nawrocki wrote:
> > > From: Stephen Boyd <sboyd@codeaurora.org>
> > > 
> > > On some SoCs the Adaptive Voltage Scaling (AVS) technique is
> > > employed to optimize the operating voltage of a device. At a
> > > given frequency, the hardware monitors dynamic factors and either
> > > makes a suggestion for how much to adjust a voltage for the
> > > current frequency, or it automatically adjusts the voltage
> > > without software intervention. Add an API to the OPP library for
> > > the former case, so that AVS type devices can update the voltages
> > > for an OPP when the hardware determines the voltage should
> > > change. The assumption is that drivers like CPUfreq or devfreq
> > > will register for the OPP notifiers and adjust the voltage
> > > according to suggestions that AVS makes.
> > > 
> > > This patch is derived from [1] submitted by Stephen.
> > > [1] https://lore.kernel.org/patchwork/patch/599279/
> > > 
> > > Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> > > Signed-off-by: Roger Lu <roger.lu@mediatek.com>
> > > [s.nawrocki@samsung.com: added handling of OPP min/max voltage]
> > > Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> > > ---
> > >  drivers/opp/core.c     | 69 ++++++++++++++++++++++++++++++++++++++++++
> > >  include/linux/pm_opp.h | 13 ++++++++
> > >  2 files changed, 82 insertions(+)
> > 
> > Applied. Thanks.
> 
> Hi Viresh,
> 
> Can you provide a stable tag with this patch so I can take soc/samsung
> driver?

opp-5.4-support-adjust-voltages

-- 
viresh

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

* Re: [PATCH v5 1/4] PM / OPP: Support adjusting OPP voltages at runtime
  2019-10-22  2:23             ` Viresh Kumar
@ 2019-10-22 18:43               ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2019-10-22 18:43 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Sylwester Nawrocki, vireshk, robh+dt, sboyd, roger.lu, linux-pm,
	linux-arm-kernel, linux-samsung-soc, devicetree, b.zolnierkie,
	m.szyprowski, Stephen Boyd

On Tue, Oct 22, 2019 at 07:53:41AM +0530, Viresh Kumar wrote:
> On 21-10-19, 13:23, Krzysztof Kozlowski wrote:
> > On Thu, Oct 17, 2019 at 12:12:58PM +0530, Viresh Kumar wrote:
> > > On 16-10-19, 16:57, Sylwester Nawrocki wrote:
> > > > From: Stephen Boyd <sboyd@codeaurora.org>
> > > > 
> > > > On some SoCs the Adaptive Voltage Scaling (AVS) technique is
> > > > employed to optimize the operating voltage of a device. At a
> > > > given frequency, the hardware monitors dynamic factors and either
> > > > makes a suggestion for how much to adjust a voltage for the
> > > > current frequency, or it automatically adjusts the voltage
> > > > without software intervention. Add an API to the OPP library for
> > > > the former case, so that AVS type devices can update the voltages
> > > > for an OPP when the hardware determines the voltage should
> > > > change. The assumption is that drivers like CPUfreq or devfreq
> > > > will register for the OPP notifiers and adjust the voltage
> > > > according to suggestions that AVS makes.
> > > > 
> > > > This patch is derived from [1] submitted by Stephen.
> > > > [1] https://lore.kernel.org/patchwork/patch/599279/
> > > > 
> > > > Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> > > > Signed-off-by: Roger Lu <roger.lu@mediatek.com>
> > > > [s.nawrocki@samsung.com: added handling of OPP min/max voltage]
> > > > Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> > > > ---
> > > >  drivers/opp/core.c     | 69 ++++++++++++++++++++++++++++++++++++++++++
> > > >  include/linux/pm_opp.h | 13 ++++++++
> > > >  2 files changed, 82 insertions(+)
> > > 
> > > Applied. Thanks.
> > 
> > Hi Viresh,
> > 
> > Can you provide a stable tag with this patch so I can take soc/samsung
> > driver?
> 
> opp-5.4-support-adjust-voltages

Thanks, merged.

Best regards,
Krzysztof


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

* Re: [PATCH v5 1/4] PM / OPP: Support adjusting OPP voltages at runtime
@ 2019-10-22 18:43               ` Krzysztof Kozlowski
  0 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2019-10-22 18:43 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: devicetree, linux-samsung-soc, linux-pm, sboyd, vireshk,
	b.zolnierkie, roger.lu, robh+dt, Sylwester Nawrocki,
	Stephen Boyd, linux-arm-kernel, m.szyprowski

On Tue, Oct 22, 2019 at 07:53:41AM +0530, Viresh Kumar wrote:
> On 21-10-19, 13:23, Krzysztof Kozlowski wrote:
> > On Thu, Oct 17, 2019 at 12:12:58PM +0530, Viresh Kumar wrote:
> > > On 16-10-19, 16:57, Sylwester Nawrocki wrote:
> > > > From: Stephen Boyd <sboyd@codeaurora.org>
> > > > 
> > > > On some SoCs the Adaptive Voltage Scaling (AVS) technique is
> > > > employed to optimize the operating voltage of a device. At a
> > > > given frequency, the hardware monitors dynamic factors and either
> > > > makes a suggestion for how much to adjust a voltage for the
> > > > current frequency, or it automatically adjusts the voltage
> > > > without software intervention. Add an API to the OPP library for
> > > > the former case, so that AVS type devices can update the voltages
> > > > for an OPP when the hardware determines the voltage should
> > > > change. The assumption is that drivers like CPUfreq or devfreq
> > > > will register for the OPP notifiers and adjust the voltage
> > > > according to suggestions that AVS makes.
> > > > 
> > > > This patch is derived from [1] submitted by Stephen.
> > > > [1] https://lore.kernel.org/patchwork/patch/599279/
> > > > 
> > > > Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> > > > Signed-off-by: Roger Lu <roger.lu@mediatek.com>
> > > > [s.nawrocki@samsung.com: added handling of OPP min/max voltage]
> > > > Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> > > > ---
> > > >  drivers/opp/core.c     | 69 ++++++++++++++++++++++++++++++++++++++++++
> > > >  include/linux/pm_opp.h | 13 ++++++++
> > > >  2 files changed, 82 insertions(+)
> > > 
> > > Applied. Thanks.
> > 
> > Hi Viresh,
> > 
> > Can you provide a stable tag with this patch so I can take soc/samsung
> > driver?
> 
> opp-5.4-support-adjust-voltages

Thanks, merged.

Best regards,
Krzysztof


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

* Re: [PATCH v5 3/4] soc: samsung: Add Exynos Adaptive Supply Voltage driver
  2019-10-16 14:57       ` Sylwester Nawrocki
@ 2019-10-22 19:04         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2019-10-22 19:04 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: vireshk, robh+dt, sboyd, roger.lu, linux-pm, linux-arm-kernel,
	linux-samsung-soc, devicetree, b.zolnierkie, m.szyprowski

On Wed, Oct 16, 2019 at 04:57:55PM +0200, Sylwester Nawrocki wrote:
> The Adaptive Supply Voltage (ASV) driver adjusts CPU cluster operating
> points depending on exact revision of an SoC retrieved from the CHIPID
> block or the OTP memory.  This allows for some power saving as for some
> CPU clock frequencies we can lower CPU cluster's supply voltage comparing
> to safe values common to all the SoC revisions.
> 
> This patch adds support for Exynos5422/5800 SoC, it is partially based
> on code from https://github.com/hardkernel/linux repository,
> branch odroidxu4-4.14.y, files: arch/arm/mach-exynos/exynos5422-asv.[ch].
> 
> Tested on Odroid XU3, XU4, XU3 Lite.
> 
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>

Hi Sylwester,

I wanted to apply this patch but spotted some unusual printk... and then started looking for more...

Sparse complains:
../drivers/soc/samsung/exynos5422-asv.c:457:5: warning: symbol 'exynos5422_asv_init' was not declared. Should it be static?


> ---
> Changes since v4:
>  - Fixed include guard in drivers/soc/samsung/exynos5422-asv.h
> 
> Changes since v3:
>  - instead of removing/adding OPP use dedicated API to adjust OPP's
>    voltage, only exynos_asv_update_cpu_opps() function has changed,
>  - added a comment describing ASV tables at beginning of
>    exynos5422-asv.c file.
> 
> Changes since v2:
>  - use devm_kzalloc() in probe() to avoid memory leak,
>  - removed leading spaces in exynos-chipid.h,
>  - removed unneeded <linux/init.h> header inclusion,
>  - dropped parentheses from exynos542_asv_parse_sg(),
>  - updated Kconfig entry,
>  - added const attribute to struct exynos_asv_susbsys::cpu_dt_compat.
> 
> Changes since v1 (RFC):
>  - removed code for parsing the ASV OPP tables from DT, the ASV OPP tables
>    moved to the driver,
>  - converted to use the regmap API,
>  - converted to normal platform driver.
> 
>  drivers/soc/samsung/Kconfig          |  10 +
>  drivers/soc/samsung/Makefile         |   3 +
>  drivers/soc/samsung/exynos-asv.c     | 179 ++++++++++
>  drivers/soc/samsung/exynos-asv.h     |  82 +++++
>  drivers/soc/samsung/exynos5422-asv.c | 509 +++++++++++++++++++++++++++
>  drivers/soc/samsung/exynos5422-asv.h |  25 ++
>  6 files changed, 808 insertions(+)
>  create mode 100644 drivers/soc/samsung/exynos-asv.c
>  create mode 100644 drivers/soc/samsung/exynos-asv.h
>  create mode 100644 drivers/soc/samsung/exynos5422-asv.c
>  create mode 100644 drivers/soc/samsung/exynos5422-asv.h
> 
> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> index 33ad0de2de3c..27fc59bbb520 100644
> --- a/drivers/soc/samsung/Kconfig
> +++ b/drivers/soc/samsung/Kconfig
> @@ -7,6 +7,16 @@ menuconfig SOC_SAMSUNG
> 
>  if SOC_SAMSUNG
> 
> +config EXYNOS_ASV
> +	bool "Exynos Adaptive Supply Voltage support" if COMPILE_TEST
> +	depends on (ARCH_EXYNOS && EXYNOS_CHIPID) || COMPILE_TEST
> +	select EXYNOS_ASV_ARM if ARM && ARCH_EXYNOS
> +
> +# There is no need to enable these drivers for ARMv8
> +config EXYNOS_ASV_ARM
> +	bool "Exynos ASV ARMv7-specific driver extensions" if COMPILE_TEST
> +	depends on EXYNOS_ASV
> +
>  config EXYNOS_CHIPID
>  	bool "Exynos Chipid controller driver" if COMPILE_TEST
>  	depends on ARCH_EXYNOS || COMPILE_TEST
> diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
> index 3b6a8797416c..edd1d6ea064d 100644
> --- a/drivers/soc/samsung/Makefile
> +++ b/drivers/soc/samsung/Makefile
> @@ -1,5 +1,8 @@
>  # SPDX-License-Identifier: GPL-2.0
> 
> +obj-$(CONFIG_EXYNOS_ASV)	+= exynos-asv.o
> +obj-$(CONFIG_EXYNOS_ASV_ARM)	+= exynos5422-asv.o
> +
>  obj-$(CONFIG_EXYNOS_CHIPID)	+= exynos-chipid.o
>  obj-$(CONFIG_EXYNOS_PMU)	+= exynos-pmu.o
> 
> diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c
> new file mode 100644
> index 000000000000..c6f2e4f0dcc5
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-asv.c
> @@ -0,0 +1,179 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019 Samsung Electronics Co., Ltd.
> + *	      http://www.samsung.com/
> + * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
> + *
> + * Samsung Exynos SoC Adaptive Supply Voltage support
> + */
> +
> +#include <linux/cpu.h>
> +#include <linux/delay.h>

Do you use this header?

> +#include <linux/device.h>
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_opp.h>
> +#include <linux/regmap.h>
> +#include <linux/soc/samsung/exynos-chipid.h>
> +
> +#include "exynos-asv.h"
> +#include "exynos5422-asv.h"
> +
> +#define MHZ 1000000U
> +
> +static int exynos_asv_update_cpu_opps(struct exynos_asv *asv,
> +				      struct device *cpu)
> +{
> +	struct exynos_asv_subsys *subsys = NULL;
> +	struct dev_pm_opp *opp;
> +	unsigned int opp_freq;
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(asv->subsys); i++) {
> +		if (of_device_is_compatible(cpu->of_node,
> +					    asv->subsys[i].cpu_dt_compat)) {
> +			subsys = &asv->subsys[i];
> +			break;
> +		}
> +	}
> +	if (!subsys)
> +		return -EINVAL;
> +
> +	for (i = 0; i < subsys->table.num_rows; i++) {
> +		unsigned int new_volt, volt;
> +		int ret;
> +
> +		opp_freq = exynos_asv_opp_get_frequency(subsys, i);
> +
> +		opp = dev_pm_opp_find_freq_exact(cpu, opp_freq * MHZ, true);
> +		if (IS_ERR(opp)) {
> +			dev_info(asv->dev, "cpu%d opp%d, freq: %u missing\n",
> +				 cpu->id, i, opp_freq);
> +
> +			continue;
> +		}
> +
> +		volt = dev_pm_opp_get_voltage(opp);
> +		new_volt = asv->opp_get_voltage(subsys, i, volt);
> +		dev_pm_opp_put(opp);
> +
> +		if (new_volt == volt)
> +			continue;
> +
> +		ret = dev_pm_opp_adjust_voltage(cpu, opp_freq * MHZ,
> +						new_volt, new_volt, new_volt);
> +		if (ret < 0)
> +			dev_err(asv->dev,
> +				"Failed to adjust OPP %u Hz/%u uV for cpu%d\n",
> +				opp_freq, new_volt, cpu->id);
> +		else
> +			dev_dbg(asv->dev,
> +				"Adjusted OPP %u Hz/%u -> %u uV, cpu%d\n",
> +				opp_freq, volt, new_volt, cpu->id);
> +	}
> +
> +	return 0;
> +}
> +
> +static int exynos_asv_update_opps(struct exynos_asv *asv)
> +{
> +	struct opp_table *last_opp_table = NULL;
> +	struct device *cpu;
> +	int ret, cpuid;
> +
> +	for_each_possible_cpu(cpuid) {
> +		struct opp_table *opp_table;
> +
> +		cpu = get_cpu_device(cpuid);
> +		if (!cpu)
> +			continue;
> +
> +		opp_table = dev_pm_opp_get_opp_table(cpu);
> +		if (IS_ERR(opp_table))
> +			continue;
> +
> +		if (!last_opp_table || opp_table != last_opp_table) {
> +			last_opp_table = opp_table;
> +
> +			ret = exynos_asv_update_cpu_opps(asv, cpu);
> +			if (ret < 0)
> +				dev_err(asv->dev, "Couldn't udate OPPs for cpu%d\n",
> +					cpuid);
> +		}
> +
> +		dev_pm_opp_put_opp_table(opp_table);
> +	}
> +
> +	return	0;
> +}
> +
> +static int exynos_asv_probe(struct platform_device *pdev)
> +{
> +	int (*probe_func)(struct exynos_asv *asv);
> +	struct exynos_asv *asv;
> +	struct device *cpu_dev;
> +	u32 product_id = 0;
> +	int ret, i;
> +
> +	cpu_dev = get_cpu_device(0);
> +	ret = dev_pm_opp_get_opp_count(cpu_dev);
> +	if (ret < 0)
> +		return -EPROBE_DEFER;
> +
> +	asv = devm_kzalloc(&pdev->dev, sizeof(*asv), GFP_KERNEL);
> +	if (!asv)
> +		return -ENOMEM;
> +
> +	asv->chipid_regmap = syscon_node_to_regmap(pdev->dev.of_node);

Since this binds to the same node as chipid, why do you need syscon for
it? Why regular IO access does not work? Eventually, if this has to be
regmap because of locking (does it?), then maybe simply
device_node_to_regmap()?

> +	if (IS_ERR(asv->chipid_regmap)) {
> +		dev_err(&pdev->dev, "Could not find syscon regmap\n");
> +		return PTR_ERR(asv->chipid_regmap);
> +	}
> +
> +	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);
> +
> +	switch (product_id & EXYNOS_MASK) {
> +	case 0xE5422000:
> +		probe_func = exynos5422_asv_init;
> +		break;
> +	default:
> +		dev_err(&pdev->dev, "Unsupported product ID: %#x", product_id);

Is this going to scream for every Exynos matching the 4210-chipid?

> +		return -ENODEV;
> +	}
> +
> +	ret = of_property_read_u32(pdev->dev.of_node, "samsung,asv-bin",
> +				   &asv->of_bin);
> +	if (ret < 0)
> +		asv->of_bin = -EINVAL;
> +
> +	asv->dev = &pdev->dev;
> +	dev_set_drvdata(&pdev->dev, asv);
> +
> +	for (i = 0; i < ARRAY_SIZE(asv->subsys); i++)
> +		asv->subsys[i].asv = asv;
> +
> +	ret = probe_func(asv);
> +	if (ret < 0)
> +		return ret;
> +
> +	return exynos_asv_update_opps(asv);
> +}
> +
> +static const struct of_device_id exynos_asv_of_device_ids[] = {
> +	{ .compatible = "samsung,exynos4210-chipid" },
> +	{}
> +};
> +
> +static struct platform_driver exynos_asv_driver = {
> +	.driver = {
> +		.name = "exynos-asv",
> +		.of_match_table = exynos_asv_of_device_ids,
> +	},
> +	.probe	= exynos_asv_probe,
> +};
> +module_platform_driver(exynos_asv_driver);
> diff --git a/drivers/soc/samsung/exynos-asv.h b/drivers/soc/samsung/exynos-asv.h
> new file mode 100644
> index 000000000000..14b4fedf2ddd
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-asv.h
> @@ -0,0 +1,82 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2019 Samsung Electronics Co., Ltd.
> + *	      http://www.samsung.com/
> + * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
> + *
> + * Samsung Exynos SoC Adaptive Supply Voltage support
> + */
> +#ifndef __LINUX_SOC_EXYNOS_ASV_H
> +#define __LINUX_SOC_EXYNOS_ASV_H
> +
> +enum {
> +	EXYNOS_ASV_SUBSYS_ID_ARM,
> +	EXYNOS_ASV_SUBSYS_ID_EGL = EXYNOS_ASV_SUBSYS_ID_ARM,
> +	EXYNOS_ASV_SUBSYS_ID_KFC,
> +	EXYNOS_ASV_SUBSYS_ID_INT,
> +	EXYNOS_ASV_SUBSYS_ID_MIF,
> +	EXYNOS_ASV_SUBSYS_ID_G3D,
> +	EXYNOS_ASV_SUBSYS_ID_CAM,
> +	EXYNOS_ASV_SUBSYS_ID_MAX
> +};

I cannot find usage of it in generic part of ASV driver. What's the
purpose? Isn't it specific to Exynos5422?

> +
> +struct regmap;
> +
> +/* HPM, IDS values to select target group */
> +struct asv_limit_entry {
> +	unsigned int hpm;
> +	unsigned int ids;
> +};
> +
> +struct exynos_asv_table {
> +	unsigned int num_rows;
> +	unsigned int num_cols;
> +	u32 *buf;
> +};
> +
> +struct exynos_asv_subsys {
> +	struct exynos_asv *asv;
> +	const char *cpu_dt_compat;
> +	int id;
> +	struct exynos_asv_table table;
> +
> +	unsigned int base_volt;
> +	unsigned int offset_volt_h;
> +	unsigned int offset_volt_l;
> +};
> +
> +struct exynos_asv {
> +	struct device *dev;
> +	struct regmap *chipid_regmap;
> +	struct exynos_asv_subsys subsys[2];
> +
> +	int (*opp_get_voltage)(struct exynos_asv_subsys *subs, int level,
> +			       unsigned int voltage);
> +	unsigned int group;
> +	unsigned int table;
> +
> +	/* True if SG fields from PKG_ID register should be used */
> +	bool use_sg;
> +	/* ASV bin read from DT */
> +	int of_bin;
> +};
> +
> +static inline u32 __asv_get_table_entry(struct exynos_asv_table *table,

'table' looks here like pointer to const.

> +					unsigned int row, unsigned int col)
> +{
> +	return table->buf[row * (table->num_cols) + col];
> +}
> +
> +static inline u32 exynos_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
> +					unsigned int level, unsigned int group)
> +{

The same, for subsys.

> +	return __asv_get_table_entry(&subsys->table, level, group + 1);
> +}
> +
> +static inline u32 exynos_asv_opp_get_frequency(struct exynos_asv_subsys *subsys,
> +					unsigned int level)
> +{

The same.

> +	return __asv_get_table_entry(&subsys->table, level, 0);
> +}
> +
> +#endif /* __LINUX_SOC_EXYNOS_ASV_H */
> diff --git a/drivers/soc/samsung/exynos5422-asv.c b/drivers/soc/samsung/exynos5422-asv.c
> new file mode 100644
> index 000000000000..7982f2ca0f11
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos5422-asv.c
> @@ -0,0 +1,509 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019 Samsung Electronics Co., Ltd.
> + *	      http://www.samsung.com/
> + *
> + * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
> + */
> +
> +#include <linux/bitrev.h>
> +#include <linux/device.h>

Is it used?

> +#include <linux/errno.h>
> +#include <linux/of.h>

The same?

> +#include <linux/regmap.h>
> +#include <linux/soc/samsung/exynos-chipid.h>
> +#include <linux/slab.h>
> +
> +#include "exynos-asv.h"
> +
> +#define ASV_GROUPS_NUM		14
> +#define ASV_ARM_DVFS_NUM	20
> +#define ASV_ARM_BIN2_DVFS_NUM	17
> +#define ASV_KFC_DVFS_NUM	14
> +#define ASV_KFC_BIN2_DVFS_NUM	12
> +
> +/*
> + * This array is a set of 4 ASV data tables, first column of each ASV table
> + * contains frequency value in MHz and subsequent columns contain the CPU
> + * cluster's supply voltage values in uV.
> + * In order to create a set of OPPs for specific SoC revision one of the voltage
> + * columns (1...14) from one of the tables (0...3) is selected during
> + * initialization. There are separate ASV tables for the big (ARM) and little
> + * (KFC) CPU cluster. Only OPPs which are already defined in devicetree
> + * will be updated.
> + */
> +
> +static const u32 asv_arm_table[][ASV_ARM_DVFS_NUM][ASV_GROUPS_NUM + 1] = {
> +{
> +	/* ARM 0, 1 */
> +	{ 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
> +	  1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
> +	{ 2000,    1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000,
> +	  1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +	{ 1900,    1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000,
> +	  1162500, 1150000, 1162500, 1150000, 1137500, 1125000, 1112500 },
> +	{ 1800,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
> +	  1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
> +	{ 1700,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
> +	  1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
> +	{ 1600,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
> +	  1037500, 1025000, 1037500, 1025000, 1012500, 1000000, 987500 },
> +	{ 1500,    1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
> +	  1000000, 987500,  1000000, 987500,  975000,  962500,  950000 },
> +	{ 1400,    1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
> +	  975000,  962500,  975000,  962500,  950000,  937500,  925000 },
> +	{ 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
> +	  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
> +	{ 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +	  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
> +	{ 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
> +	  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +	/* ARM 2 */
> +	{ 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
> +	  1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
> +	{ 2000,    1312500, 1312500, 1312500, 1300000, 1275000, 1262500, 1250000,
> +	  1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +	{ 1900,    1262500, 1250000, 1250000, 1237500, 1212500, 1200000, 1187500,
> +	  1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
> +	{ 1800,    1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500,
> +	  1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
> +	{ 1700,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
> +	  1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
> +	{ 1600,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
> +	  1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
> +	{ 1500,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +	  1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
> +	{ 1400,    1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,
> +	  987500,  975000,  987500,  975000,  962500,  950000,  937500 },
> +	{ 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
> +	  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
> +	{ 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +	  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
> +	{ 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
> +	  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +	/* ARM 3 */
> +	{ 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
> +	  1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
> +	{ 2000,    1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000,
> +	  1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +	{ 1900,    1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500,
> +	  1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
> +	{ 1800,    1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500,
> +	  1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
> +	{ 1700,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
> +	  1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
> +	{ 1600,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
> +	  1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
> +	{ 1500,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +	  1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
> +	{ 1400,    1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,
> +	  987500,  975000,  987500,  975000,  962500,  950000,  937500 },
> +	{ 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
> +	  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
> +	{ 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +	  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
> +	{ 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
> +	  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +	/* ARM bin 2 */
> +	{ 1800,    1237500, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500,
> +	  1150000, 1137500, 1150000, 1137500, 1125000, 1112500, 1100000 },
> +	{ 1700,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
> +	  1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
> +	{ 1600,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
> +	  1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
> +	{ 1500,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
> +	  1037500, 1025000, 1037500, 1025000, 1012500, 1000000, 987500 },
> +	{ 1400,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +	  1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
> +	{ 1300,    1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
> +	  1000000, 987500,  1000000, 987500,  975000,  962500,  950000 },
> +	{ 1200,    1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
> +	  975000,  962500,  975000,  962500,  950000,  937500,  925000 },
> +	{ 1100,    1037500, 1025000, 1012500, 1000000, 987500,  975000,  962500,
> +	  950000,  937500,  950000,  937500,  925000,  912500,  900000 },
> +	{ 1000,    1012500, 1000000, 987500,  975000,  962500,  950000,  937500,
> +	  925000,  912500,  925000,  912500,  900000,  900000,  900000 },
> +	{ 900,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 800,     962500,  950000,  937500,  925000,  912500,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 700,     937500,  925000,  912500,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}
> +};
> +
> +static const u32 asv_kfc_table[][ASV_KFC_DVFS_NUM][ASV_GROUPS_NUM + 1] = {
> +{
> +	/* KFC 0, 1 */
> +	{ 1500000, 1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
> +	  1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +	{ 1400000, 1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
> +	  1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
> +	{ 1300000, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
> +	  1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
> +	{ 1200000, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
> +	  1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
> +	{ 1100000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
> +	  1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
> +	{ 1000000, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +	  1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
> +	{ 900000,  1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
> +	  975000,  962500,  950000,  937500,  925000,  912500,  900000 },
> +	{ 800000,  1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +	  937500,  925000,  912500,  900000,  900000,  900000,  900000 },
> +	{ 700000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 600000,  950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 500000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 400000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 300000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 200000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +	/* KFC 2 */
> +	{ 1500,    1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
> +	  1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +	{ 1400,    1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
> +	  1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
> +	{ 1300,    1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
> +	  1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
> +	{ 1200,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
> +	  1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
> +	{ 1100,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
> +	  1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
> +	{ 1000,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +	  1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
> +	{ 900,     1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
> +	  975000,  962500,  950000,  937500,  925000,  912500,  900000 },
> +	{ 800,     1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +	  937500,  925000,  912500,  900000,  900000,  900000,  900000 },
> +	{ 700,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 600,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 500,     912500,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +	/* KFC 3 */
> +	{ 1500,    1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
> +	  1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +	{ 1400,    1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
> +	  1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
> +	{ 1300,    1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
> +	  1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
> +	{ 1200,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
> +	  1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
> +	{ 1100,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
> +	  1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
> +	{ 1000,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +	  1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
> +	{ 900,     1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
> +	  975000,  962500,  950000,  937500,  925000,  912500,  900000 },
> +	{ 800,     1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +	  937500,  925000,  912500,  900000,  900000,  900000,  900000 },
> +	{ 700,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 600,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 500,     912500,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +	/* KFC bin 2 */
> +	{ 1300,    1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000,
> +	  1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500 },
> +	{ 1200,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
> +	  1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500 },
> +	{ 1100,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
> +	  1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000 },
> +	{ 1000,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
> +	  1037500, 1025000, 1012500, 1000000, 987500,  975000,  962500 },
> +	{ 900,     1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
> +	  1000000, 987500,  975000,  962500,  950000,  937500,  925000 },
> +	{ 800,     1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
> +	  962500,  950000,  937500,  925000,  912500,  900000,  900000 },
> +	{ 700,     1012500, 1000000, 987500,  975000,  962500,  950000,  937500,
> +	  925000,  912500,  900000,  900000,  900000,  900000,  900000 },
> +	{ 600,     975000,  962500,  950000,  937500,  925000,  912500,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 500,     937500,  925000,  912500,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 400,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}
> +};
> +
> +static const struct asv_limit_entry __asv_limits[ASV_GROUPS_NUM] = {
> +	{ 13, 55 },
> +	{ 21, 65 },
> +	{ 25, 69 },
> +	{ 30, 72 },
> +	{ 36, 74 },
> +	{ 43, 76 },
> +	{ 51, 78 },
> +	{ 65, 80 },
> +	{ 81, 82 },
> +	{ 98, 84 },
> +	{ 119, 87 },
> +	{ 135, 89 },
> +	{ 150, 92 },
> +	{ 999, 999 },
> +};
> +
> +static int exynos5422_asv_get_group(struct exynos_asv *asv)
> +{
> +	unsigned int pkgid_reg, auxi_reg;
> +	int hpm, ids, i;
> +
> +	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PKG_ID, &pkgid_reg);
> +	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_AUX_INFO, &auxi_reg);
> +
> +	if (asv->use_sg) {
> +		u32 sga = (pkgid_reg >> EXYNOS5422_SG_A_OFFSET) &
> +			   EXYNOS5422_SG_A_MASK;
> +
> +		u32 sgb = (pkgid_reg >> EXYNOS5422_SG_B_OFFSET) &
> +			   EXYNOS5422_SG_B_MASK;
> +
> +		if ((pkgid_reg >> EXYNOS5422_SG_BSIGN_OFFSET) &
> +		     EXYNOS5422_SG_BSIGN_MASK)
> +			return sga + sgb;
> +		else
> +			return sga - sgb;
> +	}
> +
> +	hpm = (auxi_reg >> EXYNOS5422_TMCB_OFFSET) & EXYNOS5422_TMCB_MASK;
> +	ids = (pkgid_reg >> EXYNOS5422_IDS_OFFSET) & EXYNOS5422_IDS_MASK;
> +
> +	for (i = 0; i < ASV_GROUPS_NUM; i++) {
> +		if (ids <= __asv_limits[i].ids)
> +			break;
> +		if (hpm <= __asv_limits[i].hpm)
> +			break;
> +	}
> +	if (i < ASV_GROUPS_NUM)
> +		return i;
> +
> +	return 0;
> +}
> +
> +static int __asv_offset_voltage(unsigned int index)
> +{
> +	switch (index) {
> +	case 1:
> +		return 12500;
> +	case 2:
> +		return 50000;
> +	case 3:
> +		return 25000;
> +	default:
> +		return 0;
> +	};
> +}
> +
> +static void exynos5422_asv_offset_voltage_setup(struct exynos_asv *asv)
> +{
> +	struct exynos_asv_subsys *subsys;
> +	unsigned int reg, value;
> +
> +	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_AUX_INFO, &reg);
> +
> +	/* ARM offset voltage setup */
> +	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_ARM];
> +
> +	subsys->base_volt = 1000000;
> +
> +	value = (reg >> EXYNOS5422_ARM_UP_OFFSET) & EXYNOS5422_ARM_UP_MASK;
> +	subsys->offset_volt_h = __asv_offset_voltage(value);
> +
> +	value = (reg >> EXYNOS5422_ARM_DN_OFFSET) & EXYNOS5422_ARM_DN_MASK;
> +	subsys->offset_volt_l = __asv_offset_voltage(value);
> +
> +	/* KFC offset voltage setup */
> +	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_KFC];
> +
> +	subsys->base_volt = 1000000;
> +
> +	value = (reg >> EXYNOS5422_KFC_UP_OFFSET) & EXYNOS5422_KFC_UP_MASK;
> +	subsys->offset_volt_h = __asv_offset_voltage(value);
> +
> +	value = (reg >> EXYNOS5422_KFC_DN_OFFSET) & EXYNOS5422_KFC_DN_MASK;
> +	subsys->offset_volt_l = __asv_offset_voltage(value);
> +}
> +
> +static int exynos5422_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
> +				int level, unsigned int volt)

subsys is not modified.

> +{
> +	unsigned int asv_volt;
> +
> +	if (level >= subsys->table.num_rows)
> +		return volt;
> +
> +	asv_volt = exynos_asv_opp_get_voltage(subsys, level,
> +					      subsys->asv->group);
> +
> +	if (volt > subsys->base_volt)
> +		asv_volt += subsys->offset_volt_h;
> +	else
> +		asv_volt += subsys->offset_volt_l;
> +
> +	return asv_volt;
> +}
> +
> +static unsigned int exynos5422_asv_parse_table(struct exynos_asv *asv,
> +				      unsigned int pkg_id)
> +{

The same, for asv. Looks BTW unused...

> +	return (pkg_id >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
> +}
> +
> +static bool exynos5422_asv_parse_bin2(struct exynos_asv *asv,
> +				     unsigned int pkg_id)
> +{

The same.

> +	return (pkg_id >> EXYNOS5422_BIN2_OFFSET) & EXYNOS5422_BIN2_MASK;
> +}
> +
> +static bool exynos5422_asv_parse_sg(struct exynos_asv *asv,
> +					unsigned int pkg_id)
> +{

The same.

> +	return (pkg_id >> EXYNOS5422_USESG_OFFSET) & EXYNOS5422_USESG_MASK;
> +}
> +
> +int exynos5422_asv_init(struct exynos_asv *asv)
> +{
> +	struct exynos_asv_subsys *subsys;
> +	unsigned int table_index;
> +	unsigned int pkg_id;
> +	bool bin2;
> +

How about checking if asv != null? It's a header exposed function.

Best regards,
Krzysztof


> +	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PKG_ID, &pkg_id);
> +
> +	if (asv->of_bin == 2) {
> +		bin2 = true;
> +		asv->use_sg = false;
> +	} else {
> +		asv->use_sg = exynos5422_asv_parse_sg(asv, pkg_id);
> +		bin2 = exynos5422_asv_parse_bin2(asv, pkg_id);
> +	}
> +
> +	asv->group = exynos5422_asv_get_group(asv);
> +	asv->table = exynos5422_asv_parse_table(asv, pkg_id);
> +
> +	exynos5422_asv_offset_voltage_setup(asv);
> +
> +	if (bin2) {
> +		table_index = 3;
> +	} else {
> +		if (asv->table == 2 || asv->table == 3)
> +			table_index = asv->table - 1;
> +		else
> +			table_index = 0;
> +	}
> +
> +	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_ARM];
> +	subsys->cpu_dt_compat = "arm,cortex-a15";
> +	if (bin2)
> +		subsys->table.num_rows = ASV_ARM_BIN2_DVFS_NUM;
> +	else
> +		subsys->table.num_rows = ASV_ARM_DVFS_NUM;
> +	subsys->table.num_cols = ASV_GROUPS_NUM + 1;
> +	subsys->table.buf = (u32 *)asv_arm_table[table_index];
> +
> +	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_KFC];
> +	subsys->cpu_dt_compat = "arm,cortex-a7";
> +	if (bin2)
> +		subsys->table.num_rows = ASV_KFC_BIN2_DVFS_NUM;
> +	else
> +		subsys->table.num_rows = ASV_KFC_DVFS_NUM;
> +	subsys->table.num_cols = ASV_GROUPS_NUM + 1;
> +	subsys->table.buf = (u32 *)asv_kfc_table[table_index];
> +
> +	asv->opp_get_voltage = exynos5422_asv_opp_get_voltage;
> +
> +	return 0;
> +}
> diff --git a/drivers/soc/samsung/exynos5422-asv.h b/drivers/soc/samsung/exynos5422-asv.h
> new file mode 100644
> index 000000000000..85218d2800fb
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos5422-asv.h
> @@ -0,0 +1,25 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2019 Samsung Electronics Co., Ltd.
> + *	      http://www.samsung.com/
> + *
> + * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
> + */
> +
> +#ifndef __LINUX_SOC_EXYNOS5422_ASV_H
> +#define __LINUX_SOC_EXYNOS5422_ASV_H
> +
> +#include <linux/errno.h>
> +
> +struct exynos_asv;
> +
> +#ifdef CONFIG_EXYNOS_ASV_ARM
> +int exynos5422_asv_init(struct exynos_asv *asv);
> +#else
> +static inline int exynos5422_asv_init(struct exynos_asv *asv)
> +{
> +	return -ENOTSUPP;
> +}
> +#endif
> +
> +#endif /* __LINUX_SOC_EXYNOS5422_ASV_H */
> --
> 2.17.1
> 

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

* Re: [PATCH v5 3/4] soc: samsung: Add Exynos Adaptive Supply Voltage driver
@ 2019-10-22 19:04         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2019-10-22 19:04 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: devicetree, linux-samsung-soc, linux-pm, sboyd, vireshk,
	b.zolnierkie, roger.lu, robh+dt, linux-arm-kernel, m.szyprowski

On Wed, Oct 16, 2019 at 04:57:55PM +0200, Sylwester Nawrocki wrote:
> The Adaptive Supply Voltage (ASV) driver adjusts CPU cluster operating
> points depending on exact revision of an SoC retrieved from the CHIPID
> block or the OTP memory.  This allows for some power saving as for some
> CPU clock frequencies we can lower CPU cluster's supply voltage comparing
> to safe values common to all the SoC revisions.
> 
> This patch adds support for Exynos5422/5800 SoC, it is partially based
> on code from https://github.com/hardkernel/linux repository,
> branch odroidxu4-4.14.y, files: arch/arm/mach-exynos/exynos5422-asv.[ch].
> 
> Tested on Odroid XU3, XU4, XU3 Lite.
> 
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>

Hi Sylwester,

I wanted to apply this patch but spotted some unusual printk... and then started looking for more...

Sparse complains:
../drivers/soc/samsung/exynos5422-asv.c:457:5: warning: symbol 'exynos5422_asv_init' was not declared. Should it be static?


> ---
> Changes since v4:
>  - Fixed include guard in drivers/soc/samsung/exynos5422-asv.h
> 
> Changes since v3:
>  - instead of removing/adding OPP use dedicated API to adjust OPP's
>    voltage, only exynos_asv_update_cpu_opps() function has changed,
>  - added a comment describing ASV tables at beginning of
>    exynos5422-asv.c file.
> 
> Changes since v2:
>  - use devm_kzalloc() in probe() to avoid memory leak,
>  - removed leading spaces in exynos-chipid.h,
>  - removed unneeded <linux/init.h> header inclusion,
>  - dropped parentheses from exynos542_asv_parse_sg(),
>  - updated Kconfig entry,
>  - added const attribute to struct exynos_asv_susbsys::cpu_dt_compat.
> 
> Changes since v1 (RFC):
>  - removed code for parsing the ASV OPP tables from DT, the ASV OPP tables
>    moved to the driver,
>  - converted to use the regmap API,
>  - converted to normal platform driver.
> 
>  drivers/soc/samsung/Kconfig          |  10 +
>  drivers/soc/samsung/Makefile         |   3 +
>  drivers/soc/samsung/exynos-asv.c     | 179 ++++++++++
>  drivers/soc/samsung/exynos-asv.h     |  82 +++++
>  drivers/soc/samsung/exynos5422-asv.c | 509 +++++++++++++++++++++++++++
>  drivers/soc/samsung/exynos5422-asv.h |  25 ++
>  6 files changed, 808 insertions(+)
>  create mode 100644 drivers/soc/samsung/exynos-asv.c
>  create mode 100644 drivers/soc/samsung/exynos-asv.h
>  create mode 100644 drivers/soc/samsung/exynos5422-asv.c
>  create mode 100644 drivers/soc/samsung/exynos5422-asv.h
> 
> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> index 33ad0de2de3c..27fc59bbb520 100644
> --- a/drivers/soc/samsung/Kconfig
> +++ b/drivers/soc/samsung/Kconfig
> @@ -7,6 +7,16 @@ menuconfig SOC_SAMSUNG
> 
>  if SOC_SAMSUNG
> 
> +config EXYNOS_ASV
> +	bool "Exynos Adaptive Supply Voltage support" if COMPILE_TEST
> +	depends on (ARCH_EXYNOS && EXYNOS_CHIPID) || COMPILE_TEST
> +	select EXYNOS_ASV_ARM if ARM && ARCH_EXYNOS
> +
> +# There is no need to enable these drivers for ARMv8
> +config EXYNOS_ASV_ARM
> +	bool "Exynos ASV ARMv7-specific driver extensions" if COMPILE_TEST
> +	depends on EXYNOS_ASV
> +
>  config EXYNOS_CHIPID
>  	bool "Exynos Chipid controller driver" if COMPILE_TEST
>  	depends on ARCH_EXYNOS || COMPILE_TEST
> diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
> index 3b6a8797416c..edd1d6ea064d 100644
> --- a/drivers/soc/samsung/Makefile
> +++ b/drivers/soc/samsung/Makefile
> @@ -1,5 +1,8 @@
>  # SPDX-License-Identifier: GPL-2.0
> 
> +obj-$(CONFIG_EXYNOS_ASV)	+= exynos-asv.o
> +obj-$(CONFIG_EXYNOS_ASV_ARM)	+= exynos5422-asv.o
> +
>  obj-$(CONFIG_EXYNOS_CHIPID)	+= exynos-chipid.o
>  obj-$(CONFIG_EXYNOS_PMU)	+= exynos-pmu.o
> 
> diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c
> new file mode 100644
> index 000000000000..c6f2e4f0dcc5
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-asv.c
> @@ -0,0 +1,179 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019 Samsung Electronics Co., Ltd.
> + *	      http://www.samsung.com/
> + * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
> + *
> + * Samsung Exynos SoC Adaptive Supply Voltage support
> + */
> +
> +#include <linux/cpu.h>
> +#include <linux/delay.h>

Do you use this header?

> +#include <linux/device.h>
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_opp.h>
> +#include <linux/regmap.h>
> +#include <linux/soc/samsung/exynos-chipid.h>
> +
> +#include "exynos-asv.h"
> +#include "exynos5422-asv.h"
> +
> +#define MHZ 1000000U
> +
> +static int exynos_asv_update_cpu_opps(struct exynos_asv *asv,
> +				      struct device *cpu)
> +{
> +	struct exynos_asv_subsys *subsys = NULL;
> +	struct dev_pm_opp *opp;
> +	unsigned int opp_freq;
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(asv->subsys); i++) {
> +		if (of_device_is_compatible(cpu->of_node,
> +					    asv->subsys[i].cpu_dt_compat)) {
> +			subsys = &asv->subsys[i];
> +			break;
> +		}
> +	}
> +	if (!subsys)
> +		return -EINVAL;
> +
> +	for (i = 0; i < subsys->table.num_rows; i++) {
> +		unsigned int new_volt, volt;
> +		int ret;
> +
> +		opp_freq = exynos_asv_opp_get_frequency(subsys, i);
> +
> +		opp = dev_pm_opp_find_freq_exact(cpu, opp_freq * MHZ, true);
> +		if (IS_ERR(opp)) {
> +			dev_info(asv->dev, "cpu%d opp%d, freq: %u missing\n",
> +				 cpu->id, i, opp_freq);
> +
> +			continue;
> +		}
> +
> +		volt = dev_pm_opp_get_voltage(opp);
> +		new_volt = asv->opp_get_voltage(subsys, i, volt);
> +		dev_pm_opp_put(opp);
> +
> +		if (new_volt == volt)
> +			continue;
> +
> +		ret = dev_pm_opp_adjust_voltage(cpu, opp_freq * MHZ,
> +						new_volt, new_volt, new_volt);
> +		if (ret < 0)
> +			dev_err(asv->dev,
> +				"Failed to adjust OPP %u Hz/%u uV for cpu%d\n",
> +				opp_freq, new_volt, cpu->id);
> +		else
> +			dev_dbg(asv->dev,
> +				"Adjusted OPP %u Hz/%u -> %u uV, cpu%d\n",
> +				opp_freq, volt, new_volt, cpu->id);
> +	}
> +
> +	return 0;
> +}
> +
> +static int exynos_asv_update_opps(struct exynos_asv *asv)
> +{
> +	struct opp_table *last_opp_table = NULL;
> +	struct device *cpu;
> +	int ret, cpuid;
> +
> +	for_each_possible_cpu(cpuid) {
> +		struct opp_table *opp_table;
> +
> +		cpu = get_cpu_device(cpuid);
> +		if (!cpu)
> +			continue;
> +
> +		opp_table = dev_pm_opp_get_opp_table(cpu);
> +		if (IS_ERR(opp_table))
> +			continue;
> +
> +		if (!last_opp_table || opp_table != last_opp_table) {
> +			last_opp_table = opp_table;
> +
> +			ret = exynos_asv_update_cpu_opps(asv, cpu);
> +			if (ret < 0)
> +				dev_err(asv->dev, "Couldn't udate OPPs for cpu%d\n",
> +					cpuid);
> +		}
> +
> +		dev_pm_opp_put_opp_table(opp_table);
> +	}
> +
> +	return	0;
> +}
> +
> +static int exynos_asv_probe(struct platform_device *pdev)
> +{
> +	int (*probe_func)(struct exynos_asv *asv);
> +	struct exynos_asv *asv;
> +	struct device *cpu_dev;
> +	u32 product_id = 0;
> +	int ret, i;
> +
> +	cpu_dev = get_cpu_device(0);
> +	ret = dev_pm_opp_get_opp_count(cpu_dev);
> +	if (ret < 0)
> +		return -EPROBE_DEFER;
> +
> +	asv = devm_kzalloc(&pdev->dev, sizeof(*asv), GFP_KERNEL);
> +	if (!asv)
> +		return -ENOMEM;
> +
> +	asv->chipid_regmap = syscon_node_to_regmap(pdev->dev.of_node);

Since this binds to the same node as chipid, why do you need syscon for
it? Why regular IO access does not work? Eventually, if this has to be
regmap because of locking (does it?), then maybe simply
device_node_to_regmap()?

> +	if (IS_ERR(asv->chipid_regmap)) {
> +		dev_err(&pdev->dev, "Could not find syscon regmap\n");
> +		return PTR_ERR(asv->chipid_regmap);
> +	}
> +
> +	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);
> +
> +	switch (product_id & EXYNOS_MASK) {
> +	case 0xE5422000:
> +		probe_func = exynos5422_asv_init;
> +		break;
> +	default:
> +		dev_err(&pdev->dev, "Unsupported product ID: %#x", product_id);

Is this going to scream for every Exynos matching the 4210-chipid?

> +		return -ENODEV;
> +	}
> +
> +	ret = of_property_read_u32(pdev->dev.of_node, "samsung,asv-bin",
> +				   &asv->of_bin);
> +	if (ret < 0)
> +		asv->of_bin = -EINVAL;
> +
> +	asv->dev = &pdev->dev;
> +	dev_set_drvdata(&pdev->dev, asv);
> +
> +	for (i = 0; i < ARRAY_SIZE(asv->subsys); i++)
> +		asv->subsys[i].asv = asv;
> +
> +	ret = probe_func(asv);
> +	if (ret < 0)
> +		return ret;
> +
> +	return exynos_asv_update_opps(asv);
> +}
> +
> +static const struct of_device_id exynos_asv_of_device_ids[] = {
> +	{ .compatible = "samsung,exynos4210-chipid" },
> +	{}
> +};
> +
> +static struct platform_driver exynos_asv_driver = {
> +	.driver = {
> +		.name = "exynos-asv",
> +		.of_match_table = exynos_asv_of_device_ids,
> +	},
> +	.probe	= exynos_asv_probe,
> +};
> +module_platform_driver(exynos_asv_driver);
> diff --git a/drivers/soc/samsung/exynos-asv.h b/drivers/soc/samsung/exynos-asv.h
> new file mode 100644
> index 000000000000..14b4fedf2ddd
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-asv.h
> @@ -0,0 +1,82 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2019 Samsung Electronics Co., Ltd.
> + *	      http://www.samsung.com/
> + * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
> + *
> + * Samsung Exynos SoC Adaptive Supply Voltage support
> + */
> +#ifndef __LINUX_SOC_EXYNOS_ASV_H
> +#define __LINUX_SOC_EXYNOS_ASV_H
> +
> +enum {
> +	EXYNOS_ASV_SUBSYS_ID_ARM,
> +	EXYNOS_ASV_SUBSYS_ID_EGL = EXYNOS_ASV_SUBSYS_ID_ARM,
> +	EXYNOS_ASV_SUBSYS_ID_KFC,
> +	EXYNOS_ASV_SUBSYS_ID_INT,
> +	EXYNOS_ASV_SUBSYS_ID_MIF,
> +	EXYNOS_ASV_SUBSYS_ID_G3D,
> +	EXYNOS_ASV_SUBSYS_ID_CAM,
> +	EXYNOS_ASV_SUBSYS_ID_MAX
> +};

I cannot find usage of it in generic part of ASV driver. What's the
purpose? Isn't it specific to Exynos5422?

> +
> +struct regmap;
> +
> +/* HPM, IDS values to select target group */
> +struct asv_limit_entry {
> +	unsigned int hpm;
> +	unsigned int ids;
> +};
> +
> +struct exynos_asv_table {
> +	unsigned int num_rows;
> +	unsigned int num_cols;
> +	u32 *buf;
> +};
> +
> +struct exynos_asv_subsys {
> +	struct exynos_asv *asv;
> +	const char *cpu_dt_compat;
> +	int id;
> +	struct exynos_asv_table table;
> +
> +	unsigned int base_volt;
> +	unsigned int offset_volt_h;
> +	unsigned int offset_volt_l;
> +};
> +
> +struct exynos_asv {
> +	struct device *dev;
> +	struct regmap *chipid_regmap;
> +	struct exynos_asv_subsys subsys[2];
> +
> +	int (*opp_get_voltage)(struct exynos_asv_subsys *subs, int level,
> +			       unsigned int voltage);
> +	unsigned int group;
> +	unsigned int table;
> +
> +	/* True if SG fields from PKG_ID register should be used */
> +	bool use_sg;
> +	/* ASV bin read from DT */
> +	int of_bin;
> +};
> +
> +static inline u32 __asv_get_table_entry(struct exynos_asv_table *table,

'table' looks here like pointer to const.

> +					unsigned int row, unsigned int col)
> +{
> +	return table->buf[row * (table->num_cols) + col];
> +}
> +
> +static inline u32 exynos_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
> +					unsigned int level, unsigned int group)
> +{

The same, for subsys.

> +	return __asv_get_table_entry(&subsys->table, level, group + 1);
> +}
> +
> +static inline u32 exynos_asv_opp_get_frequency(struct exynos_asv_subsys *subsys,
> +					unsigned int level)
> +{

The same.

> +	return __asv_get_table_entry(&subsys->table, level, 0);
> +}
> +
> +#endif /* __LINUX_SOC_EXYNOS_ASV_H */
> diff --git a/drivers/soc/samsung/exynos5422-asv.c b/drivers/soc/samsung/exynos5422-asv.c
> new file mode 100644
> index 000000000000..7982f2ca0f11
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos5422-asv.c
> @@ -0,0 +1,509 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019 Samsung Electronics Co., Ltd.
> + *	      http://www.samsung.com/
> + *
> + * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
> + */
> +
> +#include <linux/bitrev.h>
> +#include <linux/device.h>

Is it used?

> +#include <linux/errno.h>
> +#include <linux/of.h>

The same?

> +#include <linux/regmap.h>
> +#include <linux/soc/samsung/exynos-chipid.h>
> +#include <linux/slab.h>
> +
> +#include "exynos-asv.h"
> +
> +#define ASV_GROUPS_NUM		14
> +#define ASV_ARM_DVFS_NUM	20
> +#define ASV_ARM_BIN2_DVFS_NUM	17
> +#define ASV_KFC_DVFS_NUM	14
> +#define ASV_KFC_BIN2_DVFS_NUM	12
> +
> +/*
> + * This array is a set of 4 ASV data tables, first column of each ASV table
> + * contains frequency value in MHz and subsequent columns contain the CPU
> + * cluster's supply voltage values in uV.
> + * In order to create a set of OPPs for specific SoC revision one of the voltage
> + * columns (1...14) from one of the tables (0...3) is selected during
> + * initialization. There are separate ASV tables for the big (ARM) and little
> + * (KFC) CPU cluster. Only OPPs which are already defined in devicetree
> + * will be updated.
> + */
> +
> +static const u32 asv_arm_table[][ASV_ARM_DVFS_NUM][ASV_GROUPS_NUM + 1] = {
> +{
> +	/* ARM 0, 1 */
> +	{ 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
> +	  1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
> +	{ 2000,    1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000,
> +	  1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +	{ 1900,    1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000,
> +	  1162500, 1150000, 1162500, 1150000, 1137500, 1125000, 1112500 },
> +	{ 1800,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
> +	  1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
> +	{ 1700,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
> +	  1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
> +	{ 1600,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
> +	  1037500, 1025000, 1037500, 1025000, 1012500, 1000000, 987500 },
> +	{ 1500,    1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
> +	  1000000, 987500,  1000000, 987500,  975000,  962500,  950000 },
> +	{ 1400,    1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
> +	  975000,  962500,  975000,  962500,  950000,  937500,  925000 },
> +	{ 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
> +	  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
> +	{ 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +	  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
> +	{ 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
> +	  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +	/* ARM 2 */
> +	{ 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
> +	  1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
> +	{ 2000,    1312500, 1312500, 1312500, 1300000, 1275000, 1262500, 1250000,
> +	  1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +	{ 1900,    1262500, 1250000, 1250000, 1237500, 1212500, 1200000, 1187500,
> +	  1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
> +	{ 1800,    1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500,
> +	  1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
> +	{ 1700,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
> +	  1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
> +	{ 1600,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
> +	  1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
> +	{ 1500,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +	  1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
> +	{ 1400,    1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,
> +	  987500,  975000,  987500,  975000,  962500,  950000,  937500 },
> +	{ 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
> +	  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
> +	{ 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +	  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
> +	{ 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
> +	  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +	/* ARM 3 */
> +	{ 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
> +	  1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
> +	{ 2000,    1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000,
> +	  1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +	{ 1900,    1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500,
> +	  1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
> +	{ 1800,    1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500,
> +	  1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
> +	{ 1700,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
> +	  1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
> +	{ 1600,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
> +	  1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
> +	{ 1500,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +	  1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
> +	{ 1400,    1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,
> +	  987500,  975000,  987500,  975000,  962500,  950000,  937500 },
> +	{ 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
> +	  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
> +	{ 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +	  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
> +	{ 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
> +	  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +	/* ARM bin 2 */
> +	{ 1800,    1237500, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500,
> +	  1150000, 1137500, 1150000, 1137500, 1125000, 1112500, 1100000 },
> +	{ 1700,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
> +	  1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
> +	{ 1600,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
> +	  1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
> +	{ 1500,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
> +	  1037500, 1025000, 1037500, 1025000, 1012500, 1000000, 987500 },
> +	{ 1400,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +	  1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
> +	{ 1300,    1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
> +	  1000000, 987500,  1000000, 987500,  975000,  962500,  950000 },
> +	{ 1200,    1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
> +	  975000,  962500,  975000,  962500,  950000,  937500,  925000 },
> +	{ 1100,    1037500, 1025000, 1012500, 1000000, 987500,  975000,  962500,
> +	  950000,  937500,  950000,  937500,  925000,  912500,  900000 },
> +	{ 1000,    1012500, 1000000, 987500,  975000,  962500,  950000,  937500,
> +	  925000,  912500,  925000,  912500,  900000,  900000,  900000 },
> +	{ 900,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 800,     962500,  950000,  937500,  925000,  912500,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 700,     937500,  925000,  912500,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}
> +};
> +
> +static const u32 asv_kfc_table[][ASV_KFC_DVFS_NUM][ASV_GROUPS_NUM + 1] = {
> +{
> +	/* KFC 0, 1 */
> +	{ 1500000, 1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
> +	  1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +	{ 1400000, 1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
> +	  1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
> +	{ 1300000, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
> +	  1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
> +	{ 1200000, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
> +	  1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
> +	{ 1100000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
> +	  1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
> +	{ 1000000, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +	  1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
> +	{ 900000,  1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
> +	  975000,  962500,  950000,  937500,  925000,  912500,  900000 },
> +	{ 800000,  1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +	  937500,  925000,  912500,  900000,  900000,  900000,  900000 },
> +	{ 700000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 600000,  950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 500000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 400000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 300000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 200000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +	/* KFC 2 */
> +	{ 1500,    1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
> +	  1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +	{ 1400,    1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
> +	  1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
> +	{ 1300,    1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
> +	  1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
> +	{ 1200,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
> +	  1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
> +	{ 1100,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
> +	  1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
> +	{ 1000,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +	  1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
> +	{ 900,     1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
> +	  975000,  962500,  950000,  937500,  925000,  912500,  900000 },
> +	{ 800,     1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +	  937500,  925000,  912500,  900000,  900000,  900000,  900000 },
> +	{ 700,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 600,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 500,     912500,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +	/* KFC 3 */
> +	{ 1500,    1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
> +	  1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +	{ 1400,    1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
> +	  1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
> +	{ 1300,    1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
> +	  1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
> +	{ 1200,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
> +	  1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
> +	{ 1100,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
> +	  1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
> +	{ 1000,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +	  1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
> +	{ 900,     1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
> +	  975000,  962500,  950000,  937500,  925000,  912500,  900000 },
> +	{ 800,     1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +	  937500,  925000,  912500,  900000,  900000,  900000,  900000 },
> +	{ 700,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 600,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 500,     912500,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +	/* KFC bin 2 */
> +	{ 1300,    1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000,
> +	  1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500 },
> +	{ 1200,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
> +	  1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500 },
> +	{ 1100,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
> +	  1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000 },
> +	{ 1000,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
> +	  1037500, 1025000, 1012500, 1000000, 987500,  975000,  962500 },
> +	{ 900,     1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
> +	  1000000, 987500,  975000,  962500,  950000,  937500,  925000 },
> +	{ 800,     1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
> +	  962500,  950000,  937500,  925000,  912500,  900000,  900000 },
> +	{ 700,     1012500, 1000000, 987500,  975000,  962500,  950000,  937500,
> +	  925000,  912500,  900000,  900000,  900000,  900000,  900000 },
> +	{ 600,     975000,  962500,  950000,  937500,  925000,  912500,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 500,     937500,  925000,  912500,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 400,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}
> +};
> +
> +static const struct asv_limit_entry __asv_limits[ASV_GROUPS_NUM] = {
> +	{ 13, 55 },
> +	{ 21, 65 },
> +	{ 25, 69 },
> +	{ 30, 72 },
> +	{ 36, 74 },
> +	{ 43, 76 },
> +	{ 51, 78 },
> +	{ 65, 80 },
> +	{ 81, 82 },
> +	{ 98, 84 },
> +	{ 119, 87 },
> +	{ 135, 89 },
> +	{ 150, 92 },
> +	{ 999, 999 },
> +};
> +
> +static int exynos5422_asv_get_group(struct exynos_asv *asv)
> +{
> +	unsigned int pkgid_reg, auxi_reg;
> +	int hpm, ids, i;
> +
> +	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PKG_ID, &pkgid_reg);
> +	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_AUX_INFO, &auxi_reg);
> +
> +	if (asv->use_sg) {
> +		u32 sga = (pkgid_reg >> EXYNOS5422_SG_A_OFFSET) &
> +			   EXYNOS5422_SG_A_MASK;
> +
> +		u32 sgb = (pkgid_reg >> EXYNOS5422_SG_B_OFFSET) &
> +			   EXYNOS5422_SG_B_MASK;
> +
> +		if ((pkgid_reg >> EXYNOS5422_SG_BSIGN_OFFSET) &
> +		     EXYNOS5422_SG_BSIGN_MASK)
> +			return sga + sgb;
> +		else
> +			return sga - sgb;
> +	}
> +
> +	hpm = (auxi_reg >> EXYNOS5422_TMCB_OFFSET) & EXYNOS5422_TMCB_MASK;
> +	ids = (pkgid_reg >> EXYNOS5422_IDS_OFFSET) & EXYNOS5422_IDS_MASK;
> +
> +	for (i = 0; i < ASV_GROUPS_NUM; i++) {
> +		if (ids <= __asv_limits[i].ids)
> +			break;
> +		if (hpm <= __asv_limits[i].hpm)
> +			break;
> +	}
> +	if (i < ASV_GROUPS_NUM)
> +		return i;
> +
> +	return 0;
> +}
> +
> +static int __asv_offset_voltage(unsigned int index)
> +{
> +	switch (index) {
> +	case 1:
> +		return 12500;
> +	case 2:
> +		return 50000;
> +	case 3:
> +		return 25000;
> +	default:
> +		return 0;
> +	};
> +}
> +
> +static void exynos5422_asv_offset_voltage_setup(struct exynos_asv *asv)
> +{
> +	struct exynos_asv_subsys *subsys;
> +	unsigned int reg, value;
> +
> +	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_AUX_INFO, &reg);
> +
> +	/* ARM offset voltage setup */
> +	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_ARM];
> +
> +	subsys->base_volt = 1000000;
> +
> +	value = (reg >> EXYNOS5422_ARM_UP_OFFSET) & EXYNOS5422_ARM_UP_MASK;
> +	subsys->offset_volt_h = __asv_offset_voltage(value);
> +
> +	value = (reg >> EXYNOS5422_ARM_DN_OFFSET) & EXYNOS5422_ARM_DN_MASK;
> +	subsys->offset_volt_l = __asv_offset_voltage(value);
> +
> +	/* KFC offset voltage setup */
> +	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_KFC];
> +
> +	subsys->base_volt = 1000000;
> +
> +	value = (reg >> EXYNOS5422_KFC_UP_OFFSET) & EXYNOS5422_KFC_UP_MASK;
> +	subsys->offset_volt_h = __asv_offset_voltage(value);
> +
> +	value = (reg >> EXYNOS5422_KFC_DN_OFFSET) & EXYNOS5422_KFC_DN_MASK;
> +	subsys->offset_volt_l = __asv_offset_voltage(value);
> +}
> +
> +static int exynos5422_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
> +				int level, unsigned int volt)

subsys is not modified.

> +{
> +	unsigned int asv_volt;
> +
> +	if (level >= subsys->table.num_rows)
> +		return volt;
> +
> +	asv_volt = exynos_asv_opp_get_voltage(subsys, level,
> +					      subsys->asv->group);
> +
> +	if (volt > subsys->base_volt)
> +		asv_volt += subsys->offset_volt_h;
> +	else
> +		asv_volt += subsys->offset_volt_l;
> +
> +	return asv_volt;
> +}
> +
> +static unsigned int exynos5422_asv_parse_table(struct exynos_asv *asv,
> +				      unsigned int pkg_id)
> +{

The same, for asv. Looks BTW unused...

> +	return (pkg_id >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
> +}
> +
> +static bool exynos5422_asv_parse_bin2(struct exynos_asv *asv,
> +				     unsigned int pkg_id)
> +{

The same.

> +	return (pkg_id >> EXYNOS5422_BIN2_OFFSET) & EXYNOS5422_BIN2_MASK;
> +}
> +
> +static bool exynos5422_asv_parse_sg(struct exynos_asv *asv,
> +					unsigned int pkg_id)
> +{

The same.

> +	return (pkg_id >> EXYNOS5422_USESG_OFFSET) & EXYNOS5422_USESG_MASK;
> +}
> +
> +int exynos5422_asv_init(struct exynos_asv *asv)
> +{
> +	struct exynos_asv_subsys *subsys;
> +	unsigned int table_index;
> +	unsigned int pkg_id;
> +	bool bin2;
> +

How about checking if asv != null? It's a header exposed function.

Best regards,
Krzysztof


> +	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PKG_ID, &pkg_id);
> +
> +	if (asv->of_bin == 2) {
> +		bin2 = true;
> +		asv->use_sg = false;
> +	} else {
> +		asv->use_sg = exynos5422_asv_parse_sg(asv, pkg_id);
> +		bin2 = exynos5422_asv_parse_bin2(asv, pkg_id);
> +	}
> +
> +	asv->group = exynos5422_asv_get_group(asv);
> +	asv->table = exynos5422_asv_parse_table(asv, pkg_id);
> +
> +	exynos5422_asv_offset_voltage_setup(asv);
> +
> +	if (bin2) {
> +		table_index = 3;
> +	} else {
> +		if (asv->table == 2 || asv->table == 3)
> +			table_index = asv->table - 1;
> +		else
> +			table_index = 0;
> +	}
> +
> +	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_ARM];
> +	subsys->cpu_dt_compat = "arm,cortex-a15";
> +	if (bin2)
> +		subsys->table.num_rows = ASV_ARM_BIN2_DVFS_NUM;
> +	else
> +		subsys->table.num_rows = ASV_ARM_DVFS_NUM;
> +	subsys->table.num_cols = ASV_GROUPS_NUM + 1;
> +	subsys->table.buf = (u32 *)asv_arm_table[table_index];
> +
> +	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_KFC];
> +	subsys->cpu_dt_compat = "arm,cortex-a7";
> +	if (bin2)
> +		subsys->table.num_rows = ASV_KFC_BIN2_DVFS_NUM;
> +	else
> +		subsys->table.num_rows = ASV_KFC_DVFS_NUM;
> +	subsys->table.num_cols = ASV_GROUPS_NUM + 1;
> +	subsys->table.buf = (u32 *)asv_kfc_table[table_index];
> +
> +	asv->opp_get_voltage = exynos5422_asv_opp_get_voltage;
> +
> +	return 0;
> +}
> diff --git a/drivers/soc/samsung/exynos5422-asv.h b/drivers/soc/samsung/exynos5422-asv.h
> new file mode 100644
> index 000000000000..85218d2800fb
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos5422-asv.h
> @@ -0,0 +1,25 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2019 Samsung Electronics Co., Ltd.
> + *	      http://www.samsung.com/
> + *
> + * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
> + */
> +
> +#ifndef __LINUX_SOC_EXYNOS5422_ASV_H
> +#define __LINUX_SOC_EXYNOS5422_ASV_H
> +
> +#include <linux/errno.h>
> +
> +struct exynos_asv;
> +
> +#ifdef CONFIG_EXYNOS_ASV_ARM
> +int exynos5422_asv_init(struct exynos_asv *asv);
> +#else
> +static inline int exynos5422_asv_init(struct exynos_asv *asv)
> +{
> +	return -ENOTSUPP;
> +}
> +#endif
> +
> +#endif /* __LINUX_SOC_EXYNOS5422_ASV_H */
> --
> 2.17.1
> 

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

* Re: [PATCH v5 3/4] soc: samsung: Add Exynos Adaptive Supply Voltage driver
  2019-10-22 19:04         ` Krzysztof Kozlowski
@ 2019-10-23 10:48           ` Sylwester Nawrocki
  -1 siblings, 0 replies; 28+ messages in thread
From: Sylwester Nawrocki @ 2019-10-23 10:48 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: devicetree, linux-samsung-soc, linux-pm, sboyd, vireshk,
	b.zolnierkie, roger.lu, robh+dt, linux-arm-kernel, m.szyprowski

Hi Krzysztof,

On 10/22/19 21:04, Krzysztof Kozlowski wrote:
 
> I wanted to apply this patch but spotted some unusual printk... 
> and then started looking for more...
> 
> Sparse complains:
> ../drivers/soc/samsung/exynos5422-asv.c:457:5: warning: symbol 
> 'exynos5422_asv_init' was not declared. Should it be static?
 
#include "exynos5422-asv.h" should be added to 
drivers/soc/samsung/exynos5422-asv.c.

>>  drivers/soc/samsung/Kconfig          |  10 +
>>  drivers/soc/samsung/Makefile         |   3 +
>>  drivers/soc/samsung/exynos-asv.c     | 179 ++++++++++
>>  drivers/soc/samsung/exynos-asv.h     |  82 +++++
>>  drivers/soc/samsung/exynos5422-asv.c | 509 +++++++++++++++++++++++++++
>>  drivers/soc/samsung/exynos5422-asv.h |  25 ++
>>  6 files changed, 808 insertions(+)
>>  create mode 100644 drivers/soc/samsung/exynos-asv.c
>>  create mode 100644 drivers/soc/samsung/exynos-asv.h
>>  create mode 100644 drivers/soc/samsung/exynos5422-asv.c
>>  create mode 100644 drivers/soc/samsung/exynos5422-asv.h
>>

>> +++ b/drivers/soc/samsung/exynos-asv.c

>> +#include <linux/cpu.h>
>> +#include <linux/delay.h>
> 
> Do you use this header?

It can be removed now, after conversion to dev_pm_opp_adjust_voltage().

>> +static int exynos_asv_probe(struct platform_device *pdev)
>> +{
>> +	int (*probe_func)(struct exynos_asv *asv);
>> +	struct exynos_asv *asv;
>> +	struct device *cpu_dev;
>> +	u32 product_id = 0;
>> +	int ret, i;
>> +
>> +	cpu_dev = get_cpu_device(0);
>> +	ret = dev_pm_opp_get_opp_count(cpu_dev);
>> +	if (ret < 0)
>> +		return -EPROBE_DEFER;
>> +
>> +	asv = devm_kzalloc(&pdev->dev, sizeof(*asv), GFP_KERNEL);
>> +	if (!asv)
>> +		return -ENOMEM;
>> +
>> +	asv->chipid_regmap = syscon_node_to_regmap(pdev->dev.of_node);
> 
> Since this binds to the same node as chipid, why do you need syscon for
> it? Why regular IO access does not work? Eventually, if this has to be
> regmap because of locking (does it?), then maybe simply
> device_node_to_regmap()?

We just need regmap available to any of the two drivers whichever needs it
first. device_node_to_regmap() sounds like a good idea. Then we could drop
"syscon" compatible from the binding.

>> +	if (IS_ERR(asv->chipid_regmap)) {
>> +		dev_err(&pdev->dev, "Could not find syscon regmap\n");
>> +		return PTR_ERR(asv->chipid_regmap);
>> +	}
>> +
>> +	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);
>> +
>> +	switch (product_id & EXYNOS_MASK) {
>> +	case 0xE5422000:
>> +		probe_func = exynos5422_asv_init;
>> +		break;
>> +	default:
>> +		dev_err(&pdev->dev, "Unsupported product ID: %#x", product_id);
> 
> Is this going to scream for every Exynos matching the 4210-chipid?

Yes, it should really be dev_info() or removed entirely.

>> +		return -ENODEV;
>> +	}


>> +++ b/drivers/soc/samsung/exynos-asv.h

>> +enum {
>> +	EXYNOS_ASV_SUBSYS_ID_ARM,
>> +	EXYNOS_ASV_SUBSYS_ID_EGL = EXYNOS_ASV_SUBSYS_ID_ARM,
>> +	EXYNOS_ASV_SUBSYS_ID_KFC,
>> +	EXYNOS_ASV_SUBSYS_ID_INT,
>> +	EXYNOS_ASV_SUBSYS_ID_MIF,
>> +	EXYNOS_ASV_SUBSYS_ID_G3D,
>> +	EXYNOS_ASV_SUBSYS_ID_CAM,
>> +	EXYNOS_ASV_SUBSYS_ID_MAX
>> +};
> 
> I cannot find usage of it in generic part of ASV driver. What's the
> purpose? Isn't it specific to Exynos5422?

It was meant as generic enumeration of available subsystems, it's not
Exynos5422 specific. It could be moved to the exynos5422 part of the 
driver (limited to EXYNOS_ASV_SUBSYS_ID_ARM, EXYNOS_ASV_SUBSYS_ID_KFC)
until support for of ther subsystems than CPU clusters is added.
The CPUs are now matched by compatible.

>> +struct regmap;
>> +
>> +/* HPM, IDS values to select target group */

>> +struct exynos_asv_subsys {
>> +	struct exynos_asv *asv;
>> +	const char *cpu_dt_compat;
>> +	int id;
>> +	struct exynos_asv_table table;
>> +
>> +	unsigned int base_volt;
>> +	unsigned int offset_volt_h;
>> +	unsigned int offset_volt_l;
>> +};
>> +
>> +struct exynos_asv {
>> +	struct device *dev;
>> +	struct regmap *chipid_regmap;
>> +	struct exynos_asv_subsys subsys[2];
>> +
>> +	int (*opp_get_voltage)(struct exynos_asv_subsys *subs, int level,
>> +			       unsigned int voltage);
>> +	unsigned int group;
>> +	unsigned int table;
>> +
>> +	/* True if SG fields from PKG_ID register should be used */
>> +	bool use_sg;
>> +	/* ASV bin read from DT */
>> +	int of_bin;
>> +};
>> +
>> +static inline u32 __asv_get_table_entry(struct exynos_asv_table *table,
> 
> 'table' looks here like pointer to const.

Yes, const could be added here.

>> +					unsigned int row, unsigned int col)
>> +{
>> +	return table->buf[row * (table->num_cols) + col];
>> +}
>> +
>> +static inline u32 exynos_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
>> +					unsigned int level, unsigned int group)
>> +{
> 
> The same, for subsys.

Agreed.
 
>> +	return __asv_get_table_entry(&subsys->table, level, group + 1);
>> +}

>> +++ b/drivers/soc/samsung/exynos5422-asv.c

>> +#include <linux/bitrev.h>
>> +#include <linux/device.h>
> 
> Is it used?
> 
>> +#include <linux/errno.h>
>> +#include <linux/of.h>
> 
> The same?

Some might be not used now, I will check it again.

>> +#include <linux/regmap.h>
>> +#include <linux/soc/samsung/exynos-chipid.h>
>> +#include <linux/slab.h>
>> +
>> +#include "exynos-asv.h"


>> +static int exynos5422_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
>> +				int level, unsigned int volt)
> 
> subsys is not modified.
 

>> +static unsigned int exynos5422_asv_parse_table(struct exynos_asv *asv,
>> +				      unsigned int pkg_id)
>> +{
> 
> The same, for asv. Looks BTW unused...

Indeed the asv argument should be dropped now.

>> +	return (pkg_id >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
>> +}

>> +int exynos5422_asv_init(struct exynos_asv *asv)
>> +{
>> +	struct exynos_asv_subsys *subsys;
>> +	unsigned int table_index;
>> +	unsigned int pkg_id;
>> +	bool bin2;
>> +
> 
> How about checking if asv != null? It's a header exposed function.

Do we really need it? The caller will ensure that asv is not null.

>> +	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PKG_ID, &pkg_id);

-- 
Regards,
Sylwester

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

* Re: [PATCH v5 3/4] soc: samsung: Add Exynos Adaptive Supply Voltage driver
@ 2019-10-23 10:48           ` Sylwester Nawrocki
  0 siblings, 0 replies; 28+ messages in thread
From: Sylwester Nawrocki @ 2019-10-23 10:48 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: devicetree, linux-samsung-soc, b.zolnierkie, sboyd, vireshk,
	linux-pm, roger.lu, robh+dt, linux-arm-kernel, m.szyprowski

Hi Krzysztof,

On 10/22/19 21:04, Krzysztof Kozlowski wrote:
 
> I wanted to apply this patch but spotted some unusual printk... 
> and then started looking for more...
> 
> Sparse complains:
> ../drivers/soc/samsung/exynos5422-asv.c:457:5: warning: symbol 
> 'exynos5422_asv_init' was not declared. Should it be static?
 
#include "exynos5422-asv.h" should be added to 
drivers/soc/samsung/exynos5422-asv.c.

>>  drivers/soc/samsung/Kconfig          |  10 +
>>  drivers/soc/samsung/Makefile         |   3 +
>>  drivers/soc/samsung/exynos-asv.c     | 179 ++++++++++
>>  drivers/soc/samsung/exynos-asv.h     |  82 +++++
>>  drivers/soc/samsung/exynos5422-asv.c | 509 +++++++++++++++++++++++++++
>>  drivers/soc/samsung/exynos5422-asv.h |  25 ++
>>  6 files changed, 808 insertions(+)
>>  create mode 100644 drivers/soc/samsung/exynos-asv.c
>>  create mode 100644 drivers/soc/samsung/exynos-asv.h
>>  create mode 100644 drivers/soc/samsung/exynos5422-asv.c
>>  create mode 100644 drivers/soc/samsung/exynos5422-asv.h
>>

>> +++ b/drivers/soc/samsung/exynos-asv.c

>> +#include <linux/cpu.h>
>> +#include <linux/delay.h>
> 
> Do you use this header?

It can be removed now, after conversion to dev_pm_opp_adjust_voltage().

>> +static int exynos_asv_probe(struct platform_device *pdev)
>> +{
>> +	int (*probe_func)(struct exynos_asv *asv);
>> +	struct exynos_asv *asv;
>> +	struct device *cpu_dev;
>> +	u32 product_id = 0;
>> +	int ret, i;
>> +
>> +	cpu_dev = get_cpu_device(0);
>> +	ret = dev_pm_opp_get_opp_count(cpu_dev);
>> +	if (ret < 0)
>> +		return -EPROBE_DEFER;
>> +
>> +	asv = devm_kzalloc(&pdev->dev, sizeof(*asv), GFP_KERNEL);
>> +	if (!asv)
>> +		return -ENOMEM;
>> +
>> +	asv->chipid_regmap = syscon_node_to_regmap(pdev->dev.of_node);
> 
> Since this binds to the same node as chipid, why do you need syscon for
> it? Why regular IO access does not work? Eventually, if this has to be
> regmap because of locking (does it?), then maybe simply
> device_node_to_regmap()?

We just need regmap available to any of the two drivers whichever needs it
first. device_node_to_regmap() sounds like a good idea. Then we could drop
"syscon" compatible from the binding.

>> +	if (IS_ERR(asv->chipid_regmap)) {
>> +		dev_err(&pdev->dev, "Could not find syscon regmap\n");
>> +		return PTR_ERR(asv->chipid_regmap);
>> +	}
>> +
>> +	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);
>> +
>> +	switch (product_id & EXYNOS_MASK) {
>> +	case 0xE5422000:
>> +		probe_func = exynos5422_asv_init;
>> +		break;
>> +	default:
>> +		dev_err(&pdev->dev, "Unsupported product ID: %#x", product_id);
> 
> Is this going to scream for every Exynos matching the 4210-chipid?

Yes, it should really be dev_info() or removed entirely.

>> +		return -ENODEV;
>> +	}


>> +++ b/drivers/soc/samsung/exynos-asv.h

>> +enum {
>> +	EXYNOS_ASV_SUBSYS_ID_ARM,
>> +	EXYNOS_ASV_SUBSYS_ID_EGL = EXYNOS_ASV_SUBSYS_ID_ARM,
>> +	EXYNOS_ASV_SUBSYS_ID_KFC,
>> +	EXYNOS_ASV_SUBSYS_ID_INT,
>> +	EXYNOS_ASV_SUBSYS_ID_MIF,
>> +	EXYNOS_ASV_SUBSYS_ID_G3D,
>> +	EXYNOS_ASV_SUBSYS_ID_CAM,
>> +	EXYNOS_ASV_SUBSYS_ID_MAX
>> +};
> 
> I cannot find usage of it in generic part of ASV driver. What's the
> purpose? Isn't it specific to Exynos5422?

It was meant as generic enumeration of available subsystems, it's not
Exynos5422 specific. It could be moved to the exynos5422 part of the 
driver (limited to EXYNOS_ASV_SUBSYS_ID_ARM, EXYNOS_ASV_SUBSYS_ID_KFC)
until support for of ther subsystems than CPU clusters is added.
The CPUs are now matched by compatible.

>> +struct regmap;
>> +
>> +/* HPM, IDS values to select target group */

>> +struct exynos_asv_subsys {
>> +	struct exynos_asv *asv;
>> +	const char *cpu_dt_compat;
>> +	int id;
>> +	struct exynos_asv_table table;
>> +
>> +	unsigned int base_volt;
>> +	unsigned int offset_volt_h;
>> +	unsigned int offset_volt_l;
>> +};
>> +
>> +struct exynos_asv {
>> +	struct device *dev;
>> +	struct regmap *chipid_regmap;
>> +	struct exynos_asv_subsys subsys[2];
>> +
>> +	int (*opp_get_voltage)(struct exynos_asv_subsys *subs, int level,
>> +			       unsigned int voltage);
>> +	unsigned int group;
>> +	unsigned int table;
>> +
>> +	/* True if SG fields from PKG_ID register should be used */
>> +	bool use_sg;
>> +	/* ASV bin read from DT */
>> +	int of_bin;
>> +};
>> +
>> +static inline u32 __asv_get_table_entry(struct exynos_asv_table *table,
> 
> 'table' looks here like pointer to const.

Yes, const could be added here.

>> +					unsigned int row, unsigned int col)
>> +{
>> +	return table->buf[row * (table->num_cols) + col];
>> +}
>> +
>> +static inline u32 exynos_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
>> +					unsigned int level, unsigned int group)
>> +{
> 
> The same, for subsys.

Agreed.
 
>> +	return __asv_get_table_entry(&subsys->table, level, group + 1);
>> +}

>> +++ b/drivers/soc/samsung/exynos5422-asv.c

>> +#include <linux/bitrev.h>
>> +#include <linux/device.h>
> 
> Is it used?
> 
>> +#include <linux/errno.h>
>> +#include <linux/of.h>
> 
> The same?

Some might be not used now, I will check it again.

>> +#include <linux/regmap.h>
>> +#include <linux/soc/samsung/exynos-chipid.h>
>> +#include <linux/slab.h>
>> +
>> +#include "exynos-asv.h"


>> +static int exynos5422_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
>> +				int level, unsigned int volt)
> 
> subsys is not modified.
 

>> +static unsigned int exynos5422_asv_parse_table(struct exynos_asv *asv,
>> +				      unsigned int pkg_id)
>> +{
> 
> The same, for asv. Looks BTW unused...

Indeed the asv argument should be dropped now.

>> +	return (pkg_id >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
>> +}

>> +int exynos5422_asv_init(struct exynos_asv *asv)
>> +{
>> +	struct exynos_asv_subsys *subsys;
>> +	unsigned int table_index;
>> +	unsigned int pkg_id;
>> +	bool bin2;
>> +
> 
> How about checking if asv != null? It's a header exposed function.

Do we really need it? The caller will ensure that asv is not null.

>> +	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PKG_ID, &pkg_id);

-- 
Regards,
Sylwester

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

* Re: [PATCH v5 3/4] soc: samsung: Add Exynos Adaptive Supply Voltage driver
  2019-10-23 10:48           ` Sylwester Nawrocki
@ 2019-10-23 11:20             ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2019-10-23 11:20 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: devicetree, linux-samsung-soc, linux-pm, sboyd, vireshk,
	b.zolnierkie, roger.lu, robh+dt, linux-arm-kernel, m.szyprowski

On Wed, Oct 23, 2019 at 12:48:34PM +0200, Sylwester Nawrocki wrote:
> Hi Krzysztof,
> 
> On 10/22/19 21:04, Krzysztof Kozlowski wrote:
>  
> > I wanted to apply this patch but spotted some unusual printk... 
> > and then started looking for more...
> > 
> > Sparse complains:
> > ../drivers/soc/samsung/exynos5422-asv.c:457:5: warning: symbol 
> > 'exynos5422_asv_init' was not declared. Should it be static?
>  
> #include "exynos5422-asv.h" should be added to 
> drivers/soc/samsung/exynos5422-asv.c.
> 
> >>  drivers/soc/samsung/Kconfig          |  10 +
> >>  drivers/soc/samsung/Makefile         |   3 +
> >>  drivers/soc/samsung/exynos-asv.c     | 179 ++++++++++
> >>  drivers/soc/samsung/exynos-asv.h     |  82 +++++
> >>  drivers/soc/samsung/exynos5422-asv.c | 509 +++++++++++++++++++++++++++
> >>  drivers/soc/samsung/exynos5422-asv.h |  25 ++
> >>  6 files changed, 808 insertions(+)
> >>  create mode 100644 drivers/soc/samsung/exynos-asv.c
> >>  create mode 100644 drivers/soc/samsung/exynos-asv.h
> >>  create mode 100644 drivers/soc/samsung/exynos5422-asv.c
> >>  create mode 100644 drivers/soc/samsung/exynos5422-asv.h
> >>
> 
> >> +++ b/drivers/soc/samsung/exynos-asv.c
> 
> >> +#include <linux/cpu.h>
> >> +#include <linux/delay.h>
> > 
> > Do you use this header?
> 
> It can be removed now, after conversion to dev_pm_opp_adjust_voltage().
> 
> >> +static int exynos_asv_probe(struct platform_device *pdev)
> >> +{
> >> +	int (*probe_func)(struct exynos_asv *asv);
> >> +	struct exynos_asv *asv;
> >> +	struct device *cpu_dev;
> >> +	u32 product_id = 0;
> >> +	int ret, i;
> >> +
> >> +	cpu_dev = get_cpu_device(0);
> >> +	ret = dev_pm_opp_get_opp_count(cpu_dev);
> >> +	if (ret < 0)
> >> +		return -EPROBE_DEFER;
> >> +
> >> +	asv = devm_kzalloc(&pdev->dev, sizeof(*asv), GFP_KERNEL);
> >> +	if (!asv)
> >> +		return -ENOMEM;
> >> +
> >> +	asv->chipid_regmap = syscon_node_to_regmap(pdev->dev.of_node);
> > 
> > Since this binds to the same node as chipid, why do you need syscon for
> > it? Why regular IO access does not work? Eventually, if this has to be
> > regmap because of locking (does it?), then maybe simply
> > device_node_to_regmap()?
> 
> We just need regmap available to any of the two drivers whichever needs it
> first. device_node_to_regmap() sounds like a good idea. Then we could drop
> "syscon" compatible from the binding.

OK, let's keep the regmap for safe access to the same region by multiple
drivers.

> 
> >> +	if (IS_ERR(asv->chipid_regmap)) {
> >> +		dev_err(&pdev->dev, "Could not find syscon regmap\n");
> >> +		return PTR_ERR(asv->chipid_regmap);
> >> +	}
> >> +
> >> +	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);
> >> +
> >> +	switch (product_id & EXYNOS_MASK) {
> >> +	case 0xE5422000:
> >> +		probe_func = exynos5422_asv_init;
> >> +		break;
> >> +	default:
> >> +		dev_err(&pdev->dev, "Unsupported product ID: %#x", product_id);
> > 
> > Is this going to scream for every Exynos matching the 4210-chipid?
> 
> Yes, it should really be dev_info() or removed entirely.

Remove it entirely please or leave it to dev_dbg (but even then add some
calming message like "Unsupported ...., skipping ASV"). Driver binds on
many devices and lack of ASV is kind of regular (till now there was no
ASV at all).

> 
> >> +		return -ENODEV;
> >> +	}
> 
> 
> >> +++ b/drivers/soc/samsung/exynos-asv.h
> 
> >> +enum {
> >> +	EXYNOS_ASV_SUBSYS_ID_ARM,
> >> +	EXYNOS_ASV_SUBSYS_ID_EGL = EXYNOS_ASV_SUBSYS_ID_ARM,
> >> +	EXYNOS_ASV_SUBSYS_ID_KFC,
> >> +	EXYNOS_ASV_SUBSYS_ID_INT,
> >> +	EXYNOS_ASV_SUBSYS_ID_MIF,
> >> +	EXYNOS_ASV_SUBSYS_ID_G3D,
> >> +	EXYNOS_ASV_SUBSYS_ID_CAM,
> >> +	EXYNOS_ASV_SUBSYS_ID_MAX
> >> +};
> > 
> > I cannot find usage of it in generic part of ASV driver. What's the
> > purpose? Isn't it specific to Exynos5422?
> 
> It was meant as generic enumeration of available subsystems, it's not
> Exynos5422 specific. It could be moved to the exynos5422 part of the 
> driver (limited to EXYNOS_ASV_SUBSYS_ID_ARM, EXYNOS_ASV_SUBSYS_ID_KFC)
> until support for of ther subsystems than CPU clusters is added.
> The CPUs are now matched by compatible.

Then let's move it to exynos5422 part, and later make it generic if
needed.

> 
> >> +struct regmap;
> >> +
> >> +/* HPM, IDS values to select target group */
> 
> >> +struct exynos_asv_subsys {
> >> +	struct exynos_asv *asv;
> >> +	const char *cpu_dt_compat;
> >> +	int id;
> >> +	struct exynos_asv_table table;
> >> +
> >> +	unsigned int base_volt;
> >> +	unsigned int offset_volt_h;
> >> +	unsigned int offset_volt_l;
> >> +};
> >> +
> >> +struct exynos_asv {
> >> +	struct device *dev;
> >> +	struct regmap *chipid_regmap;
> >> +	struct exynos_asv_subsys subsys[2];
> >> +
> >> +	int (*opp_get_voltage)(struct exynos_asv_subsys *subs, int level,
> >> +			       unsigned int voltage);
> >> +	unsigned int group;
> >> +	unsigned int table;
> >> +
> >> +	/* True if SG fields from PKG_ID register should be used */
> >> +	bool use_sg;
> >> +	/* ASV bin read from DT */
> >> +	int of_bin;
> >> +};
> >> +
> >> +static inline u32 __asv_get_table_entry(struct exynos_asv_table *table,
> > 
> > 'table' looks here like pointer to const.
> 
> Yes, const could be added here.
> 
> >> +					unsigned int row, unsigned int col)
> >> +{
> >> +	return table->buf[row * (table->num_cols) + col];
> >> +}
> >> +
> >> +static inline u32 exynos_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
> >> +					unsigned int level, unsigned int group)
> >> +{
> > 
> > The same, for subsys.
> 
> Agreed.
>  
> >> +	return __asv_get_table_entry(&subsys->table, level, group + 1);
> >> +}
> 
> >> +++ b/drivers/soc/samsung/exynos5422-asv.c
> 
> >> +#include <linux/bitrev.h>
> >> +#include <linux/device.h>
> > 
> > Is it used?
> > 
> >> +#include <linux/errno.h>
> >> +#include <linux/of.h>
> > 
> > The same?
> 
> Some might be not used now, I will check it again.
> 
> >> +#include <linux/regmap.h>
> >> +#include <linux/soc/samsung/exynos-chipid.h>
> >> +#include <linux/slab.h>
> >> +
> >> +#include "exynos-asv.h"
> 
> 
> >> +static int exynos5422_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
> >> +				int level, unsigned int volt)
> > 
> > subsys is not modified.
>  
> 
> >> +static unsigned int exynos5422_asv_parse_table(struct exynos_asv *asv,
> >> +				      unsigned int pkg_id)
> >> +{
> > 
> > The same, for asv. Looks BTW unused...
> 
> Indeed the asv argument should be dropped now.
> 
> >> +	return (pkg_id >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
> >> +}
> 
> >> +int exynos5422_asv_init(struct exynos_asv *asv)
> >> +{
> >> +	struct exynos_asv_subsys *subsys;
> >> +	unsigned int table_index;
> >> +	unsigned int pkg_id;
> >> +	bool bin2;
> >> +
> > 
> > How about checking if asv != null? It's a header exposed function.
> 
> Do we really need it? The caller will ensure that asv is not null.

Indeed, it's not needed. Skip my comment.

Best regards,
Krzysztof

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

* Re: [PATCH v5 3/4] soc: samsung: Add Exynos Adaptive Supply Voltage driver
@ 2019-10-23 11:20             ` Krzysztof Kozlowski
  0 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2019-10-23 11:20 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: devicetree, linux-samsung-soc, b.zolnierkie, sboyd, vireshk,
	linux-pm, roger.lu, robh+dt, linux-arm-kernel, m.szyprowski

On Wed, Oct 23, 2019 at 12:48:34PM +0200, Sylwester Nawrocki wrote:
> Hi Krzysztof,
> 
> On 10/22/19 21:04, Krzysztof Kozlowski wrote:
>  
> > I wanted to apply this patch but spotted some unusual printk... 
> > and then started looking for more...
> > 
> > Sparse complains:
> > ../drivers/soc/samsung/exynos5422-asv.c:457:5: warning: symbol 
> > 'exynos5422_asv_init' was not declared. Should it be static?
>  
> #include "exynos5422-asv.h" should be added to 
> drivers/soc/samsung/exynos5422-asv.c.
> 
> >>  drivers/soc/samsung/Kconfig          |  10 +
> >>  drivers/soc/samsung/Makefile         |   3 +
> >>  drivers/soc/samsung/exynos-asv.c     | 179 ++++++++++
> >>  drivers/soc/samsung/exynos-asv.h     |  82 +++++
> >>  drivers/soc/samsung/exynos5422-asv.c | 509 +++++++++++++++++++++++++++
> >>  drivers/soc/samsung/exynos5422-asv.h |  25 ++
> >>  6 files changed, 808 insertions(+)
> >>  create mode 100644 drivers/soc/samsung/exynos-asv.c
> >>  create mode 100644 drivers/soc/samsung/exynos-asv.h
> >>  create mode 100644 drivers/soc/samsung/exynos5422-asv.c
> >>  create mode 100644 drivers/soc/samsung/exynos5422-asv.h
> >>
> 
> >> +++ b/drivers/soc/samsung/exynos-asv.c
> 
> >> +#include <linux/cpu.h>
> >> +#include <linux/delay.h>
> > 
> > Do you use this header?
> 
> It can be removed now, after conversion to dev_pm_opp_adjust_voltage().
> 
> >> +static int exynos_asv_probe(struct platform_device *pdev)
> >> +{
> >> +	int (*probe_func)(struct exynos_asv *asv);
> >> +	struct exynos_asv *asv;
> >> +	struct device *cpu_dev;
> >> +	u32 product_id = 0;
> >> +	int ret, i;
> >> +
> >> +	cpu_dev = get_cpu_device(0);
> >> +	ret = dev_pm_opp_get_opp_count(cpu_dev);
> >> +	if (ret < 0)
> >> +		return -EPROBE_DEFER;
> >> +
> >> +	asv = devm_kzalloc(&pdev->dev, sizeof(*asv), GFP_KERNEL);
> >> +	if (!asv)
> >> +		return -ENOMEM;
> >> +
> >> +	asv->chipid_regmap = syscon_node_to_regmap(pdev->dev.of_node);
> > 
> > Since this binds to the same node as chipid, why do you need syscon for
> > it? Why regular IO access does not work? Eventually, if this has to be
> > regmap because of locking (does it?), then maybe simply
> > device_node_to_regmap()?
> 
> We just need regmap available to any of the two drivers whichever needs it
> first. device_node_to_regmap() sounds like a good idea. Then we could drop
> "syscon" compatible from the binding.

OK, let's keep the regmap for safe access to the same region by multiple
drivers.

> 
> >> +	if (IS_ERR(asv->chipid_regmap)) {
> >> +		dev_err(&pdev->dev, "Could not find syscon regmap\n");
> >> +		return PTR_ERR(asv->chipid_regmap);
> >> +	}
> >> +
> >> +	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);
> >> +
> >> +	switch (product_id & EXYNOS_MASK) {
> >> +	case 0xE5422000:
> >> +		probe_func = exynos5422_asv_init;
> >> +		break;
> >> +	default:
> >> +		dev_err(&pdev->dev, "Unsupported product ID: %#x", product_id);
> > 
> > Is this going to scream for every Exynos matching the 4210-chipid?
> 
> Yes, it should really be dev_info() or removed entirely.

Remove it entirely please or leave it to dev_dbg (but even then add some
calming message like "Unsupported ...., skipping ASV"). Driver binds on
many devices and lack of ASV is kind of regular (till now there was no
ASV at all).

> 
> >> +		return -ENODEV;
> >> +	}
> 
> 
> >> +++ b/drivers/soc/samsung/exynos-asv.h
> 
> >> +enum {
> >> +	EXYNOS_ASV_SUBSYS_ID_ARM,
> >> +	EXYNOS_ASV_SUBSYS_ID_EGL = EXYNOS_ASV_SUBSYS_ID_ARM,
> >> +	EXYNOS_ASV_SUBSYS_ID_KFC,
> >> +	EXYNOS_ASV_SUBSYS_ID_INT,
> >> +	EXYNOS_ASV_SUBSYS_ID_MIF,
> >> +	EXYNOS_ASV_SUBSYS_ID_G3D,
> >> +	EXYNOS_ASV_SUBSYS_ID_CAM,
> >> +	EXYNOS_ASV_SUBSYS_ID_MAX
> >> +};
> > 
> > I cannot find usage of it in generic part of ASV driver. What's the
> > purpose? Isn't it specific to Exynos5422?
> 
> It was meant as generic enumeration of available subsystems, it's not
> Exynos5422 specific. It could be moved to the exynos5422 part of the 
> driver (limited to EXYNOS_ASV_SUBSYS_ID_ARM, EXYNOS_ASV_SUBSYS_ID_KFC)
> until support for of ther subsystems than CPU clusters is added.
> The CPUs are now matched by compatible.

Then let's move it to exynos5422 part, and later make it generic if
needed.

> 
> >> +struct regmap;
> >> +
> >> +/* HPM, IDS values to select target group */
> 
> >> +struct exynos_asv_subsys {
> >> +	struct exynos_asv *asv;
> >> +	const char *cpu_dt_compat;
> >> +	int id;
> >> +	struct exynos_asv_table table;
> >> +
> >> +	unsigned int base_volt;
> >> +	unsigned int offset_volt_h;
> >> +	unsigned int offset_volt_l;
> >> +};
> >> +
> >> +struct exynos_asv {
> >> +	struct device *dev;
> >> +	struct regmap *chipid_regmap;
> >> +	struct exynos_asv_subsys subsys[2];
> >> +
> >> +	int (*opp_get_voltage)(struct exynos_asv_subsys *subs, int level,
> >> +			       unsigned int voltage);
> >> +	unsigned int group;
> >> +	unsigned int table;
> >> +
> >> +	/* True if SG fields from PKG_ID register should be used */
> >> +	bool use_sg;
> >> +	/* ASV bin read from DT */
> >> +	int of_bin;
> >> +};
> >> +
> >> +static inline u32 __asv_get_table_entry(struct exynos_asv_table *table,
> > 
> > 'table' looks here like pointer to const.
> 
> Yes, const could be added here.
> 
> >> +					unsigned int row, unsigned int col)
> >> +{
> >> +	return table->buf[row * (table->num_cols) + col];
> >> +}
> >> +
> >> +static inline u32 exynos_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
> >> +					unsigned int level, unsigned int group)
> >> +{
> > 
> > The same, for subsys.
> 
> Agreed.
>  
> >> +	return __asv_get_table_entry(&subsys->table, level, group + 1);
> >> +}
> 
> >> +++ b/drivers/soc/samsung/exynos5422-asv.c
> 
> >> +#include <linux/bitrev.h>
> >> +#include <linux/device.h>
> > 
> > Is it used?
> > 
> >> +#include <linux/errno.h>
> >> +#include <linux/of.h>
> > 
> > The same?
> 
> Some might be not used now, I will check it again.
> 
> >> +#include <linux/regmap.h>
> >> +#include <linux/soc/samsung/exynos-chipid.h>
> >> +#include <linux/slab.h>
> >> +
> >> +#include "exynos-asv.h"
> 
> 
> >> +static int exynos5422_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
> >> +				int level, unsigned int volt)
> > 
> > subsys is not modified.
>  
> 
> >> +static unsigned int exynos5422_asv_parse_table(struct exynos_asv *asv,
> >> +				      unsigned int pkg_id)
> >> +{
> > 
> > The same, for asv. Looks BTW unused...
> 
> Indeed the asv argument should be dropped now.
> 
> >> +	return (pkg_id >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
> >> +}
> 
> >> +int exynos5422_asv_init(struct exynos_asv *asv)
> >> +{
> >> +	struct exynos_asv_subsys *subsys;
> >> +	unsigned int table_index;
> >> +	unsigned int pkg_id;
> >> +	bool bin2;
> >> +
> > 
> > How about checking if asv != null? It's a header exposed function.
> 
> Do we really need it? The caller will ensure that asv is not null.

Indeed, it's not needed. Skip my comment.

Best regards,
Krzysztof

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

end of thread, other threads:[~2019-10-23 11:20 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20191016145806eucas1p2d522901fc79e1ca6e03f1bb516a81370@eucas1p2.samsung.com>
2019-10-16 14:57 ` [PATCH v5 0/4] Exynos Adaptive Supply Voltage support Sylwester Nawrocki
2019-10-16 14:57   ` Sylwester Nawrocki
     [not found]   ` <CGME20191016145810eucas1p1b31400c9b2e7f30cdf6deeb4ccee2788@eucas1p1.samsung.com>
2019-10-16 14:57     ` [PATCH v5 1/4] PM / OPP: Support adjusting OPP voltages at runtime Sylwester Nawrocki
2019-10-16 14:57       ` Sylwester Nawrocki
2019-10-17  6:42       ` Viresh Kumar
2019-10-17  6:42         ` Viresh Kumar
2019-10-21 11:23         ` Krzysztof Kozlowski
2019-10-21 11:23           ` Krzysztof Kozlowski
2019-10-22  2:23           ` Viresh Kumar
2019-10-22  2:23             ` Viresh Kumar
2019-10-22 18:43             ` Krzysztof Kozlowski
2019-10-22 18:43               ` Krzysztof Kozlowski
     [not found]   ` <CGME20191016145812eucas1p1a3cf3f44a2cff4c32a2270334630c4a2@eucas1p1.samsung.com>
2019-10-16 14:57     ` [PATCH v5 2/4] dt-bindings: arm: samsung: Update the CHIPID binding for ASV Sylwester Nawrocki
2019-10-16 14:57       ` Sylwester Nawrocki
2019-10-16 16:16       ` Krzysztof Kozlowski
2019-10-16 16:16         ` Krzysztof Kozlowski
2019-10-17  9:03         ` Sylwester Nawrocki
2019-10-17  9:03           ` Sylwester Nawrocki
     [not found]   ` <CGME20191016145813eucas1p1623db169f1ee93f88cb2c75090804747@eucas1p1.samsung.com>
2019-10-16 14:57     ` [PATCH v5 3/4] soc: samsung: Add Exynos Adaptive Supply Voltage driver Sylwester Nawrocki
2019-10-16 14:57       ` Sylwester Nawrocki
2019-10-22 19:04       ` Krzysztof Kozlowski
2019-10-22 19:04         ` Krzysztof Kozlowski
2019-10-23 10:48         ` Sylwester Nawrocki
2019-10-23 10:48           ` Sylwester Nawrocki
2019-10-23 11:20           ` Krzysztof Kozlowski
2019-10-23 11:20             ` Krzysztof Kozlowski
     [not found]   ` <CGME20191016145814eucas1p10d50d438abb850fd82f622122b223196@eucas1p1.samsung.com>
2019-10-16 14:57     ` [PATCH v5 4/4] ARM: EXYNOS: Enable exynos-asv driver for ARCH_EXYNOS Sylwester Nawrocki
2019-10-16 14:57       ` Sylwester Nawrocki

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