@@ -130,14 +130,85 @@ static void rk_context_deinit(struct platform_device *pdev)
130130
131131#define FALLBACK_STATIC_TEMPERATURE 55000
132132
133+ static u32 dynamic_coefficient ;
134+ static u32 static_coefficient ;
135+ static s32 ts [4 ];
133136static struct thermal_zone_device * gpu_tz ;
134137
138+ static int power_model_simple_init (struct platform_device * pdev )
139+ {
140+ struct device_node * power_model_node ;
141+ const char * tz_name ;
142+ u32 static_power , dynamic_power ;
143+ u32 voltage , voltage_squared , voltage_cubed , frequency ;
144+
145+ power_model_node = of_get_child_by_name (pdev -> dev .of_node ,
146+ "power_model" );
147+ if (!power_model_node ) {
148+ dev_err (& pdev -> dev , "could not find power_model node\n" );
149+ return - ENODEV ;
150+ }
151+ if (!of_device_is_compatible (power_model_node ,
152+ "arm,mali-simple-power-model" )) {
153+ dev_err (& pdev -> dev , "power_model incompatible with simple power model\n" );
154+ return - ENODEV ;
155+ }
156+
157+ if (of_property_read_string (power_model_node , "thermal-zone" ,
158+ & tz_name )) {
159+ dev_err (& pdev -> dev , "ts in power_model not available\n" );
160+ return - EINVAL ;
161+ }
162+
163+ gpu_tz = thermal_zone_get_zone_by_name (tz_name );
164+ if (IS_ERR (gpu_tz )) {
165+ pr_warn_ratelimited ("Error getting gpu thermal zone '%s'(%ld), not yet ready?\n" ,
166+ tz_name ,
167+ PTR_ERR (gpu_tz ));
168+ gpu_tz = NULL ;
169+
170+ return - EPROBE_DEFER ;
171+ }
172+
173+ if (of_property_read_u32 (power_model_node , "static-power" ,
174+ & static_power )) {
175+ dev_err (& pdev -> dev , "static-power in power_model not available\n" );
176+ return - EINVAL ;
177+ }
178+ if (of_property_read_u32 (power_model_node , "dynamic-power" ,
179+ & dynamic_power )) {
180+ dev_err (& pdev -> dev , "dynamic-power in power_model not available\n" );
181+ return - EINVAL ;
182+ }
183+ if (of_property_read_u32 (power_model_node , "voltage" ,
184+ & voltage )) {
185+ dev_err (& pdev -> dev , "voltage in power_model not available\n" );
186+ return - EINVAL ;
187+ }
188+ if (of_property_read_u32 (power_model_node , "frequency" ,
189+ & frequency )) {
190+ dev_err (& pdev -> dev , "frequency in power_model not available\n" );
191+ return - EINVAL ;
192+ }
193+ voltage_squared = (voltage * voltage ) / 1000 ;
194+ voltage_cubed = voltage * voltage * voltage ;
195+ static_coefficient = (static_power << 20 ) / (voltage_cubed >> 10 );
196+ dynamic_coefficient = (((dynamic_power * 1000 ) / voltage_squared )
197+ * 1000 ) / frequency ;
198+
199+ if (of_property_read_u32_array (power_model_node , "ts" , (u32 * )ts , 4 )) {
200+ dev_err (& pdev -> dev , "ts in power_model not available\n" );
201+ return - EINVAL ;
202+ }
203+
204+ return 0 ;
205+ }
206+
135207/* Calculate gpu static power example for reference */
136208static unsigned long rk_model_static_power (unsigned long voltage )
137209{
138210 int temperature , temp ;
139211 int temp_squared , temp_cubed , temp_scaling_factor ;
140- const unsigned long coefficient = (410UL << 20 ) / (729000000UL >> 10 );
141212 const unsigned long voltage_cubed = (voltage * voltage * voltage ) >> 10 ;
142213 unsigned long static_power ;
143214
@@ -160,12 +231,12 @@ static unsigned long rk_model_static_power(unsigned long voltage)
160231 temp_squared = temp * temp ;
161232 temp_cubed = temp_squared * temp ;
162233 temp_scaling_factor =
163- ( 2 * temp_cubed )
164- - ( 80 * temp_squared )
165- + (4700 * temp )
166- + 32000 ;
234+ ( ts [ 3 ] * temp_cubed )
235+ + ( ts [ 2 ] * temp_squared )
236+ + (ts [ 1 ] * temp )
237+ + ts [ 0 ] ;
167238
168- static_power = (((coefficient * voltage_cubed ) >> 20 )
239+ static_power = (((static_coefficient * voltage_cubed ) >> 20 )
169240 * temp_scaling_factor )
170241 / 1000000 ;
171242
@@ -184,10 +255,9 @@ static unsigned long rk_model_dynamic_power(unsigned long freq,
184255 */
185256 const unsigned long v2 = (voltage * voltage ) / 1000 ; /* m*(V*V) */
186257 const unsigned long f_mhz = freq / 1000000 ; /* MHz */
187- const unsigned long coefficient = 3600 ; /* mW/(MHz*mV*mV) */
188258 unsigned long dynamic_power ;
189259
190- dynamic_power = (coefficient * v2 * f_mhz ) / 1000000 ; /* mW */
260+ dynamic_power = (dynamic_coefficient * v2 * f_mhz ) / 1000000 ; /* mW */
191261
192262 return dynamic_power ;
193263}
@@ -453,27 +523,31 @@ int mali_platform_device_init(struct platform_device *pdev)
453523 sizeof (mali_gpu_data ));
454524 if (err ) {
455525 E ("fail to add platform_specific_data. err : %d." , err );
456- goto EXIT ;
526+ goto add_data_failed ;
457527 }
458528
459529 err = rk_context_init (pdev );
460530 if (err ) {
461531 E ("fail to init rk_context. err : %d." , err );
462- goto EXIT ;
532+ goto init_rk_context_failed ;
463533 }
464534
465535#if defined(CONFIG_MALI_DEVFREQ ) && defined(CONFIG_DEVFREQ_THERMAL )
466- /* Get thermal zone */
467- gpu_tz = thermal_zone_get_zone_by_name ("gpu_thermal" );
468- if (IS_ERR (gpu_tz )) {
469- W ("Error getting gpu thermal zone (%ld), not yet ready?" ,
470- PTR_ERR (gpu_tz ));
471- gpu_tz = NULL ;
472- /* err = -EPROBE_DEFER; */
536+ err = power_model_simple_init (pdev );
537+ if (err ) {
538+ E ("fail to init simple_power_model, err : %d." , err );
539+ goto init_power_model_failed ;
473540 }
474541#endif
475542
476- EXIT :
543+ return 0 ;
544+
545+ #if defined(CONFIG_MALI_DEVFREQ ) && defined(CONFIG_DEVFREQ_THERMAL )
546+ init_power_model_failed :
547+ rk_context_deinit (pdev );
548+ #endif
549+ init_rk_context_failed :
550+ add_data_failed :
477551 return err ;
478552}
479553
0 commit comments