blob: e87b9210664dc3e55e109504d8afaff1c53a0095 [file] [log] [blame]
Chris Cain78e86012021-03-04 16:15:31 -06001#include <fmt/core.h>
2
Chris Cain78e86012021-03-04 16:15:31 -06003#include <phosphor-logging/log.hpp>
4#include <powermode.hpp>
Chris Cain78e86012021-03-04 16:15:31 -06005#include <xyz/openbmc_project/Control/Power/Mode/server.hpp>
6
George Liub5ca1012021-09-10 12:53:11 +08007#include <cassert>
8#include <regex>
9
Chris Cain78e86012021-03-04 16:15:31 -060010namespace open_power
11{
12namespace occ
13{
14namespace powermode
15{
16
17using namespace phosphor::logging;
18using Mode = sdbusplus::xyz::openbmc_project::Control::Power::server::Mode;
19
20void PowerMode::modeChanged(sdbusplus::message::message& msg)
21{
22 if (!occStatus.occActive())
23 {
Chris Cain1d51da22021-09-21 14:13:41 -050024 // Nothing to do
Chris Cain78e86012021-03-04 16:15:31 -060025 return;
26 }
27
Chris Cain78e86012021-03-04 16:15:31 -060028 std::map<std::string, std::variant<std::string>> properties{};
29 std::string interface;
30 std::string propVal;
31 msg.read(interface, properties);
32 const auto modeEntry = properties.find(POWER_MODE_PROP);
33 if (modeEntry != properties.end())
34 {
35 auto modeEntryValue = modeEntry->second;
36 propVal = std::get<std::string>(modeEntryValue);
Chris Cain78e86012021-03-04 16:15:31 -060037
George Liuf3a4a692021-12-28 13:59:51 +080038 if (convertStringToMode(propVal) != SysPwrMode::NO_CHANGE)
Chris Cain78e86012021-03-04 16:15:31 -060039 {
40 log<level::INFO>(
41 fmt::format("Power Mode Change Requested: {}", propVal)
42 .c_str());
43
44 // Trigger mode change to OCC
45 occStatus.sendModeChange();
46 }
47 }
48
49 return;
50}
51
52// Convert PowerMode string to OCC SysPwrMode
53SysPwrMode convertStringToMode(const std::string& i_modeString)
54{
55 SysPwrMode pmode = SysPwrMode::NO_CHANGE;
56
57 Mode::PowerMode mode = Mode::convertPowerModeFromString(i_modeString);
58 if (mode == Mode::PowerMode::MaximumPerformance)
59 {
60 pmode = SysPwrMode::MAX_PERF;
61 }
62 else if (mode == Mode::PowerMode::PowerSaving)
63 {
64 pmode = SysPwrMode::POWER_SAVING;
65 }
66 else if (mode == Mode::PowerMode::Static)
67 {
68 pmode = SysPwrMode::DISABLE;
69 }
70 else
71 {
72 log<level::ERR>(
73 fmt::format("convertStringToMode: Invalid Power Mode specified: {}",
74 i_modeString)
75 .c_str());
76 }
77
78 return pmode;
79}
80
Chris Cain1d51da22021-09-21 14:13:41 -050081void PowerIPS::ipsChanged(sdbusplus::message::message& msg)
82{
83 if (!occStatus.occActive())
84 {
85 // Nothing to do
86 return;
87 }
88
89 bool parmsChanged = false;
90 std::string interface;
91 std::map<std::string, std::variant<bool, uint8_t, uint64_t>>
92 ipsProperties{};
93 msg.read(interface, ipsProperties);
94
95 auto ipsEntry = ipsProperties.find(IPS_ENABLED_PROP);
96 if (ipsEntry != ipsProperties.end())
97 {
98 const auto ipsEnabled = std::get<bool>(ipsEntry->second);
99 log<level::INFO>(
100 fmt::format("Idle Power Saver change: Enabled={}", ipsEnabled)
101 .c_str());
102 parmsChanged = true;
103 }
104 ipsEntry = ipsProperties.find(IPS_ENTER_UTIL);
105 if (ipsEntry != ipsProperties.end())
106 {
107 const auto enterUtil = std::get<uint8_t>(ipsEntry->second);
108 log<level::INFO>(
109 fmt::format("Idle Power Saver change: Enter Util={}%", enterUtil)
110 .c_str());
111 parmsChanged = true;
112 }
113 ipsEntry = ipsProperties.find(IPS_ENTER_TIME);
114 if (ipsEntry != ipsProperties.end())
115 {
116 std::chrono::milliseconds ms(std::get<uint64_t>(ipsEntry->second));
117 const auto enterTime =
118 std::chrono::duration_cast<std::chrono::seconds>(ms).count();
119 log<level::INFO>(
120 fmt::format("Idle Power Saver change: Enter Time={}sec", enterTime)
121 .c_str());
122 parmsChanged = true;
123 }
124 ipsEntry = ipsProperties.find(IPS_EXIT_UTIL);
125 if (ipsEntry != ipsProperties.end())
126 {
127 const auto exitUtil = std::get<uint8_t>(ipsEntry->second);
128 log<level::INFO>(
129 fmt::format("Idle Power Saver change: Exit Util={}%", exitUtil)
130 .c_str());
131 parmsChanged = true;
132 }
133 ipsEntry = ipsProperties.find(IPS_EXIT_TIME);
134 if (ipsEntry != ipsProperties.end())
135 {
136 std::chrono::milliseconds ms(std::get<uint64_t>(ipsEntry->second));
137 const auto exitTime =
138 std::chrono::duration_cast<std::chrono::seconds>(ms).count();
139 log<level::INFO>(
140 fmt::format("Idle Power Saver change: Exit Time={}sec", exitTime)
141 .c_str());
142 parmsChanged = true;
143 }
144
145 if (parmsChanged)
146 {
147 // Trigger mode change to OCC
148 occStatus.sendIpsData();
149 }
150
151 return;
152}
153
Chris Cain78e86012021-03-04 16:15:31 -0600154} // namespace powermode
155
156} // namespace occ
157
158} // namespace open_power