msm: krait-regulator: handle efuse differences
Scaling factor version is valid for
- 8974 based devices when the version bits read 1
- 8974pro based devices when the version bits read 1 or 2
- 8084 based devices when the version bits read 0
- 8092 based devices when the version bits read 0
Moreover the three bit scaling factor data for
- 8974 based devices starts at bit 16
- 8974pro based devices starts at bit 16
- 8084 based devices starts at bit 14
- 8092 based devices starts at bit 14
Update the code to handle these differences.
CRs-Fixed: 614657
Change-Id: I30c65026341ece9a03f88514127b563417df46ee
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/regulator/krait-regulator.txt b/Documentation/devicetree/bindings/regulator/krait-regulator.txt
index 7c661fe..004c4df 100644
--- a/Documentation/devicetree/bindings/regulator/krait-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/krait-regulator.txt
@@ -22,7 +22,12 @@
the phase scaling factor eFuse address.
- qcom,pfm-threshold The power coeff threshold in abstract power units below which
pmic will be made to operate in PFM mode.
-
+- qcom,phase-scaling-factor-bits-pos indicates bit position of scaling factor data within the efuse
+ register.
+- qcom,valid-scaling-factor-versions This is an array holding four boolean values and indicates whether
+ the version read from efuses is valid.
+ The version is a two bit field and the value read from hardware is
+ used as an index in this array to check for validity.
Optional properties:
- qcom,use-phase-switching indicates whether the driver should add/shed phases on the PMIC
ganged regulator as cpus are hotplugged.
@@ -70,6 +75,9 @@
qcom,use-phase-switching;
qcom,use-phase-scaling-factor;
qcom,pfm-threshold = <376975>;
+ qcom,phase-scaling-factor-bits-pos = <18>;
+ qcom,valid-scaling-factor-versions = <0 1 1 0>;
+
#address-cells = <1>;
#size-cells = <1>;
ranges;
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index 5cf98d6..45b716a 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -465,6 +465,8 @@
ranges;
qcom,pfm-threshold = <76>;
qcom,use-phase-scaling-factor;
+ qcom,phase-scaling-factor-bits-pos = <16>;
+ qcom,valid-scaling-factor-versions = <0 1 0 0>;
krait0_vreg: regulator@f9088000 {
compatible = "qcom,krait-regulator";
diff --git a/arch/arm/boot/dts/msm8974pro-pm8941.dtsi b/arch/arm/boot/dts/msm8974pro-pm8941.dtsi
index decd444..9c2be1a 100644
--- a/arch/arm/boot/dts/msm8974pro-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pm8941.dtsi
@@ -34,6 +34,8 @@
&krait_pdn {
qcom,use-phase-switching;
+ qcom,valid-scaling-factor-versions = <0 1 1 0>;
+
};
&krait0_vreg {
diff --git a/arch/arm/boot/dts/msm8974pro-pma8084-regulator.dtsi b/arch/arm/boot/dts/msm8974pro-pma8084-regulator.dtsi
index 78e2167..49bf4ea 100644
--- a/arch/arm/boot/dts/msm8974pro-pma8084-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pma8084-regulator.dtsi
@@ -481,6 +481,8 @@
ranges;
qcom,pfm-threshold = <76>;
qcom,use-phase-scaling-factor;
+ qcom,phase-scaling-factor-bits-pos = <16>;
+ qcom,valid-scaling-factor-versions = <0 1 1 0>;
krait0_vreg: regulator@f9088000 {
compatible = "qcom,krait-regulator";
diff --git a/arch/arm/mach-msm/krait-regulator.c b/arch/arm/mach-msm/krait-regulator.c
index f4456c0..a291b90 100644
--- a/arch/arm/mach-msm/krait-regulator.c
+++ b/arch/arm/mach-msm/krait-regulator.c
@@ -1443,11 +1443,17 @@
{
struct resource *res;
void __iomem *efuse;
- u32 efuse_data, efuse_version;
- bool scaling_factor_valid, use_efuse;
+ u32 efuse_data, efuse_version, efuse_version_data;
+ bool sf_valid, use_efuse;
+ int sf_pos, sf_mask;
+ struct device_node *node = pdev->dev.of_node;
+ struct device *dev = &pdev->dev;
+ int valid_sfs[4] = {0, 0, 0, 0};
+ int sf_versions_len;
+ int rc;
- use_efuse = of_property_read_bool(pdev->dev.of_node,
- "qcom,use-phase-scaling-factor");
+ use_efuse = of_property_read_bool(node,
+ "qcom,use-phase-scaling-factor");
/*
* Allow usage of the eFuse phase scaling factor if it is enabled in
* either device tree or by module parameter.
@@ -1462,6 +1468,7 @@
return -EINVAL;
}
+ /* Read efuse registers */
efuse = ioremap(res->start, 8);
if (!efuse) {
pr_err("could not map phase scaling eFuse address\n");
@@ -1469,25 +1476,47 @@
}
efuse_data = readl_relaxed(efuse);
- efuse_version = readl_relaxed(efuse + 4);
-
+ efuse_version_data = readl_relaxed(efuse + 4);
iounmap(efuse);
- scaling_factor_valid
- = ((efuse_version & PHASE_SCALING_EFUSE_VERSION_MASK) >>
- PHASE_SCALING_EFUSE_VERSION_POS)
- == PHASE_SCALING_EFUSE_VERSION_SET;
+ rc = of_property_read_u32(pdev->dev.of_node,
+ "qcom,phase-scaling-factor-bits-pos",
+ &sf_pos);
+ if (rc < 0) {
+ dev_err(dev, "qcom,phase-scaling-factor-bits-pos missing rc=%d\n",
+ rc);
+ return -EINVAL;
+ }
- if (scaling_factor_valid)
+ sf_mask = KRAIT_MASK(sf_pos + 2, sf_pos);
+
+ efuse_version
+ = ((efuse_version_data & PHASE_SCALING_EFUSE_VERSION_MASK) >>
+ PHASE_SCALING_EFUSE_VERSION_POS);
+
+ if (of_find_property(node, "qcom,valid-scaling-factor-versions",
+ &sf_versions_len)
+ && (sf_versions_len == 4 * sizeof(u32))) {
+ rc = of_property_read_u32_array(node,
+ "qcom,valid-scaling-factor-versions",
+ valid_sfs, 4);
+ sf_valid = (valid_sfs[efuse_version] == 1);
+ } else {
+ dev_err(dev, "qcom,valid-scaling-factor-versions missing or its size is incorrect rc=%d\n",
+ rc);
+ return -EINVAL;
+ }
+
+ if (sf_valid)
pvreg->efuse_phase_scaling_factor
- = ((efuse_data & PHASE_SCALING_EFUSE_VALUE_MASK)
- >> PHASE_SCALING_EFUSE_VALUE_POS) + 1;
+ = ((efuse_data & sf_mask)
+ >> sf_pos) + 1;
else
pvreg->efuse_phase_scaling_factor = PHASE_SCALING_REF;
pr_info("eFuse phase scaling factor = %d/%d%s\n",
pvreg->efuse_phase_scaling_factor, PHASE_SCALING_REF,
- scaling_factor_valid ? "" : " (eFuse not blown)");
+ sf_valid ? "" : " (eFuse not blown)");
pr_info("initial phase scaling factor = %d/%d%s\n",
use_efuse_phase_scaling_factor
? pvreg->efuse_phase_scaling_factor : PHASE_SCALING_REF,