linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC 0/8] Exynos Adaptive Supply Voltage support
       [not found] <CGME20190404172220epcas1p3a6a8d843780321c4914a63d589c56b33@epcas1p3.samsung.com>
@ 2019-04-04 17:17 ` Sylwester Nawrocki
       [not found]   ` <CGME20190404172224epcas2p21b449c0ae8e36f7e800ae67c18db35a2@epcas2p2.samsung.com>
                     ` (7 more replies)
  0 siblings, 8 replies; 22+ messages in thread
From: Sylwester Nawrocki @ 2019-04-04 17:17 UTC (permalink / raw)
  To: krzk
  Cc: kgene, robh+dt, mark.rutland, cw00.choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, b.zolnierkie, m.szyprowski, Sylwester Nawrocki

The Adaptive Supply Voltage (ASV) on Exynos SoCs is a technique of adjusting
subsystem operating points, i.e. power supply voltage for given clock 
frequency, in order to better match actual capabilities of the hardware 
and optimize power consumption.  This applies to subsystems of the SoC like: 
CPU clusters, GPU, the memory controller or camera ISP.  During production 
process the SoC chip is assigned to one of several bins (ASV groups) and 
the group information is encoded in the SoC CHIPID block registers and/or 
OTP memory.  This information is then used to select more finely matching 
operating points for devices.

The motivation of this patch set was, amongst others, to ensure proper 
Odroid XU3/XU4 operation with highest performance operating points.

This patch set adds a driver parsing ASV tables from DT and finely 
adjusting CPU operating points to optimize power consumption and ensure 
proper operation for each SoC revision.

I just recently noticed there are already somewhat similar drivers located
in drivers/power/avs, I'm considering moving exynos-asv driver there in next 
iteration of this patch set. 

This patch set includes Exynos CHIPID driver posted by Pankaj Dubey and
futher improved by Bartlomiej Zolnierkiewicz [1].

Tested on Odroid XU3, XU3 Lite, XU4 and Exynos5433 TM2 board (with further 
patches not included in this series).

The DT binding documented in patch 3/8 doesn't describe any hardware,
it's purely software description.  I'd like to get some feedback specially
on that one, I thought it was reasonable to put that data in DT.  There 
will be many of this tables, per each SoC type and the driver looks much
better with those tables in DT IMHO. 

[1] https://lkml.org/lkml/2018/11/15/908

Pankaj Dubey (3):
  soc: samsung: Add exynos chipid driver support
  ARM: EXYNOS: enable exynos_chipid for ARCH_EXYNOS
  ARM64: EXYNOS: enable exynos_chipid for ARCH_EXYNOS

Sylwester Nawrocki (5):
  soc: samsung: Exynos chipid driver update
  dt-bindings: exynos: Add ASV tables binding documentation
  soc: samsung: Add Exynos Adaptive Supply Voltage driver
  ARM: EXYNOS: Enable exynos-asv driver for ARCH_EXYNOS
  ARM: dts: exynos: Add ASV tables for exynos5422/5800

 .../devicetree/bindings/arm/samsung/asv.txt   |  76 +++++
 arch/arm/boot/dts/exynos5.dtsi                |   2 +-
 arch/arm/boot/dts/exynos5800.dtsi             | 207 +++++++++++++
 arch/arm/mach-exynos/Kconfig                  |   2 +
 arch/arm64/Kconfig.platforms                  |   1 +
 drivers/soc/samsung/Kconfig                   |  16 +
 drivers/soc/samsung/Makefile                  |   5 +
 drivers/soc/samsung/exynos-asv.c              | 279 ++++++++++++++++++
 drivers/soc/samsung/exynos-asv.h              | 114 +++++++
 drivers/soc/samsung/exynos-chipid.c           | 113 +++++++
 drivers/soc/samsung/exynos-chipid.h           |  48 +++
 drivers/soc/samsung/exynos5422-asv.c          | 209 +++++++++++++
 drivers/soc/samsung/exynos5422-asv.h          |  25 ++
 13 files changed, 1096 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/arm/samsung/asv.txt
 create mode 100644 drivers/soc/samsung/exynos-asv.c
 create mode 100644 drivers/soc/samsung/exynos-asv.h
 create mode 100644 drivers/soc/samsung/exynos-chipid.c
 create mode 100644 drivers/soc/samsung/exynos-chipid.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] 22+ messages in thread

* [PATCH RFC 1/8] soc: samsung: Add exynos chipid driver support
       [not found]   ` <CGME20190404172224epcas2p21b449c0ae8e36f7e800ae67c18db35a2@epcas2p2.samsung.com>
@ 2019-04-04 17:17     ` Sylwester Nawrocki
  2019-04-05  6:53       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 22+ messages in thread
From: Sylwester Nawrocki @ 2019-04-04 17:17 UTC (permalink / raw)
  To: krzk
  Cc: kgene, robh+dt, mark.rutland, cw00.choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, b.zolnierkie, m.szyprowski

From: Pankaj Dubey <pankaj.dubey@samsung.com>

Exynos SoCs have Chipid, for identification of product IDs and SoC
revisions. This patch intends to provide initialization code for all
these functionalities, at the same time it provides some sysfs entries
for accessing these information to user-space.

This driver uses existing binding for exynos-chipid.

Changes by Bartlomiej:
- fixed return values on errors
- removed bogus kfree_const()
- added missing Exynos4210 EVT0 id
- converted code to use EXYNOS_MASK define
- fixed np use after of_node_put()
- fixed too early use of dev_info()
- made driver fail for unknown SoC-s
- added SPDX tag
- updated Copyrights

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
[m.szyprowski: for suggestion and code snippet of product_id_to_soc_id]
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
 drivers/soc/samsung/Kconfig         |   5 ++
 drivers/soc/samsung/Makefile        |   2 +
 drivers/soc/samsung/exynos-chipid.c | 111 ++++++++++++++++++++++++++++
 3 files changed, 118 insertions(+)
 create mode 100644 drivers/soc/samsung/exynos-chipid.c

diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
index 2186285fda92..2905f5262197 100644
--- a/drivers/soc/samsung/Kconfig
+++ b/drivers/soc/samsung/Kconfig
@@ -7,6 +7,11 @@ menuconfig SOC_SAMSUNG

 if SOC_SAMSUNG

+config EXYNOS_CHIPID
+	bool "Exynos Chipid controller driver" if COMPILE_TEST
+	depends on ARCH_EXYNOS || COMPILE_TEST
+	select SOC_BUS
+
 config EXYNOS_PMU
 	bool "Exynos PMU controller driver" if COMPILE_TEST
 	depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
index 29f294baac6e..3b6a8797416c 100644
--- a/drivers/soc/samsung/Makefile
+++ b/drivers/soc/samsung/Makefile
@@ -1,4 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_EXYNOS_CHIPID)	+= exynos-chipid.o
 obj-$(CONFIG_EXYNOS_PMU)	+= exynos-pmu.o

 obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)	+= exynos3250-pmu.o exynos4-pmu.o \
diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
new file mode 100644
index 000000000000..5cb018807817
--- /dev/null
+++ b/drivers/soc/samsung/exynos-chipid.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ *
+ * EXYNOS - CHIP ID support
+ * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
+ * Author: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+
+#define EXYNOS_SUBREV_MASK	(0xF << 4)
+#define EXYNOS_MAINREV_MASK	(0xF << 0)
+#define EXYNOS_REV_MASK		(EXYNOS_SUBREV_MASK | EXYNOS_MAINREV_MASK)
+#define EXYNOS_MASK		0xFFFFF000
+
+static const struct exynos_soc_id {
+	const char *name;
+	unsigned int id;
+} soc_ids[] = {
+	{ "EXYNOS3250", 0xE3472000 },
+	{ "EXYNOS4210", 0x43200000 },	/* EVT0 revision */
+	{ "EXYNOS4210", 0x43210000 },
+	{ "EXYNOS4212", 0x43220000 },
+	{ "EXYNOS4412", 0xE4412000 },
+	{ "EXYNOS5250", 0x43520000 },
+	{ "EXYNOS5260", 0xE5260000 },
+	{ "EXYNOS5410", 0xE5410000 },
+	{ "EXYNOS5420", 0xE5420000 },
+	{ "EXYNOS5440", 0xE5440000 },
+	{ "EXYNOS5800", 0xE5422000 },
+	{ "EXYNOS7420", 0xE7420000 },
+	{ "EXYNOS5433", 0xE5433000 },
+};
+
+static const char * __init product_id_to_soc_id(unsigned int product_id)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(soc_ids); i++)
+		if ((product_id & EXYNOS_MASK) == soc_ids[i].id)
+			return soc_ids[i].name;
+	return NULL;
+}
+
+int __init exynos_chipid_early_init(void)
+{
+	struct soc_device_attribute *soc_dev_attr;
+	void __iomem *exynos_chipid_base;
+	struct soc_device *soc_dev;
+	struct device_node *root;
+	struct device_node *np;
+	u32 product_id;
+	u32 revision;
+
+	/* look up for chipid node */
+	np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-chipid");
+	if (!np)
+		return -ENODEV;
+
+	exynos_chipid_base = of_iomap(np, 0);
+	of_node_put(np);
+
+	if (!exynos_chipid_base) {
+		pr_err("Failed to map SoC chipid\n");
+		return -ENXIO;
+	}
+
+	product_id = readl_relaxed(exynos_chipid_base);
+	revision = product_id & EXYNOS_REV_MASK;
+	iounmap(exynos_chipid_base);
+
+	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+	if (!soc_dev_attr)
+		return -ENOMEM;
+
+	soc_dev_attr->family = "Samsung Exynos";
+
+	root = of_find_node_by_path("/");
+	of_property_read_string(root, "model", &soc_dev_attr->machine);
+	of_node_put(root);
+
+	soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision);
+	soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
+	if (!soc_dev_attr->soc_id) {
+		pr_err("Unknown SoC\n");
+		return -ENODEV;
+	}
+
+	/* please note that the actual registration will be deferred */
+	soc_dev = soc_device_register(soc_dev_attr);
+	if (IS_ERR(soc_dev)) {
+		kfree(soc_dev_attr->revision);
+		kfree(soc_dev_attr);
+		return PTR_ERR(soc_dev);
+	}
+
+	/* it is too early to use dev_info() here (soc_dev is NULL) */
+	pr_info("soc soc0: Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
+		soc_dev_attr->soc_id, product_id, revision);
+
+	return 0;
+}
+early_initcall(exynos_chipid_early_init);
--
2.17.1


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

* [PATCH RFC 2/8] soc: samsung: Exynos chipid driver update
       [not found]   ` <CGME20190404172229epcas2p25a819e37035b26ccf53613e880bdcacf@epcas2p2.samsung.com>
@ 2019-04-04 17:17     ` Sylwester Nawrocki
  2019-04-05  9:22       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 22+ messages in thread
From: Sylwester Nawrocki @ 2019-04-04 17:17 UTC (permalink / raw)
  To: krzk
  Cc: kgene, robh+dt, mark.rutland, cw00.choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, b.zolnierkie, m.szyprowski, Sylwester Nawrocki

This patch adds definition of selected CHIP ID register offsets
and register bit field definitions for Exynos5422 SoC.

exynos_chipid_read() helper function is added to allow reading
the CHIP ID block registers.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 drivers/soc/samsung/exynos-chipid.c | 16 +++++-----
 drivers/soc/samsung/exynos-chipid.h | 48 +++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+), 7 deletions(-)
 create mode 100644 drivers/soc/samsung/exynos-chipid.h

diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
index 5cb018807817..4920f0ef2c55 100644
--- a/drivers/soc/samsung/exynos-chipid.c
+++ b/drivers/soc/samsung/exynos-chipid.c
@@ -16,10 +16,7 @@
 #include <linux/slab.h>
 #include <linux/sys_soc.h>
 
-#define EXYNOS_SUBREV_MASK	(0xF << 4)
-#define EXYNOS_MAINREV_MASK	(0xF << 0)
-#define EXYNOS_REV_MASK		(EXYNOS_SUBREV_MASK | EXYNOS_MAINREV_MASK)
-#define EXYNOS_MASK		0xFFFFF000
+#include "exynos-chipid.h"
 
 static const struct exynos_soc_id {
 	const char *name;
@@ -40,6 +37,13 @@ static const struct exynos_soc_id {
 	{ "EXYNOS5433", 0xE5433000 },
 };
 
+static void __iomem *exynos_chipid_base;
+
+unsigned int exynos_chipid_read(unsigned int offset)
+{
+	return readl_relaxed(exynos_chipid_base + offset);
+}
+
 static const char * __init product_id_to_soc_id(unsigned int product_id)
 {
 	int i;
@@ -53,7 +57,6 @@ static const char * __init product_id_to_soc_id(unsigned int product_id)
 int __init exynos_chipid_early_init(void)
 {
 	struct soc_device_attribute *soc_dev_attr;
-	void __iomem *exynos_chipid_base;
 	struct soc_device *soc_dev;
 	struct device_node *root;
 	struct device_node *np;
@@ -73,9 +76,8 @@ int __init exynos_chipid_early_init(void)
 		return -ENXIO;
 	}
 
-	product_id = readl_relaxed(exynos_chipid_base);
+	product_id = exynos_chipid_read(EXYNOS_CHIPID_REG_PRO_ID);
 	revision = product_id & EXYNOS_REV_MASK;
-	iounmap(exynos_chipid_base);
 
 	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
 	if (!soc_dev_attr)
diff --git a/drivers/soc/samsung/exynos-chipid.h b/drivers/soc/samsung/exynos-chipid.h
new file mode 100644
index 000000000000..826a12c25fa2
--- /dev/null
+++ b/drivers/soc/samsung/exynos-chipid.h
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ *
+ * EXYNOS - CHIP ID support
+ */
+
+#define EXYNOS_CHIPID_REG_PRO_ID	0x00
+ #define EXYNOS_SUBREV_MASK		(0xf << 4)
+ #define EXYNOS_MAINREV_MASK		(0xf << 0)
+ #define EXYNOS_REV_MASK		(EXYNOS_SUBREV_MASK | \
+					 EXYNOS_MAINREV_MASK)
+ #define EXYNOS_MASK			0xfffff000
+
+#define EXYNOS_CHIPID_REG_PKG_ID	0x04
+ #define EXYNOS5422_IDS_OFFSET		24
+ #define EXYNOS5422_IDS_MASK		0xff
+ #define EXYNOS5422_USESG_OFFSET	3
+ #define EXYNOS5422_USESG_MASK		0x01
+ #define EXYNOS5422_SG_OFFSET		0
+ #define EXYNOS5422_SG_MASK		0x07
+ #define EXYNOS5422_TABLE_OFFSET	8
+ #define EXYNOS5422_TABLE_MASK		0x03
+ #define EXYNOS5422_SG_A_OFFSET		17
+ #define EXYNOS5422_SG_A_MASK		0x0f
+ #define EXYNOS5422_SG_B_OFFSET		21
+ #define EXYNOS5422_SG_B_MASK		0x03
+ #define EXYNOS5422_SG_BSIGN_OFFSET	23
+ #define EXYNOS5422_SG_BSIGN_MASK	0x01
+ #define EXYNOS5422_BIN2_OFFSET		12
+ #define EXYNOS5422_BIN2_MASK		0x01
+
+#define EXYNOS_CHIPID_REG_LOT_ID	0x14
+
+#define EXYNOS_CHIPID_AUX_INFO		0x1c
+ #define EXYNOS5422_TMCB_OFFSET		0
+ #define EXYNOS5422_TMCB_MASK		0x7f
+ #define EXYNOS5422_ARM_UP_OFFSET	8
+ #define EXYNOS5422_ARM_UP_MASK		0x03
+ #define EXYNOS5422_ARM_DN_OFFSET	10
+ #define EXYNOS5422_ARM_DN_MASK		0x03
+ #define EXYNOS5422_KFC_UP_OFFSET	12
+ #define EXYNOS5422_KFC_UP_MASK		0x03
+ #define EXYNOS5422_KFC_DN_OFFSET	14
+ #define EXYNOS5422_KFC_DN_MASK		0x03
+
+unsigned int exynos_chipid_read(unsigned int offset);
-- 
2.17.1


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

* [PATCH RFC 3/8] dt-bindings: exynos: Add ASV tables binding documentation
       [not found]   ` <CGME20190404172234epcas1p37667ec0996000aff9297f13639908dfc@epcas1p3.samsung.com>
@ 2019-04-04 17:17     ` Sylwester Nawrocki
  2019-04-29 17:23       ` Rob Herring
  0 siblings, 1 reply; 22+ messages in thread
From: Sylwester Nawrocki @ 2019-04-04 17:17 UTC (permalink / raw)
  To: krzk
  Cc: kgene, robh+dt, mark.rutland, cw00.choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, b.zolnierkie, m.szyprowski, Sylwester Nawrocki

This patch adds documentation of the Exynos ASV (Adaptive Voltage Supply)
tables DT binding.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 .../devicetree/bindings/arm/samsung/asv.txt   | 76 +++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/samsung/asv.txt

diff --git a/Documentation/devicetree/bindings/arm/samsung/asv.txt b/Documentation/devicetree/bindings/arm/samsung/asv.txt
new file mode 100644
index 000000000000..0db907263a91
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/samsung/asv.txt
@@ -0,0 +1,76 @@
+Exynos Adaptive Supply Voltage (ASV) tables
+-------------------------------------------
+
+The Adaptive Supply Voltage (ASV) on Exynos SoCs is a technique of adjusting
+operating points, i.e. the power supply voltage for given clock frequency,
+in order to better match actual capabilities of the hardware and optimize power
+consumption.  This applies to subsystem of the SoC like: CPU clusters, GPU,
+the memory controller or camera ISP.  During production process the SoC chip
+is assigned to one of several bins (ASV groups) and the group information
+is encoded in the SoC CHIPID block registers and/or OTP memory. This information
+is then used by the OS to select more finely matching operating points for
+devices.
+
+This binding describes data used to create actual operating points for the
+subsystems.  The data is in form of two-dimensional arrays of M x N cells,
+where the first column contains frequency values and subsequent columns
+associated with ASV groups contain corresponding voltage values.
+
+    frequency group0 group1 ...  group(N-1)
+       0        1      2    ...  N-1
+0    <f0      V00    V01    ...  V0n>,
+1    <f1      V10    V11    ...  V1n>,
+...  <        ...                 >,
+M-1  <fm      Vm0    Vm1    ...  Vmn>,
+
+In simplest form the actual operating points set may be created by selecting
+whole column for the voltage values, however also parts of multiple columns may
+be combined by the OS to create series of voltage values corresponding to
+frequencies in column 0.
+
+The ASV tables are defined as sub-nodes of parent node containing all tables.
+
+* Main node
+
+Required properties:
+ - compatible : should at least contain "samsung,exynos-asv-v1".
+
+* Table node
+
+Required properties:
+ - samsung,asv-table-size : specifies dimension of the table, the first cell is
+   total number of rows (M), the second cell is total number of columns (N),
+ - samsung,asv-table-id : ID of the table, lower 8-bits is an index (revision)
+   of the table, remaining bits (31...8) specify a subsystem the table applies
+   to:  0 - ARM/Eagle (big) CPU cluster, 1 - KFC (little) CPU cluster,
+ - samsung,asv-data : the ASV table data as described earlier in this document.
+   First cell is frequency value, then N-1 voltage values. Such sequence
+   is repeated M times.
+
+Optional properties:
+ - samsung,asv-common-data : a list of frequency, voltage pairs used to describe
+   operating points where voltage is same for all N-1 ASV groups. This allows
+   to avoid data duplication is the "samsung,asv-data" property.
+
+Example:
+
+&chipid {
+	asv {
+		compatible = "samsung,exynos-asv-v1";
+		asv-table-0 {
+			samsung,asv-table-size = <8 6>;
+			samsung,asv-table-id = <0x0>;
+			samsung,asv-data =
+				/*     ASV0    ASV1    ASV2    ASV3    ASV4  */
+				<1700 1187500 1175000 1162500 1150000 1137500 >,
+				<1500 1125000 1112500 1100000 1087500 1075000 >,
+				<1300 1075000 1062500 1050000 1037500 1025000 >,
+				<1000  987500  975000  962500  950000  937500 >,
+				< 900  950000  937500  925000  925000  925000 >,
+				< 700  925000  912500  912500  912500  912500 >;
+						     /* ASV0...15 */
+			samsung,asv-common-data = <600 900000>,
+						  <500 900000>;
+		};
+	};
+};
-- 
2.17.1


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

* [PATCH RFC 4/8] soc: samsung: Add Exynos Adaptive Supply Voltage driver
       [not found]   ` <CGME20190404172238epcas2p21ef28f46b728127dcd6e8ee72752a1b8@epcas2p2.samsung.com>
@ 2019-04-04 17:17     ` Sylwester Nawrocki
  2019-04-05 10:24       ` Krzysztof Kozlowski
  2019-04-23 10:50       ` Krzysztof Kozlowski
  0 siblings, 2 replies; 22+ messages in thread
From: Sylwester Nawrocki @ 2019-04-04 17:17 UTC (permalink / raw)
  To: krzk
  Cc: kgene, robh+dt, mark.rutland, cw00.choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, b.zolnierkie, m.szyprowski, Sylwester Nawrocki

The Adaptive Supply Voltage (ASV) on Exynos SoCs is a technique of adjusting
operating points of devices in order to better match actual capabilities
of the hardware and optimize power consumption.

This patch adds common code for parsing the ASV tables from devicetree
and updating CPU OPPs.

Also support for Exynos5422/5800 SoC is added, the Exynos5422 specific part
of the patch 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>
---
 drivers/soc/samsung/Kconfig          |  11 ++
 drivers/soc/samsung/Makefile         |   3 +
 drivers/soc/samsung/exynos-asv.c     | 279 +++++++++++++++++++++++++++
 drivers/soc/samsung/exynos-asv.h     | 114 +++++++++++
 drivers/soc/samsung/exynos5422-asv.c | 209 ++++++++++++++++++++
 drivers/soc/samsung/exynos5422-asv.h |  25 +++
 6 files changed, 641 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 2905f5262197..4d121984f71a 100644
--- a/drivers/soc/samsung/Kconfig
+++ b/drivers/soc/samsung/Kconfig
@@ -7,6 +7,17 @@ menuconfig SOC_SAMSUNG
 
 if SOC_SAMSUNG
 
+config EXYNOS_ASV
+	bool "Exynos Adaptive Supply Voltage support" if COMPILE_TEST
+	depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
+	depends on EXYNOS_CHIPID
+	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..60532c7eb3aa
--- /dev/null
+++ b/drivers/soc/samsung/exynos-asv.c
@@ -0,0 +1,279 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 - 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/of.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
+
+#include "exynos-asv.h"
+#include "exynos5422-asv.h"
+#include "exynos5433-asv.h"
+
+#ifndef MHZ
+#define MHZ 1000000U
+#endif
+
+static struct exynos_asv *exynos_asv;
+
+int exynos_asv_parse_of_table(struct device_node *node,
+			      struct exynos_asv_table *table,
+			      int index)
+{
+	u32 table_size, table_id = 0;
+	unsigned int len1, len2 = 0;
+	unsigned int num_cols, num_rows;
+	u32 tmp[20];
+	u32 *buf;
+	int ret;
+
+	ret = of_property_read_u32(node, "samsung,asv-table-id",
+				   &table_id);
+	if (ret < 0) {
+		pr_err("ASV: Missing table id in %pOF\n", node);
+		return ret;
+	}
+	table->id = table_id;
+
+	if (index >= 0 && asv_table_to_index(table_id) != index)
+		return -EBADR;
+
+	ret = of_property_read_u32_array(node, "samsung,asv-table-size",
+					 tmp, 2);
+	if (ret < 0)
+		return ret;
+
+	num_rows = tmp[0];
+	num_cols = tmp[1];
+	if (num_rows > EXYNOS_ASV_MAX_LEVELS ||
+	    num_cols > (EXYNOS_ASV_MAX_GROUPS + 1)) {
+		pr_err("ASV: Unsupported ASV table size (%d x %d)\n",
+		       num_rows, num_cols);
+		return -EINVAL;
+	}
+
+	table_size = num_rows * num_cols;
+	buf = kcalloc(table_size, sizeof(u32), GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = of_property_read_variable_u32_array(node, "samsung,asv-data",
+						  buf, 0, table_size);
+	if (ret < 0)
+		goto err_free_buf;
+
+	len1 = ret;
+
+	if (ret < table_size) {
+		u32 *dst, *src;
+		ret = of_property_read_variable_u32_array(node,
+						"samsung,asv-common-data",
+						(u32 *)tmp, 0,
+						ARRAY_SIZE(tmp));
+		if (ret < 0) {
+			pr_err("ASV: Not enough data for table #%x (%d x %d)\n",
+			       table_id, num_rows, num_cols);
+			goto err_free_buf;
+		}
+		len2 = ret;
+
+		if (len1 + ((len2 / 2) * num_cols) > table_size) {
+			pr_err("ASV: Incorrect table %#x definition\n",
+			       table_id);
+				ret = -EINVAL;
+				goto err_free_buf;
+			}
+		/*
+		 * Copy data common to all ASV levels to first and second column
+		 * in the main buffer.  We don't replicate data to further
+		 * columns, instead they are left initialized to 0 (invalid,
+		 * unused frequency value).  We assume that users of the table
+		 * will refer to voltage data in column 1 if 0 is encountered
+		 * in any further column (2, 3,...).
+		 */
+		dst = buf + len1;
+		src = tmp;
+
+		while (len2 >= 2) {
+			memcpy(dst, src, 2 * sizeof(u32));
+			dst += num_cols;
+			src += 2;
+			len2 -= 2;
+		}
+	}
+
+	table->num_cols = num_cols;
+	table->num_rows = num_rows;
+	table->buf = buf;
+	return 0;
+
+err_free_buf:
+	kfree(buf);
+	return ret;
+}
+
+int exynos_asv_parse_cpu_tables(struct exynos_asv *asv,	struct device_node *np,
+				int table_index)
+{
+	struct exynos_asv_subsys *subsys;
+	struct exynos_asv_table table;
+	struct device_node *child;
+	int ret;
+
+	for_each_child_of_node(np, child) {
+		ret = exynos_asv_parse_of_table(child, &table, table_index);
+		if (ret < 0) {
+			if (ret == -EBADR)
+				continue;
+			of_node_put(child);
+			return ret;
+		}
+
+		pr_debug("%s: Matching table: id: %#x at %pOF\n",
+			 __func__, table.id, child);
+
+		switch(asv_table_to_subsys_id(table.id)) {
+		case EXYNOS_ASV_SUBSYS_ID_ARM:
+			subsys = &asv->arm;
+			break;
+		case EXYNOS_ASV_SUBSYS_ID_KFC:
+			subsys = &asv->kfc;
+			break;
+		default:
+			of_node_put(child);
+			return -EINVAL;
+		}
+
+		subsys->num_asv_levels = table.num_rows;
+		subsys->num_asv_groups = table.num_cols - 1;
+		subsys->table = table;
+		subsys->id = asv_table_to_subsys_id(table.id);
+	}
+
+	return 0;
+}
+
+static int exynos_asv_update_cpu_opps(struct device *cpu)
+{
+	struct exynos_asv_subsys *subsys = NULL;
+	struct dev_pm_opp *opp;
+	unsigned int opp_freq;
+	int i;
+
+	if (of_device_is_compatible(cpu->of_node,
+				    exynos_asv->arm.cpu_dt_compat))
+		subsys = &exynos_asv->arm;
+	else if (of_device_is_compatible(cpu->of_node,
+					 exynos_asv->kfc.cpu_dt_compat))
+		subsys = &exynos_asv->kfc;
+
+	if (!subsys)
+		return -EINVAL;
+
+	for (i = 0; i < subsys->num_asv_levels; i++) {
+		unsigned int new_voltage;
+		unsigned int voltage;
+		int timeout = 1000;
+		int err;
+
+		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)) {
+			pr_info("%s cpu%d opp%d, freq: %u missing\n",
+				__func__, cpu->id, i, opp_freq);
+
+			continue;
+		}
+
+		voltage = dev_pm_opp_get_voltage(opp);
+		new_voltage = exynos_asv->opp_get_voltage(subsys, i, voltage);
+		dev_pm_opp_put(opp);
+
+		opp_freq *= MHZ;
+		dev_pm_opp_remove(cpu, opp_freq);
+
+		while (--timeout) {
+			opp = dev_pm_opp_find_freq_exact(cpu, opp_freq, true);
+			if (IS_ERR(opp))
+				break;
+			dev_pm_opp_put(opp);
+			msleep(1);
+		}
+
+		err = dev_pm_opp_add(cpu, opp_freq, new_voltage);
+		if (err < 0)
+			pr_err("%s: Failed to add OPP %u Hz/%u uV for cpu%d\n",
+			       __func__, opp_freq, new_voltage, cpu->id);
+	}
+
+	return 0;
+}
+
+static int exynos_asv_update_opps(void)
+{
+	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(cpu);
+			if (ret < 0)
+				pr_err("%s: Couldn't udate OPPs for cpu%d\n",
+				       __func__, cpuid);
+		}
+
+		dev_pm_opp_put_opp_table(opp_table);
+	}
+
+	return	0;
+}
+
+static int __init exynos_asv_init(void)
+{
+	int ret;
+
+	exynos_asv = kcalloc(1, sizeof(struct exynos_asv), GFP_KERNEL);
+	if (!exynos_asv)
+		return -ENOMEM;
+
+	if (of_machine_is_compatible("samsung,exynos5800") ||
+	    of_machine_is_compatible("samsung,exynos5420"))
+		ret = exynos5422_asv_init(exynos_asv);
+	else
+		return 0;
+
+	if (ret < 0)
+		return ret;
+
+	ret = exynos_asv_update_opps();
+
+	if (exynos_asv->release)
+		exynos_asv->release(exynos_asv);
+
+	return ret;
+}
+late_initcall(exynos_asv_init)
diff --git a/drivers/soc/samsung/exynos-asv.h b/drivers/soc/samsung/exynos-asv.h
new file mode 100644
index 000000000000..3444b361e5e3
--- /dev/null
+++ b/drivers/soc/samsung/exynos-asv.h
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 - 2019 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * Samsung Exynos SoC Adaptive Supply Voltage support
+ */
+#ifndef __EXYNOS_ASV_H
+#define __EXYNOS_ASV_H
+
+#define EXYNOS_ASV_MAX_GROUPS		16
+#define EXYNOS_ASV_MAX_LEVELS		24
+
+#define EXYNOS_ASV_TABLE_INDEX_MASK	(0xff)
+#define EXYNOS_ASV_SUBSYS_ID_MASK	(0xff << 8)
+
+#define asv_table_to_subsys_id(_id)	((_id >> 8) & 0xff)
+#define asv_table_to_index(_id)		((_id) & 0xff)
+
+#define EXYNOS_ASV_SUBSYS_ID_ARM	0x0
+#define EXYNOS_ASV_SUBSYS_ID_EGL	EXYNOS_ASV_SUBSYS_ID_ARM
+#define EXYNOS_ASV_SUBSYS_ID_KFC	0x1
+#define EXYNOS_ASV_SUBSYS_ID_INT	0x2
+#define EXYNOS_ASV_SUBSYS_ID_MIF	0x3
+#define EXYNOS_ASV_SUBSYS_ID_G3D	0x4
+#define EXYNOS_ASV_SUBSYS_ID_CAM	0x5
+#define EXYNOS_ASV_SUBSYS_ID_MAX	0x6
+
+struct device_node;
+
+/* 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;
+	unsigned int id;
+	u32 *buf;
+};
+
+struct exynos_asv_subsys {
+	int id;
+	char *cpu_dt_compat;
+
+	unsigned int base_volt;
+	unsigned int num_asv_levels;
+	unsigned int num_asv_groups;
+	unsigned int offset_volt_h;
+	unsigned int offset_volt_l;
+	struct exynos_asv_table table;
+};
+
+struct exynos_asv {
+	struct device_node *chipid_node;
+	struct exynos_asv_subsys arm;
+	struct exynos_asv_subsys kfc;
+
+	int (*opp_get_voltage)(struct exynos_asv_subsys *subs, int level,
+			       unsigned int voltage);
+	void (*release)(struct exynos_asv *asv);
+
+	unsigned int group;
+	unsigned int table;
+
+	/* TODO: Move member fields below to SoC type specific data structure */
+	unsigned int is_bin2;
+	unsigned int is_special_lot;
+};
+
+static inline u32 __exynos_asv_get_item(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_frequency(struct exynos_asv_subsys *subsys,
+					       unsigned int index)
+{
+	return __exynos_asv_get_item(&subsys->table, index, 0);
+}
+/**
+ * exynos_asv_parse_of_table - Parse ASV table from devicetree
+ *
+ * @node: DT node containing the table
+ * @table: The parsed table data
+ * @index: Used to select table with specific index to parse, if >= 0.
+ *         This argument is ignored if the value is less than 0.
+ *
+ * Returns: 0 on success, or negative value on failure. EBADR is returned
+ * when @index is >= 0 but the index value of the parsed table ID is different
+ * than @index.
+ */
+int exynos_asv_parse_of_table(struct device_node *node,
+			      struct exynos_asv_table *table,
+			      int index);
+
+/**
+ * exynos_asv_parse_cpu_tables - Parse ARM and KFC ASV tables from DT
+ *
+ * @asv: data structure to store the parsed data to
+ * @node: DT node containing the tables
+ * @index: Used to select table with specific index to parse, if >= 0.
+ *         This argument is ignored if the value is less than 0.
+ *
+ * Returns: 0 on success, or negative value on failure.
+ */
+int exynos_asv_parse_cpu_tables(struct exynos_asv *asv,	struct device_node *np,
+				int table_index);
+
+#endif /* __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..f0b7bdd873a9
--- /dev/null
+++ b/drivers/soc/samsung/exynos5422-asv.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 - 2019 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ *
+ * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#include "exynos-asv.h"
+#include "exynos-chipid.h"
+
+#define EXYNOS5422_NUM_ASV_GROUPS	14
+
+static struct exynos_asv *exynos_asv;
+
+static int exynos5422_asv_get_table(void)
+{
+	unsigned int reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
+
+	return (reg >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
+}
+
+static int exynos5422_asv_check_bin2(void)
+{
+	unsigned int reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
+
+	return (reg >> EXYNOS5422_BIN2_OFFSET) & EXYNOS5422_BIN2_MASK;
+}
+
+static bool exynos5422_asv_check_lot_id(void)
+{
+	unsigned int reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
+
+	return ((reg >> EXYNOS5422_USESG_OFFSET) & EXYNOS5422_USESG_MASK);
+}
+
+static const struct asv_limit_entry __asv_limits[EXYNOS5422_NUM_ASV_GROUPS] = {
+	{ 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 = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
+	unsigned int auxi_reg = exynos_chipid_read(EXYNOS_CHIPID_AUX_INFO);
+	int hpm, ids, i;
+
+	if (asv->is_special_lot) {
+		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 < EXYNOS5422_NUM_ASV_GROUPS; i++) {
+		if (ids <= __asv_limits[i].ids)
+			break;
+		if (hpm <= __asv_limits[i].hpm)
+			break;
+	}
+	if (i < EXYNOS5422_NUM_ASV_GROUPS)
+		return i;
+
+	return 0;
+}
+
+static int __asv_offset_voltage(unsigned int index)
+{
+	static const unsigned int offset_table[] = { 12500, 50000, 25000 };
+
+	if (index == 0 || index > 3)
+		return 0;
+
+	return offset_table[index - 1];
+}
+
+static void exynos5422_asv_offset_voltage_setup(struct exynos_asv *asv)
+{
+	struct exynos_asv_subsys *subsys;
+	unsigned int reg, value;
+
+	reg = exynos_chipid_read(EXYNOS_CHIPID_AUX_INFO);
+
+	/* ARM offset voltage setup */
+	subsys = &asv->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->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->num_asv_levels)
+		return volt;
+
+	asv_volt = __exynos_asv_get_item(&subsys->table, level,
+					 exynos_asv->group + 1);
+	if (asv_volt == 0 && exynos_asv->group > 1)
+		asv_volt = __exynos_asv_get_item(&subsys->table, level, 1);
+
+	if (volt > subsys->base_volt)
+		asv_volt += subsys->offset_volt_h;
+	else
+		asv_volt += subsys->offset_volt_l;
+
+	return asv_volt;
+}
+
+static void __init exynos5422_asv_release(struct exynos_asv *asv)
+{
+	kfree(asv->arm.table.buf);
+	asv->arm.table.buf = NULL;
+	kfree(asv->kfc.table.buf);
+	asv->kfc.table.buf = NULL;
+}
+
+int __init exynos5422_asv_init(struct exynos_asv *asv)
+{
+	struct device_node *node;
+	unsigned int table_index;
+	int ret;
+
+	exynos_asv = asv;
+
+	asv->is_bin2 = exynos5422_asv_check_bin2();
+	asv->is_special_lot = exynos5422_asv_check_lot_id();
+
+	if (of_machine_is_compatible("hardkernel,odroid-xu3-lite")) {
+		asv->is_bin2 = true;
+		asv->is_special_lot = false;
+	}
+
+	asv->group = exynos5422_asv_get_group(asv);
+	asv->table = exynos5422_asv_get_table();
+
+	exynos5422_asv_offset_voltage_setup(asv);
+
+	node = of_find_compatible_node(NULL, NULL, "samsung,exynos-asv-v1");
+	if (!node)
+		return -ENODEV;
+
+	if (!asv->is_bin2) {
+		if (asv->table == 2 || asv->table == 3)
+			table_index = asv->table;
+		else
+			table_index = 0;
+	} else {
+		table_index = 4;
+	}
+
+	ret = exynos_asv_parse_cpu_tables(asv, node, table_index);
+	of_node_put(node);
+	if (ret < 0)
+		return ret;
+
+	asv->arm.cpu_dt_compat = "arm,cortex-a15";
+	asv->kfc.cpu_dt_compat = "arm,cortex-a7";
+
+	asv->opp_get_voltage = exynos5422_asv_opp_get_voltage;
+	asv->release = exynos5422_asv_release;
+
+	return ret;
+}
diff --git a/drivers/soc/samsung/exynos5422-asv.h b/drivers/soc/samsung/exynos5422-asv.h
new file mode 100644
index 000000000000..f0d9107d6d0a
--- /dev/null
+++ b/drivers/soc/samsung/exynos5422-asv.h
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 - 2019 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ *
+ * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
+ */
+
+#ifndef __EXYNOS5422_ASV_H
+#define __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 /* __EXYNOS5422_ASV_H */
-- 
2.17.1


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

* [PATCH RFC 5/8] ARM: EXYNOS: enable exynos_chipid for ARCH_EXYNOS
       [not found]   ` <CGME20190404172243epcas1p39af2498a51772ee4ab2a31f26e469c5b@epcas1p3.samsung.com>
@ 2019-04-04 17:17     ` Sylwester Nawrocki
  0 siblings, 0 replies; 22+ messages in thread
From: Sylwester Nawrocki @ 2019-04-04 17:17 UTC (permalink / raw)
  To: krzk
  Cc: kgene, robh+dt, mark.rutland, cw00.choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, b.zolnierkie, m.szyprowski

From: Pankaj Dubey <pankaj.dubey@samsung.com>

As now we have chipid driver to initialize SoC related information
let's include it in build by default.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
 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 b40963cf91c7..e3e63aa5d60a 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_CHIPID
 	select EXYNOS_THERMAL
 	select EXYNOS_PMU
 	select EXYNOS_SROM
-- 
2.17.1


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

* [PATCH RFC 6/8] ARM64: EXYNOS: enable exynos_chipid for ARCH_EXYNOS
       [not found]   ` <CGME20190404172247epcas2p2d24f19f76db3cee177bd5b9df783eb3b@epcas2p2.samsung.com>
@ 2019-04-04 17:17     ` Sylwester Nawrocki
  0 siblings, 0 replies; 22+ messages in thread
From: Sylwester Nawrocki @ 2019-04-04 17:17 UTC (permalink / raw)
  To: krzk
  Cc: kgene, robh+dt, mark.rutland, cw00.choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, b.zolnierkie, m.szyprowski

From: Pankaj Dubey <pankaj.dubey@samsung.com>

This patch enables exynos_chipid driver for ARCH_EXYNOS
based SoC.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
 arch/arm64/Kconfig.platforms | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 70498a033cf5..794c65a4910a 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -67,6 +67,7 @@ config ARCH_BRCMSTB
 config ARCH_EXYNOS
 	bool "ARMv8 based Samsung Exynos SoC family"
 	select COMMON_CLK_SAMSUNG
+	select EXYNOS_CHIPID
 	select EXYNOS_PM_DOMAINS if PM_GENERIC_DOMAINS
 	select EXYNOS_PMU
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
-- 
2.17.1


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

* [PATCH RFC 7/8] ARM: EXYNOS: Enable exynos-asv driver for ARCH_EXYNOS
       [not found]   ` <CGME20190404172252epcas2p284b7e2e9e7102f6f95c982d547ed9d64@epcas2p2.samsung.com>
@ 2019-04-04 17:17     ` Sylwester Nawrocki
  0 siblings, 0 replies; 22+ messages in thread
From: Sylwester Nawrocki @ 2019-04-04 17:17 UTC (permalink / raw)
  To: krzk
  Cc: kgene, robh+dt, mark.rutland, cw00.choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, b.zolnierkie, m.szyprowski, Sylwester Nawrocki

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

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 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 e3e63aa5d60a..fe306a85228c 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] 22+ messages in thread

* [PATCH RFC 8/8] ARM: dts: exynos: Add ASV tables for exynos5422/5800
       [not found]   ` <CGME20190404172257epcas1p20d789242a2353dc8e9ffd7f435dc5eee@epcas1p2.samsung.com>
@ 2019-04-04 17:17     ` Sylwester Nawrocki
  2019-04-11  7:39       ` Anand Moon
  0 siblings, 1 reply; 22+ messages in thread
From: Sylwester Nawrocki @ 2019-04-04 17:17 UTC (permalink / raw)
  To: krzk
  Cc: kgene, robh+dt, mark.rutland, cw00.choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, b.zolnierkie, m.szyprowski, Sylwester Nawrocki

This patch ASV (Adaptive Supply Voltage) table entries for
Exynos5422/5800 SoC.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 arch/arm/boot/dts/exynos5.dtsi    |   2 +-
 arch/arm/boot/dts/exynos5800.dtsi | 207 ++++++++++++++++++++++++++++++
 2 files changed, 208 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi
index 67f9b4504a42..22eb951c614c 100644
--- a/arch/arm/boot/dts/exynos5.dtsi
+++ b/arch/arm/boot/dts/exynos5.dtsi
@@ -35,7 +35,7 @@
 		#size-cells = <1>;
 		ranges;
 
-		chipid@10000000 {
+		chipid: chipid@10000000 {
 			compatible = "samsung,exynos4210-chipid";
 			reg = <0x10000000 0x100>;
 		};
diff --git a/arch/arm/boot/dts/exynos5800.dtsi b/arch/arm/boot/dts/exynos5800.dtsi
index 57d3b319fd65..5358865f5c0b 100644
--- a/arch/arm/boot/dts/exynos5800.dtsi
+++ b/arch/arm/boot/dts/exynos5800.dtsi
@@ -16,6 +16,213 @@
 	compatible = "samsung,exynos5800", "samsung,exynos5";
 };
 
+&chipid {
+	asv {
+		compatible = "samsung,exynos-asv-v1";
+		asv-table-0 {
+			/* ARM 0, 1 */
+			samsung,asv-table-size = <20 15>;
+			samsung,asv-table-id = <0x0>;
+			samsung,asv-data =
+				      /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12   ASV13 */
+				<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>;
+						     /* ASV0...13 */
+			samsung,asv-common-data = <700 900000>,
+						  <600 900000>,
+						  <500 900000>,
+						  <400 900000>,
+						  <300 900000>,
+						  <200 900000>;
+		};
+		asv-table-2 {
+			/* ARM 2 */
+			samsung,asv-table-size = <20 15>;
+			samsung,asv-table-id = <0x2>;
+			samsung,asv-data =
+				      /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
+				<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>;
+						     /* ASV0...13 */
+			samsung,asv-common-data = <700 900000>,
+						  <600 900000>,
+						  <500 900000>,
+						  <400 900000>,
+						  <300 900000>,
+						  <200 900000>;
+		};
+		asv-table-3 {
+			/* ARM 3 */
+			samsung,asv-table-size = <20 15>;
+			samsung,asv-table-id = <0x3>;
+			samsung,asv-data =
+				      /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
+				<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>;
+						     /* ASV0...13 */
+			samsung,asv-common-data = <700 900000>,
+						  <600 900000>,
+						  <500 900000>,
+						  <400 900000>,
+						  <300 900000>,
+						  <200 900000>;
+		};
+
+		asv-table-4 {
+			/* ARM BIN2 */
+			samsung,asv-table-size = <17 15>;
+			samsung,asv-table-id = <0x4>;
+			samsung,asv-data =
+				      /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
+				<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>;
+						       /* ASV0...13 */
+			samsung,asv-common-data = <600 900000>,
+						  <500 900000>,
+						  <400 900000>,
+						  <300 900000>,
+						  <200 900000>;
+		};
+
+
+		asv-table-100 {
+			/* KFC 0, 1 */
+			samsung,asv-table-size = <14 15>;
+			samsung,asv-table-id = <0x100>;
+			samsung,asv-data =
+				      /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
+				<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>;
+						      /* ASV0...13 */
+			samsung,asv-common-data = <400 900000>,
+						  <300 900000>,
+						  <200 900000>;
+		};
+
+		asv-table-102 {
+			/* KFC 2 */
+			samsung,asv-table-size = <14 15>;
+			samsung,asv-table-id = <0x102>;
+			samsung,asv-data =
+				      /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
+				<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>;
+						      /* ASV0...13 */
+			samsung,asv-common-data = <400 900000>,
+						  <300 900000>,
+						  <200 900000>;
+		};
+
+		asv-table-103 {
+			/* KFC 3 */
+			samsung,asv-table-size = <14 15>;
+			samsung,asv-table-id = <0x103>;
+			samsung,asv-data =
+				      /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
+				<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>;
+						      /* ASV0...13 */
+			samsung,asv-common-data = <400 900000>,
+						  <300 900000>,
+						  <200 900000>;
+		};
+
+		asv-table-104 {
+			/* KFC BIN2 */
+			samsung,asv-table-size = <12 15>;
+			samsung,asv-table-id = <0x104>;
+			samsung,asv-data =
+				      /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
+				<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>;
+						      /* ASV0...13 */
+			samsung,asv-common-data = <300 900000>,
+						  <200 900000>;
+		};
+	};
+};
+
 &clock {
 	compatible = "samsung,exynos5800-clock";
 };
-- 
2.17.1


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

* Re: [PATCH RFC 1/8] soc: samsung: Add exynos chipid driver support
  2019-04-04 17:17     ` [PATCH RFC 1/8] soc: samsung: Add exynos chipid driver support Sylwester Nawrocki
@ 2019-04-05  6:53       ` Krzysztof Kozlowski
  2019-04-05  8:49         ` Sylwester Nawrocki
  0 siblings, 1 reply; 22+ messages in thread
From: Krzysztof Kozlowski @ 2019-04-05  6:53 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: kgene, robh+dt, mark.rutland, Chanwoo Choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, Bartłomiej Żołnierkiewicz,
	Marek Szyprowski

On Thu, 4 Apr 2019 at 19:22, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> From: Pankaj Dubey <pankaj.dubey@samsung.com>
>
> Exynos SoCs have Chipid, for identification of product IDs and SoC
> revisions. This patch intends to provide initialization code for all
> these functionalities, at the same time it provides some sysfs entries
> for accessing these information to user-space.
>
> This driver uses existing binding for exynos-chipid.
>
> Changes by Bartlomiej:
> - fixed return values on errors
> - removed bogus kfree_const()
> - added missing Exynos4210 EVT0 id
> - converted code to use EXYNOS_MASK define
> - fixed np use after of_node_put()
> - fixed too early use of dev_info()
> - made driver fail for unknown SoC-s
> - added SPDX tag
> - updated Copyrights
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> [m.szyprowski: for suggestion and code snippet of product_id_to_soc_id]
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>

Toy need to add your SoB here.

> ---
>  drivers/soc/samsung/Kconfig         |   5 ++
>  drivers/soc/samsung/Makefile        |   2 +
>  drivers/soc/samsung/exynos-chipid.c | 111 ++++++++++++++++++++++++++++
>  3 files changed, 118 insertions(+)
>  create mode 100644 drivers/soc/samsung/exynos-chipid.c
>
> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> index 2186285fda92..2905f5262197 100644
> --- a/drivers/soc/samsung/Kconfig
> +++ b/drivers/soc/samsung/Kconfig
> @@ -7,6 +7,11 @@ menuconfig SOC_SAMSUNG
>
>  if SOC_SAMSUNG
>
> +config EXYNOS_CHIPID
> +       bool "Exynos Chipid controller driver" if COMPILE_TEST
> +       depends on ARCH_EXYNOS || COMPILE_TEST
> +       select SOC_BUS
> +
>  config EXYNOS_PMU
>         bool "Exynos PMU controller driver" if COMPILE_TEST
>         depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
> diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
> index 29f294baac6e..3b6a8797416c 100644
> --- a/drivers/soc/samsung/Makefile
> +++ b/drivers/soc/samsung/Makefile
> @@ -1,4 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_EXYNOS_CHIPID)    += exynos-chipid.o
>  obj-$(CONFIG_EXYNOS_PMU)       += exynos-pmu.o
>
>  obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)   += exynos3250-pmu.o exynos4-pmu.o \
> diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
> new file mode 100644
> index 000000000000..5cb018807817
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-chipid.c
> @@ -0,0 +1,111 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2018 Samsung Electronics Co., Ltd.
> + *           http://www.samsung.com/
> + *
> + * EXYNOS - CHIP ID support
> + * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
> + * Author: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> + */
> +
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>

I commented Bartlomiej's patch which you included here. I did not
receive any further feedback from him so I do not know whether he
agrees with my comments or not... but if you send the same patch again
without addressing these comments, I feel like ignored.

I stopped on first ignored comment.

Therefore please address be sure that you addressed my comments from
Bartlomiej's patchset. If you do not agree with them, please let me
know. The comments are here:
https://patchwork.kernel.org/project/linux-samsung-soc/list/?series=43565&state=*

Best regards,
Krzysztof

> +#include <linux/slab.h>
> +#include <linux/sys_soc.h>
> +
> +#define EXYNOS_SUBREV_MASK     (0xF << 4)
> +#define EXYNOS_MAINREV_MASK    (0xF << 0)
> +#define EXYNOS_REV_MASK                (EXYNOS_SUBREV_MASK | EXYNOS_MAINREV_MASK)
> +#define EXYNOS_MASK            0xFFFFF000
> +
> +static const struct exynos_soc_id {
> +       const char *name;
> +       unsigned int id;
> +} soc_ids[] = {
> +       { "EXYNOS3250", 0xE3472000 },
> +       { "EXYNOS4210", 0x43200000 },   /* EVT0 revision */
> +       { "EXYNOS4210", 0x43210000 },
> +       { "EXYNOS4212", 0x43220000 },
> +       { "EXYNOS4412", 0xE4412000 },
> +       { "EXYNOS5250", 0x43520000 },
> +       { "EXYNOS5260", 0xE5260000 },
> +       { "EXYNOS5410", 0xE5410000 },
> +       { "EXYNOS5420", 0xE5420000 },
> +       { "EXYNOS5440", 0xE5440000 },
> +       { "EXYNOS5800", 0xE5422000 },
> +       { "EXYNOS7420", 0xE7420000 },
> +       { "EXYNOS5433", 0xE5433000 },
> +};
> +
> +static const char * __init product_id_to_soc_id(unsigned int product_id)
> +{
> +       int i;
> +
> +       for (i = 0; i < ARRAY_SIZE(soc_ids); i++)
> +               if ((product_id & EXYNOS_MASK) == soc_ids[i].id)
> +                       return soc_ids[i].name;
> +       return NULL;
> +}
> +
> +int __init exynos_chipid_early_init(void)
> +{
> +       struct soc_device_attribute *soc_dev_attr;
> +       void __iomem *exynos_chipid_base;
> +       struct soc_device *soc_dev;
> +       struct device_node *root;
> +       struct device_node *np;
> +       u32 product_id;
> +       u32 revision;
> +
> +       /* look up for chipid node */
> +       np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-chipid");
> +       if (!np)
> +               return -ENODEV;
> +
> +       exynos_chipid_base = of_iomap(np, 0);
> +       of_node_put(np);
> +
> +       if (!exynos_chipid_base) {
> +               pr_err("Failed to map SoC chipid\n");
> +               return -ENXIO;
> +       }
> +
> +       product_id = readl_relaxed(exynos_chipid_base);
> +       revision = product_id & EXYNOS_REV_MASK;
> +       iounmap(exynos_chipid_base);
> +
> +       soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
> +       if (!soc_dev_attr)
> +               return -ENOMEM;
> +
> +       soc_dev_attr->family = "Samsung Exynos";
> +
> +       root = of_find_node_by_path("/");
> +       of_property_read_string(root, "model", &soc_dev_attr->machine);
> +       of_node_put(root);
> +
> +       soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision);
> +       soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
> +       if (!soc_dev_attr->soc_id) {
> +               pr_err("Unknown SoC\n");
> +               return -ENODEV;
> +       }
> +
> +       /* please note that the actual registration will be deferred */
> +       soc_dev = soc_device_register(soc_dev_attr);
> +       if (IS_ERR(soc_dev)) {
> +               kfree(soc_dev_attr->revision);
> +               kfree(soc_dev_attr);
> +               return PTR_ERR(soc_dev);
> +       }
> +
> +       /* it is too early to use dev_info() here (soc_dev is NULL) */
> +       pr_info("soc soc0: Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
> +               soc_dev_attr->soc_id, product_id, revision);
> +
> +       return 0;
> +}
> +early_initcall(exynos_chipid_early_init);
> --
> 2.17.1
>

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

* Re: [PATCH RFC 1/8] soc: samsung: Add exynos chipid driver support
  2019-04-05  6:53       ` Krzysztof Kozlowski
@ 2019-04-05  8:49         ` Sylwester Nawrocki
  0 siblings, 0 replies; 22+ messages in thread
From: Sylwester Nawrocki @ 2019-04-05  8:49 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: kgene, robh+dt, mark.rutland, Chanwoo Choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, Bartłomiej Żołnierkiewicz,
	Marek Szyprowski

On 4/5/19 08:53, Krzysztof Kozlowski wrote:
> On Thu, 4 Apr 2019 at 19:22, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>> From: Pankaj Dubey <pankaj.dubey@samsung.com>
>>
>> Exynos SoCs have Chipid, for identification of product IDs and SoC
>> revisions. This patch intends to provide initialization code for all
>> these functionalities, at the same time it provides some sysfs entries
>> for accessing these information to user-space.

>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> [m.szyprowski: for suggestion and code snippet of product_id_to_soc_id]
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> 
> Toy need to add your SoB here.

Will correct that in next iteration.

>> diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
>> new file mode 100644
>> index 000000000000..5cb018807817
>> --- /dev/null
>> +++ b/drivers/soc/samsung/exynos-chipid.c
>> @@ -0,0 +1,111 @@

>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_platform.h>
>> +#include <linux/platform_device.h>
> 
> I commented Bartlomiej's patch which you included here. I did not
> receive any further feedback from him so I do not know whether he
> agrees with my comments or not... but if you send the same patch again
> without addressing these comments, I feel like ignored.
> 
> I stopped on first ignored comment.
> 
> Therefore please address be sure that you addressed my comments from
> Bartlomiej's patchset. If you do not agree with them, please let me
> know. The comments are here:
> https://patchwork.kernel.org/project/linux-samsung-soc/list/?series=43565&state=*

I will drop that unneeded header inclusion in next iteration.  It was 
just my oversight, I somehow missed your previous comments.  And of
course your reviews are appreciated. 

-- 
Regards,
Sylwester

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

* Re: [PATCH RFC 2/8] soc: samsung: Exynos chipid driver update
  2019-04-04 17:17     ` [PATCH RFC 2/8] soc: samsung: Exynos chipid driver update Sylwester Nawrocki
@ 2019-04-05  9:22       ` Krzysztof Kozlowski
  2019-04-05 10:04         ` Sylwester Nawrocki
  0 siblings, 1 reply; 22+ messages in thread
From: Krzysztof Kozlowski @ 2019-04-05  9:22 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: kgene, robh+dt, mark.rutland, Chanwoo Choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, Bartłomiej Żołnierkiewicz,
	Marek Szyprowski

On Thu, 4 Apr 2019 at 19:22, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> This patch adds definition of selected CHIP ID register offsets
> and register bit field definitions for Exynos5422 SoC.
>
> exynos_chipid_read() helper function is added to allow reading
> the CHIP ID block registers.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  drivers/soc/samsung/exynos-chipid.c | 16 +++++-----
>  drivers/soc/samsung/exynos-chipid.h | 48 +++++++++++++++++++++++++++++
>  2 files changed, 57 insertions(+), 7 deletions(-)
>  create mode 100644 drivers/soc/samsung/exynos-chipid.h
>
> diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
> index 5cb018807817..4920f0ef2c55 100644
> --- a/drivers/soc/samsung/exynos-chipid.c
> +++ b/drivers/soc/samsung/exynos-chipid.c
> @@ -16,10 +16,7 @@
>  #include <linux/slab.h>
>  #include <linux/sys_soc.h>
>
> -#define EXYNOS_SUBREV_MASK     (0xF << 4)
> -#define EXYNOS_MAINREV_MASK    (0xF << 0)
> -#define EXYNOS_REV_MASK                (EXYNOS_SUBREV_MASK | EXYNOS_MAINREV_MASK)
> -#define EXYNOS_MASK            0xFFFFF000

Create hex-addresses in first commit in lower case.

> +#include "exynos-chipid.h"
>
>  static const struct exynos_soc_id {
>         const char *name;
> @@ -40,6 +37,13 @@ static const struct exynos_soc_id {
>         { "EXYNOS5433", 0xE5433000 },
>  };
>
> +static void __iomem *exynos_chipid_base;

No, this was removed in Pankaj's version v6 -> v7 and I do not want it
to be file-scope. Having it file-scope is error prone and prevents
having multiple instances (I do not expect having more than one but
still code should be rather nicely generic).

> +
> +unsigned int exynos_chipid_read(unsigned int offset)
> +{
> +       return readl_relaxed(exynos_chipid_base + offset);
> +}
> +
>  static const char * __init product_id_to_soc_id(unsigned int product_id)
>  {
>         int i;
> @@ -53,7 +57,6 @@ static const char * __init product_id_to_soc_id(unsigned int product_id)
>  int __init exynos_chipid_early_init(void)
>  {
>         struct soc_device_attribute *soc_dev_attr;
> -       void __iomem *exynos_chipid_base;
>         struct soc_device *soc_dev;
>         struct device_node *root;
>         struct device_node *np;
> @@ -73,9 +76,8 @@ int __init exynos_chipid_early_init(void)
>                 return -ENXIO;
>         }
>
> -       product_id = readl_relaxed(exynos_chipid_base);
> +       product_id = exynos_chipid_read(EXYNOS_CHIPID_REG_PRO_ID);
>         revision = product_id & EXYNOS_REV_MASK;
> -       iounmap(exynos_chipid_base);
>
>         soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
>         if (!soc_dev_attr)
> diff --git a/drivers/soc/samsung/exynos-chipid.h b/drivers/soc/samsung/exynos-chipid.h
> new file mode 100644
> index 000000000000..826a12c25fa2
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-chipid.h
> @@ -0,0 +1,48 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2018 Samsung Electronics Co., Ltd.
> + *           http://www.samsung.com/
> + *
> + * EXYNOS - CHIP ID support
> + */
> +
> +#define EXYNOS_CHIPID_REG_PRO_ID       0x00
> + #define EXYNOS_SUBREV_MASK            (0xf << 4)
> + #define EXYNOS_MAINREV_MASK           (0xf << 0)
> + #define EXYNOS_REV_MASK               (EXYNOS_SUBREV_MASK | \
> +                                        EXYNOS_MAINREV_MASK)
> + #define EXYNOS_MASK                   0xfffff000
> +
> +#define EXYNOS_CHIPID_REG_PKG_ID       0x04

Can you comment that these are fields from this register?
The same in second one.

Best regards,
Krzysztof

> + #define EXYNOS5422_IDS_OFFSET         24
> + #define EXYNOS5422_IDS_MASK           0xff
> + #define EXYNOS5422_USESG_OFFSET       3
> + #define EXYNOS5422_USESG_MASK         0x01
> + #define EXYNOS5422_SG_OFFSET          0
> + #define EXYNOS5422_SG_MASK            0x07
> + #define EXYNOS5422_TABLE_OFFSET       8
> + #define EXYNOS5422_TABLE_MASK         0x03
> + #define EXYNOS5422_SG_A_OFFSET                17
> + #define EXYNOS5422_SG_A_MASK          0x0f
> + #define EXYNOS5422_SG_B_OFFSET                21
> + #define EXYNOS5422_SG_B_MASK          0x03
> + #define EXYNOS5422_SG_BSIGN_OFFSET    23
> + #define EXYNOS5422_SG_BSIGN_MASK      0x01
> + #define EXYNOS5422_BIN2_OFFSET                12
> + #define EXYNOS5422_BIN2_MASK          0x01
> +
> +#define EXYNOS_CHIPID_REG_LOT_ID       0x14
> +
> +#define EXYNOS_CHIPID_AUX_INFO         0x1c
> + #define EXYNOS5422_TMCB_OFFSET                0
> + #define EXYNOS5422_TMCB_MASK          0x7f
> + #define EXYNOS5422_ARM_UP_OFFSET      8
> + #define EXYNOS5422_ARM_UP_MASK                0x03
> + #define EXYNOS5422_ARM_DN_OFFSET      10
> + #define EXYNOS5422_ARM_DN_MASK                0x03
> + #define EXYNOS5422_KFC_UP_OFFSET      12
> + #define EXYNOS5422_KFC_UP_MASK                0x03
> + #define EXYNOS5422_KFC_DN_OFFSET      14
> + #define EXYNOS5422_KFC_DN_MASK                0x03
> +
> +unsigned int exynos_chipid_read(unsigned int offset);
> --
> 2.17.1
>

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

* Re: [PATCH RFC 2/8] soc: samsung: Exynos chipid driver update
  2019-04-05  9:22       ` Krzysztof Kozlowski
@ 2019-04-05 10:04         ` Sylwester Nawrocki
  0 siblings, 0 replies; 22+ messages in thread
From: Sylwester Nawrocki @ 2019-04-05 10:04 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: kgene, robh+dt, mark.rutland, Chanwoo Choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, Bartłomiej Żołnierkiewicz,
	Marek Szyprowski

On 4/5/19 11:22, Krzysztof Kozlowski wrote:
> On Thu, 4 Apr 2019 at 19:22, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>>
>> This patch adds definition of selected CHIP ID register offsets
>> and register bit field definitions for Exynos5422 SoC.
>>
>> exynos_chipid_read() helper function is added to allow reading
>> the CHIP ID block registers.
>>
>> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
>> ---
>>  drivers/soc/samsung/exynos-chipid.c | 16 +++++-----
>>  drivers/soc/samsung/exynos-chipid.h | 48 +++++++++++++++++++++++++++++
>>  2 files changed, 57 insertions(+), 7 deletions(-)
>>  create mode 100644 drivers/soc/samsung/exynos-chipid.h
>>
>> diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
>> index 5cb018807817..4920f0ef2c55 100644
>> --- a/drivers/soc/samsung/exynos-chipid.c
>> +++ b/drivers/soc/samsung/exynos-chipid.c
>> @@ -16,10 +16,7 @@

>> -#define EXYNOS_SUBREV_MASK     (0xF << 4)
>> -#define EXYNOS_MAINREV_MASK    (0xF << 0)
>> -#define EXYNOS_REV_MASK                (EXYNOS_SUBREV_MASK | EXYNOS_MAINREV_MASK)
>> -#define EXYNOS_MASK            0xFFFFF000
> 
> Create hex-addresses in first commit in lower case.

>> +static void __iomem *exynos_chipid_base;
> 
> No, this was removed in Pankaj's version v6 -> v7 and I do not want it
> to be file-scope. Having it file-scope is error prone and prevents
> having multiple instances (I do not expect having more than one but
> still code should be rather nicely generic).

I'm going to switch to using regmap so that will not be needed any 
more, together with exynos_chipid_read() helper. Then the header
file would be moved to include/linux/soc/samsung.
 
>> +unsigned int exynos_chipid_read(unsigned int offset)
>> +{
>> +       return readl_relaxed(exynos_chipid_base + offset);
>> +}

>> diff --git a/drivers/soc/samsung/exynos-chipid.h b/drivers/soc/samsung/exynos-chipid.h
>> new file mode 100644
>> index 000000000000..826a12c25fa2
>> --- /dev/null
>> +++ b/drivers/soc/samsung/exynos-chipid.h
>> @@ -0,0 +1,48 @@

>> +#define EXYNOS_CHIPID_REG_PRO_ID       0x00
>> + #define EXYNOS_SUBREV_MASK            (0xf << 4)
>> + #define EXYNOS_MAINREV_MASK           (0xf << 0)
>> + #define EXYNOS_REV_MASK               (EXYNOS_SUBREV_MASK | \
>> +                                        EXYNOS_MAINREV_MASK)
>> + #define EXYNOS_MASK                   0xfffff000
>> +
>> +#define EXYNOS_CHIPID_REG_PKG_ID       0x04
> 
> Can you comment that these are fields from this register?
> The same in second one.

OK, I will add some comment here.
 
>> + #define EXYNOS5422_IDS_OFFSET         24
>> + #define EXYNOS5422_IDS_MASK           0xff
-- 
Regards,
Sylwester

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

* Re: [PATCH RFC 4/8] soc: samsung: Add Exynos Adaptive Supply Voltage driver
  2019-04-04 17:17     ` [PATCH RFC 4/8] soc: samsung: Add Exynos Adaptive Supply Voltage driver Sylwester Nawrocki
@ 2019-04-05 10:24       ` Krzysztof Kozlowski
  2019-04-09 17:40         ` Sylwester Nawrocki
  2019-04-23 10:50       ` Krzysztof Kozlowski
  1 sibling, 1 reply; 22+ messages in thread
From: Krzysztof Kozlowski @ 2019-04-05 10:24 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: kgene, robh+dt, mark.rutland, Chanwoo Choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, Bartłomiej Żołnierkiewicz,
	Marek Szyprowski

Hi Sylwester,

Nice work, thank you!

I have a lot of minor nits all around and few more architecture-like comments.

I think this should be a driver. You initialize it quite late and it
is required by other drivers (cpufreq, devfreq), not by core.

I would also prefer it to be slightly more generic. I mean, now you
get the tables from "samsung,exynos-asv-v1" node and then, depending
on many different compatibles, you do this or that. If it is
samsung,exynos5800, you call 542x code. If it is hardkernel, you
assume it is bin2. This will be not easily portable to other Exynos
chips and other boards (e.g. you need to update the driver for new
board which is forced to be in bin2).

Instead all this information should come from chipid and/or DT. I
could imagine that the device binds to ASV node and parses its
properties. Optionally it could bind to chipid... but then you would
have two devices on same node. Then depending on the of_device_id
match, you have all necessary static configuration data (the same as
PMU driver or all other typical drivers). Dynamic data you read from
chip id.

There are some comments below but I guess the code will change a lot
so there is no point to do through code review.

On Thu, 4 Apr 2019 at 19:22, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> The Adaptive Supply Voltage (ASV) on Exynos SoCs is a technique of adjusting
> operating points of devices in order to better match actual capabilities
> of the hardware and optimize power consumption.
>
> This patch adds common code for parsing the ASV tables from devicetree
> and updating CPU OPPs.
>
> Also support for Exynos5422/5800 SoC is added, the Exynos5422 specific part
> of the patch 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>
> ---
>  drivers/soc/samsung/Kconfig          |  11 ++
>  drivers/soc/samsung/Makefile         |   3 +
>  drivers/soc/samsung/exynos-asv.c     | 279 +++++++++++++++++++++++++++
>  drivers/soc/samsung/exynos-asv.h     | 114 +++++++++++
>  drivers/soc/samsung/exynos5422-asv.c | 209 ++++++++++++++++++++
>  drivers/soc/samsung/exynos5422-asv.h |  25 +++
>  6 files changed, 641 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 2905f5262197..4d121984f71a 100644
> --- a/drivers/soc/samsung/Kconfig
> +++ b/drivers/soc/samsung/Kconfig
> @@ -7,6 +7,17 @@ menuconfig SOC_SAMSUNG
>
>  if SOC_SAMSUNG
>
> +config EXYNOS_ASV
> +       bool "Exynos Adaptive Supply Voltage support" if COMPILE_TEST
> +       depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)

Why it cannot be compile tested outside of ARM? The PMU driver has
this constraint because of asm/cputype.h but you probably do not need
it.

> +       depends on EXYNOS_CHIPID
> +       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..60532c7eb3aa
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-asv.c
> @@ -0,0 +1,279 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2018 - 2019 Samsung Electronics Co., Ltd.

Since it is first publish date, copyright should be only 2019....
unless this was copied from hardkernel repo but then original
copyright should be included as well.

> + *           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/of.h>
> +#include <linux/pm_opp.h>
> +#include <linux/slab.h>
> +
> +#include "exynos-asv.h"
> +#include "exynos5422-asv.h"
> +#include "exynos5433-asv.h"
> +
> +#ifndef MHZ

There is no existing definition, so just #define. It will also easily
be noticed by preprocessor if someone adds such define later.

> +#define MHZ 1000000U
> +#endif
> +
> +static struct exynos_asv *exynos_asv;

Please avoid it. This should be a driver which registers it's state as drvdata.

> +
> +int exynos_asv_parse_of_table(struct device_node *node,

A nit: node->np because it is more popular. And shorter.

> +                             struct exynos_asv_table *table,
> +                             int index)
> +{
> +       u32 table_size, table_id = 0;
> +       unsigned int len1, len2 = 0;

Please move the initialized variables to separate lines (first probably).

> +       unsigned int num_cols, num_rows;
> +       u32 tmp[20];
> +       u32 *buf;
> +       int ret;
> +
> +       ret = of_property_read_u32(node, "samsung,asv-table-id",
> +                                  &table_id);
> +       if (ret < 0) {
> +               pr_err("ASV: Missing table id in %pOF\n", node);
> +               return ret;
> +       }
> +       table->id = table_id;
> +
> +       if (index >= 0 && asv_table_to_index(table_id) != index)
> +               return -EBADR;
> +
> +       ret = of_property_read_u32_array(node, "samsung,asv-table-size",
> +                                        tmp, 2);
> +       if (ret < 0)
> +               return ret;
> +
> +       num_rows = tmp[0];
> +       num_cols = tmp[1];
> +       if (num_rows > EXYNOS_ASV_MAX_LEVELS ||
> +           num_cols > (EXYNOS_ASV_MAX_GROUPS + 1)) {
> +               pr_err("ASV: Unsupported ASV table size (%d x %d)\n",
> +                      num_rows, num_cols);
> +               return -EINVAL;
> +       }
> +
> +       table_size = num_rows * num_cols;
> +       buf = kcalloc(table_size, sizeof(u32), GFP_KERNEL);
> +       if (!buf)
> +               return -ENOMEM;
> +
> +       ret = of_property_read_variable_u32_array(node, "samsung,asv-data",
> +                                                 buf, 0, table_size);
> +       if (ret < 0)
> +               goto err_free_buf;
> +
> +       len1 = ret;
> +
> +       if (ret < table_size) {
> +               u32 *dst, *src;
> +               ret = of_property_read_variable_u32_array(node,
> +                                               "samsung,asv-common-data",
> +                                               (u32 *)tmp, 0,
> +                                               ARRAY_SIZE(tmp));
> +               if (ret < 0) {
> +                       pr_err("ASV: Not enough data for table #%x (%d x %d)\n",
> +                              table_id, num_rows, num_cols);
> +                       goto err_free_buf;
> +               }
> +               len2 = ret;
> +
> +               if (len1 + ((len2 / 2) * num_cols) > table_size) {
> +                       pr_err("ASV: Incorrect table %#x definition\n",
> +                              table_id);
> +                               ret = -EINVAL;
> +                               goto err_free_buf;
> +                       }
> +               /*
> +                * Copy data common to all ASV levels to first and second column
> +                * in the main buffer.  We don't replicate data to further
> +                * columns, instead they are left initialized to 0 (invalid,
> +                * unused frequency value).  We assume that users of the table
> +                * will refer to voltage data in column 1 if 0 is encountered
> +                * in any further column (2, 3,...).
> +                */
> +               dst = buf + len1;
> +               src = tmp;
> +
> +               while (len2 >= 2) {
> +                       memcpy(dst, src, 2 * sizeof(u32));
> +                       dst += num_cols;
> +                       src += 2;
> +                       len2 -= 2;
> +               }
> +       }
> +
> +       table->num_cols = num_cols;
> +       table->num_rows = num_rows;
> +       table->buf = buf;
> +       return 0;
> +
> +err_free_buf:
> +       kfree(buf);
> +       return ret;
> +}
> +
> +int exynos_asv_parse_cpu_tables(struct exynos_asv *asv,        struct device_node *np,
> +                               int table_index)
> +{
> +       struct exynos_asv_subsys *subsys;
> +       struct exynos_asv_table table;
> +       struct device_node *child;
> +       int ret;
> +
> +       for_each_child_of_node(np, child) {
> +               ret = exynos_asv_parse_of_table(child, &table, table_index);
> +               if (ret < 0) {
> +                       if (ret == -EBADR)
> +                               continue;
> +                       of_node_put(child);
> +                       return ret;
> +               }
> +
> +               pr_debug("%s: Matching table: id: %#x at %pOF\n",
> +                        __func__, table.id, child);
> +
> +               switch(asv_table_to_subsys_id(table.id)) {
> +               case EXYNOS_ASV_SUBSYS_ID_ARM:
> +                       subsys = &asv->arm;
> +                       break;
> +               case EXYNOS_ASV_SUBSYS_ID_KFC:
> +                       subsys = &asv->kfc;
> +                       break;
> +               default:
> +                       of_node_put(child);
> +                       return -EINVAL;
> +               }
> +
> +               subsys->num_asv_levels = table.num_rows;
> +               subsys->num_asv_groups = table.num_cols - 1;
> +               subsys->table = table;
> +               subsys->id = asv_table_to_subsys_id(table.id);
> +       }
> +
> +       return 0;
> +}
> +
> +static int exynos_asv_update_cpu_opps(struct device *cpu)
> +{
> +       struct exynos_asv_subsys *subsys = NULL;
> +       struct dev_pm_opp *opp;
> +       unsigned int opp_freq;
> +       int i;
> +
> +       if (of_device_is_compatible(cpu->of_node,
> +                                   exynos_asv->arm.cpu_dt_compat))
> +               subsys = &exynos_asv->arm;
> +       else if (of_device_is_compatible(cpu->of_node,
> +                                        exynos_asv->kfc.cpu_dt_compat))
> +               subsys = &exynos_asv->kfc;
> +
> +       if (!subsys)
> +               return -EINVAL;
> +
> +       for (i = 0; i < subsys->num_asv_levels; i++) {
> +               unsigned int new_voltage;
> +               unsigned int voltage;
> +               int timeout = 1000;
> +               int err;
> +
> +               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)) {
> +                       pr_info("%s cpu%d opp%d, freq: %u missing\n",
> +                               __func__, cpu->id, i, opp_freq);
> +
> +                       continue;
> +               }
> +
> +               voltage = dev_pm_opp_get_voltage(opp);
> +               new_voltage = exynos_asv->opp_get_voltage(subsys, i, voltage);
> +               dev_pm_opp_put(opp);
> +
> +               opp_freq *= MHZ;
> +               dev_pm_opp_remove(cpu, opp_freq);
> +
> +               while (--timeout) {
> +                       opp = dev_pm_opp_find_freq_exact(cpu, opp_freq, true);
> +                       if (IS_ERR(opp))
> +                               break;
> +                       dev_pm_opp_put(opp);
> +                       msleep(1);
> +               }
> +
> +               err = dev_pm_opp_add(cpu, opp_freq, new_voltage);
> +               if (err < 0)
> +                       pr_err("%s: Failed to add OPP %u Hz/%u uV for cpu%d\n",
> +                              __func__, opp_freq, new_voltage, cpu->id);
> +       }
> +
> +       return 0;
> +}
> +
> +static int exynos_asv_update_opps(void)
> +{
> +       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(cpu);
> +                       if (ret < 0)
> +                               pr_err("%s: Couldn't udate OPPs for cpu%d\n",
> +                                      __func__, cpuid);
> +               }
> +
> +               dev_pm_opp_put_opp_table(opp_table);
> +       }
> +
> +       return  0;
> +}
> +
> +static int __init exynos_asv_init(void)
> +{
> +       int ret;
> +
> +       exynos_asv = kcalloc(1, sizeof(struct exynos_asv), GFP_KERNEL);

sizeof(*exynos_asv)

> +       if (!exynos_asv)
> +               return -ENOMEM;
> +
> +       if (of_machine_is_compatible("samsung,exynos5800") ||
> +           of_machine_is_compatible("samsung,exynos5420"))
> +               ret = exynos5422_asv_init(exynos_asv);

No, as I mentioned at beginning, bind to specific node and
differentiate behavior based on of_device_id.

> +       else
> +               return 0;
> +
> +       if (ret < 0)
> +               return ret;
> +
> +       ret = exynos_asv_update_opps();
> +
> +       if (exynos_asv->release)
> +               exynos_asv->release(exynos_asv);
> +
> +       return ret;
> +}
> +late_initcall(exynos_asv_init)
> diff --git a/drivers/soc/samsung/exynos-asv.h b/drivers/soc/samsung/exynos-asv.h
> new file mode 100644
> index 000000000000..3444b361e5e3
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-asv.h
> @@ -0,0 +1,114 @@
> +// SPDX-License-Identifier: GPL-2.0

In headers this goes with /* */

> +/*
> + * Copyright (c) 2018 - 2019 Samsung Electronics Co., Ltd.

Date.

> + *           http://www.samsung.com/
> + * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
> + *
> + * Samsung Exynos SoC Adaptive Supply Voltage support
> + */
> +#ifndef __EXYNOS_ASV_H
> +#define __EXYNOS_ASV_H
> +
> +#define EXYNOS_ASV_MAX_GROUPS          16
> +#define EXYNOS_ASV_MAX_LEVELS          24
> +
> +#define EXYNOS_ASV_TABLE_INDEX_MASK    (0xff)
> +#define EXYNOS_ASV_SUBSYS_ID_MASK      (0xff << 8)
> +
> +#define asv_table_to_subsys_id(_id)    ((_id >> 8) & 0xff)
> +#define asv_table_to_index(_id)                ((_id) & 0xff)
> +
> +#define EXYNOS_ASV_SUBSYS_ID_ARM       0x0
> +#define EXYNOS_ASV_SUBSYS_ID_EGL       EXYNOS_ASV_SUBSYS_ID_ARM
> +#define EXYNOS_ASV_SUBSYS_ID_KFC       0x1
> +#define EXYNOS_ASV_SUBSYS_ID_INT       0x2
> +#define EXYNOS_ASV_SUBSYS_ID_MIF       0x3
> +#define EXYNOS_ASV_SUBSYS_ID_G3D       0x4
> +#define EXYNOS_ASV_SUBSYS_ID_CAM       0x5
> +#define EXYNOS_ASV_SUBSYS_ID_MAX       0x6
> +
> +struct device_node;
> +
> +/* 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;
> +       unsigned int id;
> +       u32 *buf;
> +};
> +
> +struct exynos_asv_subsys {
> +       int id;
> +       char *cpu_dt_compat;
> +
> +       unsigned int base_volt;
> +       unsigned int num_asv_levels;
> +       unsigned int num_asv_groups;
> +       unsigned int offset_volt_h;
> +       unsigned int offset_volt_l;
> +       struct exynos_asv_table table;
> +};
> +
> +struct exynos_asv {
> +       struct device_node *chipid_node;
> +       struct exynos_asv_subsys arm;
> +       struct exynos_asv_subsys kfc;
> +
> +       int (*opp_get_voltage)(struct exynos_asv_subsys *subs, int level,
> +                              unsigned int voltage);
> +       void (*release)(struct exynos_asv *asv);
> +
> +       unsigned int group;
> +       unsigned int table;
> +
> +       /* TODO: Move member fields below to SoC type specific data structure */
> +       unsigned int is_bin2;
> +       unsigned int is_special_lot;
> +};
> +
> +static inline u32 __exynos_asv_get_item(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_frequency(struct exynos_asv_subsys *subsys,
> +                                              unsigned int index)
> +{
> +       return __exynos_asv_get_item(&subsys->table, index, 0);
> +}

Empty line needed.

> +/**
> + * exynos_asv_parse_of_table - Parse ASV table from devicetree
> + *
> + * @node: DT node containing the table
> + * @table: The parsed table data
> + * @index: Used to select table with specific index to parse, if >= 0.
> + *         This argument is ignored if the value is less than 0.
> + *
> + * Returns: 0 on success, or negative value on failure. EBADR is returned
> + * when @index is >= 0 but the index value of the parsed table ID is different
> + * than @index.
> + */
> +int exynos_asv_parse_of_table(struct device_node *node,
> +                             struct exynos_asv_table *table,
> +                             int index);
> +
> +/**
> + * exynos_asv_parse_cpu_tables - Parse ARM and KFC ASV tables from DT
> + *
> + * @asv: data structure to store the parsed data to
> + * @node: DT node containing the tables
> + * @index: Used to select table with specific index to parse, if >= 0.
> + *         This argument is ignored if the value is less than 0.
> + *
> + * Returns: 0 on success, or negative value on failure.
> + */
> +int exynos_asv_parse_cpu_tables(struct exynos_asv *asv,        struct device_node *np,
> +                               int table_index);
> +
> +#endif /* __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..f0b7bdd873a9
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos5422-asv.c
> @@ -0,0 +1,209 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2018 - 2019 Samsung Electronics Co., Ltd.

The same - copyright date.

> + *           http://www.samsung.com/
> + *
> + * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/of.h>
> +#include <linux/slab.h>
> +
> +#include "exynos-asv.h"
> +#include "exynos-chipid.h"
> +
> +#define EXYNOS5422_NUM_ASV_GROUPS      14
> +
> +static struct exynos_asv *exynos_asv;
> +
> +static int exynos5422_asv_get_table(void)
> +{
> +       unsigned int reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
> +
> +       return (reg >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
> +}
> +
> +static int exynos5422_asv_check_bin2(void)
> +{
> +       unsigned int reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
> +
> +       return (reg >> EXYNOS5422_BIN2_OFFSET) & EXYNOS5422_BIN2_MASK;
> +}
> +
> +static bool exynos5422_asv_check_lot_id(void)
> +{
> +       unsigned int reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
> +
> +       return ((reg >> EXYNOS5422_USESG_OFFSET) & EXYNOS5422_USESG_MASK);
> +}
> +
> +static const struct asv_limit_entry __asv_limits[EXYNOS5422_NUM_ASV_GROUPS] = {
> +       { 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 = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
> +       unsigned int auxi_reg = exynos_chipid_read(EXYNOS_CHIPID_AUX_INFO);
> +       int hpm, ids, i;
> +
> +       if (asv->is_special_lot) {
> +               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 < EXYNOS5422_NUM_ASV_GROUPS; i++) {
> +               if (ids <= __asv_limits[i].ids)
> +                       break;
> +               if (hpm <= __asv_limits[i].hpm)
> +                       break;
> +       }
> +       if (i < EXYNOS5422_NUM_ASV_GROUPS)
> +               return i;
> +
> +       return 0;
> +}
> +
> +static int __asv_offset_voltage(unsigned int index)
> +{
> +       static const unsigned int offset_table[] = { 12500, 50000, 25000 };
> +
> +       if (index == 0 || index > 3)
> +               return 0;
> +
> +       return offset_table[index - 1];
> +}
> +
> +static void exynos5422_asv_offset_voltage_setup(struct exynos_asv *asv)
> +{
> +       struct exynos_asv_subsys *subsys;
> +       unsigned int reg, value;
> +
> +       reg = exynos_chipid_read(EXYNOS_CHIPID_AUX_INFO);
> +
> +       /* ARM offset voltage setup */
> +       subsys = &asv->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->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->num_asv_levels)
> +               return volt;
> +
> +       asv_volt = __exynos_asv_get_item(&subsys->table, level,
> +                                        exynos_asv->group + 1);
> +       if (asv_volt == 0 && exynos_asv->group > 1)
> +               asv_volt = __exynos_asv_get_item(&subsys->table, level, 1);
> +
> +       if (volt > subsys->base_volt)
> +               asv_volt += subsys->offset_volt_h;
> +       else
> +               asv_volt += subsys->offset_volt_l;
> +
> +       return asv_volt;
> +}
> +
> +static void __init exynos5422_asv_release(struct exynos_asv *asv)
> +{
> +       kfree(asv->arm.table.buf);
> +       asv->arm.table.buf = NULL;
> +       kfree(asv->kfc.table.buf);
> +       asv->kfc.table.buf = NULL;
> +}
> +
> +int __init exynos5422_asv_init(struct exynos_asv *asv)
> +{
> +       struct device_node *node;
> +       unsigned int table_index;
> +       int ret;
> +
> +       exynos_asv = asv;
> +
> +       asv->is_bin2 = exynos5422_asv_check_bin2();
> +       asv->is_special_lot = exynos5422_asv_check_lot_id();
> +
> +       if (of_machine_is_compatible("hardkernel,odroid-xu3-lite")) {
> +               asv->is_bin2 = true;
> +               asv->is_special_lot = false;
> +       }
> +
> +       asv->group = exynos5422_asv_get_group(asv);
> +       asv->table = exynos5422_asv_get_table();
> +
> +       exynos5422_asv_offset_voltage_setup(asv);
> +
> +       node = of_find_compatible_node(NULL, NULL, "samsung,exynos-asv-v1");
> +       if (!node)
> +               return -ENODEV;
> +
> +       if (!asv->is_bin2) {
> +               if (asv->table == 2 || asv->table == 3)
> +                       table_index = asv->table;
> +               else
> +                       table_index = 0;
> +       } else {
> +               table_index = 4;
> +       }
> +
> +       ret = exynos_asv_parse_cpu_tables(asv, node, table_index);
> +       of_node_put(node);
> +       if (ret < 0)
> +               return ret;
> +
> +       asv->arm.cpu_dt_compat = "arm,cortex-a15";
> +       asv->kfc.cpu_dt_compat = "arm,cortex-a7";
> +
> +       asv->opp_get_voltage = exynos5422_asv_opp_get_voltage;
> +       asv->release = exynos5422_asv_release;
> +
> +       return ret;
> +}
> diff --git a/drivers/soc/samsung/exynos5422-asv.h b/drivers/soc/samsung/exynos5422-asv.h
> new file mode 100644
> index 000000000000..f0d9107d6d0a
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos5422-asv.h
> @@ -0,0 +1,25 @@
> +// SPDX-License-Identifier: GPL-2.0

/**/ needed

> +/*
> + * Copyright (c) 2018 - 2019 Samsung Electronics Co., Ltd.

Date

Best regards,
Krzysztof

> + *           http://www.samsung.com/
> + *
> + * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
> + */
> +
> +#ifndef __EXYNOS5422_ASV_H
> +#define __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 /* __EXYNOS5422_ASV_H */
> --
> 2.17.1
>

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

* Re: [PATCH RFC 4/8] soc: samsung: Add Exynos Adaptive Supply Voltage driver
  2019-04-05 10:24       ` Krzysztof Kozlowski
@ 2019-04-09 17:40         ` Sylwester Nawrocki
  0 siblings, 0 replies; 22+ messages in thread
From: Sylwester Nawrocki @ 2019-04-09 17:40 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: kgene, robh+dt, mark.rutland, Chanwoo Choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, Bartłomiej Żołnierkiewicz,
	Marek Szyprowski

On 4/5/19 12:24, Krzysztof Kozlowski wrote:
> I have a lot of minor nits all around and few more architecture-like comments.
> 
> I think this should be a driver. You initialize it quite late and it
> is required by other drivers (cpufreq, devfreq), not by core.

Thanks for your comments, it helped me to finally get around and convert
this code to proper driver.  The advantage is that it can be more 
reliably ensured that the ASV driver updates OPPs properly after they
have been parsed from DT by cpufreq-dt or other drivers.  And if we 
add support for the Body Bias through regulator API it would be easier
to acquire the regulator resource, i.e. deferred probing could ensure 
proper driver probe ordering.
 
> I would also prefer it to be slightly more generic. I mean, now you
> get the tables from "samsung,exynos-asv-v1" node and then, depending
> on many different compatibles, you do this or that. If it is
> samsung,exynos5800, you call 542x code. If it is hardkernel, you
> assume it is bin2. This will be not easily portable to other Exynos
> chips and other boards (e.g. you need to update the driver for new
> board which is forced to be in bin2).

The bin2 part for Odroid XU3 Lite is really a hack and I wish it was 
not there. It seems there is not enough data fused in the SoC to 
properly detect chips used on XU3 Lite. 

> Instead all this information should come from chipid and/or DT. I

Perhaps we could try to be more generic but I'm afraid in practice 
we will need to have some logic coded in the driver per each SoC type 
anyway. We could probably add DT property in chipid node to provide 
missing data that is normally read from CHIPID registers. The BIN2
flag is really about forcing specific ASV table. The "special group"
quirk means different thing for each SoC type, in case of exynos5422
it's selecting different method of the ASV group decoding.
It's a bit hard to try to put anything in DT with sparse or missing
documentation of such quirks.

> could imagine that the device binds to ASV node and parses its
> properties. Optionally it could bind to chipid... but then you would

The ASV node on older SoCs doesn't correspond to real hardware so
we shouldn't try to bind drivers to it I'd say. The chipid node 
seems a better alternative to me.
I'm thinking about dropping 'asv' node completely. But then the 
table sub-nodes would need to be put into chipid node.

> have two devices on same node. Then depending on the of_device_id
> match, you have all necessary static configuration data (the same as
> PMU driver or all other typical drivers). Dynamic data you read from
> chip id.

I will post next version of the patch series and we could continue
discussion from there, I have switched to of_device_id matching but
left per SoC init function.

> On Thu, 4 Apr 2019 at 19:22, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>>
>> The Adaptive Supply Voltage (ASV) on Exynos SoCs is a technique of adjusting
>> operating points of devices in order to better match actual capabilities
>> of the hardware and optimize power consumption.
>>
>> This patch adds common code for parsing the ASV tables from devicetree
>> and updating CPU OPPs.
>>
>> Also support for Exynos5422/5800 SoC is added, the Exynos5422 specific part
>> of the patch 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>
>> ---

>> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
>> index 2905f5262197..4d121984f71a 100644
>> --- a/drivers/soc/samsung/Kconfig
>> +++ b/drivers/soc/samsung/Kconfig
>> @@ -7,6 +7,17 @@ menuconfig SOC_SAMSUNG
>>
>>  if SOC_SAMSUNG
>>
>> +config EXYNOS_ASV
>> +       bool "Exynos Adaptive Supply Voltage support" if COMPILE_TEST
>> +       depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
> 
> Why it cannot be compile tested outside of ARM? The PMU driver has
> this constraint because of asm/cputype.h but you probably do not need
> it.

Yes, it's not needed, I will drop the (ARM || ARM64) part in next iteration. 

>> diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c
>> new file mode 100644
>> index 000000000000..60532c7eb3aa
>> --- /dev/null
>> +++ b/drivers/soc/samsung/exynos-asv.c
>> @@ -0,0 +1,279 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (c) 2018 - 2019 Samsung Electronics Co., Ltd.
> 
> Since it is first publish date, copyright should be only 2019....
> unless this was copied from hardkernel repo but then original
> copyright should be included as well.

I will change it to 2019. I have written code in this file from 
scratch by myself. Some reused code is in exynos5422-asv.c, I will 
copy the original copyright notice there, however it is same 
Samsung's copyright notice, only with 2012 date.

-- 
Regards,
Sylwester

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

* Re: [PATCH RFC 8/8] ARM: dts: exynos: Add ASV tables for exynos5422/5800
  2019-04-04 17:17     ` [PATCH RFC 8/8] ARM: dts: exynos: Add ASV tables for exynos5422/5800 Sylwester Nawrocki
@ 2019-04-11  7:39       ` Anand Moon
  2019-04-11  8:50         ` Willy Wolff
  0 siblings, 1 reply; 22+ messages in thread
From: Anand Moon @ 2019-04-11  7:39 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: Krzysztof Kozlowski, Kukjin Kim, Rob Herring, Mark Rutland,
	Chanwoo Choi, myungjoo.ham, linux-samsung-soc, Linux Kernel,
	linux-arm-kernel, devicetree, Pankaj Dubey,
	Bartlomiej Zolnierkiewicz, Marek Szyprowski

Hi Sylwester,

As per my knowledge HK soc introduce this table to support
overclocking of cpufreq for Odroid XU3 XU4 family for boards.

ARM Cortex-A15 Quad CPU (Eagle) 1800 to 2000
ARM Cortex-A7 Quard CPU (Kingfisher) 1400 to 1500

For Exynos5422  below table
asv-table-[0-3]  AVS range from 200 to 2100
asv-table-[100-103] AVS range from 200 to 1500.

Are these setting stable for this board to cover clock the cpu now.

Can you also enable support for this clk-exynos5420.c
For example exynos5800_eglclk_d and exynos5420_kfcclk_d table.

Also can you update exynos5420.dtsi  following opp table
For example cluster_a15_opp_table and cluster_a7_opp_table opt binding.

To make this work synchronously with AVS.

Best Regards
-Anand

On Thu, 4 Apr 2019 at 22:55, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> This patch ASV (Adaptive Supply Voltage) table entries for
> Exynos5422/5800 SoC.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  arch/arm/boot/dts/exynos5.dtsi    |   2 +-
>  arch/arm/boot/dts/exynos5800.dtsi | 207 ++++++++++++++++++++++++++++++
>  2 files changed, 208 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi
> index 67f9b4504a42..22eb951c614c 100644
> --- a/arch/arm/boot/dts/exynos5.dtsi
> +++ b/arch/arm/boot/dts/exynos5.dtsi
> @@ -35,7 +35,7 @@
>                 #size-cells = <1>;
>                 ranges;
>
> -               chipid@10000000 {
> +               chipid: chipid@10000000 {
>                         compatible = "samsung,exynos4210-chipid";
>                         reg = <0x10000000 0x100>;
>                 };
> diff --git a/arch/arm/boot/dts/exynos5800.dtsi b/arch/arm/boot/dts/exynos5800.dtsi
> index 57d3b319fd65..5358865f5c0b 100644
> --- a/arch/arm/boot/dts/exynos5800.dtsi
> +++ b/arch/arm/boot/dts/exynos5800.dtsi
> @@ -16,6 +16,213 @@
>         compatible = "samsung,exynos5800", "samsung,exynos5";
>  };
>
> +&chipid {
> +       asv {
> +               compatible = "samsung,exynos-asv-v1";
> +               asv-table-0 {
> +                       /* ARM 0, 1 */
> +                       samsung,asv-table-size = <20 15>;
> +                       samsung,asv-table-id = <0x0>;
> +                       samsung,asv-data =
> +                                     /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12   ASV13 */
> +                               <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>;
> +                                                    /* ASV0...13 */
> +                       samsung,asv-common-data = <700 900000>,
> +                                                 <600 900000>,
> +                                                 <500 900000>,
> +                                                 <400 900000>,
> +                                                 <300 900000>,
> +                                                 <200 900000>;
> +               };
> +               asv-table-2 {
> +                       /* ARM 2 */
> +                       samsung,asv-table-size = <20 15>;
> +                       samsung,asv-table-id = <0x2>;
> +                       samsung,asv-data =
> +                                     /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
> +                               <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>;
> +                                                    /* ASV0...13 */
> +                       samsung,asv-common-data = <700 900000>,
> +                                                 <600 900000>,
> +                                                 <500 900000>,
> +                                                 <400 900000>,
> +                                                 <300 900000>,
> +                                                 <200 900000>;
> +               };
> +               asv-table-3 {
> +                       /* ARM 3 */
> +                       samsung,asv-table-size = <20 15>;
> +                       samsung,asv-table-id = <0x3>;
> +                       samsung,asv-data =
> +                                     /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
> +                               <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>;
> +                                                    /* ASV0...13 */
> +                       samsung,asv-common-data = <700 900000>,
> +                                                 <600 900000>,
> +                                                 <500 900000>,
> +                                                 <400 900000>,
> +                                                 <300 900000>,
> +                                                 <200 900000>;
> +               };
> +
> +               asv-table-4 {
> +                       /* ARM BIN2 */
> +                       samsung,asv-table-size = <17 15>;
> +                       samsung,asv-table-id = <0x4>;
> +                       samsung,asv-data =
> +                                     /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
> +                               <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>;
> +                                                      /* ASV0...13 */
> +                       samsung,asv-common-data = <600 900000>,
> +                                                 <500 900000>,
> +                                                 <400 900000>,
> +                                                 <300 900000>,
> +                                                 <200 900000>;
> +               };
> +
> +
> +               asv-table-100 {
> +                       /* KFC 0, 1 */
> +                       samsung,asv-table-size = <14 15>;
> +                       samsung,asv-table-id = <0x100>;
> +                       samsung,asv-data =
> +                                     /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
> +                               <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>;
> +                                                     /* ASV0...13 */
> +                       samsung,asv-common-data = <400 900000>,
> +                                                 <300 900000>,
> +                                                 <200 900000>;
> +               };
> +
> +               asv-table-102 {
> +                       /* KFC 2 */
> +                       samsung,asv-table-size = <14 15>;
> +                       samsung,asv-table-id = <0x102>;
> +                       samsung,asv-data =
> +                                     /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
> +                               <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>;
> +                                                     /* ASV0...13 */
> +                       samsung,asv-common-data = <400 900000>,
> +                                                 <300 900000>,
> +                                                 <200 900000>;
> +               };
> +
> +               asv-table-103 {
> +                       /* KFC 3 */
> +                       samsung,asv-table-size = <14 15>;
> +                       samsung,asv-table-id = <0x103>;
> +                       samsung,asv-data =
> +                                     /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
> +                               <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>;
> +                                                     /* ASV0...13 */
> +                       samsung,asv-common-data = <400 900000>,
> +                                                 <300 900000>,
> +                                                 <200 900000>;
> +               };
> +
> +               asv-table-104 {
> +                       /* KFC BIN2 */
> +                       samsung,asv-table-size = <12 15>;
> +                       samsung,asv-table-id = <0x104>;
> +                       samsung,asv-data =
> +                                     /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
> +                               <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>;
> +                                                     /* ASV0...13 */
> +                       samsung,asv-common-data = <300 900000>,
> +                                                 <200 900000>;
> +               };
> +       };
> +};
> +
>  &clock {
>         compatible = "samsung,exynos5800-clock";
>  };
> --
> 2.17.1
>

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

* Re: [PATCH RFC 8/8] ARM: dts: exynos: Add ASV tables for exynos5422/5800
  2019-04-11  7:39       ` Anand Moon
@ 2019-04-11  8:50         ` Willy Wolff
  0 siblings, 0 replies; 22+ messages in thread
From: Willy Wolff @ 2019-04-11  8:50 UTC (permalink / raw)
  To: Anand Moon
  Cc: Sylwester Nawrocki, Krzysztof Kozlowski, Kukjin Kim, Rob Herring,
	Mark Rutland, Chanwoo Choi, myungjoo.ham, linux-samsung-soc,
	Linux Kernel, linux-arm-kernel, devicetree, Pankaj Dubey,
	Bartlomiej Zolnierkiewicz, Marek Szyprowski

Hi Anand,

I'm using this frequencies on the board since 3 years, without any stability
issues. The kind of worklaod used is intensive CPU-bound benchmarks running 
for 20 mins at least in order to stress the system, I'm studying schedulability
under high thermal constraints.

So, I would say these frequencies are safe by experience.

Best Regards,
Willy


On Thu, Apr 11, 2019 at 01:09:04PM +0530, Anand Moon wrote:
> Hi Sylwester,
> 
> As per my knowledge HK soc introduce this table to support
> overclocking of cpufreq for Odroid XU3 XU4 family for boards.
> 
> ARM Cortex-A15 Quad CPU (Eagle) 1800 to 2000
> ARM Cortex-A7 Quard CPU (Kingfisher) 1400 to 1500
> 
> For Exynos5422  below table
> asv-table-[0-3]  AVS range from 200 to 2100
> asv-table-[100-103] AVS range from 200 to 1500.
> 
> Are these setting stable for this board to cover clock the cpu now.
> 
> Can you also enable support for this clk-exynos5420.c
> For example exynos5800_eglclk_d and exynos5420_kfcclk_d table.
> 
> Also can you update exynos5420.dtsi  following opp table
> For example cluster_a15_opp_table and cluster_a7_opp_table opt binding.
> 
> To make this work synchronously with AVS.
> 
> Best Regards
> -Anand
> 
> On Thu, 4 Apr 2019 at 22:55, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
> >
> > This patch ASV (Adaptive Supply Voltage) table entries for
> > Exynos5422/5800 SoC.
> >
> > Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> > ---
> >  arch/arm/boot/dts/exynos5.dtsi    |   2 +-
> >  arch/arm/boot/dts/exynos5800.dtsi | 207 ++++++++++++++++++++++++++++++
> >  2 files changed, 208 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi
> > index 67f9b4504a42..22eb951c614c 100644
> > --- a/arch/arm/boot/dts/exynos5.dtsi
> > +++ b/arch/arm/boot/dts/exynos5.dtsi
> > @@ -35,7 +35,7 @@
> >                 #size-cells = <1>;
> >                 ranges;
> >
> > -               chipid@10000000 {
> > +               chipid: chipid@10000000 {
> >                         compatible = "samsung,exynos4210-chipid";
> >                         reg = <0x10000000 0x100>;
> >                 };
> > diff --git a/arch/arm/boot/dts/exynos5800.dtsi b/arch/arm/boot/dts/exynos5800.dtsi
> > index 57d3b319fd65..5358865f5c0b 100644
> > --- a/arch/arm/boot/dts/exynos5800.dtsi
> > +++ b/arch/arm/boot/dts/exynos5800.dtsi
> > @@ -16,6 +16,213 @@
> >         compatible = "samsung,exynos5800", "samsung,exynos5";
> >  };
> >
> > +&chipid {
> > +       asv {
> > +               compatible = "samsung,exynos-asv-v1";
> > +               asv-table-0 {
> > +                       /* ARM 0, 1 */
> > +                       samsung,asv-table-size = <20 15>;
> > +                       samsung,asv-table-id = <0x0>;
> > +                       samsung,asv-data =
> > +                                     /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12   ASV13 */
> > +                               <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>;
> > +                                                    /* ASV0...13 */
> > +                       samsung,asv-common-data = <700 900000>,
> > +                                                 <600 900000>,
> > +                                                 <500 900000>,
> > +                                                 <400 900000>,
> > +                                                 <300 900000>,
> > +                                                 <200 900000>;
> > +               };
> > +               asv-table-2 {
> > +                       /* ARM 2 */
> > +                       samsung,asv-table-size = <20 15>;
> > +                       samsung,asv-table-id = <0x2>;
> > +                       samsung,asv-data =
> > +                                     /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
> > +                               <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>;
> > +                                                    /* ASV0...13 */
> > +                       samsung,asv-common-data = <700 900000>,
> > +                                                 <600 900000>,
> > +                                                 <500 900000>,
> > +                                                 <400 900000>,
> > +                                                 <300 900000>,
> > +                                                 <200 900000>;
> > +               };
> > +               asv-table-3 {
> > +                       /* ARM 3 */
> > +                       samsung,asv-table-size = <20 15>;
> > +                       samsung,asv-table-id = <0x3>;
> > +                       samsung,asv-data =
> > +                                     /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
> > +                               <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>;
> > +                                                    /* ASV0...13 */
> > +                       samsung,asv-common-data = <700 900000>,
> > +                                                 <600 900000>,
> > +                                                 <500 900000>,
> > +                                                 <400 900000>,
> > +                                                 <300 900000>,
> > +                                                 <200 900000>;
> > +               };
> > +
> > +               asv-table-4 {
> > +                       /* ARM BIN2 */
> > +                       samsung,asv-table-size = <17 15>;
> > +                       samsung,asv-table-id = <0x4>;
> > +                       samsung,asv-data =
> > +                                     /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
> > +                               <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>;
> > +                                                      /* ASV0...13 */
> > +                       samsung,asv-common-data = <600 900000>,
> > +                                                 <500 900000>,
> > +                                                 <400 900000>,
> > +                                                 <300 900000>,
> > +                                                 <200 900000>;
> > +               };
> > +
> > +
> > +               asv-table-100 {
> > +                       /* KFC 0, 1 */
> > +                       samsung,asv-table-size = <14 15>;
> > +                       samsung,asv-table-id = <0x100>;
> > +                       samsung,asv-data =
> > +                                     /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
> > +                               <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>;
> > +                                                     /* ASV0...13 */
> > +                       samsung,asv-common-data = <400 900000>,
> > +                                                 <300 900000>,
> > +                                                 <200 900000>;
> > +               };
> > +
> > +               asv-table-102 {
> > +                       /* KFC 2 */
> > +                       samsung,asv-table-size = <14 15>;
> > +                       samsung,asv-table-id = <0x102>;
> > +                       samsung,asv-data =
> > +                                     /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
> > +                               <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>;
> > +                                                     /* ASV0...13 */
> > +                       samsung,asv-common-data = <400 900000>,
> > +                                                 <300 900000>,
> > +                                                 <200 900000>;
> > +               };
> > +
> > +               asv-table-103 {
> > +                       /* KFC 3 */
> > +                       samsung,asv-table-size = <14 15>;
> > +                       samsung,asv-table-id = <0x103>;
> > +                       samsung,asv-data =
> > +                                     /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
> > +                               <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>;
> > +                                                     /* ASV0...13 */
> > +                       samsung,asv-common-data = <400 900000>,
> > +                                                 <300 900000>,
> > +                                                 <200 900000>;
> > +               };
> > +
> > +               asv-table-104 {
> > +                       /* KFC BIN2 */
> > +                       samsung,asv-table-size = <12 15>;
> > +                       samsung,asv-table-id = <0x104>;
> > +                       samsung,asv-data =
> > +                                     /* ASV0  ASV1    ASV2    ASV3    ASV4    ASV5    ASV6    ASV7    ASV8    ASV9    ASV10   ASV11   ASV12  ASV13 */
> > +                               <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>;
> > +                                                     /* ASV0...13 */
> > +                       samsung,asv-common-data = <300 900000>,
> > +                                                 <200 900000>;
> > +               };
> > +       };
> > +};
> > +
> >  &clock {
> >         compatible = "samsung,exynos5800-clock";
> >  };
> > --
> > 2.17.1
> >

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

* Re: [PATCH RFC 4/8] soc: samsung: Add Exynos Adaptive Supply Voltage driver
  2019-04-04 17:17     ` [PATCH RFC 4/8] soc: samsung: Add Exynos Adaptive Supply Voltage driver Sylwester Nawrocki
  2019-04-05 10:24       ` Krzysztof Kozlowski
@ 2019-04-23 10:50       ` Krzysztof Kozlowski
  2019-04-24  8:11         ` Sylwester Nawrocki
  1 sibling, 1 reply; 22+ messages in thread
From: Krzysztof Kozlowski @ 2019-04-23 10:50 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: kgene, robh+dt, mark.rutland, Chanwoo Choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, Bartłomiej Żołnierkiewicz,
	Marek Szyprowski

On Thu, 4 Apr 2019 at 19:22, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> The Adaptive Supply Voltage (ASV) on Exynos SoCs is a technique of adjusting
> operating points of devices in order to better match actual capabilities
> of the hardware and optimize power consumption.
>
> This patch adds common code for parsing the ASV tables from devicetree
> and updating CPU OPPs.
>
> Also support for Exynos5422/5800 SoC is added, the Exynos5422 specific part
> of the patch 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>
> ---
>  drivers/soc/samsung/Kconfig          |  11 ++
>  drivers/soc/samsung/Makefile         |   3 +
>  drivers/soc/samsung/exynos-asv.c     | 279 +++++++++++++++++++++++++++
>  drivers/soc/samsung/exynos-asv.h     | 114 +++++++++++
>  drivers/soc/samsung/exynos5422-asv.c | 209 ++++++++++++++++++++
>  drivers/soc/samsung/exynos5422-asv.h |  25 +++
>  6 files changed, 641 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 2905f5262197..4d121984f71a 100644
> --- a/drivers/soc/samsung/Kconfig
> +++ b/drivers/soc/samsung/Kconfig
> @@ -7,6 +7,17 @@ menuconfig SOC_SAMSUNG
>
>  if SOC_SAMSUNG
>
> +config EXYNOS_ASV
> +       bool "Exynos Adaptive Supply Voltage support" if COMPILE_TEST
> +       depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
> +       depends on EXYNOS_CHIPID
> +       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..60532c7eb3aa
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-asv.c
> @@ -0,0 +1,279 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2018 - 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/of.h>
> +#include <linux/pm_opp.h>
> +#include <linux/slab.h>
> +
> +#include "exynos-asv.h"
> +#include "exynos5422-asv.h"
> +#include "exynos5433-asv.h"
> +
> +#ifndef MHZ
> +#define MHZ 1000000U
> +#endif
> +
> +static struct exynos_asv *exynos_asv;
> +
> +int exynos_asv_parse_of_table(struct device_node *node,
> +                             struct exynos_asv_table *table,
> +                             int index)
> +{
> +       u32 table_size, table_id = 0;
> +       unsigned int len1, len2 = 0;
> +       unsigned int num_cols, num_rows;
> +       u32 tmp[20];
> +       u32 *buf;
> +       int ret;
> +
> +       ret = of_property_read_u32(node, "samsung,asv-table-id",
> +                                  &table_id);
> +       if (ret < 0) {
> +               pr_err("ASV: Missing table id in %pOF\n", node);
> +               return ret;
> +       }
> +       table->id = table_id;
> +
> +       if (index >= 0 && asv_table_to_index(table_id) != index)
> +               return -EBADR;
> +
> +       ret = of_property_read_u32_array(node, "samsung,asv-table-size",
> +                                        tmp, 2);
> +       if (ret < 0)
> +               return ret;
> +
> +       num_rows = tmp[0];
> +       num_cols = tmp[1];
> +       if (num_rows > EXYNOS_ASV_MAX_LEVELS ||
> +           num_cols > (EXYNOS_ASV_MAX_GROUPS + 1)) {
> +               pr_err("ASV: Unsupported ASV table size (%d x %d)\n",
> +                      num_rows, num_cols);
> +               return -EINVAL;
> +       }
> +
> +       table_size = num_rows * num_cols;
> +       buf = kcalloc(table_size, sizeof(u32), GFP_KERNEL);
> +       if (!buf)
> +               return -ENOMEM;
> +
> +       ret = of_property_read_variable_u32_array(node, "samsung,asv-data",
> +                                                 buf, 0, table_size);
> +       if (ret < 0)
> +               goto err_free_buf;
> +
> +       len1 = ret;
> +
> +       if (ret < table_size) {
> +               u32 *dst, *src;
> +               ret = of_property_read_variable_u32_array(node,
> +                                               "samsung,asv-common-data",
> +                                               (u32 *)tmp, 0,
> +                                               ARRAY_SIZE(tmp));
> +               if (ret < 0) {
> +                       pr_err("ASV: Not enough data for table #%x (%d x %d)\n",
> +                              table_id, num_rows, num_cols);
> +                       goto err_free_buf;
> +               }
> +               len2 = ret;
> +
> +               if (len1 + ((len2 / 2) * num_cols) > table_size) {
> +                       pr_err("ASV: Incorrect table %#x definition\n",
> +                              table_id);
> +                               ret = -EINVAL;
> +                               goto err_free_buf;
> +                       }
> +               /*
> +                * Copy data common to all ASV levels to first and second column
> +                * in the main buffer.  We don't replicate data to further
> +                * columns, instead they are left initialized to 0 (invalid,
> +                * unused frequency value).  We assume that users of the table
> +                * will refer to voltage data in column 1 if 0 is encountered
> +                * in any further column (2, 3,...).
> +                */
> +               dst = buf + len1;
> +               src = tmp;
> +
> +               while (len2 >= 2) {
> +                       memcpy(dst, src, 2 * sizeof(u32));
> +                       dst += num_cols;
> +                       src += 2;
> +                       len2 -= 2;
> +               }
> +       }
> +
> +       table->num_cols = num_cols;
> +       table->num_rows = num_rows;
> +       table->buf = buf;
> +       return 0;
> +
> +err_free_buf:
> +       kfree(buf);
> +       return ret;
> +}
> +
> +int exynos_asv_parse_cpu_tables(struct exynos_asv *asv,        struct device_node *np,
> +                               int table_index)
> +{
> +       struct exynos_asv_subsys *subsys;
> +       struct exynos_asv_table table;
> +       struct device_node *child;
> +       int ret;
> +
> +       for_each_child_of_node(np, child) {
> +               ret = exynos_asv_parse_of_table(child, &table, table_index);
> +               if (ret < 0) {
> +                       if (ret == -EBADR)
> +                               continue;
> +                       of_node_put(child);
> +                       return ret;
> +               }
> +
> +               pr_debug("%s: Matching table: id: %#x at %pOF\n",
> +                        __func__, table.id, child);
> +
> +               switch(asv_table_to_subsys_id(table.id)) {
> +               case EXYNOS_ASV_SUBSYS_ID_ARM:
> +                       subsys = &asv->arm;
> +                       break;
> +               case EXYNOS_ASV_SUBSYS_ID_KFC:
> +                       subsys = &asv->kfc;
> +                       break;
> +               default:
> +                       of_node_put(child);
> +                       return -EINVAL;
> +               }
> +
> +               subsys->num_asv_levels = table.num_rows;
> +               subsys->num_asv_groups = table.num_cols - 1;
> +               subsys->table = table;
> +               subsys->id = asv_table_to_subsys_id(table.id);
> +       }
> +
> +       return 0;
> +}
> +
> +static int exynos_asv_update_cpu_opps(struct device *cpu)
> +{
> +       struct exynos_asv_subsys *subsys = NULL;
> +       struct dev_pm_opp *opp;
> +       unsigned int opp_freq;
> +       int i;
> +
> +       if (of_device_is_compatible(cpu->of_node,
> +                                   exynos_asv->arm.cpu_dt_compat))
> +               subsys = &exynos_asv->arm;
> +       else if (of_device_is_compatible(cpu->of_node,
> +                                        exynos_asv->kfc.cpu_dt_compat))
> +               subsys = &exynos_asv->kfc;
> +
> +       if (!subsys)
> +               return -EINVAL;
> +
> +       for (i = 0; i < subsys->num_asv_levels; i++) {
> +               unsigned int new_voltage;
> +               unsigned int voltage;
> +               int timeout = 1000;
> +               int err;
> +
> +               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)) {
> +                       pr_info("%s cpu%d opp%d, freq: %u missing\n",
> +                               __func__, cpu->id, i, opp_freq);
> +
> +                       continue;
> +               }
> +
> +               voltage = dev_pm_opp_get_voltage(opp);
> +               new_voltage = exynos_asv->opp_get_voltage(subsys, i, voltage);
> +               dev_pm_opp_put(opp);
> +
> +               opp_freq *= MHZ;
> +               dev_pm_opp_remove(cpu, opp_freq);
> +
> +               while (--timeout) {
> +                       opp = dev_pm_opp_find_freq_exact(cpu, opp_freq, true);
> +                       if (IS_ERR(opp))
> +                               break;
> +                       dev_pm_opp_put(opp);
> +                       msleep(1);
> +               }
> +
> +               err = dev_pm_opp_add(cpu, opp_freq, new_voltage);
> +               if (err < 0)
> +                       pr_err("%s: Failed to add OPP %u Hz/%u uV for cpu%d\n",
> +                              __func__, opp_freq, new_voltage, cpu->id);
> +       }
> +
> +       return 0;
> +}
> +
> +static int exynos_asv_update_opps(void)
> +{
> +       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(cpu);
> +                       if (ret < 0)
> +                               pr_err("%s: Couldn't udate OPPs for cpu%d\n",
> +                                      __func__, cpuid);
> +               }
> +
> +               dev_pm_opp_put_opp_table(opp_table);
> +       }
> +
> +       return  0;
> +}
> +
> +static int __init exynos_asv_init(void)
> +{
> +       int ret;
> +
> +       exynos_asv = kcalloc(1, sizeof(struct exynos_asv), GFP_KERNEL);
> +       if (!exynos_asv)
> +               return -ENOMEM;
> +
> +       if (of_machine_is_compatible("samsung,exynos5800") ||
> +           of_machine_is_compatible("samsung,exynos5420"))
> +               ret = exynos5422_asv_init(exynos_asv);
> +       else
> +               return 0;
> +
> +       if (ret < 0)
> +               return ret;
> +
> +       ret = exynos_asv_update_opps();
> +
> +       if (exynos_asv->release)
> +               exynos_asv->release(exynos_asv);
> +
> +       return ret;
> +}
> +late_initcall(exynos_asv_init)
> diff --git a/drivers/soc/samsung/exynos-asv.h b/drivers/soc/samsung/exynos-asv.h
> new file mode 100644
> index 000000000000..3444b361e5e3
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-asv.h
> @@ -0,0 +1,114 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2018 - 2019 Samsung Electronics Co., Ltd.
> + *           http://www.samsung.com/
> + * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
> + *
> + * Samsung Exynos SoC Adaptive Supply Voltage support
> + */
> +#ifndef __EXYNOS_ASV_H
> +#define __EXYNOS_ASV_H
> +
> +#define EXYNOS_ASV_MAX_GROUPS          16
> +#define EXYNOS_ASV_MAX_LEVELS          24
> +
> +#define EXYNOS_ASV_TABLE_INDEX_MASK    (0xff)
> +#define EXYNOS_ASV_SUBSYS_ID_MASK      (0xff << 8)
> +
> +#define asv_table_to_subsys_id(_id)    ((_id >> 8) & 0xff)
> +#define asv_table_to_index(_id)                ((_id) & 0xff)
> +
> +#define EXYNOS_ASV_SUBSYS_ID_ARM       0x0
> +#define EXYNOS_ASV_SUBSYS_ID_EGL       EXYNOS_ASV_SUBSYS_ID_ARM
> +#define EXYNOS_ASV_SUBSYS_ID_KFC       0x1
> +#define EXYNOS_ASV_SUBSYS_ID_INT       0x2
> +#define EXYNOS_ASV_SUBSYS_ID_MIF       0x3
> +#define EXYNOS_ASV_SUBSYS_ID_G3D       0x4
> +#define EXYNOS_ASV_SUBSYS_ID_CAM       0x5
> +#define EXYNOS_ASV_SUBSYS_ID_MAX       0x6
> +
> +struct device_node;
> +
> +/* 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;
> +       unsigned int id;
> +       u32 *buf;
> +};
> +
> +struct exynos_asv_subsys {
> +       int id;
> +       char *cpu_dt_compat;
> +
> +       unsigned int base_volt;
> +       unsigned int num_asv_levels;
> +       unsigned int num_asv_groups;
> +       unsigned int offset_volt_h;
> +       unsigned int offset_volt_l;
> +       struct exynos_asv_table table;
> +};
> +
> +struct exynos_asv {
> +       struct device_node *chipid_node;
> +       struct exynos_asv_subsys arm;
> +       struct exynos_asv_subsys kfc;
> +
> +       int (*opp_get_voltage)(struct exynos_asv_subsys *subs, int level,
> +                              unsigned int voltage);
> +       void (*release)(struct exynos_asv *asv);
> +
> +       unsigned int group;
> +       unsigned int table;
> +
> +       /* TODO: Move member fields below to SoC type specific data structure */
> +       unsigned int is_bin2;
> +       unsigned int is_special_lot;
> +};
> +
> +static inline u32 __exynos_asv_get_item(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_frequency(struct exynos_asv_subsys *subsys,
> +                                              unsigned int index)
> +{
> +       return __exynos_asv_get_item(&subsys->table, index, 0);
> +}
> +/**
> + * exynos_asv_parse_of_table - Parse ASV table from devicetree
> + *
> + * @node: DT node containing the table
> + * @table: The parsed table data
> + * @index: Used to select table with specific index to parse, if >= 0.
> + *         This argument is ignored if the value is less than 0.
> + *
> + * Returns: 0 on success, or negative value on failure. EBADR is returned
> + * when @index is >= 0 but the index value of the parsed table ID is different
> + * than @index.
> + */
> +int exynos_asv_parse_of_table(struct device_node *node,
> +                             struct exynos_asv_table *table,
> +                             int index);
> +
> +/**
> + * exynos_asv_parse_cpu_tables - Parse ARM and KFC ASV tables from DT
> + *
> + * @asv: data structure to store the parsed data to
> + * @node: DT node containing the tables
> + * @index: Used to select table with specific index to parse, if >= 0.
> + *         This argument is ignored if the value is less than 0.
> + *
> + * Returns: 0 on success, or negative value on failure.
> + */
> +int exynos_asv_parse_cpu_tables(struct exynos_asv *asv,        struct device_node *np,
> +                               int table_index);
> +
> +#endif /* __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..f0b7bdd873a9
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos5422-asv.c
> @@ -0,0 +1,209 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2018 - 2019 Samsung Electronics Co., Ltd.
> + *           http://www.samsung.com/
> + *
> + * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/of.h>
> +#include <linux/slab.h>
> +
> +#include "exynos-asv.h"
> +#include "exynos-chipid.h"
> +
> +#define EXYNOS5422_NUM_ASV_GROUPS      14
> +
> +static struct exynos_asv *exynos_asv;
> +
> +static int exynos5422_asv_get_table(void)
> +{
> +       unsigned int reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);

One more thought: you read this register multiple times in the same
function. I think it is not needed - just read once, store the value
and use the helpers to parse it.

Best regards,
Krzysztof

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

* Re: [PATCH RFC 4/8] soc: samsung: Add Exynos Adaptive Supply Voltage driver
  2019-04-23 10:50       ` Krzysztof Kozlowski
@ 2019-04-24  8:11         ` Sylwester Nawrocki
  2019-04-24  8:20           ` Krzysztof Kozlowski
  0 siblings, 1 reply; 22+ messages in thread
From: Sylwester Nawrocki @ 2019-04-24  8:11 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: kgene, robh+dt, mark.rutland, Chanwoo Choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, Bartłomiej Żołnierkiewicz,
	Marek Szyprowski

On 4/23/19 12:50, Krzysztof Kozlowski wrote:
>> +static int exynos5422_asv_get_table(void)
>> +{
>> +       unsigned int reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
>
> One more thought: you read this register multiple times in the same
> function. I think it is not needed - just read once, store the value
> and use the helpers to parse it.

Yes, I have noticed that as well. I'm not sure though if it is worth 
to additionally cache registers manually like this when we use the 
regmap.  I have already converted that code to use the regmap API for 
v2.  And these are barely few registers reads at the driver 
initialization time, not any hot path.

-- 
Thanks,
Sylwester

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

* Re: [PATCH RFC 4/8] soc: samsung: Add Exynos Adaptive Supply Voltage driver
  2019-04-24  8:11         ` Sylwester Nawrocki
@ 2019-04-24  8:20           ` Krzysztof Kozlowski
  0 siblings, 0 replies; 22+ messages in thread
From: Krzysztof Kozlowski @ 2019-04-24  8:20 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: kgene, robh+dt, mark.rutland, Chanwoo Choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, Bartłomiej Żołnierkiewicz,
	Marek Szyprowski

On Wed, 24 Apr 2019 at 10:10, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> On 4/23/19 12:50, Krzysztof Kozlowski wrote:
> >> +static int exynos5422_asv_get_table(void)
> >> +{
> >> +       unsigned int reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
> >
> > One more thought: you read this register multiple times in the same
> > function. I think it is not needed - just read once, store the value
> > and use the helpers to parse it.
>
> Yes, I have noticed that as well. I'm not sure though if it is worth
> to additionally cache registers manually like this when we use the
> regmap.  I have already converted that code to use the regmap API for
> v2.  And these are barely few registers reads at the driver
> initialization time, not any hot path.

By default regmap does not use caching so there is no benefit out of
it. In the same time reading with regmap involves its layer of
abstraction with locks, indirect calls etc... I agree that there is no
point for implementing specific "caching" but with the same code
readability/simplicity you can have it without multiple regmap
accesses one after another. Consider this:
    unsigned int pkgid = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
    asv->table = exynos5422_asv_get_table(pkgid);
    asv->is_bin2 = exynos5422_asv_check_bin2(pkgid);
(and probably renaming the helpers)
The code is equivalent. The same readability.

Best regards,
Krzysztof

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

* Re: [PATCH RFC 3/8] dt-bindings: exynos: Add ASV tables binding documentation
  2019-04-04 17:17     ` [PATCH RFC 3/8] dt-bindings: exynos: Add ASV tables binding documentation Sylwester Nawrocki
@ 2019-04-29 17:23       ` Rob Herring
  2019-07-18 14:02         ` Sylwester Nawrocki
  0 siblings, 1 reply; 22+ messages in thread
From: Rob Herring @ 2019-04-29 17:23 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: krzk, kgene, mark.rutland, cw00.choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, b.zolnierkie, m.szyprowski

On Thu, Apr 04, 2019 at 07:17:30PM +0200, Sylwester Nawrocki wrote:
> This patch adds documentation of the Exynos ASV (Adaptive Voltage Supply)
> tables DT binding.
> 
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  .../devicetree/bindings/arm/samsung/asv.txt   | 76 +++++++++++++++++++
>  1 file changed, 76 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/samsung/asv.txt
> 
> diff --git a/Documentation/devicetree/bindings/arm/samsung/asv.txt b/Documentation/devicetree/bindings/arm/samsung/asv.txt
> new file mode 100644
> index 000000000000..0db907263a91
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/samsung/asv.txt
> @@ -0,0 +1,76 @@
> +Exynos Adaptive Supply Voltage (ASV) tables
> +-------------------------------------------
> +
> +The Adaptive Supply Voltage (ASV) on Exynos SoCs is a technique of adjusting
> +operating points, i.e. the power supply voltage for given clock frequency,
> +in order to better match actual capabilities of the hardware and optimize power
> +consumption.  This applies to subsystem of the SoC like: CPU clusters, GPU,
> +the memory controller or camera ISP.  During production process the SoC chip
> +is assigned to one of several bins (ASV groups) and the group information
> +is encoded in the SoC CHIPID block registers and/or OTP memory. This information
> +is then used by the OS to select more finely matching operating points for
> +devices.

We already have OPP tables defined for QCom CPUs to do speed bining, and 
I just reviewed something from Allwinner for similar purposes. We can't 
have each vendor doing their own thing here.

Rob

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

* Re: [PATCH RFC 3/8] dt-bindings: exynos: Add ASV tables binding documentation
  2019-04-29 17:23       ` Rob Herring
@ 2019-07-18 14:02         ` Sylwester Nawrocki
  0 siblings, 0 replies; 22+ messages in thread
From: Sylwester Nawrocki @ 2019-07-18 14:02 UTC (permalink / raw)
  To: Rob Herring
  Cc: krzk, kgene, mark.rutland, cw00.choi, myungjoo.ham,
	linux-samsung-soc, linux-kernel, linux-arm-kernel, devicetree,
	pankaj.dubey, b.zolnierkie, m.szyprowski

On 4/29/19 19:23, Rob Herring wrote:
> We already have OPP tables defined for QCom CPUs to do speed bining, and 
> I just reviewed something from Allwinner for similar purposes. We can't 
> have each vendor doing their own thing here.

I tried that opp-supported-hw bitmask approach but number of OPP DT nodes
was rather high, around 200 per CPU cluster.  So I moved OPP tables to
the driver. I'm going to post next version of the patch set soon.

-- 
Regards,
Sylwester

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

end of thread, other threads:[~2019-07-18 14:02 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20190404172220epcas1p3a6a8d843780321c4914a63d589c56b33@epcas1p3.samsung.com>
2019-04-04 17:17 ` [PATCH RFC 0/8] Exynos Adaptive Supply Voltage support Sylwester Nawrocki
     [not found]   ` <CGME20190404172224epcas2p21b449c0ae8e36f7e800ae67c18db35a2@epcas2p2.samsung.com>
2019-04-04 17:17     ` [PATCH RFC 1/8] soc: samsung: Add exynos chipid driver support Sylwester Nawrocki
2019-04-05  6:53       ` Krzysztof Kozlowski
2019-04-05  8:49         ` Sylwester Nawrocki
     [not found]   ` <CGME20190404172229epcas2p25a819e37035b26ccf53613e880bdcacf@epcas2p2.samsung.com>
2019-04-04 17:17     ` [PATCH RFC 2/8] soc: samsung: Exynos chipid driver update Sylwester Nawrocki
2019-04-05  9:22       ` Krzysztof Kozlowski
2019-04-05 10:04         ` Sylwester Nawrocki
     [not found]   ` <CGME20190404172234epcas1p37667ec0996000aff9297f13639908dfc@epcas1p3.samsung.com>
2019-04-04 17:17     ` [PATCH RFC 3/8] dt-bindings: exynos: Add ASV tables binding documentation Sylwester Nawrocki
2019-04-29 17:23       ` Rob Herring
2019-07-18 14:02         ` Sylwester Nawrocki
     [not found]   ` <CGME20190404172238epcas2p21ef28f46b728127dcd6e8ee72752a1b8@epcas2p2.samsung.com>
2019-04-04 17:17     ` [PATCH RFC 4/8] soc: samsung: Add Exynos Adaptive Supply Voltage driver Sylwester Nawrocki
2019-04-05 10:24       ` Krzysztof Kozlowski
2019-04-09 17:40         ` Sylwester Nawrocki
2019-04-23 10:50       ` Krzysztof Kozlowski
2019-04-24  8:11         ` Sylwester Nawrocki
2019-04-24  8:20           ` Krzysztof Kozlowski
     [not found]   ` <CGME20190404172243epcas1p39af2498a51772ee4ab2a31f26e469c5b@epcas1p3.samsung.com>
2019-04-04 17:17     ` [PATCH RFC 5/8] ARM: EXYNOS: enable exynos_chipid for ARCH_EXYNOS Sylwester Nawrocki
     [not found]   ` <CGME20190404172247epcas2p2d24f19f76db3cee177bd5b9df783eb3b@epcas2p2.samsung.com>
2019-04-04 17:17     ` [PATCH RFC 6/8] ARM64: " Sylwester Nawrocki
     [not found]   ` <CGME20190404172252epcas2p284b7e2e9e7102f6f95c982d547ed9d64@epcas2p2.samsung.com>
2019-04-04 17:17     ` [PATCH RFC 7/8] ARM: EXYNOS: Enable exynos-asv driver " Sylwester Nawrocki
     [not found]   ` <CGME20190404172257epcas1p20d789242a2353dc8e9ffd7f435dc5eee@epcas1p2.samsung.com>
2019-04-04 17:17     ` [PATCH RFC 8/8] ARM: dts: exynos: Add ASV tables for exynos5422/5800 Sylwester Nawrocki
2019-04-11  7:39       ` Anand Moon
2019-04-11  8:50         ` Willy Wolff

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