]> www.infradead.org Git - users/hch/misc.git/commitdiff
cpufreq: tegra186: Initialize all cores to max frequencies
authorAaron Kling <webgeek1234@gmail.com>
Fri, 29 Aug 2025 02:48:13 +0000 (21:48 -0500)
committerViresh Kumar <viresh.kumar@linaro.org>
Mon, 29 Sep 2025 09:25:50 +0000 (14:55 +0530)
During initialization, the EDVD_COREx_VOLT_FREQ registers for some cores
are still at reset values and not reflecting the actual frequency. This
causes get calls to fail. Set all cores to their respective max
frequency during probe to initialize the registers to working values.

Suggested-by: Mikko Perttunen <mperttunen@nvidia.com>
Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
drivers/cpufreq/tegra186-cpufreq.c

index a9e1f9bd2a4e9be37921609d5ae172ffa65ba6f2..136ab102f636aa57741639ed1909d095881c14d3 100644 (file)
@@ -136,13 +136,14 @@ static struct cpufreq_driver tegra186_cpufreq_driver = {
 
 static struct cpufreq_frequency_table *init_vhint_table(
        struct platform_device *pdev, struct tegra_bpmp *bpmp,
-       struct tegra186_cpufreq_cluster *cluster, unsigned int cluster_id)
+       struct tegra186_cpufreq_cluster *cluster, unsigned int cluster_id,
+       int *num_rates)
 {
        struct cpufreq_frequency_table *table;
        struct mrq_cpu_vhint_request req;
        struct tegra_bpmp_message msg;
        struct cpu_vhint_data *data;
-       int err, i, j, num_rates = 0;
+       int err, i, j;
        dma_addr_t phys;
        void *virt;
 
@@ -172,6 +173,7 @@ static struct cpufreq_frequency_table *init_vhint_table(
                goto free;
        }
 
+       *num_rates = 0;
        for (i = data->vfloor; i <= data->vceil; i++) {
                u16 ndiv = data->ndiv[i];
 
@@ -182,10 +184,10 @@ static struct cpufreq_frequency_table *init_vhint_table(
                if (i > 0 && ndiv == data->ndiv[i - 1])
                        continue;
 
-               num_rates++;
+               (*num_rates)++;
        }
 
-       table = devm_kcalloc(&pdev->dev, num_rates + 1, sizeof(*table),
+       table = devm_kcalloc(&pdev->dev, *num_rates + 1, sizeof(*table),
                             GFP_KERNEL);
        if (!table) {
                table = ERR_PTR(-ENOMEM);
@@ -227,7 +229,9 @@ static int tegra186_cpufreq_probe(struct platform_device *pdev)
 {
        struct tegra186_cpufreq_data *data;
        struct tegra_bpmp *bpmp;
-       unsigned int i = 0, err;
+       unsigned int i = 0, err, edvd_offset;
+       int num_rates = 0;
+       u32 edvd_val, cpu;
 
        data = devm_kzalloc(&pdev->dev,
                            struct_size(data, clusters, TEGRA186_NUM_CLUSTERS),
@@ -250,10 +254,21 @@ static int tegra186_cpufreq_probe(struct platform_device *pdev)
        for (i = 0; i < TEGRA186_NUM_CLUSTERS; i++) {
                struct tegra186_cpufreq_cluster *cluster = &data->clusters[i];
 
-               cluster->table = init_vhint_table(pdev, bpmp, cluster, i);
+               cluster->table = init_vhint_table(pdev, bpmp, cluster, i, &num_rates);
                if (IS_ERR(cluster->table)) {
                        err = PTR_ERR(cluster->table);
                        goto put_bpmp;
+               } else if (!num_rates) {
+                       err = -EINVAL;
+                       goto put_bpmp;
+               }
+
+               for (cpu = 0; cpu < ARRAY_SIZE(tegra186_cpus); cpu++) {
+                       if (data->cpus[cpu].bpmp_cluster_id == i) {
+                               edvd_val = cluster->table[num_rates - 1].driver_data;
+                               edvd_offset = data->cpus[cpu].edvd_offset;
+                               writel(edvd_val, data->regs + edvd_offset);
+                       }
                }
        }