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 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: a8811ec764 ("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>
This commit is contained in:
Christian Marangi 2023-10-25 15:04:27 +05:30 committed by Viresh Kumar
parent ff63282ed2
commit 4a3754f73e

View File

@ -30,6 +30,12 @@
#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 },