3939/* cpufreq transisition latency */
4040#define TEGRA_CPUFREQ_TRANSITION_LATENCY (300 * 1000) /* unit in nanoseconds */
4141
42+ struct tegra_cpu_data {
43+ u32 cpuid ;
44+ u32 clusterid ;
45+ void __iomem * freq_core_reg ;
46+ };
47+
4248struct tegra_cpu_ctr {
4349 u32 cpu ;
4450 u32 coreclk_cnt , last_coreclk_cnt ;
@@ -69,6 +75,7 @@ struct tegra194_cpufreq_data {
6975 struct cpufreq_frequency_table * * bpmp_luts ;
7076 const struct tegra_cpufreq_soc * soc ;
7177 bool icc_dram_bw_scaling ;
78+ struct tegra_cpu_data * cpu_data ;
7279};
7380
7481static struct workqueue_struct * read_counters_wq ;
@@ -116,34 +123,19 @@ static void tegra234_get_cpu_cluster_id(u32 cpu, u32 *cpuid, u32 *clusterid)
116123static int tegra234_get_cpu_ndiv (u32 cpu , u32 cpuid , u32 clusterid , u64 * ndiv )
117124{
118125 struct tegra194_cpufreq_data * data = cpufreq_get_driver_data ();
119- void __iomem * freq_core_reg ;
120- u64 mpidr_id ;
121-
122- /* use physical id to get address of per core frequency register */
123- mpidr_id = (clusterid * data -> soc -> maxcpus_per_cluster ) + cpuid ;
124- freq_core_reg = SCRATCH_FREQ_CORE_REG (data , mpidr_id );
125126
126- * ndiv = readl (freq_core_reg ) & NDIV_MASK ;
127+ * ndiv = readl (data -> cpu_data [ cpu ]. freq_core_reg ) & NDIV_MASK ;
127128
128129 return 0 ;
129130}
130131
131132static void tegra234_set_cpu_ndiv (struct cpufreq_policy * policy , u64 ndiv )
132133{
133134 struct tegra194_cpufreq_data * data = cpufreq_get_driver_data ();
134- void __iomem * freq_core_reg ;
135- u32 cpu , cpuid , clusterid ;
136- u64 mpidr_id ;
137-
138- for_each_cpu_and (cpu , policy -> cpus , cpu_online_mask ) {
139- data -> soc -> ops -> get_cpu_cluster_id (cpu , & cpuid , & clusterid );
140-
141- /* use physical id to get address of per core frequency register */
142- mpidr_id = (clusterid * data -> soc -> maxcpus_per_cluster ) + cpuid ;
143- freq_core_reg = SCRATCH_FREQ_CORE_REG (data , mpidr_id );
135+ u32 cpu ;
144136
145- writel ( ndiv , freq_core_reg );
146- }
137+ for_each_cpu_and ( cpu , policy -> cpus , cpu_online_mask )
138+ writel ( ndiv , data -> cpu_data [ cpu ]. freq_core_reg );
147139}
148140
149141/*
@@ -157,11 +149,10 @@ static void tegra234_read_counters(struct tegra_cpu_ctr *c)
157149{
158150 struct tegra194_cpufreq_data * data = cpufreq_get_driver_data ();
159151 void __iomem * actmon_reg ;
160- u32 cpuid , clusterid ;
161152 u64 val ;
162153
163- data -> soc -> ops -> get_cpu_cluster_id ( c -> cpu , & cpuid , & clusterid );
164- actmon_reg = CORE_ACTMON_CNTR_REG ( data , clusterid , cpuid );
154+ actmon_reg = CORE_ACTMON_CNTR_REG ( data , data -> cpu_data [ c -> cpu ]. clusterid ,
155+ data -> cpu_data [ c -> cpu ]. cpuid );
165156
166157 val = readq (actmon_reg );
167158 c -> last_refclk_cnt = upper_32_bits (val );
@@ -357,19 +348,17 @@ static void tegra194_set_cpu_ndiv(struct cpufreq_policy *policy, u64 ndiv)
357348static unsigned int tegra194_get_speed (u32 cpu )
358349{
359350 struct tegra194_cpufreq_data * data = cpufreq_get_driver_data ();
351+ u32 clusterid = data -> cpu_data [cpu ].clusterid ;
360352 struct cpufreq_frequency_table * pos ;
361- u32 cpuid , clusterid ;
362353 unsigned int rate ;
363354 u64 ndiv ;
364355 int ret ;
365356
366- data -> soc -> ops -> get_cpu_cluster_id (cpu , & cpuid , & clusterid );
367-
368357 /* reconstruct actual cpu freq using counters */
369358 rate = tegra194_calculate_speed (cpu );
370359
371360 /* get last written ndiv value */
372- ret = data -> soc -> ops -> get_cpu_ndiv (cpu , cpuid , clusterid , & ndiv );
361+ ret = data -> soc -> ops -> get_cpu_ndiv (cpu , data -> cpu_data [ cpu ]. cpuid , clusterid , & ndiv );
373362 if (WARN_ON_ONCE (ret ))
374363 return rate ;
375364
@@ -475,13 +464,12 @@ static int tegra194_cpufreq_init(struct cpufreq_policy *policy)
475464{
476465 struct tegra194_cpufreq_data * data = cpufreq_get_driver_data ();
477466 int maxcpus_per_cluster = data -> soc -> maxcpus_per_cluster ;
467+ u32 clusterid = data -> cpu_data [policy -> cpu ].clusterid ;
478468 struct cpufreq_frequency_table * freq_table ;
479469 struct cpufreq_frequency_table * bpmp_lut ;
480470 u32 start_cpu , cpu ;
481- u32 clusterid ;
482471 int ret ;
483472
484- data -> soc -> ops -> get_cpu_cluster_id (policy -> cpu , NULL , & clusterid );
485473 if (clusterid >= data -> soc -> num_clusters || !data -> bpmp_luts [clusterid ])
486474 return - EINVAL ;
487475
@@ -659,13 +647,36 @@ tegra_cpufreq_bpmp_read_lut(struct platform_device *pdev, struct tegra_bpmp *bpm
659647 return freq_table ;
660648}
661649
650+ static int tegra194_cpufreq_store_physids (unsigned int cpu , struct tegra194_cpufreq_data * data )
651+ {
652+ int num_cpus = data -> soc -> maxcpus_per_cluster * data -> soc -> num_clusters ;
653+ u32 cpuid , clusterid ;
654+ u64 mpidr_id ;
655+
656+ if (cpu > (num_cpus - 1 )) {
657+ pr_err ("cpufreq: wrong num of cpus or clusters in soc data\n" );
658+ return - EINVAL ;
659+ }
660+
661+ data -> soc -> ops -> get_cpu_cluster_id (cpu , & cpuid , & clusterid );
662+
663+ mpidr_id = (clusterid * data -> soc -> maxcpus_per_cluster ) + cpuid ;
664+
665+ data -> cpu_data [cpu ].cpuid = cpuid ;
666+ data -> cpu_data [cpu ].clusterid = clusterid ;
667+ data -> cpu_data [cpu ].freq_core_reg = SCRATCH_FREQ_CORE_REG (data , mpidr_id );
668+
669+ return 0 ;
670+ }
671+
662672static int tegra194_cpufreq_probe (struct platform_device * pdev )
663673{
664674 const struct tegra_cpufreq_soc * soc ;
665675 struct tegra194_cpufreq_data * data ;
666676 struct tegra_bpmp * bpmp ;
667677 struct device * cpu_dev ;
668678 int err , i ;
679+ u32 cpu ;
669680
670681 data = devm_kzalloc (& pdev -> dev , sizeof (* data ), GFP_KERNEL );
671682 if (!data )
@@ -692,6 +703,12 @@ static int tegra194_cpufreq_probe(struct platform_device *pdev)
692703 return PTR_ERR (data -> regs );
693704 }
694705
706+ data -> cpu_data = devm_kcalloc (& pdev -> dev , data -> soc -> num_clusters *
707+ data -> soc -> maxcpus_per_cluster ,
708+ sizeof (* data -> cpu_data ), GFP_KERNEL );
709+ if (!data -> cpu_data )
710+ return - ENOMEM ;
711+
695712 platform_set_drvdata (pdev , data );
696713
697714 bpmp = tegra_bpmp_get (& pdev -> dev );
@@ -713,6 +730,12 @@ static int tegra194_cpufreq_probe(struct platform_device *pdev)
713730 }
714731 }
715732
733+ for_each_possible_cpu (cpu ) {
734+ err = tegra194_cpufreq_store_physids (cpu , data );
735+ if (err )
736+ goto err_free_res ;
737+ }
738+
716739 tegra194_cpufreq_driver .driver_data = data ;
717740
718741 /* Check for optional OPPv2 and interconnect paths on CPU0 to enable ICC scaling */
0 commit comments