diff options
-rw-r--r-- | drivers/cpufreq/cpufreq-dt-platdev.c | 1 | ||||
-rw-r--r-- | drivers/cpufreq/qcom-cpufreq-nvmem.c | 66 |
2 files changed, 67 insertions, 0 deletions
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index 6ac3800db450..98883290f183 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c @@ -163,6 +163,7 @@ static const struct of_device_id blocklist[] __initconst = { { .compatible = "qcom,ipq8064", }, { .compatible = "qcom,apq8064", }, + { .compatible = "qcom,msm8939", }, { .compatible = "qcom,msm8974", }, { .compatible = "qcom,msm8960", }, diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c index c0092cbd3ee2..105f7ddcc794 100644 --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c @@ -403,12 +403,78 @@ static struct platform_driver qcom_cpufreq_driver = { }, }; +static int qcom_cpufreq_msm8939_name_version(struct device *cpu_dev, + struct nvmem_cell *speedbin_nvmem, + char **pvs_name, + size_t pvs_name_size, + struct qcom_cpufreq_drv *drv) +{ + int speed = 0, pvs = 0; + u8 *speedbin; + size_t len; + + speedbin = nvmem_cell_read(speedbin_nvmem, &len); + if (IS_ERR(speedbin)) + return PTR_ERR(speedbin); + + if (len != 16) { + dev_err(cpu_dev, + "expected to read 16 bytes but got %zu bytes instead\n", + len); + kfree(speedbin); + return -EIO; + } + + speed = (speedbin[0xc] >> 2) & 0x7; + pvs = (speedbin[0x3] >> 5 & 0x1) | ((speedbin[0x6] >> 2 & 0x3) << 1); + kfree(speedbin); + + dev_dbg(cpu_dev, "Speed %d, PVS %d\n", speed, pvs); + + snprintf(*pvs_name, pvs_name_size, "speed%d-pvs%d", speed, pvs); + + /* + * Convert speedbin and PVS into version bit map: + * speed0-bin-v0: 0x1 + * speed2-bin-v0: 0x2 + * speed2-bin-v2: 0x4 + * speed4-bin-v0: 0x8 + * speed5-bin-v0: 0x10 + * speed5-bin-v6: 0x20 + * otherwise: 0x1 + */ + if (speed == 0 && pvs == 0) + drv->versions = 0x1; + else if (speed == 2 && pvs == 0) + drv->versions = 0x2; + else if (speed == 2 && pvs == 2) + drv->versions = 0x4; + else if (speed == 4 && pvs == 0) + drv->versions = 0x8; + else if (speed == 5 && pvs == 0) + drv->versions = 0x10; + else if (speed == 5 && pvs == 6) + drv->versions = 0x20; + else + drv->versions = 0x1; + + return 0; +} + +static const char *msm8939_genpd_names[] = { "cpr", NULL }; + +static const struct qcom_cpufreq_match_data match_data_msm8939 = { + .get_version = qcom_cpufreq_msm8939_name_version, + .genpd_names = msm8939_genpd_names, +}; + 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,apq8064", .data = &match_data_krait }, + { .compatible = "qcom,msm8939", .data = &match_data_msm8939 }, { .compatible = "qcom,msm8974", .data = &match_data_krait }, { .compatible = "qcom,msm8960", .data = &match_data_krait }, {}, |