Merge "USB: dwc3: msm: Host: Don't turn off core clock when SS session is active"
diff --git a/arch/arm/boot/dts/msm9625-v2-1-cdp.dts b/arch/arm/boot/dts/msm9625-cdp.dtsi
similarity index 79%
rename from arch/arm/boot/dts/msm9625-v2-1-cdp.dts
rename to arch/arm/boot/dts/msm9625-cdp.dtsi
index da07100..1f9cbb0 100644
--- a/arch/arm/boot/dts/msm9625-v2-1-cdp.dts
+++ b/arch/arm/boot/dts/msm9625-cdp.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, 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
@@ -10,17 +10,10 @@
* GNU General Public License for more details.
*/
-/dts-v1/;
-
-/include/ "msm9625-v2-1.dtsi"
+/include/ "msm9625-display.dtsi"
+/include/ "qpic-panel-ili-qvga.dtsi"
/ {
- model = "Qualcomm MSM 9625V2.1 CDP";
- compatible = "qcom,msm9625-cdp", "qcom,msm9625", "qcom,cdp";
- qcom,msm-id = <134 1 0x20001>, <152 1 0x20001>, <149 1 0x20001>,
- <150 1 0x20001>, <151 1 0x20001>, <148 1 0x20001>,
- <173 1 0x20001>, <174 1 0x20001>, <175 1 0x20001>;
-
i2c@f9925000 {
charger@57 {
compatible = "summit,smb137c";
@@ -42,10 +35,18 @@
wlan0: qca,wlan {
cell-index = <0>;
- compatible = "qca,ar6004-sdio";
+ compatible = "qca,ar6004-hsic";
qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
- qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+ qca,vdd-io-supply = <&pm8019_l11>;
+ };
+
+ qca,wlan_ar6003 {
+ cell-index = <0>;
+ compatible = "qca,ar6003-sdio";
+ qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
+ qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
+ qca,vdd-io-supply = <&pm8019_l11>;
};
};
diff --git a/arch/arm/boot/dts/msm9625-v2-1-cdp.dts b/arch/arm/boot/dts/msm9625-mtp.dtsi
similarity index 73%
copy from arch/arm/boot/dts/msm9625-v2-1-cdp.dts
copy to arch/arm/boot/dts/msm9625-mtp.dtsi
index da07100..cc0bf5e 100644
--- a/arch/arm/boot/dts/msm9625-v2-1-cdp.dts
+++ b/arch/arm/boot/dts/msm9625-mtp.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, 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
@@ -10,17 +10,7 @@
* GNU General Public License for more details.
*/
-/dts-v1/;
-
-/include/ "msm9625-v2-1.dtsi"
-
/ {
- model = "Qualcomm MSM 9625V2.1 CDP";
- compatible = "qcom,msm9625-cdp", "qcom,msm9625", "qcom,cdp";
- qcom,msm-id = <134 1 0x20001>, <152 1 0x20001>, <149 1 0x20001>,
- <150 1 0x20001>, <151 1 0x20001>, <148 1 0x20001>,
- <173 1 0x20001>, <174 1 0x20001>, <175 1 0x20001>;
-
i2c@f9925000 {
charger@57 {
compatible = "summit,smb137c";
@@ -42,10 +32,18 @@
wlan0: qca,wlan {
cell-index = <0>;
- compatible = "qca,ar6004-sdio";
+ compatible = "qca,ar6004-hsic";
qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
- qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+ qca,vdd-io-supply = <&pm8019_l11>;
+ };
+
+ qca,wlan_ar6003 {
+ cell-index = <0>;
+ compatible = "qca,ar6003-sdio";
+ qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
+ qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
+ qca,vdd-io-supply = <&pm8019_l11>;
};
};
@@ -89,11 +87,23 @@
};
mpp@a300 { /* MPP 4 */
+ /* VADC channel 19 */
+ qcom,mode = <4>;
+ qcom,ain-route = <3>; /* AMUX 8 */
+ qcom,master-en = <1>;
+ qcom,src-sel = <0>; /* Function constant */
+ qcom,invert = <1>;
};
mpp@a400 { /* MPP 5 */
};
mpp@a500 { /* MPP 6 */
+ /* channel 21 */
+ qcom,mode = <4>;
+ qcom,ain-route = <1>; /* AMUX 6 */
+ qcom,master-en = <1>;
+ qcom,src-sel = <0>; /* Function constant */
+ qcom,invert = <1>;
};
};
diff --git a/arch/arm/boot/dts/msm9625-v1-cdp.dts b/arch/arm/boot/dts/msm9625-v1-cdp.dts
index cf17c69..d7537eb 100644
--- a/arch/arm/boot/dts/msm9625-v1-cdp.dts
+++ b/arch/arm/boot/dts/msm9625-v1-cdp.dts
@@ -13,6 +13,7 @@
/dts-v1/;
/include/ "msm9625-v1.dtsi"
+/include/ "msm9625-cdp.dtsi"
/ {
model = "Qualcomm MSM 9625V1 CDP";
@@ -20,88 +21,4 @@
qcom,msm-id = <134 1 0>, <152 1 0>, <149 1 0>, <150 1 0>,
<151 1 0>, <148 1 0>, <173 1 0>, <174 1 0>,
<175 1 0>;
-
- i2c@f9925000 {
- charger@57 {
- compatible = "summit,smb137c";
- reg = <0x57>;
- summit,chg-current-ma = <1500>;
- summit,term-current-ma = <50>;
- summit,pre-chg-current-ma = <100>;
- summit,float-voltage-mv = <4200>;
- summit,thresh-voltage-mv = <3000>;
- summit,recharge-thresh-mv = <75>;
- summit,system-voltage-mv = <4250>;
- summit,charging-timeout = <382>;
- summit,pre-charge-timeout = <48>;
- summit,therm-current-ua = <10>;
- summit,temperature-min = <4>; /* 0 C */
- summit,temperature-max = <3>; /* 45 C */
- };
- };
-
- wlan0: qca,wlan {
- cell-index = <0>;
- compatible = "qca,ar6004-sdio";
- qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
- qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
- qca,vdd-io-supply = <&pm8019_l11>;
- };
-
- qca,wlan_ar6003 {
- cell-index = <0>;
- compatible = "qca,ar6003-sdio";
- qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
- qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
- qca,vdd-io-supply = <&pm8019_l11>;
- };
-};
-
-/* PM8019 GPIO and MPP configuration */
-&pm8019_gpios {
- gpio@c000 { /* GPIO 1 */
- };
-
- gpio@c100 { /* GPIO 2 */
- };
-
- gpio@c200 { /* GPIO 3 */
- };
-
- gpio@c300 { /* GPIO 4 */
- /* ext_2p95v regulator enable config */
- qcom,mode = <1>; /* Digital output */
- qcom,output-type = <0>; /* CMOS */
- qcom,invert = <0>; /* Output low */
- qcom,out-strength = <1>; /* Low */
- qcom,vin-sel = <2>; /* PM8019 L11 - 1.8V */
- qcom,src-sel = <0>; /* Constant */
- qcom,master-en = <1>; /* Enable GPIO */
- };
-
- gpio@c400 { /* GPIO 5 */
- };
-
- gpio@c500 { /* GPIO 6 */
- };
-};
-
-&pm8019_mpps {
- mpp@a000 { /* MPP 1 */
- };
-
- mpp@a100 { /* MPP 2 */
- };
-
- mpp@a200 { /* MPP 3 */
- };
-
- mpp@a300 { /* MPP 4 */
- };
-
- mpp@a400 { /* MPP 5 */
- };
-
- mpp@a500 { /* MPP 6 */
- };
};
diff --git a/arch/arm/boot/dts/msm9625-v1-mtp.dts b/arch/arm/boot/dts/msm9625-v1-mtp.dts
index 24aa3af..a70ec1a 100644
--- a/arch/arm/boot/dts/msm9625-v1-mtp.dts
+++ b/arch/arm/boot/dts/msm9625-v1-mtp.dts
@@ -13,6 +13,7 @@
/dts-v1/;
/include/ "msm9625-v1.dtsi"
+/include/ "msm9625-mtp.dtsi"
/ {
model = "Qualcomm MSM 9625V1 MTP";
@@ -20,100 +21,4 @@
qcom,msm-id = <134 7 0>, <152 7 0>, <149 7 0>, <150 7 0>,
<151 7 0>, <148 7 0>, <173 7 0>, <174 7 0>,
<175 7 0>;
-
- i2c@f9925000 {
- charger@57 {
- compatible = "summit,smb137c";
- reg = <0x57>;
- summit,chg-current-ma = <1500>;
- summit,term-current-ma = <50>;
- summit,pre-chg-current-ma = <100>;
- summit,float-voltage-mv = <4200>;
- summit,thresh-voltage-mv = <3000>;
- summit,recharge-thresh-mv = <75>;
- summit,system-voltage-mv = <4250>;
- summit,charging-timeout = <382>;
- summit,pre-charge-timeout = <48>;
- summit,therm-current-ua = <10>;
- summit,temperature-min = <4>; /* 0 C */
- summit,temperature-max = <3>; /* 45 C */
- };
- };
-
- wlan0: qca,wlan {
- cell-index = <0>;
- compatible = "qca,ar6004-sdio";
- qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
- qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
- qca,vdd-io-supply = <&pm8019_l11>;
- };
-
- qca,wlan_ar6003 {
- cell-index = <0>;
- compatible = "qca,ar6003-sdio";
- qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
- qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
- qca,vdd-io-supply = <&pm8019_l11>;
- };
-};
-
-/* PM8019 GPIO and MPP configuration */
-&pm8019_gpios {
- gpio@c000 { /* GPIO 1 */
- };
-
- gpio@c100 { /* GPIO 2 */
- };
-
- gpio@c200 { /* GPIO 3 */
- };
-
- gpio@c300 { /* GPIO 4 */
- /* ext_2p95v regulator enable config */
- qcom,mode = <1>; /* Digital output */
- qcom,output-type = <0>; /* CMOS */
- qcom,invert = <0>; /* Output low */
- qcom,out-strength = <1>; /* Low */
- qcom,vin-sel = <2>; /* PM8019 L11 - 1.8V */
- qcom,src-sel = <0>; /* Constant */
- qcom,master-en = <1>; /* Enable GPIO */
- };
-
- gpio@c400 { /* GPIO 5 */
- };
-
- gpio@c500 { /* GPIO 6 */
- };
-};
-
-&pm8019_mpps {
- mpp@a000 { /* MPP 1 */
- };
-
- mpp@a100 { /* MPP 2 */
- };
-
- mpp@a200 { /* MPP 3 */
- };
-
- mpp@a300 { /* MPP 4 */
- /* VADC channel 19 */
- qcom,mode = <4>;
- qcom,ain-route = <3>; /* AMUX 8 */
- qcom,master-en = <1>;
- qcom,src-sel = <0>; /* Function constant */
- qcom,invert = <1>;
- };
-
- mpp@a400 { /* MPP 5 */
- };
-
- mpp@a500 { /* MPP 6 */
- /* VADC channel 21 */
- qcom,mode = <4>;
- qcom,ain-route = <1>; /* AMUX 6 */
- qcom,master-en = <1>;
- qcom,src-sel = <0>; /* Function constant */
- qcom,invert = <1>;
- };
};
diff --git a/arch/arm/boot/dts/msm9625-v2-1-mtp.dts b/arch/arm/boot/dts/msm9625-v2-1-mtp.dts
deleted file mode 100644
index 1e0f3c0..0000000
--- a/arch/arm/boot/dts/msm9625-v2-1-mtp.dts
+++ /dev/null
@@ -1,99 +0,0 @@
-/* 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.
- */
-
-/dts-v1/;
-
-/include/ "msm9625-v2-1.dtsi"
-
-/ {
- model = "Qualcomm MSM 9625V2.1 MTP";
- compatible = "qcom,msm9625-mtp", "qcom,msm9625", "qcom,mtp";
- qcom,msm-id = <134 7 0x20001>, <152 7 0x20001>, <149 7 0x20001>,
- <150 7 0x20001>, <151 7 0x20001>, <148 7 0x20001>,
- <173 7 0x20001>, <174 7 0x20001>, <175 7 0x20001>;
-
- i2c@f9925000 {
- charger@57 {
- compatible = "summit,smb137c";
- reg = <0x57>;
- summit,chg-current-ma = <1500>;
- summit,term-current-ma = <50>;
- summit,pre-chg-current-ma = <100>;
- summit,float-voltage-mv = <4200>;
- summit,thresh-voltage-mv = <3000>;
- summit,recharge-thresh-mv = <75>;
- summit,system-voltage-mv = <4250>;
- summit,charging-timeout = <382>;
- summit,pre-charge-timeout = <48>;
- summit,therm-current-ua = <10>;
- summit,temperature-min = <4>; /* 0 C */
- summit,temperature-max = <3>; /* 45 C */
- };
- };
-
- wlan0: qca,wlan {
- cell-index = <0>;
- compatible = "qca,ar6004-sdio";
- qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
- qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
- qca,ar6004-vdd-io-supply = <&pm8019_l11>;
- };
-};
-
-/* PM8019 GPIO and MPP configuration */
-&pm8019_gpios {
- gpio@c000 { /* GPIO 1 */
- };
-
- gpio@c100 { /* GPIO 2 */
- };
-
- gpio@c200 { /* GPIO 3 */
- };
-
- gpio@c300 { /* GPIO 4 */
- /* ext_2p95v regulator enable config */
- qcom,mode = <1>; /* Digital output */
- qcom,output-type = <0>; /* CMOS */
- qcom,invert = <0>; /* Output low */
- qcom,out-strength = <1>; /* Low */
- qcom,vin-sel = <2>; /* PM8019 L11 - 1.8V */
- qcom,src-sel = <0>; /* Constant */
- qcom,master-en = <1>; /* Enable GPIO */
- };
-
- gpio@c400 { /* GPIO 5 */
- };
-
- gpio@c500 { /* GPIO 6 */
- };
-};
-
-&pm8019_mpps {
- mpp@a000 { /* MPP 1 */
- };
-
- mpp@a100 { /* MPP 2 */
- };
-
- mpp@a200 { /* MPP 3 */
- };
-
- mpp@a300 { /* MPP 4 */
- };
-
- mpp@a400 { /* MPP 5 */
- };
-
- mpp@a500 { /* MPP 6 */
- };
-};
diff --git a/arch/arm/boot/dts/msm9625-v2-cdp.dts b/arch/arm/boot/dts/msm9625-v2-cdp.dts
index 660bdbd..9fbe5ec 100644
--- a/arch/arm/boot/dts/msm9625-v2-cdp.dts
+++ b/arch/arm/boot/dts/msm9625-v2-cdp.dts
@@ -13,8 +13,7 @@
/dts-v1/;
/include/ "msm9625-v2.dtsi"
-/include/ "msm9625-display.dtsi"
-/include/ "qpic-panel-ili-qvga.dtsi"
+/include/ "msm9625-cdp.dtsi"
/ {
model = "Qualcomm MSM 9625V2 CDP";
@@ -22,88 +21,4 @@
qcom,msm-id = <134 1 0x20000>, <152 1 0x20000>, <149 1 0x20000>,
<150 1 0x20000>, <151 1 0x20000>, <148 1 0x20000>,
<173 1 0x20000>, <174 1 0x20000>, <175 1 0x20000>;
-
- i2c@f9925000 {
- charger@57 {
- compatible = "summit,smb137c";
- reg = <0x57>;
- summit,chg-current-ma = <1500>;
- summit,term-current-ma = <50>;
- summit,pre-chg-current-ma = <100>;
- summit,float-voltage-mv = <4200>;
- summit,thresh-voltage-mv = <3000>;
- summit,recharge-thresh-mv = <75>;
- summit,system-voltage-mv = <4250>;
- summit,charging-timeout = <382>;
- summit,pre-charge-timeout = <48>;
- summit,therm-current-ua = <10>;
- summit,temperature-min = <4>; /* 0 C */
- summit,temperature-max = <3>; /* 45 C */
- };
- };
-
- wlan0: qca,wlan {
- cell-index = <0>;
- compatible = "qca,ar6004-hsic";
- qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
- qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
- qca,vdd-io-supply = <&pm8019_l11>;
- };
-
- qca,wlan_ar6003 {
- cell-index = <0>;
- compatible = "qca,ar6003-sdio";
- qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
- qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
- qca,vdd-io-supply = <&pm8019_l11>;
- };
-};
-
-/* PM8019 GPIO and MPP configuration */
-&pm8019_gpios {
- gpio@c000 { /* GPIO 1 */
- };
-
- gpio@c100 { /* GPIO 2 */
- };
-
- gpio@c200 { /* GPIO 3 */
- };
-
- gpio@c300 { /* GPIO 4 */
- /* ext_2p95v regulator enable config */
- qcom,mode = <1>; /* Digital output */
- qcom,output-type = <0>; /* CMOS */
- qcom,invert = <0>; /* Output low */
- qcom,out-strength = <1>; /* Low */
- qcom,vin-sel = <2>; /* PM8019 L11 - 1.8V */
- qcom,src-sel = <0>; /* Constant */
- qcom,master-en = <1>; /* Enable GPIO */
- };
-
- gpio@c400 { /* GPIO 5 */
- };
-
- gpio@c500 { /* GPIO 6 */
- };
-};
-
-&pm8019_mpps {
- mpp@a000 { /* MPP 1 */
- };
-
- mpp@a100 { /* MPP 2 */
- };
-
- mpp@a200 { /* MPP 3 */
- };
-
- mpp@a300 { /* MPP 4 */
- };
-
- mpp@a400 { /* MPP 5 */
- };
-
- mpp@a500 { /* MPP 6 */
- };
};
diff --git a/arch/arm/boot/dts/msm9625-v2-mtp.dts b/arch/arm/boot/dts/msm9625-v2-mtp.dts
index c9e54be..5324e2c 100644
--- a/arch/arm/boot/dts/msm9625-v2-mtp.dts
+++ b/arch/arm/boot/dts/msm9625-v2-mtp.dts
@@ -13,6 +13,7 @@
/dts-v1/;
/include/ "msm9625-v2.dtsi"
+/include/ "msm9625-mtp.dtsi"
/ {
model = "Qualcomm MSM 9625V2 MTP";
diff --git a/arch/arm/boot/dts/msm9625-v2.1-cdp.dts b/arch/arm/boot/dts/msm9625-v2.1-cdp.dts
new file mode 100644
index 0000000..b643593
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-v2.1-cdp.dts
@@ -0,0 +1,24 @@
+/* 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.
+ */
+
+/dts-v1/;
+
+/include/ "msm9625-v2.1.dtsi"
+/include/ "msm9625-cdp.dtsi"
+
+/ {
+ model = "Qualcomm MSM 9625V2.1 CDP";
+ compatible = "qcom,msm9625-cdp", "qcom,msm9625", "qcom,cdp";
+ qcom,msm-id = <134 1 0x20001>, <152 1 0x20001>, <149 1 0x20001>,
+ <150 1 0x20001>, <151 1 0x20001>, <148 1 0x20001>,
+ <173 1 0x20001>, <174 1 0x20001>, <175 1 0x20001>;
+};
diff --git a/arch/arm/boot/dts/msm9625-v2.1-mtp.dts b/arch/arm/boot/dts/msm9625-v2.1-mtp.dts
new file mode 100644
index 0000000..8bbcc0d
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-v2.1-mtp.dts
@@ -0,0 +1,24 @@
+/* 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.
+ */
+
+/dts-v1/;
+
+/include/ "msm9625-v2.1.dtsi"
+/include/ "msm9625-mtp.dtsi"
+
+/ {
+ model = "Qualcomm MSM 9625V2.1 MTP";
+ compatible = "qcom,msm9625-mtp", "qcom,msm9625", "qcom,mtp";
+ qcom,msm-id = <134 7 0x20001>, <152 7 0x20001>, <149 7 0x20001>,
+ <150 7 0x20001>, <151 7 0x20001>, <148 7 0x20001>,
+ <173 7 0x20001>, <174 7 0x20001>, <175 7 0x20001>;
+};
diff --git a/arch/arm/boot/dts/msm9625-v2-1.dtsi b/arch/arm/boot/dts/msm9625-v2.1.dtsi
similarity index 100%
rename from arch/arm/boot/dts/msm9625-v2-1.dtsi
rename to arch/arm/boot/dts/msm9625-v2.1.dtsi
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index f67cb0d..aa2c028 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -98,6 +98,7 @@
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_IDLE=y
CONFIG_VFP=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index b5e67fd..c9f068a 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -102,6 +102,7 @@
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_IDLE=y
CONFIG_VFP=y
diff --git a/arch/arm/configs/msm9625-perf_defconfig b/arch/arm/configs/msm9625-perf_defconfig
index 42acd99..ae73bad 100644
--- a/arch/arm/configs/msm9625-perf_defconfig
+++ b/arch/arm/configs/msm9625-perf_defconfig
@@ -230,9 +230,6 @@
CONFIG_REGULATOR_QPNP=y
CONFIG_ION=y
CONFIG_ION_MSM=y
-CONFIG_FB=y
-CONFIG_FB_MSM=y
-CONFIG_FB_MSM_QPIC_PANEL_DETECT=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index 041e89a..f7c3bff 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -231,9 +231,6 @@
CONFIG_REGULATOR_QPNP=y
CONFIG_ION=y
CONFIG_ION_MSM=y
-CONFIG_FB=y
-CONFIG_FB_MSM=y
-CONFIG_FB_MSM_QPIC_PANEL_DETECT=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index f20f6ae..8c366da 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -76,8 +76,8 @@
dtb-$(CONFIG_ARCH_MSM9625) += msm9625-v1-rumi.dtb
dtb-$(CONFIG_ARCH_MSM9625) += msm9625-v2-cdp.dtb
dtb-$(CONFIG_ARCH_MSM9625) += msm9625-v2-mtp.dtb
- dtb-$(CONFIG_ARCH_MSM9625) += msm9625-v2-1-mtp.dtb
- dtb-$(CONFIG_ARCH_MSM9625) += msm9625-v2-1-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM9625) += msm9625-v2.1-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM9625) += msm9625-v2.1-cdp.dtb
# MSM8226
zreladdr-$(CONFIG_ARCH_MSM8226) := 0x00008000
diff --git a/arch/arm/mach-msm/board-9625-gpiomux.c b/arch/arm/mach-msm/board-9625-gpiomux.c
index 75aaaec..a6ac986 100644
--- a/arch/arm/mach-msm/board-9625-gpiomux.c
+++ b/arch/arm/mach-msm/board-9625-gpiomux.c
@@ -276,6 +276,7 @@
},
};
+#ifdef CONFIG_FB_MSM_QPIC
static struct gpiomux_setting qpic_lcdc_a_d = {
.func = GPIOMUX_FUNC_1,
.drv = GPIOMUX_DRV_10MA,
@@ -327,6 +328,17 @@
},
};
+static void msm9625_disp_init_gpiomux(void)
+{
+ msm_gpiomux_install(msm9625_qpic_lcdc_configs,
+ ARRAY_SIZE(msm9625_qpic_lcdc_configs));
+}
+#else
+static void msm9625_disp_init_gpiomux(void)
+{
+}
+#endif /* CONFIG_FB_MSM_QPIC */
+
void __init msm9625_init_gpiomux(void)
{
int rc;
@@ -347,7 +359,5 @@
ARRAY_SIZE(mdm9625_cdc_reset_config));
msm_gpiomux_install(sdc2_card_det_config,
ARRAY_SIZE(sdc2_card_det_config));
- msm_gpiomux_install(msm9625_qpic_lcdc_configs,
- ARRAY_SIZE(msm9625_qpic_lcdc_configs));
-
+ msm9625_disp_init_gpiomux();
}
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index f3ee02b..439ecdc 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -2782,7 +2782,7 @@
if (device->state == KGSL_STATE_ACTIVE) {
/* Is the ring buffer is empty? */
GSL_RB_GET_READPTR(rb, &rb->rptr);
- if (!device->active_cnt && (rb->rptr == rb->wptr)) {
+ if (rb->rptr == rb->wptr) {
/*
* Are there interrupts pending? If so then pretend we
* are not idle - this avoids the possiblity that we go
@@ -3596,15 +3596,20 @@
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
- unsigned int cycles;
+ unsigned int cycles = 0;
- /* Get the busy cycles counted since the counter was last reset */
- /* Calling this function also resets and restarts the counter */
+ /*
+ * Get the busy cycles counted since the counter was last reset.
+ * If we're not currently active, there shouldn't have been
+ * any cycles since the last time this function was called.
+ */
+ if (device->state == KGSL_STATE_ACTIVE)
+ cycles = adreno_dev->gpudev->busy_cycles(adreno_dev);
- cycles = adreno_dev->gpudev->busy_cycles(adreno_dev);
-
- /* In order to calculate idle you have to have run the algorithm *
- * at least once to get a start time. */
+ /*
+ * In order to calculate idle you have to have run the algorithm
+ * at least once to get a start time.
+ */
if (pwr->time != 0) {
s64 tmp = ktime_to_us(ktime_get());
stats->total_time = tmp - pwr->time;
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index ef599e9..980ff13 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -93,4 +93,7 @@
adreno_dev->ft_pf_policy = KGSL_FT_PAGEFAULT_DEFAULT_POLICY;
debugfs_create_u32("ft_pagefault_policy", 0644, device->d_debugfs,
&adreno_dev->ft_pf_policy);
+
+ debugfs_create_u32("active_cnt", 0444, device->d_debugfs,
+ &device->active_cnt);
}
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 53ef392..08dd886 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -413,27 +413,6 @@
kfree(context);
}
-static void kgsl_check_idle_locked(struct kgsl_device *device)
-{
- if (device->pwrctrl.nap_allowed == true &&
- device->state == KGSL_STATE_ACTIVE &&
- device->requested_state == KGSL_STATE_NONE) {
- kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
- kgsl_pwrscale_idle(device);
- if (kgsl_pwrctrl_sleep(device) != 0)
- mod_timer(&device->idle_timer,
- jiffies +
- device->pwrctrl.interval_timeout);
- }
-}
-
-static void kgsl_check_idle(struct kgsl_device *device)
-{
- mutex_lock(&device->mutex);
- kgsl_check_idle_locked(device);
- mutex_unlock(&device->mutex);
-}
-
struct kgsl_device *kgsl_get_device(int dev_idx)
{
int i;
@@ -496,13 +475,12 @@
policy_saved = device->pwrscale.policy;
device->pwrscale.policy = NULL;
kgsl_pwrctrl_request_state(device, KGSL_STATE_SUSPEND);
- /* Make sure no user process is waiting for a timestamp *
- * before supending */
- if (device->active_cnt != 0) {
- mutex_unlock(&device->mutex);
- wait_for_completion(&device->suspend_gate);
- mutex_lock(&device->mutex);
- }
+ /*
+ * Make sure no user process is waiting for a timestamp
+ * before supending.
+ */
+ kgsl_active_count_wait(device);
+
/* Don't let the timer wake us during suspended sleep. */
del_timer_sync(&device->idle_timer);
switch (device->state) {
@@ -513,6 +491,8 @@
device->ftbl->idle(device);
case KGSL_STATE_NAP:
case KGSL_STATE_SLEEP:
+ /* make sure power is on to stop the device */
+ kgsl_pwrctrl_enable(device);
/* Get the completion ready to be waited upon. */
INIT_COMPLETION(device->hwaccess_gate);
device->ftbl->suspend_context(device);
@@ -632,9 +612,16 @@
device->pwrctrl.restore_slumber = false;
if (device->pwrscale.policy == NULL)
kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_TURBO);
- kgsl_pwrctrl_wake(device);
+ if (kgsl_pwrctrl_wake(device) != 0)
+ return;
+ /*
+ * We don't have a way to go directly from
+ * a deeper sleep state to NAP, which is
+ * the desired state here.
+ */
+ kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
+ kgsl_pwrctrl_sleep(device);
mutex_unlock(&device->mutex);
- kgsl_check_idle(device);
KGSL_PWR_WARN(device, "late resume end\n");
}
EXPORT_SYMBOL(kgsl_late_resume_driver);
@@ -745,7 +732,7 @@
filep->private_data = NULL;
mutex_lock(&device->mutex);
- kgsl_check_suspended(device);
+ kgsl_active_count_get(device);
while (1) {
context = idr_get_next(&device->context_idr, &next);
@@ -767,10 +754,17 @@
device->open_count--;
if (device->open_count == 0) {
+ BUG_ON(device->active_cnt > 1);
result = device->ftbl->stop(device);
kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
+ /*
+ * active_cnt special case: we just stopped the device,
+ * so no need to use kgsl_active_count_put()
+ */
+ device->active_cnt--;
+ } else {
+ kgsl_active_count_put(device);
}
-
mutex_unlock(&device->mutex);
kfree(dev_priv);
@@ -816,9 +810,14 @@
filep->private_data = dev_priv;
mutex_lock(&device->mutex);
- kgsl_check_suspended(device);
if (device->open_count == 0) {
+ /*
+ * active_cnt special case: we are starting up for the first
+ * time, so use this sequence instead of the kgsl_pwrctrl_wake()
+ * which will be called by kgsl_active_count_get().
+ */
+ device->active_cnt++;
kgsl_sharedmem_set(&device->memstore, 0, 0,
device->memstore.size);
@@ -831,6 +830,7 @@
goto err_freedevpriv;
kgsl_pwrctrl_set_state(device, KGSL_STATE_ACTIVE);
+ kgsl_active_count_put(device);
}
device->open_count++;
mutex_unlock(&device->mutex);
@@ -856,10 +856,15 @@
mutex_lock(&device->mutex);
device->open_count--;
if (device->open_count == 0) {
+ /* make sure power is on to stop the device */
+ kgsl_pwrctrl_enable(device);
result = device->ftbl->stop(device);
kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
}
err_freedevpriv:
+ /* only the first open takes an active count */
+ if (device->open_count == 0)
+ device->active_cnt--;
mutex_unlock(&device->mutex);
filep->private_data = NULL;
kfree(dev_priv);
@@ -1073,10 +1078,6 @@
struct kgsl_device *device = dev_priv->device;
unsigned int context_id = context ? context->id : KGSL_MEMSTORE_GLOBAL;
- /* Set the active count so that suspend doesn't do the wrong thing */
-
- device->active_cnt++;
-
trace_kgsl_waittimestamp_entry(device, context_id,
kgsl_readtimestamp(device, context,
KGSL_TIMESTAMP_RETIRED),
@@ -1090,9 +1091,6 @@
KGSL_TIMESTAMP_RETIRED),
result);
- /* Fire off any pending suspend operations that are in flight */
- kgsl_active_count_put(dev_priv->device);
-
return result;
}
@@ -1887,7 +1885,6 @@
trace_kgsl_mem_map(entry, param->fd);
- kgsl_check_idle(dev_priv->device);
return result;
error_unmap:
@@ -1907,7 +1904,6 @@
}
error:
kfree(entry);
- kgsl_check_idle(dev_priv->device);
return result;
}
@@ -2035,7 +2031,6 @@
entry->memtype = KGSL_MEM_ENTRY_KERNEL;
- kgsl_check_idle(dev_priv->device);
*ret_entry = entry;
return result;
err:
@@ -2370,7 +2365,7 @@
kgsl_ioctl_cff_user_event, 0),
KGSL_IOCTL_FUNC(IOCTL_KGSL_TIMESTAMP_EVENT,
kgsl_ioctl_timestamp_event,
- KGSL_IOCTL_LOCK),
+ KGSL_IOCTL_LOCK | KGSL_IOCTL_WAKE),
KGSL_IOCTL_FUNC(IOCTL_KGSL_SETPROPERTY,
kgsl_ioctl_device_setproperty,
KGSL_IOCTL_LOCK | KGSL_IOCTL_WAKE),
@@ -2462,14 +2457,19 @@
if (lock) {
mutex_lock(&dev_priv->device->mutex);
- if (use_hw)
- kgsl_check_suspended(dev_priv->device);
+ if (use_hw) {
+ ret = kgsl_active_count_get(dev_priv->device);
+ if (ret < 0)
+ goto unlock;
+ }
}
ret = func(dev_priv, cmd, uptr);
+unlock:
if (lock) {
- kgsl_check_idle_locked(dev_priv->device);
+ if (use_hw)
+ kgsl_active_count_put(dev_priv->device);
mutex_unlock(&dev_priv->device->mutex);
}
@@ -3032,11 +3032,7 @@
/* For a manual dump, make sure that the system is idle */
if (manual) {
- if (device->active_cnt != 0) {
- mutex_unlock(&device->mutex);
- wait_for_completion(&device->suspend_gate);
- mutex_lock(&device->mutex);
- }
+ kgsl_active_count_wait(device);
if (device->state == KGSL_STATE_ACTIVE)
kgsl_idle(device);
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 0d11660..ac82820 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -454,23 +454,4 @@
kref_put(&context->refcount, kgsl_context_destroy);
}
-/**
- * kgsl_active_count_put - Decrease the device active count
- * @device: Pointer to a KGSL device
- *
- * Decrease the active count for the KGSL device and trigger the suspend_gate
- * completion if it hits zero
- */
-static inline void
-kgsl_active_count_put(struct kgsl_device *device)
-{
- if (device->active_cnt == 1)
- INIT_COMPLETION(device->suspend_gate);
-
- device->active_cnt--;
-
- if (device->active_cnt == 0)
- complete(&device->suspend_gate);
-}
-
#endif /* __KGSL_DEVICE_H */
diff --git a/drivers/gpu/msm/kgsl_events.c b/drivers/gpu/msm/kgsl_events.c
index 9e9c0da..d872783 100644
--- a/drivers/gpu/msm/kgsl_events.c
+++ b/drivers/gpu/msm/kgsl_events.c
@@ -51,6 +51,7 @@
void (*cb)(struct kgsl_device *, void *, u32, u32), void *priv,
void *owner)
{
+ int ret;
struct kgsl_event *event;
unsigned int cur_ts;
struct kgsl_context *context = NULL;
@@ -82,6 +83,16 @@
if (event == NULL)
return -ENOMEM;
+ /*
+ * Increase the active count on the device to avoid going into power
+ * saving modes while events are pending
+ */
+ ret = kgsl_active_count_get_light(device);
+ if (ret < 0) {
+ kfree(event);
+ return ret;
+ }
+
event->context = context;
event->timestamp = ts;
event->priv = priv;
@@ -112,13 +123,6 @@
} else
_add_event_to_list(&device->events, event);
- /*
- * Increase the active count on the device to avoid going into power
- * saving modes while events are pending
- */
-
- device->active_cnt++;
-
queue_work(device->work_queue, &device->ts_expired_ws);
return 0;
}
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 2f8d93e..7d05aea 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -1055,6 +1055,14 @@
pwr->power_flags = 0;
}
+/**
+ * kgsl_idle_check() - Work function for GPU interrupts and idle timeouts.
+ * @device: The device
+ *
+ * This function is called for work that is queued by the interrupt
+ * handler or the idle timer. It attempts to transition to a clocks
+ * off state if the active_cnt is 0 and the hardware is idle.
+ */
void kgsl_idle_check(struct work_struct *work)
{
struct kgsl_device *device = container_of(work, struct kgsl_device,
@@ -1064,15 +1072,22 @@
return;
mutex_lock(&device->mutex);
- if (device->state & (KGSL_STATE_ACTIVE | KGSL_STATE_NAP)) {
- kgsl_pwrscale_idle(device);
- if (kgsl_pwrctrl_sleep(device) != 0) {
+ kgsl_pwrscale_idle(device);
+
+ if (device->state == KGSL_STATE_ACTIVE
+ || device->state == KGSL_STATE_NAP) {
+ if (device->active_cnt > 0 || kgsl_pwrctrl_sleep(device) != 0) {
+
+ kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+
mod_timer(&device->idle_timer,
jiffies +
device->pwrctrl.interval_timeout);
- /* If the GPU has been too busy to sleep, make sure *
- * that is acurately reflected in the % busy numbers. */
+ /*
+ * If the GPU has been too busy to sleep, make sure
+ * that is acurately reflected in the % busy numbers.
+ */
device->pwrctrl.clk_stats.no_nap_cnt++;
if (device->pwrctrl.clk_stats.no_nap_cnt >
UPDATE_BUSY) {
@@ -1104,54 +1119,26 @@
}
}
+
+/**
+ * kgsl_pre_hwaccess - Enforce preconditions for touching registers
+ * @device: The device
+ *
+ * This function ensures that the correct lock is held and that the GPU
+ * clock is on immediately before a register is read or written. Note
+ * that this function does not check active_cnt because the registers
+ * must be accessed during device start and stop, when the active_cnt
+ * may legitimately be 0.
+ */
void kgsl_pre_hwaccess(struct kgsl_device *device)
{
+ /* In order to touch a register you must hold the device mutex...*/
BUG_ON(!mutex_is_locked(&device->mutex));
- switch (device->state) {
- case KGSL_STATE_ACTIVE:
- return;
- case KGSL_STATE_NAP:
- case KGSL_STATE_SLEEP:
- case KGSL_STATE_SLUMBER:
- kgsl_pwrctrl_wake(device);
- break;
- case KGSL_STATE_SUSPEND:
- kgsl_check_suspended(device);
- break;
- case KGSL_STATE_INIT:
- case KGSL_STATE_HUNG:
- case KGSL_STATE_DUMP_AND_FT:
- if (test_bit(KGSL_PWRFLAGS_CLK_ON,
- &device->pwrctrl.power_flags))
- break;
- else
- KGSL_PWR_ERR(device,
- "hw access while clocks off from state %d\n",
- device->state);
- break;
- default:
- KGSL_PWR_ERR(device, "hw access while in unknown state %d\n",
- device->state);
- break;
- }
+ /* and have the clock on! */
+ BUG_ON(!test_bit(KGSL_PWRFLAGS_CLK_ON, &device->pwrctrl.power_flags));
}
EXPORT_SYMBOL(kgsl_pre_hwaccess);
-void kgsl_check_suspended(struct kgsl_device *device)
-{
- if (device->requested_state == KGSL_STATE_SUSPEND ||
- device->state == KGSL_STATE_SUSPEND) {
- mutex_unlock(&device->mutex);
- wait_for_completion(&device->hwaccess_gate);
- mutex_lock(&device->mutex);
- } else if (device->state == KGSL_STATE_DUMP_AND_FT) {
- mutex_unlock(&device->mutex);
- wait_for_completion(&device->ft_gate);
- mutex_lock(&device->mutex);
- } else if (device->state == KGSL_STATE_SLUMBER)
- kgsl_pwrctrl_wake(device);
-}
-
static int
_nap(struct kgsl_device *device)
{
@@ -1230,6 +1217,8 @@
case KGSL_STATE_NAP:
case KGSL_STATE_SLEEP:
del_timer_sync(&device->idle_timer);
+ /* make sure power is on to stop the device*/
+ kgsl_pwrctrl_enable(device);
device->ftbl->suspend_context(device);
device->ftbl->stop(device);
_sleep_accounting(device);
@@ -1278,9 +1267,9 @@
/******************************************************************/
/* Caller must hold the device mutex. */
-void kgsl_pwrctrl_wake(struct kgsl_device *device)
+int kgsl_pwrctrl_wake(struct kgsl_device *device)
{
- int status;
+ int status = 0;
unsigned int context_id;
unsigned int state = device->state;
unsigned int ts_processed = 0xdeaddead;
@@ -1329,8 +1318,10 @@
KGSL_PWR_WARN(device, "unhandled state %s\n",
kgsl_pwrstate_to_str(device->state));
kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+ status = -EINVAL;
break;
}
+ return status;
}
EXPORT_SYMBOL(kgsl_pwrctrl_wake);
@@ -1396,3 +1387,124 @@
}
EXPORT_SYMBOL(kgsl_pwrstate_to_str);
+
+/**
+ * kgsl_active_count_get() - Increase the device active count
+ * @device: Pointer to a KGSL device
+ *
+ * Increase the active count for the KGSL device and turn on
+ * clocks if this is the first reference. Code paths that need
+ * to touch the hardware or wait for the hardware to complete
+ * an operation must hold an active count reference until they
+ * are finished. An error code will be returned if waking the
+ * device fails. The device mutex must be held while *calling
+ * this function.
+ */
+int kgsl_active_count_get(struct kgsl_device *device)
+{
+ int ret = 0;
+ BUG_ON(!mutex_is_locked(&device->mutex));
+
+ if (device->active_cnt == 0) {
+ if (device->requested_state == KGSL_STATE_SUSPEND ||
+ device->state == KGSL_STATE_SUSPEND) {
+ mutex_unlock(&device->mutex);
+ wait_for_completion(&device->hwaccess_gate);
+ mutex_lock(&device->mutex);
+ } else if (device->state == KGSL_STATE_DUMP_AND_FT) {
+ mutex_unlock(&device->mutex);
+ wait_for_completion(&device->ft_gate);
+ mutex_lock(&device->mutex);
+ }
+ ret = kgsl_pwrctrl_wake(device);
+ }
+ if (ret == 0)
+ device->active_cnt++;
+ return ret;
+}
+EXPORT_SYMBOL(kgsl_active_count_get);
+
+/**
+ * kgsl_active_count_get_light() - Increase the device active count
+ * @device: Pointer to a KGSL device
+ *
+ * Increase the active count for the KGSL device WITHOUT
+ * turning on the clocks. Currently this is only used for creating
+ * kgsl_events. The device mutex must be held while calling this function.
+ */
+int kgsl_active_count_get_light(struct kgsl_device *device)
+{
+ BUG_ON(!mutex_is_locked(&device->mutex));
+
+ if (device->state != KGSL_STATE_ACTIVE) {
+ dev_WARN_ONCE(device->dev, 1, "device in unexpected state %s\n",
+ kgsl_pwrstate_to_str(device->state));
+ return -EINVAL;
+ }
+
+ if (device->active_cnt == 0) {
+ dev_WARN_ONCE(device->dev, 1, "active count is 0!\n");
+ return -EINVAL;
+ }
+
+ device->active_cnt++;
+ return 0;
+}
+EXPORT_SYMBOL(kgsl_active_count_get_light);
+
+/**
+ * kgsl_active_count_put() - Decrease the device active count
+ * @device: Pointer to a KGSL device
+ *
+ * Decrease the active count for the KGSL device and turn off
+ * clocks if there are no remaining references. This function will
+ * transition the device to NAP if there are no other pending state
+ * changes. It also completes the suspend gate. The device mutex must
+ * be held while calling this function.
+ */
+void kgsl_active_count_put(struct kgsl_device *device)
+{
+ BUG_ON(!mutex_is_locked(&device->mutex));
+ BUG_ON(device->active_cnt == 0);
+
+ kgsl_pwrscale_idle(device);
+ if (device->active_cnt > 1) {
+ device->active_cnt--;
+ return;
+ }
+
+ INIT_COMPLETION(device->suspend_gate);
+
+ if (device->pwrctrl.nap_allowed == true &&
+ (device->state == KGSL_STATE_ACTIVE &&
+ device->requested_state == KGSL_STATE_NONE)) {
+ kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
+ if (kgsl_pwrctrl_sleep(device) != 0)
+ mod_timer(&device->idle_timer,
+ jiffies
+ + device->pwrctrl.interval_timeout);
+ }
+ device->active_cnt--;
+
+ if (device->active_cnt == 0)
+ complete(&device->suspend_gate);
+}
+EXPORT_SYMBOL(kgsl_active_count_put);
+
+/**
+ * kgsl_active_count_wait() - Wait for activity to finish.
+ * @device: Pointer to a KGSL device
+ *
+ * Block until all active_cnt users put() their reference.
+ */
+void kgsl_active_count_wait(struct kgsl_device *device)
+{
+ BUG_ON(!mutex_is_locked(&device->mutex));
+
+ if (device->active_cnt != 0) {
+ mutex_unlock(&device->mutex);
+ wait_for_completion(&device->suspend_gate);
+ mutex_lock(&device->mutex);
+ }
+}
+EXPORT_SYMBOL(kgsl_active_count_wait);
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index ced52e1..0fd64c3 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -99,9 +99,8 @@
void kgsl_timer(unsigned long data);
void kgsl_idle_check(struct work_struct *work);
void kgsl_pre_hwaccess(struct kgsl_device *device);
-void kgsl_check_suspended(struct kgsl_device *device);
int kgsl_pwrctrl_sleep(struct kgsl_device *device);
-void kgsl_pwrctrl_wake(struct kgsl_device *device);
+int kgsl_pwrctrl_wake(struct kgsl_device *device);
void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device,
unsigned int level);
int kgsl_pwrctrl_init_sysfs(struct kgsl_device *device);
@@ -115,4 +114,10 @@
void kgsl_pwrctrl_set_state(struct kgsl_device *device, unsigned int state);
void kgsl_pwrctrl_request_state(struct kgsl_device *device, unsigned int state);
+
+int kgsl_active_count_get(struct kgsl_device *device);
+int kgsl_active_count_get_light(struct kgsl_device *device);
+void kgsl_active_count_put(struct kgsl_device *device);
+void kgsl_active_count_wait(struct kgsl_device *device);
+
#endif /* __KGSL_PWRCTRL_H */
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index deda0c8..29b269a 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -397,6 +397,7 @@
atomic_t st_enabled;
atomic_t st_pending_irqs;
struct completion st_completion;
+ struct completion st_powerdown;
#endif
};
@@ -1001,8 +1002,8 @@
static irqreturn_t mxt_filter_interrupt(struct mxt_data *data)
{
if (atomic_read(&data->st_enabled)) {
- atomic_cmpxchg(&data->st_pending_irqs, 0, 1);
- complete(&data->st_completion);
+ if (atomic_cmpxchg(&data->st_pending_irqs, 0, 1) == 0)
+ complete(&data->st_completion);
return IRQ_HANDLED;
}
return IRQ_NONE;
@@ -1996,6 +1997,7 @@
atomic_set(&data->st_enabled, 0);
complete(&data->st_completion);
mxt_interrupt(data->client->irq, data);
+ complete(&data->st_powerdown);
break;
case 1:
if (atomic_read(&data->st_enabled)) {
@@ -2008,6 +2010,8 @@
err = -EIO;
break;
}
+ INIT_COMPLETION(data->st_completion);
+ INIT_COMPLETION(data->st_powerdown);
atomic_set(&data->st_pending_irqs, 0);
atomic_set(&data->st_enabled, 1);
break;
@@ -2035,7 +2039,7 @@
return err;
if (atomic_cmpxchg(&data->st_pending_irqs, 1, 0) != 1)
- return -EBADF;
+ return -EINVAL;
return scnprintf(buf, PAGE_SIZE, "%u", 1);
}
@@ -2064,9 +2068,25 @@
.attrs = mxt_attrs,
};
+
+#if defined(CONFIG_SECURE_TOUCH)
+static void mxt_secure_touch_stop(struct mxt_data *data)
+{
+ if (atomic_read(&data->st_enabled)) {
+ complete(&data->st_completion);
+ wait_for_completion_interruptible(&data->st_powerdown);
+ }
+}
+#else
+static void mxt_secure_touch_stop(struct mxt_data *data)
+{
+}
+#endif
+
static int mxt_start(struct mxt_data *data)
{
int error;
+ mxt_secure_touch_stop(data);
/* restore the old power state values and reenable touch */
error = __mxt_write_reg(data->client, data->t7_start_addr,
@@ -2084,6 +2104,7 @@
{
int error;
u8 t7_data[T7_DATA_SIZE] = {0};
+ mxt_secure_touch_stop(data);
error = __mxt_write_reg(data->client, data->t7_start_addr,
T7_DATA_SIZE, t7_data);
@@ -2465,6 +2486,7 @@
/* calibrate */
if (data->pdata->need_calibration) {
+ mxt_secure_touch_stop(data);
error = mxt_write_object(data, MXT_GEN_COMMAND_T6,
MXT_COMMAND_CALIBRATE, 1);
if (error < 0)
@@ -2800,12 +2822,13 @@
#endif
#if defined(CONFIG_SECURE_TOUCH)
-static void __devinit secure_touch_init(struct mxt_data *data)
+static void __devinit mxt_secure_touch_init(struct mxt_data *data)
{
init_completion(&data->st_completion);
+ init_completion(&data->st_powerdown);
}
#else
-static void __devinit secure_touch_init(struct mxt_data *data)
+static void __devinit mxt_secure_touch_init(struct mxt_data *data)
{
}
#endif
@@ -3002,7 +3025,7 @@
mxt_debugfs_init(data);
- secure_touch_init(data);
+ mxt_secure_touch_init(data);
return 0;
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 61adfec..55e3e4e 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -673,7 +673,7 @@
app_id = ret;
if (app_id) {
- pr_warn("App id %d (%s) already exists\n", app_id,
+ pr_debug("App id %d (%s) already exists\n", app_id,
(char *)(req.app_name));
spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
list_for_each_entry(entry,
@@ -831,7 +831,7 @@
break;
} else {
ptr_app->ref_cnt--;
- pr_warn("Can't unload app(%d) inuse\n",
+ pr_debug("Can't unload app(%d) inuse\n",
ptr_app->app_id);
break;
}
@@ -2316,7 +2316,7 @@
pr_err(" scm call to check if app is loaded failed");
return ret; /* scm call failed */
} else if (ret > 0) {
- pr_warn("App id %d (%s) already exists\n", ret,
+ pr_debug("App id %d (%s) already exists\n", ret,
(char *)(req.app_name));
spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
list_for_each_entry(entry,
diff --git a/drivers/video/msm/mdss/dsi_host_v2.c b/drivers/video/msm/mdss/dsi_host_v2.c
index 453cbaa..887dde7 100644
--- a/drivers/video/msm/mdss/dsi_host_v2.c
+++ b/drivers/video/msm/mdss/dsi_host_v2.c
@@ -29,6 +29,7 @@
#define DSI_POLL_SLEEP_US 1000
#define DSI_POLL_TIMEOUT_US 16000
#define DSI_ESC_CLK_RATE 19200000
+#define DSI_DMA_CMD_TIMEOUT_MS 200
struct dsi_host_v2_private {
struct completion dma_comp;
@@ -426,18 +427,15 @@
dsi_ctrl = MIPI_INP(ctrl_base + DSI_CTRL);
/*If Video enabled, Keep Video and Cmd mode ON */
- if (dsi_ctrl & 0x02)
- dsi_ctrl &= ~0x05;
- else
- dsi_ctrl &= ~0x07;
+
+
+ dsi_ctrl &= ~0x06;
if (mode == DSI_VIDEO_MODE) {
- dsi_ctrl |= 0x03;
+ dsi_ctrl |= 0x02;
intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK;
} else { /* command mode */
- dsi_ctrl |= 0x05;
- if (pdata->panel_info.type == MIPI_VIDEO_PANEL)
- dsi_ctrl |= 0x02;
+ dsi_ctrl |= 0x04;
intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK | DSI_INTR_ERROR_MASK |
DSI_INTR_CMD_MDP_DONE_MASK;
@@ -480,7 +478,7 @@
int msm_dsi_cmd_dma_tx(struct dsi_buf *tp)
{
- int len;
+ int len, rc;
unsigned long size, addr;
unsigned char *ctrl_base = dsi_host_private->dsi_base;
@@ -505,12 +503,17 @@
MIPI_OUTP(ctrl_base + DSI_CMD_MODE_DMA_SW_TRIGGER, 0x01);
wmb();
- wait_for_completion_interruptible(&dsi_host_private->dma_comp);
+ rc = wait_for_completion_timeout(&dsi_host_private->dma_comp,
+ msecs_to_jiffies(DSI_DMA_CMD_TIMEOUT_MS));
+ if (rc == 0) {
+ pr_err("DSI command transaction time out\n");
+ rc = -ETIME;
+ }
dma_unmap_single(&dsi_host_private->dis_dev, tp->dmap, size,
DMA_TO_DEVICE);
tp->dmap = 0;
- return 0;
+ return rc;
}
int msm_dsi_cmd_dma_rx(struct dsi_buf *rp, int rlen)
@@ -723,6 +726,7 @@
static int msm_dsi_cal_clk_rate(struct mdss_panel_data *pdata,
u32 *bitclk_rate,
+ u32 *dsiclk_rate,
u32 *byteclk_rate,
u32 *pclk_rate)
{
@@ -761,10 +765,11 @@
*bitclk_rate /= lanes;
*byteclk_rate = *bitclk_rate / 8;
+ *dsiclk_rate = *byteclk_rate * lanes;
*pclk_rate = *byteclk_rate * lanes * 8 / pdata->panel_info.bpp;
- pr_debug("bitclk=%u, byteclk=%u, pck_=%u\n",
- *bitclk_rate, *byteclk_rate, *pclk_rate);
+ pr_debug("dsiclk_rate=%u, byteclk=%u, pck_=%u\n",
+ *dsiclk_rate, *byteclk_rate, *pclk_rate);
return 0;
}
@@ -777,7 +782,7 @@
u32 hbp, hfp, vbp, vfp, hspw, vspw, width, height;
u32 ystride, bpp, data;
u32 dummy_xres, dummy_yres;
- u32 bitclk_rate = 0, byteclk_rate = 0, pclk_rate = 0;
+ u32 bitclk_rate = 0, byteclk_rate = 0, pclk_rate = 0, dsiclk_rate = 0;
unsigned char *ctrl_base = dsi_host_private->dsi_base;
pr_debug("msm_dsi_on\n");
@@ -794,8 +799,10 @@
msm_dsi_phy_sw_reset(dsi_host_private->dsi_base);
msm_dsi_phy_init(dsi_host_private->dsi_base, pdata);
- msm_dsi_cal_clk_rate(pdata, &bitclk_rate, &byteclk_rate, &pclk_rate);
- msm_dsi_clk_set_rate(DSI_ESC_CLK_RATE, byteclk_rate, pclk_rate);
+ msm_dsi_cal_clk_rate(pdata, &bitclk_rate, &dsiclk_rate,
+ &byteclk_rate, &pclk_rate);
+ msm_dsi_clk_set_rate(DSI_ESC_CLK_RATE, dsiclk_rate,
+ byteclk_rate, pclk_rate);
msm_dsi_prepare_clocks();
msm_dsi_clk_enable();
@@ -879,12 +886,11 @@
int ret = 0;
pr_debug("msm_dsi_off\n");
- msm_dsi_clk_set_rate(0, 0, 0);
+ msm_dsi_controller_cfg(0);
+ msm_dsi_clk_set_rate(DSI_ESC_CLK_RATE, 0, 0, 0);
msm_dsi_clk_disable();
msm_dsi_unprepare_clocks();
- /* disable DSI controller */
- msm_dsi_controller_cfg(0);
msm_dsi_ahb_ctrl(0);
ret = msm_dsi_regulator_disable();
diff --git a/drivers/video/msm/mdss/dsi_io_v2.c b/drivers/video/msm/mdss/dsi_io_v2.c
index 0486c4c..93f2c76 100644
--- a/drivers/video/msm/mdss/dsi_io_v2.c
+++ b/drivers/video/msm/mdss/dsi_io_v2.c
@@ -29,6 +29,7 @@
struct clk *dsi_esc_clk;
struct clk *dsi_pixel_clk;
struct clk *dsi_ahb_clk;
+ struct clk *dsi_clk;
int msm_dsi_clk_on;
int msm_dsi_ahb_clk_on;
};
@@ -97,6 +98,13 @@
{
int rc = 0;
+ dsi_io_private->dsi_clk = clk_get(&dev->dev, "dsi_clk");
+ if (IS_ERR(dsi_io_private->dsi_clk)) {
+ pr_err("can't find dsi core_clk\n");
+ rc = PTR_ERR(dsi_io_private->dsi_clk);
+ dsi_io_private->dsi_clk = NULL;
+ return rc;
+ }
dsi_io_private->dsi_byte_clk = clk_get(&dev->dev, "byte_clk");
if (IS_ERR(dsi_io_private->dsi_byte_clk)) {
pr_err("can't find dsi byte_clk\n");
@@ -135,6 +143,10 @@
void msm_dsi_clk_deinit(void)
{
+ if (dsi_io_private->dsi_clk) {
+ clk_put(dsi_io_private->dsi_clk);
+ dsi_io_private->dsi_clk = NULL;
+ }
if (dsi_io_private->dsi_byte_clk) {
clk_put(dsi_io_private->dsi_byte_clk);
dsi_io_private->dsi_byte_clk = NULL;
@@ -156,6 +168,7 @@
int msm_dsi_prepare_clocks(void)
{
+ clk_prepare(dsi_io_private->dsi_clk);
clk_prepare(dsi_io_private->dsi_byte_clk);
clk_prepare(dsi_io_private->dsi_esc_clk);
clk_prepare(dsi_io_private->dsi_pixel_clk);
@@ -164,16 +177,24 @@
int msm_dsi_unprepare_clocks(void)
{
+ clk_unprepare(dsi_io_private->dsi_clk);
clk_unprepare(dsi_io_private->dsi_esc_clk);
clk_unprepare(dsi_io_private->dsi_byte_clk);
clk_unprepare(dsi_io_private->dsi_pixel_clk);
return 0;
}
-int msm_dsi_clk_set_rate(unsigned long esc_rate, unsigned long byte_rate,
+int msm_dsi_clk_set_rate(unsigned long esc_rate,
+ unsigned long dsi_rate,
+ unsigned long byte_rate,
unsigned long pixel_rate)
{
int rc;
+ rc = clk_set_rate(dsi_io_private->dsi_clk, dsi_rate);
+ if (rc) {
+ pr_err("dsi_esc_clk - clk_set_rate failed =%d\n", rc);
+ return rc;
+ }
rc = clk_set_rate(dsi_io_private->dsi_esc_clk, esc_rate);
if (rc) {
@@ -202,6 +223,7 @@
return 0;
}
+ clk_enable(dsi_io_private->dsi_clk);
clk_enable(dsi_io_private->dsi_esc_clk);
clk_enable(dsi_io_private->dsi_byte_clk);
clk_enable(dsi_io_private->dsi_pixel_clk);
@@ -217,6 +239,7 @@
return 0;
}
+ clk_disable(dsi_io_private->dsi_clk);
clk_disable(dsi_io_private->dsi_byte_clk);
clk_disable(dsi_io_private->dsi_esc_clk);
clk_disable(dsi_io_private->dsi_pixel_clk);
@@ -246,7 +269,7 @@
void msm_dsi_regulator_deinit(void)
{
- if (dsi_io_private->vdda_vreg) {
+ if (!IS_ERR(dsi_io_private->vdda_vreg)) {
devm_regulator_put(dsi_io_private->vdda_vreg);
dsi_io_private->vdda_vreg = NULL;
}
diff --git a/drivers/video/msm/mdss/dsi_io_v2.h b/drivers/video/msm/mdss/dsi_io_v2.h
index 25ecd7f..285bf30 100644
--- a/drivers/video/msm/mdss/dsi_io_v2.h
+++ b/drivers/video/msm/mdss/dsi_io_v2.h
@@ -29,7 +29,9 @@
int msm_dsi_unprepare_clocks(void);
-int msm_dsi_clk_set_rate(unsigned long esc_rate, unsigned long byte_rate,
+int msm_dsi_clk_set_rate(unsigned long esc_rate,
+ unsigned long dsi_rate,
+ unsigned long byte_rate,
unsigned long pixel_rate);
int msm_dsi_clk_enable(void);
diff --git a/drivers/video/msm/mdss/dsi_panel_v2.c b/drivers/video/msm/mdss/dsi_panel_v2.c
index 6686de3..e46ea3b 100644
--- a/drivers/video/msm/mdss/dsi_panel_v2.c
+++ b/drivers/video/msm/mdss/dsi_panel_v2.c
@@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/leds.h>
+#include <linux/err.h>
#include <linux/regulator/consumer.h>
#include "dsi_v2.h"
@@ -32,6 +33,7 @@
int rst_gpio;
int disp_en_gpio;
+ int video_mode_gpio;
char bl_ctrl;
struct regulator *vddio_vreg;
@@ -40,6 +42,9 @@
struct dsi_panel_cmds_list *on_cmds_list;
struct dsi_panel_cmds_list *off_cmds_list;
struct mdss_dsi_phy_ctrl phy_params;
+
+ char *on_cmds;
+ char *off_cmds;
};
static struct dsi_panel_private *panel_private;
@@ -82,15 +87,54 @@
kfree(panel_private->dsi_panel_tx_buf.start);
kfree(panel_private->dsi_panel_rx_buf.start);
- if (panel_private->vddio_vreg)
+ if (!IS_ERR(panel_private->vddio_vreg))
devm_regulator_put(panel_private->vddio_vreg);
- if (panel_private->vdda_vreg)
- devm_regulator_put(panel_private->vddio_vreg);
+ if (!IS_ERR(panel_private->vdda_vreg))
+ devm_regulator_put(panel_private->vdda_vreg);
+ if (panel_private->on_cmds_list) {
+ kfree(panel_private->on_cmds_list->buf);
+ kfree(panel_private->on_cmds_list);
+ }
+ if (panel_private->off_cmds_list) {
+ kfree(panel_private->off_cmds_list->buf);
+ kfree(panel_private->off_cmds_list);
+ }
+
+ kfree(panel_private->on_cmds);
+ kfree(panel_private->off_cmds);
kfree(panel_private);
panel_private = NULL;
}
+int dsi_panel_power(int enable)
+{
+ int ret;
+ if (enable) {
+ ret = regulator_enable(panel_private->vddio_vreg);
+ if (ret) {
+ pr_err("dsi_panel_power regulator enable vddio fail\n");
+ return ret;
+ }
+ ret = regulator_enable(panel_private->vdda_vreg);
+ if (ret) {
+ pr_err("dsi_panel_power regulator enable vdda fail\n");
+ return ret;
+ }
+ } else {
+ ret = regulator_disable(panel_private->vddio_vreg);
+ if (ret) {
+ pr_err("dsi_panel_power regulator disable vddio fail\n");
+ return ret;
+ }
+ ret = regulator_disable(panel_private->vdda_vreg);
+ if (ret) {
+ pr_err("dsi_panel_power regulator dsiable vdda fail\n");
+ return ret;
+ }
+ }
+ return 0;
+}
void dsi_panel_reset(struct mdss_panel_data *pdata, int enable)
{
@@ -113,6 +157,8 @@
pr_debug("%s: enable = %d\n", __func__, enable);
if (enable) {
+ dsi_panel_power(1);
+ gpio_request(panel_private->rst_gpio, "panel_reset");
gpio_set_value(panel_private->rst_gpio, 1);
/*
* these delay values are by experiments currently, will need
@@ -123,12 +169,34 @@
udelay(200);
gpio_set_value(panel_private->rst_gpio, 1);
msleep(20);
- if (gpio_is_valid(panel_private->disp_en_gpio))
+ if (gpio_is_valid(panel_private->disp_en_gpio)) {
+ gpio_request(panel_private->disp_en_gpio,
+ "panel_enable");
gpio_set_value(panel_private->disp_en_gpio, 1);
+ }
+ if (gpio_is_valid(panel_private->video_mode_gpio)) {
+ gpio_request(panel_private->video_mode_gpio,
+ "panel_video_mdoe");
+ if (pdata->panel_info.mipi.mode == DSI_VIDEO_MODE)
+ gpio_set_value(panel_private->video_mode_gpio,
+ 1);
+ else
+ gpio_set_value(panel_private->video_mode_gpio,
+ 0);
+ }
} else {
gpio_set_value(panel_private->rst_gpio, 0);
- if (gpio_is_valid(panel_private->disp_en_gpio))
+ gpio_free(panel_private->rst_gpio);
+
+ if (gpio_is_valid(panel_private->disp_en_gpio)) {
gpio_set_value(panel_private->disp_en_gpio, 0);
+ gpio_free(panel_private->disp_en_gpio);
+ }
+
+ if (gpio_is_valid(panel_private->video_mode_gpio))
+ gpio_free(panel_private->video_mode_gpio);
+
+ dsi_panel_power(0);
}
}
@@ -196,13 +264,42 @@
panel_private->disp_en_gpio = of_get_named_gpio(np,
"qcom,enable-gpio", 0);
panel_private->rst_gpio = of_get_named_gpio(np, "qcom,rst-gpio", 0);
+ panel_private->video_mode_gpio = of_get_named_gpio(np,
+ "qcom,mode-selection-gpio", 0);
return 0;
}
static int dsi_panel_parse_regulator(struct platform_device *pdev)
{
+ int ret;
panel_private->vddio_vreg = devm_regulator_get(&pdev->dev, "vddio");
+ if (IS_ERR(panel_private->vddio_vreg)) {
+ pr_err("%s: could not get vddio vreg, rc=%ld\n",
+ __func__, PTR_ERR(panel_private->vddio_vreg));
+ return PTR_ERR(panel_private->vddio_vreg);
+ }
+ ret = regulator_set_voltage(panel_private->vddio_vreg,
+ 1800000,
+ 1800000);
+ if (ret) {
+ pr_err("%s: set voltage failed on vddio_vreg, rc=%d\n",
+ __func__, ret);
+ return ret;
+ }
panel_private->vdda_vreg = devm_regulator_get(&pdev->dev, "vdda");
+ if (IS_ERR(panel_private->vdda_vreg)) {
+ pr_err("%s: could not get vdda_vreg , rc=%ld\n",
+ __func__, PTR_ERR(panel_private->vdda_vreg));
+ return PTR_ERR(panel_private->vdda_vreg);
+ }
+ ret = regulator_set_voltage(panel_private->vdda_vreg,
+ 2850000,
+ 2850000);
+ if (ret) {
+ pr_err("%s: set voltage failed on vdda_vreg, rc=%d\n",
+ __func__, ret);
+ return ret;
+ }
return 0;
}
@@ -398,180 +495,163 @@
int cmd_plen, data_offset;
const char *data;
const char *on_cmds_state, *off_cmds_state;
- char *on_cmds = NULL, *off_cmds = NULL;
int num_of_on_cmds = 0, num_of_off_cmds = 0;
data = of_get_property(np, "qcom,panel-on-cmds", &len);
if (!data) {
pr_err("%s:%d, Unable to read ON cmds", __func__, __LINE__);
- goto parse_init_cmds_error;
+ return -EINVAL;
}
- on_cmds = kzalloc(sizeof(char) * len, GFP_KERNEL);
- if (!on_cmds)
- goto parse_init_cmds_error;
+ panel_private->on_cmds = kzalloc(sizeof(char) * len, GFP_KERNEL);
+ if (!panel_private->on_cmds)
+ return -ENOMEM;
- memcpy(on_cmds, data, len);
+ memcpy(panel_private->on_cmds, data, len);
data_offset = 0;
cmd_plen = 0;
while ((len - data_offset) >= DT_CMD_HDR) {
data_offset += (DT_CMD_HDR - 1);
- cmd_plen = on_cmds[data_offset++];
+ cmd_plen = panel_private->on_cmds[data_offset++];
data_offset += cmd_plen;
num_of_on_cmds++;
}
if (!num_of_on_cmds) {
pr_err("%s:%d, No ON cmds specified", __func__, __LINE__);
- goto parse_init_cmds_error;
+ return -EINVAL;
}
- panel_data->dsi_panel_on_cmds =
+ panel_private->on_cmds_list =
kzalloc(sizeof(struct dsi_panel_cmds_list), GFP_KERNEL);
- if (!panel_data->dsi_panel_on_cmds)
- goto parse_init_cmds_error;
+ if (!panel_private->on_cmds_list)
+ return -ENOMEM;
- (panel_data->dsi_panel_on_cmds)->buf =
+ panel_private->on_cmds_list->buf =
kzalloc((num_of_on_cmds * sizeof(struct dsi_cmd_desc)),
GFP_KERNEL);
- if (!(panel_data->dsi_panel_on_cmds)->buf)
- goto parse_init_cmds_error;
+ if (!panel_private->on_cmds_list->buf)
+ return -ENOMEM;
data_offset = 0;
for (i = 0; i < num_of_on_cmds; i++) {
- panel_data->dsi_panel_on_cmds->buf[i].dtype =
- on_cmds[data_offset++];
- panel_data->dsi_panel_on_cmds->buf[i].last =
- on_cmds[data_offset++];
- panel_data->dsi_panel_on_cmds->buf[i].vc =
- on_cmds[data_offset++];
- panel_data->dsi_panel_on_cmds->buf[i].ack =
- on_cmds[data_offset++];
- panel_data->dsi_panel_on_cmds->buf[i].wait =
- on_cmds[data_offset++];
- panel_data->dsi_panel_on_cmds->buf[i].dlen =
- on_cmds[data_offset++];
- panel_data->dsi_panel_on_cmds->buf[i].payload =
- &on_cmds[data_offset];
- data_offset += (panel_data->dsi_panel_on_cmds->buf[i].dlen);
+ panel_private->on_cmds_list->buf[i].dtype =
+ panel_private->on_cmds[data_offset++];
+ panel_private->on_cmds_list->buf[i].last =
+ panel_private->on_cmds[data_offset++];
+ panel_private->on_cmds_list->buf[i].vc =
+ panel_private->on_cmds[data_offset++];
+ panel_private->on_cmds_list->buf[i].ack =
+ panel_private->on_cmds[data_offset++];
+ panel_private->on_cmds_list->buf[i].wait =
+ panel_private->on_cmds[data_offset++];
+ panel_private->on_cmds_list->buf[i].dlen =
+ panel_private->on_cmds[data_offset++];
+ panel_private->on_cmds_list->buf[i].payload =
+ &panel_private->on_cmds[data_offset];
+ data_offset += (panel_private->on_cmds_list->buf[i].dlen);
}
if (data_offset != len) {
pr_err("%s:%d, Incorrect ON command entries",
__func__, __LINE__);
- goto parse_init_cmds_error;
+ return -EINVAL;
}
- (panel_data->dsi_panel_on_cmds)->size = num_of_on_cmds;
+ panel_private->on_cmds_list->size = num_of_on_cmds;
on_cmds_state = of_get_property(pdev->dev.of_node,
"qcom,on-cmds-dsi-state", NULL);
if (!strncmp(on_cmds_state, "DSI_LP_MODE", 11)) {
- (panel_data->dsi_panel_on_cmds)->ctrl_state = DSI_LP_MODE;
+ panel_private->on_cmds_list->ctrl_state = DSI_LP_MODE;
} else if (!strncmp(on_cmds_state, "DSI_HS_MODE", 11)) {
- (panel_data->dsi_panel_on_cmds)->ctrl_state = DSI_HS_MODE;
+ panel_private->on_cmds_list->ctrl_state = DSI_HS_MODE;
} else {
pr_debug("%s: ON cmds state not specified. Set Default\n",
__func__);
- (panel_data->dsi_panel_on_cmds)->ctrl_state = DSI_LP_MODE;
+ panel_private->on_cmds_list->ctrl_state = DSI_LP_MODE;
}
- panel_private->on_cmds_list = panel_data->dsi_panel_on_cmds;
+ panel_data->dsi_panel_on_cmds = panel_private->on_cmds_list;
+
data = of_get_property(np, "qcom,panel-off-cmds", &len);
if (!data) {
pr_err("%s:%d, Unable to read OFF cmds", __func__, __LINE__);
- goto parse_init_cmds_error;
+ return -EINVAL;
}
- off_cmds = kzalloc(sizeof(char) * len, GFP_KERNEL);
- if (!off_cmds)
- goto parse_init_cmds_error;
+ panel_private->off_cmds = kzalloc(sizeof(char) * len, GFP_KERNEL);
+ if (!panel_private->off_cmds)
+ return -ENOMEM;
- memcpy(off_cmds, data, len);
+ memcpy(panel_private->off_cmds, data, len);
data_offset = 0;
cmd_plen = 0;
while ((len - data_offset) >= DT_CMD_HDR) {
data_offset += (DT_CMD_HDR - 1);
- cmd_plen = off_cmds[data_offset++];
+ cmd_plen = panel_private->off_cmds[data_offset++];
data_offset += cmd_plen;
num_of_off_cmds++;
}
if (!num_of_off_cmds) {
pr_err("%s:%d, No OFF cmds specified", __func__, __LINE__);
- goto parse_init_cmds_error;
+ return -ENOMEM;
}
- panel_data->dsi_panel_off_cmds =
+ panel_private->off_cmds_list =
kzalloc(sizeof(struct dsi_panel_cmds_list), GFP_KERNEL);
- if (!panel_data->dsi_panel_off_cmds)
- goto parse_init_cmds_error;
+ if (!panel_private->off_cmds_list)
+ return -ENOMEM;
- (panel_data->dsi_panel_off_cmds)->buf = kzalloc(num_of_off_cmds
+ panel_private->off_cmds_list->buf = kzalloc(num_of_off_cmds
* sizeof(struct dsi_cmd_desc),
GFP_KERNEL);
- if (!(panel_data->dsi_panel_off_cmds)->buf)
- goto parse_init_cmds_error;
+ if (!panel_private->off_cmds_list->buf)
+ return -ENOMEM;
data_offset = 0;
for (i = 0; i < num_of_off_cmds; i++) {
- panel_data->dsi_panel_off_cmds->buf[i].dtype =
- off_cmds[data_offset++];
- panel_data->dsi_panel_off_cmds->buf[i].last =
- off_cmds[data_offset++];
- panel_data->dsi_panel_off_cmds->buf[i].vc =
- off_cmds[data_offset++];
- panel_data->dsi_panel_off_cmds->buf[i].ack =
- off_cmds[data_offset++];
- panel_data->dsi_panel_off_cmds->buf[i].wait =
- off_cmds[data_offset++];
- panel_data->dsi_panel_off_cmds->buf[i].dlen =
- off_cmds[data_offset++];
- panel_data->dsi_panel_off_cmds->buf[i].payload =
- &off_cmds[data_offset];
- data_offset += (panel_data->dsi_panel_off_cmds->buf[i].dlen);
+ panel_private->off_cmds_list->buf[i].dtype =
+ panel_private->off_cmds[data_offset++];
+ panel_private->off_cmds_list->buf[i].last =
+ panel_private->off_cmds[data_offset++];
+ panel_private->off_cmds_list->buf[i].vc =
+ panel_private->off_cmds[data_offset++];
+ panel_private->off_cmds_list->buf[i].ack =
+ panel_private->off_cmds[data_offset++];
+ panel_private->off_cmds_list->buf[i].wait =
+ panel_private->off_cmds[data_offset++];
+ panel_private->off_cmds_list->buf[i].dlen =
+ panel_private->off_cmds[data_offset++];
+ panel_private->off_cmds_list->buf[i].payload =
+ &panel_private->off_cmds[data_offset];
+ data_offset += (panel_private->off_cmds_list->buf[i].dlen);
}
if (data_offset != len) {
pr_err("%s:%d, Incorrect OFF command entries",
__func__, __LINE__);
- goto parse_init_cmds_error;
+ return -EINVAL;
}
- (panel_data->dsi_panel_off_cmds)->size = num_of_off_cmds;
- off_cmds_state = of_get_property(pdev->dev.of_node,
+ panel_private->off_cmds_list->size = num_of_off_cmds;
+ off_cmds_state = of_get_property(pdev->dev.of_node,
"qcom,off-cmds-dsi-state", NULL);
if (!strncmp(off_cmds_state, "DSI_LP_MODE", 11)) {
- (panel_data->dsi_panel_off_cmds)->ctrl_state =
+ panel_private->off_cmds_list->ctrl_state =
DSI_LP_MODE;
} else if (!strncmp(off_cmds_state, "DSI_HS_MODE", 11)) {
- (panel_data->dsi_panel_off_cmds)->ctrl_state = DSI_HS_MODE;
+ panel_private->off_cmds_list->ctrl_state = DSI_HS_MODE;
} else {
pr_debug("%s: ON cmds state not specified. Set Default\n",
__func__);
- (panel_data->dsi_panel_off_cmds)->ctrl_state = DSI_LP_MODE;
+ panel_private->off_cmds_list->ctrl_state = DSI_LP_MODE;
}
- panel_private->off_cmds_list = panel_data->dsi_panel_on_cmds;
- kfree(on_cmds);
- kfree(off_cmds);
+ panel_data->dsi_panel_off_cmds = panel_private->off_cmds_list;
return 0;
-parse_init_cmds_error:
- if (panel_data->dsi_panel_on_cmds) {
- kfree((panel_data->dsi_panel_on_cmds)->buf);
- kfree(panel_data->dsi_panel_on_cmds);
- panel_data->dsi_panel_on_cmds = NULL;
- }
- if (panel_data->dsi_panel_off_cmds) {
- kfree((panel_data->dsi_panel_off_cmds)->buf);
- kfree(panel_data->dsi_panel_off_cmds);
- panel_data->dsi_panel_off_cmds = NULL;
- }
-
- kfree(on_cmds);
- kfree(off_cmds);
- return -EINVAL;
}
static int dsi_panel_parse_backlight(struct platform_device *pdev,
@@ -709,6 +789,7 @@
vendor_pdata.on = dsi_panel_on;
vendor_pdata.off = dsi_panel_off;
+ vendor_pdata.reset = dsi_panel_reset;
vendor_pdata.bl_fnc = dsi_panel_bl_ctrl;
rc = dsi_panel_device_register_v2(pdev, &vendor_pdata,
diff --git a/drivers/video/msm/mdss/dsi_v2.c b/drivers/video/msm/mdss/dsi_v2.c
index 5e46bf5..5833796 100644
--- a/drivers/video/msm/mdss/dsi_v2.c
+++ b/drivers/video/msm/mdss/dsi_v2.c
@@ -29,6 +29,14 @@
if (!panel_common_data || !pdata)
return -ENODEV;
+ if (dsi_intf.op_mode_config)
+ dsi_intf.op_mode_config(DSI_CMD_MODE, pdata);
+
+ pr_debug("panel off commands\n");
+ if (panel_common_data->off)
+ panel_common_data->off(pdata);
+
+ pr_debug("turn off dsi controller\n");
if (dsi_intf.off)
rc = dsi_intf.off(pdata);
@@ -37,9 +45,9 @@
return rc;
}
- pr_debug("dsi_off reset\n");
- if (panel_common_data->off)
- panel_common_data->off(pdata);
+ pr_debug("turn off panel power\n");
+ if (panel_common_data->reset)
+ panel_common_data->reset(pdata, 0);
return rc;
}
@@ -53,8 +61,6 @@
if (!panel_common_data || !pdata)
return -ENODEV;
- if (panel_common_data->reset)
- panel_common_data->reset(1);
pr_debug("dsi_on DSI controller ont\n");
if (dsi_intf.on)
@@ -64,6 +70,9 @@
pr_err("mdss_dsi_on DSI failed %d\n", rc);
return rc;
}
+ pr_debug("dsi_on power on panel\n");
+ if (panel_common_data->reset)
+ panel_common_data->reset(pdata, 1);
pr_debug("dsi_on DSI panel ont\n");
if (panel_common_data->on)
diff --git a/drivers/video/msm/mdss/dsi_v2.h b/drivers/video/msm/mdss/dsi_v2.h
index fa868ab..f68527c 100644
--- a/drivers/video/msm/mdss/dsi_v2.h
+++ b/drivers/video/msm/mdss/dsi_v2.h
@@ -189,7 +189,7 @@
struct mdss_panel_info panel_info;
int (*on) (struct mdss_panel_data *pdata);
int (*off) (struct mdss_panel_data *pdata);
- void (*reset)(int enable);
+ void (*reset)(struct mdss_panel_data *pdata, int enable);
void (*bl_fnc) (struct mdss_panel_data *pdata, u32 bl_level);
struct dsi_panel_cmds_list *dsi_panel_on_cmds;
struct dsi_panel_cmds_list *dsi_panel_off_cmds;
diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c
index 890b00b..52243eb 100644
--- a/drivers/video/msm/mdss/mdp3.c
+++ b/drivers/video/msm/mdss/mdp3.c
@@ -47,7 +47,7 @@
#include "mdp3_hwio.h"
#include "mdp3_ctrl.h"
-#define MDP_CORE_HW_VERSION 0x03030304
+#define MDP_CORE_HW_VERSION 0x03040310
struct mdp3_hw_resource *mdp3_res;
#define MDP_BUS_VECTOR_ENTRY(ab_val, ib_val) \
@@ -302,16 +302,7 @@
return ret;
}
-int mdp3_vsync_clk_enable(int enable)
-{
- int ret = 0;
- pr_debug("vsync clk enable=%d\n", enable);
- mutex_lock(&mdp3_res->res_mutex);
- mdp3_clk_update(MDP3_CLK_VSYNC, enable);
- mutex_unlock(&mdp3_res->res_mutex);
- return ret;
-}
int mdp3_clk_set_rate(int clk_type, unsigned long clk_rate)
{
@@ -400,6 +391,9 @@
if (rc)
return rc;
+ rc = mdp3_clk_register("dsi_clk", MDP3_CLK_DSI);
+ if (rc)
+ return rc;
return rc;
}
@@ -409,6 +403,7 @@
clk_put(mdp3_res->clocks[MDP3_CLK_CORE]);
clk_put(mdp3_res->clocks[MDP3_CLK_VSYNC]);
clk_put(mdp3_res->clocks[MDP3_CLK_LCDC]);
+ clk_put(mdp3_res->clocks[MDP3_CLK_DSI]);
}
int mdp3_clk_enable(int enable)
@@ -421,6 +416,7 @@
rc = mdp3_clk_update(MDP3_CLK_AHB, enable);
rc |= mdp3_clk_update(MDP3_CLK_CORE, enable);
rc |= mdp3_clk_update(MDP3_CLK_VSYNC, enable);
+ rc |= mdp3_clk_update(MDP3_CLK_DSI, enable);
mutex_unlock(&mdp3_res->res_mutex);
return rc;
}
@@ -577,12 +573,14 @@
int rc;
rc = mdp3_clk_update(MDP3_CLK_AHB, 1);
+ rc |= mdp3_clk_update(MDP3_CLK_CORE, 1);
if (rc)
return rc;
mdp3_res->mdp_rev = MDP3_REG_READ(MDP3_REG_HW_VERSION);
rc = mdp3_clk_update(MDP3_CLK_AHB, 0);
+ rc |= mdp3_clk_update(MDP3_CLK_CORE, 0);
if (rc)
pr_err("fail to turn off the MDP3_CLK_AHB clk\n");
diff --git a/drivers/video/msm/mdss/mdp3.h b/drivers/video/msm/mdss/mdp3.h
index c853664..5774e5a 100644
--- a/drivers/video/msm/mdss/mdp3.h
+++ b/drivers/video/msm/mdss/mdp3.h
@@ -29,6 +29,7 @@
MDP3_CLK_CORE,
MDP3_CLK_VSYNC,
MDP3_CLK_LCDC,
+ MDP3_CLK_DSI,
MDP3_MAX_CLK
};
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index e07c0a4..99b7604 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -28,7 +28,7 @@
void vsync_notify_handler(void *arg)
{
- struct mdp3_session_data *session = (struct mdp3_session_data *)session;
+ struct mdp3_session_data *session = (struct mdp3_session_data *)arg;
complete(&session->vsync_comp);
}
@@ -100,18 +100,30 @@
.attrs = vsync_fs_attrs,
};
-static int mdp3_ctrl_res_req_dma(struct msm_fb_data_type *mfd, int status)
+static int mdp3_ctrl_res_req_bus(struct msm_fb_data_type *mfd, int status)
{
int rc = 0;
if (status) {
struct mdss_panel_info *panel_info = mfd->panel_info;
int ab = 0;
int ib = 0;
- unsigned long core_clk = 0;
- int vtotal = 0;
ab = panel_info->xres * panel_info->yres * 4;
ab *= panel_info->mipi.frame_rate;
ib = (ab * 3) / 2;
+ rc = mdp3_bus_scale_set_quota(MDP3_BW_CLIENT_DMA_P, ab, ib);
+ } else {
+ rc = mdp3_bus_scale_set_quota(MDP3_BW_CLIENT_DMA_P, 0, 0);
+ }
+ return rc;
+}
+
+static int mdp3_ctrl_res_req_clk(struct msm_fb_data_type *mfd, int status)
+{
+ int rc = 0;
+ if (status) {
+ struct mdss_panel_info *panel_info = mfd->panel_info;
+ unsigned long core_clk;
+ int vtotal;
vtotal = panel_info->lcdc.v_back_porch +
panel_info->lcdc.v_front_porch +
panel_info->lcdc.v_pulse_width +
@@ -126,10 +138,8 @@
if (rc)
return rc;
- mdp3_bus_scale_set_quota(MDP3_BW_CLIENT_DMA_P, ab, ib);
} else {
rc = mdp3_clk_enable(false);
- rc |= mdp3_bus_scale_set_quota(MDP3_BW_CLIENT_DMA_P, 0, 0);
}
return rc;
}
@@ -285,13 +295,25 @@
}
mutex_lock(&mdp3_session->lock);
if (mdp3_session->status) {
- pr_info("fb%d is on already", mfd->index);
+ pr_debug("fb%d is on already", mfd->index);
goto on_error;
}
- rc = mdp3_ctrl_res_req_dma(mfd, 1);
+ /* request bus bandwidth before DSI DMA traffic */
+ rc = mdp3_ctrl_res_req_bus(mfd, 1);
+ if (rc)
+ pr_err("fail to request bus resource\n");
+
+ panel = mdp3_session->panel;
+ if (panel->event_handler)
+ rc = panel->event_handler(panel, MDSS_EVENT_PANEL_ON, NULL);
if (rc) {
- pr_err("resource request for dma on failed\n");
+ pr_err("fail to turn on the panel\n");
+ goto on_error;
+ }
+ rc = mdp3_ctrl_res_req_clk(mfd, 1);
+ if (rc) {
+ pr_err("fail to request mdp clk resource\n");
goto on_error;
}
@@ -304,16 +326,9 @@
rc = mdp3_ctrl_intf_init(mfd, mdp3_session->intf);
if (rc) {
pr_err("display interface init failed\n");
- goto on_error;
- }
- panel = mdp3_session->panel;
- if (panel->event_handler)
- rc = panel->event_handler(panel, MDSS_EVENT_PANEL_ON, NULL);
- if (rc) {
- pr_err("fail to turn on the panel\n");
goto on_error;
}
@@ -348,26 +363,31 @@
mutex_lock(&mdp3_session->lock);
if (!mdp3_session->status) {
- pr_info("fb%d is off already", mfd->index);
+ pr_debug("fb%d is off already", mfd->index);
goto off_error;
}
- panel = mdp3_session->panel;
- if (panel->event_handler)
- rc = panel->event_handler(panel, MDSS_EVENT_PANEL_OFF, NULL);
-
- if (rc)
- pr_err("fail to turn off the panel\n");
+ pr_debug("mdp3_ctrl_off stop mdp3 dma engine\n");
rc = mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf);
if (rc)
pr_err("fail to stop the MDP3 dma\n");
- rc = mdp3_ctrl_res_req_dma(mfd, 0);
+ pr_debug("mdp3_ctrl_off stop dsi panel and controller\n");
+ panel = mdp3_session->panel;
+ if (panel->event_handler)
+ rc = panel->event_handler(panel, MDSS_EVENT_PANEL_OFF, NULL);
if (rc)
- pr_err("resource release for dma on failed\n");
+ pr_err("fail to turn off the panel\n");
+ pr_debug("mdp3_ctrl_off release bus and clock\n");
+ rc = mdp3_ctrl_res_req_bus(mfd, 0);
+ if (rc)
+ pr_err("mdp bus resource release failed\n");
+ rc = mdp3_ctrl_res_req_clk(mfd, 0);
+ if (rc)
+ pr_err("mdp clock resource release failed\n");
off_error:
mdp3_session->status = 0;
diff --git a/drivers/video/msm/mdss/mdss_qpic.c b/drivers/video/msm/mdss/mdss_qpic.c
index be02113..fa6bd3d 100644
--- a/drivers/video/msm/mdss/mdss_qpic.c
+++ b/drivers/video/msm/mdss/mdss_qpic.c
@@ -428,7 +428,7 @@
param[0]);
param++;
bytes_left -= 4;
- space++;
+ space--;
} else if (bytes_left == 2) {
QPIC_OUTPW(QPIC_REG_QPIC_LCDC_FIFO_DATA_PORT0,
*(u16 *)param);