Message ID | 20230827032803.934819-6-dmitry.baryshkov@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | cpufreq: qcom-nvmem: support apq8064 cpufreq scaling | expand |
On 27.08.2023 05:28, Dmitry Baryshkov wrote: > APQ8064 can scale core voltage according to the frequency needs. Rather > than reusing the A/B format multiplexer, use a simple fuse parsing > function and configure required regulator. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> > --- > drivers/cpufreq/qcom-cpufreq-nvmem.c | 49 ++++++++++++++++++++++++++-- > 1 file changed, 47 insertions(+), 2 deletions(-) > > diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c > index 81c080b854fe..35e2610c9526 100644 > --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c > +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c > @@ -26,6 +26,7 @@ > #include <linux/platform_device.h> > #include <linux/pm_domain.h> > #include <linux/pm_opp.h> > +#include <linux/regulator/consumer.h> > #include <linux/slab.h> > #include <linux/soc/qcom/smem.h> > > @@ -39,6 +40,7 @@ struct qcom_cpufreq_match_data { > char **pvs_name, > struct qcom_cpufreq_drv *drv); > const char **genpd_names; > + const char * const *regulator_names; > }; > > struct qcom_cpufreq_drv { > @@ -203,6 +205,34 @@ static int qcom_cpufreq_krait_name_version(struct device *cpu_dev, > return ret; > } > > +static int qcom_cpufreq_apq8064_name_version(struct device *cpu_dev, > + struct nvmem_cell *speedbin_nvmem, > + char **pvs_name, > + struct qcom_cpufreq_drv *drv) > +{ > + int speed = 0, pvs = 0; > + u8 *speedbin; > + size_t len; > + int ret = 0; Unused, just return 0 > + > + speedbin = nvmem_cell_read(speedbin_nvmem, &len); > + if (IS_ERR(speedbin)) > + return PTR_ERR(speedbin); > + > + if (len != 4) > + return -EINVAL; > + > + get_krait_bin_format_a(cpu_dev, &speed, &pvs, speedbin); > + > + snprintf(*pvs_name, sizeof("speedXX-pvsXX"), "speed%d-pvs%d", > + speed, pvs); speed and pvs are both one hex digit long at best (see masking in get_krait_bin_format_a) Konrad
On 28/08/2023 14:04, Konrad Dybcio wrote: > On 27.08.2023 05:28, Dmitry Baryshkov wrote: >> APQ8064 can scale core voltage according to the frequency needs. Rather >> than reusing the A/B format multiplexer, use a simple fuse parsing >> function and configure required regulator. >> >> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> >> --- >> drivers/cpufreq/qcom-cpufreq-nvmem.c | 49 ++++++++++++++++++++++++++-- >> 1 file changed, 47 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c >> index 81c080b854fe..35e2610c9526 100644 >> --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c >> +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c >> @@ -26,6 +26,7 @@ >> #include <linux/platform_device.h> >> #include <linux/pm_domain.h> >> #include <linux/pm_opp.h> >> +#include <linux/regulator/consumer.h> >> #include <linux/slab.h> >> #include <linux/soc/qcom/smem.h> >> >> @@ -39,6 +40,7 @@ struct qcom_cpufreq_match_data { >> char **pvs_name, >> struct qcom_cpufreq_drv *drv); >> const char **genpd_names; >> + const char * const *regulator_names; >> }; >> >> struct qcom_cpufreq_drv { >> @@ -203,6 +205,34 @@ static int qcom_cpufreq_krait_name_version(struct device *cpu_dev, >> return ret; >> } >> >> +static int qcom_cpufreq_apq8064_name_version(struct device *cpu_dev, >> + struct nvmem_cell *speedbin_nvmem, >> + char **pvs_name, >> + struct qcom_cpufreq_drv *drv) >> +{ >> + int speed = 0, pvs = 0; >> + u8 *speedbin; >> + size_t len; >> + int ret = 0; > Unused, just return 0 > >> + >> + speedbin = nvmem_cell_read(speedbin_nvmem, &len); >> + if (IS_ERR(speedbin)) >> + return PTR_ERR(speedbin); >> + >> + if (len != 4) >> + return -EINVAL; >> + >> + get_krait_bin_format_a(cpu_dev, &speed, &pvs, speedbin); >> + >> + snprintf(*pvs_name, sizeof("speedXX-pvsXX"), "speed%d-pvs%d", >> + speed, pvs); > speed and pvs are both one hex digit long at best (see masking in > get_krait_bin_format_a) One hex translates to two decimal digits (0xf = 15). > > Konrad
diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c index 81c080b854fe..35e2610c9526 100644 --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c @@ -26,6 +26,7 @@ #include <linux/platform_device.h> #include <linux/pm_domain.h> #include <linux/pm_opp.h> +#include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/soc/qcom/smem.h> @@ -39,6 +40,7 @@ struct qcom_cpufreq_match_data { char **pvs_name, struct qcom_cpufreq_drv *drv); const char **genpd_names; + const char * const *regulator_names; }; struct qcom_cpufreq_drv { @@ -203,6 +205,34 @@ static int qcom_cpufreq_krait_name_version(struct device *cpu_dev, return ret; } +static int qcom_cpufreq_apq8064_name_version(struct device *cpu_dev, + struct nvmem_cell *speedbin_nvmem, + char **pvs_name, + struct qcom_cpufreq_drv *drv) +{ + int speed = 0, pvs = 0; + u8 *speedbin; + size_t len; + int ret = 0; + + speedbin = nvmem_cell_read(speedbin_nvmem, &len); + if (IS_ERR(speedbin)) + return PTR_ERR(speedbin); + + if (len != 4) + return -EINVAL; + + get_krait_bin_format_a(cpu_dev, &speed, &pvs, speedbin); + + snprintf(*pvs_name, sizeof("speedXX-pvsXX"), "speed%d-pvs%d", + speed, pvs); + + drv->versions = (1 << speed); + + kfree(speedbin); + return ret; +} + static const struct qcom_cpufreq_match_data match_data_kryo = { .get_version = qcom_cpufreq_kryo_name_version, }; @@ -217,6 +247,16 @@ static const struct qcom_cpufreq_match_data match_data_qcs404 = { .genpd_names = qcs404_genpd_names, }; +static const char * apq8064_regulator_names[] = { + "vdd-core", + NULL +}; + +static const struct qcom_cpufreq_match_data match_data_apq8064 = { + .get_version = qcom_cpufreq_apq8064_name_version, + .regulator_names = apq8064_regulator_names, +}; + static int qcom_cpufreq_probe(struct platform_device *pdev) { struct qcom_cpufreq_drv *drv; @@ -304,7 +344,12 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) config.virt_devs = NULL; } - if (config.supported_hw || config.genpd_names) { + if (drv->data->regulator_names) + config.regulator_names = drv->data->regulator_names; + + if (config.supported_hw || + config.genpd_names || + config.regulator_names) { drv->opp_tokens[cpu] = dev_pm_opp_set_config(cpu_dev, &config); if (drv->opp_tokens[cpu] < 0) { ret = drv->opp_tokens[cpu]; @@ -361,7 +406,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,apq8064", .data = &match_data_krait }, + { .compatible = "qcom,apq8064", .data = &match_data_apq8064 }, { .compatible = "qcom,msm8974", .data = &match_data_krait }, { .compatible = "qcom,msm8960", .data = &match_data_krait }, {},
APQ8064 can scale core voltage according to the frequency needs. Rather than reusing the A/B format multiplexer, use a simple fuse parsing function and configure required regulator. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/cpufreq/qcom-cpufreq-nvmem.c | 49 ++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-)