diff options
-rw-r--r-- | pixelstats/SysfsCollector.cpp | 131 | ||||
-rw-r--r-- | pixelstats/include/pixelstats/SysfsCollector.h | 5 | ||||
-rw-r--r-- | pixelstats/pixelatoms.proto | 32 | ||||
-rw-r--r-- | usb/MonitorFfs.cpp | 36 | ||||
-rw-r--r-- | usb/include/pixelusb/UsbGadgetCommon.h | 59 | ||||
-rw-r--r-- | vibrator/cs40l26/Hardware.h | 7 | ||||
-rw-r--r-- | vibrator/cs40l26/Vibrator.cpp | 1 | ||||
-rw-r--r-- | vibrator/cs40l26/Vibrator.h | 3 |
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); |