2222#include <linux/cpumask.h>
2323#include <linux/err.h>
2424#include <linux/module.h>
25+ #include <linux/nvmem-consumer.h>
2526#include <linux/of.h>
2627#include <linux/pm_opp.h>
2728#include <linux/platform_device.h>
2829#include <linux/regulator/consumer.h>
2930#include <linux/slab.h>
3031#include <linux/thermal.h>
3132
33+ #define MAX_PROP_NAME_LEN 6
34+ #define VERSION_ELEMENTS 1
35+ #define INVALID_VALUE 0xff
36+ #define SAFE_FREQ (24 * 67 * 1000000)
37+
3238struct private_data {
3339 struct device * cpu_dev ;
3440 struct thermal_cooling_device * cdev ;
@@ -41,6 +47,8 @@ static struct freq_attr *cpufreq_dt_attr[] = {
4147 NULL ,
4248};
4349
50+ static unsigned char package_info = INVALID_VALUE ;
51+ extern unsigned long apll_safefreq ;
4452static int set_target (struct cpufreq_policy * policy , unsigned int index )
4553{
4654 struct private_data * priv = policy -> driver_data ;
@@ -49,6 +57,87 @@ static int set_target(struct cpufreq_policy *policy, unsigned int index)
4957 policy -> freq_table [index ].frequency * 1000 );
5058}
5159
60+ static int fetch_package_info (struct device * dev , unsigned char * package_info )
61+ {
62+ struct nvmem_cell * cell ;
63+ unsigned char * buf ;
64+ size_t len ;
65+
66+ cell = nvmem_cell_get (dev , "package_info" );
67+ if (IS_ERR (cell ))
68+ return PTR_ERR (cell );
69+
70+ buf = (unsigned char * )nvmem_cell_read (cell , & len );
71+
72+ nvmem_cell_put (cell );
73+
74+ if (IS_ERR (buf ))
75+ return PTR_ERR (buf );
76+
77+ if (buf [0 ] == INVALID_VALUE )
78+ return - EINVAL ;
79+
80+ * package_info = buf [0 ];
81+ kfree (buf );
82+
83+ return 0 ;
84+ }
85+
86+ static int set_opp_info (struct device * dev )
87+ {
88+ struct device_node * opp_np , * np ;
89+ unsigned char chip_vesion ;
90+ char name [MAX_PROP_NAME_LEN ];
91+ unsigned int version ;
92+ unsigned int count = 0 ;
93+ int ret ;
94+
95+ if (package_info == INVALID_VALUE ) {
96+ dev_info (dev , "package_info NULL\n" );
97+ return 0 ;
98+ }
99+
100+ opp_np = of_parse_phandle (dev -> of_node , "operating-points-v2" , 0 );
101+ if (!opp_np )
102+ return 0 ;
103+ for_each_available_child_of_node (opp_np , np ) {
104+ ret = of_property_read_u32_index (np , "opp-supported-hw" ,
105+ VERSION_ELEMENTS - 1 ,
106+ & version );
107+ if (!ret ) {
108+ count ++ ;
109+ break ;
110+ }
111+ }
112+ if (count == 0 )
113+ return 0 ;
114+
115+ if ((package_info & 0xc0 ) == 0xc0 ) {
116+ chip_vesion = 1 ;
117+ apll_safefreq = ULONG_MAX ;
118+ } else {
119+ chip_vesion = 0 ;
120+ apll_safefreq = SAFE_FREQ ;
121+ }
122+ snprintf (name , MAX_PROP_NAME_LEN , "v%d" , chip_vesion );
123+ ret = dev_pm_opp_set_prop_name (dev , name );
124+ if (ret ) {
125+ dev_err (dev , "Failed to set prop name\n" );
126+ return ret ;
127+ }
128+
129+ version = BIT (chip_vesion );
130+ ret = dev_pm_opp_set_supported_hw (dev , & version , VERSION_ELEMENTS );
131+ if (ret ) {
132+ dev_err (dev , "Failed to set supported hardware\n" );
133+ return ret ;
134+ }
135+
136+ dev_info (dev , "chip_version: %d 0x%x\n" , chip_vesion , version );
137+
138+ return 0 ;
139+ }
140+
52141/*
53142 * An earlier version of opp-v1 bindings used to name the regulator
54143 * "cpu0-supply", we still need to handle that for backwards compatibility.
@@ -139,6 +228,11 @@ static int resources_available(void)
139228 }
140229
141230 regulator_put (cpu_reg );
231+
232+ ret = fetch_package_info (cpu_dev , & package_info );
233+ if (ret )
234+ dev_dbg (cpu_dev , "Failed to fetch wafer_info\n" );
235+
142236 return 0 ;
143237}
144238
@@ -149,9 +243,8 @@ static int cpufreq_init(struct cpufreq_policy *policy)
149243 struct device * cpu_dev ;
150244 struct clk * cpu_clk ;
151245 struct dev_pm_opp * suspend_opp ;
152- #ifdef CONFIG_ARCH_ROCKCHIP
153246 struct cpumask cpus ;
154- #endif
247+
155248 unsigned int transition_latency ;
156249 bool opp_v1 = false;
157250 const char * name ;
@@ -183,6 +276,12 @@ static int cpufreq_init(struct cpufreq_policy *policy)
183276 goto out_put_clk ;
184277 }
185278
279+ if (!opp_v1 ) {
280+ ret = set_opp_info (cpu_dev );
281+ if (ret )
282+ dev_err (cpu_dev , "Failed to set_opp_info: %d\n" , ret );
283+ }
284+
186285 /*
187286 * OPP layer will be taking care of regulators now, but it needs to know
188287 * the name of the regulator first.
@@ -207,7 +306,6 @@ static int cpufreq_init(struct cpufreq_policy *policy)
207306 *
208307 * OPPs might be populated at runtime, don't check for error here
209308 */
210- #ifdef CONFIG_ARCH_ROCKCHIP
211309 ret = dev_pm_opp_of_add_table (cpu_dev );
212310 if (ret ) {
213311 dev_err (cpu_dev , "couldn't find opp table for cpu:%d, %d\n" ,
@@ -220,9 +318,6 @@ static int cpufreq_init(struct cpufreq_policy *policy)
220318 dev_pm_opp_of_remove_table (cpu_dev );
221319 }
222320 }
223- #else
224- dev_pm_opp_of_cpumask_add_table (policy -> cpus );
225- #endif
226321
227322 /*
228323 * But we need OPP table to function so if it is not there let's
@@ -318,12 +413,11 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
318413 struct cpumask cpus ;
319414 struct private_data * priv = policy -> driver_data ;
320415
321- #ifdef CONFIG_ARCH_ROCKCHIP
322416 cpumask_set_cpu (policy -> cpu , policy -> cpus );
323417 if (cpufreq_generic_suspend (policy ))
324418 pr_err ("%s: Failed to suspend driver: %p\n" , __func__ , policy );
325419 cpumask_clear_cpu (policy -> cpu , policy -> cpus );
326- #endif
420+
327421 priv -> cpu_dev = get_cpu_device (policy -> cpu );
328422 cpufreq_cooling_unregister (priv -> cdev );
329423 dev_pm_opp_free_cpufreq_table (priv -> cpu_dev , & policy -> freq_table );
@@ -373,11 +467,7 @@ static void cpufreq_ready(struct cpufreq_policy *policy)
373467}
374468
375469static struct cpufreq_driver dt_cpufreq_driver = {
376- #ifdef CONFIG_ARCH_ROCKCHIP
377470 .flags = CPUFREQ_STICKY | CPUFREQ_HAVE_GOVERNOR_PER_POLICY ,
378- #else
379- .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK ,
380- #endif
381471 .verify = cpufreq_generic_frequency_table_verify ,
382472 .target_index = set_target ,
383473 .get = cpufreq_generic_get ,
0 commit comments