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