On downstream power domains and regular regulators are somewhat mixed together (like this). On mainline, power domains go in one place and regulators in another, because it turns out, they are completely different beasts.
I can’t really explain what the difference is, but power domains are like a cooktop you can configure from 0 (off) to N (highest power).
The source is mainly DT and a little bit of header files. Keep in mind that the regulator code is contained in a few different source dtsi files, so it’s best to look at the final full device DT.
Look under the
qcom,rpm-smd node, there are a bunch of
rpm-regulator-XXXX nodes, which have subnodes. Those have to be translated to something like this:
DEFINE_RPMPD_PAIR(sm6115, vddcx, vddcx_ao, RWCX, LEVEL, 0); DEFINE_RPMPD_VFL(sm6115, vddcx_vfl, RWCX, 0);
First of all, we need to figure out which
rpm-regulator-XXX nodes are power domains, and which are regulators; for this we need to look at the
qcom,resource-name field, if it’s
smpa then it’s regulator (most are regulators). NOTE: Of course with time this can change, treat this more as an example than an exact process. Another thing to keep in mind that sometimes the resource names differ from DS and ML. Check troubleshooting section.
I’m not really sure how this is called. Anyway, the subnodes under
rpm-regulator-XXX (for power supplies) have interesting suffixes, like
floor-level (some might
status = "disabled", so keep an eye for that).
So apparently the
ao stands for
always-on), are a pair, so they are defined using
floor-level on the other hand is defined using
FL stands for
floor-level). Also other platforms might have the word
corner which is an alternative to
Lastly there is the
rpm-regulator-XXX, this goes as the last argument of the declaring macro.
There is one last bit of data needed — the maximum state allowed by the hardware for all power supplies on the platform. It goes in the
plat_desc struct in ML. To get it you need to look for the file included by all the clk DS drivers (in my case the file is called
vdd-level-bengal.h). So take the last corner value (in my case
RPMH_REGULATOR_LEVEL_TURBO_L1 corresponds to 416), and then find the right constant name from
include/dt-bindings/power/qcom-rpmpd.h (in ML), in my case:
#define RPM_SMD_LEVEL_TURBO_NO_CPR 416
So I stick
.max_state and that’s it.
Power supply names
In my case they were comments inside the source dts (you loose comments if you look at decompiled DT, so you have to search through the source files to find the original definitions). So
PM6125 S3/S4 - VDD_CX supply becomes
vddcx in mainline (look for previously defined names for inspiration.
So you’ll either get a
floor-level, or a
corner-ao and optionally a
floor-corner. That is for each power supply defined in Downstream.
So if you have both a level+ao or corner+ao you use the PAIR macro with
CORNER second-to-last arg, then you put the resource name as third-to-last arg, and the resource-id as last arg:
DEFINE_RPMPD_PAIR(platform_name, name, name_ao, RES_NAME, CORNER_OR_LEVEL, RES_ID);
Otherwise you define them one by one with the corresponding macro:
DEFINE_RPMPD_TYPE(platform_name, name, RES_NAME, RES_ID);
Then you have to stick those inside the
platform_name_rpmpds, but that part is obvious. The indexes are arbitrary and go in the binding include file, so they can be included and used from DT files.
If the resource name from downstream doesn’t match, you’ll have to look at the magic constants and try to match them with DS:
// from drivers/soc/qcom/rpmpd.c in mainline #define RPMPD_SMPA 0x61706d73 #define RPMPD_LDOA 0x616f646c #define RPMPD_SMPB 0x62706d73 #define RPMPD_LDOB 0x626f646c #define RPMPD_RWCX 0x78637772 #define RPMPD_RWMX 0x786d7772 #define RPMPD_RWLC 0x636c7772 #define RPMPD_RWLM 0x6d6c7772 #define RPMPD_RWSC 0x63737772 #define RPMPD_RWSM 0x6d737772
All in all there is not much to go wrong, but when I first stumbled with it it was totally NOT obvious what goes where and where it comes from, so hopefully this helps somebody in the future.
Special thanks to user
aka_ and Konrad from PostmarketOS Mainlining channel for the help in figuring this out.