Linux-PM Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v2 0/9] Exynos Adaptive Supply Voltage support
       [not found] <CGME20190718143117eucas1p1e534b9075d10fbbbe427c66192205eb1@eucas1p1.samsung.com>
@ 2019-07-18 14:30 ` Sylwester Nawrocki
       [not found]   ` <CGME20190718143127eucas1p13b1e2c98d270140a87f09562ef46c9a3@eucas1p1.samsung.com>
                     ` (9 more replies)
  0 siblings, 10 replies; 25+ messages in thread
From: Sylwester Nawrocki @ 2019-07-18 14:30 UTC (permalink / raw)
  To: krzk
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	b.zolnierkie, m.szyprowski, Sylwester Nawrocki

This is second iteration of patch series adding ASV (Adaptive Supply 
Voltage) support for Exynos SoCs. The first one can be found at:
https://lore.kernel.org/lkml/20190404171735.12815-1-s.nawrocki@samsung.com

The main changes comparing to the first (RFC) version are:
 - moving ASV data tables from DT to the driver,
 - converting the chipid and the ASV drivers to use regmap,
 - converting the ASV driver to proper platform driver.

I tried the opp-supported-hw bitmask approach as in the Qualcomm CPUFreq
DT bindings but it resulted in too many OPPs and DT nodes, around 200
per CPU cluster. So the ASV OPP tables are now in the ASV driver, as in
downstream kernels.  I might give it a try and restrucure these tables
to avoid data repetition.

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.

One of the things on TODO list is support for the Adaptive Body Bias.
This will require modifications on the cpufreq driver side in order to 
support multiple voltage regulators and changes in the OPP framework 
to support adding OPPs with multiple voltages.

[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 (6):
  soc: samsung: Convert exynos-chipid driver to use the regmap API
  soc: samsung: Add Exynos Adaptive Supply Voltage driver
  ARM: EXYNOS: Enable exynos-asv driver for ARCH_EXYNOS
  soc: samsung: Update the CHIP ID DT binding documentation
  ARM: dts: Add "syscon" compatible string to chipid node
  ARM: dts: Add samsung,asv-bin property for odroidxu3-lite

 .../bindings/arm/samsung/exynos-chipid.txt    |  10 +-
 arch/arm/boot/dts/exynos5.dtsi                |   4 +-
 .../boot/dts/exynos5422-odroidxu3-lite.dts    |   4 +
 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              | 185 +++++++
 drivers/soc/samsung/exynos-asv.h              |  82 +++
 drivers/soc/samsung/exynos-chipid.c           | 104 ++++
 drivers/soc/samsung/exynos5422-asv.c          | 499 ++++++++++++++++++
 drivers/soc/samsung/exynos5422-asv.h          |  25 +
 include/linux/soc/samsung/exynos-chipid.h     |  48 ++
 13 files changed, 981 insertions(+), 4 deletions(-)
 create mode 100644 drivers/soc/samsung/exynos-asv.c
 create mode 100644 drivers/soc/samsung/exynos-asv.h
 create mode 100644 drivers/soc/samsung/exynos-chipid.c
 create mode 100644 drivers/soc/samsung/exynos5422-asv.c
 create mode 100644 drivers/soc/samsung/exynos5422-asv.h
 create mode 100644 include/linux/soc/samsung/exynos-chipid.h

-- 
2.17.1


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

* [PATCH v2 1/9] soc: samsung: Add exynos chipid driver support
       [not found]   ` <CGME20190718143127eucas1p13b1e2c98d270140a87f09562ef46c9a3@eucas1p1.samsung.com>
@ 2019-07-18 14:30     ` Sylwester Nawrocki
  2019-07-23 12:57       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 25+ messages in thread
From: Sylwester Nawrocki @ 2019-07-18 14:30 UTC (permalink / raw)
  To: krzk
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	b.zolnierkie, m.szyprowski, Sylwester Nawrocki

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>
[s.nawrocki: updated copyright date]
Signed-off-by: Sylwester Nawrocki <s.nawrocki@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..78b123ee60c0
--- /dev/null
+++ b/drivers/soc/samsung/exynos-chipid.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 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	[flat|nested] 25+ messages in thread

* [PATCH v2 2/9] soc: samsung: Convert exynos-chipid driver to use the regmap API
       [not found]   ` <CGME20190718143128eucas1p2677ae16d229dddcd9a0db8084f0da5cf@eucas1p2.samsung.com>
@ 2019-07-18 14:30     ` Sylwester Nawrocki
  2019-07-23 13:01       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 25+ messages in thread
From: Sylwester Nawrocki @ 2019-07-18 14:30 UTC (permalink / raw)
  To: krzk
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	b.zolnierkie, m.szyprowski, Sylwester Nawrocki

Convert the driver to use regmap API in order to allow other
drivers, like ASV, to access the CHIPID registers.

This patch adds definition of selected CHIPID register offsets
and register bit fields for Exynos5422 SoC.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes since v1 (RFC):
 - new patch
---
 drivers/soc/samsung/exynos-chipid.c       | 33 ++++++----------
 include/linux/soc/samsung/exynos-chipid.h | 48 +++++++++++++++++++++++
 2 files changed, 61 insertions(+), 20 deletions(-)
 create mode 100644 include/linux/soc/samsung/exynos-chipid.h

diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
index 78b123ee60c0..594b00488013 100644
--- a/drivers/soc/samsung/exynos-chipid.c
+++ b/drivers/soc/samsung/exynos-chipid.c
@@ -9,18 +9,16 @@
  */
 
 #include <linux/io.h>
+#include <linux/mfd/syscon.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
+#include <linux/soc/samsung/exynos-chipid.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;
@@ -53,29 +51,24 @@ 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;
+	struct regmap *regmap;
 	u32 product_id;
 	u32 revision;
+	int ret;
 
-	/* 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;
+	regmap = syscon_regmap_lookup_by_compatible("samsung,exynos4210-chipid");
+	if (IS_ERR(regmap)) {
+		pr_err("%s: failed to get regmap\n", __func__);
+		return PTR_ERR(regmap);
 	}
 
-	product_id = readl_relaxed(exynos_chipid_base);
+	ret = regmap_read(regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);
+	if (ret < 0)
+		return ret;
+
 	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/include/linux/soc/samsung/exynos-chipid.h b/include/linux/soc/samsung/exynos-chipid.h
new file mode 100644
index 000000000000..25359d70d617
--- /dev/null
+++ b/include/linux/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 - CHIPID 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
+/* Bit field definitions for EXYNOS_CHIPID_REG_PKG_ID register */
+ #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_REG_AUX_INFO	0x1c
+/* Bit field definitions for EXYNOS_CHIPID_REG_AUX_INFO register */
+ #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
-- 
2.17.1


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

* [PATCH v2 3/9] soc: samsung: Add Exynos Adaptive Supply Voltage driver
       [not found]   ` <CGME20190718143130eucas1p26f2058f47eb2f4020e1ddbf1619d1ac8@eucas1p2.samsung.com>
@ 2019-07-18 14:30     ` Sylwester Nawrocki
  2019-07-23 13:38       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 25+ messages in thread
From: Sylwester Nawrocki @ 2019-07-18 14:30 UTC (permalink / raw)
  To: krzk
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	b.zolnierkie, m.szyprowski, Sylwester Nawrocki

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

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

Tested on Odroid XU3, XU4, XU3 Lite.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes since v1 (RFC):
 - removed code for parsing the ASV OPP tables from DT, the ASV OPP tables
   moved to the driver;
 - converted to use the regmap API;
 - converted to normal platform driver.
---
 drivers/soc/samsung/Kconfig          |  11 +
 drivers/soc/samsung/Makefile         |   3 +
 drivers/soc/samsung/exynos-asv.c     | 185 ++++++++++
 drivers/soc/samsung/exynos-asv.h     |  82 +++++
 drivers/soc/samsung/exynos5422-asv.c | 499 +++++++++++++++++++++++++++
 drivers/soc/samsung/exynos5422-asv.h |  25 ++
 6 files changed, 805 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..539cd95dd176 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 || 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..b1a7e0ba8870
--- /dev/null
+++ b/drivers/soc/samsung/exynos-asv.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * Samsung Exynos SoC Adaptive Supply Voltage support
+ */
+
+#include <linux/cpu.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/soc/samsung/exynos-chipid.h>
+
+#include "exynos-asv.h"
+#include "exynos5422-asv.h"
+
+#define MHZ 1000000U
+
+static int exynos_asv_update_cpu_opps(struct exynos_asv *asv,
+				      struct device *cpu)
+{
+	struct exynos_asv_subsys *subsys = NULL;
+	struct dev_pm_opp *opp;
+	unsigned int opp_freq;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(asv->subsys); i++) {
+		if (of_device_is_compatible(cpu->of_node,
+					    asv->subsys[i].cpu_dt_compat)) {
+			subsys = &asv->subsys[i];
+			break;
+		}
+	}
+	if (!subsys)
+		return -EINVAL;
+
+	for (i = 0; i < subsys->table.num_rows; i++) {
+		unsigned int new_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)) {
+			dev_info(asv->dev, "cpu%d opp%d, freq: %u missing\n",
+				 cpu->id, i, opp_freq);
+
+			continue;
+		}
+
+		voltage = dev_pm_opp_get_voltage(opp);
+		new_voltage = 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)
+			dev_err(asv->dev,
+				"Failed to add OPP %u Hz/%u uV for cpu%d\n",
+				opp_freq, new_voltage, cpu->id);
+	}
+
+	return 0;
+}
+
+static int exynos_asv_update_opps(struct exynos_asv *asv)
+{
+	struct opp_table *last_opp_table = NULL;
+	struct device *cpu;
+	int ret, cpuid;
+
+	for_each_possible_cpu(cpuid) {
+		struct opp_table *opp_table;
+
+		cpu = get_cpu_device(cpuid);
+		if (!cpu)
+			continue;
+
+		opp_table = dev_pm_opp_get_opp_table(cpu);
+		if (IS_ERR(opp_table))
+			continue;
+
+		if (!last_opp_table || opp_table != last_opp_table) {
+			last_opp_table = opp_table;
+
+			ret = exynos_asv_update_cpu_opps(asv, cpu);
+			if (ret < 0)
+				dev_err(asv->dev, "Couldn't udate OPPs for cpu%d\n",
+					cpuid);
+		}
+
+		dev_pm_opp_put_opp_table(opp_table);
+	}
+
+	return	0;
+}
+
+static int exynos_asv_probe(struct platform_device *pdev)
+{
+	int (*probe_func)(struct exynos_asv *asv);
+	struct exynos_asv *asv;
+	struct device *cpu_dev;
+	u32 product_id = 0;
+	int ret, i;
+
+	cpu_dev = get_cpu_device(0);
+	ret = dev_pm_opp_get_opp_count(cpu_dev);
+	if (ret < 0)
+		return -EPROBE_DEFER;
+
+	asv = kcalloc(1, sizeof(*asv), GFP_KERNEL);
+	if (!asv)
+		return -ENOMEM;
+
+	asv->chipid_regmap = syscon_node_to_regmap(pdev->dev.of_node);
+	if (IS_ERR(asv->chipid_regmap)) {
+		dev_err(&pdev->dev, "Could not find syscon regmap\n");
+		return PTR_ERR(asv->chipid_regmap);
+	}
+
+	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);
+
+	switch (product_id & EXYNOS_MASK) {
+	case 0xE5422000:
+		probe_func = exynos5422_asv_init;
+		break;
+	default:
+		dev_err(&pdev->dev, "Unsupported product ID: %#x", product_id);
+		return -ENODEV;
+	}
+
+	ret = of_property_read_u32(pdev->dev.of_node, "samsung,asv-bin",
+				   &asv->of_bin);
+	if (ret < 0)
+		asv->of_bin = -EINVAL;
+
+	asv->dev = &pdev->dev;
+	dev_set_drvdata(&pdev->dev, asv);
+
+	for (i = 0; i < ARRAY_SIZE(asv->subsys); i++)
+		asv->subsys[i].asv = asv;
+
+	ret = probe_func(asv);
+	if (ret < 0)
+		return ret;
+
+	return exynos_asv_update_opps(asv);
+}
+
+static const struct of_device_id exynos_asv_of_device_ids[] = {
+	{ .compatible = "samsung,exynos4210-chipid" },
+	{}
+};
+
+static struct platform_driver exynos_asv_driver = {
+	.driver = {
+		.name = "exynos-asv",
+		.of_match_table = exynos_asv_of_device_ids,
+	},
+	.probe	= exynos_asv_probe,
+};
+module_platform_driver(exynos_asv_driver);
diff --git a/drivers/soc/samsung/exynos-asv.h b/drivers/soc/samsung/exynos-asv.h
new file mode 100644
index 000000000000..d0a5d603093d
--- /dev/null
+++ b/drivers/soc/samsung/exynos-asv.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * Samsung Exynos SoC Adaptive Supply Voltage support
+ */
+#ifndef _EXYNOS_ASV_H
+#define _EXYNOS_ASV_H
+
+enum {
+	EXYNOS_ASV_SUBSYS_ID_ARM,
+	EXYNOS_ASV_SUBSYS_ID_EGL = EXYNOS_ASV_SUBSYS_ID_ARM,
+	EXYNOS_ASV_SUBSYS_ID_KFC,
+	EXYNOS_ASV_SUBSYS_ID_INT,
+	EXYNOS_ASV_SUBSYS_ID_MIF,
+	EXYNOS_ASV_SUBSYS_ID_G3D,
+	EXYNOS_ASV_SUBSYS_ID_CAM,
+	EXYNOS_ASV_SUBSYS_ID_MAX
+};
+
+struct regmap;
+
+/* HPM, IDS values to select target group */
+struct asv_limit_entry {
+	unsigned int hpm;
+	unsigned int ids;
+};
+
+struct exynos_asv_table {
+	unsigned int num_rows;
+	unsigned int num_cols;
+	u32 *buf;
+};
+
+struct exynos_asv_subsys {
+	struct exynos_asv *asv;
+	char *cpu_dt_compat;
+	int id;
+	struct exynos_asv_table table;
+
+	unsigned int base_volt;
+	unsigned int offset_volt_h;
+	unsigned int offset_volt_l;
+};
+
+struct exynos_asv {
+	struct device *dev;
+	struct regmap *chipid_regmap;
+	struct exynos_asv_subsys subsys[2];
+
+	int (*opp_get_voltage)(struct exynos_asv_subsys *subs, int level,
+			       unsigned int voltage);
+	unsigned int group;
+	unsigned int table;
+
+	/* True if SG fields from PKG_ID register should be used */
+	bool use_sg;
+	/* ASV bin read from DT */
+	int of_bin;
+};
+
+static inline u32 __asv_get_table_entry(struct exynos_asv_table *table,
+					unsigned int row, unsigned int col)
+{
+	return table->buf[row * (table->num_cols) + col];
+}
+
+static inline u32 exynos_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
+					unsigned int level, unsigned int group)
+{
+	return __asv_get_table_entry(&subsys->table, level, group + 1);
+}
+
+static inline u32 exynos_asv_opp_get_frequency(struct exynos_asv_subsys *subsys,
+					unsigned int level)
+{
+	return __asv_get_table_entry(&subsys->table, level, 0);
+}
+
+#endif /* _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..5fd673a6a733
--- /dev/null
+++ b/drivers/soc/samsung/exynos5422-asv.c
@@ -0,0 +1,499 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ *
+ * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
+ */
+
+#include <linux/bitrev.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/soc/samsung/exynos-chipid.h>
+#include <linux/slab.h>
+
+#include "exynos-asv.h"
+
+#define ASV_GROUPS_NUM		14
+#define ASV_ARM_DVFS_NUM	20
+#define ASV_ARM_BIN2_DVFS_NUM	17
+#define ASV_KFC_DVFS_NUM	14
+#define ASV_KFC_BIN2_DVFS_NUM	12
+
+static const u32 asv_arm_table[][ASV_ARM_DVFS_NUM][ASV_GROUPS_NUM + 1] = {
+{
+	/* ARM 0, 1 */
+	{ 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
+	  1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
+	{ 2000,    1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000,
+	  1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1900,    1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000,
+	  1162500, 1150000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+	{ 1800,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
+	  1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+	{ 1700,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
+	  1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
+	{ 1600,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
+	  1037500, 1025000, 1037500, 1025000, 1012500, 1000000, 987500 },
+	{ 1500,    1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
+	  1000000, 987500,  1000000, 987500,  975000,  962500,  950000 },
+	{ 1400,    1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+	  975000,  962500,  975000,  962500,  950000,  937500,  925000 },
+	{ 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
+	  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
+	{ 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
+	{ 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
+	  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* ARM 2 */
+	{ 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
+	  1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
+	{ 2000,    1312500, 1312500, 1312500, 1300000, 1275000, 1262500, 1250000,
+	  1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1900,    1262500, 1250000, 1250000, 1237500, 1212500, 1200000, 1187500,
+	  1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
+	{ 1800,    1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500,
+	  1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
+	{ 1700,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+	  1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
+	{ 1600,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+	  1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
+	{ 1500,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
+	{ 1400,    1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,
+	  987500,  975000,  987500,  975000,  962500,  950000,  937500 },
+	{ 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
+	  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
+	{ 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
+	{ 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
+	  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* ARM 3 */
+	{ 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
+	  1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
+	{ 2000,    1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000,
+	  1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1900,    1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500,
+	  1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
+	{ 1800,    1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500,
+	  1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
+	{ 1700,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+	  1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
+	{ 1600,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+	  1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
+	{ 1500,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
+	{ 1400,    1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,
+	  987500,  975000,  987500,  975000,  962500,  950000,  937500 },
+	{ 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
+	  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
+	{ 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
+	{ 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
+	  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* ARM bin 2 */
+	{ 1800,    1237500, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500,
+	  1150000, 1137500, 1150000, 1137500, 1125000, 1112500, 1100000 },
+	{ 1700,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
+	  1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+	{ 1600,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
+	  1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
+	{ 1500,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
+	  1037500, 1025000, 1037500, 1025000, 1012500, 1000000, 987500 },
+	{ 1400,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
+	{ 1300,    1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
+	  1000000, 987500,  1000000, 987500,  975000,  962500,  950000 },
+	{ 1200,    1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+	  975000,  962500,  975000,  962500,  950000,  937500,  925000 },
+	{ 1100,    1037500, 1025000, 1012500, 1000000, 987500,  975000,  962500,
+	  950000,  937500,  950000,  937500,  925000,  912500,  900000 },
+	{ 1000,    1012500, 1000000, 987500,  975000,  962500,  950000,  937500,
+	  925000,  912500,  925000,  912500,  900000,  900000,  900000 },
+	{ 900,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 800,     962500,  950000,  937500,  925000,  912500,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 700,     937500,  925000,  912500,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}
+};
+
+static const u32 asv_kfc_table[][ASV_KFC_DVFS_NUM][ASV_GROUPS_NUM + 1] = {
+{
+	/* KFC 0, 1 */
+	{ 1500000, 1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
+	  1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1400000, 1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
+	  1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+	{ 1300000, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
+	  1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+	{ 1200000, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+	  1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
+	{ 1100000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+	  1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
+	{ 1000000, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
+	{ 900000,  1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+	  975000,  962500,  950000,  937500,  925000,  912500,  900000 },
+	{ 800000,  1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  912500,  900000,  900000,  900000,  900000 },
+	{ 700000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600000,  950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* KFC 2 */
+	{ 1500,    1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
+	  1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1400,    1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
+	  1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+	{ 1300,    1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
+	  1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+	{ 1200,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+	  1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
+	{ 1100,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+	  1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
+	{ 1000,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
+	{ 900,     1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+	  975000,  962500,  950000,  937500,  925000,  912500,  900000 },
+	{ 800,     1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  912500,  900000,  900000,  900000,  900000 },
+	{ 700,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     912500,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* KFC 3 */
+	{ 1500,    1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
+	  1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+	{ 1400,    1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
+	  1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+	{ 1300,    1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
+	  1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+	{ 1200,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+	  1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
+	{ 1100,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+	  1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
+	{ 1000,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+	  1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
+	{ 900,     1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+	  975000,  962500,  950000,  937500,  925000,  912500,  900000 },
+	{ 800,     1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+	  937500,  925000,  912500,  900000,  900000,  900000,  900000 },
+	{ 700,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     912500,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+	/* KFC bin 2 */
+	{ 1300,    1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000,
+	  1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500 },
+	{ 1200,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
+	  1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500 },
+	{ 1100,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
+	  1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000 },
+	{ 1000,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
+	  1037500, 1025000, 1012500, 1000000, 987500,  975000,  962500 },
+	{ 900,     1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
+	  1000000, 987500,  975000,  962500,  950000,  937500,  925000 },
+	{ 800,     1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
+	  962500,  950000,  937500,  925000,  912500,  900000,  900000 },
+	{ 700,     1012500, 1000000, 987500,  975000,  962500,  950000,  937500,
+	  925000,  912500,  900000,  900000,  900000,  900000,  900000 },
+	{ 600,     975000,  962500,  950000,  937500,  925000,  912500,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 500,     937500,  925000,  912500,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 400,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+	{ 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+	  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}
+};
+
+static const struct asv_limit_entry __asv_limits[ASV_GROUPS_NUM] = {
+	{ 13, 55 },
+	{ 21, 65 },
+	{ 25, 69 },
+	{ 30, 72 },
+	{ 36, 74 },
+	{ 43, 76 },
+	{ 51, 78 },
+	{ 65, 80 },
+	{ 81, 82 },
+	{ 98, 84 },
+	{ 119, 87 },
+	{ 135, 89 },
+	{ 150, 92 },
+	{ 999, 999 },
+};
+
+static int exynos5422_asv_get_group(struct exynos_asv *asv)
+{
+	unsigned int pkgid_reg, auxi_reg;
+	int hpm, ids, i;
+
+	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PKG_ID, &pkgid_reg);
+	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_AUX_INFO, &auxi_reg);
+
+	if (asv->use_sg) {
+		u32 sga = (pkgid_reg >> EXYNOS5422_SG_A_OFFSET) &
+			   EXYNOS5422_SG_A_MASK;
+
+		u32 sgb = (pkgid_reg >> EXYNOS5422_SG_B_OFFSET) &
+			   EXYNOS5422_SG_B_MASK;
+
+		if ((pkgid_reg >> EXYNOS5422_SG_BSIGN_OFFSET) &
+		     EXYNOS5422_SG_BSIGN_MASK)
+			return sga + sgb;
+		else
+			return sga - sgb;
+	}
+
+	hpm = (auxi_reg >> EXYNOS5422_TMCB_OFFSET) & EXYNOS5422_TMCB_MASK;
+	ids = (pkgid_reg >> EXYNOS5422_IDS_OFFSET) & EXYNOS5422_IDS_MASK;
+
+	for (i = 0; i < ASV_GROUPS_NUM; i++) {
+		if (ids <= __asv_limits[i].ids)
+			break;
+		if (hpm <= __asv_limits[i].hpm)
+			break;
+	}
+	if (i < ASV_GROUPS_NUM)
+		return i;
+
+	return 0;
+}
+
+static int __asv_offset_voltage(unsigned int index)
+{
+	switch (index) {
+	case 1:
+		return 12500;
+	case 2:
+		return 50000;
+	case 3:
+		return 25000;
+	default:
+		return 0;
+	};
+}
+
+static void exynos5422_asv_offset_voltage_setup(struct exynos_asv *asv)
+{
+	struct exynos_asv_subsys *subsys;
+	unsigned int reg, value;
+
+	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_AUX_INFO, &reg);
+
+	/* ARM offset voltage setup */
+	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_ARM];
+
+	subsys->base_volt = 1000000;
+
+	value = (reg >> EXYNOS5422_ARM_UP_OFFSET) & EXYNOS5422_ARM_UP_MASK;
+	subsys->offset_volt_h = __asv_offset_voltage(value);
+
+	value = (reg >> EXYNOS5422_ARM_DN_OFFSET) & EXYNOS5422_ARM_DN_MASK;
+	subsys->offset_volt_l = __asv_offset_voltage(value);
+
+	/* KFC offset voltage setup */
+	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_KFC];
+
+	subsys->base_volt = 1000000;
+
+	value = (reg >> EXYNOS5422_KFC_UP_OFFSET) & EXYNOS5422_KFC_UP_MASK;
+	subsys->offset_volt_h = __asv_offset_voltage(value);
+
+	value = (reg >> EXYNOS5422_KFC_DN_OFFSET) & EXYNOS5422_KFC_DN_MASK;
+	subsys->offset_volt_l = __asv_offset_voltage(value);
+}
+
+static int exynos5422_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
+				int level, unsigned int volt)
+{
+	unsigned int asv_volt;
+
+	if (level >= subsys->table.num_rows)
+		return volt;
+
+	asv_volt = exynos_asv_opp_get_voltage(subsys, level,
+					      subsys->asv->group);
+
+	if (volt > subsys->base_volt)
+		asv_volt += subsys->offset_volt_h;
+	else
+		asv_volt += subsys->offset_volt_l;
+
+	return asv_volt;
+}
+
+static unsigned int exynos5422_asv_parse_table(struct exynos_asv *asv,
+				      unsigned int pkg_id)
+{
+	return (pkg_id >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
+}
+
+static bool exynos5422_asv_parse_bin2(struct exynos_asv *asv,
+				     unsigned int pkg_id)
+{
+	return (pkg_id >> EXYNOS5422_BIN2_OFFSET) & EXYNOS5422_BIN2_MASK;
+}
+
+static bool exynos5422_asv_parse_sg(struct exynos_asv *asv,
+					unsigned int pkg_id)
+{
+	return ((pkg_id >> EXYNOS5422_USESG_OFFSET) & EXYNOS5422_USESG_MASK);
+}
+
+int exynos5422_asv_init(struct exynos_asv *asv)
+{
+	struct exynos_asv_subsys *subsys;
+	unsigned int table_index;
+	unsigned int pkg_id;
+	bool bin2;
+
+	regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PKG_ID, &pkg_id);
+
+	if (asv->of_bin == 2) {
+		bin2 = true;
+		asv->use_sg = false;
+	} else {
+		asv->use_sg = exynos5422_asv_parse_sg(asv, pkg_id);
+		bin2 = exynos5422_asv_parse_bin2(asv, pkg_id);
+	}
+
+	asv->group = exynos5422_asv_get_group(asv);
+	asv->table = exynos5422_asv_parse_table(asv, pkg_id);
+
+	exynos5422_asv_offset_voltage_setup(asv);
+
+	if (bin2) {
+		table_index = 3;
+	} else {
+		if (asv->table == 2 || asv->table == 3)
+			table_index = asv->table - 1;
+		else
+			table_index = 0;
+	}
+
+	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_ARM];
+	subsys->cpu_dt_compat = "arm,cortex-a15";
+	if (bin2)
+		subsys->table.num_rows = ASV_ARM_BIN2_DVFS_NUM;
+	else
+		subsys->table.num_rows = ASV_ARM_DVFS_NUM;
+	subsys->table.num_cols = ASV_GROUPS_NUM + 1;
+	subsys->table.buf = (u32 *)asv_arm_table[table_index];
+
+	subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_KFC];
+	subsys->cpu_dt_compat = "arm,cortex-a7";
+	if (bin2)
+		subsys->table.num_rows = ASV_KFC_BIN2_DVFS_NUM;
+	else
+		subsys->table.num_rows = ASV_KFC_DVFS_NUM;
+	subsys->table.num_cols = ASV_GROUPS_NUM + 1;
+	subsys->table.buf = (u32 *)asv_kfc_table[table_index];
+
+	asv->opp_get_voltage = exynos5422_asv_opp_get_voltage;
+
+	return 0;
+}
diff --git a/drivers/soc/samsung/exynos5422-asv.h b/drivers/soc/samsung/exynos5422-asv.h
new file mode 100644
index 000000000000..d8f108fcc39b
--- /dev/null
+++ b/drivers/soc/samsung/exynos5422-asv.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ *
+ * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
+ */
+
+#ifndef __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] 25+ messages in thread

* [PATCH v2 4/9] ARM: EXYNOS: enable exynos_chipid for ARCH_EXYNOS
       [not found]   ` <CGME20190718143131eucas1p2e1afc9fe816fff52ee4d12e0979eeb4c@eucas1p2.samsung.com>
@ 2019-07-18 14:30     ` Sylwester Nawrocki
  0 siblings, 0 replies; 25+ messages in thread
From: Sylwester Nawrocki @ 2019-07-18 14:30 UTC (permalink / raw)
  To: krzk
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	b.zolnierkie, m.szyprowski, Sylwester Nawrocki

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>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes since v1 (RFC):
 - none
---
 arch/arm/mach-exynos/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 1c518b8ee520..6fc4af312361 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	[flat|nested] 25+ messages in thread

* [PATCH v2 5/9] ARM64: EXYNOS: enable exynos_chipid for ARCH_EXYNOS
       [not found]   ` <CGME20190718143132eucas1p2afecae86f2ef17aa8a4a99df8ffa47d9@eucas1p2.samsung.com>
@ 2019-07-18 14:30     ` " Sylwester Nawrocki
  0 siblings, 0 replies; 25+ messages in thread
From: Sylwester Nawrocki @ 2019-07-18 14:30 UTC (permalink / raw)
  To: krzk
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	b.zolnierkie, m.szyprowski, Sylwester Nawrocki

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>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes since v1 (RFC):
 - none
---
 arch/arm64/Kconfig.platforms | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index d07fc063c930..e432d26f37d3 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -74,6 +74,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	[flat|nested] 25+ messages in thread

* [PATCH v2 6/9] ARM: EXYNOS: Enable exynos-asv driver for ARCH_EXYNOS
       [not found]   ` <CGME20190718143134eucas1p2aed09e2171d0d2d6b916dddac3637017@eucas1p2.samsung.com>
@ 2019-07-18 14:30     ` " Sylwester Nawrocki
  0 siblings, 0 replies; 25+ messages in thread
From: Sylwester Nawrocki @ 2019-07-18 14:30 UTC (permalink / raw)
  To: krzk
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	b.zolnierkie, m.szyprowski, Sylwester Nawrocki

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

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes since v1 (RFC):
 - none
---
 arch/arm/mach-exynos/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 6fc4af312361..c6ed153c3151 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	[flat|nested] 25+ messages in thread

* [PATCH v2 7/9] soc: samsung: Update the CHIP ID DT binding documentation
       [not found]   ` <CGME20190718143135eucas1p2da5b7842b35327c60667064184619a9f@eucas1p2.samsung.com>
@ 2019-07-18 14:30     ` Sylwester Nawrocki
  0 siblings, 0 replies; 25+ messages in thread
From: Sylwester Nawrocki @ 2019-07-18 14:30 UTC (permalink / raw)
  To: krzk
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	b.zolnierkie, m.szyprowski, Sylwester Nawrocki

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

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes since v1 (RFC):
 - new patch
---
 .../devicetree/bindings/arm/samsung/exynos-chipid.txt  | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.txt b/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.txt
index 85c5dfd4a720..be3657e6c00c 100644
--- a/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.txt
+++ b/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.txt
@@ -1,12 +1,18 @@
-SAMSUNG Exynos SoCs Chipid driver.
+SAMSUNG Exynos SoC series CHIPID subsystem
 
 Required properties:
-- compatible : Should at least contain "samsung,exynos4210-chipid".
+- compatible : Should at least contain "samsung,exynos4210-chipid", "syscon".
 
 - reg: offset and length of the register set
 
+Optional properties:
+ - samsung,asv-bin : Adaptive Supply Voltage bin selection. This can be used
+   to determine the ASV bin of an SoC if respective information is missing
+   in the CHIPID registers or in the OTP memory. Possible values: 0...3.
+
 Example:
 	chipid@10000000 {
 		compatible = "samsung,exynos4210-chipid";
 		reg = <0x10000000 0x100>;
+		samsung,asv-bin = <2>;
 	};
-- 
2.17.1


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

* [PATCH v2 8/9] ARM: dts: Add "syscon" compatible string to chipid node
       [not found]   ` <CGME20190718143136eucas1p2cedfe5ed5e8e6316e82b30a565dc4855@eucas1p2.samsung.com>
@ 2019-07-18 14:30     ` Sylwester Nawrocki
  0 siblings, 0 replies; 25+ messages in thread
From: Sylwester Nawrocki @ 2019-07-18 14:30 UTC (permalink / raw)
  To: krzk
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	b.zolnierkie, m.szyprowski, Sylwester Nawrocki

The CHIP ID block in addition to exact chip revision information
contains data and control registers for ASV (Adaptive Supply Voltage)
and ABB (Adaptive Body Bias). Add "syscon" compatible so the CHIPID
block can be shared by respective drivers.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes since v1 (RFC):
 - new patch
---
 arch/arm/boot/dts/exynos5.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi
index 67f9b4504a42..4801ca759feb 100644
--- a/arch/arm/boot/dts/exynos5.dtsi
+++ b/arch/arm/boot/dts/exynos5.dtsi
@@ -35,8 +35,8 @@
 		#size-cells = <1>;
 		ranges;
 
-		chipid@10000000 {
-			compatible = "samsung,exynos4210-chipid";
+		chipid: chipid@10000000 {
+			compatible = "samsung,exynos4210-chipid", "syscon";
 			reg = <0x10000000 0x100>;
 		};
 
-- 
2.17.1


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

* [PATCH v2 9/9] ARM: dts: Add samsung,asv-bin property for odroidxu3-lite
       [not found]   ` <CGME20190718143138eucas1p127542c4cb8416cee9af6a95f4bc98366@eucas1p1.samsung.com>
@ 2019-07-18 14:30     ` Sylwester Nawrocki
  0 siblings, 0 replies; 25+ messages in thread
From: Sylwester Nawrocki @ 2019-07-18 14:30 UTC (permalink / raw)
  To: krzk
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	b.zolnierkie, m.szyprowski, Sylwester Nawrocki

The Exynos5422 SoC used on Odroid XU3 Lite boards belongs to
a special ASV bin but this information cannot be read from the
CHIPID block registers. Add samsung,asv-bin property for XU3
Lite to ensure the ASV bin is properly determined.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes since v1 (RFC):
 - new patch
---
 arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts b/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts
index c19b5a51ca44..a31ca2ef750f 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts
@@ -26,6 +26,10 @@
 	status = "disabled";
 };
 
+&chipid {
+	samsung,asv-bin = <2>;
+};
+
 &pwm {
 	/*
 	 * PWM 0 -- fan
-- 
2.17.1


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

* Re: [PATCH v2 0/9] Exynos Adaptive Supply Voltage support
  2019-07-18 14:30 ` [PATCH v2 0/9] Exynos Adaptive Supply Voltage support Sylwester Nawrocki
                     ` (8 preceding siblings ...)
       [not found]   ` <CGME20190718143138eucas1p127542c4cb8416cee9af6a95f4bc98366@eucas1p1.samsung.com>
@ 2019-07-23  2:04   ` Viresh Kumar
  2019-07-24 13:10     ` Marek Szyprowski
  9 siblings, 1 reply; 25+ messages in thread
From: Viresh Kumar @ 2019-07-23  2:04 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: krzk, robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	b.zolnierkie, m.szyprowski

On 18-07-19, 16:30, Sylwester Nawrocki wrote:
> This is second iteration of patch series adding ASV (Adaptive Supply 
> Voltage) support for Exynos SoCs. The first one can be found at:
> https://lore.kernel.org/lkml/20190404171735.12815-1-s.nawrocki@samsung.com
> 
> The main changes comparing to the first (RFC) version are:
>  - moving ASV data tables from DT to the driver,
>  - converting the chipid and the ASV drivers to use regmap,
>  - converting the ASV driver to proper platform driver.
> 
> I tried the opp-supported-hw bitmask approach as in the Qualcomm CPUFreq
> DT bindings but it resulted in too many OPPs and DT nodes, around 200
> per CPU cluster. So the ASV OPP tables are now in the ASV driver, as in
> downstream kernels.

Hmm. Can you explain why do you have so many OPPs? How many
frequencies do you actually support per cluster and what all varies
per frequency based on hw ? How many hw version do u have ?

I am asking as the OPP core can be improved to support your case if
possible. But I need to understand the problem first.

-- 
viresh

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

* Re: [PATCH v2 1/9] soc: samsung: Add exynos chipid driver support
  2019-07-18 14:30     ` [PATCH v2 1/9] soc: samsung: Add exynos chipid driver support Sylwester Nawrocki
@ 2019-07-23 12:57       ` Krzysztof Kozlowski
  2019-07-23 14:10         ` Bartlomiej Zolnierkiewicz
  2019-08-08 12:07         ` Sylwester Nawrocki
  0 siblings, 2 replies; 25+ messages in thread
From: Krzysztof Kozlowski @ 2019-07-23 12:57 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	Bartłomiej Żołnierkiewicz, Marek Szyprowski

On Thu, 18 Jul 2019 at 16:31, 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>
> [s.nawrocki: updated copyright date]
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@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..78b123ee60c0
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-chipid.c
> @@ -0,0 +1,111 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019 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>

Any changes here from my previous comments?

I have also one more new thought later.

> +#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");

In case of running old kernel on unknown SoC (new revision of existing
one or older design not longer supported like 4415), the device will
not bind. This was added by Bartlomiej. Why? I imagine that soc driver
could be still matched and just report "Unknown". I am not sure if
this changes anything, though.

Best regards,
Krzysztof


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

* Re: [PATCH v2 2/9] soc: samsung: Convert exynos-chipid driver to use the regmap API
  2019-07-18 14:30     ` [PATCH v2 2/9] soc: samsung: Convert exynos-chipid driver to use the regmap API Sylwester Nawrocki
@ 2019-07-23 13:01       ` Krzysztof Kozlowski
  2019-08-08 12:07         ` Sylwester Nawrocki
  0 siblings, 1 reply; 25+ messages in thread
From: Krzysztof Kozlowski @ 2019-07-23 13:01 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	Bartłomiej Żołnierkiewicz, Marek Szyprowski

On Thu, 18 Jul 2019 at 16:31, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> Convert the driver to use regmap API in order to allow other
> drivers, like ASV, to access the CHIPID registers.
>
> This patch adds definition of selected CHIPID register offsets
> and register bit fields for Exynos5422 SoC.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
> Changes since v1 (RFC):
>  - new patch
> ---
>  drivers/soc/samsung/exynos-chipid.c       | 33 ++++++----------
>  include/linux/soc/samsung/exynos-chipid.h | 48 +++++++++++++++++++++++
>  2 files changed, 61 insertions(+), 20 deletions(-)
>  create mode 100644 include/linux/soc/samsung/exynos-chipid.h
>
> diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
> index 78b123ee60c0..594b00488013 100644
> --- a/drivers/soc/samsung/exynos-chipid.c
> +++ b/drivers/soc/samsung/exynos-chipid.c
> @@ -9,18 +9,16 @@
>   */
>
>  #include <linux/io.h>
> +#include <linux/mfd/syscon.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  #include <linux/of_platform.h>
>  #include <linux/platform_device.h>
> +#include <linux/regmap.h>
>  #include <linux/slab.h>
> +#include <linux/soc/samsung/exynos-chipid.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;
> @@ -53,29 +51,24 @@ 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;
> +       struct regmap *regmap;
>         u32 product_id;
>         u32 revision;
> +       int ret;
>
> -       /* 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;
> +       regmap = syscon_regmap_lookup_by_compatible("samsung,exynos4210-chipid");
> +       if (IS_ERR(regmap)) {
> +               pr_err("%s: failed to get regmap\n", __func__);

Other places do not use __func__ prefix so make it consistent. Add it
in patch #1?

> +               return PTR_ERR(regmap);
>         }
>
> -       product_id = readl_relaxed(exynos_chipid_base);
> +       ret = regmap_read(regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);
> +       if (ret < 0)
> +               return ret;
> +
>         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/include/linux/soc/samsung/exynos-chipid.h b/include/linux/soc/samsung/exynos-chipid.h
> new file mode 100644
> index 000000000000..25359d70d617
> --- /dev/null
> +++ b/include/linux/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 - CHIPID support
> + */
> +
> +#define EXYNOS_CHIPID_REG_PRO_ID       0x00
> + #define EXYNOS_SUBREV_MASK            (0xf << 4)

" #define" is unusual syntax. I think not used anywhere else. Stick to
regular one.

Best regards,
Krzysztof

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

* Re: [PATCH v2 3/9] soc: samsung: Add Exynos Adaptive Supply Voltage driver
  2019-07-18 14:30     ` [PATCH v2 3/9] soc: samsung: Add Exynos Adaptive Supply Voltage driver Sylwester Nawrocki
@ 2019-07-23 13:38       ` Krzysztof Kozlowski
  2019-08-08 12:07         ` Sylwester Nawrocki
  0 siblings, 1 reply; 25+ messages in thread
From: Krzysztof Kozlowski @ 2019-07-23 13:38 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	Bartłomiej Żołnierkiewicz, Marek Szyprowski

On Thu, 18 Jul 2019 at 16:31, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> The Adaptive Supply Voltage (ASV) driver adjusts CPU cluster operating
> points depending on exact revision of an SoC retrieved from the CHIPID
> block or the OTP memory.  This allows for some power saving as for some
> CPU clock frequencies we can lower CPU cluster supply voltage comparing
> to safe values common to the all chip revisions.
>
> This patch adds support for Exynos5422/5800 SoC, it is partially based
> on code from https://github.com/hardkernel/linux repository,
> branch odroidxu4-4.14.y, files: arch/arm/mach-exynos/exynos5422-asv.[ch].
>
> Tested on Odroid XU3, XU4, XU3 Lite.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
> Changes since v1 (RFC):
>  - removed code for parsing the ASV OPP tables from DT, the ASV OPP tables
>    moved to the driver;
>  - converted to use the regmap API;
>  - converted to normal platform driver.
> ---
>  drivers/soc/samsung/Kconfig          |  11 +
>  drivers/soc/samsung/Makefile         |   3 +
>  drivers/soc/samsung/exynos-asv.c     | 185 ++++++++++
>  drivers/soc/samsung/exynos-asv.h     |  82 +++++
>  drivers/soc/samsung/exynos5422-asv.c | 499 +++++++++++++++++++++++++++
>  drivers/soc/samsung/exynos5422-asv.h |  25 ++
>  6 files changed, 805 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..539cd95dd176 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 || COMPILE_TEST
> +       depends on EXYNOS_CHIPID

(ARCH_EXYNOS && EXYNOS_CHIPID) || COMPILE_TEST

> +       select EXYNOS_ASV_ARM if ARM && ARCH_EXYNOS
> +
> +# There is no need to enable these drivers for ARMv8
> +config EXYNOS_ASV_ARM
> +       bool "Exynos ASV ARMv7-specific driver extensions" if COMPILE_TEST
> +       depends on EXYNOS_ASV
> +
>  config EXYNOS_CHIPID
>         bool "Exynos Chipid controller driver" if COMPILE_TEST
>         depends on ARCH_EXYNOS || COMPILE_TEST
> diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
> index 3b6a8797416c..edd1d6ea064d 100644
> --- a/drivers/soc/samsung/Makefile
> +++ b/drivers/soc/samsung/Makefile
> @@ -1,5 +1,8 @@
>  # SPDX-License-Identifier: GPL-2.0
>
> +obj-$(CONFIG_EXYNOS_ASV)       += exynos-asv.o
> +obj-$(CONFIG_EXYNOS_ASV_ARM)   += exynos5422-asv.o
> +
>  obj-$(CONFIG_EXYNOS_CHIPID)    += exynos-chipid.o
>  obj-$(CONFIG_EXYNOS_PMU)       += exynos-pmu.o
>
> diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c
> new file mode 100644
> index 000000000000..b1a7e0ba8870
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-asv.c
> @@ -0,0 +1,185 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019 Samsung Electronics Co., Ltd.
> + *           http://www.samsung.com/
> + * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
> + *
> + * Samsung Exynos SoC Adaptive Supply Voltage support
> + */
> +
> +#include <linux/cpu.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_opp.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/soc/samsung/exynos-chipid.h>
> +
> +#include "exynos-asv.h"
> +#include "exynos5422-asv.h"
> +
> +#define MHZ 1000000U
> +
> +static int exynos_asv_update_cpu_opps(struct exynos_asv *asv,
> +                                     struct device *cpu)
> +{
> +       struct exynos_asv_subsys *subsys = NULL;
> +       struct dev_pm_opp *opp;
> +       unsigned int opp_freq;
> +       int i;
> +
> +       for (i = 0; i < ARRAY_SIZE(asv->subsys); i++) {
> +               if (of_device_is_compatible(cpu->of_node,
> +                                           asv->subsys[i].cpu_dt_compat)) {
> +                       subsys = &asv->subsys[i];
> +                       break;
> +               }
> +       }
> +       if (!subsys)
> +               return -EINVAL;
> +
> +       for (i = 0; i < subsys->table.num_rows; i++) {
> +               unsigned int new_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)) {
> +                       dev_info(asv->dev, "cpu%d opp%d, freq: %u missing\n",
> +                                cpu->id, i, opp_freq);
> +
> +                       continue;
> +               }
> +
> +               voltage = dev_pm_opp_get_voltage(opp);
> +               new_voltage = 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)
> +                       dev_err(asv->dev,
> +                               "Failed to add OPP %u Hz/%u uV for cpu%d\n",
> +                               opp_freq, new_voltage, cpu->id);
> +       }
> +
> +       return 0;
> +}
> +
> +static int exynos_asv_update_opps(struct exynos_asv *asv)
> +{
> +       struct opp_table *last_opp_table = NULL;
> +       struct device *cpu;
> +       int ret, cpuid;
> +
> +       for_each_possible_cpu(cpuid) {
> +               struct opp_table *opp_table;
> +
> +               cpu = get_cpu_device(cpuid);
> +               if (!cpu)
> +                       continue;
> +
> +               opp_table = dev_pm_opp_get_opp_table(cpu);
> +               if (IS_ERR(opp_table))
> +                       continue;
> +
> +               if (!last_opp_table || opp_table != last_opp_table) {
> +                       last_opp_table = opp_table;
> +
> +                       ret = exynos_asv_update_cpu_opps(asv, cpu);
> +                       if (ret < 0)
> +                               dev_err(asv->dev, "Couldn't udate OPPs for cpu%d\n",
> +                                       cpuid);
> +               }
> +
> +               dev_pm_opp_put_opp_table(opp_table);
> +       }
> +
> +       return  0;
> +}
> +
> +static int exynos_asv_probe(struct platform_device *pdev)
> +{
> +       int (*probe_func)(struct exynos_asv *asv);
> +       struct exynos_asv *asv;
> +       struct device *cpu_dev;
> +       u32 product_id = 0;
> +       int ret, i;
> +
> +       cpu_dev = get_cpu_device(0);
> +       ret = dev_pm_opp_get_opp_count(cpu_dev);
> +       if (ret < 0)
> +               return -EPROBE_DEFER;
> +
> +       asv = kcalloc(1, sizeof(*asv), GFP_KERNEL);
> +       if (!asv)
> +               return -ENOMEM;
> +
> +       asv->chipid_regmap = syscon_node_to_regmap(pdev->dev.of_node);
> +       if (IS_ERR(asv->chipid_regmap)) {
> +               dev_err(&pdev->dev, "Could not find syscon regmap\n");

Here and in following error-paths - kfree().

> +               return PTR_ERR(asv->chipid_regmap);
> +       }
> +
> +       regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);
> +
> +       switch (product_id & EXYNOS_MASK) {
> +       case 0xE5422000:
> +               probe_func = exynos5422_asv_init;
> +               break;
> +       default:
> +               dev_err(&pdev->dev, "Unsupported product ID: %#x", product_id);
> +               return -ENODEV;
> +       }
> +
> +       ret = of_property_read_u32(pdev->dev.of_node, "samsung,asv-bin",
> +                                  &asv->of_bin);
> +       if (ret < 0)
> +               asv->of_bin = -EINVAL;
> +
> +       asv->dev = &pdev->dev;
> +       dev_set_drvdata(&pdev->dev, asv);
> +
> +       for (i = 0; i < ARRAY_SIZE(asv->subsys); i++)
> +               asv->subsys[i].asv = asv;
> +
> +       ret = probe_func(asv);
> +       if (ret < 0)
> +               return ret;
> +
> +       return exynos_asv_update_opps(asv);
> +}
> +
> +static const struct of_device_id exynos_asv_of_device_ids[] = {
> +       { .compatible = "samsung,exynos4210-chipid" },
> +       {}
> +};
> +
> +static struct platform_driver exynos_asv_driver = {
> +       .driver = {
> +               .name = "exynos-asv",
> +               .of_match_table = exynos_asv_of_device_ids,
> +       },
> +       .probe  = exynos_asv_probe,
> +};
> +module_platform_driver(exynos_asv_driver);
> diff --git a/drivers/soc/samsung/exynos-asv.h b/drivers/soc/samsung/exynos-asv.h
> new file mode 100644
> index 000000000000..d0a5d603093d
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-asv.h
> @@ -0,0 +1,82 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2019 Samsung Electronics Co., Ltd.
> + *           http://www.samsung.com/
> + * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
> + *
> + * Samsung Exynos SoC Adaptive Supply Voltage support
> + */
> +#ifndef _EXYNOS_ASV_H
> +#define _EXYNOS_ASV_H

Here and in other header use prefix:
__LINUX_SOC_
(just like the existing exynos-pmu.h)

> +
> +enum {
> +       EXYNOS_ASV_SUBSYS_ID_ARM,
> +       EXYNOS_ASV_SUBSYS_ID_EGL = EXYNOS_ASV_SUBSYS_ID_ARM,
> +       EXYNOS_ASV_SUBSYS_ID_KFC,
> +       EXYNOS_ASV_SUBSYS_ID_INT,
> +       EXYNOS_ASV_SUBSYS_ID_MIF,
> +       EXYNOS_ASV_SUBSYS_ID_G3D,
> +       EXYNOS_ASV_SUBSYS_ID_CAM,
> +       EXYNOS_ASV_SUBSYS_ID_MAX
> +};
> +
> +struct regmap;
> +
> +/* HPM, IDS values to select target group */
> +struct asv_limit_entry {
> +       unsigned int hpm;
> +       unsigned int ids;
> +};
> +
> +struct exynos_asv_table {
> +       unsigned int num_rows;
> +       unsigned int num_cols;
> +       u32 *buf;
> +};
> +
> +struct exynos_asv_subsys {
> +       struct exynos_asv *asv;
> +       char *cpu_dt_compat;

const char *

> +       int id;
> +       struct exynos_asv_table table;
> +
> +       unsigned int base_volt;
> +       unsigned int offset_volt_h;
> +       unsigned int offset_volt_l;
> +};
> +
> +struct exynos_asv {
> +       struct device *dev;
> +       struct regmap *chipid_regmap;
> +       struct exynos_asv_subsys subsys[2];
> +
> +       int (*opp_get_voltage)(struct exynos_asv_subsys *subs, int level,
> +                              unsigned int voltage);
> +       unsigned int group;
> +       unsigned int table;
> +
> +       /* True if SG fields from PKG_ID register should be used */
> +       bool use_sg;
> +       /* ASV bin read from DT */
> +       int of_bin;
> +};
> +
> +static inline u32 __asv_get_table_entry(struct exynos_asv_table *table,
> +                                       unsigned int row, unsigned int col)
> +{
> +       return table->buf[row * (table->num_cols) + col];
> +}
> +
> +static inline u32 exynos_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
> +                                       unsigned int level, unsigned int group)
> +{
> +       return __asv_get_table_entry(&subsys->table, level, group + 1);
> +}
> +
> +static inline u32 exynos_asv_opp_get_frequency(struct exynos_asv_subsys *subsys,
> +                                       unsigned int level)
> +{
> +       return __asv_get_table_entry(&subsys->table, level, 0);
> +}
> +
> +#endif /* _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..5fd673a6a733
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos5422-asv.c
> @@ -0,0 +1,499 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019 Samsung Electronics Co., Ltd.
> + *           http://www.samsung.com/
> + *
> + * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
> + */
> +
> +#include <linux/bitrev.h>
> +#include <linux/device.h>
> +#include <linux/errno.h>
> +#include <linux/init.h>

Looks unused.

> +#include <linux/of.h>
> +#include <linux/regmap.h>
> +#include <linux/soc/samsung/exynos-chipid.h>
> +#include <linux/slab.h>
> +
> +#include "exynos-asv.h"
> +
> +#define ASV_GROUPS_NUM         14
> +#define ASV_ARM_DVFS_NUM       20
> +#define ASV_ARM_BIN2_DVFS_NUM  17
> +#define ASV_KFC_DVFS_NUM       14
> +#define ASV_KFC_BIN2_DVFS_NUM  12
> +
> +static const u32 asv_arm_table[][ASV_ARM_DVFS_NUM][ASV_GROUPS_NUM + 1] = {
> +{
> +       /* ARM 0, 1 */
> +       { 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
> +         1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
> +       { 2000,    1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000,
> +         1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +       { 1900,    1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000,
> +         1162500, 1150000, 1162500, 1150000, 1137500, 1125000, 1112500 },
> +       { 1800,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
> +         1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
> +       { 1700,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
> +         1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
> +       { 1600,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
> +         1037500, 1025000, 1037500, 1025000, 1012500, 1000000, 987500 },
> +       { 1500,    1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
> +         1000000, 987500,  1000000, 987500,  975000,  962500,  950000 },
> +       { 1400,    1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
> +         975000,  962500,  975000,  962500,  950000,  937500,  925000 },
> +       { 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
> +         962500,  950000,  962500,  950000,  937500,  925000,  912500 },
> +       { 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +         937500,  925000,  937500,  925000,  912500,  900000,  900000 },
> +       { 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
> +         912500,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +       /* ARM 2 */
> +       { 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
> +         1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
> +       { 2000,    1312500, 1312500, 1312500, 1300000, 1275000, 1262500, 1250000,
> +         1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +       { 1900,    1262500, 1250000, 1250000, 1237500, 1212500, 1200000, 1187500,
> +         1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
> +       { 1800,    1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500,
> +         1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
> +       { 1700,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
> +         1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
> +       { 1600,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
> +         1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
> +       { 1500,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +         1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
> +       { 1400,    1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,
> +         987500,  975000,  987500,  975000,  962500,  950000,  937500 },
> +       { 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
> +         962500,  950000,  962500,  950000,  937500,  925000,  912500 },
> +       { 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +         937500,  925000,  937500,  925000,  912500,  900000,  900000 },
> +       { 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
> +         912500,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +       /* ARM 3 */
> +       { 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
> +         1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
> +       { 2000,    1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000,
> +         1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +       { 1900,    1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500,
> +         1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
> +       { 1800,    1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500,
> +         1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
> +       { 1700,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
> +         1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
> +       { 1600,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
> +         1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
> +       { 1500,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +         1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
> +       { 1400,    1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,
> +         987500,  975000,  987500,  975000,  962500,  950000,  937500 },
> +       { 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
> +         962500,  950000,  962500,  950000,  937500,  925000,  912500 },
> +       { 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +         937500,  925000,  937500,  925000,  912500,  900000,  900000 },
> +       { 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
> +         912500,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +       /* ARM bin 2 */
> +       { 1800,    1237500, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500,
> +         1150000, 1137500, 1150000, 1137500, 1125000, 1112500, 1100000 },
> +       { 1700,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
> +         1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
> +       { 1600,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
> +         1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
> +       { 1500,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
> +         1037500, 1025000, 1037500, 1025000, 1012500, 1000000, 987500 },
> +       { 1400,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +         1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
> +       { 1300,    1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
> +         1000000, 987500,  1000000, 987500,  975000,  962500,  950000 },
> +       { 1200,    1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
> +         975000,  962500,  975000,  962500,  950000,  937500,  925000 },
> +       { 1100,    1037500, 1025000, 1012500, 1000000, 987500,  975000,  962500,
> +         950000,  937500,  950000,  937500,  925000,  912500,  900000 },
> +       { 1000,    1012500, 1000000, 987500,  975000,  962500,  950000,  937500,
> +         925000,  912500,  925000,  912500,  900000,  900000,  900000 },
> +       { 900,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 800,     962500,  950000,  937500,  925000,  912500,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 700,     937500,  925000,  912500,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}
> +};
> +
> +static const u32 asv_kfc_table[][ASV_KFC_DVFS_NUM][ASV_GROUPS_NUM + 1] = {
> +{
> +       /* KFC 0, 1 */
> +       { 1500000, 1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
> +         1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +       { 1400000, 1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
> +         1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
> +       { 1300000, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
> +         1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
> +       { 1200000, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
> +         1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
> +       { 1100000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
> +         1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
> +       { 1000000, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +         1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
> +       { 900000,  1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
> +         975000,  962500,  950000,  937500,  925000,  912500,  900000 },
> +       { 800000,  1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +         937500,  925000,  912500,  900000,  900000,  900000,  900000 },
> +       { 700000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 600000,  950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 500000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 400000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 300000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 200000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +       /* KFC 2 */
> +       { 1500,    1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
> +         1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +       { 1400,    1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
> +         1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
> +       { 1300,    1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
> +         1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
> +       { 1200,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
> +         1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
> +       { 1100,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
> +         1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
> +       { 1000,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +         1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
> +       { 900,     1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
> +         975000,  962500,  950000,  937500,  925000,  912500,  900000 },
> +       { 800,     1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +         937500,  925000,  912500,  900000,  900000,  900000,  900000 },
> +       { 700,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 600,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 500,     912500,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +       /* KFC 3 */
> +       { 1500,    1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
> +         1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
> +       { 1400,    1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
> +         1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
> +       { 1300,    1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
> +         1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
> +       { 1200,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
> +         1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
> +       { 1100,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
> +         1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
> +       { 1000,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
> +         1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
> +       { 900,     1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
> +         975000,  962500,  950000,  937500,  925000,  912500,  900000 },
> +       { 800,     1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
> +         937500,  925000,  912500,  900000,  900000,  900000,  900000 },
> +       { 700,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 600,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 500,     912500,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}, {
> +       /* KFC bin 2 */
> +       { 1300,    1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000,
> +         1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500 },
> +       { 1200,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
> +         1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500 },
> +       { 1100,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
> +         1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000 },
> +       { 1000,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
> +         1037500, 1025000, 1012500, 1000000, 987500,  975000,  962500 },
> +       { 900,     1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
> +         1000000, 987500,  975000,  962500,  950000,  937500,  925000 },
> +       { 800,     1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
> +         962500,  950000,  937500,  925000,  912500,  900000,  900000 },
> +       { 700,     1012500, 1000000, 987500,  975000,  962500,  950000,  937500,
> +         925000,  912500,  900000,  900000,  900000,  900000,  900000 },
> +       { 600,     975000,  962500,  950000,  937500,  925000,  912500,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 500,     937500,  925000,  912500,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 400,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +       { 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
> +         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
> +}
> +};
> +
> +static const struct asv_limit_entry __asv_limits[ASV_GROUPS_NUM] = {
> +       { 13, 55 },
> +       { 21, 65 },
> +       { 25, 69 },
> +       { 30, 72 },
> +       { 36, 74 },
> +       { 43, 76 },
> +       { 51, 78 },
> +       { 65, 80 },
> +       { 81, 82 },
> +       { 98, 84 },
> +       { 119, 87 },
> +       { 135, 89 },
> +       { 150, 92 },
> +       { 999, 999 },
> +};
> +
> +static int exynos5422_asv_get_group(struct exynos_asv *asv)
> +{
> +       unsigned int pkgid_reg, auxi_reg;
> +       int hpm, ids, i;
> +
> +       regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PKG_ID, &pkgid_reg);
> +       regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_AUX_INFO, &auxi_reg);
> +
> +       if (asv->use_sg) {
> +               u32 sga = (pkgid_reg >> EXYNOS5422_SG_A_OFFSET) &
> +                          EXYNOS5422_SG_A_MASK;
> +
> +               u32 sgb = (pkgid_reg >> EXYNOS5422_SG_B_OFFSET) &
> +                          EXYNOS5422_SG_B_MASK;
> +
> +               if ((pkgid_reg >> EXYNOS5422_SG_BSIGN_OFFSET) &
> +                    EXYNOS5422_SG_BSIGN_MASK)
> +                       return sga + sgb;
> +               else
> +                       return sga - sgb;
> +       }
> +
> +       hpm = (auxi_reg >> EXYNOS5422_TMCB_OFFSET) & EXYNOS5422_TMCB_MASK;
> +       ids = (pkgid_reg >> EXYNOS5422_IDS_OFFSET) & EXYNOS5422_IDS_MASK;
> +
> +       for (i = 0; i < ASV_GROUPS_NUM; i++) {
> +               if (ids <= __asv_limits[i].ids)
> +                       break;
> +               if (hpm <= __asv_limits[i].hpm)
> +                       break;
> +       }
> +       if (i < ASV_GROUPS_NUM)
> +               return i;
> +
> +       return 0;
> +}
> +
> +static int __asv_offset_voltage(unsigned int index)
> +{
> +       switch (index) {
> +       case 1:
> +               return 12500;
> +       case 2:
> +               return 50000;
> +       case 3:
> +               return 25000;
> +       default:
> +               return 0;
> +       };
> +}
> +
> +static void exynos5422_asv_offset_voltage_setup(struct exynos_asv *asv)
> +{
> +       struct exynos_asv_subsys *subsys;
> +       unsigned int reg, value;
> +
> +       regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_AUX_INFO, &reg);
> +
> +       /* ARM offset voltage setup */
> +       subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_ARM];
> +
> +       subsys->base_volt = 1000000;
> +
> +       value = (reg >> EXYNOS5422_ARM_UP_OFFSET) & EXYNOS5422_ARM_UP_MASK;
> +       subsys->offset_volt_h = __asv_offset_voltage(value);
> +
> +       value = (reg >> EXYNOS5422_ARM_DN_OFFSET) & EXYNOS5422_ARM_DN_MASK;
> +       subsys->offset_volt_l = __asv_offset_voltage(value);
> +
> +       /* KFC offset voltage setup */
> +       subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_KFC];
> +
> +       subsys->base_volt = 1000000;
> +
> +       value = (reg >> EXYNOS5422_KFC_UP_OFFSET) & EXYNOS5422_KFC_UP_MASK;
> +       subsys->offset_volt_h = __asv_offset_voltage(value);
> +
> +       value = (reg >> EXYNOS5422_KFC_DN_OFFSET) & EXYNOS5422_KFC_DN_MASK;
> +       subsys->offset_volt_l = __asv_offset_voltage(value);
> +}
> +
> +static int exynos5422_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
> +                               int level, unsigned int volt)
> +{
> +       unsigned int asv_volt;
> +
> +       if (level >= subsys->table.num_rows)
> +               return volt;
> +
> +       asv_volt = exynos_asv_opp_get_voltage(subsys, level,
> +                                             subsys->asv->group);
> +
> +       if (volt > subsys->base_volt)
> +               asv_volt += subsys->offset_volt_h;
> +       else
> +               asv_volt += subsys->offset_volt_l;
> +
> +       return asv_volt;
> +}
> +
> +static unsigned int exynos5422_asv_parse_table(struct exynos_asv *asv,
> +                                     unsigned int pkg_id)
> +{
> +       return (pkg_id >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
> +}
> +
> +static bool exynos5422_asv_parse_bin2(struct exynos_asv *asv,
> +                                    unsigned int pkg_id)
> +{
> +       return (pkg_id >> EXYNOS5422_BIN2_OFFSET) & EXYNOS5422_BIN2_MASK;

return !!() for converting to boolean.

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

Unneeded () over entire statement.

Best regards,
Krzysztof

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

* Re: [PATCH v2 1/9] soc: samsung: Add exynos chipid driver support
  2019-07-23 12:57       ` Krzysztof Kozlowski
@ 2019-07-23 14:10         ` Bartlomiej Zolnierkiewicz
  2019-07-24 10:47           ` Krzysztof Kozlowski
  2019-08-08 12:07         ` Sylwester Nawrocki
  1 sibling, 1 reply; 25+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2019-07-23 14:10 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Sylwester Nawrocki, robh+dt, vireshk, devicetree, kgene,
	pankaj.dubey, linux-samsung-soc, linux-arm-kernel, linux-kernel,
	linux-pm, Marek Szyprowski


Hi Krzysztof,

On 7/23/19 2:57 PM, Krzysztof Kozlowski wrote:
> On Thu, 18 Jul 2019 at 16:31, 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>
>> [s.nawrocki: updated copyright date]
>> Signed-off-by: Sylwester Nawrocki <s.nawrocki@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..78b123ee60c0
>> --- /dev/null
>> +++ b/drivers/soc/samsung/exynos-chipid.c
>> @@ -0,0 +1,111 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (c) 2019 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>
> 
> Any changes here from my previous comments?
> 
> I have also one more new thought later.
> 
>> +#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");
> 
> In case of running old kernel on unknown SoC (new revision of existing
> one or older design not longer supported like 4415), the device will
> not bind. This was added by Bartlomiej. Why? I imagine that soc driver
> could be still matched and just report "Unknown". I am not sure if
> this changes anything, though.

I was thinking that we shouldn't be pretending that we know how to
handle unsupported SoCs, i.e. that we know how to correctly read its
product_id and revision.

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

> Best regards,
> Krzysztof
> 
> 
>> +               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] 25+ messages in thread

* Re: [PATCH v2 1/9] soc: samsung: Add exynos chipid driver support
  2019-07-23 14:10         ` Bartlomiej Zolnierkiewicz
@ 2019-07-24 10:47           ` Krzysztof Kozlowski
  0 siblings, 0 replies; 25+ messages in thread
From: Krzysztof Kozlowski @ 2019-07-24 10:47 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: Sylwester Nawrocki, robh+dt, vireshk, devicetree, kgene,
	pankaj.dubey, linux-samsung-soc, linux-arm-kernel, linux-kernel,
	linux-pm, Marek Szyprowski

On Tue, 23 Jul 2019 at 16:10, Bartlomiej Zolnierkiewicz
<b.zolnierkie@samsung.com> wrote:
>
>
> Hi Krzysztof,
>
> On 7/23/19 2:57 PM, Krzysztof Kozlowski wrote:
> > On Thu, 18 Jul 2019 at 16:31, 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>
> >> [s.nawrocki: updated copyright date]
> >> Signed-off-by: Sylwester Nawrocki <s.nawrocki@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..78b123ee60c0
> >> --- /dev/null
> >> +++ b/drivers/soc/samsung/exynos-chipid.c
> >> @@ -0,0 +1,111 @@
> >> +// SPDX-License-Identifier: GPL-2.0
> >> +/*
> >> + * Copyright (c) 2019 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>
> >
> > Any changes here from my previous comments?
> >
> > I have also one more new thought later.
> >
> >> +#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");
> >
> > In case of running old kernel on unknown SoC (new revision of existing
> > one or older design not longer supported like 4415), the device will
> > not bind. This was added by Bartlomiej. Why? I imagine that soc driver
> > could be still matched and just report "Unknown". I am not sure if
> > this changes anything, though.
>
> I was thinking that we shouldn't be pretending that we know how to
> handle unsupported SoCs, i.e. that we know how to correctly read its
> product_id and revision.

Reasonable, thanks for explanation.
Best regards,
Krzysztof

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

* Re: [PATCH v2 0/9] Exynos Adaptive Supply Voltage support
  2019-07-23  2:04   ` [PATCH v2 0/9] Exynos Adaptive Supply Voltage support Viresh Kumar
@ 2019-07-24 13:10     ` Marek Szyprowski
  2019-07-25  2:23       ` Viresh Kumar
  0 siblings, 1 reply; 25+ messages in thread
From: Marek Szyprowski @ 2019-07-24 13:10 UTC (permalink / raw)
  To: Viresh Kumar, Sylwester Nawrocki
  Cc: krzk, robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	b.zolnierkie

Hi Viresh,

On 2019-07-23 04:04, Viresh Kumar wrote:
> On 18-07-19, 16:30, Sylwester Nawrocki wrote:
>> This is second iteration of patch series adding ASV (Adaptive Supply
>> Voltage) support for Exynos SoCs. The first one can be found at:
>> https://lore.kernel.org/lkml/20190404171735.12815-1-s.nawrocki@samsung.com
>>
>> The main changes comparing to the first (RFC) version are:
>>   - moving ASV data tables from DT to the driver,
>>   - converting the chipid and the ASV drivers to use regmap,
>>   - converting the ASV driver to proper platform driver.
>>
>> I tried the opp-supported-hw bitmask approach as in the Qualcomm CPUFreq
>> DT bindings but it resulted in too many OPPs and DT nodes, around 200
>> per CPU cluster. So the ASV OPP tables are now in the ASV driver, as in
>> downstream kernels.
> Hmm. Can you explain why do you have so many OPPs? How many
> frequencies do you actually support per cluster and what all varies
> per frequency based on hw ? How many hw version do u have ?

For big cores there are 20 frequencies (2100MHz .. 200MHz). Each SoC 
might belong to one of the 3 production 'sets' and each set contains 14 
so called 'asv groups', which assign the certain voltage values for each 
of those 20 frequencies (the lower asv group means lower voltage needed 
for given frequency).

> I am asking as the OPP core can be improved to support your case if
> possible. But I need to understand the problem first.


Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


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

* Re: [PATCH v2 0/9] Exynos Adaptive Supply Voltage support
  2019-07-24 13:10     ` Marek Szyprowski
@ 2019-07-25  2:23       ` Viresh Kumar
  2019-08-09 15:58         ` Sylwester Nawrocki
  0 siblings, 1 reply; 25+ messages in thread
From: Viresh Kumar @ 2019-07-25  2:23 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Sylwester Nawrocki, krzk, robh+dt, vireshk, devicetree, kgene,
	pankaj.dubey, linux-samsung-soc, linux-arm-kernel, linux-kernel,
	linux-pm, b.zolnierkie

On 24-07-19, 15:10, Marek Szyprowski wrote:
> Hi Viresh,
> 
> On 2019-07-23 04:04, Viresh Kumar wrote:
> > On 18-07-19, 16:30, Sylwester Nawrocki wrote:
> >> This is second iteration of patch series adding ASV (Adaptive Supply
> >> Voltage) support for Exynos SoCs. The first one can be found at:
> >> https://lore.kernel.org/lkml/20190404171735.12815-1-s.nawrocki@samsung.com
> >>
> >> The main changes comparing to the first (RFC) version are:
> >>   - moving ASV data tables from DT to the driver,
> >>   - converting the chipid and the ASV drivers to use regmap,
> >>   - converting the ASV driver to proper platform driver.
> >>
> >> I tried the opp-supported-hw bitmask approach as in the Qualcomm CPUFreq
> >> DT bindings but it resulted in too many OPPs and DT nodes, around 200
> >> per CPU cluster. So the ASV OPP tables are now in the ASV driver, as in
> >> downstream kernels.
> > Hmm. Can you explain why do you have so many OPPs? How many
> > frequencies do you actually support per cluster and what all varies
> > per frequency based on hw ? How many hw version do u have ?
> 
> For big cores there are 20 frequencies (2100MHz .. 200MHz). Each SoC 
> might belong to one of the 3 production 'sets' and each set contains 14 
> so called 'asv groups', which assign the certain voltage values for each 
> of those 20 frequencies (the lower asv group means lower voltage needed 
> for given frequency).

There is another property which might be useful in this case:
"opp-microvolt-<name>" and then you can use API
dev_pm_opp_set_prop_name() to choose which voltage value to apply to
all OPPs.

opp-supported-hw property is more useful for the cases where only a
subset of frequencies will be supported for different versions of the
SoC. And what you need is a different voltage value for all
frequencies based on some h/w version.

-- 
viresh

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

* Re: [PATCH v2 1/9] soc: samsung: Add exynos chipid driver support
  2019-07-23 12:57       ` Krzysztof Kozlowski
  2019-07-23 14:10         ` Bartlomiej Zolnierkiewicz
@ 2019-08-08 12:07         ` Sylwester Nawrocki
  1 sibling, 0 replies; 25+ messages in thread
From: Sylwester Nawrocki @ 2019-08-08 12:07 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	Bartłomiej Żołnierkiewicz, Marek Szyprowski

On 7/23/19 14:57, Krzysztof Kozlowski wrote:
>> diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c

>> --- /dev/null
>> +++ b/drivers/soc/samsung/exynos-chipid.c
>> @@ -0,0 +1,111 @@
>> +// SPDX-License-Identifier: GPL-2.0

>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_platform.h>
>> +#include <linux/platform_device.h>
>
> Any changes here from my previous comments?

Oops, I tried hard to not miss any of the comments but probably not hard enough.
The two above platform header files will be removed in v3.

-- 
Regards,
Sylwester

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

* Re: [PATCH v2 2/9] soc: samsung: Convert exynos-chipid driver to use the regmap API
  2019-07-23 13:01       ` Krzysztof Kozlowski
@ 2019-08-08 12:07         ` Sylwester Nawrocki
  0 siblings, 0 replies; 25+ messages in thread
From: Sylwester Nawrocki @ 2019-08-08 12:07 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	Bartłomiej Żołnierkiewicz, Marek Szyprowski

On 7/23/19 15:01, Krzysztof Kozlowski wrote:
> On Thu, 18 Jul 2019 at 16:31, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>>
>> Convert the driver to use regmap API in order to allow other
>> drivers, like ASV, to access the CHIPID registers.
>>
>> This patch adds definition of selected CHIPID register offsets
>> and register bit fields for Exynos5422 SoC.
>>
>> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>

>> diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
>> index 78b123ee60c0..594b00488013 100644
>> --- a/drivers/soc/samsung/exynos-chipid.c
>> +++ b/drivers/soc/samsung/exynos-chipid.c
>> @@ -9,18 +9,16 @@
>>   */
>> @@ -53,29 +51,24 @@ static const char * __init product_id_to_soc_id(unsigned int product_id)
>>  int __init exynos_chipid_early_init(void)
>>  {

>> +       regmap = syscon_regmap_lookup_by_compatible("samsung,exynos4210-chipid");
>> +       if (IS_ERR(regmap)) {
>> +               pr_err("%s: failed to get regmap\n", __func__);
> 
> Other places do not use __func__ prefix so make it consistent. Add it
> in patch #1?

I would rather drop the function name prefix here, there should be 
no problem in finding those error messages with grep. I'll just make
the above log a bit more specific.

>> +               return PTR_ERR(regmap);
>>         }

>> diff --git a/include/linux/soc/samsung/exynos-chipid.h b/include/linux/soc/samsung/exynos-chipid.h
>> new file mode 100644
>> index 000000000000..25359d70d617
>> --- /dev/null
>> +++ b/include/linux/soc/samsung/exynos-chipid.h
>> @@ -0,0 +1,48 @@

>> +#define EXYNOS_CHIPID_REG_PRO_ID       0x00
>> + #define EXYNOS_SUBREV_MASK            (0xf << 4)
> 
> " #define" is unusual syntax. I think not used anywhere else. Stick to
> regular one.

Indeed it's almost not used anywhere, I will drop those leading spaces.

git grep "^\ #define" *.[ch] | wc -l

-- 
Regards,
Sylwester

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

* Re: [PATCH v2 3/9] soc: samsung: Add Exynos Adaptive Supply Voltage driver
  2019-07-23 13:38       ` Krzysztof Kozlowski
@ 2019-08-08 12:07         ` Sylwester Nawrocki
  2019-08-08 12:31           ` Krzysztof Kozlowski
  0 siblings, 1 reply; 25+ messages in thread
From: Sylwester Nawrocki @ 2019-08-08 12:07 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	Bartłomiej Żołnierkiewicz, Marek Szyprowski

On 7/23/19 15:38, Krzysztof Kozlowski wrote:
> On Thu, 18 Jul 2019 at 16:31, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>>
>> The Adaptive Supply Voltage (ASV) driver adjusts CPU cluster operating
>> points depending on exact revision of an SoC retrieved from the CHIPID
>> block or the OTP memory.  This allows for some power saving as for some
>> CPU clock frequencies we can lower CPU cluster supply voltage comparing
>> to safe values common to the all chip revisions.
>>
>> This patch adds support for Exynos5422/5800 SoC, it is partially based
>> on code from https://github.com/hardkernel/linux repository,
>> branch odroidxu4-4.14.y, files: arch/arm/mach-exynos/exynos5422-asv.[ch].
>>
>> Tested on Odroid XU3, XU4, XU3 Lite.
>>
>> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
>> ---
>> Changes since v1 (RFC):
>>  - removed code for parsing the ASV OPP tables from DT, the ASV OPP tables
>>    moved to the driver;
>>  - converted to use the regmap API;
>>  - converted to normal platform driver.
>> ---
>>  drivers/soc/samsung/Kconfig          |  11 +
>>  drivers/soc/samsung/Makefile         |   3 +
>>  drivers/soc/samsung/exynos-asv.c     | 185 ++++++++++
>>  drivers/soc/samsung/exynos-asv.h     |  82 +++++
>>  drivers/soc/samsung/exynos5422-asv.c | 499 +++++++++++++++++++++++++++
>>  drivers/soc/samsung/exynos5422-asv.h |  25 ++
>>  6 files changed, 805 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..539cd95dd176 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 || COMPILE_TEST
>> +       depends on EXYNOS_CHIPID
> 
> (ARCH_EXYNOS && EXYNOS_CHIPID) || COMPILE_TEST

OK
>> +       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

>> diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c
>> new file mode 100644
>> index 000000000000..b1a7e0ba8870
>> --- /dev/null
>> +++ b/drivers/soc/samsung/exynos-asv.c
>> @@ -0,0 +1,185 @@

>> +static int exynos_asv_probe(struct platform_device *pdev)
>> +{
>> +       int (*probe_func)(struct exynos_asv *asv);
>> +       struct exynos_asv *asv;
>> +       struct device *cpu_dev;
>> +       u32 product_id = 0;
>> +       int ret, i;
>> +
>> +       cpu_dev = get_cpu_device(0);
>> +       ret = dev_pm_opp_get_opp_count(cpu_dev);
>> +       if (ret < 0)
>> +               return -EPROBE_DEFER;
>> +
>> +       asv = kcalloc(1, sizeof(*asv), GFP_KERNEL);
>> +       if (!asv)
>> +               return -ENOMEM;
>> +
>> +       asv->chipid_regmap = syscon_node_to_regmap(pdev->dev.of_node);
>> +       if (IS_ERR(asv->chipid_regmap)) {
>> +               dev_err(&pdev->dev, "Could not find syscon regmap\n");
> 
> Here and in following error-paths - kfree().

Thanks, I will fix that.

>> +               return PTR_ERR(asv->chipid_regmap);
>> +       }
>> +
>> +       regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);

>> +module_platform_driver(exynos_asv_driver);
>> diff --git a/drivers/soc/samsung/exynos-asv.h b/drivers/soc/samsung/exynos-asv.h
>> new file mode 100644
>> index 000000000000..d0a5d603093d
>> --- /dev/null
>> +++ b/drivers/soc/samsung/exynos-asv.h
>> @@ -0,0 +1,82 @@

>> +#ifndef _EXYNOS_ASV_H
>> +#define _EXYNOS_ASV_H
> 
> Here and in other header use prefix:
> __LINUX_SOC_
> (just like the existing exynos-pmu.h)

OK, I will change that.

>> +struct exynos_asv_subsys {
>> +       struct exynos_asv *asv;
>> +       char *cpu_dt_compat;
> 
> const char *

OK
>> +       int id;

>> +#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..5fd673a6a733
>> --- /dev/null
>> +++ b/drivers/soc/samsung/exynos5422-asv.c
>> @@ -0,0 +1,499 @@

>> +#include <linux/bitrev.h>
>> +#include <linux/device.h>
>> +#include <linux/errno.h>
>> +#include <linux/init.h>
> 
> Looks unused.

Indeed, I will drop it.

>> +static unsigned int exynos5422_asv_parse_table(struct exynos_asv *asv,
>> +                                     unsigned int pkg_id)
>> +{
>> +       return (pkg_id >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
>> +}
>> +
>> +static bool exynos5422_asv_parse_bin2(struct exynos_asv *asv,
>> +                                    unsigned int pkg_id)
>> +{
>> +       return (pkg_id >> EXYNOS5422_BIN2_OFFSET) & EXYNOS5422_BIN2_MASK;
> 
> return !!() for converting to boolean.

I'm not convinced it is needed, the return type of the function is bool
and value of the expression will be implicitly converted to that type.
Is there any compiler warning related to that?

>> +}
>> +
>> +static bool exynos5422_asv_parse_sg(struct exynos_asv *asv,
>> +                                       unsigned int pkg_id)
>> +{
>> +       return ((pkg_id >> EXYNOS5422_USESG_OFFSET) & EXYNOS5422_USESG_MASK);
> 
> Unneeded () over entire statement.

Will drop it.

-- 
Regards,
Sylwester

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

* Re: [PATCH v2 3/9] soc: samsung: Add Exynos Adaptive Supply Voltage driver
  2019-08-08 12:07         ` Sylwester Nawrocki
@ 2019-08-08 12:31           ` Krzysztof Kozlowski
  2019-08-08 12:48             ` Robin Murphy
  0 siblings, 1 reply; 25+ messages in thread
From: Krzysztof Kozlowski @ 2019-08-08 12:31 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: robh+dt, vireshk, devicetree, kgene, pankaj.dubey,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, linux-pm,
	Bartłomiej Żołnierkiewicz, Marek Szyprowski

On Thu, 8 Aug 2019 at 14:07, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
> >> +static unsigned int exynos5422_asv_parse_table(struct exynos_asv *asv,
> >> +                                     unsigned int pkg_id)
> >> +{
> >> +       return (pkg_id >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
> >> +}
> >> +
> >> +static bool exynos5422_asv_parse_bin2(struct exynos_asv *asv,
> >> +                                    unsigned int pkg_id)
> >> +{
> >> +       return (pkg_id >> EXYNOS5422_BIN2_OFFSET) & EXYNOS5422_BIN2_MASK;
> >
> > return !!() for converting to boolean.
>
> I'm not convinced it is needed, the return type of the function is bool
> and value of the expression will be implicitly converted to that type.
> Is there any compiler warning related to that?

Yeah, but bool is int so there will be no implicit conversion... I
guess it is a convention. In theory !! is the proper conversion to
bool but if bool==int then it's essentially conversion to 1. I am not
sure what's the benefit, maybe for some wrong code which would do
comparisons on result like if (exynos5422_asv_parse_bin2() == TRUE)...

Best regards,
Krzysztof

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

* Re: [PATCH v2 3/9] soc: samsung: Add Exynos Adaptive Supply Voltage driver
  2019-08-08 12:31           ` Krzysztof Kozlowski
@ 2019-08-08 12:48             ` Robin Murphy
  2019-08-08 13:14               ` Krzysztof Kozlowski
  0 siblings, 1 reply; 25+ messages in thread
From: Robin Murphy @ 2019-08-08 12:48 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sylwester Nawrocki
  Cc: devicetree, linux-samsung-soc, linux-pm, pankaj.dubey,
	Bartłomiej Żołnierkiewicz, linux-kernel, robh+dt,
	kgene, vireshk, linux-arm-kernel, Marek Szyprowski

On 08/08/2019 13:31, Krzysztof Kozlowski wrote:
> On Thu, 8 Aug 2019 at 14:07, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>>>> +static unsigned int exynos5422_asv_parse_table(struct exynos_asv *asv,
>>>> +                                     unsigned int pkg_id)
>>>> +{
>>>> +       return (pkg_id >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
>>>> +}
>>>> +
>>>> +static bool exynos5422_asv_parse_bin2(struct exynos_asv *asv,
>>>> +                                    unsigned int pkg_id)
>>>> +{
>>>> +       return (pkg_id >> EXYNOS5422_BIN2_OFFSET) & EXYNOS5422_BIN2_MASK;
>>>
>>> return !!() for converting to boolean.
>>
>> I'm not convinced it is needed, the return type of the function is bool
>> and value of the expression will be implicitly converted to that type.
>> Is there any compiler warning related to that?
> 
> Yeah, but bool is int so there will be no implicit conversion... I
> guess it is a convention. In theory !! is the proper conversion to
> bool but if bool==int then it's essentially conversion to 1. I am not
> sure what's the benefit, maybe for some wrong code which would do
> comparisons on result like if (exynos5422_asv_parse_bin2() == TRUE)...

Not so - since we use "-std=gnu89", we have C99-like _Bool, which our 
bool is a typedef of. Conversions, either implicit or explicit, are 
well-defined:

"6.3.1.2 Boolean type

When any scalar value is converted to _Bool, the result is 0 if the 
value compares equal
to 0; otherwise, the result is 1."

This is even called out in Documentation/process/coding-style.rst:

"When using bool types the !! construction is not needed, which 
eliminates a class of bugs."

Robin.

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

* Re: [PATCH v2 3/9] soc: samsung: Add Exynos Adaptive Supply Voltage driver
  2019-08-08 12:48             ` Robin Murphy
@ 2019-08-08 13:14               ` Krzysztof Kozlowski
  0 siblings, 0 replies; 25+ messages in thread
From: Krzysztof Kozlowski @ 2019-08-08 13:14 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Sylwester Nawrocki, devicetree, linux-samsung-soc, linux-pm,
	pankaj.dubey, Bartłomiej Żołnierkiewicz,
	linux-kernel, robh+dt, kgene, vireshk, linux-arm-kernel,
	Marek Szyprowski

On Thu, 8 Aug 2019 at 14:48, Robin Murphy <robin.murphy@arm.com> wrote:
>
> On 08/08/2019 13:31, Krzysztof Kozlowski wrote:
> > On Thu, 8 Aug 2019 at 14:07, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
> >>>> +static unsigned int exynos5422_asv_parse_table(struct exynos_asv *asv,
> >>>> +                                     unsigned int pkg_id)
> >>>> +{
> >>>> +       return (pkg_id >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
> >>>> +}
> >>>> +
> >>>> +static bool exynos5422_asv_parse_bin2(struct exynos_asv *asv,
> >>>> +                                    unsigned int pkg_id)
> >>>> +{
> >>>> +       return (pkg_id >> EXYNOS5422_BIN2_OFFSET) & EXYNOS5422_BIN2_MASK;
> >>>
> >>> return !!() for converting to boolean.
> >>
> >> I'm not convinced it is needed, the return type of the function is bool
> >> and value of the expression will be implicitly converted to that type.
> >> Is there any compiler warning related to that?
> >
> > Yeah, but bool is int so there will be no implicit conversion... I
> > guess it is a convention. In theory !! is the proper conversion to
> > bool but if bool==int then it's essentially conversion to 1. I am not
> > sure what's the benefit, maybe for some wrong code which would do
> > comparisons on result like if (exynos5422_asv_parse_bin2() == TRUE)...
>
> Not so - since we use "-std=gnu89", we have C99-like _Bool, which our
> bool is a typedef of. Conversions, either implicit or explicit, are
> well-defined:
>
> "6.3.1.2 Boolean type
>
> When any scalar value is converted to _Bool, the result is 0 if the
> value compares equal
> to 0; otherwise, the result is 1."
>
> This is even called out in Documentation/process/coding-style.rst:
>
> "When using bool types the !! construction is not needed, which
> eliminates a class of bugs."

Good point, thanks!

Best regards,
Krzysztof

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

* Re: [PATCH v2 0/9] Exynos Adaptive Supply Voltage support
  2019-07-25  2:23       ` Viresh Kumar
@ 2019-08-09 15:58         ` Sylwester Nawrocki
  0 siblings, 0 replies; 25+ messages in thread
From: Sylwester Nawrocki @ 2019-08-09 15:58 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Marek Szyprowski, krzk, robh+dt, vireshk, devicetree, kgene,
	pankaj.dubey, linux-samsung-soc, linux-arm-kernel, linux-kernel,
	linux-pm, b.zolnierkie

Hi Viresh,

On 7/25/19 04:23, Viresh Kumar wrote:
> On 24-07-19, 15:10, Marek Szyprowski wrote:
>> On 2019-07-23 04:04, Viresh Kumar wrote:
>>> On 18-07-19, 16:30, Sylwester Nawrocki wrote:
>>>> This is second iteration of patch series adding ASV (Adaptive Supply
>>>> Voltage) support for Exynos SoCs. The first one can be found at:
>>>> https://lore.kernel.org/lkml/20190404171735.12815-1-s.nawrocki@samsung.com
>>>>
>>>> The main changes comparing to the first (RFC) version are:
>>>>   - moving ASV data tables from DT to the driver,
>>>>   - converting the chipid and the ASV drivers to use regmap,
>>>>   - converting the ASV driver to proper platform driver.
>>>>
>>>> I tried the opp-supported-hw bitmask approach as in the Qualcomm CPUFreq
>>>> DT bindings but it resulted in too many OPPs and DT nodes, around 200
>>>> per CPU cluster. So the ASV OPP tables are now in the ASV driver, as in
>>>> downstream kernels.
>>> 
>>> Hmm. Can you explain why do you have so many OPPs? How many
>>> frequencies do you actually support per cluster and what all varies
>>> per frequency based on hw ? How many hw version do u have ?
>>
>> For big cores there are 20 frequencies (2100MHz .. 200MHz). Each SoC 
>> might belong to one of the 3 production 'sets' and each set contains 14 
>> so called 'asv groups', which assign the certain voltage values for each 
>> of those 20 frequencies (the lower asv group means lower voltage needed 
>> for given frequency).
>
> There is another property which might be useful in this case:
> "opp-microvolt-<name>" and then you can use API
> dev_pm_opp_set_prop_name() to choose which voltage value to apply to
> all OPPs.

Thank you for your suggestions.

For some Exynos SoC variants the algorithm of selecting CPU voltage supply
is a bit more complex than just selecting a column in the frequency/voltage 
matrix, i.e. selecting a set of voltage values for whole frequency range.

Frequency range could be divided into sub-ranges and to each such a sub-range 
part of different column could be assigned, depending on data fused in 
the CHIPID block registers.

We could create OPP node for each frequency and specify all needed voltages 
as a list of "opp-microvolt-<name>" properties but apart from the fact that 
it would have been quite many properties, e.g. 42 (3 tables * 14 columns), 
only for some SoC types the dev_pm_opp_set_prop_name() approach could be 
used. We would need to be able to set opp-microvolt-* property name 
separately for each frequency (OPP).

Probably most future proof would be a DT binding where we could still 
re-create those Exynos-specific ASV tables from DT. For example add named 
opp-microvolt-* properties or something similar to hold rows of each ASV 
table. But that conflicts with "operating-points-v2" binding, where 
multiple OPP voltage values are described by just named properties and 
multiple entries correspond to min/target/max.

opp_table0 {
	compatible = "...", "operating-points-v2";
	opp-shared;
	opp-2100000000 {
		opp-hz = /bits/ 64 <1800000000>;
		opp-microvolt = <...>;
		opp-microvolt-t1 = <1362500>, <1350000>, ....;
		opp-microvolt-t2 = <1362500>, <1360000>, ....;
		opp-microvolt-t3 = <1362500>, <1340000>, ....;
	};
	...
	opp-200000000 {
		opp-hz = /bits/ 64 <200000000>;
		opp-microvolt = <...>;
		opp-microvolt-t1 = <900000>, <900000>, ....;
		opp-microvolt-t2 = <900000>, <900000>, ....;
		opp-microvolt-t3 = <900000>, <900000>, ....;
	};
};

I might be missing some information now on how those Exynos ASV tables 
are used on other SoCs that would need to be supported.

There will be even more data to include when adding support for the Body
Bias voltage, for each CPU supply voltage we could possibly have 
corresponding Body Bias voltage.

-- 
Thanks,
Sylwester

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

end of thread, back to index

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20190718143117eucas1p1e534b9075d10fbbbe427c66192205eb1@eucas1p1.samsung.com>
2019-07-18 14:30 ` [PATCH v2 0/9] Exynos Adaptive Supply Voltage support Sylwester Nawrocki
     [not found]   ` <CGME20190718143127eucas1p13b1e2c98d270140a87f09562ef46c9a3@eucas1p1.samsung.com>
2019-07-18 14:30     ` [PATCH v2 1/9] soc: samsung: Add exynos chipid driver support Sylwester Nawrocki
2019-07-23 12:57       ` Krzysztof Kozlowski
2019-07-23 14:10         ` Bartlomiej Zolnierkiewicz
2019-07-24 10:47           ` Krzysztof Kozlowski
2019-08-08 12:07         ` Sylwester Nawrocki
     [not found]   ` <CGME20190718143128eucas1p2677ae16d229dddcd9a0db8084f0da5cf@eucas1p2.samsung.com>
2019-07-18 14:30     ` [PATCH v2 2/9] soc: samsung: Convert exynos-chipid driver to use the regmap API Sylwester Nawrocki
2019-07-23 13:01       ` Krzysztof Kozlowski
2019-08-08 12:07         ` Sylwester Nawrocki
     [not found]   ` <CGME20190718143130eucas1p26f2058f47eb2f4020e1ddbf1619d1ac8@eucas1p2.samsung.com>
2019-07-18 14:30     ` [PATCH v2 3/9] soc: samsung: Add Exynos Adaptive Supply Voltage driver Sylwester Nawrocki
2019-07-23 13:38       ` Krzysztof Kozlowski
2019-08-08 12:07         ` Sylwester Nawrocki
2019-08-08 12:31           ` Krzysztof Kozlowski
2019-08-08 12:48             ` Robin Murphy
2019-08-08 13:14               ` Krzysztof Kozlowski
     [not found]   ` <CGME20190718143131eucas1p2e1afc9fe816fff52ee4d12e0979eeb4c@eucas1p2.samsung.com>
2019-07-18 14:30     ` [PATCH v2 4/9] ARM: EXYNOS: enable exynos_chipid for ARCH_EXYNOS Sylwester Nawrocki
     [not found]   ` <CGME20190718143132eucas1p2afecae86f2ef17aa8a4a99df8ffa47d9@eucas1p2.samsung.com>
2019-07-18 14:30     ` [PATCH v2 5/9] ARM64: " Sylwester Nawrocki
     [not found]   ` <CGME20190718143134eucas1p2aed09e2171d0d2d6b916dddac3637017@eucas1p2.samsung.com>
2019-07-18 14:30     ` [PATCH v2 6/9] ARM: EXYNOS: Enable exynos-asv driver " Sylwester Nawrocki
     [not found]   ` <CGME20190718143135eucas1p2da5b7842b35327c60667064184619a9f@eucas1p2.samsung.com>
2019-07-18 14:30     ` [PATCH v2 7/9] soc: samsung: Update the CHIP ID DT binding documentation Sylwester Nawrocki
     [not found]   ` <CGME20190718143136eucas1p2cedfe5ed5e8e6316e82b30a565dc4855@eucas1p2.samsung.com>
2019-07-18 14:30     ` [PATCH v2 8/9] ARM: dts: Add "syscon" compatible string to chipid node Sylwester Nawrocki
     [not found]   ` <CGME20190718143138eucas1p127542c4cb8416cee9af6a95f4bc98366@eucas1p1.samsung.com>
2019-07-18 14:30     ` [PATCH v2 9/9] ARM: dts: Add samsung,asv-bin property for odroidxu3-lite Sylwester Nawrocki
2019-07-23  2:04   ` [PATCH v2 0/9] Exynos Adaptive Supply Voltage support Viresh Kumar
2019-07-24 13:10     ` Marek Szyprowski
2019-07-25  2:23       ` Viresh Kumar
2019-08-09 15:58         ` Sylwester Nawrocki

Linux-PM Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-pm/0 linux-pm/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-pm linux-pm/ https://lore.kernel.org/linux-pm \
		linux-pm@vger.kernel.org linux-pm@archiver.kernel.org
	public-inbox-index linux-pm


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-pm


AGPL code for this site: git clone https://public-inbox.org/ public-inbox