cpufreq: qcom-nvmem: add support for IPQ8064
authorChristian Marangi <ansuelsmth@gmail.com>
Wed, 25 Oct 2023 09:34:27 +0000 (15:04 +0530)
committerViresh Kumar <viresh.kumar@linaro.org>
Wed, 25 Oct 2023 10:21:10 +0000 (15:51 +0530)
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 support one OPP table, add support for
IPQ8064 family based of SMEM SoC ID-s and correctly set the version so
opp-supported-hw can be correctly used.

Bit are set with the following logic:
* IPQ8062 BIT 0
* IPQ8064/IPQ8066/IPQ8068 BIT 1
* IPQ8065/IPQ8069 BIT 2

speed is never fused, only pvs values are fused.

IPQ806x SoC doesn't have pvs_version so we drop and we use the new
pattern:
opp-microvolt-speed0-pvs<PSV_VALUE>

Example:
- for ipq8062 psv2
  opp-microvolt-speed0-pvs2 = < 925000 878750 971250>

Fixes: a8811ec764f9 ("cpufreq: qcom: Add support for krait based socs")
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
[ Viresh: Fixed rebase conflict. ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
drivers/cpufreq/qcom-cpufreq-nvmem.c

index ba6720351a4ca73ff7e0292a106ba0336b107490..15367ac08b2b8c55d5bb7d8cf92c633136681409 100644 (file)
 
 #include <dt-bindings/arm/qcom,ids.h>
 
+enum ipq806x_versions {
+       IPQ8062_VERSION = 0,
+       IPQ8064_VERSION,
+       IPQ8065_VERSION,
+};
+
 #define IPQ6000_VERSION        BIT(2)
 
 struct qcom_cpufreq_drv;
@@ -226,6 +232,61 @@ len_error:
        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;
+       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);
+
+       if (len != 4) {
+               dev_err(cpu_dev, "Unable to read nvmem data. Defaulting to 0!\n");
+               ret = -ENODEV;
+               goto exit;
+       }
+
+       get_krait_bin_format_a(cpu_dev, &speed, &pvs, speedbin);
+
+       ret = qcom_smem_get_soc_id(&msm_id);
+       if (ret)
+               goto exit;
+
+       switch (msm_id) {
+       case QCOM_ID_IPQ8062:
+               drv->versions = BIT(IPQ8062_VERSION);
+               break;
+       case QCOM_ID_IPQ8064:
+       case QCOM_ID_IPQ8066:
+       case QCOM_ID_IPQ8068:
+               drv->versions = BIT(IPQ8064_VERSION);
+               break;
+       case QCOM_ID_IPQ8065:
+       case QCOM_ID_IPQ8069:
+               drv->versions = BIT(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 = BIT(IPQ8062_VERSION);
+               break;
+       }
+
+       /* IPQ8064 speed is never fused. Only pvs values are fused. */
+       snprintf(*pvs_name, sizeof("speed0-pvsXX"), "speed0-pvs%d", pvs);
+
+exit:
+       kfree(speedbin);
+       return ret;
+}
+
 static int qcom_cpufreq_ipq6018_name_version(struct device *cpu_dev,
                                             struct nvmem_cell *speedbin_nvmem,
                                             char **pvs_name,
@@ -302,6 +363,10 @@ static const struct qcom_cpufreq_match_data match_data_ipq6018 = {
        .get_version = qcom_cpufreq_ipq6018_name_version,
 };
 
+static const struct qcom_cpufreq_match_data match_data_ipq8064 = {
+       .get_version = qcom_cpufreq_ipq8064_name_version,
+};
+
 static int qcom_cpufreq_probe(struct platform_device *pdev)
 {
        struct qcom_cpufreq_drv *drv;
@@ -430,7 +495,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,ipq6018", .data = &match_data_ipq6018 },
-       { .compatible = "qcom,ipq8064", .data = &match_data_krait },
+       { .compatible = "qcom,ipq8064", .data = &match_data_ipq8064 },
        { .compatible = "qcom,apq8064", .data = &match_data_krait },
        { .compatible = "qcom,msm8974", .data = &match_data_krait },
        { .compatible = "qcom,msm8960", .data = &match_data_krait },