Last active
May 30, 2023 15:22
-
-
Save robimarko/fbfa9fcc5b6fb00d5141adeec89236c2 to your computer and use it in GitHub Desktop.
NVMEM CPUFREQ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 80dc7a28475513c2b84df0d220c117c6bb978dd3 Mon Sep 17 00:00:00 2001 | |
From: Robert Marko <robimarko@gmail.com> | |
Date: Sat, 31 Dec 2022 13:03:41 +0100 | |
Subject: [PATCH 1/2] cpufreq: qcom-nvmem: add support for IPQ8074 | |
IPQ8074 comes in 2 families: | |
* IPQ8070A/IPQ8071A (Acorn) up to 1.4GHz | |
* IPQ8072A/IPQ8074A/IPQ8076A/IPQ8078A (Hawkeye) up to 2.2GHz | |
So, in order to be able to share one OPP table lets add support for IPQ8074 | |
family based of SMEM SoC ID-s as speedbin fuse is always 0 on IPQ8074. | |
IPQ8074 compatible is blacklisted from DT platdev as the cpufreq device | |
will get created by NVMEM CPUFreq driver. | |
Signed-off-by: Robert Marko <robimarko@gmail.com> | |
--- | |
Changes in v2: | |
* Print an error if SMEM ID is not part of the IPQ8074 family | |
and restrict the speed to Acorn variant (1.4GHz) | |
--- | |
drivers/cpufreq/cpufreq-dt-platdev.c | 1 + | |
drivers/cpufreq/qcom-cpufreq-nvmem.c | 43 ++++++++++++++++++++++++++++ | |
2 files changed, 44 insertions(+) | |
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c | |
index ea86c9f3ed7a..78f6ff933f93 100644 | |
--- a/drivers/cpufreq/cpufreq-dt-platdev.c | |
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c | |
@@ -170,6 +170,7 @@ static const struct of_device_id blocklist[] __initconst = { | |
{ .compatible = "ti,am62a7", }, | |
{ .compatible = "qcom,ipq8064", }, | |
+ { .compatible = "qcom,ipq8074", }, | |
{ .compatible = "qcom,apq8064", }, | |
{ .compatible = "qcom,msm8974", }, | |
{ .compatible = "qcom,msm8960", }, | |
diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c | |
index a88b6fe5db50..ce444b5962f2 100644 | |
--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c | |
+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c | |
@@ -31,6 +31,9 @@ | |
#include <dt-bindings/arm/qcom,ids.h> | |
+#define IPQ8074_HAWKEYE_VERSION BIT(0) | |
+#define IPQ8074_ACORN_VERSION BIT(1) | |
+ | |
struct qcom_cpufreq_drv; | |
struct qcom_cpufreq_match_data { | |
@@ -204,6 +207,41 @@ static int qcom_cpufreq_krait_name_version(struct device *cpu_dev, | |
return ret; | |
} | |
+static int qcom_cpufreq_ipq8074_name_version(struct device *cpu_dev, | |
+ struct nvmem_cell *speedbin_nvmem, | |
+ char **pvs_name, | |
+ struct qcom_cpufreq_drv *drv) | |
+{ | |
+ u32 msm_id; | |
+ int ret; | |
+ *pvs_name = NULL; | |
+ | |
+ ret = qcom_smem_get_soc_id(&msm_id); | |
+ if (ret) | |
+ return ret; | |
+ | |
+ switch (msm_id) { | |
+ case QCOM_ID_IPQ8070A: | |
+ case QCOM_ID_IPQ8071A: | |
+ drv->versions = IPQ8074_ACORN_VERSION; | |
+ break; | |
+ case QCOM_ID_IPQ8072A: | |
+ case QCOM_ID_IPQ8074A: | |
+ case QCOM_ID_IPQ8076A: | |
+ case QCOM_ID_IPQ8078A: | |
+ drv->versions = IPQ8074_HAWKEYE_VERSION; | |
+ break; | |
+ default: | |
+ dev_err(cpu_dev, | |
+ "SoC ID %u is not part of IPQ8074 family, limiting to 1.4GHz!\n", | |
+ msm_id); | |
+ drv->versions = IPQ8074_ACORN_VERSION; | |
+ break; | |
+ } | |
+ | |
+ return 0; | |
+} | |
+ | |
static const struct qcom_cpufreq_match_data match_data_kryo = { | |
.get_version = qcom_cpufreq_kryo_name_version, | |
}; | |
@@ -218,6 +256,10 @@ static const struct qcom_cpufreq_match_data match_data_qcs404 = { | |
.genpd_names = qcs404_genpd_names, | |
}; | |
+static const struct qcom_cpufreq_match_data match_data_ipq8074 = { | |
+ .get_version = qcom_cpufreq_ipq8074_name_version, | |
+}; | |
+ | |
static int qcom_cpufreq_probe(struct platform_device *pdev) | |
{ | |
struct qcom_cpufreq_drv *drv; | |
@@ -363,6 +405,7 @@ static const struct of_device_id qcom_cpufreq_match_list[] __initconst = { | |
{ .compatible = "qcom,msm8996", .data = &match_data_kryo }, | |
{ .compatible = "qcom,qcs404", .data = &match_data_qcs404 }, | |
{ .compatible = "qcom,ipq8064", .data = &match_data_krait }, | |
+ { .compatible = "qcom,ipq8074", .data = &match_data_ipq8074 }, | |
{ .compatible = "qcom,apq8064", .data = &match_data_krait }, | |
{ .compatible = "qcom,msm8974", .data = &match_data_krait }, | |
{ .compatible = "qcom,msm8960", .data = &match_data_krait }, | |
-- | |
2.40.1 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 5d90f5ee4b7cb7ca1bb31ecbf7274a3a63310402 Mon Sep 17 00:00:00 2001 | |
From: Christian Marangi <ansuelsmth@gmail.com> | |
Date: Mon, 23 Jan 2023 22:39:57 +0100 | |
Subject: [PATCH 2/2] cpufreq: qcom-nvmem: add support for IPQ8064 | |
IPQ8064 comes in 3 families: | |
* IPQ8062 up to 1.0GHz | |
* IPQ8064/IPQ8066/IPQ8068 up to 1.4GHz | |
* IPQ8065/IPQ8069 up to 1.7Ghz | |
So, in order to be able to share one OPP table, add support for | |
IPQ8064 family based of SMEM SoC ID-s as speedbin fuse is always 0 on | |
IPQ8064. | |
Bit are set with the following logic: | |
* IPQ8062 BIT 0 | |
* IPQ8064/IPQ8066/IPQ8068 BIT 1 | |
* IPQ8065/IPQ8069 BIT 2 | |
speed is never fused, only psv values are fused. | |
Set speed to the versions to permit a unified opp table following | |
this named opp: | |
opp-microvolt-speed<SPEED_VALUE>-pvs<PSV_VALUE>-v0 | |
Example: | |
- for ipq8062 psv2 | |
opp-microvolt-speed0-pvs2-v0 = < 925000 878750 971250> | |
- for ipq8064 psv2 | |
opp-microvolt-speed2-pvs2-v0 = <925000 878750 971250>; | |
- for ipq8065 psv2 | |
opp-microvolt-speed4-pvs2-v0 = <950000 902500 997500>; | |
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> | |
Signed-off-by: Robert Marko <robimarko@gmail.com> | |
--- | |
drivers/cpufreq/qcom-cpufreq-nvmem.c | 73 +++++++++++++++++++++++++++- | |
1 file changed, 72 insertions(+), 1 deletion(-) | |
diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c | |
index ce444b5962f2..c644138680ba 100644 | |
--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c | |
+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c | |
@@ -34,6 +34,10 @@ | |
#define IPQ8074_HAWKEYE_VERSION BIT(0) | |
#define IPQ8074_ACORN_VERSION BIT(1) | |
+#define IPQ8062_VERSION BIT(0) | |
+#define IPQ8064_VERSION BIT(1) | |
+#define IPQ8065_VERSION BIT(2) | |
+ | |
struct qcom_cpufreq_drv; | |
struct qcom_cpufreq_match_data { | |
@@ -207,6 +211,69 @@ static int qcom_cpufreq_krait_name_version(struct device *cpu_dev, | |
return ret; | |
} | |
+static int qcom_cpufreq_ipq8064_name_version(struct device *cpu_dev, | |
+ struct nvmem_cell *speedbin_nvmem, | |
+ char **pvs_name, | |
+ struct qcom_cpufreq_drv *drv) | |
+{ | |
+ int speed = 0, pvs = 0, pvs_ver = 0; | |
+ int msm_id, ret = 0; | |
+ u8 *speedbin; | |
+ size_t len; | |
+ | |
+ speedbin = nvmem_cell_read(speedbin_nvmem, &len); | |
+ | |
+ if (IS_ERR(speedbin)) | |
+ return PTR_ERR(speedbin); | |
+ | |
+ switch (len) { | |
+ case 4: | |
+ get_krait_bin_format_a(cpu_dev, &speed, &pvs, &pvs_ver, | |
+ speedbin); | |
+ break; | |
+ default: | |
+ dev_err(cpu_dev, "Unable to read nvmem data. Defaulting to 0!\n"); | |
+ ret = -ENODEV; | |
+ goto len_error; | |
+ } | |
+ | |
+ ret = qcom_smem_get_soc_id(&msm_id); | |
+ if (ret) | |
+ return ret; | |
+ | |
+ switch (msm_id) { | |
+ case QCOM_ID_IPQ8062: | |
+ drv->versions = IPQ8062_VERSION; | |
+ break; | |
+ case QCOM_ID_IPQ8064: | |
+ case QCOM_ID_IPQ8066: | |
+ case QCOM_ID_IPQ8068: | |
+ drv->versions = IPQ8064_VERSION; | |
+ break; | |
+ case QCOM_ID_IPQ8065: | |
+ case QCOM_ID_IPQ8069: | |
+ drv->versions = IPQ8065_VERSION; | |
+ break; | |
+ default: | |
+ dev_err(cpu_dev, | |
+ "SoC ID %u is not part of IPQ8064 family, limiting to 1.0GHz!\n", | |
+ msm_id); | |
+ drv->versions = IPQ8062_VERSION; | |
+ break; | |
+ } | |
+ | |
+ /* | |
+ * IPQ8064 speed is never fused. Only psv values are fused. | |
+ * Set speed to the versions to permit a unified opp table. | |
+ */ | |
+ snprintf(*pvs_name, sizeof("speedXX-pvsXX-vXX"), "speed%d-pvs%d-v%d", | |
+ drv->versions, pvs, pvs_ver); | |
+ | |
+len_error: | |
+ kfree(speedbin); | |
+ return ret; | |
+} | |
+ | |
static int qcom_cpufreq_ipq8074_name_version(struct device *cpu_dev, | |
struct nvmem_cell *speedbin_nvmem, | |
char **pvs_name, | |
@@ -256,6 +323,10 @@ static const struct qcom_cpufreq_match_data match_data_qcs404 = { | |
.genpd_names = qcs404_genpd_names, | |
}; | |
+static const struct qcom_cpufreq_match_data match_data_ipq8064 = { | |
+ .get_version = qcom_cpufreq_ipq8064_name_version, | |
+}; | |
+ | |
static const struct qcom_cpufreq_match_data match_data_ipq8074 = { | |
.get_version = qcom_cpufreq_ipq8074_name_version, | |
}; | |
@@ -404,7 +475,7 @@ static const struct of_device_id qcom_cpufreq_match_list[] __initconst = { | |
{ .compatible = "qcom,apq8096", .data = &match_data_kryo }, | |
{ .compatible = "qcom,msm8996", .data = &match_data_kryo }, | |
{ .compatible = "qcom,qcs404", .data = &match_data_qcs404 }, | |
- { .compatible = "qcom,ipq8064", .data = &match_data_krait }, | |
+ { .compatible = "qcom,ipq8064", .data = &match_data_ipq8064 }, | |
{ .compatible = "qcom,ipq8074", .data = &match_data_ipq8074 }, | |
{ .compatible = "qcom,apq8064", .data = &match_data_krait }, | |
{ .compatible = "qcom,msm8974", .data = &match_data_krait }, | |
-- | |
2.40.1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment