1# Voltage Regulator Configuration 2 3Author: Shawn McCarney (Discord ShawnMcCarney) 4 5Other contributors: Derek Howard (Discord derekh55), Matt Spinler (Discord mspinler) 6 7Created: 2019-07-13 8 9 10## Problem Description 11[Voltage regulators][1] have many configurable properties such as output 12voltage, over-current limit, and pgood thresholds. The configuration is often 13dependent on the system type and rail type. Regulators have a hardware default 14configuration that is defined by hardware engineers early in system design. 15However, this default configuration sometimes must be modified by firmware. A 16new application is needed to configure regulators. It should be data-driven to 17support a variety of regulator types and to avoid hard-coded logic. 18 19 20## Background and References 21 22### Regulator Configuration Data ("Config File") 23Hardware engineers must specify many low-level configuration values for a 24regulator. Some simple examples include output voltage, over-current limit, 25and pgood thresholds. These values often vary depending on the system type and 26rail type. 27 28Depending on the regulator type, the hardware engineer may enter the 29configuration values into a tool that produces a "config file". 30 31The regulator configuration information is sent to manufacturing and stored in 32non-volatile memory on the regulator. This provides the hardware/power-on 33default configuration. 34 35The default configuration values often need to be changed later. This can be 36due to factors such as the following: 37* New information found during hardware testing. For example, downstream 38 hardware requires a higher voltage or is drawing more current than expected. 39* Hardware workarounds. Problems in the regulator hardware or related hardware 40 sometimes require new configuration values to work around the issue. The 41 problem may be resolved in newer versions of the hardware, but firmware still 42 must support the older hardware. For this reason, hardware workarounds are 43 sometimes conditional, applied only to regulators with a certain version 44 register value or [Vital Product Data (VPD)][2] keyword value. 45* Improve manufacturing yields. Sometimes regulator configuration values must 46 be changed to allow more hardware to pass manufacturing tests. For example, 47 the voltage may need to be increased to overcome minor manufacturing defects. 48 49### OpenBMC Regulator Configuration Scripts 50Regulator configuration changes are performed on some OpenBMC systems using 51shell scripts. For example, the following scripts configure regulators on 52Witherspoon systems: 53* [vrm-control.sh][3] 54* [power-workarounds.sh][4] 55 56### Hwmon and IIO Device Driver Frameworks 57The Linux [Hardware Monitoring Kernel API (hwmon)][5] and [Industrial I/O 58Subsystem (IIO)][6] provide device driver frameworks for monitoring hardware 59and making sensor values available to applications. They do not provide an 60interface for performing low-level regulator configuration. 61 62### Voltage and Current Regulator Device Framework 63The Linux [Voltage and Current Regulator API][7] provides a device driver 64framework for voltage and current regulators. It provides a mechanism for the 65device drivers of "consumer" devices to request a voltage or current level from 66the regulator. It does not provide an interface for performing low-level 67regulator configuration. 68 69 70## Requirements 71* Provide ability to modify configuration of any voltage regulator with a PMBus 72 or I2C connection to the BMC. 73* Apply the configuration changes early in the boot before the regulators are 74 enabled. 75* If an error occurs trying to configure a regulator, log the error and 76 continue with the next regulator. 77* Read configuration changes from a data file that is read at run-time. 78* Provide a method for testing new configuration changes by copying a new data 79 file to the BMC. 80 81### Non-Requirements 82* Enable/disable voltage regulators and monitor their pgood signals. 83 * This is handled by the power sequencer chip and related firmware. 84* Modify regulator configuration after regulator has been enabled. 85 * Modifying regulator configuration while the system is running 86 is often done by the host using a different bus connection. 87* Validate that the correct number and types of regulators are present in the 88 system. 89* Concurrent maintenance or hot-plugging of regulators, where a regulator is 90 removed/added/replaced while the system is running. 91 92 93## Proposed Design 94 95### Application 96A new application named `phosphor-regulators` will be created to configure 97voltage regulators. The application will be located in the proposed new 98`phosphor-power` repository. 99 100*Statement of direction: This application will provide other regulator-based 101functionality in the future, such as detecting redundant phase faults.* 102 103### Application Data File 104The application will read a JSON file at runtime that defines the configuration 105changes for all regulators. The JSON file will be specific to a system type, 106so it will be stored in the GitHub repository for the appropriate build layer 107(such as meta-ibm). 108 109JSON file location on the BMC: 110* Standard directory: `/usr/share/phosphor-regulators` (read-only) 111* Test directory: `/etc/phosphor-regulators` (writable) 112 113A new version of the JSON file can be tested by copying it to the test 114directory. The application will search both directories, and the file in the 115test directory will override the file in the standard directory. If the 116application receives a SIGHUP signal, it will re-read the JSON file. 117 118A document will be provided that describes the objects and properties that can 119appear in the JSON file. A validation tool will also be provided to verify the 120syntax and contents of the JSON file. 121 122*Statement of direction: This JSON file will be used in the future to define 123other regulator operations, such as how to detect a redundant phase fault.* 124 125### D-Bus Interfaces 126The following new D-Bus interface will be created: 127* Name: `xyz.openbmc_project.Regulator.Collection.Configure` 128* Description: Configures all voltage regulators. 129* Properties: None 130* Methods: Configure() 131 132*Statement of direction: New interfaces that apply to all regulators would use 133the same xyz.openbmc_project.Regulator.Collection namespace. New interfaces 134that apply to a single regulator would use the xyz.openbmc_project.Regulator 135namespace.* 136 137### D-Bus Paths 138The new `xyz.openbmc_project.Regulator.Collection.Configure` interface will be 139implemented on the object path `/xyz/openbmc_project/regulators`. 140 141*Statement of direction: New interfaces that apply to all regulators would be 142implemented on the same object path. Individual regulators would be 143represented by the object path 144`/xyz/openbmc_project/regulators/<regulator_name>`, and interfaces that apply 145to a single regulator would be implemented on that path.* 146 147### Systemd 148The application will be started using systemd when the BMC is at standby. The 149service file will be named `xyz.openbmc_project.Regulators.service`. 150 151During the boot when the chassis is being powered on, the Configure() method on 152the new `xyz.openbmc_project.Regulator.Collection.Configure` interface will be 153called. This must be done prior to the systemd target that enables the 154regulators (powers them on). 155 156### Regulator Device Interface 157The application will communicate with the voltage regulators directly using the 158[i2c-dev][8] userspace I2C interface. Direct communication will be used rather 159than device drivers because the current Linux device driver frameworks do not 160provide the necessary functionality. See the [Alternatives 161Considered](#alternatives-considered) section for more information. 162 163Voltage regulators that are configured using this application will not be bound 164to device drivers in the Linux device tree. When the system is powered on, the 165application will obtain the regulator sensor values and store them on D-Bus in 166the same format as `phosphor-hwmon`. 167 168*Statement of direction: If a driver framework is developed in the future that 169supports low-level regulator configuration, then this application will be 170enhanced to utilize those drivers. The goal is for the application to support 171a flexible device interface, where drivers are used if possible and i2c-dev is 172used if necessary.* 173 174 175## Alternatives Considered 176 177### Using Standard Linux Device Drivers to Configure Regulators 178Ideally one of the following device driver frameworks could be used rather than 179i2c-dev to configure the regulators: 180* [Hardware Monitoring Kernel API][5] 181* [Industrial I/O Subsystem][6] 182* [Voltage and Current Regulator API][7] 183 184Unfortunately none of these provide the required functionality: 185* Ability to perform system-specific and rail-specific, low-level 186 configuration. 187* Ability to perform dynamic configuration based on regulator version register 188 values or [VPD][2] values. 189* Ability to test new configuration values iteratively and quickly without 190 needing to modify a device driver or rebuild the kernel. 191 192A meeting was held with Joel Stanley and Andrew Jeffery to discuss this issue. 193They believe long term a new driver framework could be designed that would 194provide this functionality and would be acceptable to the Linux upstream 195community. If this occurs, this application will be modified to utilize the 196new driver framework rather than performing direct I2C communication from 197userspace. 198 199### Using Shell Scripts to Configure Regulators 200Currently shell scripts are used to configure regulators on some OpenBMC 201systems, such as Witherspoon. During boot, the shell scripts unbind device 202drivers, perform `i2cset` commands to configure regulators, and then re-bind 203device drivers. 204 205Using shell scripts has the following disadvantages: 206* Typically no error checking is performed to verify the `i2cset` command 207 worked. If error checking were added based on return code, it would be 208 difficult to log an appropriate error with all the necessary information. 209* On a large system with many regulators and register updates, a shell 210 script would run more slowly than an application and negatively impact boot 211 speed. Each `i2cset` command requires starting a separate child process. 212* Scripts are usually hard-coded to one system type and do not provide a 213 common, data-driven solution. 214 215 216## Impacts 217* No major impacts are expected to existing APIs, security, documentation, 218 performance, or upgradability. 219* The new D-Bus interface is documented in the [Proposed 220 Design](#proposed-design) section. 221* The application should be able to configure regulators using 222 i2c-dev as fast or faster than equivalent shell scripts using `i2cset`. 223* The regulator sensor values will be stored on D-Bus in a way that is 224 consistent with `phosphor-hwmon`. 225 226 227## Testing 228* Automated test cases will be written to test as much of the application code 229 as possible. 230* A mock device interface will be used to test that the correct I2C reads and 231 writes are occurring without accessing real hardware. 232* End-to-end boot testing will be performed to ensure that the correct I2C 233 reads/writes occurred, that the system boots, and that no errors occur. 234* CI tests that boot a system will indirectly test this application. 235 236 237[1]: https://en.wikipedia.org/wiki/Voltage_regulator_module 238[2]: https://en.wikipedia.org/wiki/Vital_Product_Data 239[3]: https://github.com/openbmc/meta-ibm/blob/master/meta-witherspoon/recipes-phosphor/chassis/vrm-control/vrm-control.sh 240[4]: https://github.com/openbmc/meta-ibm/blob/master/meta-witherspoon/recipes-phosphor/chassis/power-workarounds/witherspoon/power-workarounds.sh 241[5]: https://www.kernel.org/doc/html/latest/hwmon/hwmon-kernel-api.html 242[6]: https://www.kernel.org/doc/html/latest/driver-api/iio/index.html 243[7]: https://www.kernel.org/doc/html/latest/driver-api/regulator.html 244[8]: https://www.kernel.org/doc/Documentation/i2c/dev-interface 245