summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pixelstats/SysfsCollector.cpp131
-rw-r--r--pixelstats/include/pixelstats/SysfsCollector.h5
-rw-r--r--pixelstats/pixelatoms.proto32
-rw-r--r--usb/MonitorFfs.cpp36
-rw-r--r--usb/include/pixelusb/UsbGadgetCommon.h59
-rw-r--r--vibrator/cs40l26/Hardware.h7
-rw-r--r--vibrator/cs40l26/Vibrator.cpp1
-rw-r--r--vibrator/cs40l26/Vibrator.h3
8 files changed, 238 insertions, 36 deletions
diff --git a/pixelstats/SysfsCollector.cpp b/pixelstats/SysfsCollector.cpp
index 203ff0f..f9dc7ab 100644
--- a/pixelstats/SysfsCollector.cpp
+++ b/pixelstats/SysfsCollector.cpp
@@ -32,6 +32,10 @@
#include <cinttypes>
#include <string>
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+#endif
+
namespace android {
namespace hardware {
namespace google {
@@ -49,6 +53,7 @@ using android::hardware::google::pixel::PixelAtoms::F2fsCompressionInfo;
using android::hardware::google::pixel::PixelAtoms::F2fsGcSegmentInfo;
using android::hardware::google::pixel::PixelAtoms::F2fsSmartIdleMaintEnabledStateChanged;
using android::hardware::google::pixel::PixelAtoms::F2fsStatsInfo;
+using android::hardware::google::pixel::PixelAtoms::PcieLinkStatsReported;
using android::hardware::google::pixel::PixelAtoms::StorageUfsHealth;
using android::hardware::google::pixel::PixelAtoms::StorageUfsResetCount;
using android::hardware::google::pixel::PixelAtoms::ThermalDfsStats;
@@ -95,7 +100,9 @@ SysfsCollector::SysfsCollector(const struct SysfsPaths &sysfs_paths)
kCCARatePath(sysfs_paths.CCARatePath),
kTempResidencyPath(sysfs_paths.TempResidencyPath),
kLongIRQMetricsPath(sysfs_paths.LongIRQMetricsPath),
- kResumeLatencyMetricsPath(sysfs_paths.ResumeLatencyMetricsPath) {}
+ kResumeLatencyMetricsPath(sysfs_paths.ResumeLatencyMetricsPath),
+ kModemPcieLinkStatsPath(sysfs_paths.ModemPcieLinkStatsPath),
+ kWifiPcieLinkStatsPath(sysfs_paths.WifiPcieLinkStatsPath) {}
bool SysfsCollector::ReadFileToInt(const std::string &path, int *val) {
return ReadFileToInt(path.c_str(), val);
@@ -1058,6 +1065,10 @@ void SysfsCollector::logVendorAudioHardwareStats(const std::shared_ptr<IStats> &
* Logs the Resume Latency stats.
*/
void SysfsCollector::logVendorResumeLatencyStats(const std::shared_ptr<IStats> &stats_client) {
+ std::string uart_enabled = android::base::GetProperty("init.svc.console", "");
+ if (uart_enabled == "running") {
+ return;
+ }
std::string file_contents;
if (!kResumeLatencyMetricsPath) {
ALOGE("ResumeLatencyMetrics path not specified");
@@ -1182,6 +1193,10 @@ void process_irqatom_values(std::vector<std::pair<int, int64_t>> sorted_pair,
* Logs the Long irq stats.
*/
void SysfsCollector::logVendorLongIRQStatsReported(const std::shared_ptr<IStats> &stats_client) {
+ std::string uart_enabled = android::base::GetProperty("init.svc.console", "");
+ if (uart_enabled == "running") {
+ return;
+ }
std::string file_contents;
if (!kLongIRQMetricsPath) {
ALOGV("LongIRQ path not specified");
@@ -1276,6 +1291,119 @@ void SysfsCollector::logVendorLongIRQStatsReported(const std::shared_ptr<IStats>
ALOGE("Unable to report kVendorLongIRQStatsReported to Stats service");
}
+void SysfsCollector::logPcieLinkStats(const std::shared_ptr<IStats> &stats_client) {
+ struct sysfs_map {
+ const char *sysfs_path;
+ bool is_counter;
+ int modem_val;
+ int wifi_val;
+ int modem_msg_field_number;
+ int wifi_msg_field_number;
+ };
+
+ int i;
+ bool reportPcieLinkStats = false;
+
+ /* Map sysfs data to PcieLinkStatsReported message elements */
+ struct sysfs_map datamap[] = {
+ {"link_down_irqs", true, 0, 0,
+ PcieLinkStatsReported::kModemPcieLinkdownsFieldNumber,
+ PcieLinkStatsReported::kWifiPcieLinkdownsFieldNumber},
+
+ {"complete_timeout_irqs", true, 0, 0,
+ PcieLinkStatsReported::kModemPcieCompletionTimeoutsFieldNumber,
+ PcieLinkStatsReported::kWifiPcieCompletionTimeoutsFieldNumber},
+
+ {"link_up_failures", true, 0, 0,
+ PcieLinkStatsReported::kModemPcieLinkupFailuresFieldNumber,
+ PcieLinkStatsReported::kWifiPcieLinkupFailuresFieldNumber},
+
+ {"pll_lock_average", false, 0, 0,
+ PcieLinkStatsReported::kModemPciePllLockAvgFieldNumber,
+ PcieLinkStatsReported::kWifiPciePllLockAvgFieldNumber},
+
+ {"link_up_average", false, 0, 0,
+ PcieLinkStatsReported::kWifiPcieLinkUpAvgFieldNumber,
+ PcieLinkStatsReported::kWifiPcieLinkUpAvgFieldNumber },
+ };
+
+
+ if (kModemPcieLinkStatsPath == nullptr) {
+ ALOGD("Modem PCIe stats path not specified");
+ } else {
+ for (i=0; i < ARRAY_SIZE(datamap); i++) {
+ std::string modempath = std::string (kModemPcieLinkStatsPath) + \
+ "/" + datamap[i].sysfs_path;
+
+ if (ReadFileToInt(modempath, &(datamap[i].modem_val))) {
+ reportPcieLinkStats = true;
+ ALOGD("Modem %s = %d", datamap[i].sysfs_path,
+ datamap[i].modem_val);
+ if (datamap[i].is_counter) {
+ std::string value = std::to_string(datamap[i].modem_val);
+ /* Writing the value back clears the counter */
+ if (!WriteStringToFile(value, modempath)) {
+ ALOGE("Unable to clear modem PCIe statistics file: %s - %s",
+ modempath.c_str(), strerror(errno));
+ }
+ }
+ }
+ }
+ }
+
+ if (kWifiPcieLinkStatsPath == nullptr) {
+ ALOGD("Wifi PCIe stats path not specified");
+ } else {
+ for (i=0; i < ARRAY_SIZE(datamap); i++) {
+ std::string wifipath = std::string (kWifiPcieLinkStatsPath) + \
+ "/" + datamap[i].sysfs_path;
+
+ if (ReadFileToInt(wifipath, &(datamap[i].wifi_val))) {
+ reportPcieLinkStats = true;
+ ALOGD("Wifi %s = %d", datamap[i].sysfs_path,
+ datamap[i].wifi_val);
+ if (datamap[i].is_counter) {
+ std::string value = std::to_string(datamap[i].wifi_val);
+ /* Writing the value back clears the counter */
+ if (!WriteStringToFile(value, wifipath)) {
+ ALOGE("Unable to clear wifi PCIe statistics file: %s - %s",
+ wifipath.c_str(), strerror(errno));
+ }
+ }
+ }
+ }
+ }
+
+ if (!reportPcieLinkStats) {
+ ALOGD("No PCIe link stats to report");
+ return;
+ }
+
+ // Load values array
+ std::vector<VendorAtomValue> values(2 * ARRAY_SIZE(datamap));
+ VendorAtomValue tmp;
+ for (i=0; i < ARRAY_SIZE(datamap); i++) {
+ if (datamap[i].modem_val > 0) {
+ tmp.set<VendorAtomValue::intValue>(datamap[i].modem_val);
+ values[datamap[i].modem_msg_field_number - kVendorAtomOffset] = tmp;
+ }
+ if (datamap[i].wifi_val > 0) {
+ tmp.set<VendorAtomValue::intValue>(datamap[i].wifi_val);
+ values[datamap[i].wifi_msg_field_number - kVendorAtomOffset] = tmp;
+ }
+ }
+
+ // Send vendor atom to IStats HAL
+ VendorAtom event = {.reverseDomainName = "",
+ .atomId = PixelAtoms::Atom::kPcieLinkStats,
+ .values = std::move(values)};
+
+ const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
+ if (!ret.isOk()) {
+ ALOGE("Unable to report PCIe link statistics to stats service");
+ }
+}
+
void SysfsCollector::logPerDay() {
const std::shared_ptr<IStats> stats_client = getStatsService();
if (!stats_client) {
@@ -1310,6 +1438,7 @@ void SysfsCollector::logPerDay() {
logTempResidencyStats(stats_client);
logVendorLongIRQStatsReported(stats_client);
logVendorResumeLatencyStats(stats_client);
+ logPcieLinkStats(stats_client);
}
void SysfsCollector::aggregatePer5Min() {
diff --git a/pixelstats/include/pixelstats/SysfsCollector.h b/pixelstats/include/pixelstats/SysfsCollector.h
index df4a331..80ec1a2 100644
--- a/pixelstats/include/pixelstats/SysfsCollector.h
+++ b/pixelstats/include/pixelstats/SysfsCollector.h
@@ -69,6 +69,8 @@ class SysfsCollector {
const char *const TempResidencyPath;
const char *const LongIRQMetricsPath;
const char *const ResumeLatencyMetricsPath;
+ const char *const ModemPcieLinkStatsPath;
+ const char *const WifiPcieLinkStatsPath;
};
SysfsCollector(const struct SysfsPaths &paths);
@@ -111,6 +113,7 @@ class SysfsCollector {
void logVendorAudioHardwareStats(const std::shared_ptr<IStats> &stats_client);
void logVendorLongIRQStatsReported(const std::shared_ptr<IStats> &stats_client);
void logVendorResumeLatencyStats(const std::shared_ptr<IStats> &stats_client);
+ void logPcieLinkStats(const std::shared_ptr<IStats> &stats_client);
const char *const kSlowioReadCntPath;
const char *const kSlowioWriteCntPath;
@@ -142,6 +145,8 @@ class SysfsCollector {
const char *const kTempResidencyPath;
const char *const kLongIRQMetricsPath;
const char *const kResumeLatencyMetricsPath;
+ const char *const kModemPcieLinkStatsPath;
+ const char *const kWifiPcieLinkStatsPath;
BatteryEEPROMReporter battery_EEPROM_reporter_;
MmMetricsReporter mm_metrics_reporter_;
diff --git a/pixelstats/pixelatoms.proto b/pixelstats/pixelatoms.proto
index 433768a..16db5b4 100644
--- a/pixelstats/pixelatoms.proto
+++ b/pixelstats/pixelatoms.proto
@@ -87,6 +87,8 @@ message Atom {
VendorLongIRQStatsReported vendor_long_irq_stats_reported = 105043;
VendorResumeLatencyStats vendor_resume_latency_stats = 105044;
VendorTempResidencyStats vendor_temp_residency_stats = 105045;
+
+ PcieLinkStatsReported pcie_link_stats = 105047;
}
// AOSP atom ID range ends at 109999
}
@@ -1411,3 +1413,33 @@ message VendorResumeLatencyStats {
optional int64 resume_count_bucket_35 = 38;
optional int64 resume_count_bucket_36 = 39;
}
+
+/*
+ * PCIe Link Statistics
+ */
+message PcieLinkStatsReported {
+ /* Vendor reverse domain name (expecting "com.google.pixel"). */
+ optional string reverse_domain_name = 1;
+
+ /* Count of new PCIe Link Down events on the modem interface */
+ optional int32 modem_pcie_linkdowns = 2;
+ /* Count of new PCIe Completion Timeout events on the modem interface */
+ optional int32 modem_pcie_completion_timeouts = 3;
+ /* Count of new PCIe Link Up Failure events on the modem interface */
+ optional int32 modem_pcie_linkup_failures = 4;
+ /* Average pll lock time (uS) during PCIe Link Up on modem interface */
+ optional int32 modem_pcie_pll_lock_avg = 5;
+ /* Average time (uS) for successful PCIe Link Up on modem interface */
+ optional int32 modem_pcie_link_up_avg = 6;
+
+ /* Count of new PCIe Link Down events on the wifi interface */
+ optional int32 wifi_pcie_linkdowns = 7;
+ /* Count of new PCIe Completion Timeout events on the wifi interface */
+ optional int32 wifi_pcie_completion_timeouts = 8;
+ /* Count of new PCIe Link Up Failure events on the wifi interface */
+ optional int32 wifi_pcie_linkup_failures = 9;
+ /* Average pll lock time (uS) during PCIe Link Up on wifi interface */
+ optional int32 wifi_pcie_pll_lock_avg = 10;
+ /* Average time (uS) for successful PCIe Link Up on wifi interface */
+ optional int32 wifi_pcie_link_up_avg = 11;
+}
diff --git a/usb/MonitorFfs.cpp b/usb/MonitorFfs.cpp
index 717e6a7..7a5ad9d 100644
--- a/usb/MonitorFfs.cpp
+++ b/usb/MonitorFfs.cpp
@@ -26,7 +26,8 @@ namespace usb {
static volatile bool gadgetPullup;
-MonitorFfs::MonitorFfs(const char *const gadget)
+MonitorFfs::MonitorFfs(const char *const gadget, const char *const extconTypecState,
+ const char *const usbGadgetState)
: mWatchFd(),
mEndpointList(),
mLock(),
@@ -37,6 +38,8 @@ MonitorFfs::MonitorFfs(const char *const gadget)
mCallback(NULL),
mPayload(NULL),
mGadgetName(gadget),
+ mExtconTypecState(extconTypecState),
+ mUsbGadgetState(usbGadgetState),
mMonitorRunning(false) {
unique_fd eventFd(eventfd(0, 0));
if (eventFd == -1) {
@@ -112,12 +115,26 @@ static void displayInotifyEvent(struct inotify_event *i) {
ALOGE(" name = %s\n", i->name);
}
+void updateState(const char *typecState, const char *usbGadgetState, std::string &typec_state,
+ std::string &usb_gadget_state) {
+ if (ReadFileToString(typecState, &typec_state))
+ typec_state = Trim(typec_state);
+ else
+ typec_state = TYPEC_GADGET_MODE_ENABLE;
+
+ if (ReadFileToString(usbGadgetState, &usb_gadget_state))
+ usb_gadget_state = Trim(usb_gadget_state);
+ else
+ usb_gadget_state = "";
+}
+
void *MonitorFfs::startMonitorFd(void *param) {
MonitorFfs *monitorFfs = (MonitorFfs *)param;
char buf[kBufferSize];
bool writeUdc = true, stopMonitor = false;
struct epoll_event events[kEpollEvents];
steady_clock::time_point disconnect;
+ std::string typec_state, usb_gadget_state;
bool descriptorWritten = true;
for (int i = 0; i < static_cast<int>(monitorFfs->mEndpointList.size()); i++) {
@@ -127,8 +144,14 @@ void *MonitorFfs::startMonitorFd(void *param) {
}
}
+ updateState(monitorFfs->mExtconTypecState, monitorFfs->mUsbGadgetState, typec_state,
+ usb_gadget_state);
+
// notify here if the endpoints are already present.
- if (descriptorWritten) {
+ if (typec_state == TYPEC_GADGET_MODE_DISABLE && usb_gadget_state == GADGET_ACTIVATE) {
+ gadgetPullup = false;
+ ALOGI("pending GADGET pulled up due to USB disconnected");
+ } else if (descriptorWritten) {
usleep(kPullUpDelay);
if (!!WriteStringToFile(monitorFfs->mGadgetName, PULLUP_PATH)) {
lock_guard<mutex> lock(monitorFfs->mLock);
@@ -172,7 +195,14 @@ void *MonitorFfs::startMonitorFd(void *param) {
}
}
- if (!descriptorPresent && !writeUdc) {
+ updateState(monitorFfs->mExtconTypecState, monitorFfs->mUsbGadgetState,
+ typec_state, usb_gadget_state);
+
+ if (typec_state == TYPEC_GADGET_MODE_DISABLE &&
+ usb_gadget_state == GADGET_ACTIVATE) {
+ gadgetPullup = false;
+ ALOGI("pending GADGET pulled up due to USB disconnected");
+ } else if (!descriptorPresent && !writeUdc) {
if (kDebug)
ALOGI("endpoints not up");
writeUdc = true;
diff --git a/usb/include/pixelusb/UsbGadgetCommon.h b/usb/include/pixelusb/UsbGadgetCommon.h
index 964a1d6..01467e0 100644
--- a/usb/include/pixelusb/UsbGadgetCommon.h
+++ b/usb/include/pixelusb/UsbGadgetCommon.h
@@ -19,10 +19,9 @@
#include <android-base/file.h>
#include <android-base/properties.h>
+#include <android-base/strings.h>
#include <android-base/unique_fd.h>
-
#include <android/hardware/usb/gadget/1.0/IUsbGadget.h>
-
#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
@@ -34,6 +33,7 @@
#include <sys/types.h>
#include <unistd.h>
#include <utils/Log.h>
+
#include <chrono>
#include <condition_variable>
#include <mutex>
@@ -74,9 +74,15 @@ constexpr char kVendorRndisConfig[] = "vendor.usb.rndis.config";
#define FUNCTION_NAME "function"
#define FUNCTION_PATH CONFIG_PATH FUNCTION_NAME
#define RNDIS_PATH FUNCTIONS_PATH "gsi.rndis"
+#define TYPEC_GADGET_MODE_DISABLE "0"
+#define TYPEC_GADGET_MODE_ENABLE "1"
+#define GADGET_DEACTIVATE "0"
+#define GADGET_ACTIVATE "1"
using ::android::base::GetProperty;
+using ::android::base::ReadFileToString;
using ::android::base::SetProperty;
+using ::android::base::Trim;
using ::android::base::unique_fd;
using ::android::base::WriteStringToFile;
using ::android::hardware::usb::gadget::V1_0::GadgetFunction;
@@ -126,31 +132,35 @@ class MonitorFfs {
void *mPayload;
// Name of the USB gadget. Used for pullup.
const char *const mGadgetName;
+ // Extcon USB state from Type-C notification.
+ const char *const mExtconTypecState;
+ // USB Gadget state from Dwc3 device.
+ const char *const mUsbGadgetState;
// Monitor State
bool mMonitorRunning;
public:
- MonitorFfs(const char *const gadget);
- // Inits all the UniqueFds.
- void reset();
- // Starts monitoring endpoints and pullup the gadget when
- // the descriptors are written.
- bool startMonitor();
- // Waits for timeout_ms for gadget pull up to happen.
- // Returns immediately if the gadget is already pulled up.
- bool waitForPullUp(int timeout_ms);
- // Adds the given fd to the watch list.
- bool addInotifyFd(string fd);
- // Adds the given endpoint to the watch list.
- void addEndPoint(string ep);
- // Registers the async callback from the caller to notify the caller
- // when the gadget pull up happens.
- void registerFunctionsAppliedCallback(void (*callback)(bool functionsApplied,
- void *(payload)),
- void *payload);
- bool isMonitorRunning();
- // Ep monitoring and the gadget pull up logic.
- static void *startMonitorFd(void *param);
+ MonitorFfs(const char *const gadget, const char *const extconTypecState = "",
+ const char *const usbGadgetState = "");
+ // Inits all the UniqueFds.
+ void reset();
+ // Starts monitoring endpoints and pullup the gadget when
+ // the descriptors are written.
+ bool startMonitor();
+ // Waits for timeout_ms for gadget pull up to happen.
+ // Returns immediately if the gadget is already pulled up.
+ bool waitForPullUp(int timeout_ms);
+ // Adds the given fd to the watch list.
+ bool addInotifyFd(string fd);
+ // Adds the given endpoint to the watch list.
+ void addEndPoint(string ep);
+ // Registers the async callback from the caller to notify the caller
+ // when the gadget pull up happens.
+ void registerFunctionsAppliedCallback(void (*callback)(bool functionsApplied, void *(payload)),
+ void *payload);
+ bool isMonitorRunning();
+ // Ep monitoring and the gadget pull up logic.
+ static void *startMonitorFd(void *param);
};
//**************** Helper functions ************************//
@@ -172,6 +182,9 @@ Status addGenericAndroidFunctions(MonitorFfs *monitorFfs, uint64_t functions,
bool *ffsEnabled, int *functionCount);
// Pulls down USB gadget.
Status resetGadget();
+// Update the state from typec and usb gadget
+void updateState(const char *typecState, const char *usbGadgetState, std::string &typec_state,
+ std::string &usb_gadget_state);
} // namespace usb
} // namespace pixel
diff --git a/vibrator/cs40l26/Hardware.h b/vibrator/cs40l26/Hardware.h
index 2143b96..ae052ba 100644
--- a/vibrator/cs40l26/Hardware.h
+++ b/vibrator/cs40l26/Hardware.h
@@ -220,10 +220,7 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
ALOGE("Invalid waveform index for OWT erase: %d", effectIndex);
return false;
}
- // Turn off the waiting time for SVC init phase to complete since chip
- // should already under STOP state
- setMinOnOffInterval(0);
- // Do erase flow
+
if (effectIndex < WAVEFORM_MAX_INDEX) {
/* Normal situation. Only erase the effect which we just played. */
if (ioctl(fd, EVIOCRMFF, effectIndex) < 0) {
@@ -251,8 +248,6 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
(*effect)[i].id = -1;
}
}
- // Turn on the waiting time for SVC init phase to complete
- setMinOnOffInterval(Vibrator::MIN_ON_OFF_INTERVAL_US);
return true;
}
diff --git a/vibrator/cs40l26/Vibrator.cpp b/vibrator/cs40l26/Vibrator.cpp
index 2501224..c19c7f8 100644
--- a/vibrator/cs40l26/Vibrator.cpp
+++ b/vibrator/cs40l26/Vibrator.cpp
@@ -48,6 +48,7 @@ static constexpr uint32_t WAVEFORM_LONG_VIBRATION_THRESHOLD_MS = 50;
static constexpr uint8_t VOLTAGE_SCALE_MAX = 100;
static constexpr int8_t MAX_COLD_START_LATENCY_MS = 6; // I2C Transaction + DSP Return-From-Standby
+static constexpr uint32_t MIN_ON_OFF_INTERVAL_US = 8500; // SVC initialization time
static constexpr int8_t MAX_PAUSE_TIMING_ERROR_MS = 1; // ALERT Irq Handling
static constexpr uint32_t MAX_TIME_MS = UINT16_MAX;
diff --git a/vibrator/cs40l26/Vibrator.h b/vibrator/cs40l26/Vibrator.h
index 27ee283..220c974 100644
--- a/vibrator/cs40l26/Vibrator.h
+++ b/vibrator/cs40l26/Vibrator.h
@@ -154,9 +154,6 @@ class Vibrator : public BnVibrator {
binder_status_t dump(int fd, const char **args, uint32_t numArgs) override;
- // SVC initialization time
- static constexpr uint32_t MIN_ON_OFF_INTERVAL_US = 8500;
-
private:
ndk::ScopedAStatus on(uint32_t timeoutMs, uint32_t effectIndex, struct dspmem_chunk *ch,
const std::shared_ptr<IVibratorCallback> &callback);