@@ -80,6 +80,7 @@ struct osm_entry {
8080};
8181
8282struct clk_osm {
83+ struct device * dev ;
8384 struct clk_hw hw ;
8485 struct osm_entry osm_table [OSM_TABLE_SIZE ];
8586 struct dentry * debugfs ;
@@ -90,6 +91,7 @@ struct clk_osm {
9091 u32 num_entries ;
9192 u32 cluster_num ;
9293 u32 core_num ;
94+ u32 osm_table_size ;
9395 unsigned long rate ;
9496 u64 total_cycle_counter ;
9597 u32 prev_cycle_counter ;
@@ -386,6 +388,7 @@ static struct clk_init_data osm_clks_init[] = {
386388static struct clk_osm l3_clk = {
387389 .cluster_num = 0 ,
388390 .max_core_count = 4 ,
391+ .osm_table_size = OSM_TABLE_SIZE ,
389392 .hw .init = & osm_clks_init [0 ],
390393};
391394
@@ -397,6 +400,7 @@ static DEFINE_CLK_VOTER(l3_gpu_vote_clk, l3_clk, 0);
397400static struct clk_osm pwrcl_clk = {
398401 .cluster_num = 1 ,
399402 .max_core_count = 4 ,
403+ .osm_table_size = OSM_TABLE_SIZE ,
400404 .hw .init = & osm_clks_init [1 ],
401405};
402406
@@ -481,6 +485,7 @@ static struct clk_osm cpu5_pwrcl_clk = {
481485static struct clk_osm perfcl_clk = {
482486 .cluster_num = 2 ,
483487 .max_core_count = 4 ,
488+ .osm_table_size = OSM_TABLE_SIZE ,
484489 .hw .init = & osm_clks_init [2 ],
485490};
486491
@@ -717,14 +722,31 @@ static unsigned int osm_cpufreq_get(unsigned int cpu)
717722 return XO_RATE * curr_lval / 1000 ;
718723}
719724
725+ static bool osm_dt_find_freq (u32 * of_table , int of_len , long frequency )
726+ {
727+ int i ;
728+
729+ if (!of_table )
730+ return true;
731+
732+ for (i = 0 ; i < of_len ; i ++ ) {
733+ if (frequency == of_table [i ])
734+ return true;
735+ }
736+
737+ return false;
738+ }
739+
720740static int osm_cpufreq_cpu_init (struct cpufreq_policy * policy )
721741{
722742 struct cpufreq_frequency_table * table ;
723743 struct clk_osm * c , * parent ;
724744 struct clk_hw * p_hw ;
725- int ret ;
745+ int ret , of_len ;
726746 unsigned int i , prev_cc = 0 ;
727747 unsigned int xo_kHz ;
748+ u32 * of_table = NULL ;
749+ char tbl_name [] = "qcom,cpufreq-table-##" ;
728750
729751 c = osm_configure_policy (policy );
730752 if (!c ) {
@@ -748,11 +770,33 @@ static int osm_cpufreq_cpu_init(struct cpufreq_policy *policy)
748770 }
749771 xo_kHz = clk_hw_get_rate (p_hw ) / 1000 ;
750772
751- table = kcalloc (OSM_TABLE_SIZE + 1 , sizeof (* table ), GFP_KERNEL );
773+ table = kcalloc (parent -> osm_table_size + 1 , sizeof (* table ), GFP_KERNEL );
774+
775+ snprintf (tbl_name , sizeof (tbl_name ), "qcom,cpufreq-table-%d" , policy -> cpu );
776+ if (of_find_property (parent -> dev -> of_node , tbl_name , & of_len ) && of_len > 0 ) {
777+ of_len /= sizeof (* of_table );
778+
779+ of_table = kcalloc (of_len , sizeof (* of_table ), GFP_KERNEL );
780+ if (!of_table ) {
781+ pr_err ("failed to allocate DT frequency table memory for CPU%d\n" ,
782+ policy -> cpu );
783+ return - ENOMEM ;
784+ }
785+
786+ ret = of_property_read_u32_array (parent -> dev -> of_node , tbl_name ,
787+ of_table , of_len );
788+ if (ret ) {
789+ pr_err ("failed to read DT frequency table for CPU%d, err=%d\n" ,
790+ policy -> cpu , ret );
791+ return ret ;
792+ }
793+ }
794+
795+ table = kcalloc (parent -> osm_table_size + 1 , sizeof (* table ), GFP_KERNEL );
752796 if (!table )
753797 return - ENOMEM ;
754798
755- for (i = 0 ; i < OSM_TABLE_SIZE ; i ++ ) {
799+ for (i = 0 ; i < parent -> osm_table_size ; i ++ ) {
756800 u32 data , src , div , lval , core_count ;
757801
758802 data = clk_osm_read_reg (c , FREQ_REG + i * OSM_REG_SIZE );
@@ -767,6 +811,10 @@ static int osm_cpufreq_cpu_init(struct cpufreq_policy *policy)
767811 table [i ].frequency = xo_kHz * lval ;
768812 table [i ].driver_data = table [i ].frequency ;
769813
814+ /* Ignore frequency if not present in DT table */
815+ if (!osm_dt_find_freq (of_table , of_len , table [i ].frequency ))
816+ table [i ].frequency = CPUFREQ_ENTRY_INVALID ;
817+
770818 if (core_count != parent -> max_core_count )
771819 table [i ].frequency = CPUFREQ_ENTRY_INVALID ;
772820
@@ -795,9 +843,12 @@ static int osm_cpufreq_cpu_init(struct cpufreq_policy *policy)
795843
796844 policy -> cpuinfo .transition_latency = MIN_RATE_LIMIT_US ;
797845 policy -> driver_data = c ;
846+
847+ kfree (of_table );
798848 return 0 ;
799849
800850err :
851+ kfree (of_table );
801852 kfree (table );
802853 return ret ;
803854}
@@ -1019,10 +1070,11 @@ static u64 clk_osm_get_cpu_cycle_counter(int cpu)
10191070
10201071static int clk_osm_read_lut (struct platform_device * pdev , struct clk_osm * c )
10211072{
1022- u32 data , src , lval , i , j = OSM_TABLE_SIZE ;
1073+ u32 data , src , lval , i , j = c -> osm_table_size ;
10231074 struct clk_vdd_class * vdd = osm_clks_init [c -> cluster_num ].vdd_class ;
10241075
1025- for (i = 0 ; i < OSM_TABLE_SIZE ; i ++ ) {
1076+ c -> dev = & pdev -> dev ;
1077+ for (i = 0 ; i < c -> osm_table_size ; i ++ ) {
10261078 data = clk_osm_read_reg (c , FREQ_REG + i * OSM_REG_SIZE );
10271079 src = ((data & GENMASK (31 , 30 )) >> 30 );
10281080 lval = (data & GENMASK (7 , 0 ));
@@ -1044,7 +1096,7 @@ static int clk_osm_read_lut(struct platform_device *pdev, struct clk_osm *c)
10441096 c -> osm_table [i ].virtual_corner ,
10451097 c -> osm_table [i ].open_loop_volt );
10461098
1047- if (i > 0 && j == OSM_TABLE_SIZE &&
1099+ if (i > 0 && j == c -> osm_table_size &&
10481100 c -> osm_table [i ].frequency ==
10491101 c -> osm_table [i - 1 ].frequency &&
10501102 c -> osm_table [i ].ccount == c -> osm_table [i - 1 ].ccount )
0 commit comments