Merge "ARM: dts: msm: Add UART support for sdxpoorwills"
diff --git a/Documentation/devicetree/bindings/usb/msm-phy.txt b/Documentation/devicetree/bindings/usb/msm-phy.txt
index 9ee2cc6..6716785 100644
--- a/Documentation/devicetree/bindings/usb/msm-phy.txt
+++ b/Documentation/devicetree/bindings/usb/msm-phy.txt
@@ -176,6 +176,8 @@
- qcom,hold-reset: Indicates that hold QUSB PHY into reset state.
- qcom,phy-clk-scheme: Should be one of "cml" or "cmos" if ref_clk_addr is provided.
- qcom,major-rev: provide major revision number to differentiate power up sequence. default is 2.0
+ - pinctrl-names/pinctrl-0/1: The GPIOs configured as output function. Names represents "active"
+ state when attached in host mode and "suspend" state when detached.
Example:
qusb_phy: qusb@f9b39000 {
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi
index 908c388..7819d26 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi
@@ -59,7 +59,7 @@
bcm_ip0: bcm-ip0 {
cell-id = <MSM_BUS_BCM_IP0>;
label = "IP0";
- qcom,bcm-name = "CE";
+ qcom,bcm-name = "IP0";
qcom,rscs = <&rsc_apps>;
qcom,bcm-dev;
};
@@ -261,7 +261,7 @@
mas_llcc_mc: mas-llcc-mc {
cell-id = <MSM_BUS_MASTER_LLCC>;
label = "mas-llcc-mc";
- qcom,buswidth = <16>;
+ qcom,buswidth = <4>;
qcom,agg-ports = <1>;
qcom,connections = <&slv_ebi>;
qcom,bus-dev = <&fab_mc_virt>;
@@ -573,7 +573,7 @@
slv_ebi:slv-ebi {
cell-id = <MSM_BUS_SLAVE_EBI_CH0>;
label = "slv-ebi";
- qcom,buswidth = <16>;
+ qcom,buswidth = <4>;
qcom,agg-ports = <1>;
qcom,bus-dev = <&fab_mc_virt>;
qcom,bcms = <&bcm_mc0>;
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dts
index e45f523..30484fb 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dts
@@ -20,7 +20,7 @@
model = "Qualcomm Technologies, Inc. SDXPOORWILLS CDP";
compatible = "qcom,sdxpoorwills-cdp",
"qcom,sdxpoorwills", "qcom,cdp";
- qcom,board-id = <1 0x0>, <1 0x100>;
+ qcom,board-id = <1 0x0>, <1 0x100>, <1 0x2>, <1 0x102>;
};
&serial_uart {
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts
index 083ccf8..73adbdc 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts
@@ -20,7 +20,7 @@
model = "Qualcomm Technologies, Inc. SDXPOORWILLS MTP";
compatible = "qcom,sdxpoorwills-mtp",
"qcom,sdxpoorwills", "qcom,mtp";
- qcom,board-id = <8 0x0>, <8 0x100>;
+ qcom,board-id = <8 0x0>, <8 0x100>, <8 0x2>, <8 0x102>;
};
&serial_uart {
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index a000878..ce38838 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -523,6 +523,7 @@
qcom,ipa-hw-mode = <0>;
qcom,ee = <0>;
qcom,use-ipa-tethering-bridge;
+ qcom,mhi-event-ring-id-limits = <9 10>; /* start and end */
qcom,modem-cfg-emb-pipe-flt;
qcom,use-ipa-pm;
qcom,bandwidth-vote-for-ipa;
@@ -694,7 +695,7 @@
reg = <0xc300000 0x400>,
<0x17811008 0x4>;
reg-names = "msgram", "irq-reg-base";
- qcom,irq-mask = <0x1>;
+ qcom,irq-mask = <0x2>;
interrupts = <GIC_SPI 221 IRQ_TYPE_EDGE_RISING>;
priority = <0>;
mbox-desc-offset = <0x0>;
diff --git a/arch/arm64/boot/dts/qcom/batterydata-ascent-3450mAh.dtsi b/arch/arm64/boot/dts/qcom/batterydata-ascent-3450mAh.dtsi
new file mode 100644
index 0000000..3eed42a
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/batterydata-ascent-3450mAh.dtsi
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+qcom,ascent-3450mah {
+ /* #Ascent_860_82209_0000_3450mAh_averaged_MasterSlave_Sept28th2015*/
+ qcom,max-voltage-uv = <4350000>;
+ qcom,nom-batt-capacity-mah = <3450>;
+ qcom,batt-id-kohm = <60>;
+ qcom,battery-beta = <3435>;
+ qcom,battery-type = "ascent_3450mah";
+ qcom,chg-rslow-comp-c1 = <6834679>;
+ qcom,chg-rslow-comp-c2 = <20647220>;
+ qcom,chg-rs-to-rslow = <915002>;
+ qcom,chg-rslow-comp-thr = <0xD5>;
+ qcom,checksum = <0xE50C>;
+ qcom,fg-profile-data = [
+ C5 83 25 77
+ AB 7B CA 74
+ 4C 83 7F 5B
+ EB 80 ED 8C
+ EA 81 61 9B
+ A6 BE 2B D0
+ 55 0E D6 83
+ 09 77 25 7B
+ 03 74 49 83
+ CC 70 0C 70
+ 0C 85 67 82
+ E6 93 27 B5
+ 61 C0 58 10
+ 23 0D 50 59
+ CE 6E 71 FD
+ CD 15 CC 3F
+ 1D 36 00 00
+ B9 47 29 3B
+ 1D 2E 00 00
+ 00 00 00 00
+ 00 00 00 00
+ D8 6A E7 69
+ B3 7C 4E 7A
+ 7E 77 77 70
+ 40 77 0D 73
+ 22 76 96 6A
+ 71 65 20 B0
+ 2C 97 63 12
+ 64 A0 71 0C
+ 28 00 FF 36
+ F0 11 30 03
+ 00 00 00 0C
+ ];
+};
diff --git a/arch/arm64/boot/dts/qcom/batterydata-itech-3000mah.dtsi b/arch/arm64/boot/dts/qcom/batterydata-itech-3000mah.dtsi
new file mode 100644
index 0000000..24b4626
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/batterydata-itech-3000mah.dtsi
@@ -0,0 +1,61 @@
+/* Copyright (c) 2014-2015, 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.
+ */
+
+qcom,itech-3000mah {
+ /* #Itech_B00826LF_3000mAh_Feb24th_Averaged*/
+ qcom,max-voltage-uv = <4350000>;
+ qcom,v-cutoff-uv = <3400000>;
+ qcom,chg-term-ua = <100000>;
+ qcom,batt-id-kohm = <100>;
+ qcom,battery-type = "itech_3000mah";
+ qcom,chg-rslow-comp-c1 = <4365000>;
+ qcom,chg-rslow-comp-c2 = <8609000>;
+ qcom,chg-rslow-comp-thr = <0xBE>;
+ qcom,chg-rs-to-rslow = <761000>;
+ qcom,fastchg-current-ma = <2000>;
+ qcom,fg-cc-cv-threshold-mv = <4340>;
+ qcom,checksum = <0x0B7C>;
+ qcom,fg-profile-data = [
+ F0 83 6B 7D
+ 66 81 EC 77
+ 43 83 E3 5A
+ 7C 81 33 8D
+ E1 81 EC 98
+ 7B B5 F8 BB
+ 5B 12 E2 83
+ 4A 7C 63 80
+ CF 75 50 83
+ FD 5A 83 82
+ E6 8E 12 82
+ B6 9A 1A BE
+ BE CB 55 0E
+ 96 0B E0 5A
+ CE 6E 71 FD
+ 2A 31 7E 47
+ CF 40 00 00
+ DB 45 0F 32
+ AF 31 00 00
+ 00 00 00 00
+ 00 00 00 00
+ E3 6A 60 69
+ 9E 6D 47 83
+ 13 7C 23 70
+ 0B 74 8F 80
+ DB 75 17 68
+ BA 75 BF B3
+ 21 5B 69 B5
+ 6C A0 71 0C
+ 28 00 FF 36
+ F0 11 30 03
+ 00 00 00 0E
+ ];
+};
diff --git a/arch/arm64/boot/dts/qcom/batterydata-qrd-sku1-4v4-2800mah.dtsi b/arch/arm64/boot/dts/qcom/batterydata-qrd-sku1-4v4-2800mah.dtsi
new file mode 100644
index 0000000..da52039
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/batterydata-qrd-sku1-4v4-2800mah.dtsi
@@ -0,0 +1,62 @@
+/* Copyright (c) 2015-2016, 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.
+ */
+
+qcom,qrd_msm8937_sku1_2920mah {
+ /* #QRD8937_2800mAh_China_data_averaged_MasterSlave_Oct30th2015*/
+ qcom,max-voltage-uv = <4400000>;
+ qcom,nom-batt-capacity-mah = <2800>;
+ qcom,batt-id-kohm = <90>;
+ qcom,battery-beta = <3380>;
+ qcom,battery-type = "qrd_msm8937_sku1_2800mah";
+ qcom,fastchg-current-ma = <2600>;
+ qcom,fg-cc-cv-threshold-mv = <4390>;
+ qcom,chg-rslow-comp-c1 = <6733839>;
+ qcom,chg-rslow-comp-c2 = <23336040>;
+ qcom,chg-rs-to-rslow = <1049243>;
+ qcom,chg-rslow-comp-thr = <0xDB>;
+ qcom,checksum = <0x7E2A>;
+ qcom,gui-version = "PMI8950GUI - 2.0.0.14";
+ qcom,fg-profile-data = [
+ C6 83 8A 77
+ 3E 80 84 75
+ 72 83 A1 7C
+ A0 90 FC 97
+ 3F 82 09 99
+ 92 B7 97 C3
+ 4C 14 EB 83
+ A7 7C CE 80
+ 79 76 60 83
+ 3B 64 34 88
+ 19 94 49 82
+ 07 9A 7F BD
+ BF CA 53 0D
+ 32 0B 68 59
+ 14 70 71 FD
+ 8C 28 9C 45
+ 3F 21 00 00
+ B6 47 FE 30
+ 0B 40 00 00
+ 00 00 00 00
+ 00 00 00 00
+ 3A 70 78 6B
+ F7 77 7F 88
+ 32 7C F2 70
+ 64 75 0B 79
+ 2B 77 F3 6B
+ CA 70 7D B1
+ 21 57 6B 6B
+ 6D A0 71 0C
+ 28 00 FF 36
+ F0 11 30 03
+ 00 00 00 0C
+ ];
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-cpu.dtsi b/arch/arm64/boot/dts/qcom/msm8953-cpu.dtsi
index 1b78fdd..8d80a40 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-cpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-cpu.dtsi
@@ -58,6 +58,7 @@
reg = <0x0>;
enable-method = "psci";
efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_0>;
L2_0: l2-cache {
compatible = "arm,arch-cache";
@@ -81,6 +82,7 @@
enable-method = "psci";
reg = <0x1>;
efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_0>;
L1_I_1: l1-icache {
compatible = "arm,arch-cache";
@@ -98,6 +100,7 @@
enable-method = "psci";
reg = <0x2>;
efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_0>;
L1_I_2: l1-icache {
compatible = "arm,arch-cache";
@@ -115,6 +118,7 @@
enable-method = "psci";
reg = <0x3>;
efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_0>;
L1_I_3: l1-icache {
compatible = "arm,arch-cache";
@@ -132,6 +136,7 @@
enable-method = "psci";
reg = <0x100>;
efficiency = <1126>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
next-level-cache = <&L2_1>;
L2_1: l2-cache {
compatible = "arm,arch-cache";
@@ -155,6 +160,7 @@
enable-method = "psci";
reg = <0x101>;
efficiency = <1126>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
next-level-cache = <&L2_1>;
L1_I_101: l1-icache {
compatible = "arm,arch-cache";
@@ -172,6 +178,7 @@
enable-method = "psci";
reg = <0x102>;
efficiency = <1126>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
next-level-cache = <&L2_1>;
L1_I_102: l1-icache {
compatible = "arm,arch-cache";
@@ -189,6 +196,7 @@
enable-method = "psci";
reg = <0x103>;
efficiency = <1126>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
next-level-cache = <&L2_1>;
L1_I_103: l1-icache {
compatible = "arm,arch-cache";
@@ -200,6 +208,77 @@
};
};
};
+
+ energy_costs: energy-costs {
+ compatible = "sched-energy";
+
+ CPU_COST_0: core-cost0 {
+ busy-cost-data = <
+ 652800 5
+ 883200 8
+ 1036800 10
+ 1248000 13
+ 1401600 16
+ 1536000 19
+ 1689600 22
+ 1804800 26
+ 1843200 27
+ 1958400 33
+ 2016000 36
+ 2150400 43
+ 2208000 44
+ 2304000 54
+ 2400000 65
+ >;
+ idle-cost-data = <
+ 4 3 2 1
+ >;
+ };
+ CLUSTER_COST_0: cluster-cost0 {
+ busy-cost-data = <
+ 652800 69
+ 883200 72
+ 1036800 74
+ 1248000 77
+ 1401600 80
+ 1536000 90
+ 1689600 100
+ 1804800 110
+ 1843200 120
+ 1958400 130
+ 2016000 140
+ 2150400 150
+ 2208000 160
+ 2304000 170
+ 2400000 180
+ >;
+ idle-cost-data = <
+ 4 3 2 1
+ >;
+ };
+ CLUSTER_COST_1: cluster-cost1 {
+ busy-cost-data = <
+ 652800 5
+ 883200 8
+ 1036800 10
+ 1248000 13
+ 1401600 16
+ 1536000 85
+ 1689600 95
+ 1804800 105
+ 1843200 115
+ 1958400 125
+ 2016000 135
+ 2150400 145
+ 2208000 155
+ 2304000 165
+ 2400000 175
+ >;
+ idle-cost-data = <
+ 4 3 2 1
+ >;
+ };
+ };
};
&soc {
diff --git a/arch/arm64/boot/dts/qcom/msm8953-mtp.dts b/arch/arm64/boot/dts/qcom/msm8953-mtp.dts
index 1e8b0f0..12b039c 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/msm8953-mtp.dts
@@ -14,7 +14,9 @@
/dts-v1/;
#include "msm8953.dtsi"
+#include "pmi8950.dtsi"
#include "msm8953-mtp.dtsi"
+#include "msm8953-pmi8950.dtsi"
/ {
model = "Qualcomm Technologies, Inc. MSM8953 + PMI8950 MTP";
@@ -22,3 +24,21 @@
qcom,board-id= <8 0>;
qcom,pmic-id = <0x010016 0x010011 0x0 0x0>;
};
+
+/{
+ mtp_batterydata: qcom,battery-data {
+ qcom,batt-id-range-pct = <15>;
+ #include "batterydata-itech-3000mah.dtsi"
+ #include "batterydata-ascent-3450mAh.dtsi"
+ };
+};
+
+&pmi8950_fg {
+ qcom,battery-data = <&mtp_batterydata>;
+};
+
+&pmi8950_charger {
+ qcom,battery-data = <&mtp_batterydata>;
+ qcom,chg-led-sw-controls;
+ qcom,chg-led-support;
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-pmi8950.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pmi8950.dtsi
new file mode 100644
index 0000000..6270223
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8953-pmi8950.dtsi
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+&soc {
+ led_flash0: qcom,camera-flash {
+ cell-index = <0>;
+ compatible = "qcom,camera-flash";
+ qcom,flash-type = <1>;
+ qcom,flash-source = <&pmi8950_flash0 &pmi8950_flash1>;
+ qcom,torch-source = <&pmi8950_torch0 &pmi8950_torch1>;
+ qcom,switch-source = <&pmi8950_switch>;
+ };
+};
+
+&labibb {
+ status = "ok";
+ qpnp,qpnp-labibb-mode = "lcd";
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-regulator.dtsi b/arch/arm64/boot/dts/qcom/msm8953-regulator.dtsi
new file mode 100644
index 0000000..e4634c4
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8953-regulator.dtsi
@@ -0,0 +1,928 @@
+/*
+ * Copyright (c) 2015-2017, 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.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+&rpm_bus {
+ rpm-regulator-smpa1 {
+ status = "okay";
+ pm8953_s1: regulator-s1 {
+ regulator-min-microvolt = <870000>;
+ regulator-max-microvolt = <1156000>;
+ qcom,init-voltage = <1000000>;
+ status = "okay";
+ };
+ };
+
+ /* PM8953 S2 - VDD_CX supply */
+ rpm-regulator-smpa2 {
+ status = "okay";
+ pm8953_s2_level: regulator-s2-level {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm8953_s2_level";
+ qcom,set = <3>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,use-voltage-level;
+ };
+
+ pm8953_s2_floor_level: regulator-s2-floor-level {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm8953_s2_floor_level";
+ qcom,set = <3>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,use-voltage-floor-level;
+ qcom,always-send-voltage;
+ };
+
+ pm8953_s2_level_ao: regulator-s2-level-ao {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm8953_s2_level_ao";
+ qcom,set = <1>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,use-voltage-level;
+ };
+ };
+
+ rpm-regulator-smpa3 {
+ status = "okay";
+ pm8953_s3: regulator-s3 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ qcom,init-voltage = <1225000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-smpa4 {
+ status = "okay";
+ pm8953_s4: regulator-s4 {
+ regulator-min-microvolt = <1900000>;
+ regulator-max-microvolt = <2050000>;
+ qcom,init-voltage = <1900000>;
+ status = "okay";
+ };
+ };
+
+ /* VDD_MX supply */
+ rpm-regulator-smpa7 {
+ status = "okay";
+ pm8953_s7_level: regulator-s7-level {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm8953_s7_level";
+ qcom,set = <3>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,init-voltage-level =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ qcom,use-voltage-level;
+ qcom,always-send-voltage;
+ };
+
+ pm8953_s7_level_ao: regulator-s7-level-ao {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm8953_s7_level_ao";
+ qcom,set = <1>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,use-voltage-level;
+ qcom,always-send-voltage;
+ };
+
+ pm8953_s7_level_so: regulator-s7-level-so {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm8953_s7_level_so";
+ qcom,set = <2>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,init-voltage-level =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ qcom,use-voltage-level;
+ };
+ };
+
+ rpm-regulator-ldoa1 {
+ status = "okay";
+ pm8953_l1: regulator-l1 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1100000>;
+ qcom,init-voltage = <1000000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa2 {
+ status = "okay";
+ pm8953_l2: regulator-l2 {
+ regulator-min-microvolt = <975000>;
+ regulator-max-microvolt = <1225000>;
+ qcom,init-voltage = <975000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa3 {
+ status = "okay";
+ pm8953_l3: regulator-l3 {
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <925000>;
+ qcom,init-voltage = <925000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa5 {
+ status = "okay";
+ pm8953_l5: regulator-l5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa6 {
+ status = "okay";
+ pm8953_l6: regulator-l6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa7 {
+ status = "okay";
+ pm8953_l7: regulator-l7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1900000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+
+ pm8953_l7_ao: regulator-l7-ao {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm8953_l7_ao";
+ qcom,set = <1>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1900000>;
+ qcom,init-voltage = <1800000>;
+ };
+ };
+
+ rpm-regulator-ldoa8 {
+ status = "okay";
+ pm8953_l8: regulator-l8 {
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ qcom,init-voltage = <2900000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa9 {
+ status = "okay";
+ pm8953_l9: regulator-l9 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ qcom,init-voltage = <3000000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa10 {
+ status = "okay";
+ pm8953_l10: regulator-l10 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ qcom,init-voltage = <2850000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa11 {
+ status = "okay";
+ pm8953_l11: regulator-l11 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ qcom,init-voltage = <2950000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa12 {
+ status = "okay";
+ pm8953_l12: regulator-l12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa13 {
+ status = "okay";
+ pm8953_l13: regulator-l13 {
+ regulator-min-microvolt = <3125000>;
+ regulator-max-microvolt = <3125000>;
+ qcom,init-voltage = <3125000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa16 {
+ status = "okay";
+ pm8953_l16: regulator-l16 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa17 {
+ status = "okay";
+ pm8953_l17: regulator-l17 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ qcom,init-voltage = <2850000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa19 {
+ status = "okay";
+ pm8953_l19: regulator-l19 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1350000>;
+ qcom,init-voltage = <1200000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa22 {
+ status = "okay";
+ pm8953_l22: regulator-l22 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2850000>;
+ qcom,init-voltage = <2800000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa23 {
+ status = "okay";
+ pm8953_l23: regulator-l23 {
+ regulator-min-microvolt = <975000>;
+ regulator-max-microvolt = <1225000>;
+ qcom,init-voltage = <975000>;
+ status = "okay";
+ };
+ };
+};
+
+&spmi_bus {
+ qcom,pm8953@1 {
+ /* PM8953 S5 + S6 = VDD_APC supply */
+ pm8953_s5: spm-regulator@2000 {
+ compatible = "qcom,spm-regulator";
+ reg = <0x2000 0x100>;
+ regulator-name = "pm8953_s5";
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1140000>;
+
+ pm8953_s5_limit: avs-limit-regulator {
+ regulator-name = "pm8953_s5_avs_limit";
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1140000>;
+ };
+ };
+ };
+};
+
+&soc {
+ apc_mem_acc_vreg: regulator@19461d4 {
+ compatible = "qcom,mem-acc-regulator";
+ reg = <0x019461d4 0x4>, <0x019461d8 0x4>;
+ reg-names = "acc-sel-l1", "acc-sel-l2";
+ regulator-name = "apc_mem_acc_corner";
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <2>;
+
+ qcom,corner-acc-map = <0x1 0x0>;
+ qcom,acc-sel-l1-bit-pos = <0>;
+ qcom,acc-sel-l1-bit-size = <1>;
+ qcom,acc-sel-l2-bit-pos = <0>;
+ qcom,acc-sel-l2-bit-size = <1>;
+ };
+
+ apc_cpr: cpr4-ctrl@b018000 {
+ compatible = "qcom,cpr4-msm8953-apss-regulator";
+ reg = <0xb018000 0x4000>, <0xa4000 0x1000>;
+ reg-names = "cpr_ctrl", "fuse_base";
+ interrupts = <GIC_SPI 15 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "cpr";
+
+ qcom,cpr-ctrl-name = "apc";
+
+ qcom,cpr-sensor-time = <1000>;
+ qcom,cpr-loop-time = <5000000>;
+ qcom,cpr-idle-cycles = <15>;
+ qcom,cpr-step-quot-init-min = <12>;
+ qcom,cpr-step-quot-init-max = <14>;
+ qcom,cpr-count-mode = <0>; /* All-at-once */
+ qcom,cpr-count-repeat = <14>;
+ qcom,cpr-down-error-step-limit = <1>;
+ qcom,cpr-up-error-step-limit = <1>;
+
+ qcom,apm-ctrl = <&apc_apm>;
+ qcom,apm-threshold-voltage = <850000>;
+ qcom,apm-hysteresis-voltage = <5000>;
+
+ vdd-supply = <&pm8953_s5>;
+ qcom,voltage-step = <5000>;
+ vdd-limit-supply = <&pm8953_s5_limit>;
+ mem-acc-supply = <&apc_mem_acc_vreg>;
+
+ qcom,cpr-enable;
+ qcom,cpr-hw-closed-loop;
+
+ qcom,cpr-panic-reg-addr-list =
+ <0xb1d2c18 0xb1d2900 0x0b1112b0 0xb018798>;
+ qcom,cpr-panic-reg-name-list =
+ "CCI_SAW4_PMIC_STS", "CCI_SAW4_VCTL",
+ "APCS_ALIAS0_APM_CTLER_STATUS",
+ "APCS0_CPR_CORE_ADJ_MODE_REG";
+
+ qcom,cpr-temp-point-map = <250 650 850>;
+ qcom,cpr-initial-temp-band = <0>;
+
+ /* Turbo (corner 6) ceiling voltage */
+ qcom,cpr-aging-ref-voltage = <990000>;
+
+ thread@0 {
+ qcom,cpr-thread-id = <0>;
+ qcom,cpr-consecutive-up = <0>;
+ qcom,cpr-consecutive-down = <2>;
+ qcom,cpr-up-threshold = <2>;
+ qcom,cpr-down-threshold = <1>;
+
+ apc_vreg: regulator {
+ regulator-name = "apc_corner";
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <9>;
+
+ qcom,cpr-fuse-corners = <4>;
+ qcom,cpr-fuse-combos = <64>;
+ qcom,cpr-speed-bins = <8>;
+ qcom,cpr-speed-bin-corners =
+ <9 0 7 0 0 0 7 9>;
+ qcom,cpr-corners =
+ /* Speed bin 0 */
+ <9 9 9 9 9 9 9 9>,
+
+ /* Speed bin 1 */
+ <0 0 0 0 0 0 0 0>,
+
+ /* Speed bin 2 */
+ <7 7 7 7 7 7 7 7>,
+
+ /* Speed bin 3..5 */
+ <0 0 0 0 0 0 0 0>,
+ <0 0 0 0 0 0 0 0>,
+ <0 0 0 0 0 0 0 0>,
+
+ /* Speed bin 6 */
+ <7 7 7 7 7 7 7 7>,
+
+ /* Speed bin 7 */
+ <9 9 9 9 9 9 9 9>;
+
+ qcom,cpr-corner-fmax-map =
+ /* Speed bin 0 */
+ <1 2 4 9>,
+
+ /* Speed bin 1 */
+ <0 0 0 0>,
+
+ /* Speed bin 2 */
+ <1 2 4 7>,
+
+ /* Speed bin 3..5 */
+ <0 0 0 0>,
+ <0 0 0 0>,
+ <0 0 0 0>,
+
+ /* Speed bin 6 */
+ <1 2 4 7>,
+
+ /* Speed bin 7 */
+ <1 2 4 9>;
+
+ qcom,cpr-voltage-ceiling =
+ /* Speed bin 0 */
+ <715000 790000 860000 865000 920000
+ 990000 1065000 1065000 1065000>,
+
+ /* Speed bin 2 */
+ <715000 790000 860000 865000 920000
+ 990000 1065000>,
+
+ /* Speed bin 6 */
+ <715000 790000 860000 865000 920000
+ 990000 1065000>,
+
+ /* Speed bin 7 */
+ <715000 790000 860000 865000 920000
+ 990000 1065000 1065000 1065000>;
+
+ qcom,cpr-voltage-floor =
+ /* Speed bin 0 */
+ <500000 500000 500000 500000 500000
+ 500000 500000 500000 500000>,
+
+ /* Speed bin 2 */
+ <500000 500000 500000 500000 500000
+ 500000 500000>,
+
+ /* Speed bin 6 */
+ <500000 500000 500000 500000 500000
+ 500000 500000>,
+
+ /* Speed bin 7 */
+ <500000 500000 500000 500000 500000
+ 500000 500000 500000 500000>;
+
+ qcom,cpr-floor-to-ceiling-max-range =
+ /* Speed bin 0; CPR rev 0..7 */
+ < 0 0 0 0 0
+ 0 0 0 0>,
+ <50000 50000 50000 50000 50000
+ 50000 50000 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000 50000 50000>,
+
+ /* Speed bin 2; CPR rev 0..7 */
+ < 0 0 0 0 0
+ 0 0>,
+ <50000 50000 50000 50000 50000
+ 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000>,
+
+ /* Speed bin 6; CPR rev 0..7 */
+ < 0 0 0 0 0
+ 0 0>,
+ <50000 50000 50000 50000 50000
+ 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000>,
+
+ /* Speed bin 7; CPR rev 0..7 */
+ < 0 0 0 0 0
+ 0 0 0 0>,
+ <50000 50000 50000 50000 50000
+ 50000 50000 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000 50000 50000>,
+ <50000 50000 50000 50000 50000
+ 50000 50000 50000 50000>;
+
+ qcom,cpr-misc-fuse-voltage-adjustment =
+ /* Speed bin 0; misc fuse 0..1 */
+ < 0 0 0 0 0
+ 0 0 0 0>,
+ < 0 0 30000 0 0
+ 0 0 0 0>,
+
+ /* Speed bin 2; misc fuse 0..1 */
+ < 0 0 0 0 0
+ 0 0>,
+ < 0 0 30000 0 0
+ 0 0>,
+
+ /* Speed bin 6; misc fuse 0..1 */
+ < 0 0 0 0 0
+ 0 0>,
+ < 0 0 30000 0 0
+ 0 0>,
+
+ /* Speed bin 7; misc fuse 0..1 */
+ < 0 0 0 0 0
+ 0 0 0 0>,
+ < 0 0 30000 0 0
+ 0 0 0 0>;
+
+ qcom,mem-acc-voltage =
+ /* Speed bin 0 */
+ <1 1 2 2 2 2 2 2 2>,
+
+ /* Speed bin 2 */
+ <1 1 2 2 2 2 2>,
+
+ /* Speed bin 6 */
+ <1 1 2 2 2 2 2>,
+
+ /* Speed bin 7 */
+ <1 1 2 2 2 2 2 2 2>;
+
+ qcom,corner-frequencies =
+ /* Speed bin 0 */
+ <652800000 1036800000 1401600000
+ 1689600000 1804800000 1958400000
+ 2016000000 2150400000 2208000000>,
+
+ /* Speed bin 2 */
+ <652800000 1036800000 1401600000
+ 1689600000 1804800000 1958400000
+ 2016000000>,
+
+ /* Speed bin 6 */
+ <652800000 1036800000 1401600000
+ 1689600000 1804800000 1958400000
+ 2016000000>,
+
+ /* Speed bin 7 */
+ <652800000 1036800000 1401600000
+ 1689600000 1804800000 1958400000
+ 2016000000 2150400000 2208000000>;
+
+ qcom,cpr-open-loop-voltage-fuse-adjustment =
+ /* Speed bin 0; CPR rev 0..7 */
+ < 0 0 0 0>,
+ < 25000 0 5000 40000>,
+ < 25000 0 5000 40000>,
+ < 25000 0 5000 40000>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+
+ /* Speed bin 1; CPR rev 0..7 */
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+
+ /* Speed bin 2; CPR rev 0..7 */
+ < 0 0 0 0>,
+ < 25000 0 5000 40000>,
+ < 25000 0 5000 40000>,
+ < 25000 0 5000 40000>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+
+ /* Speed bin 3; CPR rev 0..7 */
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+
+ /* Speed bin 4; CPR rev 0..7 */
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+
+ /* Speed bin 5; CPR rev 0..7 */
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+
+ /* Speed bin 6; CPR rev 0..7 */
+ < 0 0 0 0>,
+ < 25000 0 5000 40000>,
+ < 25000 0 5000 40000>,
+ < 25000 0 5000 40000>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+
+ /* Speed bin 7; CPR rev 0..7 */
+ < 0 0 0 0>,
+ < 25000 0 5000 40000>,
+ < 25000 0 5000 40000>,
+ < 25000 0 5000 40000>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>;
+
+ qcom,cpr-closed-loop-voltage-fuse-adjustment =
+ /* Speed bin 0; CPR rev 0..7 */
+ < 0 0 0 0>,
+ < 10000 (-15000) 0 25000>,
+ < 10000 (-15000) 0 25000>,
+ <(-5000) (-30000) (-15000) 10000>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+
+ /* Speed bin 1; CPR rev 0..7 */
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+
+ /* Speed bin 2; CPR rev 0..7 */
+ < 0 0 0 0>,
+ < 10000 (-15000) 0 25000>,
+ < 10000 (-15000) 0 25000>,
+ <(-5000) (-30000) (-15000) 10000>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+
+ /* Speed bin 3; CPR rev 0..7 */
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+
+ /* Speed bin 4; CPR rev 0..7 */
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+
+ /* Speed bin 5; CPR rev 0..7 */
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+
+ /* Speed bin 6; CPR rev 0..7 */
+ < 0 0 0 0>,
+ < 10000 (-15000) 0 25000>,
+ < 10000 (-15000) 0 25000>,
+ <(-5000) (-30000) (-15000) 10000>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+
+ /* Speed bin 7; CPR rev 0..7 */
+ < 0 0 0 0>,
+ < 10000 (-15000) 0 25000>,
+ < 10000 (-15000) 0 25000>,
+ <(-5000) (-30000) (-15000) 10000>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>,
+ < 0 0 0 0>;
+
+ qcom,cpr-ro-scaling-factor =
+ <3610 3790 0 2200 2450 2310 2170 2210
+ 2330 2210 2470 2340 780 2700 2450 2090>,
+ <3610 3790 0 2200 2450 2310 2170 2210
+ 2330 2210 2470 2340 780 2700 2450 2090>,
+ <3610 3790 0 2200 2450 2310 2170 2210
+ 2330 2210 2470 2340 780 2700 2450 2090>,
+ <3610 3790 0 2200 2450 2310 2170 2210
+ 2330 2210 2470 2340 780 2700 2450 2090>;
+
+ qcom,allow-voltage-interpolation;
+ qcom,allow-quotient-interpolation;
+ qcom,cpr-scaled-open-loop-voltage-as-ceiling;
+
+ qcom,corner-allow-temp-adjustment =
+ /* Speed bin 0; CPR rev 0..7 */
+ <0 0 0 0 0 0 0 0 0>,
+ <0 0 0 0 0 0 0 0 0>,
+ <0 0 0 0 0 0 0 0 0>,
+ <1 1 1 1 0 0 0 0 0>,
+ <1 1 1 1 0 0 0 0 0>,
+ <1 1 1 1 0 0 0 0 0>,
+ <1 1 1 1 0 0 0 0 0>,
+ <1 1 1 1 0 0 0 0 0>,
+
+ /* Speed bin 2; CPR rev 0..7 */
+ <0 0 0 0 0 0 0>,
+ <0 0 0 0 0 0 0>,
+ <0 0 0 0 0 0 0>,
+ <1 1 1 1 0 0 0>,
+ <1 1 1 1 0 0 0>,
+ <1 1 1 1 0 0 0>,
+ <1 1 1 1 0 0 0>,
+ <1 1 1 1 0 0 0>,
+
+ /* Speed bin 6; CPR rev 0..7 */
+ <0 0 0 0 0 0 0>,
+ <0 0 0 0 0 0 0>,
+ <0 0 0 0 0 0 0>,
+ <1 1 1 1 0 0 0>,
+ <1 1 1 1 0 0 0>,
+ <1 1 1 1 0 0 0>,
+ <1 1 1 1 0 0 0>,
+ <1 1 1 1 0 0 0>,
+
+ /* Speed bin 7; CPR rev 0..7 */
+ <0 0 0 0 0 0 0 0 0>,
+ <0 0 0 0 0 0 0 0 0>,
+ <0 0 0 0 0 0 0 0 0>,
+ <1 1 1 1 0 0 0 0 0>,
+ <1 1 1 1 0 0 0 0 0>,
+ <1 1 1 1 0 0 0 0 0>,
+ <1 1 1 1 0 0 0 0 0>,
+ <1 1 1 1 0 0 0 0 0>;
+
+ qcom,cpr-corner1-temp-core-voltage-adjustment =
+ <(0) (-5000) (-15000) (-20000)>;
+
+ qcom,cpr-corner2-temp-core-voltage-adjustment =
+ <(0) (-5000) (-15000) (-15000)>;
+
+ qcom,cpr-corner3-temp-core-voltage-adjustment =
+ <(0) (-5000) (-15000) (0)>;
+
+ qcom,cpr-corner4-temp-core-voltage-adjustment =
+ <(0) (-5000) (-15000) (0)>;
+
+ qcom,cpr-aging-max-voltage-adjustment = <15000>;
+ qcom,cpr-aging-ref-corner = <6>; /* Turbo */
+ qcom,cpr-aging-ro-scaling-factor = <2800>;
+ qcom,allow-aging-voltage-adjustment =
+ /* Speed bin 0 */
+ <0 0 0 1 1 1 1 1>,
+
+ /* Speed bin 1 */
+ <0 0 0 0 0 0 0 0>,
+
+ /* Speed bin 2 */
+ <0 0 0 1 1 1 1 1>,
+
+ /* Speed bin 3..5 */
+ <0 0 0 0 0 0 0 0>,
+ <0 0 0 0 0 0 0 0>,
+ <0 0 0 0 0 0 0 0>,
+
+ /* Speed bin 6 */
+ <0 0 0 1 1 1 1 1>,
+
+ /* Speed bin 7 */
+ <0 0 0 1 1 1 1 1>;
+ };
+ };
+ };
+
+ gfx_mem_acc: regulator@194415c {
+ compatible = "qcom,mem-acc-regulator";
+ reg = <0x0194415c 0x4>;
+ reg-names = "acc-sel-l1";
+ regulator-name = "gfx_mem_acc_corner";
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <2>;
+
+ qcom,acc-sel-l1-bit-pos = <0>;
+ qcom,acc-sel-l1-bit-size = <1>;
+ qcom,corner-acc-map = <0x1 0x0>;
+ };
+
+ gfx_vreg_corner: ldo@185f000 {
+ compatible = "qcom,msm8953-gfx-ldo";
+ reg = <0x0185f000 0x30>, <0xa4000 0x1000>;
+ reg-names = "ldo_addr", "efuse_addr";
+
+ regulator-name = "msm_gfx_ldo";
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <7>;
+
+ qcom,ldo-voltage-ceiling = <620000 680000 750000>;
+ qcom,ldo-voltage-floor = <510000 510000 600000>;
+
+ qcom,num-corners = <7>;
+ qcom,num-ldo-corners = <3>;
+ qcom,ldo-enable-corner-map = <1 1 1 0 0 0 0>;
+ qcom,init-corner = <4>;
+
+ vdd-cx-supply = <&pm8953_s2_level>;
+ qcom,vdd-cx-corner-map = <RPM_SMD_REGULATOR_LEVEL_LOW_SVS>,
+ <RPM_SMD_REGULATOR_LEVEL_LOW_SVS>,
+ <RPM_SMD_REGULATOR_LEVEL_SVS>,
+ <RPM_SMD_REGULATOR_LEVEL_SVS_PLUS>,
+ <RPM_SMD_REGULATOR_LEVEL_NOM>,
+ <RPM_SMD_REGULATOR_LEVEL_NOM_PLUS>,
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+
+ mem-acc-supply = <&gfx_mem_acc>;
+ qcom,mem-acc-corner-map = <1 1 1 2 2 2 2>;
+ qcom,ldo-init-voltage-adjustment = <35000 25000 0>;
+ };
+
+ eldo2_8953: eldo2 {
+ compatible = "regulator-fixed";
+ regulator-name = "eldo2_8953";
+ startup-delay-us = <0>;
+ enable-active-high;
+ gpio = <&tlmm 50 0>;
+ regulator-always-on;
+ };
+
+ adv_vreg: adv_vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "adv_vreg";
+ startup-delay-us = <400>;
+ enable-active-high;
+ gpio = <&pm8953_gpios 5 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi
index e99b9ac..a9ca87c 100644
--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -13,7 +13,9 @@
#include "skeleton64.dtsi"
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/spmi/spmi.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/regulator/qcom,rpm-smd-regulator.h>
/ {
model = "Qualcomm Technologies, Inc. MSM 8953";
@@ -769,3 +771,7 @@
cell-index = <0>;
};
};
+
+#include "pm8953-rpm-regulator.dtsi"
+#include "pm8953.dtsi"
+#include "msm8953-regulator.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/pm8953-rpm-regulator.dtsi b/arch/arm64/boot/dts/qcom/pm8953-rpm-regulator.dtsi
new file mode 100644
index 0000000..1e594c6
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pm8953-rpm-regulator.dtsi
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2015-2017, 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-smd-regulator-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-smd-regulator";
+ regulator-name = "pm8953_s1";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-smpa2 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "smpa";
+ qcom,resource-id = <2>;
+ qcom,regulator-type = <1>;
+ qcom,hpm-min-load = <100000>;
+ status = "disabled";
+
+ regulator-s2 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm8953_s2";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-smpa3 {
+ compatible = "qcom,rpm-smd-regulator-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-smd-regulator";
+ regulator-name = "pm8953_s3";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-smpa4 {
+ compatible = "qcom,rpm-smd-regulator-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-smd-regulator";
+ regulator-name = "pm8953_s4";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-smpa7 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "smpa";
+ qcom,resource-id = <7>;
+ qcom,regulator-type = <1>;
+ qcom,hpm-min-load = <100000>;
+ status = "disabled";
+
+ regulator-s7 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm8953_s7";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa1 {
+ compatible = "qcom,rpm-smd-regulator-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-smd-regulator";
+ regulator-name = "pm8953_l1";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa2 {
+ compatible = "qcom,rpm-smd-regulator-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-smd-regulator";
+ regulator-name = "pm8953_l2";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa3 {
+ compatible = "qcom,rpm-smd-regulator-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-smd-regulator";
+ regulator-name = "pm8953_l3";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa5 {
+ compatible = "qcom,rpm-smd-regulator-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-smd-regulator";
+ regulator-name = "pm8953_l5";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa6 {
+ compatible = "qcom,rpm-smd-regulator-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-smd-regulator";
+ regulator-name = "pm8953_l6";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa7 {
+ compatible = "qcom,rpm-smd-regulator-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-smd-regulator";
+ regulator-name = "pm8953_l7";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa8 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <8>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l8 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm8953_l8";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa9 {
+ compatible = "qcom,rpm-smd-regulator-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-smd-regulator";
+ regulator-name = "pm8953_l9";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa10 {
+ compatible = "qcom,rpm-smd-regulator-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-smd-regulator";
+ regulator-name = "pm8953_l10";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa11 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <11>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l11 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm8953_l11";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa12 {
+ compatible = "qcom,rpm-smd-regulator-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-smd-regulator";
+ regulator-name = "pm8953_l12";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa13 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <13>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <5000>;
+ status = "disabled";
+
+ regulator-l13 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm8953_l13";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa16 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <16>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <5000>;
+ status = "disabled";
+
+ regulator-l16 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm8953_l16";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa17 {
+ compatible = "qcom,rpm-smd-regulator-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-smd-regulator";
+ regulator-name = "pm8953_l17";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa19 {
+ compatible = "qcom,rpm-smd-regulator-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-smd-regulator";
+ regulator-name = "pm8953_l19";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa22 {
+ compatible = "qcom,rpm-smd-regulator-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-smd-regulator";
+ regulator-name = "pm8953_l22";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa23 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <23>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l23 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm8953_l23";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ /* Regulator to notify APC corner to RPM */
+ rpm-regulator-clk0 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "clk0";
+ qcom,resource-id = <3>;
+ qcom,regulator-type = <1>;
+ status = "disabled";
+
+ regulator-clk0 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "rpm_apc";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/pm8953.dtsi b/arch/arm64/boot/dts/qcom/pm8953.dtsi
new file mode 100644
index 0000000..60162e3
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pm8953.dtsi
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2015-2017, 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.
+ */
+
+&spmi_bus {
+
+ qcom,pm8953@0 {
+ compatible = "qcom,spmi-pmic";
+ reg = <0x0 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ pm8953_revid: qcom,revid@100 {
+ compatible = "qcom,qpnp-revid";
+ reg = <0x100 0x100>;
+ };
+
+ qcom,power-on@800 {
+ compatible = "qcom,qpnp-power-on";
+ reg = <0x800 0x100>;
+ interrupts = <0x0 0x8 0x0 IRQ_TYPE_NONE>,
+ <0x0 0x8 0x1 IRQ_TYPE_NONE>,
+ <0x0 0x8 0x4 IRQ_TYPE_NONE>,
+ <0x0 0x8 0x5 IRQ_TYPE_NONE>;
+ interrupt-names = "kpdpwr", "resin",
+ "resin-bark", "kpdpwr-resin-bark";
+ qcom,pon-dbc-delay = <15625>;
+ qcom,system-reset;
+
+ qcom,pon_1 {
+ qcom,pon-type = <0>;
+ qcom,pull-up = <1>;
+ linux,code = <116>;
+ };
+
+ qcom,pon_2 {
+ qcom,pon-type = <1>;
+ qcom,pull-up = <1>;
+ linux,code = <114>;
+ };
+ };
+
+ pm8953_temp_alarm: qcom,temp-alarm@2400 {
+ compatible = "qcom,qpnp-temp-alarm";
+ reg = <0x2400 0x100>;
+ interrupts = <0x0 0x24 0x0 IRQ_TYPE_EDGE_RISING>;
+ label = "pm8953_tz";
+ qcom,channel-num = <8>;
+ qcom,threshold-set = <0>;
+ qcom,temp_alarm-vadc = <&pm8953_vadc>;
+ };
+
+ pm8953_coincell: qcom,coincell@2800 {
+ compatible = "qcom,qpnp-coincell";
+ reg = <0x2800 0x100>;
+ };
+
+ pm8953_mpps: mpps {
+ compatible = "qcom,qpnp-pin";
+ spmi-dev-container;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ label = "pm8953-mpp";
+
+ mpp@a000 {
+ reg = <0xa000 0x100>;
+ qcom,pin-num = <1>;
+ status = "disabled";
+ };
+
+ mpp@a100 {
+ reg = <0xa100 0x100>;
+ qcom,pin-num = <2>;
+ };
+
+ mpp@a200 {
+ reg = <0xa200 0x100>;
+ qcom,pin-num = <3>;
+ status = "disabled";
+ };
+
+ mpp@a300 {
+ reg = <0xa300 0x100>;
+ qcom,pin-num = <4>;
+ };
+ };
+
+ pm8953_gpios: gpios {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-pin";
+ gpio-controller;
+ #gpio-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ label = "pm8953-gpio";
+
+ gpio@c000 {
+ reg = <0xc000 0x100>;
+ qcom,pin-num = <1>;
+ status = "disabled";
+ };
+
+ gpio@c100 {
+ reg = <0xc100 0x100>;
+ qcom,pin-num = <2>;
+ status = "disabled";
+ };
+
+ gpio@c200 {
+ reg = <0xc200 0x100>;
+ qcom,pin-num = <3>;
+ status = "disabled";
+ };
+
+ gpio@c300 {
+ reg = <0xc300 0x100>;
+ qcom,pin-num = <4>;
+ status = "disabled";
+ };
+
+ gpio@c400 {
+ reg = <0xc400 0x100>;
+ qcom,pin-num = <5>;
+ status = "disabled";
+ };
+
+ gpio@c500 {
+ reg = <0xc500 0x100>;
+ qcom,pin-num = <6>;
+ status = "disabled";
+ };
+
+ gpio@c600 {
+ reg = <0xc600 0x100>;
+ qcom,pin-num = <7>;
+ status = "disabled";
+ };
+
+ gpio@c700 {
+ reg = <0xc700 0x100>;
+ qcom,pin-num = <8>;
+ status = "disabled";
+ };
+ };
+
+ pm8953_vadc: vadc@3100 {
+ compatible = "qcom,qpnp-vadc";
+ reg = <0x3100 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "eoc-int-en-set";
+ qcom,adc-bit-resolution = <15>;
+ qcom,adc-vdd-reference = <1800>;
+ qcom,vadc-poll-eoc;
+
+ chan@8 {
+ label = "die_temp";
+ reg = <8>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <3>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@9 {
+ label = "ref_625mv";
+ reg = <9>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@a {
+ label = "ref_1250v";
+ reg = <0xa>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@c {
+ label = "ref_buf_625mv";
+ reg = <0xc>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+ };
+
+ pm8953_adc_tm: vadc@3400 {
+ compatible = "qcom,qpnp-adc-tm";
+ reg = <0x3400 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0x0 0x34 0x0 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x34 0x3 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x34 0x4 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "eoc-int-en-set",
+ "high-thr-en-set",
+ "low-thr-en-set";
+ qcom,adc-bit-resolution = <15>;
+ qcom,adc-vdd-reference = <1800>;
+ qcom,adc_tm-vadc = <&pm8953_vadc>;
+
+ };
+
+ pm8953_rtc: qcom,pm8953_rtc {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-rtc";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ qcom,qpnp-rtc-write = <0>;
+ qcom,qpnp-rtc-alarm-pwrup = <0>;
+
+ qcom,pm8953_rtc_rw@6000 {
+ reg = <0x6000 0x100>;
+ };
+
+ qcom,pm8953_rtc_alarm@6100 {
+ reg = <0x6100 0x100>;
+ interrupts = <0x0 0x61 0x1 IRQ_TYPE_NONE>;
+ };
+ };
+
+ pm8953_typec: qcom,pm8953_typec@bf00 {
+ compatible = "qcom,qpnp-typec";
+ reg = <0xbf00 0x100>;
+ interrupts = <0x0 0xbf 0x0 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0xbf 0x1 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0xbf 0x2 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0xbf 0x3 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0xbf 0x4 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0xbf 0x6 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0xbf 0x7 IRQ_TYPE_EDGE_RISING>;
+
+ interrupt-names = "vrd-change",
+ "ufp-detect",
+ "ufp-detach",
+ "dfp-detect",
+ "dfp-detach",
+ "vbus-err",
+ "vconn-oc";
+ };
+ };
+
+ pm8953_1: qcom,pm8953@1 {
+ compatible = "qcom,spmi-pmic";
+ reg = <0x1 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ pm8953_pwm: pwm@bc00 {
+ status = "disabled";
+ compatible = "qcom,qpnp-pwm";
+ reg = <0xbc00 0x100>;
+ reg-names = "qpnp-lpg-channel-base";
+ qcom,channel-id = <0>;
+ qcom,supported-sizes = <6>, <9>;
+ #pwm-cells = <2>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/pmi8950.dtsi b/arch/arm64/boot/dts/qcom/pmi8950.dtsi
index 4223cfe..8b4fccb 100644
--- a/arch/arm64/boot/dts/qcom/pmi8950.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi8950.dtsi
@@ -43,7 +43,7 @@
reg = <0x3100 0x100>;
#address-cells = <1>;
#size-cells = <0>;
- interrupts = <0x2 0x31 0x0>;
+ interrupts = <0x2 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "eoc-int-en-set";
qcom,adc-bit-resolution = <15>;
qcom,adc-vdd-reference = <1800>;
@@ -140,7 +140,6 @@
};
pmi8950_gpios: gpios {
- spmi-dev-container;
compatible = "qcom,qpnp-pin";
gpio-controller;
#gpio-cells = <2>;
@@ -162,7 +161,6 @@
};
pmi8950_mpps: mpps {
- spmi-dev-container;
compatible = "qcom,qpnp-pin";
gpio-controller;
#gpio-cells = <2>;
@@ -196,7 +194,6 @@
};
pmi8950_charger: qcom,qpnp-smbcharger {
- spmi-dev-container;
compatible = "qcom,qpnp-smbcharger";
#address-cells = <1>;
#size-cells = <1>;
@@ -218,14 +215,14 @@
qcom,chgr@1000 {
reg = <0x1000 0x100>;
- interrupts = <0x2 0x10 0x0>,
- <0x2 0x10 0x1>,
- <0x2 0x10 0x2>,
- <0x2 0x10 0x3>,
- <0x2 0x10 0x4>,
- <0x2 0x10 0x5>,
- <0x2 0x10 0x6>,
- <0x2 0x10 0x7>;
+ interrupts = <0x2 0x10 0x0 IRQ_TYPE_NONE>,
+ <0x2 0x10 0x1 IRQ_TYPE_NONE>,
+ <0x2 0x10 0x2 IRQ_TYPE_NONE>,
+ <0x2 0x10 0x3 IRQ_TYPE_NONE>,
+ <0x2 0x10 0x4 IRQ_TYPE_NONE>,
+ <0x2 0x10 0x5 IRQ_TYPE_NONE>,
+ <0x2 0x10 0x6 IRQ_TYPE_NONE>,
+ <0x2 0x10 0x7 IRQ_TYPE_NONE>;
interrupt-names = "chg-error",
"chg-inhibit",
@@ -239,9 +236,9 @@
qcom,otg@1100 {
reg = <0x1100 0x100>;
- interrupts = <0x2 0x11 0x0>,
- <0x2 0x11 0x1>,
- <0x2 0x11 0x3>;
+ interrupts = <0x2 0x11 0x0 IRQ_TYPE_NONE>,
+ <0x2 0x11 0x1 IRQ_TYPE_NONE>,
+ <0x2 0x11 0x3 IRQ_TYPE_NONE>;
interrupt-names = "otg-fail",
"otg-oc",
"usbid-change";
@@ -249,14 +246,14 @@
qcom,bat-if@1200 {
reg = <0x1200 0x100>;
- interrupts = <0x2 0x12 0x0>,
- <0x2 0x12 0x1>,
- <0x2 0x12 0x2>,
- <0x2 0x12 0x3>,
- <0x2 0x12 0x4>,
- <0x2 0x12 0x5>,
- <0x2 0x12 0x6>,
- <0x2 0x12 0x7>;
+ interrupts = <0x2 0x12 0x0 IRQ_TYPE_NONE>,
+ <0x2 0x12 0x1 IRQ_TYPE_NONE>,
+ <0x2 0x12 0x2 IRQ_TYPE_NONE>,
+ <0x2 0x12 0x3 IRQ_TYPE_NONE>,
+ <0x2 0x12 0x4 IRQ_TYPE_NONE>,
+ <0x2 0x12 0x5 IRQ_TYPE_NONE>,
+ <0x2 0x12 0x6 IRQ_TYPE_NONE>,
+ <0x2 0x12 0x7 IRQ_TYPE_NONE>;
interrupt-names = "batt-hot",
"batt-warm",
@@ -270,10 +267,10 @@
qcom,usb-chgpth@1300 {
reg = <0x1300 0x100>;
- interrupts = <0x2 0x13 0x0>,
- <0x2 0x13 0x1>,
- <0x2 0x13 0x2>,
- <0x2 0x13 0x5>;
+ interrupts = <0x2 0x13 0x0 IRQ_TYPE_NONE>,
+ <0x2 0x13 0x1 IRQ_TYPE_NONE>,
+ <0x2 0x13 0x2 IRQ_TYPE_NONE>,
+ <0x2 0x13 0x5 IRQ_TYPE_NONE>;
interrupt-names = "usbin-uv",
"usbin-ov",
@@ -283,20 +280,20 @@
qcom,dc-chgpth@1400 {
reg = <0x1400 0x100>;
- interrupts = <0x2 0x14 0x0>,
- <0x2 0x14 0x1>;
+ interrupts = <0x2 0x14 0x0 IRQ_TYPE_NONE>,
+ <0x2 0x14 0x1 IRQ_TYPE_NONE>;
interrupt-names = "dcin-uv",
"dcin-ov";
};
qcom,chgr-misc@1600 {
reg = <0x1600 0x100>;
- interrupts = <0x2 0x16 0x0>,
- <0x2 0x16 0x1>,
- <0x2 0x16 0x2>,
- <0x2 0x16 0x3>,
- <0x2 0x16 0x4>,
- <0x2 0x16 0x5>;
+ interrupts = <0x2 0x16 0x0 IRQ_TYPE_NONE>,
+ <0x2 0x16 0x1 IRQ_TYPE_NONE>,
+ <0x2 0x16 0x2 IRQ_TYPE_NONE>,
+ <0x2 0x16 0x3 IRQ_TYPE_NONE>,
+ <0x2 0x16 0x4 IRQ_TYPE_NONE>,
+ <0x2 0x16 0x5 IRQ_TYPE_NONE>;
interrupt-names = "power-ok",
"temp-shutdown",
@@ -312,7 +309,6 @@
};
pmi8950_fg: qcom,fg {
- spmi-dev-container;
compatible = "qcom,qpnp-fg";
#address-cells = <1>;
#size-cells = <1>;
@@ -330,13 +326,13 @@
qcom,fg-soc@4000 {
status = "okay";
reg = <0x4000 0x100>;
- interrupts = <0x2 0x40 0x0>,
- <0x2 0x40 0x1>,
- <0x2 0x40 0x2>,
- <0x2 0x40 0x3>,
- <0x2 0x40 0x4>,
- <0x2 0x40 0x5>,
- <0x2 0x40 0x6>;
+ interrupts = <0x2 0x40 0x0 IRQ_TYPE_NONE>,
+ <0x2 0x40 0x1 IRQ_TYPE_NONE>,
+ <0x2 0x40 0x2 IRQ_TYPE_NONE>,
+ <0x2 0x40 0x3 IRQ_TYPE_NONE>,
+ <0x2 0x40 0x4 IRQ_TYPE_NONE>,
+ <0x2 0x40 0x5 IRQ_TYPE_NONE>,
+ <0x2 0x40 0x6 IRQ_TYPE_NONE>;
interrupt-names = "high-soc",
"low-soc",
@@ -349,14 +345,14 @@
qcom,fg-batt@4100 {
reg = <0x4100 0x100>;
- interrupts = <0x2 0x41 0x0>,
- <0x2 0x41 0x1>,
- <0x2 0x41 0x2>,
- <0x2 0x41 0x3>,
- <0x2 0x41 0x4>,
- <0x2 0x41 0x5>,
- <0x2 0x41 0x6>,
- <0x2 0x41 0x7>;
+ interrupts = <0x2 0x41 0x0 IRQ_TYPE_NONE>,
+ <0x2 0x41 0x1 IRQ_TYPE_NONE>,
+ <0x2 0x41 0x2 IRQ_TYPE_NONE>,
+ <0x2 0x41 0x3 IRQ_TYPE_NONE>,
+ <0x2 0x41 0x4 IRQ_TYPE_NONE>,
+ <0x2 0x41 0x5 IRQ_TYPE_NONE>,
+ <0x2 0x41 0x6 IRQ_TYPE_NONE>,
+ <0x2 0x41 0x7 IRQ_TYPE_NONE>;
interrupt-names = "soft-cold",
"soft-hot",
@@ -375,8 +371,8 @@
qcom,fg-memif@4400 {
status = "okay";
reg = <0x4400 0x100>;
- interrupts = <0x2 0x44 0x0>,
- <0x2 0x44 0x2>;
+ interrupts = <0x2 0x44 0x0 IRQ_TYPE_NONE>,
+ <0x2 0x44 0x2 IRQ_TYPE_NONE>;
interrupt-names = "mem-avail",
"data-rcvry-sug";
@@ -387,8 +383,8 @@
compatible = "qcom,msm-bcl";
reg = <0x4200 0xFF 0x88E 0x2>;
reg-names = "fg_user_adc", "pon_spare";
- interrupts = <0x2 0x42 0x0>,
- <0x2 0x42 0x1>;
+ interrupts = <0x2 0x42 0x0 IRQ_TYPE_NONE>,
+ <0x2 0x42 0x1 IRQ_TYPE_NONE>;
interrupt-names = "bcl-high-ibat-int",
"bcl-low-vbat-int";
qcom,vbat-scaling-factor = <39000>;
@@ -429,7 +425,6 @@
labibb: qpnp-labibb-regulator {
status = "disabled";
- spmi-dev-container;
compatible = "qcom,qpnp-labibb-regulator";
#address-cells = <1>;
#size-cells = <1>;
@@ -512,7 +507,7 @@
"qpnp-wled-sink-base",
"qpnp-wled-ibb-base",
"qpnp-wled-lab-base";
- interrupts = <0x3 0xd8 0x2>;
+ interrupts = <0x3 0xd8 0x2 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "sc-irq";
status = "okay";
linux,name = "wled";
@@ -531,6 +526,7 @@
qcom,fs-curr-ua = <20000>;
qcom,led-strings-list = [00 01];
qcom,en-ext-pfet-sc-pro;
+ qcom,pmic-revid = <&pmi8950_revid>;
qcom,cons-sync-write-delay-us = <1000>;
};
@@ -617,8 +613,8 @@
pmi_haptic: qcom,haptic@c000 {
compatible = "qcom,qpnp-haptic";
reg = <0xc000 0x100>;
- interrupts = <0x3 0xc0 0x0>,
- <0x3 0xc0 0x1>;
+ interrupts = <0x3 0xc0 0x0 IRQ_TYPE_EDGE_BOTH>,
+ <0x3 0xc0 0x1 IRQ_TYPE_EDGE_BOTH>;
interrupt-names = "sc-irq", "play-irq";
qcom,pmic-revid = <&pmi8950_revid>;
vcc_pon-supply = <&pon_perph_reg>;
diff --git a/arch/arm64/boot/dts/qcom/sdm670-coresight.dtsi b/arch/arm64/boot/dts/qcom/sdm670-coresight.dtsi
index 8323476..f8a8e15 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-coresight.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-coresight.dtsi
@@ -63,6 +63,9 @@
clocks = <&clock_aop QDSS_CLK>;
clock-names = "apb_pclk";
+ interrupts = <GIC_SPI 270 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "byte-cntr-irq";
+
port {
tmc_etr_in_replicator: endpoint {
slave-mode;
diff --git a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
index e9924e2..c136752 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
@@ -371,4 +371,7 @@
xo-therm-mdm-step {
status = "disabled";
};
+ xo-therm-batt-step {
+ status = "disabled";
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi b/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
index 0a7e25d..5d3975c 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
@@ -385,3 +385,63 @@
vbus_dwc3-supply = <&smb2_vbus>;
qcom,no-vbus-vote-with-type-C;
};
+
+&thermal_zones {
+ xo-therm-batt-step {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&pm660_adc_tm 0x4c>;
+ thermal-governor = "step_wise";
+
+ trips {
+ batt_trip1: batt-trip1 {
+ temperature = <40000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ batt_trip2: batt-trip2 {
+ temperature = <45000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ batt_trip3: batt-trip3 {
+ temperature = <48000>;
+ hysteresis = <3000>;
+ type = "passive";
+ };
+ batt_trip4: batt-trip4 {
+ temperature = <50000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ batt_trip5: batt-trip5 {
+ temperature = <52000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ };
+
+ cooling-maps {
+ battery_lvl1 {
+ trip = <&batt_trip1>;
+ cooling-device = <&pm660_charger 1 1>;
+ };
+ battery_lvl2 {
+ trip = <&batt_trip2>;
+ cooling-device = <&pm660_charger 2 2>;
+ };
+ battery_lvl3 {
+ trip = <&batt_trip3>;
+ cooling-device = <&pm660_charger 3 3>;
+ };
+ battery_lvl4 {
+ trip = <&batt_trip4>;
+ cooling-device = <&pm660_charger 4 4>;
+ };
+ battery_lvl5 {
+ trip = <&batt_trip5>;
+ cooling-device = <&pm660_charger 5 5>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
index 3c84314..9898ada 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
@@ -459,9 +459,9 @@
pm660_l19: regulator-pm660-l19 {
regulator-name = "pm660_l19";
qcom,set = <RPMH_REGULATOR_SET_ALL>;
- regulator-min-microvolt = <3312000>;
+ regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3312000>;
- qcom,init-voltage = <3312000>;
+ qcom,init-voltage = <3000000>;
qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-thermal.dtsi b/arch/arm64/boot/dts/qcom/sdm670-thermal.dtsi
index 6324b64..8cbc84f 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-thermal.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-thermal.dtsi
@@ -1539,7 +1539,7 @@
type = "passive";
};
silver_trip1: silver-trip1 {
- temperature = <48000>;
+ temperature = <50000>;
hysteresis = <0>;
type = "passive";
};
@@ -1606,7 +1606,7 @@
};
modem_trip2: modem-trip2 {
temperature = <48000>;
- hysteresis = <2000>;
+ hysteresis = <3000>;
type = "passive";
};
modem_trip3: modem-trip3 {
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 4065954..0b8ddf3 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -571,6 +571,8 @@
#include "sdm670-smp2p.dtsi"
+#include "msm-rdbg.dtsi"
+
#include "sdm670-qupv3.dtsi"
#include "sdm670-coresight.dtsi"
@@ -1114,7 +1116,7 @@
reg-names = "wdt-base";
interrupts = <0 0 0>, <0 1 0>;
qcom,bark-time = <11000>;
- qcom,pet-time = <10000>;
+ qcom,pet-time = <9360>;
qcom,ipi-ping;
qcom,wakeup-enable;
};
@@ -2475,6 +2477,7 @@
vdd-1.8-xo-supply = <&pm660_l9>;
vdd-1.3-rfa-supply = <&pm660_l6>;
vdd-3.3-ch0-supply = <&pm660_l19>;
+ qcom,vdd-3.3-ch0-config = <3000000 3312000>;
qcom,wlan-msa-memory = <0x100000>;
qcom,smmu-s1-bypass;
};
diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig
index b95fdc2..2539aa2 100644
--- a/arch/arm64/configs/msm8953-perf_defconfig
+++ b/arch/arm64/configs/msm8953-perf_defconfig
@@ -280,6 +280,7 @@
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_HBTP_INPUT=y
+CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_INPUT_UINPUT=y
# CONFIG_SERIO_SERPORT is not set
# CONFIG_VT is not set
@@ -302,10 +303,17 @@
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_QPNP_PIN=y
+CONFIG_GPIO_QPNP_PIN_DEBUG=y
CONFIG_POWER_RESET_QCOM=y
CONFIG_QCOM_DLOAD_MODE=y
CONFIG_POWER_RESET_XGENE=y
CONFIG_POWER_RESET_SYSCON=y
+CONFIG_QPNP_FG=y
+CONFIG_SMB135X_CHARGER=y
+CONFIG_SMB1351_USB_CHARGER=y
+CONFIG_QPNP_SMBCHARGER=y
+CONFIG_MSM_APM=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_THERMAL=y
CONFIG_THERMAL_QPNP=y
@@ -313,10 +321,16 @@
CONFIG_THERMAL_TSENS=y
CONFIG_MSM_BCL_PERIPHERAL_CTL=y
CONFIG_QTI_THERMAL_LIMITS_DCVS=y
+CONFIG_MFD_SPMI_PMIC=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_CPR4_APSS=y
CONFIG_REGULATOR_CPRH_KBSS=y
+CONFIG_REGULATOR_MEM_ACC=y
+CONFIG_REGULATOR_MSM_GFX_LDO=y
CONFIG_REGULATOR_QPNP_LABIBB=y
CONFIG_REGULATOR_QPNP=y
+CONFIG_REGULATOR_RPM_SMD=y
+CONFIG_REGULATOR_SPM=y
CONFIG_REGULATOR_STUB=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
@@ -372,7 +386,9 @@
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_QPNP=y
+CONFIG_LEDS_QPNP_FLASH=y
CONFIG_LEDS_QPNP_WLED=y
+CONFIG_LEDS_QPNP_HAPTICS=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
@@ -401,6 +417,8 @@
CONFIG_REMOTE_SPINLOCK_MSM=y
CONFIG_MAILBOX=y
CONFIG_ARM_SMMU=y
+CONFIG_MSM_SPM=y
+CONFIG_MSM_L2_SPM=y
CONFIG_MSM_BOOT_STATS=y
CONFIG_QCOM_EUD=y
CONFIG_QCOM_WATCHDOG_V2=y
diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig
index 04bdb9b..52f9976 100644
--- a/arch/arm64/configs/msm8953_defconfig
+++ b/arch/arm64/configs/msm8953_defconfig
@@ -290,6 +290,7 @@
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_HBTP_INPUT=y
+CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_INPUT_UINPUT=y
# CONFIG_SERIO_SERPORT is not set
# CONFIG_VT is not set
@@ -312,10 +313,17 @@
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_QPNP_PIN=y
+CONFIG_GPIO_QPNP_PIN_DEBUG=y
CONFIG_POWER_RESET_QCOM=y
CONFIG_QCOM_DLOAD_MODE=y
CONFIG_POWER_RESET_XGENE=y
CONFIG_POWER_RESET_SYSCON=y
+CONFIG_QPNP_FG=y
+CONFIG_SMB135X_CHARGER=y
+CONFIG_SMB1351_USB_CHARGER=y
+CONFIG_QPNP_SMBCHARGER=y
+CONFIG_MSM_APM=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_THERMAL=y
CONFIG_THERMAL_QPNP=y
@@ -323,10 +331,16 @@
CONFIG_THERMAL_TSENS=y
CONFIG_MSM_BCL_PERIPHERAL_CTL=y
CONFIG_QTI_THERMAL_LIMITS_DCVS=y
+CONFIG_MFD_SPMI_PMIC=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_CPR4_APSS=y
CONFIG_REGULATOR_CPRH_KBSS=y
+CONFIG_REGULATOR_MEM_ACC=y
+CONFIG_REGULATOR_MSM_GFX_LDO=y
CONFIG_REGULATOR_QPNP_LABIBB=y
CONFIG_REGULATOR_QPNP=y
+CONFIG_REGULATOR_RPM_SMD=y
+CONFIG_REGULATOR_SPM=y
CONFIG_REGULATOR_STUB=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
@@ -384,7 +398,9 @@
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_QPNP=y
+CONFIG_LEDS_QPNP_FLASH=y
CONFIG_LEDS_QPNP_WLED=y
+CONFIG_LEDS_QPNP_HAPTICS=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
@@ -415,6 +431,8 @@
CONFIG_IOMMU_DEBUG=y
CONFIG_IOMMU_DEBUG_TRACKING=y
CONFIG_IOMMU_TESTS=y
+CONFIG_MSM_SPM=y
+CONFIG_MSM_L2_SPM=y
CONFIG_MSM_BOOT_STATS=y
CONFIG_MSM_CORE_HANG_DETECT=y
CONFIG_MSM_GLADIATOR_HANG_DETECT=y
diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig
index 822324d..ab7268f 100644
--- a/arch/arm64/configs/sdm670_defconfig
+++ b/arch/arm64/configs/sdm670_defconfig
@@ -314,6 +314,7 @@
CONFIG_HW_RANDOM_MSM_LEGACY=y
# CONFIG_DEVPORT is not set
CONFIG_MSM_ADSPRPC=y
+CONFIG_MSM_RDBG=m
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_QCOM_GENI=y
CONFIG_SPI=y
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 35eea02..8a28212 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -238,13 +238,13 @@
int ramdumpenabled;
void *remoteheap_ramdump_dev;
struct fastrpc_glink_info link;
- struct mutex mut;
};
struct fastrpc_apps {
struct fastrpc_channel_ctx *channel;
struct cdev cdev;
struct class *class;
+ struct mutex smd_mutex;
struct smq_phy_page range;
struct hlist_head maps;
uint32_t staticpd_flags;
@@ -654,10 +654,6 @@
if (err)
goto bail;
- map->uncached = !ION_IS_CACHED(flags);
- if (map->attr & FASTRPC_ATTR_NOVA)
- map->uncached = 1;
-
map->secure = flags & ION_FLAG_SECURE;
if (map->secure) {
if (!fl->secsctx)
@@ -670,9 +666,15 @@
sess = fl->secsctx;
else
sess = fl->sctx;
+
VERIFY(err, !IS_ERR_OR_NULL(sess));
if (err)
goto bail;
+
+ map->uncached = !ION_IS_CACHED(flags);
+ if (map->attr & FASTRPC_ATTR_NOVA && !sess->smmu.coherent)
+ map->uncached = 1;
+
VERIFY(err, !IS_ERR_OR_NULL(map->buf = dma_buf_get(fd)));
if (err)
goto bail;
@@ -1496,12 +1498,12 @@
INIT_HLIST_HEAD(&me->drivers);
spin_lock_init(&me->hlock);
+ mutex_init(&me->smd_mutex);
me->channel = &gcinfo[0];
for (i = 0; i < NUM_CHANNELS; i++) {
init_completion(&me->channel[i].work);
init_completion(&me->channel[i].workport);
me->channel[i].sesscount = 0;
- mutex_init(&me->channel[i].mut);
}
}
@@ -1619,7 +1621,7 @@
int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
int hlosVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
- VERIFY(err, !fastrpc_channel_open(fl));
+ VERIFY(err, 0 == (err = fastrpc_channel_open(fl)));
if (err)
goto bail;
if (init->flags == FASTRPC_INIT_ATTACH) {
@@ -2122,7 +2124,7 @@
ctx->chan = NULL;
glink_unregister_link_state_cb(ctx->link.link_notify_handle);
ctx->link.link_notify_handle = NULL;
- mutex_unlock(&ctx->mut);
+ mutex_unlock(&me->smd_mutex);
pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name,
MAJOR(me->dev_no), cid);
}
@@ -2215,15 +2217,6 @@
link->port_state = FASTRPC_LINK_DISCONNECTED;
break;
case GLINK_REMOTE_DISCONNECTED:
- mutex_lock(&me->channel[cid].mut);
- if (me->channel[cid].chan) {
- link->port_state = FASTRPC_LINK_REMOTE_DISCONNECTING;
- fastrpc_glink_close(me->channel[cid].chan, cid);
- me->channel[cid].chan = NULL;
- } else {
- link->port_state = FASTRPC_LINK_DISCONNECTED;
- }
- mutex_unlock(&me->channel[cid].mut);
break;
default:
break;
@@ -2234,20 +2227,23 @@
struct fastrpc_session_ctx **session)
{
int err = 0;
+ struct fastrpc_apps *me = &gfa;
- mutex_lock(&chan->mut);
+ mutex_lock(&me->smd_mutex);
if (!*session)
err = fastrpc_session_alloc_locked(chan, secure, session);
- mutex_unlock(&chan->mut);
+ mutex_unlock(&me->smd_mutex);
return err;
}
static void fastrpc_session_free(struct fastrpc_channel_ctx *chan,
struct fastrpc_session_ctx *session)
{
- mutex_lock(&chan->mut);
+ struct fastrpc_apps *me = &gfa;
+
+ mutex_lock(&me->smd_mutex);
session->used = 0;
- mutex_unlock(&chan->mut);
+ mutex_unlock(&me->smd_mutex);
}
static int fastrpc_file_free(struct fastrpc_file *fl)
@@ -2280,7 +2276,7 @@
}
if (fl->ssrcount == fl->apps->channel[cid].ssrcount)
kref_put_mutex(&fl->apps->channel[cid].kref,
- fastrpc_channel_close, &fl->apps->channel[cid].mut);
+ fastrpc_channel_close, &fl->apps->smd_mutex);
if (fl->sctx)
fastrpc_session_free(&fl->apps->channel[cid], fl->sctx);
if (fl->secsctx)
@@ -2357,20 +2353,6 @@
return err;
}
-static void fastrpc_glink_stop(int cid)
-{
- int err = 0;
- struct fastrpc_glink_info *link;
-
- VERIFY(err, (cid >= 0 && cid < NUM_CHANNELS));
- if (err)
- return;
- link = &gfa.channel[cid].link;
-
- if (link->port_state == FASTRPC_LINK_CONNECTED)
- link->port_state = FASTRPC_LINK_REMOTE_DISCONNECTING;
-}
-
static void fastrpc_glink_close(void *chan, int cid)
{
int err = 0;
@@ -2548,20 +2530,23 @@
struct fastrpc_apps *me = &gfa;
int cid, err = 0;
+ mutex_lock(&me->smd_mutex);
+
VERIFY(err, fl && fl->sctx);
if (err)
- return err;
+ goto bail;
cid = fl->cid;
VERIFY(err, cid >= 0 && cid < NUM_CHANNELS);
if (err)
goto bail;
- mutex_lock(&me->channel[cid].mut);
if (me->channel[cid].ssrcount !=
me->channel[cid].prevssrcount) {
if (!me->channel[cid].issubsystemup) {
VERIFY(err, 0);
- if (err)
+ if (err) {
+ err = -ENOTCONN;
goto bail;
+ }
}
}
fl->ssrcount = me->channel[cid].ssrcount;
@@ -2574,11 +2559,9 @@
if (err)
goto bail;
- mutex_unlock(&me->channel[cid].mut);
VERIFY(err,
wait_for_completion_timeout(&me->channel[cid].workport,
RPC_TIMEOUT));
- mutex_lock(&me->channel[cid].mut);
if (err) {
me->channel[cid].chan = NULL;
goto bail;
@@ -2603,7 +2586,7 @@
}
bail:
- mutex_unlock(&me->channel[cid].mut);
+ mutex_unlock(&me->smd_mutex);
return err;
}
@@ -2866,7 +2849,7 @@
p.init.init.memlen < INIT_MEMLEN_MAX);
if (err)
goto bail;
- VERIFY(err, 0 == fastrpc_init_process(fl, &p.init));
+ VERIFY(err, 0 == (err = fastrpc_init_process(fl, &p.init)));
if (err)
goto bail;
break;
@@ -2892,14 +2875,16 @@
ctx = container_of(nb, struct fastrpc_channel_ctx, nb);
cid = ctx - &me->channel[0];
if (code == SUBSYS_BEFORE_SHUTDOWN) {
- mutex_lock(&ctx->mut);
+ mutex_lock(&me->smd_mutex);
ctx->ssrcount++;
ctx->issubsystemup = 0;
- pr_info("'restart notifier: /dev/%s c %d %d'\n",
- gcinfo[cid].name, MAJOR(me->dev_no), cid);
- if (ctx->chan)
- fastrpc_glink_stop(cid);
- mutex_unlock(&ctx->mut);
+ if (ctx->chan) {
+ fastrpc_glink_close(ctx->chan, cid);
+ ctx->chan = NULL;
+ pr_info("'restart notifier: closed /dev/%s c %d %d'\n",
+ gcinfo[cid].name, MAJOR(me->dev_no), cid);
+ }
+ mutex_unlock(&me->smd_mutex);
if (cid == 0)
me->staticpd_flags = 0;
fastrpc_notify_drivers(me, cid);
@@ -3071,15 +3056,15 @@
static void fastrpc_deinit(void)
{
+ struct fastrpc_apps *me = &gfa;
struct fastrpc_channel_ctx *chan = gcinfo;
int i, j;
for (i = 0; i < NUM_CHANNELS; i++, chan++) {
if (chan->chan) {
kref_put_mutex(&chan->kref,
- fastrpc_channel_close, &chan->mut);
+ fastrpc_channel_close, &me->smd_mutex);
chan->chan = NULL;
- mutex_destroy(&chan->mut);
}
for (j = 0; j < NUM_SESSIONS; j++) {
struct fastrpc_session_ctx *sess = &chan->session[j];
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index bf9b99d..514c0ad 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -401,8 +401,8 @@
{
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
const struct pll_vco *vco;
- u32 l, off = pll->offset;
- u64 a;
+ u32 l = 0, off = pll->offset;
+ u64 a = 0;
rate = alpha_pll_round_rate(pll, rate, prate, &l, &a);
vco = alpha_pll_find_vco(pll, rate);
@@ -668,9 +668,9 @@
{
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
unsigned long rrate;
- u32 regval, l, off = pll->offset;
- u64 a;
- int ret;
+ u32 regval = 0, l = 0, off = pll->offset;
+ u64 a = 0;
+ int ret = 0;
ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, ®val);
if (ret)
@@ -1146,8 +1146,8 @@
unsigned long rrate;
bool is_enabled;
int ret;
- u32 l, val, off = pll->offset;
- u64 a;
+ u32 l = 0, val = 0, off = pll->offset;
+ u64 a = 0;
rrate = alpha_pll_round_rate(pll, rate, prate, &l, &a);
/*
diff --git a/drivers/clk/qcom/gcc-sdxpoorwills.c b/drivers/clk/qcom/gcc-sdxpoorwills.c
index fcf3601..a62a9a8 100644
--- a/drivers/clk/qcom/gcc-sdxpoorwills.c
+++ b/drivers/clk/qcom/gcc-sdxpoorwills.c
@@ -1353,6 +1353,19 @@
},
};
+static struct clk_branch gcc_pcie_0_clkref_clk = {
+ .halt_reg = 0x88004,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x88004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pcie_0_clkref_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct clk_branch gcc_pcie_aux_clk = {
.halt_reg = 0x37020,
.halt_check = BRANCH_HALT_VOTED,
@@ -1695,14 +1708,26 @@
},
};
-static struct clk_branch gcc_usb3_phy_pipe_clk = {
- .halt_reg = 0xb054,
- .halt_check = BRANCH_HALT,
+static struct clk_gate2 gcc_usb3_phy_pipe_clk = {
+ .udelay = 500,
.clkr = {
.enable_reg = 0xb054,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_usb3_phy_pipe_clk",
+ .ops = &clk_gate2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb3_prim_clkref_clk = {
+ .halt_reg = 0x88000,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x88000,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb3_prim_clkref_clk",
.ops = &clk_branch2_ops,
},
},
@@ -1782,6 +1807,7 @@
[GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr,
[GCC_MSS_GPLL0_DIV_CLK_SRC] = &gcc_mss_gpll0_div_clk_src.clkr,
[GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr,
+ [GCC_PCIE_0_CLKREF_CLK] = &gcc_pcie_0_clkref_clk.clkr,
[GCC_PCIE_AUX_CLK] = &gcc_pcie_aux_clk.clkr,
[GCC_PCIE_AUX_PHY_CLK_SRC] = &gcc_pcie_aux_phy_clk_src.clkr,
[GCC_PCIE_CFG_AHB_CLK] = &gcc_pcie_cfg_ahb_clk.clkr,
@@ -1813,6 +1839,7 @@
[GCC_USB3_PHY_AUX_CLK] = &gcc_usb3_phy_aux_clk.clkr,
[GCC_USB3_PHY_AUX_CLK_SRC] = &gcc_usb3_phy_aux_clk_src.clkr,
[GCC_USB3_PHY_PIPE_CLK] = &gcc_usb3_phy_pipe_clk.clkr,
+ [GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_clk.clkr,
[GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr,
[GPLL0] = &gpll0.clkr,
[GPLL0_OUT_EVEN] = &gpll0_out_even.clkr,
@@ -1837,6 +1864,8 @@
[GCC_SDCC1_BCR] = { 0xf000 },
[GCC_SPMI_FETCHER_BCR] = { 0x3f000 },
[GCC_USB30_BCR] = { 0xb000 },
+ [GCC_USB3_PHY_BCR] = { 0xc000 },
+ [GCC_USB3PHY_PHY_BCR] = { 0xc004 },
[GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0xe000 },
};
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c
index 0ddb47f..f2c2985 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c
@@ -83,6 +83,7 @@
dsi_ctrl_hw_14_reg_dump_to_buffer;
ctrl->ops.schedule_dma_cmd = NULL;
ctrl->ops.get_cont_splash_status = NULL;
+ ctrl->ops.kickoff_command_non_embedded_mode = NULL;
break;
case DSI_CTRL_VERSION_2_0:
ctrl->ops.setup_lane_map = dsi_ctrl_hw_20_setup_lane_map;
@@ -97,6 +98,7 @@
ctrl->ops.clamp_disable = NULL;
ctrl->ops.schedule_dma_cmd = NULL;
ctrl->ops.get_cont_splash_status = NULL;
+ ctrl->ops.kickoff_command_non_embedded_mode = NULL;
break;
case DSI_CTRL_VERSION_2_2:
ctrl->ops.phy_reset_config = dsi_ctrl_hw_22_phy_reset_config;
@@ -113,6 +115,8 @@
ctrl->ops.clamp_enable = NULL;
ctrl->ops.clamp_disable = NULL;
ctrl->ops.schedule_dma_cmd = dsi_ctrl_hw_22_schedule_dma_cmd;
+ ctrl->ops.kickoff_command_non_embedded_mode =
+ dsi_ctrl_hw_kickoff_non_embedded_mode;
break;
default:
break;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h
index 735f61f..f7756dc 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h
@@ -213,6 +213,9 @@
ssize_t dsi_ctrl_hw_20_reg_dump_to_buffer(struct dsi_ctrl_hw *ctrl,
char *buf,
u32 size);
+void dsi_ctrl_hw_kickoff_non_embedded_mode(struct dsi_ctrl_hw *ctrl,
+ struct dsi_ctrl_cmd_dma_info *cmd,
+ u32 flags);
/* Definitions specific to 2.2 DSI controller hardware */
bool dsi_ctrl_hw_22_get_cont_splash_status(struct dsi_ctrl_hw *ctrl);
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index 1f10e3c..609ae52 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -940,6 +940,62 @@
udelay(sleep_ms * 1000);
}
+void dsi_message_setup_tx_mode(struct dsi_ctrl *dsi_ctrl,
+ u32 cmd_len,
+ u32 *flags)
+{
+ /**
+ * Setup the mode of transmission
+ * override cmd fetch mode during secure session
+ */
+ if (dsi_ctrl->secure_mode) {
+ *flags &= ~DSI_CTRL_CMD_FETCH_MEMORY;
+ *flags |= DSI_CTRL_CMD_FIFO_STORE;
+ pr_debug("[%s] override to TPG during secure session\n",
+ dsi_ctrl->name);
+ return;
+ }
+
+ /* Check to see if cmd len plus header is greater than fifo size */
+ if ((cmd_len + 4) > DSI_EMBEDDED_MODE_DMA_MAX_SIZE_BYTES) {
+ *flags |= DSI_CTRL_CMD_NON_EMBEDDED_MODE;
+ pr_debug("[%s] override to non-embedded mode,cmd len =%d\n",
+ dsi_ctrl->name, cmd_len);
+ return;
+ }
+}
+
+int dsi_message_validate_tx_mode(struct dsi_ctrl *dsi_ctrl,
+ u32 cmd_len,
+ u32 *flags)
+{
+ int rc = 0;
+
+ if (*flags & DSI_CTRL_CMD_FIFO_STORE) {
+ /* if command size plus header is greater than fifo size */
+ if ((cmd_len + 4) > DSI_CTRL_MAX_CMD_FIFO_STORE_SIZE) {
+ pr_err("Cannot transfer Cmd in FIFO config\n");
+ return -ENOTSUPP;
+ }
+ if (!dsi_ctrl->hw.ops.kickoff_fifo_command) {
+ pr_err("Cannot transfer command,ops not defined\n");
+ return -ENOTSUPP;
+ }
+ }
+
+ if (*flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+ if (*flags & DSI_CTRL_CMD_BROADCAST) {
+ pr_err("Non embedded not supported with broadcast\n");
+ return -ENOTSUPP;
+ }
+ if (!dsi_ctrl->hw.ops.kickoff_command_non_embedded_mode) {
+ pr_err(" Cannot transfer command,ops not defined\n");
+ return -ENOTSUPP;
+ }
+ }
+ return rc;
+}
+
static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
const struct mipi_dsi_msg *msg,
u32 flags)
@@ -955,12 +1011,34 @@
u8 *cmdbuf;
struct dsi_mode_info *timing;
- /* override cmd fetch mode during secure session */
- if (dsi_ctrl->secure_mode) {
- flags &= ~DSI_CTRL_CMD_FETCH_MEMORY;
- flags |= DSI_CTRL_CMD_FIFO_STORE;
- pr_debug("[%s] override to TPG during secure session\n",
- dsi_ctrl->name);
+ /* Select the tx mode to transfer the command */
+ dsi_message_setup_tx_mode(dsi_ctrl, msg->tx_len, &flags);
+
+ /* Validate the mode before sending the command */
+ rc = dsi_message_validate_tx_mode(dsi_ctrl, msg->tx_len, &flags);
+ if (rc) {
+ pr_err(" Cmd tx validation failed, cannot transfer cmd\n");
+ rc = -ENOTSUPP;
+ goto error;
+ }
+
+ if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+ cmd_mem.offset = dsi_ctrl->cmd_buffer_iova;
+ cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ?
+ true : false;
+ cmd_mem.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ?
+ true : false;
+ cmd_mem.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ?
+ true : false;
+ cmd_mem.datatype = msg->type;
+ cmd_mem.length = msg->tx_len;
+
+ dsi_ctrl->cmd_len = msg->tx_len;
+ memcpy(dsi_ctrl->vaddr, msg->tx_buf, msg->tx_len);
+ pr_debug(" non-embedded mode , size of command =%zd\n",
+ msg->tx_len);
+
+ goto kickoff;
}
rc = mipi_dsi_create_packet(&packet, msg);
@@ -969,16 +1047,6 @@
goto error;
}
- /* fail cmds more than the supported size in TPG mode */
- if ((flags & DSI_CTRL_CMD_FIFO_STORE) &&
- (msg->tx_len > DSI_CTRL_MAX_CMD_FIFO_STORE_SIZE)) {
- pr_err("[%s] TPG cmd size:%zd not supported, secure:%d\n",
- dsi_ctrl->name, msg->tx_len,
- dsi_ctrl->secure_mode);
- rc = -ENOTSUPP;
- goto error;
- }
-
rc = dsi_ctrl_copy_and_pad_cmd(dsi_ctrl,
&packet,
&buffer,
@@ -993,6 +1061,7 @@
buffer[3] |= BIT(7);//set the last cmd bit in header.
if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
+ /* Embedded mode config is selected */
cmd_mem.offset = dsi_ctrl->cmd_buffer_iova;
cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ?
true : false;
@@ -1026,6 +1095,7 @@
true : false;
}
+kickoff:
timing = &(dsi_ctrl->host_config.video_timing);
if (timing)
line_no += timing->v_back_porch + timing->v_sync_width +
@@ -1045,9 +1115,18 @@
if (flags & DSI_CTRL_CMD_DEFER_TRIGGER) {
if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
- dsi_ctrl->hw.ops.kickoff_command(&dsi_ctrl->hw,
+ if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+ dsi_ctrl->hw.ops.
+ kickoff_command_non_embedded_mode(
+ &dsi_ctrl->hw,
&cmd_mem,
hw_flags);
+ } else {
+ dsi_ctrl->hw.ops.kickoff_command(
+ &dsi_ctrl->hw,
+ &cmd_mem,
+ hw_flags);
+ }
} else if (flags & DSI_CTRL_CMD_FIFO_STORE) {
dsi_ctrl->hw.ops.kickoff_fifo_command(&dsi_ctrl->hw,
&cmd,
@@ -1065,9 +1144,18 @@
reinit_completion(&dsi_ctrl->irq_info.cmd_dma_done);
if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
- dsi_ctrl->hw.ops.kickoff_command(&dsi_ctrl->hw,
- &cmd_mem,
- hw_flags);
+ if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+ dsi_ctrl->hw.ops.
+ kickoff_command_non_embedded_mode(
+ &dsi_ctrl->hw,
+ &cmd_mem,
+ hw_flags);
+ } else {
+ dsi_ctrl->hw.ops.kickoff_command(
+ &dsi_ctrl->hw,
+ &cmd_mem,
+ hw_flags);
+ }
} else if (flags & DSI_CTRL_CMD_FIFO_STORE) {
dsi_ctrl->hw.ops.kickoff_fifo_command(&dsi_ctrl->hw,
&cmd,
@@ -1106,6 +1194,16 @@
dsi_ctrl->hw.ops.mask_error_intr(&dsi_ctrl->hw,
BIT(DSI_FIFO_OVERFLOW), false);
dsi_ctrl->hw.ops.reset_cmd_fifo(&dsi_ctrl->hw);
+
+ /*
+ * DSI 2.2 needs a soft reset whenever we send non-embedded
+ * mode command followed by embedded mode. Otherwise it will
+ * result in smmu write faults with DSI as client.
+ */
+ if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+ dsi_ctrl->hw.ops.soft_reset(&dsi_ctrl->hw);
+ dsi_ctrl->cmd_len = 0;
+ }
}
error:
if (buffer)
@@ -2682,6 +2780,11 @@
if (dsi_ctrl->hw.ops.mask_error_intr)
dsi_ctrl->hw.ops.mask_error_intr(&dsi_ctrl->hw,
BIT(DSI_FIFO_OVERFLOW), false);
+
+ if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+ dsi_ctrl->hw.ops.soft_reset(&dsi_ctrl->hw);
+ dsi_ctrl->cmd_len = 0;
+ }
}
mutex_unlock(&dsi_ctrl->ctrl_lock);
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
index f5b08a0..80b91ca 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
@@ -37,6 +37,7 @@
* and transfer it.
* @DSI_CTRL_CMD_LAST_COMMAND: Trigger the DMA cmd transfer if this is last
* command in the batch.
+ * @DSI_CTRL_CMD_NON_EMBEDDED_MODE:Trasfer cmd packets in non embedded mode.
*/
#define DSI_CTRL_CMD_READ 0x1
#define DSI_CTRL_CMD_BROADCAST 0x2
@@ -45,6 +46,12 @@
#define DSI_CTRL_CMD_FIFO_STORE 0x10
#define DSI_CTRL_CMD_FETCH_MEMORY 0x20
#define DSI_CTRL_CMD_LAST_COMMAND 0x40
+#define DSI_CTRL_CMD_NON_EMBEDDED_MODE 0x80
+
+/* DSI embedded mode fifo size
+ * If the command is greater than 256 bytes it is sent in non-embedded mode.
+ */
+#define DSI_EMBEDDED_MODE_DMA_MAX_SIZE_BYTES 256
/* max size supported for dsi cmd transfer using TPG */
#define DSI_CTRL_MAX_CMD_FIFO_STORE_SIZE 64
@@ -680,4 +687,20 @@
*/
int dsi_ctrl_vid_engine_en(struct dsi_ctrl *dsi_ctrl, bool on);
+/**
+ * @dsi_ctrl: DSI controller handle.
+ * cmd_len: Length of command.
+ * flags: Config mode flags.
+ */
+void dsi_message_setup_tx_mode(struct dsi_ctrl *dsi_ctrl, u32 cmd_len,
+ u32 *flags);
+
+/**
+ * @dsi_ctrl: DSI controller handle.
+ * cmd_len: Length of command.
+ * flags: Config mode flags.
+ */
+int dsi_message_validate_tx_mode(struct dsi_ctrl *dsi_ctrl, u32 cmd_len,
+ u32 *flags);
+
#endif /* _DSI_CTRL_H_ */
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h
index c77065c..567f289 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h
@@ -296,6 +296,7 @@
* struct dsi_ctrl_cmd_dma_info - command buffer information
* @offset: IOMMU VA for command buffer address.
* @length: Length of the command buffer.
+ * @datatype: Datatype of cmd.
* @en_broadcast: Enable broadcast mode if set to true.
* @is_master: Is master in broadcast mode.
* @use_lpm: Use low power mode for command transmission.
@@ -303,6 +304,7 @@
struct dsi_ctrl_cmd_dma_info {
u32 offset;
u32 length;
+ u8 datatype;
bool en_broadcast;
bool is_master;
bool use_lpm;
@@ -497,6 +499,25 @@
u32 flags);
/**
+ * kickoff_command_non_embedded_mode() - cmd in non embedded mode
+ * @ctrl: Pointer to the controller host hardware.
+ * @cmd: Command information.
+ * @flags: Modifiers for command transmission.
+ *
+ * If command length is greater than DMA FIFO size of 256 bytes we use
+ * this non- embedded mode.
+ * The controller hardware is programmed with address and size of the
+ * command buffer. The transmission is kicked off if
+ * DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER flag is not set. If this flag is
+ * set, caller should make a separate call to trigger_command_dma() to
+ * transmit the command.
+ */
+
+ void (*kickoff_command_non_embedded_mode)(struct dsi_ctrl_hw *ctrl,
+ struct dsi_ctrl_cmd_dma_info *cmd,
+ u32 flags);
+
+ /**
* kickoff_fifo_command() - transmits a command using FIFO in dsi
* hardware.
* @ctrl: Pointer to the controller host hardware.
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_2_2.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_2_2.c
index 650c2e0..d94d6f7b 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_2_2.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_2_2.c
@@ -79,3 +79,48 @@
reg = DSI_R32(ctrl, DSI_SCRATCH_REGISTER_1);
return reg == 0x1 ? true : false;
}
+
+/*
+ * dsi_ctrl_hw_kickoff_non_embedded_mode()-Kickoff cmd in non-embedded mode
+ * @ctrl: - Pointer to the controller host hardware.
+ * @dsi_ctrl_cmd_dma_info: - command buffer information.
+ * @flags: - DSI CTRL Flags.
+ */
+void dsi_ctrl_hw_kickoff_non_embedded_mode(struct dsi_ctrl_hw *ctrl,
+ struct dsi_ctrl_cmd_dma_info *cmd,
+ u32 flags)
+{
+ u32 reg = 0;
+
+ reg = DSI_R32(ctrl, DSI_COMMAND_MODE_DMA_CTRL);
+
+ reg &= ~BIT(31);/* disable broadcast */
+ reg &= ~BIT(30);
+
+ if (cmd->use_lpm)
+ reg |= BIT(26);
+ else
+ reg &= ~BIT(26);
+
+ /* Select non EMBEDDED_MODE, pick the packet header from register */
+ reg &= ~BIT(28);
+ reg |= BIT(24);/* long packet */
+ reg |= BIT(29);/* wc_sel = 1 */
+ reg |= (((cmd->datatype) & 0x03f) << 16);/* data type */
+ DSI_W32(ctrl, DSI_COMMAND_MODE_DMA_CTRL, reg);
+
+ /* Enable WRITE_WATERMARK_DISABLE and READ_WATERMARK_DISABLE bits */
+ reg = DSI_R32(ctrl, DSI_DMA_FIFO_CTRL);
+ reg |= BIT(20);
+ reg |= BIT(16);
+ DSI_W32(ctrl, DSI_DMA_FIFO_CTRL, reg);
+
+ DSI_W32(ctrl, DSI_DMA_CMD_OFFSET, cmd->offset);
+ DSI_W32(ctrl, DSI_DMA_CMD_LENGTH, ((cmd->length) & 0xFFFFFF));
+
+ /* wait for writes to complete before kick off */
+ wmb();
+
+ if (!(flags & DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER))
+ DSI_W32(ctrl, DSI_CMD_MODE_DMA_SW_TRIGGER, 0x1);
+}
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
index c2c8f57..c753c80 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
@@ -612,9 +612,17 @@
else
reg &= ~BIT(26);
- reg |= BIT(28);
+ reg |= BIT(28);/* Select embedded mode */
+ reg &= ~BIT(24);/* packet type */
+ reg &= ~BIT(29);/* WC_SEL to 0 */
DSI_W32(ctrl, DSI_COMMAND_MODE_DMA_CTRL, reg);
+ reg = DSI_R32(ctrl, DSI_DMA_FIFO_CTRL);
+ reg &= ~BIT(20);/* Enable write watermark*/
+ reg &= ~BIT(16);/* Enable read watermark */
+
+
+ DSI_W32(ctrl, DSI_DMA_FIFO_CTRL, reg);
DSI_W32(ctrl, DSI_DMA_CMD_OFFSET, cmd->offset);
DSI_W32(ctrl, DSI_DMA_CMD_LENGTH, (cmd->length & 0xFFFFFF));
diff --git a/drivers/gpu/drm/msm/sde/sde_core_perf.c b/drivers/gpu/drm/msm/sde/sde_core_perf.c
index 6b36745..3879d4d 100644
--- a/drivers/gpu/drm/msm/sde/sde_core_perf.c
+++ b/drivers/gpu/drm/msm/sde/sde_core_perf.c
@@ -170,6 +170,15 @@
}
SDE_EVT32(crtc->base.id, perf->core_clk_rate);
+ trace_sde_perf_calc_crtc(crtc->base.id,
+ perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC],
+ perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC],
+ perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_EBI],
+ perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_MNOC],
+ perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_LLCC],
+ perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_EBI],
+ perf->core_clk_rate);
+
SDE_DEBUG(
"crtc=%d clk_rate=%llu core_ib=%llu core_ab=%llu llcc_ib=%llu llcc_ab=%llu mem_ib=%llu mem_ab=%llu\n",
crtc->base.id, perf->core_clk_rate,
@@ -552,19 +561,32 @@
* 2. new bandwidth vote - "ab or ib vote" is lower
* than current vote at end of commit or stop.
*/
- if ((params_changed && ((new->bw_ctl[i] >
- old->bw_ctl[i]) ||
- (new->max_per_pipe_ib[i] >
- old->max_per_pipe_ib[i]))) ||
- (!params_changed && ((new->bw_ctl[i] <
- old->bw_ctl[i]) ||
- (new->max_per_pipe_ib[i] <
- old->max_per_pipe_ib[i])))) {
+
+ if ((params_changed &&
+ (new->bw_ctl[i] > old->bw_ctl[i])) ||
+ (!params_changed &&
+ (new->bw_ctl[i] < old->bw_ctl[i]))) {
+
SDE_DEBUG(
"crtc=%d p=%d new_bw=%llu,old_bw=%llu\n",
crtc->base.id, params_changed,
new->bw_ctl[i], old->bw_ctl[i]);
old->bw_ctl[i] = new->bw_ctl[i];
+ update_bus |= BIT(i);
+ }
+
+ if ((params_changed &&
+ (new->max_per_pipe_ib[i] >
+ old->max_per_pipe_ib[i])) ||
+ (!params_changed &&
+ (new->max_per_pipe_ib[i] <
+ old->max_per_pipe_ib[i]))) {
+
+ SDE_DEBUG(
+ "crtc=%d p=%d new_ib=%llu,old_ib=%llu\n",
+ crtc->base.id, params_changed,
+ new->max_per_pipe_ib[i],
+ old->max_per_pipe_ib[i]);
old->max_per_pipe_ib[i] =
new->max_per_pipe_ib[i];
update_bus |= BIT(i);
@@ -608,11 +630,14 @@
update_clk = 1;
}
trace_sde_perf_crtc_update(crtc->base.id,
- new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC],
- new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC],
- new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_EBI],
- new->core_clk_rate, stop_req,
- update_bus, update_clk);
+ new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC],
+ new->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_MNOC],
+ new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC],
+ new->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_LLCC],
+ new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_EBI],
+ new->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_EBI],
+ new->core_clk_rate, stop_req,
+ update_bus, update_clk, params_changed);
for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) {
if (update_bus & BIT(i))
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index df65ea3..b6888df 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -1512,6 +1512,7 @@
struct drm_crtc *primary_crtc;
int pipe = -1;
int rc = 0;
+ int wait_refcount;
if (!drm_enc || !drm_enc->dev) {
SDE_ERROR("invalid encoder arguments\n");
@@ -1599,6 +1600,12 @@
return ret;
}
+ if (wait_vblank_crtc_id)
+ wait_refcount =
+ sde_rsc_client_get_vsync_refcount(sde_enc->rsc_client);
+ SDE_EVT32_VERBOSE(DRMID(drm_enc), wait_vblank_crtc_id, wait_refcount,
+ SDE_EVTLOG_FUNC_ENTRY);
+
if (crtc->base.id != wait_vblank_crtc_id) {
primary_crtc = drm_crtc_find(drm_enc->dev, wait_vblank_crtc_id);
if (!primary_crtc) {
@@ -1636,6 +1643,11 @@
SDE_EVT32(DRMID(drm_enc), wait_vblank_crtc_id, wait_count,
SDE_EVTLOG_ERROR);
+ if (wait_refcount)
+ sde_rsc_client_reset_vsync_refcount(sde_enc->rsc_client);
+ SDE_EVT32_VERBOSE(DRMID(drm_enc), wait_vblank_crtc_id, wait_refcount,
+ SDE_EVTLOG_FUNC_EXIT);
+
return ret;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_trace.h b/drivers/gpu/drm/msm/sde/sde_trace.h
index ef4cdeb..2909778 100644
--- a/drivers/gpu/drm/msm/sde/sde_trace.h
+++ b/drivers/gpu/drm/msm/sde/sde_trace.h
@@ -93,21 +93,24 @@
)
TRACE_EVENT(sde_perf_update_bus,
- TP_PROTO(int client, unsigned long long ab_quota,
+ TP_PROTO(int client, u32 bus_id, unsigned long long ab_quota,
unsigned long long ib_quota),
- TP_ARGS(client, ab_quota, ib_quota),
+ TP_ARGS(client, bus_id, ab_quota, ib_quota),
TP_STRUCT__entry(
__field(int, client)
+ __field(u32, bus_id);
__field(u64, ab_quota)
__field(u64, ib_quota)
),
TP_fast_assign(
__entry->client = client;
+ __entry->bus_id = bus_id;
__entry->ab_quota = ab_quota;
__entry->ib_quota = ib_quota;
),
- TP_printk("Request client:%d ab=%llu ib=%llu",
+ TP_printk("Request client:%d bus_id:%d ab=%llu ib=%llu",
__entry->client,
+ __entry->bus_id,
__entry->ab_quota,
__entry->ib_quota)
)
@@ -209,41 +212,111 @@
)
TRACE_EVENT(sde_perf_crtc_update,
- TP_PROTO(u32 crtc, u64 bw_ctl_mnoc, u64 bw_ctl_llcc,
- u64 bw_ctl_ebi, u32 core_clk_rate,
- bool stop_req, u32 update_bus, u32 update_clk),
- TP_ARGS(crtc, bw_ctl_mnoc, bw_ctl_llcc, bw_ctl_ebi, core_clk_rate,
- stop_req, update_bus, update_clk),
+ TP_PROTO(u32 crtc,
+ u64 bw_ctl_mnoc, u64 per_pipe_ib_mnoc,
+ u64 bw_ctl_llcc, u64 per_pipe_ib_llcc,
+ u64 bw_ctl_ebi, u64 per_pipe_ib_ebi,
+ u32 core_clk_rate, bool stop_req,
+ u32 update_bus, u32 update_clk, int params),
+ TP_ARGS(crtc,
+ bw_ctl_mnoc, per_pipe_ib_mnoc,
+ bw_ctl_llcc, per_pipe_ib_llcc,
+ bw_ctl_ebi, per_pipe_ib_ebi,
+ core_clk_rate, stop_req,
+ update_bus, update_clk, params),
+ TP_STRUCT__entry(
+ __field(u32, crtc)
+ __field(u64, bw_ctl_mnoc)
+ __field(u64, per_pipe_ib_mnoc)
+ __field(u64, bw_ctl_llcc)
+ __field(u64, per_pipe_ib_llcc)
+ __field(u64, bw_ctl_ebi)
+ __field(u64, per_pipe_ib_ebi)
+ __field(u32, core_clk_rate)
+ __field(bool, stop_req)
+ __field(u32, update_bus)
+ __field(u32, update_clk)
+ __field(int, params)
+ ),
+ TP_fast_assign(
+ __entry->crtc = crtc;
+ __entry->bw_ctl_mnoc = bw_ctl_mnoc;
+ __entry->per_pipe_ib_mnoc = per_pipe_ib_mnoc;
+ __entry->bw_ctl_llcc = bw_ctl_llcc;
+ __entry->per_pipe_ib_llcc = per_pipe_ib_llcc;
+ __entry->bw_ctl_ebi = bw_ctl_ebi;
+ __entry->per_pipe_ib_ebi = per_pipe_ib_ebi;
+ __entry->core_clk_rate = core_clk_rate;
+ __entry->stop_req = stop_req;
+ __entry->update_bus = update_bus;
+ __entry->update_clk = update_clk;
+ __entry->params = params;
+ ),
+ TP_printk(
+ "crtc=%d mnoc=[%llu %llu] llcc=[%llu %llu] ebi=[%llu %llu] clk=%u stop=%d ubus=%d uclk=%d %d",
+ __entry->crtc,
+ __entry->bw_ctl_mnoc,
+ __entry->per_pipe_ib_mnoc,
+ __entry->bw_ctl_llcc,
+ __entry->per_pipe_ib_llcc,
+ __entry->bw_ctl_ebi,
+ __entry->per_pipe_ib_ebi,
+ __entry->core_clk_rate,
+ __entry->stop_req,
+ __entry->update_bus,
+ __entry->update_clk,
+ __entry->params)
+);
+
+TRACE_EVENT(sde_perf_calc_crtc,
+ TP_PROTO(u32 crtc,
+ u64 bw_ctl_mnoc,
+ u64 bw_ctl_llcc,
+ u64 bw_ctl_ebi,
+ u64 ib_mnoc,
+ u64 ib_llcc,
+ u64 ib_ebi,
+ u32 core_clk_rate
+ ),
+ TP_ARGS(crtc,
+ bw_ctl_mnoc,
+ bw_ctl_llcc,
+ bw_ctl_ebi,
+ ib_mnoc,
+ ib_llcc,
+ ib_ebi,
+ core_clk_rate),
TP_STRUCT__entry(
__field(u32, crtc)
__field(u64, bw_ctl_mnoc)
__field(u64, bw_ctl_llcc)
__field(u64, bw_ctl_ebi)
+ __field(u64, ib_mnoc)
+ __field(u64, ib_llcc)
+ __field(u64, ib_ebi)
__field(u32, core_clk_rate)
- __field(bool, stop_req)
- __field(u32, update_bus)
- __field(u32, update_clk)
+
),
TP_fast_assign(
__entry->crtc = crtc;
__entry->bw_ctl_mnoc = bw_ctl_mnoc;
__entry->bw_ctl_llcc = bw_ctl_llcc;
__entry->bw_ctl_ebi = bw_ctl_ebi;
+ __entry->ib_mnoc = ib_mnoc;
+ __entry->ib_llcc = ib_llcc;
+ __entry->ib_ebi = ib_ebi;
__entry->core_clk_rate = core_clk_rate;
- __entry->stop_req = stop_req;
- __entry->update_bus = update_bus;
- __entry->update_clk = update_clk;
),
TP_printk(
- "crtc=%d bw_mnoc=%llu bw_llcc=%llu bw_ebi=%llu clk_rate=%u stop_req=%d u_bus=%d u_clk=%d",
+ "crtc=%d mnoc=[%llu, %llu] llcc=[%llu %llu] ebi=[%llu, %llu] clk_rate=%u",
__entry->crtc,
__entry->bw_ctl_mnoc,
+ __entry->ib_mnoc,
__entry->bw_ctl_llcc,
+ __entry->ib_llcc,
__entry->bw_ctl_ebi,
- __entry->core_clk_rate,
- __entry->stop_req,
- __entry->update_bus,
- __entry->update_clk)
+ __entry->ib_ebi,
+ __entry->core_clk_rate)
);
#define SDE_ATRACE_END(name) trace_tracing_mark_write(current->tgid, name, 0)
diff --git a/drivers/gpu/drm/msm/sde_power_handle.c b/drivers/gpu/drm/msm/sde_power_handle.c
index 34a826d..4244c00 100644
--- a/drivers/gpu/drm/msm/sde_power_handle.c
+++ b/drivers/gpu/drm/msm/sde_power_handle.c
@@ -470,7 +470,7 @@
pclient->ab[bus_client] = ab_quota;
pclient->ib[bus_client] = ib_quota;
- trace_sde_perf_update_bus(bus_client, ab_quota, ib_quota);
+ trace_sde_perf_update_bus(bus_client, bus_id, ab_quota, ib_quota);
list_for_each_entry(client, &phandle->power_client_clist, list) {
for (i = 0; i < SDE_POWER_HANDLE_DATA_BUS_CLIENT_MAX; i++) {
diff --git a/drivers/gpu/drm/msm/sde_rsc.c b/drivers/gpu/drm/msm/sde_rsc.c
index 82b1199..429ab01 100644
--- a/drivers/gpu/drm/msm/sde_rsc.c
+++ b/drivers/gpu/drm/msm/sde_rsc.c
@@ -561,6 +561,23 @@
msleep(PRIMARY_VBLANK_WORST_CASE_MS);
} else {
*wait_vblank_crtc_id = rsc->primary_client->crtc_id;
+
+ /* increase refcount, so we wait for the next vsync */
+ atomic_inc(&rsc->rsc_vsync_wait);
+ SDE_EVT32(atomic_read(&rsc->rsc_vsync_wait));
+ }
+ } else if (atomic_read(&rsc->rsc_vsync_wait)) {
+ SDE_EVT32(rsc->primary_client, rsc->current_state,
+ atomic_read(&rsc->rsc_vsync_wait));
+
+ /* Wait for the vsync, if the refcount is set */
+ rc = wait_event_timeout(rsc->rsc_vsync_waitq,
+ atomic_read(&rsc->rsc_vsync_wait) == 0,
+ msecs_to_jiffies(PRIMARY_VBLANK_WORST_CASE_MS*2));
+ if (!rc) {
+ pr_err("Timeout waiting for vsync\n");
+ SDE_EVT32(atomic_read(&rsc->rsc_vsync_wait),
+ SDE_EVTLOG_ERROR);
}
}
end:
@@ -600,6 +617,23 @@
msleep(PRIMARY_VBLANK_WORST_CASE_MS);
} else {
*wait_vblank_crtc_id = rsc->primary_client->crtc_id;
+
+ /* increase refcount, so we wait for the next vsync */
+ atomic_inc(&rsc->rsc_vsync_wait);
+ SDE_EVT32(atomic_read(&rsc->rsc_vsync_wait));
+ }
+ } else if (atomic_read(&rsc->rsc_vsync_wait)) {
+ SDE_EVT32(rsc->primary_client, rsc->current_state,
+ atomic_read(&rsc->rsc_vsync_wait));
+
+ /* Wait for the vsync, if the refcount is set */
+ rc = wait_event_timeout(rsc->rsc_vsync_waitq,
+ atomic_read(&rsc->rsc_vsync_wait) == 0,
+ msecs_to_jiffies(PRIMARY_VBLANK_WORST_CASE_MS*2));
+ if (!rc) {
+ pr_err("Timeout waiting for vsync\n");
+ SDE_EVT32(atomic_read(&rsc->rsc_vsync_wait),
+ SDE_EVTLOG_ERROR);
}
}
@@ -608,6 +642,65 @@
}
/**
+ * sde_rsc_client_get_vsync_refcount() - returns the status of the vsync
+ * refcount, to signal if the client needs to reset the refcounting logic
+ * @client: Client pointer provided by sde_rsc_client_create().
+ *
+ * Return: value of the vsync refcount.
+ */
+int sde_rsc_client_get_vsync_refcount(
+ struct sde_rsc_client *caller_client)
+{
+ struct sde_rsc_priv *rsc;
+
+ if (!caller_client) {
+ pr_err("invalid client for rsc state update\n");
+ return -EINVAL;
+ } else if (caller_client->rsc_index >= MAX_RSC_COUNT) {
+ pr_err("invalid rsc index\n");
+ return -EINVAL;
+ }
+
+ rsc = rsc_prv_list[caller_client->rsc_index];
+ if (!rsc)
+ return 0;
+
+ return atomic_read(&rsc->rsc_vsync_wait);
+}
+
+/**
+ * sde_rsc_client_reset_vsync_refcount() - reduces the refcounting
+ * logic that waits for the vsync.
+ * @client: Client pointer provided by sde_rsc_client_create().
+ *
+ * Return: zero if refcount was already zero.
+ */
+int sde_rsc_client_reset_vsync_refcount(
+ struct sde_rsc_client *caller_client)
+{
+ struct sde_rsc_priv *rsc;
+ int ret;
+
+ if (!caller_client) {
+ pr_err("invalid client for rsc state update\n");
+ return -EINVAL;
+ } else if (caller_client->rsc_index >= MAX_RSC_COUNT) {
+ pr_err("invalid rsc index\n");
+ return -EINVAL;
+ }
+
+ rsc = rsc_prv_list[caller_client->rsc_index];
+ if (!rsc)
+ return 0;
+
+ ret = atomic_add_unless(&rsc->rsc_vsync_wait, -1, 0);
+ wake_up_all(&rsc->rsc_vsync_waitq);
+ SDE_EVT32(atomic_read(&rsc->rsc_vsync_wait));
+
+ return ret;
+}
+
+/**
* sde_rsc_client_is_state_update_complete() - check if state update is complete
* RSC state transition is not complete until HW receives VBLANK signal. This
* function checks RSC HW to determine whether that signal has been received.
@@ -1307,6 +1400,7 @@
INIT_LIST_HEAD(&rsc->client_list);
INIT_LIST_HEAD(&rsc->event_list);
mutex_init(&rsc->client_lock);
+ init_waitqueue_head(&rsc->rsc_vsync_waitq);
pr_info("sde rsc index:%d probed successfully\n",
SDE_RSC_INDEX + counter);
diff --git a/drivers/gpu/drm/msm/sde_rsc_priv.h b/drivers/gpu/drm/msm/sde_rsc_priv.h
index 64b0216..5c62466 100644
--- a/drivers/gpu/drm/msm/sde_rsc_priv.h
+++ b/drivers/gpu/drm/msm/sde_rsc_priv.h
@@ -149,6 +149,8 @@
* and ab/ib vote on display rsc
* master_drm: Primary client waits for vsync on this drm object based
* on crtc id
+ * rsc_vsync_wait: Refcount to indicate if we have to wait for the vsync.
+ * rsc_vsync_waitq: Queue to wait for the vsync.
*/
struct sde_rsc_priv {
u32 version;
@@ -177,6 +179,8 @@
struct sde_rsc_client *primary_client;
struct drm_device *master_drm;
+ atomic_t rsc_vsync_wait;
+ wait_queue_head_t rsc_vsync_waitq;
};
/**
diff --git a/drivers/gpu/msm/adreno_a6xx_snapshot.c b/drivers/gpu/msm/adreno_a6xx_snapshot.c
index 3f92f75..589417f 100644
--- a/drivers/gpu/msm/adreno_a6xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a6xx_snapshot.c
@@ -195,6 +195,35 @@
unsigned int ctxt_id;
};
+static const unsigned int a6xx_hlsq_non_ctx_registers[] = {
+ 0xBE00, 0xBE01, 0xBE04, 0xBE05, 0xBE08, 0xBE09, 0xBE10, 0xBE15,
+ 0xBE20, 0xBE23,
+};
+
+static const unsigned int a6xx_sp_non_ctx_registers[] = {
+ 0xAE00, 0xAE04, 0xAE0C, 0xAE0C, 0xAE0F, 0xAE2B, 0xAE30, 0xAE32,
+ 0xAE35, 0xAE35, 0xAE3A, 0xAE3F, 0xAE50, 0xAE52,
+};
+
+static const unsigned int a6xx_tp_non_ctx_registers[] = {
+ 0xB600, 0xB601, 0xB604, 0xB605, 0xB610, 0xB61B, 0xB620, 0xB623,
+};
+
+static struct a6xx_non_ctx_dbgahb_registers {
+ unsigned int regbase;
+ unsigned int statetype;
+ const unsigned int *regs;
+ unsigned int num_sets;
+ unsigned int offset;
+} a6xx_non_ctx_dbgahb[] = {
+ { 0x0002F800, 0x40, a6xx_hlsq_non_ctx_registers,
+ ARRAY_SIZE(a6xx_hlsq_non_ctx_registers) / 2 },
+ { 0x0002B800, 0x20, a6xx_sp_non_ctx_registers,
+ ARRAY_SIZE(a6xx_sp_non_ctx_registers) / 2 },
+ { 0x0002D800, 0x0, a6xx_tp_non_ctx_registers,
+ ARRAY_SIZE(a6xx_tp_non_ctx_registers) / 2 },
+};
+
static const unsigned int a6xx_vbif_ver_20xxxxxx_registers[] = {
/* VBIF */
0x3000, 0x3007, 0x300C, 0x3014, 0x3018, 0x302D, 0x3030, 0x3031,
@@ -308,15 +337,6 @@
/* VFD */
0xA600, 0xA601, 0xA603, 0xA603, 0xA60A, 0xA60A, 0xA610, 0xA617,
0xA630, 0xA630,
- /* SP */
- 0xAE00, 0xAE04, 0xAE0C, 0xAE0C, 0xAE0F, 0xAE2B, 0xAE30, 0xAE32,
- 0xAE35, 0xAE35, 0xAE3A, 0xAE3F, 0xAE50, 0xAE52,
- /* TP */
- 0xB600, 0xB601, 0xB604, 0xB605, 0xB610, 0xB61B, 0xB620, 0xB623,
- /* HLSQ */
- 0xBE00, 0xBE01, 0xBE04, 0xBE05, 0xBE08, 0xBE09, 0xBE10, 0xBE15,
- 0xBE20, 0xBE23,
-
};
/*
@@ -832,6 +852,106 @@
return data_size + sizeof(*header);
}
+static size_t a6xx_legacy_snapshot_non_ctx_dbgahb(struct kgsl_device *device,
+ u8 *buf, size_t remain, void *priv)
+{
+ struct kgsl_snapshot_regs *header =
+ (struct kgsl_snapshot_regs *)buf;
+ struct a6xx_non_ctx_dbgahb_registers *regs =
+ (struct a6xx_non_ctx_dbgahb_registers *)priv;
+ unsigned int *data = (unsigned int *)(buf + sizeof(*header));
+ int count = 0;
+ unsigned int read_sel;
+ int i, j;
+
+ if (!device->snapshot_legacy)
+ return 0;
+
+ /* Figure out how many registers we are going to dump */
+ for (i = 0; i < regs->num_sets; i++) {
+ int start = regs->regs[i * 2];
+ int end = regs->regs[i * 2 + 1];
+
+ count += (end - start + 1);
+ }
+
+ if (remain < (count * 8) + sizeof(*header)) {
+ SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
+ return 0;
+ }
+
+ header->count = count;
+
+ read_sel = (regs->statetype & 0xff) << 8;
+ kgsl_regwrite(device, A6XX_HLSQ_DBG_READ_SEL, read_sel);
+
+ for (i = 0; i < regs->num_sets; i++) {
+ unsigned int start = regs->regs[2 * i];
+ unsigned int end = regs->regs[2 * i + 1];
+
+ for (j = start; j <= end; j++) {
+ unsigned int val;
+
+ val = a6xx_read_dbgahb(device, regs->regbase, j);
+ *data++ = j;
+ *data++ = val;
+
+ }
+ }
+ return (count * 8) + sizeof(*header);
+}
+
+static size_t a6xx_snapshot_non_ctx_dbgahb(struct kgsl_device *device, u8 *buf,
+ size_t remain, void *priv)
+{
+ struct kgsl_snapshot_regs *header =
+ (struct kgsl_snapshot_regs *)buf;
+ struct a6xx_non_ctx_dbgahb_registers *regs =
+ (struct a6xx_non_ctx_dbgahb_registers *)priv;
+ unsigned int count = 0;
+ unsigned int *data = (unsigned int *)(buf + sizeof(*header));
+ unsigned int i, k;
+ unsigned int *src;
+
+ if (crash_dump_valid == false)
+ return a6xx_legacy_snapshot_non_ctx_dbgahb(device, buf, remain,
+ regs);
+
+ if (remain < sizeof(*header)) {
+ SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
+ return 0;
+ }
+
+ remain -= sizeof(*header);
+
+ src = (unsigned int *)(a6xx_crashdump_registers.hostptr + regs->offset);
+
+ for (i = 0; i < regs->num_sets; i++) {
+ unsigned int start;
+ unsigned int end;
+
+ start = regs->regs[2 * i];
+ end = regs->regs[(2 * i) + 1];
+
+ if (remain < (end - start + 1) * 8) {
+ SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
+ goto out;
+ }
+
+ remain -= ((end - start) + 1) * 8;
+
+ for (k = start; k <= end; k++, count++) {
+ *data++ = k;
+ *data++ = *src++;
+ }
+ }
+out:
+ header->count = count;
+
+ /* Return the size of the section */
+ return (count * 8) + sizeof(*header);
+}
+
static void a6xx_snapshot_dbgahb_regs(struct kgsl_device *device,
struct kgsl_snapshot *snapshot)
{
@@ -851,6 +971,12 @@
a6xx_snapshot_cluster_dbgahb, &info);
}
}
+
+ for (i = 0; i < ARRAY_SIZE(a6xx_non_ctx_dbgahb); i++) {
+ kgsl_snapshot_add_section(device,
+ KGSL_SNAPSHOT_SECTION_REGS, snapshot,
+ a6xx_snapshot_non_ctx_dbgahb, &a6xx_non_ctx_dbgahb[i]);
+ }
}
static size_t a6xx_legacy_snapshot_mvc(struct kgsl_device *device, u8 *buf,
@@ -1622,6 +1748,40 @@
return qwords;
}
+static int _a6xx_crashdump_init_non_ctx_dbgahb(uint64_t *ptr, uint64_t *offset)
+{
+ int qwords = 0;
+ unsigned int i, k;
+ unsigned int count;
+
+ for (i = 0; i < ARRAY_SIZE(a6xx_non_ctx_dbgahb); i++) {
+ struct a6xx_non_ctx_dbgahb_registers *regs =
+ &a6xx_non_ctx_dbgahb[i];
+
+ regs->offset = *offset;
+
+ /* Program the aperture */
+ ptr[qwords++] = (regs->statetype & 0xff) << 8;
+ ptr[qwords++] = (((uint64_t)A6XX_HLSQ_DBG_READ_SEL << 44)) |
+ (1 << 21) | 1;
+
+ for (k = 0; k < regs->num_sets; k++) {
+ unsigned int start = regs->regs[2 * k];
+
+ count = REG_PAIR_COUNT(regs->regs, k);
+ ptr[qwords++] =
+ a6xx_crashdump_registers.gpuaddr + *offset;
+ ptr[qwords++] =
+ (((uint64_t)(A6XX_HLSQ_DBG_AHB_READ_APERTURE +
+ start - regs->regbase / 4) << 44)) |
+ count;
+
+ *offset += count * sizeof(unsigned int);
+ }
+ }
+ return qwords;
+}
+
void a6xx_crashdump_init(struct adreno_device *adreno_dev)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
@@ -1713,6 +1873,26 @@
}
}
+ /*
+ * Calculate the script and data size for non context debug
+ * AHB registers
+ */
+ for (i = 0; i < ARRAY_SIZE(a6xx_non_ctx_dbgahb); i++) {
+ struct a6xx_non_ctx_dbgahb_registers *regs =
+ &a6xx_non_ctx_dbgahb[i];
+
+ /* 16 bytes for programming the aperture */
+ script_size += 16;
+
+ /* Reading each pair of registers takes 16 bytes */
+ script_size += 16 * regs->num_sets;
+
+ /* A dword per register read from the cluster list */
+ for (k = 0; k < regs->num_sets; k++)
+ data_size += REG_PAIR_COUNT(regs->regs, k) *
+ sizeof(unsigned int);
+ }
+
/* Now allocate the script and data buffers */
/* The script buffers needs 2 extra qwords on the end */
@@ -1763,6 +1943,8 @@
ptr += _a6xx_crashdump_init_ctx_dbgahb(ptr, &offset);
+ ptr += _a6xx_crashdump_init_non_ctx_dbgahb(ptr, &offset);
+
*ptr++ = 0;
*ptr++ = 0;
}
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index b81be8f..6876796 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -424,16 +424,6 @@
return ERR_PTR(ret);
}
- if (gpudev->preemption_context_init) {
- ret = gpudev->preemption_context_init(&drawctxt->base);
- if (ret != 0) {
- kgsl_context_detach(&drawctxt->base);
- kgsl_context_put(&drawctxt->base);
- kfree(drawctxt);
- return ERR_PTR(ret);
- }
- }
-
kgsl_sharedmem_writel(device, &device->memstore,
KGSL_MEMSTORE_OFFSET(drawctxt->base.id, soptimestamp),
0);
@@ -445,6 +435,14 @@
INIT_LIST_HEAD(&drawctxt->active_node);
+ if (gpudev->preemption_context_init) {
+ ret = gpudev->preemption_context_init(&drawctxt->base);
+ if (ret != 0) {
+ kgsl_context_detach(&drawctxt->base);
+ return ERR_PTR(ret);
+ }
+ }
+
/* copy back whatever flags we dediced were valid */
*flags = drawctxt->base.flags;
return &drawctxt->base;
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index ab3ab31..b354ef2 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -796,7 +796,7 @@
struct kgsl_iommu_context *ctx;
u64 ptbase;
u32 contextidr;
- pid_t tid = 0;
+ pid_t pid = 0;
pid_t ptname;
struct _mem_entry prev, next;
int write;
@@ -851,7 +851,7 @@
if (context != NULL) {
/* save pagefault timestamp for GFT */
set_bit(KGSL_CONTEXT_PRIV_PAGEFAULT, &context->priv);
- tid = context->tid;
+ pid = context->proc_priv->pid;
}
ctx->fault = 1;
@@ -872,7 +872,7 @@
contextidr = KGSL_IOMMU_GET_CTX_REG(ctx, CONTEXTIDR);
ptname = MMU_FEATURE(mmu, KGSL_MMU_GLOBAL_PAGETABLE) ?
- KGSL_MMU_GLOBAL_PT : tid;
+ KGSL_MMU_GLOBAL_PT : pid;
/*
* Trace needs to be logged before searching the faulting
* address in free list as it takes quite long time in
diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c
index 5bd52e4..1a2aea9 100644
--- a/drivers/leds/leds-qpnp-flash-v2.c
+++ b/drivers/leds/leds-qpnp-flash-v2.c
@@ -731,7 +731,8 @@
#define FLASH_VDIP_MARGIN 50000
#define BOB_EFFICIENCY 900LL
#define VIN_FLASH_MIN_UV 3300000LL
-static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led)
+static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led,
+ int *max_current)
{
int ocv_uv, ibat_now, voltage_hdrm_mv, rc;
int rbatt_uohm = 0;
@@ -747,8 +748,10 @@
}
/* If no battery is connected, return max possible flash current */
- if (!rbatt_uohm)
- return FLASH_LED_MAX_TOTAL_CURRENT_MA;
+ if (!rbatt_uohm) {
+ *max_current = FLASH_LED_MAX_TOTAL_CURRENT_MA;
+ return 0;
+ }
rc = get_property_from_fg(led, POWER_SUPPLY_PROP_VOLTAGE_OCV, &ocv_uv);
if (rc < 0) {
@@ -785,7 +788,7 @@
/* Wait for LMH mitigation to take effect */
udelay(100);
- return qpnp_flash_led_calc_max_current(led);
+ return qpnp_flash_led_calc_max_current(led, max_current);
}
/*
@@ -825,13 +828,14 @@
avail_flash_ua = div64_s64(avail_flash_power_fw, vin_flash_uv * MCONV);
pr_debug("avail_iflash=%lld, ocv=%d, ibat=%d, rbatt=%d, trigger_lmh=%d\n",
avail_flash_ua, ocv_uv, ibat_now, rbatt_uohm, led->trigger_lmh);
- return min(FLASH_LED_MAX_TOTAL_CURRENT_MA,
+ *max_current = min(FLASH_LED_MAX_TOTAL_CURRENT_MA,
(int)(div64_s64(avail_flash_ua, MCONV)));
+ return 0;
}
-static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led)
+static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led,
+ int *thermal_current_lim)
{
- int thermal_current_lim = 0;
int rc;
u8 thermal_thrsh1, thermal_thrsh2, thermal_thrsh3, otst_status;
@@ -888,7 +892,7 @@
/* Look up current limit based on THERMAL_OTST status */
if (otst_status)
- thermal_current_lim =
+ *thermal_current_lim =
led->pdata->thermal_derate_current[otst_status >> 1];
/* Restore THERMAL_THRESHx registers to original values */
@@ -913,23 +917,36 @@
if (rc < 0)
return rc;
- return thermal_current_lim;
+ return 0;
}
-static int qpnp_flash_led_get_max_avail_current(struct qpnp_flash_led *led)
+static int qpnp_flash_led_get_max_avail_current(struct qpnp_flash_led *led,
+ int *max_avail_current)
{
- int max_avail_current, thermal_current_lim = 0;
+ int thermal_current_lim = 0, rc;
led->trigger_lmh = false;
- max_avail_current = qpnp_flash_led_calc_max_current(led);
- if (led->pdata->thermal_derate_en)
- thermal_current_lim =
- qpnp_flash_led_calc_thermal_current_lim(led);
+ rc = qpnp_flash_led_calc_max_current(led, max_avail_current);
+ if (rc < 0) {
+ pr_err("Couldn't calculate max_avail_current, rc=%d\n", rc);
+ return rc;
+ }
+
+ if (led->pdata->thermal_derate_en) {
+ rc = qpnp_flash_led_calc_thermal_current_lim(led,
+ &thermal_current_lim);
+ if (rc < 0) {
+ pr_err("Couldn't calculate thermal_current_lim, rc=%d\n",
+ rc);
+ return rc;
+ }
+ }
if (thermal_current_lim)
- max_avail_current = min(max_avail_current, thermal_current_lim);
+ *max_avail_current = min(*max_avail_current,
+ thermal_current_lim);
- return max_avail_current;
+ return 0;
}
static void qpnp_flash_led_aggregate_max_current(struct flash_node_data *fnode)
@@ -1237,12 +1254,11 @@
}
if (options & QUERY_MAX_CURRENT) {
- rc = qpnp_flash_led_get_max_avail_current(led);
+ rc = qpnp_flash_led_get_max_avail_current(led, max_current);
if (rc < 0) {
pr_err("query max current failed, rc=%d\n", rc);
return rc;
}
- *max_current = rc;
}
return 0;
@@ -1291,7 +1307,7 @@
static ssize_t qpnp_flash_led_max_current_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- int rc;
+ int rc, max_current = 0;
struct flash_switch_data *snode;
struct qpnp_flash_led *led;
struct led_classdev *led_cdev = dev_get_drvdata(dev);
@@ -1299,11 +1315,11 @@
snode = container_of(led_cdev, struct flash_switch_data, cdev);
led = dev_get_drvdata(&snode->pdev->dev);
- rc = qpnp_flash_led_get_max_avail_current(led);
+ rc = qpnp_flash_led_get_max_avail_current(led, &max_current);
if (rc < 0)
pr_err("query max current failed, rc=%d\n", rc);
- return snprintf(buf, PAGE_SIZE, "%d\n", rc);
+ return snprintf(buf, PAGE_SIZE, "%d\n", max_current);
}
/* sysfs attributes exported by flash_led */
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index 9dc85cd..620cc7e 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -53,17 +53,16 @@
return idx;
}
-static void msg_submit(struct mbox_chan *chan)
+static int __msg_submit(struct mbox_chan *chan)
{
unsigned count, idx;
unsigned long flags;
void *data;
int err = -EBUSY;
-again:
spin_lock_irqsave(&chan->lock, flags);
- if (!chan->msg_count || (chan->active_req && err != -EAGAIN))
+ if (!chan->msg_count || chan->active_req)
goto exit;
count = chan->msg_count;
@@ -86,15 +85,23 @@
exit:
spin_unlock_irqrestore(&chan->lock, flags);
+ return err;
+}
+
+static void msg_submit(struct mbox_chan *chan)
+{
+ int err = 0;
+
/*
* If the controller returns -EAGAIN, then it means, our spinlock
* here is preventing the controller from receiving its interrupt,
* that would help clear the controller channels that are currently
* blocked waiting on the interrupt response.
- * Unlock and retry again.
+ * Retry again.
*/
- if (err == -EAGAIN)
- goto again;
+ do {
+ err = __msg_submit(chan);
+ } while (err == -EAGAIN);
if (!err && (chan->txdone_method & TXDONE_BY_POLL))
/* kick start the timer immediately to avoid delays */
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index ba49f24..7bb6d89 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -2274,11 +2274,8 @@
struct hal_frame_size blur_res;
struct hal_quantization_range qp_range;
struct hal_quantization qp;
- struct hal_hdr10_pq_sei hdr10_sei_params;
- struct msm_vidc_mastering_display_colour_sei_payload *mdisp_sei
- = &(hdr10_sei_params.disp_color_sei);
- struct msm_vidc_content_light_level_sei_payload *cll_sei
- = &(hdr10_sei_params.cll_sei);
+ struct msm_vidc_mastering_display_colour_sei_payload *mdisp_sei = NULL;
+ struct msm_vidc_content_light_level_sei_payload *cll_sei = NULL;
if (!inst || !inst->core || !inst->core->device || !ctrl) {
dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
@@ -2293,6 +2290,9 @@
control = ctrl->controls;
+ mdisp_sei = &(inst->hdr10_sei_params.disp_color_sei);
+ cll_sei = &(inst->hdr10_sei_params.cll_sei);
+
for (i = 0; i < ctrl->count; i++) {
switch (control[i].id) {
case V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE:
@@ -2429,9 +2429,9 @@
break;
case V4L2_CID_MPEG_VIDC_VENC_HDR_INFO:
if (control[i].value ==
- V4L2_MPEG_VIDC_VENC_HDR_INFO_DISABLED)
+ V4L2_MPEG_VIDC_VENC_HDR_INFO_DISABLED ||
+ !mdisp_sei || !cll_sei)
break;
- memset(&hdr10_sei_params, 0, sizeof(hdr10_sei_params));
i++;
while (i < ctrl->count) {
switch (control[i].id) {
@@ -2494,7 +2494,7 @@
}
property_id =
HAL_PARAM_VENC_HDR10_PQ_SEI;
- pdata = &hdr10_sei_params;
+ pdata = &inst->hdr10_sei_params;
break;
default:
dprintk(VIDC_ERR, "Invalid id set: %d\n",
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
index 1d22077..dc9302e 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
@@ -640,8 +640,8 @@
else if (temp->clk_data.core_id == VIDC_CORE_ID_2)
freq_core_2 += temp->clk_data.min_freq;
else if (temp->clk_data.core_id == VIDC_CORE_ID_3) {
- freq_core_1 += temp->clk_data.min_freq / 2;
- freq_core_2 += temp->clk_data.min_freq / 2;
+ freq_core_1 += temp->clk_data.min_freq;
+ freq_core_2 += temp->clk_data.min_freq;
}
freq_core_max = max_t(unsigned long, freq_core_1, freq_core_2);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 4c000b7..7d4e4a1 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -5488,8 +5488,9 @@
input_height = inst->prop.height[OUTPUT_PORT];
input_width = inst->prop.width[OUTPUT_PORT];
- if (input_width % 2 != 0 || input_height % 2 != 0 ||
- output_width % 2 != 0 || output_height % 2 != 0) {
+ if (inst->session_type == MSM_VIDC_ENCODER && (input_width % 2 != 0 ||
+ input_height % 2 != 0 || output_width % 2 != 0 ||
+ output_height % 2 != 0)) {
dprintk(VIDC_ERR,
"Height and Width should be even numbers for NV12\n");
dprintk(VIDC_ERR,
@@ -5682,7 +5683,7 @@
handle = msm_smem_get_handle(inst->mem_client, dma_buf);
offset = b->m.planes[i].data_offset;
- size = b->m.planes[i].length;
+ size = b->m.planes[i].length - offset;
cache_ops = SMEM_CACHE_INVALIDATE;
skip = false;
@@ -5751,7 +5752,7 @@
handle = msm_smem_get_handle(inst->mem_client, dma_buf);
offset = b->m.planes[i].data_offset;
- size = b->m.planes[i].length;
+ size = b->m.planes[i].length - offset;
cache_ops = SMEM_CACHE_INVALIDATE;
skip = false;
@@ -5771,8 +5772,15 @@
skip = true;
} else if (b->type ==
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- if (!i) /* bitstream */
- skip = true;
+ if (!i) { /* bitstream */
+ /*
+ * Include vp8e header bytes as well
+ * by making offset equal to zero
+ */
+ offset = 0;
+ size = b->m.planes[i].bytesused +
+ b->m.planes[i].data_offset;
+ }
}
}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 0b6331c..98b5714 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -410,6 +410,7 @@
u32 level;
u32 entropy_mode;
struct msm_vidc_codec_data *codec_data;
+ struct hal_hdr10_pq_sei hdr10_sei_params;
};
extern struct msm_vidc_drv *vidc_driver;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_platform.c b/drivers/media/platform/msm/vidc/msm_vidc_platform.c
index d7641c3..c84490f 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_platform.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_platform.c
@@ -199,11 +199,11 @@
},
{
.key = "qcom,power-collapse-delay",
- .value = 500,
+ .value = 1500,
},
{
.key = "qcom,hw-resp-timeout",
- .value = 250,
+ .value = 1000,
},
};
@@ -250,11 +250,11 @@
},
{
.key = "qcom,power-collapse-delay",
- .value = 500,
+ .value = 1500,
},
{
.key = "qcom,hw-resp-timeout",
- .value = 250,
+ .value = 1000,
},
};
diff --git a/drivers/platform/msm/msm_11ad/msm_11ad.c b/drivers/platform/msm/msm_11ad/msm_11ad.c
index 4c0b38d..4c0531f 100644
--- a/drivers/platform/msm/msm_11ad/msm_11ad.c
+++ b/drivers/platform/msm/msm_11ad/msm_11ad.c
@@ -33,16 +33,14 @@
#include "wil_platform.h"
#include "msm_11ad.h"
-#define WIGIG_VENDOR (0x1ae9)
-#define WIGIG_DEVICE (0x0310)
-
#define SMMU_BASE 0x20000000 /* Device address range base */
#define SMMU_SIZE ((SZ_1G * 4ULL) - SMMU_BASE)
#define WIGIG_ENABLE_DELAY 50
#define WIGIG_SUBSYS_NAME "WIGIG"
-#define WIGIG_RAMDUMP_SIZE 0x200000 /* maximum ramdump size */
+#define WIGIG_RAMDUMP_SIZE_SPARROW 0x200000 /* maximum ramdump size */
+#define WIGIG_RAMDUMP_SIZE_TALYN 0x400000 /* maximum ramdump size */
#define WIGIG_DUMP_FORMAT_VER 0x1
#define WIGIG_DUMP_MAGIC_VER_V1 0x57474947
#define VDD_MIN_UV 1028000
@@ -61,6 +59,18 @@
static const char * const gpio_en_name = "qcom,wigig-en";
static const char * const sleep_clk_en_name = "qcom,sleep-clk-en";
+struct wigig_pci {
+ struct pci_device_id pci_dev;
+ u32 ramdump_sz;
+};
+
+static const struct wigig_pci wigig_pci_tbl[] = {
+ { .pci_dev = { PCI_DEVICE(0x1ae9, 0x0310) },
+ .ramdump_sz = WIGIG_RAMDUMP_SIZE_SPARROW},
+ { .pci_dev = { PCI_DEVICE(0x17cb, 0x1201) },
+ .ramdump_sz = WIGIG_RAMDUMP_SIZE_TALYN},
+};
+
struct msm11ad_vreg {
const char *name;
struct regulator *reg;
@@ -113,6 +123,7 @@
void *ramdump_addr;
struct msm_dump_data dump_data;
struct ramdump_device *ramdump_dev;
+ u32 ramdump_size;
/* external vregs and clocks */
struct msm11ad_vreg vdd;
@@ -859,7 +870,7 @@
{
if (ctx->rops.ramdump && ctx->wil_handle) {
int rc = ctx->rops.ramdump(ctx->wil_handle, ctx->ramdump_addr,
- WIGIG_RAMDUMP_SIZE);
+ ctx->ramdump_size);
if (rc) {
dev_err(ctx->dev, "ramdump failed : %d\n", rc);
return -EINVAL;
@@ -898,7 +909,7 @@
memset(&segment, 0, sizeof(segment));
segment.v_address = ctx->ramdump_addr;
- segment.size = WIGIG_RAMDUMP_SIZE;
+ segment.size = ctx->ramdump_size;
return do_ramdump(ctx->ramdump_dev, &segment, 1);
}
@@ -961,14 +972,14 @@
}
/* register ramdump area */
- ctx->ramdump_addr = kmalloc(WIGIG_RAMDUMP_SIZE, GFP_KERNEL);
+ ctx->ramdump_addr = kmalloc(ctx->ramdump_size, GFP_KERNEL);
if (!ctx->ramdump_addr) {
rc = -ENOMEM;
goto out_rc;
}
ctx->dump_data.addr = virt_to_phys(ctx->ramdump_addr);
- ctx->dump_data.len = WIGIG_RAMDUMP_SIZE;
+ ctx->dump_data.len = ctx->ramdump_size;
dump_entry.id = MSM_DUMP_DATA_WIGIG;
dump_entry.addr = virt_to_phys(&ctx->dump_data);
@@ -1031,8 +1042,9 @@
struct device_node *rc_node;
struct pci_dev *pcidev = NULL;
u32 smmu_mapping[2];
- int rc;
+ int rc, i;
u32 val;
+ bool pcidev_found = false;
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
@@ -1161,21 +1173,32 @@
goto out_rc;
}
/* search for PCIE device in our domain */
- do {
- pcidev = pci_get_device(WIGIG_VENDOR, WIGIG_DEVICE, pcidev);
- if (!pcidev)
- break;
+ for (i = 0; i < ARRAY_SIZE(wigig_pci_tbl); ++i) {
+ do {
+ pcidev = pci_get_device(wigig_pci_tbl[i].pci_dev.vendor,
+ wigig_pci_tbl[i].pci_dev.device,
+ pcidev);
+ if (!pcidev)
+ break;
- if (pci_domain_nr(pcidev->bus) == ctx->rc_index)
+ if (pci_domain_nr(pcidev->bus) == ctx->rc_index) {
+ ctx->ramdump_size = wigig_pci_tbl[i].ramdump_sz;
+ pcidev_found = true;
+ break;
+ }
+ } while (true);
+
+ if (pcidev_found)
break;
- } while (true);
- if (!pcidev) {
+ }
+ if (!pcidev_found) {
rc = -ENODEV;
- dev_err(ctx->dev, "Wigig device %4x:%4x not found\n",
- WIGIG_VENDOR, WIGIG_DEVICE);
+ dev_err(ctx->dev, "Wigig device not found\n");
goto out_rc;
}
ctx->pcidev = pcidev;
+ dev_dbg(ctx->dev, "Wigig device %4x:%4x found\n",
+ ctx->pcidev->vendor, ctx->pcidev->device);
rc = msm_pcie_pm_control(MSM_PCIE_RESUME, pcidev->bus->number,
pcidev, NULL, 0);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index e463117..1f60635 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -4184,6 +4184,7 @@
debugfs_remove_recursive(rdev->debugfs);
if (rdev->debug_consumer)
rdev->debug_consumer->debugfs = NULL;
+ rdev->debugfs = NULL;
regulator_put(rdev->debug_consumer);
}
}
@@ -4225,9 +4226,10 @@
regulator = regulator_get(NULL, rdev_get_name(rdev));
if (IS_ERR(regulator)) {
- debugfs_remove_recursive(rdev->debugfs);
- rdev_err(rdev, "regulator get failed, ret=%ld\n",
- PTR_ERR(regulator));
+ rdev_deinit_debugfs(rdev);
+ if (PTR_ERR(regulator) != -EPROBE_DEFER)
+ rdev_err(rdev, "regulator get failed, ret=%ld\n",
+ PTR_ERR(regulator));
return;
}
rdev->debug_consumer = regulator;
diff --git a/drivers/soc/qcom/peripheral-loader.c b/drivers/soc/qcom/peripheral-loader.c
index 9d22925..e0df954 100644
--- a/drivers/soc/qcom/peripheral-loader.c
+++ b/drivers/soc/qcom/peripheral-loader.c
@@ -511,11 +511,12 @@
}
static int pil_alloc_region(struct pil_priv *priv, phys_addr_t min_addr,
- phys_addr_t max_addr, size_t align)
+ phys_addr_t max_addr, size_t align,
+ size_t mdt_size)
{
void *region;
size_t size = max_addr - min_addr;
- size_t aligned_size;
+ size_t aligned_size = max(size, mdt_size);
/* Don't reallocate due to fragmentation concerns, just sanity check */
if (priv->region) {
@@ -526,9 +527,11 @@
}
if (align > SZ_4M)
- aligned_size = ALIGN(size, SZ_4M);
+ aligned_size = ALIGN(aligned_size, SZ_4M);
+ else if (align > SZ_1M)
+ aligned_size = ALIGN(aligned_size, SZ_1M);
else
- aligned_size = ALIGN(size, SZ_1M);
+ aligned_size = ALIGN(aligned_size, SZ_4K);
priv->desc->attrs = 0;
priv->desc->attrs |= DMA_ATTR_SKIP_ZEROING | DMA_ATTR_NO_KERNEL_MAPPING;
@@ -553,7 +556,8 @@
return 0;
}
-static int pil_setup_region(struct pil_priv *priv, const struct pil_mdt *mdt)
+static int pil_setup_region(struct pil_priv *priv, const struct pil_mdt *mdt,
+ size_t mdt_size)
{
const struct elf32_phdr *phdr;
phys_addr_t min_addr_r, min_addr_n, max_addr_r, max_addr_n, start, end;
@@ -598,7 +602,8 @@
max_addr_r = ALIGN(max_addr_r, SZ_4K);
if (relocatable) {
- ret = pil_alloc_region(priv, min_addr_r, max_addr_r, align);
+ ret = pil_alloc_region(priv, min_addr_r, max_addr_r, align,
+ mdt_size);
} else {
priv->region_start = min_addr_n;
priv->region_end = max_addr_n;
@@ -629,14 +634,15 @@
return ret;
}
-static int pil_init_mmap(struct pil_desc *desc, const struct pil_mdt *mdt)
+static int pil_init_mmap(struct pil_desc *desc, const struct pil_mdt *mdt,
+ size_t mdt_size)
{
struct pil_priv *priv = desc->priv;
const struct elf32_phdr *phdr;
struct pil_seg *seg;
int i, ret;
- ret = pil_setup_region(priv, mdt);
+ ret = pil_setup_region(priv, mdt, mdt_size);
if (ret)
return ret;
@@ -922,7 +928,7 @@
goto release_fw;
}
- ret = pil_init_mmap(desc, mdt);
+ ret = pil_init_mmap(desc, mdt, fw->size);
if (ret)
goto release_fw;
@@ -935,7 +941,8 @@
trace_pil_event("before_init_image", desc);
if (desc->ops->init_image)
- ret = desc->ops->init_image(desc, fw->data, fw->size);
+ ret = desc->ops->init_image(desc, fw->data, fw->size,
+ priv->region_start, priv->region);
if (ret) {
pil_err(desc, "Initializing image failed(rc:%d)\n", ret);
goto err_boot;
diff --git a/drivers/soc/qcom/peripheral-loader.h b/drivers/soc/qcom/peripheral-loader.h
index f09adf5..27ed336 100644
--- a/drivers/soc/qcom/peripheral-loader.h
+++ b/drivers/soc/qcom/peripheral-loader.h
@@ -119,7 +119,7 @@
*/
struct pil_reset_ops {
int (*init_image)(struct pil_desc *pil, const u8 *metadata,
- size_t size);
+ size_t size, phys_addr_t mdata_phys, void *region);
int (*mem_setup)(struct pil_desc *pil, phys_addr_t addr, size_t size);
int (*verify_blob)(struct pil_desc *pil, phys_addr_t phy_addr,
size_t size);
diff --git a/drivers/soc/qcom/pil-msa.c b/drivers/soc/qcom/pil-msa.c
index a3eb551..ce31d66 100644
--- a/drivers/soc/qcom/pil-msa.c
+++ b/drivers/soc/qcom/pil-msa.c
@@ -769,7 +769,8 @@
}
static int pil_msa_auth_modem_mdt(struct pil_desc *pil, const u8 *metadata,
- size_t size)
+ size_t size, phys_addr_t region_start,
+ void *region)
{
struct modem_data *drv = dev_get_drvdata(pil->dev);
void *mdata_virt;
@@ -851,7 +852,8 @@
}
static int pil_msa_mss_reset_mba_load_auth_mdt(struct pil_desc *pil,
- const u8 *metadata, size_t size)
+ const u8 *metadata, size_t size,
+ phys_addr_t region_start, void *region)
{
int ret;
@@ -859,7 +861,8 @@
if (ret)
return ret;
- return pil_msa_auth_modem_mdt(pil, metadata, size);
+ return pil_msa_auth_modem_mdt(pil, metadata, size, region_start,
+ region);
}
static int pil_msa_mba_verify_blob(struct pil_desc *pil, phys_addr_t phy_addr,
diff --git a/drivers/soc/qcom/subsys-pil-tz.c b/drivers/soc/qcom/subsys-pil-tz.c
index 01b4790..d3819b6 100644
--- a/drivers/soc/qcom/subsys-pil-tz.c
+++ b/drivers/soc/qcom/subsys-pil-tz.c
@@ -47,6 +47,13 @@
#define desc_to_data(d) container_of(d, struct pil_tz_data, desc)
#define subsys_to_data(d) container_of(d, struct pil_tz_data, subsys_desc)
+struct pil_map_fw_info {
+ void *region;
+ unsigned long attrs;
+ phys_addr_t base_addr;
+ struct device *dev;
+};
+
/**
* struct reg_info - regulator info
* @reg: regulator handle
@@ -586,7 +593,8 @@
}
static int pil_init_image_trusted(struct pil_desc *pil,
- const u8 *metadata, size_t size)
+ const u8 *metadata, size_t size, phys_addr_t mdata_phys,
+ void *region)
{
struct pil_tz_data *d = desc_to_data(pil);
struct pas_init_image_req {
@@ -595,11 +603,15 @@
} request;
u32 scm_ret = 0;
void *mdata_buf;
- dma_addr_t mdata_phys;
int ret;
- unsigned long attrs = 0;
- struct device dev = {0};
struct scm_desc desc = {0};
+ struct pil_map_fw_info map_fw_info = {
+ .attrs = pil->attrs,
+ .region = region,
+ .base_addr = mdata_phys,
+ .dev = pil->dev,
+ };
+ void *map_data = pil->map_data ? pil->map_data : &map_fw_info;
if (d->subsys_desc.no_auth)
return 0;
@@ -607,15 +619,10 @@
ret = scm_pas_enable_bw();
if (ret)
return ret;
- arch_setup_dma_ops(&dev, 0, 0, NULL, 0);
- dev.coherent_dma_mask =
- DMA_BIT_MASK(sizeof(dma_addr_t) * 8);
- attrs |= DMA_ATTR_STRONGLY_ORDERED;
- mdata_buf = dma_alloc_attrs(&dev, size, &mdata_phys, GFP_KERNEL,
- attrs);
+ mdata_buf = pil->map_fw_mem(mdata_phys, size, map_data);
if (!mdata_buf) {
- pr_err("scm-pas: Allocation for metadata failed.\n");
+ dev_err(pil->dev, "Failed to map memory for metadata.\n");
scm_pas_disable_bw();
return -ENOMEM;
}
@@ -637,7 +644,7 @@
scm_ret = desc.ret[0];
}
- dma_free_attrs(&dev, size, mdata_buf, mdata_phys, attrs);
+ pil->unmap_fw_mem(mdata_buf, size, map_data);
scm_pas_disable_bw();
if (ret)
return ret;
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 874499d..3b92db9 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -3989,7 +3989,10 @@
psy_type = get_psy_type(mdwc);
if (psy_type == POWER_SUPPLY_TYPE_USB_FLOAT) {
- pval.intval = -ETIMEDOUT;
+ if (!mA)
+ pval.intval = -ETIMEDOUT;
+ else
+ pval.intval = 1000 * mA;
goto set_prop;
}
diff --git a/drivers/usb/gadget/function/f_gsi.h b/drivers/usb/gadget/function/f_gsi.h
index bdd0dfa..295f681 100644
--- a/drivers/usb/gadget/function/f_gsi.h
+++ b/drivers/usb/gadget/function/f_gsi.h
@@ -572,7 +572,7 @@
static struct usb_endpoint_descriptor rndis_gsi_fs_in_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
-
+ .wMaxPacketSize = cpu_to_le16(64),
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
@@ -580,7 +580,7 @@
static struct usb_endpoint_descriptor rndis_gsi_fs_out_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
-
+ .wMaxPacketSize = cpu_to_le16(64),
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
diff --git a/drivers/usb/gadget/function/f_mtp.c b/drivers/usb/gadget/function/f_mtp.c
index aea32e4..239d9bf 100644
--- a/drivers/usb/gadget/function/f_mtp.c
+++ b/drivers/usb/gadget/function/f_mtp.c
@@ -1464,6 +1464,7 @@
mtp_ss_out_comp_desc.bMaxBurst = max_burst;
}
+ fi_mtp->func_inst.f = &dev->function;
DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
gadget_is_superspeed(c->cdev->gadget) ? "super" :
(gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full"),
@@ -1475,9 +1476,10 @@
mtp_function_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct mtp_dev *dev = func_to_mtp(f);
+ struct mtp_instance *fi_mtp;
struct usb_request *req;
int i;
-
+ fi_mtp = container_of(f->fi, struct mtp_instance, func_inst);
mtp_string_defs[INTERFACE_STRING_INDEX].id = 0;
mutex_lock(&dev->read_mutex);
while ((req = mtp_req_get(dev, &dev->tx_idle)))
@@ -1490,6 +1492,7 @@
dev->state = STATE_OFFLINE;
kfree(f->os_desc_table);
f->os_desc_n = 0;
+ fi_mtp->func_inst.f = NULL;
}
static int mtp_function_set_alt(struct usb_function *f,
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 5434902..643e087 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -23,6 +23,7 @@
#include <linux/gfp.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
+#include <linux/usb/phy.h>
#include "xhci.h"
#include "xhci-trace.h"
@@ -1065,6 +1066,7 @@
u16 wake_mask = 0;
u16 timeout = 0;
u16 test_mode = 0;
+ enum usb_device_speed s = hcd->self.root_hub->speed;
max_ports = xhci_get_ports(hcd, &port_array);
bus_state = &xhci->bus_state[hcd_index(hcd)];
@@ -1314,6 +1316,10 @@
writel(temp, port_array[wIndex]);
temp = readl(port_array[wIndex]);
+
+ if (s == USB_SPEED_HIGH)
+ usb_phy_start_port_reset(hcd->usb_phy);
+
xhci_dbg(xhci, "set port reset, actual port %d status = 0x%x\n", wIndex, temp);
break;
case USB_PORT_FEAT_REMOTE_WAKE_MASK:
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ab3633c..ae8a727 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -138,7 +138,13 @@
{
u32 temp;
int ret;
+ struct usb_hcd *hcd = xhci_to_hcd(xhci);
+ /*
+ * disable irq to avoid xhci_irq flooding due to unhandeled port
+ * change event in halt state, as soon as xhci_start clears halt bit
+ */
+ disable_irq(hcd->irq);
temp = readl(&xhci->op_regs->command);
temp |= (CMD_RUN);
xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Turn on HC, cmd = 0x%x.",
@@ -159,6 +165,8 @@
/* clear state flags. Including dying, halted or removing */
xhci->xhc_state = 0;
+ enable_irq(hcd->irq);
+
return ret;
}
diff --git a/drivers/usb/phy/phy-msm-qusb-v2.c b/drivers/usb/phy/phy-msm-qusb-v2.c
index 81c39a3..cce17e0 100644
--- a/drivers/usb/phy/phy-msm-qusb-v2.c
+++ b/drivers/usb/phy/phy-msm-qusb-v2.c
@@ -27,6 +27,7 @@
#include <linux/usb/phy.h>
#include <linux/reset.h>
#include <linux/debugfs.h>
+#include <linux/hrtimer.h>
/* QUSB2PHY_PWR_CTRL1 register related bits */
#define PWR_CTRL1_POWR_DOWN BIT(0)
@@ -126,6 +127,10 @@
u32 sq_ctrl2_default;
bool chirp_disable;
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *atest_usb13_suspend;
+ struct pinctrl_state *atest_usb13_active;
+
/* emulation targets specific */
void __iomem *emu_phy_base;
bool emulation;
@@ -139,6 +144,8 @@
/* override TUNEX registers value */
struct dentry *root;
u8 tune[5];
+
+ struct hrtimer timer;
};
static void qusb_phy_enable_clocks(struct qusb_phy *qphy, bool on)
@@ -511,6 +518,42 @@
return 0;
}
+static enum hrtimer_restart qusb_dis_ext_pulldown_timer(struct hrtimer *timer)
+{
+ struct qusb_phy *qphy = container_of(timer, struct qusb_phy, timer);
+ int ret = 0;
+
+ if (qphy->pinctrl && qphy->atest_usb13_suspend) {
+ ret = pinctrl_select_state(qphy->pinctrl,
+ qphy->atest_usb13_suspend);
+ if (ret < 0)
+ dev_err(qphy->phy.dev,
+ "pinctrl state suspend select failed\n");
+ }
+
+ return HRTIMER_NORESTART;
+}
+
+static void qusb_phy_enable_ext_pulldown(struct usb_phy *phy)
+{
+ struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
+ int ret = 0;
+
+ dev_dbg(phy->dev, "%s\n", __func__);
+
+ if (qphy->pinctrl && qphy->atest_usb13_active) {
+ ret = pinctrl_select_state(qphy->pinctrl,
+ qphy->atest_usb13_active);
+ if (ret < 0) {
+ dev_err(phy->dev,
+ "pinctrl state active select failed\n");
+ return;
+ }
+
+ hrtimer_start(&qphy->timer, ms_to_ktime(10), HRTIMER_MODE_REL);
+ }
+}
+
static void qusb_phy_shutdown(struct usb_phy *phy)
{
struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
@@ -1082,6 +1125,30 @@
return PTR_ERR(qphy->vdda18);
}
+ qphy->pinctrl = devm_pinctrl_get(dev);
+ if (IS_ERR(qphy->pinctrl)) {
+ ret = PTR_ERR(qphy->pinctrl);
+ if (ret == -EPROBE_DEFER)
+ return ret;
+ dev_err(dev, "pinctrl not available\n");
+ goto skip_pinctrl_config;
+ }
+ qphy->atest_usb13_suspend = pinctrl_lookup_state(qphy->pinctrl,
+ "atest_usb13_suspend");
+ if (IS_ERR(qphy->atest_usb13_suspend)) {
+ dev_err(dev, "pinctrl lookup atest_usb13_suspend failed\n");
+ goto skip_pinctrl_config;
+ }
+
+ qphy->atest_usb13_active = pinctrl_lookup_state(qphy->pinctrl,
+ "atest_usb13_active");
+ if (IS_ERR(qphy->atest_usb13_active))
+ dev_err(dev, "pinctrl lookup atest_usb13_active failed\n");
+
+ hrtimer_init(&qphy->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ qphy->timer.function = qusb_dis_ext_pulldown_timer;
+
+skip_pinctrl_config:
mutex_init(&qphy->lock);
platform_set_drvdata(pdev, qphy);
@@ -1093,6 +1160,7 @@
qphy->phy.notify_connect = qusb_phy_notify_connect;
qphy->phy.notify_disconnect = qusb_phy_notify_disconnect;
qphy->phy.disable_chirp = qusb_phy_disable_chirp;
+ qphy->phy.start_port_reset = qusb_phy_enable_ext_pulldown;
ret = usb_add_phy_dev(&qphy->phy);
if (ret)
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 7d4b557..6cb3a8c 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -276,11 +276,11 @@
goto loop;
end_loop:
- write_unlock(&journal->j_state_lock);
del_timer_sync(&journal->j_commit_timer);
journal->j_task = NULL;
wake_up(&journal->j_wait_done_commit);
jbd_debug(1, "Journal thread exiting.\n");
+ write_unlock(&journal->j_state_lock);
return 0;
}
diff --git a/include/dt-bindings/clock/qcom,gcc-sdxpoorwills.h b/include/dt-bindings/clock/qcom,gcc-sdxpoorwills.h
index 950811f..7e1394c 100644
--- a/include/dt-bindings/clock/qcom,gcc-sdxpoorwills.h
+++ b/include/dt-bindings/clock/qcom,gcc-sdxpoorwills.h
@@ -65,43 +65,44 @@
#define GCC_MSS_CFG_AHB_CLK 47
#define GCC_MSS_GPLL0_DIV_CLK_SRC 48
#define GCC_MSS_SNOC_AXI_CLK 49
-#define GCC_PCIE_AUX_CLK 50
-#define GCC_PCIE_AUX_PHY_CLK_SRC 51
-#define GCC_PCIE_CFG_AHB_CLK 52
-#define GCC_PCIE_MSTR_AXI_CLK 53
-#define GCC_PCIE_PHY_REFGEN_CLK 54
-#define GCC_PCIE_PHY_REFGEN_CLK_SRC 55
-#define GCC_PCIE_PIPE_CLK 56
-#define GCC_PCIE_SLEEP_CLK 57
-#define GCC_PCIE_SLV_AXI_CLK 58
-#define GCC_PCIE_SLV_Q2A_AXI_CLK 59
-#define GCC_PDM2_CLK 60
-#define GCC_PDM2_CLK_SRC 61
-#define GCC_PDM_AHB_CLK 62
-#define GCC_PDM_XO4_CLK 63
-#define GCC_PRNG_AHB_CLK 64
-#define GCC_SDCC1_AHB_CLK 65
-#define GCC_SDCC1_APPS_CLK 66
-#define GCC_SDCC1_APPS_CLK_SRC 67
-#define GCC_SPMI_FETCHER_AHB_CLK 68
-#define GCC_SPMI_FETCHER_CLK 69
-#define GCC_SPMI_FETCHER_CLK_SRC 70
-#define GCC_SYS_NOC_CPUSS_AHB_CLK 71
-#define GCC_SYS_NOC_USB3_CLK 72
-#define GCC_USB30_MASTER_CLK 73
-#define GCC_USB30_MASTER_CLK_SRC 74
-#define GCC_USB30_MOCK_UTMI_CLK 75
-#define GCC_USB30_MOCK_UTMI_CLK_SRC 76
-#define GCC_USB30_SLEEP_CLK 77
-#define GCC_USB3_PHY_AUX_CLK 78
-#define GCC_USB3_PHY_AUX_CLK_SRC 79
-#define GCC_USB3_PHY_PIPE_CLK 80
-#define GCC_USB_PHY_CFG_AHB2PHY_CLK 81
-#define GPLL0 82
-#define GPLL0_OUT_EVEN 83
-#define GPLL4 84
-#define GPLL4_OUT_EVEN 85
-#define GCC_USB3_PRIM_CLKREF_CLK 86
+#define GCC_PCIE_0_CLKREF_CLK 50
+#define GCC_PCIE_AUX_CLK 51
+#define GCC_PCIE_AUX_PHY_CLK_SRC 52
+#define GCC_PCIE_CFG_AHB_CLK 53
+#define GCC_PCIE_MSTR_AXI_CLK 54
+#define GCC_PCIE_PHY_REFGEN_CLK 55
+#define GCC_PCIE_PHY_REFGEN_CLK_SRC 56
+#define GCC_PCIE_PIPE_CLK 57
+#define GCC_PCIE_SLEEP_CLK 58
+#define GCC_PCIE_SLV_AXI_CLK 59
+#define GCC_PCIE_SLV_Q2A_AXI_CLK 60
+#define GCC_PDM2_CLK 61
+#define GCC_PDM2_CLK_SRC 62
+#define GCC_PDM_AHB_CLK 63
+#define GCC_PDM_XO4_CLK 64
+#define GCC_PRNG_AHB_CLK 65
+#define GCC_SDCC1_AHB_CLK 66
+#define GCC_SDCC1_APPS_CLK 67
+#define GCC_SDCC1_APPS_CLK_SRC 68
+#define GCC_SPMI_FETCHER_AHB_CLK 69
+#define GCC_SPMI_FETCHER_CLK 70
+#define GCC_SPMI_FETCHER_CLK_SRC 71
+#define GCC_SYS_NOC_CPUSS_AHB_CLK 72
+#define GCC_SYS_NOC_USB3_CLK 73
+#define GCC_USB30_MASTER_CLK 74
+#define GCC_USB30_MASTER_CLK_SRC 75
+#define GCC_USB30_MOCK_UTMI_CLK 76
+#define GCC_USB30_MOCK_UTMI_CLK_SRC 77
+#define GCC_USB30_SLEEP_CLK 78
+#define GCC_USB3_PHY_AUX_CLK 79
+#define GCC_USB3_PHY_AUX_CLK_SRC 80
+#define GCC_USB3_PHY_PIPE_CLK 81
+#define GCC_USB3_PRIM_CLKREF_CLK 82
+#define GCC_USB_PHY_CFG_AHB2PHY_CLK 83
+#define GPLL0 84
+#define GPLL0_OUT_EVEN 85
+#define GPLL4 86
+#define GPLL4_OUT_EVEN 87
/* CPU clocks */
#define CLOCK_A7SS 0
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 9b21e2a..907e029 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1164,8 +1164,6 @@
struct address_space *check_mapping; /* Check page->mapping if set */
pgoff_t first_index; /* Lowest page->index to unmap */
pgoff_t last_index; /* Highest page->index to unmap */
- bool ignore_dirty; /* Ignore dirty pages */
- bool check_swap_entries; /* Check also swap entries */
};
struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
diff --git a/include/linux/sde_rsc.h b/include/linux/sde_rsc.h
index cda2654..d2c1a95 100644
--- a/include/linux/sde_rsc.h
+++ b/include/linux/sde_rsc.h
@@ -186,6 +186,26 @@
int *wait_vblank_crtc_id);
/**
+ * sde_rsc_client_get_vsync_refcount() - returns the status of the vsync
+ * refcount, to signal if the client needs to reset the refcounting logic
+ * @client: Client pointer provided by sde_rsc_client_create().
+ *
+ * Return: true if the state update has completed.
+ */
+int sde_rsc_client_get_vsync_refcount(
+ struct sde_rsc_client *caller_client);
+
+/**
+ * sde_rsc_client_reset_vsync_refcount() - reduces the refcounting
+ * logic that waits for the vsync.
+ * @client: Client pointer provided by sde_rsc_client_create().
+ *
+ * Return: true if the state update has completed.
+ */
+int sde_rsc_client_reset_vsync_refcount(
+ struct sde_rsc_client *caller_client);
+
+/**
* sde_rsc_client_is_state_update_complete() - check if state update is complete
* RSC state transition is not complete until HW receives VBLANK signal. This
* function checks RSC HW to determine whether that signal has been received.
@@ -265,6 +285,18 @@
return 0;
}
+int sde_rsc_client_get_vsync_refcount(
+ struct sde_rsc_client *caller_client)
+{
+ return 0;
+}
+
+int sde_rsc_client_reset_vsync_refcount(
+ struct sde_rsc_client *caller_client)
+{
+ return 0;
+}
+
static inline bool sde_rsc_client_is_state_update_complete(
struct sde_rsc_client *caller_client)
{
diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h
index 092c32e..742ef8d 100644
--- a/include/linux/usb/phy.h
+++ b/include/linux/usb/phy.h
@@ -114,6 +114,8 @@
/* enable/disable VBUS */
int (*set_vbus)(struct usb_phy *x, int on);
+ /* callback to indicate port is being reset or reset the port */
+ void (*start_port_reset)(struct usb_phy *x);
/* effective for B devices, ignored for A-peripheral */
int (*set_power)(struct usb_phy *x,
@@ -213,6 +215,15 @@
return x->set_vbus(x, false);
}
+static inline void
+usb_phy_start_port_reset(struct usb_phy *x)
+{
+ if (!x || !x->start_port_reset)
+ return;
+
+ x->start_port_reset(x);
+}
+
static inline int
usb_phy_reset(struct usb_phy *x)
{
diff --git a/include/trace/events/oom.h b/include/trace/events/oom.h
index 1e97498..beddb19 100644
--- a/include/trace/events/oom.h
+++ b/include/trace/events/oom.h
@@ -27,6 +27,85 @@
__entry->pid, __entry->comm, __entry->oom_score_adj)
);
+TRACE_EVENT(mark_victim,
+ TP_PROTO(int pid),
+
+ TP_ARGS(pid),
+
+ TP_STRUCT__entry(
+ __field(int, pid)
+ ),
+
+ TP_fast_assign(
+ __entry->pid = pid;
+ ),
+
+ TP_printk("pid=%d", __entry->pid)
+);
+
+TRACE_EVENT(wake_reaper,
+ TP_PROTO(int pid),
+
+ TP_ARGS(pid),
+
+ TP_STRUCT__entry(
+ __field(int, pid)
+ ),
+
+ TP_fast_assign(
+ __entry->pid = pid;
+ ),
+
+ TP_printk("pid=%d", __entry->pid)
+);
+
+TRACE_EVENT(start_task_reaping,
+ TP_PROTO(int pid),
+
+ TP_ARGS(pid),
+
+ TP_STRUCT__entry(
+ __field(int, pid)
+ ),
+
+ TP_fast_assign(
+ __entry->pid = pid;
+ ),
+
+ TP_printk("pid=%d", __entry->pid)
+);
+
+TRACE_EVENT(finish_task_reaping,
+ TP_PROTO(int pid),
+
+ TP_ARGS(pid),
+
+ TP_STRUCT__entry(
+ __field(int, pid)
+ ),
+
+ TP_fast_assign(
+ __entry->pid = pid;
+ ),
+
+ TP_printk("pid=%d", __entry->pid)
+);
+
+TRACE_EVENT(skip_task_reaping,
+ TP_PROTO(int pid),
+
+ TP_ARGS(pid),
+
+ TP_STRUCT__entry(
+ __field(int, pid)
+ ),
+
+ TP_fast_assign(
+ __entry->pid = pid;
+ ),
+
+ TP_printk("pid=%d", __entry->pid)
+);
#endif
/* This part must be outside protection */
diff --git a/kernel/fork.c b/kernel/fork.c
index 610aded..b83adf9 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -879,7 +879,6 @@
}
if (mm->binfmt)
module_put(mm->binfmt->module);
- set_bit(MMF_OOM_SKIP, &mm->flags);
mmdrop(mm);
}
diff --git a/mm/internal.h b/mm/internal.h
index 0ee4f54..6aa1c51 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -41,6 +41,11 @@
void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
unsigned long floor, unsigned long ceiling);
+static inline bool can_madv_dontneed_vma(struct vm_area_struct *vma)
+{
+ return !(vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_PFNMAP));
+}
+
void unmap_page_range(struct mmu_gather *tlb,
struct vm_area_struct *vma,
unsigned long addr, unsigned long end,
diff --git a/mm/madvise.c b/mm/madvise.c
index 088a5b22..8b25167 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -25,6 +25,8 @@
#include <asm/tlb.h>
+#include "internal.h"
+
/*
* Any behaviour which results in changes to the vma->vm_flags needs to
* take mmap_sem for writing. Others, which simply traverse vmas, need
@@ -474,7 +476,7 @@
unsigned long start, unsigned long end)
{
*prev = vma;
- if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_PFNMAP))
+ if (!can_madv_dontneed_vma(vma))
return -EINVAL;
zap_page_range(vma, start, end - start, NULL);
diff --git a/mm/memory.c b/mm/memory.c
index 378ebc0..82d2000 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1154,12 +1154,6 @@
if (!PageAnon(page)) {
if (pte_dirty(ptent)) {
- /*
- * oom_reaper cannot tear down dirty
- * pages
- */
- if (unlikely(details && details->ignore_dirty))
- continue;
force_flush = 1;
set_page_dirty(page);
}
@@ -1179,8 +1173,8 @@
}
continue;
}
- /* only check swap_entries if explicitly asked for in details */
- if (unlikely(details && !details->check_swap_entries))
+ /* If details->check_mapping, we leave swap entries. */
+ if (unlikely(details))
continue;
entry = pte_to_swp_entry(ptent);
diff --git a/mm/mmap.c b/mm/mmap.c
index 6f90f07..7e6c049 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -44,6 +44,7 @@
#include <linux/userfaultfd_k.h>
#include <linux/moduleparam.h>
#include <linux/pkeys.h>
+#include <linux/oom.h>
#include <asm/uaccess.h>
#include <asm/cacheflush.h>
@@ -2983,6 +2984,23 @@
/* Use -1 here to ensure all VMAs in the mm are unmapped */
unmap_vmas(&tlb, vma, 0, -1);
+ set_bit(MMF_OOM_SKIP, &mm->flags);
+ if (unlikely(tsk_is_oom_victim(current))) {
+ /*
+ * Wait for oom_reap_task() to stop working on this
+ * mm. Because MMF_OOM_SKIP is already set before
+ * calling down_read(), oom_reap_task() will not run
+ * on this "mm" post up_write().
+ *
+ * tsk_is_oom_victim() cannot be set from under us
+ * either because current->mm is already set to NULL
+ * under task_lock before calling mmput and oom_mm is
+ * set not NULL by the OOM killer only if current->mm
+ * is found not NULL while holding the task_lock.
+ */
+ down_write(&mm->mmap_sem);
+ up_write(&mm->mmap_sem);
+ }
free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, USER_PGTABLES_CEILING);
tlb_finish_mmu(&tlb, 0, -1);
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 1f13413..af9a8a6 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -470,8 +470,6 @@
{
struct mmu_gather tlb;
struct vm_area_struct *vma;
- struct zap_details details = {.check_swap_entries = true,
- .ignore_dirty = true};
bool ret = true;
/*
@@ -492,6 +490,7 @@
if (!down_read_trylock(&mm->mmap_sem)) {
ret = false;
+ trace_skip_task_reaping(tsk->pid);
goto unlock_oom;
}
@@ -511,15 +510,19 @@
}
/*
- * increase mm_users only after we know we will reap something so
- * that the mmput_async is called only when we have reaped something
- * and delayed __mmput doesn't matter that much
+ * MMF_OOM_SKIP is set by exit_mmap when the OOM reaper can't
+ * work on the mm anymore. The check for MMF_OOM_SKIP must run
+ * under mmap_sem for reading because it serializes against the
+ * down_write();up_write() cycle in exit_mmap().
*/
- if (!mmget_not_zero(mm)) {
+ if (test_bit(MMF_OOM_SKIP, &mm->flags)) {
up_read(&mm->mmap_sem);
+ trace_skip_task_reaping(tsk->pid);
goto unlock_oom;
}
+ trace_start_task_reaping(tsk->pid);
+
/*
* Tell all users of get_user/copy_from_user etc... that the content
* is no longer stable. No barriers really needed because unmapping
@@ -528,16 +531,8 @@
*/
set_bit(MMF_UNSTABLE, &mm->flags);
- tlb_gather_mmu(&tlb, mm, 0, -1);
for (vma = mm->mmap ; vma; vma = vma->vm_next) {
- if (is_vm_hugetlb_page(vma))
- continue;
-
- /*
- * mlocked VMAs require explicit munlocking before unmap.
- * Let's keep it simple here and skip such VMAs.
- */
- if (vma->vm_flags & VM_LOCKED)
+ if (!can_madv_dontneed_vma(vma))
continue;
/*
@@ -550,11 +545,13 @@
* we do not want to block exit_mmap by keeping mm ref
* count elevated without a good reason.
*/
- if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED))
+ if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) {
+ tlb_gather_mmu(&tlb, mm, vma->vm_start, vma->vm_end);
unmap_page_range(&tlb, vma, vma->vm_start, vma->vm_end,
- &details);
+ NULL);
+ tlb_finish_mmu(&tlb, vma->vm_start, vma->vm_end);
+ }
}
- tlb_finish_mmu(&tlb, 0, -1);
pr_info("oom_reaper: reaped process %d (%s), now anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n",
task_pid_nr(tsk), tsk->comm,
K(get_mm_counter(mm, MM_ANONPAGES)),
@@ -562,12 +559,7 @@
K(get_mm_counter(mm, MM_SHMEMPAGES)));
up_read(&mm->mmap_sem);
- /*
- * Drop our reference but make sure the mmput slow path is called from a
- * different context because we shouldn't risk we get stuck there and
- * put the oom_reaper out of the way.
- */
- mmput_async(mm);
+ trace_finish_task_reaping(tsk->pid);
unlock_oom:
mutex_unlock(&oom_lock);
return ret;
@@ -644,6 +636,7 @@
tsk->oom_reaper_list = oom_reaper_list;
oom_reaper_list = tsk;
spin_unlock(&oom_reaper_lock);
+ trace_wake_reaper(tsk->pid);
wake_up(&oom_reaper_wait);
}
@@ -695,6 +688,7 @@
*/
__thaw_task(tsk);
atomic_inc(&oom_victims);
+ trace_mark_victim(tsk->pid);
}
/**