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