From: Sylwester Nawrocki Date: Wed, 30 Jan 2019 16:55:49 +0000 (+0100) Subject: soc: samsung: Split the ASV driver into common and SoC-specific part X-Git-Tag: submit/tizen/20190329.020226~87 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cf7711dad856c53cb08a5e49a6083b0ceee30948;p=platform%2Fkernel%2Flinux-exynos.git soc: samsung: Split the ASV driver into common and SoC-specific part The exynos-asv driver is re-factored as a prerequisite for adding support for other SoCs. Change-Id: I252a2f51d101ad39b0469ee7f31f69cd9f0120b5 Signed-off-by: Sylwester Nawrocki --- diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile index cd5498ad464f..d6118f53379d 100644 --- a/drivers/soc/samsung/Makefile +++ b/drivers/soc/samsung/Makefile @@ -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 diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c index 7117f925c96b..6373fce0f24a 100644 --- a/drivers/soc/samsung/exynos-asv.c +++ b/drivers/soc/samsung/exynos-asv.c @@ -12,381 +12,41 @@ #include #include #include -#include #include -#include -#include #include #include +#include -#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 index 000000000000..b0f70fdea801 --- /dev/null +++ b/drivers/soc/samsung/exynos-asv.h @@ -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 index 000000000000..750becd6cbda --- /dev/null +++ b/drivers/soc/samsung/exynos5422-asv.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 index 000000000000..9d994c5d0de4 --- /dev/null +++ b/drivers/soc/samsung/exynos5422-asv.h @@ -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 */