Merge "msm: mdss: Prevent kernel log overflow"
diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
index 0422b57..bb19768 100644
--- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
@@ -108,7 +108,10 @@
- qcom,mdss-rot-block-size: The size of a memory block (in pixels) to be used
by the rotator. If this property is not specified,
then a default value of 128 pixels would be used.
-
+- qcom,mdss-has-bwc: Boolean property to indicate the presence of bandwidth
+ compression feature in the rotator.
+- qcom,mdss-has-decimation: Boolean property to indicate the presence of
+ decimation feature in fetch.
Optional subnodes:
Child nodes representing the frame buffer virtual devices.
@@ -141,6 +144,8 @@
qcom,mdss-pipe-dma-fetch-id = <10 13>;
qcom,mdss-smp-data = <22 4096>;
qcom,mdss-rot-block-size = <64>;
+ qcom,mdss-has-bwc;
+ qcom,mdss-has-decimation;
qcom,mdss-ctl-off = <0x00000600 0x00000700 0x00000800
0x00000900 0x0000A00>;
diff --git a/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt b/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt
index fbe8ffa..418447d 100644
--- a/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt
+++ b/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt
@@ -16,7 +16,10 @@
- interrupt-names : Should contain "eoc-int-en-set".
- qcom,adc-bit-resolution : Bit resolution of the ADC.
- qcom,adc-vdd-reference : Voltage reference used by the ADC.
-- qcom,rsense : Internal rsense resistor used for current measurements.
+
+Optional properties:
+- qcom,rsense : Use this property when external rsense should be used
+ for current calculation and specify the units in nano-ohms.
Channel node
NOTE: Atleast one Channel node is required.
diff --git a/Documentation/devicetree/bindings/pil/pil-q6v5-lpass.txt b/Documentation/devicetree/bindings/pil/pil-q6v5-lpass.txt
index 70f8b55..ac8ea73 100644
--- a/Documentation/devicetree/bindings/pil/pil-q6v5-lpass.txt
+++ b/Documentation/devicetree/bindings/pil/pil-q6v5-lpass.txt
@@ -14,6 +14,8 @@
- interrupts: The lpass watchdog interrupt
- vdd_cx-supply: Reference to the regulator that supplies the vdd_cx domain.
- qcom,firmware-name: Base name of the firmware image. Ex. "lpass"
+- qcom,gpio-err-fatal: GPIO used by the lpass to indicate error fatal to the apps.
+- qcom,gpio-force-stop: GPIO used by the apps to force the lpass to shutdown.
Optional properties:
- vdd_pll-supply: Reference to the regulator that supplies the PLL's rail.
@@ -29,4 +31,10 @@
interrupts = <0 194 1>;
vdd_cx-supply = <&pm8841_s2>;
qcom,firmware-name = "lpass";
+
+ /* GPIO input from lpass */
+ qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_2_in 0 0>;
+
+ /* GPIO output to lpass */
+ qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_2_out 0 0>;
};
diff --git a/Documentation/devicetree/bindings/power/qpnp-charger.txt b/Documentation/devicetree/bindings/power/qpnp-charger.txt
index b8a39d3..fced0d7 100644
--- a/Documentation/devicetree/bindings/power/qpnp-charger.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-charger.txt
@@ -55,6 +55,7 @@
- qcom,ibatmax-warm-ma: Maximum warm battery charge current.
- qcom,warm-bat-mv: Warm temperature battery target voltage.
- qcom,cool-bat-mv: Cool temperature battery target voltage.
+- qcom,tchg-mins: Maximum total software initialized charge time.
Sub node required structure:
- A qcom,chg node must be a child of an SPMI node that has specified
diff --git a/Documentation/devicetree/bindings/regulator/krait-regulator.txt b/Documentation/devicetree/bindings/regulator/krait-regulator.txt
index 6a02e86..aaa731e 100644
--- a/Documentation/devicetree/bindings/regulator/krait-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/krait-regulator.txt
@@ -13,8 +13,6 @@
register base
- reg-names: "apcs_gcc" -string to identify the area where
the APCS GCC registers reside.
-- qcom,pfm-threshold The power coeff threshold in abstract power units below which
- pmic will be made to operate in PFM mode.
Optional properties:
- qcom,use-phase-switching indicates whether the driver should add/shed phases on the PMIC
@@ -53,7 +51,6 @@
reg-names = "apcs_gcc";
compatible = "qcom,krait-pdn";
qcom,use-phase-switching;
- qcom,pfm-threshold = <376975>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
index fd5b93e..6d54f7e 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -12,6 +12,7 @@
Optional properties:
- tx-fifo-resize: determines if the FIFO *has* to be reallocated.
+ - host-only-mode: if present then dwc3 should be run in HOST only mode.
This is usually a subnode to DWC3 glue to which it is connected.
diff --git a/arch/arm/boot/dts/msm-pm8110-rpm-regulator.dtsi b/arch/arm/boot/dts/msm-pm8110-rpm-regulator.dtsi
new file mode 100644
index 0000000..0de72b0
--- /dev/null
+++ b/arch/arm/boot/dts/msm-pm8110-rpm-regulator.dtsi
@@ -0,0 +1,381 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&rpm_bus {
+ rpm-regulator-smpa1 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "smpa";
+ qcom,resource-id = <1>;
+ qcom,regulator-type = <1>;
+ qcom,hpm-min-load = <100000>;
+ status = "disabled";
+
+ regulator-s1 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_s1";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-smpa3 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "smpa";
+ qcom,resource-id = <3>;
+ qcom,regulator-type = <1>;
+ qcom,hpm-min-load = <100000>;
+ status = "disabled";
+
+ regulator-s3 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_s3";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-smpa4 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "smpa";
+ qcom,resource-id = <4>;
+ qcom,regulator-type = <1>;
+ qcom,hpm-min-load = <100000>;
+ status = "disabled";
+
+ regulator-s4 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_s4";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa1 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <1>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l1 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l1";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa2 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <2>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l2 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l2";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa3 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <3>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l3 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l3";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa4 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <4>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l4 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l4";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa5 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <5>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l5 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l5";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa6 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <6>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l6 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l6";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa7 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <7>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l7 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l7";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa8 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <8>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <5000>;
+ status = "disabled";
+
+ regulator-l8 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l8";
+ qcom,set = <1>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa9 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <9>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l9 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l9";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa10 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <10>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l10 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l10";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa12 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <12>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l12 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l12";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa14 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <14>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l14 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l14";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa15 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <15>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l15 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l15";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa16 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <16>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l16 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l16";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa17 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <17>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l17 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l17";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa18 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <18>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l18 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l18";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa19 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <19>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l19 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l19";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa20 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <20>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <5000>;
+ status = "disabled";
+
+ regulator-l20 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l20";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa21 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <21>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l21 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l21";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa22 {
+ compatible = "qcom,rpm-regulator-smd-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <22>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l22 {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l22";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/msm-pm8110.dtsi b/arch/arm/boot/dts/msm-pm8110.dtsi
index 28766cf..9ebfb56 100644
--- a/arch/arm/boot/dts/msm-pm8110.dtsi
+++ b/arch/arm/boot/dts/msm-pm8110.dtsi
@@ -22,6 +22,98 @@
#address-cells = <1>;
#size-cells = <1>;
+ pm8110_chg: qcom,charger {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-charger";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+
+ qcom,chg-vddmax-mv = <4200>;
+ qcom,chg-vddsafe-mv = <4200>;
+ qcom,chg-vinmin-mv = <4200>;
+ qcom,chg-vbatdet-mv = <4100>;
+ qcom,chg-ibatmax-ma = <1500>;
+ qcom,chg-ibatterm-ma = <200>;
+ qcom,chg-ibatsafe-ma = <1500>;
+ qcom,chg-thermal-mitigation = <1500 700 600 325>;
+
+ qcom,chg-chgr@1000 {
+ status = "disabled";
+ reg = <0x1000 0x100>;
+ interrupts = <0x0 0x10 0x0>,
+ <0x0 0x10 0x1>,
+ <0x0 0x10 0x2>,
+ <0x0 0x10 0x3>,
+ <0x0 0x10 0x4>,
+ <0x0 0x10 0x5>,
+ <0x0 0x10 0x6>,
+ <0x0 0x10 0x7>;
+
+ interrupt-names = "vbat-det-lo",
+ "vbat-det-hi",
+ "chgwdog",
+ "state-change",
+ "trkl-chg-on",
+ "fast-chg-on",
+ "chg-failed",
+ "chg-done";
+ };
+
+ qcom,chg-buck@1100 {
+ status = "disabled";
+ reg = <0x1100 0x100>;
+ interrupts = <0x0 0x11 0x0>,
+ <0x0 0x11 0x1>,
+ <0x0 0x11 0x2>,
+ <0x0 0x11 0x3>,
+ <0x0 0x11 0x4>,
+ <0x0 0x11 0x5>,
+ <0x0 0x11 0x6>;
+
+ interrupt-names = "vbat-ov",
+ "vreg-ov",
+ "overtemp",
+ "vchg-loop",
+ "ichg-loop",
+ "ibat-loop",
+ "vdd-loop";
+ };
+
+ qcom,chg-bat-if@1200 {
+ status = "disabled";
+ reg = <0x1200 0x100>;
+ interrupts = <0x0 0x12 0x0>,
+ <0x0 0x12 0x1>,
+ <0x0 0x12 0x2>,
+ <0x0 0x12 0x3>,
+ <0x0 0x12 0x4>;
+
+ interrupt-names = "batt-pres",
+ "bat-temp-ok",
+ "bat-fet-on",
+ "vcp-on",
+ "psi";
+ };
+
+ qcom,chg-usb-chgpth@1300 {
+ status = "disabled";
+ reg = <0x1300 0x100>;
+ interrupts = <0 0x13 0x0>,
+ <0 0x13 0x1>,
+ <0x0 0x13 0x2>;
+
+ interrupt-names = "coarse-det-usb",
+ "usbin-valid",
+ "chg-gone";
+ };
+
+ qcom,chg-misc@1600 {
+ status = "disabled";
+ reg = <0x1600 0x100>;
+ };
+ };
+
pm8110_vadc: vadc@3100 {
compatible = "qcom,qpnp-vadc";
reg = <0x3100 0x100>;
@@ -75,7 +167,6 @@
interrupt-names = "eoc-int-en-set";
qcom,adc-bit-resolution = <16>;
qcom,adc-vdd-reference = <1800>;
- qcom,rsense = <1500>;
chan@0 {
label = "internal_rsense";
diff --git a/arch/arm/boot/dts/msm-pm8226.dtsi b/arch/arm/boot/dts/msm-pm8226.dtsi
index 161b580..99410b3 100644
--- a/arch/arm/boot/dts/msm-pm8226.dtsi
+++ b/arch/arm/boot/dts/msm-pm8226.dtsi
@@ -59,11 +59,12 @@
qcom,vddmax-mv = <4200>;
qcom,vddsafe-mv = <4200>;
qcom,vinmin-mv = <4200>;
- qcom,vbatdet-mv = <4100>;
+ qcom,vbatdet-delta-mv = <150>;
qcom,ibatmax-ma = <1500>;
qcom,ibatterm-ma = <200>;
qcom,ibatsafe-ma = <1500>;
qcom,thermal-mitigation = <1500 700 600 325>;
+ qcom,tchg-mins = <150>;
qcom,chgr@1000 {
status = "disabled";
@@ -367,7 +368,6 @@
interrupt-names = "eoc-int-en-set";
qcom,adc-bit-resolution = <16>;
qcom,adc-vdd-reference = <1800>;
- qcom,rsense = <1500>;
chan@0 {
label = "internal_rsense";
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 21606e2..43b7d03 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -184,6 +184,7 @@
qcom,warm-bat-mv = <4100>;
qcom,ibatmax-cool-ma = <350>;
qcom,vbatdet-delta-mv = <350>;
+ qcom,tchg-mins = <150>;
qcom,chgr@1000 {
status = "disabled";
@@ -790,7 +791,6 @@
interrupt-names = "eoc-int-en-set";
qcom,adc-bit-resolution = <16>;
qcom,adc-vdd-reference = <1800>;
- qcom,rsense = <1500>;
chan@0 {
label = "internal_rsense";
diff --git a/arch/arm/boot/dts/msm8226-cdp.dts b/arch/arm/boot/dts/msm8226-cdp.dts
index 5f0dcc3..e4700a1 100644
--- a/arch/arm/boot/dts/msm8226-cdp.dts
+++ b/arch/arm/boot/dts/msm8226-cdp.dts
@@ -266,7 +266,7 @@
qcom,mode = <1>; /* Digital output */
qcom,output-type = <0>; /* CMOS logic */
qcom,pull = <5>; /* QPNP_PIN_PULL_NO*/
- qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */
+ qcom,vin-sel = <3>; /* QPNP_PIN_VIN3 */
qcom,out-strength = <3>;/* QPNP_PIN_OUT_STRENGTH_HIGH */
qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */
qcom,master-en = <1>; /* Enable GPIO */
@@ -276,7 +276,7 @@
qcom,mode = <1>;
qcom,output-type = <0>;
qcom,pull = <5>;
- qcom,vin-sel = <2>;
+ qcom,vin-sel = <3>;
qcom,out-strength = <3>;
qcom,src-sel = <2>;
qcom,master-en = <1>;
diff --git a/arch/arm/boot/dts/msm8226-mtp.dts b/arch/arm/boot/dts/msm8226-mtp.dts
index 59741c6..478d064 100644
--- a/arch/arm/boot/dts/msm8226-mtp.dts
+++ b/arch/arm/boot/dts/msm8226-mtp.dts
@@ -259,7 +259,7 @@
qcom,mode = <1>; /* Digital output */
qcom,output-type = <0>; /* CMOS logic */
qcom,pull = <5>; /* QPNP_PIN_PULL_NO*/
- qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */
+ qcom,vin-sel = <3>; /* QPNP_PIN_VIN3 */
qcom,out-strength = <3>;/* QPNP_PIN_OUT_STRENGTH_HIGH */
qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */
qcom,master-en = <1>; /* Enable GPIO */
@@ -269,7 +269,7 @@
qcom,mode = <1>;
qcom,output-type = <0>;
qcom,pull = <5>;
- qcom,vin-sel = <2>;
+ qcom,vin-sel = <3>;
qcom,out-strength = <3>;
qcom,src-sel = <2>;
qcom,master-en = <1>;
@@ -359,3 +359,7 @@
&pm8226_bms {
status = "ok";
};
+
+&pm8226_chg {
+ qcom,charging-disabled;
+};
diff --git a/arch/arm/boot/dts/msm8226-qrd.dts b/arch/arm/boot/dts/msm8226-qrd.dts
index bbde23f..ecb3b5a 100644
--- a/arch/arm/boot/dts/msm8226-qrd.dts
+++ b/arch/arm/boot/dts/msm8226-qrd.dts
@@ -269,7 +269,7 @@
qcom,mode = <1>; /* Digital output */
qcom,output-type = <0>; /* CMOS logic */
qcom,pull = <5>; /* QPNP_PIN_PULL_NO*/
- qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */
+ qcom,vin-sel = <3>; /* QPNP_PIN_VIN3 */
qcom,out-strength = <3>;/* QPNP_PIN_OUT_STRENGTH_HIGH */
qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */
qcom,master-en = <1>; /* Enable GPIO */
@@ -279,7 +279,7 @@
qcom,mode = <1>;
qcom,output-type = <0>;
qcom,pull = <5>;
- qcom,vin-sel = <2>;
+ qcom,vin-sel = <3>;
qcom,out-strength = <3>;
qcom,src-sel = <2>;
qcom,master-en = <1>;
diff --git a/arch/arm/boot/dts/msm8226-smp2p.dtsi b/arch/arm/boot/dts/msm8226-smp2p.dtsi
index 91029e2..079e4ca 100644
--- a/arch/arm/boot/dts/msm8226-smp2p.dtsi
+++ b/arch/arm/boot/dts/msm8226-smp2p.dtsi
@@ -148,6 +148,29 @@
gpios = <&smp2pgpio_smp2p_2_out 0 0>;
};
+ /* SMP2P SSR Driver for inbound entry from lpass. */
+ smp2pgpio_ssr_smp2p_2_in: qcom,smp2pgpio-ssr-smp2p-2-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "slave-kernel";
+ qcom,remote-pid = <2>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* SMP2P SSR Driver for outbound entry to lpass */
+ smp2pgpio_ssr_smp2p_2_out: qcom,smp2pgpio-ssr-smp2p-2-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "master-kernel";
+ qcom,remote-pid = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
smp2pgpio_smp2p_4_in: qcom,smp2pgpio-smp2p-4-in {
compatible = "qcom,smp2pgpio";
qcom,entry-name = "smp2p";
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index cb2047f..b949d3b 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -755,6 +755,12 @@
interrupts = <0 162 1>;
qcom,firmware-name = "adsp";
+
+ /* GPIO input from lpass */
+ qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_2_in 0 0>;
+
+ /* GPIO output to lpass */
+ qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_2_out 0 0>;
};
qcom,mss@fc880000 {
diff --git a/arch/arm/boot/dts/msm8610-cdp.dts b/arch/arm/boot/dts/msm8610-cdp.dts
index 08da115..533ad53 100644
--- a/arch/arm/boot/dts/msm8610-cdp.dts
+++ b/arch/arm/boot/dts/msm8610-cdp.dts
@@ -79,3 +79,25 @@
status = "ok";
};
+
+&pm8110_chg {
+ status = "ok";
+ qcom,chg-charging-disabled;
+ qcom,chg-use-default-batt-values;
+
+ qcom,chg-chgr@1000 {
+ status = "ok";
+ };
+
+ qcom,chg-buck@1100 {
+ status = "ok";
+ };
+
+ qcom,chg-usb-chgpth@1300 {
+ status = "ok";
+ };
+
+ qcom,chg-misc@1600 {
+ status = "ok";
+ };
+};
diff --git a/arch/arm/boot/dts/msm8610-mtp.dts b/arch/arm/boot/dts/msm8610-mtp.dts
index e3eed72..c906e89 100644
--- a/arch/arm/boot/dts/msm8610-mtp.dts
+++ b/arch/arm/boot/dts/msm8610-mtp.dts
@@ -79,3 +79,28 @@
status = "ok";
};
+
+&pm8110_chg {
+ status = "ok";
+ qcom,chg-charging-disabled;
+
+ qcom,chg-chgr@1000 {
+ status = "ok";
+ };
+
+ qcom,chg-buck@1100 {
+ status = "ok";
+ };
+
+ qcom,chg-bat-if@1200 {
+ status = "ok";
+ };
+
+ qcom,chg-usb-chgpth@1300 {
+ status = "ok";
+ };
+
+ qcom,chg-misc@1600 {
+ status = "ok";
+ };
+};
diff --git a/arch/arm/boot/dts/msm8610-pm.dtsi b/arch/arm/boot/dts/msm8610-pm.dtsi
index 08a3758..e8849f6 100644
--- a/arch/arm/boot/dts/msm8610-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-pm.dtsi
@@ -368,6 +368,7 @@
reg = <0xfe805664 0x40>;
qcom,pc-mode = "tz_l2_int";
qcom,use-sync-timer;
+ qcom,pc-resets-timer;
};
qcom,rpm-log@fc19dc00 {
diff --git a/arch/arm/boot/dts/msm8610-regulator.dtsi b/arch/arm/boot/dts/msm8610-regulator.dtsi
index d50902c..67eee5c 100644
--- a/arch/arm/boot/dts/msm8610-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8610-regulator.dtsi
@@ -10,19 +10,6 @@
* GNU General Public License for more details.
*/
- /* Stub Regulators */
-
-/ {
- pm8110_s1_corner: regulator-s1-corner {
- compatible = "qcom,stub-regulator";
- regulator-name = "8110_s1_corner";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <1>;
- regulator-max-microvolt = <7>;
- qcom,consumer-supplies = "vdd_dig", "", "vdd_sr2_dig", "";
- };
-};
-
/* SPM controlled regulators */
&spmi_bus {
@@ -60,195 +47,274 @@
};
};
-/* QPNP controlled regulators: */
+/* RPM controlled regulators: */
-&spmi_bus {
+&rpm_bus {
- qcom,pm8110@1 {
-
- pm8110_s1: regulator@1400 {
+ rpm-regulator-smpa1 {
+ status = "okay";
+ pm8110_s1: regulator-s1 {
status = "okay";
- regulator-min-microvolt = <1150000>;
- regulator-max-microvolt = <1150000>;
- qcom,enable-time = <500>;
- qcom,system-load = <100000>;
- regulator-always-on;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1275000>;
};
- pm8110_s3: regulator@1a00 {
- status = "okay";
- regulator-min-microvolt = <1350000>;
+ pm8110_s1_corner: regulator-s1-corner {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_s1_corner";
+ qcom,set = <3>;
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <7>;
+ qcom,use-voltage-corner;
+ qcom,consumer-supplies = "vdd_dig", "", "vdd_sr2_dig", "";
+ };
+
+ pm8110_s1_corner_ao: regulator-s1-corner-ao {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_s1_corner_ao";
+ qcom,set = <1>;
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <7>;
+ qcom,use-voltage-corner;
+ };
+ };
+
+ rpm-regulator-smpa3 {
+ status = "okay";
+ pm8110_s3: regulator-s3 {
+ regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1350000>;
- qcom,enable-time = <500>;
- qcom,system-load = <100000>;
- regulator-always-on;
- };
-
- pm8110_s4: regulator@1d00 {
+ qcom,init-voltage = <1200000>;
status = "okay";
+ };
+ };
+
+ rpm-regulator-smpa4 {
+ status = "okay";
+ pm8110_s4: regulator-s4 {
regulator-min-microvolt = <2150000>;
regulator-max-microvolt = <2150000>;
- qcom,enable-time = <500>;
- qcom,system-load = <100000>;
- regulator-always-on;
- };
-
- pm8110_l1: regulator@4000 {
+ qcom,init-voltage = <2150000>;
status = "okay";
- parent-supply = <&pm8110_s3>;
+ };
+ };
+
+ rpm-regulator-ldoa1 {
+ status = "okay";
+ pm8110_l1: regulator-l1 {
regulator-min-microvolt = <1225000>;
regulator-max-microvolt = <1225000>;
- qcom,enable-time = <200>;
- };
-
- pm8110_l2: regulator@4100 {
+ qcom,init-voltage = <1225000>;
status = "okay";
- parent-supply = <&pm8110_s3>;
+ };
+ };
+
+ rpm-regulator-ldoa2 {
+ status = "okay";
+ pm8110_l2: regulator-l2 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
- qcom,enable-time = <200>;
- qcom,system-load = <10000>;
- regulator-always-on;
+ qcom,init-voltage = <1200000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa3 {
+ status = "okay";
+ pm8110_l3: regulator-l3 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1275000>;
+ status = "okay";
};
- pm8110_l3: regulator@4200 {
+ pm8110_l3_ao: regulator-l3-ao {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l3_ao";
+ qcom,set = <1>;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1275000>;
status = "okay";
- parent-supply = <&pm8110_s3>;
- regulator-min-microvolt = <1150000>;
- regulator-max-microvolt = <1150000>;
- qcom,enable-time = <200>;
- qcom,system-load = <10000>;
- regulator-always-on;
};
- pm8110_l4: regulator@4300 {
+ pm8110_l3_so: regulator-l3-so {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8110_l3_so";
+ qcom,set = <2>;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1275000>;
+ qcom,init-voltage = <750000>;
status = "okay";
- parent-supply = <&pm8110_s3>;
+ };
+ };
+
+ rpm-regulator-ldoa4 {
+ status = "okay";
+ pm8110_l4: regulator-l4 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
- qcom,enable-time = <200>;
- };
-
- pm8110_l5: regulator@4400 {
+ qcom,init-voltage = <1200000>;
status = "okay";
- parent-supply = <&pm8110_s3>;
+ };
+ };
+
+ rpm-regulator-ldoa5 {
+ status = "okay";
+ pm8110_l5: regulator-l5 {
regulator-min-microvolt = <1300000>;
regulator-max-microvolt = <1300000>;
- qcom,enable-time = <200>;
- };
-
- pm8110_l6: regulator@4500 {
+ qcom,init-voltage = <1300000>;
status = "okay";
- parent-supply = <&pm8110_s4>;
+ };
+ };
+
+ rpm-regulator-ldoa6 {
+ status = "okay";
+ pm8110_l6: regulator-l6 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- qcom,enable-time = <200>;
- qcom,system-load = <10000>;
- regulator-always-on;
- };
-
- pm8110_l7: regulator@4600 {
+ qcom,init-voltage = <1800000>;
status = "okay";
- parent-supply = <&pm8110_s4>;
+ };
+ };
+
+ rpm-regulator-ldoa7 {
+ status = "okay";
+ pm8110_l7: regulator-l7 {
regulator-min-microvolt = <2050000>;
regulator-max-microvolt = <2050000>;
- qcom,enable-time = <200>;
- };
-
- pm8110_l8: regulator@4700 {
+ qcom,init-voltage = <2050000>;
status = "okay";
- parent-supply = <&pm8110_s4>;
+ };
+ };
+
+ rpm-regulator-ldoa8 {
+ status = "okay";
+ pm8110_l8: regulator-l8 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- qcom,enable-time = <200>;
- };
-
- pm8110_l9: regulator@4800 {
+ qcom,init-voltage = <1800000>;
status = "okay";
- parent-supply = <&pm8110_s4>;
+ };
+ };
+
+ rpm-regulator-ldoa9 {
+ status = "okay";
+ pm8110_l9: regulator-l9 {
regulator-min-microvolt = <2050000>;
regulator-max-microvolt = <2050000>;
- qcom,enable-time = <200>;
- };
-
- pm8110_l10: regulator@4900 {
+ qcom,init-voltage = <2050000>;
status = "okay";
- parent-supply = <&pm8110_s4>;
+ };
+ };
+
+ rpm-regulator-ldoa10 {
+ status = "okay";
+ pm8110_l10: regulator-l10 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- qcom,enable-time = <200>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
qcom,consumer-supplies = "vdd_sr2_pll", "";
};
+ };
- pm8110_l12: regulator@4b00 {
- status = "okay";
+ rpm-regulator-ldoa12 {
+ status = "okay";
+ pm8110_l12: regulator-l12 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
- qcom,enable-time = <200>;
- };
-
- pm8110_l14: regulator@4d00 {
+ qcom,init-voltage = <3300000>;
status = "okay";
- parent-supply = <&pm8110_s4>;
+ };
+ };
+
+ rpm-regulator-ldoa14 {
+ status = "okay";
+ pm8110_l14: regulator-l14 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- qcom,enable-time = <200>;
- };
-
- pm8110_l15: regulator@4e00 {
+ qcom,init-voltage = <1800000>;
status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa15 {
+ status = "okay";
+ pm8110_l15: regulator-l15 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
- qcom,enable-time = <200>;
- };
-
- pm8110_l16: regulator@4f00 {
+ qcom,init-voltage = <3300000>;
status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa16 {
+ status = "okay";
+ pm8110_l16: regulator-l16 {
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
- qcom,enable-time = <200>;
- };
-
- pm8110_l17: regulator@5000 {
+ qcom,init-voltage = <3000000>;
status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa17 {
+ status = "okay";
+ pm8110_l17: regulator-l17 {
regulator-min-microvolt = <2900000>;
regulator-max-microvolt = <2900000>;
- qcom,enable-time = <200>;
- };
-
- pm8110_l18: regulator@5100 {
+ qcom,init-voltage = <2900000>;
status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa18 {
+ status = "okay";
+ pm8110_l18: regulator-l18 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2950000>;
- qcom,enable-time = <200>;
- };
-
- pm8110_l19: regulator@5200 {
+ qcom,init-voltage = <2950000>;
status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa19 {
+ status = "okay";
+ pm8110_l19: regulator-l19 {
regulator-min-microvolt = <2850000>;
regulator-max-microvolt = <2850000>;
- qcom,enable-time = <200>;
- };
-
- pm8110_l20: regulator@5300 {
+ qcom,init-voltage = <2850000>;
status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa20 {
+ status = "okay";
+ pm8110_l20: regulator-l20 {
regulator-min-microvolt = <3075000>;
regulator-max-microvolt = <3075000>;
- qcom,enable-time = <200>;
- };
-
- pm8110_l21: regulator@5400 {
+ qcom,init-voltage = <3075000>;
status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa21 {
+ status = "okay";
+ pm8110_l21: regulator-l21 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2950000>;
- qcom,enable-time = <200>;
- };
-
- pm8110_l22: regulator@5500 {
+ qcom,init-voltage = <2950000>;
status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa22 {
+ status = "okay";
+ pm8110_l22: regulator-l22 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
- qcom,enable-time = <200>;
+ qcom,init-voltage = <3300000>;
+ status = "okay";
};
};
};
diff --git a/arch/arm/boot/dts/msm8610-smp2p.dtsi b/arch/arm/boot/dts/msm8610-smp2p.dtsi
index 91029e2..079e4ca 100644
--- a/arch/arm/boot/dts/msm8610-smp2p.dtsi
+++ b/arch/arm/boot/dts/msm8610-smp2p.dtsi
@@ -148,6 +148,29 @@
gpios = <&smp2pgpio_smp2p_2_out 0 0>;
};
+ /* SMP2P SSR Driver for inbound entry from lpass. */
+ smp2pgpio_ssr_smp2p_2_in: qcom,smp2pgpio-ssr-smp2p-2-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "slave-kernel";
+ qcom,remote-pid = <2>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* SMP2P SSR Driver for outbound entry to lpass */
+ smp2pgpio_ssr_smp2p_2_out: qcom,smp2pgpio-ssr-smp2p-2-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "master-kernel";
+ qcom,remote-pid = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
smp2pgpio_smp2p_4_in: qcom,smp2pgpio-smp2p-4-in {
compatible = "qcom,smp2pgpio";
qcom,entry-name = "smp2p";
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 12c6e3e..ad8b24b 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -57,6 +57,65 @@
clock-frequency = <19200000>;
};
+ timer@f9020000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "arm,armv7-timer-mem";
+ reg = <0xf9020000 0x1000>;
+ clock-frequency = <19200000>;
+
+ frame@f9021000 {
+ frame-number = <0>;
+ interrupts = <0 8 0x4>,
+ <0 7 0x4>;
+ reg = <0xf9021000 0x1000>,
+ <0xf9022000 0x1000>;
+ };
+
+ frame@f9023000 {
+ frame-number = <1>;
+ interrupts = <0 9 0x4>;
+ reg = <0xf9023000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9024000 {
+ frame-number = <2>;
+ interrupts = <0 10 0x4>;
+ reg = <0xf9024000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9025000 {
+ frame-number = <3>;
+ interrupts = <0 11 0x4>;
+ reg = <0xf9025000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9026000 {
+ frame-number = <4>;
+ interrupts = <0 12 0x4>;
+ reg = <0xf9026000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9027000 {
+ frame-number = <5>;
+ interrupts = <0 13 0x4>;
+ reg = <0xf9027000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9028000 {
+ frame-number = <6>;
+ interrupts = <0 14 0x4>;
+ reg = <0xf9028000 0x1000>;
+ status = "disabled";
+ };
+ };
+
qcom,msm-adsp-loader {
compatible = "qcom,adsp-loader";
qcom,adsp-state = <0>;
@@ -342,7 +401,7 @@
reg = <0xf9011050 0x8>;
reg-names = "rcg_base";
a7_cpu-supply = <&apc_vreg_corner>;
- a7_mem-supply = <&pm8110_l3>;
+ a7_mem-supply = <&pm8110_l3_ao>;
};
spmi_bus: qcom,spmi@fc4c0000 {
@@ -580,6 +639,12 @@
interrupts = <0 162 1>;
vdd_cx-supply = <&pm8110_s1_corner>;
qcom,firmware-name = "adsp";
+
+ /* GPIO input from lpass */
+ qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_2_in 0 0>;
+
+ /* GPIO output to lpass */
+ qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_2_out 0 0>;
};
tsens: tsens@fc4a8000 {
@@ -634,6 +699,34 @@
<55 512 3936000 393600>,
<55 512 3936000 393600>;
};
+
+ jtag_mm0: jtagmm@fc34c000 {
+ compatible = "qcom,jtag-mm";
+ reg = <0xfc34c000 0x1000>,
+ <0xfc340000 0x1000>;
+ reg-names = "etm-base","debug-base";
+ };
+
+ jtag_mm1: jtagmm@fc34d000 {
+ compatible = "qcom,jtag-mm";
+ reg = <0xfc34d000 0x1000>,
+ <0xfc342000 0x1000>;
+ reg-names = "etm-base","debug-base";
+ };
+
+ jtag_mm2: jtagmm@fc34e000 {
+ compatible = "qcom,jtag-mm";
+ reg = <0xfc34e000 0x1000>,
+ <0xfc344000 0x1000>;
+ reg-names = "etm-base","debug-base";
+ };
+
+ jtag_mm3: jtagmm@fc34f000 {
+ compatible = "qcom,jtag-mm";
+ reg = <0xfc34f000 0x1000>,
+ <0xfc346000 0x1000>;
+ reg-names = "etm-base","debug-base";
+ };
};
&gdsc_vfe {
@@ -670,6 +763,7 @@
/include/ "msm8610-iommu-domains.dtsi"
+/include/ "msm-pm8110-rpm-regulator.dtsi"
/include/ "msm-pm8110.dtsi"
/include/ "msm8610-regulator.dtsi"
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index 79e6371..25d0885 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -353,7 +353,7 @@
&pm8941_chg {
status = "ok";
- qcom,chg-charging-disabled;
+ qcom,charging-disabled;
qcom,chgr@1000 {
status = "ok";
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index cd83668..8b9ef87 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -336,7 +336,7 @@
&pm8941_chg {
status = "ok";
- qcom,chg-charging-disabled;
+ qcom,charging-disabled;
qcom,chgr@1000 {
status = "ok";
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index 49450f3..05451671 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -448,7 +448,6 @@
#address-cells = <1>;
#size-cells = <1>;
ranges;
- qcom,pfm-threshold = <376975>;
krait0_vreg: regulator@f9088000 {
compatible = "qcom,krait-regulator";
diff --git a/arch/arm/boot/dts/msm8974-smp2p.dtsi b/arch/arm/boot/dts/msm8974-smp2p.dtsi
index 91029e2..079e4ca 100644
--- a/arch/arm/boot/dts/msm8974-smp2p.dtsi
+++ b/arch/arm/boot/dts/msm8974-smp2p.dtsi
@@ -148,6 +148,29 @@
gpios = <&smp2pgpio_smp2p_2_out 0 0>;
};
+ /* SMP2P SSR Driver for inbound entry from lpass. */
+ smp2pgpio_ssr_smp2p_2_in: qcom,smp2pgpio-ssr-smp2p-2-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "slave-kernel";
+ qcom,remote-pid = <2>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* SMP2P SSR Driver for outbound entry to lpass */
+ smp2pgpio_ssr_smp2p_2_out: qcom,smp2pgpio-ssr-smp2p-2-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "master-kernel";
+ qcom,remote-pid = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
smp2pgpio_smp2p_4_in: qcom,smp2pgpio-smp2p-4-in {
compatible = "qcom,smp2pgpio";
qcom,entry-name = "smp2p";
diff --git a/arch/arm/boot/dts/msm8974-v2.dtsi b/arch/arm/boot/dts/msm8974-v2.dtsi
index 777d26c..494b12c 100644
--- a/arch/arm/boot/dts/msm8974-v2.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2.dtsi
@@ -63,6 +63,8 @@
qcom,mdss-intf-off = <0x00012500 0x00012700
0x00012900 0x00012b00>;
qcom,mdss-pingpong-off = <0x00012D00 0x00012E00 0x00012F00>;
+ qcom,mdss-has-bwc;
+ qcom,mdss-has-decimation;
};
&mdss_hdmi_tx {
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 9f11839..a9685cc 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -833,6 +833,12 @@
interrupts = <0 162 1>;
qcom,firmware-name = "adsp";
+
+ /* GPIO input from lpass */
+ qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_2_in 0 0>;
+
+ /* GPIO output to lpass */
+ qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_2_out 0 0>;
};
qcom,msm-adsp-loader {
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 7faa07d..348e8c9 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -58,14 +58,6 @@
clock-frequency = <32768>;
};
- timer: msm-qtimer@f9021000 {
- compatible = "arm,armv7-timer";
- reg = <0xF9021000 0x1000>;
- interrupts = <0 7 0>;
- irq-is-not-percpu;
- clock-frequency = <19200000>;
- };
-
timer@f9020000 {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
index 366debb..ac4c7a3 100644
--- a/arch/arm/kernel/arch_timer.c
+++ b/arch/arm/kernel/arch_timer.c
@@ -23,6 +23,7 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/export.h>
+#include <linux/slab.h>
#include <asm/cputype.h>
#include <asm/delay.h>
@@ -33,46 +34,13 @@
#include <asm/system_info.h>
static unsigned long arch_timer_rate;
+static int arch_timer_spi;
static int arch_timer_ppi;
static int arch_timer_ppi2;
-static int is_irq_percpu;
static struct clock_event_device __percpu **arch_timer_evt;
static void __iomem *timer_base;
-static u32 timer_reg_read_cp15(int reg);
-static void timer_reg_write_cp15(int reg, u32 val);
-static inline cycle_t counter_get_cntpct_cp15(void);
-static inline cycle_t counter_get_cntvct_cp15(void);
-
-static u32 timer_reg_read_mem(int reg);
-static void timer_reg_write_mem(int reg, u32 val);
-static inline cycle_t counter_get_cntpct_mem(void);
-static inline cycle_t counter_get_cntvct_mem(void);
-
-struct arch_timer_operations {
- void (*reg_write)(int, u32);
- u32 (*reg_read)(int);
- cycle_t (*get_cntpct)(void);
- cycle_t (*get_cntvct)(void);
-};
-
-static struct arch_timer_operations arch_timer_ops_cp15 = {
- .reg_read = &timer_reg_read_cp15,
- .reg_write = &timer_reg_write_cp15,
- .get_cntpct = &counter_get_cntpct_cp15,
- .get_cntvct = &counter_get_cntvct_cp15,
-};
-
-static struct arch_timer_operations arch_timer_ops_mem = {
- .reg_read = &timer_reg_read_mem,
- .reg_write = &timer_reg_write_mem,
- .get_cntpct = &counter_get_cntpct_mem,
- .get_cntvct = &counter_get_cntvct_mem,
-};
-
-static struct arch_timer_operations *arch_specific_timer = &arch_timer_ops_cp15;
-
static struct delay_timer arch_delay_timer;
/*
@@ -97,7 +65,7 @@
#define QTIMER_CNTP_TVAL_REG 0x028
#define QTIMER_CNTV_TVAL_REG 0x038
-static void timer_reg_write_mem(int reg, u32 val)
+static inline void timer_reg_write_mem(int reg, u32 val)
{
switch (reg) {
case ARCH_TIMER_REG_CTRL:
@@ -109,7 +77,7 @@
}
}
-static void timer_reg_write_cp15(int reg, u32 val)
+static inline void timer_reg_write_cp15(int reg, u32 val)
{
switch (reg) {
case ARCH_TIMER_REG_CTRL:
@@ -123,7 +91,15 @@
isb();
}
-static u32 timer_reg_read_mem(int reg)
+static inline void arch_timer_reg_write(int cp15, int reg, u32 val)
+{
+ if (cp15)
+ timer_reg_write_cp15(reg, val);
+ else
+ timer_reg_write_mem(reg, val);
+}
+
+static inline u32 timer_reg_read_mem(int reg)
{
u32 val;
@@ -144,7 +120,7 @@
return val;
}
-static u32 timer_reg_read_cp15(int reg)
+static inline u32 timer_reg_read_cp15(int reg)
{
u32 val;
@@ -165,17 +141,23 @@
return val;
}
-static irqreturn_t arch_timer_handler(int irq, void *dev_id)
+static inline u32 arch_timer_reg_read(int cp15, int reg)
{
- struct clock_event_device *evt;
+ if (cp15)
+ return timer_reg_read_cp15(reg);
+ else
+ return timer_reg_read_mem(reg);
+}
+
+static inline irqreturn_t arch_timer_handler(int cp15,
+ struct clock_event_device *evt)
+{
unsigned long ctrl;
- ctrl = arch_specific_timer->reg_read(ARCH_TIMER_REG_CTRL);
+ ctrl = arch_timer_reg_read(cp15, ARCH_TIMER_REG_CTRL);
if (ctrl & ARCH_TIMER_CTRL_IT_STAT) {
ctrl |= ARCH_TIMER_CTRL_IT_MASK;
- arch_specific_timer->reg_write(ARCH_TIMER_REG_CTRL,
- ctrl);
- evt = *__this_cpu_ptr(arch_timer_evt);
+ arch_timer_reg_write(cp15, ARCH_TIMER_REG_CTRL, ctrl);
evt->event_handler(evt);
return IRQ_HANDLED;
}
@@ -183,16 +165,18 @@
return IRQ_NONE;
}
-static void arch_timer_disable(void)
+static irqreturn_t arch_timer_handler_cp15(int irq, void *dev_id)
{
- unsigned long ctrl;
-
- ctrl = arch_specific_timer->reg_read(ARCH_TIMER_REG_CTRL);
- ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
- arch_specific_timer->reg_write(ARCH_TIMER_REG_CTRL, ctrl);
+ struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
+ return arch_timer_handler(1, evt);
}
-static void arch_timer_set_mode(enum clock_event_mode mode,
+static irqreturn_t arch_timer_handler_mem(int irq, void *dev_id)
+{
+ return arch_timer_handler(0, dev_id);
+}
+
+static inline void arch_timer_set_mode(int cp15, enum clock_event_mode mode,
struct clock_event_device *clk)
{
unsigned long ctrl;
@@ -200,46 +184,72 @@
switch (mode) {
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
- arch_timer_disable();
+ ctrl = arch_timer_reg_read(cp15, ARCH_TIMER_REG_CTRL);
+ ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
+ arch_timer_reg_write(cp15, ARCH_TIMER_REG_CTRL, ctrl);
break;
case CLOCK_EVT_MODE_ONESHOT:
- ctrl = arch_specific_timer->reg_read(ARCH_TIMER_REG_CTRL);
+ ctrl = arch_timer_reg_read(cp15, ARCH_TIMER_REG_CTRL);
ctrl |= ARCH_TIMER_CTRL_ENABLE;
- arch_specific_timer->reg_write(ARCH_TIMER_REG_CTRL, ctrl);
+ arch_timer_reg_write(cp15, ARCH_TIMER_REG_CTRL, ctrl);
default:
break;
}
}
-static int arch_timer_set_next_event(unsigned long evt,
+static void arch_timer_set_mode_cp15(enum clock_event_mode mode,
+ struct clock_event_device *clk)
+{
+ arch_timer_set_mode(1, mode, clk);
+}
+
+static void arch_timer_set_mode_mem(enum clock_event_mode mode,
+ struct clock_event_device *clk)
+{
+ arch_timer_set_mode(0, mode, clk);
+}
+
+static int arch_timer_set_next_event(int cp15, unsigned long evt,
struct clock_event_device *unused)
{
unsigned long ctrl;
- ctrl = arch_specific_timer->reg_read(ARCH_TIMER_REG_CTRL);
+ ctrl = arch_timer_reg_read(cp15, ARCH_TIMER_REG_CTRL);
ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
- arch_specific_timer->reg_write(ARCH_TIMER_REG_CTRL, ctrl);
- arch_specific_timer->reg_write(ARCH_TIMER_REG_TVAL, evt);
+ arch_timer_reg_write(cp15, ARCH_TIMER_REG_CTRL, ctrl);
+ arch_timer_reg_write(cp15, ARCH_TIMER_REG_TVAL, evt);
return 0;
}
+static int arch_timer_set_next_event_cp15(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ return arch_timer_set_next_event(1, evt, unused);
+}
+
+static int arch_timer_set_next_event_mem(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ return arch_timer_set_next_event(0, evt, unused);
+}
+
static int __cpuinit arch_timer_setup(struct clock_event_device *clk)
{
/* setup clock event only once for CPU 0 */
if (!smp_processor_id() && clk->irq == arch_timer_ppi)
return 0;
- /* Be safe... */
- arch_timer_disable();
-
- clk->features = CLOCK_EVT_FEAT_ONESHOT;
+ clk->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP;
clk->name = "arch_sys_timer";
clk->rating = 450;
- clk->set_mode = arch_timer_set_mode;
- clk->set_next_event = arch_timer_set_next_event;
+ clk->set_mode = arch_timer_set_mode_cp15;
+ clk->set_next_event = arch_timer_set_next_event_cp15;
clk->irq = arch_timer_ppi;
+ /* Be safe... */
+ clk->set_mode(CLOCK_EVT_MODE_SHUTDOWN, clk);
+
clockevents_config_and_register(clk, arch_timer_rate,
0xf, 0x7fffffff);
@@ -264,8 +274,8 @@
unsigned long freq;
if (arch_timer_rate == 0) {
- arch_specific_timer->reg_write(ARCH_TIMER_REG_CTRL, 0);
- freq = arch_specific_timer->reg_read(ARCH_TIMER_REG_FREQ);
+ arch_timer_reg_write(1, ARCH_TIMER_REG_CTRL, 0);
+ freq = arch_timer_reg_read(1, ARCH_TIMER_REG_FREQ);
/* Check the timer frequency. */
if (freq == 0) {
@@ -323,9 +333,12 @@
return ((cycle_t) cvalh << 32) | cvall;
}
+static cycle_t (*get_cntpct_func)(void) = counter_get_cntpct_cp15;
+static cycle_t (*get_cntvct_func)(void) = counter_get_cntvct_cp15;
+
cycle_t arch_counter_get_cntpct(void)
{
- return arch_specific_timer->get_cntpct();
+ return get_cntpct_func();
}
EXPORT_SYMBOL(arch_counter_get_cntpct);
@@ -351,7 +364,7 @@
{
cycle_t cntvct;
- cntvct = arch_specific_timer->get_cntvct();
+ cntvct = get_cntvct_func();
/*
* The sched_clock infrastructure only knows about counters
@@ -373,7 +386,7 @@
disable_percpu_irq(clk->irq);
if (arch_timer_ppi2)
disable_percpu_irq(arch_timer_ppi2);
- arch_timer_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
+ clk->set_mode(CLOCK_EVT_MODE_UNUSED, clk);
}
static struct local_timer_ops arch_timer_ops __cpuinitdata = {
@@ -383,13 +396,23 @@
static struct clock_event_device arch_timer_global_evt;
+static void __init arch_timer_counter_init(void)
+{
+ clocksource_register_hz(&clocksource_counter, arch_timer_rate);
+
+ setup_sched_clock(arch_timer_update_sched_clock, 32, arch_timer_rate);
+
+ /* Use the architected timer for the delay loop. */
+ arch_delay_timer.read_current_timer = &arch_timer_read_current_timer;
+ arch_delay_timer.freq = arch_timer_rate;
+ register_current_timer_delay(&arch_delay_timer);
+}
+
static int __init arch_timer_common_register(void)
{
int err;
- if (timer_base)
- arch_specific_timer = &arch_timer_ops_mem;
- else if (!local_timer_is_architected())
+ if (!local_timer_is_architected())
return -ENXIO;
err = arch_timer_available();
@@ -400,16 +423,8 @@
if (!arch_timer_evt)
return -ENOMEM;
- clocksource_register_hz(&clocksource_counter, arch_timer_rate);
-
- setup_sched_clock(arch_timer_update_sched_clock, 32, arch_timer_rate);
-
- if (is_irq_percpu)
- err = request_percpu_irq(arch_timer_ppi, arch_timer_handler,
- "arch_timer", arch_timer_evt);
- else
- err = request_irq(arch_timer_ppi, arch_timer_handler, 0,
- "arch_timer", arch_timer_evt);
+ err = request_percpu_irq(arch_timer_ppi, arch_timer_handler_cp15,
+ "arch_timer", arch_timer_evt);
if (err) {
pr_err("arch_timer: can't register interrupt %d (%d)\n",
arch_timer_ppi, err);
@@ -417,13 +432,9 @@
}
if (arch_timer_ppi2) {
- if (is_irq_percpu)
- err = request_percpu_irq(arch_timer_ppi2,
- arch_timer_handler, "arch_timer",
- arch_timer_evt);
- else
- err = request_irq(arch_timer_ppi2, arch_timer_handler,
- 0, "arch_timer", arch_timer_evt);
+ err = request_percpu_irq(arch_timer_ppi2,
+ arch_timer_handler_cp15,
+ "arch_timer", arch_timer_evt);
if (err) {
pr_err("arch_timer: can't register interrupt %d (%d)\n",
arch_timer_ppi2, err);
@@ -447,10 +458,6 @@
if (err)
goto out_free_irq;
- /* Use the architected timer for the delay loop. */
- arch_delay_timer.read_current_timer = &arch_timer_read_current_timer;
- arch_delay_timer.freq = arch_timer_rate;
- register_current_timer_delay(&arch_delay_timer);
return 0;
out_free_irq:
@@ -464,6 +471,34 @@
return err;
}
+static int __init arch_timer_mem_register(void)
+{
+ int err;
+ struct clock_event_device *clk;
+
+ clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+ if (!clk)
+ return -ENOMEM;
+
+ clk->features = CLOCK_EVT_FEAT_ONESHOT;
+ clk->name = "arch_mem_timer";
+ clk->rating = 400;
+ clk->set_mode = arch_timer_set_mode_mem;
+ clk->set_next_event = arch_timer_set_next_event_mem;
+ clk->irq = arch_timer_spi;
+ clk->cpumask = cpu_all_mask;
+
+ clk->set_mode(CLOCK_EVT_MODE_SHUTDOWN, clk);
+
+ clockevents_config_and_register(clk, arch_timer_rate,
+ 0xf, 0x7fffffff);
+
+ err = request_irq(arch_timer_spi, arch_timer_handler_mem, 0,
+ "arch_timer", clk);
+
+ return err;
+}
+
int __init arch_timer_register(struct arch_timer *at)
{
if (at->res[0].start <= 0 || !(at->res[0].flags & IORESOURCE_IRQ))
@@ -493,48 +528,86 @@
{},
};
+static const struct of_device_id arch_timer_mem_of_match[] __initconst = {
+ { .compatible = "arm,armv7-timer-mem", },
+ {},
+};
+
int __init arch_timer_of_register(void)
{
- struct device_node *np;
+ struct device_node *np, *frame;
u32 freq;
int ret;
+ int has_cp15 = false, has_mem = false;
np = of_find_matching_node(NULL, arch_timer_of_match);
- if (!np) {
- pr_err("arch_timer: can't find DT node\n");
- return -ENODEV;
+ if (np) {
+ has_cp15 = true;
+ /*
+ * Try to determine the frequency from the device tree
+ */
+ if (!of_property_read_u32(np, "clock-frequency", &freq))
+ arch_timer_rate = freq;
+
+ ret = irq_of_parse_and_map(np, 0);
+ if (ret <= 0) {
+ pr_err("arch_timer: interrupt not specified in timer node\n");
+ return -ENODEV;
+ }
+ arch_timer_ppi = ret;
+ ret = irq_of_parse_and_map(np, 1);
+ if (ret > 0)
+ arch_timer_ppi2 = ret;
+
+ ret = arch_timer_common_register();
+ if (ret)
+ return ret;
}
- /* Try to determine the frequency from the device tree or CNTFRQ */
- if (!of_property_read_u32(np, "clock-frequency", &freq))
- arch_timer_rate = freq;
+ np = of_find_matching_node(NULL, arch_timer_mem_of_match);
+ if (np) {
+ has_mem = true;
- ret = irq_of_parse_and_map(np, 0);
- if (ret <= 0) {
- pr_err("arch_timer: interrupt not specified in timer node\n");
- return -ENODEV;
- }
+ if (!has_cp15) {
+ get_cntpct_func = counter_get_cntpct_mem;
+ get_cntvct_func = counter_get_cntvct_mem;
+ }
+ /*
+ * Try to determine the frequency from the device tree
+ */
+ if (!of_property_read_u32(np, "clock-frequency", &freq))
+ arch_timer_rate = freq;
- if (of_get_address(np, 0, NULL, NULL)) {
- timer_base = of_iomap(np, 0);
+ frame = of_get_next_child(np, NULL);
+ if (!frame) {
+ pr_err("arch_timer: no child frame\n");
+ return -EINVAL;
+ }
+
+ timer_base = of_iomap(frame, 0);
if (!timer_base) {
pr_err("arch_timer: cant map timer base\n");
return -ENOMEM;
}
+
+ arch_timer_spi = irq_of_parse_and_map(frame, 0);
+ if (!arch_timer_spi) {
+ pr_err("arch_timer: no physical timer irq\n");
+ return -EINVAL;
+ }
+
+ ret = arch_timer_mem_register();
+ if (ret)
+ return ret;
}
- if (of_get_property(np, "irq-is-not-percpu", NULL))
- is_irq_percpu = 0;
- else
- is_irq_percpu = 1;
+ if (!has_cp15 && !has_mem) {
+ pr_err("arch_timer: can't find DT node\n");
+ return -ENODEV;
+ }
- arch_timer_ppi = ret;
- ret = irq_of_parse_and_map(np, 1);
- if (ret > 0)
- arch_timer_ppi2 = ret;
- pr_info("arch_timer: found %s irqs %d %d\n",
- np->name, arch_timer_ppi, arch_timer_ppi2);
+ arch_timer_counter_init();
- return arch_timer_common_register();
+ return 0;
}
#endif
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index a61f5ca..c60e89a 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -128,122 +128,122 @@
};
static struct acpu_level acpu_freq_tbl_v1_pvs0[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 825000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(3), 825000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(3), 825000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(6), 825000, 124 },
- { 1, { 576000, HFPLL, 1, 30 }, L2(6), 825000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(7), 825000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(7), 825000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(10), 835000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(10), 845000, 229 },
- { 0, { 960000, HFPLL, 1, 50 }, L2(10), 860000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 880000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(12), 905000, 298 },
- { 0, { 1190400, HFPLL, 1, 62 }, L2(12), 920000, 321 },
- { 0, { 1267200, HFPLL, 1, 66 }, L2(12), 940000, 346 },
- { 1, { 1344000, HFPLL, 1, 70 }, L2(12), 960000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(16), 980000, 397 },
- { 0, { 1497600, HFPLL, 1, 78 }, L2(16), 995000, 423 },
- { 0, { 1574400, HFPLL, 1, 82 }, L2(16), 1015000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(16), 1030000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(16), 1050000, 506 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 825000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(3), 825000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(3), 825000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(6), 825000, 3200000 },
+ { 1, { 576000, HFPLL, 1, 30 }, L2(6), 825000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(7), 825000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(7), 825000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(10), 835000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(10), 845000, 3200000 },
+ { 0, { 960000, HFPLL, 1, 50 }, L2(10), 860000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 880000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(12), 905000, 3200000 },
+ { 0, { 1190400, HFPLL, 1, 62 }, L2(12), 920000, 3200000 },
+ { 0, { 1267200, HFPLL, 1, 66 }, L2(12), 940000, 3200000 },
+ { 1, { 1344000, HFPLL, 1, 70 }, L2(12), 960000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(16), 980000, 3200000 },
+ { 0, { 1497600, HFPLL, 1, 78 }, L2(16), 995000, 3200000 },
+ { 0, { 1574400, HFPLL, 1, 82 }, L2(16), 1015000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(16), 1030000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(16), 1050000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_v1_pvs1[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 825000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(3), 825000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(3), 825000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(6), 825000, 124 },
- { 1, { 576000, HFPLL, 1, 30 }, L2(6), 825000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(7), 825000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(7), 825000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(10), 835000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(10), 845000, 229 },
- { 0, { 960000, HFPLL, 1, 50 }, L2(10), 860000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 880000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(12), 905000, 298 },
- { 0, { 1190400, HFPLL, 1, 62 }, L2(12), 920000, 321 },
- { 0, { 1267200, HFPLL, 1, 66 }, L2(12), 940000, 346 },
- { 1, { 1344000, HFPLL, 1, 70 }, L2(12), 960000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(16), 980000, 397 },
- { 0, { 1497600, HFPLL, 1, 78 }, L2(16), 995000, 423 },
- { 0, { 1574400, HFPLL, 1, 82 }, L2(16), 1015000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(16), 1030000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(16), 1050000, 506 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 825000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(3), 825000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(3), 825000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(6), 825000, 3200000 },
+ { 1, { 576000, HFPLL, 1, 30 }, L2(6), 825000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(7), 825000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(7), 825000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(10), 835000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(10), 845000, 3200000 },
+ { 0, { 960000, HFPLL, 1, 50 }, L2(10), 860000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 880000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(12), 905000, 3200000 },
+ { 0, { 1190400, HFPLL, 1, 62 }, L2(12), 920000, 3200000 },
+ { 0, { 1267200, HFPLL, 1, 66 }, L2(12), 940000, 3200000 },
+ { 1, { 1344000, HFPLL, 1, 70 }, L2(12), 960000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(16), 980000, 3200000 },
+ { 0, { 1497600, HFPLL, 1, 78 }, L2(16), 995000, 3200000 },
+ { 0, { 1574400, HFPLL, 1, 82 }, L2(16), 1015000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(16), 1030000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(16), 1050000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_v1_pvs2[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 825000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(3), 825000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(3), 825000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(6), 825000, 124 },
- { 1, { 576000, HFPLL, 1, 30 }, L2(6), 825000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(7), 825000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(7), 825000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(10), 825000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(10), 825000, 229 },
- { 0, { 960000, HFPLL, 1, 50 }, L2(10), 835000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 855000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(12), 875000, 298 },
- { 0, { 1190400, HFPLL, 1, 62 }, L2(12), 895000, 321 },
- { 0, { 1267200, HFPLL, 1, 66 }, L2(12), 915000, 346 },
- { 1, { 1344000, HFPLL, 1, 70 }, L2(12), 930000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(16), 945000, 397 },
- { 0, { 1497600, HFPLL, 1, 78 }, L2(16), 960000, 423 },
- { 0, { 1574400, HFPLL, 1, 82 }, L2(16), 975000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(16), 990000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(16), 1000000, 506 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 825000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(3), 825000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(3), 825000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(6), 825000, 3200000 },
+ { 1, { 576000, HFPLL, 1, 30 }, L2(6), 825000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(7), 825000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(7), 825000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(10), 825000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(10), 825000, 3200000 },
+ { 0, { 960000, HFPLL, 1, 50 }, L2(10), 835000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 855000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(12), 875000, 3200000 },
+ { 0, { 1190400, HFPLL, 1, 62 }, L2(12), 895000, 3200000 },
+ { 0, { 1267200, HFPLL, 1, 66 }, L2(12), 915000, 3200000 },
+ { 1, { 1344000, HFPLL, 1, 70 }, L2(12), 930000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(16), 945000, 3200000 },
+ { 0, { 1497600, HFPLL, 1, 78 }, L2(16), 960000, 3200000 },
+ { 0, { 1574400, HFPLL, 1, 82 }, L2(16), 975000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(16), 990000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(16), 1000000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_v1_pvs3[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 825000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(3), 825000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(3), 825000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(6), 825000, 124 },
- { 1, { 576000, HFPLL, 1, 30 }, L2(6), 825000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(7), 825000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(7), 825000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(10), 825000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(10), 825000, 229 },
- { 0, { 960000, HFPLL, 1, 50 }, L2(10), 835000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 855000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(12), 875000, 298 },
- { 0, { 1190400, HFPLL, 1, 62 }, L2(12), 895000, 321 },
- { 0, { 1267200, HFPLL, 1, 66 }, L2(12), 915000, 346 },
- { 1, { 1344000, HFPLL, 1, 70 }, L2(12), 930000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(16), 945000, 397 },
- { 0, { 1497600, HFPLL, 1, 78 }, L2(16), 960000, 423 },
- { 0, { 1574400, HFPLL, 1, 82 }, L2(16), 975000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(16), 990000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(16), 1000000, 506 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 825000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(3), 825000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(3), 825000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(6), 825000, 3200000 },
+ { 1, { 576000, HFPLL, 1, 30 }, L2(6), 825000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(7), 825000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(7), 825000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(10), 825000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(10), 825000, 3200000 },
+ { 0, { 960000, HFPLL, 1, 50 }, L2(10), 835000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 855000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(12), 875000, 3200000 },
+ { 0, { 1190400, HFPLL, 1, 62 }, L2(12), 895000, 3200000 },
+ { 0, { 1267200, HFPLL, 1, 66 }, L2(12), 915000, 3200000 },
+ { 1, { 1344000, HFPLL, 1, 70 }, L2(12), 930000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(16), 945000, 3200000 },
+ { 0, { 1497600, HFPLL, 1, 78 }, L2(16), 960000, 3200000 },
+ { 0, { 1574400, HFPLL, 1, 82 }, L2(16), 975000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(16), 990000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(16), 1000000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_v1_pvs4[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 825000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(3), 825000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(3), 825000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(6), 825000, 124 },
- { 1, { 576000, HFPLL, 1, 30 }, L2(6), 825000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(7), 825000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(7), 825000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(10), 825000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(10), 825000, 229 },
- { 0, { 960000, HFPLL, 1, 50 }, L2(10), 825000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 825000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(12), 835000, 298 },
- { 0, { 1190400, HFPLL, 1, 62 }, L2(12), 855000, 321 },
- { 0, { 1267200, HFPLL, 1, 66 }, L2(12), 870000, 346 },
- { 1, { 1344000, HFPLL, 1, 70 }, L2(12), 885000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(16), 900000, 397 },
- { 0, { 1497600, HFPLL, 1, 78 }, L2(16), 910000, 423 },
- { 0, { 1574400, HFPLL, 1, 82 }, L2(16), 925000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(16), 940000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(16), 950000, 506 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 825000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(3), 825000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(3), 825000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(6), 825000, 3200000 },
+ { 1, { 576000, HFPLL, 1, 30 }, L2(6), 825000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(7), 825000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(7), 825000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(10), 825000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(10), 825000, 3200000 },
+ { 0, { 960000, HFPLL, 1, 50 }, L2(10), 825000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 825000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(12), 835000, 3200000 },
+ { 0, { 1190400, HFPLL, 1, 62 }, L2(12), 855000, 3200000 },
+ { 0, { 1267200, HFPLL, 1, 66 }, L2(12), 870000, 3200000 },
+ { 1, { 1344000, HFPLL, 1, 70 }, L2(12), 885000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(16), 900000, 3200000 },
+ { 0, { 1497600, HFPLL, 1, 78 }, L2(16), 910000, 3200000 },
+ { 0, { 1574400, HFPLL, 1, 82 }, L2(16), 925000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(16), 940000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(16), 950000, 3200000 },
{ 0, { 0 } }
};
@@ -284,618 +284,618 @@
};
static struct acpu_level acpu_freq_tbl_2g_pvs0[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 815000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 825000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 835000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 845000, 124 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 855000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 865000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 875000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 890000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 900000, 229 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 915000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 925000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 940000, 298 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 950000, 321 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 965000, 346 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 980000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 995000, 397 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 1010000, 423 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 1025000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 1040000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 1055000, 506 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 1070000, 536 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1085000, 567 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1100000, 598 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 815000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 825000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 835000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 845000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 855000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 865000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 875000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 890000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 900000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 915000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 925000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 940000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 950000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 965000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 980000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 995000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 1010000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 1025000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 1040000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 1055000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 1070000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1085000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1100000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2g_pvs1[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 810000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 820000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 830000, 124 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 840000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 850000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 860000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 875000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 885000, 229 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 895000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 910000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 920000, 298 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 930000, 321 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 945000, 346 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 960000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 975000, 397 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 990000, 423 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 1005000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 1020000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 1030000, 506 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 1045000, 536 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1060000, 567 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1075000, 598 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 810000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 820000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 830000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 840000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 850000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 860000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 875000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 885000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 895000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 910000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 920000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 930000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 945000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 960000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 975000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 990000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 1005000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 1020000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 1030000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 1045000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1060000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1075000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2g_pvs2[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 785000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 795000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 805000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 815000, 124 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 825000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 835000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 845000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 855000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 865000, 229 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 875000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 890000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 900000, 298 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 910000, 321 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 925000, 346 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 940000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 955000, 397 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 970000, 423 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 980000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 995000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 1005000, 506 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 1020000, 536 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1035000, 567 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1050000, 598 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 785000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 795000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 805000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 815000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 825000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 835000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 845000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 855000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 865000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 875000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 890000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 900000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 910000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 925000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 940000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 955000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 970000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 980000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 995000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 1005000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 1020000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1035000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1050000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2g_pvs3[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 780000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 790000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 124 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 810000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 820000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 830000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 840000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 850000, 229 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 860000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 875000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 885000, 298 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 895000, 321 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 910000, 346 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 925000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 935000, 397 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 950000, 423 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 960000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 970000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 985000, 506 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 995000, 536 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1010000, 567 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1025000, 598 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 780000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 790000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 810000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 820000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 830000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 840000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 850000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 860000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 875000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 885000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 895000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 910000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 925000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 935000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 950000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 960000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 970000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 985000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 995000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1010000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1025000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2g_pvs4[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 780000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 790000, 124 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 800000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 810000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 820000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 830000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 840000, 229 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 850000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 860000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 870000, 298 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 880000, 321 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 895000, 346 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 910000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 920000, 397 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 930000, 423 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 940000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 950000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 960000, 506 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 975000, 536 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 985000, 567 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1000000, 598 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 780000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 790000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 800000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 810000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 820000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 830000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 840000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 850000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 860000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 870000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 880000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 895000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 910000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 920000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 930000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 940000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 950000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 960000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 975000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 985000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1000000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2g_pvs5[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 760000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 770000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 780000, 124 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 790000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 800000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 810000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 820000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 830000, 229 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 840000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 850000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 860000, 298 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 870000, 321 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 880000, 346 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 890000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 900000, 397 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 910000, 423 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 920000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 930000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 940000, 506 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 955000, 536 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 965000, 567 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 975000, 598 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 760000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 770000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 780000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 790000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 800000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 810000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 820000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 830000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 840000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 850000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 860000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 870000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 880000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 890000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 900000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 910000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 920000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 930000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 940000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 955000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 965000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 975000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2g_pvs6[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 760000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 770000, 124 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 780000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 790000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 800000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 810000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 820000, 229 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 830000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 840000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 850000, 298 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 860000, 321 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 870000, 346 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 875000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 885000, 397 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 895000, 423 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 905000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 915000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 920000, 506 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 930000, 536 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 940000, 567 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 950000, 598 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 760000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 770000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 780000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 790000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 800000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 810000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 820000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 830000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 840000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 850000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 860000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 870000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 875000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 885000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 895000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 905000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 915000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 920000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 930000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 940000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 950000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2p2g_pvs0[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 72 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 83 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 805000, 102 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 815000, 121 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 825000, 141 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 835000, 161 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 845000, 181 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 855000, 202 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 865000, 223 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 875000, 245 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 890000, 267 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 900000, 289 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 915000, 313 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 925000, 336 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 940000, 360 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 950000, 383 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 965000, 409 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 980000, 435 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 995000, 461 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 1010000, 488 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 1025000, 516 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1040000, 543 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1055000, 573 },
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1070000, 604 },
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1085000, 636 },
- { 1, { 2150400, HFPLL, 1, 112 }, L2(19), 1100000, 656 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 805000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 815000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 825000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 835000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 845000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 855000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 865000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 875000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 890000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 900000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 915000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 925000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 940000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 950000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 965000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 980000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 995000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 1010000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 1025000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1040000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1055000, 3200000 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1070000, 3200000 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1085000, 3200000 },
+ { 1, { 2150400, HFPLL, 1, 112 }, L2(19), 1100000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2p2g_pvs1[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 72 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 83 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 102 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 121 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 810000, 141 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 820000, 161 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 830000, 181 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 840000, 202 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 850000, 223 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 860000, 245 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 875000, 267 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 885000, 289 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 895000, 313 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 910000, 336 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 920000, 360 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 930000, 383 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 945000, 409 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 960000, 435 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 975000, 461 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 990000, 488 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 1005000, 516 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1020000, 543 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1030000, 573 },
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1045000, 604 },
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1060000, 636 },
- { 1, { 2150400, HFPLL, 1, 112 }, L2(19), 1075000, 656 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 810000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 820000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 830000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 840000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 850000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 860000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 875000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 885000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 895000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 910000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 920000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 930000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 945000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 960000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 975000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 990000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 1005000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1020000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1030000, 3200000 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1045000, 3200000 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1060000, 3200000 },
+ { 1, { 2150400, HFPLL, 1, 112 }, L2(19), 1075000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2p2g_pvs2[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 72 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 83 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 102 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 785000, 121 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 795000, 141 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 805000, 161 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 815000, 181 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 825000, 202 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 835000, 223 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 845000, 245 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 855000, 267 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 865000, 289 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 875000, 313 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 890000, 336 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 900000, 360 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 910000, 383 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 925000, 409 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 940000, 435 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 955000, 461 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 970000, 488 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 980000, 516 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 995000, 543 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1005000, 573 },
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1020000, 604 },
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1035000, 636 },
- { 1, { 2150400, HFPLL, 1, 112 }, L2(19), 1050000, 656 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 785000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 795000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 805000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 815000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 825000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 835000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 845000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 855000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 865000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 875000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 890000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 900000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 910000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 925000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 940000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 955000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 970000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 980000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 995000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1005000, 3200000 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1020000, 3200000 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1035000, 3200000 },
+ { 1, { 2150400, HFPLL, 1, 112 }, L2(19), 1050000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2p2g_pvs3[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 72 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 83 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 102 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 121 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 780000, 141 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 790000, 161 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 800000, 181 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 810000, 202 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 820000, 223 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 830000, 245 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 840000, 267 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 850000, 289 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 860000, 313 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 875000, 336 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 885000, 360 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 895000, 383 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 910000, 409 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 925000, 435 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 935000, 461 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 950000, 488 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 960000, 516 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 970000, 543 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 985000, 573 },
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 995000, 604 },
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1010000, 636 },
- { 1, { 2150400, HFPLL, 1, 112 }, L2(19), 1025000, 656 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 780000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 790000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 800000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 810000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 820000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 830000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 840000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 850000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 860000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 875000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 885000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 895000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 910000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 925000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 935000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 950000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 960000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 970000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 985000, 3200000 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 995000, 3200000 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1010000, 3200000 },
+ { 1, { 2150400, HFPLL, 1, 112 }, L2(19), 1025000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2p2g_pvs4[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 72 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 83 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 102 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 121 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 141 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 780000, 161 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 790000, 181 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 800000, 202 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 810000, 223 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 820000, 245 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 830000, 267 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 840000, 289 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 850000, 313 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 860000, 336 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 870000, 360 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 880000, 383 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 895000, 409 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 910000, 435 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 920000, 461 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 930000, 488 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 940000, 516 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 950000, 543 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 960000, 573 },
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 975000, 604 },
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 985000, 636 },
- { 1, { 2150400, HFPLL, 1, 112 }, L2(19), 1000000, 656 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 780000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 790000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 800000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 810000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 820000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 830000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 840000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 850000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 860000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 870000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 880000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 895000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 910000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 920000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 930000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 940000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 950000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 960000, 3200000 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 975000, 3200000 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 985000, 3200000 },
+ { 1, { 2150400, HFPLL, 1, 112 }, L2(19), 1000000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2p2g_pvs5[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 72 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 83 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 102 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 121 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 760000, 141 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 770000, 161 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 780000, 181 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 790000, 202 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 800000, 223 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 810000, 245 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 820000, 267 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 830000, 289 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 840000, 313 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 850000, 336 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 860000, 360 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 870000, 383 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 880000, 409 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 890000, 435 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 900000, 461 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 910000, 488 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 920000, 516 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 930000, 543 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 940000, 573 },
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 955000, 604 },
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 965000, 636 },
- { 1, { 2150400, HFPLL, 1, 112 }, L2(19), 975000, 656 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 760000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 770000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 780000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 790000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 800000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 810000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 820000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 830000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 840000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 850000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 860000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 870000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 880000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 890000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 900000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 910000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 920000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 930000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 940000, 3200000 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 955000, 3200000 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 965000, 3200000 },
+ { 1, { 2150400, HFPLL, 1, 112 }, L2(19), 975000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2p2g_pvs6[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 72 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 83 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 102 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 121 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 141 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 760000, 161 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 770000, 181 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 780000, 202 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 790000, 223 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 800000, 245 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 810000, 267 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 820000, 289 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 830000, 313 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 840000, 336 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 850000, 360 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 860000, 383 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 870000, 409 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 875000, 435 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 885000, 461 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 895000, 488 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 905000, 516 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 915000, 543 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 920000, 573 },
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 930000, 604 },
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 940000, 636 },
- { 1, { 2150400, HFPLL, 1, 112 }, L2(19), 950000, 656 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 760000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 770000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 780000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 790000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 800000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 810000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 820000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 830000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 840000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 850000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 860000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 870000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 875000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 885000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 895000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 905000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 915000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 920000, 3200000 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 930000, 3200000 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 940000, 3200000 },
+ { 1, { 2150400, HFPLL, 1, 112 }, L2(19), 950000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2p3g_pvs0[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 72 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 83 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 101 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 805000, 120 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 815000, 139 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 825000, 159 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 835000, 180 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 845000, 200 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 855000, 221 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 865000, 242 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 875000, 264 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 890000, 287 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 900000, 308 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 915000, 333 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 925000, 356 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 940000, 380 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 950000, 404 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 965000, 430 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 980000, 456 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 995000, 482 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 1010000, 510 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1025000, 538 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1040000, 565 },
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1055000, 596 },
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1070000, 627 },
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1085000, 659 },
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1100000, 691 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 805000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 815000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 825000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 835000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 845000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 855000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 865000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 875000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 890000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 900000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 915000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 925000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 940000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 950000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 965000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 980000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 995000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 1010000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1025000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1040000, 3200000 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1055000, 3200000 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1070000, 3200000 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1085000, 3200000 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1100000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2p3g_pvs1[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 72 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 83 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 101 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 120 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 800000, 139 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 810000, 159 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 820000, 180 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 830000, 200 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 840000, 221 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 850000, 242 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 860000, 264 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 875000, 287 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 885000, 308 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 895000, 333 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 910000, 356 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 920000, 380 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 930000, 404 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 945000, 430 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 960000, 456 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 975000, 482 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 990000, 510 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1005000, 538 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1020000, 565 },
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1030000, 596 },
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1045000, 627 },
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1060000, 659 },
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1075000, 691 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 800000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 810000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 820000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 830000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 840000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 850000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 860000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 875000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 885000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 895000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 910000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 920000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 930000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 945000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 960000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 975000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 990000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1005000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1020000, 3200000 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1030000, 3200000 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1045000, 3200000 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1060000, 3200000 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1075000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2p3g_pvs2[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 72 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 83 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 101 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 120 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 785000, 139 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 795000, 159 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 805000, 180 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 815000, 200 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 825000, 221 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 835000, 242 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 845000, 264 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 855000, 287 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 865000, 308 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 875000, 333 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 890000, 356 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 900000, 380 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 910000, 404 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 925000, 430 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 940000, 456 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 955000, 482 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 970000, 510 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 980000, 538 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 995000, 565 },
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1005000, 596 },
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1020000, 627 },
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1035000, 659 },
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1050000, 691 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 785000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 795000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 805000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 815000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 825000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 835000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 845000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 855000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 865000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 875000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 890000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 900000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 910000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 925000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 940000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 955000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 970000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 980000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 995000, 3200000 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1005000, 3200000 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1020000, 3200000 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1035000, 3200000 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1050000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2p3g_pvs3[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 72 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 83 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 101 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 120 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 139 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 780000, 159 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 790000, 180 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 800000, 200 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 810000, 221 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 820000, 242 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 830000, 264 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 840000, 287 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 850000, 308 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 860000, 333 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 875000, 356 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 885000, 380 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 895000, 404 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 910000, 430 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 925000, 456 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 935000, 482 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 950000, 510 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 960000, 538 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 970000, 565 },
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 985000, 596 },
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 995000, 627 },
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1010000, 659 },
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1025000, 691 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 780000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 790000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 800000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 810000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 820000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 830000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 840000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 850000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 860000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 875000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 885000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 895000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 910000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 925000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 935000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 950000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 960000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 970000, 3200000 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 985000, 3200000 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 995000, 3200000 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1010000, 3200000 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1025000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2p3g_pvs4[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 72 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 83 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 101 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 120 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 139 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 159 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 780000, 180 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 790000, 200 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 800000, 221 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 810000, 242 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 820000, 264 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 830000, 287 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 840000, 308 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 850000, 333 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 860000, 356 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 870000, 380 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 880000, 404 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 895000, 430 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 910000, 456 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 920000, 482 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 930000, 510 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 940000, 538 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 950000, 565 },
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 960000, 596 },
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 975000, 627 },
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 985000, 659 },
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1000000, 691 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 780000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 790000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 800000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 810000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 820000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 830000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 840000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 850000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 860000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 870000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 880000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 895000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 910000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 920000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 930000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 940000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 950000, 3200000 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 960000, 3200000 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 975000, 3200000 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 985000, 3200000 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1000000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2p3g_pvs5[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 72 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 83 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 101 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 120 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 139 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 760000, 159 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 770000, 180 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 780000, 200 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 790000, 221 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 800000, 242 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 810000, 264 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 820000, 287 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 830000, 308 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 840000, 333 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 850000, 356 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 860000, 380 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 870000, 404 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 880000, 430 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 890000, 456 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 900000, 482 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 910000, 510 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 920000, 538 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 930000, 565 },
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 940000, 596 },
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 955000, 627 },
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 965000, 659 },
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 975000, 691 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 760000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 770000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 780000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 790000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 800000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 810000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 820000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 830000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 840000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 850000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 860000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 870000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 880000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 890000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 900000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 910000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 920000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 930000, 3200000 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 940000, 3200000 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 955000, 3200000 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 965000, 3200000 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 975000, 3200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_2p3g_pvs6[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 72 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 83 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 101 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 120 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 139 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 750000, 159 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 760000, 180 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 770000, 200 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 780000, 221 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 790000, 242 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 800000, 264 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 810000, 287 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 820000, 308 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 830000, 333 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 840000, 356 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 850000, 380 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 860000, 404 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 870000, 430 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 875000, 456 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 885000, 482 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 895000, 510 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 905000, 538 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 915000, 565 },
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 920000, 596 },
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 930000, 627 },
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 940000, 659 },
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 950000, 691 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 750000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 760000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 770000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 780000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 790000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 800000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 810000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 820000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 830000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 840000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 850000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 860000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 870000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 875000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 885000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 895000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 905000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 915000, 3200000 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 920000, 3200000 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 930000, 3200000 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 940000, 3200000 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 950000, 3200000 },
{ 0, { 0 } }
};
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index a0644e6..2f09162 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -913,8 +913,10 @@
if (!bam_is_connected) {
read_unlock(&ul_wakeup_lock);
ul_wakeup();
- if (unlikely(in_global_reset == 1))
+ if (unlikely(in_global_reset == 1)) {
+ kfree(hdr);
return -EFAULT;
+ }
read_lock(&ul_wakeup_lock);
notify_all(BAM_DMUX_UL_CONNECTED, (unsigned long)(NULL));
}
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 0fe94d5..f969e31 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -437,7 +437,7 @@
if (fixed_position != NOT_FIXED)
fixed_size += heap->size;
- else
+ else if (!use_cma)
reserve_mem_for_ion(MEMTYPE_EBI1, heap->size);
if (fixed_position == FIXED_LOW) {
@@ -3585,6 +3585,18 @@
if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
apq8064_pm8917_pdata_fixup();
platform_device_register(&msm_gpio_device);
+ if (cpu_is_apq8064ab())
+ apq8064ab_update_krait_spm();
+ if (cpu_is_krait_v3()) {
+ struct msm_pm_init_data_type *pdata =
+ msm8064_pm_8x60.dev.platform_data;
+ pdata->retention_calls_tz = false;
+ apq8064ab_update_retention_spm();
+ }
+ platform_device_register(&msm8064_pm_8x60);
+
+ msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
+ msm_spm_l2_init(msm_spm_l2_data);
msm_tsens_early_init(&apq_tsens_pdata);
msm_thermal_init(&msm_thermal_pdata);
if (socinfo_init() < 0)
@@ -3699,18 +3711,6 @@
apq8064_init_dsps();
platform_device_register(&msm_8960_riva);
}
- if (cpu_is_apq8064ab())
- apq8064ab_update_krait_spm();
- if (cpu_is_krait_v3()) {
- struct msm_pm_init_data_type *pdata =
- msm8064_pm_8x60.dev.platform_data;
- pdata->retention_calls_tz = false;
- apq8064ab_update_retention_spm();
- }
- platform_device_register(&msm8064_pm_8x60);
-
- msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
- msm_spm_l2_init(msm_spm_l2_data);
BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
apq8064_epm_adc_init();
}
diff --git a/arch/arm/mach-msm/board-8610.c b/arch/arm/mach-msm/board-8610.c
index 67334d5..2cd7134 100644
--- a/arch/arm/mach-msm/board-8610.c
+++ b/arch/arm/mach-msm/board-8610.c
@@ -44,6 +44,7 @@
#include <mach/clk-provider.h>
#include <mach/msm_smd.h>
#include <mach/rpm-smd.h>
+#include <mach/rpm-regulator-smd.h>
#include <linux/msm_thermal.h>
#include "board-dt.h"
#include "clock.h"
@@ -105,6 +106,7 @@
msm_rpm_driver_init();
msm_lpmrs_module_init();
msm_spm_device_init();
+ rpm_regulator_smd_driver_init();
qpnp_regulator_init();
tsens_tm_init_driver();
msm_thermal_device_init();
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 8be128c..6ccaba6 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -477,7 +477,7 @@
if (fixed_position != NOT_FIXED)
fixed_size += heap->size;
- else
+ else if (!use_cma)
reserve_mem_for_ion(MEMTYPE_EBI1, heap->size);
if (fixed_position == FIXED_LOW) {
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index c5fc418..5d96389 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -532,7 +532,7 @@
if (fixed_position != NOT_FIXED)
fixed_size += heap->size;
- else
+ else if (!use_cma)
reserve_mem_for_ion(MEMTYPE_EBI1, heap->size);
if (fixed_position == FIXED_LOW) {
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index 5f9eafd..4eb3d29 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -3060,7 +3060,7 @@
/* WCNSS CLOCKS */
CLK_LOOKUP("xo", cxo_wlan_clk.c, "fb000000.qcom,wcnss-wlan"),
- CLK_LOOKUP("rf_clk", cxo_a2.c, "fb000000.qcom,wcnss-wlan"),
+ CLK_LOOKUP("rf_clk", cxo_a1.c, "fb000000.qcom,wcnss-wlan"),
/* BUS DRIVER */
CLK_LOOKUP("bus_clk", cnoc_msmbus_clk.c, "msm_config_noc"),
diff --git a/arch/arm/mach-msm/clock-8610.c b/arch/arm/mach-msm/clock-8610.c
index 2e35d8a..8880661 100644
--- a/arch/arm/mach-msm/clock-8610.c
+++ b/arch/arm/mach-msm/clock-8610.c
@@ -462,9 +462,9 @@
#define D0_ID 1
#define D1_ID 2
-#define A0_ID 3
-#define A1_ID 4
-#define A2_ID 5
+#define A0_ID 4
+#define A1_ID 5
+#define A2_ID 6
#define DIFF_CLK_ID 7
#define DIV_CLK_ID 11
@@ -2620,6 +2620,10 @@
CLK_LOOKUP("core_clk", qdss_clk.c, "fc352000.cti"),
CLK_LOOKUP("core_clk", qdss_clk.c, "fc353000.cti"),
CLK_LOOKUP("core_clk", qdss_clk.c, "fc354000.cti"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc34c000.jtagmm"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc34d000.jtagmm"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc34e000.jtagmm"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc34f000.jtagmm"),
CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc326000.tmc"),
@@ -2649,6 +2653,10 @@
CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc352000.cti"),
CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc353000.cti"),
CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc354000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc34c000.jtagmm"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc34d000.jtagmm"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc34e000.jtagmm"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc34f000.jtagmm"),
@@ -2804,7 +2812,7 @@
CLK_LOOKUP("measure_clk", l2_m_clk, ""),
CLK_LOOKUP("xo", gcc_xo_clk_src.c, "fb000000.qcom,wcnss-wlan"),
- CLK_LOOKUP("rf_clk", cxo_a2.c, "fb000000.qcom,wcnss-wlan"),
+ CLK_LOOKUP("rf_clk", cxo_a1.c, "fb000000.qcom,wcnss-wlan"),
CLK_LOOKUP("iface_clk", mdp_ahb_clk.c, "fd900000.qcom,mdss_mdp"),
CLK_LOOKUP("core_clk", mdp_axi_clk.c, "fd900000.qcom,mdss_mdp"),
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 73e44b1..1d7af9b 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -4757,7 +4757,8 @@
CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f991f000.serial"),
CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f9924000.i2c"),
CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f991e000.serial"),
- CLK_LOOKUP("core_clk", gcc_blsp1_qup1_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup1_i2c_apps_clk.c, "f9923000.i2c"),
+ CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f9923000.i2c"),
CLK_LOOKUP("core_clk", gcc_blsp1_qup2_i2c_apps_clk.c, "f9924000.i2c"),
CLK_LOOKUP("core_clk", gcc_blsp1_qup2_spi_apps_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_blsp1_qup1_spi_apps_clk.c, "f9923000.spi"),
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index d81dbb4..0d617a6 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -1587,9 +1587,11 @@
if (!rport_ptr)
pr_err("%s: Remote port create "
"failed\n", __func__);
- rport_ptr->sec_rule =
- msm_ipc_get_security_rule(
- msg->srv.service, msg->srv.instance);
+ else
+ rport_ptr->sec_rule =
+ msm_ipc_get_security_rule(
+ msg->srv.service,
+ msg->srv.instance);
}
wake_up(&newserver_wait);
}
@@ -1890,6 +1892,7 @@
head_skb = skb_peek(pkt->pkt_fragment_q);
if (!head_skb) {
pr_err("%s: pkt_fragment_q is empty\n", __func__);
+ release_pkt(pkt);
return -EINVAL;
}
hdr = (struct rr_header *)skb_push(head_skb, IPC_ROUTER_HDR_SIZE);
diff --git a/arch/arm/mach-msm/ipc_socket.c b/arch/arm/mach-msm/ipc_socket.c
index c0422a1..342663e 100644
--- a/arch/arm/mach-msm/ipc_socket.c
+++ b/arch/arm/mach-msm/ipc_socket.c
@@ -367,7 +367,8 @@
if (port_ptr->type == CLIENT_PORT)
wait_for_irsc_completion();
ipc_buf = skb_peek(msg);
- msm_ipc_router_ipc_log(IPC_SEND, ipc_buf, port_ptr);
+ if (ipc_buf)
+ msm_ipc_router_ipc_log(IPC_SEND, ipc_buf, port_ptr);
ret = msm_ipc_router_send_to(port_ptr, msg, &dest->address);
if (ret == (IPC_ROUTER_HDR_SIZE + total_len))
ret = total_len;
@@ -429,7 +430,8 @@
ret = msm_ipc_router_extract_msg(m, msg);
ipc_buf = skb_peek(msg);
- msm_ipc_router_ipc_log(IPC_RECV, ipc_buf, port_ptr);
+ if (ipc_buf)
+ msm_ipc_router_ipc_log(IPC_RECV, ipc_buf, port_ptr);
msm_ipc_router_release_msg(msg);
msg = NULL;
release_sock(sk);
diff --git a/arch/arm/mach-msm/krait-regulator.c b/arch/arm/mach-msm/krait-regulator.c
index af2fbab..953f941d 100644
--- a/arch/arm/mach-msm/krait-regulator.c
+++ b/arch/arm/mach-msm/krait-regulator.c
@@ -61,7 +61,9 @@
#define PMIC_VOLTAGE_MAX 1355000
#define LV_RANGE_STEP 5000
-#define CORE_VOLTAGE_BOOTUP 900000
+#define LOAD_PER_PHASE 3200000
+
+#define CORE_VOLTAGE_MIN 900000
#define KRAIT_LDO_VOLTAGE_MIN 465000
#define KRAIT_LDO_VOLTAGE_OFFSET 465000
@@ -133,7 +135,6 @@
#define LDO_DELTA_MIN 10000
#define LDO_DELTA_MAX 100000
-#define MSM_L2_SAW_PHYS 0xf9012000
/**
* struct pmic_gang_vreg -
* @name: the string used to represent the gang
@@ -145,10 +146,7 @@
* regulator's callback functions to prevent
* simultaneous updates to the pmic's phase
* voltage.
- * @apcs_gcc_base: virtual address of the APCS GCC registers
- * @manage_phases: begin phase control
- * @pfm_threshold: the sum of coefficients below which PFM can be
- * enabled
+ * @apcs_gcc_base virtual address of the APCS GCC registers
*/
struct pmic_gang_vreg {
const char *name;
@@ -161,8 +159,6 @@
bool retention_enabled;
bool use_phase_switching;
void __iomem *apcs_gcc_base;
- bool manage_phases;
- int pfm_threshold;
};
static struct pmic_gang_vreg *the_gang;
@@ -172,9 +168,6 @@
LDO_MODE = REGULATOR_MODE_IDLE,
};
-#define WAIT_FOR_LOAD 0x2
-#define WAIT_FOR_VOLTAGE 0x1
-
struct krait_power_vreg {
struct list_head link;
struct regulator_desc desc;
@@ -182,7 +175,7 @@
const char *name;
struct pmic_gang_vreg *pvreg;
int uV;
- int load;
+ int load_uA;
enum krait_supply_mode mode;
void __iomem *reg_base;
void __iomem *mdd_base;
@@ -192,10 +185,7 @@
int ldo_threshold_uV;
int ldo_delta_uV;
int cpu_num;
- int coeff1;
- int coeff2;
bool online;
- int online_at_probe;
};
DEFINE_PER_CPU(struct krait_power_vreg *, krait_vregs);
@@ -303,229 +293,6 @@
return 0;
}
-#define COEFF2_UV_THRESHOLD 850000
-static int get_coeff2(int krait_uV)
-{
- int coeff2 = 0;
- int krait_mV = krait_uV / 1000;
-
- if (krait_uV <= COEFF2_UV_THRESHOLD)
- coeff2 = (612229 * krait_mV) / 1000 - 211258;
- else
- coeff2 = (892564 * krait_mV) / 1000 - 449543;
-
- return coeff2;
-}
-
-static int get_coeff1(int actual_uV, int requested_uV, int load)
-{
- int ratio = actual_uV * 1000 / requested_uV;
- int coeff1 = 330 * load + (load * 673 * ratio / 1000);
-
- return coeff1;
-}
-
-static int get_coeff_total(struct krait_power_vreg *from)
-{
- int coeff_total = 0;
- struct krait_power_vreg *kvreg;
- struct pmic_gang_vreg *pvreg = from->pvreg;
-
- list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
- if (!kvreg->online)
- continue;
-
- if (kvreg->mode == LDO_MODE) {
- kvreg->coeff1 =
- get_coeff1(kvreg->uV - kvreg->ldo_delta_uV,
- kvreg->uV, kvreg->load);
- kvreg->coeff2 =
- get_coeff2(kvreg->uV - kvreg->ldo_delta_uV);
- } else {
- kvreg->coeff1 =
- get_coeff1(pvreg->pmic_vmax_uV,
- kvreg->uV, kvreg->load);
- kvreg->coeff2 = get_coeff2(pvreg->pmic_vmax_uV);
- }
- coeff_total += kvreg->coeff1 + kvreg->coeff2;
- }
-
- return coeff_total;
-}
-
-static int set_pmic_gang_phases(struct pmic_gang_vreg *pvreg, int phase_count)
-{
- pr_debug("programming phase_count = %d\n", phase_count);
- if (pvreg->use_phase_switching)
- /*
- * note the PMIC sets the phase count to one more than
- * the value in the register - hence subtract 1 from it
- */
- return msm_spm_apcs_set_phase(phase_count - 1);
- else
- return 0;
-}
-
-static int num_online(struct pmic_gang_vreg *pvreg)
-{
- int online_total = 0;
- struct krait_power_vreg *kvreg;
-
- list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
- if (kvreg->online)
- online_total++;
- }
- return online_total;
-}
-
-static bool enable_phase_management(struct pmic_gang_vreg *pvreg)
-{
- struct krait_power_vreg *kvreg;
-
- list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
- pr_debug("%s online_at_probe:0x%x\n", kvreg->name,
- kvreg->online_at_probe);
- if (kvreg->online_at_probe)
- return false;
- }
- return true;
-}
-
-#define PMIC_FTS_MODE_PFM 0x00
-#define PMIC_FTS_MODE_PWM 0x80
-#define ONE_PHASE_COEFF 1000000
-#define TWO_PHASE_COEFF 2000000
-
-#define PHASE_SETTLING_TIME_US 10
-static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
- int coeff_total)
-{
- struct pmic_gang_vreg *pvreg = from->pvreg;
- int phase_count;
- int rc = 0;
- int n_online = num_online(pvreg);
-
- if (pvreg->manage_phases == false) {
- if (enable_phase_management(pvreg))
- pvreg->manage_phases = true;
- else
- return 0;
- }
-
- /* First check if the coeff is low for PFM mode */
- if (coeff_total < pvreg->pfm_threshold && n_online == 1) {
- if (!pvreg->pfm_mode) {
- rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PFM);
- if (rc) {
- pr_err("%s PFM en failed coeff_t %d rc = %d\n",
- from->name, coeff_total, rc);
- return rc;
- } else {
- pvreg->pfm_mode = true;
- }
- }
- return rc;
- }
-
- /* coeff is high switch to PWM mode before changing phases */
- if (pvreg->pfm_mode) {
- rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PWM);
- if (rc) {
- pr_err("%s PFM exit failed load %d rc = %d\n",
- from->name, coeff_total, rc);
- return rc;
- } else {
- pvreg->pfm_mode = false;
- }
- }
-
- /* calculate phases */
- if (coeff_total < ONE_PHASE_COEFF)
- phase_count = 1;
- else if (coeff_total < TWO_PHASE_COEFF)
- phase_count = 2;
- else
- phase_count = 4;
-
- /* don't increase the phase count higher than number of online cpus */
- if (phase_count > n_online)
- phase_count = n_online;
-
- if (phase_count != pvreg->pmic_phase_count) {
- rc = set_pmic_gang_phases(pvreg, phase_count);
- if (rc < 0) {
- pr_err("%s failed set phase %d rc = %d\n",
- from->name, phase_count, rc);
- return rc;
- }
-
- /* complete the writes before the delay */
- mb();
-
- /*
- * delay until the phases are settled when
- * the count is raised
- */
- if (phase_count > pvreg->pmic_phase_count)
- udelay(PHASE_SETTLING_TIME_US);
-
- pvreg->pmic_phase_count = phase_count;
- }
-
- return rc;
-}
-
-static unsigned int _get_optimum_mode(struct regulator_dev *rdev,
- int input_uV, int output_uV, int load)
-{
- struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
- int coeff_total;
- int rc;
-
- kvreg->online_at_probe &= ~WAIT_FOR_LOAD;
- coeff_total = get_coeff_total(kvreg);
-
- rc = pmic_gang_set_phases(kvreg, coeff_total);
- if (rc < 0) {
- dev_err(&rdev->dev, "%s failed set mode %d rc = %d\n",
- kvreg->name, coeff_total, rc);
- }
-
- return kvreg->mode;
-}
-
-static unsigned int krait_power_get_optimum_mode(struct regulator_dev *rdev,
- int input_uV, int output_uV, int load_uA)
-{
- struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
- struct pmic_gang_vreg *pvreg = kvreg->pvreg;
- int rc;
-
- mutex_lock(&pvreg->krait_power_vregs_lock);
- kvreg->load = load_uA;
- if (!kvreg->online) {
- mutex_unlock(&pvreg->krait_power_vregs_lock);
- return kvreg->mode;
- }
-
- rc = _get_optimum_mode(rdev, input_uV, output_uV, load_uA);
- mutex_unlock(&pvreg->krait_power_vregs_lock);
-
- return rc;
-}
-
-static int krait_power_set_mode(struct regulator_dev *rdev, unsigned int mode)
-{
- return 0;
-}
-
-static unsigned int krait_power_get_mode(struct regulator_dev *rdev)
-{
- struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
-
- return kvreg->mode;
-}
-
static int switch_to_using_hs(struct krait_power_vreg *kvreg)
{
if (kvreg->mode == HS_MODE)
@@ -601,6 +368,19 @@
return 0;
}
+static int set_pmic_gang_phases(struct pmic_gang_vreg *pvreg, int phase_count)
+{
+ pr_debug("programming phase_count = %d\n", phase_count);
+ if (pvreg->use_phase_switching)
+ /*
+ * note the PMIC sets the phase count to one more than
+ * the value in the register - hence subtract 1 from it
+ */
+ return msm_spm_apcs_set_phase(phase_count - 1);
+ else
+ return 0;
+}
+
static int set_pmic_gang_voltage(struct pmic_gang_vreg *pvreg, int uV)
{
int setpoint;
@@ -744,6 +524,46 @@
return rc;
}
+#define PHASE_SETTLING_TIME_US 10
+static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
+ int load_uA)
+{
+ struct pmic_gang_vreg *pvreg = from->pvreg;
+ int phase_count = DIV_ROUND_UP(load_uA, LOAD_PER_PHASE);
+ int rc = 0;
+
+ if (phase_count <= 0)
+ phase_count = 1;
+
+ /* Increase phases if it is less than the number of cpus online */
+ if (phase_count < num_online_cpus()) {
+ phase_count = num_online_cpus();
+ }
+
+ if (phase_count != pvreg->pmic_phase_count) {
+ rc = set_pmic_gang_phases(pvreg, phase_count);
+ if (rc < 0) {
+ dev_err(&from->rdev->dev,
+ "%s failed set phase %d rc = %d\n",
+ pvreg->name, phase_count, rc);
+ return rc;
+ }
+
+ /* complete the writes before the delay */
+ mb();
+
+ /*
+ * delay until the phases are settled when
+ * the count is raised
+ */
+ if (phase_count > pvreg->pmic_phase_count)
+ udelay(PHASE_SETTLING_TIME_US);
+
+ pvreg->pmic_phase_count = phase_count;
+ }
+ return rc;
+}
+
static int krait_power_get_voltage(struct regulator_dev *rdev)
{
struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
@@ -770,6 +590,21 @@
return vmax;
}
+static int get_total_load(struct krait_power_vreg *from)
+{
+ int load_total = 0;
+ struct krait_power_vreg *kvreg;
+ struct pmic_gang_vreg *pvreg = from->pvreg;
+
+ list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
+ if (!kvreg->online)
+ continue;
+ load_total += kvreg->load_uA;
+ }
+
+ return load_total;
+}
+
#define ROUND_UP_VOLTAGE(v, res) (DIV_ROUND_UP(v, res) * res)
static int _set_voltage(struct regulator_dev *rdev,
int orig_krait_uV, int requested_uV)
@@ -778,7 +613,6 @@
struct pmic_gang_vreg *pvreg = kvreg->pvreg;
int rc;
int vmax;
- int coeff_total;
pr_debug("%s: %d to %d\n", kvreg->name, orig_krait_uV, requested_uV);
/*
@@ -802,11 +636,6 @@
kvreg->name, requested_uV, orig_krait_uV, rc);
}
- kvreg->online_at_probe &= ~WAIT_FOR_VOLTAGE;
- coeff_total = get_coeff_total(kvreg);
- /* adjust the phases since coeff2 would have changed */
- rc = pmic_gang_set_phases(kvreg, coeff_total);
-
return rc;
}
@@ -841,6 +670,89 @@
return rc;
}
+#define PMIC_FTS_MODE_PFM 0x00
+#define PMIC_FTS_MODE_PWM 0x80
+#define PFM_LOAD_UA 500000
+static unsigned int _get_optimum_mode(struct regulator_dev *rdev,
+ int input_uV, int output_uV, int load_uA)
+{
+ struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
+ struct pmic_gang_vreg *pvreg = kvreg->pvreg;
+ int rc;
+ int load_total_uA;
+
+ load_total_uA = get_total_load(kvreg);
+
+ if (load_total_uA < PFM_LOAD_UA) {
+ if (!pvreg->pfm_mode) {
+ rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PFM);
+ if (rc) {
+ dev_err(&rdev->dev,
+ "%s enter PFM failed load %d rc = %d\n",
+ kvreg->name, load_total_uA, rc);
+ goto out;
+ } else {
+ pvreg->pfm_mode = true;
+ }
+ }
+ return kvreg->mode;
+ }
+
+ if (pvreg->pfm_mode) {
+ rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PWM);
+ if (rc) {
+ dev_err(&rdev->dev,
+ "%s exit PFM failed load %d rc = %d\n",
+ kvreg->name, load_total_uA, rc);
+ goto out;
+ } else {
+ pvreg->pfm_mode = false;
+ }
+ }
+
+ rc = pmic_gang_set_phases(kvreg, load_total_uA);
+ if (rc < 0) {
+ dev_err(&rdev->dev, "%s failed set mode %d rc = %d\n",
+ kvreg->name, load_total_uA, rc);
+ goto out;
+ }
+
+out:
+ return kvreg->mode;
+}
+
+static unsigned int krait_power_get_optimum_mode(struct regulator_dev *rdev,
+ int input_uV, int output_uV, int load_uA)
+{
+ struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
+ struct pmic_gang_vreg *pvreg = kvreg->pvreg;
+ int rc;
+
+ mutex_lock(&pvreg->krait_power_vregs_lock);
+ kvreg->load_uA = load_uA;
+ if (!kvreg->online) {
+ mutex_unlock(&pvreg->krait_power_vregs_lock);
+ return kvreg->mode;
+ }
+
+ rc = _get_optimum_mode(rdev, input_uV, output_uV, load_uA);
+ mutex_unlock(&pvreg->krait_power_vregs_lock);
+
+ return rc;
+}
+
+static int krait_power_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+ return 0;
+}
+
+static unsigned int krait_power_get_mode(struct regulator_dev *rdev)
+{
+ struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
+
+ return kvreg->mode;
+}
+
static int krait_power_is_enabled(struct regulator_dev *rdev)
{
struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
@@ -857,7 +769,7 @@
mutex_lock(&pvreg->krait_power_vregs_lock);
__krait_power_mdd_enable(kvreg, true);
kvreg->online = true;
- rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV, kvreg->load);
+ rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV, kvreg->load_uA);
if (rc < 0)
goto en_err;
/*
@@ -879,7 +791,8 @@
mutex_lock(&pvreg->krait_power_vregs_lock);
kvreg->online = false;
- rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV, kvreg->load);
+ rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV,
+ kvreg->load_uA);
if (rc < 0)
goto dis_err;
@@ -938,10 +851,8 @@
DEFINE_SIMPLE_ATTRIBUTE(retention_fops,
get_retention_dbg_uV, set_retention_dbg_uV, "%llu\n");
-#define CPU_PWR_CTL_ONLINE_MASK 0x80
static void kvreg_hw_init(struct krait_power_vreg *kvreg)
{
- int online;
/*
* bhs_cnt value sets the ramp-up time from power collapse,
* initialize the ramp up time
@@ -954,10 +865,6 @@
/* Enable MDD */
writel_relaxed(0x00000002, kvreg->mdd_base + MDD_MODE);
mb();
- online = CPU_PWR_CTL_ONLINE_MASK
- & readl_relaxed(kvreg->reg_base + CPU_PWR_CTL);
- kvreg->online_at_probe
- = online ? (WAIT_FOR_LOAD | WAIT_FOR_VOLTAGE) : 0x0;
}
static void glb_init(void __iomem *apcs_gcc_base)
@@ -1105,7 +1012,7 @@
kvreg->desc.ops = &krait_power_ops;
kvreg->desc.type = REGULATOR_VOLTAGE;
kvreg->desc.owner = THIS_MODULE;
- kvreg->uV = CORE_VOLTAGE_BOOTUP;
+ kvreg->uV = CORE_VOLTAGE_MIN;
kvreg->mode = HS_MODE;
kvreg->desc.ops = &krait_power_ops;
kvreg->headroom_uV = headroom_uV;
@@ -1204,7 +1111,6 @@
{
int rc;
bool use_phase_switching = false;
- int pfm_threshold;
struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
struct pmic_gang_vreg *pvreg;
@@ -1217,13 +1123,6 @@
use_phase_switching = of_property_read_bool(node,
"qcom,use-phase-switching");
-
- rc = of_property_read_u32(node, "qcom,pfm-threshold", &pfm_threshold);
- if (rc < 0) {
- dev_err(dev, "pfm-threshold missing rc=%d, pfm disabled\n", rc);
- return -EINVAL;
- }
-
pvreg = devm_kzalloc(&pdev->dev,
sizeof(struct pmic_gang_vreg), GFP_KERNEL);
if (!pvreg) {
@@ -1249,7 +1148,6 @@
pvreg->retention_enabled = true;
pvreg->pmic_min_uV_for_retention = INT_MAX;
pvreg->use_phase_switching = use_phase_switching;
- pvreg->pfm_threshold = pfm_threshold;
mutex_init(&pvreg->krait_power_vregs_lock);
INIT_LIST_HEAD(&pvreg->krait_power_vregs);
@@ -1310,8 +1208,6 @@
void secondary_cpu_hs_init(void *base_ptr)
{
- void *l2_saw_base;
-
/* Turn on the BHS, turn off LDO Bypass and power down LDO */
writel_relaxed(
BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
@@ -1338,23 +1234,6 @@
| BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
| BHS_EN_MASK,
base_ptr + APC_PWR_GATE_CTL);
-
- if (the_gang && the_gang->manage_phases)
- return;
-
- /* If the driver has not yet started to manage phases then enable
- * max phases.
- */
- l2_saw_base = ioremap_nocache(MSM_L2_SAW_PHYS, SZ_4K);
- if (!l2_saw_base) {
- __WARN();
- return;
- }
- writel_relaxed(0x10003, l2_saw_base + 0x1c);
- mb();
- udelay(PHASE_SETTLING_TIME_US);
-
- iounmap(l2_saw_base);
}
MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/mpm-of.c b/arch/arm/mach-msm/mpm-of.c
index fcd7cef..5c654b0 100644
--- a/arch/arm/mach-msm/mpm-of.c
+++ b/arch/arm/mach-msm/mpm-of.c
@@ -377,7 +377,7 @@
if (!msm_mpm_is_initialized())
return -EINVAL;
- if (pin > MSM_MPM_NR_MPM_IRQS)
+ if (pin >= MSM_MPM_NR_MPM_IRQS)
return -EINVAL;
spin_lock_irqsave(&msm_mpm_lock, flags);
@@ -767,7 +767,7 @@
return;
failed_malloc:
- for (i = 0; i < MSM_MPM_NR_MPM_IRQS; i++) {
+ for (i = 0; i < MSM_MPM_NR_IRQ_DOMAINS; i++) {
mpm_of_map[i].chip->irq_mask = NULL;
mpm_of_map[i].chip->irq_unmask = NULL;
mpm_of_map[i].chip->irq_disable = NULL;
diff --git a/arch/arm/mach-msm/rpm-smd.c b/arch/arm/mach-msm/rpm-smd.c
index b84ade9..6ed80f6 100644
--- a/arch/arm/mach-msm/rpm-smd.c
+++ b/arch/arm/mach-msm/rpm-smd.c
@@ -673,7 +673,7 @@
static struct msm_rpm_wait_data *msm_rpm_get_entry_from_msg_id(uint32_t msg_id)
{
struct list_head *ptr;
- struct msm_rpm_wait_data *elem;
+ struct msm_rpm_wait_data *elem = NULL;
unsigned long flags;
spin_lock_irqsave(&msm_rpm_list_lock, flags);
@@ -739,7 +739,7 @@
static void msm_rpm_process_ack(uint32_t msg_id, int errno)
{
struct list_head *ptr;
- struct msm_rpm_wait_data *elem;
+ struct msm_rpm_wait_data *elem = NULL;
unsigned long flags;
spin_lock_irqsave(&msm_rpm_list_lock, flags);
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index 8a9042e..07ac930 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -3838,6 +3838,12 @@
for_each_child_of_node(pdev->dev.of_node, node) {
compatible = of_get_property(node, "compatible", NULL);
+ if (!compatible) {
+ pr_err("%s: invalid child node: compatible null\n",
+ __func__);
+ ret = -ENODEV;
+ goto rollback_subnodes;
+ }
if (!strcmp(compatible, "qcom,smd")) {
ret = parse_smd_devicetree(node, irq_out_base);
if (ret)
diff --git a/arch/arm/mach-msm/spm_devices.c b/arch/arm/mach-msm/spm_devices.c
index 233c5a5..174d444 100644
--- a/arch/arm/mach-msm/spm_devices.c
+++ b/arch/arm/mach-msm/spm_devices.c
@@ -74,6 +74,7 @@
info.cpu = cpu;
info.vlevel = vlevel;
+ info.err = -ENODEV;
if (cpu_online(cpu)) {
/**
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 5b929d7..a4003ff 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -693,8 +693,7 @@
diag_update_sleeping_process(entry.process_id, PKT_TYPE);
} else {
if (len > 0) {
- if ((entry.client_id >= 0) &&
- (entry.client_id < NUM_SMD_DATA_CHANNELS)) {
+ if (entry.client_id < NUM_SMD_DATA_CHANNELS) {
int index = entry.client_id;
if (driver->smd_data[index].ch) {
if ((index == MODEM_DATA) &&
@@ -907,94 +906,186 @@
/* bld time masks */
switch (ssid_first) {
case MSG_SSID_0:
+ if (ssid_range > sizeof(msg_bld_masks_0)) {
+ pr_warning("diag: truncating ssid range for ssid 0");
+ ssid_range = sizeof(msg_bld_masks_0);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_0[i/4];
break;
case MSG_SSID_1:
+ if (ssid_range > sizeof(msg_bld_masks_1)) {
+ pr_warning("diag: truncating ssid range for ssid 1");
+ ssid_range = sizeof(msg_bld_masks_1);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_1[i/4];
break;
case MSG_SSID_2:
+ if (ssid_range > sizeof(msg_bld_masks_2)) {
+ pr_warning("diag: truncating ssid range for ssid 2");
+ ssid_range = sizeof(msg_bld_masks_2);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_2[i/4];
break;
case MSG_SSID_3:
+ if (ssid_range > sizeof(msg_bld_masks_3)) {
+ pr_warning("diag: truncating ssid range for ssid 3");
+ ssid_range = sizeof(msg_bld_masks_3);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_3[i/4];
break;
case MSG_SSID_4:
+ if (ssid_range > sizeof(msg_bld_masks_4)) {
+ pr_warning("diag: truncating ssid range for ssid 4");
+ ssid_range = sizeof(msg_bld_masks_4);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_4[i/4];
break;
case MSG_SSID_5:
+ if (ssid_range > sizeof(msg_bld_masks_5)) {
+ pr_warning("diag: truncating ssid range for ssid 5");
+ ssid_range = sizeof(msg_bld_masks_5);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_5[i/4];
break;
case MSG_SSID_6:
+ if (ssid_range > sizeof(msg_bld_masks_6)) {
+ pr_warning("diag: truncating ssid range for ssid 6");
+ ssid_range = sizeof(msg_bld_masks_6);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_6[i/4];
break;
case MSG_SSID_7:
+ if (ssid_range > sizeof(msg_bld_masks_7)) {
+ pr_warning("diag: truncating ssid range for ssid 7");
+ ssid_range = sizeof(msg_bld_masks_7);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_7[i/4];
break;
case MSG_SSID_8:
+ if (ssid_range > sizeof(msg_bld_masks_8)) {
+ pr_warning("diag: truncating ssid range for ssid 8");
+ ssid_range = sizeof(msg_bld_masks_8);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_8[i/4];
break;
case MSG_SSID_9:
+ if (ssid_range > sizeof(msg_bld_masks_9)) {
+ pr_warning("diag: truncating ssid range for ssid 9");
+ ssid_range = sizeof(msg_bld_masks_9);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_9[i/4];
break;
case MSG_SSID_10:
+ if (ssid_range > sizeof(msg_bld_masks_10)) {
+ pr_warning("diag: truncating ssid range for ssid 10");
+ ssid_range = sizeof(msg_bld_masks_10);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_10[i/4];
break;
case MSG_SSID_11:
+ if (ssid_range > sizeof(msg_bld_masks_11)) {
+ pr_warning("diag: truncating ssid range for ssid 11");
+ ssid_range = sizeof(msg_bld_masks_11);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_11[i/4];
break;
case MSG_SSID_12:
+ if (ssid_range > sizeof(msg_bld_masks_12)) {
+ pr_warning("diag: truncating ssid range for ssid 12");
+ ssid_range = sizeof(msg_bld_masks_12);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_12[i/4];
break;
case MSG_SSID_13:
+ if (ssid_range > sizeof(msg_bld_masks_13)) {
+ pr_warning("diag: truncating ssid range for ssid 13");
+ ssid_range = sizeof(msg_bld_masks_13);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_13[i/4];
break;
case MSG_SSID_14:
+ if (ssid_range > sizeof(msg_bld_masks_14)) {
+ pr_warning("diag: truncating ssid range for ssid 14");
+ ssid_range = sizeof(msg_bld_masks_14);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_14[i/4];
break;
case MSG_SSID_15:
+ if (ssid_range > sizeof(msg_bld_masks_15)) {
+ pr_warning("diag: truncating ssid range for ssid 15");
+ ssid_range = sizeof(msg_bld_masks_15);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_15[i/4];
break;
case MSG_SSID_16:
+ if (ssid_range > sizeof(msg_bld_masks_16)) {
+ pr_warning("diag: truncating ssid range for ssid 16");
+ ssid_range = sizeof(msg_bld_masks_16);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_16[i/4];
break;
case MSG_SSID_17:
+ if (ssid_range > sizeof(msg_bld_masks_17)) {
+ pr_warning("diag: truncating ssid range for ssid 17");
+ ssid_range = sizeof(msg_bld_masks_17);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_17[i/4];
break;
case MSG_SSID_18:
+ if (ssid_range > sizeof(msg_bld_masks_18)) {
+ pr_warning("diag: truncating ssid range for ssid 18");
+ ssid_range = sizeof(msg_bld_masks_18);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_18[i/4];
break;
case MSG_SSID_19:
+ if (ssid_range > sizeof(msg_bld_masks_19)) {
+ pr_warning("diag: truncating ssid range for ssid 19");
+ ssid_range = sizeof(msg_bld_masks_19);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_19[i/4];
break;
case MSG_SSID_20:
+ if (ssid_range > sizeof(msg_bld_masks_20)) {
+ pr_warning("diag: truncating ssid range for ssid 20");
+ ssid_range = sizeof(msg_bld_masks_20);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_20[i/4];
break;
case MSG_SSID_21:
+ if (ssid_range > sizeof(msg_bld_masks_21)) {
+ pr_warning("diag: truncating ssid range for ssid 21");
+ ssid_range = sizeof(msg_bld_masks_21);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_21[i/4];
break;
case MSG_SSID_22:
+ if (ssid_range > sizeof(msg_bld_masks_22)) {
+ pr_warning("diag: truncating ssid range for ssid 22");
+ ssid_range = sizeof(msg_bld_masks_22);
+ }
for (i = 0; i < ssid_range; i += 4)
*(int *)(ptr + i) = msg_bld_masks_22[i/4];
break;
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index e946b42..9a43ea4 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -181,8 +181,7 @@
pr_err("ion_import_dma_buf() failed\n");
return PTR_ERR(*pihdl);
}
- pr_debug("%s(): ion_hdl %p, ion_fd %d\n", __func__, *pihdl,
- ion_share_dma_buf(msm_rotator_dev->client, *pihdl));
+ pr_debug("%s(): ion_hdl %p, ion_fd %d\n", __func__, *pihdl, mem_id);
if (rot_iommu_split_domain) {
if (secure) {
diff --git a/drivers/crypto/msm/qce.c b/drivers/crypto/msm/qce.c
index 24cf30a..7778477 100644
--- a/drivers/crypto/msm/qce.c
+++ b/drivers/crypto/msm/qce.c
@@ -2203,6 +2203,18 @@
}
EXPORT_SYMBOL(qce_process_sha_req);
+int qce_enable_clk(void *handle)
+{
+ return 0;
+}
+EXPORT_SYMBOL(qce_enable_clk);
+
+int qce_disable_clk(void *handle)
+{
+ return 0;
+}
+EXPORT_SYMBOL(qce_disable_clk);
+
/*
* crypto engine open function.
*/
diff --git a/drivers/crypto/msm/qce.h b/drivers/crypto/msm/qce.h
index 3ff84cf..51a74b6 100644
--- a/drivers/crypto/msm/qce.h
+++ b/drivers/crypto/msm/qce.h
@@ -160,5 +160,7 @@
int qce_ablk_cipher_req(void *handle, struct qce_req *req);
int qce_hw_support(void *handle, struct ce_hw_support *support);
int qce_process_sha_req(void *handle, struct qce_sha_req *s_req);
+int qce_enable_clk(void *handle);
+int qce_disable_clk(void *handle);
#endif /* __CRYPTO_MSM_QCE_H */
diff --git a/drivers/crypto/msm/qce40.c b/drivers/crypto/msm/qce40.c
index 7b0964d..5249917 100644
--- a/drivers/crypto/msm/qce40.c
+++ b/drivers/crypto/msm/qce40.c
@@ -2426,6 +2426,18 @@
}
EXPORT_SYMBOL(qce_process_sha_req);
+int qce_enable_clk(void *handle)
+{
+ return 0;
+}
+EXPORT_SYMBOL(qce_enable_clk);
+
+int qce_disable_clk(void *handle)
+{
+ return 0;
+}
+EXPORT_SYMBOL(qce_disable_clk);
+
/* crypto engine open function. */
void *qce_open(struct platform_device *pdev, int *rc)
{
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index 739a753..2b1ad80 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -39,7 +39,7 @@
#include "qcryptohw_50.h"
#define CRYPTO_CONFIG_RESET 0xE001F
-#define QCE_MAX_NUM_DSCR 0x400
+#define QCE_MAX_NUM_DSCR 0x500
#define QCE_SECTOR_SIZE 0x200
static DEFINE_MUTEX(bam_register_cnt);
@@ -919,17 +919,23 @@
iovec->flags |= flag;
}
-static void _qce_sps_add_data(uint32_t addr, uint32_t len,
+static int _qce_sps_add_data(uint32_t addr, uint32_t len,
struct sps_transfer *sps_bam_pipe)
{
struct sps_iovec *iovec = sps_bam_pipe->iovec +
sps_bam_pipe->iovec_count;
+ if (sps_bam_pipe->iovec_count == QCE_MAX_NUM_DSCR) {
+ pr_err("Num of descrptor %d exceed max (%d)",
+ sps_bam_pipe->iovec_count, (uint32_t)QCE_MAX_NUM_DSCR);
+ return -ENOMEM;
+ }
if (len) {
iovec->size = len;
iovec->addr = addr;
iovec->flags = 0;
sps_bam_pipe->iovec_count++;
}
+ return 0;
}
static int _qce_sps_add_sg_data(struct qce_device *pce_dev,
@@ -947,6 +953,12 @@
if (pce_dev->ce_sps.minor_version == 0)
len = ALIGN(len, pce_dev->ce_sps.ce_burst_size);
while (len > 0) {
+ if (sps_bam_pipe->iovec_count == QCE_MAX_NUM_DSCR) {
+ pr_err("Num of descrptor %d exceed max (%d)",
+ sps_bam_pipe->iovec_count,
+ (uint32_t)QCE_MAX_NUM_DSCR);
+ return -ENOMEM;
+ }
if (len > SPS_MAX_PKT_SIZE) {
data_cnt = SPS_MAX_PKT_SIZE;
iovec->size = data_cnt;
@@ -2375,15 +2387,17 @@
&pce_dev->ce_sps.in_transfer);
if (pce_dev->ce_sps.minor_version == 0) {
- _qce_sps_add_sg_data(pce_dev, areq->src, totallen_in,
- &pce_dev->ce_sps.in_transfer);
+ if (_qce_sps_add_sg_data(pce_dev, areq->src, totallen_in,
+ &pce_dev->ce_sps.in_transfer))
+ goto bad;
_qce_set_flag(&pce_dev->ce_sps.in_transfer,
SPS_IOVEC_FLAG_EOT|SPS_IOVEC_FLAG_NWD);
- _qce_sps_add_sg_data(pce_dev, areq->dst, out_len +
+ if (_qce_sps_add_sg_data(pce_dev, areq->dst, out_len +
areq->assoclen + hw_pad_out,
- &pce_dev->ce_sps.out_transfer);
+ &pce_dev->ce_sps.out_transfer))
+ goto bad;
if (totallen_in > SPS_MAX_PKT_SIZE) {
_qce_set_flag(&pce_dev->ce_sps.out_transfer,
SPS_IOVEC_FLAG_INT);
@@ -2391,42 +2405,52 @@
SPS_O_DESC_DONE;
pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_IDLE;
} else {
- _qce_sps_add_data(GET_PHYS_ADDR(
+ if (_qce_sps_add_data(GET_PHYS_ADDR(
pce_dev->ce_sps.result_dump),
CRYPTO_RESULT_DUMP_SIZE,
- &pce_dev->ce_sps.out_transfer);
+ &pce_dev->ce_sps.out_transfer))
+ goto bad;
_qce_set_flag(&pce_dev->ce_sps.out_transfer,
SPS_IOVEC_FLAG_INT);
pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_COMP;
}
} else {
- _qce_sps_add_sg_data(pce_dev, areq->assoc, areq->assoclen,
- &pce_dev->ce_sps.in_transfer);
- _qce_sps_add_data((uint32_t)pce_dev->phy_iv_in, ivsize,
- &pce_dev->ce_sps.in_transfer);
- _qce_sps_add_sg_data(pce_dev, areq->src, areq->cryptlen,
- &pce_dev->ce_sps.in_transfer);
+ if (_qce_sps_add_sg_data(pce_dev, areq->assoc, areq->assoclen,
+ &pce_dev->ce_sps.in_transfer))
+ goto bad;
+ if (_qce_sps_add_data((uint32_t)pce_dev->phy_iv_in, ivsize,
+ &pce_dev->ce_sps.in_transfer))
+ goto bad;
+ if (_qce_sps_add_sg_data(pce_dev, areq->src, areq->cryptlen,
+ &pce_dev->ce_sps.in_transfer))
+ goto bad;
_qce_set_flag(&pce_dev->ce_sps.in_transfer,
SPS_IOVEC_FLAG_EOT|SPS_IOVEC_FLAG_NWD);
/* Pass through to ignore associated (+iv, if applicable) data*/
- _qce_sps_add_data(GET_PHYS_ADDR(pce_dev->ce_sps.ignore_buffer),
+ if (_qce_sps_add_data(
+ GET_PHYS_ADDR(pce_dev->ce_sps.ignore_buffer),
(ivsize + areq->assoclen),
- &pce_dev->ce_sps.out_transfer);
- _qce_sps_add_sg_data(pce_dev, areq->dst, out_len,
- &pce_dev->ce_sps.out_transfer);
+ &pce_dev->ce_sps.out_transfer))
+ goto bad;
+ if (_qce_sps_add_sg_data(pce_dev, areq->dst, out_len,
+ &pce_dev->ce_sps.out_transfer))
+ goto bad;
/* Pass through to ignore hw_pad (padding of the MAC data) */
- _qce_sps_add_data(GET_PHYS_ADDR(pce_dev->ce_sps.ignore_buffer),
- hw_pad_out, &pce_dev->ce_sps.out_transfer);
+ if (_qce_sps_add_data(
+ GET_PHYS_ADDR(pce_dev->ce_sps.ignore_buffer),
+ hw_pad_out, &pce_dev->ce_sps.out_transfer))
+ goto bad;
if (totallen_in > SPS_MAX_PKT_SIZE) {
_qce_set_flag(&pce_dev->ce_sps.out_transfer,
SPS_IOVEC_FLAG_INT);
pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_IDLE;
} else {
- _qce_sps_add_data(
+ if (_qce_sps_add_data(
GET_PHYS_ADDR(pce_dev->ce_sps.result_dump),
CRYPTO_RESULT_DUMP_SIZE,
- &pce_dev->ce_sps.out_transfer);
+ &pce_dev->ce_sps.out_transfer))
+ goto bad;
_qce_set_flag(&pce_dev->ce_sps.out_transfer,
SPS_IOVEC_FLAG_INT);
pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_COMP;
@@ -2530,22 +2554,26 @@
_qce_sps_add_cmd(pce_dev, SPS_IOVEC_FLAG_LOCK, cmdlistinfo,
&pce_dev->ce_sps.in_transfer);
- _qce_sps_add_sg_data(pce_dev, areq->src, areq->nbytes,
- &pce_dev->ce_sps.in_transfer);
+ if (_qce_sps_add_sg_data(pce_dev, areq->src, areq->nbytes,
+ &pce_dev->ce_sps.in_transfer))
+ goto bad;
_qce_set_flag(&pce_dev->ce_sps.in_transfer,
SPS_IOVEC_FLAG_EOT|SPS_IOVEC_FLAG_NWD);
- _qce_sps_add_sg_data(pce_dev, areq->dst, areq->nbytes,
- &pce_dev->ce_sps.out_transfer);
+ if (_qce_sps_add_sg_data(pce_dev, areq->dst, areq->nbytes,
+ &pce_dev->ce_sps.out_transfer))
+ goto bad;
if (areq->nbytes > SPS_MAX_PKT_SIZE) {
_qce_set_flag(&pce_dev->ce_sps.out_transfer,
SPS_IOVEC_FLAG_INT);
pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_IDLE;
} else {
pce_dev->ce_sps.producer_state = QCE_PIPE_STATE_COMP;
- _qce_sps_add_data(GET_PHYS_ADDR(pce_dev->ce_sps.result_dump),
- CRYPTO_RESULT_DUMP_SIZE,
- &pce_dev->ce_sps.out_transfer);
+ if (_qce_sps_add_data(
+ GET_PHYS_ADDR(pce_dev->ce_sps.result_dump),
+ CRYPTO_RESULT_DUMP_SIZE,
+ &pce_dev->ce_sps.out_transfer))
+ goto bad;
_qce_set_flag(&pce_dev->ce_sps.out_transfer,
SPS_IOVEC_FLAG_INT);
}
@@ -2613,14 +2641,16 @@
_qce_sps_add_cmd(pce_dev, SPS_IOVEC_FLAG_LOCK, cmdlistinfo,
&pce_dev->ce_sps.in_transfer);
- _qce_sps_add_sg_data(pce_dev, areq->src, areq->nbytes,
- &pce_dev->ce_sps.in_transfer);
+ if (_qce_sps_add_sg_data(pce_dev, areq->src, areq->nbytes,
+ &pce_dev->ce_sps.in_transfer))
+ goto bad;
_qce_set_flag(&pce_dev->ce_sps.in_transfer,
SPS_IOVEC_FLAG_EOT|SPS_IOVEC_FLAG_NWD);
- _qce_sps_add_data(GET_PHYS_ADDR(pce_dev->ce_sps.result_dump),
+ if (_qce_sps_add_data(GET_PHYS_ADDR(pce_dev->ce_sps.result_dump),
CRYPTO_RESULT_DUMP_SIZE,
- &pce_dev->ce_sps.out_transfer);
+ &pce_dev->ce_sps.out_transfer))
+ goto bad;
_qce_set_flag(&pce_dev->ce_sps.out_transfer, SPS_IOVEC_FLAG_INT);
rc = _qce_sps_transfer(pce_dev);
if (rc)
@@ -2800,7 +2830,7 @@
}
}
-static int __qce_enable_clk(void *handle)
+int qce_enable_clk(void *handle)
{
struct qce_device *pce_dev = (struct qce_device *) handle;
int rc = 0;
@@ -2813,6 +2843,7 @@
return rc;
}
}
+
/* Enable CE clk */
if (pce_dev->ce_clk != NULL) {
rc = clk_prepare_enable(pce_dev->ce_clk);
@@ -2834,8 +2865,9 @@
}
return rc;
}
+EXPORT_SYMBOL(qce_enable_clk);
-static int __qce_disable_clk(void *handle)
+int qce_disable_clk(void *handle)
{
struct qce_device *pce_dev = (struct qce_device *) handle;
int rc = 0;
@@ -2849,6 +2881,7 @@
return rc;
}
+EXPORT_SYMBOL(qce_disable_clk);
/* crypto engine open function. */
void *qce_open(struct platform_device *pdev, int *rc)
@@ -2886,19 +2919,20 @@
if (*rc)
goto err_mem;
- *rc = __qce_enable_clk(pce_dev);
+ *rc = qce_enable_clk(pce_dev);
if (*rc)
goto err;
if (_probe_ce_engine(pce_dev)) {
*rc = -ENXIO;
- __qce_disable_clk(pce_dev);
goto err;
}
*rc = 0;
qce_setup_ce_sps_data(pce_dev);
qce_sps_init(pce_dev);
+ qce_disable_clk(pce_dev);
+
return pce_dev;
err:
__qce_deinit_clk(pce_dev);
@@ -2932,7 +2966,7 @@
dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
pce_dev->coh_vmem, pce_dev->coh_pmem);
- __qce_disable_clk(pce_dev);
+ qce_disable_clk(pce_dev);
__qce_deinit_clk(pce_dev);
qce_sps_exit(pce_dev);
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index 8cc42df..e91dcaa 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -98,7 +98,7 @@
};
static DEFINE_MUTEX(send_cmd_lock);
-static DEFINE_MUTEX(sent_bw_req);
+static DEFINE_MUTEX(qcedev_sent_bw_req);
/**********************************************************************
* Register ourselves as a misc device to be able to access the dev driver
* from userspace. */
@@ -177,25 +177,51 @@
{
int ret = 0;
- mutex_lock(&sent_bw_req);
+ mutex_lock(&qcedev_sent_bw_req);
if (high_bw_req) {
- if (podev->high_bw_req_count == 0)
+ if (podev->high_bw_req_count == 0) {
+ ret = qce_enable_clk(podev->qce);
+ if (ret) {
+ pr_err("%s Unable enable clk\n", __func__);
+ mutex_unlock(&qcedev_sent_bw_req);
+ return;
+ }
ret = msm_bus_scale_client_update_request(
podev->bus_scale_handle, 1);
- if (ret)
- pr_err("%s Unable to set to high bandwidth\n",
+ if (ret) {
+ pr_err("%s Unable to set to high bandwidth\n",
__func__);
+ ret = qce_disable_clk(podev->qce);
+ mutex_unlock(&qcedev_sent_bw_req);
+ return;
+ }
+ }
podev->high_bw_req_count++;
} else {
- if (podev->high_bw_req_count == 1)
+ if (podev->high_bw_req_count == 1) {
ret = msm_bus_scale_client_update_request(
podev->bus_scale_handle, 0);
- if (ret)
- pr_err("%s Unable to set to low bandwidth\n",
+ if (ret) {
+ pr_err("%s Unable to set to low bandwidth\n",
__func__);
+ mutex_unlock(&qcedev_sent_bw_req);
+ return;
+ }
+ ret = qce_disable_clk(podev->qce);
+ if (ret) {
+ pr_err("%s Unable disable clk\n", __func__);
+ ret = msm_bus_scale_client_update_request(
+ podev->bus_scale_handle, 1);
+ if (ret)
+ pr_err("%s Unable to set to high bandwidth\n",
+ __func__);
+ mutex_unlock(&qcedev_sent_bw_req);
+ return;
+ }
+ }
podev->high_bw_req_count--;
}
- mutex_unlock(&sent_bw_req);
+ mutex_unlock(&qcedev_sent_bw_req);
}
@@ -1854,6 +1880,14 @@
podev->platform_support.hw_key_support = 0;
podev->platform_support.bus_scale_table = NULL;
podev->platform_support.sha_hmac = 1;
+
+ if (podev->ce_support.is_shared == false) {
+ podev->platform_support.bus_scale_table =
+ (struct msm_bus_scale_pdata *)
+ msm_bus_cl_get_pdata(pdev);
+ if (!podev->platform_support.bus_scale_table)
+ pr_err("bus_scale_table is NULL\n");
+ }
} else {
platform_support =
(struct msm_ce_hw_support *)pdev->dev.platform_data;
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index 85c25c7..40fb29ac 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -121,7 +121,7 @@
#define NUM_RETRY 1000
#define CE_BUSY 55
-static DEFINE_MUTEX(sent_bw_req);
+static DEFINE_MUTEX(qcrypto_sent_bw_req);
static int qcrypto_scm_cmd(int resource, int cmd, int *response)
{
@@ -346,25 +346,51 @@
{
int ret = 0;
- mutex_lock(&sent_bw_req);
+ mutex_lock(&qcrypto_sent_bw_req);
if (high_bw_req) {
- if (cp->high_bw_req_count == 0)
+ if (cp->high_bw_req_count == 0) {
+ ret = qce_enable_clk(cp->qce);
+ if (ret) {
+ pr_err("%s Unable enable clk\n", __func__);
+ mutex_unlock(&qcrypto_sent_bw_req);
+ return;
+ }
ret = msm_bus_scale_client_update_request(
- cp->bus_scale_handle, 1);
- if (ret)
- pr_err("%s Unable to set to high bandwidth\n",
+ cp->bus_scale_handle, 1);
+ if (ret) {
+ pr_err("%s Unable to set to high bandwidth\n",
__func__);
+ qce_disable_clk(cp->qce);
+ mutex_unlock(&qcrypto_sent_bw_req);
+ return;
+ }
+ }
cp->high_bw_req_count++;
} else {
- if (cp->high_bw_req_count == 1)
+ if (cp->high_bw_req_count == 1) {
ret = msm_bus_scale_client_update_request(
- cp->bus_scale_handle, 0);
- if (ret)
- pr_err("%s Unable to set to low bandwidth\n",
+ cp->bus_scale_handle, 0);
+ if (ret) {
+ pr_err("%s Unable to set to low bandwidth\n",
__func__);
+ mutex_unlock(&qcrypto_sent_bw_req);
+ return;
+ }
+ ret = qce_disable_clk(cp->qce);
+ if (ret) {
+ pr_err("%s Unable disable clk\n", __func__);
+ ret = msm_bus_scale_client_update_request(
+ cp->bus_scale_handle, 1);
+ if (ret)
+ pr_err("%s Unable to set to high bandwidth\n",
+ __func__);
+ mutex_unlock(&qcrypto_sent_bw_req);
+ return;
+ }
+ }
cp->high_bw_req_count--;
}
- mutex_unlock(&sent_bw_req);
+ mutex_unlock(&qcrypto_sent_bw_req);
}
static int _start_qcrypto_process(struct crypto_priv *cp);
@@ -3336,6 +3362,14 @@
cp->platform_support.hw_key_support = 0;
cp->platform_support.bus_scale_table = NULL;
cp->platform_support.sha_hmac = 1;
+
+ if (cp->ce_support.is_shared == false) {
+ cp->platform_support.bus_scale_table =
+ (struct msm_bus_scale_pdata *)
+ msm_bus_cl_get_pdata(pdev);
+ if (!cp->platform_support.bus_scale_table)
+ pr_warn("bus_scale_table is NULL\n");
+ }
} else {
platform_support =
(struct msm_ce_hw_support *)pdev->dev.platform_data;
diff --git a/drivers/gpu/ion/Makefile b/drivers/gpu/ion/Makefile
index f4f9a92..d7ff73a 100644
--- a/drivers/gpu/ion/Makefile
+++ b/drivers/gpu/ion/Makefile
@@ -1,4 +1,6 @@
-obj-$(CONFIG_ION) += ion.o ion_heap.o ion_system_heap.o ion_carveout_heap.o ion_iommu_heap.o ion_cp_heap.o ion_removed_heap.o
+obj-$(CONFIG_ION) += ion.o ion_heap.o ion_system_heap.o ion_carveout_heap.o \
+ ion_iommu_heap.o ion_cp_heap.o ion_removed_heap.o \
+ ion_page_pool.o ion_chunk_heap.o
obj-$(CONFIG_CMA) += ion_cma_heap.o ion_cma_secure_heap.o
obj-$(CONFIG_ION_TEGRA) += tegra/
obj-$(CONFIG_ION_MSM) += msm/
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index a01ef3f..4282f02 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -1,4 +1,5 @@
/*
+
* drivers/gpu/ion/ion.c
*
* Copyright (C) 2011 Google, Inc.
@@ -18,15 +19,18 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/file.h>
+#include <linux/freezer.h>
#include <linux/fs.h>
#include <linux/anon_inodes.h>
#include <linux/ion.h>
+#include <linux/kthread.h>
#include <linux/list.h>
#include <linux/memblock.h>
#include <linux/miscdevice.h>
#include <linux/mm.h>
#include <linux/mm_types.h>
#include <linux/rbtree.h>
+#include <linux/rtmutex.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
@@ -43,16 +47,18 @@
/**
* struct ion_device - the metadata of the ion device node
* @dev: the actual misc device
- * @buffers: an rb tree of all the existing buffers
- * @lock: lock protecting the buffers & heaps trees
+ * @buffers: an rb tree of all the existing buffers
+ * @buffer_lock: lock protecting the tree of buffers
+ * @lock: rwsem protecting the tree of heaps and clients
* @heaps: list of all the heaps in the system
* @user_clients: list of all the clients created from userspace
*/
struct ion_device {
struct miscdevice dev;
struct rb_root buffers;
- struct mutex lock;
- struct rb_root heaps;
+ struct mutex buffer_lock;
+ struct rw_semaphore lock;
+ struct plist_head heaps;
long (*custom_ioctl) (struct ion_client *client, unsigned int cmd,
unsigned long arg);
struct rb_root clients;
@@ -65,7 +71,6 @@
* @dev: backpointer to ion device
* @handles: an rb tree of all the handles in this client
* @lock: lock protecting the tree of handles
- * @heap_mask: mask of all supported heaps
* @name: used for debugging
* @task: used for debugging
*
@@ -78,7 +83,7 @@
struct ion_device *dev;
struct rb_root handles;
struct mutex lock;
- unsigned int heap_mask;
+ unsigned int heap_type_mask;
char *name;
struct task_struct *task;
pid_t pid;
@@ -112,6 +117,11 @@
!(buffer->flags & ION_FLAG_CACHED_NEEDS_SYNC));
}
+bool ion_buffer_cached(struct ion_buffer *buffer)
+{
+ return !!(buffer->flags & ION_FLAG_CACHED);
+}
+
/* this function should only be called while dev->lock is held */
static void ion_buffer_add(struct ion_device *dev,
struct ion_buffer *buffer)
@@ -140,6 +150,7 @@
static int ion_buffer_alloc_dirty(struct ion_buffer *buffer);
+static bool ion_heap_drain_freelist(struct ion_heap *heap);
/* this function should only be called while dev->lock is held */
static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
struct ion_device *dev,
@@ -161,9 +172,16 @@
kref_init(&buffer->ref);
ret = heap->ops->allocate(heap, buffer, len, align, flags);
+
if (ret) {
- kfree(buffer);
- return ERR_PTR(ret);
+ if (!(heap->flags & ION_HEAP_FLAG_DEFER_FREE))
+ goto err2;
+
+ ion_heap_drain_freelist(heap);
+ ret = heap->ops->allocate(heap, buffer, len, align,
+ flags);
+ if (ret)
+ goto err2;
}
buffer->dev = dev;
@@ -208,12 +226,15 @@
if (sg_dma_address(sg) == 0)
sg_dma_address(sg) = sg_phys(sg);
}
+ mutex_lock(&dev->buffer_lock);
ion_buffer_add(dev, buffer);
+ mutex_unlock(&dev->buffer_lock);
return buffer;
err:
heap->ops->unmap_dma(heap, buffer);
heap->ops->free(buffer);
+err2:
kfree(buffer);
return ERR_PTR(ret);
}
@@ -224,25 +245,39 @@
buffer->heap->ops->unsecure_buffer(buffer, 1);
}
-static void ion_buffer_destroy(struct kref *kref)
+static void _ion_buffer_destroy(struct ion_buffer *buffer)
{
- struct ion_buffer *buffer = container_of(kref, struct ion_buffer, ref);
- struct ion_device *dev = buffer->dev;
-
if (WARN_ON(buffer->kmap_cnt > 0))
buffer->heap->ops->unmap_kernel(buffer->heap, buffer);
buffer->heap->ops->unmap_dma(buffer->heap, buffer);
ion_delayed_unsecure(buffer);
buffer->heap->ops->free(buffer);
- mutex_lock(&dev->lock);
- rb_erase(&buffer->node, &dev->buffers);
- mutex_unlock(&dev->lock);
if (buffer->flags & ION_FLAG_CACHED)
kfree(buffer->dirty);
kfree(buffer);
}
+static void ion_buffer_destroy(struct kref *kref)
+{
+ struct ion_buffer *buffer = container_of(kref, struct ion_buffer, ref);
+ struct ion_heap *heap = buffer->heap;
+ struct ion_device *dev = buffer->dev;
+
+ mutex_lock(&dev->buffer_lock);
+ rb_erase(&buffer->node, &dev->buffers);
+ mutex_unlock(&dev->buffer_lock);
+
+ if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) {
+ rt_mutex_lock(&heap->lock);
+ list_add(&buffer->list, &heap->free_list);
+ rt_mutex_unlock(&heap->lock);
+ wake_up(&heap->waitqueue);
+ return;
+ }
+ _ion_buffer_destroy(buffer);
+}
+
static void ion_buffer_get(struct ion_buffer *buffer)
{
kref_get(&buffer->ref);
@@ -253,6 +288,37 @@
return kref_put(&buffer->ref, ion_buffer_destroy);
}
+static void ion_buffer_add_to_handle(struct ion_buffer *buffer)
+{
+ mutex_lock(&buffer->lock);
+ buffer->handle_count++;
+ mutex_unlock(&buffer->lock);
+}
+
+static void ion_buffer_remove_from_handle(struct ion_buffer *buffer)
+{
+ /*
+ * when a buffer is removed from a handle, if it is not in
+ * any other handles, copy the taskcomm and the pid of the
+ * process it's being removed from into the buffer. At this
+ * point there will be no way to track what processes this buffer is
+ * being used by, it only exists as a dma_buf file descriptor.
+ * The taskcomm and pid can provide a debug hint as to where this fd
+ * is in the system
+ */
+ mutex_lock(&buffer->lock);
+ buffer->handle_count--;
+ BUG_ON(buffer->handle_count < 0);
+ if (!buffer->handle_count) {
+ struct task_struct *task;
+
+ task = current->group_leader;
+ get_task_comm(buffer->task_comm, task);
+ buffer->pid = task_pid_nr(task);
+ }
+ mutex_unlock(&buffer->lock);
+}
+
static struct ion_handle *ion_handle_create(struct ion_client *client,
struct ion_buffer *buffer)
{
@@ -265,6 +331,7 @@
rb_init_node(&handle->node);
handle->client = client;
ion_buffer_get(buffer);
+ ion_buffer_add_to_handle(buffer);
handle->buffer = buffer;
return handle;
@@ -286,7 +353,9 @@
if (!RB_EMPTY_NODE(&handle->node))
rb_erase(&handle->node, &client->handles);
+ ion_buffer_remove_from_handle(buffer);
ion_buffer_put(buffer);
+
kfree(handle);
}
@@ -359,13 +428,13 @@
}
struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
- size_t align, unsigned int heap_mask,
+ size_t align, unsigned int heap_id_mask,
unsigned int flags)
{
- struct rb_node *n;
struct ion_handle *handle;
struct ion_device *dev = client->dev;
struct ion_buffer *buffer = NULL;
+ struct ion_heap *heap;
unsigned long secure_allocation = flags & ION_FLAG_SECURE;
const unsigned int MAX_DBG_STR_LEN = 64;
char dbg_str[MAX_DBG_STR_LEN];
@@ -381,8 +450,8 @@
*/
flags |= ION_FLAG_CACHED_NEEDS_SYNC;
- pr_debug("%s: len %d align %d heap_mask %u flags %x\n", __func__, len,
- align, heap_mask, flags);
+ pr_debug("%s: len %d align %d heap_id_mask %u flags %x\n", __func__,
+ len, align, heap_id_mask, flags);
/*
* traverse the list of heaps available in this system in priority
* order. If the heap type is supported by the client, and matches the
@@ -394,29 +463,26 @@
len = PAGE_ALIGN(len);
- mutex_lock(&dev->lock);
- for (n = rb_first(&dev->heaps); n != NULL; n = rb_next(n)) {
- struct ion_heap *heap = rb_entry(n, struct ion_heap, node);
- /* if the client doesn't support this heap type */
- if (!((1 << heap->type) & client->heap_mask))
- continue;
- /* if the caller didn't specify this heap type */
- if (!((1 << heap->id) & heap_mask))
+ down_read(&dev->lock);
+ plist_for_each_entry(heap, &dev->heaps, node) {
+ /* if the caller didn't specify this heap id */
+ if (!((1 << heap->id) & heap_id_mask))
continue;
/* Do not allow un-secure heap if secure is specified */
if (secure_allocation &&
!ion_heap_allow_secure_allocation(heap->type))
continue;
trace_ion_alloc_buffer_start(client->name, heap->name, len,
- heap_mask, flags);
+ heap_id_mask, flags);
buffer = ion_buffer_create(heap, dev, len, align, flags);
trace_ion_alloc_buffer_end(client->name, heap->name, len,
- heap_mask, flags);
+ heap_id_mask, flags);
if (!IS_ERR_OR_NULL(buffer))
break;
trace_ion_alloc_buffer_fallback(client->name, heap->name, len,
- heap_mask, flags, PTR_ERR(buffer));
+ heap_id_mask, flags,
+ PTR_ERR(buffer));
if (dbg_str_idx < MAX_DBG_STR_LEN) {
unsigned int len_left = MAX_DBG_STR_LEN-dbg_str_idx-1;
int ret_value = snprintf(&dbg_str[dbg_str_idx],
@@ -433,21 +499,21 @@
}
}
}
- mutex_unlock(&dev->lock);
+ up_read(&dev->lock);
if (buffer == NULL) {
trace_ion_alloc_buffer_fail(client->name, dbg_str, len,
- heap_mask, flags, -ENODEV);
+ heap_id_mask, flags, -ENODEV);
return ERR_PTR(-ENODEV);
}
if (IS_ERR(buffer)) {
trace_ion_alloc_buffer_fail(client->name, dbg_str, len,
- heap_mask, flags, PTR_ERR(buffer));
+ heap_id_mask, flags,
+ PTR_ERR(buffer));
pr_debug("ION is unable to allocate 0x%x bytes (alignment: "
- "0x%x) from heap(s) %sfor client %s with heap "
- "mask 0x%x\n",
- len, align, dbg_str, client->name, client->heap_mask);
+ "0x%x) from heap(s) %sfor client %s\n",
+ len, align, dbg_str, client->name);
return ERR_PTR(PTR_ERR(buffer));
}
@@ -620,6 +686,7 @@
for (n = rb_first(&client->handles); n; n = rb_next(n)) {
struct ion_handle *handle = rb_entry(n, struct ion_handle,
node);
+
enum ion_heap_type type = handle->buffer->heap->type;
seq_printf(s, "%16.16s: %16x : %16d : %12p",
@@ -638,7 +705,6 @@
seq_printf(s, "\n");
}
mutex_unlock(&client->lock);
-
return 0;
}
@@ -655,7 +721,6 @@
};
struct ion_client *ion_client_create(struct ion_device *dev,
- unsigned int heap_mask,
const char *name)
{
struct ion_client *client;
@@ -705,11 +770,10 @@
strlcpy(client->name, name, name_len+1);
}
- client->heap_mask = heap_mask;
client->task = task;
client->pid = pid;
- mutex_lock(&dev->lock);
+ down_write(&dev->lock);
p = &dev->clients.rb_node;
while (*p) {
parent = *p;
@@ -727,96 +791,16 @@
client->debug_root = debugfs_create_file(name, 0664,
dev->debug_root, client,
&debug_client_fops);
- mutex_unlock(&dev->lock);
+ up_write(&dev->lock);
return client;
}
-
-/**
- * ion_mark_dangling_buffers_locked() - Mark dangling buffers
- * @dev: the ion device whose buffers will be searched
- *
- * Sets marked=1 for all known buffers associated with `dev' that no
- * longer have a handle pointing to them. dev->lock should be held
- * across a call to this function (and should only be unlocked after
- * checking for marked buffers).
- */
-static void ion_mark_dangling_buffers_locked(struct ion_device *dev)
-{
- struct rb_node *n, *n2;
- /* mark all buffers as 1 */
- for (n = rb_first(&dev->buffers); n; n = rb_next(n)) {
- struct ion_buffer *buf = rb_entry(n, struct ion_buffer,
- node);
-
- buf->marked = 1;
- }
-
- /* now see which buffers we can access */
- for (n = rb_first(&dev->clients); n; n = rb_next(n)) {
- struct ion_client *client = rb_entry(n, struct ion_client,
- node);
-
- mutex_lock(&client->lock);
- for (n2 = rb_first(&client->handles); n2; n2 = rb_next(n2)) {
- struct ion_handle *handle
- = rb_entry(n2, struct ion_handle, node);
-
- handle->buffer->marked = 0;
-
- }
- mutex_unlock(&client->lock);
-
- }
-}
-
-#ifdef CONFIG_ION_LEAK_CHECK
-static u32 ion_debug_check_leaks_on_destroy;
-
-static int ion_check_for_and_print_leaks(struct ion_device *dev)
-{
- struct rb_node *n;
- int num_leaks = 0;
-
- if (!ion_debug_check_leaks_on_destroy)
- return 0;
-
- /* check for leaked buffers (those that no longer have a
- * handle pointing to them) */
- ion_mark_dangling_buffers_locked(dev);
-
- /* Anyone still marked as a 1 means a leaked handle somewhere */
- for (n = rb_first(&dev->buffers); n; n = rb_next(n)) {
- struct ion_buffer *buf = rb_entry(n, struct ion_buffer,
- node);
-
- if (buf->marked == 1) {
- pr_info("Leaked ion buffer at %p\n", buf);
- num_leaks++;
- }
- }
- return num_leaks;
-}
-static void setup_ion_leak_check(struct dentry *debug_root)
-{
- debugfs_create_bool("check_leaks_on_destroy", 0664, debug_root,
- &ion_debug_check_leaks_on_destroy);
-}
-#else
-static int ion_check_for_and_print_leaks(struct ion_device *dev)
-{
- return 0;
-}
-static void setup_ion_leak_check(struct dentry *debug_root)
-{
-}
-#endif
+EXPORT_SYMBOL(ion_client_create);
void ion_client_destroy(struct ion_client *client)
{
struct ion_device *dev = client->dev;
struct rb_node *n;
- int num_leaks;
pr_debug("%s: %d\n", __func__, __LINE__);
while ((n = rb_first(&client->handles))) {
@@ -824,25 +808,13 @@
node);
ion_handle_destroy(&handle->ref);
}
- mutex_lock(&dev->lock);
+ down_write(&dev->lock);
if (client->task)
put_task_struct(client->task);
rb_erase(&client->node, &dev->clients);
debugfs_remove_recursive(client->debug_root);
- num_leaks = ion_check_for_and_print_leaks(dev);
-
- mutex_unlock(&dev->lock);
-
- if (num_leaks) {
- struct task_struct *current_task = current;
- char current_task_name[TASK_COMM_LEN];
- get_task_comm(current_task_name, current_task);
- WARN(1, "%s: Detected %d leaked ion buffer%s.\n",
- __func__, num_leaks, num_leaks == 1 ? "" : "s");
- pr_info("task name at time of leak: %s, pid: %d\n",
- current_task_name, current_task->pid);
- }
+ up_write(&dev->lock);
kfree(client->name);
kfree(client);
@@ -1115,7 +1087,7 @@
static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset)
{
struct ion_buffer *buffer = dmabuf->priv;
- return buffer->vaddr + offset;
+ return buffer->vaddr + offset * PAGE_SIZE;
}
static void ion_dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long offset,
@@ -1171,19 +1143,19 @@
.kunmap = ion_dma_buf_kunmap,
};
-int ion_share_dma_buf(struct ion_client *client, struct ion_handle *handle)
+struct dma_buf *ion_share_dma_buf(struct ion_client *client,
+ struct ion_handle *handle)
{
struct ion_buffer *buffer;
struct dma_buf *dmabuf;
bool valid_handle;
- int fd;
mutex_lock(&client->lock);
valid_handle = ion_handle_validate(client, handle);
mutex_unlock(&client->lock);
if (!valid_handle) {
WARN(1, "%s: invalid handle passed to share.\n", __func__);
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
buffer = handle->buffer;
@@ -1191,15 +1163,29 @@
dmabuf = dma_buf_export(buffer, &dma_buf_ops, buffer->size, O_RDWR);
if (IS_ERR(dmabuf)) {
ion_buffer_put(buffer);
- return PTR_ERR(dmabuf);
+ return dmabuf;
}
+
+ return dmabuf;
+}
+EXPORT_SYMBOL(ion_share_dma_buf);
+
+int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle)
+{
+ struct dma_buf *dmabuf;
+ int fd;
+
+ dmabuf = ion_share_dma_buf(client, handle);
+ if (IS_ERR(dmabuf))
+ return PTR_ERR(dmabuf);
+
fd = dma_buf_fd(dmabuf, O_CLOEXEC);
if (fd < 0)
dma_buf_put(dmabuf);
return fd;
}
-EXPORT_SYMBOL(ion_share_dma_buf);
+EXPORT_SYMBOL(ion_share_dma_buf_fd);
struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd)
{
@@ -1308,7 +1294,8 @@
if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
return -EFAULT;
- data.fd = ion_share_dma_buf(client, data.handle);
+ data.fd = ion_share_dma_buf_fd(client, data.handle);
+
if (copy_to_user((void __user *)arg, &data, sizeof(data)))
return -EFAULT;
if (data.fd < 0)
@@ -1388,7 +1375,7 @@
pr_debug("%s: %d\n", __func__, __LINE__);
snprintf(debug_name, 64, "%u", task_pid_nr(current->group_leader));
- client = ion_client_create(dev, -1, debug_name);
+ client = ion_client_create(dev, debug_name);
if (IS_ERR_OR_NULL(client))
return PTR_ERR(client);
file->private_data = client;
@@ -1570,9 +1557,12 @@
struct ion_heap *heap = s->private;
struct ion_device *dev = heap->dev;
struct rb_node *n;
+ size_t total_size = 0;
+ size_t total_orphaned_size = 0;
- mutex_lock(&dev->lock);
+ mutex_lock(&dev->buffer_lock);
seq_printf(s, "%16.s %16.s %16.s\n", "client", "pid", "size");
+ seq_printf(s, "----------------------------------------------------\n");
for (n = rb_first(&dev->clients); n; n = rb_next(n)) {
struct ion_client *client = rb_entry(n, struct ion_client,
@@ -1591,8 +1581,28 @@
client->pid, size);
}
}
+ seq_printf(s, "----------------------------------------------------\n");
+ seq_printf(s, "orphaned allocations (info is from last known client):"
+ "\n");
+ for (n = rb_first(&dev->buffers); n; n = rb_next(n)) {
+ struct ion_buffer *buffer = rb_entry(n, struct ion_buffer,
+ node);
+ if (buffer->heap->type == heap->type)
+ total_size += buffer->size;
+ if (!buffer->handle_count) {
+ seq_printf(s, "%16.s %16u %16u\n", buffer->task_comm,
+ buffer->pid, buffer->size);
+ total_orphaned_size += buffer->size;
+ }
+ }
+ seq_printf(s, "----------------------------------------------------\n");
+ seq_printf(s, "%16.s %16u\n", "total orphaned",
+ total_orphaned_size);
+ seq_printf(s, "%16.s %16u\n", "total ", total_size);
+ seq_printf(s, "----------------------------------------------------\n");
+
ion_heap_print_debug(s, heap);
- mutex_unlock(&dev->lock);
+ mutex_unlock(&dev->buffer_lock);
return 0;
}
@@ -1608,40 +1618,90 @@
.release = single_release,
};
+static size_t ion_heap_free_list_is_empty(struct ion_heap *heap)
+{
+ bool is_empty;
+
+ rt_mutex_lock(&heap->lock);
+ is_empty = list_empty(&heap->free_list);
+ rt_mutex_unlock(&heap->lock);
+
+ return is_empty;
+}
+
+static int ion_heap_deferred_free(void *data)
+{
+ struct ion_heap *heap = data;
+
+ while (true) {
+ struct ion_buffer *buffer;
+
+ wait_event_freezable(heap->waitqueue,
+ !ion_heap_free_list_is_empty(heap));
+
+ rt_mutex_lock(&heap->lock);
+ if (list_empty(&heap->free_list)) {
+ rt_mutex_unlock(&heap->lock);
+ continue;
+ }
+ buffer = list_first_entry(&heap->free_list, struct ion_buffer,
+ list);
+ list_del(&buffer->list);
+ rt_mutex_unlock(&heap->lock);
+ _ion_buffer_destroy(buffer);
+ }
+
+ return 0;
+}
+
+static bool ion_heap_drain_freelist(struct ion_heap *heap)
+{
+ struct ion_buffer *buffer, *tmp;
+
+ if (ion_heap_free_list_is_empty(heap))
+ return false;
+ rt_mutex_lock(&heap->lock);
+ list_for_each_entry_safe(buffer, tmp, &heap->free_list, list) {
+ _ion_buffer_destroy(buffer);
+ list_del(&buffer->list);
+ }
+ BUG_ON(!list_empty(&heap->free_list));
+ rt_mutex_unlock(&heap->lock);
+
+
+ return true;
+}
+
void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
{
- struct rb_node **p = &dev->heaps.rb_node;
- struct rb_node *parent = NULL;
- struct ion_heap *entry;
+ struct sched_param param = { .sched_priority = 0 };
if (!heap->ops->allocate || !heap->ops->free || !heap->ops->map_dma ||
!heap->ops->unmap_dma)
pr_err("%s: can not add heap with invalid ops struct.\n",
__func__);
- heap->dev = dev;
- mutex_lock(&dev->lock);
- while (*p) {
- parent = *p;
- entry = rb_entry(parent, struct ion_heap, node);
-
- if (heap->id < entry->id) {
- p = &(*p)->rb_left;
- } else if (heap->id > entry->id ) {
- p = &(*p)->rb_right;
- } else {
- pr_err("%s: can not insert multiple heaps with "
- "id %d\n", __func__, heap->id);
- goto end;
- }
+ if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) {
+ INIT_LIST_HEAD(&heap->free_list);
+ rt_mutex_init(&heap->lock);
+ init_waitqueue_head(&heap->waitqueue);
+ heap->task = kthread_run(ion_heap_deferred_free, heap,
+ "%s", heap->name);
+ sched_setscheduler(heap->task, SCHED_IDLE, ¶m);
+ if (IS_ERR(heap->task))
+ pr_err("%s: creating thread for deferred free failed\n",
+ __func__);
}
- rb_link_node(&heap->node, parent, p);
- rb_insert_color(&heap->node, &dev->heaps);
+ heap->dev = dev;
+ down_write(&dev->lock);
+ /* use negative heap->id to reverse the priority -- when traversing
+ the list later attempt higher id numbers first */
+ plist_node_init(&heap->node, -heap->id);
+ plist_add(&heap->node, &dev->heaps);
debugfs_create_file(heap->name, 0664, dev->debug_root, heap,
&debug_heap_fops);
-end:
- mutex_unlock(&dev->lock);
+ up_write(&dev->lock);
}
int ion_secure_handle(struct ion_client *client, struct ion_handle *handle,
@@ -1714,16 +1774,15 @@
int ion_secure_heap(struct ion_device *dev, int heap_id, int version,
void *data)
{
- struct rb_node *n;
int ret_val = 0;
+ struct ion_heap *heap;
/*
* traverse the list of heaps available in this system
* and find the heap that is specified.
*/
- mutex_lock(&dev->lock);
- for (n = rb_first(&dev->heaps); n != NULL; n = rb_next(n)) {
- struct ion_heap *heap = rb_entry(n, struct ion_heap, node);
+ down_write(&dev->lock);
+ plist_for_each_entry(heap, &dev->heaps, node) {
if (!ion_heap_allow_heap_secure(heap->type))
continue;
if (ION_HEAP(heap->id) != heap_id)
@@ -1734,7 +1793,7 @@
ret_val = -EINVAL;
break;
}
- mutex_unlock(&dev->lock);
+ up_write(&dev->lock);
return ret_val;
}
EXPORT_SYMBOL(ion_secure_heap);
@@ -1742,16 +1801,15 @@
int ion_unsecure_heap(struct ion_device *dev, int heap_id, int version,
void *data)
{
- struct rb_node *n;
int ret_val = 0;
+ struct ion_heap *heap;
/*
* traverse the list of heaps available in this system
* and find the heap that is specified.
*/
- mutex_lock(&dev->lock);
- for (n = rb_first(&dev->heaps); n != NULL; n = rb_next(n)) {
- struct ion_heap *heap = rb_entry(n, struct ion_heap, node);
+ down_write(&dev->lock);
+ plist_for_each_entry(heap, &dev->heaps, node) {
if (!ion_heap_allow_heap_secure(heap->type))
continue;
if (ION_HEAP(heap->id) != heap_id)
@@ -1762,50 +1820,11 @@
ret_val = -EINVAL;
break;
}
- mutex_unlock(&dev->lock);
+ up_write(&dev->lock);
return ret_val;
}
EXPORT_SYMBOL(ion_unsecure_heap);
-static int ion_debug_leak_show(struct seq_file *s, void *unused)
-{
- struct ion_device *dev = s->private;
- struct rb_node *n;
-
- seq_printf(s, "%16.s %16.s %16.s %16.s\n", "buffer", "heap", "size",
- "ref cnt");
-
- mutex_lock(&dev->lock);
- ion_mark_dangling_buffers_locked(dev);
-
- /* Anyone still marked as a 1 means a leaked handle somewhere */
- for (n = rb_first(&dev->buffers); n; n = rb_next(n)) {
- struct ion_buffer *buf = rb_entry(n, struct ion_buffer,
- node);
-
- if (buf->marked == 1)
- seq_printf(s, "%16.x %16.s %16.x %16.d\n",
- (int)buf, buf->heap->name, buf->size,
- atomic_read(&buf->ref.refcount));
- }
- mutex_unlock(&dev->lock);
- return 0;
-}
-
-static int ion_debug_leak_open(struct inode *inode, struct file *file)
-{
- return single_open(file, ion_debug_leak_show, inode->i_private);
-}
-
-static const struct file_operations debug_leak_fops = {
- .open = ion_debug_leak_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-
-
struct ion_device *ion_device_create(long (*custom_ioctl)
(struct ion_client *client,
unsigned int cmd,
@@ -1834,13 +1853,10 @@
idev->custom_ioctl = custom_ioctl;
idev->buffers = RB_ROOT;
- mutex_init(&idev->lock);
- idev->heaps = RB_ROOT;
+ mutex_init(&idev->buffer_lock);
+ init_rwsem(&idev->lock);
+ plist_head_init(&idev->heaps);
idev->clients = RB_ROOT;
- debugfs_create_file("check_leaked_fds", 0664, idev->debug_root, idev,
- &debug_leak_fops);
-
- setup_ion_leak_check(idev->debug_root);
return idev;
}
@@ -1853,16 +1869,35 @@
void __init ion_reserve(struct ion_platform_data *data)
{
- int i, ret;
+ int i;
for (i = 0; i < data->nr; i++) {
if (data->heaps[i].size == 0)
continue;
- ret = memblock_reserve(data->heaps[i].base,
- data->heaps[i].size);
- if (ret)
- pr_err("memblock reserve of %x@%pa failed\n",
- data->heaps[i].size,
- &data->heaps[i].base);
+
+ if (data->heaps[i].base == 0) {
+ phys_addr_t paddr;
+ paddr = memblock_alloc_base(data->heaps[i].size,
+ data->heaps[i].align,
+ MEMBLOCK_ALLOC_ANYWHERE);
+ if (!paddr) {
+ pr_err("%s: error allocating memblock for "
+ "heap %d\n",
+ __func__, i);
+ continue;
+ }
+ data->heaps[i].base = paddr;
+ } else {
+ int ret = memblock_reserve(data->heaps[i].base,
+ data->heaps[i].size);
+ if (ret)
+ pr_err("memblock reserve of %x@%pa failed\n",
+ data->heaps[i].size,
+ &data->heaps[i].base);
+ }
+ pr_info("%s: %s reserved base %pa size %d\n", __func__,
+ data->heaps[i].name,
+ &data->heaps[i].base,
+ data->heaps[i].size);
}
}
diff --git a/drivers/gpu/ion/ion_chunk_heap.c b/drivers/gpu/ion/ion_chunk_heap.c
new file mode 100644
index 0000000..b76f898
--- /dev/null
+++ b/drivers/gpu/ion/ion_chunk_heap.c
@@ -0,0 +1,180 @@
+/*
+ * drivers/gpu/ion/ion_chunk_heap.c
+ *
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+//#include <linux/spinlock.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/genalloc.h>
+#include <linux/io.h>
+#include <linux/ion.h>
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include "ion_priv.h"
+
+#include <asm/mach/map.h>
+
+struct ion_chunk_heap {
+ struct ion_heap heap;
+ struct gen_pool *pool;
+ ion_phys_addr_t base;
+ unsigned long chunk_size;
+ unsigned long size;
+ unsigned long allocated;
+};
+
+static int ion_chunk_heap_allocate(struct ion_heap *heap,
+ struct ion_buffer *buffer,
+ unsigned long size, unsigned long align,
+ unsigned long flags)
+{
+ struct ion_chunk_heap *chunk_heap =
+ container_of(heap, struct ion_chunk_heap, heap);
+ struct sg_table *table;
+ struct scatterlist *sg;
+ int ret, i;
+ unsigned long num_chunks;
+
+ if (ion_buffer_fault_user_mappings(buffer))
+ return -ENOMEM;
+
+ num_chunks = ALIGN(size, chunk_heap->chunk_size) /
+ chunk_heap->chunk_size;
+ buffer->size = num_chunks * chunk_heap->chunk_size;
+
+ if (buffer->size > chunk_heap->size - chunk_heap->allocated)
+ return -ENOMEM;
+
+ table = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
+ if (!table)
+ return -ENOMEM;
+ ret = sg_alloc_table(table, num_chunks, GFP_KERNEL);
+ if (ret) {
+ kfree(table);
+ return ret;
+ }
+
+ sg = table->sgl;
+ for (i = 0; i < num_chunks; i++) {
+ unsigned long paddr = gen_pool_alloc(chunk_heap->pool,
+ chunk_heap->chunk_size);
+ if (!paddr)
+ goto err;
+ sg_set_page(sg, phys_to_page(paddr), chunk_heap->chunk_size, 0);
+ sg = sg_next(sg);
+ }
+
+ buffer->priv_virt = table;
+ chunk_heap->allocated += buffer->size;
+ return 0;
+err:
+ sg = table->sgl;
+ for (i -= 1; i >= 0; i--) {
+ gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)),
+ sg_dma_len(sg));
+ sg = sg_next(sg);
+ }
+ sg_free_table(table);
+ kfree(table);
+ return -ENOMEM;
+}
+
+static void ion_chunk_heap_free(struct ion_buffer *buffer)
+{
+ struct ion_heap *heap = buffer->heap;
+ struct ion_chunk_heap *chunk_heap =
+ container_of(heap, struct ion_chunk_heap, heap);
+ struct sg_table *table = buffer->priv_virt;
+ struct scatterlist *sg;
+ int i;
+
+ ion_heap_buffer_zero(buffer);
+
+ for_each_sg(table->sgl, sg, table->nents, i) {
+ if (ion_buffer_cached(buffer))
+ dma_sync_sg_for_device(NULL, sg, 1, DMA_BIDIRECTIONAL);
+ gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)),
+ sg_dma_len(sg));
+ }
+ chunk_heap->allocated -= buffer->size;
+ sg_free_table(table);
+ kfree(table);
+}
+
+struct sg_table *ion_chunk_heap_map_dma(struct ion_heap *heap,
+ struct ion_buffer *buffer)
+{
+ return buffer->priv_virt;
+}
+
+void ion_chunk_heap_unmap_dma(struct ion_heap *heap,
+ struct ion_buffer *buffer)
+{
+ return;
+}
+
+static struct ion_heap_ops chunk_heap_ops = {
+ .allocate = ion_chunk_heap_allocate,
+ .free = ion_chunk_heap_free,
+ .map_dma = ion_chunk_heap_map_dma,
+ .unmap_dma = ion_chunk_heap_unmap_dma,
+ .map_user = ion_heap_map_user,
+ .map_kernel = ion_heap_map_kernel,
+ .unmap_kernel = ion_heap_unmap_kernel,
+};
+
+struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data)
+{
+ struct ion_chunk_heap *chunk_heap;
+ struct scatterlist sg;
+
+ chunk_heap = kzalloc(sizeof(struct ion_chunk_heap), GFP_KERNEL);
+ if (!chunk_heap)
+ return ERR_PTR(-ENOMEM);
+
+ chunk_heap->chunk_size = (unsigned long)heap_data->priv;
+ chunk_heap->pool = gen_pool_create(get_order(chunk_heap->chunk_size) +
+ PAGE_SHIFT, -1);
+ if (!chunk_heap->pool) {
+ kfree(chunk_heap);
+ return ERR_PTR(-ENOMEM);
+ }
+ chunk_heap->base = heap_data->base;
+ chunk_heap->size = heap_data->size;
+ chunk_heap->allocated = 0;
+
+ sg_init_table(&sg, 1);
+ sg_set_page(&sg, phys_to_page(heap_data->base), heap_data->size, 0);
+ dma_sync_sg_for_device(NULL, &sg, 1, DMA_BIDIRECTIONAL);
+ gen_pool_add(chunk_heap->pool, chunk_heap->base, heap_data->size, -1);
+ chunk_heap->heap.ops = &chunk_heap_ops;
+ chunk_heap->heap.type = ION_HEAP_TYPE_CHUNK;
+ chunk_heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE;
+ pr_info("%s: base %pa size %zd align %pa\n", __func__,
+ &chunk_heap->base, heap_data->size, &heap_data->align);
+
+ return &chunk_heap->heap;
+}
+
+void ion_chunk_heap_destroy(struct ion_heap *heap)
+{
+ struct ion_chunk_heap *chunk_heap =
+ container_of(heap, struct ion_chunk_heap, heap);
+
+ gen_pool_destroy(chunk_heap->pool);
+ kfree(chunk_heap);
+ chunk_heap = NULL;
+}
diff --git a/drivers/gpu/ion/ion_cma_heap.c b/drivers/gpu/ion/ion_cma_heap.c
index f64ad4d..193f4d4 100644
--- a/drivers/gpu/ion/ion_cma_heap.c
+++ b/drivers/gpu/ion/ion_cma_heap.c
@@ -47,7 +47,7 @@
int ion_cma_get_sgtable(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t handle, size_t size)
{
- struct page *page = virt_to_page(cpu_addr);
+ struct page *page = phys_to_page(handle);
int ret;
ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
diff --git a/drivers/gpu/ion/ion_cma_secure_heap.c b/drivers/gpu/ion/ion_cma_secure_heap.c
index d622a51..e1b3eea 100644
--- a/drivers/gpu/ion/ion_cma_secure_heap.c
+++ b/drivers/gpu/ion/ion_cma_secure_heap.c
@@ -52,7 +52,7 @@
int ion_secure_cma_get_sgtable(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t handle, size_t size)
{
- struct page *page = virt_to_page(cpu_addr);
+ struct page *page = phys_to_page(handle);
int ret;
ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
diff --git a/drivers/gpu/ion/ion_heap.c b/drivers/gpu/ion/ion_heap.c
index 510b9ce..3d37541 100644
--- a/drivers/gpu/ion/ion_heap.c
+++ b/drivers/gpu/ion/ion_heap.c
@@ -17,8 +17,120 @@
#include <linux/err.h>
#include <linux/ion.h>
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/vmalloc.h>
#include "ion_priv.h"
+void *ion_heap_map_kernel(struct ion_heap *heap,
+ struct ion_buffer *buffer)
+{
+ struct scatterlist *sg;
+ int i, j;
+ void *vaddr;
+ pgprot_t pgprot;
+ struct sg_table *table = buffer->sg_table;
+ int npages = PAGE_ALIGN(buffer->size) / PAGE_SIZE;
+ struct page **pages = vmalloc(sizeof(struct page *) * npages);
+ struct page **tmp = pages;
+
+ if (!pages)
+ return 0;
+
+ if (buffer->flags & ION_FLAG_CACHED)
+ pgprot = PAGE_KERNEL;
+ else
+ pgprot = pgprot_writecombine(PAGE_KERNEL);
+
+ for_each_sg(table->sgl, sg, table->nents, i) {
+ int npages_this_entry = PAGE_ALIGN(sg_dma_len(sg)) / PAGE_SIZE;
+ struct page *page = sg_page(sg);
+ BUG_ON(i >= npages);
+ for (j = 0; j < npages_this_entry; j++) {
+ *(tmp++) = page++;
+ }
+ }
+ vaddr = vmap(pages, npages, VM_MAP, pgprot);
+ vfree(pages);
+
+ return vaddr;
+}
+
+void ion_heap_unmap_kernel(struct ion_heap *heap,
+ struct ion_buffer *buffer)
+{
+ vunmap(buffer->vaddr);
+}
+
+int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
+ struct vm_area_struct *vma)
+{
+ struct sg_table *table = buffer->sg_table;
+ unsigned long addr = vma->vm_start;
+ unsigned long offset = vma->vm_pgoff * PAGE_SIZE;
+ struct scatterlist *sg;
+ int i;
+
+ for_each_sg(table->sgl, sg, table->nents, i) {
+ struct page *page = sg_page(sg);
+ unsigned long remainder = vma->vm_end - addr;
+ unsigned long len = sg_dma_len(sg);
+
+ if (offset >= sg_dma_len(sg)) {
+ offset -= sg_dma_len(sg);
+ continue;
+ } else if (offset) {
+ page += offset / PAGE_SIZE;
+ len = sg_dma_len(sg) - offset;
+ offset = 0;
+ }
+ len = min(len, remainder);
+ remap_pfn_range(vma, addr, page_to_pfn(page), len,
+ vma->vm_page_prot);
+ addr += len;
+ if (addr >= vma->vm_end)
+ return 0;
+ }
+ return 0;
+}
+
+int ion_heap_buffer_zero(struct ion_buffer *buffer)
+{
+ struct sg_table *table = buffer->sg_table;
+ pgprot_t pgprot;
+ struct scatterlist *sg;
+ struct vm_struct *vm_struct;
+ int i, j, ret = 0;
+
+ if (buffer->flags & ION_FLAG_CACHED)
+ pgprot = PAGE_KERNEL;
+ else
+ pgprot = pgprot_writecombine(PAGE_KERNEL);
+
+ vm_struct = get_vm_area(PAGE_SIZE, VM_ALLOC);
+ if (!vm_struct)
+ return -ENOMEM;
+
+ for_each_sg(table->sgl, sg, table->nents, i) {
+ struct page *page = sg_page(sg);
+ unsigned long len = sg_dma_len(sg);
+
+ for (j = 0; j < len / PAGE_SIZE; j++) {
+ struct page *sub_page = page + j;
+ struct page **pages = &sub_page;
+ ret = map_vm_area(vm_struct, pgprot, &pages);
+ if (ret)
+ goto end;
+ memset(vm_struct->addr, 0, PAGE_SIZE);
+ unmap_kernel_range((unsigned long)vm_struct->addr,
+ PAGE_SIZE);
+ }
+ }
+end:
+ free_vm_area(vm_struct);
+ return ret;
+}
+
struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data)
{
struct ion_heap *heap = NULL;
@@ -33,6 +145,9 @@
case ION_HEAP_TYPE_CARVEOUT:
heap = ion_carveout_heap_create(heap_data);
break;
+ case ION_HEAP_TYPE_CHUNK:
+ heap = ion_chunk_heap_create(heap_data);
+ break;
default:
pr_err("%s: Invalid heap type %d\n", __func__,
heap_data->type);
@@ -67,6 +182,9 @@
case ION_HEAP_TYPE_CARVEOUT:
ion_carveout_heap_destroy(heap);
break;
+ case ION_HEAP_TYPE_CHUNK:
+ ion_chunk_heap_destroy(heap);
+ break;
default:
pr_err("%s: Invalid heap type %d\n", __func__,
heap->type);
diff --git a/drivers/gpu/ion/ion_iommu_heap.c b/drivers/gpu/ion/ion_iommu_heap.c
index ca29016..53d853d 100644
--- a/drivers/gpu/ion/ion_iommu_heap.c
+++ b/drivers/gpu/ion/ion_iommu_heap.c
@@ -111,7 +111,7 @@
int j;
void *ptr = NULL;
unsigned int npages_to_vmap, total_pages, num_large_pages = 0;
- long size_remaining = PAGE_ALIGN(size);
+ unsigned long size_remaining = PAGE_ALIGN(size);
unsigned int max_order = ION_IS_CACHED(flags) ? 0 : orders[0];
data = kmalloc(sizeof(*data), GFP_KERNEL);
diff --git a/drivers/gpu/ion/ion_page_pool.c b/drivers/gpu/ion/ion_page_pool.c
new file mode 100644
index 0000000..e8b5489
--- /dev/null
+++ b/drivers/gpu/ion/ion_page_pool.c
@@ -0,0 +1,282 @@
+/*
+ * drivers/gpu/ion/ion_mem_pool.c
+ *
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/debugfs.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/shrinker.h>
+#include "ion_priv.h"
+
+/* #define DEBUG_PAGE_POOL_SHRINKER */
+
+static struct plist_head pools = PLIST_HEAD_INIT(pools);
+static struct shrinker shrinker;
+
+struct ion_page_pool_item {
+ struct page *page;
+ struct list_head list;
+};
+
+static void *ion_page_pool_alloc_pages(struct ion_page_pool *pool)
+{
+ struct page *page = alloc_pages(pool->gfp_mask, pool->order);
+ struct scatterlist sg;
+
+ if (!page)
+ return NULL;
+
+ sg_init_table(&sg, 1);
+ sg_set_page(&sg, page, PAGE_SIZE << pool->order, 0);
+ dma_sync_sg_for_device(NULL, &sg, 1, DMA_BIDIRECTIONAL);
+
+ return page;
+}
+
+static void ion_page_pool_free_pages(struct ion_page_pool *pool,
+ struct page *page)
+{
+ __free_pages(page, pool->order);
+}
+
+static int ion_page_pool_add(struct ion_page_pool *pool, struct page *page)
+{
+ struct ion_page_pool_item *item;
+
+ item = kmalloc(sizeof(struct ion_page_pool_item), GFP_KERNEL);
+ if (!item)
+ return -ENOMEM;
+
+ mutex_lock(&pool->mutex);
+ item->page = page;
+ if (PageHighMem(page)) {
+ list_add_tail(&item->list, &pool->high_items);
+ pool->high_count++;
+ } else {
+ list_add_tail(&item->list, &pool->low_items);
+ pool->low_count++;
+ }
+ mutex_unlock(&pool->mutex);
+ return 0;
+}
+
+static struct page *ion_page_pool_remove(struct ion_page_pool *pool, bool high)
+{
+ struct ion_page_pool_item *item;
+ struct page *page;
+
+ if (high) {
+ BUG_ON(!pool->high_count);
+ item = list_first_entry(&pool->high_items,
+ struct ion_page_pool_item, list);
+ pool->high_count--;
+ } else {
+ BUG_ON(!pool->low_count);
+ item = list_first_entry(&pool->low_items,
+ struct ion_page_pool_item, list);
+ pool->low_count--;
+ }
+
+ list_del(&item->list);
+ page = item->page;
+ kfree(item);
+ return page;
+}
+
+void *ion_page_pool_alloc(struct ion_page_pool *pool)
+{
+ struct page *page = NULL;
+
+ BUG_ON(!pool);
+
+ mutex_lock(&pool->mutex);
+ if (pool->high_count)
+ page = ion_page_pool_remove(pool, true);
+ else if (pool->low_count)
+ page = ion_page_pool_remove(pool, false);
+ mutex_unlock(&pool->mutex);
+
+ if (!page)
+ page = ion_page_pool_alloc_pages(pool);
+
+ return page;
+}
+
+void ion_page_pool_free(struct ion_page_pool *pool, struct page* page)
+{
+ int ret;
+
+ ret = ion_page_pool_add(pool, page);
+ if (ret)
+ ion_page_pool_free_pages(pool, page);
+}
+
+#ifdef DEBUG_PAGE_POOL_SHRINKER
+static int debug_drop_pools_set(void *data, u64 val)
+{
+ struct shrink_control sc;
+ int objs;
+
+ sc.gfp_mask = -1;
+ sc.nr_to_scan = 0;
+
+ if (!val)
+ return 0;
+
+ objs = shrinker.shrink(&shrinker, &sc);
+ sc.nr_to_scan = objs;
+
+ shrinker.shrink(&shrinker, &sc);
+ return 0;
+}
+
+static int debug_drop_pools_get(void *data, u64 *val)
+{
+ struct shrink_control sc;
+ int objs;
+
+ sc.gfp_mask = -1;
+ sc.nr_to_scan = 0;
+
+ objs = shrinker.shrink(&shrinker, &sc);
+ *val = objs;
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(debug_drop_pools_fops, debug_drop_pools_get,
+ debug_drop_pools_set, "%llu\n");
+
+static int debug_grow_pools_set(void *data, u64 val)
+{
+ struct ion_page_pool *pool;
+ struct page *page;
+
+ plist_for_each_entry(pool, &pools, list) {
+ if (val != pool->list.prio)
+ continue;
+ page = ion_page_pool_alloc_pages(pool);
+ if (page)
+ ion_page_pool_add(pool, page);
+ }
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(debug_grow_pools_fops, debug_drop_pools_get,
+ debug_grow_pools_set, "%llu\n");
+#endif
+
+static int ion_page_pool_total(bool high)
+{
+ struct ion_page_pool *pool;
+ int total = 0;
+
+ plist_for_each_entry(pool, &pools, list) {
+ total += high ? (pool->high_count + pool->low_count) *
+ (1 << pool->order) :
+ pool->low_count * (1 << pool->order);
+ }
+ return total;
+}
+
+static int ion_page_pool_shrink(struct shrinker *shrinker,
+ struct shrink_control *sc)
+{
+ struct ion_page_pool *pool;
+ int nr_freed = 0;
+ int i;
+ bool high;
+ int nr_to_scan = sc->nr_to_scan;
+
+ if (sc->gfp_mask & __GFP_HIGHMEM)
+ high = true;
+
+ if (nr_to_scan == 0)
+ return ion_page_pool_total(high);
+
+ plist_for_each_entry(pool, &pools, list) {
+ for (i = 0; i < nr_to_scan; i++) {
+ struct page *page;
+
+ mutex_lock(&pool->mutex);
+ if (high && pool->high_count) {
+ page = ion_page_pool_remove(pool, true);
+ } else if (pool->low_count) {
+ page = ion_page_pool_remove(pool, false);
+ } else {
+ mutex_unlock(&pool->mutex);
+ break;
+ }
+ mutex_unlock(&pool->mutex);
+ ion_page_pool_free_pages(pool, page);
+ nr_freed += (1 << pool->order);
+ }
+ nr_to_scan -= i;
+ }
+
+ return ion_page_pool_total(high);
+}
+
+struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order)
+{
+ struct ion_page_pool *pool = kmalloc(sizeof(struct ion_page_pool),
+ GFP_KERNEL);
+ if (!pool)
+ return NULL;
+ pool->high_count = 0;
+ pool->low_count = 0;
+ INIT_LIST_HEAD(&pool->low_items);
+ INIT_LIST_HEAD(&pool->high_items);
+ pool->gfp_mask = gfp_mask;
+ pool->order = order;
+ mutex_init(&pool->mutex);
+ plist_node_init(&pool->list, order);
+ plist_add(&pool->list, &pools);
+
+ return pool;
+}
+
+void ion_page_pool_destroy(struct ion_page_pool *pool)
+{
+ plist_del(&pool->list, &pools);
+ kfree(pool);
+}
+
+static int __init ion_page_pool_init(void)
+{
+ shrinker.shrink = ion_page_pool_shrink;
+ shrinker.seeks = DEFAULT_SEEKS;
+ shrinker.batch = 0;
+ register_shrinker(&shrinker);
+#ifdef DEBUG_PAGE_POOL_SHRINKER
+ debugfs_create_file("ion_pools_shrink", 0644, NULL, NULL,
+ &debug_drop_pools_fops);
+ debugfs_create_file("ion_pools_grow", 0644, NULL, NULL,
+ &debug_grow_pools_fops);
+#endif
+ return 0;
+}
+
+static void __exit ion_page_pool_exit(void)
+{
+ unregister_shrinker(&shrinker);
+}
+
+module_init(ion_page_pool_init);
+module_exit(ion_page_pool_exit);
diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h
index 71527ae..4b724df 100644
--- a/drivers/gpu/ion/ion_priv.h
+++ b/drivers/gpu/ion/ion_priv.h
@@ -18,14 +18,17 @@
#ifndef _ION_PRIV_H
#define _ION_PRIV_H
+#include <linux/ion.h>
#include <linux/kref.h>
#include <linux/mm_types.h>
#include <linux/mutex.h>
#include <linux/rbtree.h>
-#include <linux/ion.h>
#include <linux/seq_file.h>
#include "msm_ion_priv.h"
+#include <linux/sched.h>
+#include <linux/shrinker.h>
+#include <linux/types.h>
struct ion_buffer *ion_handle_buffer(struct ion_handle *handle);
@@ -46,10 +49,22 @@
* @vaddr: the kenrel mapping if kmap_cnt is not zero
* @dmap_cnt: number of times the buffer is mapped for dma
* @sg_table: the sg table for the buffer if dmap_cnt is not zero
+ * @dirty: bitmask representing which pages of this buffer have
+ * been dirtied by the cpu and need cache maintenance
+ * before dma
+ * @vmas: list of vma's mapping this buffer
+ * @handle_count: count of handles referencing this buffer
+ * @task_comm: taskcomm of last client to reference this buffer in a
+ * handle, used for debugging
+ * @pid: pid of last client to reference this buffer in a
+ * handle, used for debugging
*/
struct ion_buffer {
struct kref ref;
- struct rb_node node;
+ union {
+ struct rb_node node;
+ struct list_head list;
+ };
struct ion_device *dev;
struct ion_heap *heap;
unsigned long flags;
@@ -65,7 +80,10 @@
struct sg_table *sg_table;
unsigned long *dirty;
struct list_head vmas;
- int marked;
+ /* used to track orphaned buffers */
+ int handle_count;
+ char task_comm[TASK_COMM_LEN];
+ pid_t pid;
};
/**
@@ -106,16 +124,28 @@
};
/**
+ * heap flags - flags between the heaps and core ion code
+ */
+#define ION_HEAP_FLAG_DEFER_FREE (1 << 0)
+
+/**
* struct ion_heap - represents a heap in the system
* @node: rb node to put the heap on the device's tree of heaps
* @dev: back pointer to the ion_device
* @type: type of heap
* @ops: ops struct as above
+ * @flags: flags
* @id: id of heap, also indicates priority of this heap when
* allocating. These are specified by platform data and
* MUST be unique
* @name: used for debugging
* @priv: private heap data
+ * @free_list: free list head if deferred free is used
+ * @lock: protects the free list
+ * @waitqueue: queue to wait on from deferred free thread
+ * @task: task struct of deferred free thread
+ * @debug_show: called when heap debug file is read to add any
+ * heap specific debug info to output
*
* Represents a pool of memory from which buffers can be made. In some
* systems the only heap is regular system memory allocated via vmalloc.
@@ -123,16 +153,30 @@
* that are allocated from a specially reserved heap.
*/
struct ion_heap {
- struct rb_node node;
+ struct plist_node node;
struct ion_device *dev;
enum ion_heap_type type;
struct ion_heap_ops *ops;
- int id;
+ unsigned long flags;
+ unsigned int id;
const char *name;
void *priv;
+ struct list_head free_list;
+ struct rt_mutex lock;
+ wait_queue_head_t waitqueue;
+ struct task_struct *task;
+ int (*debug_show)(struct ion_heap *heap, struct seq_file *, void *);
};
/**
+ * ion_buffer_cached - this ion buffer is cached
+ * @buffer: buffer
+ *
+ * indicates whether this ion buffer is cached
+ */
+bool ion_buffer_cached(struct ion_buffer *buffer);
+
+/**
* ion_buffer_fault_user_mappings - fault in user mappings of this buffer
* @buffer: buffer
*
@@ -166,6 +210,17 @@
void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap);
/**
+ * some helpers for common operations on buffers using the sg_table
+ * and vaddr fields
+ */
+void *ion_heap_map_kernel(struct ion_heap *, struct ion_buffer *);
+void ion_heap_unmap_kernel(struct ion_heap *, struct ion_buffer *);
+int ion_heap_map_user(struct ion_heap *, struct ion_buffer *,
+ struct vm_area_struct *);
+int ion_heap_buffer_zero(struct ion_buffer *buffer);
+
+
+/**
* functions for creating and destroying the built in ion heaps.
* architectures can add their own custom architecture specific
* heaps as appropriate.
@@ -173,7 +228,6 @@
struct ion_heap *ion_heap_create(struct ion_platform_heap *);
void ion_heap_destroy(struct ion_heap *);
-
struct ion_heap *ion_system_heap_create(struct ion_platform_heap *);
void ion_system_heap_destroy(struct ion_heap *);
@@ -183,6 +237,8 @@
struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *);
void ion_carveout_heap_destroy(struct ion_heap *);
+struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *);
+void ion_chunk_heap_destroy(struct ion_heap *);
/**
* kernel api to allocate/free from carveout -- used when carveout is
* used to back an architecture specific custom heap
@@ -198,4 +254,52 @@
*/
#define ION_CARVEOUT_ALLOCATE_FAIL -1
+
+/**
+ * functions for creating and destroying a heap pool -- allows you
+ * to keep a pool of pre allocated memory to use from your heap. Keeping
+ * a pool of memory that is ready for dma, ie any cached mapping have been
+ * invalidated from the cache, provides a significant peformance benefit on
+ * many systems */
+
+/**
+ * struct ion_page_pool - pagepool struct
+ * @high_count: number of highmem items in the pool
+ * @low_count: number of lowmem items in the pool
+ * @high_items: list of highmem items
+ * @low_items: list of lowmem items
+ * @shrinker: a shrinker for the items
+ * @mutex: lock protecting this struct and especially the count
+ * item list
+ * @alloc: function to be used to allocate pageory when the pool
+ * is empty
+ * @free: function to be used to free pageory back to the system
+ * when the shrinker fires
+ * @gfp_mask: gfp_mask to use from alloc
+ * @order: order of pages in the pool
+ * @list: plist node for list of pools
+ *
+ * Allows you to keep a pool of pre allocated pages to use from your heap.
+ * Keeping a pool of pages that is ready for dma, ie any cached mapping have
+ * been invalidated from the cache, provides a significant peformance benefit
+ * on many systems
+ */
+struct ion_page_pool {
+ int high_count;
+ int low_count;
+ struct list_head high_items;
+ struct list_head low_items;
+ struct mutex mutex;
+ void *(*alloc)(struct ion_page_pool *pool);
+ void (*free)(struct ion_page_pool *pool, struct page *page);
+ gfp_t gfp_mask;
+ unsigned int order;
+ struct plist_node list;
+};
+
+struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order);
+void ion_page_pool_destroy(struct ion_page_pool *);
+void *ion_page_pool_alloc(struct ion_page_pool *);
+void ion_page_pool_free(struct ion_page_pool *, struct page *);
+
#endif /* _ION_PRIV_H */
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index f3f627d..02f6d93 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -22,6 +22,7 @@
#include <linux/ion.h>
#include <linux/mm.h>
#include <linux/scatterlist.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/seq_file.h>
@@ -34,30 +35,111 @@
static atomic_t system_heap_allocated;
static atomic_t system_contig_heap_allocated;
+static unsigned int high_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO |
+ __GFP_NOWARN | __GFP_NORETRY |
+ __GFP_NO_KSWAPD) & ~__GFP_WAIT;
+static unsigned int low_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO |
+ __GFP_NOWARN);
+static const unsigned int orders[] = {8, 4, 0};
+static const int num_orders = ARRAY_SIZE(orders);
+static int order_to_index(unsigned int order)
+{
+ int i;
+ for (i = 0; i < num_orders; i++)
+ if (order == orders[i])
+ return i;
+ BUG();
+ return -1;
+}
+
+static unsigned int order_to_size(int order)
+{
+ return PAGE_SIZE << order;
+}
+
+struct ion_system_heap {
+ struct ion_heap heap;
+ struct ion_page_pool **pools;
+};
+
struct page_info {
struct page *page;
- unsigned long order;
+ unsigned int order;
struct list_head list;
};
-static struct page_info *alloc_largest_available(unsigned long size,
- bool split_pages)
+static struct page *alloc_buffer_page(struct ion_system_heap *heap,
+ struct ion_buffer *buffer,
+ unsigned long order)
{
- static unsigned int orders[] = {8, 4, 0};
+ bool cached = ion_buffer_cached(buffer);
+ bool split_pages = ion_buffer_fault_user_mappings(buffer);
+ struct ion_page_pool *pool = heap->pools[order_to_index(order)];
+ struct page *page;
+
+ if (!cached) {
+ page = ion_page_pool_alloc(pool);
+ } else {
+ struct scatterlist sg;
+ gfp_t gfp_flags = low_order_gfp_flags;
+
+ if (order > 4)
+ gfp_flags = high_order_gfp_flags;
+ page = alloc_pages(gfp_flags, order);
+ if (!page)
+ return 0;
+ sg_init_table(&sg, 1);
+ sg_set_page(&sg, page, PAGE_SIZE << order, 0);
+ dma_sync_sg_for_device(NULL, &sg, 1, DMA_BIDIRECTIONAL);
+ }
+ if (!page)
+ return 0;
+
+ if (split_pages)
+ split_page(page, order);
+ return page;
+}
+
+static void free_buffer_page(struct ion_system_heap *heap,
+ struct ion_buffer *buffer, struct page *page,
+ unsigned int order)
+{
+ bool cached = ion_buffer_cached(buffer);
+ bool split_pages = ion_buffer_fault_user_mappings(buffer);
+ int i;
+
+ if (!cached) {
+ struct ion_page_pool *pool = heap->pools[order_to_index(order)];
+ ion_page_pool_free(pool, page);
+ } else if (split_pages) {
+ for (i = 0; i < (1 << order); i++)
+ __free_page(page + i);
+ } else {
+ __free_pages(page, order);
+ }
+}
+
+
+static struct page_info *alloc_largest_available(struct ion_system_heap *heap,
+ struct ion_buffer *buffer,
+ unsigned long size,
+ unsigned int max_order)
+{
struct page *page;
struct page_info *info;
int i;
- for (i = 0; i < ARRAY_SIZE(orders); i++) {
- if (size < (1 << orders[i]) * PAGE_SIZE)
+ for (i = 0; i < num_orders; i++) {
+ if (size < order_to_size(orders[i]))
continue;
- page = alloc_pages(GFP_HIGHUSER | __GFP_ZERO |
- __GFP_NOWARN | __GFP_NORETRY, orders[i]);
+ if (max_order < orders[i])
+ continue;
+
+ page = alloc_buffer_page(heap, buffer, orders[i]);
if (!page)
continue;
- if (split_pages)
- split_page(page, orders[i]);
- info = kmalloc(sizeof(struct page_info *), GFP_KERNEL);
+
+ info = kmalloc(sizeof(struct page_info), GFP_KERNEL);
info->page = page;
info->order = orders[i];
return info;
@@ -70,23 +152,27 @@
unsigned long size, unsigned long align,
unsigned long flags)
{
+ struct ion_system_heap *sys_heap = container_of(heap,
+ struct ion_system_heap,
+ heap);
struct sg_table *table;
struct scatterlist *sg;
int ret;
struct list_head pages;
struct page_info *info, *tmp_info;
int i = 0;
- long size_remaining = PAGE_ALIGN(size);
+ unsigned long size_remaining = PAGE_ALIGN(size);
+ unsigned int max_order = orders[0];
bool split_pages = ion_buffer_fault_user_mappings(buffer);
-
INIT_LIST_HEAD(&pages);
while (size_remaining > 0) {
- info = alloc_largest_available(size_remaining, split_pages);
+ info = alloc_largest_available(sys_heap, buffer, size_remaining, max_order);
if (!info)
goto err;
list_add_tail(&info->list, &pages);
size_remaining -= (1 << info->order) * PAGE_SIZE;
+ max_order = info->order;
i++;
}
@@ -106,7 +192,6 @@
sg = table->sgl;
list_for_each_entry_safe(info, tmp_info, &pages, list) {
struct page *page = info->page;
-
if (split_pages) {
for (i = 0; i < (1 << info->order); i++) {
sg_set_page(sg, page + i, PAGE_SIZE, 0);
@@ -121,9 +206,6 @@
kfree(info);
}
- dma_sync_sg_for_device(NULL, table->sgl, table->nents,
- DMA_BIDIRECTIONAL);
-
buffer->priv_virt = table;
atomic_add(size, &system_heap_allocated);
return 0;
@@ -131,12 +213,7 @@
kfree(table);
err:
list_for_each_entry(info, &pages, list) {
- if (split_pages)
- for (i = 0; i < (1 << info->order); i++)
- __free_page(info->page + i);
- else
- __free_pages(info->page, info->order);
-
+ free_buffer_page(sys_heap, buffer, info->page, info->order);
kfree(info);
}
return -ENOMEM;
@@ -144,15 +221,26 @@
void ion_system_heap_free(struct ion_buffer *buffer)
{
- int i;
+ struct ion_heap *heap = buffer->heap;
+ struct ion_system_heap *sys_heap = container_of(heap,
+ struct ion_system_heap,
+ heap);
+ struct sg_table *table = buffer->sg_table;
+ bool cached = ion_buffer_cached(buffer);
struct scatterlist *sg;
- struct sg_table *table = buffer->priv_virt;
+ LIST_HEAD(pages);
+ int i;
+
+ /* uncached pages come from the page pools, zero them before returning
+ for security purposes (other allocations are zerod at alloc time */
+ if (!cached)
+ ion_heap_buffer_zero(buffer);
for_each_sg(table->sgl, sg, table->nents, i)
- __free_pages(sg_page(sg), get_order(sg_dma_len(sg)));
- if (buffer->sg_table)
- sg_free_table(buffer->sg_table);
- kfree(buffer->sg_table);
+ free_buffer_page(sys_heap, buffer, sg_page(sg),
+ get_order(sg_dma_len(sg)));
+ sg_free_table(table);
+ kfree(table);
atomic_sub(buffer->size, &system_heap_allocated);
}
@@ -168,70 +256,6 @@
return;
}
-void *ion_system_heap_map_kernel(struct ion_heap *heap,
- struct ion_buffer *buffer)
-{
- struct scatterlist *sg;
- int i, j;
- void *vaddr;
- pgprot_t pgprot;
- struct sg_table *table = buffer->priv_virt;
- int npages = PAGE_ALIGN(buffer->size) / PAGE_SIZE;
- struct page **pages = kzalloc(sizeof(struct page *) * npages,
- GFP_KERNEL);
- struct page **tmp = pages;
-
- if (buffer->flags & ION_FLAG_CACHED)
- pgprot = PAGE_KERNEL;
- else
- pgprot = pgprot_writecombine(PAGE_KERNEL);
-
- for_each_sg(table->sgl, sg, table->nents, i) {
- int npages_this_entry = PAGE_ALIGN(sg_dma_len(sg)) / PAGE_SIZE;
- struct page *page = sg_page(sg);
- BUG_ON(i >= npages);
- for (j = 0; j < npages_this_entry; j++) {
- *(tmp++) = page++;
- }
- }
- vaddr = vmap(pages, npages, VM_MAP, pgprot);
- kfree(pages);
-
- return vaddr;
-}
-
-void ion_system_heap_unmap_kernel(struct ion_heap *heap,
- struct ion_buffer *buffer)
-{
- vunmap(buffer->vaddr);
-}
-
-int ion_system_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
- struct vm_area_struct *vma)
-{
- struct sg_table *table = buffer->priv_virt;
- unsigned long addr = vma->vm_start;
- unsigned long offset = vma->vm_pgoff;
- struct scatterlist *sg;
- int i;
-
- if (!ION_IS_CACHED(buffer->flags)) {
- pr_err("%s: cannot map system heap uncached\n", __func__);
- return -EINVAL;
- }
-
- for_each_sg(table->sgl, sg, table->nents, i) {
- if (offset) {
- offset--;
- continue;
- }
- remap_pfn_range(vma, addr, page_to_pfn(sg_page(sg)),
- sg_dma_len(sg), vma->vm_page_prot);
- addr += sg_dma_len(sg);
- }
- return 0;
-}
-
static int ion_system_print_debug(struct ion_heap *heap, struct seq_file *s,
const struct rb_root *unused)
{
@@ -241,32 +265,65 @@
return 0;
}
-static struct ion_heap_ops vmalloc_ops = {
+static struct ion_heap_ops system_heap_ops = {
.allocate = ion_system_heap_allocate,
.free = ion_system_heap_free,
.map_dma = ion_system_heap_map_dma,
.unmap_dma = ion_system_heap_unmap_dma,
- .map_kernel = ion_system_heap_map_kernel,
- .unmap_kernel = ion_system_heap_unmap_kernel,
- .map_user = ion_system_heap_map_user,
+ .map_kernel = ion_heap_map_kernel,
+ .unmap_kernel = ion_heap_unmap_kernel,
+ .map_user = ion_heap_map_user,
.print_debug = ion_system_print_debug,
};
struct ion_heap *ion_system_heap_create(struct ion_platform_heap *pheap)
{
- struct ion_heap *heap;
+ struct ion_system_heap *heap;
+ int i;
- heap = kzalloc(sizeof(struct ion_heap), GFP_KERNEL);
+ heap = kzalloc(sizeof(struct ion_system_heap), GFP_KERNEL);
if (!heap)
return ERR_PTR(-ENOMEM);
- heap->ops = &vmalloc_ops;
- heap->type = ION_HEAP_TYPE_SYSTEM;
- return heap;
+ heap->heap.ops = &system_heap_ops;
+ heap->heap.type = ION_HEAP_TYPE_SYSTEM;
+ heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE;
+ heap->pools = kzalloc(sizeof(struct ion_page_pool *) * num_orders,
+ GFP_KERNEL);
+ if (!heap->pools)
+ goto err_alloc_pools;
+ for (i = 0; i < num_orders; i++) {
+ struct ion_page_pool *pool;
+ gfp_t gfp_flags = low_order_gfp_flags;
+
+ if (orders[i] > 4)
+ gfp_flags = high_order_gfp_flags;
+ pool = ion_page_pool_create(gfp_flags, orders[i]);
+ if (!pool)
+ goto err_create_pool;
+ heap->pools[i] = pool;
+ }
+ return &heap->heap;
+err_create_pool:
+ for (i = 0; i < num_orders; i++)
+ if (heap->pools[i])
+ ion_page_pool_destroy(heap->pools[i]);
+ kfree(heap->pools);
+err_alloc_pools:
+ kfree(heap);
+ return ERR_PTR(-ENOMEM);
}
void ion_system_heap_destroy(struct ion_heap *heap)
{
- kfree(heap);
+ struct ion_system_heap *sys_heap = container_of(heap,
+ struct ion_system_heap,
+ heap);
+ int i;
+
+ for (i = 0; i < num_orders; i++)
+ ion_page_pool_destroy(sys_heap->pools[i]);
+ kfree(sys_heap->pools);
+ kfree(sys_heap);
}
static int ion_system_contig_heap_allocate(struct ion_heap *heap,
@@ -367,8 +424,8 @@
.phys = ion_system_contig_heap_phys,
.map_dma = ion_system_contig_heap_map_dma,
.unmap_dma = ion_system_contig_heap_unmap_dma,
- .map_kernel = ion_system_contig_heap_map_kernel,
- .unmap_kernel = ion_system_contig_heap_unmap_kernel,
+ .map_kernel = ion_heap_map_kernel,
+ .unmap_kernel = ion_heap_unmap_kernel,
.map_user = ion_system_contig_heap_map_user,
.print_debug = ion_system_contig_print_debug,
};
diff --git a/drivers/gpu/ion/msm/ion_iommu_map.c b/drivers/gpu/ion/msm/ion_iommu_map.c
index ae4ae37..5ce03db 100644
--- a/drivers/gpu/ion/msm/ion_iommu_map.c
+++ b/drivers/gpu/ion/msm/ion_iommu_map.c
@@ -206,8 +206,8 @@
* biggest entry. To take advantage of bigger mapping sizes both the
* VA and PA addresses have to be aligned to the biggest size.
*/
- if (table->sgl->length > align)
- align = table->sgl->length;
+ if (sg_dma_len(table->sgl) > align)
+ align = sg_dma_len(table->sgl);
ret = msm_allocate_iova_address(domain_num, partition_num,
data->mapped_size, align,
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index 9259de2..f43d276 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -128,7 +128,7 @@
struct ion_client *msm_ion_client_create(unsigned int heap_mask,
const char *name)
{
- return ion_client_create(idev, heap_mask, name);
+ return ion_client_create(idev, name);
}
EXPORT_SYMBOL(msm_ion_client_create);
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 5589ff0..f3ee02b 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -3040,7 +3040,7 @@
if (context && device->state != KGSL_STATE_SLUMBER) {
adreno_ringbuffer_issuecmds(device, context->devctxt,
- KGSL_CMD_FLAGS_NONE, NULL, 0);
+ KGSL_CMD_FLAGS_GET_INT, NULL, 0);
}
}
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 90d6027..3935cd8 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -34,6 +34,7 @@
#define KGSL_CMD_FLAGS_NONE 0x00000000
#define KGSL_CMD_FLAGS_PMODE 0x00000001
#define KGSL_CMD_FLAGS_INTERNAL_ISSUE 0x00000002
+#define KGSL_CMD_FLAGS_GET_INT 0x00000004
#define KGSL_CMD_FLAGS_EOF 0x00000100
/* Command identifiers */
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index a4bb4fa..628d38c 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -544,13 +544,15 @@
/*
* if the context was not created with per context timestamp
* support, we must use the global timestamp since issueibcmds
- * will be returning that one.
+ * will be returning that one, or if an internal issue then
+ * use global timestamp.
*/
- if (context && context->flags & CTXT_FLAGS_PER_CONTEXT_TS)
+ if ((context && (context->flags & CTXT_FLAGS_PER_CONTEXT_TS)) &&
+ !(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE))
context_id = context->id;
- if ((context && context->flags & CTXT_FLAGS_USER_GENERATED_TS) &&
- (!(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE))) {
+ if ((context && (context->flags & CTXT_FLAGS_USER_GENERATED_TS)) &&
+ !(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE)) {
if (timestamp_cmp(rb->timestamp[context_id],
timestamp) >= 0) {
KGSL_DRV_ERR(rb->device,
@@ -574,6 +576,11 @@
/* Add CP_COND_EXEC commands to generate CP_INTERRUPT */
total_sizedwords += context ? 13 : 0;
+ if ((context) && (context->flags & CTXT_FLAGS_PER_CONTEXT_TS) &&
+ (flags & (KGSL_CMD_FLAGS_INTERNAL_ISSUE |
+ KGSL_CMD_FLAGS_GET_INT)))
+ total_sizedwords += 2;
+
if (adreno_is_a3xx(adreno_dev))
total_sizedwords += 7;
@@ -584,11 +591,9 @@
total_sizedwords += 3; /* sop timestamp */
total_sizedwords += 4; /* eop timestamp */
- if (context && context->flags & CTXT_FLAGS_PER_CONTEXT_TS &&
- !(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE)) {
+ if (KGSL_MEMSTORE_GLOBAL != context_id)
total_sizedwords += 3; /* global timestamp without cache
* flush for non-zero context */
- }
if (adreno_is_a20x(adreno_dev))
total_sizedwords += 2; /* CACHE_FLUSH */
@@ -619,12 +624,12 @@
/* always increment the global timestamp. once. */
rb->timestamp[KGSL_MEMSTORE_GLOBAL]++;
- /* Do not update context's timestamp for internal submissions */
- if (context && !(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE)) {
- if (context_id == KGSL_MEMSTORE_GLOBAL)
- rb->timestamp[context->id] =
- rb->timestamp[KGSL_MEMSTORE_GLOBAL];
- else if (context->flags & CTXT_FLAGS_USER_GENERATED_TS)
+ /*
+ * If global timestamp then we are not using per context ts for
+ * this submission
+ */
+ if (context_id != KGSL_MEMSTORE_GLOBAL) {
+ if (context->flags & CTXT_FLAGS_USER_GENERATED_TS)
rb->timestamp[context_id] = timestamp;
else
rb->timestamp[context_id]++;
@@ -695,9 +700,7 @@
KGSL_MEMSTORE_OFFSET(context_id, eoptimestamp)));
GSL_RB_WRITE(ringcmds, rcmd_gpu, timestamp);
- if (context && context->flags & CTXT_FLAGS_PER_CONTEXT_TS
- && !(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE)) {
-
+ if (KGSL_MEMSTORE_GLOBAL != context_id) {
GSL_RB_WRITE(ringcmds, rcmd_gpu,
cp_type3_packet(CP_MEM_WRITE, 2));
GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
@@ -749,6 +752,19 @@
GSL_RB_WRITE(ringcmds, rcmd_gpu, CP_INT_CNTL__RB_INT_MASK);
}
+ /*
+ * If per context timestamps are enabled and any of the kgsl
+ * internal commands want INT to be generated trigger the INT
+ */
+ if ((context) && (context->flags & CTXT_FLAGS_PER_CONTEXT_TS) &&
+ (flags & (KGSL_CMD_FLAGS_INTERNAL_ISSUE |
+ KGSL_CMD_FLAGS_GET_INT))) {
+ GSL_RB_WRITE(ringcmds, rcmd_gpu,
+ cp_type3_packet(CP_INTERRUPT, 1));
+ GSL_RB_WRITE(ringcmds, rcmd_gpu,
+ CP_INT_CNTL__RB_INT_MASK);
+ }
+
if (adreno_is_a3xx(adreno_dev)) {
/* Dummy set-constant to trigger context rollover */
GSL_RB_WRITE(ringcmds, rcmd_gpu,
diff --git a/drivers/hwmon/qpnp-adc-current.c b/drivers/hwmon/qpnp-adc-current.c
index 0b02a34..66811bf 100644
--- a/drivers/hwmon/qpnp-adc-current.c
+++ b/drivers/hwmon/qpnp-adc-current.c
@@ -129,6 +129,7 @@
struct qpnp_iadc_drv {
struct qpnp_adc_drv *adc;
int32_t rsense;
+ bool external_rsense;
struct device *iadc_hwmon;
bool iadc_initialized;
int64_t die_temp_calib_offset;
@@ -543,6 +544,9 @@
if (!iadc || !iadc->iadc_initialized)
return -EPROBE_DEFER;
+ if (iadc->external_rsense)
+ *rsense = iadc->rsense;
+
rc = qpnp_iadc_read_reg(QPNP_IADC_NOMINAL_RSENSE, &rslt_rsense);
if (rc < 0) {
pr_err("qpnp adc rsense read failed with %d\n", rc);
@@ -571,15 +575,21 @@
{
struct qpnp_iadc_drv *iadc = qpnp_iadc;
struct qpnp_vadc_result result_pmic_therm;
+ int64_t die_temp_offset;
int rc = 0;
rc = qpnp_vadc_read(DIE_TEMP, &result_pmic_therm);
if (rc < 0)
return rc;
- if (((uint64_t) (result_pmic_therm.physical -
- iadc->die_temp_calib_offset))
- > QPNP_IADC_DIE_TEMP_CALIB_OFFSET) {
+ die_temp_offset = result_pmic_therm.physical -
+ iadc->die_temp_calib_offset;
+ if (die_temp_offset < 0)
+ die_temp_offset = -die_temp_offset;
+
+ if (die_temp_offset > QPNP_IADC_DIE_TEMP_CALIB_OFFSET) {
+ iadc->die_temp_calib_offset =
+ result_pmic_therm.physical;
rc = qpnp_iadc_calibrate_for_trim();
if (rc)
pr_err("periodic IADC calibration failed\n");
@@ -822,9 +832,11 @@
rc = of_property_read_u32(node, "qcom,rsense",
&iadc->rsense);
- if (rc) {
- pr_err("Invalid rsens reference property\n");
- goto fail;
+ if (rc)
+ pr_debug("Defaulting to internal rsense\n");
+ else {
+ pr_debug("Use external rsense\n");
+ iadc->external_rsense = true;
}
rc = devm_request_irq(&spmi->dev, iadc->adc->adc_irq_eoc,
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 0ea230a..deda0c8 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -128,6 +128,7 @@
#define MXT_SPT_DIGITIZER_T43 43
#define MXT_SPT_MESSAGECOUNT_T44 44
#define MXT_SPT_CTECONFIG_T46 46
+#define MXT_SPT_EXTRANOISESUPCTRLS_T58 58
#define MXT_SPT_TIMER_T61 61
/* MXT_GEN_COMMAND_T6 field */
@@ -432,6 +433,7 @@
case MXT_SPT_USERDATA_T38:
case MXT_SPT_DIGITIZER_T43:
case MXT_SPT_CTECONFIG_T46:
+ case MXT_SPT_EXTRANOISESUPCTRLS_T58:
case MXT_SPT_TIMER_T61:
case MXT_PROCI_ADAPTIVETHRESHOLD_T55:
return true;
@@ -469,6 +471,7 @@
case MXT_SPT_USERDATA_T38:
case MXT_SPT_DIGITIZER_T43:
case MXT_SPT_CTECONFIG_T46:
+ case MXT_SPT_EXTRANOISESUPCTRLS_T58:
case MXT_SPT_TIMER_T61:
case MXT_PROCI_ADAPTIVETHRESHOLD_T55:
return true;
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.c b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
index 417ef83..4e2b1a4 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi4.c
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
@@ -34,6 +34,9 @@
#define DRIVER_NAME "synaptics_rmi4_i2c"
#define INPUT_PHYS_NAME "synaptics_rmi4_i2c/input0"
+
+#define RESET_DELAY 100
+
#define TYPE_B_PROTOCOL
#define NO_0D_WHILE_2D
@@ -68,6 +71,16 @@
#define NO_SLEEP_OFF (0 << 2)
#define NO_SLEEP_ON (1 << 2)
+enum device_status {
+ STATUS_NO_ERROR = 0x00,
+ STATUS_RESET_OCCURED = 0x01,
+ STATUS_INVALID_CONFIG = 0x02,
+ STATUS_DEVICE_FAILURE = 0x03,
+ STATUS_CONFIG_CRC_FAILURE = 0x04,
+ STATUS_FIRMWARE_CRC_FAILURE = 0x05,
+ STATUS_CRC_IN_PROGRESS = 0x06
+};
+
#define RMI4_VTG_MIN_UV 2700000
#define RMI4_VTG_MAX_UV 3300000
#define RMI4_ACTIVE_LOAD_UA 15000
@@ -79,7 +92,6 @@
#define RMI4_I2C_LPM_LOAD_UA 10
#define RMI4_GPIO_SLEEP_LOW_US 10000
-#define RMI4_GPIO_WAIT_HIGH_MS 25
static int synaptics_rmi4_i2c_read(struct synaptics_rmi4_data *rmi4_data,
unsigned short addr, unsigned char *data,
@@ -1482,6 +1494,16 @@
if (retval < 0)
return retval;
+ while (status.status_code == STATUS_CRC_IN_PROGRESS) {
+ msleep(1);
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ rmi4_data->f01_data_base_addr,
+ status.data,
+ sizeof(status.data));
+ if (retval < 0)
+ return retval;
+ }
+
if (status.flash_prog == 1) {
pr_notice("%s: In flash prog mode, status = 0x%02x\n",
__func__,
@@ -1645,7 +1667,7 @@
return retval;
}
- msleep(100);
+ msleep(RESET_DELAY);
return retval;
};
@@ -2110,7 +2132,7 @@
gpio_set_value(platform_data->reset_gpio, 0);
usleep(RMI4_GPIO_SLEEP_LOW_US);
gpio_set_value(platform_data->reset_gpio, 1);
- msleep(RMI4_GPIO_WAIT_HIGH_MS);
+ msleep(RESET_DELAY);
} else
synaptics_rmi4_reset_command(rmi4_data);
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index e88e574..1d34b06 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -1433,7 +1433,7 @@
rc = of_property_read_u32(node, "qcom,pwm-channel", &val);
if (!rc)
- led->rgb_cfg->pwm_channel = (u8) val;
+ led->rgb_cfg->pwm_channel = val;
else
return rc;
@@ -1495,22 +1495,22 @@
rc = of_property_read_u32(node, "qcom,start-idx", &val);
if (!rc) {
- led->rgb_cfg->lut_params.start_idx = (u8) val;
- led->rgb_cfg->duty_cycles->start_idx = (u8) val;
+ led->rgb_cfg->lut_params.start_idx = val;
+ led->rgb_cfg->duty_cycles->start_idx = val;
} else
return rc;
led->rgb_cfg->lut_params.lut_pause_hi = 0;
rc = of_property_read_u32(node, "qcom,pause-hi", &val);
if (!rc)
- led->rgb_cfg->lut_params.lut_pause_hi = (u8) val;
+ led->rgb_cfg->lut_params.lut_pause_hi = val;
else if (rc != -EINVAL)
return rc;
led->rgb_cfg->lut_params.lut_pause_lo = 0;
rc = of_property_read_u32(node, "qcom,pause-lo", &val);
if (!rc)
- led->rgb_cfg->lut_params.lut_pause_lo = (u8) val;
+ led->rgb_cfg->lut_params.lut_pause_lo = val;
else if (rc != -EINVAL)
return rc;
@@ -1518,14 +1518,14 @@
QPNP_LUT_RAMP_STEP_DEFAULT;
rc = of_property_read_u32(node, "qcom,ramp-step-ms", &val);
if (!rc)
- led->rgb_cfg->lut_params.ramp_step_ms = (u8) val;
+ led->rgb_cfg->lut_params.ramp_step_ms = val;
else if (rc != -EINVAL)
return rc;
led->rgb_cfg->lut_params.flags = QPNP_LED_PWM_FLAGS;
rc = of_property_read_u32(node, "qcom,lut-flags", &val);
if (!rc)
- led->rgb_cfg->lut_params.flags = (u8) val;
+ led->rgb_cfg->lut_params.flags = val;
else if (rc != -EINVAL)
return rc;
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
index 431d35d..14d1197 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
@@ -1085,7 +1085,7 @@
feed_data->buffer_desc.desc[0].read_ptr = 0;
feed_data->buffer_desc.desc[0].write_ptr = 0;
feed_data->buffer_desc.desc[0].handle =
- ion_share_dma_buf(client, temp_handle);
+ ion_share_dma_buf_fd(client, temp_handle);
if (IS_ERR_VALUE(feed_data->buffer_desc.desc[0].handle)) {
MPQ_DVB_ERR_PRINT(
"%s: FAILED to share payload buffer %d\n",
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index ef3e698..0d5dc8c 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -1203,6 +1203,16 @@
}
case HAL_CONFIG_VPE_DEINTERLACE:
break;
+ case HAL_PARAM_VENC_H264_GENERATE_AUDNAL:
+ {
+ struct hfi_enable *hfi;
+ pkt->rg_property_data[0] =
+ HFI_PROPERTY_PARAM_VENC_H264_GENERATE_AUDNAL;
+ hfi = (struct hfi_enable *) &pkt->rg_property_data[1];
+ hfi->enable = ((struct hal_enable *) pdata)->enable;
+ pkt->size += sizeof(u32) + sizeof(struct hfi_enable);
+ break;
+ }
/* FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET */
case HAL_CONFIG_BUFFER_REQUIREMENTS:
case HAL_CONFIG_PRIORITY:
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index da97c7a..8ce7414 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -641,6 +641,15 @@
V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED,
.cluster = MSM_VENC_CTRL_CLUSTER_TIMING,
},
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER,
+ .name = "H264 AU Delimiter",
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED,
+ .maximum = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED,
+ .default_value =
+ V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED,
+ },
};
#define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls)
@@ -1680,6 +1689,23 @@
pdata = &vui_timing_info;
break;
}
+ case V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER:
+ property_id = HAL_PARAM_VENC_H264_GENERATE_AUDNAL;
+
+ switch (ctrl->val) {
+ case V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED:
+ enable.enable = 0;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED:
+ enable.enable = 1;
+ break;
+ default:
+ rc = -ENOTSUPP;
+ break;
+ }
+
+ pdata = &enable;
+ break;
default:
rc = -ENOTSUPP;
break;
@@ -1713,10 +1739,13 @@
for (c = 0; c < ctrl->ncontrols; ++c) {
if (ctrl->cluster[c]->is_new) {
- rc = try_set_ctrl(inst, ctrl->cluster[c]);
+ struct v4l2_ctrl *temp = ctrl->cluster[c];
+
+ rc = try_set_ctrl(inst, temp);
if (rc) {
- dprintk(VIDC_ERR, "Failed setting %x",
- ctrl->cluster[c]->id);
+ dprintk(VIDC_ERR, "Failed setting %s (%x)",
+ v4l2_ctrl_get_name(temp->id),
+ temp->id);
break;
}
}
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 8031c74..ddb3063 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -547,7 +547,7 @@
q_info = &device->iface_queues[VIDC_IFACEQ_CMDQ_IDX];
if (!q_info) {
dprintk(VIDC_ERR, "cannot write to shared Q's");
- goto err_q_write;
+ goto err_q_null;
}
mutex_lock(&device->clock_lock);
result = venus_hfi_clk_gating_off(device);
@@ -572,8 +572,9 @@
dprintk(VIDC_ERR, "venus_hfi_iface_cmdq_write:queue_full");
}
err_q_write:
- mutex_unlock(&device->write_lock);
mutex_unlock(&device->clock_lock);
+err_q_null:
+ mutex_unlock(&device->write_lock);
return result;
}
@@ -592,7 +593,7 @@
q_array.align_virtual_addr == 0) {
dprintk(VIDC_ERR, "cannot read from shared MSG Q's");
rc = -ENODATA;
- goto read_error;
+ goto read_error_null;
}
q_info = &device->iface_queues[VIDC_IFACEQ_MSGQ_IDX];
mutex_lock(&device->clock_lock);
@@ -614,8 +615,9 @@
rc = -ENODATA;
}
read_error:
- mutex_unlock(&device->read_lock);
mutex_unlock(&device->clock_lock);
+read_error_null:
+ mutex_unlock(&device->read_lock);
return rc;
}
@@ -634,7 +636,7 @@
q_array.align_virtual_addr == 0) {
dprintk(VIDC_ERR, "cannot read from shared DBG Q's");
rc = -ENODATA;
- goto dbg_error;
+ goto dbg_error_null;
}
mutex_lock(&device->clock_lock);
rc = venus_hfi_clk_gating_off(device);
@@ -656,8 +658,9 @@
rc = -ENODATA;
}
dbg_error:
- mutex_unlock(&device->read_lock);
mutex_unlock(&device->clock_lock);
+dbg_error_null:
+ mutex_unlock(&device->read_lock);
return rc;
}
@@ -1070,8 +1073,8 @@
disable_irq_nosync(dev->hal_data->irq);
dev->intr_status = 0;
venus_hfi_interface_queues_release(dev);
+ mutex_unlock(&dev->clock_lock);
}
- mutex_unlock(&dev->clock_lock);
dprintk(VIDC_INFO, "HAL exited\n");
return 0;
}
@@ -1867,8 +1870,8 @@
if (((ctrl_status & VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK)
!= 0) && !rc)
venus_hfi_clk_gating_on(device);
- mutex_unlock(&device->write_lock);
mutex_unlock(&device->clock_lock);
+ mutex_unlock(&device->write_lock);
return rc;
}
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index 3729c3a..c91d1d2 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -168,6 +168,7 @@
HAL_PARAM_VENC_H264_ENTROPY_CABAC_MODEL,
HAL_CONFIG_VENC_MAX_BITRATE,
HAL_PARAM_VENC_H264_VUI_TIMING_INFO,
+ HAL_PARAM_VENC_H264_GENERATE_AUDNAL,
};
enum hal_domain {
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 05a15b1..61adfec 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -565,13 +565,14 @@
if (wait_event_freezable(qseecom.send_resp_wq,
__qseecom_listener_has_sent_rsp(data))) {
pr_warning("Interrupted: exiting send_cmd loop\n");
- return -ERESTARTSYS;
+ ret = -ERESTARTSYS;
}
- if (data->abort) {
- pr_err("Aborting listener service %d\n",
- data->listener.id);
- rc = -ENODEV;
+ if ((data->abort) || (ret == -ERESTARTSYS)) {
+ pr_err("Abort clnt %d waiting on lstnr svc %d, ret %d",
+ data->client.app_id, lstnr, ret);
+ if (data->abort)
+ rc = -ENODEV;
send_data_rsp.status = QSEOS_RESULT_FAILURE;
} else {
send_data_rsp.status = QSEOS_RESULT_SUCCESS;
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index d1909aa..49222b9 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -2262,6 +2262,7 @@
msm_host->mmc->caps2 |= MMC_CAP2_CACHE_CTRL;
msm_host->mmc->caps2 |= MMC_CAP2_POWEROFF_NOTIFY;
msm_host->mmc->caps2 |= MMC_CAP2_CLK_SCALE;
+ msm_host->mmc->caps2 |= MMC_CAP2_STOP_REQUEST;
if (msm_host->pdata->nonremovable)
msm_host->mmc->caps |= MMC_CAP_NONREMOVABLE;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 70a9e96..0549b4a 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2124,6 +2124,11 @@
sdhci_runtime_pm_put(host);
}
+static int sdhci_stop_request(struct mmc_host *mmc)
+{
+ return -ENOSYS;
+}
+
static const struct mmc_host_ops sdhci_ops = {
.pre_req = sdhci_pre_req,
.post_req = sdhci_post_req,
@@ -2137,6 +2142,7 @@
.enable_preset_value = sdhci_enable_preset_value,
.enable = sdhci_enable,
.disable = sdhci_disable,
+ .stop_request = sdhci_stop_request,
};
/*****************************************************************************\
diff --git a/drivers/platform/msm/ipa/ipa.c b/drivers/platform/msm/ipa/ipa.c
index 5cc5d46..16f722c 100644
--- a/drivers/platform/msm/ipa/ipa.c
+++ b/drivers/platform/msm/ipa/ipa.c
@@ -1460,6 +1460,41 @@
WARN_ON(1);
}
+/**
+* ipa_inc_client_enable_clks() - Increase active clients counter, and
+* enable ipa clocks if necessary
+*
+* Return codes:
+* None
+*/
+void ipa_inc_client_enable_clks(void)
+{
+ mutex_lock(&ipa_ctx->ipa_active_clients_lock);
+ ipa_ctx->ipa_active_clients++;
+ if (ipa_ctx->ipa_active_clients == 1)
+ if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
+ ipa_enable_clks();
+ mutex_unlock(&ipa_ctx->ipa_active_clients_lock);
+}
+
+/**
+* ipa_dec_client_disable_clks() - Decrease active clients counter, and
+* disable ipa clocks if necessary
+*
+* Return codes:
+* None
+*/
+void ipa_dec_client_disable_clks(void)
+{
+ mutex_lock(&ipa_ctx->ipa_active_clients_lock);
+ ipa_ctx->ipa_active_clients--;
+ if (ipa_ctx->ipa_active_clients == 0)
+ if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
+ ipa_disable_clks();
+ mutex_unlock(&ipa_ctx->ipa_active_clients_lock);
+}
+
+
static int ipa_setup_bam_cfg(const struct ipa_plat_drv_res *res)
{
void *bam_cnfg_bits;
@@ -1845,7 +1880,8 @@
ipa_ctx->flt_rule_hdl_tree = RB_ROOT;
ipa_ctx->tag_tree = RB_ROOT;
- atomic_set(&ipa_ctx->ipa_active_clients, 0);
+ mutex_init(&ipa_ctx->ipa_active_clients_lock);
+ ipa_ctx->ipa_active_clients = 0;
result = ipa_bridge_init();
if (result) {
diff --git a/drivers/platform/msm/ipa/ipa_bridge.c b/drivers/platform/msm/ipa/ipa_bridge.c
index dd00081..83b7175 100644
--- a/drivers/platform/msm/ipa/ipa_bridge.c
+++ b/drivers/platform/msm/ipa/ipa_bridge.c
@@ -726,10 +726,7 @@
return -EINVAL;
}
- if (atomic_inc_return(&ipa_ctx->ipa_active_clients) == 1) {
- if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
- ipa_enable_clks();
- }
+ ipa_inc_client_enable_clks();
if (setup_bridge_to_ipa(dir, type, props, clnt_hdl)) {
IPAERR("fail to setup SYS pipe to IPA dir=%d type=%d\n",
@@ -751,10 +748,7 @@
bail_a2:
ipa_bridge_teardown(dir, type, *clnt_hdl);
bail_ipa:
- if (atomic_dec_return(&ipa_ctx->ipa_active_clients) == 0) {
- if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
- ipa_disable_clks();
- }
+ ipa_dec_client_disable_clks();
return ret;
}
EXPORT_SYMBOL(ipa_bridge_setup);
@@ -826,10 +820,7 @@
memset(&ipa_ctx->ep[clnt_hdl], 0, sizeof(struct ipa_ep_context));
- if (atomic_dec_return(&ipa_ctx->ipa_active_clients) == 0) {
- if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
- ipa_disable_clks();
- }
+ ipa_dec_client_disable_clks();
return 0;
}
diff --git a/drivers/platform/msm/ipa/ipa_client.c b/drivers/platform/msm/ipa/ipa_client.c
index f2f80bf..6033510 100644
--- a/drivers/platform/msm/ipa/ipa_client.c
+++ b/drivers/platform/msm/ipa/ipa_client.c
@@ -204,9 +204,7 @@
int result = -EFAULT;
struct ipa_ep_context *ep;
- if (atomic_inc_return(&ipa_ctx->ipa_active_clients) == 1)
- if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
- ipa_enable_clks();
+ ipa_inc_client_enable_clks();
if (in == NULL || sps == NULL || clnt_hdl == NULL ||
in->client >= IPA_CLIENT_MAX ||
@@ -342,11 +340,7 @@
ipa_cfg_ep_fail:
memset(&ipa_ctx->ep[ipa_ep_idx], 0, sizeof(struct ipa_ep_context));
fail:
- if (atomic_dec_return(&ipa_ctx->ipa_active_clients) == 0) {
- if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
- ipa_disable_clks();
- }
-
+ ipa_dec_client_disable_clks();
return result;
}
EXPORT_SYMBOL(ipa_connect);
@@ -421,10 +415,7 @@
ipa_enable_data_path(clnt_hdl);
memset(&ipa_ctx->ep[clnt_hdl], 0, sizeof(struct ipa_ep_context));
- if (atomic_dec_return(&ipa_ctx->ipa_active_clients) == 0) {
- if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
- ipa_disable_clks();
- }
+ ipa_dec_client_disable_clks();
IPADBG("client (ep: %d) disconnected\n", clnt_hdl);
diff --git a/drivers/platform/msm/ipa/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_debugfs.c
index 51a950d..bc5aa6f 100644
--- a/drivers/platform/msm/ipa/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_debugfs.c
@@ -563,7 +563,7 @@
ipa_ctx->stats.rx_repl_repost,
ipa_ctx->stats.x_intr_repost,
ipa_ctx->stats.rx_q_len,
- atomic_read(&ipa_ctx->ipa_active_clients),
+ ipa_ctx->ipa_active_clients,
connect);
cnt += nbytes;
diff --git a/drivers/platform/msm/ipa/ipa_dp.c b/drivers/platform/msm/ipa/ipa_dp.c
index 2555c6b..228c77fe 100644
--- a/drivers/platform/msm/ipa/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_dp.c
@@ -433,9 +433,7 @@
struct ipa_desc *desc;
int result = 0;
- if (atomic_inc_return(&ipa_ctx->ipa_active_clients) == 1)
- if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
- ipa_enable_clks();
+ ipa_inc_client_enable_clks();
if (num_desc == 1) {
init_completion(&descr->xfer_done);
@@ -471,9 +469,7 @@
IPA_STATS_INC_IC_CNT(num_desc, descr, ipa_ctx->stats.imm_cmds);
bail:
- if (atomic_dec_return(&ipa_ctx->ipa_active_clients) == 0)
- if (ipa_ctx->ipa_hw_mode == IPA_HW_MODE_NORMAL)
- ipa_disable_clks();
+ ipa_dec_client_disable_clks();
return result;
}
@@ -1087,6 +1083,7 @@
int inactive_cycles = 0;
int cnt;
+ ipa_inc_client_enable_clks();
do {
cnt = ipa_handle_rx_core(true, true);
if (cnt == 0) {
@@ -1098,6 +1095,7 @@
} while (inactive_cycles <= POLLING_INACTIVITY);
ipa_rx_switch_to_intr_mode();
+ ipa_dec_client_disable_clks();
}
/**
diff --git a/drivers/platform/msm/ipa/ipa_i.h b/drivers/platform/msm/ipa/ipa_i.h
index cb67514..a03ba16 100644
--- a/drivers/platform/msm/ipa/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_i.h
@@ -644,7 +644,8 @@
struct ipa_mem_buffer empty_rt_tbl_mem;
struct gen_pool *pipe_mem_pool;
struct dma_pool *dma_pool;
- atomic_t ipa_active_clients;
+ struct mutex ipa_active_clients_lock;
+ int ipa_active_clients;
u32 clnt_hdl_cmd;
u32 clnt_hdl_data_in;
u32 clnt_hdl_data_out;
@@ -795,6 +796,8 @@
struct ipa_context *ipa_get_ctx(void);
void ipa_enable_clks(void);
void ipa_disable_clks(void);
+void ipa_inc_client_enable_clks(void);
+void ipa_dec_client_disable_clks(void);
int __ipa_del_rt_rule(u32 rule_hdl);
int __ipa_del_hdr(u32 hdr_hdl);
int __ipa_release_hdr(u32 hdr_hdl);
diff --git a/drivers/platform/msm/ipa/ipa_rm_resource.c b/drivers/platform/msm/ipa/ipa_rm_resource.c
index 0a6771c..3615952 100644
--- a/drivers/platform/msm/ipa/ipa_rm_resource.c
+++ b/drivers/platform/msm/ipa/ipa_rm_resource.c
@@ -80,7 +80,8 @@
int result = 0;
int driver_result;
unsigned long flags;
- IPADBG("IPA RM ::ipa_rm_resource_consumer_request ENTER\n");
+ IPADBG("IPA RM ::ipa_rm_resource_consumer_request %d ENTER\n",
+ consumer->resource.name);
spin_lock_irqsave(&consumer->resource.state_lock, flags);
switch (consumer->resource.state) {
case IPA_RM_RELEASED:
@@ -114,7 +115,8 @@
consumer->usage_count++;
bail:
spin_unlock_irqrestore(&consumer->resource.state_lock, flags);
- IPADBG("IPA RM ::ipa_rm_resource_consumer_request EXIT [%d]\n", result);
+ IPADBG("IPA RM ::ipa_rm_resource_consumer_request %d EXIT %d\n",
+ consumer->resource.name, result);
return result;
}
@@ -125,7 +127,8 @@
int driver_result;
unsigned long flags;
enum ipa_rm_resource_state save_state;
- IPADBG("IPA RM ::ipa_rm_resource_consumer_release ENTER\n");
+ IPADBG("IPA RM ::ipa_rm_resource_consumer_release %d ENTER\n",
+ consumer->resource.name);
spin_lock_irqsave(&consumer->resource.state_lock, flags);
switch (consumer->resource.state) {
case IPA_RM_RELEASED:
@@ -160,7 +163,8 @@
}
bail:
spin_unlock_irqrestore(&consumer->resource.state_lock, flags);
- IPADBG("IPA RM ::ipa_rm_resource_consumer_release EXIT [%d]\n", result);
+ IPADBG("IPA RM ::ipa_rm_resource_consumer_release %d EXIT %d\n",
+ consumer->resource.name, result);
return result;
}
@@ -564,7 +568,7 @@
unsigned long flags;
struct ipa_rm_resource *consumer;
int consumer_result;
- IPADBG("IPA RM ::ipa_rm_resource_producer_request [%d] ENTER\n",
+ IPADBG("IPA RM ::ipa_rm_resource_producer_request %d ENTER\n",
producer->resource.name);
if (ipa_rm_peers_list_is_empty(producer->resource.peers_list)) {
spin_lock_irqsave(&producer->resource.state_lock, flags);
@@ -628,7 +632,8 @@
unlock_and_bail:
spin_unlock_irqrestore(&producer->resource.state_lock, flags);
bail:
- IPADBG("IPA RM ::ipa_rm_resource_producer_request EXIT[%d]\n", result);
+ IPADBG("IPA RM ::ipa_rm_resource_producer_request %d EXIT %d\n",
+ producer->resource.name, result);
return result;
}
@@ -646,7 +651,8 @@
unsigned long flags;
struct ipa_rm_resource *consumer;
int consumer_result;
- IPADBG("IPA RM ::ipa_rm_resource_producer_release ENTER\n");
+ IPADBG("IPA RM ::ipa_rm_resource_producer_release %d ENTER\n",
+ producer->resource.name);
if (ipa_rm_peers_list_is_empty(producer->resource.peers_list)) {
spin_lock_irqsave(&producer->resource.state_lock, flags);
producer->resource.state = IPA_RM_RELEASED;
@@ -702,7 +708,8 @@
return result;
bail:
spin_unlock_irqrestore(&producer->resource.state_lock, flags);
- IPADBG("IPA RM ::ipa_rm_resource_producer_release EXIT[%d]\n", result);
+ IPADBG("IPA RM ::ipa_rm_resource_producer_release %d EXIT %d\n",
+ producer->resource.name, result);
return result;
}
diff --git a/drivers/platform/msm/ipa/teth_bridge.c b/drivers/platform/msm/ipa/teth_bridge.c
index 5b26e41..774c0e6 100644
--- a/drivers/platform/msm/ipa/teth_bridge.c
+++ b/drivers/platform/msm/ipa/teth_bridge.c
@@ -58,6 +58,8 @@
#define TETH_AGGR_MAX_DATAGRAMS_DEFAULT 16
#define TETH_AGGR_MAX_AGGR_PACKET_SIZE_DEFAULT (8*1024)
+#define TETH_MTU_BYTE 1500
+
struct mac_addresses_type {
u8 host_pc_mac_addr[ETH_ALEN];
bool host_pc_mac_addr_known;
@@ -283,14 +285,7 @@
TETH_ERR("Configuration of header removal/insertion failed\n");
goto bail;
}
-
- res = ipa_commit_hdr();
- if (res) {
- TETH_ERR("Failed committing headers\n");
- goto bail;
- }
TETH_DBG_FUNC_EXIT();
-
bail:
return res;
}
@@ -425,20 +420,7 @@
TETH_ERR("A2 to USB routing block configuration failed\n");
goto bail;
}
-
- /* Commit all the changes to HW in one shot */
- res = ipa_commit_rt(IPA_IP_v4);
- if (res) {
- TETH_ERR("Failed commiting IPv4 routing tables\n");
- goto bail;
- }
- res = ipa_commit_rt(IPA_IP_v6);
- if (res) {
- TETH_ERR("Failed commiting IPv6 routing tables\n");
- goto bail;
- }
TETH_DBG_FUNC_EXIT();
-
bail:
return res;
}
@@ -533,20 +515,7 @@
TETH_ERR("A2_PROD filtering configuration failed\n");
goto bail;
}
-
- /* Commit all the changes to HW in one shot */
- res = ipa_commit_flt(IPA_IP_v4);
- if (res) {
- TETH_ERR("Failed commiting IPv4 filtering tables\n");
- goto bail;
- }
- res = ipa_commit_flt(IPA_IP_v6);
- if (res) {
- TETH_ERR("Failed commiting IPv6 filtering tables\n");
- goto bail;
- }
TETH_DBG_FUNC_EXIT();
-
bail:
return res;
}
@@ -578,8 +547,15 @@
return -EFAULT;
}
+ /*
+ * Due to a HW 'feature', the maximal aggregated packet size may be the
+ * requested aggr_byte_limit plus the MTU. Therefore, the MTU is
+ * subtracted from the requested aggr_byte_limit so that the requested
+ * byte limit is honored .
+ */
ipa_aggr_params->aggr_byte_limit =
- teth_aggr_params->max_transfer_size_byte / 1024;
+ (teth_aggr_params->max_transfer_size_byte - TETH_MTU_BYTE) /
+ 1024;
ipa_aggr_params->aggr_time_limit = TETH_DEFAULT_AGGR_TIME_LIMIT;
TETH_DBG_FUNC_EXIT();
@@ -699,9 +675,6 @@
static void complete_hw_bridge(struct work_struct *work)
{
int res;
- static DEFINE_MUTEX(f_lock);
-
- mutex_lock(&f_lock);
TETH_DBG_FUNC_ENTRY();
TETH_DBG("Completing HW bridge in %s mode\n",
@@ -715,17 +688,6 @@
goto bail;
}
- /*
- * Reset the Header, Routing and Filtering blocks.
- * Resetting the Header block will also reset the other blocks.
- * This reset is not comitted to HW.
- */
- res = ipa_reset_hdr();
- if (res) {
- TETH_ERR("Failed resetting IPA\n");
- goto bail;
- }
-
res = configure_ipa_header_block();
if (res) {
TETH_ERR("Configuration of IPA header block Failed\n");
@@ -744,10 +706,19 @@
goto bail;
}
+ /*
+ * Commit all the data to HW, including header, routing and filtering
+ * blocks, IPv4 and IPv6
+ */
+ res = ipa_commit_hdr();
+ if (res) {
+ TETH_ERR("Failed committing headers / routing / filtering.\n");
+ goto bail;
+ }
+
teth_ctx->is_hw_bridge_complete = true;
- teth_ctx->comp_hw_bridge_in_progress = false;
bail:
- mutex_unlock(&f_lock);
+ teth_ctx->comp_hw_bridge_in_progress = false;
TETH_DBG_FUNC_EXIT();
return;
@@ -1102,6 +1073,19 @@
return -EINVAL;
}
+ /*
+ * In case the requested max transfer size is larger than 8K, set it to
+ * to the default 8K
+ */
+ if (aggr_params->dl.max_transfer_size_byte >
+ TETH_AGGR_MAX_AGGR_PACKET_SIZE_DEFAULT)
+ aggr_params->dl.max_transfer_size_byte =
+ TETH_AGGR_MAX_AGGR_PACKET_SIZE_DEFAULT;
+ if (aggr_params->ul.max_transfer_size_byte >
+ TETH_AGGR_MAX_AGGR_PACKET_SIZE_DEFAULT)
+ aggr_params->ul.max_transfer_size_byte =
+ TETH_AGGR_MAX_AGGR_PACKET_SIZE_DEFAULT;
+
memcpy(&teth_ctx->aggr_params,
aggr_params,
sizeof(struct teth_aggr_params));
@@ -1110,10 +1094,8 @@
teth_ctx->aggr_params_known = true;
res = teth_set_aggregation();
- if (res) {
+ if (res)
TETH_ERR("Failed setting aggregation params\n");
- res = -EFAULT;
- }
return res;
}
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 459ab1d..e00e1c3 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -213,6 +213,8 @@
* @alarm_high_mv: the battery alarm voltage high
* @cool_temp_dc: the cool temp threshold in deciCelcius
* @warm_temp_dc: the warm temp threshold in deciCelcius
+ * @hysteresis_temp_dc: the hysteresis between temp thresholds in
+ * deciCelcius
* @resume_voltage_delta: the voltage delta from vdd max at which the
* battery should resume charging
* @term_current: The charging based term current
@@ -235,6 +237,7 @@
unsigned int alarm_high_mv;
int cool_temp_dc;
int warm_temp_dc;
+ int hysteresis_temp_dc;
unsigned int temp_check_period;
unsigned int cool_bat_chg_current;
unsigned int warm_bat_chg_current;
@@ -308,6 +311,7 @@
static int thermal_mitigation;
static struct pm8921_chg_chip *the_chip;
+static void check_temp_thresholds(struct pm8921_chg_chip *chip);
#define LPM_ENABLE_BIT BIT(2)
static int pm8921_chg_set_lpm(struct pm8921_chg_chip *chip, int enable)
@@ -3162,6 +3166,22 @@
struct delayed_work *dwork = to_delayed_work(work);
struct pm8921_chg_chip *chip = container_of(dwork,
struct pm8921_chg_chip, update_heartbeat_work);
+ bool chg_present = chip->usb_present || chip->dc_present;
+
+ /* for battery health when charger is not connected */
+ if (chip->btc_override && !chg_present)
+ schedule_delayed_work(&chip->btc_override_work,
+ round_jiffies_relative(msecs_to_jiffies
+ (chip->btc_delay_ms)));
+
+ /*
+ * check temp thresholds when charger is present and
+ * and battery is FULL. The temperature here can impact
+ * the charging restart conditions.
+ */
+ if (chip->btc_override && chg_present &&
+ !wake_lock_active(&chip->eoc_wake_lock))
+ check_temp_thresholds(chip);
power_supply_changed(&chip->batt_psy);
if (chip->recent_reported_soc <= 20)
@@ -3317,7 +3337,7 @@
if (chip->warm_temp_dc != INT_MIN) {
if (chip->is_bat_warm
- && temp < chip->warm_temp_dc - TEMP_HYSTERISIS_DECIDEGC)
+ && temp < chip->warm_temp_dc - chip->hysteresis_temp_dc)
battery_warm(false);
else if (!chip->is_bat_warm && temp >= chip->warm_temp_dc)
battery_warm(true);
@@ -3325,7 +3345,7 @@
if (chip->cool_temp_dc != INT_MIN) {
if (chip->is_bat_cool
- && temp > chip->cool_temp_dc + TEMP_HYSTERISIS_DECIDEGC)
+ && temp > chip->cool_temp_dc + chip->hysteresis_temp_dc)
battery_cool(false);
else if (!chip->is_bat_cool && temp <= chip->cool_temp_dc)
battery_cool(true);
@@ -3543,7 +3563,8 @@
temp = pm_chg_get_rt_status(chip, BATTTEMP_HOT_IRQ);
if (temp) {
- if (decidegc < chip->btc_override_hot_decidegc)
+ if (decidegc < chip->btc_override_hot_decidegc -
+ chip->hysteresis_temp_dc)
/* stop forcing batt hot */
rc = pm_chg_override_hot(chip, 0);
if (rc)
@@ -3558,7 +3579,8 @@
temp = pm_chg_get_rt_status(chip, BATTTEMP_COLD_IRQ);
if (temp) {
- if (decidegc > chip->btc_override_cold_decidegc)
+ if (decidegc > chip->btc_override_cold_decidegc +
+ chip->hysteresis_temp_dc)
/* stop forcing batt cold */
rc = pm_chg_override_cold(chip, 0);
if (rc)
@@ -3622,7 +3644,8 @@
end = is_charging_finished(chip, vbat_batt_terminal_uv, ichg_meas_ma);
- if (end == CHG_NOT_IN_PROGRESS) {
+ if (end == CHG_NOT_IN_PROGRESS && (!chip->btc_override ||
+ !(chip->usb_present || chip->dc_present))) {
count = 0;
goto eoc_worker_stop;
}
@@ -3650,7 +3673,8 @@
chgdone_irq_handler(chip->pmic_chg_irq[CHGDONE_IRQ], chip);
} else {
check_temp_thresholds(chip);
- adjust_vdd_max_for_fastchg(chip, vbat_batt_terminal_uv);
+ if (end != CHG_NOT_IN_PROGRESS)
+ adjust_vdd_max_for_fastchg(chip, vbat_batt_terminal_uv);
pr_debug("EOC count = %d\n", count);
schedule_delayed_work(&chip->eoc_work,
round_jiffies_relative(msecs_to_jiffies
@@ -3659,9 +3683,9 @@
}
eoc_worker_stop:
- wake_unlock(&chip->eoc_wake_lock);
/* set the vbatdet back, in case it was changed to trigger charging */
set_appropriate_vbatdet(chip);
+ wake_unlock(&chip->eoc_wake_lock);
}
/**
@@ -3795,6 +3819,11 @@
schedule_delayed_work(&chip->unplug_check_work,
msecs_to_jiffies(UNPLUG_CHECK_WAIT_PERIOD_MS));
pm8921_chg_enable_irq(chip, CHG_GONE_IRQ);
+
+ if (chip->btc_override)
+ schedule_delayed_work(&chip->btc_override_work,
+ round_jiffies_relative(msecs_to_jiffies
+ (chip->btc_delay_ms)));
}
pm8921_chg_enable_irq(chip, DCIN_VALID_IRQ);
@@ -4600,6 +4629,8 @@
is_usb_chg_plugged_in(the_chip)))
schedule_delayed_work(&chip->btc_override_work, 0);
+ schedule_delayed_work(&chip->update_heartbeat_work, 0);
+
return 0;
}
@@ -4607,6 +4638,8 @@
{
struct pm8921_chg_chip *chip = dev_get_drvdata(dev);
+ cancel_delayed_work_sync(&chip->update_heartbeat_work);
+
if (chip->btc_override)
cancel_delayed_work_sync(&chip->btc_override_work);
@@ -4663,6 +4696,11 @@
else
chip->warm_temp_dc = INT_MIN;
+ if (pdata->hysteresis_temp)
+ chip->hysteresis_temp_dc = pdata->hysteresis_temp * 10;
+ else
+ chip->hysteresis_temp_dc = TEMP_HYSTERISIS_DECIDEGC;
+
chip->temp_check_period = pdata->temp_check_period;
chip->max_bat_chg_current = pdata->max_bat_chg_current;
/* Assign to corresponding module parameter */
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 6cc27c2..da0a5b6 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -105,6 +105,13 @@
#define SMBBP_BOOST_SUBTYPE 0x36
#define SMBBP_MISC_SUBTYPE 0x37
+/* SMBCL peripheral subtype values */
+#define SMBCL_CHGR_SUBTYPE 0x41
+#define SMBCL_BUCK_SUBTYPE 0x42
+#define SMBCL_BAT_IF_SUBTYPE 0x43
+#define SMBCL_USB_CHGPTH_SUBTYPE 0x44
+#define SMBCL_MISC_SUBTYPE 0x47
+
#define QPNP_CHARGER_DEV_NAME "qcom,qpnp-charger"
/* Status bits and masks */
@@ -225,7 +232,6 @@
u16 freq_base;
unsigned int usbin_valid_irq;
unsigned int dcin_valid_irq;
- unsigned int chg_done_irq;
unsigned int chg_fastchg_irq;
unsigned int chg_trklchg_irq;
unsigned int chg_failed_irq;
@@ -639,26 +645,6 @@
return IRQ_HANDLED;
}
-static irqreturn_t
-qpnp_chg_chgr_chg_done_irq_handler(int irq, void *_chip)
-{
- struct qpnp_chg_chip *chip = _chip;
- u8 chgr_sts;
- int rc;
-
- pr_debug("CHG_DONE IRQ triggered\n");
-
- rc = qpnp_chg_read(chip, &chgr_sts,
- INT_RT_STS(chip->chgr_base), 1);
- if (rc)
- pr_err("failed to read interrupt sts %d\n", rc);
-
- chip->chg_done = true;
- power_supply_changed(&chip->batt_psy);
-
- return IRQ_HANDLED;
-}
-
static int
qpnp_batt_property_is_writeable(struct power_supply *psy,
enum power_supply_property psp)
@@ -1223,7 +1209,7 @@
QPNP_CHG_ITERM_MASK, temp, 1);
}
-#define QPNP_CHG_IBATMAX_MIN 100
+#define QPNP_CHG_IBATMAX_MIN 50
#define QPNP_CHG_IBATMAX_MAX 3250
static int
qpnp_chg_ibatmax_set(struct qpnp_chg_chip *chip, int chg_current)
@@ -1235,11 +1221,28 @@
pr_err("bad mA=%d asked to set\n", chg_current);
return -EINVAL;
}
- temp = (chg_current - QPNP_CHG_I_MIN_MA) / QPNP_CHG_I_STEP_MA;
+ temp = chg_current / QPNP_CHG_I_STEP_MA;
return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_IBAT_MAX,
QPNP_CHG_I_MASK, temp, 1);
}
+#define QPNP_CHG_TCHG_MASK 0x7F
+#define QPNP_CHG_TCHG_MIN 4
+#define QPNP_CHG_TCHG_MAX 512
+#define QPNP_CHG_TCHG_STEP 4
+static int qpnp_chg_tchg_max_set(struct qpnp_chg_chip *chip, int minutes)
+{
+ u8 temp;
+
+ if (minutes < QPNP_CHG_TCHG_MIN || minutes > QPNP_CHG_TCHG_MAX) {
+ pr_err("bad max minutes =%d asked to set\n", minutes);
+ return -EINVAL;
+ }
+
+ temp = (minutes - 1)/QPNP_CHG_TCHG_STEP;
+ return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_TCHG_MAX,
+ QPNP_CHG_I_MASK, temp, 1);
+}
#define QPNP_CHG_VBATDET_MIN_MV 3240
#define QPNP_CHG_VBATDET_MAX_MV 5780
#define QPNP_CHG_VBATDET_STEP_MV 20
@@ -1462,6 +1465,160 @@
chip->flags |= CHG_FLAGS_VCP_WA;
}
+static int
+qpnp_chg_request_irqs(struct qpnp_chg_chip *chip)
+{
+ int rc = 0;
+ struct resource *resource;
+ struct spmi_resource *spmi_resource;
+ u8 subtype;
+ struct spmi_device *spmi = chip->spmi;
+
+ spmi_for_each_container_dev(spmi_resource, chip->spmi) {
+ if (!spmi_resource) {
+ pr_err("qpnp_chg: spmi resource absent\n");
+ return rc;
+ }
+
+ resource = spmi_get_resource(spmi, spmi_resource,
+ IORESOURCE_MEM, 0);
+ if (!(resource && resource->start)) {
+ pr_err("node %s IO resource absent!\n",
+ spmi->dev.of_node->full_name);
+ return rc;
+ }
+
+ rc = qpnp_chg_read(chip, &subtype,
+ resource->start + REG_OFFSET_PERP_SUBTYPE, 1);
+ if (rc) {
+ pr_err("Peripheral subtype read failed rc=%d\n", rc);
+ return rc;
+ }
+
+ switch (subtype) {
+ case SMBB_CHGR_SUBTYPE:
+ case SMBBP_CHGR_SUBTYPE:
+ case SMBCL_CHGR_SUBTYPE:
+ chip->chg_fastchg_irq = spmi_get_irq_byname(spmi,
+ spmi_resource, "fast-chg-on");
+ if (chip->chg_fastchg_irq < 0) {
+ pr_err("Unable to get fast-chg-on irq\n");
+ return rc;
+ }
+
+ chip->chg_trklchg_irq = spmi_get_irq_byname(spmi,
+ spmi_resource, "trkl-chg-on");
+ if (chip->chg_trklchg_irq < 0) {
+ pr_err("Unable to get trkl-chg-on irq\n");
+ return rc;
+ }
+
+ chip->chg_failed_irq = spmi_get_irq_byname(spmi,
+ spmi_resource, "chg-failed");
+ if (chip->chg_failed_irq < 0) {
+ pr_err("Unable to get chg_failed irq\n");
+ return rc;
+ }
+
+ rc |= devm_request_irq(chip->dev, chip->chg_failed_irq,
+ qpnp_chg_chgr_chg_failed_irq_handler,
+ IRQF_TRIGGER_RISING, "chg_failed", chip);
+ if (rc < 0) {
+ pr_err("Can't request %d chg_failed chg: %d\n",
+ chip->chg_failed_irq, rc);
+ return rc;
+ }
+
+ rc |= devm_request_irq(chip->dev, chip->chg_fastchg_irq,
+ qpnp_chg_chgr_chg_fastchg_irq_handler,
+ IRQF_TRIGGER_RISING,
+ "fast-chg-on", chip);
+ if (rc < 0) {
+ pr_err("Can't request %d fast-chg-on: %d\n",
+ chip->chg_fastchg_irq, rc);
+ return rc;
+ }
+
+ rc |= devm_request_irq(chip->dev, chip->chg_trklchg_irq,
+ qpnp_chg_chgr_chg_trklchg_irq_handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "fast-chg-on", chip);
+ if (rc < 0) {
+ pr_err("Can't request %d trkl-chg-on: %d\n",
+ chip->chg_trklchg_irq, rc);
+ return rc;
+ }
+ enable_irq_wake(chip->chg_fastchg_irq);
+ enable_irq_wake(chip->chg_trklchg_irq);
+ enable_irq_wake(chip->chg_failed_irq);
+
+ break;
+ case SMBB_BAT_IF_SUBTYPE:
+ case SMBBP_BAT_IF_SUBTYPE:
+ case SMBCL_BAT_IF_SUBTYPE:
+ chip->batt_pres_irq = spmi_get_irq_byname(spmi,
+ spmi_resource, "batt-pres");
+ if (chip->batt_pres_irq < 0) {
+ pr_err("Unable to get batt-pres irq\n");
+ return rc;
+ }
+ rc = devm_request_irq(chip->dev, chip->batt_pres_irq,
+ qpnp_chg_bat_if_batt_pres_irq_handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "bat_if_batt_pres", chip);
+ if (rc < 0) {
+ pr_err("Can't request %d batt-pres irq: %d\n",
+ chip->batt_pres_irq, rc);
+ return rc;
+ }
+
+ enable_irq_wake(chip->batt_pres_irq);
+ break;
+ case SMBB_USB_CHGPTH_SUBTYPE:
+ case SMBBP_USB_CHGPTH_SUBTYPE:
+ case SMBCL_USB_CHGPTH_SUBTYPE:
+ chip->usbin_valid_irq = spmi_get_irq_byname(spmi,
+ spmi_resource, "usbin-valid");
+ if (chip->usbin_valid_irq < 0) {
+ pr_err("Unable to get usbin irq\n");
+ return rc;
+ }
+ rc = devm_request_irq(chip->dev, chip->usbin_valid_irq,
+ qpnp_chg_usb_usbin_valid_irq_handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "chg_usbin_valid", chip);
+ if (rc < 0) {
+ pr_err("Can't request %d usbinvalid: %d\n",
+ chip->usbin_valid_irq, rc);
+ return rc;
+ }
+ enable_irq_wake(chip->usbin_valid_irq);
+ break;
+ case SMBB_DC_CHGPTH_SUBTYPE:
+ chip->dcin_valid_irq = spmi_get_irq_byname(spmi,
+ spmi_resource, "dcin-valid");
+ if (chip->dcin_valid_irq < 0) {
+ pr_err("Unable to get dcin irq\n");
+ return -rc;
+ }
+ rc = devm_request_irq(chip->dev, chip->dcin_valid_irq,
+ qpnp_chg_dc_dcin_valid_irq_handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "chg_dcin_valid", chip);
+ if (rc < 0) {
+ pr_err("Can't request %d dcinvalid: %d\n",
+ chip->dcin_valid_irq, rc);
+ return rc;
+ }
+
+ enable_irq_wake(chip->dcin_valid_irq);
+ break;
+ }
+ }
+
+ return rc;
+}
+
#define WDOG_EN_BIT BIT(7)
static int
qpnp_chg_hwinit(struct qpnp_chg_chip *chip, u8 subtype,
@@ -1473,73 +1630,7 @@
switch (subtype) {
case SMBB_CHGR_SUBTYPE:
case SMBBP_CHGR_SUBTYPE:
- chip->chg_done_irq = spmi_get_irq_byname(chip->spmi,
- spmi_resource, "chg-done");
- if (chip->chg_done_irq < 0) {
- pr_err("Unable to get chg_done irq\n");
- return -ENXIO;
- }
-
- chip->chg_fastchg_irq = spmi_get_irq_byname(chip->spmi,
- spmi_resource, "fast-chg-on");
- if (chip->chg_fastchg_irq < 0) {
- pr_err("Unable to get fast-chg-on irq\n");
- return -ENXIO;
- }
-
- chip->chg_trklchg_irq = spmi_get_irq_byname(chip->spmi,
- spmi_resource, "trkl-chg-on");
- if (chip->chg_trklchg_irq < 0) {
- pr_err("Unable to get trkl-chg-on irq\n");
- return -ENXIO;
- }
-
- chip->chg_failed_irq = spmi_get_irq_byname(chip->spmi,
- spmi_resource, "chg-failed");
- if (chip->chg_failed_irq < 0) {
- pr_err("Unable to get chg_failed irq\n");
- return -ENXIO;
- }
-
- rc |= devm_request_irq(chip->dev, chip->chg_done_irq,
- qpnp_chg_chgr_chg_done_irq_handler,
- IRQF_TRIGGER_RISING,
- "chg_done", chip);
- if (rc < 0) {
- pr_err("Can't request %d chg_done for chg: %d\n",
- chip->chg_done_irq, rc);
- return -ENXIO;
- }
-
- rc |= devm_request_irq(chip->dev, chip->chg_failed_irq,
- qpnp_chg_chgr_chg_failed_irq_handler,
- IRQF_TRIGGER_RISING, "chg_failed", chip);
- if (rc < 0) {
- pr_err("Can't request %d chg_failed chg: %d\n",
- chip->chg_failed_irq, rc);
- return -ENXIO;
- }
-
- rc |= devm_request_irq(chip->dev, chip->chg_fastchg_irq,
- qpnp_chg_chgr_chg_fastchg_irq_handler,
- IRQF_TRIGGER_RISING,
- "fast-chg-on", chip);
- if (rc < 0) {
- pr_err("Can't request %d fast-chg-on for chg: %d\n",
- chip->chg_fastchg_irq, rc);
- return -ENXIO;
- }
-
- rc |= devm_request_irq(chip->dev, chip->chg_trklchg_irq,
- qpnp_chg_chgr_chg_trklchg_irq_handler,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- "fast-chg-on", chip);
- if (rc < 0) {
- pr_err("Can't request %d trkl-chg-on for chg: %d\n",
- chip->chg_trklchg_irq, rc);
- return -ENXIO;
- }
-
+ case SMBCL_CHGR_SUBTYPE:
rc = qpnp_chg_vinmin_set(chip, chip->min_voltage_mv);
if (rc) {
pr_debug("failed setting min_voltage rc=%d\n", rc);
@@ -1578,6 +1669,12 @@
pr_debug("failed setting ibat_Safe rc=%d\n", rc);
return rc;
}
+ rc = qpnp_chg_tchg_max_set(chip, chip->tchg_mins);
+ if (rc) {
+ pr_debug("failed setting tchg_mins rc=%d\n", rc);
+ return rc;
+ }
+
/* HACK: Disable wdog */
rc = qpnp_chg_masked_write(chip, chip->chgr_base + 0x62,
0xFF, 0xA0, 1);
@@ -1587,13 +1684,10 @@
CHGR_IBAT_TERM_CHGR,
0x88, 0x80, 1);
- enable_irq_wake(chip->chg_fastchg_irq);
- enable_irq_wake(chip->chg_trklchg_irq);
- enable_irq_wake(chip->chg_failed_irq);
- enable_irq_wake(chip->chg_done_irq);
break;
case SMBB_BUCK_SUBTYPE:
case SMBBP_BUCK_SUBTYPE:
+ case SMBCL_BUCK_SUBTYPE:
rc = qpnp_chg_masked_write(chip,
chip->chgr_base + CHGR_BUCK_BCK_VBAT_REG_MODE,
BUCK_VBAT_REG_NODE_SEL_BIT,
@@ -1605,43 +1699,11 @@
break;
case SMBB_BAT_IF_SUBTYPE:
case SMBBP_BAT_IF_SUBTYPE:
- chip->batt_pres_irq = spmi_get_irq_byname(chip->spmi,
- spmi_resource, "batt-pres");
- if (chip->batt_pres_irq < 0) {
- pr_err("Unable to get batt-pres irq\n");
- return -ENXIO;
- }
- rc = devm_request_irq(chip->dev, chip->batt_pres_irq,
- qpnp_chg_bat_if_batt_pres_irq_handler,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- "bat_if_batt_pres", chip);
- if (rc < 0) {
- pr_err("Can't request %d batt-pres irq for chg: %d\n",
- chip->batt_pres_irq, rc);
- return -ENXIO;
- }
-
- enable_irq_wake(chip->batt_pres_irq);
+ case SMBCL_BAT_IF_SUBTYPE:
break;
case SMBB_USB_CHGPTH_SUBTYPE:
case SMBBP_USB_CHGPTH_SUBTYPE:
- chip->usbin_valid_irq = spmi_get_irq_byname(chip->spmi,
- spmi_resource, "usbin-valid");
- if (chip->usbin_valid_irq < 0) {
- pr_err("Unable to get usbin irq\n");
- return -ENXIO;
- }
- rc = devm_request_irq(chip->dev, chip->usbin_valid_irq,
- qpnp_chg_usb_usbin_valid_irq_handler,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- "chg_usbin_valid", chip);
- if (rc < 0) {
- pr_err("Can't request %d usbinvalid for chg: %d\n",
- chip->usbin_valid_irq, rc);
- return -ENXIO;
- }
-
- enable_irq_wake(chip->usbin_valid_irq);
+ case SMBCL_USB_CHGPTH_SUBTYPE:
chip->usb_present = qpnp_chg_is_usb_chg_plugged_in(chip);
if (chip->usb_present) {
rc = qpnp_chg_masked_write(chip,
@@ -1666,23 +1728,6 @@
break;
case SMBB_DC_CHGPTH_SUBTYPE:
- chip->dcin_valid_irq = spmi_get_irq_byname(chip->spmi,
- spmi_resource, "dcin-valid");
- if (chip->dcin_valid_irq < 0) {
- pr_err("Unable to get dcin irq\n");
- return -ENXIO;
- }
- rc = devm_request_irq(chip->dev, chip->dcin_valid_irq,
- qpnp_chg_dc_dcin_valid_irq_handler,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- "chg_dcin_valid", chip);
- if (rc < 0) {
- pr_err("Can't request %d dcinvalid for chg: %d\n",
- chip->dcin_valid_irq, rc);
- return -ENXIO;
- }
-
- enable_irq_wake(chip->dcin_valid_irq);
break;
case SMBB_BOOST_SUBTYPE:
case SMBBP_BOOST_SUBTYPE:
@@ -1691,6 +1736,8 @@
chip->type = SMBB;
case SMBBP_MISC_SUBTYPE:
chip->type = SMBBP;
+ case SMBCL_MISC_SUBTYPE:
+ chip->type = SMBCL;
pr_debug("Setting BOOT_DONE\n");
rc = qpnp_chg_masked_write(chip,
chip->misc_base + CHGR_MISC_BOOT_DONE,
@@ -1710,6 +1757,100 @@
return rc;
}
+#define OF_PROP_READ(chip, prop, qpnp_dt_property, retval, optional) \
+do { \
+ if (retval) \
+ break; \
+ \
+ retval = of_property_read_u32(chip->spmi->dev.of_node, \
+ "qcom," qpnp_dt_property, \
+ &chip->prop); \
+ \
+ if ((retval == -EINVAL) && optional) \
+ retval = 0; \
+ else if (retval) \
+ pr_err("Error reading " #qpnp_dt_property \
+ " property rc = %d\n", rc); \
+} while (0)
+
+static int
+qpnp_charger_read_dt_props(struct qpnp_chg_chip *chip)
+{
+ int rc = 0;
+
+ OF_PROP_READ(chip, max_voltage_mv, "vddmax-mv", rc, 0);
+ OF_PROP_READ(chip, min_voltage_mv, "vinmin-mv", rc, 0);
+ OF_PROP_READ(chip, safe_voltage_mv, "vddsafe-mv", rc, 0);
+ OF_PROP_READ(chip, resume_delta_mv, "vbatdet-delta-mv", rc, 0);
+ OF_PROP_READ(chip, safe_current, "ibatsafe-ma", rc, 0);
+ OF_PROP_READ(chip, max_bat_chg_current, "ibatmax-ma", rc, 0);
+ if (rc)
+ pr_err("failed to read required dt parameters %d\n", rc);
+
+ OF_PROP_READ(chip, term_current, "ibatterm-ma", rc, 1);
+ OF_PROP_READ(chip, maxinput_dc_ma, "maxinput-dc-ma", rc, 1);
+ OF_PROP_READ(chip, maxinput_usb_ma, "maxinput-usb-ma", rc, 1);
+ OF_PROP_READ(chip, warm_bat_decidegc, "warm-bat-decidegc", rc, 1);
+ OF_PROP_READ(chip, cool_bat_decidegc, "cool-bat-decidegc", rc, 1);
+ OF_PROP_READ(chip, tchg_mins, "tchg-mins", rc, 1);
+ if (rc)
+ return rc;
+
+ /* Look up JEITA compliance parameters if cool and warm temp provided */
+ if (chip->cool_bat_decidegc && chip->warm_bat_decidegc) {
+ rc = qpnp_adc_tm_is_ready();
+ if (rc) {
+ pr_err("tm not ready %d\n", rc);
+ return rc;
+ }
+
+ OF_PROP_READ(chip, warm_bat_chg_ma, "ibatmax-warm-ma", rc, 1);
+ OF_PROP_READ(chip, cool_bat_chg_ma, "ibatmax-cool-ma", rc, 1);
+ OF_PROP_READ(chip, warm_bat_mv, "warm-bat-mv", rc, 1);
+ OF_PROP_READ(chip, cool_bat_mv, "cool-bat-mv", rc, 1);
+ if (rc)
+ return rc;
+ }
+
+ /* Get the charging-disabled property */
+ chip->charging_disabled = of_property_read_bool(chip->spmi->dev.of_node,
+ "qcom,charging-disabled");
+
+ /* Get the fake-batt-values property */
+ chip->use_default_batt_values =
+ of_property_read_bool(chip->spmi->dev.of_node,
+ "qcom,use-default-batt-values");
+
+ /* Disable charging when faking battery values */
+ if (chip->use_default_batt_values)
+ chip->charging_disabled = true;
+
+ of_get_property(chip->spmi->dev.of_node, "qcom,thermal-mitigation",
+ &(chip->thermal_levels));
+
+ if (chip->thermal_levels > sizeof(int)) {
+ chip->thermal_mitigation = kzalloc(
+ chip->thermal_levels,
+ GFP_KERNEL);
+
+ if (chip->thermal_mitigation == NULL) {
+ pr_err("thermal mitigation kzalloc() failed.\n");
+ return rc;
+ }
+
+ chip->thermal_levels /= sizeof(int);
+ rc = of_property_read_u32_array(chip->spmi->dev.of_node,
+ "qcom,thermal-mitigation",
+ chip->thermal_mitigation, chip->thermal_levels);
+ if (rc) {
+ pr_err("qcom,thermal-mitigation missing in dt\n");
+ return rc;
+ }
+ }
+
+ return rc;
+}
+
static int __devinit
qpnp_charger_probe(struct spmi_device *spmi)
{
@@ -1736,178 +1877,10 @@
goto fail_chg_enable;
}
- /* Get the vddmax property */
- rc = of_property_read_u32(spmi->dev.of_node, "qcom,vddmax-mv",
- &chip->max_voltage_mv);
- if (rc) {
- pr_err("Error reading vddmax property %d\n", rc);
+ /* Get all device tree properties */
+ rc = qpnp_charger_read_dt_props(chip);
+ if (rc)
goto fail_chg_enable;
- }
-
- /* Get the vinmin property */
- rc = of_property_read_u32(spmi->dev.of_node, "qcom,vinmin-mv",
- &chip->min_voltage_mv);
- if (rc) {
- pr_err("Error reading vddmax property %d\n", rc);
- goto fail_chg_enable;
- }
-
- /* Get the vddmax property */
- rc = of_property_read_u32(spmi->dev.of_node, "qcom,vddsafe-mv",
- &chip->safe_voltage_mv);
- if (rc) {
- pr_err("Error reading vddsave property %d\n", rc);
- goto fail_chg_enable;
- }
-
- /* Get the vbatdet-delta property */
- rc = of_property_read_u32(spmi->dev.of_node,
- "qcom,vbatdet-delta-mv",
- &chip->resume_delta_mv);
- if (rc && rc != -EINVAL) {
- pr_err("Error reading vbatdet-delta property %d\n", rc);
- goto fail_chg_enable;
- }
-
- /* Get the ibatsafe property */
- rc = of_property_read_u32(spmi->dev.of_node,
- "qcom,ibatsafe-ma",
- &chip->safe_current);
- if (rc) {
- pr_err("Error reading ibatsafe property %d\n", rc);
- goto fail_chg_enable;
- }
-
- /* Get the ibatterm property */
- rc = of_property_read_u32(spmi->dev.of_node,
- "qcom,ibatterm-ma",
- &chip->term_current);
- if (rc && rc != -EINVAL) {
- pr_err("Error reading ibatterm property %d\n", rc);
- goto fail_chg_enable;
- }
-
- /* Get the ibatmax property */
- rc = of_property_read_u32(spmi->dev.of_node, "qcom,ibatmax-ma",
- &chip->max_bat_chg_current);
- if (rc) {
- pr_err("Error reading ibatmax property %d\n", rc);
- goto fail_chg_enable;
- }
-
- /* Get the maxinput-dc-ma property */
- rc = of_property_read_u32(spmi->dev.of_node,
- "qcom,maxinput-dc-ma",
- &chip->maxinput_dc_ma);
- if (rc && rc != -EINVAL) {
- pr_err("Error reading maxinput-dc-ma property %d\n", rc);
- goto fail_chg_enable;
- }
-
- /* Get the maxinput-usb-ma property */
- rc = of_property_read_u32(spmi->dev.of_node,
- "qcom,maxinput-usb-ma",
- &chip->maxinput_usb_ma);
- if (rc && rc != -EINVAL) {
- pr_err("Error reading maxinput-usb-ma property %d\n", rc);
- goto fail_chg_enable;
- }
-
- /* Get the charging-disabled property */
- chip->charging_disabled = of_property_read_bool(spmi->dev.of_node,
- "qcom,charging-disabled");
-
- /* Get the warm-bat-degc property */
- rc = of_property_read_u32(spmi->dev.of_node,
- "qcom,warm-bat-decidegc",
- &chip->warm_bat_decidegc);
- if (rc && rc != -EINVAL) {
- pr_err("Error reading warm-bat-degc property %d\n", rc);
- goto fail_chg_enable;
- }
-
- /* Get the cool-bat-degc property */
- rc = of_property_read_u32(spmi->dev.of_node,
- "qcom,cool-bat-decidegc",
- &chip->cool_bat_decidegc);
- if (rc && rc != -EINVAL) {
- pr_err("Error reading cool-bat-degc property %d\n", rc);
- goto fail_chg_enable;
- }
-
- if (chip->cool_bat_decidegc && chip->warm_bat_decidegc) {
- rc = qpnp_adc_tm_is_ready();
- if (rc) {
- pr_err("tm not ready %d\n", rc);
- goto fail_chg_enable;
- }
-
- /* Get the ibatmax-warm property */
- rc = of_property_read_u32(spmi->dev.of_node,
- "qcom,ibatmax-warm-ma",
- &chip->warm_bat_chg_ma);
- if (rc) {
- pr_err("Error reading ibatmax-warm-ma %d\n", rc);
- goto fail_chg_enable;
- }
-
- /* Get the ibatmax-cool property */
- rc = of_property_read_u32(spmi->dev.of_node,
- "qcom,ibatmax-cool-ma",
- &chip->cool_bat_chg_ma);
- if (rc) {
- pr_err("Error reading ibatmax-cool-ma %d\n", rc);
- goto fail_chg_enable;
- }
- /* Get the cool-bat-mv property */
- rc = of_property_read_u32(spmi->dev.of_node,
- "qcom,cool-bat-mv",
- &chip->cool_bat_mv);
- if (rc) {
- pr_err("Error reading cool-bat-mv property %d\n", rc);
- goto fail_chg_enable;
- }
-
- /* Get the warm-bat-mv property */
- rc = of_property_read_u32(spmi->dev.of_node,
- "qcom,warm-bat-mv",
- &chip->warm_bat_mv);
- if (rc) {
- pr_err("Error reading warm-bat-mv property %d\n", rc);
- goto fail_chg_enable;
- }
- }
-
- /* Get the fake-batt-values property */
- chip->use_default_batt_values = of_property_read_bool(spmi->dev.of_node,
- "qcom,use-default-batt-values");
-
- of_get_property(spmi->dev.of_node, "qcom,thermal-mitigation",
- &(chip->thermal_levels));
-
- if (chip->thermal_levels > sizeof(int)) {
- chip->thermal_mitigation = kzalloc(
- chip->thermal_levels,
- GFP_KERNEL);
-
- if (chip->thermal_mitigation == NULL) {
- pr_err("thermal mitigation kzalloc() failed.\n");
- goto fail_chg_enable;
- }
-
- chip->thermal_levels /= sizeof(int);
- rc = of_property_read_u32_array(spmi->dev.of_node,
- "qcom,thermal-mitigation",
- chip->thermal_mitigation, chip->thermal_levels);
- if (rc) {
- pr_err("qcom,thermal-mitigation missing in dt\n");
- goto fail_chg_enable;
- }
- }
-
- /* Disable charging when faking battery values */
- if (chip->use_default_batt_values)
- chip->charging_disabled = true;
spmi_for_each_container_dev(spmi_resource, spmi) {
if (!spmi_resource) {
@@ -1935,6 +1908,7 @@
switch (subtype) {
case SMBB_CHGR_SUBTYPE:
case SMBBP_CHGR_SUBTYPE:
+ case SMBCL_CHGR_SUBTYPE:
chip->chgr_base = resource->start;
rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
if (rc) {
@@ -1945,6 +1919,7 @@
break;
case SMBB_BUCK_SUBTYPE:
case SMBBP_BUCK_SUBTYPE:
+ case SMBCL_BUCK_SUBTYPE:
chip->buck_base = resource->start;
rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
if (rc) {
@@ -1955,6 +1930,7 @@
break;
case SMBB_BAT_IF_SUBTYPE:
case SMBBP_BAT_IF_SUBTYPE:
+ case SMBCL_BAT_IF_SUBTYPE:
chip->bat_if_base = resource->start;
rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
if (rc) {
@@ -1965,6 +1941,7 @@
break;
case SMBB_USB_CHGPTH_SUBTYPE:
case SMBBP_USB_CHGPTH_SUBTYPE:
+ case SMBCL_USB_CHGPTH_SUBTYPE:
chip->usb_chgpth_base = resource->start;
rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
if (rc) {
@@ -1994,6 +1971,7 @@
break;
case SMBB_MISC_SUBTYPE:
case SMBBP_MISC_SUBTYPE:
+ case SMBCL_MISC_SUBTYPE:
chip->misc_base = resource->start;
rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
if (rc) {
@@ -2097,6 +2075,12 @@
qpnp_chg_charge_en(chip, !chip->charging_disabled);
qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
+ rc = qpnp_chg_request_irqs(chip);
+ if (rc) {
+ pr_err("failed to request interrupts %d\n", rc);
+ goto unregister_batt;
+ }
+
pr_info("success chg_dis = %d, usb = %d, dc = %d b_health = %d batt_present = %d\n",
chip->charging_disabled,
qpnp_chg_is_usb_chg_plugged_in(chip),
diff --git a/drivers/thermal/msm8974-tsens.c b/drivers/thermal/msm8974-tsens.c
index 676f69d..95378c5 100644
--- a/drivers/thermal/msm8974-tsens.c
+++ b/drivers/thermal/msm8974-tsens.c
@@ -284,7 +284,7 @@
while (i < tmdev->tsens_num_sensor && !id_found) {
if (sensor_hw_num == tmdev->sensor[i].sensor_hw_num) {
- *sensor_sw_idx = i;
+ *sensor_sw_idx = tmdev->sensor[i].sensor_sw_id;
id_found = true;
}
i++;
@@ -304,7 +304,7 @@
while (i < tmdev->tsens_num_sensor && !id_found) {
if (sensor_sw_id == tmdev->sensor[i].sensor_sw_id) {
- *sensor_hw_num = i;
+ *sensor_hw_num = tmdev->sensor[i].sensor_hw_num;
id_found = true;
}
i++;
@@ -1373,12 +1373,16 @@
"qcom,sensor-id", sensor_id, tsens_num_sensors);
if (rc) {
pr_debug("Default sensor id mapping\n");
- for (i = 0; i < tsens_num_sensors; i++)
+ for (i = 0; i < tsens_num_sensors; i++) {
tmdev->sensor[i].sensor_hw_num = i;
+ tmdev->sensor[i].sensor_sw_id = i;
+ }
} else {
pr_debug("Use specified sensor id mapping\n");
- for (i = 0; i < tsens_num_sensors; i++)
+ for (i = 0; i < tsens_num_sensors; i++) {
tmdev->sensor[i].sensor_hw_num = sensor_id[i];
+ tmdev->sensor[i].sensor_sw_id = i;
+ }
}
tmdev->tsens_irq = platform_get_irq(pdev, 0);
diff --git a/drivers/thermal/qpnp-adc-tm.c b/drivers/thermal/qpnp-adc-tm.c
index e7d2e0f..d848a18 100644
--- a/drivers/thermal/qpnp-adc-tm.c
+++ b/drivers/thermal/qpnp-adc-tm.c
@@ -36,6 +36,8 @@
/* QPNP VADC TM register definition */
#define QPNP_REVISION3 0x2
+#define QPNP_PERPH_SUBTYPE 0x5
+#define QPNP_PERPH_TYPE2 0x2
#define QPNP_REVISION_EIGHT_CHANNEL_SUPPORT 2
#define QPNP_STATUS1 0x8
#define QPNP_STATUS1_OP_MODE 4
@@ -366,7 +368,7 @@
static int32_t qpnp_adc_tm_check_revision(uint32_t btm_chan_num)
{
- u8 rev;
+ u8 rev, perph_subtype;
int rc = 0;
rc = qpnp_adc_tm_read_reg(QPNP_REVISION3, &rev);
@@ -375,10 +377,18 @@
return rc;
}
- if ((rev < QPNP_REVISION_EIGHT_CHANNEL_SUPPORT) &&
- (btm_chan_num > QPNP_ADC_TM_M4_ADC_CH_SEL_CTL)) {
- pr_debug("Version does not support more than 5 channels\n");
- return -EINVAL;
+ rc = qpnp_adc_tm_read_reg(QPNP_PERPH_SUBTYPE, &perph_subtype);
+ if (rc) {
+ pr_err("adc-tm perph_subtype read failed\n");
+ return rc;
+ }
+
+ if (perph_subtype == QPNP_PERPH_TYPE2) {
+ if ((rev < QPNP_REVISION_EIGHT_CHANNEL_SUPPORT) &&
+ (btm_chan_num > QPNP_ADC_TM_M4_ADC_CH_SEL_CTL)) {
+ pr_debug("Version does not support more than 5 channels\n");
+ return -EINVAL;
+ }
}
return rc;
@@ -1584,6 +1594,8 @@
adc_tm->sensor[sen_idx].sensor_num = sen_idx;
pr_debug("btm_chan:%x, vadc_chan:%x\n", btm_channel_num,
adc_tm->adc->adc_channels[sen_idx].channel_num);
+ thermal_node = of_property_read_bool(child,
+ "qcom,thermal-node");
if (thermal_node) {
/* Register with the thermal zone */
pr_debug("thermal node%x\n", btm_channel_num);
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 6619e96..fc8f4b3 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -475,6 +475,7 @@
void *mem;
u8 mode;
+ bool host_only_mode;
mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
if (!mem) {
@@ -548,6 +549,7 @@
dwc->maximum_speed = DWC3_DCFG_SUPERSPEED;
dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
+ host_only_mode = of_property_read_bool(node, "host-only-mode");
pm_runtime_no_callbacks(dev);
pm_runtime_set_active(dev);
@@ -561,6 +563,12 @@
mode = DWC3_MODE(dwc->hwparams.hwparams0);
+ /* Override mode if user selects host-only config with DRD core */
+ if (host_only_mode && (mode == DWC3_MODE_DRD)) {
+ dev_dbg(dev, "host only mode selected\n");
+ mode = DWC3_MODE_HOST;
+ }
+
switch (mode) {
case DWC3_MODE_DEVICE:
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 7a6765b..5bbf106 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -177,6 +177,9 @@
struct regulator *hsusb_vddcx;
struct regulator *ssusb_1p8;
struct regulator *ssusb_vddcx;
+
+ /* VBUS regulator if no OTG and running in host only mode */
+ struct regulator *vbus_otg;
struct dwc3_ext_xceiv ext_xceiv;
bool resume_pending;
atomic_t pm_suspended;
@@ -1606,7 +1609,8 @@
0x37, 0x0);
}
- dcp = mdwc->charger.chg_type == DWC3_DCP_CHARGER;
+ dcp = ((mdwc->charger.chg_type == DWC3_DCP_CHARGER) ||
+ (mdwc->charger.chg_type == DWC3_PROPRIETARY_CHARGER));
host_bus_suspend = mdwc->host_mode == 1;
/* Sequence to put SSPHY in low power state:
@@ -1684,15 +1688,19 @@
dwc3_ssusb_ldo_enable(0);
dwc3_ssusb_config_vddcx(0);
- if (!host_bus_suspend)
+ if (!host_bus_suspend && !dcp)
dwc3_hsusb_config_vddcx(0);
wake_unlock(&mdwc->wlock);
atomic_set(&mdwc->in_lpm, 1);
dev_info(mdwc->dev, "DWC3 in low power mode\n");
- if (mdwc->hs_phy_irq)
+ if (mdwc->hs_phy_irq) {
enable_irq(mdwc->hs_phy_irq);
+ /* with DCP we dont require wakeup using HS_PHY_IRQ */
+ if (dcp)
+ disable_irq_wake(mdwc->hs_phy_irq);
+ }
return 0;
}
@@ -1719,7 +1727,8 @@
dev_err(mdwc->dev, "Failed to vote for bus scaling\n");
}
- dcp = mdwc->charger.chg_type == DWC3_DCP_CHARGER;
+ dcp = ((mdwc->charger.chg_type == DWC3_DCP_CHARGER) ||
+ (mdwc->charger.chg_type == DWC3_PROPRIETARY_CHARGER));
host_bus_suspend = mdwc->host_mode == 1;
if (!host_bus_suspend) {
@@ -1728,6 +1737,8 @@
if (ret)
dev_err(mdwc->dev, "%s failed to vote TCXO buffer%d\n",
__func__, ret);
+
+ clk_prepare_enable(mdwc->utmi_clk);
}
if (mdwc->otg_xceiv && mdwc->ext_xceiv.otg_capability && !dcp &&
@@ -1737,10 +1748,8 @@
dwc3_ssusb_ldo_enable(1);
dwc3_ssusb_config_vddcx(1);
- if (!host_bus_suspend) {
+ if (!host_bus_suspend && !dcp)
dwc3_hsusb_config_vddcx(1);
- clk_prepare_enable(mdwc->utmi_clk);
- }
clk_prepare_enable(mdwc->ref_clk);
usleep_range(1000, 1200);
@@ -1809,6 +1818,9 @@
enable_irq(mdwc->hs_phy_irq);
mdwc->lpm_irq_seen = false;
}
+ /* it must DCP disconnect, re-enable HS_PHY wakeup IRQ */
+ if (mdwc->hs_phy_irq && dcp)
+ enable_irq_wake(mdwc->hs_phy_irq);
dev_info(mdwc->dev, "DWC3 exited from low power mode\n");
@@ -1838,7 +1850,7 @@
if (mdwc->otg_xceiv)
mdwc->ext_xceiv.notify_ext_events(mdwc->otg_xceiv->otg,
DWC3_EVENT_PHY_RESUME);
- pm_runtime_put_sync(mdwc->dev);
+ pm_runtime_put_noidle(mdwc->dev);
if (mdwc->otg_xceiv && (mdwc->ext_xceiv.otg_capability))
mdwc->ext_xceiv.notify_ext_events(mdwc->otg_xceiv->otg,
DWC3_EVENT_XCEIV_STATE);
@@ -2529,24 +2541,28 @@
goto disable_hs_ldo;
}
- msm->usb_psy.name = "usb";
- msm->usb_psy.type = POWER_SUPPLY_TYPE_USB;
- msm->usb_psy.supplied_to = dwc3_msm_pm_power_supplied_to;
- msm->usb_psy.num_supplicants = ARRAY_SIZE(
- dwc3_msm_pm_power_supplied_to);
- msm->usb_psy.properties = dwc3_msm_pm_power_props_usb;
- msm->usb_psy.num_properties = ARRAY_SIZE(dwc3_msm_pm_power_props_usb);
- msm->usb_psy.get_property = dwc3_msm_power_get_property_usb;
- msm->usb_psy.set_property = dwc3_msm_power_set_property_usb;
- msm->usb_psy.external_power_changed =
- dwc3_msm_external_power_changed;
+ /* usb_psy required only for vbus_notifications or charging support */
+ if (msm->ext_xceiv.otg_capability || !msm->charger.charging_disabled) {
+ msm->usb_psy.name = "usb";
+ msm->usb_psy.type = POWER_SUPPLY_TYPE_USB;
+ msm->usb_psy.supplied_to = dwc3_msm_pm_power_supplied_to;
+ msm->usb_psy.num_supplicants = ARRAY_SIZE(
+ dwc3_msm_pm_power_supplied_to);
+ msm->usb_psy.properties = dwc3_msm_pm_power_props_usb;
+ msm->usb_psy.num_properties =
+ ARRAY_SIZE(dwc3_msm_pm_power_props_usb);
+ msm->usb_psy.get_property = dwc3_msm_power_get_property_usb;
+ msm->usb_psy.set_property = dwc3_msm_power_set_property_usb;
+ msm->usb_psy.external_power_changed =
+ dwc3_msm_external_power_changed;
- ret = power_supply_register(&pdev->dev, &msm->usb_psy);
- if (ret < 0) {
- dev_err(&pdev->dev,
- "%s:power_supply_register usb failed\n",
- __func__);
- goto disable_hs_ldo;
+ ret = power_supply_register(&pdev->dev, &msm->usb_psy);
+ if (ret < 0) {
+ dev_err(&pdev->dev,
+ "%s:power_supply_register usb failed\n",
+ __func__);
+ goto disable_hs_ldo;
+ }
}
if (node) {
@@ -2571,7 +2587,8 @@
}
msm->otg_xceiv = usb_get_transceiver();
- if (msm->otg_xceiv) {
+ /* Register with OTG if present, ignore USB2 OTG using other PHY */
+ if (msm->otg_xceiv && !(msm->otg_xceiv->flags & ENABLE_SECONDARY_PHY)) {
msm->charger.start_detection = dwc3_start_chg_det;
ret = dwc3_set_charger(msm->otg_xceiv->otg, &msm->charger);
if (ret || !msm->charger.notify_detection_complete) {
@@ -2589,7 +2606,20 @@
goto put_xcvr;
}
} else {
- dev_err(&pdev->dev, "%s: No OTG transceiver found\n", __func__);
+ dev_dbg(&pdev->dev, "No OTG, DWC3 running in host only mode\n");
+ msm->host_mode = 1;
+ msm->vbus_otg = devm_regulator_get(&pdev->dev, "vbus_dwc3");
+ if (IS_ERR(msm->vbus_otg)) {
+ dev_dbg(&pdev->dev, "Failed to get vbus regulator\n");
+ msm->vbus_otg = 0;
+ } else {
+ ret = regulator_enable(msm->vbus_otg);
+ if (ret) {
+ msm->vbus_otg = 0;
+ dev_err(&pdev->dev, "Failed to enable vbus_otg\n");
+ }
+ }
+ msm->otg_xceiv = NULL;
}
wake_lock_init(&msm->wlock, WAKE_LOCK_SUSPEND, "msm_dwc3");
@@ -2601,7 +2631,8 @@
put_xcvr:
usb_put_transceiver(msm->otg_xceiv);
put_psupply:
- power_supply_unregister(&msm->usb_psy);
+ if (msm->usb_psy.dev)
+ power_supply_unregister(&msm->usb_psy);
disable_hs_ldo:
dwc3_hsusb_ldo_enable(0);
free_hs_ldo_init:
@@ -2650,6 +2681,10 @@
dwc3_start_chg_det(&msm->charger, false);
usb_put_transceiver(msm->otg_xceiv);
}
+ if (msm->usb_psy.dev)
+ power_supply_unregister(&msm->usb_psy);
+ if (msm->vbus_otg)
+ regulator_disable(msm->vbus_otg);
pm_runtime_disable(msm->dev);
wake_lock_destroy(&msm->wlock);
diff --git a/drivers/usb/dwc3/dwc3_otg.c b/drivers/usb/dwc3/dwc3_otg.c
index 1d67cee..a3b2617 100644
--- a/drivers/usb/dwc3/dwc3_otg.c
+++ b/drivers/usb/dwc3/dwc3_otg.c
@@ -198,8 +198,6 @@
} else {
dev_dbg(otg->phy->dev, "%s: turn off host\n", __func__);
- platform_device_del(dwc->xhci);
-
ret = regulator_disable(dotg->vbus_otg);
if (ret) {
dev_err(otg->phy->dev, "unable to disable vbus_otg\n");
@@ -207,6 +205,7 @@
}
dwc3_otg_notify_host_mode(otg, on);
+ platform_device_del(dwc->xhci);
/*
* Perform USB hardware RESET (both core reset and DBM reset)
* when moving from host to peripheral. This is required for
diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index d6d8a76..420d030 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -79,6 +79,7 @@
/* Add XHCI device if !OTG, otherwise OTG takes care of this */
if (!dwc->dotg) {
+ xhci->dev.parent = dwc->dev;
ret = platform_device_add(xhci);
if (ret) {
dev_err(dwc->dev, "failed to register xHCI device\n");
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 79dcf2f..46b5ce4 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/usb/otg.h>
+#include <linux/usb/msm_hsusb.h>
#include "xhci.h"
@@ -140,6 +141,10 @@
goto release_mem_region;
}
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+
ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (ret)
goto unmap_registers;
@@ -166,7 +171,8 @@
goto put_usb3_hcd;
phy = usb_get_transceiver();
- if (phy && phy->otg) {
+ /* Register with OTG if present, ignore USB2 OTG using other PHY */
+ if (phy && phy->otg && !(phy->flags & ENABLE_SECONDARY_PHY)) {
dev_dbg(&pdev->dev, "%s otg support available\n", __func__);
ret = otg_set_host(phy->otg, &hcd->self);
if (ret) {
@@ -175,15 +181,12 @@
usb_put_transceiver(phy);
goto put_usb3_hcd;
}
- pm_runtime_set_active(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
} else {
pm_runtime_no_callbacks(&pdev->dev);
- pm_runtime_set_active(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
- pm_runtime_get(&pdev->dev);
}
+ pm_runtime_put(&pdev->dev);
+
return 0;
put_usb3_hcd:
@@ -222,9 +225,6 @@
if (phy && phy->otg) {
otg_set_host(phy->otg, NULL);
usb_put_transceiver(phy);
- } else {
- pm_runtime_put(&dev->dev);
- pm_runtime_disable(&dev->dev);
}
return 0;
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index e8d7489..afa7b97 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -245,7 +245,7 @@
return PTR_ERR(*srcp_ihdl);
}
pr_debug("%s(): ion_hdl %p, ion_buf %d\n", __func__, *srcp_ihdl,
- ion_share_dma_buf(display_iclient, *srcp_ihdl));
+ mem_id);
pr_debug("mixer %u, pipe %u, plane %u\n", pipe->mixer_num,
pipe->pipe_ndx, plane);
if (ion_map_iommu(display_iclient, *srcp_ihdl,
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 763c7f6..04217f5 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -73,6 +73,8 @@
u32 irq_mask;
u32 irq_ena;
u32 irq_buzy;
+ u32 has_bwc;
+ u32 has_decimation;
u32 mdp_irq_mask;
u32 mdp_hist_irq_mask;
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index baedd03..a3be773 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -330,7 +330,6 @@
hw->hw_ndx, mdss_res->mdp_irq_mask,
mdss_res->mdp_hist_irq_mask);
} else {
- mdss_irq_handlers[hw->hw_ndx] = NULL;
mdss_res->irq_mask &= ~ndx_bit;
if (mdss_res->irq_mask == 0) {
mdss_res->irq_ena = false;
@@ -1508,6 +1507,10 @@
&data);
mdata->rot_block_size = (!rc ? data : 128);
+ mdata->has_bwc = of_property_read_bool(pdev->dev.of_node,
+ "qcom,mdss-has-bwc");
+ mdata->has_decimation = of_property_read_bool(pdev->dev.of_node,
+ "qcom,mdss-has-decimation");
return 0;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 175a07f..daa7f1a 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -38,6 +38,7 @@
#define MAX_PLANES 4
#define MAX_DOWNSCALE_RATIO 4
#define MAX_UPSCALE_RATIO 20
+#define MAX_DECIMATION 4
#define C3_ALPHA 3 /* alpha */
#define C2_R_Cr 2 /* R/Cr */
@@ -268,6 +269,8 @@
u16 img_width;
u16 img_height;
+ u8 horz_deci;
+ u8 vert_deci;
struct mdss_mdp_img_rect src;
struct mdss_mdp_img_rect dst;
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 03a33cd..5bc077c 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -1235,6 +1235,7 @@
{
struct mdss_mdp_ctl *ctl;
struct mdss_mdp_mixer *mixer;
+ int i;
if (!pipe)
return -EINVAL;
@@ -1258,7 +1259,12 @@
if (params_changed) {
mixer->params_changed++;
- mixer->stage_pipe[pipe->mixer_stage] = pipe;
+ for (i = 0; i < MDSS_MDP_MAX_STAGE; i++) {
+ if (i == pipe->mixer_stage)
+ mixer->stage_pipe[i] = pipe;
+ else if (mixer->stage_pipe[i] == pipe)
+ mixer->stage_pipe[i] = NULL;
+ }
}
if (pipe->type == MDSS_MDP_PIPE_TYPE_DMA)
diff --git a/drivers/video/msm/mdss/mdss_mdp_formats.h b/drivers/video/msm/mdss/mdss_mdp_formats.h
index c6d5fb9..acb8dc2 100644
--- a/drivers/video/msm/mdss/mdss_mdp_formats.h
+++ b/drivers/video/msm/mdss/mdss_mdp_formats.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -108,6 +108,8 @@
FMT_YUV_COMMON(fmt), \
.fetch_planes = MDSS_MDP_PLANE_PLANAR, \
.chroma_sample = samp, \
+ .bpp = 1, \
+ .unpack_count = 1, \
.element = { (e0), (e1) } \
}
@@ -134,9 +136,9 @@
FMT_YUV_PSEUDO(MDP_Y_CBCR_H2V2_VENUS, MDSS_MDP_CHROMA_420,
C1_B_Cb, C2_R_Cr),
- FMT_YUV_PLANR(MDP_Y_CR_CB_H2V2, MDSS_MDP_CHROMA_420, C2_R_Cr, C1_B_Cb),
- FMT_YUV_PLANR(MDP_Y_CB_CR_H2V2, MDSS_MDP_CHROMA_420, C1_B_Cb, C2_R_Cr),
- FMT_YUV_PLANR(MDP_Y_CR_CB_GH2V2, MDSS_MDP_CHROMA_420, C2_R_Cr, C1_B_Cb),
+ FMT_YUV_PLANR(MDP_Y_CB_CR_H2V2, MDSS_MDP_CHROMA_420, C2_R_Cr, C1_B_Cb),
+ FMT_YUV_PLANR(MDP_Y_CR_CB_H2V2, MDSS_MDP_CHROMA_420, C1_B_Cb, C2_R_Cr),
+ FMT_YUV_PLANR(MDP_Y_CR_CB_GH2V2, MDSS_MDP_CHROMA_420, C1_B_Cb, C2_R_Cr),
{
FMT_YUV_COMMON(MDP_YCBCR_H1V1),
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index d50f47e..ecbdaf0 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -190,8 +190,7 @@
#define MDSS_MDP_REG_SSPP_CURRENT_SRC1_ADDR 0x0A8
#define MDSS_MDP_REG_SSPP_CURRENT_SRC2_ADDR 0x0AC
#define MDSS_MDP_REG_SSPP_CURRENT_SRC3_ADDR 0x0B0
-#define MDSS_MDP_REG_SSPP_LINE_SKIP_STEP_C03 0x0B4
-#define MDSS_MDP_REG_SSPP_LINE_SKIP_STEP_C12 0x0B8
+#define MDSS_MDP_REG_SSPP_DECIMATION_CONFIG 0x0B4
#define MDSS_MDP_REG_VIG_OP_MODE 0x200
#define MDSS_MDP_REG_VIG_QSEED2_CONFIG 0x204
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
index b3f15a7..d86527b 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
@@ -173,28 +173,24 @@
dst_format |= BIT(14); /* DST_ALPHA_X */
}
- if (fmt->fetch_planes != MDSS_MDP_PLANE_PLANAR) {
- mdata = mdss_mdp_get_mdata();
- if (mdata && mdata->mdp_rev >= MDSS_MDP_HW_REV_102) {
- pattern = (fmt->element[3] << 24) |
- (fmt->element[2] << 16) |
- (fmt->element[1] << 8) |
- (fmt->element[0] << 0);
- } else {
- pattern = (fmt->element[3] << 24) |
- (fmt->element[2] << 15) |
- (fmt->element[1] << 8) |
- (fmt->element[0] << 0);
- }
-
- dst_format |= (fmt->unpack_align_msb << 18) |
- (fmt->unpack_tight << 17) |
- ((fmt->unpack_count - 1) << 12) |
- ((fmt->bpp - 1) << 9);
+ mdata = mdss_mdp_get_mdata();
+ if (mdata && mdata->mdp_rev >= MDSS_MDP_HW_REV_102) {
+ pattern = (fmt->element[3] << 24) |
+ (fmt->element[2] << 16) |
+ (fmt->element[1] << 8) |
+ (fmt->element[0] << 0);
} else {
- pattern = 0;
+ pattern = (fmt->element[3] << 24) |
+ (fmt->element[2] << 15) |
+ (fmt->element[1] << 8) |
+ (fmt->element[0] << 0);
}
+ dst_format |= (fmt->unpack_align_msb << 18) |
+ (fmt->unpack_tight << 17) |
+ ((fmt->unpack_count - 1) << 12) |
+ ((fmt->bpp - 1) << 9);
+
ystride0 = (ctx->dst_planes.ystride[0]) |
(ctx->dst_planes.ystride[1] << 16);
ystride1 = (ctx->dst_planes.ystride[2]) |
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 3cce4f9..5fc4cc4 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -98,8 +98,20 @@
return -EOVERFLOW;
}
+ if (req->horz_deci || req->vert_deci) {
+ if (!mdata->has_decimation) {
+ pr_err("No Decimation in MDP V=%x\n", mdata->mdp_rev);
+ return -EINVAL;
+ } else if ((req->horz_deci > MAX_DECIMATION) ||
+ (req->vert_deci > MAX_DECIMATION)) {
+ pr_err("Invalid decimation factors horz=%d vert=%d\n",
+ req->horz_deci, req->vert_deci);
+ return -EINVAL;
+ }
+ }
+
if (!(req->flags & MDSS_MDP_ROT_ONLY)) {
- u32 dst_w, dst_h;
+ u32 src_w, src_h, dst_w, dst_h;
if ((CHECK_BOUNDS(req->dst_rect.x, req->dst_rect.w, xres) ||
CHECK_BOUNDS(req->dst_rect.y, req->dst_rect.h, yres))) {
@@ -117,27 +129,36 @@
dst_h = req->dst_rect.h;
}
- if ((req->src_rect.w * MAX_UPSCALE_RATIO) < dst_w) {
+ src_w = req->src_rect.w >> req->horz_deci;
+ src_h = req->src_rect.h >> req->vert_deci;
+
+ if (src_w > MAX_MIXER_WIDTH) {
+ pr_err("invalid source width=%d HDec=%d\n",
+ req->src_rect.w, req->horz_deci);
+ return -EINVAL;
+ }
+
+ if ((src_w * MAX_UPSCALE_RATIO) < dst_w) {
pr_err("too much upscaling Width %d->%d\n",
req->src_rect.w, req->dst_rect.w);
return -EINVAL;
}
- if ((req->src_rect.h * MAX_UPSCALE_RATIO) < dst_h) {
+ if ((src_h * MAX_UPSCALE_RATIO) < dst_h) {
pr_err("too much upscaling. Height %d->%d\n",
req->src_rect.h, req->dst_rect.h);
return -EINVAL;
}
- if (req->src_rect.w > (dst_w * MAX_DOWNSCALE_RATIO)) {
- pr_err("too much downscaling. Width %d->%d\n",
- req->src_rect.w, req->dst_rect.w);
+ if (src_w > (dst_w * MAX_DOWNSCALE_RATIO)) {
+ pr_err("too much downscaling. Width %d->%d H Dec=%d\n",
+ src_w, req->dst_rect.w, req->horz_deci);
return -EINVAL;
}
- if (req->src_rect.h > (dst_h * MAX_DOWNSCALE_RATIO)) {
- pr_err("too much downscaling. Height %d->%d\n",
- req->src_rect.h, req->dst_rect.h);
+ if (src_h > (dst_h * MAX_DOWNSCALE_RATIO)) {
+ pr_err("too much downscaling. Height %d->%d V Dec=%d\n",
+ src_h, req->dst_rect.h, req->vert_deci);
return -EINVAL;
}
@@ -176,6 +197,7 @@
struct mdss_mdp_rotator_session *rot;
struct mdss_mdp_format_params *fmt;
int ret = 0;
+ u32 bwc_enabled;
pr_debug("rot ctl=%u req id=%x\n", mdp5_data->ctl->num, req->id);
@@ -212,7 +234,14 @@
rot->flags = req->flags & (MDP_ROT_90 | MDP_FLIP_LR | MDP_FLIP_UD |
MDP_SECURE_OVERLAY_SESSION);
- rot->bwc_mode = (req->flags & MDP_BWC_EN) ? 1 : 0;
+ bwc_enabled = req->flags & MDP_BWC_EN;
+ if (bwc_enabled && !mdp5_data->mdata->has_bwc) {
+ pr_err("BWC is not supported in MDP version %x\n",
+ mdp5_data->mdata->mdp_rev);
+ rot->bwc_mode = 0;
+ } else {
+ rot->bwc_mode = bwc_enabled ? 1 : 0;
+ }
rot->format = fmt->format;
rot->img_width = req->src.width;
rot->img_height = req->src.height;
@@ -248,6 +277,7 @@
struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
struct mdp_histogram_start_req hist;
int ret;
+ u32 bwc_enabled;
if (mdp5_data->ctl == NULL)
return -ENODEV;
@@ -356,8 +386,15 @@
}
pipe->flags = req->flags;
- pipe->bwc_mode = pipe->mixer->rotator_mode ?
- 0 : (req->flags & MDP_BWC_EN ? 1 : 0) ;
+ bwc_enabled = req->flags & MDP_BWC_EN;
+ if (bwc_enabled && !mdp5_data->mdata->has_bwc) {
+ pr_err("BWC is not supported in MDP version %x\n",
+ mdp5_data->mdata->mdp_rev);
+ pipe->bwc_mode = 0;
+ } else {
+ pipe->bwc_mode = pipe->mixer->rotator_mode ?
+ 0 : (bwc_enabled ? 1 : 0) ;
+ }
pipe->img_width = req->src.width & 0x3fff;
pipe->img_height = req->src.height & 0x3fff;
pipe->src.x = req->src_rect.x;
@@ -368,7 +405,8 @@
pipe->dst.y = req->dst_rect.y;
pipe->dst.w = req->dst_rect.w;
pipe->dst.h = req->dst_rect.h;
-
+ pipe->horz_deci = req->horz_deci;
+ pipe->vert_deci = req->vert_deci;
pipe->src_fmt = fmt;
pipe->mixer_stage = req->z_order;
@@ -1562,6 +1600,10 @@
caps->vig_pipes = mdata->nvig_pipes;
caps->rgb_pipes = mdata->nrgb_pipes;
caps->dma_pipes = mdata->ndma_pipes;
+ if (mdata->has_bwc)
+ caps->features |= MDP_BWC_EN;
+ if (mdata->has_decimation)
+ caps->features |= MDP_DECIMATION_EN;
return 0;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index fe9eb8f..746705d 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -126,11 +126,10 @@
return rc;
pr_debug("BWC SMP strides ystride0=%x ystride1=%x\n",
ps.ystride[0], ps.ystride[1]);
- } else if ((mdata->mdp_rev >= MDSS_MDP_HW_REV_102) &&
- pipe->src_fmt->is_yuv) {
+ } else if (mdata->has_decimation && pipe->src_fmt->is_yuv) {
ps.num_planes = 2;
- ps.ystride[0] = pipe->src.w;
- ps.ystride[1] = pipe->src.w;
+ ps.ystride[0] = pipe->src.w >> pipe->horz_deci;
+ ps.ystride[1] = pipe->src.h >> pipe->vert_deci;
} else {
rc = mdss_mdp_get_plane_sizes(pipe->src_fmt->format,
pipe->src.w, pipe->src.h, &ps, 0);
@@ -377,6 +376,7 @@
{
u32 img_size, src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
u32 width, height;
+ u32 decimation;
pr_debug("pnum=%d wh=%dx%d src={%d,%d,%d,%d} dst={%d,%d,%d,%d}\n",
pipe->num, pipe->img_width, pipe->img_height,
@@ -397,6 +397,12 @@
height /= 2;
}
+ decimation = ((1 << pipe->horz_deci) - 1) << 8;
+ decimation |= ((1 << pipe->vert_deci) - 1);
+ if (decimation)
+ pr_debug("Image decimation h=%d v=%d\n",
+ pipe->horz_deci, pipe->vert_deci);
+
img_size = (height << 16) | width;
src_size = (pipe->src.h << 16) | pipe->src.w;
src_xy = (pipe->src.y << 16) | pipe->src.x;
@@ -419,6 +425,8 @@
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_OUT_XY, dst_xy);
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_YSTRIDE0, ystride0);
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_YSTRIDE1, ystride1);
+ mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_DECIMATION_CONFIG,
+ decimation);
return 0;
}
@@ -466,17 +474,12 @@
fmt->fetch_planes != MDSS_MDP_PLANE_INTERLEAVED)
src_format |= BIT(8); /* SRCC3_EN */
- if (fmt->fetch_planes != MDSS_MDP_PLANE_PLANAR) {
- unpack = (fmt->element[3] << 24) | (fmt->element[2] << 16) |
+ unpack = (fmt->element[3] << 24) | (fmt->element[2] << 16) |
(fmt->element[1] << 8) | (fmt->element[0] << 0);
-
- src_format |= ((fmt->unpack_count - 1) << 12) |
- (fmt->unpack_tight << 17) |
- (fmt->unpack_align_msb << 18) |
- ((fmt->bpp - 1) << 9);
- } else {
- unpack = 0;
- }
+ src_format |= ((fmt->unpack_count - 1) << 12) |
+ (fmt->unpack_tight << 17) |
+ (fmt->unpack_align_msb << 18) |
+ ((fmt->bpp - 1) << 9);
mdss_mdp_pipe_sspp_setup(pipe, &opmode);
@@ -538,7 +541,7 @@
static int mdss_mdp_src_addr_setup(struct mdss_mdp_pipe *pipe,
struct mdss_mdp_data *data)
{
- int is_rot = pipe->mixer->rotator_mode;
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
int ret = 0;
pr_debug("pnum=%d\n", pipe->num);
@@ -554,8 +557,9 @@
&pipe->src_planes, pipe->src_fmt);
/* planar format expects YCbCr, swap chroma planes if YCrCb */
- if (!is_rot && (pipe->src_fmt->fetch_planes == MDSS_MDP_PLANE_PLANAR) &&
- (pipe->src_fmt->element[0] == C2_R_Cr))
+ if (mdata->mdp_rev < MDSS_MDP_HW_REV_102 &&
+ (pipe->src_fmt->fetch_planes == MDSS_MDP_PLANE_PLANAR)
+ && (pipe->src_fmt->element[0] == C1_B_Cb))
swap(data->p[1].addr, data->p[2].addr);
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC0_ADDR, data->p[0].addr);
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index cf9a8b6..5a0c27e 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -536,6 +536,7 @@
u32 chroma_sample;
u32 filter_mode;
struct mdss_data_type *mdata;
+ u32 src_w, src_h;
mdata = mdss_mdp_get_mdata();
if (mdata->mdp_rev >= MDSS_MDP_HW_REV_102 && pipe->src_fmt->is_yuv)
@@ -552,6 +553,9 @@
}
}
+ src_w = pipe->src.w >> pipe->horz_deci;
+ src_h = pipe->src.h >> pipe->vert_deci;
+
chroma_sample = pipe->src_fmt->chroma_sample;
if (pipe->flags & MDP_SOURCE_ROTATED_90) {
if (chroma_sample == MDSS_MDP_CHROMA_H1V2)
@@ -570,23 +574,22 @@
}
if ((pipe->src_fmt->is_yuv) &&
- !((pipe->dst.w < pipe->src.w) || (pipe->dst.h < pipe->src.h))) {
+ !((pipe->dst.w < src_w) || (pipe->dst.h < src_h))) {
pp_sharp_config(pipe->base +
MDSS_MDP_REG_VIG_QSEED2_SHARP,
&pipe->pp_res.pp_sts,
&pipe->pp_cfg.sharp_cfg);
}
- if ((pipe->src.h != pipe->dst.h) ||
+ if ((src_h != pipe->dst.h) ||
(pipe->pp_res.pp_sts.sharp_sts & PP_STS_ENABLE) ||
(chroma_sample == MDSS_MDP_CHROMA_420) ||
(chroma_sample == MDSS_MDP_CHROMA_H1V2)) {
- pr_debug("scale y - src_h=%d dst_h=%d\n",
- pipe->src.h, pipe->dst.h);
+ pr_debug("scale y - src_h=%d dst_h=%d\n", src_h, pipe->dst.h);
- if ((pipe->src.h / MAX_DOWNSCALE_RATIO) > pipe->dst.h) {
+ if ((src_h / MAX_DOWNSCALE_RATIO) > pipe->dst.h) {
pr_err("too much downscaling height=%d->%d",
- pipe->src.h, pipe->dst.h);
+ src_h, pipe->dst.h);
return -EINVAL;
}
@@ -594,11 +597,12 @@
if (pipe->type == MDSS_MDP_PIPE_TYPE_VIG) {
u32 chr_dst_h = pipe->dst.h;
- if ((chroma_sample == MDSS_MDP_CHROMA_420) ||
- (chroma_sample == MDSS_MDP_CHROMA_H1V2))
+ if (!pipe->vert_deci &&
+ ((chroma_sample == MDSS_MDP_CHROMA_420) ||
+ (chroma_sample == MDSS_MDP_CHROMA_H1V2)))
chr_dst_h *= 2; /* 2x upsample chroma */
- if (pipe->src.h <= pipe->dst.h) {
+ if (src_h <= pipe->dst.h) {
scale_config |= /* G/Y, A */
(filter_mode << 10) |
(MDSS_MDP_SCALE_FILTER_NEAREST << 18);
@@ -607,7 +611,7 @@
(MDSS_MDP_SCALE_FILTER_PCMN << 10) |
(MDSS_MDP_SCALE_FILTER_PCMN << 18);
- if (pipe->src.h <= chr_dst_h)
+ if (src_h <= chr_dst_h)
scale_config |= /* CrCb */
(MDSS_MDP_SCALE_FILTER_BIL << 14);
else
@@ -615,12 +619,12 @@
(MDSS_MDP_SCALE_FILTER_PCMN << 14);
phasey_step = mdss_mdp_scale_phase_step(
- PHASE_STEP_SHIFT, pipe->src.h, chr_dst_h);
+ PHASE_STEP_SHIFT, src_h, chr_dst_h);
writel_relaxed(phasey_step, pipe->base +
MDSS_MDP_REG_VIG_QSEED2_C12_PHASESTEPY);
} else {
- if (pipe->src.h <= pipe->dst.h)
+ if (src_h <= pipe->dst.h)
scale_config |= /* RGB, A */
(MDSS_MDP_SCALE_FILTER_BIL << 10) |
(MDSS_MDP_SCALE_FILTER_NEAREST << 18);
@@ -631,19 +635,18 @@
}
phasey_step = mdss_mdp_scale_phase_step(
- PHASE_STEP_SHIFT, pipe->src.h, pipe->dst.h);
+ PHASE_STEP_SHIFT, src_h, pipe->dst.h);
}
- if ((pipe->src.w != pipe->dst.w) ||
+ if ((src_w != pipe->dst.w) ||
(pipe->pp_res.pp_sts.sharp_sts & PP_STS_ENABLE) ||
(chroma_sample == MDSS_MDP_CHROMA_420) ||
(chroma_sample == MDSS_MDP_CHROMA_H2V1)) {
- pr_debug("scale x - src_w=%d dst_w=%d\n",
- pipe->src.w, pipe->dst.w);
+ pr_debug("scale x - src_w=%d dst_w=%d\n", src_w, pipe->dst.w);
- if ((pipe->src.w / MAX_DOWNSCALE_RATIO) > pipe->dst.w) {
+ if ((src_w / MAX_DOWNSCALE_RATIO) > pipe->dst.w) {
pr_err("too much downscaling width=%d->%d",
- pipe->src.w, pipe->dst.w);
+ src_w, pipe->dst.w);
return -EINVAL;
}
@@ -652,11 +655,12 @@
if (pipe->type == MDSS_MDP_PIPE_TYPE_VIG) {
u32 chr_dst_w = pipe->dst.w;
- if ((chroma_sample == MDSS_MDP_CHROMA_420) ||
- (chroma_sample == MDSS_MDP_CHROMA_H2V1))
+ if (!pipe->horz_deci &&
+ ((chroma_sample == MDSS_MDP_CHROMA_420) ||
+ (chroma_sample == MDSS_MDP_CHROMA_H2V1)))
chr_dst_w *= 2; /* 2x upsample chroma */
- if (pipe->src.w <= pipe->dst.w) {
+ if (src_w <= pipe->dst.w) {
scale_config |= /* G/Y, A */
(filter_mode << 8) |
(MDSS_MDP_SCALE_FILTER_NEAREST << 16);
@@ -665,7 +669,7 @@
(MDSS_MDP_SCALE_FILTER_PCMN << 8) |
(MDSS_MDP_SCALE_FILTER_PCMN << 16);
- if (pipe->src.w <= chr_dst_w)
+ if (src_w <= chr_dst_w)
scale_config |= /* CrCb */
(MDSS_MDP_SCALE_FILTER_BIL << 12);
else
@@ -673,11 +677,11 @@
(MDSS_MDP_SCALE_FILTER_PCMN << 12);
phasex_step = mdss_mdp_scale_phase_step(
- PHASE_STEP_SHIFT, pipe->src.w, chr_dst_w);
+ PHASE_STEP_SHIFT, src_w, chr_dst_w);
writel_relaxed(phasex_step, pipe->base +
MDSS_MDP_REG_VIG_QSEED2_C12_PHASESTEPX);
} else {
- if (pipe->src.w <= pipe->dst.w)
+ if (src_w <= pipe->dst.w)
scale_config |= /* RGB, A */
(MDSS_MDP_SCALE_FILTER_BIL << 8) |
(MDSS_MDP_SCALE_FILTER_NEAREST << 16);
@@ -688,7 +692,7 @@
}
phasex_step = mdss_mdp_scale_phase_step(
- PHASE_STEP_SHIFT, pipe->src.w, pipe->dst.w);
+ PHASE_STEP_SHIFT, src_w, pipe->dst.w);
}
writel_relaxed(scale_config, pipe->base +
diff --git a/include/linux/ion.h b/include/linux/ion.h
index 88ad9a0..4983316 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -35,6 +35,7 @@
ION_HEAP_TYPE_SYSTEM,
ION_HEAP_TYPE_SYSTEM_CONTIG,
ION_HEAP_TYPE_CARVEOUT,
+ ION_HEAP_TYPE_CHUNK,
ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always
are at the end of this enum */
ION_NUM_HEAPS,
@@ -44,8 +45,10 @@
#define ION_HEAP_SYSTEM_CONTIG_MASK (1 << ION_HEAP_TYPE_SYSTEM_CONTIG)
#define ION_HEAP_CARVEOUT_MASK (1 << ION_HEAP_TYPE_CARVEOUT)
+#define ION_NUM_HEAP_IDS sizeof(unsigned int) * 8
+
/**
- * heap flags - the lower 16 bits are used by core ion, the upper 16
+ * allocation flags - the lower 16 bits are used by core ion, the upper 16
* bits are reserved for use by the heaps themselves.
*/
#define ION_FLAG_CACHED 1 /* mappings of this buffer should be
@@ -74,8 +77,9 @@
/**
* struct ion_platform_heap - defines a heap in the given platform
* @type: type of the heap from ion_heap_type enum
- * @id: unique identifier for heap. When allocating (lower numbers
- * will be allocated from first)
+ * @id: unique identifier for heap. When allocating higher numbers
+ * will be allocated from first. At allocation these are passed
+ * as a bit mask and therefore can not exceed ION_NUM_HEAP_IDS.
* @name: used for debug purposes
* @base: base address of heap in physical memory if applicable
* @size: size of the heap in bytes if applicable
@@ -83,6 +87,10 @@
* @has_outer_cache: set to 1 if outer cache is used, 0 otherwise.
* @extra_data: Extra data specific to each heap type
* @priv: heap private data
+ * @align: required alignment in physical memory if applicable
+ * @priv: private info passed from the board file
+ *
+ * Provided by the board file.
*/
struct ion_platform_heap {
enum ion_heap_type type;
@@ -93,6 +101,7 @@
enum ion_memory_types memory_type;
unsigned int has_outer_cache;
void *extra_data;
+ ion_phys_addr_t align;
void *priv;
};
@@ -125,12 +134,12 @@
/**
* ion_client_create() - allocate a client and returns it
- * @dev: the global ion device
- * @heap_mask: mask of heaps this client can allocate from
- * @name: used for debugging
+ * @dev: the global ion device
+ * @heap_type_mask: mask of heaps this client can allocate from
+ * @name: used for debugging
*/
struct ion_client *ion_client_create(struct ion_device *dev,
- unsigned int heap_mask, const char *name);
+ const char *name);
/**
* ion_client_destroy() - free's a client and all it's handles
@@ -143,21 +152,22 @@
/**
* ion_alloc - allocate ion memory
- * @client: the client
- * @len: size of the allocation
- * @align: requested allocation alignment, lots of hardware blocks have
- * alignment requirements of some kind
- * @heap_mask: mask of heaps to allocate from, if multiple bits are set
- * heaps will be tried in order from lowest to highest order bit
- * @flags: heap flags, the low 16 bits are consumed by ion, the high 16
- * bits are passed on to the respective heap and can be heap
- * custom
+ * @client: the client
+ * @len: size of the allocation
+ * @align: requested allocation alignment, lots of hardware blocks
+ * have alignment requirements of some kind
+ * @heap_id_mask: mask of heaps to allocate from, if multiple bits are set
+ * heaps will be tried in order from highest to lowest
+ * id
+ * @flags: heap flags, the low 16 bits are consumed by ion, the
+ * high 16 bits are passed on to the respective heap and
+ * can be heap custom
*
* Allocate memory in one of the heaps provided in heap mask and return
* an opaque handle to it.
*/
struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
- size_t align, unsigned int heap_mask,
+ size_t align, unsigned int heap_id_mask,
unsigned int flags);
/**
@@ -217,11 +227,19 @@
void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle);
/**
- * ion_share_dma_buf() - given an ion client, create a dma-buf fd
+ * ion_share_dma_buf() - share buffer as dma-buf
* @client: the client
* @handle: the handle
*/
-int ion_share_dma_buf(struct ion_client *client, struct ion_handle *handle);
+struct dma_buf *ion_share_dma_buf(struct ion_client *client,
+ struct ion_handle *handle);
+
+/**
+ * ion_share_dma_buf_fd() - given an ion client, create a dma-buf fd
+ * @client: the client
+ * @handle: the handle
+ */
+int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle);
/**
* ion_import_dma_buf() - given an dma-buf fd from the ion exporter get handle
@@ -310,12 +328,12 @@
/**
* struct ion_allocation_data - metadata passed from userspace for allocations
- * @len: size of the allocation
- * @align: required alignment of the allocation
- * @heap_mask: mask of heaps to allocate from
- * @flags: flags passed to heap
- * @handle: pointer that will be populated with a cookie to use to refer
- * to this allocation
+ * @len: size of the allocation
+ * @align: required alignment of the allocation
+ * @heap_id_mask: mask of heap ids to allocate from
+ * @flags: flags passed to heap
+ * @handle: pointer that will be populated with a cookie to use to
+ * refer to this allocation
*
* Provided by userspace as an argument to the ioctl
*/
diff --git a/include/linux/iopoll.h b/include/linux/iopoll.h
index 8aa758d..b882fe2 100644
--- a/include/linux/iopoll.h
+++ b/include/linux/iopoll.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -40,8 +40,12 @@
might_sleep_if(timeout_us); \
for (;;) { \
(val) = readl(addr); \
- if ((cond) || (timeout_us && time_after(jiffies, timeout))) \
+ if (cond) \
break; \
+ if (timeout_us && time_after(jiffies, timeout)) { \
+ (val) = readl(addr); \
+ break; \
+ } \
if (sleep_us) \
usleep_range(DIV_ROUND_UP(sleep_us, 4), sleep_us); \
} \
diff --git a/include/linux/mfd/pm8xxx/pm8921-charger.h b/include/linux/mfd/pm8xxx/pm8921-charger.h
index 1c67b1e..5439fd1 100644
--- a/include/linux/mfd/pm8xxx/pm8921-charger.h
+++ b/include/linux/mfd/pm8xxx/pm8921-charger.h
@@ -165,6 +165,7 @@
unsigned int warm_bat_chg_current;
unsigned int cool_bat_voltage;
unsigned int warm_bat_voltage;
+ int hysteresis_temp;
unsigned int (*get_batt_capacity_percent) (void);
int64_t batt_id_min;
int64_t batt_id_max;
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index db5c69c..f9e483c 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -173,6 +173,7 @@
#define MDP_OV_PIPE_FORCE_DMA 0x00004000
#define MDP_MEMORY_ID_TYPE_FB 0x00001000
#define MDP_BWC_EN 0x00000400
+#define MDP_DECIMATION_EN 0x00000800
#define MDP_TRANSP_NOP 0xffffffff
#define MDP_ALPHA_NOP 0xff
@@ -406,7 +407,9 @@
uint32_t transp_mask;
uint32_t flags;
uint32_t id;
- uint32_t user_data[8];
+ uint32_t user_data[7];
+ uint8_t horz_deci;
+ uint8_t vert_deci;
struct mdp_overlay_pp_params overlay_pp_cfg;
};
@@ -696,6 +699,7 @@
uint8_t rgb_pipes;
uint8_t vig_pipes;
uint8_t dma_pipes;
+ uint32_t features;
};
struct msmfb_metadata {
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index aacc9df..1d01d2e 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -89,7 +89,7 @@
#define WCD9XXX_MEAS_INVALD_RANGE_LOW_MV 20
#define WCD9XXX_MEAS_INVALD_RANGE_HIGH_MV 80
#define WCD9XXX_GM_SWAP_THRES_MIN_MV 150
-#define WCD9XXX_GM_SWAP_THRES_MAX_MV 500
+#define WCD9XXX_GM_SWAP_THRES_MAX_MV 650
#define WCD9XXX_USLEEP_RANGE_MARGIN_US 1000
diff --git a/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.c b/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.c
index b43c3bd..f77ec0f 100644
--- a/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.c
+++ b/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.c
@@ -305,6 +305,7 @@
}
if (idx >= NUM_DOLBY_ENDP_DEVICE) {
pr_err("%s: device is not set accordingly\n", __func__);
+ kfree(params_value);
return -EINVAL;
}
for (i = 0; i < DOLBY_ENDDEP_PARAM_LENGTH; i++) {
@@ -367,6 +368,7 @@
params_length);
if (rc) {
pr_err("%s: send dolby params failed\n", __func__);
+ kfree(params_value);
return -EINVAL;
}
for (i = 0; i < MAX_DOLBY_PARAMS; i++) {
@@ -584,7 +586,7 @@
if (rc) {
pr_err("%s: get parameters failed\n", __func__);
kfree(params_value);
- rc = -EINVAL;
+ return -EINVAL;
}
update_params_value = (int *)params_value;
ucontrol->value.integer.value[0] = dolby_dap_params_get.device_id;