pass: thermal: Add support for scenario_level for thermal scenario 18/224718/7
authorChanwoo Choi <cw00.choi@samsung.com>
Tue, 11 Feb 2020 12:45:12 +0000 (21:45 +0900)
committerChanwoo Choi <cw00.choi@samsung.com>
Wed, 26 Feb 2020 10:22:19 +0000 (19:22 +0900)
Prior to that thermal monitor has been monitoring the temperature
and then decide current thermal scenario like 'Release', 'Warning'.
And send the broadcast dbus message to inform the current thermal scenario
to otther Tizen framework. It didn't support to change the value
of the h/w resource like frequency, the number of online CPU.

Finally, thermal monitor is able to change the value of h/w resource
according to their own 'scenario_level' value on each thermal scenario.

For example with following configuration example,
- If thermal monitor decide the current thermal scenario as 'Release',
  'Release' sceanrio has 'scenario_level=0'. It means that set 'ScenarioLeve0'.
  It allow max_freq as 1.3GHz and max_cpu as 4 core.

- If thermal monitor decide the current thermal scenario as 'Warning',
  'Warning' sceanrio has 'scenario_level=2'. It means that set 'ScenarioLeve2'.
  It allow max_freq as 768MHz and max_cpu as 2 core.

This feature is important for preventing the dangerous overheating of h/w
target and it is very easy to tune up the configuration of thermal monitor
by editing the configuration files under '/etc/pass' path.

[Example of configuraiton file for CPU h/w resource]
(snip)
[ScenarioLevel0]
limit_min_freq=768000
limit_max_freq=1300000
limit_min_cpu=0
limit_max_cpu=4

[ScenarioLevel2]
limit_min_freq=768000
limit_max_freq=768000
limit_min_cpu=0
limit_max_cpu=2

(snip)
[thermal.scenario0]
support=yes
name=Release
temperature=25
timer_interval_ms=5000
scenario_level=0 <- It means 'ScenarioLevel0' is used for 'Release'.
Allow max_freq as 1.3GHz and max_cpu as 4 core.

[thermal.scenario1]
support=yes
name=Warning
temperature=30
timer_interval_ms=3000
scenario_level=2 <- It means 'ScenarioLevel2' is used for 'Warning'.
Allow max_freq as 768MHz and max_cpu as 2 core.

Change-Id: I3a5ff802e68f1452e90d766cfe1f04b4554413fd
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
src/pass/pass-thermal.c
src/pass/pass.h

index 4cbfccfa8b8474053c7f0f950892adb525a00bf2..366c03e8b0da60138c8971dd9baa04a024c9e46a 100644 (file)
@@ -30,6 +30,7 @@
 #include <pass/device-notifier.h>
 
 #include "pass.h"
+#include "pass-rescon.h"
 #include "pass-resmon.h"
 
 #define DEFAULT_TEMPERATURE            (-1000)
@@ -38,6 +39,7 @@ static int thermal_update(struct pass_resource *res,
                        struct resmon_result_src_thermal *thermal_result)
 {
        struct pass_thermal *thermal = &res->thermal;;
+       struct pass_scenario *scenario;
        int timer_interval_of_scenario, timer_interval;
        int curr_temp, prev_temp, temp;
        int i, scenario_idx;
@@ -77,10 +79,10 @@ static int thermal_update(struct pass_resource *res,
 
        if (thermal->curr_scenario_idx == scenario_idx)
                return 0;
+       scenario = &thermal->scenarios[scenario_idx];
 
        /* Get the new timer interval of each scenario */
-       timer_interval_of_scenario
-               = thermal->scenarios[scenario_idx].thermal.timer_interval;
+       timer_interval_of_scenario = scenario->thermal.timer_interval;
        if (timer_interval_of_scenario > 0)
                timer_interval = timer_interval_of_scenario;
        else
@@ -94,11 +96,42 @@ static int thermal_update(struct pass_resource *res,
                        res->config_data.res_name, RESMON_SRC_THERMAL);
        }
 
+       /* Update thermal information of each h/w resource */
        thermal->curr_temp = curr_temp;
+       thermal->prev_scenario_idx = thermal->curr_scenario_idx;
        thermal->curr_scenario_idx = scenario_idx;
 
+       /* Set ScenarioLevel for current scenario */
+       ret = pass_rescon_set_scenario_level(res, scenario->level);
+       if (ret < 0) {
+               _W("failed to set ScenarioLevel%d " \
+                       "(res_name:%s, src_type: 0x%x)\n",
+                       scenario->level,
+                       res->config_data.res_name, RESMON_SRC_THERMAL);
+       }
+
+       /* Unset ScenarioLevel of previous scenario */
+       if (thermal->prev_scenario_idx >= 0) {
+               struct pass_scenario *p_scenario =
+                       &thermal->scenarios[thermal->prev_scenario_idx];
+               ret = pass_rescon_unset_scenario_level(res, p_scenario->level);
+               if (ret < 0) {
+                       _W("failed to unset ScenarioLevel%d " \
+                               "(res_name:%s, src_type: 0x%x)\n",
+                               p_scenario->level,
+                               res->config_data.res_name, RESMON_SRC_THERMAL);
+               }
+       }
+
+       ret = pass_rescon_sync(res);
+       if (ret < 0) {
+               _W("failed to synchronize h/w resource " \
+                       "(res_name:%s, src_type: 0x%x)\n",
+                       res->config_data.res_name, RESMON_SRC_THERMAL);
+       }
+
        _I("Monitor '%-12s' of '%s' resource ('%3d' degrees,'%5d' ms)\n",
-                               thermal->scenarios[scenario_idx].name,
+                               scenario->name,
                                res->config_data.res_name,
                                curr_temp, timer_interval);
 
index a88c61c6b6175e2ef2726af4748749bb9391bb23..89a5494ff297443ecd13b3e976234b7abf90e128 100644 (file)
@@ -384,6 +384,8 @@ struct pass_thermal {
        unsigned int timer_interval;
        /** Index of current thermal scenario */
        int curr_scenario_idx;
+       /** Index of previous thermal scenario */
+       int prev_scenario_idx;
        /** Current temperature */
        int curr_temp;
 };