Home | History | Annotate | Download | only in power
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "android.hardware.power (at) 1.1-service.marlin"
     18 
     19 #include <android/log.h>
     20 #include <utils/Log.h>
     21 
     22 #include <android-base/properties.h>
     23 
     24 #include "Power.h"
     25 #include "power-helper.h"
     26 
     27 /* RPM runs at 19.2Mhz. Divide by 19200 for msec */
     28 #define RPM_CLK 19200
     29 
     30 namespace android {
     31 namespace hardware {
     32 namespace power {
     33 namespace V1_1 {
     34 namespace implementation {
     35 
     36 using ::android::hardware::power::V1_0::Feature;
     37 using ::android::hardware::power::V1_0::PowerHint;
     38 using ::android::hardware::power::V1_0::PowerStatePlatformSleepState;
     39 using ::android::hardware::power::V1_0::Status;
     40 using ::android::hardware::power::V1_1::PowerStateSubsystem;
     41 using ::android::hardware::hidl_vec;
     42 using ::android::hardware::Return;
     43 using ::android::hardware::Void;
     44 
     45 Power::Power() {
     46     power_init();
     47 }
     48 
     49 // Methods from ::android::hardware::power::V1_0::IPower follow.
     50 Return<void> Power::setInteractive(bool interactive)  {
     51     power_set_interactive(interactive ? 1 : 0);
     52     return Void();
     53 }
     54 
     55 Return<void> Power::powerHint(PowerHint hint, int32_t data) {
     56     if (android::base::GetProperty("init.svc.vendor.perfd", "") != "running") {
     57         ALOGW("perfd is not started");
     58         return Void();
     59     }
     60     power_hint(static_cast<power_hint_t>(hint), data ? (&data) : NULL);
     61     return Void();
     62 }
     63 
     64 Return<void> Power::setFeature(Feature /*feature*/, bool /*activate*/)  {
     65     return Void();
     66 }
     67 
     68 Return<void> Power::getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb) {
     69 
     70     hidl_vec<PowerStatePlatformSleepState> states;
     71     uint64_t stats[platform_param_id::PLATFORM_PARAM_COUNT] = {0};
     72     struct PowerStatePlatformSleepState *state;
     73     int ret;
     74 
     75     ret = extract_platform_stats(stats);
     76     if (ret != 0) {
     77         states.resize(0);
     78         goto done;
     79     }
     80 
     81     states.resize(platform_mode_id::RPM_MODE_COUNT);
     82 
     83     /* Update statistics for XO_shutdown */
     84     state = &states[platform_mode_id::RPM_MODE_XO];
     85     state->name = "XO_shutdown";
     86 
     87     state->residencyInMsecSinceBoot = stats[platform_param_id::ACCUMULATED_VLOW_TIME];
     88     state->totalTransitions = stats[platform_param_id::VLOW_COUNT];
     89     state->supportedOnlyInSuspend = false;
     90     state->voters.resize(XO_VOTERS);
     91 
     92     /* Update statistics for APSS voter */
     93     state->voters[0].name = "APSS";
     94     state->voters[0].totalTimeInMsecVotedForSinceBoot =
     95         stats[platform_param_id::XO_ACCUMULATED_DURATION_APSS] / RPM_CLK;
     96     state->voters[0].totalNumberOfTimesVotedSinceBoot = stats[platform_param_id::XO_COUNT_APSS];
     97 
     98     /* Update statistics for MPSS voter */
     99     state->voters[1].name = "MPSS";
    100     state->voters[1].totalTimeInMsecVotedForSinceBoot =
    101         stats[platform_param_id::XO_ACCUMULATED_DURATION_MPSS] / RPM_CLK;
    102     state->voters[1].totalNumberOfTimesVotedSinceBoot = stats[platform_param_id::XO_COUNT_MPSS];
    103 
    104     /* Update statistics for ADSP voter */
    105     state->voters[2].name = "ADSP";
    106     state->voters[2].totalTimeInMsecVotedForSinceBoot =
    107         stats[platform_param_id::XO_ACCUMULATED_DURATION_ADSP] / RPM_CLK;
    108     state->voters[2].totalNumberOfTimesVotedSinceBoot = stats[platform_param_id::XO_COUNT_ADSP];
    109 
    110     /* Update statistics for SLPI voter */
    111     state->voters[3].name = "SLPI";
    112     state->voters[3].totalTimeInMsecVotedForSinceBoot =
    113         stats[platform_param_id::XO_ACCUMULATED_DURATION_SLPI] / RPM_CLK;
    114     state->voters[3].totalNumberOfTimesVotedSinceBoot = stats[platform_param_id::XO_COUNT_SLPI];
    115 
    116 
    117     /* Update statistics for VMIN state */
    118     state = &states[platform_mode_id::RPM_MODE_VMIN];
    119     state->name = "VMIN";
    120 
    121     state->residencyInMsecSinceBoot = stats[platform_param_id::ACCUMULATED_VMIN_TIME];
    122     state->totalTransitions = stats[platform_param_id::VMIN_COUNT];
    123     state->supportedOnlyInSuspend = false;
    124     state->voters.resize(VMIN_VOTERS);
    125     //Note: No filling of state voters since VMIN_VOTERS = 0
    126 
    127 done:
    128     _hidl_cb(states, Status::SUCCESS);
    129     return Void();
    130 }
    131 
    132 
    133 // Methods from ::android::hardware::power::V1_1::IPower follow.
    134 
    135 static int get_wlan_low_power_stats(struct PowerStateSubsystem &subsystem) {
    136 
    137     uint64_t stats[WLAN_PARAM_COUNT] = {0};
    138     struct PowerStateSubsystemSleepState *state;
    139     int ret;
    140 
    141     ret = extract_wlan_stats(stats);
    142     if (ret)
    143         return ret;
    144 
    145     subsystem.name = "wlan";
    146     subsystem.states.resize(WLAN_STATE_COUNT);
    147 
    148     /* Update statistics for Active State */
    149     state = &subsystem.states[WLAN_STATE_ACTIVE];
    150     state->name = "Active";
    151     state->residencyInMsecSinceBoot = stats[wlan_param_id::CUMULATIVE_TOTAL_ON_TIME_MS];
    152     state->totalTransitions = stats[wlan_param_id::DEEP_SLEEP_ENTER_COUNTER];
    153     state->lastEntryTimestampMs = 0; //FIXME need a new value from Qcom
    154     state->supportedOnlyInSuspend = false;
    155 
    156     /* Update statistics for Deep-Sleep state */
    157     state = &subsystem.states[WLAN_STATE_DEEP_SLEEP];
    158     state->name = "Deep-Sleep";
    159     state->residencyInMsecSinceBoot = stats[wlan_param_id::CUMULATIVE_SLEEP_TIME_MS];
    160     state->totalTransitions = stats[wlan_param_id::DEEP_SLEEP_ENTER_COUNTER];
    161     state->lastEntryTimestampMs = stats[wlan_param_id::LAST_DEEP_SLEEP_ENTER_TSTAMP_MS];
    162     state->supportedOnlyInSuspend = false;
    163 
    164     return 0;
    165 }
    166 
    167 Return<void> Power::getSubsystemLowPowerStats(getSubsystemLowPowerStats_cb _hidl_cb) {
    168 
    169     hidl_vec<PowerStateSubsystem> subsystems;
    170     int ret;
    171 
    172     subsystems.resize(subsystem_type::SUBSYSTEM_COUNT);
    173 
    174     //We currently have only one Subsystem for WLAN
    175     ret = get_wlan_low_power_stats(subsystems[subsystem_type::SUBSYSTEM_WLAN]);
    176     if (ret != 0) {
    177         goto done;
    178     }
    179 
    180     //Add query for other subsystems here
    181 
    182 done:
    183     _hidl_cb(subsystems, Status::SUCCESS);
    184     return Void();
    185 }
    186 
    187 Return<void> Power::powerHintAsync(PowerHint hint, int32_t data) {
    188     // just call the normal power hint in this oneway function
    189     return powerHint(hint, data);
    190 }
    191 
    192 }  // namespace implementation
    193 }  // namespace V1_1
    194 }  // namespace power
    195 }  // namespace hardware
    196 }  // namespace android
    197