Pmic ldo voltages


#1

I am trying to change the pmic ldo voltages, but I can seem to get them to change. I’ve been working wtih L11 (SD Card regulator), and I can get /sys/class/regulator/regulator.18/microvolts to change, but the voltage level is always the default (2.95V).

I have also tried to change the registers directly in qcom_spmi-regulator.c, but that causes a board reboot.

I am using the 4.9 kernel on yocto morty.


#2

Update: I added a printk in smd-rpm.c qcom_rpm_smd_write() (see code below) to verify that I am sending what I think I am.

I see the enable & disable and this works as expected. The set voltage looks good, but it never changes on the o-scope (always 2.95V).

Is there something I am missing? What else can I check to ensure SMD is sending the data to the PMIC?

Why are both qcom_smd_regulator and qcom_spmi_regulator used?

Thanks for the help with this.
Mark


printk output

[ 0.258509] l11: Bringing 0uV into 1750000-1750000uV
[ 0.258518] qcom_rpm_smd_regulator smd:rpm:rpm_requests:pm8916-regulators: ((((((((((((((rpm_reg_set_voltage
[ 0.258529] qcom_smd_rpm smd:rpm.rpm_requests.-1.-1: ***********smd-rpm: 0x0, 0x616f646c, 0xb, 0x7675, 0x4, 0x1e8480
[ 0.258696] qcom_smd_rpm smd:rpm.rpm_requests.-1.-1: ***********smd-rpm: 0x0, 0x616f646c, 0xb, 0x6e657773, 0x4, 0x1


qcom_rpm_smd_write()

/**

  • qcom_rpm_smd_write - write @buf to @type:@id

  • @rpm: rpm handle

  • @type: resource type

  • @id: resource identifier

  • @buf: the data to be written

  • @count: number of bytes in @buf
    */
    int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
    int state,
    u32 type, u32 id,
    void *buf,
    size_t count)
    {
    static unsigned msg_id = 1;
    int left;
    int ret;
    struct {
    struct qcom_rpm_header hdr;
    struct qcom_rpm_request req;
    u8 payload[];
    } *pkt;
    size_t size = sizeof(*pkt) + count;

    /* SMD packets to the RPM may not exceed 256 bytes */
    if (WARN_ON(size >= 256))
    return -EINVAL;

    pkt = kmalloc(size, GFP_KERNEL);
    if (!pkt)
    return -ENOMEM;

    mutex_lock(&rpm->lock);

    pkt->hdr.service_type = cpu_to_le32(RPM_SERVICE_TYPE_REQUEST);
    pkt->hdr.length = cpu_to_le32(sizeof(struct qcom_rpm_request) + count);

    pkt->req.msg_id = cpu_to_le32(msg_id++);
    pkt->req.flags = cpu_to_le32(state);
    pkt->req.type = cpu_to_le32(type);
    pkt->req.id = cpu_to_le32(id);
    pkt->req.data_len = cpu_to_le32(count);
    memcpy(pkt->payload, buf, count);

    if(type == 0x616f646c )
    {
    u32 buf_ptru32 = buf;
    dev_info(rpm->dev,"
    ********** smd-rpm: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x",state,type,id,buf_ptru32[0],buf_ptru32[1],buf_ptru32[2]);
    }

    ret = rpmsg_send(rpm->rpm_channel, pkt, size);
    if (ret)
    goto out;

    left = wait_for_completion_timeout(&rpm->ack, RPM_REQUEST_TIMEOUT);
    if (!left)
    ret = -ETIMEDOUT;
    else
    ret = rpm->ack_status;

out:
kfree(pkt);
mutex_unlock(&rpm->lock);
return ret;
}
EXPORT_SYMBOL(qcom_rpm_smd_write);


#3

Hi @Mark_Vogt,

I also get similar problems by using kernel 4.4 on Yocto krogoth.

Here is my situation.
I try to modify the DTS to change all LDO regulators for our power test.
The change is as below. (In this patch, I change L8, L11 & L12 to v3.3)

index 2e9d51a9e..9303fe821
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
@@ -104,8 +104,8 @@

                                        };
                                        l8 {
-                                               regulator-min-microvolt = <1750000>;
-                                               regulator-max-microvolt = <3337000>;
+                                               regulator-min-microvolt = <3300000>;
+                                               regulator-max-microvolt = <3300000>;

                                        };
                                        l9 {
@@ -119,13 +119,13 @@

                                        };
                                        l11 {
-                                               regulator-min-microvolt = <1750000>;
-                                               regulator-max-microvolt = <3337000>;
+                                               regulator-min-microvolt = <3300000>;
+                                               regulator-max-microvolt = <3300000>;

                                        };
                                        l12 {
-                                               regulator-min-microvolt = <1750000>;
-                                               regulator-max-microvolt = <3337000>;
+                                               regulator-min-microvolt = <3300000>;
+                                               regulator-max-microvolt = <3300000>;

                                        };
                                        l13 {

Then, I can get some correct values in regulator_summary.
You can see voltages at the upper part of L8, L11, L12 are all correct as expected.
However, the actual voltages we measured on o-scope are still unchanged as the bottom part.

$ cat /sys/kernel/debug/regulator/regulator_summary
 regulator                      use open bypass voltage current     min     max
-------------------------------------------------------------------------------
 regulator-dummy                  0    8      0     0mV     0mA     0mV     0mV
    1c00000.qcom,adreno-3xx                                         0mV     0mV
    1c00000.qcom,adreno-3xx                                         0mV     0mV
    1a00000.qcom,mdss_mdp                                           0mV     0mV
    1a98000.qcom,mdss_dsi                                           0mV     0mV
    a204000.wcnss                                                   0mV     0mV
    venus_pil                                                       0mV     0mV
    4080000.hexagon                                                 0mV     0mV
    4080000.hexagon                                                 0mV     0mV
 camera_vdddo                     0    0      0  1800mV     0mA  1800mV  1800mV
 camera_vdda                      0    0      0  2800mV     0mA  2800mV  2800mV
 camera_vddd                      0    0      0  1500mV     0mA  1500mV  1500mV
 s1                               0    0      0     0mV     0mA   375mV  1550mV
 s2                               0    0      0     0mV     0mA   375mV  1550mV
 s3                               2    3      0  1300mV     0mA   375mV  1550mV
    a204000.wcnss:iris                                           1300mV  1300mV
    l2                            1    1      0  1200mV     0mA   375mV  1525mV
       1a98000.qcom,mdss_dsi                                     1200mV  1200mV
    l3                            1    3      0  1287mV     0mA   375mV  1525mV
       a204000.wcnss                                             1287mV  1287mV
       4080000.hexagon                                              0mV     0mV
       b018000.cpr                                                  0mV     0mV
 s4                               0    3      0  1800mV     0mA  1800mV  1800mV
    l5                            3    4      0  1800mV     0mA  1750mV  3325mV
       200f000.spmi:pm8916@1:codec@f000                                     0mV     0mV
       200f000.spmi:pm8916@1:codec@f000                                     0mV     0mV
       a204000.wcnss:iris                                        1800mV  1800mV
       7824900.sdhci                                             1750mV  1950mV
    l6                            3    3      0  1800mV     0mA  1750mV  3325mV
       1a98000.qcom,mdss_dsi                                     1800mV  1800mV
       2-0039                                                    1800mV  1800mV
       1a98300.qcom,mdss_dsi_phy                                  1800mV  1800mV
    l7                            1    4      0  1800mV     0mA  1750mV  3325mV
       78d9000.phy                                               1800mV  1800mV
       a204000.wcnss:iris                                        1800mV  1800mV
       a204000.wcnss                                             1800mV  1800mV
       4080000.hexagon                                              0mV     0mV
 l1                               0    0      0     0mV     0mA   375mV  1525mV
 l4                               0    0      0     0mV     0mA  1750mV  3325mV
 l8                               1    1      0  3300mV     0mA  3300mV  3300mV
    7824900.sdhci                                                3300mV  3400mV
 l9                               0    1      0  3300mV     0mA  1750mV  3325mV
    a204000.wcnss:iris                                           3300mV  3300mV
 l10                              0    0      0     0mV     0mA  1750mV  3325mV
 l11                              0    1      0  3300mV     0mA  3300mV  3300mV
    7864900.sdhci                                                3300mV  3400mV
 l12                              1    1      0  3300mV     0mA  3300mV  3300mV
    7864900.sdhci                                                2700mV  3600mV
 l13                              1    2      0  3050mV     0mA  1750mV  3325mV
    78d9000.phy                                                  3050mV  3300mV
    200f000.spmi:pm8916@1:codec@f000                                     0mV     0mV
 l14                              0    0      0     0mV     0mA  1750mV  3325mV
 l15                              0    0      0     0mV     0mA  1750mV  3325mV
 l16                              0    0      0     0mV     0mA  1750mV  3325mV
 l17                              2    2      0  3300mV     0mA  1750mV  3325mV
    1a98000.qcom,mdss_dsi                                        2850mV  3300mV
    2-0039                                                       3300mV  3300mV
 l18                              0    0      0     0mV     0mA  1750mV  3325mV
 ------------------------------------------------------------------------------
 s1                               0    0      0  1137mV     0mA     0mV     0mV
 s2                               1    2      0  1050mV     0mA  1050mV  1350mV
    cpu0                                                         1050mV  1050mV
    cpu0                                                            0mV     0mV
 s3                               0    0      0  1350mV     0mA     0mV     0mV
 s4                               0    0      0  2050mV     0mA     0mV     0mV
 l1                               0    0      0  1287mV     0mA     0mV     0mV
 l2                               0    0      0  1200mV     0mA     0mV     0mV
 l3                               0    0      0  1287mV     0mA     0mV     0mV
 l4                               0    0      0  2050mV     0mA     0mV     0mV
 l5                               0    0      0  1800mV     0mA     0mV     0mV
 l6                               0    0      0  1800mV     0mA     0mV     0mV
 l7                               0    0      0  1800mV     0mA     0mV     0mV
 l8                               0    0      0  2900mV     0mA     0mV     0mV
 l9                               0    0      0  3300mV     0mA     0mV     0mV
 l10                              0    0      0  2800mV     0mA     0mV     0mV
 l11                              0    0      0  2950mV     0mA     0mV     0mV
 l12                              0    0      0  2950mV     0mA     0mV     0mV
 l13                              0    0      0  3075mV     0mA     0mV     0mV
 l14                              0    0      0  1800mV     0mA     0mV     0mV
 l15                              0    0      0  1800mV     0mA     0mV     0mV
 l16                              0    0      0  1800mV     0mA     0mV     0mV
 l17                              0    0      0  3300mV     0mA     0mV     0mV
 l18                              0    0      0  2700mV     0mA     0mV     0mV

But, by this way, some LDO regulators can be changed actually, e.g. L2.
It can work because it seems to bind with a dummy regulator.

[    1.861413] 1a98000.qcom,mdss_dsi supply gdsc not found, using dummy regulator
[    1.863037] 1a98000.qcom,mdss_dsi supply gdsc not found, using dummy regulator
[    1.870637] l2: supplied by s3

I also get the reboot issue, if I modify some LDO regulators in spmi device tree.
By experiment, it seems only S2 can be modified in qcom-spmi-regulator.

diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi
index 48d2068..4191c7d 100644
--- a/arch/arm64/boot/dts/qcom/pm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi
@@ -113,8 +113,9 @@
                        pm8916_spmi_s2: s2@1700 {
                                reg = <0x1700 0x300>;
                                status = "ok";
-                               regulator-min-microvolt = <1050000>;
-                               regulator-max-microvolt = <1350000>;
+                               regulator-min-microvolt = <1150000>;
+                               regulator-max-microvolt = <1150000>;
+                               regulator-always-on;
                        };

                        s3@1a00 {

In my observation, it seems to have two groups.

  • SPM controlled regulators : S2 (for CPU)
  • RPM controlled regulators : Others (S1, S3, S4, L1 ~ L18)

Unfortuantely, I’m still trying to find how to change them correctly.
Look forward to others’ comments.

Best regards,
Daniel


#4

Hi Daniel,

Here is what I learned this week. The PMIC will only allow values from the “specified range” from table 3-16 (page 35-36) in this doc https://developer.qualcomm.com/qfile/29367/lm80-p0436-35_a_pm8916-pm8916-1_device_spec.pdf . Any other values are ignored.

For me this means L11 is fixed at 2.95V even though the programmable range is listed at 1.75-3.337V. FYI, I was able to change a few of the regulators.

Hope this helps,
Mark


#5

Hi @Mark_Vogt,

Thanks for sharing. That’s helpful.
May I know how do you change the voltage? DTS as I mentioned or driver modifying?

Thanks,
Daniel


#6

I used the device tree min voltage.

Mark


#7

Hi Mark,

It seems not all regulators can be modified as “specified range”.
I try to modify S3 to 1.3v which the specified range is 1.25-1.35.

index 2279c73..e8d550c 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
@@ -41,122 +41,121 @@
                                        };
                                        s3 {
                                                regulator-min-microvolt = <375000>;
-                                               regulator-max-microvolt = <1562000>;
-
+                                               regulator-max-microvolt = <1300000>;
+                                               regulator-always-on;
                                        };
                                        s4 {

From kernel log, it looks like success, but I still get 1.35v on the o-scope.

[    3.993809] s3: Restricting voltage, 1300000-1287500uV

Best regards,
Daniel


#8

I never tried the S regulators, only the L’s