soc: samsung: Split the ASV driver into common and SoC-specific part
authorSylwester Nawrocki <s.nawrocki@samsung.com>
Wed, 30 Jan 2019 16:55:49 +0000 (17:55 +0100)
committerJunghoon Kim <jhoon20.kim@samsung.com>
Thu, 14 Feb 2019 07:26:49 +0000 (16:26 +0900)
The exynos-asv driver is re-factored as a prerequisite for adding support
for other SoCs.

Change-Id: I252a2f51d101ad39b0469ee7f31f69cd9f0120b5
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
drivers/soc/samsung/Makefile
drivers/soc/samsung/exynos-asv.c
drivers/soc/samsung/exynos-asv.h [new file with mode: 0644]
drivers/soc/samsung/exynos5422-asv.c [new file with mode: 0644]
drivers/soc/samsung/exynos5422-asv.h [new file with mode: 0644]

index cd5498a..d6118f5 100644 (file)
@@ -1,7 +1,7 @@
 obj-$(CONFIG_EXYNOS_CHIPID)    += exynos-chipid.o
 obj-$(CONFIG_EXYNOS_PMU)       += exynos-pmu.o exynos-sysram.o
 
-obj-$(CONFIG_EXYNOS_ASV)       += exynos-asv.o
+obj-$(CONFIG_EXYNOS_ASV)       += exynos-asv.o exynos5422-asv.o
 
 obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)   += exynos3250-pmu.o exynos4-pmu.o \
                                        exynos5250-pmu.o exynos5420-pmu.o
index 7117f92..6373fce 100644 (file)
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/io.h>
-#include <linux/irqchip.h>
 #include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
 #include <linux/platform_device.h>
 #include <linux/pm_opp.h>
+#include <linux/slab.h>
 
-#include "exynos-chipid.h"
+#include "exynos-asv.h"
+#include "exynos5422-asv.h"
 
-#define        EXYNOS5422_ASV_NR               14
 
-#define ARM_DVFS_NR                    20
-#define ARM_BIN2_DVFS_NR               17
+static struct exynos_asv *exynos_asv;
 
-#define KFC_DVFS_NR                    14
-#define KFC_BIN2_DVFS_NR               12
-
- /* HPM, IDS values to select target group */
-struct asv_limit_entry {
-       unsigned int hpm;
-       unsigned int ids;
-};
-
-struct asv_cluster {
-       unsigned int base_volt;
-       unsigned int dvfs_nr;
-       unsigned int offset_volt_h;
-       unsigned int offset_volt_l;
-       const unsigned int (*asv_table)[EXYNOS5422_ASV_NR + 1];
-};
-
-enum {
-       CLUSTER_ID_ARM,
-       CLUSTER_ID_KFC,
-       CLUSTER_ID_MAX
-};
-
-struct exynos_asv {
-       struct asv_cluster cluster[CLUSTER_ID_MAX];
-       unsigned int bin2;
-       unsigned int special_lot;
-       unsigned int group;
-       unsigned int table;
-};
-
-static struct exynos_asv *exynos_asv = NULL;
-
-static const unsigned int arm_info_table01[ARM_DVFS_NR][EXYNOS5422_ASV_NR + 1] = {
-       { 2100000, 1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000, 1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
-       { 2000000, 1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000, 1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
-       { 1900000, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1162500, 1150000, 1137500, 1125000, 1112500 },
-       { 1800000, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
-       { 1700000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
-       { 1600000, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1037500, 1025000, 1012500, 1000000,  987500 },
-       { 1500000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,  987500, 1000000,  987500,  975000,  962500,  950000 },
-       { 1400000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  962500,  975000,  962500,  950000,  937500,  925000 },
-       { 1300000, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
-       { 1200000, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
-       { 1100000, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
-       { 1000000,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  900000,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  800000,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  700000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  600000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  500000,  900000,  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 },
-};
-
-static const unsigned int arm_info_table2[ARM_DVFS_NR][EXYNOS5422_ASV_NR + 1] = {
-       { 2100000, 1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000, 1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
-       { 2000000, 1312500, 1312500, 1312500, 1300000, 1275000, 1262500, 1250000, 1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
-       { 1900000, 1262500, 1250000, 1250000, 1237500, 1212500, 1200000, 1187500, 1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
-       { 1800000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
-       { 1700000, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
-       { 1600000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
-       { 1500000, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 1012500, 1000000,  987500,  975000,  962500 },
-       { 1400000, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  987500,  975000,  962500,  950000,  937500 },
-       { 1300000, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
-       { 1200000, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
-       { 1100000, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
-       { 1000000,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  900000,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  800000,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  700000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  600000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  500000,  900000,  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 },
-};
-
-static const unsigned int arm_info_table3[ARM_DVFS_NR][EXYNOS5422_ASV_NR + 1] = {
-       { 2100000, 1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000, 1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
-       { 2000000, 1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000, 1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
-       { 1900000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
-       { 1800000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
-       { 1700000, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
-       { 1600000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
-       { 1500000, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 1012500, 1000000,  987500,  975000,  962500 },
-       { 1400000, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  987500,  975000,  962500,  950000,  937500 },
-       { 1300000, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
-       { 1200000, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
-       { 1100000, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
-       { 1000000,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  900000,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  800000,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  700000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  600000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  500000,  900000,  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 },
-};
-
-static const unsigned int arm_info_bin2[ARM_BIN2_DVFS_NR][EXYNOS5422_ASV_NR + 1] = {
-       { 1800000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1150000, 1137500, 1125000, 1112500, 1100000 },
-       { 1700000, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
-       { 1600000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
-       { 1500000, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1037500, 1025000, 1012500, 1000000,  987500 },
-       { 1400000, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 1012500, 1000000,  987500,  975000,  962500 },
-       { 1300000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,  987500, 1000000,  987500,  975000,  962500,  950000 },
-       { 1200000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  962500,  975000,  962500,  950000,  937500,  925000 },
-       { 1100000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  937500,  950000,  937500,  925000,  912500,  900000 },
-       { 1000000, 1012500, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,  925000,  912500,  900000,  900000,  900000 },
-       {  900000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  800000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  700000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  600000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  500000,  900000,  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 },
-};
-
-static const unsigned int kfc_info_table01[KFC_DVFS_NR][EXYNOS5422_ASV_NR + 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 },
-};
-
-static const unsigned int kfc_info_table2[KFC_DVFS_NR][EXYNOS5422_ASV_NR + 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 },
-};
-
-static const unsigned int kfc_info_table3[KFC_DVFS_NR][EXYNOS5422_ASV_NR + 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 },
-};
-
-static const unsigned int kfc_info_bin2[KFC_BIN2_DVFS_NR][EXYNOS5422_ASV_NR + 1] = {
-       { 1300000, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500 },
-       { 1200000, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500 },
-       { 1100000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000 },
-       { 1000000, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  962500 },
-       {  900000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  937500,  925000 },
-       {  800000, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000 },
-       {  700000, 1012500, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000 },
-       {  600000,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  500000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
-       {  400000,  925000,  912500,  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 },
-
-};
-
-
-static unsigned int exynos_asv_opp_get_voltage(struct asv_cluster *cluster,
-                                  unsigned int freq, unsigned int volt)
-{
-       unsigned int i, asv_volt;
-
-       for (i = 0; i < cluster->dvfs_nr; i++) {
-               if (freq == cluster->asv_table[i][0])
-                       break;
-       }
-
-       if (i == cluster->dvfs_nr)
-               return  0;
-
-       asv_volt = cluster->asv_table[i][exynos_asv->group + 1];
-
-       if (volt > cluster->base_volt)
-               asv_volt += cluster->offset_volt_h;
-       else
-               asv_volt += cluster->offset_volt_l;
-
-       return asv_volt;
-}
-
-static int exynos_asv_get_bin2(void)
-{
-       unsigned int reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
-
-       return (reg >> EXYNOS5422_BIN2_OFFSET) & EXYNOS5422_BIN2_MASK;
-}
-
-static bool asv_special_group_check(void)
-{
-       unsigned int reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
-
-       return (((reg >> EXYNOS5422_USESG_OFFSET) & EXYNOS5422_USESG_MASK)
-               && exynos_asv->bin2 == 0);
-}
-
-static const struct asv_limit_entry exynos5422_asv_limits[EXYNOS5422_ASV_NR] = {
-       { 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 exynos_asv_get_group(struct exynos_asv *exynos_asv)
-{
-       unsigned int pkgid_reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
-       unsigned int auxi_reg = exynos_chipid_read(EXYNOS_CHIPID_AUX_INFO);
-       int hpm, ids, i;
-
-       if (exynos_asv->special_lot) {
-               u32 sga = (pkgid_reg >> EXYNOS5422_SG_A_OFFSET) &
-                          EXYNOS5422_SG_A_MASK;
-
-               u32 sgb = (pkgid_reg >> EXYNOS5422_SG_B_OFFSET) &
-                          EXYNOS5422_SG_B_MASK;
-
-               if ((pkgid_reg >> EXYNOS5422_SG_BSIGN_OFFSET) &
-                    EXYNOS5422_SG_BSIGN_MASK)
-                       return sga + sgb;
-               else
-                       return sga - sgb;
-       }
-
-       hpm = (auxi_reg >> EXYNOS5422_TMCB_OFFSET) & EXYNOS5422_TMCB_MASK;
-       ids = (pkgid_reg >> EXYNOS5422_IDS_OFFSET) & EXYNOS5422_IDS_MASK;
-
-       for (i = 0; i < EXYNOS5422_ASV_NR; i++) {
-               if (ids <= exynos5422_asv_limits[i].ids)
-                       break;
-               if (hpm <= exynos5422_asv_limits[i].hpm)
-                       break;
-       }
-
-       if (i < EXYNOS5422_ASV_NR)
-               return i;
-       else
-               return 0;
-}
-
-static int asv_table_check(void)
-{
-       unsigned int pkg_id_reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
-
-       return  (pkg_id_reg >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
-}
-
-static int exynos5422_offset_voltage(unsigned int index)
-{
-       static const unsigned int offset_table[] = { 12500, 50000, 25000 };
-
-       if (index == 0 || index > 3)
-               return 0;
-
-       return offset_table[index - 1];
-}
-
-static void asv_offset_voltage_setup(void)
-{
-       struct asv_cluster *cluster;
-       unsigned int reg, value;
-
-       if (exynos_asv->bin2) {
-               exynos_asv->cluster[CLUSTER_ID_ARM].dvfs_nr = ARM_BIN2_DVFS_NR;
-               exynos_asv->cluster[CLUSTER_ID_KFC].dvfs_nr = KFC_BIN2_DVFS_NR;
-       } else {
-               exynos_asv->cluster[CLUSTER_ID_ARM].dvfs_nr = ARM_DVFS_NR;
-               exynos_asv->cluster[CLUSTER_ID_KFC].dvfs_nr = KFC_DVFS_NR;
-       }
-
-       reg = exynos_chipid_read(EXYNOS_CHIPID_AUX_INFO);
-
-       /* ARM offset voltage setup */
-       cluster = &exynos_asv->cluster[CLUSTER_ID_ARM];
-
-       cluster->base_volt = 1000000;
-
-       value = (reg >> EXYNOS5422_ARM_UP_OFFSET) & EXYNOS5422_ARM_UP_MASK;
-       cluster->offset_volt_h = exynos5422_offset_voltage(value);
-
-       value = (reg >> EXYNOS5422_ARM_DN_OFFSET) & EXYNOS5422_ARM_DN_MASK;
-       cluster->offset_volt_l = exynos5422_offset_voltage(value);
-
-       /* KFC offset voltage setup */
-       cluster = &exynos_asv->cluster[CLUSTER_ID_KFC];
-
-       cluster->base_volt = 1000000;
-
-       value = (reg >> EXYNOS5422_KFC_UP_OFFSET) & EXYNOS5422_KFC_UP_MASK;
-       cluster->offset_volt_h = exynos5422_offset_voltage(value);
-
-       value = (reg >> EXYNOS5422_KFC_DN_OFFSET) & EXYNOS5422_KFC_DN_MASK;
-       cluster->offset_volt_l = exynos5422_offset_voltage(value);
-}
-
-int exynos_asv_update_opps(struct device *cpu)
+int exynos_asv_update_cpu_opp(struct device *cpu)
 {
+       struct exynos_asv_subsys *subsys = NULL;
        struct dev_pm_opp *opp;
-       struct asv_cluster *cluster;
        unsigned int opp_freq;
        int cpuid = cpu->id;
-       int cluster_id = -1;
        int i;
 
-       if (of_device_is_compatible(cpu->of_node, "arm,cortex-a7"))
-               cluster_id = CLUSTER_ID_KFC;
-       else if (of_device_is_compatible(cpu->of_node, "arm,cortex-a15"))
-               cluster_id = CLUSTER_ID_ARM;
+       if (of_device_is_compatible(cpu->of_node,
+                                   exynos_asv->arm.cpu_dt_compat))
+               subsys = &exynos_asv->arm;
+       else if (of_device_is_compatible(cpu->of_node,
+                                        exynos_asv->kfc.cpu_dt_compat))
+               subsys = &exynos_asv->kfc;
 
-       if (cluster_id < 0)
+       if (!subsys)
                return -EINVAL;
 
-       cluster = &exynos_asv->cluster[cluster_id];
-
-       for (i = 0; i < cluster->dvfs_nr; i++) {
+       for (i = 0; i < subsys->dvfs_nr; i++) {
                unsigned int new_voltage;
                unsigned int voltage;
                int err;
 
-               opp_freq = cluster->asv_table[i][0];
+               opp_freq = subsys->asv_table[i][0];
 
                opp = dev_pm_opp_find_freq_exact(cpu, opp_freq * 1000, true);
                if (IS_ERR(opp)) {
@@ -397,7 +57,7 @@ int exynos_asv_update_opps(struct device *cpu)
                }
 
                voltage = dev_pm_opp_get_voltage(opp);
-               new_voltage = exynos_asv_opp_get_voltage(cluster, opp_freq,
+               new_voltage = exynos_asv->opp_get_voltage(subsys, i, opp_freq,
                                                         voltage);
                dev_pm_opp_put(opp);
 
@@ -413,58 +73,12 @@ int exynos_asv_update_opps(struct device *cpu)
        return 0;
 }
 
-
-static int __init exynos_asv_init(void)
+static int exynos_asv_update_opp(void)
 {
-       const unsigned int (*arm_asv_table)[EXYNOS5422_ASV_NR + 1];
-       const unsigned int (*kfc_asv_table)[EXYNOS5422_ASV_NR + 1];
        struct opp_table *last_opp_table = NULL;
        struct device *cpu;
        int ret, cpuid;
 
-       /* Currently only exynos5800 is supported */
-       if (!of_machine_is_compatible("samsung,exynos5800") &&
-           !of_machine_is_compatible("samsung,exynos5420"))
-               return 0;
-
-       exynos_asv = kmalloc(sizeof(struct exynos_asv), GFP_KERNEL);
-       if (!exynos_asv)
-               return -ENOMEM;
-
-       exynos_asv->bin2 = exynos_asv_get_bin2();
-
-       if (of_machine_is_compatible("hardkernel,odroid-xu3-lite"))
-               exynos_asv->bin2 = true;
-
-       exynos_asv->special_lot = asv_special_group_check();
-       exynos_asv->group = exynos_asv_get_group(exynos_asv);
-       exynos_asv->table = asv_table_check();
-
-       asv_offset_voltage_setup();
-
-       if (exynos_asv->bin2) {
-               arm_asv_table = arm_info_bin2;
-               kfc_asv_table = kfc_info_bin2;
-       } else {
-               switch(exynos_asv->table) {
-               case 2:
-                       arm_asv_table = arm_info_table2;
-                       kfc_asv_table = kfc_info_table2;
-                       break;
-               case 3:
-                       arm_asv_table = arm_info_table3;
-                       kfc_asv_table = kfc_info_table3;
-                       break;
-               default:
-                       arm_asv_table = arm_info_table01;
-                       kfc_asv_table = kfc_info_table01;
-                       break;
-               }
-       }
-
-       exynos_asv->cluster[CLUSTER_ID_ARM].asv_table = arm_asv_table;
-       exynos_asv->cluster[CLUSTER_ID_KFC].asv_table = kfc_asv_table;
-
        for_each_possible_cpu(cpuid) {
                struct opp_table *opp_table;
 
@@ -479,7 +93,7 @@ static int __init exynos_asv_init(void)
                if (!last_opp_table || opp_table != last_opp_table) {
                        last_opp_table = opp_table;
 
-                       ret = exynos_asv_update_opps(cpu);
+                       ret = exynos_asv_update_cpu_opp(cpu);
                        if (ret < 0)
                                pr_err("%s: Couldn't udate OPPs for cpu%d\n",
                                       __func__, cpuid);
@@ -490,4 +104,24 @@ static int __init exynos_asv_init(void)
 
        return  0;
 }
-late_initcall(exynos_asv_init);
+
+static int __init exynos_asv_init(void)
+{
+       int ret;
+
+       exynos_asv = kcalloc(1, sizeof(struct exynos_asv), GFP_KERNEL);
+       if (!exynos_asv)
+               return -ENOMEM;
+
+       if (of_machine_is_compatible("samsung,exynos5800") ||
+           of_machine_is_compatible("samsung,exynos5420"))
+               ret = exynos5422_asv_init(exynos_asv);
+       else
+               return 0;
+
+       if (ret < 0)
+               return ret;
+
+       return exynos_asv_update_opp();
+}
+late_initcall(exynos_asv_init)
diff --git a/drivers/soc/samsung/exynos-asv.h b/drivers/soc/samsung/exynos-asv.h
new file mode 100644 (file)
index 0000000..b0f70fd
--- /dev/null
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *           http://www.samsung.com/
+ *
+ * Samsung Exynos SoC Adaptive Supply Voltage support
+ */
+
+#define EXYNOS_ASV_MAX_NUM     16
+
+ /* HPM, IDS values to select target group */
+struct asv_limit_entry {
+       unsigned int hpm;
+       unsigned int ids;
+};
+
+struct exynos_asv_subsys {
+       int id;
+       char *cpu_dt_compat;
+
+       unsigned int base_volt;
+       unsigned int dvfs_nr;
+       unsigned int offset_volt_h;
+       unsigned int offset_volt_l;
+       const u32 (*asv_table)[EXYNOS_ASV_MAX_NUM + 1];
+};
+
+struct exynos_asv {
+       struct exynos_asv_subsys arm;
+       struct exynos_asv_subsys kfc;
+
+       int (*opp_get_voltage)(struct exynos_asv_subsys *subs, int idx,
+                              unsigned int frequency, unsigned int voltage);
+       unsigned int group;
+       unsigned int table;
+
+       unsigned int bin2;
+       unsigned int special_lot;
+};
diff --git a/drivers/soc/samsung/exynos5422-asv.c b/drivers/soc/samsung/exynos5422-asv.c
new file mode 100644 (file)
index 0000000..750becd
--- /dev/null
@@ -0,0 +1,379 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *           http://www.samsung.com/
+ *
+ * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
+ */
+
+#include <linux/bitrev.h>
+#include <linux/cpu.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+
+#include "exynos-asv.h"
+#include "exynos-chipid.h"
+
+#define EXYNOS5422_ASV_NUM             14
+
+#define EXYNOS5422_ARM_DVFS_NUM                20
+#define EXYNOS5422_ARM_BIN2_DVFS_NUM   17
+
+#define EXYNOS5422_KFC_DVFS_NUM                14
+#define EXYNOS5422_KFC_BIN2_DVFS_NUM   12
+
+static struct exynos_asv *exynos_asv;
+
+static const unsigned int arm_info_table01[EXYNOS5422_ARM_DVFS_NUM][EXYNOS_ASV_MAX_NUM + 1] = {
+       { 2100000, 1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000, 1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
+       { 2000000, 1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000, 1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+       { 1900000, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+       { 1800000, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+       { 1700000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
+       { 1600000, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1037500, 1025000, 1012500, 1000000,  987500 },
+       { 1500000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,  987500, 1000000,  987500,  975000,  962500,  950000 },
+       { 1400000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  962500,  975000,  962500,  950000,  937500,  925000 },
+       { 1300000, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
+       { 1200000, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
+       { 1100000, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 1000000,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  900000,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  800000,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  700000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  600000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  500000,  900000,  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 },
+};
+
+static const unsigned int arm_info_table2[EXYNOS5422_ARM_DVFS_NUM][EXYNOS_ASV_MAX_NUM + 1] = {
+       { 2100000, 1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000, 1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
+       { 2000000, 1312500, 1312500, 1312500, 1300000, 1275000, 1262500, 1250000, 1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+       { 1900000, 1262500, 1250000, 1250000, 1237500, 1212500, 1200000, 1187500, 1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
+       { 1800000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
+       { 1700000, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
+       { 1600000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
+       { 1500000, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 1012500, 1000000,  987500,  975000,  962500 },
+       { 1400000, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  987500,  975000,  962500,  950000,  937500 },
+       { 1300000, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
+       { 1200000, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
+       { 1100000, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 1000000,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  900000,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  800000,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  700000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  600000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  500000,  900000,  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 },
+};
+
+static const unsigned int arm_info_table3[EXYNOS5422_ARM_DVFS_NUM][EXYNOS_ASV_MAX_NUM + 1] = {
+       { 2100000, 1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000, 1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
+       { 2000000, 1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000, 1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+       { 1900000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
+       { 1800000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
+       { 1700000, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
+       { 1600000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
+       { 1500000, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 1012500, 1000000,  987500,  975000,  962500 },
+       { 1400000, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  987500,  975000,  962500,  950000,  937500 },
+       { 1300000, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  962500,  950000,  937500,  925000,  912500 },
+       { 1200000, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  937500,  925000,  912500,  900000,  900000 },
+       { 1100000, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 1000000,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  900000,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  800000,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  700000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  600000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  500000,  900000,  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 },
+};
+
+static const unsigned int arm_info_bin2[EXYNOS5422_ARM_BIN2_DVFS_NUM][EXYNOS_ASV_MAX_NUM + 1] = {
+       { 1800000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1150000, 1137500, 1125000, 1112500, 1100000 },
+       { 1700000, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+       { 1600000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
+       { 1500000, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1037500, 1025000, 1012500, 1000000, 987500 },
+       { 1400000, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
+       { 1300000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,  1000000, 987500,  975000,  962500,  950000 },
+       { 1200000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,  962500,  975000,  962500,  950000,  937500,  925000 },
+       { 1100000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,  937500,  950000,  937500,  925000,  912500,  900000 },
+       { 1000000, 1012500, 1000000,  987500,  975000, 962500,  950000,  937500,  925000,  912500,  925000,  912500,  900000,  900000,  900000 },
+       {  900000,  987500,  975000,  962500,  950000, 937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  800000,  962500,  950000,  937500,  925000, 912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  700000,  937500,  925000,  912500,  900000, 900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  600000,  900000,  900000,  900000,  900000, 900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  500000,  900000,  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 },
+};
+
+static const unsigned int kfc_info_table01[EXYNOS5422_KFC_DVFS_NUM][EXYNOS_ASV_MAX_NUM + 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 },
+};
+
+static const unsigned int kfc_info_table2[EXYNOS5422_KFC_DVFS_NUM][EXYNOS_ASV_MAX_NUM + 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 },
+};
+
+static const unsigned int kfc_info_table3[EXYNOS5422_KFC_DVFS_NUM][EXYNOS_ASV_MAX_NUM + 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 },
+};
+
+static const unsigned int kfc_info_bin2[EXYNOS5422_KFC_BIN2_DVFS_NUM][EXYNOS_ASV_MAX_NUM + 1] = {
+       { 1300000, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500 },
+       { 1200000, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500 },
+       { 1100000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000 },
+       { 1000000, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  962500 },
+       {  900000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  937500,  925000 },
+       {  800000, 1050000, 1037500, 1025000, 1012500, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000 },
+       {  700000, 1012500, 1000000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000 },
+       {  600000,  975000,  962500,  950000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  500000,  937500,  925000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       {  400000,  925000,  912500,  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 },
+
+};
+
+static int exynos5422_asv_opp_get_voltage(struct exynos_asv_subsys *subsys,
+                               int idx, unsigned int freq, unsigned int volt)
+{
+       unsigned int i, asv_volt;
+
+       for (i = 0; i < subsys->dvfs_nr; i++) {
+               if (freq == subsys->asv_table[i][0])
+                       break;
+       }
+
+       if (i == subsys->dvfs_nr)
+               return  0;
+
+       asv_volt = subsys->asv_table[i][exynos_asv->group + 1];
+
+       if (volt > subsys->base_volt)
+               asv_volt += subsys->offset_volt_h;
+       else
+               asv_volt += subsys->offset_volt_l;
+
+       return asv_volt;
+}
+
+static int exynos5422_asv_get_bin2(void)
+{
+       unsigned int reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
+
+       return (reg >> EXYNOS5422_BIN2_OFFSET) & EXYNOS5422_BIN2_MASK;
+}
+
+static bool exynos5422_asv_special_group_check(void)
+{
+       unsigned int reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
+
+       return (((reg >> EXYNOS5422_USESG_OFFSET) & EXYNOS5422_USESG_MASK)
+               && exynos_asv->bin2 == 0);
+}
+
+static const struct asv_limit_entry exynos5422_asv_limits[EXYNOS5422_ASV_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 *exynos_asv)
+{
+       unsigned int pkgid_reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
+       unsigned int auxi_reg = exynos_chipid_read(EXYNOS_CHIPID_AUX_INFO);
+       int hpm, ids, i;
+
+       if (exynos_asv->special_lot) {
+               u32 sga = (pkgid_reg >> EXYNOS5422_SG_A_OFFSET) &
+                          EXYNOS5422_SG_A_MASK;
+
+               u32 sgb = (pkgid_reg >> EXYNOS5422_SG_B_OFFSET) &
+                          EXYNOS5422_SG_B_MASK;
+
+               if ((pkgid_reg >> EXYNOS5422_SG_BSIGN_OFFSET) &
+                    EXYNOS5422_SG_BSIGN_MASK)
+                       return sga + sgb;
+               else
+                       return sga - sgb;
+       }
+
+       hpm = (auxi_reg >> EXYNOS5422_TMCB_OFFSET) & EXYNOS5422_TMCB_MASK;
+       ids = (pkgid_reg >> EXYNOS5422_IDS_OFFSET) & EXYNOS5422_IDS_MASK;
+
+       for (i = 0; i < EXYNOS5422_ASV_NUM; i++) {
+               if (ids <= exynos5422_asv_limits[i].ids)
+                       break;
+               if (hpm <= exynos5422_asv_limits[i].hpm)
+                       break;
+       }
+
+       if (i < EXYNOS5422_ASV_NUM)
+               return i;
+       else
+               return 0;
+}
+
+static int exynos5422_asv_get_table(void)
+{
+       unsigned int pkg_id_reg = exynos_chipid_read(EXYNOS_CHIPID_REG_PKG_ID);
+
+       return  (pkg_id_reg >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
+}
+
+static int __asv_offset_voltage(unsigned int index)
+{
+       static const unsigned int offset_table[] = { 12500, 50000, 25000 };
+
+       if (index == 0 || index > 3)
+               return 0;
+
+       return offset_table[index - 1];
+}
+
+static void exynos5422_asv_offset_voltage_setup(void)
+{
+       struct exynos_asv_subsys *subsys;
+       unsigned int reg, value;
+
+       if (exynos_asv->bin2) {
+               exynos_asv->arm.dvfs_nr = EXYNOS5422_ARM_BIN2_DVFS_NUM;
+               exynos_asv->kfc.dvfs_nr = EXYNOS5422_KFC_BIN2_DVFS_NUM;
+       } else {
+               exynos_asv->arm.dvfs_nr = EXYNOS5422_ARM_DVFS_NUM;
+               exynos_asv->kfc.dvfs_nr = EXYNOS5422_KFC_DVFS_NUM;
+       }
+
+       reg = exynos_chipid_read(EXYNOS_CHIPID_AUX_INFO);
+
+       /* ARM offset voltage setup */
+       subsys = &exynos_asv->arm;
+
+       subsys->base_volt = 1000000;
+
+       value = (reg >> EXYNOS5422_ARM_UP_OFFSET) & EXYNOS5422_ARM_UP_MASK;
+       subsys->offset_volt_h = __asv_offset_voltage(value);
+
+       value = (reg >> EXYNOS5422_ARM_DN_OFFSET) & EXYNOS5422_ARM_DN_MASK;
+       subsys->offset_volt_l = __asv_offset_voltage(value);
+
+       /* KFC offset voltage setup */
+       subsys = &exynos_asv->kfc;
+
+       subsys->base_volt = 1000000;
+
+       value = (reg >> EXYNOS5422_KFC_UP_OFFSET) & EXYNOS5422_KFC_UP_MASK;
+       subsys->offset_volt_h = __asv_offset_voltage(value);
+
+       value = (reg >> EXYNOS5422_KFC_DN_OFFSET) & EXYNOS5422_KFC_DN_MASK;
+       subsys->offset_volt_l = __asv_offset_voltage(value);
+}
+
+int __init exynos5422_asv_init(struct exynos_asv *asv)
+{
+       exynos_asv = asv;
+
+       asv->bin2 = exynos5422_asv_get_bin2();
+
+       if (of_machine_is_compatible("hardkernel,odroid-xu3-lite"))
+               asv->bin2 = true;
+
+       asv->special_lot = exynos5422_asv_special_group_check();
+       asv->group = exynos5422_asv_get_group(asv);
+       asv->table = exynos5422_asv_get_table();
+
+       exynos5422_asv_offset_voltage_setup();
+
+       if (asv->bin2) {
+               asv->arm.asv_table = arm_info_bin2;
+               asv->kfc.asv_table = kfc_info_bin2;
+       } else {
+               switch(asv->table) {
+               case 2:
+                       asv->arm.asv_table = arm_info_table2;
+                       asv->kfc.asv_table = kfc_info_table2;
+                       break;
+               case 3:
+                       asv->arm.asv_table = arm_info_table3;
+                       asv->kfc.asv_table = kfc_info_table3;
+                       break;
+               default:
+                       asv->arm.asv_table = arm_info_table01;
+                       asv->kfc.asv_table = kfc_info_table01;
+                       break;
+               }
+       }
+
+       asv->arm.cpu_dt_compat = "arm,cortex-a15";
+       asv->kfc.cpu_dt_compat = "arm,cortex-a7";
+
+       asv->opp_get_voltage = exynos5422_asv_opp_get_voltage;
+
+
+       return 0;
+}
diff --git a/drivers/soc/samsung/exynos5422-asv.h b/drivers/soc/samsung/exynos5422-asv.h
new file mode 100644 (file)
index 0000000..9d994c5
--- /dev/null
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *           http://www.samsung.com/
+ *
+ * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
+ */
+
+#ifndef __EXYNOS5422_ASV_H
+#define __EXYNOS5422_ASV_H
+
+struct exynos_asv;
+int exynos5422_asv_init(struct exynos_asv *asv);
+
+#endif /* __EXYNOS5422_ASV_H */