Merge "msm: ipa4: Update IPA_PM_MAX_CLIENTS"
diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt
index e65439a..561a181 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm.txt
@@ -128,8 +128,8 @@
- MDM9640
compatible = "qcom,mdm9640"
-- MDMCALIFORNIUM
- compatible = "qcom,mdmcalifornium"
+- MDM9650
+ compatible = "qcom,mdm9650"
- SDXPOORWILLS
compatible = "qcom,sdxpoorwills"
@@ -190,6 +190,9 @@
- IPC device:
compatible = "qcom,ipc"
+- TTP device:
+ compatible = "qcom,ttp"
+
Boards (SoC type + board variant):
compatible = "qcom,apq8016"
@@ -356,10 +359,8 @@
compatible = "qcom,mdm9607-rumi"
compatible = "qcom,mdm9607-cdp"
compatible = "qcom,mdm9607-mtp"
-compatible = "qcom,mdmcalifornium-rumi"
-compatible = "qcom,mdmcalifornium-sim"
-compatible = "qcom,mdmcalifornium-cdp"
-compatible = "qcom,mdmcalifornium-mtp"
+compatible = "qcom,mdm9650-mtp"
+compatible = "qcom,mdm9650-ttp"
compatible = "qcom,apq8009-cdp"
compatible = "qcom,apq8009-mtp"
compatible = "qcom,sdxpoorwills-rumi"
diff --git a/Documentation/devicetree/bindings/gpu/adreno.txt b/Documentation/devicetree/bindings/gpu/adreno.txt
index 7976a87..4fb47d6 100644
--- a/Documentation/devicetree/bindings/gpu/adreno.txt
+++ b/Documentation/devicetree/bindings/gpu/adreno.txt
@@ -29,7 +29,7 @@
Current values of clock-names are:
"src_clk", "core_clk", "iface_clk", "mem_clk", "mem_iface_clk",
"alt_mem_iface_clk", "rbbmtimer_clk", "alwayson_clk",
- "iref_clk"
+ "iref_clk", "l3_vote"
"core_clk" and "iface_clk" are required and others are optional
- qcom,base-leakage-coefficient: Dynamic leakage coefficient.
@@ -78,7 +78,10 @@
GPU Power levels:
- qcom,gpu-pwrlevel-bins: Container for sets of GPU power levels (see
adreno-pwrlevels.txt)
-
+L3 Power levels:
+- qcom,l3-pwrlevels: Container for sets of L3 power levels, the
+ L3 frequency is adjusted according to the
+ performance hint received from userspace.
DCVS Core info
- qcom,dcvs-core-info Container for the DCVS core info (see
dcvs-core-info.txt)
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,mdm9650-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,mdm9650-pinctrl.txt
new file mode 100644
index 0000000..b493285
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,mdm9650-pinctrl.txt
@@ -0,0 +1,139 @@
+QTI MDM9650 TLMM block
+
+This binding describes the Top Level Mode Multiplexer block found in the
+MDM9650 platform.
+
+- compatible:
+ Usage: required
+ Value type: <string>
+ Definition: must be "qcom,mdm9650-pinctrl"
+
+- reg:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: the base address and size of the TLMM register space.
+
+- interrupts:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: should specify the TLMM summary IRQ.
+
+- interrupt-controller:
+ Usage: required
+ Value type: <none>
+ Definition: identifies this node as an interrupt controller
+
+- #interrupt-cells:
+ Usage: required
+ Value type: <u32>
+ Definition: must be 2. Specifying the pin number and flags, as defined
+ in <dt-bindings/interrupt-controller/irq.h>
+
+- gpio-controller:
+ Usage: required
+ Value type: <none>
+ Definition: identifies this node as a gpio controller
+
+- #gpio-cells:
+ Usage: required
+ Value type: <u32>
+ Definition: must be 2. Specifying the pin number and flags, as defined
+ in <dt-bindings/gpio/gpio.h>
+
+Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
+a general description of GPIO and interrupt bindings.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+The pin configuration nodes act as a container for an arbitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those pin(s)/group(s), and various pin configuration
+parameters, such as pull-up, drive strength, etc.
+
+
+PIN CONFIGURATION NODES:
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+
+The following generic properties as defined in pinctrl-bindings.txt are valid
+to specify in a pin configuration subnode:
+
+- pins:
+ Usage: required
+ Value type: <string-array>
+ Definition: List of gpio pins affected by the properties specified in
+ this subnode.
+
+- function:
+ Usage: required
+ Value type: <string>
+ Definition: Specify the alternative function to be configured for the
+ specified pins.
+
+- bias-disable:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins should be configued as no pull.
+
+- bias-pull-down:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins should be configued as pull down.
+
+- bias-pull-up:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins should be configued as pull up.
+
+- output-high:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins are configured in output mode, driven
+ high.
+
+- output-low:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins are configured in output mode, driven
+ low.
+
+- drive-strength:
+ Usage: optional
+ Value type: <u32>
+ Definition: Selects the drive strength for the specified pins, in mA.
+
+Example:
+
+ tlmm_pinmux: pinctrl@1000000 {
+ compatible = "qcom,mdm9650-pinctrl";
+ reg = <0x1000000 0x300000>;
+ interrupts = <0 208 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ uart1_console_active: uart1_console_active {
+ mux {
+ pins = "gpio0", "gpio1";
+ function = "blsp_uart1";
+ };
+
+ config {
+ pins = "gpio0", "gpio1";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
index 75996a5..5034e9f 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
@@ -323,6 +323,20 @@
discharging. If not specified, a value of 0 will be set.
Allowed range is from 245 to 62256.
+- qcom,ki-coeff-low-dischg
+ Usage: optional
+ Value type: <u32>
+ Definition: Ki coefficient value for low discharge current during
+ discharging. Value has no unit. Allowed range is 0-62200
+ in micro units.
+
+- qcom,ki-coeff-hi-chg
+ Usage: optional
+ Value type: <u32>
+ Definition: Ki coefficient value for high charge current during
+ charging. Value has no unit. Allowed range is 0-62200
+ in micro units.
+
- qcom,fg-rconn-mohms
Usage: optional
Value type: <u32>
diff --git a/Documentation/devicetree/bindings/regulator/cpr4-apss-regulator.txt b/Documentation/devicetree/bindings/regulator/cpr4-apss-regulator.txt
index 05792b0..8fecf90 100644
--- a/Documentation/devicetree/bindings/regulator/cpr4-apss-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/cpr4-apss-regulator.txt
@@ -36,7 +36,8 @@
Usage: required
Value type: <string>
Definition: should be one of the following:
- "qcom,cpr4-msm8953-apss-regulator";
+ "qcom,cpr4-msm8953-apss-regulator",
+ "qcom,cpr4-sdm632-apss-regulator";
- interrupts
Usage: required
diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
index 5d3b232..83ecdc7 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -61,6 +61,8 @@
- usb-core-id: Differentiates between different controllers present on a device.
- snps,bus-suspend-enable: If present then controller supports low power mode
during bus suspend.
+ - snps,usb3-u1u2-disable: If present, disable U1U2 low power modes in Superspeed mode
+ - snps,usb2-l1-disable: If present, disable L1 low power modes in Highspeed mode
This is usually a subnode to DWC3 glue to which it is connected.
diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile
index 28b2ec2..d9be3c3 100644
--- a/arch/arm/boot/dts/qcom/Makefile
+++ b/arch/arm/boot/dts/qcom/Makefile
@@ -7,6 +7,11 @@
sdxpoorwills-pcie-ep-cdp.dtb \
sdxpoorwills-pcie-ep-mtp.dtb
+dtb-$(CONFIG_ARCH_MDM9650) += mdm9650-nand-mtp.dtb \
+ mdm9650-ttp.dtb \
+ mdm9650-v1.1-nand-mtp.dtb \
+ mdm9650-v1.1-nand-cv2x.dtb
+
targets += dtbs
targets += $(addprefix ../, $(dtb-y))
diff --git a/arch/arm/boot/dts/qcom/mdm9650-blsp.dtsi b/arch/arm/boot/dts/qcom/mdm9650-blsp.dtsi
new file mode 100644
index 0000000..47d276f
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-blsp.dtsi
@@ -0,0 +1,498 @@
+/*
+ * Copyright (c) 2015-2018, 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.
+ */
+
+/ {
+ aliases {
+ i2c1 = &i2c_1;
+ i2c2 = &i2c_2;
+ i2c3 = &i2c_3;
+ i2c4 = &i2c_4;
+ spi1 = &spi_1;
+ spi2 = &spi_2;
+ spi3 = &spi_3;
+ spi4 = &spi_4;
+ };
+};
+
+&soc {
+ dma_blsp1: qcom,sps-dma@7884000{ /* BLSP1 */
+ #dma-cells = <4>;
+ compatible = "qcom,sps-dma";
+ reg = <0x7884000 0x23000>;
+ interrupts = <0 238 0>;
+ qcom,summing-threshold = <0x10>;
+ };
+
+ i2c_1: i2c@78b5000 { /* BLSP1 QUP1 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "qup_phys_addr";
+ reg = <0x78b5000 0x600>;
+ interrupt-names = "qup_irq";
+ interrupts = <0 95 0>;
+ dmas = <&dma_blsp1 8 64 0x20000020 0x20>,
+ <&dma_blsp1 9 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <86>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
+ <&clock_gcc clk_gcc_blsp1_qup1_i2c_apps_clk>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_1_active>;
+ pinctrl-1 = <&i2c_1_sleep>;
+ status = "disabled";
+ };
+
+ i2c_2: i2c@78b6000 { /* BLSP1 QUP2 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "qup_phys_addr";
+ reg = <0x78b6000 0x600>;
+ interrupt-names = "qup_irq";
+ interrupts = <0 96 0>;
+ dmas = <&dma_blsp1 10 64 0x20000020 0x20>,
+ <&dma_blsp1 11 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <86>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
+ <&clock_gcc clk_gcc_blsp1_qup2_i2c_apps_clk>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_2_active>;
+ pinctrl-1 = <&i2c_2_sleep>;
+ status = "disabled";
+ };
+
+ i2c_3: i2c@78b7000 { /* BLSP1 QUP3 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "qup_phys_addr";
+ reg = <0x78b7000 0x600>;
+ interrupt-names = "qup_irq";
+ interrupts = <0 97 0>;
+ dmas = <&dma_blsp1 12 64 0x20000020 0x20>,
+ <&dma_blsp1 13 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <86>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
+ <&clock_gcc clk_gcc_blsp1_qup3_i2c_apps_clk>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_3_active>;
+ pinctrl-1 = <&i2c_3_sleep>;
+ status = "disabled";
+
+ wcd9xxx_codec@d{
+ compatible = "qcom,tasha-i2c-pgd";
+ reg = <0x0d>;
+
+ interrupt-parent = <&wcd9xxx_intc>;
+ interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+ 17 18 19 20 21 22 23 24 25 26 27 28 29
+ 30>;
+
+ qcom,cdc-reset-gpio = <&tlmm_pinmux 90 0>;
+
+ clock-names = "wcd_clk";
+ clocks = <&clock_audio clk_audio_lpass_mclk>;
+
+ qcom,msm-mbhc-hphl-swh = <0>;
+ qcom,msm-mbhc-gnd-swh = <0>;
+
+ cdc-vdd-buck-supply = <&codec_buck_vreg>;
+ qcom,cdc-vdd-buck-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-buck-current = <650000>;
+
+ cdc-buck-sido-supply = <&codec_buck_vreg>;
+ qcom,cdc-buck-sido-voltage = <1800000 1800000>;
+ qcom,cdc-buck-sido-current = <200000>;
+
+ cdc-vdd-tx-h-supply = <&pmd9650_l6>;
+ qcom,cdc-vdd-tx-h-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-tx-h-current = <25000>;
+
+ cdc-vdd-rx-h-supply = <&pmd9650_l6>;
+ qcom,cdc-vdd-rx-h-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-rx-h-current = <25000>;
+
+ cdc-vddpx-1-supply = <&pmd9650_l6>;
+ qcom,cdc-vddpx-1-voltage = <1800000 1800000>;
+ qcom,cdc-vddpx-1-current = <10000>;
+
+ qcom,cdc-static-supplies = "cdc-vdd-buck",
+ "cdc-buck-sido",
+ "cdc-vdd-tx-h",
+ "cdc-vdd-rx-h",
+ "cdc-vddpx-1";
+
+ qcom,cdc-micbias1-mv = <1800>;
+ qcom,cdc-micbias2-mv = <1800>;
+ qcom,cdc-micbias3-mv = <1800>;
+ qcom,cdc-micbias4-mv = <1800>;
+ qcom,cdc-mclk-clk-rate = <12288000>;
+ qcom,cdc-dmic-sample-rate = <4800000>;
+
+ swr_master {
+ compatible = "qcom,swr-wcd";
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ wsa881x_211: wsa881x@20170211 {
+ compatible = "qcom,wsa881x";
+ reg = <0x00 0x20170211>;
+ qcom,spkr-sd-n-gpio =
+ <&tlmm_pinmux 81 0>;
+ };
+
+ wsa881x_212: wsa881x@20170212 {
+ compatible = "qcom,wsa881x";
+ reg = <0x00 0x20170212>;
+ qcom,spkr-sd-n-gpio =
+ <&tlmm_pinmux 81 0>;
+ };
+
+ wsa881x_213: wsa881x@21170213 {
+ compatible = "qcom,wsa881x";
+ reg = <0x00 0x21170213>;
+ qcom,spkr-sd-n-gpio =
+ <&tlmm_pinmux 81 0>;
+ };
+
+ wsa881x_214: wsa881x@21170214 {
+ compatible = "qcom,wsa881x";
+ reg = <0x00 0x21170214>;
+ qcom,spkr-sd-n-gpio =
+ <&tlmm_pinmux 81 0>;
+ };
+ };
+ };
+ };
+
+ i2c_4: i2c@78b8000 { /* BLSP1 QUP4 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "qup_phys_addr";
+ reg = <0x78b8000 0x600>;
+ interrupt-names = "qup_irq";
+ interrupts = <0 98 0>;
+ dmas = <&dma_blsp1 14 64 0x20000020 0x20>,
+ <&dma_blsp1 15 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <86>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
+ <&clock_gcc clk_gcc_blsp1_qup4_i2c_apps_clk>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_4_active>;
+ pinctrl-1 = <&i2c_4_sleep>;
+ status = "disabled";
+ };
+
+
+ spi_1: spi@78b5000 { /* BLSP1 QUP1 */
+ compatible = "qcom,spi-qup-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "spi_physical", "spi_bam_physical";
+ reg = <0x078b5000 0x600>,
+ <0x7884000 0x23000>;
+ interrupt-names = "spi_irq", "spi_bam_irq";
+ interrupts = <0 95 0>, <0 238 0>;
+ spi-max-frequency = <19200000>;
+ qcom,use-bam;
+ qcom,ver-reg-exists;
+ qcom,bam-consumer-pipe-index = <8>;
+ qcom,bam-producer-pipe-index = <9>;
+ qcom,master-id = <86>;
+ qcom,use-pinctrl;
+ pinctrl-names = "spi_default", "spi_sleep";
+ pinctrl-0 = <&spi_1_active>;
+ pinctrl-1 = <&spi_1_sleep>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
+ <&clock_gcc clk_gcc_blsp1_qup1_spi_apps_clk>;
+ status = "disabled";
+ };
+
+ spi_2: spi@78b6000 { /* BLSP1 QUP2 */
+ compatible = "qcom,spi-qup-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "spi_physical", "spi_bam_physical";
+ reg = <0x78b6000 0x600>,
+ <0x7884000 0x23000>;
+ interrupt-names = "spi_irq", "spi_bam_irq";
+ interrupts = <0 96 0>, <0 238 0>;
+ spi-max-frequency = <19200000>;
+ qcom,use-bam;
+ qcom,ver-reg-exists;
+ qcom,bam-consumer-pipe-index = <10>;
+ qcom,bam-producer-pipe-index = <11>;
+ qcom,master-id = <86>;
+ qcom,use-pinctrl;
+ pinctrl-names = "spi_default", "spi_sleep";
+ pinctrl-0 = <&spi_2_active>;
+ pinctrl-1 = <&spi_2_sleep>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
+ <&clock_gcc clk_gcc_blsp1_qup2_spi_apps_clk>;
+ status = "disabled";
+ };
+
+ spi_3: spi@78b7000 { /* BLSP1 QUP3 */
+ compatible = "qcom,spi-qup-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "spi_physical", "spi_bam_physical";
+ reg = <0x078b7000 0x600>,
+ <0x7884000 0x23000>;
+ interrupt-names = "spi_irq", "spi_bam_irq";
+ interrupts = <0 97 0>, <0 238 0>;
+ spi-max-frequency = <19200000>;
+ qcom,use-bam;
+ qcom,ver-reg-exists;
+ qcom,bam-consumer-pipe-index = <12>;
+ qcom,bam-producer-pipe-index = <13>;
+ qcom,master-id = <86>;
+ qcom,use-pinctrl;
+ pinctrl-names = "spi_default", "spi_sleep";
+ pinctrl-0 = <&spi_3_active>;
+ pinctrl-1 = <&spi_3_sleep>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
+ <&clock_gcc clk_gcc_blsp1_qup3_spi_apps_clk>;
+ status = "disabled";
+ };
+
+ spi_4: spi@78b8000 { /* BLSP1 QUP4 */
+ compatible = "qcom,spi-qup-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "spi_physical", "spi_bam_physical";
+ reg = <0x078b8000 0x600>,
+ <0x7884000 0x23000>;
+ interrupt-names = "spi_irq", "spi_bam_irq";
+ interrupts = <0 98 0>, <0 238 0>;
+ spi-max-frequency = <19200000>;
+ qcom,use-bam;
+ qcom,ver-reg-exists;
+ qcom,bam-consumer-pipe-index = <14>;
+ qcom,bam-producer-pipe-index = <15>;
+ qcom,master-id = <86>;
+ qcom,use-pinctrl;
+ pinctrl-names = "spi_default", "spi_sleep";
+ pinctrl-0 = <&spi_4_active>;
+ pinctrl-1 = <&spi_4_sleep>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
+ <&clock_gcc clk_gcc_blsp1_qup4_spi_apps_clk>;
+ status = "disabled";
+ };
+
+ blsp1_uart1_hs: uart@78af000 { /* BLSP1 UART1 */
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0x78af000 0x200>,
+ <0x7884000 0x23000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&blsp1_uart1_hs>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 107 0
+ 1 &intc 0 238 0
+ 2 &tlmm_pinmux 1 0>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xFD>;
+
+ qcom,bam-tx-ep-pipe-index = <0>;
+ qcom,bam-rx-ep-pipe-index = <1>;
+ qcom,master-id = <86>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_uart1_apps_clk>,
+ <&clock_gcc clk_gcc_blsp1_ahb_clk>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp1_uart1_sleep>;
+ pinctrl-1 = <&blsp1_uart1_active>;
+
+ qcom,msm-bus,name = "buart1";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <86 512 0 0>,
+ <86 512 500 800>;
+ status = "disabled";
+ };
+
+ blsp1_uart2_hs: uart@78b0000 { /* BLSP1 UART2 */
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0x78b0000 0x200>,
+ <0x7884000 0x23000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&blsp1_uart2_hs>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 108 0
+ 1 &intc 0 238 0
+ 2 &tlmm_pinmux 5 0>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xFD>;
+
+ qcom,bam-tx-ep-pipe-index = <2>;
+ qcom,bam-rx-ep-pipe-index = <3>;
+ qcom,master-id = <86>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_uart2_apps_clk>,
+ <&clock_gcc clk_gcc_blsp1_ahb_clk>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp1_uart2_sleep>;
+ pinctrl-1 = <&blsp1_uart2_active>;
+
+ qcom,msm-bus,name = "buart2";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <86 512 0 0>,
+ <86 512 500 800>;
+ status = "disabled";
+ };
+
+ blsp1_uart3_hs: uart@78b1000 { /* BLSP1 UART3 */
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0x78b1000 0x200>,
+ <0x7884000 0x23000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&blsp1_uart3_hs>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 109 0
+ 1 &intc 0 238 0
+ 2 &tlmm_pinmux 9 0>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xFD>;
+
+ qcom,bam-tx-ep-pipe-index = <4>;
+ qcom,bam-rx-ep-pipe-index = <5>;
+ qcom,master-id = <86>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_uart3_apps_clk>,
+ <&clock_gcc clk_gcc_blsp1_ahb_clk>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp1_uart3_sleep>;
+ pinctrl-1 = <&blsp1_uart3_active>;
+
+ qcom,msm-bus,name = "buart3";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <86 512 0 0>,
+ <86 512 500 800>;
+ status = "disabled";
+ };
+
+ blsp1_uart4_hs: uart@78b2000 { /* BLSP1 UART4 */
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0x78b2000 0x200>,
+ <0x7884000 0x23000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&blsp1_uart4_hs>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 110 0
+ 1 &intc 0 238 0
+ 2 &tlmm_pinmux 13 0>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xFD>;
+
+ qcom,bam-tx-ep-pipe-index = <6>;
+ qcom,bam-rx-ep-pipe-index = <7>;
+ qcom,master-id = <86>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_uart4_apps_clk>,
+ <&clock_gcc clk_gcc_blsp1_ahb_clk>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp1_uart4_sleep>;
+ pinctrl-1 = <&blsp1_uart4_active>;
+
+ qcom,msm-bus,name = "buart4";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <86 512 0 0>,
+ <86 512 500 800>;
+ status = "disabled";
+ };
+
+ blsp1_uart4b_hs: uart@78b2000 { /* BLSP1 UART4b */
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0x78b2000 0x200>,
+ <0x7884000 0x23000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&blsp1_uart4_hs>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 110 0
+ 1 &intc 0 238 0
+ 2 &tlmm_pinmux 17 0>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xFD>;
+
+ qcom,bam-tx-ep-pipe-index = <6>;
+ qcom,bam-rx-ep-pipe-index = <7>;
+ qcom,master-id = <86>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_uart4_apps_clk>,
+ <&clock_gcc clk_gcc_blsp1_ahb_clk>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp1_uart4b_sleep>;
+ pinctrl-1 = <&blsp1_uart4b_active>;
+
+ qcom,msm-bus,name = "buart4b";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <86 512 0 0>,
+ <86 512 500 800>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-bus.dtsi b/arch/arm/boot/dts/qcom/mdm9650-bus.dtsi
new file mode 100644
index 0000000..ffa45ca
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-bus.dtsi
@@ -0,0 +1,776 @@
+/* Copyright (c) 2015, 2018, 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.
+ */
+
+/* Version = 2 */
+#include <dt-bindings/msm/msm-bus-ids.h>
+
+&soc {
+ ad_hoc_bus: ad-hoc-bus {
+ compatible = "qcom,msm-bus-device";
+ reg = <0x580000 0x14000>,
+ <0x400000 0x62000>,
+ <0x500000 0x11000>;
+ reg-names = "snoc-base", "bimc-base", "pcnoc-base";
+
+ /* Buses */
+
+ fab_bimc: fab-bimc {
+ cell-id = <MSM_BUS_FAB_BIMC>;
+ label = "fab-bimc";
+ qcom,fab-dev;
+ qcom,base-name = "bimc-base";
+ qcom,bus-type = <2>;
+ qcom,bypass-qos-prg;
+ qcom,util-fact = <153>;
+ clock-names = "bus_clk", "bus_a_clk";
+ clocks = <&clock_gcc clk_bimc_msmbus_clk>,
+ <&clock_gcc clk_bimc_msmbus_a_clk>;
+ };
+
+ fab_pcnoc: fab-pcnoc {
+ cell-id = <MSM_BUS_FAB_PERIPH_NOC>;
+ label = "fab-pcnoc";
+ qcom,fab-dev;
+ qcom,base-name = "pcnoc-base";
+ qcom,bypass-qos-prg;
+ qcom,bus-type = <1>;
+ clock-names = "bus_clk", "bus_a_clk";
+ clocks = <&clock_gcc clk_pcnoc_msmbus_clk>,
+ <&clock_gcc clk_pcnoc_msmbus_a_clk>;
+ };
+
+ fab_snoc: fab-snoc {
+ cell-id = <MSM_BUS_FAB_SYS_NOC>;
+ label = "fab-snoc";
+ qcom,fab-dev;
+ qcom,base-name = "snoc-base";
+ qcom,bypass-qos-prg;
+ qcom,bus-type = <1>;
+ clock-names = "bus_clk", "bus_a_clk";
+ clocks = <&clock_gcc clk_snoc_msmbus_clk>,
+ <&clock_gcc clk_snoc_msmbus_a_clk>;
+
+ };
+
+ /* Masters */
+
+ mas_apps_proc: mas-apps-proc {
+ cell-id = <MSM_BUS_MASTER_AMPSS_M0>;
+ label = "mas-apps-proc";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <0>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = < &slv_bimc_snoc_1_pcie &slv_ebi
+ &slv_bimc_snoc>;
+ qcom,prio-lvl = <0>;
+ qcom,prio-rd = <0>;
+ qcom,prio-wr = <0>;
+ qcom,bus-dev = <&fab_bimc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_APPSS_PROC>;
+ };
+
+ mas_snoc_bimc: mas-snoc-bimc {
+ cell-id = <MSM_BUS_SNOC_BIMC_MAS>;
+ label = "mas-snoc-bimc";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,qport = <3>;
+ qcom,qos-mode = "bypass";
+ qcom,connections = <&slv_ebi>;
+ qcom,bus-dev = <&fab_bimc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_SNOC_BIMC>;
+ };
+
+ mas_tcu_0: mas-tcu-0 {
+ cell-id = <MSM_BUS_MASTER_TCU_0>;
+ label = "mas-tcu-0";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <4>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = < &slv_bimc_snoc_1_pcie &slv_ebi
+ &slv_bimc_snoc>;
+ qcom,prio-lvl = <2>;
+ qcom,prio-rd = <2>;
+ qcom,prio-wr = <2>;
+ qcom,bus-dev = <&fab_bimc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_TCU_0>;
+ };
+
+ mas_audio: mas-audio {
+ cell-id = <MSM_BUS_MASTER_AUDIO>;
+ label = "mas-audio";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&pcnoc_m_0>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_AUDIO>;
+ qcom,blacklist = <&slv_pdm &slv_pmic_arb &slv_audio
+ &slv_usb3_phy_cfg &slv_tcsr &slv_snoc_cfg
+ &slv_blsp_1 &slv_qpic_cfg &slv_tcu
+ &slv_tlmm &slv_ipa_cfg &slv_prng
+ &slv_dcc_cfg &slv_crypto_0_cfg &slv_pcie_parf
+ &slv_message_ram &slv_sdcc_1
+ &slv_spmi_fetcher>;
+ };
+
+ mas_blsp_1: mas-blsp-1 {
+ cell-id = <MSM_BUS_MASTER_BLSP_1>;
+ label = "mas-blsp-1";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&pcnoc_m_1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_BLSP_1>;
+ };
+
+ mas_qpic: mas-qpic {
+ cell-id = <MSM_BUS_MASTER_QPIC>;
+ label = "mas-qpic";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&pcnoc_m_1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_QPIC>;
+ };
+
+ mas_crypto: mas-crypto {
+ cell-id = <MSM_BUS_MASTER_CRYPTO>;
+ label = "mas-crypto";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <0>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&pcnoc_int_1>;
+ qcom,prio1 = <0>;
+ qcom,prio0 = <0>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_CRYPTO>;
+ qcom,blacklist = <&slv_pmic_arb &slv_audio &slv_tcsr
+ &slv_snoc_cfg &slv_tcu &slv_tlmm
+ &slv_ipa_cfg &slv_dcc_cfg &slv_crypto_0_cfg
+ &slv_pcie_parf &slv_message_ram
+ &slv_spmi_fetcher>;
+ };
+
+ mas_sdcc_1: mas-sdcc-1 {
+ cell-id = <MSM_BUS_MASTER_SDCC_1>;
+ label = "mas-sdcc-1";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&pcnoc_int_1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_SDCC_1>;
+ };
+
+ mas_spmi_fetcher: mas-spmi-fetcher {
+ cell-id = <MSM_BUS_SPMI_FETCHER>;
+ label = "mas-spmi-fetcher";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&pcnoc_m_0>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_SPMI_FETCHER>;
+ qcom,blacklist = <&slv_pdm &slv_audio &slv_usb3_phy_cfg
+ &slv_tcsr &slv_snoc_cfg &slv_blsp_1
+ &slv_qpic_cfg &slv_tcu &slv_tlmm
+ &slv_ipa_cfg &slv_prng &slv_dcc_cfg
+ &slv_crypto_0_cfg &slv_pcie_parf
+ &slv_message_ram &slv_sdcc_1 &slv_spmi_fetcher>;
+ };
+
+ mas_snoc_pcnoc: mas-snoc-pcnoc {
+ cell-id = <MSM_BUS_SNOC_PNOC_MAS>;
+ label = "mas-snoc-pcnoc";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,qport = <9>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&pcnoc_int_5>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_SNOC_PCNOC>;
+ };
+
+ mas_qdss_bam: mas-qdss-bam {
+ cell-id = <MSM_BUS_MASTER_QDSS_BAM>;
+ label = "mas-qdss-bam";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <12>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&slv_usb3 &slv_imem &slv_snoc_bimc
+ &slv_snoc_pcnoc>;
+ qcom,prio1 = <0>;
+ qcom,prio0 = <0>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_QDSS_BAM>;
+ };
+
+ mas_bimc_snoc: mas-bimc-snoc {
+ cell-id = <MSM_BUS_BIMC_SNOC_MAS>;
+ label = "mas-bimc-snoc";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = < &slv_usb3 &slv_cats_0
+ &slv_snoc_pcnoc &slv_imem &slv_qdss_stm
+ &slv_apss_ahb>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_BIMC_SNOC>;
+ };
+
+ mas_bimc_snoc_1_pcie: mas-bimc-snoc-1-pcie {
+ cell-id = <MSM_BUS_BIMC_SNOC_1_MAS>;
+ label = "mas-bimc-snoc-1-pcie";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_pcie_0>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_BIMC_SNOC_1>;
+ };
+
+ mas_ipa: mas-ipa {
+ cell-id = <MSM_BUS_MASTER_IPA>;
+ label = "mas-ipa";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_usb3 &slv_snoc_pcnoc
+ &slv_pcie_0 &slv_snoc_bimc &slv_imem
+ &slv_qdss_stm>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_IPA>;
+ };
+
+ mas_usb3: mas-usb3 {
+ cell-id = <MSM_BUS_MASTER_USB3>;
+ label = "mas-usb3";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <8>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&slv_usb3 &slv_imem &slv_qdss_stm
+ &slv_snoc_bimc &slv_snoc_pcnoc>;
+ qcom,prio1 = <0>;
+ qcom,prio0 = <0>;
+ qcom,bus-dev = <&fab_snoc>;
+ //clock-names = "bus_qos_clocks";
+ //clocks = <&gcc_sys_noc_usb3_axi_clk>;
+ qcom,mas-rpm-id = <ICBID_MASTER_USB3>;
+ };
+
+ mas_pcnoc_snoc: mas-pcnoc-snoc {
+ cell-id = <MSM_BUS_PNOC_SNOC_MAS>;
+ label = "mas-pcnoc-snoc";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,qport = <5>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = < &slv_usb3 &slv_imem &slv_pcie_0
+ &slv_snoc_bimc &slv_apss_ahb
+ &slv_qdss_stm>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PNOC_SNOC>;
+ };
+
+ mas_qdss_etr: mas-qdss-etr {
+ cell-id = <MSM_BUS_MASTER_QDSS_ETR>;
+ label = "mas-qdss-etr";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <11>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&slv_usb3 &slv_imem &slv_snoc_bimc
+ &slv_snoc_pcnoc>;
+ qcom,prio1 = <0>;
+ qcom,prio0 = <0>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_QDSS_ETR>;
+ };
+
+ mas_pcie_0: mas-pcie-0 {
+ cell-id = <MSM_BUS_MASTER_PCIE>;
+ label = "mas-pcie-0";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,qport = <7>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = < &slv_imem &slv_qdss_stm
+ &slv_apss_ahb
+ &slv_snoc_bimc &slv_snoc_pcnoc>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCIE_0>;
+ };
+
+ /* Internal nodes */
+
+ pcnoc_m_0: pcnoc-m-0 {
+ cell-id = <MSM_BUS_PNOC_M_0>;
+ label = "pcnoc-m-0";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,qport = <5>;
+ qcom,qos-mode = "bypass";
+ qcom,connections = <&pcnoc_int_2>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_M_0>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_M_0>;
+ };
+
+ pcnoc_m_1: pcnoc-m-1 {
+ cell-id = <MSM_BUS_PNOC_M_1>;
+ label = "pcnoc-m-1";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,qport = <6>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&pcnoc_int_2>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_M_1>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_M_1>;
+ };
+
+ pcnoc_int_0: pcnoc-int-0 {
+ cell-id = <MSM_BUS_PNOC_INT_0>;
+ label = "pcnoc-int-0";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&pcnoc_s_1 &pcnoc_s_2 &pcnoc_s_0
+ &pcnoc_s_4 &pcnoc_s_7 &pcnoc_s_3>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_INT_0>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_INT_0>;
+ };
+
+ pcnoc_int_1: pcnoc-int-1 {
+ cell-id = <MSM_BUS_PNOC_INT_1>;
+ label = "pcnoc-int-1";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_pcnoc_snoc &pcnoc_int_5>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_INT_1>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_INT_1>;
+ };
+
+ pcnoc_int_2: pcnoc-int-2 {
+ cell-id = <MSM_BUS_PNOC_INT_2>;
+ label = "pcnoc-int-2";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&pcnoc_int_5 &pcnoc_int_4>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_INT_2>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_INT_2>;
+ };
+
+ pcnoc_int_4: pcnoc-int-4 {
+ cell-id = <MSM_BUS_PNOC_INT_4>;
+ label = "pcnoc-int-4";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_pcnoc_snoc>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_INT_4>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_INT_4>;
+ };
+
+ pcnoc_int_5: pcnoc-int-5 {
+ cell-id = <MSM_BUS_PNOC_INT_5>;
+ label = "pcnoc-int-5";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = < &pcnoc_int_6 &pcnoc_int_0>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_INT_5>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_INT_5>;
+ };
+
+ pcnoc_int_6: pcnoc-int-6 {
+ cell-id = <MSM_BUS_PNOC_INT_6>;
+ label = "pcnoc-int-6";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&pcnoc_s_8 &slv_tcu>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_INT_6>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_INT_6>;
+ };
+
+ pcnoc_s_0: pcnoc-s-0 {
+ cell-id = <MSM_BUS_PNOC_SLV_0>;
+ label = "pcnoc-s-0";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = < &slv_tlmm&slv_tcsr>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_S_0>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_S_0>;
+ };
+
+ pcnoc_s_1: pcnoc-s-1 {
+ cell-id = <MSM_BUS_PNOC_SLV_1>;
+ label = "pcnoc-s-1";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_crypto_0_cfg &slv_prng &slv_pdm
+ &slv_message_ram>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_S_1>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_S_1>;
+ };
+
+ pcnoc_s_2: pcnoc-s-2 {
+ cell-id = <MSM_BUS_PNOC_SLV_2>;
+ label = "pcnoc-s-2";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_pmic_arb>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_S_2>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_S_2>;
+ };
+
+ pcnoc_s_3: pcnoc-s-3 {
+ cell-id = <MSM_BUS_PNOC_SLV_3>;
+ label = "pcnoc-s-3";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_snoc_cfg>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_S_3>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_S_3>;
+ };
+
+ pcnoc_s_4: pcnoc-s-4 {
+ cell-id = <MSM_BUS_PNOC_SLV_4>;
+ label = "pcnoc-s-4";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_pcie_parf &slv_usb3_phy_cfg
+ &slv_audio &slv_spmi_fetcher>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_S_4>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_S_4>;
+ };
+
+ pcnoc_s_7: pcnoc-s-7 {
+ cell-id = <MSM_BUS_PNOC_SLV_7>;
+ label = "pcnoc-s-7";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_ipa_cfg>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_S_7>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_S_7>;
+ };
+
+ pcnoc_s_8: pcnoc-s-8 {
+ cell-id = <MSM_BUS_PNOC_SLV_8>;
+ label = "pcnoc-s-8";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = < &slv_dcc_cfg &slv_qpic_cfg
+ &slv_blsp_1 &slv_sdcc_1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_S_8>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_S_8>;
+ };
+
+ /* Slaves */
+
+ slv_ebi:slv-ebi {
+ cell-id = <MSM_BUS_SLAVE_EBI_CH0>;
+ label = "slv-ebi";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_bimc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_EBI1>;
+ };
+
+ slv_bimc_snoc:slv-bimc-snoc {
+ cell-id = <MSM_BUS_BIMC_SNOC_SLV>;
+ label = "slv-bimc-snoc";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_bimc>;
+ qcom,connections = <&mas_bimc_snoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_BIMC_SNOC>;
+ };
+
+ slv_bimc_snoc_1_pcie:slv-bimc-snoc-1-pcie {
+ cell-id = <MSM_BUS_BIMC_SNOC_1_SLV>;
+ label = "slv-bimc-snoc-1-pcie";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_bimc>;
+ qcom,connections = <&mas_bimc_snoc_1_pcie>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_BIMC_SNOC_1>;
+ };
+
+ slv_tcsr:slv-tcsr {
+ cell-id = <MSM_BUS_SLAVE_TCSR>;
+ label = "slv-tcsr";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_TCSR>;
+ };
+
+ slv_tlmm:slv-tlmm {
+ cell-id = <MSM_BUS_SLAVE_TLMM>;
+ label = "slv-tlmm";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_TLMM>;
+ };
+
+ slv_crypto_0_cfg:slv-crypto-0-cfg {
+ cell-id = <MSM_BUS_SLAVE_CRYPTO_0_CFG>;
+ label = "slv-crypto-0-cfg";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_CRYPTO_0_CFG>;
+ };
+
+ slv_message_ram:slv-message-ram {
+ cell-id = <MSM_BUS_SLAVE_MESSAGE_RAM>;
+ label = "slv-message-ram";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_MESSAGE_RAM>;
+ };
+
+ slv_pdm:slv-pdm {
+ cell-id = <MSM_BUS_SLAVE_PDM>;
+ label = "slv-pdm";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PDM>;
+ };
+
+ slv_prng:slv-prng {
+ cell-id = <MSM_BUS_SLAVE_PRNG>;
+ label = "slv-prng";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PRNG>;
+ };
+
+ slv_pmic_arb:slv-pmic-arb {
+ cell-id = <MSM_BUS_SLAVE_PMIC_ARB>;
+ label = "slv-pmic-arb";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PMIC_ARB>;
+ };
+
+ slv_snoc_cfg:slv-snoc-cfg {
+ cell-id = <MSM_BUS_SLAVE_SNOC_CFG>;
+ label = "slv-snoc-cfg";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_SNOC_CFG>;
+ };
+
+ slv_sdcc_1:slv-sdcc-1 {
+ cell-id = <MSM_BUS_SLAVE_SDCC_1>;
+ label = "slv-sdcc-1";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_SDCC_1>;
+ };
+
+ slv_blsp_1:slv-blsp-1 {
+ cell-id = <MSM_BUS_SLAVE_BLSP_1>;
+ label = "slv-blsp-1";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_BLSP_1>;
+ };
+
+ slv_dcc_cfg:slv-dcc-cfg {
+ cell-id = <MSM_BUS_SLAVE_DCC_CFG>;
+ label = "slv-dcc-cfg";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_DCC_CFG>;
+ };
+
+ slv_audio:slv-audio {
+ cell-id = <MSM_BUS_SLAVE_AUDIO>;
+ label = "slv-audio";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_AUDIO>;
+ };
+
+ slv_spmi_fetcher:slv-spmi-fetcher {
+ cell-id = <MSM_BUS_SLAVE_SPMI_FETCHER>;
+ label = "slv-spmi-fetcher";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_SPMI_FETCHER>;
+ };
+
+ slv_tcu:slv-tcu {
+ cell-id = <MSM_BUS_SLAVE_TCU>;
+ label = "slv-tcu";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_TCU>;
+ };
+
+ slv_pcnoc_snoc:slv-pcnoc-snoc {
+ cell-id = <MSM_BUS_PNOC_SNOC_SLV>;
+ label = "slv-pcnoc-snoc";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,connections = <&mas_pcnoc_snoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_SNOC>;
+ };
+
+ slv_pcie_parf:slv-pcie-parf {
+ cell-id = <MSM_BUS_SLAVE_PCIE_PARF>;
+ label = "slv-pcie-parf";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCIE_PARF>;
+ };
+
+ slv_usb3_phy_cfg:slv-usb3-phy-cfg {
+ cell-id = <MSM_BUS_SLAVE_USB3_PHY_CFG>;
+ label = "slv-usb3-phy-cfg";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_USB3_PHY_CFG>;
+ };
+
+ slv_qpic_cfg:slv-qpic-cfg {
+ cell-id = <MSM_BUS_SLAVE_QPIC>;
+ label = "slv-qpic-cfg";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_QPIC>;
+ };
+
+ slv_ipa_cfg:slv-ipa-cfg {
+ cell-id = <MSM_BUS_SLAVE_IPA_CFG>;
+ label = "slv-ipa-cfg";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_IPA_CFG>;
+ };
+
+ slv_apss_ahb:slv-apss-ahb {
+ cell-id = <MSM_BUS_SLAVE_APPSS>;
+ label = "slv-apss-ahb";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_APPSS>;
+ };
+
+ slv_snoc_bimc:slv-snoc-bimc {
+ cell-id = <MSM_BUS_SNOC_BIMC_SLV>;
+ label = "slv-snoc-bimc";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,connections = <&mas_snoc_bimc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_SNOC_BIMC>;
+ };
+
+ slv_imem:slv-imem {
+ cell-id = <MSM_BUS_SLAVE_OCIMEM>;
+ label = "slv-imem";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_IMEM>;
+ };
+
+ slv_snoc_pcnoc:slv-snoc-pcnoc {
+ cell-id = <MSM_BUS_SNOC_PNOC_SLV>;
+ label = "slv-snoc-pcnoc";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,connections = <&mas_snoc_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_SNOC_PCNOC>;
+ };
+
+ slv_qdss_stm:slv-qdss-stm {
+ cell-id = <MSM_BUS_SLAVE_QDSS_STM>;
+ label = "slv-qdss-stm";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_QDSS_STM>;
+ };
+
+ slv_pcie_0:slv-pcie-0 {
+ cell-id = <MSM_BUS_SLAVE_PCIE_0>;
+ label = "slv-pcie-0";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCIE_0>;
+ };
+
+ slv_usb3:slv-usb3 {
+ cell-id = <MSM_BUS_SLAVE_USB3>;
+ label = "slv-usb3";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_USB3>;
+ };
+
+ slv_cats_0:slv-cats-0 {
+ cell-id = <MSM_BUS_SLAVE_CATS_128>;
+ label = "slv-cats-0";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_CATS_0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-ccard.dtsi b/arch/arm/boot/dts/qcom/mdm9650-ccard.dtsi
new file mode 100644
index 0000000..28aa863
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-ccard.dtsi
@@ -0,0 +1,624 @@
+/* Copyright (c) 2017-2018, 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/irq.h>
+#include "mdm9650-v1.1.dtsi"
+#include "mdm9650-pinctrl.dtsi"
+
+/ {
+ aliases {
+ serial0 = &blsp1_uart3;
+ serial1 = &blsp1_uart1;
+ };
+};
+
+&soc {
+ sound {
+ status = "disabled";
+ };
+
+ usb_detect {
+ compatible = "qcom,gpio-usbdetect";
+ interrupt-parent = <&spmi_bus>;
+ interrupts = <0x0 0x0d 0x0>; /* PMD9655 VBUS DETECT */
+ interrupt-names = "vbus_det_irq";
+ };
+
+ bt_qca6174 {
+ qca,bt-vdd-core-supply = <&wlan_ext_vreg>;
+ /delete-property/ qca,bt-vdd-xtal-supply;
+ };
+
+ /* 4V regulator for peripherals */
+ periph_vreg: regulator-periph-lm53635 {
+ status = "disabled";
+ compatible = "regulator-fixed";
+ regulator-name = "periph_vreg";
+ startup-delay-us = <4000>;
+ gpio = <&tlmm_pinmux 9 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&periph_vreg_gpio>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ /* 1.8V/3.3V external regulator for wlan */
+ wlan_ext_vreg: regulator-wlan-tlv62065 {
+ compatible = "regulator-fixed";
+ regulator-name = "wlan_ext_vreg";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ startup-delay-us = <500>;
+ gpio = <&tlmm_pinmux 97 0>;
+ enable-active-high;
+ };
+
+ /* 1.8V/3.3V regulator for audio codec */
+ codec_vreg: regulator-codec-tlv7103318 {
+ compatible = "regulator-fixed";
+ regulator-name = "codec_vreg";
+ startup-delay-us = <100>;
+ gpio = <&tlmm_pinmux 38 0>;
+ enable-active-high;
+ };
+
+ /* 3.0V regulator for BTLE chip */
+ btle_vreg: regulator-btle-lp5907 {
+ compatible = "regulator-fixed";
+ regulator-name = "btle_vreg";
+ startup-delay-us = <150>;
+ gpio = <&tlmm_pinmux 34 0>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ /* 1.8V regulator for A2B transceiver */
+ a2b_vreg: regulator-a2b-lp3996 {
+ compatible = "regulator-fixed";
+ regulator-name = "a2b_vreg";
+ startup-delay-us = <300>;
+ gpio = <&tlmm_pinmux 96 0>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ /* 1.8V/3.3V regulator for gyro/accel */
+ gyro_vreg: regulator-gyro-tlv7103318 {
+ compatible = "regulator-fixed";
+ regulator-name = "gyro_vreg";
+ startup-delay-us = <100>;
+ gpio = <&tlmm_pinmux 99 0>;
+ enable-active-high;
+ regulator-always-on;
+ };
+};
+
+&tlmm_pinmux {
+ /* Set these up as hogs */
+ pinctrl-names = "default";
+ pinctrl-0 = <&ant_switch_gpio1>, <&ant_switch_gpio2>,
+ <&ant_switch_gpio3>, <ð_can_supply_gpio>,
+ <&oabr_enable_gpio>;
+
+ periph_vreg_gpio: periph_vreg_gpio {
+ mux {
+ pins = "gpio9";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio9";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ /* This gpio controls ETH supply on v1 and CAN supply on v2 */
+ eth_can_supply_gpio: eth_can_supply_gpio {
+ mux {
+ pins = "gpio69";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio69";
+ drive-strength = <2>;
+ output-high;
+ bias-pull-up;
+ };
+ };
+
+ oabr_enable_gpio: oabr_enable_gpio {
+ mux {
+ pins = "gpio29";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio29";
+ drive-strength = <2>;
+ output-high;
+ bias-pull-up;
+ };
+ };
+
+ pmx_sec_mi2s_aux {
+ sec_ws_sleep: sec_ws_sleep {
+ mux {
+ pins = "gpio20";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio20";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ sec_sck_sleep: sec_sck_sleep {
+ mux {
+ pins = "gpio23";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio23";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ sec_dout_sleep: sec_dout_sleep {
+ mux {
+ pins = "gpio22";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio22";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ sec_ws_active_master: sec_ws_active_master {
+ mux {
+ pins = "gpio20";
+ function = "sec_mi2s_ws_b";
+ };
+
+ config {
+ pins = "gpio20";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ output-high;
+ };
+ };
+
+ sec_sck_active_master: sec_sck_active_master {
+ mux {
+ pins = "gpio23";
+ function = "sec_mi2s_sck_b";
+ };
+
+ config {
+ pins = "gpio23";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ output-high;
+ };
+ };
+
+ sec_ws_active_slave: sec_ws_active_slave {
+ mux {
+ pins = "gpio20";
+ function = "sec_mi2s_ws_b";
+ };
+
+ config {
+ pins = "gpio20";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ };
+ };
+
+ sec_sck_active_slave: sec_sck_active_slave {
+ mux {
+ pins = "gpio23";
+ function = "sec_mi2s_sck_b";
+ };
+
+ config {
+ pins = "gpio23";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ };
+ };
+
+ sec_dout_active: sec_dout_active {
+ mux {
+ pins = "gpio22";
+ function = "sec_mi2s_data1_b";
+ };
+
+ config {
+ pins = "gpio22";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ output-high;
+ };
+ };
+ };
+
+ pmx_sec_mi2s_aux_din {
+ sec_din_sleep: sec_din_sleep {
+ mux {
+ pins = "gpio21";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio21";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ sec_din_active: sec_din_active {
+ mux {
+ pins = "gpio21";
+ function = "sec_mi2s_data0_b";
+ };
+
+ config {
+ pins = "gpio21";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL */
+ };
+ };
+ };
+
+ /* Pins for the antenna switch matrix */
+ pmx_antenna_switch_matrix {
+ ant_switch_gpio1: ant_switch_gpio1 {
+ mux {
+ pins = "gpio31";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio31";
+ drive-strength = <2>;
+ output-low;
+ bias-disable;
+ };
+ };
+
+ ant_switch_gpio2: ant_switch_gpio2 {
+ mux {
+ pins = "gpio32";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio32";
+ drive-strength = <2>;
+ output-high;
+ bias-pull-up;
+ };
+ };
+
+ ant_switch_gpio3: ant_switch_gpio3 {
+ mux {
+ pins = "gpio33";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio33";
+ drive-strength = <2>;
+ output-high;
+ bias-pull-up;
+ };
+ };
+ };
+
+ bmi160_int1_default: bmi160_int1_default {
+ mux {
+ pins = "gpio81";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio81";
+ drive-strength = <16>; /* 16 mA */
+ bias-pull-down; /* pull down */
+ };
+ };
+
+ bmi160_int2_default: bmi160_int2_default {
+ mux {
+ pins = "gpio94";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio94";
+ drive-strength = <16>; /* 16 mA */
+ bias-pull-down; /* pull down */
+ };
+ };
+
+ i2c_1b {
+ i2c_1b_active: i2c_1b_active {
+ mux {
+ pins = "gpio84", "gpio85";
+ function = "blsp_i2c1";
+ };
+
+ config {
+ pins = "gpio84", "gpio85";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_1b_sleep: i2c_1b_sleep {
+ mux {
+ pins = "gpio84", "gpio85";
+ function = "blsp_i2c1";
+ };
+
+ config {
+ pins = "gpio84", "gpio85";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ can_reset {
+ can_rst_on: rst_on {
+ mux {
+ pins = "gpio89";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio89";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-up;
+ };
+ };
+
+ can_rst_off: rst_off {
+ mux {
+ pins = "gpio89";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio89";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-up;
+ output-high;
+ };
+ };
+ };
+};
+
+&cnss_pcie {
+ vdd-wlan-io-supply = <&wlan_ext_vreg>;
+ /delete-property/ vdd-wlan-xtal-supply;
+ /delete-property/ vdd-wlan-xtal-aon-supply;
+};
+
+/* BLE serial (no HCI) */
+&blsp1_uart1 {
+ status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_console_active>;
+};
+
+/* Console conflicts with periph_vreg (GPIO_9) */
+&blsp1_uart3 {
+ status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_console_active>;
+};
+
+/* BT classic */
+&blsp1_uart2_hs {
+ status = "ok";
+};
+
+&i2c_1 {
+ status = "ok";
+ pinctrl-0 = <&i2c_1b_active>;
+ pinctrl-1 = <&i2c_1b_sleep>;
+};
+
+&i2c_3 {
+ status = "ok";
+
+ wcd9xxx_codec@d {
+ status = "disabled";
+ };
+
+ tlv320aic3x_codec: tlv320aic3x@18 {
+ compatible = "ti,tlv320aic3x";
+ reg = <0x18>;
+ gpio-reset = <&tlmm_pinmux 90 0>;
+ AVDD-supply = <&codec_vreg>;
+ IOVDD-supply = <&pmd9650_l6>;
+ };
+
+ lsm330-gyro@6a {
+ compatible = "st,lsm330-gyro";
+ reg = <0x6a>;
+ };
+
+ lsm330-accel@1d {
+ compatible = "st,lsm330-accel";
+ reg = <0x1d>;
+ };
+};
+
+&spi_4 {
+ status = "ok";
+ /delete-property/ qcom,use-bam;
+};
+
+&usb3 {
+ qcom,charging-disabled;
+};
+
+/* Needed by blsp1_uart1 (BLE) */
+&pmd9650_l13 {
+ regulator-always-on;
+};
+
+&pmd9650_gpios {
+ gpio@c000 { /* GPIO 1 - PCIESW_EN */
+ status = "ok";
+ qcom,mode = <1>; /* Digital output*/
+ qcom,output-type = <0>; /* CMOS logic */
+ qcom,invert = <1>; /* Output high */
+ qcom,vin-sel = <1>; /* 1.8 V */
+ qcom,src-sel = <0>; /* Constant */
+ qcom,out-strength = <1>; /* High drive strength */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+
+ gpio@c100 { /* GPIO 2 - VADC */
+ /* GPIO should be left off, and in the high
+ * impedance state when the pin is used with the VADC
+ */
+ status = "ok";
+ qcom,master-en = <0>; /* DISABLE GPIO */
+ };
+
+ gpio@c200 { /* GPIO 3 - CAN_ETH_EN, CAN on v1 and ETH on v2 */
+ status = "ok";
+ qcom,mode = <1>; /* Digital output*/
+ qcom,output-type = <0>; /* CMOS logic */
+ qcom,invert = <1>; /* Output high */
+ qcom,vin-sel = <1>; /* 1.8 V */
+ qcom,src-sel = <0>; /* Constant */
+ qcom,out-strength = <1>; /* High drive strength */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+
+ gpio@c400 { /* GPIO 5 - USB_ID */
+ status = "ok";
+ qcom,mode = <0>; /* Digital input */
+ qcom,pull = <1>; /* Pull up 1.5 uA */
+ qcom,vin-sel = <1>; /* 1.8 V */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+
+ gpio@c500 { /* GPIO 6 - Rome 3.3V control */
+ status = "ok";
+ qcom,mode = <1>; /* Digital output*/
+ qcom,output-type = <0>; /* CMOS logic */
+ qcom,invert = <1>; /* Output high */
+ qcom,vin-sel = <0>; /* VPH_PWR */
+ qcom,src-sel = <0>; /* Constant */
+ qcom,out-strength = <1>; /* High drive strength */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+
+ gpio@c700 { /* GPIO 8 - BT_EN */
+ status = "ok";
+ qcom,mode = <1>; /* Digital output*/
+ qcom,pull = <4>; /* Pulldown 10uA */
+ qcom,vin-sel = <0>; /* VPH_PWR */
+ qcom,src-sel = <0>; /* GPIO */
+ qcom,invert = <0>; /* Invert */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+};
+
+&pmd9650_vadc {
+ chan@83 {
+ label = "vph_pwr";
+ reg = <0x83>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@4c {
+ label = "xo_therm_buf";
+ reg = <0x4c>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@53 {
+ label = "ambient_therm";
+ reg = <0x53>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@4d {
+ label = "mdm_case_therm";
+ reg = <0x4d>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@4e {
+ label = "pa_therm1";
+ reg = <0x4e>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@4f {
+ label = "pa_therm2";
+ reg = <0x4f>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-coresight.dtsi b/arch/arm/boot/dts/qcom/mdm9650-coresight.dtsi
new file mode 100644
index 0000000..81ef261
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-coresight.dtsi
@@ -0,0 +1,467 @@
+/* Copyright (c) 2015-2018, 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 {
+ tmc_etr: tmc@828000 {
+ compatible = "arm,coresight-tmc";
+ reg = <0x828000 0x1000>,
+ <0x884000 0x15000>;
+ reg-names = "tmc-base", "bam-base";
+ interrupts = <0 166 0>;
+ interrupt-names = "byte-cntr-irq";
+
+ qcom,memory-size = <0x100000>;
+ qcom,sg-enable;
+
+ coresight-id = <1>;
+ coresight-name = "coresight-tmc-etr";
+ coresight-nr-inports = <1>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ replicator: replicator@3026000 {
+ compatible = "qcom,coresight-replicator";
+ reg = <0x826000 0x1000>;
+ reg-names = "replicator-base";
+
+ coresight-id = <2>;
+ coresight-name = "coresight-replicator";
+ coresight-nr-inports = <1>;
+ coresight-outports = <0>;
+ coresight-child-list = <&tmc_etr>;
+ coresight-child-ports = <0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ tmc_etf: tmc@827000 {
+ compatible = "arm,coresight-tmc";
+ reg = <0x827000 0x1000>;
+ reg-names = "tmc-base";
+
+ coresight-id = <3>;
+ coresight-name = "coresight-tmc-etf";
+ coresight-nr-inports = <1>;
+ coresight-outports = <0>;
+ coresight-child-list = <&replicator>;
+ coresight-child-ports = <0>;
+ coresight-default-sink;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ funnel_merge: funnel@825000 {
+ compatible = "arm,coresight-funnel";
+ reg = <0x825000 0x1000>;
+ reg-names = "funnel-base";
+
+ coresight-id = <4>;
+ coresight-name = "coresight-funnel-merg";
+ coresight-nr-inports = <2>;
+ coresight-outports = <0>;
+ coresight-child-list = <&tmc_etf>;
+ coresight-child-ports = <0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ funnel_in0: funnel@821000 {
+ compatible = "arm,coresight-funnel";
+ reg = <0x821000 0x1000>;
+ reg-names = "funnel-base";
+
+ coresight-id = <5>;
+ coresight-name = "coresight-funnel-in0";
+ coresight-nr-inports = <8>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_merge>;
+ coresight-child-ports = <0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ funnel_in1: funnel@822000 {
+ compatible = "arm,coresight-funnel";
+ reg = <0x822000 0x1000>;
+ reg-names = "funnel-base";
+
+ coresight-id = <6>;
+ coresight-name = "coresight-funnel-in1";
+ coresight-nr-inports = <8>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_merge>;
+ coresight-child-ports = <1>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ modem_etm0 {
+ compatible = "qcom,coresight-remote-etm";
+
+ coresight-id = <7>;
+ coresight-name = "coresight-modem-etm0";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_in1>;
+ coresight-child-ports = <6>;
+
+ qcom,inst-id = <2>;
+ };
+
+ rpm_etm0 {
+ compatible = "qcom,coresight-remote-etm";
+
+ coresight-id = <8>;
+ coresight-name = "coresight-rpm-etm0";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_in0>;
+ coresight-child-ports = <0>;
+
+ qcom,inst-id = <4>;
+ };
+
+ etm0: etm@842000 {
+ compatible = "arm,coresight-etm";
+ reg = <0x842000 0x1000>;
+ reg-names = "etm-base";
+
+ coresight-id = <9>;
+ coresight-name = "coresight-etm0";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_in1>;
+ coresight-child-ports = <7>;
+ coresight-etm-cpu = <&CPU0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ csr: csr@801000 {
+ compatible = "qcom,coresight-csr";
+ reg = <0x801000 0x1000>;
+ reg-names = "csr-base";
+
+ coresight-id = <11>;
+ coresight-name = "coresight-csr";
+ coresight-nr-inports = <0>;
+
+ qcom,blk-size = <1>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ stm: stm@802000 {
+ compatible = "arm,coresight-stm";
+ reg = <0x802000 0x1000>,
+ <0x9280000 0x180000>;
+ reg-names = "stm-base", "stm-data-base";
+
+ coresight-id = <12>;
+ coresight-name = "coresight-stm";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_in0>;
+ coresight-child-ports = <7>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ dbgui: dbgui@86d000 {
+ compatible = "qcom,coresight-dbgui";
+ reg = <0x86d000 0x1000>;
+ reg-names = "dbgui-base";
+
+ coresight-id = <13>;
+ coresight-name = "coresight-dbgui";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_in1>;
+ coresight-child-ports = <4>;
+
+ qcom,dbgui-addr-offset = <0x30>;
+ qcom,dbgui-data-offset = <0xb0>;
+ qcom,dbgui-size = <0x20>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ tpda: tpda@803000 {
+ compatible = "qcom,coresight-tpda";
+ reg = <0x803000 0x1000>;
+ reg-names = "tpda-base";
+
+ coresight-id = <14>;
+ coresight-name = "coresight-tpda";
+ coresight-nr-inports = <32>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_in0>;
+ coresight-child-ports = <6>;
+
+ qcom,tpda-atid = <65>;
+ qcom,cmb-elem-size = <0 8>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ tpda_modem: tpda@3003000 {
+ compatible = "qcom,coresight-tpda";
+ reg = <0x83b000 0x1000>;
+ reg-names = "tpda-base";
+
+ coresight-id = <15>;
+ coresight-name = "coresight-tpda-modem";
+ coresight-nr-inports = <32>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_in1>;
+ coresight-child-ports = <5>;
+
+ qcom,tpda-atid = <66>;
+ qcom,dsb-elem-size = <0 32>;
+ qcom,cmb-elem-size = <0 8>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ tpdm_dcc: tpdm@864000 {
+ compatible = "qcom,coresight-tpdm";
+ reg = <0x864000 0x1000>;
+ reg-names = "tpdm-base";
+
+ coresight-id = <16>;
+ coresight-name = "coresight-tpdm-dcc";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&tpda>;
+ coresight-child-ports = <0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ tpdm_modem: tpdm@83a000 {
+ compatible = "qcom,coresight-tpdm";
+ reg = <0x83a000 0x1000>;
+ reg-names = "tpdm-base";
+
+ coresight-id = <17>;
+ coresight-name = "coresight-tpdm-modem";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&tpda_modem>;
+ coresight-child-ports = <0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ cti0: cti@810000 {
+ compatible = "arm,coresight-cti";
+ reg = <0x810000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <18>;
+ coresight-name = "coresight-cti0";
+ coresight-nr-inports = <0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ cti1: cti@811000 {
+ compatible = "arm,coresight-cti";
+ reg = <0x811000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <19>;
+ coresight-name = "coresight-cti1";
+ coresight-nr-inports = <0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ cti2: cti@812000 {
+ compatible = "arm,coresight-cti";
+ reg = <0x812000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <20>;
+ coresight-name = "coresight-cti2";
+ coresight-nr-inports = <0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+
+ qcom,cti-gpio-trigout = <4>;
+ pinctrl-names = "cti-trigout-pctrl";
+ pinctrl-0 = <&trigout_a>;
+ };
+
+ cti3: cti@813000 {
+ compatible = "arm,coresight-cti";
+ reg = <0x813000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <21>;
+ coresight-name = "coresight-cti3";
+ coresight-nr-inports = <0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ cti4: cti@814000 {
+ compatible = "arm,coresight-cti";
+ reg = <0x814000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <22>;
+ coresight-name = "coresight-cti4";
+ coresight-nr-inports = <0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ cti5: cti@815000 {
+ compatible = "arm,coresight-cti";
+ reg = <0x815000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <23>;
+ coresight-name = "coresight-cti5";
+ coresight-nr-inports = <0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ cti6: cti@816000 {
+ compatible = "arm,coresight-cti";
+ reg = <0x816000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <24>;
+ coresight-name = "coresight-cti6";
+ coresight-nr-inports = <0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ cti_modem_cpu0: cti@8390000 {
+ compatible = "arm,coresight-cti";
+ reg = <0x839000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <25>;
+ coresight-name = "coresight-cti-modem-cpu0";
+ coresight-nr-inports = <0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ cti_pmu_cpu0: cti@841000 {
+ compatible = "arm,coresight-cti";
+ reg = <0x841000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <26>;
+ coresight-name = "coresight-cti-pmu-cpu0";
+ coresight-nr-inports = <0>;
+ coresight-cti-cpu = <&CPU0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ cti_cpu0: cti@843000 {
+ compatible = "arm,coresight-cti";
+ reg = <0x843000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-id = <27>;
+ coresight-name = "coresight-cti-cpu0";
+ coresight-nr-inports = <0>;
+ coresight-cti-cpu = <&CPU0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ hwevent: hwevent@86c000 {
+ compatible = "qcom,coresight-hwevent";
+ reg = <0x0086c000 0x148>,
+ <0x08af8860 0x4>,
+ <0x0200c000 0x4>,
+ <0x0200c008 0x20>,
+ <0x08b05014 0x4>,
+ <0x0408200c 0x4>,
+ <0X0086cfb0 0x4>,
+ <0X00801fb0 0x4>;
+ reg-names = "qdss-wrapper",
+ "usb30",
+ "spmi-test",
+ "spmi-events",
+ "usb30-bam",
+ "mss",
+ "qdss-wrapper-expd-lockaccess",
+ "qdss-apb-csr-lockaccess";
+
+ coresight-id = <28>;
+ coresight-name = "coresight-hwevent";
+ coresight-nr-inports = <0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi b/arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi
new file mode 100644
index 0000000..c2627e1
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi
@@ -0,0 +1,299 @@
+/* Copyright (c) 2017-2018, 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/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "mdm9650-v1.1.dtsi"
+#include "mdm9650-pinctrl.dtsi"
+
+/ {
+ aliases {
+ serial0 = &blsp1_uart3;
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ status {
+ gpios = <&tlmm_pinmux 14 0>;
+ default-state = "on";
+ };
+ };
+};
+
+&soc {
+ sound {
+ status = "disabled";
+ };
+
+ usb_detect {
+ compatible = "qcom,gpio-usbdetect";
+ interrupt-parent = <&spmi_bus>;
+ interrupts = <0x0 0x0d 0x0>; /* PMD9655 VBUS DETECT */
+ interrupt-names = "vbus_det_irq";
+ };
+
+ can_vreg: regulator-can-tps65051 {
+ compatible = "regulator-fixed";
+ regulator-name = "can_vreg";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ startup-delay-us = <920>;
+ gpio = <&tlmm_pinmux 69 0>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ pps {
+ use-system-time-ts;
+ };
+};
+
+&cnss_pcie {
+ status = "disabled";
+};
+
+&blsp1_uart3 {
+ status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_console_active>;
+};
+
+&i2c_3 {
+ status = "ok";
+
+ wcd9xxx_codec@d {
+ status = "disabled";
+ };
+};
+
+&spi_1 {
+ status = "ok";
+ /delete-property/ qcom,use-bam;
+};
+
+&spi_2 {
+ status = "ok";
+};
+
+&qnand_1 {
+ status = "ok";
+};
+
+&usb3 {
+ qcom,charging-disabled;
+};
+
+&pcie_ep {
+ status = "ok";
+ perst-gpio = <&tlmm_pinmux 60 0>;
+ wake-gpio = <&tlmm_pinmux 61 0>;
+ clkreq-gpio = <&tlmm_pinmux 64 0>;
+ mdm2apstatus-gpio = <&tlmm_pinmux 20 0>;
+ /delete-property/ qcom,pcie-perst-enum;
+};
+
+&pcie0 {
+ status = "disabled";
+};
+
+&cnss_pcie {
+ status = "disabled";
+};
+
+&mhi_device {
+ status = "ok";
+};
+
+/* pinctrl redefinitions */
+&bmi160_int1_default {
+ mux {
+ pins = "gpio81";
+ };
+ config {
+ pins = "gpio81";
+ };
+};
+
+&bmi160_int2_default {
+ mux {
+ pins = "gpio94";
+ };
+ config {
+ pins = "gpio94";
+ };
+};
+
+&can_rst_on {
+ mux {
+ pins = "gpio89";
+ };
+ config {
+ pins = "gpio89";
+ };
+};
+
+&can_rst_off {
+ mux {
+ pins = "gpio89";
+ };
+ config {
+ pins = "gpio89";
+ };
+};
+
+&pcie_ep_perst_default {
+ mux {
+ pins = "gpio60";
+ };
+ config {
+ pins = "gpio60";
+ };
+};
+
+&pcie0_mdm2apstatus_default {
+ mux {
+ pins = "gpio20";
+ };
+ config {
+ pins = "gpio20";
+ bias-disable;
+ /delete-property/ bias-pull-down;
+ };
+};
+
+/* Needed by spi_1 */
+&pmd9650_l13 {
+ regulator-always-on;
+};
+
+&pmd9650_gpios {
+ gpio@c000 { /* GPIO 1 - MDM2AP_VDD_MIN */
+ status = "ok";
+ qcom,mode = <1>; /* Digital output*/
+ qcom,pull = <4>; /* Pulldown 10uA */
+ qcom,vin-sel = <0>; /* VPH_PWR */
+ qcom,src-sel = <0>; /* GPIO */
+ qcom,invert = <0>; /* Invert */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+
+ gpio@c100 { /* GPIO 2 - VADC */
+ /* GPIO should be left off, and in the high
+ * impedance state when the pin is used with the VADC
+ */
+ status = "ok";
+ qcom,master-en = <0>; /* DISABLE GPIO */
+ };
+
+ gpio@c200 { /* GPIO 3 - MDM2AP_VDD_WAKEUP */
+ status = "ok";
+ qcom,mode = <1>; /* Digital output*/
+ qcom,pull = <4>; /* Pulldown 10uA */
+ qcom,vin-sel = <0>; /* VPH_PWR */
+ qcom,src-sel = <0>; /* GPIO */
+ qcom,invert = <0>; /* Invert */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+
+ gpio@c400 { /* GPIO 5 - USB_ID */
+ status = "ok";
+ qcom,mode = <0>; /* Digital input */
+ qcom,pull = <1>; /* Pull up 1.5 uA */
+ qcom,vin-sel = <1>; /* 1.8 V */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+
+ gpio@c800 { /* GPIO 9 - CAN_EN - not used */
+ /* Set as input since CAN_EN is being set
+ * from MDM GPIO, same line goes to this pin
+ */
+ status = "ok";
+ qcom,mode = <0>; /* Digital input */
+ qcom,pull = <5>; /* No pull */
+ qcom,vin-sel = <1>; /* 1.8 V */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+};
+
+&pmd9650_vadc {
+ chan@83 {
+ label = "vph_pwr";
+ reg = <0x83>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@4c {
+ label = "xo_therm_buf";
+ reg = <0x4c>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@53 {
+ label = "ambient_therm";
+ reg = <0x53>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@4d {
+ label = "mdm_case_therm";
+ reg = <0x4d>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@4e {
+ label = "pa_therm1";
+ reg = <0x4e>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@4f {
+ label = "pa_therm2";
+ reg = <0x4f>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-display.dtsi b/arch/arm/boot/dts/qcom/mdm9650-display.dtsi
new file mode 100644
index 0000000..367c290e
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-display.dtsi
@@ -0,0 +1,36 @@
+/* Copyright (c) 2015-2018, 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.
+ */
+
+/ {
+ mdss_qpic: qcom,msm_qpic@7980000 {
+ compatible = "qcom,mdss_qpic";
+ reg = <0x7980000 0x24000>;
+ reg-names = "qpic_base";
+ interrupts = <0 251 0>;
+
+ qcom,msm-bus,name = "mdss_qpic";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+
+ qcom,msm-bus,vectors-KBps =
+ <91 512 0 0>,
+ /* Voting for max b/w on PNOC bus for now */
+ <91 512 400000 800000>;
+
+ vdd-supply = <&pmd9650_l6>;
+ avdd-supply = <&pmd9650_l12>;
+
+ clock-names = "core_clk", "core_a_clk";
+ clocks = <&clock_gcc clk_qpic_clk>,
+ <&clock_gcc clk_qpic_a_clk>;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-ion.dtsi b/arch/arm/boot/dts/qcom/mdm9650-ion.dtsi
new file mode 100644
index 0000000..aab5f06
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-ion.dtsi
@@ -0,0 +1,36 @@
+/* Copyright (c) 2014-2015, 2018, 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 {
+ qcom,ion {
+ compatible = "qcom,msm-ion";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,ion-heap@25 {
+ reg = <25>;
+ qcom,ion-heap-type = "SYSTEM";
+ };
+
+ qcom,ion-heap@28 { /* AUDIO HEAP */
+ reg = <28>;
+ memory-region = <&audio_mem>;
+ qcom,ion-heap-type = "DMA";
+ };
+
+ qcom,ion-heap@27 { /* QSEECOM HEAP */
+ reg = <27>;
+ memory-region = <&qseecom_mem>;
+ qcom,ion-heap-type = "DMA";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-mtp.dtsi b/arch/arm/boot/dts/qcom/mdm9650-mtp.dtsi
new file mode 100644
index 0000000..da89cca
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-mtp.dtsi
@@ -0,0 +1,195 @@
+/* Copyright (c) 2015-2018, 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/irq.h>
+#include "mdm9650.dtsi"
+#include "mdm9650-pinctrl.dtsi"
+#include "mdm9650-display.dtsi"
+#include "qpic-panel-ili-hvga.dtsi"
+
+&blsp1_uart3 {
+ status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_console_active>;
+};
+
+&blsp1_uart2_hs {
+ status = "ok";
+};
+
+&i2c_3 {
+ status = "ok";
+ smb1351_otg_supply: smb1351-charger@55 {
+ compatible = "qcom,smb1351-charger";
+ reg = <0x55>;
+ interrupt-parent = <&tlmm_pinmux>;
+ interrupts = <83 IRQ_TYPE_LEVEL_LOW>;
+ qcom,float-voltage-mv = <4200>;
+ qcom,charging-timeout = <1536>;
+ qcom,recharge-thresh-mv = <200>;
+ qcom,iterm-ma = <100>;
+ regulator-name = "smb1351_otg_supply";
+ pinctrl-names = "default";
+ pinctrl-0 = <&smb_stat_active>;
+ qcom,id-line-not-connected;
+ qcom,switch-freq = <2>;
+ };
+};
+
+&pmd9650_gpios {
+ gpio@c100 { /* GPIO 2 - VADC */
+ /* GPIO should be left off, and in the high
+ * impedance state when the pin is used with the VADC
+ */
+ status = "ok";
+ qcom,master-en = <0>; /* DISABLE GPIO */
+ };
+
+ gpio@c200 { /* GPIO 3 - LED */
+ status = "ok";
+ qcom,master-en = <0>; /* Disable GPIO */
+ };
+
+ gpio@c400 { /* GPIO 5 - USB_ID */
+ status = "ok";
+ qcom,mode = <0>; /* Digital input */
+ qcom,pull = <1>; /* Pull up 1.5 uA */
+ qcom,vin-sel = <1>; /* 1.8 V */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+
+ gpio@c500 { /* GPIO 6 - Rome 3.3V control */
+ status = "ok";
+ qcom,mode = <1>; /* Digital output*/
+ qcom,output-type = <0>; /* CMOS logic */
+ qcom,invert = <1>; /* Output high */
+ qcom,vin-sel = <0>; /* VPH_PWR */
+ qcom,src-sel = <0>; /* Constant */
+ qcom,out-strength = <1>; /* High drive strength */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+
+ gpio@c700 { /* GPIO 8 - BT_EN */
+ status = "ok";
+ qcom,mode = <1>; /* Digital output*/
+ qcom,pull = <4>; /* Pulldown 10uA */
+ qcom,vin-sel = <0>; /* VPH_PWR */
+ qcom,src-sel = <0>; /* GPIO */
+ qcom,invert = <0>; /* Invert */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+};
+
+&pmd9650_misc {
+ qcom,pwm-sel = <2>; /* PWM2 */
+ qcom,enable-gp-driver; /* Enable GP */
+};
+
+&pmd9650_pwm_1 {
+ status = "ok";
+};
+
+&pmd9650_pwm_2 {
+ status = "ok";
+};
+
+&qnand_1 {
+ status = "ok";
+};
+
+&usb3 {
+ vbus_dwc3-supply = <&smb1351_otg_supply>;
+ cpe-gpio = <&tlmm_pinmux 87 0>;
+};
+
+&pmd9650_vadc {
+ chan@83 {
+ label = "vph_pwr";
+ reg = <0x83>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@4c {
+ label = "xo_therm_buf";
+ reg = <0x4c>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@53 {
+ label = "ambient_therm";
+ reg = <0x53>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@4d {
+ label = "mdm_case_therm";
+ reg = <0x4d>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@4e {
+ label = "pa_therm1";
+ reg = <0x4e>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@4f {
+ label = "pa_therm2";
+ reg = <0x4f>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+};
+
+/* Display */
+&mdss_qpic {
+ pinctrl-names= "mdss_default", "mdss_sleep";
+ pinctrl-0 = <&mdss_cs_active &mdss_te_active &mdss_rs_active
+ &mdss_ad_active &mdss_bl_active>;
+ pinctrl-1 = <&mdss_cs_sleep &mdss_te_sleep
+ &mdss_rs_sleep &mdss_ad_sleep &mdss_bl_sleep>;
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-nand-mtp.dts b/arch/arm/boot/dts/qcom/mdm9650-nand-mtp.dts
new file mode 100644
index 0000000..e107001
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-nand-mtp.dts
@@ -0,0 +1,40 @@
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "mdm9650-mtp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. MDM 9650 MTP (NAND)";
+ compatible = "qcom,mdm9650-mtp", "qcom,mdm9650",
+ "qcom,mtp";
+ qcom,board-id = <8 0>, <8 0x100>;
+};
+
+&sdhc_1 {
+ vdd-supply = <&sdc_vreg>;
+
+ vdd-io-supply = <&pmd9650_l7>;
+ qcom,vdd-io-voltage-level = <1800000 2848000>;
+ qcom,vdd-io-current-level = <200 10000>;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>;
+ pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>;
+
+ qcom,bus-width = <4>;
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000
+ 200000000>;
+
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-pinctrl.dtsi b/arch/arm/boot/dts/qcom/mdm9650-pinctrl.dtsi
new file mode 100644
index 0000000..f3c1491
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-pinctrl.dtsi
@@ -0,0 +1,1333 @@
+/* Copyright (c) 2015-2018, 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 {
+ tlmm_pinmux: pinctrl@1000000 {
+ compatible = "qcom,mdm9650-pinctrl";
+ reg = <0x1000000 0x300000>;
+ interrupts = <0 208 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ uart1_console_active: uart1_console_active {
+ mux {
+ pins = "gpio0", "gpio1";
+ function = "blsp_uart1";
+ };
+ config {
+ pins = "gpio0", "gpio1";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ trigout_a: trigout_a {
+ mux {
+ pins = "gpio92";
+ function = "qdss_cti";
+ };
+ config {
+ pins = "gpio92";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ uart2_console_active: uart2_console_active {
+ mux {
+ pins = "gpio4", "gpio5";
+ function = "blsp_uart2";
+ };
+ config {
+ pins = "gpio4", "gpio5";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ uart3_console_active: uart3_console_active {
+ mux {
+ pins = "gpio8", "gpio9";
+ function = "blsp_uart3";
+ };
+ config {
+ pins = "gpio8", "gpio9";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ uart3_console_sleep: uart3_console_sleep {
+ mux {
+ pins = "gpio8", "gpio9";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio8", "gpio9";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ /* I2C CONFIGURATION */
+ i2c_1 {
+ i2c_1_active: i2c_1_active {
+ mux {
+ pins = "gpio2", "gpio3";
+ function = "blsp_i2c1";
+ };
+
+ config {
+ pins = "gpio2", "gpio3";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_1_sleep: i2c_1_sleep {
+ mux {
+ pins = "gpio2", "gpio3";
+ function = "blsp_i2c1";
+ };
+
+ config {
+ pins = "gpio2", "gpio3";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ i2c_2 {
+ i2c_2_active: i2c_2_active {
+ mux {
+ pins = "gpio6", "gpio7";
+ function = "blsp_i2c2";
+ };
+
+ config {
+ pins = "gpio6", "gpio7";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_2_sleep: i2c_2_sleep {
+ mux {
+ pins = "gpio6", "gpio7";
+ function = "blsp_i2c2";
+ };
+
+ config {
+ pins = "gpio6", "gpio7";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ i2c_3 {
+ i2c_3_active: i2c_3_active {
+ mux {
+ pins = "gpio10", "gpio11";
+ function = "blsp_i2c3";
+ };
+
+ config {
+ pins = "gpio10", "gpio11";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_3_sleep: i2c_3_sleep {
+ mux {
+ pins = "gpio10", "gpio11";
+ function = "blsp_i2c3";
+ };
+
+ config {
+ pins = "gpio10", "gpio11";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ i2c_4 {
+ i2c_4_active: i2c_4_active {
+ mux {
+ pins = "gpio14", "gpio15";
+ function = "blsp_i2c4";
+ };
+
+ config {
+ pins = "gpio14", "gpio15";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_4_sleep: i2c_4_sleep {
+ mux {
+ pins = "gpio14", "gpio15";
+ function = "blsp_i2c4";
+ };
+
+ config {
+ pins = "gpio14", "gpio15";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ bmi160_int1_default: bmi160_int1_default {
+ mux {
+ pins = "gpio0";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio0";
+ drive-strength = <12>;
+ bias-pull-down;
+ };
+ };
+
+ bmi160_int2_default: bmi160_int2_default {
+ mux {
+ pins = "gpio1";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio1";
+ drive-strength = <12>;
+ bias-pull-down;
+ };
+ };
+
+ cnss_pins {
+ cnss_wlan_en_active: cnss_wlan_en_active {
+ mux {
+ pins = "gpio95";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio95";
+ drive-strength = <16>;
+ output-high;
+ bias-pull-up;
+ };
+ };
+ cnss_wlan_en_sleep: cnss_wlan_en_sleep {
+ mux {
+ pins = "gpio95";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio95";
+ drive-strength = <2>;
+ output-low;
+ bias-pull-down;
+ };
+ };
+
+ cnss_sdio_active: cnss_sdio_active {
+ mux {
+ pins = "gpio37";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio37";
+ drive-strength = <16>;
+ output-high;
+ bias-pull-up;
+ };
+ };
+
+ cnss_sdio_sleep: cnss_sdio_sleep {
+ mux {
+ pins = "gpio37";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio37";
+ drive-strength = <2>;
+ output-low;
+ bias-pull-down;
+ };
+ };
+ };
+
+ /* SPI CONFIGURATION */
+ spi_1 {
+ spi_1_active: spi_1_active {
+ mux {
+ pins = "gpio0", "gpio1", "gpio2",
+ "gpio3";
+ function = "blsp_spi1";
+ };
+
+ config {
+ pins = "gpio0", "gpio1", "gpio2",
+ "gpio3";
+ drive-strength = <6>;
+ bias-disable;
+ };
+ };
+
+ spi_1_sleep: spi_1_sleep {
+ mux {
+ pins = "gpio0", "gpio1", "gpio2",
+ "gpio3";
+ function = "blsp_spi1";
+ };
+
+ config {
+ pins = "gpio0", "gpio1", "gpio2",
+ "gpio3";
+ drive-strength = <6>;
+ bias-disable;
+ };
+ };
+ };
+
+ spi_2 {
+ spi_2_active: spi_2_active {
+ mux {
+ pins = "gpio4", "gpio5", "gpio6",
+ "gpio7";
+ function = "blsp_spi2";
+ };
+
+ config {
+ pins = "gpio4", "gpio5", "gpio6",
+ "gpio7";
+ drive-strength = <6>;
+ bias-disable;
+ };
+ };
+
+ spi_2_sleep: spi_2_sleep {
+ mux {
+ pins = "gpio4", "gpio5", "gpio6",
+ "gpio7";
+ function = "blsp_spi2";
+ };
+
+ config {
+ pins = "gpio4", "gpio5", "gpio6",
+ "gpio7";
+ drive-strength = <6>;
+ bias-disable;
+ };
+ };
+ };
+
+ spi_3 {
+ spi_3_active: spi_3_active {
+ mux {
+ pins = "gpio8", "gpio9", "gpio10",
+ "gpio11";
+ function = "blsp_spi3";
+ };
+
+ config {
+ pins = "gpio8", "gpio9", "gpio10",
+ "gpio11";
+ drive-strength = <6>;
+ bias-disable;
+ };
+ };
+
+ spi_3_sleep: spi_3_sleep {
+ mux {
+ pins = "gpio8", "gpio9", "gpio10",
+ "gpio11";
+ function = "blsp_spi3";
+ };
+
+ config {
+ pins = "gpio8", "gpio9", "gpio10",
+ "gpio11";
+ drive-strength = <6>;
+ bias-disable;
+ };
+ };
+ };
+
+ spi_4 {
+ spi_4_active: spi_4_active {
+ mux {
+ pins = "gpio16", "gpio17", "gpio18",
+ "gpio19";
+ function = "blsp_spi4";
+ };
+
+ config {
+ pins = "gpio16", "gpio17", "gpio18",
+ "gpio19";
+ drive-strength = <6>;
+ bias-disable;
+ };
+ };
+
+ spi_4_sleep: spi_4_sleep {
+ mux {
+ pins = "gpio16", "gpio17", "gpio18",
+ "gpio19";
+ function = "blsp_spi4";
+ };
+
+ config {
+ pins = "gpio16", "gpio17", "gpio18",
+ "gpio19";
+ drive-strength = <6>;
+ bias-disable;
+ };
+ };
+ };
+
+ /* SMB CONFIGURATION */
+ pmx_smb_stat {
+ smb_stat_active: smb_stat_active {
+ mux {
+ pins = "gpio83";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio83";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+ };
+
+ pcie0 {
+ pcie0_clkreq_default: pcie0_clkreq_default {
+ mux {
+ pins = "gpio64";
+ function = "pcie_clkreq";
+ };
+ config {
+ pins = "gpio64";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ pcie0_perst_default: pcie0_perst_default {
+ mux {
+ pins = "gpio60";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio60";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+
+ pcie0_wake_default: pcie0_wake_default {
+ mux {
+ pins = "gpio61";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio61";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ pcie0_mdm2apstatus_default: pcie0_mdm2apstatus_default {
+ mux {
+ pins = "gpio16";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio16";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+
+ pcie_ep_perst_default: pcie_ep_perst_default {
+ mux {
+ pins = "gpio65";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio65";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+
+ pcie_ep_wake_default: pcie_ep_wake_default {
+ mux {
+ pins = "gpio61";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio61";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+ };
+
+ /* UART HS CONFIGURATION */
+ blsp1_uart1_active: blsp1_uart1_active {
+ mux {
+ pins = "gpio0", "gpio1", "gpio2", "gpio3";
+ function = "blsp_uart1";
+ };
+
+ config {
+ pins = "gpio0", "gpio1", "gpio2", "gpio3";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart1_sleep: blsp1_uart1_sleep {
+ mux {
+ pins = "gpio0", "gpio1", "gpio2", "gpio3";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio0", "gpio1", "gpio2", "gpio3";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart2_active: blsp1_uart2_active {
+ mux {
+ pins = "gpio4", "gpio5", "gpio6", "gpio7";
+ function = "blsp_uart2";
+ };
+
+ config {
+ pins = "gpio4", "gpio5", "gpio6", "gpio7";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart2_sleep: blsp1_uart2_sleep {
+ mux {
+ pins = "gpio4", "gpio5", "gpio6", "gpio7";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio4", "gpio5", "gpio6", "gpio7";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart3_active: blsp1_uart3_active {
+ mux {
+ pins = "gpio8", "gpio9", "gpio10", "gpio11";
+ function = "blsp_uart3";
+ };
+
+ config {
+ pins = "gpio8", "gpio9", "gpio10", "gpio11";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart3_sleep: blsp1_uart3_sleep {
+ mux {
+ pins = "gpio8", "gpio9", "gpio10", "gpio11";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio8", "gpio9", "gpio10", "gpio11";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart4_active: blsp1_uart4_active {
+ mux {
+ pins = "gpio12", "gpio13", "gpio14", "gpio15";
+ function = "blsp_uart4";
+ };
+
+ config {
+ pins = "gpio12", "gpio13", "gpio14", "gpio15";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart4_sleep: blsp1_uart4_sleep {
+ mux {
+ pins = "gpio12", "gpio13", "gpio14", "gpio15";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio12", "gpio13", "gpio14", "gpio15";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart4b_active: blsp1_uart4b_active {
+ mux {
+ pins = "gpio16", "gpio17", "gpio18", "gpio19";
+ function = "blsp_uart4";
+ };
+
+ config {
+ pins = "gpio16", "gpio17", "gpio18", "gpio19";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart4b_sleep: blsp1_uart4b_sleep {
+ mux {
+ pins = "gpio16", "gpio17", "gpio18", "gpio19";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio16", "gpio17", "gpio18", "gpio19";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ mdss_cs_active: mdss_cs_active {
+ mux {
+ pins = "gpio21";
+ function = "ebi2_lcd";
+ };
+
+ config {
+ pins = "gpio21";
+ drive-strength = <10>; /* 10 mA */
+ bias-disable; /* NO pull */
+ };
+ };
+
+ mdss_cs_sleep: mdss_cs_sleep {
+ mux {
+ pins = "gpio21";
+ function = "ebi2_lcd";
+ };
+
+ config {
+ pins = "gpio21";
+ drive-strength = <2>; /* 2 mA */
+ bias-disable; /* NO pull */
+ };
+ };
+
+ mdss_te_active: mdss_te_active {
+ mux {
+ pins = "gpio22";
+ function = "ebi2_lcd";
+ };
+
+ config {
+ pins = "gpio22";
+ drive-strength = <10>; /* 10 mA */
+ bias-disable; /* NO pull */
+ };
+ };
+
+ mdss_te_sleep: mdss_te_sleep {
+ mux {
+ pins = "gpio22";
+ function = "ebi2_lcd";
+ };
+
+ config {
+ pins = "gpio22";
+ drive-strength = <2>; /* 2 mA */
+ bias-disable; /* NO pull */
+ };
+ };
+
+ mdss_rs_active: mdss_rs_active {
+ mux {
+ pins = "gpio23";
+ function = "ebi2_lcd";
+ };
+
+ config {
+ pins = "gpio23";
+ drive-strength = <10>; /* 10 mA */
+ bias-disable; /* NO pull */
+ };
+ };
+
+ mdss_rs_sleep: mdss_rs_sleep {
+ mux {
+ pins = "gpio23";
+ function = "ebi2_lcd";
+ };
+
+ config {
+ pins = "gpio23";
+ drive-strength = <2>; /* 2 mA */
+ bias-disable; /* NO pull */
+ };
+ };
+
+ mdss_ad_active: mdss_ad_active {
+ mux {
+ pins = "gpio20";
+ function = "ebi2_a";
+ };
+
+ config {
+ pins = "gpio20";
+ drive-strength = <10>; /* 10 mA */
+ bias-disable; /* NO pull */
+ };
+ };
+
+ mdss_ad_sleep: mdss_ad_sleep {
+ mux {
+ pins = "gpio20";
+ function = "ebi2_a";
+ };
+
+ config {
+ pins = "gpio20";
+ drive-strength = <2>; /* 2 mA */
+ bias-disable; /* NO pull */
+ };
+ };
+
+ mdss_bl_active: mdss_bl_active {
+ mux {
+ pins = "gpio68";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio68";
+ drive-strength = <10>; /* 10 mA */
+ bias-disable; /* NO pull */
+ output-high;
+ };
+ };
+
+ mdss_bl_sleep: mdss_bl_sleep {
+ mux {
+ pins = "gpio68";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio68";
+ drive-strength = <2>; /* 2 mA */
+ bias-disable; /* NO pull */
+ output-low;
+ };
+ };
+
+ i2s_mclk {
+ i2s_mclk_sleep: i2s_mclk_sleep {
+ mux {
+ pins = "gpio71";
+ function = "i2s_mclk";
+ };
+
+ config {
+ pins = "gpio71";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ };
+ };
+
+ i2s_mclk_active: i2s_mclk_active {
+ mux {
+ pins = "gpio71";
+ function = "i2s_mclk";
+ };
+
+ config {
+ pins = "gpio71";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ output-high;
+ };
+ };
+
+ };
+
+ pmx_pri_mi2s_aux {
+ pri_ws_sleep: pri_ws_sleep {
+ mux {
+ pins = "gpio12";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio12";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ pri_sck_sleep: pri_sck_sleep {
+ mux {
+ pins = "gpio15";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio15";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ pri_dout_sleep: pri_dout_sleep {
+ mux {
+ pins = "gpio14";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio14";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ pri_ws_active_master: pri_ws_active_master {
+ mux {
+ pins = "gpio12";
+ function = "pri_mi2s_ws_a";
+ };
+
+ config {
+ pins = "gpio12";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ output-high;
+ };
+ };
+
+ pri_sck_active_master: pri_sck_active_master {
+ mux {
+ pins = "gpio15";
+ function = "pri_mi2s_sck_a";
+ };
+
+ config {
+ pins = "gpio15";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ output-high;
+ };
+ };
+
+ pri_ws_active_slave: pri_ws_active_slave {
+ mux {
+ pins = "gpio12";
+ function = "pri_mi2s_ws_a";
+ };
+
+ config {
+ pins = "gpio12";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ };
+ };
+
+ pri_sck_active_slave: pri_sck_active_slave {
+ mux {
+ pins = "gpio15";
+ function = "pri_mi2s_sck_a";
+ };
+
+ config {
+ pins = "gpio15";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ };
+ };
+
+ pri_dout_active: pri_dout_active {
+ mux {
+ pins = "gpio14";
+ function = "pri_mi2s_data1_a";
+ };
+
+ config {
+ pins = "gpio14";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ output-high;
+ };
+ };
+ };
+
+ pmx_pri_mi2s_aux_din {
+ pri_din_sleep: pri_din_sleep {
+ mux {
+ pins = "gpio13";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio13";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ pri_din_active: pri_din_active {
+ mux {
+ pins = "gpio13";
+ function = "pri_mi2s_data0_a";
+ };
+
+ config {
+ pins = "gpio13";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL */
+ };
+ };
+ };
+
+ pmx_sec_mi2s_aux {
+ sec_ws_sleep: sec_ws_sleep {
+ mux {
+ pins = "gpio16";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio16";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ sec_sck_sleep: sec_sck_sleep {
+ mux {
+ pins = "gpio19";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio19";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ sec_dout_sleep: sec_dout_sleep {
+ mux {
+ pins = "gpio18";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio18";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ sec_ws_active_master: sec_ws_active_master {
+ mux {
+ pins = "gpio16";
+ function = "sec_mi2s_ws_a";
+ };
+
+ config {
+ pins = "gpio16";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ output-high;
+ };
+ };
+
+ sec_sck_active_master: sec_sck_active_master {
+ mux {
+ pins = "gpio19";
+ function = "sec_mi2s_sck_a";
+ };
+
+ config {
+ pins = "gpio19";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ output-high;
+ };
+ };
+
+ sec_ws_active_slave: sec_ws_active_slave {
+ mux {
+ pins = "gpio16";
+ function = "sec_mi2s_ws_a";
+ };
+
+ config {
+ pins = "gpio16";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ };
+ };
+
+ sec_sck_active_slave: sec_sck_active_slave {
+ mux {
+ pins = "gpio19";
+ function = "sec_mi2s_sck_a";
+ };
+
+ config {
+ pins = "gpio19";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ };
+ };
+
+ sec_dout_active: sec_dout_active {
+ mux {
+ pins = "gpio18";
+ function = "sec_mi2s_data1_a";
+ };
+
+ config {
+ pins = "gpio18";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ output-high;
+ };
+ };
+ };
+
+ pmx_sec_mi2s_aux_din {
+ sec_din_sleep: sec_din_sleep {
+ mux {
+ pins = "gpio17";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio17";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ sec_din_active: sec_din_active {
+ mux {
+ pins = "gpio17";
+ function = "sec_mi2s_data0_a";
+ };
+
+ config {
+ pins = "gpio17";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL */
+ };
+ };
+ };
+
+ pmx_sec_mi2s_b_aux {
+ sec_ws_b_sleep: sec_ws_b_sleep {
+ mux {
+ pins = "gpio20";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio20";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ sec_sck_b_sleep: sec_sck_b_sleep {
+ mux {
+ pins = "gpio23";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio23";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ sec_dout_b_sleep: sec_dout_b_sleep {
+ mux {
+ pins = "gpio22";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio22";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ sec_ws_b_active_master: sec_ws_b_active_master {
+ mux {
+ pins = "gpio20";
+ function = "sec_mi2s_ws_b";
+ };
+
+ config {
+ pins = "gpio20";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ output-high;
+ };
+ };
+
+ sec_sck_b_active_master: sec_sck_b_active_master {
+ mux {
+ pins = "gpio23";
+ function = "sec_mi2s_sck_b";
+ };
+
+ config {
+ pins = "gpio23";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ output-high;
+ };
+ };
+
+ sec_ws_b_active_slave: sec_ws_b_active_slave {
+ mux {
+ pins = "gpio20";
+ function = "sec_mi2s_ws_b";
+ };
+
+ config {
+ pins = "gpio20";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ };
+ };
+
+ sec_sck_b_active_slave: sec_sck_b_active_slave {
+ mux {
+ pins = "gpio23";
+ function = "sec_mi2s_sck_b";
+ };
+
+ config {
+ pins = "gpio23";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ };
+ };
+
+ sec_dout_b_active: sec_dout_b_active {
+ mux {
+ pins = "gpio22";
+ function = "sec_mi2s_data1_b";
+ };
+
+ config {
+ pins = "gpio22";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ output-high;
+ };
+ };
+ };
+
+ pmx_sec_mi2s_b_aux_din {
+ sec_din_b_sleep: sec_din_b_sleep {
+ mux {
+ pins = "gpio21";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio21";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ sec_din_b_active: sec_din_b_active {
+ mux {
+ pins = "gpio21";
+ function = "sec_mi2s_data0_b";
+ };
+
+ config {
+ pins = "gpio21";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL */
+ };
+ };
+ };
+
+ sdc1_clk_on: sdc1_clk_on {
+ config {
+ pins = "sdc1_clk";
+ bias-disable; /* NO pull */
+ drive-strength = <16>; /* 16 MA */
+ };
+ };
+
+ sdc1_clk_off: sdc1_clk_off {
+ config {
+ pins = "sdc1_clk";
+ bias-disable; /* NO pull */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ sdc1_cmd_on: sdc1_cmd_on {
+ config {
+ pins = "sdc1_cmd";
+ bias-pull-up; /* pull up */
+ drive-strength = <10>; /* 10 MA */
+ };
+ };
+
+ sdc1_cmd_off: sdc1_cmd_off {
+ config {
+ pins = "sdc1_cmd";
+ num-grp-pins = <1>;
+ bias-pull-up; /* pull up */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ sdc1_data_on: sdc1_data_on {
+ config {
+ pins = "sdc1_data";
+ bias-pull-up; /* pull up */
+ drive-strength = <10>; /* 10 MA */
+ };
+ };
+
+ sdc1_data_off: sdc1_data_off {
+ config {
+ pins = "sdc1_data";
+ bias-pull-up; /* pull up */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ sdc1_wlan_gpio {
+ sdc1_wlan_gpio_active: sdc1_wlan_gpio_active {
+ mux {
+ pins = "gpio80";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio80";
+ output-high;
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+ };
+
+ sdc1_wlan_gpio_sleep: sdc1_wlan_gpio_sleep {
+ mux {
+ pins = "gpio80";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio80";
+ drive-strength = <2>;
+ bias-pull-down;
+ output-low;
+ };
+ };
+ };
+
+ pinctrl_pps: ppsgrp{
+ mux {
+ pins = "gpio39";
+ function = "nav_dr";
+ };
+
+ config {
+ pins = "gpio39";
+ bias-pull-down;
+ };
+ };
+
+ can_reset {
+ can_rst_on: rst_on {
+ mux {
+ pins = "gpio68";
+ function = "gpio";
+ };
+
+
+ config {
+ pins = "gpio68";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-up;
+ };
+ };
+
+ can_rst_off: rst_off {
+ mux {
+ pins = "gpio68";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio68";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-up;
+ output-high;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-pm.dtsi b/arch/arm/boot/dts/qcom/mdm9650-pm.dtsi
new file mode 100644
index 0000000..f3b2626
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-pm.dtsi
@@ -0,0 +1,145 @@
+/* Copyright (c) 2015-2018, 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/msm/pm.h>
+
+&soc {
+ qcom,spm@b009000 {
+ compatible = "qcom,spm-v2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xb009000 0x1000>;
+ qcom,name = "core0";
+ qcom,cpu = <&CPU0>;
+ qcom,saw2-ver-reg = <0xfd0>;
+ qcom,saw2-cfg = <0x101>;
+ qcom,saw2-spm-dly= <0x401004>;
+ qcom,saw2-spm-ctl = <0x1>;
+ qcom,cpu-vctl-mask = <&CPU0>;
+ qcom,mode0 {
+ qcom,label = "qcom,saw2-spm-cmd-wfi";
+ qcom,sequence = [04 03 04 0f];
+ qcom,spm_en;
+ };
+ qcom,mode1 {
+ qcom,label = "qcom,saw2-spm-cmd-pc";
+ qcom,sequence = [1f 34 44 14 24 54 03
+ 54 44 14 24 3e 0f];
+ qcom,spm_en;
+ qcom,pc_mode;
+ qcom,slp_cmd_mode;
+ };
+ };
+
+ qcom,lpm-levels {
+ compatible = "qcom,lpm-levels";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,pm-cluster@0{
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ label = "system";
+ qcom,default-level = <0>;
+
+ qcom,pm-cluster-level@0 {
+ reg = <0>;
+ label = "l2-active";
+ qcom,latency-us = <100>;
+ qcom,ss-power = <8000>;
+ qcom,energy-overhead = <60100000>;
+ qcom,time-overhead = <3000>;
+ };
+
+ qcom,pm-cluster-level@1 {
+ reg = <1>;
+ label = "l2-flush-no-rpm";
+ qcom,latency-us = <2000>;
+ qcom,ss-power = <5000>;
+ qcom,energy-overhead = <60100000>;
+ qcom,time-overhead = <3000>;
+ qcom,min-child-idx = <0>;
+ };
+
+ qcom,pm-cluster-level@2 {
+ reg = <2>;
+ label = "l2-pc";
+ qcom,latency-us = <30000>;
+ qcom,ss-power = <4999>;
+ qcom,energy-overhead = <60350000>;
+ qcom,time-overhead = <7300>;
+ qcom,min-child-idx = <2>;
+ qcom,notify-rpm;
+ qcom,reset-level = <LPM_RESET_LVL_PC>;
+ };
+
+ qcom,pm-cpu {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,pm-cpu-level@0 {
+ reg = <0>;
+ qcom,spm-cpu-mode = "wfi";
+ qcom,latency-us = <100>;
+ qcom,ss-power = <8000>;
+ qcom,energy-overhead = <100000>;
+ qcom,time-overhead = <1>;
+ };
+
+ qcom,pm-cpu-level@1 {
+ reg = <1>;
+ qcom,spm-cpu-mode = "standalone_pc";
+ qcom,latency-us = <2000>;
+ qcom,ss-power = <5000>;
+ qcom,energy-overhead = <60100000>;
+ qcom,time-overhead = <3000>;
+ qcom,reset-level = <LPM_RESET_LVL_PC>;
+ };
+
+ qcom,pm-cpu-level@2 {
+ reg = <2>;
+ qcom,spm-cpu-mode = "pc";
+ qcom,latency-us = <30000>;
+ qcom,ss-power = <4999>;
+ qcom,energy-overhead = <60350000>;
+ qcom,time-overhead = <7300>;
+ qcom,reset-level = <LPM_RESET_LVL_PC>;
+ };
+ };
+ };
+ };
+
+ qcom,pm@8600664 {
+ compatible = "qcom,pm";
+ reg = <0x8600664 0x40>;
+ clocks = <&clock_cpu clk_a7ssmux>;
+ clock-names = "cpu0_clk";
+ qcom,use-sync-timer;
+ qcom,synced-clocks;
+ };
+
+ qcom,rpm-stats@2a1ba0 {
+ compatible = "qcom,rpm-stats";
+ reg = <0x2a1ba0 0x1000>;
+ reg-names = "phys_addr_base";
+ qcom,sleep-stats-version = <2>;
+ };
+
+ qcom,rpm-master-stats@60150 {
+ compatible = "qcom,rpm-master-stats";
+ reg = <0x60150 0x2030>;
+ qcom,masters = "APSS", "MPSS";
+ qcom,master-stats-version = <2>;
+ qcom,master-offset = <2560>;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-regulator.dtsi b/arch/arm/boot/dts/qcom/mdm9650-regulator.dtsi
new file mode 100644
index 0000000..d4a6cd7
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-regulator.dtsi
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2015-2018, 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/regulator/qcom,rpm-smd-regulator.h>
+
+&rpm_bus {
+ /* PMD9650 S1 = VDD_MSS supply */
+ rpm-regulator-smpa1 {
+ status = "okay";
+ pmd9650_s1: regulator-s1 {
+ regulator-name = "pmd9650_s1";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+ qcom,init-voltage = <800000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-smpa2 {
+ status = "okay";
+ pmd9650_s2: regulator-s2 {
+ regulator-name = "pmd9650_s2";
+ regulator-min-microvolt = <1256000>;
+ regulator-max-microvolt = <1256000>;
+ qcom,init-voltage = <1256000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-smpa3 {
+ status = "okay";
+ pmd9650_s3: regulator-s3 {
+ regulator-name = "pmd9650_s3";
+ regulator-min-microvolt = <1024000>;
+ regulator-max-microvolt = <1024000>;
+ qcom,init-voltage = <1024000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-smpa4 {
+ status = "okay";
+ pmd9650_s4: regulator-s4 {
+ regulator-name = "pmd9650_s4";
+ regulator-min-microvolt = <1856000>;
+ regulator-max-microvolt = <1856000>;
+ qcom,init-voltage = <1856000>;
+ status = "okay";
+ };
+ };
+
+ /* PMD9650 S5 = VDD_CX supply */
+ rpm-regulator-smpa5 {
+ status = "okay";
+ pmd9650_s5_level: regulator-s5-level {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmd9650_s5_level";
+ qcom,set = <3>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO_NO_CPR>;
+ qcom,use-voltage-level;
+ };
+
+ pmd9650_s5_level_ao: regulator-s5-level-ao {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmd9650_s5_level_ao";
+ qcom,set = <1>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO_NO_CPR>;
+ qcom,use-voltage-level;
+ };
+
+ pmd9650_s5_floor_level: regulator-s5-floor-level {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmd9650_s5_floor_level";
+ qcom,set = <3>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO_NO_CPR>;
+ qcom,use-voltage-floor-level;
+ };
+ };
+
+ rpm-regulator-ldoa1 {
+ status = "okay";
+ pmd9650_l1: regulator-l1 {
+ regulator-name = "pmd9650_l1";
+ regulator-min-microvolt = <1224000>;
+ regulator-max-microvolt = <1224000>;
+ qcom,init-voltage = <1224000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa2 {
+ status = "okay";
+ pmd9650_l2: regulator-l2 {
+ regulator-name = "pmd9650_l2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ qcom,init-voltage = <1200000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa3 {
+ status = "okay";
+ pmd9650_l3: regulator-l3 {
+ regulator-name = "pmd9650_l3";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ qcom,init-voltage = <1000000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa4 {
+ status = "okay";
+ pmd9650_l4: regulator-l4 {
+ regulator-name = "pmd9650_l4";
+ regulator-min-microvolt = <928000>;
+ regulator-max-microvolt = <928000>;
+ qcom,init-voltage = <928000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa5 {
+ status = "okay";
+ pmd9650_l5: regulator-l5 {
+ regulator-name = "pmd9650_l5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa6 {
+ status = "okay";
+ pmd9650_l6: regulator-l6 {
+ regulator-name = "pmd9650_l6";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa7 {
+ status = "okay";
+ pmd9650_l7: regulator-l7 {
+ regulator-name = "pmd9650_l7";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2848000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa8 {
+ status = "okay";
+ pmd9650_l8: regulator-l8 {
+ regulator-name = "pmd9650_l8";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ qcom,init-voltage = <1000000>;
+ status = "okay";
+ };
+ };
+
+ /* PMD9650 L9 = VDD_MX supply */
+ rpm-regulator-ldoa9 {
+ status = "okay";
+ pmd9650_l9_level: regulator-l9-level {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmd9650_l9_level";
+ qcom,set = <3>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO_NO_CPR>;
+ qcom,use-voltage-level;
+ };
+ };
+
+ rpm-regulator-ldoa10 {
+ status = "okay";
+ pmd9650_l10: regulator-l10 {
+ regulator-name = "pmd9650_l10";
+ regulator-min-microvolt = <3088000>;
+ regulator-max-microvolt = <3088000>;
+ qcom,init-voltage = <3088000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa11 {
+ status = "okay";
+ pmd9650_l11: regulator-l11 {
+ regulator-name = "pmd9650_l11";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2848000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa12 {
+ status = "okay";
+ pmd9650_l12: regulator-l12 {
+ regulator-name = "pmd9650_l12";
+ regulator-min-microvolt = <2704000>;
+ regulator-max-microvolt = <2704000>;
+ qcom,init-voltage = <2704000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa13 {
+ status = "okay";
+ pmd9650_l13: regulator-l13 {
+ regulator-name = "pmd9650_l13";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2848000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+ };
+};
+
+&soc {
+ codec_buck_vreg: codec_buck_vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "codec_1.8v";
+ regulator-always-on;
+ };
+
+ /* Rome 3.3V supply */
+ rome_vreg: rome_vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "rome_vreg";
+ startup-delay-us = <4000>;
+ enable-active-high;
+ gpio = <&pmd9650_gpios 6 0>;
+ };
+
+ /* SD card 2.95 V supply */
+ sdc_vreg: sdc_vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "sdc_vreg";
+ startup-delay-us = <4000>;
+ enable-active-high;
+ gpio = <&tlmm_pinmux 50 0>;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-smp2p.dtsi b/arch/arm/boot/dts/qcom/mdm9650-smp2p.dtsi
new file mode 100644
index 0000000..5fb7440
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-smp2p.dtsi
@@ -0,0 +1,129 @@
+/* Copyright (c) 2015-2016, 2018, 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 {
+ qcom,smp2p-modem {
+ compatible = "qcom,smp2p";
+ reg = <0xb011008 0x4>;
+ qcom,remote-pid = <1>;
+ qcom,irq-bitmask = <0x4000>;
+ interrupts = <0 27 1>;
+ };
+
+ smp2pgpio_smp2p_15_in: qcom,smp2pgpio-smp2p-15-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <15>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_15_in {
+ compatible = "qcom,smp2pgpio_test_smp2p_15_in";
+ gpios = <&smp2pgpio_smp2p_15_in 0 0>;
+ };
+
+ smp2pgpio_smp2p_15_out: qcom,smp2pgpio-smp2p-15-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <15>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_15_out {
+ compatible = "qcom,smp2pgpio_test_smp2p_15_out";
+ gpios = <&smp2pgpio_smp2p_15_out 0 0>;
+ };
+
+ smp2pgpio_smp2p_1_in: qcom,smp2pgpio-smp2p-1-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <1>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_1_in {
+ compatible = "qcom,smp2pgpio_test_smp2p_1_in";
+ gpios = <&smp2pgpio_smp2p_1_in 0 0>;
+ };
+
+ smp2pgpio_smp2p_1_out: qcom,smp2pgpio-smp2p-1-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_1_out {
+ compatible = "qcom,smp2pgpio_test_smp2p_1_out";
+ gpios = <&smp2pgpio_smp2p_1_out 0 0>;
+ };
+
+ /* ssr - inbound entry from mss. */
+ smp2pgpio_ssr_smp2p_1_in: qcom,smp2pgpio-ssr-smp2p-1-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "slave-kernel";
+ qcom,remote-pid = <1>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* ssr - outbound entry to mss. */
+ smp2pgpio_ssr_smp2p_1_out: qcom,smp2pgpio-ssr-smp2p-1-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "master-kernel";
+ qcom,remote-pid = <1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* ipa - outbound entry to mss */
+ smp2pgpio_ipa_1_out: qcom,smp2pgpio-ipa-1-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "ipa";
+ qcom,remote-pid = <1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* ipa - inbound entry from mss */
+ smp2pgpio_ipa_1_in: qcom,smp2pgpio-ipa-1-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "ipa";
+ qcom,remote-pid = <1>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-ttp.dts b/arch/arm/boot/dts/qcom/mdm9650-ttp.dts
new file mode 100644
index 0000000..4a5d0d4
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-ttp.dts
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "mdm9650-v1.1-mtp.dtsi"
+/ {
+ model = "Qualcomm Technologies, Inc. MDM 9650 TTP";
+ compatible = "qcom,mdm9650-ttp", "qcom,mdm9650", "qcom,ttp";
+ qcom,board-id = <0x1e 0>;
+};
+
+&pmd9650_l13 {
+ regulator-always-on;
+};
+
+&i2c_3 {
+ status = "ok";
+ smb1351_otg_supply: smb1351-charger@55{
+ status = "disabled";
+ };
+};
+
+&soc {
+ tlmm_pinmux: pinctrl@1000000 {
+ i2c_1 {
+ i2c_1_active {
+ config {
+ pins = "gpio2", "gpio3";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+ };
+ usb_detect {
+ compatible = "qcom,gpio-usbdetect";
+ interrupt-parent = <&spmi_bus>;
+ interrupts = <0x0 0x0d 0x0>; /* PMD9655 VBUS DETECT */
+ interrupt-names = "vbus_det_irq";
+ };
+};
+
+&usb3 {
+ cpe-gpio = <&tlmm_pinmux 87 0>;
+};
+
+&blsp1_uart4b_hs {
+ status = "ok";
+};
+
+&blsp1_uart2_hs {
+ status = "disabled";
+};
+
+&snd_tasha {
+ pinctrl-names =
+ "all_off",
+ "pri_mi2s_aux_master_active",
+ "pri_mi2s_aux_slave_active",
+ "invalid_state_1",
+ "sec_mi2s_aux_master_active",
+ "pri_master_active_sec_master_active",
+ "pri_slave_active_sec_master_active",
+ "invalid_state_2",
+ "sec_mi2s_aux_slave_active",
+ "pri_master_active_sec_slave_active",
+ "pri_slave_active_sec_slave_active";
+ pinctrl-0 = <&pri_ws_sleep &pri_sck_sleep
+ &pri_dout_sleep &pri_din_sleep
+ &sec_ws_b_sleep &sec_sck_b_sleep
+ &sec_dout_b_sleep &sec_din_b_sleep>;
+ pinctrl-1 = <&pri_ws_active_master &pri_sck_active_master
+ &pri_dout_active &pri_din_active
+ &sec_ws_b_sleep &sec_sck_b_sleep
+ &sec_dout_b_sleep &sec_din_b_sleep>;
+ pinctrl-2 = <&pri_ws_active_slave &pri_sck_active_slave
+ &pri_dout_active &pri_din_active
+ &sec_ws_b_sleep &sec_sck_b_sleep
+ &sec_dout_b_sleep &sec_din_b_sleep>;
+ pinctrl-3 = <&pri_ws_sleep &pri_sck_sleep
+ &pri_dout_sleep &pri_din_sleep
+ &sec_ws_b_sleep &sec_sck_b_sleep
+ &sec_dout_b_sleep &sec_din_b_sleep>;
+ pinctrl-4 = <&pri_ws_sleep &pri_sck_sleep
+ &pri_dout_sleep &pri_din_sleep
+ &sec_ws_b_active_master &sec_sck_b_active_master
+ &sec_dout_b_active &sec_din_b_active>;
+ pinctrl-5 = <&pri_ws_active_master &pri_sck_active_master
+ &pri_dout_active &pri_din_active
+ &sec_ws_b_active_master &sec_sck_b_active_master
+ &sec_dout_b_active &sec_din_b_active>;
+ pinctrl-6 = <&pri_ws_active_slave &pri_sck_active_slave
+ &pri_dout_active &pri_din_active
+ &sec_ws_b_active_master &sec_sck_b_active_master
+ &sec_dout_b_active &sec_din_b_active>;
+ pinctrl-7 = <&pri_ws_sleep &pri_sck_sleep
+ &pri_dout_sleep &pri_din_sleep
+ &sec_ws_b_sleep &sec_sck_b_sleep
+ &sec_dout_b_sleep &sec_din_b_sleep>;
+ pinctrl-8 = <&pri_ws_sleep &pri_sck_sleep
+ &pri_dout_sleep &pri_din_sleep
+ &sec_ws_b_active_slave &sec_sck_b_active_slave
+ &sec_dout_b_active &sec_din_b_active>;
+ pinctrl-9 = <&pri_ws_active_master &pri_sck_active_master
+ &pri_dout_active &pri_din_active
+ &sec_ws_b_active_slave &sec_sck_b_active_slave
+ &sec_dout_b_active &sec_din_b_active>;
+ pinctrl-10 = <&pri_ws_active_slave &pri_sck_active_slave
+ &pri_dout_active &pri_din_active
+ &sec_ws_b_active_slave &sec_sck_b_active_slave
+ &sec_dout_b_active &sec_din_b_active>;
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-usb.dtsi b/arch/arm/boot/dts/qcom/mdm9650-usb.dtsi
new file mode 100644
index 0000000..2b005b4
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-usb.dtsi
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2015-2018, 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 {
+ usb3: ssusb@8a00000 {
+ compatible = "qcom,dwc-usb3-msm";
+ reg = <0x08a00000 0xf8c00>,
+ <0x0007e000 0x400>;
+ reg-names = "core_base", "ahb2phy_base";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ interrupt-parent = <&usb3>;
+ interrupts = <0 1 2 3>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0x0 0xffffffff>;
+ interrupt-map = <0x0 0 &intc 0 202 0
+ 0x0 1 &intc 0 203 0
+ 0x0 2 &intc 0 180 0
+ 0x0 3 &spmi_bus 0x0 0x0 0xc4 0x0>;
+ interrupt-names = "hs_phy_irq", "ss_phy_irq", "pwr_event_irq",
+ "pmic_id_irq";
+ USB3_GDSC-supply = <&gdsc_usb30>;
+ vdda33-supply = <&pmd9650_l10>;
+ vdda18-supply = <&pmd9650_l5>;
+ qcom,usb-dbm = <&dbm_1p5>;
+
+ qcom,msm-bus,name = "usb3";
+ qcom,msm-bus,num-cases = <3>;
+ qcom,msm-bus,num-paths = <2>;
+ qcom,msm-bus,vectors-KBps =
+ <61 512 0 0>, <61 676 0 0>,
+ <61 512 0 680000>, <61 676 0 2400>,
+ <61 512 0 680000>, <61 676 0 2400>;
+ qcom,lpm-to-suspend-delay-ms = <2000>;
+
+ clocks = <&clock_gcc clk_gcc_usb30_master_clk>,
+ <&clock_gcc clk_gcc_sys_noc_usb3_axi_clk>,
+ <&clock_gcc clk_gcc_usb30_mock_utmi_clk>,
+ <&clock_gcc clk_gcc_usb30_sleep_clk>,
+ <&clock_gcc clk_cxo_dwc3_clk>,
+ <&clock_gcc clk_gcc_usb_phy_cfg_ahb_clk>;
+
+ clock-names = "core_clk", "iface_clk", "utmi_clk", "sleep_clk",
+ "xo", "cfg_ahb_clk";
+
+ qcom,core-clk-rate = <120000000>;
+ qcom,dwc-usb3-msm-tx-fifo-size = <21288>;
+ dwc3@8a00000 {
+ compatible = "snps,dwc3";
+ reg = <0x08a00000 0xcd00>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 131 0>;
+ usb-phy = <&qusb_phy>, <&ssphy>;
+ tx-fifo-resize;
+ snps,nominal-elastic-buffer;
+ snps,is-utmi-l1-suspend;
+ snps,hird-threshold = /bits/ 8 <0x0>;
+ snps,bus-suspend-enable;
+ snps,usb3-u1u2-disable;
+ snps,num-gsi-evt-buffs = <0x3>;
+ xhci-imod-value = <4000>;
+ };
+
+ qcom,usbbam@0x8B04000 {
+ compatible = "qcom,usb-bam-msm";
+ reg = <0x8b04000 0x1b000>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 132 0>;
+
+ qcom,bam-type = <0>;
+ qcom,usb-bam-fifo-baseaddr = <0x08604000>;
+ qcom,usb-bam-num-pipes = <1>;
+ qcom,ignore-core-reset-ack;
+ qcom,disable-clk-gating;
+ qcom,usb-bam-override-threshold = <0x4001>;
+ qcom,usb-bam-max-mbps-highspeed = <400>;
+ qcom,usb-bam-max-mbps-superspeed = <3600>;
+ qcom,reset-bam-on-connect;
+
+ qcom,pipe0 {
+ label = "ssusb-qdss-in-0";
+ qcom,usb-bam-mem-type = <2>;
+ qcom,dir = <1>;
+ qcom,pipe-num = <0>;
+ qcom,peer-bam = <0>;
+ qcom,peer-bam-physical-address = <0x00884000>;
+ qcom,src-bam-pipe-index = <0>;
+ qcom,dst-bam-pipe-index = <2>;
+ qcom,data-fifo-offset = <0x0>;
+ qcom,data-fifo-size = <0xc00>;
+ qcom,descriptor-fifo-offset = <0xc00>;
+ qcom,descriptor-fifo-size = <0x400>;
+ };
+ };
+ };
+
+ qusb_phy: qusb@79000 {
+ compatible = "qcom,qusb2phy";
+ reg = <0x00079000 0x180>,
+ <0x01841030 0x4>,
+ <0x01956044 0x4>;
+ reg-names = "qusb_phy_base",
+ "ref_clk_addr",
+ "tcsr_phy_clk_scheme_sel";
+ vdd-supply = <&pmd9650_l4>;
+ vdda18-supply = <&pmd9650_l5>;
+ vdda33-supply = <&pmd9650_l10>;
+ qcom,vdd-voltage-level = <0 928000 928000>;
+ qcom,qusb-phy-init-seq = <0xf8 0x80
+ 0xb3 0x84
+ 0x83 0x88
+ 0xc0 0x8c
+ 0x30 0x08
+ 0x79 0x0c
+ 0x21 0x10
+ 0x14 0x9c
+ 0x9f 0x1c
+ 0x00 0x18>;
+ phy_type = "utmi";
+ qcom,secure-level-shifter-update;
+ USB3_GDSC-supply = <&gdsc_usb30>;
+
+ clocks = <&clock_gcc clk_ln_bb_clk>,
+ <&clock_gcc clk_gcc_qusb_ref_clk>,
+ <&clock_gcc clk_gcc_usb_phy_cfg_ahb_clk>,
+ <&clock_gcc clk_gcc_qusb2a_phy_reset>,
+ <&clock_gcc clk_gcc_sys_noc_usb3_axi_clk>;
+
+ clock-names = "ref_clk_src", "ref_clk", "cfg_ahb_clk",
+ "phy_reset", "iface_clk";
+ };
+
+ ssphy: ssphy@78000 {
+ compatible = "qcom,usb-ssphy-qmp";
+ reg = <0x00078000 0x9f8>,
+ <0x01947244 0x4>,
+ <0x01956044 0x4>;
+ reg-names = "qmp_phy_base",
+ "vls_clamp_reg",
+ "tcsr_phy_clk_scheme_sel";
+ qcom,qmp-phy-init-seq = <0xac 0x14 0x1a 0x00
+ 0x34 0x08 0x08 0x00
+ 0x174 0x30 0x30 0x00
+ 0x70 0x0f 0x0f 0x00
+ 0x19c 0x01 0x01 0x00
+ 0x178 0x00 0x00 0x00
+ 0x194 0x06 0x06 0x3e8
+ 0x48 0x0f 0x0f 0x00
+ 0x3c 0x02 0x02 0x00
+ 0xd0 0x82 0x82 0x00
+ 0xdc 0x55 0x55 0x00
+ 0xe0 0x55 0x55 0x00
+ 0xe4 0x03 0x03 0x00
+ 0x78 0x0b 0x0b 0x00
+ 0x84 0x16 0x16 0x00
+ 0x90 0x28 0x28 0x00
+ 0x108 0x80 0x80 0x00
+ 0x4c 0x15 0x15 0x00
+ 0x50 0x34 0x34 0x00
+ 0x54 0x00 0x00 0x00
+ 0x18c 0x00 0x00 0x00
+ 0xcc 0x00 0x00 0x00
+ 0x128 0x00 0x00 0x00
+ 0x0c 0x0a 0x0a 0x00
+ 0x10 0x01 0x01 0x00
+ 0x1c 0x31 0x31 0x00
+ 0x20 0x01 0x01 0x00
+ 0x14 0x00 0x00 0x00
+ 0x18 0x00 0x00 0x00
+ 0x24 0xde 0xde 0x00
+ 0x28 0x07 0x07 0x00
+ 0x41c 0x06 0x06 0x00
+ 0x4d8 0x02 0x02 0x00
+ 0x4dc 0x4c 0x4c 0x00
+ 0x4e0 0xb8 0xb8 0x00
+ 0x508 0x77 0x77 0x00
+ 0x50c 0x80 0x80 0x00
+ 0x514 0x03 0x03 0x00
+ 0x51c 0x16 0x16 0x00
+ 0x510 0x0c 0x0c 0x00
+ 0x268 0x45 0x45 0x00
+ 0x2ac 0x12 0x12 0x00
+ 0x294 0x06 0x06 0x00
+ 0x824 0x15 0x15 0x00
+ 0x828 0x0e 0x0e 0x00
+ 0x8c8 0x83 0x83 0x00
+ 0x8c4 0x02 0x02 0x00
+ 0x8cc 0x09 0x09 0x00
+ 0x8d0 0xa2 0xa2 0x00
+ 0x8d4 0x85 0x85 0x00
+ 0x880 0xd1 0xd1 0x00
+ 0x884 0x1f 0x1f 0x00
+ 0x888 0x47 0x47 0x00
+ 0x864 0x1b 0x1b 0x00
+ 0x8b8 0x75 0x75 0x00
+ 0x8bc 0x13 0x13 0x00
+ 0x8b0 0x86 0x86 0x00
+ 0x8a0 0x04 0x04 0x00
+ 0x88c 0x44 0x44 0x00
+ 0x870 0xe7 0xe7 0x00
+ 0x874 0x03 0x03 0x00
+ 0x878 0x40 0x40 0x00
+ 0x87c 0x00 0x00 0x00
+ 0x9d8 0x88 0x88 0x00
+ 0xffffffff 0xffffffff 0x00 0x00>;
+ qcom,qmp-phy-reg-offset = <0x988 0x98c 0x990 0x994
+ 0x974 0x8d8 0x8dc 0x804 0x800
+ 0x808>;
+ vdd-supply = <&pmd9650_l4>;
+ core-supply = <&pmd9650_l5>;
+ qcom,vdd-voltage-level = <0 928000 928000>;
+ qcom,vbus-valid-override;
+
+ clocks = <&clock_gcc clk_gcc_usb3_aux_clk>,
+ <&clock_gcc clk_gcc_usb3_pipe_clk>,
+ <&clock_gcc clk_gcc_usb_phy_cfg_ahb_clk>,
+ <&clock_gcc clk_gcc_usb3_phy_reset>,
+ <&clock_gcc clk_gcc_usb3phy_phy_reset>,
+ <&clock_gcc clk_ln_bb_clk>,
+ <&clock_gcc clk_gcc_usb_ss_ref_clk>;
+
+ clock-names = "aux_clk", "pipe_clk", "cfg_ahb_clk",
+ "phy_reset", "phy_phy_reset",
+ "ref_clk_src", "ref_clk";
+ };
+
+ dbm_1p5: dbm@0x8af8000 {
+ compatible = "qcom,usb-dbm-1p5";
+ reg = <0x08af8000 0x300>;
+ qcom,reset-ep-after-lpm-resume;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-v1.1-mtp.dtsi b/arch/arm/boot/dts/qcom/mdm9650-v1.1-mtp.dtsi
new file mode 100644
index 0000000..508abbf
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-v1.1-mtp.dtsi
@@ -0,0 +1,183 @@
+/* Copyright (c) 2016-2018, 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/irq.h>
+#include "mdm9650-v1.1.dtsi"
+#include "mdm9650-pinctrl.dtsi"
+
+&blsp1_uart3 {
+ status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_console_active>;
+};
+
+&blsp1_uart2_hs {
+ status = "ok";
+};
+
+&i2c_3 {
+ status = "ok";
+ smb1351_otg_supply: smb1351-charger@55 {
+ compatible = "qcom,smb1351-charger";
+ reg = <0x55>;
+ interrupt-parent = <&tlmm_pinmux>;
+ interrupts = <83 IRQ_TYPE_LEVEL_LOW>;
+ qcom,float-voltage-mv = <4200>;
+ qcom,charging-timeout = <1536>;
+ qcom,recharge-thresh-mv = <200>;
+ qcom,iterm-ma = <100>;
+ regulator-name = "smb1351_otg_supply";
+ pinctrl-names = "default";
+ pinctrl-0 = <&smb_stat_active>;
+ qcom,id-line-not-connected;
+ qcom,switch-freq = <2>;
+ };
+};
+
+&pmd9650_gpios {
+ gpio@c100 { /* GPIO 2 - VADC */
+ /* GPIO should be left off, and in the high
+ * impedance state when the pin is used with the VADC
+ */
+ status = "ok";
+ qcom,master-en = <0>; /* DISABLE GPIO */
+ };
+
+ gpio@c200 { /* GPIO 3 - LED */
+ status = "ok";
+ qcom,master-en = <0>; /* Disable GPIO */
+ };
+
+ gpio@c400 { /* GPIO 5 - USB_ID */
+ status = "ok";
+ qcom,mode = <0>; /* Digital input */
+ qcom,pull = <1>; /* Pull up 1.5 uA */
+ qcom,vin-sel = <1>; /* 1.8 V */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+
+ gpio@c500 { /* GPIO 6 - Rome 3.3V control */
+ status = "ok";
+ qcom,mode = <1>; /* Digital output*/
+ qcom,output-type = <0>; /* CMOS logic */
+ qcom,invert = <1>; /* Output high */
+ qcom,vin-sel = <0>; /* VPH_PWR */
+ qcom,src-sel = <0>; /* Constant */
+ qcom,out-strength = <1>; /* High drive strength */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+
+ gpio@c700 { /* GPIO 8 - BT_EN */
+ status = "ok";
+ qcom,mode = <1>; /* Digital output*/
+ qcom,pull = <4>; /* Pulldown 10uA */
+ qcom,vin-sel = <0>; /* VPH_PWR */
+ qcom,src-sel = <0>; /* GPIO */
+ qcom,invert = <0>; /* Invert */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+};
+
+&pmd9650_misc {
+ qcom,pwm-sel = <2>; /* PWM2 */
+ qcom,enable-gp-driver; /* Enable GP */
+};
+
+&pmd9650_pwm_1 {
+ status = "ok";
+};
+
+&pmd9650_pwm_2 {
+ status = "ok";
+};
+
+&qnand_1 {
+ status = "ok";
+};
+
+&usb3 {
+ vbus_dwc3-supply = <&smb1351_otg_supply>;
+ cpe-gpio = <&tlmm_pinmux 87 0>;
+};
+
+&pmd9650_vadc {
+ chan@83 {
+ label = "vph_pwr";
+ reg = <0x83>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@4c {
+ label = "xo_therm_buf";
+ reg = <0x4c>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@53 {
+ label = "ambient_therm";
+ reg = <0x53>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@4d {
+ label = "mdm_case_therm";
+ reg = <0x4d>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@4e {
+ label = "pa_therm1";
+ reg = <0x4e>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@4f {
+ label = "pa_therm2";
+ reg = <0x4f>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-v1.1-nand-cv2x.dts b/arch/arm/boot/dts/qcom/mdm9650-v1.1-nand-cv2x.dts
new file mode 100644
index 0000000..4632607
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-v1.1-nand-cv2x.dts
@@ -0,0 +1,21 @@
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "mdm9650-cv2x.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. MDM 9650 v1.1 CV2X";
+ compatible = "qcom,mdm9650-ttp", "qcom,mdm9650", "qcom,ttp";
+ qcom,board-id = <0x1e 1>, <0x1e 0x101>;
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-v1.1-nand-mtp.dts b/arch/arm/boot/dts/qcom/mdm9650-v1.1-nand-mtp.dts
new file mode 100644
index 0000000..9fff2ae
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-v1.1-nand-mtp.dts
@@ -0,0 +1,40 @@
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "mdm9650-v1.1-mtp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. MDM 9650 v1.1 MTP (NAND)";
+ compatible = "qcom,mdm9650-mtp", "qcom,mdm9650",
+ "qcom,mtp";
+ qcom,board-id = <8 0>, <8 0x100>;
+};
+
+&sdhc_1 {
+ vdd-supply = <&sdc_vreg>;
+
+ vdd-io-supply = <&pmd9650_l7>;
+ qcom,vdd-io-voltage-level = <1800000 2848000>;
+ qcom,vdd-io-current-level = <200 10000>;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>;
+ pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>;
+
+ qcom,bus-width = <4>;
+ qcom,clk-rates = <400000 20000000 25000000
+ 50000000 100000000 200000000>;
+
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-v1.1.dtsi b/arch/arm/boot/dts/qcom/mdm9650-v1.1.dtsi
new file mode 100644
index 0000000..c02cedc
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650-v1.1.dtsi
@@ -0,0 +1,20 @@
+/* Copyright (c) 2016-2018, 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 "mdm9650.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. MDM 9650 v1.1";
+ compatible = "qcom,mdm9650";
+ qcom,msm-id = <279 0x10001>, <284 0x10001>, <285 0x10001>,
+ <286 0x10001>, <283 0x10001>;
+};
diff --git a/arch/arm/boot/dts/qcom/mdm9650.dtsi b/arch/arm/boot/dts/qcom/mdm9650.dtsi
new file mode 100644
index 0000000..fcc2377
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/mdm9650.dtsi
@@ -0,0 +1,1470 @@
+/* Copyright (c) 2015-2018, 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 "skeleton.dtsi"
+#include <dt-bindings/clock/mdm-clocks-9650.h>
+#include <dt-bindings/clock/msm-clocks-a7.h>
+#include <dt-bindings/regulator/qcom,rpm-smd-regulator.h>
+
+/ {
+ model = "Qualcomm Technologies, Inc. MDM 9650";
+ compatible = "qcom,mdm9650";
+ qcom,msm-id = <279 0x10000>, <284 0x10000>, <285 0x10000>,
+ <286 0x10000>, <283 0x10000>;
+ interrupt-parent = <&intc>;
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ peripheral1_mem: peripheral1_region@0x87800000 {
+ compatible = "removed-dma-pool";
+ no-map;
+ reg = <0x87800000 0x400000>;
+ label = "peripheral1_mem";
+ };
+
+ peripheral2_mem: peripheral2_region@0x87d00000 {
+ compatible = "removed-dma-pool";
+ no-map;
+ reg = <0x87d00000 0x300000>;
+ label = "peripheral2_mem";
+ };
+ mss_mem: mss_region@88000000 {
+ compatible = "removed-dma-pool";
+ no-map-fixup;
+ reg = <0x88000000 0x6E00000>;
+ label = "mss_mem";
+ };
+
+ audio_mem: audio_region@0 {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x400000>;
+ };
+
+ qseecom_mem: qseecom_region@0 {
+ compatible = "shared-dma-pool";
+ reusable;
+ alignment = <0x400000>;
+ size = <0x0400000>;
+ };
+ };
+
+ aliases {
+ qpic_nand1 = &qnand_1;
+ sdhc1 = &sdhc_1; /* SDC1 eMMC/SD slot */
+ };
+
+ cpus {
+ #size-cells = <0>;
+ #address-cells = <1>;
+
+ CPU0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x0>;
+ };
+ };
+
+ soc: soc { };
+};
+
+#include "mdm9650-smp2p.dtsi"
+#include "msm-gdsc.dtsi"
+#include "mdm9650-blsp.dtsi"
+#include "mdm9650-bus.dtsi"
+#include "mdm9650-coresight.dtsi"
+#include "mdm9650-ion.dtsi"
+#include "mdm9650-pm.dtsi"
+
+&soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ intc: interrupt-controller@b000000 {
+ compatible = "qcom,msm-qgic2";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x0b000000 0x1000>,
+ <0x0b002000 0x1000>;
+ };
+
+ qcom,mpm2-sleep-counter@4a3000 {
+ compatible = "qcom,mpm2-sleep-counter";
+ reg = <0x004a3000 0x1000>;
+ clock-frequency = <32768>;
+ };
+
+ qcom,msm-imem@8600000 {
+ compatible = "qcom,msm-imem";
+ reg = <0x8600000 0x1000>; /* Address and size of IMEM */
+ ranges = <0x0 0x8600000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ mem_dump_table@10 {
+ compatible = "qcom,msm-imem-mem_dump_table";
+ reg = <0x10 8>;
+ };
+
+ restart_reason@65c {
+ compatible = "qcom,msm-imem-restart_reason";
+ reg = <0x65c 4>;
+ };
+
+ boot_stats@6b0 {
+ compatible = "qcom,msm-imem-boot_stats";
+ reg = <0x6b0 32>;
+ };
+
+ pil@94c {
+ compatible = "qcom,msm-imem-pil";
+ reg = <0x94c 200>;
+ };
+ };
+
+ mss: qcom,mss@4080000{
+ compatible = "qcom,pil-q6v55-mss";
+ reg = <0x4080000 0x100>,
+ <0x194e000 0x400>,
+ <0x4180000 0x040>,
+ <0x1810000 0x004>;
+ reg-names = "qdsp6_base", "halt_base", "rmb_base",
+ "restart_reg";
+
+ clocks = <&clock_gcc clk_xo>,
+ <&clock_gcc clk_gcc_mss_cfg_ahb_clk>,
+ <&clock_gcc clk_gcc_mss_q6_bimc_axi_clk>,
+ <&clock_gcc clk_gcc_boot_rom_ahb_clk>,
+ <&clock_gcc clk_gpll0_out_msscc>,
+ <&clock_gcc clk_qpic_clk>;
+ clock-names = "xo", "iface_clk", "bus_clk", "mem_clk",
+ "gpll0_mss_clk", "qpic";
+ qcom,proxy-clock-names = "xo";
+ qcom,active-clock-names = "iface_clk", "bus_clk", "mem_clk",
+ "gpll0_mss_clk";
+
+ vdd_cx-supply = <&pmd9650_s5_level>;
+ interrupts = <0 24 1>;
+ vdd_cx-voltage = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ vdd_mx-supply = <&pmd9650_l9_level>;
+ vdd_pll-supply = <&pmd9650_l5>;
+ qcom,vdd_pll = <1800000>;
+ qcom,firmware-name = "modem";
+ qcom,pil-self-auth;
+ qcom,sysmon-id = <0>;
+ qcom,ssctl-instance-id = <0x12>;
+ qcom,override-acc;
+ qcom,qdsp6v61-1-1;
+ memory-region = <&mss_mem>;
+
+ /* GPIO inputs from mss */
+ qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
+ qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_1_in 1 0>;
+ qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_1_in 2 0>;
+ qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_1_in 3 0>;
+
+ /* GPIO output to mss */
+ qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
+
+ };
+
+ clock_gcc: qcom,gcc@1800000 {
+ compatible = "qcom,gcc-9650";
+ reg = <0x1800000 0x80000>,
+ <0xb008018 0x1c>;
+ reg-names = "cc_base", "apcs_base";
+ #clock-cells = <1>;
+
+ qcom,regulator-names = "vdd_dig", "vdd_dig_ao";
+ vdd_dig-supply = <&pmd9650_s5_level>;
+ vdd_dig_ao-supply = <&pmd9650_s5_level_ao>;
+ };
+
+ clock_debug: qcom,cc-debug@1874000 {
+ compatible = "qcom,cc-debug-9650";
+ reg = <0x1874000 0x4>;
+ reg-names = "cc_base";
+ #clock-cells = <1>;
+ };
+
+ clock_cpu: qcom,clock-a7@0b010008 {
+ compatible = "qcom,clock-a7-9650";
+ reg = <0x0b010008 0x8>;
+ reg-names = "rcg-base";
+ #clock-cells = <1>;
+
+ clock-names = "clk-1", "clk-5";
+ clocks = <&clock_gcc clk_gpll0_ao>,
+ <&clock_gcc clk_a7pll_clk>;
+
+ qcom,speed0-bin-v0 =
+ < 0 RPM_SMD_REGULATOR_LEVEL_NONE>,
+ < 200000000 RPM_SMD_REGULATOR_LEVEL_LOW_SVS>,
+ < 384000000 RPM_SMD_REGULATOR_LEVEL_SVS>,
+ < 787200000 RPM_SMD_REGULATOR_LEVEL_NOM>,
+ <1286400000 RPM_SMD_REGULATOR_LEVEL_TURBO>;
+
+ cpu-vdd-supply = <&pmd9650_s5_level_ao>;
+ qcom,a7ssmux-opp-store-vcorner = <&CPU0>;
+ };
+
+ qcom,msm-cpufreq {
+ compatible = "qcom,msm-cpufreq";
+ clocks = <&clock_cpu clk_a7ssmux>,
+ <&clock_cpu clk_a7ssmux>,
+ <&clock_cpu clk_a7ssmux>,
+ <&clock_cpu clk_a7ssmux>;
+ clock-names = "cpu0_clk", "cpu1_clk",
+ "cpu2_clk", "cpu3_clk";
+ qcom,cpufreq-table =
+ < 200000 >,
+ < 300000 >,
+ < 384000 >,
+ < 600000 >,
+ < 787200 >,
+ < 998400 >,
+ < 1190400 >,
+ < 1286400 >;
+ };
+
+ ahb_clk: qcom,ahb-clk-src {
+ compatible = "devfreq-simple-dev";
+ clock-names = "devfreq_clk";
+ clocks = <&clock_gcc clk_apss_ahb_clk_src>;
+ governor = "powersave";
+ freq-tbl-khz =
+ < 19200 >,
+ < 50000 >,
+ < 100000 >,
+ < 133330 >;
+ };
+
+ devfreq-cpufreq {
+ cpubw-cpufreq {
+ target-dev = <&cpubw>;
+ cpu-to-dev-map =
+ < 600000 1541 >,
+ < 787200 3082 >,
+ < 1286400 3952 >;
+ };
+ cpuahb-cpufreq {
+ target-dev = <&ahb_clk>;
+ cpu-to-dev-map =
+ < 200000 19200 >,
+ < 384000 50000 >,
+ < 787200 100000 >,
+ < 1286400 133330 >;
+ };
+ };
+
+ cpubw: qcom,cpubw {
+ compatible = "qcom,devbw";
+ governor = "cpufreq";
+ qcom,src-dst-ports = <1 512>;
+ qcom,active-only;
+ qcom,bw-tbl =
+ < 1541 /* 202 MHz */ >,
+ < 3082 /* 404 MHz */ >,
+ < 3952 /* 518 MHz */ >;
+ };
+
+ restart@4ab000 {
+ compatible = "qcom,pshold";
+ reg = <0x4ab000 0x4>,
+ <0x0193d100 0x4>;
+ reg-names = "pshold-base", "tcsr-boot-misc-detect";
+ };
+
+ timer@b020000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "arm,armv7-timer-mem";
+ reg = <0xb020000 0x1000>;
+ clock-frequency = <19200000>;
+
+ frame@b021000 {
+ frame-number = <0>;
+ interrupts = <0 7 0x4>,
+ <0 6 0x4>;
+ reg = <0xb021000 0x1000>,
+ <0xb022000 0x1000>;
+ };
+
+ frame@b023000 {
+ frame-number = <1>;
+ interrupts = <0 8 0x4>;
+ reg = <0xb023000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@b024000 {
+ frame-number = <2>;
+ interrupts = <0 9 0x4>;
+ reg = <0xb024000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@b025000 {
+ frame-number = <3>;
+ interrupts = <0 10 0x4>;
+ reg = <0xb025000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@b026000 {
+ frame-number = <4>;
+ interrupts = <0 11 0x4>;
+ reg = <0xb026000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@b027000 {
+ frame-number = <5>;
+ interrupts = <0 12 0x4>;
+ reg = <0xb027000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@b028000 {
+ frame-number = <6>;
+ interrupts = <0 13 0x4>;
+ reg = <0xb028000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@b029000 {
+ frame-number = <7>;
+ interrupts = <0 14 0x4>;
+ reg = <0xb029000 0x1000>;
+ status = "disabled";
+ };
+ };
+
+ pcie0: qcom,pcie@80000 {
+ compatible = "qcom,pci-msm";
+ cell-index = <0>;
+
+ reg = <0x00080000 0x2000>,
+ <0x00086000 0x1000>,
+ <0x40000000 0xf1d>,
+ <0x40000f20 0xa8>,
+ <0x40100000 0x100000>,
+ <0x40200000 0x100000>,
+ <0x40300000 0x1d00000>,
+ <0x01956044 0x4>;
+
+ reg-names = "parf", "phy", "dm_core", "elbi",
+ "conf", "io", "bars", "tcsr";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x01000000 0x0 0x40200000 0x40200000 0x0 0x100000>,
+ <0x02000000 0x0 0x40300000 0x40300000 0x0 0x1d00000>;
+ interrupt-parent = <&pcie0>;
+ interrupts = <0 1 2 3 4 5>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0xffffffff>;
+ interrupt-map = <0 0 0 0 &intc 0 53 0
+ 0 0 0 1 &intc 0 115 0
+ 0 0 0 2 &intc 0 116 0
+ 0 0 0 3 &intc 0 117 0
+ 0 0 0 4 &intc 0 118 0
+ 0 0 0 5 &intc 0 49 0>;
+
+ interrupt-names = "int_msi", "int_a", "int_b", "int_c",
+ "int_d", "int_global_int";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_clkreq_default
+ &pcie0_perst_default
+ &pcie0_wake_default>;
+
+ perst-gpio = <&tlmm_pinmux 60 0>;
+ wake-gpio = <&tlmm_pinmux 61 0>;
+
+ gdsc-vdd-supply = <&gdsc_pcie>;
+ vreg-1.8-supply = <&pmd9650_l5>;
+ vreg-0.9-supply = <&pmd9650_l4>;
+
+ qcom,vreg-0.9-voltage-level = <928000 928000 24000>;
+
+ qcom,l1-supported;
+ qcom,l1ss-supported;
+ qcom,aux-clk-sync;
+
+ qcom,ep-latency = <10>;
+
+ qcom,cpl-timeout = <0x2>;
+
+ qcom,boot-option = <0x1>;
+
+ linux,pci-domain = <0>;
+
+ qcom,pcie-phy-ver = <0x10>;
+ qcom,use-19p2mhz-aux-clk;
+
+ qcom,msm-bus,name = "pcie0";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <45 512 0 0>,
+ <45 512 500 800>;
+
+ clocks = <&clock_gcc clk_gcc_pcie_pipe_clk>,
+ <&clock_gcc clk_ln_bb_clk>,
+ <&clock_gcc clk_gcc_pcie_sleep_clk>,
+ <&clock_gcc clk_gcc_pcie_cfg_ahb_clk>,
+ <&clock_gcc clk_gcc_pcie_axi_mstr_clk>,
+ <&clock_gcc clk_gcc_pcie_axi_clk>,
+ <&clock_gcc clk_gcc_pcie_ref_clk>,
+ <&clock_gcc clk_gcc_pcie_phy_reset>;
+
+ clock-names = "pcie_0_pipe_clk", "pcie_0_ref_clk_src",
+ "pcie_0_aux_clk", "pcie_0_cfg_ahb_clk",
+ "pcie_0_mstr_axi_clk", "pcie_0_slv_axi_clk",
+ "pcie_0_ldo", "pcie_0_phy_reset";
+
+ max-clock-frequency-hz = <0>, <0>, <19200000>,
+ <0>, <0>, <0>, <0>, <0>, <0>;
+ };
+
+ blsp1_uart1: serial@78af000 {
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0x78af000 0x200>;
+ interrupts = <0 107 0>;
+ clocks = <&clock_gcc clk_gcc_blsp1_uart1_apps_clk>,
+ <&clock_gcc clk_gcc_blsp1_ahb_clk>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+
+ bt_qca6174 {
+ compatible = "qca,qca6174";
+ qca,bt-reset-gpio = <&pmd9650_gpios 8 0>; /* BT_EN */
+ qca,bt-vdd-pa-supply = <&rome_vreg>;
+ qca,bt-vdd-xtal-supply = <&pmd9650_l4>;
+ qca,bt-vdd-core-supply = <&pmd9650_l5>;
+ };
+
+ qcom,sps {
+ compatible = "qcom,msm_sps_4k";
+ qcom,pipe-attr-ee;
+ };
+
+ pcie_ep: qcom,pcie@7fffd000 {
+ compatible = "qcom,pcie-ep";
+
+ reg = <0x7fffd000 0x1000>,
+ <0x7fffe000 0xf1d>,
+ <0x7fffef20 0xa8>,
+ <0x00080000 0x2000>,
+ <0x00086000 0x1000>,
+ <0x00087000 0x1000>;
+ reg-names = "msi", "dm_core", "elbi", "parf", "phy", "mmio";
+
+ #address-cells = <0>;
+ interrupt-parent = <&pcie_ep>;
+ interrupts = <0>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 49 0>;
+ interrupt-names = "int_global";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_clkreq_default &pcie_ep_perst_default
+ &pcie_ep_wake_default &pcie0_mdm2apstatus_default>;
+
+ perst-gpio = <&tlmm_pinmux 65 0>;
+ wake-gpio = <&tlmm_pinmux 61 0>;
+ clkreq-gpio = <&tlmm_pinmux 64 0>;
+ mdm2apstatus-gpio = <&tlmm_pinmux 16 0>;
+
+ gdsc-vdd-supply = <&gdsc_pcie>;
+ vreg-1.8-supply = <&pmd9650_l5>;
+ vreg-0.9-supply = <&pmd9650_l4>;
+
+ qcom,vreg-0.9-voltage-level = <928000 928000 24000>;
+
+ clocks = <&clock_gcc clk_gcc_pcie_pipe_clk>,
+ <&clock_gcc clk_gcc_pcie_cfg_ahb_clk>,
+ <&clock_gcc clk_gcc_pcie_axi_mstr_clk>,
+ <&clock_gcc clk_gcc_pcie_axi_clk>,
+ <&clock_gcc clk_gcc_pcie_sleep_clk>,
+ <&clock_gcc clk_gcc_pcie_ref_clk>,
+ <&clock_gcc clk_gcc_pcie_phy_reset>;
+
+ clock-names = "pcie_0_pipe_clk", "pcie_0_cfg_ahb_clk",
+ "pcie_0_mstr_axi_clk", "pcie_0_slv_axi_clk",
+ "pcie_0_aux_clk", "pcie_0_ldo",
+ "pcie_0_phy_reset";
+ max-clock-frequency-hz = <0>, <0>, <0>, <0>, <19200000>,
+ <0>, <0>;
+
+ qcom,msm-bus,name = "pcie-ep";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <45 512 0 0>,
+ <45 512 500 800>;
+
+ qcom,pcie-link-speed = <2>;
+ qcom,pcie-phy-ver = <4>;
+ qcom,pcie-active-config;
+ qcom,pcie-aggregated-irq;
+ qcom,pcie-perst-enum;
+ status = "disabled";
+ };
+
+ qcom,msm_gsi {
+ compatible = "qcom,msm_gsi";
+ };
+
+ qcom_rng: qrng@e3000 {
+ compatible = "qcom,msm-rng";
+ reg = <0xe3000 0x1000>;
+ qcom,msm-rng-iface-clk;
+ qcom,no-qrng-config;
+ qcom,msm-bus,name = "msm-rng-noc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <1 618 0 0>, /* No vote */
+ <1 618 0 800>; /* 100 MB/s */
+ clocks = <&clock_gcc clk_gcc_prng_ahb_clk>;
+ clock-names = "iface_clk";
+ };
+
+ qcom_tzlog: tz-log@08600720 {
+ compatible = "qcom,tz-log";
+ reg = <0x08600720 0x2000>;
+ };
+
+ qcom,qcedev@720000 {
+ compatible = "qcom,qcedev";
+ reg = <0x720000 0x20000>,
+ <0x704000 0x20000>;
+ reg-names = "crypto-base","crypto-bam-base";
+ interrupts = <0 207 0>;
+ qcom,bam-pipe-pair = <1>;
+ qcom,ce-hw-instance = <0>;
+ qcom,ce-device = <0>;
+ qcom,ce-hw-shared;
+ qcom,msm-bus,name = "qcedev-noc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <47 512 0 0>,
+ <47 512 393600 393600>;
+ clocks =
+ <&clock_gcc clk_qcedev_ce_clk>,
+ <&clock_gcc clk_qcedev_ce_clk>,
+ <&clock_gcc clk_qcedev_ce_clk>,
+ <&clock_gcc clk_qcedev_ce_clk>;
+ clock-names = "core_clk", "iface_clk",
+ "bus_clk","core_clk_src";
+ qcom,ce-opp-freq = <171430000>;
+ };
+
+ qcom,qcrypto@720000 {
+ compatible = "qcom,qcrypto";
+ reg = <0x720000 0x20000>,
+ <0x704000 0x20000>;
+ reg-names = "crypto-base","crypto-bam-base";
+ interrupts = <0 207 0>;
+ qcom,bam-pipe-pair = <2>;
+ qcom,ce-hw-instance = <0>;
+ qcom,ce-device = <0>;
+ qcom,ce-hw-shared;
+ qcom,msm-bus,name = "qcrypto-noc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <47 512 0 0>,
+ <47 512 393600 393600>;
+ clocks =
+ <&clock_gcc clk_qcedev_ce_clk>,
+ <&clock_gcc clk_qcedev_ce_clk>,
+ <&clock_gcc clk_qcedev_ce_clk>,
+ <&clock_gcc clk_qcedev_ce_clk>;
+ clock-names = "core_clk", "iface_clk",
+ "bus_clk","core_clk_src";
+ qcom,use-sw-aes-cbc-ecb-ctr-algo;
+ qcom,use-sw-aes-xts-algo;
+ qcom,use-sw-aes-ccm-algo;
+ qcom,use-sw-ahash-algo;
+ qcom,use-sw-hmac-algo;
+ qcom,use-sw-aead-algo;
+ qcom,ce-opp-freq = <171430000>;
+ };
+
+ qcom_seecom: qseecom@87800000 {
+ compatible = "qcom,qseecom";
+ reg = <0x87800000 0x200000>;
+ reg-names = "secapp-region";
+ qcom,hlos-ce-hw-instance = <0>;
+ qcom,qsee-ce-hw-instance = <0>;
+ qcom,msm-bus,name = "qseecom-noc";
+ qcom,msm-bus,num-cases = <4>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <47 512 0 0>,
+ <47 512 200000 400000>,
+ <47 512 300000 800000>,
+ <47 512 400000 1000000>;
+ clocks = <&clock_gcc clk_qcedev_ce_clk>,
+ <&clock_gcc clk_qcedev_ce_clk>,
+ <&clock_gcc clk_qcedev_ce_clk>,
+ <&clock_gcc clk_qcedev_ce_clk>;
+ clock-names = "core_clk", "iface_clk",
+ "bus_clk","core_clk_src";
+ qcom,ce-opp-freq = <100000000>;
+ };
+
+ qcom,rmnet-ipa {
+ compatible = "qcom,rmnet-ipa3";
+ qcom,rmnet-ipa-ssr;
+ };
+
+ ipa_hw: qcom,ipa@07b00000 {
+ compatible = "qcom,ipa";
+ reg =
+ <0x07b00000 0x34000>,
+ <0x07b84000 0x31ffff>,
+ <0x07b04000 0x2c000>;
+ reg-names = "ipa-base", "bam-base", "gsi-base";
+ interrupts =
+ <0 31 0>,
+ <0 34 0>,
+ <0 34 0>;
+ interrupt-names = "ipa-irq", "bam-irq", "gsi-irq";
+ qcom,ipa-hw-ver = <10>; /* IPA core version = IPAv3.0 */
+ qcom,ipa-hw-mode = <0>; /* IPA hw type = Normal */
+ qcom,ee = <0>;
+ qcom,use-gsi;
+ qcom,use-rg10-limitation-mitigation;
+ qcom,use-ipa-tethering-bridge;
+ qcom,modem-cfg-emb-pipe-flt;
+ clock-names = "core_clk";
+ clocks = <&clock_gcc clk_ipa_clk>;
+ qcom,msm-bus,name = "ipa";
+ qcom,msm-bus,num-cases = <4>;
+ qcom,msm-bus,num-paths = <3>;
+ qcom,msm-bus,vectors-KBps =
+ /* No vote */
+ <90 512 0 0>,
+ <90 585 0 0>,
+ <1 676 0 0>,
+ /* SVS */
+ <90 512 80000 640000>,
+ <90 585 80000 640000>,
+ <1 676 80000 160000>,
+ /* NOMINAL */
+ <90 512 206000 960000>,
+ <90 585 206000 960000>,
+ <1 676 206000 400000>,
+ /* TURBO */
+ <90 512 206000 3600000>,
+ <90 585 206000 3600000>,
+ <1 676 206000 960000>;
+ qcom,bus-vector-names = "MIN", "SVS", "NOMINAL", "TURBO";
+ /* ipa tz unlock registers */
+ qcom,ipa-tz-unlock-reg =
+ <0x4043583c 0x1000>; /* 32-bit reg addr and size */
+
+ /* smp2p gpio information */
+ qcom,smp2pgpio_map_ipa_1_out {
+ compatible = "qcom,smp2pgpio-map-ipa-1-out";
+ gpios = <&smp2pgpio_ipa_1_out 0 0>;
+ };
+
+ qcom,smp2pgpio_map_ipa_1_in {
+ compatible = "qcom,smp2pgpio-map-ipa-1-in";
+ gpios = <&smp2pgpio_ipa_1_in 0 0>;
+ };
+ };
+
+ mhi_device: mhi_dev@87000 {
+ compatible = "qcom,msm-mhi-dev";
+ reg = <0x87000 0x1000>,
+ <0x7b22000 0x4>,
+ <0x7b22150 0x4>;
+ reg-names = "mhi_mmio_base", "ipa_uc_mbox_crdb",
+ "ipa_uc_mbox_erdb";
+ qcom,mhi-ifc-id = <0x030217cb>;
+ qcom,mhi-ep-msi = <0>;
+ qcom,mhi-version = <0x1000000>;
+ qcom,use-ipa-software-channel;
+ status = "disabled";
+ };
+
+ blsp1_uart1: serial@78af000 {
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0x78af000 0x200>;
+ interrupts = <0 107 0>;
+ clocks = <&clock_gcc clk_gcc_blsp1_uart1_apps_clk>,
+ <&clock_gcc clk_gcc_blsp1_ahb_clk>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+
+ blsp1_uart2: serial@78b0000 {
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0x78b0000 0x200>;
+ interrupts = <0 108 0>;
+ clocks = <&clock_gcc clk_gcc_blsp1_uart2_apps_clk>,
+ <&clock_gcc clk_gcc_blsp1_ahb_clk>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+
+ blsp1_uart3: serial@78b1000 {
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0x78b1000 0x200>;
+ interrupts = <0 109 0>;
+ clocks = <&clock_gcc clk_gcc_blsp1_uart3_apps_clk>,
+ <&clock_gcc clk_gcc_blsp1_ahb_clk>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+
+ rpm_bus: qcom,rpm-smd {
+ compatible = "qcom,rpm-smd";
+ rpm-channel-name = "rpm_requests";
+ rpm-channel-type = <15>; /* SMD_APPS_RPM */
+ };
+
+ qcom,wdt@b017000 {
+ compatible = "qcom,msm-watchdog";
+ reg = <0xb017000 0x1000>;
+ reg-names = "wdt-base";
+ interrupts = <1 3 0>, <1 2 0>;
+ qcom,bark-time = <11000>;
+ qcom,pet-time = <10000>;
+ };
+
+ qcom,msm-rtb {
+ compatible = "qcom,msm-rtb";
+ qcom,rtb-size = <0x100000>;
+ };
+
+ jtag_mm0: jtagmm@842000 {
+ compatible = "qcom,jtag-mm";
+ reg = <0x842000 0x1000>,
+ <0x840000 0x1000>;
+ reg-names = "etm-base","debug-base";
+
+ qcom,coresight-jtagmm-cpu = <&CPU0>;
+
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "core_clk", "core_a_clk";
+ };
+
+ qcom,ipc-spinlock@1905000 {
+ compatible = "qcom,ipc-spinlock-sfpb";
+ reg = <0x1905000 0x8000>;
+ qcom,num-locks = <8>;
+ };
+
+ qnand_1: nand@7980000 {
+ compatible = "qcom,msm-nand";
+ reg = <0x07980000 0x10000>,
+ <0x07984000 0x1a000>;
+ reg-names = "nand_phys",
+ "bam_phys";
+ qcom,reg-adjustment-offset = <0x4000>;
+
+ interrupts = <0 247 0>;
+ interrupt-names = "bam_irq";
+
+ qcom,msm-bus,name = "qpic_nand";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+
+ qcom,msm-bus,vectors-KBps =
+ <91 512 0 0>,
+ /* Voting for max b/w on PNOC bus for now */
+ <91 512 400000 800000>;
+
+ clock-names = "core_clk";
+ clocks = <&clock_gcc clk_qpic_clk>;
+ status = "disabled";
+ };
+
+ qcom,smem@87e80000 {
+ compatible = "qcom,smem";
+ reg = <0x87e80000 0xc0000>,
+ <0xb011008 0x4>,
+ <0x60000 0x6000>,
+ <0x193d000 0x8>;
+ reg-names = "smem", "irq-reg-base", "aux-mem1",
+ "smem_targ_info_reg";
+ qcom,mpu-enabled;
+
+ qcom,smd-modem {
+ compatible = "qcom,smd";
+ qcom,smd-edge = <0>;
+ qcom,smd-irq-offset = <0x0>;
+ qcom,smd-irq-bitmask = <0x1000>;
+ interrupts = <0 25 1>;
+ label = "modem";
+ };
+
+ qcom,smd-rpm {
+ compatible = "qcom,smd";
+ qcom,smd-edge = <15>;
+ qcom,smd-irq-offset = <0x0>;
+ qcom,smd-irq-bitmask = <0x1>;
+ interrupts = <0 168 1>;
+ label = "rpm";
+ qcom,irq-no-suspend;
+ qcom,not-loadable;
+ };
+ };
+
+ qcom,glink-smem-native-xprt-modem@87e80000 {
+ compatible = "qcom,glink-smem-native-xprt";
+ reg = <0x87e80000 0xc0000>,
+ <0xb011008 0x4>;
+ reg-names = "smem", "irq-reg-base";
+ qcom,irq-mask = <0x8000>;
+ interrupts = <0 28 1>;
+ label = "mpss";
+ };
+
+ qcom,glink-smem-native-xprt-rpm@60000 {
+ compatible = "qcom,glink-rpm-native-xprt";
+ reg = <0x60000 0x6000>,
+ <0xb011008 0x4>;
+ reg-names = "msgram", "irq-reg-base";
+ qcom,irq-mask = <0x1>;
+ interrupts = <0 168 1>;
+ label = "rpm";
+ };
+
+ glink_mpss: qcom,glink-ssr-modem {
+ compatible = "qcom,glink_ssr";
+ label = "modem";
+ qcom,edge = "mpss";
+ qcom,notify-edges = <&glink_rpm>;
+ qcom,xprt = "smem";
+ };
+
+ glink_rpm: qcom,glink-ssr-rpm {
+ compatible = "qcom,glink_ssr";
+ label = "rpm";
+ qcom,edge = "rpm";
+ qcom,notify-edges = <&glink_mpss>;
+ qcom,xprt = "smem";
+ };
+
+ qcom,glink_pkt {
+ compatible = "qcom,glinkpkt";
+
+ qcom,glinkpkt-at-mdm0 {
+ qcom,glinkpkt-transport = "smem";
+ qcom,glinkpkt-edge = "mpss";
+ qcom,glinkpkt-ch-name = "DS";
+ qcom,glinkpkt-dev-name = "at_mdm0";
+ };
+
+ qcom,glinkpkt-loopback_cntl {
+ qcom,glinkpkt-transport = "lloop";
+ qcom,glinkpkt-edge = "local";
+ qcom,glinkpkt-ch-name = "LOCAL_LOOPBACK_CLNT";
+ qcom,glinkpkt-dev-name = "glink_pkt_loopback_ctrl";
+ };
+
+ qcom,glinkpkt-loopback_data {
+ qcom,glinkpkt-transport = "lloop";
+ qcom,glinkpkt-edge = "local";
+ qcom,glinkpkt-ch-name = "glink_pkt_lloop_CLNT";
+ qcom,glinkpkt-dev-name = "glink_pkt_loopback";
+ };
+
+ qcom,glinkpkt-data5-cntl {
+ qcom,glinkpkt-transport = "smem";
+ qcom,glinkpkt-edge = "mpss";
+ qcom,glinkpkt-ch-name = "DATA5_CNTL";
+ qcom,glinkpkt-dev-name = "smdcntl0";
+ };
+
+ qcom,glinkpkt-apr-apps2 {
+ qcom,glinkpkt-transport = "smem";
+ qcom,glinkpkt-edge = "mpss";
+ qcom,glinkpkt-ch-name = "apr_apps2";
+ qcom,glinkpkt-dev-name = "apr_apps2";
+ };
+
+ qcom,glinkpkt-data22 {
+ qcom,glinkpkt-transport = "smem";
+ qcom,glinkpkt-edge = "mpss";
+ qcom,glinkpkt-ch-name = "DATA22";
+ qcom,glinkpkt-dev-name = "smd22";
+ };
+
+ qcom,glinkpkt-data40-cntl {
+ qcom,glinkpkt-transport = "smem";
+ qcom,glinkpkt-edge = "mpss";
+ qcom,glinkpkt-ch-name = "DATA40_CNTL";
+ qcom,glinkpkt-dev-name = "smdcntl8";
+ };
+
+ qcom,glinkpkt-data1 {
+ qcom,glinkpkt-transport = "smem";
+ qcom,glinkpkt-edge = "mpss";
+ qcom,glinkpkt-ch-name = "DATA1";
+ qcom,glinkpkt-dev-name = "smd7";
+ };
+
+ qcom,glinkpkt-data4 {
+ qcom,glinkpkt-transport = "smem";
+ qcom,glinkpkt-edge = "mpss";
+ qcom,glinkpkt-ch-name = "DATA4";
+ qcom,glinkpkt-dev-name = "smd8";
+ };
+
+ qcom,glinkpkt-data11 {
+ qcom,glinkpkt-transport = "smem";
+ qcom,glinkpkt-edge = "mpss";
+ qcom,glinkpkt-ch-name = "DATA11";
+ qcom,glinkpkt-dev-name = "smd11";
+ };
+
+ qcom,glinkpkt-data21 {
+ qcom,glinkpkt-transport = "smem";
+ qcom,glinkpkt-edge = "mpss";
+ qcom,glinkpkt-ch-name = "DATA21";
+ qcom,glinkpkt-dev-name = "smd21";
+ };
+ };
+
+ qcom,ipc_router {
+ compatible = "qcom,ipc_router";
+ qcom,node-id = <1>;
+ qcom,default-peripheral = "modem";
+ };
+
+ qcom,ipc_router_modem_xprt {
+ compatible = "qcom,ipc_router_glink_xprt";
+ qcom,ch-name = "IPCRTR";
+ qcom,xprt-remote = "mpss";
+ qcom,glink-xprt = "smd_trans";
+ qcom,xprt-linkid = <1>;
+ qcom,xprt-version = <1>;
+ qcom,fragmented-data;
+ };
+
+ spmi_bus: qcom,spmi@200f000 {
+ compatible = "qcom,spmi-pmic-arb";
+ reg = <0x200f000 0x1000>,
+ <0x2400000 0x800000>,
+ <0x2c00000 0x800000>,
+ <0x3800000 0x200000>,
+ <0x200a000 0x2100>; /* includes SPMI_CFG and GENI_CFG */
+ reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
+ interrupts = <0 190 0>;
+ qcom,pmic-arb-channel = <0>;
+ qcom,pmic-arb-ee = <0>;
+ qcom,pmic-arb-max-peripherals = <256>;
+ qcom,pmic-arb-max-periph-interrupts = <256>;
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ };
+
+ tsens0: tsens@4a9000 {
+ compatible = "qcom,msm8996-tsens";
+ reg = <0x4a8000 0x2000>,
+ <0x74230 0x1000>;
+ reg-names = "tsens_physical", "tsens_eeprom_physical";
+ interrupts = <0 184 0>, <0 29 0>;
+ interrupt-names = "tsens-upper-lower", "tsens-critical";
+ qcom,sensors = <5>;
+ qcom,slope = <2901 2846 3200 3200 3200>;
+ qcom,client-id = <0 1 2 3 4>;
+ qcom,sensor-id = <0 1 2 3 6>;
+ };
+
+ cnss_pcie: qcom,cnss {
+ compatible = "qcom,cnss";
+ wlan-en-gpio = <&tlmm_pinmux 95 0>;
+ vdd-wlan-supply = <&rome_vreg>;
+ vdd-wlan-xtal-supply = <&pmd9650_l5>;
+ vdd-wlan-io-supply = <&pmd9650_l6>;
+ vdd-wlan-xtal-aon-supply = <&pmd9650_l4>;
+ qcom,notify-modem-status;
+ pinctrl-names = "wlan_en_active", "wlan_en_sleep";
+ pinctrl-0 = <&cnss_wlan_en_active>;
+ pinctrl-1 = <&cnss_wlan_en_sleep>;
+ qcom,wlan-rc-num = <0>;
+ qcom,wlan-ramdump-dynamic = <0x200000>;
+
+ qcom,msm-bus,name = "msm-cnss";
+ qcom,msm-bus,num-cases = <4>;
+ qcom,msm-bus,num-paths = <2>;
+ qcom,msm-bus,vectors-KBps =
+ <45 512 0 0>, <1 512 0 0>,
+ /* Upto 200 Mbps */
+ <45 512 41421 655360>, <1 512 41421 655360>,
+ /* Upto 400 Mbps */
+ <45 512 98572 655360>, <1 512 98572 1600000>,
+ /* Upto 800 Mbps */
+ <45 512 207108 1146880>, <1 512 207108 3124992>;
+ };
+
+ cnss_sdio: qcom,cnss_sdio {
+ compatible = "qcom,cnss_sdio";
+ subsys-name = "AR6320_SDIO";
+ vdd-wlan-supply = <&rome_vreg>;
+ vdd-wlan-xtal-supply = <&pmd9650_l5>;
+ vdd-wlan-io-supply = <&pmd9650_l6>;
+ qcom,wlan-ramdump-dynamic = <0x200000>;
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&cnss_sdio_active>;
+ pinctrl-1 = <&cnss_sdio_sleep>;
+ qcom,is-antenna-shared;
+ status = "disabled";
+ };
+
+ wcd9xxx_intc: wcd9xxx-irq {
+ compatible = "qcom,wcd9xxx-irq";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&tlmm_pinmux>;
+ qcom,gpio-connect = <&tlmm_pinmux 94 0>;
+ };
+
+ clock_audio: audio_ext_clk {
+ compatible = "qcom,audio-ref-clk";
+ qcom,codec-mclk-clk-freq = <12288000>;
+ pinctrl-names = "sleep", "active";
+ pinctrl-0 = <&i2s_mclk_sleep>;
+ pinctrl-1 = <&i2s_mclk_active>;
+ #clock-cells = <1>;
+ };
+
+ snd_tasha: sound {
+ compatible = "qcom,mdm-audio-tasha";
+ qcom,model = "mdm-tasha-i2s-snd-card";
+
+ qcom,audio-routing =
+ "AIF4 VI", "MCLK",
+ "RX_BIAS", "MCLK",
+ "MADINPUT", "MCLK",
+ "AMIC2", "MIC BIAS2",
+ "MIC BIAS2", "Headset Mic",
+ "AMIC3", "MIC BIAS2",
+ "MIC BIAS2", "ANCRight Headset Mic",
+ "AMIC4", "MIC BIAS2",
+ "MIC BIAS2", "ANCLeft Headset Mic",
+ "AMIC5", "MIC BIAS3",
+ "MIC BIAS3", "Handset Mic",
+ "AMIC6", "MIC BIAS4",
+ "MIC BIAS4", "Analog Mic6",
+ "DMIC0", "MIC BIAS1",
+ "MIC BIAS1", "Digital Mic0",
+ "DMIC1", "MIC BIAS1",
+ "MIC BIAS1", "Digital Mic1",
+ "DMIC2", "MIC BIAS3",
+ "MIC BIAS3", "Digital Mic2",
+ "DMIC3", "MIC BIAS3",
+ "MIC BIAS3", "Digital Mic3",
+ "DMIC4", "MIC BIAS4",
+ "MIC BIAS4", "Digital Mic4",
+ "DMIC5", "MIC BIAS4",
+ "MIC BIAS4", "Digital Mic5",
+ "SpkrLeft IN", "SPK1 OUT",
+ "SpkrRight IN", "SPK2 OUT";
+
+ qcom,tasha-mclk-clk-freq = <12288000>;
+
+ qcom,msm-gpios =
+ "pri_mi2s_aux_master",
+ "pri_mi2s_aux_slave",
+ "sec_mi2s_aux_master",
+ "sec_mi2s_aux_slave";
+ qcom,pinctrl-names =
+ "all_off",
+ "pri_mi2s_aux_master_active",
+ "pri_mi2s_aux_slave_active",
+ "invalid_state_1",
+ "sec_mi2s_aux_master_active",
+ "pri_master_active_sec_master_active",
+ "pri_slave_active_sec_master_active",
+ "invalid_state_2",
+ "sec_mi2s_aux_slave_active",
+ "pri_master_active_sec_slave_active",
+ "pri_slave_active_sec_slave_active";
+ pinctrl-names =
+ "all_off",
+ "pri_mi2s_aux_master_active",
+ "pri_mi2s_aux_slave_active",
+ "invalid_state_1",
+ "sec_mi2s_aux_master_active",
+ "pri_master_active_sec_master_active",
+ "pri_slave_active_sec_master_active",
+ "invalid_state_2",
+ "sec_mi2s_aux_slave_active",
+ "pri_master_active_sec_slave_active",
+ "pri_slave_active_sec_slave_active";
+ pinctrl-0 = <&pri_ws_sleep &pri_sck_sleep
+ &pri_dout_sleep &pri_din_sleep
+ &sec_ws_sleep &sec_sck_sleep
+ &sec_dout_sleep &sec_din_sleep>;
+ pinctrl-1 = <&pri_ws_active_master &pri_sck_active_master
+ &pri_dout_active &pri_din_active
+ &sec_ws_sleep &sec_sck_sleep
+ &sec_dout_sleep &sec_din_sleep>;
+ pinctrl-2 = <&pri_ws_active_slave &pri_sck_active_slave
+ &pri_dout_active &pri_din_active
+ &sec_ws_sleep &sec_sck_sleep
+ &sec_dout_sleep &sec_din_sleep>;
+ pinctrl-3 = <&pri_ws_sleep &pri_sck_sleep
+ &pri_dout_sleep &pri_din_sleep
+ &sec_ws_sleep &sec_sck_sleep
+ &sec_dout_sleep &sec_din_sleep>;
+ pinctrl-4 = <&pri_ws_sleep &pri_sck_sleep
+ &pri_dout_sleep &pri_din_sleep
+ &sec_ws_active_master &sec_sck_active_master
+ &sec_dout_active &sec_din_active>;
+ pinctrl-5 = <&pri_ws_active_master &pri_sck_active_master
+ &pri_dout_active &pri_din_active
+ &sec_ws_active_master &sec_sck_active_master
+ &sec_dout_active &sec_din_active>;
+ pinctrl-6 = <&pri_ws_active_slave &pri_sck_active_slave
+ &pri_dout_active &pri_din_active
+ &sec_ws_active_master &sec_sck_active_master
+ &sec_dout_active &sec_din_active>;
+ pinctrl-7 = <&pri_ws_sleep &pri_sck_sleep
+ &pri_dout_sleep &pri_din_sleep
+ &sec_ws_sleep &sec_sck_sleep
+ &sec_dout_sleep &sec_din_sleep>;
+ pinctrl-8 = <&pri_ws_sleep &pri_sck_sleep
+ &pri_dout_sleep &pri_din_sleep
+ &sec_ws_active_slave &sec_sck_active_slave
+ &sec_dout_active &sec_din_active>;
+ pinctrl-9 = <&pri_ws_active_master &pri_sck_active_master
+ &pri_dout_active &pri_din_active
+ &sec_ws_active_slave &sec_sck_active_slave
+ &sec_dout_active &sec_din_active>;
+ pinctrl-10 = <&pri_ws_active_slave &pri_sck_active_slave
+ &pri_dout_active &pri_din_active
+ &sec_ws_active_slave &sec_sck_active_slave
+ &sec_dout_active &sec_din_active>;
+
+ asoc-platform = <&pcm0>, <&pcm1>, <&voip>, <&voice>,
+ <&loopback>, <&hostless>, <&afe>, <&routing>,
+ <&pcm_dtmf>, <&host_pcm>, <&compress>;
+ asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
+ "msm-voip-dsp", "msm-pcm-voice",
+ "msm-pcm-loopback", "msm-pcm-hostless",
+ "msm-pcm-afe", "msm-pcm-routing",
+ "msm-pcm-dtmf", "msm-voice-host-pcm",
+ "msm-compress-dsp";
+ asoc-cpu = <&dai_pri_auxpcm>, <&mi2s_prim>, <&mi2s_sec>,
+ <&dtmf_tx>,
+ <&rx_capture_tx>, <&rx_playback_rx>,
+ <&tx_capture_tx>, <&tx_playback_rx>,
+ <&afe_pcm_rx>, <&afe_pcm_tx>, <&afe_proxy_rx>,
+ <&afe_proxy_tx>, <&incall_record_rx>,
+ <&incall_record_tx>, <&incall_music_rx>,
+ <&dai_sec_auxpcm>;
+ asoc-cpu-names = "msm-dai-q6-auxpcm.1",
+ "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1",
+ "msm-dai-stub-dev.4", "msm-dai-stub-dev.5",
+ "msm-dai-stub-dev.6", "msm-dai-stub-dev.7",
+ "msm-dai-stub-dev.8", "msm-dai-q6-dev.224",
+ "msm-dai-q6-dev.225", "msm-dai-q6-dev.241",
+ "msm-dai-q6-dev.240", "msm-dai-q6-dev.32771",
+ "msm-dai-q6-dev.32772", "msm-dai-q6-dev.32773",
+ "msm-dai-q6-auxpcm.2";
+ asoc-codec = <&stub_codec>;
+ asoc-codec-names = "msm-stub-codec.1";
+ qcom,wsa-max-devs = <1>;
+ qcom,wsa-devs = <&wsa881x_211>, <&wsa881x_212>,
+ <&wsa881x_213>, <&wsa881x_214>;
+ qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
+ "SpkrLeft", "SpkrRight";
+ };
+
+ qcom,msm-adsp-loader {
+ compatible = "qcom,adsp-loader";
+ qcom,adsp-state = <0>;
+ qcom,proc-img-to-load = "modem";
+ };
+
+ qcom,msm-audio-ion {
+ compatible = "qcom,msm-audio-ion";
+ qcom,scm-mp-enabled;
+ memory-region = <&audio_mem>;
+ };
+
+ pcm0: qcom,msm-pcm {
+ compatible = "qcom,msm-pcm-dsp";
+ qcom,msm-pcm-dsp-id = <0>;
+ };
+
+ routing: qcom,msm-pcm-routing {
+ compatible = "qcom,msm-pcm-routing";
+ };
+
+ pcm1: qcom,msm-pcm-low-latency {
+ compatible = "qcom,msm-pcm-dsp";
+ qcom,msm-pcm-dsp-id = <1>;
+ qcom,msm-pcm-low-latency;
+ qcom,latency-level = "ultra";
+ };
+
+ qcom,msm-compr-dsp {
+ compatible = "qcom,msm-compr-dsp";
+ };
+
+ voip: qcom,msm-voip-dsp {
+ compatible = "qcom,msm-voip-dsp";
+ };
+
+ voice: qcom,msm-pcm-voice {
+ compatible = "qcom,msm-pcm-voice";
+ qcom,destroy-cvd;
+ };
+
+ stub_codec: qcom,msm-stub-codec {
+ compatible = "qcom,msm-stub-codec";
+ };
+
+ qcom,msm-dai-fe {
+ compatible = "qcom,msm-dai-fe";
+ };
+
+ afe: qcom,msm-pcm-afe {
+ compatible = "qcom,msm-pcm-afe";
+ };
+
+ hostless: qcom,msm-pcm-hostless {
+ compatible = "qcom,msm-pcm-hostless";
+ };
+
+ host_pcm: qcom,msm-voice-host-pcm {
+ compatible = "qcom,msm-voice-host-pcm";
+ };
+
+ loopback: qcom,msm-pcm-loopback {
+ compatible = "qcom,msm-pcm-loopback";
+ };
+
+ compress: qcom,msm-compress-dsp {
+ compatible = "qcom,msm-compress-dsp";
+ qcom,adsp-version = "MDSP 1.2";
+ };
+
+ qcom,msm-dai-stub {
+ compatible = "qcom,msm-dai-stub";
+ dtmf_tx: qcom,msm-dai-stub-dtmf-tx {
+ compatible = "qcom,msm-dai-stub-dev";
+ qcom,msm-dai-stub-dev-id = <4>;
+ };
+
+ rx_capture_tx: qcom,msm-dai-stub-host-rx-capture-tx {
+ compatible = "qcom,msm-dai-stub-dev";
+ qcom,msm-dai-stub-dev-id = <5>;
+ };
+
+ rx_playback_rx: qcom,msm-dai-stub-host-rx-playback-rx {
+ compatible = "qcom,msm-dai-stub-dev";
+ qcom,msm-dai-stub-dev-id = <6>;
+ };
+
+ tx_capture_tx: qcom,msm-dai-stub-host-tx-capture-tx {
+ compatible = "qcom,msm-dai-stub-dev";
+ qcom,msm-dai-stub-dev-id = <7>;
+ };
+
+ tx_playback_rx: qcom,msm-dai-stub-host-tx-playback-rx {
+ compatible = "qcom,msm-dai-stub-dev";
+ qcom,msm-dai-stub-dev-id = <8>;
+ };
+ };
+
+ qcom,msm-dai-q6 {
+ compatible = "qcom,msm-dai-q6";
+ afe_pcm_rx: qcom,msm-dai-q6-be-afe-pcm-rx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <224>;
+ };
+
+ afe_pcm_tx: qcom,msm-dai-q6-be-afe-pcm-tx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <225>;
+ };
+
+ afe_proxy_rx: qcom,msm-dai-q6-afe-proxy-rx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <241>;
+ };
+
+ afe_proxy_tx: qcom,msm-dai-q6-afe-proxy-tx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <240>;
+ };
+
+ incall_record_rx: qcom,msm-dai-q6-incall-record-rx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <32771>;
+ };
+
+ incall_record_tx: qcom,msm-dai-q6-incall-record-tx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <32772>;
+ };
+
+ incall_music_rx: qcom,msm-dai-q6-incall-music-rx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <32773>;
+ };
+ };
+
+ pcm_dtmf: qcom,msm-pcm-dtmf {
+ compatible = "qcom,msm-pcm-dtmf";
+ };
+
+ cpu-pmu {
+ compatible = "arm,cortex-a7-pmu";
+ qcom,irq-is-percpu;
+ interrupts = <1 8 0x100>;
+ };
+
+ dai_pri_auxpcm: qcom,msm-pri-auxpcm {
+ compatible = "qcom,msm-auxpcm-dev";
+ qcom,msm-cpudai-auxpcm-mode = <0>, <0>;
+ qcom,msm-cpudai-auxpcm-sync = <1>, <1>;
+ qcom,msm-cpudai-auxpcm-frame = <5>, <4>;
+ qcom,msm-cpudai-auxpcm-quant = <2>, <2>;
+ qcom,msm-cpudai-auxpcm-num-slots = <1>, <1>;
+ qcom,msm-cpudai-auxpcm-slot-mapping = <1>, <1>;
+ qcom,msm-cpudai-auxpcm-data = <0>, <0>;
+ qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>;
+ qcom,msm-auxpcm-interface = "primary";
+ qcom,msm-cpudai-afe-clk-ver = <2>;
+ };
+
+ dai_sec_auxpcm: qcom,msm-sec-auxpcm {
+ compatible = "qcom,msm-auxpcm-dev";
+ qcom,msm-cpudai-auxpcm-mode = <0>, <0>;
+ qcom,msm-cpudai-auxpcm-sync = <1>, <1>;
+ qcom,msm-cpudai-auxpcm-frame = <5>, <4>;
+ qcom,msm-cpudai-auxpcm-quant = <2>, <2>;
+ qcom,msm-cpudai-auxpcm-num-slots = <1>, <1>;
+ qcom,msm-cpudai-auxpcm-slot-mapping = <1>, <1>;
+ qcom,msm-cpudai-auxpcm-data = <0>, <0>;
+ qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>;
+ qcom,msm-auxpcm-interface = "secondary";
+ qcom,msm-cpudai-afe-clk-ver = <2>;
+ };
+
+ qcom,msm-dai-mi2s {
+ compatible = "qcom,msm-dai-mi2s";
+ mi2s_prim: qcom,msm-dai-q6-mi2s-prim {
+ compatible = "qcom,msm-dai-q6-mi2s";
+ qcom,msm-dai-q6-mi2s-dev-id = <0>;
+ qcom,msm-mi2s-rx-lines = <2>;
+ qcom,msm-mi2s-tx-lines = <1>;
+ };
+ mi2s_sec: qcom,msm-dai-q6-mi2s-sec {
+ compatible = "qcom,msm-dai-q6-mi2s";
+ qcom,msm-dai-q6-mi2s-dev-id = <1>;
+ qcom,msm-mi2s-rx-lines = <2>;
+ qcom,msm-mi2s-tx-lines = <1>;
+ };
+
+ };
+
+ sdhc_1: sdhci@7824000 {
+ compatible = "qcom,sdhci-msm";
+ reg = <0x07824900 0x500>, <0x07824000 0x800>;
+ reg-names = "hc_mem", "core_mem";
+
+ interrupts = <0 123 0>, <0 138 0>;
+ interrupt-names = "hc_irq", "pwr_irq";
+
+ qcom,devfreq,freq-table = <50000000 200000000>;
+
+ qcom,msm-bus,name = "sdhc1";
+ qcom,msm-bus,num-cases = <8>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps = <78 512 0 0>, /* No vote */
+ <78 512 1600 3200>, /* 400 KB/s*/
+ <78 512 80000 160000>, /* 20 MB/s */
+ <78 512 100000 200000>, /* 25 MB/s */
+ <78 512 200000 400000>, /* 50 MB/s */
+ <78 512 400000 800000>, /* 100 MB/s */
+ <78 512 400000 800000>, /* 200 MB/s */
+ <78 512 2048000 4096000>; /* Max. bandwidth */
+ qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000
+ 100000000 200000000 4294967295>;
+ clocks = <&clock_gcc clk_gcc_sdcc1_ahb_clk>,
+ <&clock_gcc clk_gcc_sdcc1_apps_clk>;
+ clock-names = "iface_clk", "core_clk";
+
+ qcom,pm-qos-cpu-groups = <0x0>;
+ qcom,pm-qos-cmdq-latency-us = <70>;
+ qcom,pm-qos-legacy-latency-us = <70>;
+ qcom,pm-qos-irq-type = "affine_cores";
+ qcom,pm-qos-irq-cpu = <0>;
+ qcom,pm-qos-irq-latency = <70>;
+
+ status = "disabled";
+ };
+
+ pps {
+ compatible = "pps-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pps>;
+ gpios = <&tlmm_pinmux 39 0>;
+ status = "okay";
+ };
+
+};
+
+&gdsc_usb30 {
+ reg = <0x185e078 0x4>;
+ status = "ok";
+};
+
+&gdsc_pcie {
+ reg = <0x0185d044 0x4>;
+ status = "ok";
+};
+
+#include "msm-pmd9650-rpm-regulator.dtsi"
+#include "msm-pmd9650.dtsi"
+#include "mdm9650-regulator.dtsi"
+#include "mdm9650-usb.dtsi"
+
+&pmd9650_pon {
+ interrupts = <0x0 0x8 0x0>;
+ interrupt-names = "kpdpwr";
+ qcom,system-reset;
+
+ qcom,pon_1 {
+ qcom,pon-type = <0>;
+ qcom,pull-up = <1>;
+ linux,code = <116>;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msm-pmd9650-rpm-regulator.dtsi b/arch/arm/boot/dts/qcom/msm-pmd9650-rpm-regulator.dtsi
new file mode 100644
index 0000000..faac696
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msm-pmd9650-rpm-regulator.dtsi
@@ -0,0 +1,301 @@
+/* Copyright (c) 2015, 2017-2018, 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 = "9650_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 = "9650_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 = "9650_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 = "9650_s4";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-smpa5 { /* VDD_CX supply */
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "rwcx";
+ qcom,resource-id = <0>;
+ qcom,regulator-type = <1>;
+ qcom,hpm-min-load = <100000>;
+ status = "disabled";
+
+ regulator-s5 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "9650_s5";
+ 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 = "9650_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 = "9650_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 = "9650_l3";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa4 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <4>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l4 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "9650_l4";
+ 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 = "9650_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 = "9650_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 = "9650_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 = "9650_l8";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa9 { /* VDD_MX supply */
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "rwmx";
+ qcom,resource-id = <0>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l9 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "9650_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 = "9650_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 = "9650_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 = "9650_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 = <10000>;
+ status = "disabled";
+
+ regulator-l13 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "9650_l13";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msm-pmd9650.dtsi b/arch/arm/boot/dts/qcom/msm-pmd9650.dtsi
new file mode 100644
index 0000000..2f84eb0
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msm-pmd9650.dtsi
@@ -0,0 +1,402 @@
+/* Copyright (c) 2015-2018, 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,pmd9650@0 {
+ spmi-slave-container;
+ reg = <0x0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ qcom,revid@100 {
+ compatible = "qcom,qpnp-revid";
+ reg = <0x100 0x100>;
+ };
+
+ pmd9650_pon: qcom,power-on@800 {
+ compatible = "qcom,qpnp-power-on";
+ reg = <0x800 0x100>;
+ qcom,pon-dbc-delay = <15625>;
+
+ };
+
+ pmd9650_misc: qcom,misc@900 {
+ compatible = "qcom,qpnp-misc";
+ reg = <0x900 0x100>;
+ };
+
+ pmd9650_gpios: gpios {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-pin";
+ gpio-controller;
+ #gpio-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ label = "pmd9650-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";
+ };
+
+ gpio@c800 {
+ reg = <0xc800 0x100>;
+ qcom,pin-num = <9>;
+ status = "disabled";
+ };
+
+ gpio@c900 {
+ reg = <0xc900 0x100>;
+ qcom,pin-num = <10>;
+ status = "disabled";
+ };
+
+ gpio@ca00 {
+ reg = <0xca00 0x100>;
+ qcom,pin-num = <11>;
+ status = "disabled";
+ };
+
+ gpio@cb00 {
+ reg = <0xcb00 0x100>;
+ qcom,pin-num = <12>;
+ status = "disabled";
+ };
+ };
+
+ pmd9650_vadc: vadc@3100 {
+ compatible = "qcom,qpnp-vadc-hc";
+ reg = <0x3100 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0x0 0x31 0x0>;
+ interrupt-names = "eoc-int-en-set";
+ qcom,adc-bit-resolution = <15>;
+ qcom,adc-vdd-reference = <1875>;
+
+ chan@6 {
+ label = "die_temp";
+ reg = <6>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <3>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,cal-val = <0>;
+ };
+
+ chan@0 {
+ label = "ref_gnd";
+ reg = <0>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,cal-val = <0>;
+ };
+
+ chan@1 {
+ label = "ref_1250v";
+ reg = <1>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,cal-val = <0>;
+ };
+ };
+
+ qcom,pmd9650_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,pmd9650_rtc_rw@6000 {
+ reg = <0x6000 0x100>;
+ };
+
+ qcom,pmd9650_rtc_alarm@6100 {
+ reg = <0x6100 0x100>;
+ interrupts = <0x0 0x61 0x1>;
+ };
+ };
+ };
+
+ qcom,pmd9650@1 {
+ spmi-slave-container;
+ reg = <0x1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ pmd9650_pwm_1: pwm@bc00 {
+ 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>;
+ status = "disabled";
+ };
+
+ pmd9650_pwm_2: pwm@bd00 {
+ compatible = "qcom,qpnp-pwm";
+ reg = <0xbd00 0x100>;
+ reg-names = "qpnp-lpg-channel-base";
+ qcom,channel-id = <1>;
+ qcom,supported-sizes = <6>, <9>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ regulator@1400 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_s1";
+ spmi-dev-container;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x1400 0x300>;
+ status = "disabled";
+
+ qcom,ctl@1400 {
+ reg = <0x1400 0x100>;
+ };
+ qcom,ps@1500 {
+ reg = <0x1500 0x100>;
+ };
+ qcom,freq@1600 {
+ reg = <0x1600 0x100>;
+ };
+ };
+
+ regulator@1700 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_s2";
+ spmi-dev-container;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x1700 0x300>;
+ status = "disabled";
+
+ qcom,ctl@1700 {
+ reg = <0x1700 0x100>;
+ };
+ qcom,ps@1800 {
+ reg = <0x1800 0x100>;
+ };
+ qcom,freq@1900 {
+ reg = <0x1900 0x100>;
+ };
+ };
+
+ regulator@1a00 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_s3";
+ spmi-dev-container;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x1a00 0x300>;
+ status = "disabled";
+
+ qcom,ctl@x1a00 {
+ reg = <0x1a00 0x100>;
+ };
+ qcom,ps@1b00 {
+ reg = <0x1b00 0x100>;
+ };
+ qcom,freq@1c00 {
+ reg = <0x1c00 0x100>;
+ };
+ };
+
+ regulator@1d00 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_s4";
+ spmi-dev-container;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x1d00 0x300>;
+ status = "disabled";
+
+ qcom,ctl@1d00 {
+ reg = <0x1d00 0x100>;
+ };
+ qcom,ps@1e00 {
+ reg = <0x1e00 0x100>;
+ };
+ qcom,freq@1f00 {
+ reg = <0x1f00 0x100>;
+ };
+ };
+
+ regulator@2000 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_s5";
+ spmi-dev-container;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x2000 0x300>;
+ status = "disabled";
+
+ qcom,ctl@2000 {
+ reg = <0x2000 0x100>;
+ };
+ qcom,ps@2100 {
+ reg = <0x2100 0x100>;
+ };
+ qcom,freq@2200 {
+ reg = <0x2200 0x100>;
+ };
+ };
+
+ regulator@4000 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_l1";
+ reg = <0x4000 0x100>;
+ status = "disabled";
+ };
+
+ regulator@4100 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_l2";
+ reg = <0x4100 0x100>;
+ status = "disabled";
+ };
+
+ regulator@4200 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_l3";
+ reg = <0x4200 0x100>;
+ status = "disabled";
+ };
+
+ regulator@4300 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_l4";
+ reg = <0x4300 0x100>;
+ status = "disabled";
+ };
+
+ regulator@4400 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_l5";
+ reg = <0x4400 0x100>;
+ status = "disabled";
+ };
+
+ regulator@4500 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_l6";
+ reg = <0x4500 0x100>;
+ status = "disabled";
+ };
+
+ regulator@4600 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_l7";
+ reg = <0x4600 0x100>;
+ status = "disabled";
+ };
+
+ regulator@4700 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_l8";
+ reg = <0x4700 0x100>;
+ status = "disabled";
+ };
+
+ regulator@4800 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_l9";
+ reg = <0x4800 0x100>;
+ status = "disabled";
+ };
+
+ regulator@4900 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_l10";
+ reg = <0x4900 0x100>;
+ status = "disabled";
+ };
+
+ regulator@4a00 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_l11";
+ reg = <0x4a00 0x100>;
+ status = "disabled";
+ };
+
+ regulator@4b00 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_l12";
+ reg = <0x4b00 0x100>;
+ status = "disabled";
+ };
+
+ regulator@4c00 {
+ compatible = "qcom,qpnp-regulator";
+ regulator-name = "9650_l13";
+ reg = <0x4c00 0x100>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-cdp-256.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-cdp-256.dtsi
index 8a7b771..0f9c8bc 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-cdp-256.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-cdp-256.dtsi
@@ -11,3 +11,13 @@
*/
#include "sdxpoorwills-cdp.dtsi"
+
+&soc {
+ vreg_sd_mmc: vreg_sd_mmc {
+ gpio = <&tlmm 76 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&sdhc_1 {
+ cd-gpios = <&tlmm 21 0x1>;
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-mtp-256.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-mtp-256.dtsi
index 4a2ece8c..7412031 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-mtp-256.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-mtp-256.dtsi
@@ -11,3 +11,13 @@
*/
#include "sdxpoorwills-mtp.dtsi"
+
+&soc {
+ vreg_sd_mmc: vreg_sd_mmc {
+ gpio = <&tlmm 76 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&sdhc_1 {
+ cd-gpios = <&tlmm 21 0x1>;
+};
diff --git a/arch/arm/configs/mdm_defconfig b/arch/arm/configs/mdm_defconfig
new file mode 100644
index 0000000..d5185cb
--- /dev/null
+++ b/arch/arm/configs/mdm_defconfig
@@ -0,0 +1,355 @@
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_SCHED=y
+# CONFIG_FAIR_GROUP_SCHED is not set
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+CONFIG_PROFILING=y
+CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ARCH_QCOM=y
+CONFIG_ARCH_MDM9650=y
+# CONFIG_VDSO is not set
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_CMA=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IPV6_PIMSM_V2=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_TIMEOUT=y
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_SNMP=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NF_CT_NETLINK_TIMEOUT=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
+CONFIG_NETFILTER_XT_TARGET_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
+CONFIG_NETFILTER_XT_MATCH_ESP=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+# CONFIG_NETFILTER_XT_MATCH_L2TP is not set
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_IP_SET=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NATTYPE_MODULE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_ECN=y
+CONFIG_IP_NF_TARGET_TTL=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_AH=y
+CONFIG_IP6_NF_MATCH_FRAG=y
+CONFIG_IP6_NF_MATCH_OPTS=y
+CONFIG_IP6_NF_MATCH_HL=y
+CONFIG_IP6_NF_MATCH_IPV6HEADER=y
+CONFIG_IP6_NF_MATCH_MH=y
+CONFIG_IP6_NF_MATCH_RT=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_BRIDGE_EBT_T_FILTER=y
+CONFIG_BRIDGE_EBT_T_NAT=y
+CONFIG_BRIDGE_EBT_ARP=y
+CONFIG_BRIDGE_EBT_IP=y
+CONFIG_BRIDGE_EBT_IP6=y
+CONFIG_BRIDGE_EBT_ARPREPLY=y
+CONFIG_BRIDGE_EBT_DNAT=y
+CONFIG_BRIDGE_EBT_SNAT=y
+CONFIG_L2TP=y
+CONFIG_L2TP_DEBUGFS=y
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+CONFIG_BRIDGE=y
+CONFIG_VLAN_8021Q=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_RMNET_DATA=y
+CONFIG_RMNET_DATA_FC=y
+CONFIG_RMNET_DATA_DEBUG_PKT=y
+CONFIG_CAN=y
+CONFIG_CAN_VCAN=y
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_CFG80211=y
+CONFIG_CFG80211_DEBUGFS=y
+CONFIG_CFG80211_INTERNAL_REGDB=y
+CONFIG_CFG80211_WEXT=y
+CONFIG_RFKILL=y
+CONFIG_IPC_ROUTER=y
+CONFIG_IPC_ROUTER_SECURITY=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=12
+CONFIG_MTD=y
+CONFIG_MTD_TESTS=m
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_UBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_QSEECOM=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_NETDEVICES=y
+CONFIG_TUN=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+CONFIG_KS8851=y
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_MICREL_PHY=y
+CONFIG_PPP=y
+CONFIG_PPPOL2TP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_SMSC75XX=y
+CONFIG_USB_NET_SMSC95XX=y
+CONFIG_WCNSS_MEM_PRE_ALLOC=y
+CONFIG_CNSS=y
+CONFIG_CNSS_SDIO=y
+CONFIG_CLD_LL_CORE=y
+CONFIG_CNSS_LOGGER=y
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=m
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_SPI=y
+CONFIG_SPI_SPIDEV=m
+CONFIG_SLIMBUS=y
+CONFIG_SPMI=y
+CONFIG_PPS_CLIENT_GPIO=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PINCTRL_MDM9650=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_SMB1351_USB_CHARGER=y
+CONFIG_THERMAL=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_CPR=y
+CONFIG_REGULATOR_MEM_ACC=y
+CONFIG_REGULATOR_SPM=y
+CONFIG_REGULATOR_STUB=y
+CONFIG_FB=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_TLV320AIC3X=y
+CONFIG_UHID=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_ELECOM=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DEBUG=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_DEBUG_FS=y
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_CI13XXX_MSM=y
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_TEST=m
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_RTC_CLASS=y
+CONFIG_DMADEVICES=y
+CONFIG_UIO=y
+CONFIG_UIO_MSM_SHAREDMEM=y
+CONFIG_STAGING=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_IPA=y
+CONFIG_RMNET_IPA=y
+CONFIG_GSI=y
+CONFIG_IPA3=y
+CONFIG_RMNET_IPA3=y
+CONFIG_SPS=y
+CONFIG_SPS_SUPPORT_NDP_BAM=y
+CONFIG_USB_BAM=y
+CONFIG_COMMON_CLK_MSM=y
+CONFIG_MAILBOX=y
+CONFIG_MSM_BOOT_STATS=y
+CONFIG_MSM_GLINK=y
+CONFIG_MSM_GLINK_LOOPBACK_SERVER=y
+CONFIG_TRACER_PKT=y
+CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y
+CONFIG_MSM_QMI_INTERFACE=y
+CONFIG_MSM_GLINK_PKT=y
+CONFIG_MSM_SUBSYSTEM_RESTART=y
+CONFIG_MSM_PIL=y
+CONFIG_MSM_PIL_SSR_GENERIC=y
+CONFIG_MSM_PIL_MSS_QDSP6V5=y
+CONFIG_CNSS_CRYPTO=y
+CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
+CONFIG_IIO=y
+CONFIG_IIO_BUFFER=y
+CONFIG_IIO_BUFFER_CB=y
+CONFIG_IIO_ST_ACCEL_3AXIS=y
+CONFIG_IIO_ST_GYRO_3AXIS=y
+CONFIG_PWM=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_MSM_TZ_LOG=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_DEBUG_KMEMLEAK=y
+CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_PANIC_TIMEOUT=5
+CONFIG_SCHEDSTATS=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_DEBUG_LIST=y
+CONFIG_FAULT_INJECTION=y
+CONFIG_FAIL_PAGE_ALLOC=y
+CONFIG_FAULT_INJECTION_DEBUG_FS=y
+CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
+CONFIG_IPC_LOGGING=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/msm8909w-perf_defconfig b/arch/arm/configs/msm8909w-perf_defconfig
index 9533fbf..8b6a931 100644
--- a/arch/arm/configs/msm8909w-perf_defconfig
+++ b/arch/arm/configs/msm8909w-perf_defconfig
@@ -258,11 +258,13 @@
CONFIG_INPUT_JOYSTICK=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_MISC=y
+CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_INPUT_UINPUT=y
CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
CONFIG_SERIAL_MSM_HS=y
CONFIG_SERIAL_MSM_SMD=y
+CONFIG_DIAG_CHAR=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_MSM_LEGACY=y
CONFIG_MSM_SMD_PKT=y
diff --git a/arch/arm/configs/msm8909w_defconfig b/arch/arm/configs/msm8909w_defconfig
index 9533fbf..8b6a931 100644
--- a/arch/arm/configs/msm8909w_defconfig
+++ b/arch/arm/configs/msm8909w_defconfig
@@ -258,11 +258,13 @@
CONFIG_INPUT_JOYSTICK=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_MISC=y
+CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_INPUT_UINPUT=y
CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
CONFIG_SERIAL_MSM_HS=y
CONFIG_SERIAL_MSM_SMD=y
+CONFIG_DIAG_CHAR=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_MSM_LEGACY=y
CONFIG_MSM_SMD_PKT=y
diff --git a/arch/arm/configs/msm8953-perf_defconfig b/arch/arm/configs/msm8953-perf_defconfig
index 40316bd..62c90b3 100644
--- a/arch/arm/configs/msm8953-perf_defconfig
+++ b/arch/arm/configs/msm8953-perf_defconfig
@@ -238,6 +238,7 @@
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_HDCP_QSEECOM=y
CONFIG_QSEECOM=y
CONFIG_MEMORY_STATE_TIME=y
CONFIG_SCSI=y
@@ -284,6 +285,7 @@
CONFIG_INPUT_JOYSTICK=y
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
@@ -350,6 +352,8 @@
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSM_VIDC_3X_V4L2=y
+CONFIG_MSM_VIDC_3X_GOVERNORS=y
CONFIG_QCOM_KGSL=y
CONFIG_FB=y
CONFIG_FB_MSM=y
@@ -501,6 +505,7 @@
CONFIG_ICNSS=y
CONFIG_MSM_PERFORMANCE=y
CONFIG_MSM_EVENT_TIMER=y
+CONFIG_MSM_AVTIMER=y
CONFIG_MSM_PM=y
CONFIG_QTI_RPM_STATS_LOG=y
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
@@ -532,6 +537,7 @@
CONFIG_FUSE_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
CONFIG_ECRYPT_FS=y
CONFIG_ECRYPT_FS_MESSAGING=y
# CONFIG_NETWORK_FILESYSTEMS is not set
diff --git a/arch/arm/configs/msm8953_defconfig b/arch/arm/configs/msm8953_defconfig
index 54c2d86..144235f 100644
--- a/arch/arm/configs/msm8953_defconfig
+++ b/arch/arm/configs/msm8953_defconfig
@@ -363,6 +363,8 @@
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSM_VIDC_3X_V4L2=y
+CONFIG_MSM_VIDC_3X_GOVERNORS=y
CONFIG_QCOM_KGSL=y
CONFIG_FB=y
CONFIG_FB_VIRTUAL=y
@@ -523,6 +525,7 @@
CONFIG_ICNSS=y
CONFIG_MSM_PERFORMANCE=y
CONFIG_MSM_EVENT_TIMER=y
+CONFIG_MSM_AVTIMER=y
CONFIG_MSM_PM=y
CONFIG_QTI_RPM_STATS_LOG=y
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h
index 41e9107..62d32bc 100644
--- a/arch/arm/include/asm/topology.h
+++ b/arch/arm/include/asm/topology.h
@@ -28,6 +28,8 @@
#ifdef CONFIG_CPU_FREQ
#define arch_scale_freq_capacity cpufreq_scale_freq_capacity
+#define arch_scale_max_freq_capacity cpufreq_scale_max_freq_capacity
+#define arch_scale_min_freq_capacity cpufreq_scale_min_freq_capacity
#endif
#define arch_scale_cpu_capacity scale_cpu_capacity
extern unsigned long scale_cpu_capacity(struct sched_domain *sd, int cpu);
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index dad9fcb..aa8fc3f 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -55,13 +55,7 @@
unsigned long scale_cpu_capacity(struct sched_domain *sd, int cpu)
{
-#ifdef CONFIG_CPU_FREQ
- unsigned long max_freq_scale = cpufreq_scale_max_freq_capacity(cpu);
-
- return per_cpu(cpu_scale, cpu) * max_freq_scale >> SCHED_CAPACITY_SHIFT;
-#else
return per_cpu(cpu_scale, cpu);
-#endif
}
static void set_capacity_scale(unsigned int cpu, unsigned long capacity)
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
index 273789c..e8d96df 100644
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -126,5 +126,31 @@
select HAVE_CLK_PREPARE
select COMMON_CLK_MSM
+config ARCH_MDM9650
+ bool "MDM9650"
+ select ARM_GIC
+ select CPU_V7
+ select REGULATOR
+ select REGULATOR_RPM_SMD
+ select HAVE_ARM_ARCH_TIMER
+ select MSM_RPM_SMD
+ select MSM_SPM
+ select MSM_PM if PM
+ select QMI_ENCDEC
+ select MSM_CORTEX_A7
+ select PINCTRL
+ select PINCTRL_MSM_TLMM
+ select USE_PINCTRL_IRQ
+ select PCI
+ select MSM_IRQ
+ select MSM_JTAG_MM if CORESIGHT_ETM
+ select MSM_CLK_CONTROLLER_V2
+ select PM_DEVFREQ
+ select MSM_DEVFREQ_DEVBW
+ select DEVFREQ_SIMPLE_DEV
+ select MSM_RPM_LOG
+ select MSM_RPM_STATS_LOG
+ select HAVE_CLK_PREPARE
+
endmenu
endif
diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile
index 9fb2bfb..cfc4eac 100644
--- a/arch/arm/mach-qcom/Makefile
+++ b/arch/arm/mach-qcom/Makefile
@@ -6,3 +6,4 @@
obj-$(CONFIG_ARCH_MSM8909) += board-msm8909.o
obj-$(CONFIG_ARCH_MSM8917) += board-msm8917.o
obj-$(CONFIG_ARCH_SDM450) += board-sdm450.o
+obj-$(CONFIG_ARCH_MDM9650) += board-9650.o
diff --git a/arch/arm/mach-qcom/board-9650.c b/arch/arm/mach-qcom/board-9650.c
new file mode 100644
index 0000000..ddc043c
--- /dev/null
+++ b/arch/arm/mach-qcom/board-9650.c
@@ -0,0 +1,32 @@
+/* Copyright (c) 2015, 2017-2018, 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 <linux/kernel.h>
+#include "board-dt.h"
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+
+static const char *mdm9650_dt_match[] __initconst = {
+ "qcom,mdm9650",
+ NULL
+};
+
+static void __init mdm9650_init(void)
+{
+ board_dt_populate(NULL);
+}
+
+DT_MACHINE_START(MDM9650_DT,
+ "Qualcomm Technologies, Inc. MDM 9650 (Flattened Device Tree)")
+ .init_machine = mdm9650_init,
+ .dt_compat = mdm9650_dt_match,
+MACHINE_END
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 0a05c0a..b57aafc 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1024,9 +1024,10 @@
.page = page,
.want_vaddr = ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) == 0),
};
+ void *addr = (args.want_vaddr) ? cpu_addr : page;
- buf = arm_dma_buffer_find(cpu_addr);
- if (WARN(!buf, "Freeing invalid buffer %p\n", cpu_addr))
+ buf = arm_dma_buffer_find(addr);
+ if (WARN(!buf, "Freeing invalid buffer %pK\n", addr))
return;
buf->allocator->free(&args);
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-hx8399c-hd-plus-video.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-hx8399c-hd-plus-video.dtsi
new file mode 100644
index 0000000..fc09a65
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-hx8399c-hd-plus-video.dtsi
@@ -0,0 +1,137 @@
+/* Copyright (c) 2018, 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.
+ */
+
+&mdss_mdp {
+ dsi_hx8399c_hd_vid: qcom,mdss_dsi_hx8399c_hd_video{
+ qcom,mdss-dsi-panel-name =
+ "hx8399c video mode dsi hd panel";
+ qcom,mdss-dsi-panel-type = "dsi_video_mode";
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-virtual-channel-id = <0>;
+ qcom,mdss-dsi-stream = <0>;
+ qcom,mdss-dsi-panel-width = <720>;
+ qcom,mdss-dsi-panel-height = <1440>;
+ qcom,mdss-dsi-h-front-porch = <24>;
+ qcom,mdss-dsi-h-back-porch = <24>;
+ qcom,mdss-dsi-h-pulse-width = <16>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <40>;
+ qcom,mdss-dsi-v-front-porch = <36>;
+ qcom,mdss-dsi-v-pulse-width = <2>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-bpp = <24>;
+ qcom,mdss-dsi-color-order = "rgb_swap_rgb";
+ qcom,mdss-dsi-underflow-color = <0xff>;
+ qcom,mdss-dsi-border-color = <0>;
+ qcom,mdss-dsi-on-command = [
+ 39 01 00 00 00 00 04
+ b9 ff 83 99
+ 39 01 00 00 00 00 02
+ d2 88
+ 39 01 00 00 00 00 10
+ b1 02 04 74 94 01 32 33
+ 11 11 e6 5d 56 73 02 02
+ 39 01 00 00 00 00 10
+ b2 00 80 80 cc 05 07 5a
+ 11 10 10 00 1e 70 03 D4
+ 39 01 00 00 00 00 2d
+ b4 00 ff 59 59 0c ac 00
+ 00 0c 00 07 0a 00 28 07
+ 08 0c 21 03 00 00 00 ae
+ 87 59 59 0c ac 00 00 0c
+ 00 07 0a 00 28 07 08 0c
+ 01 00 00 ae 01
+ 39 01 00 00 05 00 22
+ d3 00 00 01 01 00 00 10
+ 10 00 00 03 00 03 00 08
+ 78 08 78 00 00 00 00 00
+ 24 02 05 05 03 00 00 00
+ 05 40
+ 39 01 00 00 05 00 21
+ d5 20 20 19 19 18 18 02
+ 03 00 01 24 24 18 18 18
+ 18 24 24 00 00 00 00 00
+ 00 00 00 2f 2f 30 30 31
+ 31
+ 39 01 00 00 05 00 21
+ d6 24 24 18 18 19 19 01
+ 00 03 02 24 24 18 18 18
+ 18 20 20 40 40 40 40 40
+ 40 40 40 2f 2f 30 30 31
+ 31
+ 39 01 00 00 00 00 02
+ bd 00
+ 39 01 00 00 00 00 11
+ d8 aa aa aa aa aa aa aa
+ aa aa ba aa aa aa ba aa
+ aa
+ 39 01 00 00 00 00 02
+ bd 01
+ 39 01 00 00 00 00 11
+ d8 82 ea aa aa 82 ea aa
+ aa 82 ea aa aa 82 ea aa
+ aa
+ 39 01 00 00 00 00 02
+ bd 02
+ 39 01 00 00 00 00 09
+ d8 ff ff c0 3f ff ff c0
+ 3f
+ 39 01 00 00 00 00 02
+ bd 00
+ 39 01 00 00 00 00 02
+ dd 03
+ 39 01 00 00 05 00 37
+ e0 08 2a 39 35 74 7c 87
+ 7f 84 8a 8e 91 93 96 9b
+ 9c 9e a5 a6 ae a1 af b2
+ 5c 58 63 74 08 2a 39 35
+ 74 7c 87 7f 84 8a 8e 91
+ 93 96 9b 9c 9e a5 a6 ae
+ a1 af b2 5c 58 63 74
+ 39 01 00 00 00 00 03
+ b6 7e 7e
+ 39 01 00 00 00 00 02
+ cc 08
+ 39 01 00 00 00 00 06
+ c7 00 08 00 01 08
+ 39 01 00 00 00 00 03
+ c0 25 5a
+ 05 01 00 00 78 00 02 11 00
+ 05 01 00 00 14 00 02 29 00];
+ qcom,mdss-dsi-off-command = [
+ 05 01 00 00 14 00 02 28 00
+ 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ qcom,mdss-dsi-traffic-mode = "non_burst_sync_event";
+ qcom,mdss-dsi-lane-map = "lane_map_0123";
+ qcom,mdss-dsi-bllp-eof-power-mode;
+ qcom,mdss-dsi-bllp-power-mode;
+ qcom,mdss-dsi-tx-eot-append;
+ qcom,mdss-dsi-lane-0-state;
+ qcom,mdss-dsi-lane-1-state;
+ qcom,mdss-dsi-lane-2-state;
+ qcom,mdss-dsi-lane-3-state;
+ qcom,mdss-dsi-panel-timings =
+ [7a 1a 12 00 3e 42 16 1e 03 04 00];
+ qcom,mdss-dsi-t-clk-post = <0x0a>;
+ qcom,mdss-dsi-t-clk-pre = <0x1d>;
+ qcom,mdss-dsi-dma-trigger = "trigger_sw";
+ qcom,mdss-dsi-mdp-trigger = "none";
+ qcom,mdss-dsi-lp11-init;
+ qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8909.dtsi b/arch/arm64/boot/dts/qcom/msm8909.dtsi
index 9467beb..7b38370 100644
--- a/arch/arm64/boot/dts/qcom/msm8909.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8909.dtsi
@@ -23,10 +23,6 @@
<275 0>;
interrupt-parent = <&intc>;
- chosen {
- bootargs = "sched_enable_hmp=1";
- };
-
aliases {
/* smdtty devices */
smd1 = &smdtty_apps_fm;
@@ -78,6 +74,8 @@
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0x0>;
+ efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
qcom,sleep-status = <&cpu0_slp_sts>;
qcom,limits-info = <&mitigation_profile0>;
};
@@ -86,6 +84,8 @@
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0x1>;
+ efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
qcom,sleep-status = <&cpu1_slp_sts>;
qcom,limits-info = <&mitigation_profile2>;
};
@@ -94,6 +94,8 @@
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0x2>;
+ efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
qcom,sleep-status = <&cpu2_slp_sts>;
qcom,limits-info = <&mitigation_profile1>;
};
@@ -102,11 +104,38 @@
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0x3>;
+ efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
qcom,sleep-status = <&cpu3_slp_sts>;
qcom,limits-info = <&mitigation_profile2>;
};
};
+ energy_costs: energy-costs {
+ compatible = "sched-energy";
+
+ CPU_COST_0: core-cost0 {
+ busy-cost-data = <
+ 400000 82
+ 800000 164
+ 1094400 290
+ >;
+ idle-cost-data = <
+ 40 20 12 8
+ >;
+ };
+ CLUSTER_COST_0: cluster-cost0 {
+ busy-cost-data = <
+ 400000 23
+ 800000 48
+ 1094400 87
+ >;
+ idle-cost-data = <
+ 4 3 2 1
+ >;
+ };
+ };
+
firmware: firmware {
android {
compatible = "android,firmware";
@@ -326,7 +355,7 @@
reg-names = "rcg-base", "efuse";
qcom,safe-freq = < 400000000 >;
cpu-vdd-supply = <&pm8909_s1_corner_ao>;
- qcom,a7ssmux-opp-store-vcorner = <&CPU0>;
+ qcom,enable-opp;
clocks = <&clock_gcc clk_gpll0_ao_clk_src>,
<&clock_gcc clk_a7sspll>;
clock-names = "clk-4", "clk-5";
diff --git a/arch/arm64/boot/dts/qcom/msm8909w.dtsi b/arch/arm64/boot/dts/qcom/msm8909w.dtsi
index d35407c..707b56e 100644
--- a/arch/arm64/boot/dts/qcom/msm8909w.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8909w.dtsi
@@ -10,12 +10,6 @@
* GNU General Public License for more details.
*/
-/ {
- chosen {
- bootargs="sched_enable_hmp=0";
- };
-};
-
&soc {
/delete-node/ qcom,clock-a7@0b011050;
clock_cpu: qcom,clock-a7@0b011050 {
@@ -28,7 +22,7 @@
clocks = <&clock_gcc clk_gpll0_ao_clk_src>,
<&clock_gcc clk_a7sspll>;
clock-names = "clk-4", "clk-5";
- qcom,a7ssmux-opp-store-vcorner = <&CPU0>;
+ qcom,enable-opp;
qcom,speed0-bin-v0 =
< 0 0>,
< 800000000 4>,
diff --git a/arch/arm64/boot/dts/qcom/msm8917-bus.dtsi b/arch/arm64/boot/dts/qcom/msm8917-bus.dtsi
new file mode 100644
index 0000000..4a860e7
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8917-bus.dtsi
@@ -0,0 +1,987 @@
+/*
+ * Copyright (c) 2015-2016, 2018, 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/msm/msm-bus-ids.h>
+
+&soc {
+ /* Version = 11 */
+ ad_hoc_bus: ad-hoc-bus@580000 {
+ compatible = "qcom,msm-bus-device";
+ reg = <0x580000 0x16080>,
+ <0x580000 0x16080>,
+ <0x400000 0x5a000>,
+ <0x500000 0x13080>;
+ reg-names = "snoc-base", "snoc-mm-base",
+ "bimc-base", "pcnoc-base";
+
+ /* Buses */
+ fab_bimc: fab-bimc {
+ cell-id = <MSM_BUS_FAB_BIMC>;
+ label = "fab-bimc";
+ qcom,fab-dev;
+ qcom,base-name = "bimc-base";
+ qcom,bus-type = <2>;
+ qcom,util-fact = <154>;
+ clock-names = "bus_clk", "bus_a_clk";
+ clocks = <&clock_gcc clk_bimc_msmbus_clk>,
+ <&clock_gcc clk_bimc_msmbus_a_clk>;
+ };
+
+ fab_pcnoc: fab-pcnoc {
+ cell-id = <MSM_BUS_FAB_PERIPH_NOC>;
+ label = "fab-pcnoc";
+ qcom,fab-dev;
+ qcom,base-name = "pcnoc-base";
+ qcom,base-offset = <0x7000>;
+ qcom,qos-off = <0x1000>;
+ qcom,bus-type = <1>;
+ clock-names = "bus_clk", "bus_a_clk";
+ clocks = <&clock_gcc clk_pnoc_msmbus_clk>,
+ <&clock_gcc clk_pnoc_msmbus_a_clk>;
+ };
+
+ fab_snoc: fab-snoc {
+ cell-id = <MSM_BUS_FAB_SYS_NOC>;
+ label = "fab-snoc";
+ qcom,fab-dev;
+ qcom,base-name = "snoc-base";
+ qcom,base-offset = <0x7000>;
+ qcom,qos-off = <0x1000>;
+ qcom,bus-type = <1>;
+ clock-names = "bus_clk", "bus_a_clk";
+ clocks = <&clock_gcc clk_snoc_msmbus_clk>,
+ <&clock_gcc clk_snoc_msmbus_a_clk>;
+ };
+
+ fab_snoc_mm: fab-snoc-mm {
+ cell-id = <MSM_BUS_FAB_MMSS_NOC>;
+ label = "fab-snoc-mm";
+ qcom,fab-dev;
+ qcom,base-name = "snoc-mm-base";
+ qcom,base-offset = <0x7000>;
+ qcom,qos-off = <0x1000>;
+ qcom,bus-type = <1>;
+ qcom,util-fact = <154>;
+ clock-names = "bus_clk", "bus_a_clk";
+ clocks = <&clock_gcc clk_sysmmnoc_msmbus_clk>,
+ <&clock_gcc clk_sysmmnoc_msmbus_a_clk>;
+ };
+
+ /* BIMC Masters */
+ mas_apps_proc: mas-apps-proc {
+ cell-id = <MSM_BUS_MASTER_AMPSS_M0>;
+ label = "mas-apps-proc";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <0>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&slv_ebi &slv_bimc_snoc>;
+ qcom,prio-lvl = <0>;
+ qcom,prio-rd = <0>;
+ qcom,prio-wr = <0>;
+ qcom,bus-dev = <&fab_bimc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_APPSS_PROC>;
+ };
+
+ mas_oxili: mas-oxili {
+ cell-id = <MSM_BUS_MASTER_GRAPHICS_3D>;
+ label = "mas-oxili";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <2>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&slv_ebi &slv_bimc_snoc>;
+ qcom,prio-lvl = <0>;
+ qcom,prio-rd = <0>;
+ qcom,prio-wr = <0>;
+ qcom,bus-dev = <&fab_bimc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_GFX3D>;
+ };
+
+ mas_snoc_bimc_0: mas-snoc-bimc-0 {
+ cell-id = <MSM_BUS_SNOC_BIMC_0_MAS>;
+ label = "mas-snoc-bimc-0";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <3>;
+ qcom,qos-mode = "bypass";
+ qcom,connections = <&slv_ebi &slv_bimc_snoc>;
+ qcom,bus-dev = <&fab_bimc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_SNOC_BIMC_0>;
+ };
+
+ mas_snoc_bimc_2: mas-snoc-bimc-2 {
+ cell-id = <MSM_BUS_SNOC_BIMC_2_MAS>;
+ label = "mas-snoc-bimc-2";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <4>;
+ qcom,qos-mode = "bypass";
+ qcom,connections = <&slv_ebi &slv_bimc_snoc>;
+ qcom,bus-dev = <&fab_bimc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_SNOC_BIMC_2>;
+ };
+
+ mas_snoc_bimc_1: mas-snoc-bimc-1 {
+ cell-id = <MSM_BUS_SNOC_BIMC_1_MAS>;
+ label = "mas-snoc-bimc-1";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,qport = <5>;
+ qcom,qos-mode = "bypass";
+ qcom,connections = <&slv_ebi>;
+ qcom,bus-dev = <&fab_bimc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_SNOC_BIMC_1>;
+ };
+
+ mas_tcu_0: mas-tcu-0 {
+ cell-id = <MSM_BUS_MASTER_TCU_0>;
+ label = "mas-tcu-0";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <6>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&slv_ebi &slv_bimc_snoc>;
+ qcom,prio-lvl = <2>;
+ qcom,prio-rd = <2>;
+ qcom,bus-dev = <&fab_bimc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_TCU_0>;
+ };
+
+ /* PCNOC Masters */
+ mas_spdm: mas-spdm {
+ cell-id = <MSM_BUS_MASTER_SPDM>;
+ label = "mas-spdm";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,connections = <&pcnoc_m_0>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_SPDM>;
+ };
+
+ mas_blsp_1: mas-blsp-1 {
+ cell-id = <MSM_BUS_MASTER_BLSP_1>;
+ label = "mas-blsp-1";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&pcnoc_m_1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_BLSP_1>;
+ };
+
+ mas_blsp_2: mas-blsp-2 {
+ cell-id = <MSM_BUS_MASTER_BLSP_2>;
+ label = "mas-blsp-2";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&pcnoc_m_1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_BLSP_2>;
+ };
+
+ mas_usb_hs1: mas-usb-hs1 {
+ cell-id = <MSM_BUS_MASTER_USB_HS>;
+ label = "mas-usb-hs1";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <12>;
+ qcom,qos-mode = "fixed";
+ qcom,prio1 = <1>;
+ qcom,prio0 = <1>;
+ qcom,connections = <&pcnoc_int_0>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_USB_HS1>;
+ };
+
+ mas_xi_usb_hs1: mas-xi-usb-hs1 {
+ cell-id = <MSM_BUS_MASTER_XM_USB_HS1>;
+ label = "mas-xi-usb-hs1";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,qport = <11>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&pcnoc_int_0>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_XI_USB_HS1>;
+ };
+
+ mas_crypto: mas-crypto {
+ cell-id = <MSM_BUS_MASTER_CRYPTO_CORE0>;
+ label = "mas-crypto";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <0>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&pcnoc_int_0>;
+ qcom,prio1 = <1>;
+ qcom,prio0 = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_CRYPTO>;
+ };
+
+ mas_sdcc_1: mas-sdcc-1 {
+ cell-id = <MSM_BUS_MASTER_SDCC_1>;
+ label = "mas-sdcc-1";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,qport = <7>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&pcnoc_int_0>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_SDCC_1>;
+ };
+
+ mas_sdcc_2: mas-sdcc-2 {
+ cell-id = <MSM_BUS_MASTER_SDCC_2>;
+ label = "mas-sdcc-2";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,qport = <8>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&pcnoc_int_0>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_SDCC_2>;
+ };
+
+ mas_snoc_pcnoc: mas-snoc-pcnoc {
+ cell-id = <MSM_BUS_SNOC_PNOC_MAS>;
+ label = "mas-snoc-pcnoc";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,qport = <9>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&pcnoc_s_7
+ &pcnoc_int_2 &pcnoc_int_3>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_SNOC_PCNOC>;
+ };
+
+ /* SNOC Masters */
+ mas_qdss_bam: mas-qdss-bam {
+ cell-id = <MSM_BUS_MASTER_QDSS_BAM>;
+ label = "mas-qdss-bam";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <11>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&qdss_int>;
+ qcom,prio1 = <1>;
+ qcom,prio0 = <1>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_QDSS_BAM>;
+ };
+
+ mas_bimc_snoc: mas-bimc-snoc {
+ cell-id = <MSM_BUS_BIMC_SNOC_MAS>;
+ label = "mas-bimc-snoc";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&snoc_int_0
+ &snoc_int_1 &snoc_int_2>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_BIMC_SNOC>;
+ };
+
+ mas_jpeg: mas-jpeg {
+ cell-id = <MSM_BUS_MASTER_JPEG>;
+ label = "mas-jpeg";
+ qcom,buswidth = <16>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <6>;
+ qcom,qos-mode = "bypass";
+ qcom,connections = <&slv_snoc_bimc_2>;
+ qcom,bus-dev = <&fab_snoc_mm>;
+ qcom,mas-rpm-id = <ICBID_MASTER_JPEG>;
+ };
+
+ mas_mdp: mas-mdp {
+ cell-id = <MSM_BUS_MASTER_MDP_PORT0>;
+ label = "mas-mdp";
+ qcom,buswidth = <16>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <7>;
+ qcom,qos-mode = "bypass";
+ qcom,connections = <&slv_snoc_bimc_0>;
+ qcom,bus-dev = <&fab_snoc_mm>;
+ qcom,mas-rpm-id = <ICBID_MASTER_MDP>;
+ };
+
+ mas_pcnoc_snoc: mas-pcnoc-snoc {
+ cell-id = <MSM_BUS_PNOC_SNOC_MAS>;
+ label = "mas-pcnoc-snoc";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,qport = <5>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&snoc_int_0
+ &snoc_int_1 &slv_snoc_bimc_1>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PNOC_SNOC>;
+ qcom,blacklist = <&slv_snoc_pcnoc>;
+ };
+
+ mas_venus: mas-venus {
+ cell-id = <MSM_BUS_MASTER_VIDEO_P0>;
+ label = "mas-venus";
+ qcom,buswidth = <16>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <8>;
+ qcom,qos-mode = "bypass";
+ qcom,connections = <&slv_snoc_bimc_2>;
+ qcom,bus-dev = <&fab_snoc_mm>;
+ qcom,mas-rpm-id = <ICBID_MASTER_VIDEO>;
+ };
+
+ mas_vfe0: mas-vfe0 {
+ cell-id = <MSM_BUS_MASTER_VFE>;
+ label = "mas-vfe0";
+ qcom,buswidth = <16>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <9>;
+ qcom,qos-mode = "bypass";
+ qcom,connections = <&slv_snoc_bimc_0>;
+ qcom,bus-dev = <&fab_snoc_mm>;
+ qcom,mas-rpm-id = <ICBID_MASTER_VFE>;
+ };
+
+ mas_vfe1: mas-vfe1 {
+ cell-id = <MSM_BUS_MASTER_VFE1>;
+ label = "mas-vfe1";
+ qcom,buswidth = <16>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <13>;
+ qcom,qos-mode = "bypass";
+ qcom,connections = <&slv_snoc_bimc_0>;
+ qcom,bus-dev = <&fab_snoc_mm>;
+ qcom,mas-rpm-id = <ICBID_MASTER_VFE1>;
+ };
+
+ mas_cpp: mas-cpp {
+ cell-id = <MSM_BUS_MASTER_CPP>;
+ label = "mas-cpp";
+ qcom,buswidth = <16>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <12>;
+ qcom,qos-mode = "bypass";
+ qcom,connections = <&slv_snoc_bimc_2>;
+ qcom,bus-dev = <&fab_snoc_mm>;
+ qcom,mas-rpm-id = <ICBID_MASTER_CPP>;
+ };
+
+ mas_qdss_etr: mas-qdss-etr {
+ cell-id = <MSM_BUS_MASTER_QDSS_ETR>;
+ label = "mas-qdss-etr";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <10>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&qdss_int>;
+ qcom,prio1 = <1>;
+ qcom,prio0 = <1>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_QDSS_ETR>;
+ };
+
+ /* Internal nodes */
+ pcnoc_m_0: pcnoc-m-0 {
+ cell-id = <MSM_BUS_PNOC_M_0>;
+ label = "pcnoc-m-0";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <5>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&pcnoc_int_0>;
+ qcom,prio1 = <1>;
+ qcom,prio0 = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_M_0>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_M_0>;
+ };
+
+ pcnoc_m_1: pcnoc-m-1 {
+ cell-id = <MSM_BUS_PNOC_M_1>;
+ label = "pcnoc-m-1";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&pcnoc_int_0>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_M_1>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_M_1>;
+ };
+
+ pcnoc_int_0: pcnoc-int-0 {
+ cell-id = <MSM_BUS_PNOC_INT_0>;
+ label = "pcnoc-int-0";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_pcnoc_snoc
+ &pcnoc_s_7 &pcnoc_int_3 &pcnoc_int_2>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_INT_0>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_INT_0>;
+ };
+
+ pcnoc_int_1: pcnoc-int-1 {
+ cell-id = <MSM_BUS_PNOC_INT_1>;
+ label = "pcnoc-int-1";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_pcnoc_snoc
+ &pcnoc_s_7 &pcnoc_int_3 &pcnoc_int_2>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_INT_1>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_INT_1>;
+ };
+
+ pcnoc_int_2: pcnoc-int-2 {
+ cell-id = <MSM_BUS_PNOC_INT_2>;
+ label = "pcnoc-int-2";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&pcnoc_s_2
+ &pcnoc_s_3 &pcnoc_s_6 &pcnoc_s_8>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_INT_2>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_INT_2>;
+ };
+
+ pcnoc_int_3: pcnoc-int-3 {
+ cell-id = <MSM_BUS_PNOC_INT_3>;
+ label = "pcnoc-int-3";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = < &pcnoc_s_1 &pcnoc_s_0 &pcnoc_s_4
+ &slv_gpu_cfg &slv_tcu >;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_INT_3>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_INT_3>;
+ };
+
+ pcnoc_s_0: pcnoc-s-0 {
+ cell-id = <MSM_BUS_PNOC_SLV_0>;
+ label = "pcnoc-s-0";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_spdm &slv_pdm &slv_prng
+ &slv_sdcc_2>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_S_0>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_S_0>;
+ };
+
+ pcnoc_s_1: pcnoc-s-1 {
+ cell-id = <MSM_BUS_PNOC_SLV_1>;
+ label = "pcnoc-s-1";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_tcsr>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_S_1>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_S_1>;
+ };
+
+ pcnoc_s_2: pcnoc-s-2 {
+ cell-id = <MSM_BUS_PNOC_SLV_2>;
+ label = "pcnoc-s-2";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_snoc_cfg>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_S_2>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_S_2>;
+ };
+
+ pcnoc_s_3: pcnoc-s-3 {
+ cell-id = <MSM_BUS_PNOC_SLV_3>;
+ label = "pcnoc-s-3";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_message_ram>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_S_3>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_S_3>;
+ };
+
+ pcnoc_s_4: pcnoc-s-4 {
+ cell-id = <MSM_BUS_PNOC_SLV_4>;
+ label = "pcnoc-s-4";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,connections = <&slv_camera_ss_cfg
+ &slv_disp_ss_cfg &slv_venus_cfg>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_S_4>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_S_4>;
+ };
+
+ pcnoc_s_6: pcnoc-s-6 {
+ cell-id = <MSM_BUS_PNOC_SLV_6>;
+ label = "pcnoc-s-6";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_tlmm &slv_blsp_1 &slv_blsp_2>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_S_6>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_S_6>;
+ };
+
+ pcnoc_s_7: pcnoc-s-7 {
+ cell-id = <MSM_BUS_PNOC_SLV_7>;
+ label = "pcnoc-s-7";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = < &slv_sdcc_1 &slv_pmic_arb>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_S_7>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_S_7>;
+ };
+
+ pcnoc_s_8: pcnoc-s-8 {
+ cell-id = <MSM_BUS_PNOC_SLV_8>;
+ label = "pcnoc-s-8";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_usb_hs &slv_crypto_0_cfg>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_PCNOC_S_8>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_S_8>;
+ };
+
+ qdss_int: qdss-int {
+ cell-id = <MSM_BUS_SNOC_QDSS_INT>;
+ label = "qdss-int";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,connections = <&snoc_int_1 &slv_snoc_bimc_1>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_QDSS_INT>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_QDSS_INT>;
+ };
+
+ snoc_int_0: snoc-int-0 {
+ cell-id = <MSM_BUS_SNOC_INT_0>;
+ label = "snoc-int-0";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,connections = <&slv_lpass
+ &slv_wcss &slv_kpss_ahb>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_SNOC_INT_0>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_SNOC_INT_0>;
+ };
+
+ snoc_int_1: snoc-int-1 {
+ cell-id = <MSM_BUS_SNOC_INT_1>;
+ label = "snoc-int-1";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,connections = <&slv_qdss_stm
+ &slv_imem &slv_snoc_pcnoc>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_SNOC_INT_1>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_SNOC_INT_1>;
+ };
+
+ snoc_int_2: snoc-int-2 {
+ cell-id = <MSM_BUS_SNOC_INT_2>;
+ label = "snoc-int-2";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,connections = <&slv_cats_0 &slv_cats_1>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_SNOC_INT_2>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_SNOC_INT_2>;
+ };
+
+ /* Slaves */
+ slv_ebi:slv-ebi {
+ cell-id = <MSM_BUS_SLAVE_EBI_CH0>;
+ label = "slv-ebi";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_bimc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_EBI1>;
+ };
+
+ slv_bimc_snoc:slv-bimc-snoc {
+ cell-id = <MSM_BUS_BIMC_SNOC_SLV>;
+ label = "slv-bimc-snoc";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_bimc>;
+ qcom,connections = <&mas_bimc_snoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_BIMC_SNOC>;
+ };
+
+ slv_sdcc_2:slv-sdcc-2 {
+ cell-id = <MSM_BUS_SLAVE_SDCC_2>;
+ label = "slv-sdcc-2";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_SDCC_2>;
+ };
+
+ slv_spdm:slv-spdm {
+ cell-id = <MSM_BUS_SLAVE_SPDM_WRAPPER>;
+ label = "slv-spdm";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_SPDM_WRAPPER>;
+ };
+
+ slv_pdm:slv-pdm {
+ cell-id = <MSM_BUS_SLAVE_PDM>;
+ label = "slv-pdm";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PDM>;
+ };
+
+ slv_prng:slv-prng {
+ cell-id = <MSM_BUS_SLAVE_PRNG>;
+ label = "slv-prng";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PRNG>;
+ };
+
+ slv_tcsr:slv-tcsr {
+ cell-id = <MSM_BUS_SLAVE_TCSR>;
+ label = "slv-tcsr";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_TCSR>;
+ };
+
+ slv_snoc_cfg:slv-snoc-cfg {
+ cell-id = <MSM_BUS_SLAVE_SNOC_CFG>;
+ label = "slv-snoc-cfg";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_SNOC_CFG>;
+ };
+
+ slv_message_ram:slv-message-ram {
+ cell-id = <MSM_BUS_SLAVE_MESSAGE_RAM>;
+ label = "slv-message-ram";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_MESSAGE_RAM>;
+ };
+
+ slv_camera_ss_cfg:slv-camera-ss-cfg {
+ cell-id = <MSM_BUS_SLAVE_CAMERA_CFG>;
+ label = "slv-camera-ss-cfg";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_CAMERA_CFG>;
+ };
+
+ slv_disp_ss_cfg:slv-disp-ss-cfg {
+ cell-id = <MSM_BUS_SLAVE_DISPLAY_CFG>;
+ label = "slv-disp-ss-cfg";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_DISPLAY_CFG>;
+ };
+
+ slv_venus_cfg:slv-venus-cfg {
+ cell-id = <MSM_BUS_SLAVE_VENUS_CFG>;
+ label = "slv-venus-cfg";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_VENUS_CFG>;
+ };
+
+ slv_gpu_cfg:slv-gpu-cfg {
+ cell-id = <MSM_BUS_SLAVE_GRAPHICS_3D_CFG>;
+ label = "slv-gpu-cfg";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_GFX3D_CFG>;
+ };
+
+ slv_tlmm:slv-tlmm {
+ cell-id = <MSM_BUS_SLAVE_TLMM>;
+ label = "slv-tlmm";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_TLMM>;
+ };
+
+ slv_blsp_1:slv-blsp-1 {
+ cell-id = <MSM_BUS_SLAVE_BLSP_1>;
+ label = "slv-blsp-1";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_BLSP_1>;
+ };
+
+ slv_blsp_2:slv-blsp-2 {
+ cell-id = <MSM_BUS_SLAVE_BLSP_2>;
+ label = "slv-blsp-2";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_BLSP_2>;
+ };
+
+ slv_pmic_arb:slv-pmic-arb {
+ cell-id = <MSM_BUS_SLAVE_PMIC_ARB>;
+ label = "slv-pmic-arb";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PMIC_ARB>;
+ };
+
+ slv_sdcc_1:slv-sdcc-1 {
+ cell-id = <MSM_BUS_SLAVE_SDCC_1>;
+ label = "slv-sdcc-1";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_SDCC_1>;
+ };
+
+ slv_crypto_0_cfg:slv-crypto-0-cfg {
+ cell-id = <MSM_BUS_SLAVE_CRYPTO_0_CFG>;
+ label = "slv-crypto-0-cfg";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_CRYPTO_0_CFG>;
+ };
+
+ slv_usb_hs:slv-usb-hs {
+ cell-id = <MSM_BUS_SLAVE_USB_HS>;
+ label = "slv-usb-hs";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_USB_HS>;
+ };
+
+ slv_tcu:slv-tcu {
+ cell-id = <MSM_BUS_SLAVE_TCU>;
+ label = "slv-tcu";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_TCU>;
+ };
+
+ slv_pcnoc_snoc:slv-pcnoc-snoc {
+ cell-id = <MSM_BUS_PNOC_SNOC_SLV>;
+ label = "slv-pcnoc-snoc";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_pcnoc>;
+ qcom,connections = <&mas_pcnoc_snoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_PCNOC_SNOC>;
+ };
+
+ slv_kpss_ahb:slv-kpss-ahb {
+ cell-id = <MSM_BUS_SLAVE_APPSS>;
+ label = "slv-kpss-ahb";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_APPSS>;
+ };
+
+ slv_wcss:slv-wcss {
+ cell-id = <MSM_BUS_SLAVE_WCSS>;
+ label = "slv-wcss";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_WCSS>;
+ };
+
+ slv_snoc_bimc_0:slv-snoc-bimc-0 {
+ cell-id = <MSM_BUS_SNOC_BIMC_0_SLV>;
+ label = "slv-snoc-bimc-0";
+ qcom,buswidth = <16>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_snoc_mm>;
+ qcom,connections = <&mas_snoc_bimc_0>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_SNOC_BIMC_0>;
+ };
+
+ slv_snoc_bimc_1:slv-snoc-bimc-1 {
+ cell-id = <MSM_BUS_SNOC_BIMC_1_SLV>;
+ label = "slv-snoc-bimc-1";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,connections = <&mas_snoc_bimc_1>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_SNOC_BIMC_1>;
+ };
+
+ slv_snoc_bimc_2:slv-snoc-bimc-2 {
+ cell-id = <MSM_BUS_SNOC_BIMC_2_SLV>;
+ label = "slv-snoc-bimc-2";
+ qcom,buswidth = <16>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_snoc_mm>;
+ qcom,connections = <&mas_snoc_bimc_2>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_SNOC_BIMC_2>;
+ };
+
+ slv_imem:slv-imem {
+ cell-id = <MSM_BUS_SLAVE_OCIMEM>;
+ label = "slv-imem";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_IMEM>;
+ };
+
+ slv_snoc_pcnoc:slv-snoc-pcnoc {
+ cell-id = <MSM_BUS_SNOC_PNOC_SLV>;
+ label = "slv-snoc-pcnoc";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,connections = <&mas_snoc_pcnoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_SNOC_PCNOC>;
+ };
+
+ slv_qdss_stm:slv-qdss-stm {
+ cell-id = <MSM_BUS_SLAVE_QDSS_STM>;
+ label = "slv-qdss-stm";
+ qcom,buswidth = <4>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_QDSS_STM>;
+ };
+
+ slv_cats_0:slv-cats-0 {
+ cell-id = <MSM_BUS_SLAVE_CATS_128>;
+ label = "slv-cats-0";
+ qcom,buswidth = <16>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_snoc_mm>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_CATS_0>;
+ };
+
+ slv_cats_1:slv-cats-1 {
+ cell-id = <MSM_BUS_SLAVE_OCMEM_64>;
+ label = "slv-cats-1";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_CATS_1>;
+ };
+
+ slv_lpass:slv-lpass {
+ cell-id = <MSM_BUS_SLAVE_LPASS>;
+ label = "slv-lpass";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,slv-rpm-id = <ICBID_SLAVE_LPASS>;
+ };
+ };
+
+ devfreq_spdm_cpu {
+ compatible = "qcom,devfreq_spdm";
+ qcom,msm-bus,name = "devfreq_spdm";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <1 512 0 0>,
+ <1 512 0 0>;
+ qcom,msm-bus,active-only;
+ qcom,spdm-client = <0>;
+
+ clock-names = "cci_clk";
+ clocks = <&clock_cpu clk_a53_bc_clk>;
+
+ qcom,bw-upstep = <400>;
+ qcom,bw-dwnstep = <2800>;
+ qcom,max-vote = <2800>;
+ qcom,up-step-multp = <2>;
+ qcom,spdm-interval = <50>;
+
+ qcom,ports = <11>;
+ qcom,alpha-up = <8>;
+ qcom,alpha-down = <15>;
+ qcom,bucket-size = <8>;
+
+ /* max pl1 freq, max pl2 freq */
+ qcom,pl-freqs = <310000 570000>;
+
+ /* pl1 low, pl1 high, pl2 low, pl2 high, pl3 low, pl3 high */
+ qcom,reject-rate = <5000 5000 5000 5000 5000 5000>;
+ /* pl1 low, pl1 high, pl2 low, pl2 high, pl3 low, pl3 high */
+ qcom,response-time-us = <5000 5000 5000 5000 2000 2000>;
+ /* pl1 low, pl1 high, pl2 low, pl2 high, pl3 low, pl3 high */
+ qcom,cci-response-time-us = <3000 3000 4000 4000 2000 2000>;
+ qcom,max-cci-freq = <1300000>;
+ };
+
+ devfreq_spdm_gov {
+ compatible = "qcom,gov_spdm_hyp";
+ interrupt-names = "spdm-irq";
+ interrupts = <0 192 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8917-ion.dtsi b/arch/arm64/boot/dts/qcom/msm8917-ion.dtsi
index 823d99d..96e7166 100644
--- a/arch/arm64/boot/dts/qcom/msm8917-ion.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8917-ion.dtsi
@@ -33,5 +33,11 @@
memory-region = <&qseecom_mem>;
qcom,ion-heap-type = "DMA";
};
+
+ qcom,ion-heap@19 { /* QSEECOM TA HEAP */
+ reg = <19>;
+ memory-region = <&qseecom_ta_mem>;
+ qcom,ion-heap-type = "DMA";
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/msm8917-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8917-mtp.dtsi
index 65bc046..a558c8e 100644
--- a/arch/arm64/boot/dts/qcom/msm8917-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8917-mtp.dtsi
@@ -13,5 +13,55 @@
&blsp1_uart2 {
status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart_console_active>;
};
+&sdhc_1 {
+ /* device core power supply */
+ vdd-supply = <&pm8937_l8>;
+ qcom,vdd-voltage-level = <2900000 2900000>;
+ qcom,vdd-current-level = <200 570000>;
+
+ /* device communication power supply */
+ vdd-io-supply = <&pm8937_l5>;
+ qcom,vdd-io-always-on;
+ qcom,vdd-io-lpm-sup;
+ qcom,vdd-io-voltage-level = <1800000 1800000>;
+ qcom,vdd-io-current-level = <200 325000>;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>;
+ pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>;
+
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000
+ 384000000>;
+ qcom,nonremovable;
+ qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v";
+
+ status = "ok";
+};
+
+&sdhc_2 {
+ /* device core power supply */
+ vdd-supply = <&pm8937_l11>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <15000 800000>;
+
+ /* device communication power supply */
+ vdd-io-supply = <&pm8937_l12>;
+ qcom,vdd-io-voltage-level = <1800000 2950000>;
+ qcom,vdd-io-current-level = <200 22000>;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>;
+
+ cd-gpios = <&tlmm 67 0x1>;
+
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000
+ 200000000>;
+ qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
+
+ status = "ok";
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8917-pm.dtsi b/arch/arm64/boot/dts/qcom/msm8917-pm.dtsi
new file mode 100644
index 0000000..6200b4e
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8917-pm.dtsi
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2015-2016, 2018, 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/msm/pm.h>
+
+&soc {
+ qcom,spm@b012000 {
+ compatible = "qcom,spm-v2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xb012000 0x1000>;
+ qcom,name = "perf-l2";
+ qcom,saw2-ver-reg = <0xfd0>;
+ qcom,saw2-cfg = <0x14>;
+ qcom,saw2-spm-dly= <0x3C11840A>;
+ qcom,saw2-spm-ctl = <0xe>;
+ qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>;
+ qcom,vctl-timeout-us = <500>;
+ qcom,vctl-port = <0x0>;
+ };
+
+ qcom,lpm-levels {
+ compatible = "qcom,lpm-levels";
+ qcom,use-psci;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,pm-cluster@0{
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ label = "perf";
+ qcom,spm-device-names = "l2";
+ qcom,default-level=<0>;
+ qcom,psci-mode-shift = <4>;
+ qcom,psci-mode-mask = <0xf>;
+
+ qcom,pm-cluster-level@0{
+ reg = <0>;
+ label = "perf-l2-wfi";
+ qcom,psci-mode = <1>;
+ qcom,latency-us = <180>;
+ qcom,ss-power = <429>;
+ qcom,energy-overhead = <162991>;
+ qcom,time-overhead = <305>;
+ };
+
+ qcom,pm-cluster-level@1{
+ reg = <1>;
+ label = "perf-l2-gdhs";
+ qcom,psci-mode = <4>;
+ qcom,latency-us = <280>;
+ qcom,ss-power = <421>;
+ qcom,energy-overhead = <257510>;
+ qcom,time-overhead = <520>;
+ qcom,min-child-idx = <1>;
+ qcom,reset-level = <LPM_RESET_LVL_GDHS>;
+ };
+
+ qcom,pm-cluster-level@2{
+ reg = <2>;
+ label = "perf-l2-retention";
+ qcom,psci-mode = <2>;
+ qcom,latency-us = <650>;
+ qcom,ss-power = <350>;
+ qcom,energy-overhead = <651061>;
+ qcom,time-overhead = <1350>;
+ qcom,min-child-idx = <1>;
+ qcom,reset-level = <LPM_RESET_LVL_RET>;
+ };
+
+ qcom,pm-cluster-level@3{
+ reg = <3>;
+ label = "perf-l2-pc";
+ qcom,psci-mode = <5>;
+ qcom,latency-us = <11200>;
+ qcom,ss-power = <320>;
+ qcom,energy-overhead = <917561>;
+ qcom,time-overhead = <1700>;
+ qcom,min-child-idx = <1>;
+ qcom,is-reset;
+ qcom,notify-rpm;
+ qcom,reset-level = <LPM_RESET_LVL_PC>;
+ };
+
+ qcom,pm-cpu {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ qcom,psci-mode-shift = <0>;
+ qcom,psci-mode-mask = <0xf>;
+
+ qcom,pm-cpu-level@0 {
+ reg = <0>;
+ qcom,psci-cpu-mode = <0>;
+ label = "wfi";
+ qcom,latency-us = <12>;
+ qcom,ss-power = <463>;
+ qcom,energy-overhead = <23520>;
+ qcom,time-overhead = <25>;
+ };
+
+ qcom,pm-cpu-level@1 {
+ reg = <1>;
+ qcom,psci-cpu-mode = <3>;
+ label = "pc";
+ qcom,latency-us = <180>;
+ qcom,ss-power = <429>;
+ qcom,energy-overhead = <162991>;
+ qcom,time-overhead = <305>;
+ qcom,use-broadcast-timer;
+ qcom,is-reset;
+ qcom,reset-level = <LPM_RESET_LVL_PC>;
+ };
+ };
+ };
+ };
+
+ qcom,cpu-sleep-status {
+ compatible = "qcom,cpu-sleep-status";
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8917-pmi8950-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8917-pmi8950-mtp.dtsi
index a78f5fe..a194cea 100644
--- a/arch/arm64/boot/dts/qcom/msm8917-pmi8950-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8917-pmi8950-mtp.dtsi
@@ -51,17 +51,21 @@
};
};
-&pmi8950_fg {
+&qpnp_fg {
qcom,battery-data = <&mtp_batterydata>;
};
-&pmi8950_charger {
+&qpnp_smbcharger {
qcom,battery-data = <&mtp_batterydata>;
qcom,chg-led-sw-controls;
qcom,chg-led-support;
/delete-property/ dpdm-supply;
};
+&usb_otg {
+ extcon = <&qpnp_smbcharger>;
+};
+
&labibb {
status = "ok";
qpnp,qpnp-labibb-mode = "lcd";
diff --git a/arch/arm64/boot/dts/qcom/msm8917-regulator.dtsi b/arch/arm64/boot/dts/qcom/msm8917-regulator.dtsi
new file mode 100644
index 0000000..7fb3707
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8917-regulator.dtsi
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2015-2018, 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 "msm8937-regulator.dtsi"
+
+&soc {
+ /* delete the CPR and MEM ACC nodes of msm8937 */
+ /delete-node/ regulator@b018000;
+ /delete-node/ regulator@01946004;
+
+ mem_acc_vreg_corner: regulator@01946004 {
+ compatible = "qcom,mem-acc-regulator";
+ reg = <0xa4000 0x1000>;
+ reg-names = "efuse_addr";
+ regulator-name = "mem_acc_corner";
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <3>;
+
+ qcom,acc-reg-addr-list =
+ <0x01942138 0x01942130 0x01942120 0x01942124>;
+
+ qcom,acc-init-reg-config = <1 0xff>, <2 0x5555>;
+
+ qcom,num-acc-corners = <3>;
+ qcom,boot-acc-corner = <2>;
+ qcom,corner1-reg-config =
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 3 0x1041041>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x0>,
+ < 4 0x0>;
+
+ qcom,corner2-reg-config =
+ /* NOM => SVS+ */
+ < 3 0x30c30c3>, < 4 0x30c3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 3 0x0>, < 4 0x0>;
+
+ qcom,corner3-reg-config =
+ /* TURBO/NOM+ => SVS+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x30c30c3>,
+ < 4 0x30c3>,
+ /* TURBO/NOM+ => NOM */
+ < 3 0x1041041>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>;
+
+ qcom,override-acc-fuse-sel = <71 17 3 0>;
+ qcom,override-fuse-version-map = <1>,
+ <2>,
+ <3>,
+ <4>;
+ qcom,override-corner1-addr-val-map =
+ /* 1st fuse version tuple matched */
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 3 0x1041041>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x1>,
+ < 4 0x0>,
+
+ /* 2nd fuse version tuple matched */
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 3 0x1041041>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x3>,
+ < 4 0x0>,
+
+ /* 3rd fuse version tuple matched */
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 3 0x1041043>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x0>,
+ < 4 0x0>,
+
+ /* 4th fuse version tuple matched */
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 3 0x1041043>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x1>,
+ < 4 0x0>;
+
+ qcom,override-corner2-addr-val-map =
+ /* 1st fuse version tuple matched */
+ /* NOM => SVS+ */
+ < 3 0x30c30c3>, < 4 0x30c3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 3 0x1>, < 4 0x0>,
+
+ /* 2nd fuse version tuple matched */
+ /* NOM => SVS+ */
+ < 3 0x30c30c3>, < 4 0x30c3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 3 0x3>, < 4 0x0>,
+
+ /* 3rd fuse version tuple matched */
+ /* NOM => SVS+ */
+ < 3 0x30c30c3>, < 4 0x30c3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 3 0x0>, < 4 0x0>,
+
+ /* 4th fuse version tuple matched */
+ /* NOM => SVS+ */
+ < 3 0x30c30c3>, < 4 0x30c3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 3 0x1>, < 4 0x0>;
+
+ qcom,override-corner3-addr-val-map =
+ /* 1st fuse version tuple matched */
+ /* TURBO/NOM+ => SVS+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x30c30c3>,
+ < 4 0x30c3>,
+ /* TURBO/NOM+ => NOM */
+ < 3 0x1041041>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+
+ /* 2nd fuse version tuple matched */
+ /* TURBO/NOM+ => SVS+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x30c30c3>,
+ < 4 0x30c3>,
+ /* TURBO/NOM+ => NOM */
+ < 3 0x1041041>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+
+ /* 3rd fuse version tuple matched */
+ /* TURBO/NOM+ => SVS+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x30c30c3>,
+ < 4 0x30c3>,
+ /* TURBO/NOM+ => NOM */
+ < 3 0x1041043>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+
+ /* 4th fuse version tuple matched */
+ /* TURBO/NOM+ => SVS+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x30c30c3>,
+ < 4 0x30c3>,
+ /* TURBO/NOM+ => NOM */
+ < 3 0x1041043>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>;
+ };
+
+ apc_vreg_corner: regulator@b018000 {
+ compatible = "qcom,cpr-regulator";
+ reg = <0xb018000 0x1000>, <0xb011064 4>, <0xa4000 0x1000>;
+ reg-names = "rbcpr", "rbcpr_clk", "efuse_addr";
+ interrupts = <0 15 0>;
+ regulator-name = "apc_corner";
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <5>;
+
+ qcom,cpr-fuse-corners = <3>;
+ qcom,cpr-voltage-ceiling = <1155000 1225000 1350000>;
+ qcom,cpr-voltage-floor = <1050000 1050000 1090000>;
+ vdd-apc-supply = <&pm8937_s5>;
+
+ mem-acc-supply = <&mem_acc_vreg_corner>;
+
+ qcom,cpr-ref-clk = <19200>;
+ qcom,cpr-timer-delay = <5000>;
+ qcom,cpr-timer-cons-up = <0>;
+ qcom,cpr-timer-cons-down = <2>;
+ qcom,cpr-irq-line = <0>;
+ qcom,cpr-step-quotient = <16>;
+ qcom,cpr-up-threshold = <2>;
+ qcom,cpr-down-threshold = <4>;
+ qcom,cpr-idle-clocks = <15>;
+ qcom,cpr-gcnt-time = <1>;
+ qcom,vdd-apc-step-up-limit = <1>;
+ qcom,vdd-apc-step-down-limit = <1>;
+ qcom,cpr-apc-volt-step = <5000>;
+
+ qcom,cpr-fuse-row = <67 0>;
+ qcom,cpr-fuse-target-quot = <42 24 6>;
+ qcom,cpr-fuse-ro-sel = <60 57 54>;
+ qcom,cpr-init-voltage-ref = <1155000 1225000 1350000>;
+ qcom,cpr-fuse-init-voltage =
+ <67 36 6 0>,
+ <67 18 6 0>,
+ <67 0 6 0>;
+ qcom,cpr-fuse-quot-offset =
+ <71 26 6 0>,
+ <71 20 6 0>,
+ <70 54 7 0>;
+ qcom,cpr-fuse-quot-offset-scale = <5 5 5>;
+ qcom,cpr-init-voltage-step = <10000>;
+ qcom,cpr-corner-map = <1 2 3 3 3>;
+ qcom,cpr-corner-frequency-map =
+ <1 960000000>,
+ <2 1094400000>,
+ <3 1248000000>,
+ <4 1401000000>,
+ <5 1497600000>;
+ qcom,speed-bin-fuse-sel = <37 34 3 0>;
+ qcom,cpr-speed-bin-max-corners =
+ <0 (-1) 1 2 4>,
+ <1 (-1) 1 2 5>;
+ qcom,cpr-quot-adjust-scaling-factor-max = <0 1400 1400>;
+ qcom,cpr-voltage-scaling-factor-max = <0 2000 2000>;
+ qcom,cpr-scaled-init-voltage-as-ceiling;
+ qcom,cpr-fuse-revision = <69 39 3 0>;
+ qcom,pvs-version-fuse-sel = <37 40 3 0>; /* foundry */
+ qcom,cpr-fuse-version-map =
+ < 1 0 3 (-1) (-1) (-1)>,
+ < 1 5 3 (-1) (-1) (-1)>,
+ <(-1) 0 1 (-1) (-1) (-1)>,
+ <(-1) 0 2 (-1) (-1) (-1)>,
+ <(-1) 5 1 (-1) (-1) (-1)>,
+ <(-1) 5 2 (-1) (-1) (-1)>,
+ <(-1) (-1) (-1) (-1) (-1) (-1)>;
+ qcom,cpr-quotient-adjustment =
+ <50 40 50>,
+ <0 0 40>,
+ <50 40 100>,
+ <50 40 50>,
+ <0 0 100>,
+ <0 0 50>,
+ <0 0 0>;
+ qcom,cpr-init-voltage-adjustment =
+ <30000 5000 10000>,
+ <0 0 0>,
+ <30000 5000 35000>,
+ <30000 5000 10000>,
+ <0 0 20000>,
+ <0 0 0>,
+ <0 0 0>;
+ qcom,cpr-enable;
+ };
+
+ eldo2_pm8937: eldo2 {
+ compatible = "regulator-fixed";
+ regulator-name = "eldo2_pm8937";
+ startup-delay-us = <0>;
+ enable-active-high;
+ gpio = <&pm8937_gpios 7 0>;
+ regulator-always-on;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8917-smp2p.dtsi b/arch/arm64/boot/dts/qcom/msm8917-smp2p.dtsi
new file mode 100644
index 0000000..061d985
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8917-smp2p.dtsi
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2015-2016, 2018, 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>
+
+&soc {
+ qcom,smp2p-modem@b011008 {
+ compatible = "qcom,smp2p";
+ reg = <0xb011008 0x4>;
+ qcom,remote-pid = <1>;
+ qcom,irq-bitmask = <0x4000>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_EDGE_RISING>;
+ };
+
+ qcom,smp2p-wcnss@b011008 {
+ compatible = "qcom,smp2p";
+ reg = <0xb011008 0x4>;
+ qcom,remote-pid = <4>;
+ qcom,irq-bitmask = <0x40000>;
+ interrupts = <GIC_SPI 143 IRQ_TYPE_EDGE_RISING>;
+ };
+
+ qcom,smp2p-adsp@b011008 {
+ compatible = "qcom,smp2p";
+ reg = <0xb011008 0x4>;
+ qcom,remote-pid = <2>;
+ qcom,irq-bitmask = <0x400>;
+ interrupts = <GIC_SPI 291 IRQ_TYPE_EDGE_RISING>;
+ };
+
+ smp2pgpio_smp2p_15_in: qcom,smp2pgpio-smp2p-15-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <15>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_15_in {
+ compatible = "qcom,smp2pgpio_test_smp2p_15_in";
+ gpios = <&smp2pgpio_smp2p_15_in 0 0>;
+ };
+
+ smp2pgpio_smp2p_15_out: qcom,smp2pgpio-smp2p-15-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <15>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_15_out {
+ compatible = "qcom,smp2pgpio_test_smp2p_15_out";
+ gpios = <&smp2pgpio_smp2p_15_out 0 0>;
+ };
+
+ smp2pgpio_smp2p_1_in: qcom,smp2pgpio-smp2p-1-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <1>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_1_in {
+ compatible = "qcom,smp2pgpio_test_smp2p_1_in";
+ gpios = <&smp2pgpio_smp2p_1_in 0 0>;
+ };
+
+ smp2pgpio_smp2p_1_out: qcom,smp2pgpio-smp2p-1-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_1_out {
+ compatible = "qcom,smp2pgpio_test_smp2p_1_out";
+ gpios = <&smp2pgpio_smp2p_1_out 0 0>;
+ };
+
+ smp2pgpio_smp2p_4_in: qcom,smp2pgpio-smp2p-4-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <4>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_4_in {
+ compatible = "qcom,smp2pgpio_test_smp2p_4_in";
+ gpios = <&smp2pgpio_smp2p_4_in 0 0>;
+ };
+
+ smp2pgpio_smp2p_4_out: qcom,smp2pgpio-smp2p-4-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_4_out {
+ compatible = "qcom,smp2pgpio_test_smp2p_4_out";
+ gpios = <&smp2pgpio_smp2p_4_out 0 0>;
+ };
+
+ smp2pgpio_smp2p_2_in: qcom,smp2pgpio-smp2p-2-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <2>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_2_in {
+ compatible = "qcom,smp2pgpio_test_smp2p_2_in";
+ gpios = <&smp2pgpio_smp2p_2_in 0 0>;
+ };
+
+ smp2pgpio_smp2p_2_out: qcom,smp2pgpio-smp2p-2-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_2_out {
+ compatible = "qcom,smp2pgpio_test_smp2p_2_out";
+ gpios = <&smp2pgpio_smp2p_2_out 0 0>;
+ };
+
+ /* ssr - inbound entry from mss. */
+ smp2pgpio_ssr_smp2p_1_in: qcom,smp2pgpio-ssr-smp2p-1-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "slave-kernel";
+ qcom,remote-pid = <1>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* ssr - outbound entry to mss */
+ smp2pgpio_ssr_smp2p_1_out: qcom,smp2pgpio-ssr-smp2p-1-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "master-kernel";
+ qcom,remote-pid = <1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* ssr - inbound entry from lpass. */
+ smp2pgpio_ssr_smp2p_2_in: qcom,smp2pgpio-ssr-smp2p-2-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "slave-kernel";
+ qcom,remote-pid = <2>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* ssr - outbound entry to lpass */
+ smp2pgpio_ssr_smp2p_2_out: qcom,smp2pgpio-ssr-smp2p-2-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "master-kernel";
+ qcom,remote-pid = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* ssr - inbound entry from wcnss. */
+ smp2pgpio_ssr_smp2p_4_in: qcom,smp2pgpio-ssr-smp2p-4-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "slave-kernel";
+ qcom,remote-pid = <4>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* ssr - outbound entry to wcnss */
+ smp2pgpio_ssr_smp2p_4_out: qcom,smp2pgpio-ssr-smp2p-4-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "master-kernel";
+ qcom,remote-pid = <4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8917.dtsi b/arch/arm64/boot/dts/qcom/msm8917.dtsi
index c1160ad..6f0da53 100644
--- a/arch/arm64/boot/dts/qcom/msm8917.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8917.dtsi
@@ -12,9 +12,10 @@
*/
#include "skeleton64.dtsi"
+#include <dt-bindings/clock/msm-clocks-8952.h>
#include <dt-bindings/regulator/qcom,rpm-smd-regulator.h>
-#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
/ {
model = "Qualcomm Technologies, Inc. MSM8917";
@@ -39,6 +40,39 @@
smd11 = &smdtty_data11;
smd21 = &smdtty_data21;
smd36 = &smdtty_loopback;
+ sdhc1 = &sdhc_1; /* SDC1 eMMC slot */
+ sdhc2 = &sdhc_2; /* SDC2 for SD card */
+ spi3 = &spi_3;
+ spi6 = &spi_6;
+ i2c2 = &i2c_2;
+ i2c5 = &i2c_5;
+ i2c3 = &i2c_3;
+ i2c4 = &i2c_4;
+ };
+
+ firmware: firmware {
+ android {
+ compatible = "android,firmware";
+ fstab {
+ compatible = "android,fstab";
+ vendor {
+ compatible = "android,vendor";
+ dev = "/dev/block/platform/soc/7824900.sdhci/by-name/vendor";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait";
+ status = "ok";
+ };
+ system {
+ compatible = "android,system";
+ dev = "/dev/block/platform/soc/7824900.sdhci/by-name/system";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait";
+ status = "ok";
+ };
+ };
+ };
};
reserved-memory {
@@ -83,6 +117,7 @@
reusable;
alignment = <0 0x400000>;
size = <0 0x7000000>;
+ status = "disabled";
};
qseecom_mem: qseecom_region@0 {
@@ -92,6 +127,14 @@
size = <0 0x1000000>;
};
+ qseecom_ta_mem: qseecom_ta_region {
+ compatible = "shared-dma-pool";
+ alloc-ranges = <0 0x00000000 0 0xffffffff>;
+ reusable;
+ alignment = <0 0x400000>;
+ size = <0 0x400000>;
+ };
+
adsp_mem: adsp_region@0 {
compatible = "shared-dma-pool";
reusable;
@@ -105,7 +148,6 @@
};
soc: soc { };
-
vendor: vendor {
#address-cells = <1>;
#size-cells = <1>;
@@ -116,7 +158,10 @@
#include "msm8917-pinctrl.dtsi"
#include "msm8917-cpu.dtsi"
+#include "msm8917-pm.dtsi"
#include "msm8917-ion.dtsi"
+#include "msm8917-smp2p.dtsi"
+#include "msm8917-bus.dtsi"
&soc {
#address-cells = <1>;
@@ -127,9 +172,29 @@
intc: interrupt-controller@b000000 {
compatible = "qcom,msm-qgic2";
interrupt-controller;
+ interrupt-parent = <&intc>;
#interrupt-cells = <3>;
reg = <0x0b000000 0x1000>,
- <0x0b002000 0x1000>;
+ <0x0b002000 0x1000>;
+ };
+
+ wakegic: wake-gic {
+ compatible = "qcom,mpm-gic", "qcom,mpm-gic-msm8937";
+ interrupts = <GIC_SPI 171 IRQ_TYPE_EDGE_RISING>;
+ reg = <0x601d0 0x1000>,
+ <0xb011008 0x4>; /* MSM_APCS_GCC_BASE 4K */
+ reg-names = "vmpm", "ipc";
+ qcom,num-mpm-irqs = <96>;
+ interrupt-controller;
+ interrupt-parent = <&intc>;
+ #interrupt-cells = <3>;
+ };
+
+ wakegpio: wake-gpio {
+ compatible = "qcom,mpm-gpio", "qcom,mpm-gpio-msm8937";
+ interrupt-controller;
+ interrupt-parent = <&intc>;
+ #interrupt-cells = <2>;
};
timer {
@@ -243,10 +308,51 @@
status = "disabled";
};
+
blsp1_uart2: serial@78b0000 {
compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
reg = <0x78b0000 0x200>;
interrupts = <0 108 0>;
+ clocks = <&clock_gcc clk_gcc_blsp1_uart2_apps_clk>,
+ <&clock_gcc clk_gcc_blsp1_ahb_clk>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+
+ blsp1_uart1: uart@78af000 { /* BLSP1 UART1 */
+ compatible = "qcom,msm-hsuart-v14";
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x78af000 0x200>,
+ <0x7884000 0x1f000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-parent = <&blsp1_uart1>;
+ interrupts = <0 1 2>;
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ interrupt-map = <0 &intc 0 107 0
+ 1 &intc 0 238 0
+ 2 &tlmm 1 0>;
+ interrupt-map-mask = <0xffffffff>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xFD>;
+
+ qcom,bam-tx-ep-pipe-index = <0>;
+ qcom,bam-rx-ep-pipe-index = <1>;
+ qcom,master-id = <86>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_uart1_apps_clk>,
+ <&clock_gcc clk_gcc_blsp1_ahb_clk>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp1_uart1_sleep>;
+ pinctrl-1 = <&blsp1_uart1_active>;
+
+ qcom,msm-bus,name = "blsp1_uart1";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <86 512 0 0>,
+ <86 512 500 800>;
status = "disabled";
};
@@ -266,12 +372,279 @@
qcom,summing-threshold = <10>;
};
+
+ /* IO Expander SX150xq */
+ /* BLSP1 QUP4 */
+ i2c_4: i2c@78b8000 {
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "qup_phys_addr";
+ reg = <0x78b8000 0x600>;
+ interrupt-names = "qup_irq";
+ interrupts = <0 98 0>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
+ <&clock_gcc clk_gcc_blsp1_qup4_i2c_apps_clk>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_4_active>;
+ pinctrl-1 = <&i2c_4_sleep>;
+ qcom,noise-rjct-scl = <0>;
+ qcom,noise-rjct-sda = <0>;
+ qcom,master-id = <86>;
+ dmas = <&dma_blsp1 10 64 0x20000020 0x20>,
+ <&dma_blsp1 11 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
rpm_bus: qcom,rpm-smd {
compatible = "qcom,rpm-smd";
rpm-channel-name = "rpm_requests";
rpm-channel-type = <15>; /* SMD_APPS_RPM */
};
+ clock_gcc: qcom,gcc@1800000 {
+ compatible = "qcom,gcc-8917";
+ reg = <0x1800000 0x80000>,
+ <0xb016000 0x00040>,
+ <0x00a6018 0x00004>;
+ reg-names = "cc_base", "apcs_c1_base", "efuse";
+ vdd_dig-supply = <&pm8937_s2_level>;
+ vdd_hf_dig-supply = <&pm8937_s2_level_ao>;
+ vdd_hf_pll-supply = <&pm8937_l7_ao>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ clock_debug: qcom,cc-debug@1874000 {
+ compatible = "qcom,cc-debug-8917";
+ reg = <0x1874000 0x4>,
+ <0xb01101c 0x8>;
+ reg-names = "cc_base", "meas";
+ #clock-cells = <1>;
+ };
+
+ clock_cpu: qcom,cpu-clock-8939@b111050 {
+ compatible = "qcom,cpu-clock-8917";
+ reg = <0xb011050 0x8>,
+ <0x00a412c 0x8>;
+ reg-names = "apcs-c1-rcg-base", "efuse";
+ qcom,num-cluster;
+ vdd-c1-supply = <&apc_vreg_corner>;
+ clocks = <&clock_gcc clk_gpll0_ao_clk_src>,
+ <&clock_gcc clk_a53ss_c1_pll>;
+ clock-names = "clk-c1-4", "clk-c1-5";
+ qcom,speed0-bin-v0-c1 =
+ < 0 0>,
+ < 960000000 1>,
+ < 1094400000 2>,
+ < 1248000000 3>,
+ < 1401000000 4>;
+
+ qcom,speed1-bin-v0-c1 =
+ < 0 0>,
+ < 960000000 1>,
+ < 1094400000 2>,
+ < 1248000000 3>,
+ < 1401000000 4>,
+ < 1497600000 5>;
+
+ #clock-cells = <1>;
+ };
+
+ i2c_2: i2c@78b6000 { /* BLSP1 QUP2 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "qup_phys_addr";
+ reg = <0x78b6000 0x600>;
+ interrupt-names = "qup_irq";
+ interrupts = <0 96 0>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
+ <&clock_gcc clk_gcc_blsp1_qup2_i2c_apps_clk>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_2_active>;
+ pinctrl-1 = <&i2c_2_sleep>;
+ qcom,noise-rjct-scl = <0>;
+ qcom,noise-rjct-sda = <0>;
+ qcom,master-id = <86>;
+ dmas = <&dma_blsp1 6 64 0x20000020 0x20>,
+ <&dma_blsp1 7 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ i2c_3: i2c@78b7000 { /* BLSP1 QUP3 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "qup_phys_addr";
+ reg = <0x78b7000 0x600>;
+ interrupt-names = "qup_irq";
+ interrupts = <0 97 0>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
+ <&clock_gcc clk_gcc_blsp1_qup3_i2c_apps_clk>;
+
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_3_active>;
+ pinctrl-1 = <&i2c_3_sleep>;
+ qcom,noise-rjct-scl = <0>;
+ qcom,noise-rjct-sda = <0>;
+ qcom,master-id = <86>;
+ dmas = <&dma_blsp1 8 64 0x20000020 0x20>,
+ <&dma_blsp1 9 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ i2c_5: i2c@7af5000 { /* BLSP2 QUP1 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "qup_phys_addr";
+ reg = <0x7af5000 0x600>;
+ interrupt-names = "qup_irq";
+ interrupts = <0 299 0>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>,
+ <&clock_gcc clk_gcc_blsp2_qup1_i2c_apps_clk>;
+
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_5_active>;
+ pinctrl-1 = <&i2c_5_sleep>;
+ qcom,noise-rjct-scl = <0>;
+ qcom,noise-rjct-sda = <0>;
+ qcom,master-id = <84>;
+ dmas = <&dma_blsp2 4 64 0x20000020 0x20>,
+ <&dma_blsp2 5 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ spi_3: spi@78b7000 { /* BLSP1 QUP3 */
+ compatible = "qcom,spi-qup-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "spi_physical", "spi_bam_physical";
+ reg = <0x78b7000 0x600>,
+ <0x7884000 0x1f000>;
+ interrupt-names = "spi_irq", "spi_bam_irq";
+ interrupts = <0 97 0>, <0 238 0>;
+ spi-max-frequency = <19200000>;
+ pinctrl-names = "spi_default", "spi_sleep";
+ pinctrl-0 = <&spi3_default &spi3_cs0_active>;
+ pinctrl-1 = <&spi3_sleep &spi3_cs0_sleep>;
+ clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
+ <&clock_gcc clk_gcc_blsp1_qup3_spi_apps_clk>;
+ clock-names = "iface_clk", "core_clk";
+ qcom,infinite-mode = <0>;
+ qcom,use-bam;
+ qcom,use-pinctrl;
+ qcom,ver-reg-exists;
+ qcom,bam-consumer-pipe-index = <8>;
+ qcom,bam-producer-pipe-index = <9>;
+ qcom,master-id = <86>;
+ status = "disabled";
+ };
+
+ usb_otg: usb@78db000 {
+ compatible = "qcom,hsusb-otg";
+ reg = <0x78db000 0x400>, <0x6c000 0x200>;
+ reg-names = "core", "phy_csr";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ interrupts = <0 134 0>,<0 140 0>;
+ interrupt-names = "core_irq", "async_irq";
+
+ hsusb_vdd_dig-supply = <&pm8937_l2>;
+ HSUSB_1p8-supply = <&pm8937_l7>;
+ HSUSB_3p3-supply = <&pm8937_l13>;
+ qcom,vdd-voltage-level = <0 1200000 1200000>;
+ vbus_otg-supply = <&smbcharger_charger_otg>;
+
+ qcom,hsusb-otg-phy-type = <3>; /* SNPS Femto PHY */
+ qcom,hsusb-otg-mode = <3>; /* OTG mode */
+ qcom,hsusb-otg-otg-control = <2>; /* PMIC */
+ qcom,dp-manual-pullup;
+ qcom,phy-dvdd-always-on;
+ qcom,boost-sysclk-with-streaming;
+ qcom,axi-prefetch-enable;
+ qcom,enable-sdp-typec-current-limit;
+ qcom,hsusb-otg-delay-lpm;
+
+ qcom,msm-bus,name = "usb2";
+ qcom,msm-bus,num-cases = <3>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <87 512 0 0>,
+ <87 512 80000 0>,
+ <87 512 6000 6000>;
+ clocks = <&clock_gcc clk_gcc_usb_hs_ahb_clk>,
+ <&clock_gcc clk_gcc_usb_hs_system_clk>,
+ <&clock_gcc clk_gcc_usb2a_phy_sleep_clk>,
+ <&clock_gcc clk_bimc_usb_a_clk>,
+ <&clock_gcc clk_snoc_usb_a_clk>,
+ <&clock_gcc clk_pnoc_usb_a_clk>,
+ <&clock_gcc clk_gcc_qusb2_phy_clk>,
+ <&clock_gcc clk_gcc_usb2_hs_phy_only_clk>,
+ <&clock_gcc clk_gcc_usb_hs_phy_cfg_ahb_clk>,
+ <&clock_gcc clk_xo_otg_clk>;
+ clock-names = "iface_clk", "core_clk", "sleep_clk",
+ "bimc_clk", "snoc_clk", "pcnoc_clk",
+ "phy_reset_clk", "phy_por_clk", "phy_csr_clk",
+ "xo";
+ qcom,bus-clk-rate = <595200000 200000000 100000000>;
+ qcom,max-nominal-sysclk-rate = <133330000>;
+
+ resets = <&clock_gcc GCC_USB_HS_BCR>,
+ <&clock_gcc GCC_QUSB2_PHY_BCR>,
+ <&clock_gcc GCC_USB2_HS_PHY_ONLY_BCR>;
+ reset-names = "core_reset", "phy_reset", "phy_por_reset";
+
+ qcom,usbbam@78c4000 {
+ compatible = "qcom,usb-bam-msm";
+ reg = <0x78c4000 0x17000>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 135 0>;
+
+ qcom,bam-type = <1>;
+ qcom,usb-bam-num-pipes = <4>;
+ qcom,usb-bam-fifo-baseaddr = <0x08605000>;
+ qcom,ignore-core-reset-ack;
+ qcom,disable-clk-gating;
+ qcom,usb-bam-max-mbps-highspeed = <400>;
+ qcom,reset-bam-on-disconnect;
+
+ qcom,pipe0 {
+ label = "hsusb-qdss-in-0";
+ qcom,usb-bam-mem-type = <2>;
+ qcom,dir = <1>;
+ qcom,pipe-num = <0>;
+ qcom,peer-bam = <0>;
+ qcom,peer-bam-physical-address = <0x6044000>;
+ qcom,src-bam-pipe-index = <0>;
+ qcom,dst-bam-pipe-index = <0>;
+ qcom,data-fifo-offset = <0x0>;
+ qcom,data-fifo-size = <0xe00>;
+ qcom,descriptor-fifo-offset = <0xe00>;
+ qcom,descriptor-fifo-size = <0x200>;
+ };
+ };
+ };
+
cpubw: qcom,cpubw {
compatible = "qcom,devbw";
governor = "cpufreq";
@@ -382,7 +755,6 @@
};
-
qcom,ipc-spinlock@1905000 {
compatible = "qcom,ipc-spinlock-sfpb";
reg = <0x1905000 0x8000>;
@@ -595,12 +967,323 @@
qcom,fragmented-data;
};
+ bam_dmux: qcom,bam_dmux@4044000 {
+ compatible = "qcom,bam_dmux";
+ reg = <0x4044000 0x19000>;
+ interrupts = <GIC_SPI 162 IRQ_TYPE_EDGE_RISING>;
+ qcom,rx-ring-size = <32>;
+ qcom,max-rx-mtu = <4096>;
+ qcom,fast-shutdown;
+ qcom,no-cpu-affinity;
+ };
+
+ sdcc1_ice: sdcc1ice@7803000 {
+ compatible = "qcom,ice";
+ reg = <0x7803000 0x8000>;
+ interrupt-names = "sdcc_ice_nonsec_level_irq",
+ "sdcc_ice_sec_level_irq";
+ interrupts = <0 312 0>, <0 313 0>;
+ qcom,enable-ice-clk;
+ clock-names = "ice_core_clk_src", "ice_core_clk",
+ "bus_clk", "iface_clk";
+ clocks = <&clock_gcc clk_sdcc1_ice_core_clk_src>,
+ <&clock_gcc clk_gcc_sdcc1_ice_core_clk>,
+ <&clock_gcc clk_gcc_sdcc1_apps_clk>,
+ <&clock_gcc clk_gcc_sdcc1_ahb_clk>;
+ qcom,op-freq-hz = <200000000>, <0>, <0>, <0>;
+ qcom,msm-bus,name = "sdcc_ice_noc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <78 512 0 0>, /* No vote */
+ <78 512 1000 0>; /* Max. bandwidth */
+ qcom,bus-vector-names = "MIN", "MAX";
+ qcom,instance-type = "sdcc";
+ };
+
+ sdhc_1: sdhci@7824900 {
+ compatible = "qcom,sdhci-msm";
+ reg = <0x7824900 0x500>, <0x7824000 0x800>, <0x7824e00 0x200>;
+ reg-names = "hc_mem", "core_mem", "cmdq_mem";
+
+ interrupts = <0 123 0>, <0 138 0>;
+ interrupt-names = "hc_irq", "pwr_irq";
+
+ sdhc-msm-crypto = <&sdcc1_ice>;
+ qcom,bus-width = <8>;
+ qcom,large-address-bus;
+
+ qcom,devfreq,freq-table = <50000000 200000000>;
+
+ qcom,pm-qos-irq-type = "affine_irq";
+ qcom,pm-qos-irq-latency = <13 651>;
+
+ qcom,pm-qos-cpu-groups = <0x0f>;
+ qcom,pm-qos-cmdq-latency-us = <13 651>;
+
+ qcom,pm-qos-legacy-latency-us = <13 651>;
+
+ qcom,msm-bus,name = "sdhc1";
+ qcom,msm-bus,num-cases = <9>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps = <78 512 0 0>, /* No vote */
+ <78 512 1046 3200>, /* 400 KB/s*/
+ <78 512 52286 160000>, /* 20 MB/s */
+ <78 512 65360 200000>, /* 25 MB/s */
+ <78 512 130718 400000>, /* 50 MB/s */
+ <78 512 130718 400000>, /* 100 MB/s */
+ <78 512 261438 800000>, /* 200 MB/s */
+ <78 512 261438 800000>, /* 400 MB/s */
+ <78 512 1338562 4096000>; /* Max. bandwidth */
+ qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000
+ 50000000 100000000 200000000 400000000 4294967295>;
+
+ clocks = <&clock_gcc clk_gcc_sdcc1_ahb_clk>,
+ <&clock_gcc clk_gcc_sdcc1_apps_clk>,
+ <&clock_gcc clk_gcc_sdcc1_ice_core_clk>;
+ clock-names = "iface_clk", "core_clk", "ice_core_clk";
+ qcom,ice-clk-rates = <200000000 100000000>;
+
+ qcom,scaling-lower-bus-speed-mode = "DDR52";
+ status = "disabled";
+ };
+
+ sdhc_2: sdhci@7864900 {
+ compatible = "qcom,sdhci-msm";
+ reg = <0x7864900 0x500>, <0x7864000 0x800>;
+ reg-names = "hc_mem", "core_mem";
+
+ interrupts = <0 125 0>, <0 221 0>;
+ interrupt-names = "hc_irq", "pwr_irq";
+
+ qcom,bus-width = <4>;
+ qcom,large-address-bus;
+
+ qcom,pm-qos-irq-type = "affine_irq";
+ qcom,pm-qos-irq-latency = <13 651>;
+
+ qcom,pm-qos-cpu-groups = <0x0f>;
+ qcom,pm-qos-legacy-latency-us = <13 651>;
+
+ qcom,msm-bus,name = "sdhc2";
+ qcom,msm-bus,num-cases = <8>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps = <81 512 0 0>, /* No vote */
+ <81 512 1046 3200>, /* 400 KB/s*/
+ <81 512 52286 160000>, /* 20 MB/s */
+ <81 512 65360 200000>, /* 25 MB/s */
+ <81 512 130718 400000>, /* 50 MB/s */
+ <81 512 261438 800000>, /* 100 MB/s */
+ <81 512 261438 800000>, /* 200 MB/s */
+ <81 512 1338562 4096000>; /* Max. bandwidth */
+ qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000
+ 100000000 200000000 4294967295>;
+
+ qcom,devfreq,freq-table = <50000000 200000000>;
+ clocks = <&clock_gcc clk_gcc_sdcc2_ahb_clk>,
+ <&clock_gcc clk_gcc_sdcc2_apps_clk>;
+ clock-names = "iface_clk", "core_clk";
+
+ status = "disabled";
+ };
+
+ qcom_seecom: qseecom@85b00000 {
+ compatible = "qcom,qseecom";
+ reg = <0x85b00000 0x800000>;
+ reg-names = "secapp-region";
+ qcom,hlos-num-ce-hw-instances = <1>;
+ qcom,hlos-ce-hw-instance = <0>;
+ qcom,qsee-ce-hw-instance = <0>;
+ qcom,disk-encrypt-pipe-pair = <2>;
+ qcom,support-fde;
+ qcom,msm-bus,name = "qseecom-noc";
+ qcom,msm-bus,num-cases = <4>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,support-bus-scaling;
+ qcom,msm-bus,vectors-KBps =
+ <55 512 0 0>,
+ <55 512 0 0>,
+ <55 512 120000 1200000>,
+ <55 512 393600 3936000>;
+ clocks = <&clock_gcc clk_crypto_clk_src>,
+ <&clock_gcc clk_gcc_crypto_clk>,
+ <&clock_gcc clk_gcc_crypto_ahb_clk>,
+ <&clock_gcc clk_gcc_crypto_axi_clk>;
+ clock-names = "core_clk_src", "core_clk",
+ "iface_clk", "bus_clk";
+ qcom,ce-opp-freq = <100000000>;
+ };
+
+ qcom_rng: qrng@e3000 {
+ compatible = "qcom,msm-rng";
+ reg = <0xe3000 0x1000>;
+ qcom,msm-rng-iface-clk;
+ qcom,no-qrng-config;
+ qcom,msm-bus,name = "msm-rng-noc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <1 618 0 0>, /* No vote */
+ <1 618 0 800>; /* 100 MB/s */
+ clocks = <&clock_gcc clk_gcc_prng_ahb_clk>;
+ clock-names = "iface_clk";
+ };
+
+ qcom_crypto: qcrypto@720000 {
+ compatible = "qcom,qcrypto";
+ reg = <0x720000 0x20000>,
+ <0x704000 0x20000>;
+ reg-names = "crypto-base","crypto-bam-base";
+ interrupts = <0 207 0>;
+ qcom,bam-pipe-pair = <2>;
+ qcom,ce-hw-instance = <0>;
+ qcom,ce-device = <0>;
+ qcom,ce-hw-shared;
+ qcom,clk-mgmt-sus-res;
+ qcom,msm-bus,name = "qcrypto-noc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <55 512 0 0>,
+ <55 512 393600 393600>;
+ clocks = <&clock_gcc clk_crypto_clk_src>,
+ <&clock_gcc clk_gcc_crypto_clk>,
+ <&clock_gcc clk_gcc_crypto_ahb_clk>,
+ <&clock_gcc clk_gcc_crypto_axi_clk>;
+ clock-names = "core_clk_src", "core_clk",
+ "iface_clk", "bus_clk";
+ qcom,use-sw-aes-cbc-ecb-ctr-algo;
+ qcom,use-sw-aes-xts-algo;
+ qcom,use-sw-aes-ccm-algo;
+ qcom,use-sw-ahash-algo;
+ qcom,use-sw-hmac-algo;
+ qcom,use-sw-aead-algo;
+ qcom,ce-opp-freq = <100000000>;
+ };
+
+ qcom_cedev: qcedev@720000 {
+ compatible = "qcom,qcedev";
+ reg = <0x720000 0x20000>,
+ <0x704000 0x20000>;
+ reg-names = "crypto-base","crypto-bam-base";
+ interrupts = <0 207 0>;
+ qcom,bam-pipe-pair = <1>;
+ qcom,ce-hw-instance = <0>;
+ qcom,ce-device = <0>;
+ qcom,ce-hw-shared;
+ qcom,msm-bus,name = "qcedev-noc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <55 512 0 0>,
+ <55 512 393600 393600>;
+ clocks = <&clock_gcc clk_crypto_clk_src>,
+ <&clock_gcc clk_gcc_crypto_clk>,
+ <&clock_gcc clk_gcc_crypto_ahb_clk>,
+ <&clock_gcc clk_gcc_crypto_axi_clk>;
+ clock-names = "core_clk_src", "core_clk",
+ "iface_clk", "bus_clk";
+ qcom,ce-opp-freq = <100000000>;
+ };
+
qcom,adsprpc-mem {
compatible = "qcom,msm-adsprpc-mem-region";
memory-region = <&adsp_mem>;
};
+ spi_6: spi@7af6000 { /* BLSP2 QUP2 */
+ compatible = "qcom,spi-qup-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "spi_physical", "spi_bam_physical";
+ reg = <0x7af6000 0x600>,
+ <0x7ac4000 0x1d000>;
+ interrupt-names = "spi_irq", "spi_bam_irq";
+ interrupts = <0 300 0>, <0 239 0>;
+ spi-max-frequency = <50000000>;
+ pinctrl-names = "spi_default", "spi_sleep";
+ pinctrl-0 = <&spi6_default &spi6_cs0_active>;
+ pinctrl-1 = <&spi6_sleep &spi6_cs0_sleep>;
+ clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>,
+ <&clock_gcc clk_gcc_blsp2_qup2_spi_apps_clk>;
+ clock-names = "iface_clk", "core_clk";
+ qcom,infinite-mode = <0>;
+ qcom,use-bam;
+ qcom,use-pinctrl;
+ qcom,ver-reg-exists;
+ qcom,bam-consumer-pipe-index = <6>;
+ qcom,bam-producer-pipe-index = <7>;
+ qcom,master-id = <84>;
+ status = "disabled";
+ };
+
};
#include "pm8937-rpm-regulator.dtsi"
+#include "msm8917-regulator.dtsi"
#include "pm8937.dtsi"
+#include "msm-gdsc-8916.dtsi"
+
+&gdsc_venus {
+ clock-names = "bus_clk", "core_clk";
+ clocks = <&clock_gcc clk_gcc_venus0_axi_clk>,
+ <&clock_gcc clk_gcc_venus0_vcodec0_clk>;
+ status = "okay";
+};
+
+&gdsc_venus_core0 {
+ qcom,support-hw-trigger;
+ clock-names ="core0_clk";
+ clocks = <&clock_gcc clk_gcc_venus0_core0_vcodec0_clk>;
+ status = "okay";
+};
+
+&gdsc_mdss {
+ clock-names = "core_clk", "bus_clk";
+ clocks = <&clock_gcc clk_gcc_mdss_mdp_clk>,
+ <&clock_gcc clk_gcc_mdss_axi_clk>;
+ status = "okay";
+};
+
+&gdsc_jpeg {
+ clock-names = "core_clk", "bus_clk";
+ clocks = <&clock_gcc clk_gcc_camss_jpeg0_clk>,
+ <&clock_gcc clk_gcc_camss_jpeg_axi_clk>;
+ status = "okay";
+};
+
+&gdsc_vfe {
+ clock-names = "core_clk", "bus_clk", "micro_clk",
+ "csi_clk";
+ clocks = <&clock_gcc clk_gcc_camss_vfe0_clk>,
+ <&clock_gcc clk_gcc_camss_vfe_axi_clk>,
+ <&clock_gcc clk_gcc_camss_micro_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_csi_vfe0_clk>;
+ status = "okay";
+};
+
+&gdsc_vfe1 {
+ clock-names = "core_clk", "bus_clk", "micro_clk",
+ "csi_clk";
+ clocks = <&clock_gcc clk_gcc_camss_vfe1_clk>,
+ <&clock_gcc clk_gcc_camss_vfe1_axi_clk>,
+ <&clock_gcc clk_gcc_camss_micro_ahb_clk>,
+ <&clock_gcc clk_gcc_camss_csi_vfe1_clk>;
+ status = "okay";
+};
+
+&gdsc_cpp {
+ clock-names = "core_clk", "bus_clk";
+ clocks = <&clock_gcc clk_gcc_camss_cpp_clk>,
+ <&clock_gcc clk_gcc_camss_cpp_axi_clk>;
+ status = "okay";
+};
+
+&gdsc_oxili_gx {
+ clock-names = "core_root_clk", "gfx_clk";
+ clocks =<&clock_gcc clk_gfx3d_clk_src>,
+ <&clock_gcc clk_gcc_oxili_gfx3d_clk>;
+ qcom,enable-root-clk;
+ qcom,clk-dis-wait-val = <0x5>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8937-coresight.dtsi b/arch/arm64/boot/dts/qcom/msm8937-coresight.dtsi
index b82767915..0a8c0bf 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-coresight.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-coresight.dtsi
@@ -321,6 +321,15 @@
<&audio_etm0_out_funnel_mm>;
};
};
+
+ port@4 {
+ reg = <6>;
+ funnel_mm_in_gfx: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&gfx_out_funnel_mm>;
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/msm8937-cpu.dtsi b/arch/arm64/boot/dts/qcom/msm8937-cpu.dtsi
index 7aaaf7e..f72fda9 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-cpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-cpu.dtsi
@@ -60,6 +60,7 @@
efficiency = <1126>;
sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
L2_1: l2-cache {
compatible = "arm,arch-cache";
cache-level = <2>;
@@ -84,6 +85,7 @@
efficiency = <1126>;
sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
L1_I_101: l1-icache {
compatible = "arm,arch-cache";
qcom,dump-size = <0x8800>;
@@ -102,6 +104,7 @@
efficiency = <1126>;
sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
L1_I_102: l1-icache {
compatible = "arm,arch-cache";
qcom,dump-size = <0x8800>;
@@ -120,6 +123,7 @@
efficiency = <1126>;
sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
L1_I_103: l1-icache {
compatible = "arm,arch-cache";
qcom,dump-size = <0x8800>;
@@ -138,6 +142,7 @@
efficiency = <1024>;
sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_0>;
next-level-cache = <&L2_0>;
+ #cooling-cells = <2>;
L2_0: l2-cache {
compatible = "arm,arch-cache";
cache-level = <2>;
@@ -161,6 +166,7 @@
efficiency = <1024>;
sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_0>;
next-level-cache = <&L2_0>;
+ #cooling-cells = <2>;
L1_I_1: l1-icache {
compatible = "arm,arch-cache";
qcom,dump-size = <0x8800>;
@@ -179,6 +185,7 @@
efficiency = <1024>;
sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_0>;
next-level-cache = <&L2_0>;
+ #cooling-cells = <2>;
L1_I_2: l1-icache {
compatible = "arm,arch-cache";
qcom,dump-size = <0x8800>;
@@ -197,6 +204,7 @@
efficiency = <1024>;
sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_0>;
next-level-cache = <&L2_0>;
+ #cooling-cells = <2>;
L1_I_3: l1-icache {
compatible = "arm,arch-cache";
qcom,dump-size = <0x8800>;
diff --git a/arch/arm64/boot/dts/qcom/msm8937-gpu.dtsi b/arch/arm64/boot/dts/qcom/msm8937-gpu.dtsi
index 2ee4c0e..eff49a4 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-gpu.dtsi
@@ -117,6 +117,9 @@
/* Context aware jump target power level */
qcom,ca-target-pwrlevel = <1>;
+ /* Enable gpu cooling device */
+ #cooling-cells = <2>;
+
/* GPU Mempools */
qcom,gpu-mempools {
#address-cells= <1>;
@@ -137,6 +140,25 @@
};
};
+ qcom,gpu-coresights {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "qcom,gpu-coresight";
+
+ /* Trace bus */
+ qcom,gpu-coresight@0 {
+ reg = <0>;
+ coresight-name = "coresight-gfx";
+ coresight-atid = <67>;
+ port {
+ gfx_out_funnel_mm: endpoint {
+ remote-endpoint =
+ <&funnel_mm_in_gfx>;
+ };
+ };
+ };
+ };
+
/* Power levels */
qcom,gpu-pwrlevels {
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/qcom/msm8937-interposer-sdm439.dtsi b/arch/arm64/boot/dts/qcom/msm8937-interposer-sdm439.dtsi
index 9f8459d..477802a 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-interposer-sdm439.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-interposer-sdm439.dtsi
@@ -16,6 +16,16 @@
#include "sdm439-audio.dtsi"
#include "sdm439-pmi632.dtsi"
+&pm8953_s5 {
+ regulator-min-microvolt = <1155000>;
+ regulator-max-microvolt = <1350000>;
+};
+
+&pm8953_s5_limit {
+ regulator-min-microvolt = <1155000>;
+ regulator-max-microvolt = <1350000>;
+};
+
&soc {
qcom,csid@1b30000 {
/delete-property/ qcom,mipi-csi-vdd-supply;
diff --git a/arch/arm64/boot/dts/qcom/msm8937-regulator.dtsi b/arch/arm64/boot/dts/qcom/msm8937-regulator.dtsi
index 57272a4..44bdfc9 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-regulator.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, 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
@@ -58,6 +58,14 @@
<RPM_SMD_REGULATOR_LEVEL_BINNING>;
qcom,use-voltage-level;
};
+
+ pm8937_cx_cdev: regulator-cx-cdev {
+ compatible = "qcom,regulator-cooling-device";
+ regulator-cdev-supply = <&pm8937_s2_floor_level>;
+ regulator-levels = <RPM_SMD_REGULATOR_LEVEL_NOM
+ RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ #cooling-cells = <2>;
+ };
};
rpm-regulator-smpa3 {
diff --git a/arch/arm64/boot/dts/qcom/msm8937-thermal.dtsi b/arch/arm64/boot/dts/qcom/msm8937-thermal.dtsi
new file mode 100644
index 0000000..0148253
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8937-thermal.dtsi
@@ -0,0 +1,742 @@
+/* Copyright (c) 2018, 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/thermal/thermal.h>
+
+&soc {
+ qmi-tmd-devices {
+ compatible = "qcom,qmi_cooling_devices";
+
+ modem {
+ qcom,instance-id = <0x0>;
+
+ modem_pa: modem_pa {
+ qcom,qmi-dev-name = "pa";
+ #cooling-cells = <2>;
+ };
+
+ modem_proc: modem_proc {
+ qcom,qmi-dev-name = "modem";
+ #cooling-cells = <2>;
+ };
+
+ modem_current: modem_current {
+ qcom,qmi-dev-name = "modem_current";
+ #cooling-cells = <2>;
+ };
+
+ modem_vdd: modem_vdd {
+ qcom,qmi-dev-name = "cpuv_restriction_cold";
+ #cooling-cells = <2>;
+ };
+ };
+ };
+};
+
+&thermal_zones {
+ aoss0-usr {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "user_space";
+ thermal-sensors = <&tsens0 0>;
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ mdm-core-usr {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "user_space";
+ thermal-sensors = <&tsens0 1>;
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ lpass-usr {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "user_space";
+ thermal-sensors = <&tsens0 2>;
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ camera-usr {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "user_space";
+ thermal-sensors = <&tsens0 3>;
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ cpuss1-usr {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 4>;
+ thermal-governor = "user_space";
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ apc1-cpu0-usr {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 5>;
+ thermal-governor = "user_space";
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ apc1-cpu1-usr {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 6>;
+ thermal-governor = "user_space";
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ apc1-cpu2-usr {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 7>;
+ thermal-governor = "user_space";
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ apc1-cpu3-usr {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 8>;
+ thermal-governor = "user_space";
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ cpuss0-usr {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 9>;
+ thermal-governor = "user_space";
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ gpu-usr {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 10>;
+ thermal-governor = "user_space";
+ trips {
+ active-config0 {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ gpu-step {
+ polling-delay-passive = <250>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 10>;
+ thermal-governor = "step_wise";
+ trips {
+ gpu_step_trip: gpu-step-trip {
+ temperature = <95000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ gpu_cdev0 {
+ trip = <&gpu_step_trip>;
+ cooling-device =
+ <&msm_gpu THERMAL_NO_LIMIT
+ THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ hexa-cpu-max-step {
+ polling-delay-passive = <50>;
+ polling-delay = <100>;
+ thermal-governor = "step_wise";
+ trips {
+ cpu_trip:cpu-trip {
+ temperature = <85000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu0_cdev {
+ trip = <&cpu_trip>;
+ cooling-device =
+ <&CPU0 THERMAL_NO_LIMIT
+ (THERMAL_MAX_LIMIT-1)>;
+ };
+ cpu1_cdev {
+ trip = <&cpu_trip>;
+ cooling-device =
+ <&CPU1 THERMAL_NO_LIMIT
+ (THERMAL_MAX_LIMIT-1)>;
+ };
+ cpu2_cdev {
+ trip = <&cpu_trip>;
+ cooling-device =
+ <&CPU2 THERMAL_NO_LIMIT
+ (THERMAL_MAX_LIMIT-1)>;
+ };
+ cpu3_cdev {
+ trip = <&cpu_trip>;
+ cooling-device =
+ <&CPU3 THERMAL_NO_LIMIT
+ (THERMAL_MAX_LIMIT-1)>;
+ };
+ cpu4_cdev {
+ trip = <&cpu_trip>;
+ cooling-device =
+ <&CPU4 THERMAL_NO_LIMIT
+ (THERMAL_MAX_LIMIT-1)>;
+ };
+ cpu5_cdev {
+ trip = <&cpu_trip>;
+ cooling-device =
+ <&CPU5 THERMAL_NO_LIMIT
+ (THERMAL_MAX_LIMIT-1)>;
+ };
+ cpu6_cdev {
+ trip = <&cpu_trip>;
+ cooling-device =
+ <&CPU6 THERMAL_NO_LIMIT
+ (THERMAL_MAX_LIMIT-1)>;
+ };
+ cpu7_cdev {
+ trip = <&cpu_trip>;
+ cooling-device =
+ <&CPU7 THERMAL_NO_LIMIT
+ (THERMAL_MAX_LIMIT-1)>;
+ };
+ };
+ };
+
+ apc1-cpu0-step {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 5>;
+ thermal-governor = "step_wise";
+ trips {
+ apc1_cpu0_trip: apc1-cpu0-trip {
+ temperature = <105000>;
+ hysteresis = <15000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu0_cdev {
+ trip = <&apc1_cpu0_trip>;
+ cooling-device =
+ <&CPU0 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ };
+ };
+
+ apc1-cpu1-step {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 6>;
+ thermal-governor = "step_wise";
+ trips {
+ apc1_cpu1_trip: apc1-cpu1-trip {
+ temperature = <105000>;
+ hysteresis = <15000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu1_cdev {
+ trip = <&apc1_cpu1_trip>;
+ cooling-device =
+ <&CPU1 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ };
+ };
+
+ apc1-cpu2-step {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 7>;
+ thermal-governor = "step_wise";
+ trips {
+ apc1_cpu2_trip: apc1-cpu2-trip {
+ temperature = <105000>;
+ hysteresis = <15000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu2_cdev {
+ trip = <&apc1_cpu2_trip>;
+ cooling-device =
+ <&CPU2 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ };
+ };
+
+ apc1-cpu3-step {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 8>;
+ thermal-governor = "step_wise";
+ trips {
+ apc1_cpu3_trip: apc1-cpu3-trip {
+ temperature = <105000>;
+ hysteresis = <15000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu3_cdev {
+ trip = <&apc1_cpu3_trip>;
+ cooling-device =
+ <&CPU3 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ };
+ };
+
+ cpuss0-step {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 9>;
+ thermal-governor = "step_wise";
+ trips {
+ cpuss0_step_trip: cpuss0-step-trip {
+ temperature = <105000>;
+ hysteresis = <15000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu4_cdev {
+ trip = <&cpuss0_step_trip>;
+ cooling-device =
+ <&CPU4 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ cpu5_cdev {
+ trip = <&cpuss0_step_trip>;
+ cooling-device =
+ <&CPU5 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ cpu6_cdev {
+ trip = <&cpuss0_step_trip>;
+ cooling-device =
+ <&CPU6 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ cpu7_cdev {
+ trip = <&cpuss0_step_trip>;
+ cooling-device =
+ <&CPU7 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ };
+ };
+
+ aoss0-lowf {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "low_limits_floor";
+ thermal-sensors = <&tsens0 0>;
+ tracks-low;
+ trips {
+ aoss0_trip: aoss-trip {
+ temperature = <5000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu0_vdd_cdev {
+ trip = <&aoss0_trip>;
+ cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2)
+ (THERMAL_MAX_LIMIT-2)>;
+ };
+ cx_vdd_cdev {
+ trip = <&aoss0_trip>;
+ cooling-device = <&pm8937_cx_cdev 0 0>;
+ };
+ modem_vdd_cdev {
+ trip = <&aoss0_trip>;
+ cooling-device = <&modem_vdd 0 0>;
+ };
+ };
+ };
+
+ mdm-core-lowf {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "low_limits_floor";
+ thermal-sensors = <&tsens0 1>;
+ tracks-low;
+ trips {
+ mdm_core_trip: mdm-core-trip {
+ temperature = <5000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu0_vdd_cdev {
+ trip = <&mdm_core_trip>;
+ cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2)
+ (THERMAL_MAX_LIMIT-2)>;
+ };
+ cx_vdd_cdev {
+ trip = <&mdm_core_trip>;
+ cooling-device = <&pm8937_cx_cdev 0 0>;
+ };
+ modem_vdd_cdev {
+ trip = <&mdm_core_trip>;
+ cooling-device = <&modem_vdd 0 0>;
+ };
+ };
+ };
+
+ lpass-lowf {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "low_limits_floor";
+ thermal-sensors = <&tsens0 2>;
+ tracks-low;
+ trips {
+ qdsp_trip: qdsp-trip {
+ temperature = <5000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu0_vdd_cdev {
+ trip = <&qdsp_trip>;
+ cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2)
+ (THERMAL_MAX_LIMIT-2)>;
+ };
+ cx_vdd_cdev {
+ trip = <&qdsp_trip>;
+ cooling-device = <&pm8937_cx_cdev 0 0>;
+ };
+ modem_vdd_cdev {
+ trip = <&qdsp_trip>;
+ cooling-device = <&modem_vdd 0 0>;
+ };
+ };
+ };
+
+ camera-lowf {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "low_limits_floor";
+ thermal-sensors = <&tsens0 3>;
+ tracks-low;
+ trips {
+ camera_trip: camera-trip {
+ temperature = <5000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu0_vdd_cdev {
+ trip = <&camera_trip>;
+ cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2)
+ (THERMAL_MAX_LIMIT-2)>;
+ };
+ cx_vdd_cdev {
+ trip = <&camera_trip>;
+ cooling-device = <&pm8937_cx_cdev 0 0>;
+ };
+ modem_vdd_cdev {
+ trip = <&camera_trip>;
+ cooling-device = <&modem_vdd 0 0>;
+ };
+ };
+ };
+
+ cpuss1-lowf {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "low_limits_floor";
+ thermal-sensors = <&tsens0 4>;
+ tracks-low;
+ trips {
+ cpuss1_trip: cpuss1-trip {
+ temperature = <5000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu0_vdd_cdev {
+ trip = <&cpuss1_trip>;
+ cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2)
+ (THERMAL_MAX_LIMIT-2)>;
+ };
+ cx_vdd_cdev {
+ trip = <&cpuss1_trip>;
+ cooling-device = <&pm8937_cx_cdev 0 0>;
+ };
+ modem_vdd_cdev {
+ trip = <&cpuss1_trip>;
+ cooling-device = <&modem_vdd 0 0>;
+ };
+ };
+ };
+
+ apc1-cpu0-lowf {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "low_limits_floor";
+ thermal-sensors = <&tsens0 5>;
+ tracks-low;
+ trips {
+ cpu0_trip: apc1-cpu0-trip {
+ temperature = <5000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu0_vdd_cdev {
+ trip = <&cpu0_trip>;
+ cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2)
+ (THERMAL_MAX_LIMIT-2)>;
+ };
+ cx_vdd_cdev {
+ trip = <&cpu0_trip>;
+ cooling-device = <&pm8937_cx_cdev 0 0>;
+ };
+ modem_vdd_cdev {
+ trip = <&cpu0_trip>;
+ cooling-device = <&modem_vdd 0 0>;
+ };
+ };
+ };
+
+ apc1-cpu1-lowf {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "low_limits_floor";
+ thermal-sensors = <&tsens0 6>;
+ tracks-low;
+ trips {
+ cpu1_trip: apc1-cpu1-trip {
+ temperature = <5000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu0_vdd_cdev {
+ trip = <&cpu1_trip>;
+ cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2)
+ (THERMAL_MAX_LIMIT-2)>;
+ };
+ cx_vdd_cdev {
+ trip = <&cpu1_trip>;
+ cooling-device = <&pm8937_cx_cdev 0 0>;
+ };
+ modem_vdd_cdev {
+ trip = <&cpu1_trip>;
+ cooling-device = <&modem_vdd 0 0>;
+ };
+ };
+ };
+
+ apc1-cpu2-lowf {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "low_limits_floor";
+ thermal-sensors = <&tsens0 7>;
+ tracks-low;
+ trips {
+ cpu2_trip: apc1-cpu2-trip {
+ temperature = <5000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu0_vdd_cdev {
+ trip = <&cpu2_trip>;
+ cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2)
+ (THERMAL_MAX_LIMIT-2)>;
+ };
+ cx_vdd_cdev {
+ trip = <&cpu2_trip>;
+ cooling-device = <&pm8937_cx_cdev 0 0>;
+ };
+ modem_vdd_cdev {
+ trip = <&cpu2_trip>;
+ cooling-device = <&modem_vdd 0 0>;
+ };
+ };
+ };
+
+ apc1-cpu3-lowf {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "low_limits_floor";
+ thermal-sensors = <&tsens0 8>;
+ tracks-low;
+ trips {
+ cpu3_trip: apc1-cpu3-trip {
+ temperature = <5000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu0_vdd_cdev {
+ trip = <&cpu3_trip>;
+ cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2)
+ (THERMAL_MAX_LIMIT-2)>;
+ };
+ cx_vdd_cdev {
+ trip = <&cpu3_trip>;
+ cooling-device = <&pm8937_cx_cdev 0 0>;
+ };
+ modem_vdd_cdev {
+ trip = <&cpu3_trip>;
+ cooling-device = <&modem_vdd 0 0>;
+ };
+ };
+ };
+
+ cpuss0-lowf {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "low_limits_floor";
+ thermal-sensors = <&tsens0 9>;
+ tracks-low;
+ trips {
+ cpuss0_lowf_trip: cpuss0-lowf-trip {
+ temperature = <5000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu0_vdd_cdev {
+ trip = <&cpuss0_lowf_trip>;
+ cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2)
+ (THERMAL_MAX_LIMIT-2)>;
+ };
+ cx_vdd_cdev {
+ trip = <&cpuss0_lowf_trip>;
+ cooling-device = <&pm8937_cx_cdev 0 0>;
+ };
+ modem_vdd_cdev {
+ trip = <&cpuss0_lowf_trip>;
+ cooling-device = <&modem_vdd 0 0>;
+ };
+ };
+ };
+
+ gpu-lowf {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "low_limits_floor";
+ thermal-sensors = <&tsens0 10>;
+ tracks-low;
+ trips {
+ gpu_lowf_trip: gpu-lowf-trip {
+ temperature = <5000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu0_vdd_cdev {
+ trip = <&gpu_lowf_trip>;
+ cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2)
+ (THERMAL_MAX_LIMIT-2)>;
+ };
+ cx_vdd_cdev {
+ trip = <&gpu_lowf_trip>;
+ cooling-device = <&pm8937_cx_cdev 0 0>;
+ };
+ modem_vdd_cdev {
+ trip = <&gpu_lowf_trip>;
+ cooling-device = <&modem_vdd 0 0>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8937.dtsi b/arch/arm64/boot/dts/qcom/msm8937.dtsi
index 7339847..09890bb 100644
--- a/arch/arm64/boot/dts/qcom/msm8937.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937.dtsi
@@ -24,7 +24,7 @@
interrupt-parent = <&wakegic>;
chosen {
- bootargs = "sched_enable_hmp=1";
+ bootargs = "sched_enable_hmp=1 kpti=0";
};
firmware: firmware {
@@ -303,161 +303,7 @@
qcom,pipe-attr-ee;
};
- thermal_zones: thermal-zones {
- aoss0-usr {
- polling-delay-passive = <0>;
- polling-delay = <0>;
- thermal-governor = "user_space";
- thermal-sensors = <&tsens0 0>;
- trips {
- active-config0 {
- temperature = <125000>;
- hysteresis = <1000>;
- type = "passive";
- };
- };
- };
-
- mdm-core-usr {
- polling-delay-passive = <0>;
- polling-delay = <0>;
- thermal-governor = "user_space";
- thermal-sensors = <&tsens0 1>;
- trips {
- active-config0 {
- temperature = <125000>;
- hysteresis = <1000>;
- type = "passive";
- };
- };
- };
-
- mdss-usr {
- polling-delay-passive = <0>;
- polling-delay = <0>;
- thermal-governor = "user_space";
- thermal-sensors = <&tsens0 2>;
- trips {
- active-config0 {
- temperature = <125000>;
- hysteresis = <1000>;
- type = "passive";
- };
- };
- };
-
- camera-usr {
- polling-delay-passive = <0>;
- polling-delay = <0>;
- thermal-governor = "user_space";
- thermal-sensors = <&tsens0 3>;
- trips {
- active-config0 {
- temperature = <125000>;
- hysteresis = <1000>;
- type = "passive";
- };
- };
- };
-
- cpuss-0-usr {
- polling-delay-passive = <0>;
- polling-delay = <0>;
- thermal-sensors = <&tsens0 4>;
- thermal-governor = "user_space";
- trips {
- active-config0 {
- temperature = <125000>;
- hysteresis = <1000>;
- type = "passive";
- };
- };
- };
-
- apc1_cpu1-usr {
- polling-delay-passive = <0>;
- polling-delay = <0>;
- thermal-sensors = <&tsens0 5>;
- thermal-governor = "user_space";
- trips {
- active-config0 {
- temperature = <125000>;
- hysteresis = <1000>;
- type = "passive";
- };
- };
- };
-
- apc1_cpu2-usr {
- polling-delay-passive = <0>;
- polling-delay = <0>;
- thermal-sensors = <&tsens0 6>;
- thermal-governor = "user_space";
- trips {
- active-config0 {
- temperature = <125000>;
- hysteresis = <1000>;
- type = "passive";
- };
- };
- };
-
- apc1_cpu3-usr {
- polling-delay-passive = <0>;
- polling-delay = <0>;
- thermal-sensors = <&tsens0 7>;
- thermal-governor = "user_space";
- trips {
- active-config0 {
- temperature = <125000>;
- hysteresis = <1000>;
- type = "passive";
- };
- };
- };
-
- apc1_cpu4-usr {
- polling-delay-passive = <0>;
- polling-delay = <0>;
- thermal-sensors = <&tsens0 8>;
- thermal-governor = "user_space";
- trips {
- active-config0 {
- temperature = <125000>;
- hysteresis = <1000>;
- type = "passive";
- };
- };
- };
-
- apc0_cpu0-usr {
- polling-delay-passive = <0>;
- polling-delay = <0>;
- thermal-sensors = <&tsens0 9>;
- thermal-governor = "user_space";
- trips {
- active-config0 {
- temperature = <125000>;
- hysteresis = <1000>;
- type = "passive";
- };
- };
- };
-
- gpu0-usr {
- polling-delay-passive = <0>;
- polling-delay = <0>;
- thermal-sensors = <&tsens0 10>;
- thermal-governor = "user_space";
- trips {
- active-config0 {
- temperature = <125000>;
- hysteresis = <1000>;
- type = "passive";
- };
- };
- };
- };
+ thermal_zones: thermal-zones {};
tsens0: tsens@4a8000 {
compatible = "qcom,msm8937-tsens";
@@ -1264,6 +1110,12 @@
qcom,smdpkt-dev-name = "smdcntl8";
};
+ qcom,smdpkt-data2 {
+ qcom,smdpkt-remote = "modem";
+ qcom,smdpkt-port-name = "DATA2";
+ qcom,smdpkt-dev-name = "at_mdm0";
+ };
+
qcom,smdpkt-apr-apps2 {
qcom,smdpkt-remote = "adsp";
qcom,smdpkt-port-name = "apr_apps2";
@@ -1816,6 +1668,7 @@
#include "msm8937-audio.dtsi"
#include "msm-gdsc-8916.dtsi"
#include "msm8937-coresight.dtsi"
+#include "msm8937-thermal.dtsi"
&gdsc_venus {
clock-names = "bus_clk", "core_clk";
diff --git a/arch/arm64/boot/dts/qcom/msm8953-coresight.dtsi b/arch/arm64/boot/dts/qcom/msm8953-coresight.dtsi
index 55914d0..aa00147 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-coresight.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-coresight.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, 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 an
@@ -330,6 +330,15 @@
<&audio_etm0_out_funnel_mm>;
};
};
+
+ port@4 {
+ reg = <6>;
+ funnel_mm_in_gfx: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&gfx_out_funnel_mm>;
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-gpu.dtsi b/arch/arm64/boot/dts/qcom/msm8953-gpu.dtsi
index 5cf6eb2..f82b68d 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-gpu.dtsi
@@ -124,14 +124,6 @@
qcom,gpu-quirk-dp2clockgating-disable;
qcom,gpu-quirk-lmloadkill-disable;
- /* Trace bus */
- coresight-id = <67>;
- coresight-name = "coresight-gfx";
- coresight-nr-inports = <0>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_mm>;
- coresight-child-ports = <6>;
-
/* Enable context aware freq. scaling */
qcom,enable-ca-jump;
@@ -164,6 +156,25 @@
};
};
+ qcom,gpu-coresights {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "qcom,gpu-coresight";
+
+ /* Trace bus */
+ qcom,gpu-coresight@0 {
+ reg = <0>;
+ coresight-name = "coresight-gfx";
+ coresight-atid = <67>;
+ port {
+ gfx_out_funnel_mm: endpoint {
+ remote-endpoint =
+ <&funnel_mm_in_gfx>;
+ };
+ };
+ };
+ };
+
/* Power levels */
qcom,gpu-pwrlevels {
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/qcom/msm8953-pm.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pm.dtsi
index da4f4df..b40b668 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-pm.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-pm.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, 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
@@ -144,6 +144,7 @@
#size-cells = <0>;
qcom,psci-mode-shift = <0>;
qcom,psci-mode-mask = <0xf>;
+ qcom,use-prediction;
qcom,cpu = <&CPU0 &CPU1 &CPU2 &CPU3>;
qcom,pm-cpu-level@0 {
@@ -235,6 +236,7 @@
#size-cells = <0>;
qcom,psci-mode-shift = <0>;
qcom,psci-mode-mask = <0xf>;
+ qcom,use-prediction;
qcom,cpu = <&CPU4 &CPU5 &CPU6 &CPU7>;
qcom,pm-cpu-level@0 {
diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi
index c786e08..978d432 100644
--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -25,6 +25,10 @@
qcom,msm-name = "MSM8953";
interrupt-parent = <&wakegic>;
+ chosen {
+ bootargs = "kpti=0";
+ };
+
firmware: firmware {
android {
compatible = "android,firmware";
@@ -1159,6 +1163,12 @@
qcom,smdpkt-dev-name = "smdcntl8";
};
+ qcom,smdpkt-data2 {
+ qcom,smdpkt-remote = "modem";
+ qcom,smdpkt-port-name = "DATA2";
+ qcom,smdpkt-dev-name = "at_mdm0";
+ };
+
qcom,smdpkt-apr-apps2 {
qcom,smdpkt-remote = "adsp";
qcom,smdpkt-port-name = "apr_apps2";
@@ -1189,12 +1199,22 @@
qcom,wakeup-enable;
};
- qcom,chd {
+ qcom,chd_silver {
compatible = "qcom,core-hang-detect";
+ label = "silver";
qcom,threshold-arr = <0xb1880b0 0xb1980b0 0xb1a80b0
- 0xb1b80b0 0xb0880b0 0xb0980b0 0xb0a80b0 0xb0b80b0>;
+ 0xb1b80b0>;
qcom,config-arr = <0xb1880b8 0xb1980b8 0xb1a80b8
- 0xb1b80b8 0xb0880b8 0xb0980b8 0xb0a80b8 0xb0b80b8>;
+ 0xb1b80b8>;
+ };
+
+ qcom,chd_gold {
+ compatible = "qcom,core-hang-detect";
+ label = "gold";
+ qcom,threshold-arr = <0xb0880b0 0xb0980b0 0xb0a80b0
+ 0xb0b80b0>;
+ qcom,config-arr = <0xb0880b8 0xb0980b8 0xb0a80b8
+ 0xb0b80b8>;
};
qcom,msm-rtb {
@@ -1502,8 +1522,8 @@
usb-phy = <&qusb_phy>, <&ssphy>;
tx-fifo-resize;
snps,usb3-u1u2-disable;
- snps,nominal-elastic-buffer;
snps,is-utmi-l1-suspend;
+ snps,usb2-l1-disable;
snps,hird-threshold = /bits/ 8 <0x0>;
};
diff --git a/arch/arm64/boot/dts/qcom/pm8004-rpm-regulator.dtsi b/arch/arm64/boot/dts/qcom/pm8004-rpm-regulator.dtsi
new file mode 100644
index 0000000..87c43e0
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pm8004-rpm-regulator.dtsi
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018, 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-ldoc1 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoc";
+ qcom,resource-id = <1>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "disabled";
+
+ regulator-l1 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm8004_l1";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/pm8937.dtsi b/arch/arm64/boot/dts/qcom/pm8937.dtsi
index fff83d5..cd1bddb 100644
--- a/arch/arm64/boot/dts/qcom/pm8937.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8937.dtsi
@@ -57,6 +57,7 @@
qcom,channel-num = <8>;
qcom,threshold-set = <0>;
qcom,temp_alarm-vadc = <&pm8937_vadc>;
+ #thermal-sensor-cells = <0>;
};
pm8937_coincell: qcom,coincell@2800 {
@@ -404,4 +405,29 @@
};
};
};
+
+ pm8937_tz {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "step_wise";
+ thermal-sensors = <&pm8937_temp_alarm>;
+
+ trips {
+ pm8937_trip0: pm8937-trip0 {
+ temperature = <105000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+ pm8937_trip1: pm8937-trip1 {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+ pm8937_trip2: pm8937-trip2 {
+ temperature = <145000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/pm8953.dtsi b/arch/arm64/boot/dts/qcom/pm8953.dtsi
index 3a587a8..c496257 100644
--- a/arch/arm64/boot/dts/qcom/pm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8953.dtsi
@@ -272,6 +272,19 @@
qcom,adc-vdd-reference = <1800>;
qcom,adc_tm-vadc = <&pm8953_vadc>;
#thermal-sensor-cells = <1>;
+
+ chan@36 {
+ label = "pa_therm0";
+ reg = <0x36>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,decimation = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,btm-channel-number = <0x48>;
+ qcom,fast-avg-setup = <0>;
+ qcom,thermal-node;
+ };
};
pm8953_rtc: qcom,pm8953_rtc {
diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi
index fea37c9..bdd69e2 100644
--- a/arch/arm64/boot/dts/qcom/pmi632.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi
@@ -41,6 +41,8 @@
interrupt-names = "eoc-int-en-set";
qcom,adc-vdd-reference = <1875>;
qcom,adc-full-scale-code = <0x70e4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&quiet_therm_default &smb_therm_default>;
chan@0 {
label = "ref_gnd";
@@ -186,6 +188,41 @@
qcom,cal-val = <0>;
};
+ chan@52 {
+ label = "typec_therm";
+ reg = <0x52>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,cal-val = <0>;
+ };
+
+ chan@53 {
+ label = "quiet_therm";
+ reg = <0x53>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,cal-val = <0>;
+ };
+
+ chan@54 {
+ label = "smb_therm";
+ reg = <0x54>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,cal-val = <0>;
+ };
};
pmi632_tz: qcom,temp-alarm@2400 {
@@ -213,6 +250,21 @@
gpio-controller;
#gpio-cells = <2>;
qcom,gpios-disallowed = <1>;
+
+ quiet_therm {
+ quiet_therm_default: quiet_therm_default {
+ pins = "gpio3";
+ bias-high-impedance;
+ };
+ };
+
+ smb_therm {
+ smb_therm_default: smb_therm_default {
+ pins = "gpio4";
+ bias-high-impedance;
+ };
+ };
+
};
pmi632_charger: qcom,qpnp-smb5 {
@@ -697,4 +749,29 @@
};
};
};
+
+ pmi632_tz {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "step_wise";
+ thermal-sensors = <&pmi632_tz>;
+
+ trips {
+ pmi632_tz_trip0: pmi632-trip0 {
+ temperature = <105000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+ pmi632_tz_trip1: pmi632-trip1 {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+ pmi632_tz_trip2: pmi632-trip2 {
+ temperature = <145000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi b/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi
index de25ae9..5d7d0b8 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi
@@ -141,6 +141,7 @@
};
&pm660_fg {
+ qcom,fg-force-load-profile;
qcom,battery-data = <&qcs_batterydata>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi b/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi
index 9960c47..d2a8f3e 100644
--- a/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi
@@ -45,6 +45,7 @@
enable-method = "psci";
cpu-release-addr = <0x0 0x90000000>;
next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
L2_1: l2-cache {
compatible = "arm,arch-cache";
cache-level = <2>;
@@ -68,6 +69,7 @@
enable-method = "psci";
cpu-release-addr = <0x0 0x90000000>;
next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
L1_I_101: l1-icache {
compatible = "arm,arch-cache";
qcom,dump-size = <0x8800>;
@@ -85,6 +87,7 @@
enable-method = "psci";
cpu-release-addr = <0x0 0x90000000>;
next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
L1_I_102: l1-icache {
compatible = "arm,arch-cache";
qcom,dump-size = <0x8800>;
@@ -102,6 +105,7 @@
enable-method = "psci";
cpu-release-addr = <0x0 0x90000000>;
next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
L1_I_103: l1-icache {
compatible = "arm,arch-cache";
qcom,dump-size = <0x8800>;
diff --git a/arch/arm64/boot/dts/qcom/sdm429.dtsi b/arch/arm64/boot/dts/qcom/sdm429.dtsi
index 88cf1da..f31eb6e 100644
--- a/arch/arm64/boot/dts/qcom/sdm429.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm429.dtsi
@@ -40,3 +40,16 @@
/delete-node/ port@4;
};
};
+
+&thermal_zones {
+ hexa-cpu-max-step {
+ cooling-maps {
+ /delete-node/ cpu4_cdev;
+ /delete-node/ cpu5_cdev;
+ /delete-node/ cpu6_cdev;
+ /delete-node/ cpu7_cdev;
+ };
+ };
+
+ /delete-node/ cpuss0-step;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi b/arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi
index 48938a5..289d5bf 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi
@@ -48,6 +48,7 @@
/delete-node/ xo-therm-buf-adc;
/delete-node/ case-therm-adc;
/delete-node/ pa-therm0-adc;
+ /delete-node/ pm8937_tz;
};
&int_codec {
@@ -89,12 +90,6 @@
/delete-property/ vdd-cci-supply;
};
- usb@78db000 {
- /delete-property/ hsusb_vdd_dig-supply;
- /delete-property/ HSUSB_1p8-supply;
- /delete-property/ HSUSB_3p3-supply;
- };
-
qcom,lpass@c200000 {
/delete-property/ vdd_cx-supply;
};
@@ -130,9 +125,10 @@
};
&usb_otg {
- /delete-property/ hsusb_vdd_dig-supply;
- /delete-property/ HSUSB_1p8-supply;
- /delete-property/ HSUSB_3p3-supply;
+ hsusb_vdd_dig-supply = <&pm8953_l23>;
+ HSUSB_1p8-supply = <&pm8953_l7>;
+ HSUSB_3p3-supply = <&pm8953_l13>;
+ qcom,vdd-voltage-level = <0 800000 800000>;
};
&mdss_dsi0_pll {
@@ -174,3 +170,84 @@
#include "pm8953.dtsi"
#include "pm8953-rpm-regulator.dtsi"
#include "sdm439-regulator.dtsi"
+
+&thermal_zones {
+ aoss0-lowf {
+ cooling-maps {
+ cx_vdd_cdev {
+ cooling-device = <&pm8953_cx_cdev 0 0>;
+ };
+ };
+ };
+
+ mdm-core-lowf {
+ cooling-maps {
+ cx_vdd_cdev {
+ cooling-device = <&pm8953_cx_cdev 0 0>;
+ };
+ };
+ };
+ lpass-lowf {
+ cooling-maps {
+ cx_vdd_cdev {
+ cooling-device = <&pm8953_cx_cdev 0 0>;
+ };
+ };
+ };
+ camera-lowf {
+ cooling-maps {
+ cx_vdd_cdev {
+ cooling-device = <&pm8953_cx_cdev 0 0>;
+ };
+ };
+ };
+ cpuss1-lowf {
+ cooling-maps {
+ cx_vdd_cdev {
+ cooling-device = <&pm8953_cx_cdev 0 0>;
+ };
+ };
+ };
+ apc1-cpu0-lowf {
+ cooling-maps {
+ cx_vdd_cdev {
+ cooling-device = <&pm8953_cx_cdev 0 0>;
+ };
+ };
+ };
+ apc1-cpu1-lowf {
+ cooling-maps {
+ cx_vdd_cdev {
+ cooling-device = <&pm8953_cx_cdev 0 0>;
+ };
+ };
+ };
+ apc1-cpu2-lowf {
+ cooling-maps {
+ cx_vdd_cdev {
+ cooling-device = <&pm8953_cx_cdev 0 0>;
+ };
+ };
+ };
+ apc1-cpu3-lowf {
+ cooling-maps {
+ cx_vdd_cdev {
+ cooling-device = <&pm8953_cx_cdev 0 0>;
+ };
+ };
+ };
+ cpuss0-lowf {
+ cooling-maps {
+ cx_vdd_cdev {
+ cooling-device = <&pm8953_cx_cdev 0 0>;
+ };
+ };
+ };
+ gpu-lowf {
+ cooling-maps {
+ cx_vdd_cdev {
+ cooling-device = <&pm8953_cx_cdev 0 0>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm439-pmi632.dtsi b/arch/arm64/boot/dts/qcom/sdm439-pmi632.dtsi
index ad2b0fe..5075862 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-pmi632.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-pmi632.dtsi
@@ -19,6 +19,7 @@
&usb_otg {
vbus_otg-supply = <&smb5_vbus>;
+ extcon = <&pmi632_charger>;
};
&pmi632_pon {
@@ -36,5 +37,68 @@
&pmi632_qg {
qcom,battery-data = <&mtp_batterydata>;
- qcom,rbat-conn-mohm = <20>;
+};
+
+&pm8953_typec {
+ status = "disabled";
+};
+
+&thermal_zones {
+ pmi-vbat-lvl0 {
+ cooling-maps {
+ vbat_map0 {
+ trip = <&pmi632_vbat_lvl0>;
+ cooling-device =
+ <&CPU0 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ vbat_map1 {
+ trip = <&pmi632_vbat_lvl0>;
+ cooling-device =
+ <&CPU1 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ vbat_map2 {
+ trip = <&pmi632_vbat_lvl0>;
+ cooling-device =
+ <&CPU2 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ vbat_map3 {
+ trip = <&pmi632_vbat_lvl0>;
+ cooling-device =
+ <&CPU3 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ };
+ };
+
+ soc {
+ cooling-maps {
+ soc_map0 {
+ trip = <&pmi632_low_soc>;
+ cooling-device =
+ <&CPU0 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ soc_map1 {
+ trip = <&pmi632_low_soc>;
+ cooling-device =
+ <&CPU1 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ soc_map2 {
+ trip = <&pmi632_low_soc>;
+ cooling-device =
+ <&CPU2 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ soc_map3 {
+ trip = <&pmi632_low_soc>;
+ cooling-device =
+ <&CPU3 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi
index 27307d8..f9bef43 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi
@@ -63,6 +63,14 @@
<RPM_SMD_REGULATOR_LEVEL_TURBO>;
qcom,use-voltage-level;
};
+
+ pm8953_cx_cdev: regulator-cx-cdev {
+ compatible = "qcom,regulator-cooling-device";
+ regulator-cdev-supply = <&pm8953_s2_floor_level>;
+ regulator-levels = <RPM_SMD_REGULATOR_LEVEL_NOM
+ RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ #cooling-cells = <2>;
+ };
};
rpm-regulator-smpa3 {
diff --git a/arch/arm64/boot/dts/qcom/sdm632-cdp-s2.dts b/arch/arm64/boot/dts/qcom/sdm632-cdp-s2.dts
index a544d59..51c323c 100644
--- a/arch/arm64/boot/dts/qcom/sdm632-cdp-s2.dts
+++ b/arch/arm64/boot/dts/qcom/sdm632-cdp-s2.dts
@@ -16,6 +16,7 @@
#include "sdm632.dtsi"
#include "sdm450-pmi632-cdp-s2.dtsi"
#include "sdm450-pmi632.dtsi"
+#include "sdm632-camera-sensor-cdp.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM632 + PMI632 + PMI8004 CDP S2";
diff --git a/arch/arm64/boot/dts/qcom/sdm632-mtp-s3.dts b/arch/arm64/boot/dts/qcom/sdm632-mtp-s3.dts
index 6339c3c..f7770af 100644
--- a/arch/arm64/boot/dts/qcom/sdm632-mtp-s3.dts
+++ b/arch/arm64/boot/dts/qcom/sdm632-mtp-s3.dts
@@ -16,6 +16,7 @@
#include "sdm632.dtsi"
#include "sdm450-pmi632-mtp-s3.dtsi"
#include "sdm450-pmi632.dtsi"
+#include "sdm632-camera-sensor-mtp.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM632 + PMI632 + PMI8004 MTP S3";
diff --git a/arch/arm64/boot/dts/qcom/sdm632-qrd-sku4.dts b/arch/arm64/boot/dts/qcom/sdm632-qrd-sku4.dts
index a158e33..c3cc988 100644
--- a/arch/arm64/boot/dts/qcom/sdm632-qrd-sku4.dts
+++ b/arch/arm64/boot/dts/qcom/sdm632-qrd-sku4.dts
@@ -16,6 +16,7 @@
#include "sdm632.dtsi"
#include "sdm450-qrd-sku4.dtsi"
#include "sdm450-pmi632.dtsi"
+#include "msm8953-camera-sensor-qrd.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM632 + PMI632 + PMI8004 QRD SKU4";
diff --git a/arch/arm64/boot/dts/qcom/sdm632-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm632-regulator.dtsi
new file mode 100644
index 0000000..ed7ec2a
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm632-regulator.dtsi
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2018, 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-ldoc1 {
+ status = "okay";
+ pm8004_l1: regulator-l1 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ qcom,init-voltage = <1200000>;
+ status = "okay";
+ };
+ };
+};
+
+&spmi_bus {
+ qcom,pm8953@1 {
+ /delete-node/ spm-regulator@2000;
+ };
+
+ pmic@5 {
+ #size-cells = <1>;
+
+ /* PM8004 S2 + S4 + S5 = VDD_APC supply */
+ pm8004_s2: spm-regulator@1d00 {
+ compatible = "qcom,spm-regulator";
+ reg = <0x1d00 0x100>;
+ regulator-name = "pm8004_s2";
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1140000>;
+
+ pm8004_s2_limit: avs-limit-regulator {
+ regulator-name = "pm8004_s2_avs_limit";
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1140000>;
+ };
+ };
+ };
+};
+
+&soc {
+ /delete-node/ regulator@19461d4;
+ /delete-node/ cpr4-ctrl@b018000;
+ /delete-node/ regulator@194415c;
+ /delete-node/ ldo@185f000;
+
+ apc_mem_acc_vreg: apc-mem-acc-regulator {
+ compatible = "qcom,mem-acc-regulator";
+ regulator-name = "apc_mem_acc_corner";
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <3>;
+ qcom,acc-reg-addr-list = <0x0b1d1360 0x0b1d1364
+ 0x0b1d1368 0x0b1d136c 0x0b1d1370>;
+ qcom,num-acc-corners = <3>;
+ qcom,boot-acc-corner = <1>;
+ qcom,corner1-reg-config =
+ /* 1 -> 1 */
+ <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ /* 1 -> 2 */
+ < 1 0x0>, < 2 0x0>,
+ < 3 0x0>, < 4 0x0>, < 5 0x0>,
+ /* 1 -> 3 */
+ < 1 0x0>, < 2 0x1>,
+ < 3 0x0>, < 4 0x10000>, < 5 0x0>;
+ qcom,corner2-reg-config =
+ /* 2 -> 1 */
+ < 1 0x0>, < 2 0x80000000>,
+ < 3 0x0>, < 4 0x0>, < 5 0x80000000>,
+ /* 2 -> 2 */
+ <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ /* 2 -> 3 */
+ < 1 0x0>, < 2 0x1>,
+ < 3 0x0>, < 4 0x10000>, < 5 0x0>;
+ qcom,corner3-reg-config =
+ /* 3 -> 1 */
+ < 1 0x0>, < 2 0x80000000>,
+ < 3 0x0>, < 4 0x0>, < 5 0x80000000>,
+ /* 3 -> 2 */
+ < 1 0x0>, < 2 0x0>,
+ < 3 0x0>, < 4 0x0>, < 5 0x0>,
+ /* 3 -> 3 */
+ <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>;
+ };
+
+ apc_cpr: cpr4-ctrl@b018000 {
+ compatible = "qcom,cpr4-sdm632-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 = <875000>;
+ qcom,apm-hysteresis-voltage = <20000>;
+
+ vdd-supply = <&pm8004_s2>;
+ qcom,voltage-step = <5000>;
+ vdd-limit-supply = <&pm8004_s2_limit>;
+ mem-acc-supply = <&apc_mem_acc_vreg>;
+
+ 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";
+
+ 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>;
+
+ apc0_pwrcl_vreg: regulator {
+ regulator-name = "apc0_pwrcl_corner";
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <7>;
+
+ qcom,cpr-fuse-corners = <5>;
+ qcom,cpr-fuse-combos = <8>;
+ qcom,cpr-corners = <7>;
+ qcom,cpr-corner-fmax-map = <1 2 3 4 7>;
+
+ qcom,cpr-voltage-ceiling =
+ <720000 720000 790000 865000 920000
+ 990000 1065000>;
+
+ qcom,cpr-voltage-floor =
+ <500000 500000 500000 500000 500000
+ 500000 500000>;
+
+ qcom,mem-acc-voltage = <1 1 2 2 2 2 3>;
+
+ qcom,corner-frequencies =
+ <614400000 883200000 1036800000
+ 1363200000 1536000000 1670400000
+ 1785600000>;
+
+ qcom,cpr-ro-scaling-factor =
+ <3600 3600 3830 2430 2520 2700 1790 1760
+ 1970 1880 2110 2010 2510 4900 4370 4780>,
+ <3600 3600 3830 2430 2520 2700 1790 1760
+ 1970 1880 2110 2010 2510 4900 4370 4780>,
+ <3600 3600 3830 2430 2520 2700 1790 1760
+ 1970 1880 2110 2010 2510 4900 4370 4780>,
+ <3600 3600 3830 2430 2520 2700 1790 1760
+ 1970 1880 2110 2010 2510 4900 4370 4780>,
+ <3600 3600 3830 2430 2520 2700 1790 1760
+ 1970 1880 2110 2010 2510 4900 4370 4780>;
+
+ qcom,allow-voltage-interpolation;
+ qcom,allow-quotient-interpolation;
+ qcom,cpr-scaled-open-loop-voltage-as-ceiling;
+ };
+ };
+
+ thread@1 {
+ qcom,cpr-thread-id = <1>;
+ qcom,cpr-consecutive-up = <0>;
+ qcom,cpr-consecutive-down = <2>;
+ qcom,cpr-up-threshold = <2>;
+ qcom,cpr-down-threshold = <1>;
+
+ apc1_perfcl_vreg: regulator {
+ regulator-name = "apc1_perfcl_corner";
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <5>;
+
+ qcom,cpr-fuse-corners = <3>;
+ qcom,cpr-fuse-combos = <8>;
+ qcom,cpr-corners = <5>;
+ qcom,cpr-corner-fmax-map = <1 2 5>;
+
+ qcom,cpr-voltage-ceiling =
+ <790000 865000 920000 990000 1065000>;
+
+ qcom,cpr-voltage-floor =
+ <500000 500000 500000 500000 500000>;
+
+ qcom,mem-acc-voltage = <2 2 2 2 3>;
+
+ qcom,corner-frequencies =
+ <1094400000 1401600000 1555200000
+ 1785600000 1996200000>;
+
+ qcom,cpr-ro-scaling-factor =
+ <3600 3600 3830 2430 2520 2700 1790 1760
+ 1970 1880 2110 2010 2510 4900 4370 4780>,
+ <3600 3600 3830 2430 2520 2700 1790 1760
+ 1970 1880 2110 2010 2510 4900 4370 4780>,
+ <3600 3600 3830 2430 2520 2700 1790 1760
+ 1970 1880 2110 2010 2510 4900 4370 4780>;
+
+ qcom,allow-voltage-interpolation;
+ qcom,allow-quotient-interpolation;
+ qcom,cpr-scaled-open-loop-voltage-as-ceiling;
+ };
+ };
+ };
+
+ 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 = <0 0 0 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>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm632.dtsi b/arch/arm64/boot/dts/qcom/sdm632.dtsi
index 4b9dcf3..e397355 100644
--- a/arch/arm64/boot/dts/qcom/sdm632.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm632.dtsi
@@ -13,6 +13,9 @@
#include "msm8953.dtsi"
#include "sdm632-cpu.dtsi"
+#include "pm8004.dtsi"
+#include "pm8004-rpm-regulator.dtsi"
+#include "sdm632-regulator.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM632";
@@ -540,10 +543,6 @@
#clock-cells = <1>;
};
-&apc_vreg {
- status = "disabled";
-};
-
&soc {
/delete-node/ msm_cpufreq;
msm_cpufreq: qcom,msm-cpufreq {
diff --git a/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi b/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
index 7d2d657..a77f4a0 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
@@ -122,8 +122,8 @@
cache-slices = <&llcc 12>, <&llcc 11>;
/* CPU latency parameter */
- qcom,pm-qos-active-latency = <899>;
- qcom,pm-qos-wakeup-latency = <899>;
+ qcom,pm-qos-active-latency = <67>;
+ qcom,pm-qos-wakeup-latency = <67>;
/* Enable context aware freq. scaling */
qcom,enable-ca-jump;
diff --git a/arch/arm64/boot/dts/qcom/sdm670-sde.dtsi b/arch/arm64/boot/dts/qcom/sdm670-sde.dtsi
index 3022998..4ca4001 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-sde.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-sde.dtsi
@@ -399,7 +399,7 @@
qcom,mdss-inline-rot-safe-lut = <0x0000f000 0x0000ff00>;
qcom,mdss-rot-qos-cpu-mask = <0xf>;
- qcom,mdss-rot-qos-cpu-dma-latency = <75>;
+ qcom,mdss-rot-qos-cpu-dma-latency = <67>;
qcom,mdss-default-ot-rd-limit = <32>;
qcom,mdss-default-ot-wr-limit = <32>;
diff --git a/arch/arm64/boot/dts/qcom/sdm670-usb.dtsi b/arch/arm64/boot/dts/qcom/sdm670-usb.dtsi
index 8b1f3d1..1e84e2c 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-usb.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-usb.dtsi
@@ -27,7 +27,7 @@
};
&usb0 {
- qcom,pm-qos-latency = <601>; /* CPU-CLUSTER-WFI-LVL latency +1 */
+ qcom,pm-qos-latency = <67>; /* CPU WFI latency + 1 */
extcon = <0>, <0>, <&eud>, <0>, <0>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index e6bf8ee..152b760 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -372,6 +372,7 @@
1747200 641
1843200 659
1996800 696
+ 2016000 865
2054400 876
2169600 900
2208000 924
@@ -413,6 +414,7 @@
1747200 64
1843200 65
1996800 69
+ 2016000 85
2054400 87
2169600 90
2208000 92
@@ -1930,7 +1932,7 @@
/* PM QoS */
qcom,pm-qos-cpu-groups = <0x3f 0xC0>;
- qcom,pm-qos-cpu-group-latency-us = <70 70>;
+ qcom,pm-qos-cpu-group-latency-us = <67 67>;
qcom,pm-qos-default-cpu = <0>;
resets = <&clock_gcc GCC_UFS_PHY_BCR>;
@@ -2368,10 +2370,10 @@
/* PM QoS */
qcom,pm-qos-irq-type = "affine_irq";
- qcom,pm-qos-irq-latency = <70 70>;
+ qcom,pm-qos-irq-latency = <67 67>;
qcom,pm-qos-cpu-groups = <0x3f 0xc0>;
- qcom,pm-qos-cmdq-latency-us = <70 70>, <70 70>;
- qcom,pm-qos-legacy-latency-us = <70 70>, <70 70>;
+ qcom,pm-qos-cmdq-latency-us = <67 67>, <67 67>;
+ qcom,pm-qos-legacy-latency-us = <67 67>, <67 67>;
clocks = <&clock_gcc GCC_SDCC1_AHB_CLK>,
<&clock_gcc GCC_SDCC1_APPS_CLK>,
@@ -2441,9 +2443,9 @@
/* PM QoS */
qcom,pm-qos-irq-type = "affine_irq";
- qcom,pm-qos-irq-latency = <70 70>;
+ qcom,pm-qos-irq-latency = <67 67>;
qcom,pm-qos-cpu-groups = <0x3f 0xc0>;
- qcom,pm-qos-legacy-latency-us = <70 70>, <70 70>;
+ qcom,pm-qos-legacy-latency-us = <67 67>, <67 67>;
clocks = <&clock_gcc GCC_SDCC2_AHB_CLK>,
<&clock_gcc GCC_SDCC2_APPS_CLK>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi b/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
index 000f5d3..e8f85a9 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -83,10 +83,11 @@
<&clock_gpucc GPU_CC_CXO_CLK>,
<&clock_gcc GCC_DDRSS_GPU_AXI_CLK>,
<&clock_gcc GCC_GPU_MEMNOC_GFX_CLK>,
- <&clock_gpucc GPU_CC_CX_GMU_CLK>;
+ <&clock_gpucc GPU_CC_CX_GMU_CLK>,
+ <&clock_cpucc L3_GPU_VOTE_CLK>;
clock-names = "core_clk", "rbbmtimer_clk", "mem_clk",
- "mem_iface_clk", "gmu_clk";
+ "mem_iface_clk", "gmu_clk", "l3_vote";
qcom,isense-clk-on-level = <1>;
@@ -155,6 +156,28 @@
};
};
+ qcom,l3-pwrlevels {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible = "qcom,l3-pwrlevels";
+
+ qcom,l3-pwrlevel@0 {
+ reg = <0>;
+ qcom,l3-freq = <0>;
+ };
+
+ qcom,l3-pwrlevel@1 {
+ reg = <1>;
+ qcom,l3-freq = <806400000>;
+ };
+
+ qcom,l3-pwrlevel@2 {
+ reg = <2>;
+ qcom,l3-freq = <1305600000>;
+ };
+ };
+
/* GPU Mempools */
qcom,gpu-mempools {
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
index 8b67649..8d4d7df 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
@@ -536,6 +536,11 @@
&dsi_dual_nt35597_truly_video {
qcom,mdss-dsi-t-clk-post = <0x0D>;
qcom,mdss-dsi-t-clk-pre = <0x2D>;
+ qcom,mdss-dsi-min-refresh-rate = <53>;
+ qcom,mdss-dsi-max-refresh-rate = <60>;
+ qcom,mdss-dsi-pan-enable-dynamic-fps;
+ qcom,mdss-dsi-pan-fps-update =
+ "dfps_immediate_porch_mode_vfp";
qcom,esd-check-enabled;
qcom,mdss-dsi-panel-status-check-mode = "reg_read";
qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a];
@@ -601,6 +606,11 @@
&dsi_nt35597_truly_dsc_video {
qcom,mdss-dsi-t-clk-post = <0x0b>;
qcom,mdss-dsi-t-clk-pre = <0x23>;
+ qcom,mdss-dsi-min-refresh-rate = <53>;
+ qcom,mdss-dsi-max-refresh-rate = <60>;
+ qcom,mdss-dsi-pan-enable-dynamic-fps;
+ qcom,mdss-dsi-pan-fps-update =
+ "dfps_immediate_porch_mode_vfp";
qcom,esd-check-enabled;
qcom,mdss-dsi-panel-status-check-mode = "reg_read";
qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a];
diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2.dtsi b/arch/arm64/boot/dts/qcom/sdm845-v2.dtsi
index 1551952..575cf12 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-v2.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-v2.dtsi
@@ -430,7 +430,7 @@
1766400 160
>;
idle-cost-data = <
- 22 18 14 12
+ 10 8 6 4
>;
};
CPU_COST_1: core-cost1 {
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index a667b01..aa16a77 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -1267,7 +1267,7 @@
vdd_pwrcl_mx_ao-supply = <&pm8998_s6_level_ao>;
qcom,mx-turbo-freq = <1478400000 1689600000 3300000001>;
- l3-devs = <&l3_cpu0 &l3_cpu4 &l3_cdsp>;
+ l3-devs = <&l3_cpu0 &l3_cpu4 &l3_cdsp &msm_gpu>;
clock-names = "xo_ao";
clocks = <&clock_rpmh RPMH_CXO_CLK_A>;
diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig
index 6859413..f5410c1 100644
--- a/arch/arm64/configs/msm8953-perf_defconfig
+++ b/arch/arm64/configs/msm8953-perf_defconfig
@@ -65,6 +65,7 @@
CONFIG_ZSMALLOC=y
CONFIG_BALANCE_ANON_FILE_RECLAIM=y
CONFIG_SECCOMP=y
+CONFIG_HARDEN_BRANCH_PREDICTOR=y
CONFIG_ARMV8_DEPRECATED=y
CONFIG_SWP_EMULATION=y
CONFIG_CP15_BARRIER_EMULATION=y
diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig
index 8c81b28..b9d1c38 100644
--- a/arch/arm64/configs/msm8953_defconfig
+++ b/arch/arm64/configs/msm8953_defconfig
@@ -71,6 +71,7 @@
CONFIG_ZSMALLOC=y
CONFIG_BALANCE_ANON_FILE_RECLAIM=y
CONFIG_SECCOMP=y
+CONFIG_HARDEN_BRANCH_PREDICTOR=y
CONFIG_ARMV8_DEPRECATED=y
CONFIG_SWP_EMULATION=y
CONFIG_CP15_BARRIER_EMULATION=y
@@ -578,6 +579,7 @@
CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y
CONFIG_QCOM_BIMC_BWMON=y
CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
+CONFIG_DEVFREQ_SIMPLE_DEV=y
CONFIG_QCOM_DEVFREQ_DEVBW=y
CONFIG_SPDM_SCM=y
CONFIG_DEVFREQ_SPDM=y
diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig
index b8bfa44..961864b 100644
--- a/arch/arm64/configs/sdm670_defconfig
+++ b/arch/arm64/configs/sdm670_defconfig
@@ -466,7 +466,6 @@
CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
CONFIG_EDAC_KRYO3XX_ARM64=y
-CONFIG_EDAC_KRYO3XX_ARM64_PANIC_ON_CE=y
CONFIG_EDAC_KRYO3XX_ARM64_PANIC_ON_UE=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_QPNP=y
diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h
index b58f429..866c518 100644
--- a/arch/arm64/include/asm/topology.h
+++ b/arch/arm64/include/asm/topology.h
@@ -36,7 +36,10 @@
#ifdef CONFIG_CPU_FREQ
#define arch_scale_freq_capacity cpufreq_scale_freq_capacity
extern unsigned long cpufreq_scale_freq_capacity(struct sched_domain *sd, int cpu);
-extern unsigned long cpufreq_scale_max_freq_capacity(int cpu);
+#define arch_scale_max_freq_capacity cpufreq_scale_max_freq_capacity
+extern unsigned long cpufreq_scale_max_freq_capacity(struct sched_domain *sd, int cpu);
+#define arch_scale_min_freq_capacity cpufreq_scale_min_freq_capacity
+extern unsigned long cpufreq_scale_min_freq_capacity(struct sched_domain *sd, int cpu);
#endif
#define arch_scale_cpu_capacity scale_cpu_capacity
extern unsigned long scale_cpu_capacity(struct sched_domain *sd, int cpu);
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index f2fe96f..e3bc878 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -50,13 +50,7 @@
unsigned long scale_cpu_capacity(struct sched_domain *sd, int cpu)
{
-#ifdef CONFIG_CPU_FREQ
- unsigned long max_freq_scale = cpufreq_scale_max_freq_capacity(cpu);
-
- return per_cpu(cpu_scale, cpu) * max_freq_scale >> SCHED_CAPACITY_SHIFT;
-#else
return per_cpu(cpu_scale, cpu);
-#endif
}
static void set_capacity_scale(unsigned int cpu, unsigned long capacity)
diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c
index da5add9..c841cce 100644
--- a/arch/arm64/mm/context.c
+++ b/arch/arm64/mm/context.c
@@ -230,6 +230,9 @@
raw_spin_unlock_irqrestore(&cpu_asid_lock, flags);
switch_mm_fastpath:
+
+ arm64_apply_bp_hardening();
+
/*
* Defer TTBR0_EL1 setting for user threads to uaccess_enable() when
* emulating PAN.
@@ -245,8 +248,6 @@
"ic iallu; dsb nsh; isb",
ARM64_WORKAROUND_CAVIUM_27456,
CONFIG_CAVIUM_ERRATUM_27456));
-
- arm64_apply_bp_hardening();
}
static int asids_init(void)
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index b7d07dd..9988291 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -36,7 +36,11 @@
#define DIAG_MAX_REQ_SIZE (16 * 1024)
#define DIAG_MAX_RSP_SIZE (16 * 1024)
+#ifdef CONFIG_USB_CI13XXX_MSM
+#define APF_DIAG_PADDING 256
+#else
#define APF_DIAG_PADDING 0
+#endif
/*
* In the worst case, the HDLC buffer can be atmost twice the size of the
* original packet. Add 3 bytes for 16 bit CRC (2 bytes) and a delimiter
diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c
index da649bb..7225dc2 100644
--- a/drivers/char/diag/diagfwd_peripheral.c
+++ b/drivers/char/diag/diagfwd_peripheral.c
@@ -1179,8 +1179,11 @@
int index;
unsigned long flags;
+ if (!fwd_info)
+ return NULL;
spin_lock_irqsave(&fwd_info->write_buf_lock, flags);
- for (index = 0 ; index < NUM_WRITE_BUFFERS; index++) {
+ for (index = 0; (index < NUM_WRITE_BUFFERS) && fwd_info->buf_ptr[index];
+ index++) {
if (!atomic_read(&(fwd_info->buf_ptr[index]->in_busy))) {
atomic_set(&(fwd_info->buf_ptr[index]->in_busy), 1);
buf = fwd_info->buf_ptr[index]->data;
@@ -1615,7 +1618,8 @@
if (!fwd_info || !ptr)
return found;
spin_lock_irqsave(&fwd_info->write_buf_lock, flags);
- for (index = 0; index < NUM_WRITE_BUFFERS; index++) {
+ for (index = 0; (index < NUM_WRITE_BUFFERS) && fwd_info->buf_ptr[index];
+ index++) {
if (fwd_info->buf_ptr[index]->data == ptr) {
atomic_set(&fwd_info->buf_ptr[index]->in_busy, 0);
found = 1;
diff --git a/drivers/char/msm_smd_pkt.c b/drivers/char/msm_smd_pkt.c
index ff77cb2..c93c1da 100644
--- a/drivers/char/msm_smd_pkt.c
+++ b/drivers/char/msm_smd_pkt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-2018, 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
@@ -76,6 +76,8 @@
struct work_struct packet_arrival_work;
spinlock_t pa_spinlock;
int ws_locked;
+
+ int sigs_updated;
};
@@ -356,9 +358,12 @@
mutex_lock(&smd_pkt_devp->ch_lock);
switch (cmd) {
case TIOCMGET:
- D_STATUS("%s TIOCMGET command on smd_pkt_dev id:%d\n",
- __func__, smd_pkt_devp->i);
+ smd_pkt_devp->sigs_updated = false;
ret = smd_tiocmget(smd_pkt_devp->ch);
+ D_STATUS("%s TIOCMGET command on smd_pkt_dev id:%d [%d]\n",
+ __func__, smd_pkt_devp->i, ret);
+ if (ret > 0)
+ ret = put_user((uint32_t)ret, (uint32_t __user *)arg);
break;
case TIOCMSET:
ret = get_user(val, (uint32_t *)arg);
@@ -668,6 +673,12 @@
D_POLL("%s sets POLLIN for smd_pkt_dev id: %d\n",
__func__, smd_pkt_devp->i);
}
+
+ if (smd_pkt_devp->sigs_updated) {
+ mask |= POLLPRI;
+ D_POLL("%s sets POLLPRI for smd_pkt_dev id: %d\n",
+ __func__, smd_pkt_devp->i);
+ }
mutex_unlock(&smd_pkt_devp->ch_lock);
return mask;
@@ -773,6 +784,9 @@
schedule_delayed_work(&loopback_work,
msecs_to_jiffies(1000));
break;
+ case SMD_EVENT_STATUS:
+ smd_pkt_devp->sigs_updated = true;
+ break;
}
}
@@ -1099,6 +1113,7 @@
smd_pkt_devp->ws_locked = 0;
}
spin_unlock_irqrestore(&smd_pkt_devp->pa_spinlock, flags);
+ smd_pkt_devp->sigs_updated = false;
}
mutex_unlock(&smd_pkt_devp->tx_lock);
mutex_unlock(&smd_pkt_devp->rx_lock);
diff --git a/drivers/clk/msm/clock-a7.c b/drivers/clk/msm/clock-a7.c
index 1c0b45a..4ee50ff 100644
--- a/drivers/clk/msm/clock-a7.c
+++ b/drivers/clk/msm/clock-a7.c
@@ -32,7 +32,7 @@
#include "clock.h"
-DEFINE_VDD_REGS_INIT(vdd_cpu, 1);
+static DEFINE_VDD_REGS_INIT(vdd_cpu, 1);
static struct mux_div_clk a7ssmux = {
.ops = &rcg_mux_div_ops,
@@ -88,51 +88,50 @@
rcu_read_unlock();
}
-static int add_opp(struct clk *c, struct device *cpudev, struct device *vregdev,
- unsigned long max_rate)
+static int add_opp(struct clk *c, struct device *dev,
+ unsigned long max_rate)
{
unsigned long rate = 0;
int level;
- long ret, uv, corner;
+ int uv;
+ long ret;
+ bool first = true;
+ int j = 1;
while (1) {
- ret = clk_round_rate(c, rate + 1);
- if (ret < 0) {
- pr_warn("clock-cpu: round_rate failed at %lu\n", rate);
- return ret;
- }
-
- rate = ret;
+ rate = c->fmax[j++];
level = find_vdd_level(c, rate);
if (level <= 0) {
- pr_warn("clock-cpu: no uv for %lu.\n", rate);
+ pr_warn("clock-cpu: no corner for %lu\n", rate);
return -EINVAL;
}
- uv = corner = c->vdd_class->vdd_uv[level];
+ uv = c->vdd_class->vdd_uv[level];
+ if (uv < 0) {
+ pr_warn("clock-cpu: no uv for %lu\n", rate);
+ return -EINVAL;
+ }
+
+ ret = dev_pm_opp_add(dev, rate, uv);
+ if (ret) {
+ pr_warn("clock-cpu: failed to add OPP for %lu\n",
+ rate);
+ return ret;
+ }
/*
- * Populate both CPU and regulator devices with the
- * freq-to-corner OPP table to maintain backward
- * compatibility.
+ * The OPP pair for the lowest and highest frequency for
+ * each device that we're populating. This is important since
+ * this information will be used by thermal mitigation and the
+ * scheduler.
*/
- ret = dev_pm_opp_add(cpudev, rate, corner);
- if (ret) {
- pr_warn("clock-cpu: couldn't add OPP for %lu\n",
- rate);
- return ret;
+ if ((rate >= max_rate) || first) {
+ if (first)
+ first = false;
+ else
+ break;
}
-
- ret = dev_pm_opp_add(vregdev, rate, corner);
- if (ret) {
- pr_warn("clock-cpu: couldn't add OPP for %lu\n",
- rate);
- return ret;
- }
-
- if (rate >= max_rate)
- break;
}
return 0;
@@ -142,6 +141,7 @@
{
struct platform_device *apc_dev;
struct device_node *apc_node;
+ struct device *dev;
unsigned long apc_fmax;
int cpu, a7_cpu = 0;
@@ -161,13 +161,13 @@
for_each_possible_cpu(cpu) {
a7_cpu = cpu;
- if (!get_cpu_device(cpu)) {
+ dev = get_cpu_device(cpu);
+ if (!dev) {
pr_err("can't find cpu device for attaching OPPs\n");
return;
}
- WARN(add_opp(&a7ssmux.c, get_cpu_device(cpu),
- &apc_dev->dev, apc_fmax),
+ WARN(add_opp(&a7ssmux.c, dev, apc_fmax),
"Failed to add OPP levels for A7\n");
}
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index bb540a5..597aa57 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -102,14 +102,6 @@
governor. If unsure have a look at the help section of the
driver. Fallback governor will be the performance governor.
-config CPU_FREQ_DEFAULT_GOV_SCHED
- bool "sched"
- select CPU_FREQ_GOV_SCHED
- help
- Use the CPUfreq governor 'sched' as default. This scales
- cpu frequency using CPU utilization estimates from the
- scheduler.
-
config CPU_FREQ_DEFAULT_GOV_INTERACTIVE
bool "interactive"
select CPU_FREQ_GOV_INTERACTIVE
@@ -238,19 +230,6 @@
If in doubt, say N.
-config CPU_FREQ_GOV_SCHED
- bool "'sched' cpufreq governor"
- depends on CPU_FREQ
- depends on SMP
- select CPU_FREQ_GOV_COMMON
- help
- 'sched' - this governor scales cpu frequency from the
- scheduler as a function of cpu capacity utilization. It does
- not evaluate utilization on a periodic basis (as ondemand
- does) but instead is event-driven by the scheduler.
-
- If in doubt, say N.
-
config CPU_FREQ_GOV_SCHEDUTIL
bool "'schedutil' cpufreq policy governor"
depends on CPU_FREQ && SMP
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index ff72d8a..8059ef9 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -325,33 +325,24 @@
*********************************************************************/
static DEFINE_PER_CPU(unsigned long, freq_scale) = SCHED_CAPACITY_SCALE;
+static DEFINE_PER_CPU(unsigned long, max_freq_cpu);
static DEFINE_PER_CPU(unsigned long, max_freq_scale) = SCHED_CAPACITY_SCALE;
+static DEFINE_PER_CPU(unsigned long, min_freq_scale);
static void
-scale_freq_capacity(struct cpufreq_policy *policy, struct cpufreq_freqs *freqs)
+scale_freq_capacity(const cpumask_t *cpus, unsigned long cur_freq,
+ unsigned long max_freq)
{
- unsigned long cur = freqs ? freqs->new : policy->cur;
- unsigned long scale = (cur << SCHED_CAPACITY_SHIFT) / policy->max;
- struct cpufreq_cpuinfo *cpuinfo = &policy->cpuinfo;
+ unsigned long scale = (cur_freq << SCHED_CAPACITY_SHIFT) / max_freq;
int cpu;
- pr_debug("cpus %*pbl cur/cur max freq %lu/%u kHz freq scale %lu\n",
- cpumask_pr_args(policy->cpus), cur, policy->max, scale);
-
- for_each_cpu(cpu, policy->cpus)
+ for_each_cpu(cpu, cpus) {
per_cpu(freq_scale, cpu) = scale;
+ per_cpu(max_freq_cpu, cpu) = max_freq;
+ }
- if (freqs)
- return;
-
- scale = (policy->max << SCHED_CAPACITY_SHIFT) / cpuinfo->max_freq;
-
- pr_debug("cpus %*pbl cur max/max freq %u/%u kHz max freq scale %lu\n",
- cpumask_pr_args(policy->cpus), policy->max, cpuinfo->max_freq,
- scale);
-
- for_each_cpu(cpu, policy->cpus)
- per_cpu(max_freq_scale, cpu) = scale;
+ pr_debug("cpus %*pbl cur freq/max freq %lu/%lu kHz freq scale %lu\n",
+ cpumask_pr_args(cpus), cur_freq, max_freq, scale);
}
unsigned long cpufreq_scale_freq_capacity(struct sched_domain *sd, int cpu)
@@ -359,11 +350,62 @@
return per_cpu(freq_scale, cpu);
}
-unsigned long cpufreq_scale_max_freq_capacity(int cpu)
+static void
+scale_max_freq_capacity(const cpumask_t *cpus, unsigned long policy_max_freq)
+{
+ unsigned long scale, max_freq;
+ int cpu = cpumask_first(cpus);
+
+ if (cpu >= nr_cpu_ids)
+ return;
+
+ max_freq = per_cpu(max_freq_cpu, cpu);
+
+ if (!max_freq)
+ return;
+
+ scale = (policy_max_freq << SCHED_CAPACITY_SHIFT) / max_freq;
+
+ for_each_cpu(cpu, cpus)
+ per_cpu(max_freq_scale, cpu) = scale;
+
+ pr_debug("cpus %*pbl policy max freq/max freq %lu/%lu kHz max freq scale %lu\n",
+ cpumask_pr_args(cpus), policy_max_freq, max_freq, scale);
+}
+
+unsigned long cpufreq_scale_max_freq_capacity(struct sched_domain *sd, int cpu)
{
return per_cpu(max_freq_scale, cpu);
}
+static void
+scale_min_freq_capacity(const cpumask_t *cpus, unsigned long policy_min_freq)
+{
+ unsigned long scale, max_freq;
+ int cpu = cpumask_first(cpus);
+
+ if (cpu >= nr_cpu_ids)
+ return;
+
+ max_freq = per_cpu(max_freq_cpu, cpu);
+
+ if (!max_freq)
+ return;
+
+ scale = (policy_min_freq << SCHED_CAPACITY_SHIFT) / max_freq;
+
+ for_each_cpu(cpu, cpus)
+ per_cpu(min_freq_scale, cpu) = scale;
+
+ pr_debug("cpus %*pbl policy min freq/max freq %lu/%lu kHz min freq scale %lu\n",
+ cpumask_pr_args(cpus), policy_min_freq, max_freq, scale);
+}
+
+unsigned long cpufreq_scale_min_freq_capacity(struct sched_domain *sd, int cpu)
+{
+ return per_cpu(min_freq_scale, cpu);
+}
+
static void __cpufreq_notify_transition(struct cpufreq_policy *policy,
struct cpufreq_freqs *freqs, unsigned int state)
{
@@ -471,7 +513,7 @@
spin_unlock(&policy->transition_lock);
- scale_freq_capacity(policy, freqs);
+ scale_freq_capacity(policy->cpus, freqs->new, policy->cpuinfo.max_freq);
#ifdef CONFIG_SMP
for_each_cpu(cpu, policy->cpus)
trace_cpu_capacity(capacity_curr_of(cpu), cpu);
@@ -2275,7 +2317,8 @@
blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
CPUFREQ_NOTIFY, new_policy);
- scale_freq_capacity(new_policy, NULL);
+ scale_max_freq_capacity(policy->cpus, policy->max);
+ scale_min_freq_capacity(policy->cpus, policy->min);
policy->min = new_policy->min;
policy->max = new_policy->max;
diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c
index 786ba01..7fca843 100644
--- a/drivers/cpuidle/lpm-levels.c
+++ b/drivers/cpuidle/lpm-levels.c
@@ -99,6 +99,8 @@
module_param_named(tmr_add, tmr_add, uint, 0664);
static uint32_t ref_premature_cnt = 1;
+module_param_named(ref_premature_cnt, ref_premature_cnt, uint, 0664);
+
static uint32_t bias_hyst;
module_param_named(bias_hyst, bias_hyst, uint, 0664);
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index 4426bc7..8643667 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -5929,8 +5929,7 @@
int len = DUMMY_REQ_DATA_LEN;
memcpy(pce_dev->dummyreq_in_buf, input, len);
- sg_set_buf(&pce_dev->dummyreq.sg, pce_dev->dummyreq_in_buf, len);
- sg_mark_end(&pce_dev->dummyreq.sg);
+ sg_init_one(&pce_dev->dummyreq.sg, pce_dev->dummyreq_in_buf, len);
pce_dev->dummyreq.sreq.alg = QCE_HASH_SHA1;
pce_dev->dummyreq.sreq.qce_cb = qce_dummy_complete;
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 47fa966b..7649012 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -38,15 +38,6 @@
#include "sde_power_handle.h"
#include "sde_core_perf.h"
#include "sde_trace.h"
-#include <soc/qcom/scm.h>
-#include "soc/qcom/secure_buffer.h"
-
-/* defines for secure channel call */
-#define SEC_SID_CNT 2
-#define SEC_SID_MASK_0 0x80881
-#define SEC_SID_MASK_1 0x80C81
-#define MEM_PROTECT_SD_CTRL_SWITCH 0x18
-#define MDP_DEVICE_ID 0x1A
#define SDE_PSTATES_MAX (SDE_STAGE_MAX * 4)
#define SDE_MULTIRECT_PLANE_MAX (SDE_STAGE_MAX * 2)
@@ -1786,8 +1777,9 @@
struct drm_plane *plane;
struct drm_encoder *encoder;
struct sde_crtc *sde_crtc;
- struct sde_crtc_state *cstate;
- struct sde_crtc_smmu_state_data *smmu_state;
+ struct sde_kms *sde_kms;
+ struct sde_mdss_cfg *catalog;
+ struct sde_kms_smmu_state_data *smmu_state;
uint32_t translation_mode = 0, secure_level;
int ops = 0;
bool post_commit = false;
@@ -1797,10 +1789,14 @@
return -EINVAL;
}
+ sde_kms = _sde_crtc_get_kms(crtc);
+ if (!sde_kms)
+ return -EINVAL;
+
+ smmu_state = &sde_kms->smmu_state;
sde_crtc = to_sde_crtc(crtc);
- cstate = to_sde_crtc_state(crtc->state);
- smmu_state = &sde_crtc->smmu_state;
secure_level = sde_crtc_get_secure_level(crtc, crtc->state);
+ catalog = sde_kms->catalog;
SDE_DEBUG("crtc%d, secure_level%d old_valid_fb%d\n",
crtc->base.id, secure_level, old_valid_fb);
@@ -1841,6 +1837,8 @@
break;
}
+ mutex_lock(&sde_kms->secure_transition_lock);
+
switch (translation_mode) {
case SDE_DRM_FB_SEC_DIR_TRANS:
/* secure display usecase */
@@ -1848,18 +1846,22 @@
(secure_level == SDE_DRM_SEC_ONLY)) {
smmu_state->state = DETACH_ALL_REQ;
smmu_state->transition_type = PRE_COMMIT;
- ops |= SDE_KMS_OPS_CRTC_SECURE_STATE_CHANGE;
+ ops |= SDE_KMS_OPS_SECURE_STATE_CHANGE;
if (old_valid_fb) {
ops |= (SDE_KMS_OPS_WAIT_FOR_TX_DONE |
SDE_KMS_OPS_CLEANUP_PLANE_FB);
}
+ if (catalog->sui_misr_supported)
+ smmu_state->sui_misr_state =
+ SUI_MISR_ENABLE_REQ;
/* secure camera usecase */
} else if (smmu_state->state == ATTACHED) {
smmu_state->state = DETACH_SEC_REQ;
smmu_state->transition_type = PRE_COMMIT;
- ops |= SDE_KMS_OPS_CRTC_SECURE_STATE_CHANGE;
+ ops |= SDE_KMS_OPS_SECURE_STATE_CHANGE;
}
break;
+
case SDE_DRM_FB_SEC:
case SDE_DRM_FB_NON_SEC:
if ((smmu_state->state == DETACHED_SEC) ||
@@ -1867,7 +1869,7 @@
smmu_state->state = ATTACH_SEC_REQ;
smmu_state->transition_type = post_commit ?
POST_COMMIT : PRE_COMMIT;
- ops |= SDE_KMS_OPS_CRTC_SECURE_STATE_CHANGE;
+ ops |= SDE_KMS_OPS_SECURE_STATE_CHANGE;
if (old_valid_fb)
ops |= SDE_KMS_OPS_WAIT_FOR_TX_DONE;
} else if ((smmu_state->state == DETACHED) ||
@@ -1875,16 +1877,19 @@
smmu_state->state = ATTACH_ALL_REQ;
smmu_state->transition_type = post_commit ?
POST_COMMIT : PRE_COMMIT;
- ops |= SDE_KMS_OPS_CRTC_SECURE_STATE_CHANGE;
+ ops |= SDE_KMS_OPS_SECURE_STATE_CHANGE;
if (old_valid_fb)
ops |= (SDE_KMS_OPS_WAIT_FOR_TX_DONE |
SDE_KMS_OPS_CLEANUP_PLANE_FB);
+ if (catalog->sui_misr_supported)
+ smmu_state->sui_misr_state =
+ SUI_MISR_DISABLE_REQ;
}
break;
+
default:
SDE_ERROR("invalid plane fb_mode:%d\n", translation_mode);
- ops = 0;
- return -EINVAL;
+ ops = -EINVAL;
}
SDE_DEBUG("SMMU State:%d, type:%d ops:%x\n", smmu_state->state,
@@ -1894,58 +1899,13 @@
SDE_EVT32(DRMID(crtc), secure_level, translation_mode,
smmu_state->state, smmu_state->transition_type,
ops, old_valid_fb, SDE_EVTLOG_FUNC_EXIT);
+
+ mutex_unlock(&sde_kms->secure_transition_lock);
+
return ops;
}
/**
- * _sde_crtc_scm_call - makes secure channel call to switch the VMIDs
- * @vimd: switch the stage 2 translation to this VMID.
- */
-static int _sde_crtc_scm_call(int vmid)
-{
- struct scm_desc desc = {0};
- uint32_t num_sids;
- uint32_t *sec_sid;
- uint32_t mem_protect_sd_ctrl_id = MEM_PROTECT_SD_CTRL_SWITCH;
- int ret = 0;
-
- /* This info should be queried from catalog */
- num_sids = SEC_SID_CNT;
- sec_sid = kcalloc(num_sids, sizeof(uint32_t), GFP_KERNEL);
- if (!sec_sid)
- return -ENOMEM;
-
- /**
- * derive this info from device tree/catalog, this is combination of
- * smr mask and SID for secure
- */
- sec_sid[0] = SEC_SID_MASK_0;
- sec_sid[1] = SEC_SID_MASK_1;
- dmac_flush_range(sec_sid, sec_sid + num_sids);
-
- SDE_DEBUG("calling scm_call for vmid %d", vmid);
-
- desc.arginfo = SCM_ARGS(4, SCM_VAL, SCM_RW, SCM_VAL, SCM_VAL);
- desc.args[0] = MDP_DEVICE_ID;
- desc.args[1] = SCM_BUFFER_PHYS(sec_sid);
- desc.args[2] = sizeof(uint32_t) * num_sids;
- desc.args[3] = vmid;
-
- ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP,
- mem_protect_sd_ctrl_id), &desc);
- if (ret) {
- SDE_ERROR("Error:scm_call2, vmid (%lld): ret%d\n",
- desc.args[3], ret);
- }
- SDE_EVT32(mem_protect_sd_ctrl_id,
- desc.args[0], desc.args[3], num_sids,
- sec_sid[0], sec_sid[1], ret);
-
- kfree(sec_sid);
- return ret;
-}
-
-/**
* _sde_crtc_setup_scaler3_lut - Set up scaler lut
* LUTs are configured only once during boot
* @sde_crtc: Pointer to sde crtc
@@ -2015,179 +1975,6 @@
sde_fence_timeline_status(&sde_crtc->output_fence, &crtc->base);
}
-static int _sde_crtc_detach_all_cb(struct sde_kms *sde_kms)
-{
- u32 ret = 0;
-
- if (atomic_inc_return(&sde_kms->detach_all_cb) > 1)
- goto end;
-
- /* detach_all_contexts */
- ret = sde_kms_mmu_detach(sde_kms, false);
- if (ret) {
- SDE_ERROR("failed to detach all cb ret:%d\n", ret);
- goto end;
- }
-
- ret = _sde_crtc_scm_call(VMID_CP_SEC_DISPLAY);
- if (ret)
- goto end;
-
-end:
- return ret;
-}
-
-static int _sde_crtc_attach_all_cb(struct sde_kms *sde_kms)
-{
- u32 ret = 0;
-
- if (atomic_dec_return(&sde_kms->detach_all_cb) != 0)
- goto end;
-
- ret = _sde_crtc_scm_call(VMID_CP_PIXEL);
- if (ret)
- goto end;
-
- /* attach_all_contexts */
- ret = sde_kms_mmu_attach(sde_kms, false);
- if (ret) {
- SDE_ERROR("failed to attach all cb ret:%d\n", ret);
- goto end;
- }
-
-end:
- return ret;
-}
-
-static int _sde_crtc_detach_sec_cb(struct sde_kms *sde_kms)
-{
- u32 ret = 0;
-
- if (atomic_inc_return(&sde_kms->detach_sec_cb) > 1)
- goto end;
-
- /* detach secure_context */
- ret = sde_kms_mmu_detach(sde_kms, true);
- if (ret) {
- SDE_ERROR("failed to detach sec cb ret:%d\n", ret);
- goto end;
- }
-
- ret = _sde_crtc_scm_call(VMID_CP_CAMERA_PREVIEW);
- if (ret)
- goto end;
-
-end:
- return ret;
-}
-
-static int _sde_crtc_attach_sec_cb(struct sde_kms *sde_kms)
-{
- u32 ret = 0;
-
- if (atomic_dec_return(&sde_kms->detach_sec_cb) != 0)
- goto end;
-
- ret = _sde_crtc_scm_call(VMID_CP_PIXEL);
- if (ret)
- goto end;
-
- ret = sde_kms_mmu_attach(sde_kms, true);
- if (ret) {
- SDE_ERROR("failed to attach sec cb ret:%d\n", ret);
- goto end;
- }
-
-end:
- return ret;
-}
-
-/**
- * sde_crtc_secure_ctrl - Initiates the operations to swtich between secure
- * and non-secure mode
- * @crtc: Pointer to crtc
- * @post_commit: if this operation is triggered after commit
- */
-int sde_crtc_secure_ctrl(struct drm_crtc *crtc, bool post_commit)
-{
- struct sde_crtc *sde_crtc;
- struct sde_crtc_state *cstate;
- struct sde_kms *sde_kms;
- struct sde_crtc_smmu_state_data *smmu_state;
- int ret = 0;
- int old_smmu_state;
-
- if (!crtc || !crtc->state) {
- SDE_ERROR("invalid crtc\n");
- return -EINVAL;
- }
-
- sde_kms = _sde_crtc_get_kms(crtc);
- if (!sde_kms) {
- SDE_ERROR("invalid kms\n");
- return -EINVAL;
- }
-
- sde_crtc = to_sde_crtc(crtc);
- cstate = to_sde_crtc_state(crtc->state);
- smmu_state = &sde_crtc->smmu_state;
- old_smmu_state = smmu_state->state;
-
- SDE_EVT32(DRMID(crtc), smmu_state->state, smmu_state->transition_type,
- post_commit, SDE_EVTLOG_FUNC_ENTRY);
-
- if ((!smmu_state->transition_type) ||
- ((smmu_state->transition_type == POST_COMMIT) && !post_commit))
- /* Bail out */
- return 0;
-
- mutex_lock(&sde_kms->secure_transition_lock);
- /* Secure UI use case enable */
- switch (smmu_state->state) {
- case DETACH_ALL_REQ:
- ret = _sde_crtc_detach_all_cb(sde_kms);
- if (!ret)
- smmu_state->state = DETACHED;
- break;
- /* Secure UI use case disable */
- case ATTACH_ALL_REQ:
- ret = _sde_crtc_attach_all_cb(sde_kms);
- if (!ret)
- smmu_state->state = ATTACHED;
- break;
- /* Secure preview enable */
- case DETACH_SEC_REQ:
- ret = _sde_crtc_detach_sec_cb(sde_kms);
- if (!ret)
- smmu_state->state = DETACHED_SEC;
- break;
- /* Secure preview disable */
- case ATTACH_SEC_REQ:
- ret = _sde_crtc_attach_sec_cb(sde_kms);
- if (!ret)
- smmu_state->state = ATTACHED;
- break;
- default:
- SDE_ERROR("crtc:%d invalid smmu state:%d transition type:%d\n",
- crtc->base.id, smmu_state->state,
- smmu_state->transition_type);
- break;
- }
- mutex_unlock(&sde_kms->secure_transition_lock);
-
- SDE_DEBUG("crtc: %d, old_state %d new_state %d\n", crtc->base.id,
- old_smmu_state,
- smmu_state->state);
-
- smmu_state->transition_type = NONE;
- smmu_state->transition_error = ret ? true : false;
-
- SDE_EVT32(DRMID(crtc), smmu_state->state, smmu_state->transition_type,
- smmu_state->transition_error, ret,
- SDE_EVTLOG_FUNC_EXIT);
- return ret;
-}
-
static int _sde_validate_hw_resources(struct sde_crtc *sde_crtc)
{
int i;
@@ -2623,7 +2410,6 @@
struct drm_crtc_state *old_state)
{
struct sde_crtc *sde_crtc;
- struct sde_crtc_smmu_state_data *smmu_state;
if (!crtc || !crtc->state) {
SDE_ERROR("invalid crtc\n");
@@ -2632,13 +2418,8 @@
sde_crtc = to_sde_crtc(crtc);
SDE_EVT32_VERBOSE(DRMID(crtc));
- smmu_state = &sde_crtc->smmu_state;
sde_core_perf_crtc_update(crtc, 0, false);
-
- /* complete secure transitions if any */
- if (smmu_state->transition_type == POST_COMMIT)
- sde_crtc_secure_ctrl(crtc, true);
}
/**
@@ -3244,7 +3025,7 @@
struct drm_encoder *encoder;
struct drm_device *dev;
unsigned long flags;
- struct sde_crtc_smmu_state_data *smmu_state;
+ struct sde_kms *sde_kms;
if (!crtc) {
SDE_ERROR("invalid crtc\n");
@@ -3262,11 +3043,14 @@
return;
}
+ sde_kms = _sde_crtc_get_kms(crtc);
+ if (!sde_kms)
+ return;
+
SDE_DEBUG("crtc%d\n", crtc->base.id);
sde_crtc = to_sde_crtc(crtc);
dev = crtc->dev;
- smmu_state = &sde_crtc->smmu_state;
if (!sde_crtc->num_mixers) {
_sde_crtc_setup_mixers(crtc);
@@ -3309,14 +3093,11 @@
/*
* Since CP properties use AXI buffer to program the
- * HW, check if context bank is in attached
- * state,
+ * HW, check if context bank is in attached state,
* apply color processing properties only if
* smmu state is attached,
*/
- if ((smmu_state->state != DETACHED) &&
- (smmu_state->state != DETACH_ALL_REQ) &&
- sde_crtc->enabled)
+ if (!sde_kms_is_secure_session_inprogress(sde_kms))
sde_cp_crtc_apply_properties(crtc);
/*
@@ -3339,6 +3120,7 @@
struct msm_drm_thread *event_thread;
unsigned long flags;
struct sde_crtc_state *cstate;
+ struct sde_kms *sde_kms;
int idle_time = 0;
if (!crtc || !crtc->dev || !crtc->dev->dev_private) {
@@ -3357,6 +3139,12 @@
return;
}
+ sde_kms = _sde_crtc_get_kms(crtc);
+ if (!sde_kms) {
+ SDE_ERROR("invalid kms\n");
+ return;
+ }
+
SDE_DEBUG("crtc%d\n", crtc->base.id);
sde_crtc = to_sde_crtc(crtc);
@@ -3430,7 +3218,7 @@
* everything" call below.
*/
drm_atomic_crtc_for_each_plane(plane, crtc) {
- if (sde_crtc->smmu_state.transition_error)
+ if (sde_kms->smmu_state.transition_error)
sde_plane_set_error(plane, true);
sde_plane_flush(plane);
}
@@ -4578,10 +4366,12 @@
struct drm_crtc_state *state, struct plane_state pstates[],
int cnt)
{
+ struct drm_plane *plane;
struct drm_encoder *encoder;
struct sde_crtc_state *cstate;
struct sde_crtc *sde_crtc;
- struct sde_crtc_smmu_state_data *smmu_state;
+ struct sde_kms *sde_kms;
+ struct sde_kms_smmu_state_data *smmu_state;
uint32_t secure;
uint32_t fb_ns = 0, fb_sec = 0, fb_sec_dir = 0;
int encoder_cnt = 0, i;
@@ -4593,6 +4383,12 @@
return -EINVAL;
}
+ sde_kms = _sde_crtc_get_kms(crtc);
+ if (!sde_kms) {
+ SDE_ERROR("invalid kms\n");
+ return -EINVAL;
+ }
+
cstate = to_sde_crtc_state(state);
secure = sde_crtc_get_property(cstate, CRTC_PROP_SECURITY_LEVEL);
@@ -4616,8 +4412,25 @@
return -EINVAL;
}
- /* only one blending stage is allowed in sec_crtc */
+ /*
+ * - only one blending stage is allowed in sec_crtc
+ * - validate if pipe is allowed for sec-ui updates
+ */
for (i = 1; i < cnt; i++) {
+ if (!pstates[i].drm_pstate
+ || !pstates[i].drm_pstate->plane) {
+ SDE_ERROR("crtc%d: invalid pstate at i:%d\n",
+ crtc->base.id, i);
+ return -EINVAL;
+ }
+ plane = pstates[i].drm_pstate->plane;
+
+ if (!sde_plane_is_sec_ui_allowed(plane)) {
+ SDE_ERROR("crtc%d: sec-ui not allowed in p%d\n",
+ crtc->base.id, plane->base.id);
+ return -EINVAL;
+ }
+
if (pstates[i].stage != pstates[i-1].stage) {
SDE_ERROR(
"crtc%d: invalid blend stages %d:%d, %d:%d\n",
@@ -4654,7 +4467,7 @@
}
sde_crtc = to_sde_crtc(crtc);
- smmu_state = &sde_crtc->smmu_state;
+ smmu_state = &sde_kms->smmu_state;
/*
* In video mode check for null commit before transition
* from secure to non secure and vice versa
@@ -5499,6 +5312,46 @@
return ret;
}
+void sde_crtc_misr_setup(struct drm_crtc *crtc, bool enable, u32 frame_count)
+{
+ struct sde_kms *sde_kms;
+ struct sde_crtc *sde_crtc;
+ struct sde_crtc_mixer *m;
+ int i;
+
+ if (!crtc) {
+ SDE_ERROR("invalid argument\n");
+ return;
+ }
+ sde_crtc = to_sde_crtc(crtc);
+
+ sde_kms = _sde_crtc_get_kms(crtc);
+ if (!sde_kms) {
+ SDE_ERROR("invalid sde_kms\n");
+ return;
+ }
+
+ mutex_lock(&sde_crtc->crtc_lock);
+ if (sde_kms_is_secure_session_inprogress(sde_kms)) {
+ SDE_DEBUG("crtc:%d misr enable/disable not allowed\n",
+ DRMID(crtc));
+ mutex_unlock(&sde_crtc->crtc_lock);
+ return;
+ }
+
+ sde_crtc->misr_enable = enable;
+ sde_crtc->misr_frame_count = frame_count;
+ for (i = 0; i < sde_crtc->num_mixers; ++i) {
+ sde_crtc->misr_data[i] = 0;
+ m = &sde_crtc->mixers[i];
+ if (!m->hw_lm || !m->hw_lm->ops.setup_misr)
+ continue;
+
+ m->hw_lm->ops.setup_misr(m->hw_lm, enable, frame_count);
+ }
+ mutex_unlock(&sde_crtc->crtc_lock);
+}
+
#ifdef CONFIG_DEBUG_FS
static int _sde_debugfs_status_show(struct seq_file *s, void *data)
{
@@ -5646,9 +5499,9 @@
static ssize_t _sde_crtc_misr_setup(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
+ struct drm_crtc *crtc;
struct sde_crtc *sde_crtc;
- struct sde_crtc_mixer *m;
- int i = 0, rc;
+ int rc;
char buf[MISR_BUFF_SIZE + 1];
u32 frame_count, enable;
size_t buff_copy;
@@ -5657,6 +5510,8 @@
return -EINVAL;
sde_crtc = file->private_data;
+ crtc = &sde_crtc->base;
+
buff_copy = min_t(size_t, count, MISR_BUFF_SIZE);
if (copy_from_user(buf, user_buf, buff_copy)) {
SDE_ERROR("buffer copy failed\n");
@@ -5672,18 +5527,7 @@
if (rc)
return rc;
- mutex_lock(&sde_crtc->crtc_lock);
- sde_crtc->misr_enable = enable;
- sde_crtc->misr_frame_count = frame_count;
- for (i = 0; i < sde_crtc->num_mixers; ++i) {
- sde_crtc->misr_data[i] = 0;
- m = &sde_crtc->mixers[i];
- if (!m->hw_lm || !m->hw_lm->ops.setup_misr)
- continue;
-
- m->hw_lm->ops.setup_misr(m->hw_lm, enable, frame_count);
- }
- mutex_unlock(&sde_crtc->crtc_lock);
+ sde_crtc_misr_setup(crtc, enable, frame_count);
_sde_crtc_power_enable(sde_crtc, false);
return count;
@@ -5692,7 +5536,9 @@
static ssize_t _sde_crtc_misr_read(struct file *file,
char __user *user_buff, size_t count, loff_t *ppos)
{
+ struct drm_crtc *crtc;
struct sde_crtc *sde_crtc;
+ struct sde_kms *sde_kms;
struct sde_crtc_mixer *m;
int i = 0, rc;
u32 misr_status;
@@ -5706,11 +5552,21 @@
return -EINVAL;
sde_crtc = file->private_data;
+ crtc = &sde_crtc->base;
+ sde_kms = _sde_crtc_get_kms(crtc);
+ if (!sde_kms)
+ return -EINVAL;
+
rc = _sde_crtc_power_enable(sde_crtc, true);
if (rc)
return rc;
mutex_lock(&sde_crtc->crtc_lock);
+ if (sde_kms_is_secure_session_inprogress(sde_kms)) {
+ SDE_DEBUG("crtc:%d misr read not allowed\n", DRMID(crtc));
+ goto end;
+ }
+
if (!sde_crtc->misr_enable) {
len += snprintf(buf + len, MISR_BUFF_SIZE - len,
"disabled\n");
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h
index 21ce3db..bc1614c 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.h
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.h
@@ -48,50 +48,6 @@
};
/**
- * enum sde_crtc_smmu_state: smmu state
- * @ATTACHED: all the context banks are attached.
- * @DETACHED: all the context banks are detached.
- * @DETACHED_SEC: secure context bank is detached.
- * @ATTACH_ALL_REQ: transient state of attaching context banks.
- * @DETACH_ALL_REQ: transient state of detaching context banks.
- * @DETACH_SEC_REQ: tranisent state of secure context bank is detached
- * @ATTACH_SEC_REQ: transient state of attaching secure context bank.
- */
-enum sde_crtc_smmu_state {
- ATTACHED = 0,
- DETACHED,
- DETACHED_SEC,
- ATTACH_ALL_REQ,
- DETACH_ALL_REQ,
- DETACH_SEC_REQ,
- ATTACH_SEC_REQ,
-};
-
-/**
- * enum sde_crtc_smmu_state_transition_type: state transition type
- * @NONE: no pending state transitions
- * @PRE_COMMIT: state transitions should be done before processing the commit
- * @POST_COMMIT: state transitions to be done after processing the commit.
- */
-enum sde_crtc_smmu_state_transition_type {
- NONE,
- PRE_COMMIT,
- POST_COMMIT
-};
-
-/**
- * struct sde_crtc_smmu_state_data: stores the smmu state and transition type
- * @state: current state of smmu context banks
- * @transition_type: transition request type
- * @transition_error: whether there is error while transitioning the state
- */
-struct sde_crtc_smmu_state_data {
- uint32_t state;
- uint32_t transition_type;
- uint32_t transition_error;
-};
-
-/**
* @connectors : Currently associated drm connectors for retire event
* @num_connectors: Number of associated drm connectors for retire event
* @list: event list
@@ -300,8 +256,6 @@
struct mutex rp_lock;
struct list_head rp_head;
- struct sde_crtc_smmu_state_data smmu_state;
-
/* blob for histogram data */
struct drm_property_blob *hist_blob;
};
@@ -787,4 +741,12 @@
*/
uint64_t sde_crtc_get_sbuf_clk(struct drm_crtc_state *state);
+/**
+ * sde_crtc_misr_setup - to configure and enable/disable MISR
+ * @crtc: Pointer to drm crtc structure
+ * @enable: boolean to indicate enable/disable misr
+ * @frame_count: frame_count to be configured
+ */
+void sde_crtc_misr_setup(struct drm_crtc *crtc, bool enable, u32 frame_count);
+
#endif /* _SDE_CRTC_H_ */
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
index ea39dcd..92c74d8 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
@@ -3276,6 +3276,16 @@
max_vert_deci = max(max_vert_deci,
sde_cfg->sspp[i].sblk->maxvdeciexp);
}
+
+ /*
+ * set sec-ui blocked SSPP feature flag based on blocked
+ * xin-mask if sec-ui-misr feature is enabled;
+ */
+ if (sde_cfg->sui_misr_supported
+ && (sde_cfg->sui_block_xin_mask
+ & BIT(sde_cfg->sspp[i].xin_id)))
+ set_bit(SDE_SSPP_BLOCK_SEC_UI,
+ &sde_cfg->sspp[i].features);
}
/* this should be updated based on HW rev in future */
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h
index 0bb61b3..963b48f 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h
@@ -120,6 +120,7 @@
* @SDE_SSPP_TS_PREFILL Supports prefill with traffic shaper
* @SDE_SSPP_TS_PREFILL_REC1 Supports prefill with traffic shaper multirec
* @SDE_SSPP_CDP Supports client driven prefetch
+ * @SDE_SSPP_BLOCK_SEC_UI Blocks secure-ui layers
* @SDE_SSPP_MAX maximum value
*/
enum {
@@ -143,6 +144,7 @@
SDE_SSPP_TS_PREFILL,
SDE_SSPP_TS_PREFILL_REC1,
SDE_SSPP_CDP,
+ SDE_SSPP_BLOCK_SEC_UI,
SDE_SSPP_MAX
};
@@ -932,6 +934,9 @@
* @wb_formats Supported formats for wb
* @vbif_qos_nlvl number of vbif QoS priority level
* @ts_prefill_rev prefill traffic shaper feature revision
+ * @sui_misr_supported indicate if secure-ui-misr is supported
+ * @sui_block_xin_mask mask of all the xin-clients to be blocked during
+ * secure-ui when secure-ui-misr feature is supported
*/
struct sde_mdss_cfg {
u32 hwversion;
@@ -962,6 +967,9 @@
u32 vbif_qos_nlvl;
u32 ts_prefill_rev;
+ bool sui_misr_supported;
+ u32 sui_block_xin_mask;
+
bool has_hdr;
u32 mdss_count;
struct sde_mdss_base_cfg mdss[MAX_BLOCKS];
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index 979bd2f..ca205c8 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -46,9 +46,19 @@
#include "sde_crtc.h"
#include "sde_reg_dma.h"
+#include <soc/qcom/scm.h>
+#include "soc/qcom/secure_buffer.h"
+
#define CREATE_TRACE_POINTS
#include "sde_trace.h"
+/* defines for secure channel call */
+#define SEC_SID_CNT 2
+#define SEC_SID_MASK_0 0x80881
+#define SEC_SID_MASK_1 0x80C81
+#define MEM_PROTECT_SD_CTRL_SWITCH 0x18
+#define MDP_DEVICE_ID 0x1A
+
static const char * const iommu_ports[] = {
"mdp_0",
};
@@ -402,6 +412,292 @@
}
}
+static int _sde_kms_secure_ctrl_xin_clients(struct sde_kms *sde_kms,
+ struct drm_crtc *crtc, bool enable)
+{
+ struct drm_device *dev;
+ struct msm_drm_private *priv;
+ struct sde_mdss_cfg *sde_cfg;
+ struct drm_plane *plane;
+ int i, ret;
+
+ dev = sde_kms->dev;
+ priv = dev->dev_private;
+ sde_cfg = sde_kms->catalog;
+
+ ret = sde_vbif_halt_xin_mask(sde_kms,
+ sde_cfg->sui_block_xin_mask, enable);
+ if (ret) {
+ SDE_ERROR("failed to halt some xin-clients, ret:%d\n", ret);
+ return ret;
+ }
+
+ if (enable) {
+ for (i = 0; i < priv->num_planes; i++) {
+ plane = priv->planes[i];
+ sde_plane_secure_ctrl_xin_client(plane, crtc);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * _sde_kms_scm_call - makes secure channel call to switch the VMIDs
+ * @vimd: switch the stage 2 translation to this VMID.
+ */
+static int _sde_kms_scm_call(int vmid)
+{
+ struct scm_desc desc = {0};
+ uint32_t num_sids;
+ uint32_t *sec_sid;
+ uint32_t mem_protect_sd_ctrl_id = MEM_PROTECT_SD_CTRL_SWITCH;
+ int ret = 0;
+
+ /* This info should be queried from catalog */
+ num_sids = SEC_SID_CNT;
+ sec_sid = kcalloc(num_sids, sizeof(uint32_t), GFP_KERNEL);
+ if (!sec_sid)
+ return -ENOMEM;
+
+ /*
+ * derive this info from device tree/catalog, this is combination of
+ * smr mask and SID for secure
+ */
+ sec_sid[0] = SEC_SID_MASK_0;
+ sec_sid[1] = SEC_SID_MASK_1;
+ dmac_flush_range(sec_sid, sec_sid + num_sids);
+
+ SDE_DEBUG("calling scm_call for vmid %d", vmid);
+
+ desc.arginfo = SCM_ARGS(4, SCM_VAL, SCM_RW, SCM_VAL, SCM_VAL);
+ desc.args[0] = MDP_DEVICE_ID;
+ desc.args[1] = SCM_BUFFER_PHYS(sec_sid);
+ desc.args[2] = sizeof(uint32_t) * num_sids;
+ desc.args[3] = vmid;
+
+ ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP,
+ mem_protect_sd_ctrl_id), &desc);
+ if (ret)
+ SDE_ERROR("Error:scm_call2, vmid (%lld): ret%d\n",
+ desc.args[3], ret);
+ SDE_EVT32(mem_protect_sd_ctrl_id,
+ desc.args[0], desc.args[3], num_sids,
+ sec_sid[0], sec_sid[1], ret);
+
+ kfree(sec_sid);
+ return ret;
+}
+
+static int _sde_kms_detach_all_cb(struct sde_kms *sde_kms)
+{
+ u32 ret = 0;
+
+ if (atomic_inc_return(&sde_kms->detach_all_cb) > 1)
+ goto end;
+
+ /* detach_all_contexts */
+ ret = sde_kms_mmu_detach(sde_kms, false);
+ if (ret) {
+ SDE_ERROR("failed to detach all cb ret:%d\n", ret);
+ goto end;
+ }
+
+ ret = _sde_kms_scm_call(VMID_CP_SEC_DISPLAY);
+ if (ret)
+ goto end;
+
+end:
+ return ret;
+}
+
+static int _sde_kms_attach_all_cb(struct sde_kms *sde_kms)
+{
+ u32 ret = 0;
+
+ if (atomic_dec_return(&sde_kms->detach_all_cb) != 0)
+ goto end;
+
+ ret = _sde_kms_scm_call(VMID_CP_PIXEL);
+ if (ret)
+ goto end;
+
+ /* attach_all_contexts */
+ ret = sde_kms_mmu_attach(sde_kms, false);
+ if (ret) {
+ SDE_ERROR("failed to attach all cb ret:%d\n", ret);
+ goto end;
+ }
+
+end:
+ return ret;
+}
+
+static int _sde_kms_detach_sec_cb(struct sde_kms *sde_kms)
+{
+ u32 ret = 0;
+
+ if (atomic_inc_return(&sde_kms->detach_sec_cb) > 1)
+ goto end;
+
+ /* detach secure_context */
+ ret = sde_kms_mmu_detach(sde_kms, true);
+ if (ret) {
+ SDE_ERROR("failed to detach sec cb ret:%d\n", ret);
+ goto end;
+ }
+
+ ret = _sde_kms_scm_call(VMID_CP_CAMERA_PREVIEW);
+ if (ret)
+ goto end;
+
+end:
+ return ret;
+}
+
+static int _sde_kms_attach_sec_cb(struct sde_kms *sde_kms)
+{
+ u32 ret = 0;
+
+ if (atomic_dec_return(&sde_kms->detach_sec_cb) != 0)
+ goto end;
+
+ ret = _sde_kms_scm_call(VMID_CP_PIXEL);
+ if (ret)
+ goto end;
+
+ ret = sde_kms_mmu_attach(sde_kms, true);
+ if (ret) {
+ SDE_ERROR("failed to attach sec cb ret:%d\n", ret);
+ goto end;
+ }
+
+end:
+ return ret;
+}
+
+static int _sde_kms_sui_misr_ctrl(struct sde_kms *sde_kms,
+ struct drm_crtc *crtc, bool enable)
+{
+ struct drm_device *dev = sde_kms->dev;
+ struct msm_drm_private *priv = dev->dev_private;
+ int ret;
+
+ if (enable) {
+ ret = sde_power_resource_enable(&priv->phandle,
+ sde_kms->core_client, true);
+ if (ret) {
+ SDE_ERROR("failed to enable resource, ret:%d\n", ret);
+ return ret;
+ }
+
+ sde_crtc_misr_setup(crtc, true, 1);
+
+ ret = _sde_kms_secure_ctrl_xin_clients(sde_kms, crtc, true);
+ if (ret) {
+ sde_power_resource_enable(&priv->phandle,
+ sde_kms->core_client, false);
+ return ret;
+ }
+
+ } else {
+ _sde_kms_secure_ctrl_xin_clients(sde_kms, crtc, false);
+ sde_crtc_misr_setup(crtc, false, 0);
+ sde_power_resource_enable(&priv->phandle,
+ sde_kms->core_client, false);
+ }
+
+ return 0;
+}
+
+static int _sde_kms_secure_ctrl(struct sde_kms *sde_kms, struct drm_crtc *crtc,
+ bool post_commit)
+{
+ struct sde_kms_smmu_state_data *smmu_state = &sde_kms->smmu_state;
+ int old_smmu_state = smmu_state->state;
+ int ret = 0;
+
+ if (!sde_kms || !crtc) {
+ SDE_ERROR("invalid argument(s)\n");
+ return -EINVAL;
+ }
+
+ SDE_EVT32(DRMID(crtc), smmu_state->state, smmu_state->transition_type,
+ post_commit, smmu_state->sui_misr_state,
+ SDE_EVTLOG_FUNC_ENTRY);
+
+ if ((!smmu_state->transition_type) ||
+ ((smmu_state->transition_type == POST_COMMIT) && !post_commit))
+ /* Bail out */
+ return 0;
+
+ /* enable sui misr if requested, before the transition */
+ if (smmu_state->sui_misr_state == SUI_MISR_ENABLE_REQ) {
+ ret = _sde_kms_sui_misr_ctrl(sde_kms, crtc, true);
+ if (ret)
+ goto end;
+ }
+
+ mutex_lock(&sde_kms->secure_transition_lock);
+ switch (smmu_state->state) {
+ /* Secure UI use case enable */
+ case DETACH_ALL_REQ:
+ ret = _sde_kms_detach_all_cb(sde_kms);
+ if (!ret)
+ smmu_state->state = DETACHED;
+ break;
+
+ /* Secure UI use case disable */
+ case ATTACH_ALL_REQ:
+ ret = _sde_kms_attach_all_cb(sde_kms);
+ if (!ret)
+ smmu_state->state = ATTACHED;
+ break;
+
+ /* Secure preview enable */
+ case DETACH_SEC_REQ:
+ ret = _sde_kms_detach_sec_cb(sde_kms);
+ if (!ret)
+ smmu_state->state = DETACHED_SEC;
+ break;
+
+ /* Secure preview disable */
+ case ATTACH_SEC_REQ:
+ ret = _sde_kms_attach_sec_cb(sde_kms);
+ if (!ret)
+ smmu_state->state = ATTACHED;
+ break;
+
+ default:
+ SDE_ERROR("crtc:%d invalid smmu state:%d transition type:%d\n",
+ DRMID(crtc), smmu_state->state,
+ smmu_state->transition_type);
+ ret = -EINVAL;
+ break;
+ }
+ mutex_unlock(&sde_kms->secure_transition_lock);
+
+ /* disable sui misr if requested, after the transition */
+ if (!ret && (smmu_state->sui_misr_state == SUI_MISR_DISABLE_REQ)) {
+ ret = _sde_kms_sui_misr_ctrl(sde_kms, crtc, false);
+ if (ret)
+ goto end;
+ }
+
+end:
+ smmu_state->sui_misr_state = NONE;
+ smmu_state->transition_type = NONE;
+ smmu_state->transition_error = ret ? true : false;
+
+ SDE_DEBUG("crtc:%d, old_state %d new_state %d, ret %d\n",
+ DRMID(crtc), old_smmu_state, smmu_state->state, ret);
+ SDE_EVT32(DRMID(crtc), smmu_state->state, smmu_state->transition_type,
+ smmu_state->transition_error, ret,
+ SDE_EVTLOG_FUNC_EXIT);
+
+ return ret;
+}
+
static int sde_kms_prepare_secure_transition(struct msm_kms *kms,
struct drm_atomic_state *state)
{
@@ -466,9 +762,9 @@
SDE_DEBUG("cleanup planes\n");
drm_atomic_helper_cleanup_planes(dev, state);
}
- if (ops & SDE_KMS_OPS_CRTC_SECURE_STATE_CHANGE) {
+ if (ops & SDE_KMS_OPS_SECURE_STATE_CHANGE) {
SDE_DEBUG("secure ctrl\n");
- sde_crtc_secure_ctrl(crtc, false);
+ _sde_kms_secure_ctrl(sde_kms, crtc, false);
}
if (ops & SDE_KMS_OPS_PREPARE_PLANE_FB) {
SDE_DEBUG("prepare planes %d",
@@ -674,9 +970,14 @@
return;
}
- for_each_crtc_in_state(old_state, crtc, old_crtc_state, i)
+ for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
sde_crtc_complete_commit(crtc, old_crtc_state);
+ /* complete secure transitions if any */
+ if (sde_kms->smmu_state.transition_type == POST_COMMIT)
+ _sde_kms_secure_ctrl(sde_kms, crtc, true);
+ }
+
for_each_connector_in_state(old_state, connector, old_conn_state, i) {
struct sde_connector *c_conn;
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h
index 93691e8..ad6d279 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.h
+++ b/drivers/gpu/drm/msm/sde/sde_kms.h
@@ -105,14 +105,71 @@
#define MAX_ALLOWED_ENCODER_CNT_PER_SECURE_CRTC 1
/* defines the operations required for secure state transition */
-#define SDE_KMS_OPS_CRTC_SECURE_STATE_CHANGE BIT(0)
-#define SDE_KMS_OPS_WAIT_FOR_TX_DONE BIT(1)
-#define SDE_KMS_OPS_CLEANUP_PLANE_FB BIT(2)
-#define SDE_KMS_OPS_PREPARE_PLANE_FB BIT(3)
+#define SDE_KMS_OPS_SECURE_STATE_CHANGE BIT(0)
+#define SDE_KMS_OPS_WAIT_FOR_TX_DONE BIT(1)
+#define SDE_KMS_OPS_CLEANUP_PLANE_FB BIT(2)
+#define SDE_KMS_OPS_PREPARE_PLANE_FB BIT(3)
/* ESD status check interval in miliseconds */
#define STATUS_CHECK_INTERVAL_MS 5000
+/**
+ * enum sde_kms_smmu_state: smmu state
+ * @ATTACHED: all the context banks are attached.
+ * @DETACHED: all the context banks are detached.
+ * @DETACHED_SEC: secure context bank is detached.
+ * @ATTACH_ALL_REQ: transient state of attaching context banks.
+ * @DETACH_ALL_REQ: transient state of detaching context banks.
+ * @DETACH_SEC_REQ: tranisent state of secure context bank is detached
+ * @ATTACH_SEC_REQ: transient state of attaching secure context bank.
+ */
+enum sde_kms_smmu_state {
+ ATTACHED = 0,
+ DETACHED,
+ DETACHED_SEC,
+ ATTACH_ALL_REQ,
+ DETACH_ALL_REQ,
+ DETACH_SEC_REQ,
+ ATTACH_SEC_REQ,
+};
+
+/**
+ * enum sde_kms_smmu_state_transition_type: state transition type
+ * @NONE: no pending state transitions
+ * @PRE_COMMIT: state transitions should be done before processing the commit
+ * @POST_COMMIT: state transitions to be done after processing the commit.
+ */
+enum sde_kms_smmu_state_transition_type {
+ NONE,
+ PRE_COMMIT,
+ POST_COMMIT
+};
+
+/**
+ * enum sde_kms_sui_misr_state: state request for enabling/disabling MISR
+ * @NONE: no request
+ * @ENABLE_SUI_MISR_REQ: request to enable sui MISR
+ * @DISABLE_SUI_MISR_REQ: request to disable sui MISR
+ */
+enum sde_kms_sui_misr_state {
+ SUI_MISR_NONE,
+ SUI_MISR_ENABLE_REQ,
+ SUI_MISR_DISABLE_REQ
+};
+
+/**
+ * struct sde_kms_smmu_state_data: stores the smmu state and transition type
+ * @state: current state of smmu context banks
+ * @transition_type: transition request type
+ * @transition_error: whether there is error while transitioning the state
+ */
+struct sde_kms_smmu_state_data {
+ uint32_t state;
+ uint32_t transition_type;
+ uint32_t transition_error;
+ uint32_t sui_misr_state;
+};
+
/*
* struct sde_irq_callback - IRQ callback handlers
* @list: list to callback
@@ -227,6 +284,7 @@
bool has_danger_ctrl;
+ struct sde_kms_smmu_state_data smmu_state;
atomic_t detach_sec_cb;
atomic_t detach_all_cb;
struct mutex secure_transition_lock;
@@ -291,6 +349,48 @@
}
/**
+ * sde_kms_is_secure_session_inprogress - to indicate if secure-session is in
+ * currently in-progress based on the current smmu_state
+ *
+ * @sde_kms: Pointer to sde_kms
+ *
+ * return: true if secure-session is in progress; false otherwise
+ */
+static inline bool sde_kms_is_secure_session_inprogress(struct sde_kms *sde_kms)
+{
+ bool ret = false;
+
+ if (!sde_kms)
+ return false;
+
+ mutex_lock(&sde_kms->secure_transition_lock);
+ if (sde_kms->smmu_state.state == DETACHED)
+ ret = true;
+ mutex_unlock(&sde_kms->secure_transition_lock);
+
+ return ret;
+}
+
+/**
+ * sde_kms_is_vbif_operation_allowed - resticts the VBIF programming
+ * during secure-ui, if the sec_ui_misr feature is enabled
+ *
+ * @sde_kms: Pointer to sde_kms
+ *
+ * return: false if secure-session is in progress; true otherwise
+ */
+static inline bool sde_kms_is_vbif_operation_allowed(struct sde_kms *sde_kms)
+{
+ if (!sde_kms)
+ return false;
+
+ if (!sde_kms->catalog->sui_misr_supported)
+ return true;
+
+ return !sde_kms_is_secure_session_inprogress(sde_kms);
+}
+
+/**
* Debugfs functions - extra helper functions for debugfs support
*
* Main debugfs documentation is located at,
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c
index 4c281666..2e46599 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.c
+++ b/drivers/gpu/drm/msm/sde/sde_plane.c
@@ -204,6 +204,18 @@
state->crtc->state->enable;
}
+bool sde_plane_is_sec_ui_allowed(struct drm_plane *plane)
+{
+ struct sde_plane *psde;
+
+ if (!plane)
+ return false;
+
+ psde = to_sde_plane(plane);
+
+ return !(psde->features & BIT(SDE_SSPP_BLOCK_SEC_UI));
+}
+
/**
* _sde_plane_calc_fill_level - calculate fill level of the given source format
* @plane: Pointer to drm plane
@@ -2565,6 +2577,25 @@
psde->xin_halt_forced_clk, enable);
}
+void sde_plane_secure_ctrl_xin_client(struct drm_plane *plane,
+ struct drm_crtc *crtc)
+{
+ struct sde_plane *psde;
+
+ if (!plane || !crtc) {
+ SDE_ERROR("invalid plane/crtc\n");
+ return;
+ }
+ psde = to_sde_plane(plane);
+
+ if (psde->features & BIT(SDE_SSPP_BLOCK_SEC_UI))
+ return;
+
+ /* do all VBIF programming for the sec-ui allowed SSPP */
+ _sde_plane_set_qos_remap(plane);
+ _sde_plane_set_ot_limit(plane, crtc);
+}
+
int sde_plane_reset_rot(struct drm_plane *plane, struct drm_plane_state *state)
{
struct sde_plane *psde;
@@ -4370,6 +4401,8 @@
psde->pipe_sblk->maxvdeciexp);
sde_kms_info_add_keyint(info, "max_per_pipe_bw",
psde->pipe_sblk->max_per_pipe_bw * 1000LL);
+ if (psde->features & BIT(SDE_SSPP_BLOCK_SEC_UI))
+ sde_kms_info_add_keyint(info, "block_sec_ui", 1);
msm_property_set_blob(&psde->property_info, &psde->blob_info,
info->data, SDE_KMS_INFO_DATALEN(info),
PLANE_PROP_INFO);
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.h b/drivers/gpu/drm/msm/sde/sde_plane.h
index ad58097..f924aa6 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.h
+++ b/drivers/gpu/drm/msm/sde/sde_plane.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -334,4 +334,20 @@
int sde_plane_helper_reset_custom_properties(struct drm_plane *plane,
struct drm_plane_state *plane_state);
+/**
+ * sde_plane_is_sec_ui_allowed - indicates if the sspp allows secure-ui layers
+ * @plane: Pointer to DRM plane object
+ * Returns: true if allowed; false otherwise
+ */
+bool sde_plane_is_sec_ui_allowed(struct drm_plane *plane);
+
+/* sde_plane_secure_ctrl_xin_client - controls the VBIF programming of
+ * the xin-client before the secure-ui session. Programs the QOS
+ * and OT limits in VBIF for the sec-ui allowed xins
+ * @plane: Pointer to DRM plane object
+ * @crtc: Pointer to DRM CRTC state object
+ */
+void sde_plane_secure_ctrl_xin_client(struct drm_plane *plane,
+ struct drm_crtc *crtc);
+
#endif /* _SDE_PLANE_H_ */
diff --git a/drivers/gpu/drm/msm/sde/sde_vbif.c b/drivers/gpu/drm/msm/sde/sde_vbif.c
index c19ee82..33a60f9 100644
--- a/drivers/gpu/drm/msm/sde/sde_vbif.c
+++ b/drivers/gpu/drm/msm/sde/sde_vbif.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, 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
@@ -18,6 +18,8 @@
#include "sde_hw_vbif.h"
#include "sde_trace.h"
+#define MAX_XIN_CLIENT 16
+
/**
* _sde_vbif_wait_for_xin_halt - wait for the xin to halt
* @vbif: Pointer to hardware vbif driver
@@ -73,6 +75,11 @@
return -EINVAL;
}
+ if (!sde_kms_is_vbif_operation_allowed(sde_kms)) {
+ SDE_DEBUG("vbif operations not permitted\n");
+ return 0;
+ }
+
vbif = sde_kms->hw_vbif[VBIF_RT];
mdp = sde_kms->hw_mdp;
if (!vbif || !mdp || !vbif->ops.get_halt_ctrl ||
@@ -225,6 +232,12 @@
SDE_ERROR("invalid arguments\n");
return;
}
+
+ if (!sde_kms_is_vbif_operation_allowed(sde_kms)) {
+ SDE_DEBUG("vbif operations not permitted\n");
+ return;
+ }
+
mdp = sde_kms->hw_mdp;
for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) {
@@ -293,6 +306,12 @@
SDE_ERROR("invalid arguments\n");
return false;
}
+
+ if (!sde_kms_is_vbif_operation_allowed(sde_kms)) {
+ SDE_DEBUG("vbif operations not permitted\n");
+ return true;
+ }
+
mdp = sde_kms->hw_mdp;
for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) {
@@ -352,6 +371,12 @@
SDE_ERROR("invalid arguments\n");
return;
}
+
+ if (!sde_kms_is_vbif_operation_allowed(sde_kms)) {
+ SDE_DEBUG("vbif operations not permitted\n");
+ return;
+ }
+
mdp = sde_kms->hw_mdp;
for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) {
@@ -408,6 +433,11 @@
return;
}
+ if (!sde_kms_is_vbif_operation_allowed(sde_kms)) {
+ SDE_DEBUG("vbif operations not permitted\n");
+ return;
+ }
+
for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) {
vbif = sde_kms->hw_vbif[i];
if (vbif && vbif->ops.clear_errors) {
@@ -433,6 +463,11 @@
return;
}
+ if (!sde_kms_is_vbif_operation_allowed(sde_kms)) {
+ SDE_DEBUG("vbif operations not permitted\n");
+ return;
+ }
+
for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) {
vbif = sde_kms->hw_vbif[i];
if (vbif && vbif->cap && vbif->ops.set_mem_type) {
@@ -445,6 +480,52 @@
}
}
+int sde_vbif_halt_xin_mask(struct sde_kms *sde_kms, u32 xin_id_mask,
+ bool halt)
+{
+ struct sde_hw_vbif *vbif;
+ int i = 0, status, rc;
+
+ if (!sde_kms) {
+ SDE_ERROR("invalid argument\n");
+ return -EINVAL;
+ }
+
+ vbif = sde_kms->hw_vbif[VBIF_RT];
+
+ if (!vbif->ops.get_halt_ctrl || !vbif->ops.set_halt_ctrl)
+ return 0;
+
+ SDE_EVT32(xin_id_mask, halt);
+
+ for (i = 0; i < MAX_XIN_CLIENT; i++) {
+ if (xin_id_mask & BIT(i)) {
+ /* unhalt the xin-clients */
+ if (!halt) {
+ vbif->ops.set_halt_ctrl(vbif, i, false);
+ continue;
+ }
+
+ status = vbif->ops.get_halt_ctrl(vbif, i);
+ if (status)
+ continue;
+
+ /* halt xin-clients and wait for ack */
+ vbif->ops.set_halt_ctrl(vbif, i, true);
+
+ rc = _sde_vbif_wait_for_xin_halt(vbif, i);
+ if (rc) {
+ SDE_ERROR("xin_halt failed for xin:%d, rc:%d\n",
+ i, rc);
+ SDE_EVT32(xin_id_mask, i, rc, SDE_EVTLOG_ERROR);
+ return rc;
+ }
+ }
+ }
+
+ return 0;
+}
+
#ifdef CONFIG_DEBUG_FS
void sde_debugfs_vbif_destroy(struct sde_kms *sde_kms)
{
diff --git a/drivers/gpu/drm/msm/sde/sde_vbif.h b/drivers/gpu/drm/msm/sde/sde_vbif.h
index 0edc1a6..1d12fd7 100644
--- a/drivers/gpu/drm/msm/sde/sde_vbif.h
+++ b/drivers/gpu/drm/msm/sde/sde_vbif.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, 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
@@ -119,6 +119,15 @@
int sde_vbif_halt_plane_xin(struct sde_kms *sde_kms, u32 xin_id,
u32 clk_ctrl);
+/**
+ * sde_vbif_halt_xin_mask - halts/unhalts all the xin clients present in
+ * the mask.
+ * @sde_kms: SDE handler
+ * @xin_id_mask: Mask of all the xin-ids to be halted/unhalted
+ * halt: boolen to indicate halt/unhalt
+ */
+int sde_vbif_halt_xin_mask(struct sde_kms *sde_kms, u32 xin_id_mask, bool halt);
+
#ifdef CONFIG_DEBUG_FS
int sde_debugfs_vbif_init(struct sde_kms *sde_kms, struct dentry *debugfs_root);
void sde_debugfs_vbif_destroy(struct sde_kms *sde_kms);
diff --git a/drivers/gpu/msm/a6xx_reg.h b/drivers/gpu/msm/a6xx_reg.h
index fef45ec..ef0d7f1 100644
--- a/drivers/gpu/msm/a6xx_reg.h
+++ b/drivers/gpu/msm/a6xx_reg.h
@@ -923,6 +923,7 @@
#define A6XX_GMU_SYS_BUS_CONFIG 0x1F40F
#define A6XX_GMU_CM3_SYSRESET 0x1F800
#define A6XX_GMU_CM3_BOOT_CONFIG 0x1F801
+#define A6XX_GMU_CX_GMU_WFI_CONFIG 0x1F802
#define A6XX_GMU_CM3_FW_BUSY 0x1F81A
#define A6XX_GMU_CM3_FW_INIT_RESULT 0x1F81C
#define A6XX_GMU_CM3_CFG 0x1F82D
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 7f7c04e..763dc18 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -2525,7 +2525,39 @@
context->pwr_constraint.sub_type);
context->pwr_constraint.type = KGSL_CONSTRAINT_NONE;
break;
+ case KGSL_CONSTRAINT_L3_PWRLEVEL: {
+ struct kgsl_device_constraint_pwrlevel pwr;
+ if (constraint->size != sizeof(pwr)) {
+ status = -EINVAL;
+ break;
+ }
+
+ if (copy_from_user(&pwr, (void __user *)constraint->data,
+ sizeof(pwr))) {
+ status = -EFAULT;
+ break;
+ }
+ if (pwr.level >= KGSL_CONSTRAINT_PWR_MAXLEVELS)
+ pwr.level = KGSL_CONSTRAINT_PWR_MAXLEVELS-1;
+
+ context->l3_pwr_constraint.type = KGSL_CONSTRAINT_L3_PWRLEVEL;
+ context->l3_pwr_constraint.sub_type = pwr.level;
+ trace_kgsl_user_pwrlevel_constraint(device, context->id,
+ context->l3_pwr_constraint.type,
+ context->l3_pwr_constraint.sub_type);
+ }
+ break;
+ case KGSL_CONSTRAINT_L3_NONE: {
+ unsigned int type = context->l3_pwr_constraint.type;
+
+ if (type == KGSL_CONSTRAINT_L3_PWRLEVEL)
+ trace_kgsl_user_pwrlevel_constraint(device, context->id,
+ KGSL_CONSTRAINT_L3_NONE,
+ context->l3_pwr_constraint.sub_type);
+ context->l3_pwr_constraint.type = KGSL_CONSTRAINT_L3_NONE;
+ }
+ break;
default:
status = -EINVAL;
break;
@@ -2607,7 +2639,27 @@
status = adreno_set_constraint(device, context,
&constraint);
+ kgsl_context_put(context);
+ }
+ break;
+ case KGSL_PROP_L3_PWR_CONSTRAINT: {
+ struct kgsl_device_constraint constraint;
+ struct kgsl_context *context;
+ if (sizebytes != sizeof(constraint))
+ break;
+ if (copy_from_user(&constraint, value,
+ sizeof(constraint))) {
+ status = -EFAULT;
+ break;
+ }
+ context = kgsl_context_get_owner(dev_priv,
+ constraint.context_id);
+
+ if (context == NULL)
+ break;
+ status = adreno_set_constraint(device, context,
+ &constraint);
kgsl_context_put(context);
}
break;
diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c
index 1250437..daf314d 100644
--- a/drivers/gpu/msm/adreno_a6xx.c
+++ b/drivers/gpu/msm/adreno_a6xx.c
@@ -511,7 +511,7 @@
if (adreno_is_a615(adreno_dev))
return 0x00000222;
else
- return 0x00020222;
+ return 0x00020202;
}
static inline unsigned int
@@ -1390,6 +1390,7 @@
{
struct gmu_device *gmu = &device->gmu;
+ kgsl_regwrite(device, A6XX_GMU_CX_GMU_WFI_CONFIG, 0x0);
/* Write 1 first to make sure the GMU is reset */
kgsl_gmu_regwrite(device, A6XX_GMU_CM3_SYSRESET, 1);
diff --git a/drivers/gpu/msm/adreno_compat.c b/drivers/gpu/msm/adreno_compat.c
index 5a8d587..1f806da 100644
--- a/drivers/gpu/msm/adreno_compat.c
+++ b/drivers/gpu/msm/adreno_compat.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, 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
@@ -187,6 +187,37 @@
kgsl_context_put(context);
}
break;
+ case KGSL_PROP_L3_PWR_CONSTRAINT: {
+ struct kgsl_device_constraint_compat constraint32;
+ struct kgsl_device_constraint constraint;
+ struct kgsl_context *context;
+
+ if (sizebytes != sizeof(constraint32))
+ break;
+
+ if (copy_from_user(&constraint32, value,
+ sizeof(constraint32))) {
+ status = -EFAULT;
+ break;
+ }
+
+ constraint.type = constraint32.type;
+ constraint.context_id = constraint32.context_id;
+ constraint.data = compat_ptr(constraint32.data);
+ constraint.size = (size_t)constraint32.size;
+
+ context = kgsl_context_get_owner(dev_priv,
+ constraint.context_id);
+
+ if (context == NULL)
+ break;
+
+ status = adreno_set_constraint(device, context,
+ &constraint);
+ kgsl_context_put(context);
+
+ }
+ break;
default:
/*
* Call adreno_setproperty in case the property type was
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 1faad93..df93606 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -762,10 +762,55 @@
sizedwords, 0, NULL);
}
+static int
+l3_pwrlevel_probe(struct kgsl_device *device, struct device_node *node)
+{
+
+ struct device_node *pwrlevel_node, *child;
+
+ pwrlevel_node = of_find_node_by_name(node, "qcom,l3-pwrlevels");
+
+ if (pwrlevel_node == NULL) {
+ dev_err_once(&device->pdev->dev, "Unable to find 'qcom,l3-pwrlevels'\n");
+ return -EINVAL;
+ }
+
+ device->num_l3_pwrlevels = 0;
+
+ for_each_child_of_node(pwrlevel_node, child) {
+ unsigned int index;
+
+ if (of_property_read_u32(child, "reg", &index))
+ return -EINVAL;
+ if (index >= MAX_L3_LEVELS) {
+ dev_err(&device->pdev->dev, "L3 pwrlevel %d is out of range\n",
+ index);
+ continue;
+ }
+
+ if (index >= device->num_l3_pwrlevels)
+ device->num_l3_pwrlevels = index + 1;
+
+ if (of_property_read_u32(child, "qcom,l3-freq",
+ &device->l3_freq[index]))
+ return -EINVAL;
+
+ }
+
+ return 0;
+
+}
+
static void adreno_ringbuffer_set_constraint(struct kgsl_device *device,
struct kgsl_drawobj *drawobj)
{
struct kgsl_context *context = drawobj->context;
+ struct device *dev = &device->pdev->dev;
+ unsigned long flags = drawobj->flags;
+ struct device_node *node;
+
+ node = device->pdev->dev.of_node;
+
/*
* Check if the context has a constraint and constraint flags are
* set.
@@ -775,6 +820,45 @@
(drawobj->flags & KGSL_CONTEXT_PWR_CONSTRAINT)))
kgsl_pwrctrl_set_constraint(device, &context->pwr_constraint,
context->id);
+
+ if (IS_ERR_OR_NULL(device->l3_clk))
+ device->l3_clk = devm_clk_get(dev, "l3_vote");
+
+ if (IS_ERR_OR_NULL(device->l3_clk)) {
+ KGSL_DEV_ERR_ONCE(device, "Unable to get the l3_vote clock. Cannot set the L3 constraint\n");
+ return;
+ }
+
+ if (context->l3_pwr_constraint.type &&
+ ((context->flags & KGSL_CONTEXT_PWR_CONSTRAINT) ||
+ (flags & KGSL_CONTEXT_PWR_CONSTRAINT))) {
+
+ int ret = l3_pwrlevel_probe(device, node);
+
+ if (ret)
+ return;
+
+ switch (context->l3_pwr_constraint.type) {
+
+ case KGSL_CONSTRAINT_L3_PWRLEVEL: {
+ unsigned int sub_type;
+
+ sub_type = context->l3_pwr_constraint.sub_type;
+
+ if (sub_type == KGSL_CONSTRAINT_L3_PWR_MED)
+ clk_set_rate(device->l3_clk,
+ device->l3_freq[1]);
+
+ if (sub_type == KGSL_CONSTRAINT_L3_PWR_MAX)
+ clk_set_rate(device->l3_clk,
+ device->l3_freq[2]);
+ }
+ break;
+ case KGSL_CONSTRAINT_L3_NONE:
+ clk_set_rate(device->l3_clk, device->l3_freq[0]);
+ break;
+ }
+ }
}
static inline int _get_alwayson_counter(struct adreno_device *adreno_dev,
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 41d1a38..c737801 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -104,6 +104,7 @@
/* Allocate 600K for the snapshot static region*/
#define KGSL_SNAPSHOT_MEMSIZE (600 * 1024)
+#define MAX_L3_LEVELS 3
struct kgsl_device;
struct platform_device;
@@ -332,6 +333,9 @@
/* Number of active contexts seen globally for this device */
int active_context_count;
struct kobject *gpu_sysfs_kobj;
+ struct clk *l3_clk;
+ unsigned int l3_freq[MAX_L3_LEVELS];
+ unsigned int num_l3_pwrlevels;
};
#define KGSL_MMU_DEVICE(_mmu) \
@@ -410,6 +414,7 @@
struct kgsl_event_group events;
unsigned int flags;
struct kgsl_pwr_constraint pwr_constraint;
+ struct kgsl_pwr_constraint l3_pwr_constraint;
unsigned int fault_count;
unsigned long fault_time;
struct kgsl_mem_entry *user_ctxt_record;
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 1baf20e..ee9e5df 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -2602,6 +2602,9 @@
static void kgsl_pwrctrl_disable(struct kgsl_device *device)
{
+ if (!IS_ERR_OR_NULL(device->l3_clk))
+ clk_set_rate(device->l3_clk, 0);
+
if (kgsl_gmu_isenabled(device)) {
kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF);
return gmu_stop(device);
diff --git a/drivers/hwmon/qpnp-adc-voltage.c b/drivers/hwmon/qpnp-adc-voltage.c
index 88b879c..59ca208 100644
--- a/drivers/hwmon/qpnp-adc-voltage.c
+++ b/drivers/hwmon/qpnp-adc-voltage.c
@@ -35,6 +35,8 @@
#include <linux/power_supply.h>
#include <linux/thermal.h>
+#define QPNP_VADC_HC_VREF_CODE 0x4000
+
/* QPNP VADC register definition */
#define QPNP_VADC_REVISION1 0x0
#define QPNP_VADC_REVISION2 0x1
@@ -558,13 +560,15 @@
goto fail_unlock;
}
- if (!vadc->vadc_init_calib) {
- rc = qpnp_vadc_calib_device(vadc);
- if (rc) {
- pr_err("Calibration failed\n");
- goto fail_unlock;
- } else {
- vadc->vadc_init_calib = true;
+ if (vadc->adc->adc_prop->full_scale_code == QPNP_VADC_HC_VREF_CODE) {
+ if (!vadc->vadc_init_calib) {
+ rc = qpnp_vadc_calib_device(vadc);
+ if (rc) {
+ pr_err("Calibration failed\n");
+ goto fail_unlock;
+ } else {
+ vadc->vadc_init_calib = true;
+ }
}
}
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index fc949fe..40d4a2c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -2481,22 +2481,16 @@
}
static void arm_smmu_prealloc_memory(struct arm_smmu_domain *smmu_domain,
- struct scatterlist *sgl, int nents,
- struct list_head *pool)
+ size_t size, struct list_head *pool)
{
- u32 nr = 0;
int i;
- size_t size = 0;
- struct scatterlist *sg;
+ u32 nr = 0;
struct page *page;
if ((smmu_domain->attributes & (1 << DOMAIN_ATTR_ATOMIC)) ||
arm_smmu_has_secure_vmid(smmu_domain))
return;
- for_each_sg(sgl, sg, nents, i)
- size += sg->length;
-
/* number of 2nd level pagetable entries */
nr += round_up(size, SZ_1G) >> 30;
/* number of 3rd level pagetabel entries */
@@ -2511,16 +2505,32 @@
}
}
+static void arm_smmu_prealloc_memory_sg(struct arm_smmu_domain *smmu_domain,
+ struct scatterlist *sgl, int nents,
+ struct list_head *pool)
+{
+ int i;
+ size_t size = 0;
+ struct scatterlist *sg;
+
+ if ((smmu_domain->attributes & (1 << DOMAIN_ATTR_ATOMIC)) ||
+ arm_smmu_has_secure_vmid(smmu_domain))
+ return;
+
+ for_each_sg(sgl, sg, nents, i)
+ size += sg->length;
+
+ arm_smmu_prealloc_memory(smmu_domain, size, pool);
+}
+
static void arm_smmu_release_prealloc_memory(
struct arm_smmu_domain *smmu_domain, struct list_head *list)
{
struct page *page, *tmp;
- u32 remaining = 0;
list_for_each_entry_safe(page, tmp, list, lru) {
list_del(&page->lru);
__free_pages(page, 0);
- remaining++;
}
}
@@ -2602,6 +2612,7 @@
unsigned long flags;
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops;
+ LIST_HEAD(nonsecure_pool);
if (!ops)
return -ENODEV;
@@ -2609,15 +2620,19 @@
if (arm_smmu_is_slave_side_secure(smmu_domain))
return msm_secure_smmu_map(domain, iova, paddr, size, prot);
+ arm_smmu_prealloc_memory(smmu_domain, size, &nonsecure_pool);
arm_smmu_secure_domain_lock(smmu_domain);
spin_lock_irqsave(&smmu_domain->pgtbl_lock, flags);
+ list_splice_init(&nonsecure_pool, &smmu_domain->nonsecure_pool);
ret = ops->map(ops, iova, paddr, size, prot);
+ list_splice_init(&smmu_domain->nonsecure_pool, &nonsecure_pool);
spin_unlock_irqrestore(&smmu_domain->pgtbl_lock, flags);
arm_smmu_assign_table(smmu_domain);
arm_smmu_secure_domain_unlock(smmu_domain);
+ arm_smmu_release_prealloc_memory(smmu_domain, &nonsecure_pool);
return ret;
}
@@ -2695,7 +2710,7 @@
if (arm_smmu_is_slave_side_secure(smmu_domain))
return msm_secure_smmu_map_sg(domain, iova, sg, nents, prot);
- arm_smmu_prealloc_memory(smmu_domain, sg, nents, &nonsecure_pool);
+ arm_smmu_prealloc_memory_sg(smmu_domain, sg, nents, &nonsecure_pool);
arm_smmu_secure_domain_lock(smmu_domain);
__saved_iova_start = iova;
diff --git a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_intf_api.h b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_intf_api.h
index 66c75f6..2b00a87 100644
--- a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_intf_api.h
+++ b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_intf_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -81,7 +81,7 @@
enum cam_cdm_id id;
void *userdata;
void (*cam_cdm_callback)(uint32_t handle, void *userdata,
- enum cam_cdm_cb_status status, uint32_t cookie);
+ enum cam_cdm_cb_status status, uint64_t cookie);
uint32_t base_array_cnt;
struct cam_soc_reg_map *base_array[CAM_SOC_MAX_BLOCK];
struct cam_hw_version cdm_version;
@@ -128,7 +128,7 @@
struct cam_cdm_bl_request {
int flag;
void *userdata;
- uint32_t cookie;
+ uint64_t cookie;
enum cam_cdm_bl_cmd_addr_type type;
uint32_t cmd_arrary_count;
struct cam_cdm_bl_cmd cmd[1];
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context.c b/drivers/media/platform/msm/camera/cam_core/cam_context.c
index 98fff48..8beffc4 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context.c
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context.c
@@ -40,6 +40,7 @@
int cam_context_shutdown(struct cam_context *ctx)
{
int rc = 0;
+ int32_t ctx_hdl = ctx->dev_hdl;
if (ctx->state_machine[ctx->state].ioctl_ops.stop_dev) {
rc = ctx->state_machine[ctx->state].ioctl_ops.stop_dev(
@@ -54,6 +55,8 @@
CAM_ERR(CAM_CORE, "Error while dev release %d", rc);
}
+ if (!rc)
+ cam_destroy_device_hdl(ctx_hdl);
return rc;
}
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
index b85f00b..85e9058 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
@@ -143,6 +143,7 @@
ctx->dev_name, ctx->ctx_id, req->request_id);
cfg.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
+ cfg.request_id = req->request_id;
cfg.hw_update_entries = req->hw_update_entries;
cfg.num_hw_update_entries = req->num_hw_update_entries;
cfg.out_map_entries = req->out_map_entries;
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h b/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h
index cf1859c..4168ce6 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h
+++ b/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h
@@ -172,6 +172,7 @@
* @out_map_entries: Out map info
* @num_out_map_entries: Number of out map entries
* @priv: Private pointer
+ * @request_id: Request ID
*
*/
struct cam_hw_config_args {
@@ -181,6 +182,7 @@
struct cam_hw_fence_map_entry *out_map_entries;
uint32_t num_out_map_entries;
void *priv;
+ uint64_t request_id;
};
/**
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_node.c b/drivers/media/platform/msm/camera/cam_core/cam_node.c
index 4e9034e..a943680 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_node.c
+++ b/drivers/media/platform/msm/camera/cam_core/cam_node.c
@@ -381,7 +381,6 @@
for (i = 0; i < node->ctx_size; i++) {
if (node->ctx_list[i].dev_hdl >= 0) {
cam_context_shutdown(&(node->ctx_list[i]));
- cam_destroy_device_hdl(node->ctx_list[i].dev_hdl);
cam_context_putref(&(node->ctx_list[i]));
}
}
diff --git a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_core.c b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_core.c
index 4d74dec..a18afc6 100644
--- a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_core.c
+++ b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_core.c
@@ -29,10 +29,10 @@
}
static void cam_fd_hw_util_cdm_callback(uint32_t handle, void *userdata,
- enum cam_cdm_cb_status status, uint32_t cookie)
+ enum cam_cdm_cb_status status, uint64_t cookie)
{
trace_cam_cdm_cb("FD", status);
- CAM_DBG(CAM_FD, "CDM hdl=%x, udata=%pK, status=%d, cookie=%d",
+ CAM_DBG(CAM_FD, "CDM hdl=%x, udata=%pK, status=%d, cookie=%llu",
handle, userdata, status, cookie);
}
diff --git a/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_intf.h b/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_intf.h
index 178e734..f556780 100644
--- a/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_intf.h
+++ b/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_intf.h
@@ -36,6 +36,7 @@
* @msg_q: message queue hfi memory for firmware to host communication
* @dbg_q: debug queue hfi memory for firmware debug information
* @sec_heap: secondary heap hfi memory for firmware
+ * @qdss: qdss mapped memory for fw
* @icp_base: icp base address
*/
struct hfi_mem_info {
@@ -45,6 +46,7 @@
struct hfi_mem dbg_q;
struct hfi_mem sec_heap;
struct hfi_mem shmem;
+ struct hfi_mem qdss;
void __iomem *icp_base;
};
@@ -113,9 +115,10 @@
void cam_hfi_deinit(void __iomem *icp_base);
/**
* hfi_set_debug_level() - set debug level
+ * @a5_dbg_type: 1 for debug_q & 2 for qdss
* @lvl: FW debug message level
*/
-int hfi_set_debug_level(uint32_t lvl);
+int hfi_set_debug_level(u64 a5_dbg_type, uint32_t lvl);
/**
* hfi_enable_ipe_bps_pc() - Enable interframe pc
diff --git a/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_reg.h b/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_reg.h
index 73663b3..2153cea 100644
--- a/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_reg.h
+++ b/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_reg.h
@@ -41,6 +41,8 @@
#define HFI_REG_QTBL_PTR 0x58
#define HFI_REG_UNCACHED_HEAP_PTR 0x5C
#define HFI_REG_UNCACHED_HEAP_SIZE 0x60
+#define HFI_REG_QDSS_IOVA 0x6C
+#define HFI_REG_QDSS_IOVA_SIZE 0x70
/* end of ICP CSR registers */
/* flags for ICP CSR registers */
diff --git a/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_sys_defs.h b/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_sys_defs.h
index 84cc129..91190b6 100644
--- a/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_sys_defs.h
+++ b/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_sys_defs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -184,11 +184,12 @@
* Section describes different modes (HFI_DEBUG_MODE_X)
* available to communicate the debug messages
*/
- /* Debug message output through the interface debug queue. */
+ /* Debug message output through the interface debug queue. */
#define HFI_DEBUG_MODE_QUEUE 0x00000001
/* Debug message output through QDSS. */
#define HFI_DEBUG_MODE_QDSS 0x00000002
-
+ /* Number of debug modes available. */
+#define NUM_HFI_DEBUG_MODE 0x00000002
#define HFI_DEBUG_MSG_LOW 0x00000001
#define HFI_DEBUG_MSG_MEDIUM 0x00000002
@@ -199,9 +200,6 @@
#define HFI_DEBUG_CFG_WFI 0x01000000
#define HFI_DEBUG_CFG_ARM9WD 0x10000000
-#define HFI_DEBUG_MODE_QUEUE 0x00000001
-#define HFI_DEBUG_MODE_QDSS 0x00000002
-
#define HFI_DEV_VERSION_MAX 0x5
/**
diff --git a/drivers/media/platform/msm/camera/cam_icp/hfi.c b/drivers/media/platform/msm/camera/cam_icp/hfi.c
index f95f8eb..b75719b 100644
--- a/drivers/media/platform/msm/camera/cam_icp/hfi.c
+++ b/drivers/media/platform/msm/camera/cam_icp/hfi.c
@@ -285,7 +285,7 @@
return 0;
}
-int hfi_set_debug_level(uint32_t lvl)
+int hfi_set_debug_level(u64 a5_dbg_type, uint32_t lvl)
{
uint8_t *prop;
struct hfi_cmd_prop *dbg_prop;
@@ -316,9 +316,9 @@
dbg_prop->num_prop = 1;
dbg_prop->prop_data[0] = HFI_PROP_SYS_DEBUG_CFG;
dbg_prop->prop_data[1] = lvl;
- dbg_prop->prop_data[2] = HFI_DEBUG_MODE_QUEUE;
-
+ dbg_prop->prop_data[2] = a5_dbg_type;
hfi_write_cmd(prop);
+
kfree(prop);
return 0;
@@ -538,6 +538,10 @@
icp_base + HFI_REG_UNCACHED_HEAP_PTR);
cam_io_w_mb((uint32_t)hfi_mem->sec_heap.len,
icp_base + HFI_REG_UNCACHED_HEAP_SIZE);
+ cam_io_w_mb((uint32_t)hfi_mem->qdss.iova,
+ icp_base + HFI_REG_QDSS_IOVA);
+ cam_io_w_mb((uint32_t)hfi_mem->qdss.len,
+ icp_base + HFI_REG_QDSS_IOVA_SIZE);
return rc;
}
@@ -715,6 +719,10 @@
icp_base + HFI_REG_UNCACHED_HEAP_SIZE);
cam_io_w_mb((uint32_t)ICP_INIT_REQUEST_SET,
icp_base + HFI_REG_HOST_ICP_INIT_REQUEST);
+ cam_io_w_mb((uint32_t)hfi_mem->qdss.iova,
+ icp_base + HFI_REG_QDSS_IOVA);
+ cam_io_w_mb((uint32_t)hfi_mem->qdss.len,
+ icp_base + HFI_REG_QDSS_IOVA_SIZE);
hw_version = cam_io_r(icp_base + HFI_REG_A5_HW_VERSION);
diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
index 59d3534..c6c9b85 100644
--- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
@@ -245,6 +245,38 @@
return 0;
}
+static bool cam_icp_frame_pending(struct cam_icp_hw_ctx_data *ctx_data)
+{
+ return !bitmap_empty(ctx_data->hfi_frame_process.bitmap,
+ CAM_FRAME_CMD_MAX);
+}
+
+static int cam_icp_ctx_timer_reset(struct cam_icp_hw_ctx_data *ctx_data)
+{
+ if (ctx_data && ctx_data->watch_dog) {
+ ctx_data->watch_dog_reset_counter++;
+ CAM_DBG(CAM_ICP, "reset timer : ctx_id = %d, counter=%d",
+ ctx_data->ctx_id, ctx_data->watch_dog_reset_counter);
+ crm_timer_reset(ctx_data->watch_dog);
+ }
+
+ return 0;
+}
+
+static void cam_icp_device_timer_reset(struct cam_icp_hw_mgr *hw_mgr,
+ int device_index)
+{
+ if ((device_index >= ICP_CLK_HW_MAX) || (!hw_mgr))
+ return;
+
+ if (hw_mgr->clk_info[device_index].watch_dog) {
+ CAM_DBG(CAM_ICP, "reset timer : device_index = %d",
+ device_index);
+ crm_timer_reset(hw_mgr->clk_info[device_index].watch_dog);
+ hw_mgr->clk_info[device_index].watch_dog_reset_counter++;
+ }
+}
+
static int32_t cam_icp_deinit_idle_clk(void *priv, void *data)
{
struct cam_icp_hw_mgr *hw_mgr = (struct cam_icp_hw_mgr *)priv;
@@ -259,6 +291,8 @@
struct cam_hw_intf *bps_dev_intf = NULL;
struct cam_hw_intf *dev_intf = NULL;
struct cam_a5_clk_update_cmd clk_upd_cmd;
+ int rc = 0;
+ bool busy = false;
ipe0_dev_intf = hw_mgr->ipe0_dev_intf;
ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
@@ -268,19 +302,34 @@
clk_info->curr_clk = 0;
clk_info->over_clked = 0;
+ mutex_lock(&hw_mgr->hw_mgr_mutex);
+
for (i = 0; i < CAM_ICP_CTX_MAX; i++) {
ctx_data = &hw_mgr->ctx_data[i];
mutex_lock(&ctx_data->ctx_mutex);
if ((ctx_data->state == CAM_ICP_CTX_STATE_ACQUIRED) &&
(ICP_DEV_TYPE_TO_CLK_TYPE(ctx_data->
- icp_dev_acquire_info->dev_type) == clk_info->hw_type))
+ icp_dev_acquire_info->dev_type) == clk_info->hw_type)) {
+ busy = cam_icp_frame_pending(ctx_data);
+ if (busy) {
+ mutex_unlock(&ctx_data->ctx_mutex);
+ break;
+ }
cam_icp_ctx_clk_info_init(ctx_data);
+ }
mutex_unlock(&ctx_data->ctx_mutex);
}
+ if (busy) {
+ cam_icp_device_timer_reset(hw_mgr, clk_info->hw_type);
+ rc = -EBUSY;
+ goto done;
+ }
+
if ((!ipe0_dev_intf) || (!bps_dev_intf)) {
CAM_ERR(CAM_ICP, "dev intfs are wrong, failed to update clk");
- return -EINVAL;
+ rc = -EINVAL;
+ goto done;
}
if (clk_info->hw_type == ICP_CLK_HW_BPS) {
@@ -291,7 +340,7 @@
id = CAM_ICP_IPE_CMD_DISABLE_CLK;
} else {
CAM_ERR(CAM_ICP, "Error");
- return 0;
+ goto done;
}
CAM_DBG(CAM_ICP, "Disable %d", clk_info->hw_type);
@@ -308,7 +357,9 @@
&clk_upd_cmd,
sizeof(struct cam_a5_clk_update_cmd));
- return 0;
+done:
+ mutex_unlock(&hw_mgr->hw_mgr_mutex);
+ return rc;
}
static int32_t cam_icp_ctx_timer(void *priv, void *data)
@@ -339,6 +390,12 @@
return 0;
}
+ if (cam_icp_frame_pending(ctx_data)) {
+ cam_icp_ctx_timer_reset(ctx_data);
+ mutex_unlock(&ctx_data->ctx_mutex);
+ return -EBUSY;
+ }
+
CAM_DBG(CAM_ICP,
"E :ctx_id = %d ubw = %lld cbw = %lld curr_fc = %u bc = %u",
ctx_data->ctx_id,
@@ -380,8 +437,8 @@
ctx_data->clk_info.base_clk = 0;
clk_update.ahb_vote.type = CAM_VOTE_DYNAMIC;
- clk_update.ahb_vote.vote.freq = clk_info->curr_clk;
- clk_update.ahb_vote_valid = true;
+ clk_update.ahb_vote.vote.freq = 0;
+ clk_update.ahb_vote_valid = false;
clk_update.axi_vote.compressed_bw = clk_info->compressed_bw;
clk_update.axi_vote.uncompressed_bw = clk_info->uncompressed_bw;
clk_update.axi_vote_valid = true;
@@ -533,30 +590,6 @@
}
}
-static int cam_icp_ctx_timer_reset(struct cam_icp_hw_ctx_data *ctx_data)
-{
- if (ctx_data && ctx_data->watch_dog) {
- ctx_data->watch_dog_reset_counter++;
- CAM_DBG(CAM_ICP, "reset timer : ctx_id = %d, counter=%d",
- ctx_data->ctx_id, ctx_data->watch_dog_reset_counter);
- crm_timer_reset(ctx_data->watch_dog);
- }
-
- return 0;
-}
-
-static void cam_icp_device_timer_reset(struct cam_icp_hw_mgr *hw_mgr,
- int device_index)
-{
- if ((device_index >= ICP_CLK_HW_MAX) || (!hw_mgr))
- return;
-
- if (hw_mgr->clk_info[device_index].watch_dog) {
- crm_timer_reset(hw_mgr->clk_info[device_index].watch_dog);
- hw_mgr->clk_info[device_index].watch_dog_reset_counter++;
- }
-}
-
static uint32_t cam_icp_mgr_calc_base_clk(uint32_t frame_cycles,
uint64_t budget)
{
@@ -639,7 +672,6 @@
* zero. If the clock is already at highest clock rate then
* no need to update the clock
*/
- mutex_lock(&hw_mgr->hw_mgr_mutex);
ctx_data->clk_info.base_clk = base_clk;
hw_mgr_clk_info->over_clked = 0;
if (clk_info->frame_cycles > ctx_data->clk_info.curr_fc) {
@@ -665,7 +697,6 @@
}
}
ctx_data->clk_info.curr_fc = clk_info->frame_cycles;
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
return rc;
}
@@ -731,10 +762,8 @@
ctx_data->clk_info.curr_fc = clk_info->frame_cycles;
ctx_data->clk_info.base_clk = base_clk;
- mutex_lock(&hw_mgr->hw_mgr_mutex);
cam_icp_calc_total_clk(hw_mgr, hw_mgr_clk_info,
ctx_data->icp_dev_acquire_info->dev_type);
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
/*
* Current clock is not always sum of base clocks, due to
@@ -752,7 +781,6 @@
over_clocked = cam_icp_is_over_clk(hw_mgr, ctx_data,
hw_mgr_clk_info);
- mutex_lock(&hw_mgr->hw_mgr_mutex);
if (hw_mgr_clk_info->curr_clk > hw_mgr_clk_info->base_clk &&
over_clocked) {
rc = cam_icp_update_clk_overclk_free(hw_mgr, ctx_data,
@@ -765,7 +793,6 @@
ctx_data, hw_mgr_clk_info->base_clk);
rc = true;
}
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
return rc;
}
@@ -775,12 +802,10 @@
if (icp_hw_mgr.icp_debug_clk < ICP_CLK_TURBO_HZ &&
icp_hw_mgr.icp_debug_clk &&
icp_hw_mgr.icp_debug_clk != hw_mgr_clk_info->curr_clk) {
- mutex_lock(&icp_hw_mgr.hw_mgr_mutex);
hw_mgr_clk_info->base_clk = icp_hw_mgr.icp_debug_clk;
hw_mgr_clk_info->curr_clk = icp_hw_mgr.icp_debug_clk;
hw_mgr_clk_info->uncompressed_bw = icp_hw_mgr.icp_debug_clk;
hw_mgr_clk_info->compressed_bw = icp_hw_mgr.icp_debug_clk;
- mutex_unlock(&icp_hw_mgr.hw_mgr_mutex);
CAM_DBG(CAM_ICP, "bc = %d cc = %d",
hw_mgr_clk_info->base_clk, hw_mgr_clk_info->curr_clk);
return true;
@@ -792,12 +817,10 @@
static bool cam_icp_default_clk_update(struct cam_icp_clk_info *hw_mgr_clk_info)
{
if (icp_hw_mgr.icp_default_clk != hw_mgr_clk_info->curr_clk) {
- mutex_lock(&icp_hw_mgr.hw_mgr_mutex);
hw_mgr_clk_info->base_clk = icp_hw_mgr.icp_default_clk;
hw_mgr_clk_info->curr_clk = icp_hw_mgr.icp_default_clk;
hw_mgr_clk_info->uncompressed_bw = icp_hw_mgr.icp_default_clk;
hw_mgr_clk_info->compressed_bw = icp_hw_mgr.icp_default_clk;
- mutex_unlock(&icp_hw_mgr.hw_mgr_mutex);
CAM_DBG(CAM_ICP, "bc = %d cc = %d",
hw_mgr_clk_info->base_clk, hw_mgr_clk_info->curr_clk);
return true;
@@ -844,7 +867,6 @@
ctx->icp_dev_acquire_info->dev_type) ==
ICP_DEV_TYPE_TO_CLK_TYPE(
ctx_data->icp_dev_acquire_info->dev_type)) {
- mutex_lock(&hw_mgr->hw_mgr_mutex);
hw_mgr_clk_info->uncompressed_bw +=
ctx->clk_info.uncompressed_bw;
hw_mgr_clk_info->compressed_bw +=
@@ -852,7 +874,6 @@
CAM_DBG(CAM_ICP, "ubw = %lld, cbw = %lld",
hw_mgr_clk_info->uncompressed_bw,
hw_mgr_clk_info->compressed_bw);
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
}
}
@@ -1018,8 +1039,8 @@
}
clk_update.ahb_vote.type = CAM_VOTE_DYNAMIC;
- clk_update.ahb_vote.vote.freq = clk_info->curr_clk;
- clk_update.ahb_vote_valid = true;
+ clk_update.ahb_vote.vote.freq = 0;
+ clk_update.ahb_vote_valid = false;
clk_update.axi_vote.compressed_bw = clk_info->compressed_bw;
clk_update.axi_vote.uncompressed_bw = clk_info->uncompressed_bw;
clk_update.axi_vote_valid = true;
@@ -1244,6 +1265,23 @@
DEFINE_SIMPLE_ATTRIBUTE(cam_icp_debug_fs, cam_icp_get_a5_dbg_lvl,
cam_icp_set_a5_dbg_lvl, "%08llu");
+static int cam_icp_set_a5_dbg_type(void *data, u64 val)
+{
+ if (val <= NUM_HFI_DEBUG_MODE)
+ icp_hw_mgr.a5_debug_type = val;
+ return 0;
+}
+
+static int cam_icp_get_a5_dbg_type(void *data, u64 *val)
+{
+ *val = icp_hw_mgr.a5_debug_type;
+ return 0;
+}
+
+
+DEFINE_SIMPLE_ATTRIBUTE(cam_icp_debug_type_fs, cam_icp_get_a5_dbg_type,
+ cam_icp_set_a5_dbg_type, "%08llu");
+
static int cam_icp_hw_mgr_create_debugfs_entry(void)
{
int rc = 0;
@@ -1290,11 +1328,11 @@
goto err;
}
- if (!debugfs_create_bool("a5_debug_q",
+ if (!debugfs_create_file("a5_debug_type",
0644,
icp_hw_mgr.dentry,
- &icp_hw_mgr.a5_debug_q)) {
- CAM_ERR(CAM_ICP, "failed to create a5_debug_q\n");
+ NULL, &cam_icp_debug_type_fs)) {
+ CAM_ERR(CAM_ICP, "failed to create a5_debug_type\n");
rc = -ENOMEM;
goto err;
}
@@ -1393,10 +1431,6 @@
CAM_DBG(CAM_ICP, "ctx : %pK, request_id :%lld",
(void *)ctx_data->context_priv, request_id);
- clk_type = ICP_DEV_TYPE_TO_CLK_TYPE(ctx_data->icp_dev_acquire_info->
- dev_type);
- cam_icp_device_timer_reset(&icp_hw_mgr, clk_type);
-
mutex_lock(&ctx_data->ctx_mutex);
cam_icp_ctx_timer_reset(ctx_data);
if (ctx_data->state != CAM_ICP_CTX_STATE_ACQUIRED) {
@@ -1406,6 +1440,10 @@
return 0;
}
+ clk_type = ICP_DEV_TYPE_TO_CLK_TYPE(
+ ctx_data->icp_dev_acquire_info->dev_type);
+ cam_icp_device_timer_reset(&icp_hw_mgr, clk_type);
+
hfi_frame_process = &ctx_data->hfi_frame_process;
for (i = 0; i < CAM_FRAME_CMD_MAX; i++)
if (hfi_frame_process->request_id[i] == request_id)
@@ -1792,7 +1830,8 @@
}
}
- if (icp_hw_mgr.a5_debug_q)
+ if (icp_hw_mgr.a5_debug_type ==
+ HFI_DEBUG_MODE_QUEUE)
cam_icp_mgr_process_dbg_buf();
return rc;
@@ -1833,6 +1872,8 @@
rc = cam_mem_mgr_free_memory_region(&icp_hw_mgr.hfi_mem.sec_heap);
if (rc)
CAM_ERR(CAM_ICP, "failed to unreserve sec heap");
+
+ cam_smmu_dealloc_qdss(icp_hw_mgr.iommu_hdl);
cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.qtbl);
cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.cmd_q);
cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.msg_q);
@@ -1923,6 +1964,26 @@
return rc;
}
+static int cam_icp_allocate_qdss_mem(void)
+{
+ int rc;
+ size_t len;
+ dma_addr_t iova;
+
+ rc = cam_smmu_alloc_qdss(icp_hw_mgr.iommu_hdl,
+ &iova, &len);
+ if (rc)
+ return rc;
+
+ icp_hw_mgr.hfi_mem.qdss_buf.len = len;
+ icp_hw_mgr.hfi_mem.qdss_buf.iova = iova;
+ icp_hw_mgr.hfi_mem.qdss_buf.smmu_hdl = icp_hw_mgr.iommu_hdl;
+
+ CAM_DBG(CAM_ICP, "iova: %llx, len: %zu", iova, len);
+
+ return rc;
+}
+
static int cam_icp_allocate_hfi_mem(void)
{
int rc;
@@ -1941,6 +2002,12 @@
return rc;
}
+ rc = cam_icp_allocate_qdss_mem();
+ if (rc) {
+ CAM_ERR(CAM_ICP, "Unable to allocate qdss memory");
+ goto fw_alloc_failed;
+ }
+
rc = cam_icp_alloc_shared_mem(&icp_hw_mgr.hfi_mem.qtbl);
if (rc) {
CAM_ERR(CAM_ICP, "Unable to allocate qtbl memory");
@@ -1981,6 +2048,8 @@
cmd_q_alloc_failed:
cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.qtbl);
qtbl_alloc_failed:
+ cam_smmu_dealloc_qdss(icp_hw_mgr.iommu_hdl);
+fw_alloc_failed:
cam_smmu_dealloc_firmware(icp_hw_mgr.iommu_hdl);
return rc;
}
@@ -2069,6 +2138,37 @@
return 0;
}
+
+static int cam_icp_mgr_hw_close_u(void *hw_priv, void *hw_close_args)
+{
+ struct cam_icp_hw_mgr *hw_mgr = hw_priv;
+ int rc = 0;
+
+ if (!hw_mgr) {
+ CAM_ERR(CAM_ICP, "Null hw mgr");
+ return 0;
+ }
+
+ mutex_lock(&hw_mgr->hw_mgr_mutex);
+ rc = cam_icp_mgr_hw_close(hw_mgr, NULL);
+ mutex_unlock(&hw_mgr->hw_mgr_mutex);
+
+ return rc;
+}
+
+static int cam_icp_mgr_hw_close_k(void *hw_priv, void *hw_close_args)
+{
+ struct cam_icp_hw_mgr *hw_mgr = hw_priv;
+
+ if (!hw_mgr) {
+ CAM_ERR(CAM_ICP, "Null hw mgr");
+ return 0;
+ }
+
+ return cam_icp_mgr_hw_close(hw_mgr, NULL);
+
+}
+
static int cam_icp_mgr_icp_power_collapse(struct cam_icp_hw_mgr *hw_mgr)
{
int rc;
@@ -2087,7 +2187,7 @@
if (!hw_mgr->icp_pc_flag) {
cam_hfi_disable_cpu(
a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base);
- rc = cam_icp_mgr_hw_close(hw_mgr, NULL);
+ rc = cam_icp_mgr_hw_close_k(hw_mgr, NULL);
} else {
rc = cam_icp_mgr_send_pc_prep(hw_mgr);
cam_hfi_disable_cpu(
@@ -2142,6 +2242,9 @@
hfi_mem.shmem.iova = icp_hw_mgr.hfi_mem.shmem.iova_start;
hfi_mem.shmem.len = icp_hw_mgr.hfi_mem.shmem.iova_len;
+
+ hfi_mem.qdss.iova = icp_hw_mgr.hfi_mem.qdss_buf.iova;
+ hfi_mem.qdss.len = icp_hw_mgr.hfi_mem.qdss_buf.len;
return cam_hfi_resume(&hfi_mem,
a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base,
hw_mgr->a5_jtag_debug);
@@ -2268,7 +2371,8 @@
rc = -ETIMEDOUT;
CAM_ERR(CAM_ICP, "FW response timeout: %d for %u",
rc, ctx_data->ctx_id);
- if (icp_hw_mgr.a5_debug_q)
+ if (icp_hw_mgr.a5_debug_type ==
+ HFI_DEBUG_MODE_QUEUE)
cam_icp_mgr_process_dbg_buf();
}
return rc;
@@ -2287,7 +2391,6 @@
if (hw_mgr->ctx_data[ctx_id].state !=
CAM_ICP_CTX_STATE_ACQUIRED) {
mutex_unlock(&hw_mgr->ctx_data[ctx_id].ctx_mutex);
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
CAM_DBG(CAM_ICP,
"ctx with id: %d not in right state to release: %d",
ctx_id, hw_mgr->ctx_data[ctx_id].state);
@@ -2357,16 +2460,13 @@
int rc = 0;
CAM_DBG(CAM_ICP, "E");
- mutex_lock(&hw_mgr->hw_mgr_mutex);
if (hw_mgr->fw_download == false) {
CAM_DBG(CAM_ICP, "hw mgr is already closed");
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
return 0;
}
a5_dev_intf = hw_mgr->a5_dev_intf;
if (!a5_dev_intf) {
CAM_DBG(CAM_ICP, "a5_dev_intf is NULL");
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
return -EINVAL;
}
a5_dev = (struct cam_hw_info *)a5_dev_intf->hw_priv;
@@ -2394,7 +2494,7 @@
cam_icp_free_hfi_mem();
hw_mgr->fw_download = false;
hw_mgr->secure_mode = CAM_SECURE_MODE_NON_SECURE;
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
+
CAM_DBG(CAM_ICP, "Exit");
return rc;
}
@@ -2539,6 +2639,9 @@
hfi_mem.shmem.iova = icp_hw_mgr.hfi_mem.shmem.iova_start;
hfi_mem.shmem.len = icp_hw_mgr.hfi_mem.shmem.iova_len;
+ hfi_mem.qdss.iova = icp_hw_mgr.hfi_mem.qdss_buf.iova;
+ hfi_mem.qdss.len = icp_hw_mgr.hfi_mem.qdss_buf.len;
+
return cam_hfi_init(0, &hfi_mem,
a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base,
hw_mgr->a5_jtag_debug);
@@ -2577,6 +2680,35 @@
return rc;
}
+static int cam_icp_mgr_hw_open_u(void *hw_mgr_priv, void *download_fw_args)
+{
+ struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv;
+ int rc = 0;
+
+ if (!hw_mgr) {
+ CAM_ERR(CAM_ICP, "Null hw mgr");
+ return 0;
+ }
+
+ mutex_lock(&hw_mgr->hw_mgr_mutex);
+ rc = cam_icp_mgr_hw_open(hw_mgr, download_fw_args);
+ mutex_unlock(&hw_mgr->hw_mgr_mutex);
+
+ return rc;
+}
+
+static int cam_icp_mgr_hw_open_k(void *hw_mgr_priv, void *download_fw_args)
+{
+ struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv;
+
+ if (!hw_mgr) {
+ CAM_ERR(CAM_ICP, "Null hw mgr");
+ return 0;
+ }
+
+ return cam_icp_mgr_hw_open(hw_mgr, download_fw_args);
+}
+
static int cam_icp_mgr_icp_resume(struct cam_icp_hw_mgr *hw_mgr)
{
int rc = 0;
@@ -2593,9 +2725,7 @@
if (hw_mgr->fw_download == false) {
CAM_DBG(CAM_ICP, "Downloading FW");
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
- rc = cam_icp_mgr_hw_open(hw_mgr, &downloadFromResume);
- mutex_lock(&hw_mgr->hw_mgr_mutex);
+ rc = cam_icp_mgr_hw_open_k(hw_mgr, &downloadFromResume);
CAM_DBG(CAM_ICP, "FW Download Done Exit");
return rc;
}
@@ -2628,17 +2758,14 @@
return -EINVAL;
}
- mutex_lock(&hw_mgr->hw_mgr_mutex);
if (hw_mgr->fw_download) {
CAM_DBG(CAM_ICP, "FW already downloaded");
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
return rc;
}
a5_dev_intf = hw_mgr->a5_dev_intf;
if (!a5_dev_intf) {
CAM_ERR(CAM_ICP, "a5_dev_intf is invalid");
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
return -EINVAL;
}
a5_dev = (struct cam_hw_info *)a5_dev_intf->hw_priv;
@@ -2665,10 +2792,6 @@
hw_mgr->ctxt_cnt = 0;
hw_mgr->fw_download = true;
- if (icp_hw_mgr.a5_debug_q)
- hfi_set_debug_level(icp_hw_mgr.a5_dbg_lvl);
-
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
CAM_INFO(CAM_ICP, "FW download done successfully");
rc = cam_ipe_bps_deint(hw_mgr);
@@ -2700,7 +2823,6 @@
dev_init_fail:
cam_icp_free_hfi_mem();
alloc_hfi_mem_failed:
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
return rc;
}
@@ -2774,9 +2896,11 @@
}
ctx_data = config_args->ctxt_to_hw_map;
+ mutex_lock(&hw_mgr->hw_mgr_mutex);
mutex_lock(&ctx_data->ctx_mutex);
if (ctx_data->state != CAM_ICP_CTX_STATE_ACQUIRED) {
mutex_unlock(&ctx_data->ctx_mutex);
+ mutex_unlock(&hw_mgr->hw_mgr_mutex);
CAM_ERR(CAM_ICP, "ctx id :%u is not in use",
ctx_data->ctx_id);
return -EINVAL;
@@ -2793,11 +2917,13 @@
CAM_DBG(CAM_ICP, "req_id = %lld %u",
req_id, ctx_data->ctx_id);
mutex_unlock(&ctx_data->ctx_mutex);
+ mutex_unlock(&hw_mgr->hw_mgr_mutex);
return 0;
config_err:
cam_icp_mgr_handle_config_err(config_args, ctx_data, idx);
mutex_unlock(&ctx_data->ctx_mutex);
+ mutex_unlock(&hw_mgr->hw_mgr_mutex);
return rc;
}
@@ -3440,9 +3566,7 @@
rc = cam_icp_mgr_release_ctx(hw_mgr, ctx_id);
if (!hw_mgr->ctxt_cnt) {
CAM_DBG(CAM_ICP, "Last Release");
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
cam_icp_mgr_icp_power_collapse(hw_mgr);
- mutex_lock(&hw_mgr->hw_mgr_mutex);
cam_icp_hw_mgr_reset_clk_info(hw_mgr);
hw_mgr->secure_mode = CAM_SECURE_MODE_NON_SECURE;
rc = cam_ipe_bps_deint(hw_mgr);
@@ -3710,10 +3834,9 @@
mutex_lock(&ctx_data->ctx_mutex);
rc = cam_icp_get_acquire_info(hw_mgr, args, ctx_data);
- if (rc) {
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
+ if (rc)
goto acquire_info_failed;
- }
+
icp_dev_acquire_info = ctx_data->icp_dev_acquire_info;
rc = cam_mem_get_io_buf(
@@ -3722,7 +3845,6 @@
&io_buf_addr, &io_buf_size);
if (rc) {
CAM_ERR(CAM_ICP, "unable to get src buf info from io desc");
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
goto get_io_buf_failed;
}
@@ -3732,34 +3854,26 @@
if (!hw_mgr->ctxt_cnt) {
rc = cam_icp_clk_info_init(hw_mgr, ctx_data);
- if (rc) {
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
+ if (rc)
goto get_io_buf_failed;
- }
rc = cam_icp_mgr_icp_resume(hw_mgr);
- if (rc) {
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
+ if (rc)
goto get_io_buf_failed;
- }
- if (icp_hw_mgr.a5_debug_q)
- hfi_set_debug_level(icp_hw_mgr.a5_dbg_lvl);
+ if (icp_hw_mgr.a5_debug_type)
+ hfi_set_debug_level(icp_hw_mgr.a5_debug_type,
+ icp_hw_mgr.a5_dbg_lvl);
rc = cam_icp_send_ubwc_cfg(hw_mgr);
- if (rc) {
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
+ if (rc)
goto ubwc_cfg_failed;
- }
}
rc = cam_icp_mgr_ipe_bps_resume(hw_mgr, ctx_data);
- if (rc) {
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
+ if (rc)
goto ipe_bps_resume_failed;
- }
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
rc = cam_icp_mgr_send_ping(ctx_data);
if (rc) {
@@ -3789,6 +3903,7 @@
kzalloc(bitmap_size, GFP_KERNEL);
if (!ctx_data->hfi_frame_process.bitmap)
goto ioconfig_failed;
+
ctx_data->hfi_frame_process.bits = bitmap_size * BITS_PER_BYTE;
hw_mgr->ctx_data[ctx_id].ctxt_event_cb = args->event_cb;
icp_dev_acquire_info->scratch_mem_size = ctx_data->scratch_mem_size;
@@ -3803,7 +3918,6 @@
CAM_DBG(CAM_ICP, "scratch size = %x fw_handle = %x",
(unsigned int)icp_dev_acquire_info->scratch_mem_size,
(unsigned int)ctx_data->fw_handle);
- mutex_lock(&hw_mgr->hw_mgr_mutex);
/* Start device timer*/
if (((hw_mgr->bps_ctxt_cnt == 1) || (hw_mgr->ipe_ctxt_cnt == 1)))
cam_icp_device_timer_start(hw_mgr);
@@ -3833,6 +3947,7 @@
acquire_info_failed:
cam_icp_mgr_put_ctx(ctx_data);
mutex_unlock(&ctx_data->ctx_mutex);
+ mutex_unlock(&hw_mgr->hw_mgr_mutex);
return rc;
}
@@ -4104,8 +4219,8 @@
hw_mgr_intf->hw_release = cam_icp_mgr_release_hw;
hw_mgr_intf->hw_prepare_update = cam_icp_mgr_prepare_hw_update;
hw_mgr_intf->hw_config = cam_icp_mgr_config_hw;
- hw_mgr_intf->hw_open = cam_icp_mgr_hw_open;
- hw_mgr_intf->hw_close = cam_icp_mgr_hw_close;
+ hw_mgr_intf->hw_open = cam_icp_mgr_hw_open_u;
+ hw_mgr_intf->hw_close = cam_icp_mgr_hw_close_u;
hw_mgr_intf->hw_flush = cam_icp_mgr_hw_flush;
icp_hw_mgr.secure_mode = CAM_SECURE_MODE_NON_SECURE;
diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h
index cffec2e..c94550d 100644
--- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h
+++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h
@@ -78,6 +78,7 @@
* @dbg_q: Memory info of debug queue
* @sec_heap: Memory info of secondary heap
* @fw_buf: Memory info of firmware
+ * @qdss_buf: Memory info of qdss
*/
struct icp_hfi_mem_info {
struct cam_mem_mgr_memory_desc qtbl;
@@ -86,6 +87,7 @@
struct cam_mem_mgr_memory_desc dbg_q;
struct cam_mem_mgr_memory_desc sec_heap;
struct cam_mem_mgr_memory_desc fw_buf;
+ struct cam_mem_mgr_memory_desc qdss_buf;
struct cam_smmu_region_info shmem;
};
@@ -275,7 +277,7 @@
* @clk_info: Clock info of hardware
* @secure_mode: Flag to enable/disable secure camera
* @a5_jtag_debug: entry to enable A5 JTAG debugging
- * @a5_debug_q : entry to enable FW debug message
+ * @a5_debug_type : entry to enable FW debug message/qdss
* @a5_dbg_lvl : debug level set to FW.
* @ipe0_enable: Flag for IPE0
* @ipe1_enable: Flag for IPE1
@@ -321,7 +323,7 @@
struct cam_icp_clk_info clk_info[ICP_CLK_HW_MAX];
bool secure_mode;
bool a5_jtag_debug;
- bool a5_debug_q;
+ u64 a5_debug_type;
u64 a5_dbg_lvl;
bool ipe0_enable;
bool ipe1_enable;
diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
index fe42f70..8753bbb 100644
--- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
+++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
@@ -1070,6 +1070,7 @@
req_isp->bubble_report = apply->report_if_bubble;
cfg.ctxt_to_hw_map = ctx_isp->hw_ctx;
+ cfg.request_id = req->request_id;
cfg.hw_update_entries = req_isp->cfg;
cfg.num_hw_update_entries = req_isp->num_cfg;
cfg.priv = &req_isp->hw_update_data;
@@ -2180,6 +2181,7 @@
}
arg.ctxt_to_hw_map = ctx_isp->hw_ctx;
+ arg.request_id = req->request_id;
arg.hw_update_entries = req_isp->cfg;
arg.num_hw_update_entries = req_isp->num_cfg;
arg.priv = &req_isp->hw_update_data;
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
index 33dd8eb..4628172 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
@@ -242,6 +242,7 @@
{
int i;
struct cam_hw_intf *hw_intf;
+ uint32_t dummy_args;
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
if (!isp_hw_res->hw_res[i])
@@ -253,6 +254,12 @@
sizeof(struct cam_isp_resource_node));
else
CAM_ERR(CAM_ISP, "stop null");
+ if (hw_intf->hw_ops.process_cmd &&
+ isp_hw_res->res_type == CAM_IFE_HW_MGR_RES_IFE_OUT) {
+ hw_intf->hw_ops.process_cmd(hw_intf->hw_priv,
+ CAM_ISP_HW_CMD_STOP_BUS_ERR_IRQ,
+ &dummy_args, sizeof(dummy_args));
+ }
}
}
@@ -1089,7 +1096,7 @@
struct cam_ife_hw_mgr_res *cid_res;
struct cam_hw_intf *hw_intf;
struct cam_isp_out_port_info *out_port;
- uint32_t cid_res_id;
+ uint32_t cid_res_id;
struct cam_csid_hw_reserve_resource_args csid_acquire;
ife_hw_mgr = ife_ctx->hw_mgr;
@@ -1099,13 +1106,15 @@
if (!cam_ife_hw_mgr_is_rdi_res(out_port->res_type))
continue;
- /* get cid resource */
- rc = cam_ife_mgr_acquire_cid_res(ife_ctx, in_port, &cid_res_id,
- cam_ife_hw_mgr_get_ife_csid_rdi_res_type(
- out_port->res_type));
- if (rc) {
- CAM_ERR(CAM_ISP, "Acquire IFE CID resource Failed");
- goto err;
+ /* get cid resource */
+ rc = cam_ife_mgr_acquire_cid_res(ife_ctx,
+ in_port, &cid_res_id,
+ cam_ife_hw_mgr_get_ife_csid_rdi_res_type(
+ out_port->res_type));
+ if (rc) {
+ CAM_ERR(CAM_ISP,
+ "Acquire IFE CID resource Failed");
+ goto err;
}
rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list,
@@ -1308,11 +1317,27 @@
}
void cam_ife_cam_cdm_callback(uint32_t handle, void *userdata,
- enum cam_cdm_cb_status status, uint32_t cookie)
+ enum cam_cdm_cb_status status, uint64_t cookie)
{
- CAM_DBG(CAM_ISP,
- "Called by CDM hdl=%x, udata=%pK, status=%d, cookie=%d",
- handle, userdata, status, cookie);
+ struct cam_ife_hw_mgr_ctx *ctx = NULL;
+
+ if (!userdata) {
+ CAM_ERR(CAM_ISP, "Invalid args");
+ return;
+ }
+
+ ctx = userdata;
+
+ if (status == CAM_CDM_CB_STATUS_BL_SUCCESS) {
+ complete(&ctx->config_done_complete);
+ CAM_DBG(CAM_ISP,
+ "Called by CDM hdl=%x, udata=%pK, status=%d, cookie=%llu",
+ handle, userdata, status, cookie);
+ } else {
+ CAM_WARN(CAM_ISP,
+ "Called by CDM hdl=%x, udata=%pK, status=%d, cookie=%llu",
+ handle, userdata, status, cookie);
+ }
}
/* entry function: acquire_hw */
@@ -1575,9 +1600,9 @@
cdm_cmd = ctx->cdm_cmd;
cdm_cmd->cmd_arrary_count = cfg->num_hw_update_entries;
cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE;
- cdm_cmd->flag = false;
- cdm_cmd->userdata = NULL;
- cdm_cmd->cookie = 0;
+ cdm_cmd->flag = true;
+ cdm_cmd->userdata = ctx;
+ cdm_cmd->cookie = cfg->request_id;
for (i = 0 ; i <= cfg->num_hw_update_entries; i++) {
cmd = (cfg->hw_update_entries + i);
@@ -1588,8 +1613,31 @@
CAM_DBG(CAM_ISP, "Submit to CDM");
rc = cam_cdm_submit_bls(ctx->cdm_handle, cdm_cmd);
- if (rc)
+ if (rc) {
CAM_ERR(CAM_ISP, "Failed to apply the configs");
+ return rc;
+ }
+
+ if (cfg->request_id == 1) {
+ init_completion(&ctx->config_done_complete);
+ rc = wait_for_completion_timeout(
+ &ctx->config_done_complete,
+ msecs_to_jiffies(30));
+ if (rc <= 0) {
+ CAM_ERR(CAM_ISP,
+ "config done completion timeout for req_id=%llu rc = %d",
+ cfg->request_id, rc);
+ if (rc == 0)
+ rc = -ETIMEDOUT;
+ } else {
+ rc = 0;
+ CAM_DBG(CAM_ISP,
+ "config done Success for req_id=%llu",
+ cfg->request_id);
+ }
+
+ rc = 0;
+ }
} else {
CAM_ERR(CAM_ISP, "No commands to config");
}
@@ -1679,6 +1727,48 @@
return rc;
}
+static int cam_ife_mgr_bw_control(struct cam_ife_hw_mgr_ctx *ctx,
+ enum cam_vfe_bw_control_action action)
+{
+ struct cam_ife_hw_mgr_res *hw_mgr_res;
+ struct cam_hw_intf *hw_intf;
+ struct cam_vfe_bw_control_args bw_ctrl_args;
+ int rc = -EINVAL;
+ uint32_t i;
+
+ CAM_DBG(CAM_ISP, "Enter...ctx id:%d", ctx->ctx_index);
+
+ list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
+ for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+ if (!hw_mgr_res->hw_res[i])
+ continue;
+
+ hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+ if (hw_intf && hw_intf->hw_ops.process_cmd) {
+ bw_ctrl_args.node_res =
+ hw_mgr_res->hw_res[i];
+ bw_ctrl_args.action = action;
+
+ rc = hw_intf->hw_ops.process_cmd(
+ hw_intf->hw_priv,
+ CAM_ISP_HW_CMD_BW_CONTROL,
+ &bw_ctrl_args,
+ sizeof(struct cam_vfe_bw_control_args));
+ if (rc)
+ CAM_ERR(CAM_ISP, "BW Update failed");
+ } else
+ CAM_WARN(CAM_ISP, "NULL hw_intf!");
+ }
+ }
+
+ return rc;
+}
+
+static int cam_ife_mgr_pause_hw(struct cam_ife_hw_mgr_ctx *ctx)
+{
+ return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_EXCLUDE);
+}
+
/* entry function: stop_hw */
static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
{
@@ -1699,8 +1789,7 @@
return -EPERM;
}
- CAM_DBG(CAM_ISP, " Enter...ctx id:%d",
- ctx->ctx_index);
+ CAM_DBG(CAM_ISP, " Enter...ctx id:%d", ctx->ctx_index);
/* Set the csid halt command */
if (!stop_args->args)
@@ -1715,6 +1804,25 @@
return -EINVAL;
}
+ CAM_DBG(CAM_ISP, "Halting CSIDs");
+
+ if (cam_cdm_stream_off(ctx->cdm_handle))
+ CAM_ERR(CAM_ISP, "CDM stream off failed %d",
+ ctx->cdm_handle);
+ cam_tasklet_stop(ctx->common.tasklet_info);
+
+ CAM_DBG(CAM_ISP, "Going to stop IFE Mux");
+
+ /* IFE mux in resources */
+ list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
+ cam_ife_hw_mgr_stop_hw_res(hw_mgr_res);
+ }
+
+ CAM_DBG(CAM_ISP, "Going to stop IFE Out");
+
+ /* IFE out resources */
+ for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++)
+ cam_ife_hw_mgr_stop_hw_res(&ctx->res_list_ife_out[i]);
/* get master base index first */
for (i = 0; i < ctx->num_base; i++) {
if (ctx->base[i].split_id == CAM_ISP_HW_SPLIT_LEFT) {
@@ -1730,6 +1838,18 @@
if (i == ctx->num_base)
master_base_idx = ctx->base[0].idx;
+ /* Stop the master CIDs first */
+ cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_cid,
+ master_base_idx, csid_halt_type);
+
+ /* stop rest of the CIDs */
+ for (i = 0; i < ctx->num_base; i++) {
+ if (i == master_base_idx)
+ continue;
+ cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_cid,
+ ctx->base[i].idx, csid_halt_type);
+ }
+
/* Stop the master CSID path first */
cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid,
master_base_idx, csid_halt_type);
@@ -1743,44 +1863,16 @@
ctx->base[i].idx, csid_halt_type);
}
- /* Stop the master CIDs first */
- cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_cid,
- master_base_idx, csid_halt_type);
-
- /* stop rest of the CIDs */
- for (i = 0; i < ctx->num_base; i++) {
- if (i == master_base_idx)
- continue;
- cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_cid,
- ctx->base[i].idx, csid_halt_type);
- }
-
- if (cam_cdm_stream_off(ctx->cdm_handle))
- CAM_ERR(CAM_ISP, "CDM stream off failed %d",
- ctx->cdm_handle);
-
- /* IFE mux in resources */
- list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
- cam_ife_hw_mgr_stop_hw_res(hw_mgr_res);
- }
-
- /* IFE out resources */
- for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++)
- cam_ife_hw_mgr_stop_hw_res(&ctx->res_list_ife_out[i]);
-
- /* Update vote bandwidth should be done at the HW layer */
-
- cam_tasklet_stop(ctx->common.tasklet_info);
-
- /* Deinit IFE root node: do nothing */
/* Deinit IFE CID */
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_cid, list) {
+ CAM_DBG(CAM_ISP, "%s: Going to DeInit IFE CID\n", __func__);
cam_ife_hw_mgr_deinit_hw_res(hw_mgr_res);
}
/* Deinit IFE CSID */
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) {
+ CAM_DBG(CAM_ISP, "%s: Going to DeInit IFE CSID\n", __func__);
cam_ife_hw_mgr_deinit_hw_res(hw_mgr_res);
}
@@ -1907,6 +1999,8 @@
{
int rc = -1;
struct cam_hw_config_args *start_args = start_hw_args;
+ struct cam_hw_stop_args stop_args;
+ struct cam_isp_stop_hw_method stop_hw_method;
struct cam_ife_hw_mgr_ctx *ctx;
struct cam_ife_hw_mgr_res *hw_mgr_res;
uint32_t i;
@@ -2072,7 +2166,10 @@
CAM_DBG(CAM_ISP, "Exit...(success)");
return 0;
err:
- cam_ife_mgr_stop_hw(hw_mgr_priv, start_hw_args);
+ stop_hw_method.hw_stop_cmd = CAM_CSID_HALT_IMMEDIATELY;
+ stop_args.ctxt_to_hw_map = start_args->ctxt_to_hw_map;
+ stop_args.args = (void *)(&stop_hw_method);
+ cam_ife_mgr_stop_hw(hw_mgr_priv, &stop_args);
CAM_DBG(CAM_ISP, "Exit...(rc=%d)", rc);
return rc;
}
@@ -2529,48 +2626,6 @@
return rc;
}
-static int cam_ife_mgr_bw_control(struct cam_ife_hw_mgr_ctx *ctx,
- enum cam_vfe_bw_control_action action)
-{
- struct cam_ife_hw_mgr_res *hw_mgr_res;
- struct cam_hw_intf *hw_intf;
- struct cam_vfe_bw_control_args bw_ctrl_args;
- int rc = -EINVAL;
- uint32_t i;
-
- CAM_DBG(CAM_ISP, "Enter...ctx id:%d", ctx->ctx_index);
-
- list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
- for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
- if (!hw_mgr_res->hw_res[i])
- continue;
-
- hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
- if (hw_intf && hw_intf->hw_ops.process_cmd) {
- bw_ctrl_args.node_res =
- hw_mgr_res->hw_res[i];
- bw_ctrl_args.action = action;
-
- rc = hw_intf->hw_ops.process_cmd(
- hw_intf->hw_priv,
- CAM_ISP_HW_CMD_BW_CONTROL,
- &bw_ctrl_args,
- sizeof(struct cam_vfe_bw_control_args));
- if (rc)
- CAM_ERR(CAM_ISP, "BW Update failed");
- } else
- CAM_WARN(CAM_ISP, "NULL hw_intf!");
- }
- }
-
- return rc;
-}
-
-static int cam_ife_mgr_pause_hw(struct cam_ife_hw_mgr_ctx *ctx)
-{
- return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_EXCLUDE);
-}
-
static int cam_ife_mgr_resume_hw(struct cam_ife_hw_mgr_ctx *ctx)
{
return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_INCLUDE);
@@ -2996,7 +3051,7 @@
void *handler_priv,
void *payload)
{
- int32_t error_status = CAM_ISP_HW_ERROR_NONE;
+ int32_t error_status;
uint32_t core_idx;
struct cam_ife_hw_mgr_ctx *ife_hwr_mgr_ctx;
struct cam_vfe_top_irq_evt_payload *evt_payload;
@@ -3017,15 +3072,15 @@
case CAM_ISP_HW_ERROR_OVERFLOW:
case CAM_ISP_HW_ERROR_P2I_ERROR:
case CAM_ISP_HW_ERROR_VIOLATION:
- CAM_DBG(CAM_ISP, "Enter: error_type (%d)", error_status);
+ CAM_ERR(CAM_ISP, "Enter: error_type (%d)", error_status);
error_event_data.error_type =
CAM_ISP_HW_ERROR_OVERFLOW;
cam_ife_hw_mgr_process_overflow(ife_hwr_mgr_ctx,
- &error_event_data,
- core_idx,
- &recovery_data);
+ &error_event_data,
+ core_idx,
+ &recovery_data);
/* Trigger for recovery */
recovery_data.error_type = CAM_ISP_HW_ERROR_OVERFLOW;
@@ -3035,7 +3090,7 @@
CAM_DBG(CAM_ISP, "None error (%d)", error_status);
}
- return error_status;
+ return 0;
}
/*
@@ -3100,6 +3155,15 @@
rup_status = hw_res->bottom_half_handler(
hw_res, evt_payload);
}
+
+ if (ife_src_res->is_dual_vfe) {
+ hw_res = ife_src_res->hw_res[0];
+ if (core_idx == hw_res->hw_intf->hw_idx) {
+ hw_res->bottom_half_handler(
+ hw_res, evt_payload);
+ }
+ }
+
if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending))
break;
@@ -3115,13 +3179,6 @@
case CAM_ISP_HW_VFE_IN_RDI1:
case CAM_ISP_HW_VFE_IN_RDI2:
case CAM_ISP_HW_VFE_IN_RDI3:
- if (!ife_hwr_mgr_ctx->is_rdi_only_context)
- continue;
-
- /*
- * This is RDI only context, send Reg update and epoch
- * HW event to cam context
- */
hw_res = ife_src_res->hw_res[0];
if (!hw_res) {
@@ -3133,6 +3190,9 @@
rup_status = hw_res->bottom_half_handler(
hw_res, evt_payload);
+ if (!ife_hwr_mgr_ctx->is_rdi_only_context)
+ continue;
+
if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending))
break;
if (!rup_status) {
@@ -3334,8 +3394,6 @@
struct cam_ife_hw_mgr_ctx *ife_hwr_mgr_ctx,
struct cam_vfe_top_irq_evt_payload *evt_payload)
{
- struct cam_isp_hw_sof_event_data sof_done_event_data;
- cam_hw_event_cb_func ife_hwr_irq_sof_cb;
struct cam_isp_resource_node *hw_res_l = NULL;
struct cam_isp_resource_node *hw_res_r = NULL;
int32_t rc = -EINVAL;
@@ -3351,9 +3409,6 @@
CAM_DBG(CAM_ISP, "is_dual_vfe ? = %d",
isp_ife_camif_res->is_dual_vfe);
- ife_hwr_irq_sof_cb =
- ife_hwr_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_SOF];
-
switch (isp_ife_camif_res->is_dual_vfe) {
/* Handling Single VFE Scenario */
case 0:
@@ -3370,16 +3425,8 @@
evt_payload);
if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending))
break;
- if (!sof_status) {
- cam_ife_mgr_cmd_get_sof_timestamp(
- ife_hwr_mgr_ctx,
- &sof_done_event_data.timestamp);
-
- ife_hwr_irq_sof_cb(
- ife_hwr_mgr_ctx->common.cb_priv,
- CAM_ISP_HW_EVENT_SOF,
- &sof_done_event_data);
- }
+ if (!sof_status)
+ rc = 0;
}
break;
@@ -3431,15 +3478,6 @@
rc = cam_ife_hw_mgr_check_irq_for_dual_vfe(ife_hwr_mgr_ctx,
core_index0, core_index1, evt_payload->evt_id);
- if (!rc) {
- cam_ife_mgr_cmd_get_sof_timestamp(
- ife_hwr_mgr_ctx,
- &sof_done_event_data.timestamp);
-
- ife_hwr_irq_sof_cb(ife_hwr_mgr_ctx->common.cb_priv,
- CAM_ISP_HW_EVENT_SOF, &sof_done_event_data);
- }
-
break;
default:
@@ -3449,14 +3487,13 @@
CAM_DBG(CAM_ISP, "Exit (sof_status = %d)", sof_status);
- return 0;
+ return rc;
}
static int cam_ife_hw_mgr_handle_sof(
void *handler_priv,
void *payload)
{
- int32_t rc = -EINVAL;
struct cam_isp_resource_node *hw_res = NULL;
struct cam_ife_hw_mgr_ctx *ife_hw_mgr_ctx;
struct cam_vfe_top_irq_evt_payload *evt_payload;
@@ -3464,6 +3501,7 @@
cam_hw_event_cb_func ife_hw_irq_sof_cb;
struct cam_isp_hw_sof_event_data sof_done_event_data;
uint32_t sof_status = 0;
+ bool sof_sent = false;
CAM_DBG(CAM_ISP, "Enter");
@@ -3489,13 +3527,13 @@
case CAM_ISP_HW_VFE_IN_RDI1:
case CAM_ISP_HW_VFE_IN_RDI2:
case CAM_ISP_HW_VFE_IN_RDI3:
+ hw_res = ife_src_res->hw_res[0];
+ sof_status = hw_res->bottom_half_handler(
+ hw_res, evt_payload);
+
/* check if it is rdi only context */
if (ife_hw_mgr_ctx->is_rdi_only_context) {
- hw_res = ife_src_res->hw_res[0];
- sof_status = hw_res->bottom_half_handler(
- hw_res, evt_payload);
-
- if (!sof_status) {
+ if (!sof_status && !sof_sent) {
cam_ife_mgr_cmd_get_sof_timestamp(
ife_hw_mgr_ctx,
&sof_done_event_data.timestamp);
@@ -3506,16 +3544,30 @@
&sof_done_event_data);
CAM_DBG(CAM_ISP, "sof_status = %d",
sof_status);
+
+ sof_sent = true;
}
- /* this is RDI only context so exit from here */
- return 0;
}
break;
case CAM_ISP_HW_VFE_IN_CAMIF:
- rc = cam_ife_hw_mgr_process_camif_sof(ife_src_res,
- ife_hw_mgr_ctx, evt_payload);
+ sof_status = cam_ife_hw_mgr_process_camif_sof(
+ ife_src_res, ife_hw_mgr_ctx, evt_payload);
+ if (!sof_status && !sof_sent) {
+ cam_ife_mgr_cmd_get_sof_timestamp(
+ ife_hw_mgr_ctx,
+ &sof_done_event_data.timestamp);
+
+ ife_hw_irq_sof_cb(
+ ife_hw_mgr_ctx->common.cb_priv,
+ CAM_ISP_HW_EVENT_SOF,
+ &sof_done_event_data);
+ CAM_DBG(CAM_ISP, "sof_status = %d",
+ sof_status);
+
+ sof_sent = true;
+ }
break;
default:
CAM_ERR(CAM_ISP, "Invalid resource id :%d",
@@ -3832,7 +3884,7 @@
evt_payload = evt_payload_priv;
if (!handler_priv)
- goto put_payload;
+ return rc;
ife_hwr_mgr_ctx = (struct cam_ife_hw_mgr_ctx *)handler_priv;
@@ -3851,8 +3903,8 @@
*/
if (g_ife_hw_mgr.debug_cfg.enable_recovery) {
CAM_DBG(CAM_ISP, "IFE Mgr recovery is enabled");
- rc = cam_ife_hw_mgr_handle_camif_error(ife_hwr_mgr_ctx,
- evt_payload_priv);
+ rc = cam_ife_hw_mgr_handle_camif_error(ife_hwr_mgr_ctx,
+ evt_payload_priv);
} else {
CAM_DBG(CAM_ISP, "recovery is not enabled");
rc = 0;
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
index c418a41..0e678b4 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
@@ -13,6 +13,7 @@
#ifndef _CAM_IFE_HW_MGR_H_
#define _CAM_IFE_HW_MGR_H_
+#include <linux/completion.h>
#include "cam_isp_hw_mgr.h"
#include "cam_vfe_hw_intf.h"
#include "cam_ife_csid_hw_intf.h"
@@ -121,6 +122,7 @@
* @overflow_pending flat to specify the overflow is pending for the
* context
* @is_rdi_only_context flag to specify the context has only rdi resource
+ * @config_done_complete indicator for configuration complete
*/
struct cam_ife_hw_mgr_ctx {
struct list_head list;
@@ -153,6 +155,7 @@
uint32_t eof_cnt[CAM_IFE_HW_NUM_MAX];
atomic_t overflow_pending;
uint32_t is_rdi_only_context;
+ struct completion config_done_complete;
};
/**
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
index b632e77..24df4ce 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -431,11 +431,17 @@
irq_mask = cam_io_r_mb(controller->mem_base +
controller->irq_register_arr[i].
mask_reg_offset);
+ CAM_DBG(CAM_ISP, "irq_mask 0x%x before disable 0x%x",
+ controller->irq_register_arr[i].mask_reg_offset,
+ irq_mask);
irq_mask &= ~(evt_handler->evt_bit_mask_arr[i]);
cam_io_w_mb(irq_mask, controller->mem_base +
controller->irq_register_arr[i].
mask_reg_offset);
+ CAM_DBG(CAM_ISP, "irq_mask 0x%x after disable 0x%x",
+ controller->irq_register_arr[i].mask_reg_offset,
+ irq_mask);
/* Clear the IRQ bits of this handler */
cam_io_w_mb(evt_handler->evt_bit_mask_arr[i],
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
index 78336d2..2601190 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
@@ -51,6 +51,25 @@
};
/**
+ * enum cam_isp_hw_stop_cmd - Specify the stop command type
+ */
+enum cam_isp_hw_stop_cmd {
+ CAM_ISP_HW_STOP_AT_FRAME_BOUNDARY,
+ CAM_ISP_HW_STOP_IMMEDIATELY,
+ CAM_ISP_HW_STOP_MAX,
+};
+
+/**
+ * struct cam_isp_stop_hw_method - hardware stop method
+ *
+ * @hw_stop_cmd: Hardware stop command type information
+ *
+ */
+struct cam_isp_stop_hw_method {
+ enum cam_isp_hw_stop_cmd hw_stop_cmd;
+};
+
+/**
* struct cam_isp_bw_config_internal - Internal Bandwidth configuration
*
* @usage_type: Usage type (Single/Dual)
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
index 1359f78..328aaaf 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
@@ -30,7 +30,7 @@
/* Timeout values in usec */
#define CAM_IFE_CSID_TIMEOUT_SLEEP_US 1000
-#define CAM_IFE_CSID_TIMEOUT_ALL_US 1000000
+#define CAM_IFE_CSID_TIMEOUT_ALL_US 100000
/*
* Constant Factors needed to change QTimer ticks to nanoseconds
@@ -355,8 +355,7 @@
struct cam_hw_soc_info *soc_info;
struct cam_ife_csid_reg_offset *csid_reg;
int rc = 0;
- uint32_t i, irq_mask_rx, irq_mask_ipp = 0,
- irq_mask_rdi[CAM_IFE_CSID_RDI_MAX];
+ uint32_t val = 0, i;
soc_info = &csid_hw->hw_info->soc_info;
csid_reg = csid_hw->csid_info->csid_reg;
@@ -373,19 +372,6 @@
init_completion(&csid_hw->csid_top_complete);
- /* Save interrupt mask registers values*/
- irq_mask_rx = cam_io_r_mb(soc_info->reg_map[0].mem_base +
- csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
-
- if (csid_reg->cmn_reg->no_pix)
- irq_mask_ipp = cam_io_r_mb(soc_info->reg_map[0].mem_base +
- csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
-
- for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
- irq_mask_rdi[i] = cam_io_r_mb(soc_info->reg_map[0].mem_base +
- csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
- }
-
/* Mask all interrupts */
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
@@ -448,17 +434,11 @@
rc = 0;
}
- /*restore all interrupt masks */
- cam_io_w_mb(irq_mask_rx, soc_info->reg_map[0].mem_base +
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
-
- if (csid_reg->cmn_reg->no_pix)
- cam_io_w_mb(irq_mask_ipp, soc_info->reg_map[0].mem_base +
- csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
-
- for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
- cam_io_w_mb(irq_mask_rdi[i], soc_info->reg_map[0].mem_base +
- csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
+ if (val != 0)
+ CAM_ERR(CAM_ISP, "CSID:%d IRQ value after reset rc = %d",
+ csid_hw->hw_intf->hw_idx, val);
return rc;
}
@@ -1058,6 +1038,10 @@
soc_info = &csid_hw->hw_info->soc_info;
csid_reg = csid_hw->csid_info->csid_reg;
+ CAM_DBG(CAM_ISP, "%s:Calling Global Reset\n", __func__);
+ cam_ife_csid_global_reset(csid_hw);
+ CAM_DBG(CAM_ISP, "%s:Global Reset Done\n", __func__);
+
CAM_DBG(CAM_ISP, "CSID:%d De-init CSID HW",
csid_hw->hw_intf->hw_idx);
@@ -1516,7 +1500,6 @@
struct cam_isp_resource_node *res)
{
int rc = 0;
- uint32_t val = 0;
struct cam_ife_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
@@ -1538,13 +1521,6 @@
rc = -EINVAL;
}
- /* Disable the IPP path */
- val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
- csid_reg->ipp_reg->csid_ipp_cfg0_addr);
- val &= ~(1 << csid_reg->cmn_reg->path_en_shift_val);
- cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
- csid_reg->ipp_reg->csid_ipp_cfg0_addr);
-
res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
return rc;
}
@@ -1615,7 +1591,6 @@
enum cam_ife_csid_halt_cmd stop_cmd)
{
int rc = 0;
- uint32_t val = 0;
struct cam_ife_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
struct cam_ife_csid_path_cfg *path_data;
@@ -1661,19 +1636,8 @@
CAM_DBG(CAM_ISP, "CSID:%d res_id:%d",
csid_hw->hw_intf->hw_idx, res->res_id);
- if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
- /* configure Halt */
- val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
- csid_reg->ipp_reg->csid_ipp_ctrl_addr);
- val &= ~0x3;
- val |= stop_cmd;
- cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
- csid_reg->ipp_reg->csid_ipp_ctrl_addr);
- } else if (path_data->sync_mode == CAM_ISP_HW_SYNC_NONE)
- cam_io_w_mb(stop_cmd, soc_info->reg_map[0].mem_base +
- csid_reg->ipp_reg->csid_ipp_ctrl_addr);
-
- /* For slave mode, halt command should take it from master */
+ cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
+ csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
return rc;
}
@@ -1815,7 +1779,7 @@
struct cam_isp_resource_node *res)
{
int rc = 0;
- uint32_t val = 0, id;
+ uint32_t id;
struct cam_ife_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
@@ -1832,13 +1796,6 @@
return -EINVAL;
}
- /* Disable the RDI path */
- val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
- csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
- val &= ~(1 << csid_reg->cmn_reg->path_en_shift_val);
- cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
- csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
-
res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
return rc;
}
@@ -1935,9 +1892,8 @@
CAM_DBG(CAM_ISP, "CSID:%d res_id:%d",
csid_hw->hw_intf->hw_idx, res->res_id);
- /*Halt the RDI path */
- cam_io_w_mb(stop_cmd, soc_info->reg_map[0].mem_base +
- csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
+ cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
+ csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
return rc;
}
@@ -2014,79 +1970,6 @@
return 0;
}
-static int cam_ife_csid_res_wait_for_halt(
- struct cam_ife_csid_hw *csid_hw,
- struct cam_isp_resource_node *res)
-{
- int rc = 0;
- uint32_t val = 0, id, status, path_status_reg;
- struct cam_ife_csid_reg_offset *csid_reg;
- struct cam_hw_soc_info *soc_info;
-
- csid_reg = csid_hw->csid_info->csid_reg;
- soc_info = &csid_hw->hw_info->soc_info;
-
- if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d Invalid res id%d",
- csid_hw->hw_intf->hw_idx, res->res_id);
- return -EINVAL;
- }
-
- if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
- res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
- CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d Res:%d already in stopped state:%d",
- csid_hw->hw_intf->hw_idx,
- res->res_id, res->res_state);
- return rc;
- }
-
- if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
- CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d Res:%d Invalid state%d",
- csid_hw->hw_intf->hw_idx, res->res_id,
- res->res_state);
- return -EINVAL;
- }
-
- if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
- path_status_reg = csid_reg->ipp_reg->csid_ipp_status_addr;
- else
- path_status_reg = csid_reg->rdi_reg[res->res_id]->
- csid_rdi_status_addr;
-
- rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
- path_status_reg, status,
- (status == 1),
- CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
- if (rc < 0) {
- CAM_ERR(CAM_ISP, "Time out: Res id:%d Path has not halted",
- res->res_id);
- rc = -ETIMEDOUT;
- }
-
- /* Disable the interrupt */
- if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
- val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
- csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
- val &= ~(CSID_PATH_INFO_INPUT_EOF | CSID_PATH_INFO_RST_DONE |
- CSID_PATH_ERROR_FIFO_OVERFLOW);
- cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
- csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
- } else {
- id = res->res_id;
- val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
- csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
- val &= ~(CSID_PATH_INFO_INPUT_EOF | CSID_PATH_INFO_RST_DONE |
- CSID_PATH_ERROR_FIFO_OVERFLOW);
- cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
- csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
- }
- /* set state to init HW */
- res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
- return rc;
-}
-
static int cam_ife_csid_get_hw_caps(void *hw_priv,
void *get_hw_cap_args, uint32_t arg_size)
{
@@ -2307,7 +2190,6 @@
return rc;
}
-
static int cam_ife_csid_init_hw(void *hw_priv,
void *init_args, uint32_t arg_size)
{
@@ -2379,7 +2261,6 @@
rc = cam_ife_csid_reset_retain_sw_reg(csid_hw);
if (rc < 0) {
CAM_ERR(CAM_ISP, "CSID: Failed in SW reset");
- return rc;
}
if (rc)
@@ -2403,6 +2284,7 @@
return -EINVAL;
}
+ CAM_DBG(CAM_ISP, "Enter");
res = (struct cam_isp_resource_node *)deinit_args;
csid_hw_info = (struct cam_hw_info *)hw_priv;
csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
@@ -2417,9 +2299,11 @@
switch (res->res_type) {
case CAM_ISP_RESOURCE_CID:
+ CAM_DBG(CAM_ISP, "De-Init ife_csid");
rc = cam_ife_csid_disable_csi2(csid_hw, res);
break;
case CAM_ISP_RESOURCE_PIX_PATH:
+ CAM_DBG(CAM_ISP, "De-Init Pix Path: %d\n", res->res_id);
if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
rc = cam_ife_csid_deinit_ipp_path(csid_hw, res);
else
@@ -2434,7 +2318,9 @@
}
/* Disable CSID HW */
+ CAM_DBG(CAM_ISP, "Disabling CSID Hw\n");
cam_ife_csid_disable_hw(csid_hw);
+ CAM_DBG(CAM_ISP, "%s: Exit\n", __func__);
end:
mutex_unlock(&csid_hw->hw_info->hw_mutex);
@@ -2540,16 +2426,13 @@
}
}
- /*wait for the path to halt */
for (i = 0; i < csid_stop->num_res; i++) {
res = csid_stop->node_res[i];
- if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
- csid_stop->stop_cmd == CAM_CSID_HALT_AT_FRAME_BOUNDARY)
- rc = cam_ife_csid_res_wait_for_halt(csid_hw, res);
- else
- res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
+ res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
}
+ CAM_DBG(CAM_ISP, "%s: Exit\n", __func__);
+
return rc;
}
@@ -2602,35 +2485,8 @@
}
-static int cam_ife_csid_halt_device(
- struct cam_ife_csid_hw *csid_hw)
-{
- uint32_t i;
- int rc = 0;
- struct cam_isp_resource_node *res_node;
-
- res_node = &csid_hw->ipp_res;
- if (res_node->res_state == CAM_ISP_RESOURCE_STATE_STREAMING) {
- rc = cam_ife_csid_disable_ipp_path(csid_hw,
- res_node, CAM_CSID_HALT_IMMEDIATELY);
- res_node->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
- }
-
- for (i = 0; i < CAM_IFE_CSID_RDI_MAX; i++) {
- res_node = &csid_hw->rdi_res[i];
- if (res_node->res_state == CAM_ISP_RESOURCE_STATE_STREAMING) {
- rc = cam_ife_csid_disable_rdi_path(csid_hw,
- res_node, CAM_CSID_HALT_IMMEDIATELY);
- res_node->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
- }
- }
- return rc;
-}
-
-
irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
{
- int rc = 0;
struct cam_ife_csid_hw *csid_hw;
struct cam_hw_soc_info *soc_info;
struct cam_ife_csid_reg_offset *csid_reg;
@@ -2704,52 +2560,22 @@
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 0 over flow",
csid_hw->hw_intf->hw_idx);
- rc = cam_ife_csid_halt_device(csid_hw);
- if (rc) {
- CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d csid halt device fail rc = %d",
- csid_hw->hw_intf->hw_idx, rc);
- }
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 1 over flow",
csid_hw->hw_intf->hw_idx);
- rc = cam_ife_csid_halt_device(csid_hw);
- if (rc) {
- CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d csid halt device fail rc = %d",
- csid_hw->hw_intf->hw_idx, rc);
- }
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 2 over flow",
csid_hw->hw_intf->hw_idx);
- rc = cam_ife_csid_halt_device(csid_hw);
- if (rc) {
- CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d csid halt device fail rc = %d",
- csid_hw->hw_intf->hw_idx, rc);
- }
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 3 over flow",
csid_hw->hw_intf->hw_idx);
- rc = cam_ife_csid_halt_device(csid_hw);
- if (rc) {
- CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d csid halt device fail rc = %d",
- csid_hw->hw_intf->hw_idx, rc);
- }
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d TG OVER FLOW",
csid_hw->hw_intf->hw_idx);
- rc = cam_ife_csid_halt_device(csid_hw);
- if (rc) {
- CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d csid halt device fail rc = %d",
- csid_hw->hw_intf->hw_idx, rc);
- }
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d CPHY_EOT_RECEPTION",
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
index 4b546ea..681a47f 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
@@ -360,7 +360,6 @@
* @dt: Data type
* @cnt: Cid resource reference count.
* @tpg_set: Tpg used for this cid resource
- * @pixel_count: Pixel resource connected
*
*/
struct cam_ife_csid_cid_data {
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
index b9f6d77..c56c49f 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
@@ -93,6 +93,8 @@
CAM_ISP_HW_CMD_CLOCK_UPDATE,
CAM_ISP_HW_CMD_BW_UPDATE,
CAM_ISP_HW_CMD_BW_CONTROL,
+ CAM_ISP_HW_CMD_STOP_BUS_ERR_IRQ,
+ CAM_ISP_HW_CMD_GET_REG_DUMP,
CAM_ISP_HW_CMD_MAX,
};
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
index 8927d6a..05c3c61 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
@@ -49,6 +49,9 @@
CAM_VFE_IRQ_STATUS_COMP_OWRT = -2,
CAM_VFE_IRQ_STATUS_ERR = -1,
CAM_VFE_IRQ_STATUS_SUCCESS = 0,
+ CAM_VFE_IRQ_STATUS_OVERFLOW = 1,
+ CAM_VFE_IRQ_STATUS_P2I_ERROR = 2,
+ CAM_VFE_IRQ_STATUS_VIOLATION = 3,
CAM_VFE_IRQ_STATUS_MAX,
};
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
index cc897a3..ed728f5 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
@@ -106,7 +106,6 @@
struct cam_vfe_bus_irq_evt_payload evt_payload[
CAM_VFE_BUS_VER2_PAYLOAD_MAX];
struct list_head free_payload_list;
- spinlock_t spin_lock;
struct mutex bus_mutex;
uint32_t secure_mode;
uint32_t num_sec_out;
@@ -215,23 +214,16 @@
struct cam_vfe_bus_ver2_common_data *common_data,
struct cam_vfe_bus_irq_evt_payload **evt_payload)
{
- int rc;
-
- spin_lock(&common_data->spin_lock);
if (list_empty(&common_data->free_payload_list)) {
*evt_payload = NULL;
CAM_ERR_RATE_LIMIT(CAM_ISP, "No free payload");
- rc = -ENODEV;
- goto done;
+ return -ENODEV;
}
*evt_payload = list_first_entry(&common_data->free_payload_list,
struct cam_vfe_bus_irq_evt_payload, list);
list_del_init(&(*evt_payload)->list);
- rc = 0;
-done:
- spin_unlock(&common_data->spin_lock);
- return rc;
+ return 0;
}
static enum cam_vfe_bus_comp_grp_id
@@ -262,7 +254,6 @@
struct cam_vfe_bus_ver2_common_data *common_data = NULL;
uint32_t *ife_irq_regs = NULL;
uint32_t status_reg0, status_reg1, status_reg2;
- unsigned long flags;
if (!core_info) {
CAM_ERR(CAM_ISP, "Invalid param core_info NULL");
@@ -285,14 +276,11 @@
}
common_data = core_info;
-
- spin_lock_irqsave(&common_data->spin_lock, flags);
list_add_tail(&(*evt_payload)->list,
&common_data->free_payload_list);
- spin_unlock_irqrestore(&common_data->spin_lock, flags);
-
*evt_payload = NULL;
+ CAM_DBG(CAM_ISP, "Done");
return 0;
}
@@ -1005,7 +993,6 @@
rsrc_data->width = rsrc_data->width * 2;
rsrc_data->stride = rsrc_data->width;
rsrc_data->en_cfg = 0x1;
-
/* LSB aligned */
rsrc_data->pack_fmt |= 0x10;
} else {
@@ -1112,7 +1099,12 @@
/* enable ubwc if needed*/
if (rsrc_data->en_ubwc) {
- cam_io_w_mb(0x1, common_data->mem_base +
+ int val = cam_io_r_mb(common_data->mem_base +
+ rsrc_data->hw_regs->ubwc_regs->mode_cfg);
+ CAM_DBG(CAM_ISP, "ubwc reg %d, res id %d",
+ val, rsrc_data->index);
+ val |= 0x1;
+ cam_io_w_mb(val, common_data->mem_base +
rsrc_data->hw_regs->ubwc_regs->mode_cfg);
}
@@ -1144,9 +1136,7 @@
rsrc_data->common_data;
/* Disble WM */
- cam_io_w_mb(0x0,
- common_data->mem_base + rsrc_data->hw_regs->cfg);
-
+ /* Disable all register access, reply on global reset */
CAM_DBG(CAM_ISP, "irq_enabled %d", rsrc_data->irq_enabled);
/* Unsubscribe IRQ */
if (rsrc_data->irq_enabled)
@@ -1154,10 +1144,6 @@
common_data->bus_irq_controller,
wm_res->irq_handle);
- /* Halt & Reset WM */
- cam_io_w_mb(BIT(rsrc_data->index),
- common_data->mem_base + common_data->common_reg->sw_reset);
-
wm_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
rsrc_data->init_cfg_done = false;
rsrc_data->hfr_cfg_done = false;
@@ -1188,8 +1174,6 @@
rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
if (rc) {
CAM_ERR_RATE_LIMIT(CAM_ISP,
- "No tasklet_cmd is free in queue");
- CAM_ERR_RATE_LIMIT(CAM_ISP,
"IRQ status_0 = 0x%x status_1 = 0x%x status_2 = 0x%x",
th_payload->evt_status_arr[0],
th_payload->evt_status_arr[1],
@@ -1601,7 +1585,6 @@
static int cam_vfe_bus_stop_comp_grp(struct cam_isp_resource_node *comp_grp)
{
int rc = 0;
- uint32_t addr_sync_cfg;
struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
comp_grp->res_priv;
struct cam_vfe_bus_ver2_common_data *common_data =
@@ -1617,51 +1600,6 @@
common_data->bus_irq_controller,
comp_grp->irq_handle);
}
-
- cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
- rsrc_data->hw_regs->comp_mask);
- if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
- rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5) {
-
- int dual_comp_grp = (rsrc_data->comp_grp_type -
- CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
-
- if (rsrc_data->is_master) {
- int intra_client_en = cam_io_r_mb(
- common_data->mem_base +
- common_data->common_reg->dual_master_comp_cfg);
-
- /*
- * 2 Bits per comp_grp. Hence left shift by
- * comp_grp * 2
- */
- intra_client_en &=
- ~(rsrc_data->intra_client_mask <<
- dual_comp_grp * 2);
-
- cam_io_w_mb(intra_client_en, common_data->mem_base +
- common_data->common_reg->dual_master_comp_cfg);
- }
-
- addr_sync_cfg = cam_io_r_mb(common_data->mem_base +
- common_data->common_reg->addr_sync_cfg);
- addr_sync_cfg &= ~(1 << dual_comp_grp);
- addr_sync_cfg &= ~(CAM_VFE_BUS_INTRA_CLIENT_MASK <<
- ((dual_comp_grp * 2) +
- CAM_VFE_BUS_ADDR_SYNC_INTRA_CLIENT_SHIFT));
- cam_io_w_mb(addr_sync_cfg, common_data->mem_base +
- common_data->common_reg->addr_sync_cfg);
-
- cam_io_w_mb(0, common_data->mem_base +
- rsrc_data->hw_regs->addr_sync_mask);
- common_data->addr_no_sync |= rsrc_data->composite_mask;
- cam_io_w_mb(common_data->addr_no_sync, common_data->mem_base +
- common_data->common_reg->addr_sync_no_sync);
- CAM_DBG(CAM_ISP, "addr_sync_cfg: 0x% addr_no_sync_cfg: 0x%x",
- addr_sync_cfg, common_data->addr_no_sync);
-
- }
-
comp_grp->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
return rc;
@@ -2208,6 +2146,7 @@
struct cam_isp_resource_node *vfe_out = handler_priv;
struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
+ CAM_DBG(CAM_ISP, "vfe_out %d", rsrc_data->out_type);
/*
* If this resource has Composite Group then we only handle
* Composite done. We acquire Composite if number of WM > 1.
@@ -2328,11 +2267,13 @@
struct cam_irq_th_payload *th_payload)
{
int i = 0;
- struct cam_vfe_bus_ver2_priv *bus_priv = th_payload->handler_priv;
+ struct cam_vfe_bus_ver2_priv *bus_priv =
+ th_payload->handler_priv;
CAM_ERR_RATE_LIMIT(CAM_ISP, "Bus Err IRQ");
for (i = 0; i < th_payload->num_registers; i++) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "IRQ_Status%d: 0x%x", i,
+ CAM_ERR_RATE_LIMIT(CAM_ISP, "vfe:%d: IRQ_Status%d: 0x%x",
+ bus_priv->common_data.core_index, i,
th_payload->evt_status_arr[i]);
}
cam_irq_controller_disable_irq(bus_priv->common_data.bus_irq_controller,
@@ -2842,29 +2783,34 @@
void *deinit_hw_args, uint32_t arg_size)
{
struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
- int rc;
+ int rc = 0;
- if (!bus_priv || (bus_priv->irq_handle <= 0) ||
- (bus_priv->error_irq_handle <= 0)) {
+ if (!bus_priv) {
CAM_ERR(CAM_ISP, "Error: Invalid args");
return -EINVAL;
}
- rc = cam_irq_controller_unsubscribe_irq(
- bus_priv->common_data.bus_irq_controller,
- bus_priv->error_irq_handle);
- if (rc)
- CAM_ERR(CAM_ISP, "Failed to unsubscribe error irq rc=%d", rc);
+ if (bus_priv->error_irq_handle) {
+ rc = cam_irq_controller_unsubscribe_irq(
+ bus_priv->common_data.bus_irq_controller,
+ bus_priv->error_irq_handle);
+ if (rc)
+ CAM_ERR(CAM_ISP,
+ "Failed to unsubscribe error irq rc=%d", rc);
- bus_priv->error_irq_handle = 0;
+ bus_priv->error_irq_handle = 0;
+ }
- rc = cam_irq_controller_unsubscribe_irq(
- bus_priv->common_data.vfe_irq_controller,
- bus_priv->irq_handle);
- if (rc)
- CAM_ERR(CAM_ISP, "Failed to unsubscribe irq rc=%d", rc);
+ if (bus_priv->irq_handle) {
+ rc = cam_irq_controller_unsubscribe_irq(
+ bus_priv->common_data.vfe_irq_controller,
+ bus_priv->irq_handle);
+ if (rc)
+ CAM_ERR(CAM_ISP,
+ "Failed to unsubscribe irq rc=%d", rc);
- bus_priv->irq_handle = 0;
+ bus_priv->irq_handle = 0;
+ }
return rc;
}
@@ -2880,6 +2826,7 @@
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
{
int rc = -EINVAL;
+ struct cam_vfe_bus_ver2_priv *bus_priv;
if (!priv || !cmd_args) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid input arguments");
@@ -2899,6 +2846,21 @@
case CAM_ISP_HW_CMD_STRIPE_UPDATE:
rc = cam_vfe_bus_update_stripe_cfg(priv, cmd_args, arg_size);
break;
+ case CAM_ISP_HW_CMD_STOP_BUS_ERR_IRQ:
+ bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
+ if (bus_priv->error_irq_handle) {
+ CAM_INFO(CAM_ISP, "Mask off bus error irq handler");
+ rc = cam_irq_controller_unsubscribe_irq(
+ bus_priv->common_data.bus_irq_controller,
+ bus_priv->error_irq_handle);
+ if (rc)
+ CAM_ERR(CAM_ISP,
+ "Failed to unsubscribe error irq rc=%d",
+ rc);
+
+ bus_priv->error_irq_handle = 0;
+ }
+ break;
default:
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
cmd_type);
@@ -3001,7 +2963,6 @@
}
}
- spin_lock_init(&bus_priv->common_data.spin_lock);
INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++) {
INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
index b748bc8..734cbdb 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
@@ -22,6 +22,7 @@
#include "cam_vfe_camif_ver2.h"
#include "cam_debug_util.h"
#include "cam_cdm_util.h"
+#include "cam_cpas_api.h"
struct cam_vfe_mux_camif_data {
void __iomem *mem_base;
@@ -234,6 +235,11 @@
CAM_DBG(CAM_ISP, "hw id:%d core_cfg val:%d", camif_res->hw_intf->hw_idx,
val);
+ /* disable the CGC for stats */
+ cam_io_w_mb(0xFFFFFFFF, rsrc_data->mem_base +
+ rsrc_data->common_reg->module_ctrl[
+ CAM_VFE_TOP_VER2_MODULE_STATS]->cgc_ovd);
+
/* epoch config with 20 line */
cam_io_w_mb(rsrc_data->reg_data->epoch_line_cfg,
rsrc_data->mem_base + rsrc_data->camif_reg->epoch_irq);
@@ -248,6 +254,60 @@
return 0;
}
+static int cam_vfe_camif_reg_dump(
+ struct cam_isp_resource_node *camif_res)
+{
+ struct cam_vfe_mux_camif_data *camif_priv;
+ struct cam_vfe_soc_private *soc_private;
+ int rc = 0, i;
+ uint32_t val = 0;
+
+ if (!camif_res) {
+ CAM_ERR(CAM_ISP, "Error! Invalid input arguments");
+ return -EINVAL;
+ }
+
+ if ((camif_res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) ||
+ (camif_res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE))
+ return 0;
+
+ camif_priv = (struct cam_vfe_mux_camif_data *)camif_res->res_priv;
+ soc_private = camif_priv->soc_info->soc_private;
+ for (i = 0xA3C; i <= 0xA90; i += 4) {
+ val = cam_io_r_mb(camif_priv->mem_base + i);
+ CAM_INFO(CAM_ISP, "offset 0x%x val 0x%x", i, val);
+ }
+
+ for (i = 0xE0C; i <= 0xE3C; i += 4) {
+ val = cam_io_r_mb(camif_priv->mem_base + i);
+ CAM_INFO(CAM_ISP, "offset 0x%x val 0x%x", i, val);
+ }
+
+ for (i = 0x2000; i <= 0x20B8; i += 4) {
+ val = cam_io_r_mb(camif_priv->mem_base + i);
+ CAM_INFO(CAM_ISP, "offset 0x%x val 0x%x", i, val);
+ }
+
+ for (i = 0x2500; i <= 0x255C; i += 4) {
+ val = cam_io_r_mb(camif_priv->mem_base + i);
+ CAM_INFO(CAM_ISP, "offset 0x%x val 0x%x", i, val);
+ }
+
+ for (i = 0x2600; i <= 0x265C; i += 4) {
+ val = cam_io_r_mb(camif_priv->mem_base + i);
+ CAM_INFO(CAM_ISP, "offset 0x%x val 0x%x", i, val);
+ }
+
+ cam_cpas_reg_read(soc_private->cpas_handle,
+ CAM_CPAS_REG_CAMNOC, 0x420, true, &val);
+ CAM_INFO(CAM_ISP, "IFE02_MAXWR_LOW offset 0x420 val 0x%x", val);
+
+ cam_cpas_reg_read(soc_private->cpas_handle,
+ CAM_CPAS_REG_CAMNOC, 0x820, true, &val);
+ CAM_INFO(CAM_ISP, "IFE13_MAXWR_LOW offset 0x820 val 0x%x", val);
+
+ return rc;
+}
static int cam_vfe_camif_resource_stop(
struct cam_isp_resource_node *camif_res)
@@ -299,6 +359,9 @@
rc = cam_vfe_camif_get_reg_update(rsrc_node, cmd_args,
arg_size);
break;
+ case CAM_ISP_HW_CMD_GET_REG_DUMP:
+ rc = cam_vfe_camif_reg_dump(rsrc_node);
+ break;
default:
CAM_ERR(CAM_ISP,
"unsupported process command:%d", cmd_type);
@@ -324,8 +387,10 @@
uint32_t irq_status0;
uint32_t irq_status1;
- if (!handler_priv || !evt_payload_priv)
+ if (!handler_priv || !evt_payload_priv) {
+ CAM_ERR(CAM_ISP, "Invalid params");
return ret;
+ }
camif_node = handler_priv;
camif_priv = camif_node->res_priv;
@@ -365,6 +430,7 @@
if (irq_status1 & camif_priv->reg_data->error_irq_mask1) {
CAM_DBG(CAM_ISP, "Received ERROR\n");
ret = CAM_ISP_HW_ERROR_OVERFLOW;
+ cam_vfe_camif_reg_dump(camif_node);
} else {
ret = CAM_ISP_HW_ERROR_NONE;
}
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c
index 50dca827..230698f 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -186,8 +186,10 @@
struct cam_vfe_top_irq_evt_payload *payload;
uint32_t irq_status0;
- if (!handler_priv || !evt_payload_priv)
+ if (!handler_priv || !evt_payload_priv) {
+ CAM_ERR(CAM_ISP, "Invalid params");
return ret;
+ }
rdi_node = handler_priv;
rdi_priv = rdi_node->res_priv;
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
index 3f843c3..976e6d2 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
@@ -34,13 +34,13 @@
struct cam_vfe_top_ver2_common_data common_data;
struct cam_isp_resource_node mux_rsrc[CAM_VFE_TOP_VER2_MUX_MAX];
unsigned long hw_clk_rate;
- enum cam_vfe_bw_control_action axi_vote_control[
- CAM_VFE_TOP_VER2_MUX_MAX];
struct cam_axi_vote to_be_applied_axi_vote;
struct cam_axi_vote applied_axi_vote;
uint32_t counter_to_update_axi_vote;
struct cam_axi_vote req_axi_vote[CAM_VFE_TOP_VER2_MUX_MAX];
unsigned long req_clk_rate[CAM_VFE_TOP_VER2_MUX_MAX];
+ enum cam_vfe_bw_control_action
+ axi_vote_control[CAM_VFE_TOP_VER2_MUX_MAX];
};
static int cam_vfe_top_mux_get_base(struct cam_vfe_top_ver2_priv *top_priv,
@@ -225,9 +225,11 @@
&top_priv->to_be_applied_axi_vote);
if (!rc) {
top_priv->applied_axi_vote.uncompressed_bw =
- top_priv->to_be_applied_axi_vote.uncompressed_bw;
+ top_priv->
+ to_be_applied_axi_vote.uncompressed_bw;
top_priv->applied_axi_vote.compressed_bw =
- top_priv->to_be_applied_axi_vote.compressed_bw;
+ top_priv->
+ to_be_applied_axi_vote.compressed_bw;
} else {
CAM_ERR(CAM_ISP, "BW request failed, rc=%d", rc);
}
@@ -608,6 +610,8 @@
return rc;
}
+ top_priv->hw_clk_rate = 0;
+
rc = cam_vfe_top_set_axi_bw_vote(top_priv, true);
if (rc) {
CAM_ERR(CAM_ISP,
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
index 3e6b856..e66d21d 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
@@ -659,7 +659,7 @@
link->link_hdl, link->sof_counter,
sync_link->sof_counter, sync_diff, link->sync_self_ref);
- if (sync_diff != link->sync_self_ref) {
+ if (sync_diff > SYNC_LINK_SOF_CNT_MAX_LMT) {
link->sync_link->frame_skip_flag = true;
CAM_WARN(CAM_CRM,
"Detected anomaly, skip link_hdl %x self_counter=%lld other_counter=%lld sync_self_ref=%lld",
@@ -703,6 +703,16 @@
link->link_hdl, req_id, link->sync_self_ref, link->sof_counter,
link->frame_skip_flag, link->sync_link->sync_self_ref);
+ if (sync_link->sync_link_sof_skip) {
+ CAM_DBG(CAM_CRM,
+ "No req applied on corresponding SOF on sync link: %x",
+ sync_link->link_hdl);
+ sync_link->sync_link_sof_skip = false;
+ /*It is to manage compensate inject delay for each pd*/
+ __cam_req_mgr_check_link_is_ready(link, slot->idx, true, true);
+ return -EINVAL;
+ }
+
if (link->sof_counter == -1) {
__cam_req_mgr_sof_cnt_initialize(link);
} else if ((link->frame_skip_flag) &&
@@ -720,6 +730,7 @@
CAM_DBG(CAM_CRM,
"Req: %lld [My link]not available link: %x, rc=%d",
req_id, link->link_hdl, rc);
+ link->sync_link_sof_skip = true;
goto failure;
}
@@ -768,6 +779,7 @@
"Req: %lld [Other link] not ready to apply on link: %x",
req_id, sync_link->link_hdl);
rc = -EPERM;
+ link->sync_link_sof_skip = true;
goto failure;
}
@@ -884,6 +896,9 @@
}
spin_unlock_bh(&link->link_state_spin_lock);
+ if (link->sync_link_sof_skip)
+ link->sync_link_sof_skip = false;
+
if (link->trigger_mask == link->subscribe_event) {
slot->status = CRM_SLOT_STATUS_REQ_APPLIED;
link->trigger_mask = 0;
@@ -2514,11 +2529,13 @@
link1->sof_counter = -1;
link1->sync_self_ref = -1;
link1->frame_skip_flag = false;
+ link1->sync_link_sof_skip = false;
link1->sync_link = link2;
link2->sof_counter = -1;
link2->sync_self_ref = -1;
link2->frame_skip_flag = false;
+ link2->sync_link_sof_skip = false;
link2->sync_link = link1;
cam_session->sync_mode = sync_info->sync_mode;
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h
index e4865b3..e15b3b0 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h
@@ -32,6 +32,8 @@
#define MAX_SYNC_COUNT 65535
+#define SYNC_LINK_SOF_CNT_MAX_LMT 1
+
/**
* enum crm_workq_task_type
* @codes: to identify which type of task is present
@@ -296,6 +298,9 @@
* @sync_self_ref : reference sync count against which the difference
* between sync_counts for a given link is checked
* @frame_skip_flag : flag that determines if a frame needs to be skipped
+ * @sync_link_sof_skip : flag determines if a pkt is not available for a given
+ * frame in a particular link skip corresponding
+ * frame in sync link as well.
*
*/
struct cam_req_mgr_core_link {
@@ -318,6 +323,7 @@
int64_t sof_counter;
int64_t sync_self_ref;
bool frame_skip_flag;
+ bool sync_link_sof_skip;
};
/**
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c
index bfeee6a..b975418 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c
@@ -473,6 +473,10 @@
if (cmd->reg_addr + 1 ==
(cmd+1)->reg_addr) {
len += data_len;
+ if (len > cci_dev->payload_size) {
+ len = len - data_len;
+ break;
+ }
(*pack)++;
} else {
break;
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
index 23d25a4..e7110b8 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -271,8 +271,8 @@
static int delete_req(struct cam_flash_ctrl *fctrl, uint64_t req_id)
{
int i = 0;
- int frame_offset = 0;
struct cam_flash_frame_setting *flash_data = NULL;
+ uint64_t top = 0, del_req_id = 0;
if (req_id == 0) {
flash_data = &fctrl->nrt_info;
@@ -288,14 +288,52 @@
is_settings_valid = false;
}
} else {
- frame_offset = (req_id + MAX_PER_FRAME_ARRAY -
- CAM_FLASH_PIPELINE_DELAY) % 8;
- flash_data = &fctrl->per_frame[frame_offset];
- if (req_id > flash_data->cmn_attr.request_id) {
- flash_data->cmn_attr.request_id = 0;
- flash_data->cmn_attr.is_settings_valid = false;
- for (i = 0; i < flash_data->cmn_attr.count; i++)
- flash_data->led_current_ma[i] = 0;
+ for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
+ flash_data = &fctrl->per_frame[i];
+ if (req_id >= flash_data->cmn_attr.request_id &&
+ flash_data->cmn_attr.is_settings_valid
+ == 1) {
+ if (top < flash_data->cmn_attr.request_id) {
+ del_req_id = top;
+ top = flash_data->cmn_attr.request_id;
+ } else if (top >
+ flash_data->cmn_attr.request_id &&
+ del_req_id <
+ flash_data->cmn_attr.request_id) {
+ del_req_id =
+ flash_data->cmn_attr.request_id;
+ }
+ }
+ }
+
+ if (top < req_id) {
+ if ((((top % MAX_PER_FRAME_ARRAY) - (req_id %
+ MAX_PER_FRAME_ARRAY)) >= BATCH_SIZE_MAX) ||
+ (((top % MAX_PER_FRAME_ARRAY) - (req_id %
+ MAX_PER_FRAME_ARRAY)) <= -BATCH_SIZE_MAX))
+ del_req_id = req_id;
+ }
+
+ if (!del_req_id)
+ return 0;
+
+ CAM_DBG(CAM_FLASH, "top: %llu, del_req_id:%llu",
+ top, del_req_id);
+
+ for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
+ flash_data = &fctrl->per_frame[i];
+ if ((del_req_id ==
+ flash_data->cmn_attr.request_id) &&
+ (flash_data->cmn_attr.
+ is_settings_valid == 1)) {
+ CAM_DBG(CAM_FLASH, "Deleting request[%d] %llu",
+ i, flash_data->cmn_attr.request_id);
+ flash_data->cmn_attr.request_id = 0;
+ flash_data->cmn_attr.is_settings_valid = false;
+ flash_data->opcode = 0;
+ for (i = 0; i < flash_data->cmn_attr.count; i++)
+ flash_data->led_current_ma[i] = 0;
+ }
}
}
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c
index db80584..3a0a6d6 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -299,6 +299,7 @@
uint16_t total_bytes = 0;
uint8_t *ptr = NULL;
int32_t rc = 0, cnt;
+ uint32_t fw_size;
const struct firmware *fw = NULL;
const char *fw_name_prog = NULL;
const char *fw_name_coeff = NULL;
@@ -306,6 +307,7 @@
char name_coeff[32] = {0};
struct device *dev = &(o_ctrl->pdev->dev);
struct cam_sensor_i2c_reg_setting i2c_reg_setting;
+ struct page *page = NULL;
if (!o_ctrl) {
CAM_ERR(CAM_OIS, "Invalid Args");
@@ -331,15 +333,20 @@
i2c_reg_setting.addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE;
i2c_reg_setting.data_type = CAMERA_SENSOR_I2C_TYPE_BYTE;
i2c_reg_setting.size = total_bytes;
- i2c_reg_setting.reg_setting = (struct cam_sensor_i2c_reg_array *)
- kzalloc(sizeof(struct cam_sensor_i2c_reg_array) * total_bytes,
- GFP_KERNEL);
- if (!i2c_reg_setting.reg_setting) {
+ i2c_reg_setting.delay = 0;
+ fw_size = PAGE_ALIGN(sizeof(struct cam_sensor_i2c_reg_array) *
+ total_bytes) >> PAGE_SHIFT;
+ page = cma_alloc(dev_get_cma_area((o_ctrl->soc_info.dev)),
+ fw_size, 0);
+ if (!page) {
CAM_ERR(CAM_OIS, "Failed in allocating i2c_array");
release_firmware(fw);
return -ENOMEM;
}
+ i2c_reg_setting.reg_setting = (struct cam_sensor_i2c_reg_array *)(
+ page_address(page));
+
for (cnt = 0, ptr = (uint8_t *)fw->data; cnt < total_bytes;
cnt++, ptr++) {
i2c_reg_setting.reg_setting[cnt].reg_addr =
@@ -355,7 +362,10 @@
CAM_ERR(CAM_OIS, "OIS FW download failed %d", rc);
goto release_firmware;
}
- kfree(i2c_reg_setting.reg_setting);
+ cma_release(dev_get_cma_area((o_ctrl->soc_info.dev)),
+ page, fw_size);
+ page = NULL;
+ fw_size = 0;
release_firmware(fw);
rc = request_firmware(&fw, fw_name_coeff, dev);
@@ -368,15 +378,20 @@
i2c_reg_setting.addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE;
i2c_reg_setting.data_type = CAMERA_SENSOR_I2C_TYPE_BYTE;
i2c_reg_setting.size = total_bytes;
- i2c_reg_setting.reg_setting = (struct cam_sensor_i2c_reg_array *)
- kzalloc(sizeof(struct cam_sensor_i2c_reg_array) * total_bytes,
- GFP_KERNEL);
- if (!i2c_reg_setting.reg_setting) {
+ i2c_reg_setting.delay = 0;
+ fw_size = PAGE_ALIGN(sizeof(struct cam_sensor_i2c_reg_array) *
+ total_bytes) >> PAGE_SHIFT;
+ page = cma_alloc(dev_get_cma_area((o_ctrl->soc_info.dev)),
+ fw_size, 0);
+ if (!page) {
CAM_ERR(CAM_OIS, "Failed in allocating i2c_array");
release_firmware(fw);
return -ENOMEM;
}
+ i2c_reg_setting.reg_setting = (struct cam_sensor_i2c_reg_array *)(
+ page_address(page));
+
for (cnt = 0, ptr = (uint8_t *)fw->data; cnt < total_bytes;
cnt++, ptr++) {
i2c_reg_setting.reg_setting[cnt].reg_addr =
@@ -392,7 +407,8 @@
CAM_ERR(CAM_OIS, "OIS FW download failed %d", rc);
release_firmware:
- kfree(i2c_reg_setting.reg_setting);
+ cma_release(dev_get_cma_area((o_ctrl->soc_info.dev)),
+ page, fw_size);
release_firmware(fw);
return rc;
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.h
index 516ac88..d6f0ec5 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -12,6 +12,8 @@
#ifndef _CAM_OIS_CORE_H_
#define _CAM_OIS_CORE_H_
+#include <linux/cma.h>
+#include <linux/dma-contiguous.h>
#include "cam_ois_dev.h"
/**
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
index 3066a91..5a1b67c 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
@@ -193,8 +193,9 @@
&i2c_data->
per_frame[csl_packet->header.request_id %
MAX_PER_FRAME_ARRAY];
- CAM_DBG(CAM_SENSOR, "Received Packet: %lld",
- csl_packet->header.request_id % MAX_PER_FRAME_ARRAY);
+ CAM_DBG(CAM_SENSOR, "Received Packet: %lld req: %lld",
+ csl_packet->header.request_id % MAX_PER_FRAME_ARRAY,
+ csl_packet->header.request_id);
if (i2c_reg_settings->is_settings_valid == 1) {
CAM_ERR(CAM_SENSOR,
"Already some pkt in offset req : %lld",
@@ -1010,7 +1011,8 @@
int cam_sensor_apply_settings(struct cam_sensor_ctrl_t *s_ctrl,
int64_t req_id, enum cam_sensor_packet_opcodes opcode)
{
- int rc = 0, offset, del_req_id;
+ int rc = 0, offset, i;
+ uint64_t top = 0, del_req_id = 0;
struct i2c_settings_array *i2c_set = NULL;
struct i2c_settings_list *i2c_list;
@@ -1073,21 +1075,46 @@
"Invalid/NOP request to apply: %lld", req_id);
}
- del_req_id = (req_id + MAX_PER_FRAME_ARRAY -
- MAX_SYSTEM_PIPELINE_DELAY) % MAX_PER_FRAME_ARRAY;
- CAM_DBG(CAM_SENSOR, "Deleting the Request: %d", del_req_id);
-
- if ((req_id >
- s_ctrl->i2c_data.per_frame[del_req_id].request_id) &&
- (s_ctrl->i2c_data.per_frame[del_req_id].
+ /* Change the logic dynamically */
+ for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
+ if ((req_id >=
+ s_ctrl->i2c_data.per_frame[i].request_id) &&
+ (top <
+ s_ctrl->i2c_data.per_frame[i].request_id) &&
+ (s_ctrl->i2c_data.per_frame[i].
is_settings_valid == 1)) {
- s_ctrl->i2c_data.per_frame[del_req_id].request_id = 0;
- rc = delete_request(
- &(s_ctrl->i2c_data.per_frame[del_req_id]));
- if (rc < 0)
- CAM_ERR(CAM_SENSOR,
- "Delete request Fail:%d rc:%d",
- del_req_id, rc);
+ del_req_id = top;
+ top = s_ctrl->i2c_data.per_frame[i].request_id;
+ }
+ }
+
+ if (top < req_id) {
+ if ((((top % MAX_PER_FRAME_ARRAY) - (req_id %
+ MAX_PER_FRAME_ARRAY)) >= BATCH_SIZE_MAX) ||
+ (((top % MAX_PER_FRAME_ARRAY) - (req_id %
+ MAX_PER_FRAME_ARRAY)) <= -BATCH_SIZE_MAX))
+ del_req_id = req_id;
+ }
+
+ if (!del_req_id)
+ return rc;
+
+ CAM_DBG(CAM_SENSOR, "top: %llu, del_req_id:%llu",
+ top, del_req_id);
+
+ for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
+ if ((del_req_id >
+ s_ctrl->i2c_data.per_frame[i].request_id) &&
+ (s_ctrl->i2c_data.per_frame[i].
+ is_settings_valid == 1)) {
+ s_ctrl->i2c_data.per_frame[i].request_id = 0;
+ rc = delete_request(
+ &(s_ctrl->i2c_data.per_frame[i]));
+ if (rc < 0)
+ CAM_ERR(CAM_SENSOR,
+ "Delete request Fail:%lld rc:%d",
+ del_req_id, rc);
+ }
}
}
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_spi.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_spi.c
index 07b390b..626b263 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_spi.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_spi.c
@@ -112,31 +112,49 @@
{
int32_t rc = -EINVAL;
struct spi_device *spi = client->spi_client->spi_master;
+ struct device *dev = NULL;
char *ctx = NULL, *crx = NULL;
uint32_t len, hlen;
uint8_t retries = client->spi_client->retries;
+ uint32_t txr = 0, rxr = 0;
+ struct page *page_tx = NULL, *page_rx = NULL;
hlen = cam_camera_spi_get_hlen(inst);
len = hlen + num_byte;
+ dev = &(spi->dev);
+
+ if (!dev) {
+ CAM_ERR(CAM_SENSOR, "Invalid arguments");
+ return -EINVAL;
+ }
if (tx) {
ctx = tx;
} else {
- ctx = kzalloc(len, GFP_KERNEL | GFP_DMA);
- if (!ctx)
+ txr = PAGE_ALIGN(len) >> PAGE_SHIFT;
+ page_tx = cma_alloc(dev_get_cma_area(dev),
+ txr, 0);
+ if (!page_tx)
return -ENOMEM;
+
+ ctx = page_address(page_tx);
}
if (num_byte) {
if (rx) {
crx = rx;
} else {
- crx = kzalloc(len, GFP_KERNEL | GFP_DMA);
- if (!crx) {
+ rxr = PAGE_ALIGN(len) >> PAGE_SHIFT;
+ page_rx = cma_alloc(dev_get_cma_area(dev),
+ rxr, 0);
+ if (!page_rx) {
if (!tx)
- kfree(ctx);
+ cma_release(dev_get_cma_area(dev),
+ page_tx, txr);
+
return -ENOMEM;
}
+ crx = page_address(page_rx);
}
} else {
crx = NULL;
@@ -157,9 +175,9 @@
out:
if (!tx)
- kfree(ctx);
+ cma_release(dev_get_cma_area(dev), page_tx, txr);
if (!rx)
- kfree(crx);
+ cma_release(dev_get_cma_area(dev), page_rx, rxr);
return rc;
}
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_spi.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_spi.h
index a63bff2..8ce45d8 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_spi.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_spi.h
@@ -14,6 +14,8 @@
#define _CAM_SENSOR_SPI_H_
#include <linux/spi/spi.h>
+#include <linux/cma.h>
+#include <linux/dma-contiguous.h>
#include <media/cam_sensor.h>
#include "cam_sensor_i2c.h"
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h
index 622dae6..fddff38 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h
@@ -27,6 +27,7 @@
#define MAX_POWER_CONFIG 12
#define MAX_PER_FRAME_ARRAY 32
+#define BATCH_SIZE_MAX 16
#define CAM_SENSOR_NAME "cam-sensor"
#define CAM_ACTUATOR_NAME "cam-actuator"
@@ -318,6 +319,9 @@
CAMERA_1,
CAMERA_2,
CAMERA_3,
+ CAMERA_4,
+ CAMERA_5,
+ CAMERA_6,
MAX_CAMERAS,
};
diff --git a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c
index e04c6b9..0d03df0 100644
--- a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c
+++ b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c
@@ -106,8 +106,11 @@
uint8_t shared_support;
uint8_t io_support;
uint8_t secheap_support;
+ uint8_t qdss_support;
+ dma_addr_t qdss_phy_addr;
bool is_fw_allocated;
bool is_secheap_allocated;
+ bool is_qdss_allocated;
struct scratch_mapping scratch_map;
struct gen_pool *shared_mem_pool;
@@ -117,6 +120,7 @@
struct cam_smmu_region_info shared_info;
struct cam_smmu_region_info io_info;
struct cam_smmu_region_info secheap_info;
+ struct cam_smmu_region_info qdss_info;
struct secheap_buf_info secheap_buf;
struct list_head smmu_buf_list;
@@ -176,6 +180,8 @@
size_t len;
};
+static const char *qdss_region_name = "qdss";
+
static struct cam_iommu_cb_set iommu_cb_set;
static enum dma_data_direction cam_smmu_translate_dir(
@@ -1158,6 +1164,136 @@
}
EXPORT_SYMBOL(cam_smmu_dealloc_firmware);
+int cam_smmu_alloc_qdss(int32_t smmu_hdl,
+ dma_addr_t *iova,
+ size_t *len)
+{
+ int rc;
+ int32_t idx;
+ size_t qdss_len = 0;
+ size_t qdss_start = 0;
+ dma_addr_t qdss_phy_addr;
+ struct iommu_domain *domain;
+
+ if (!iova || !len || (smmu_hdl == HANDLE_INIT)) {
+ CAM_ERR(CAM_SMMU, "Error: Input args are invalid");
+ return -EINVAL;
+ }
+
+ idx = GET_SMMU_TABLE_IDX(smmu_hdl);
+ if (idx < 0 || idx >= iommu_cb_set.cb_num) {
+ CAM_ERR(CAM_SMMU,
+ "Error: handle or index invalid. idx = %d hdl = %x",
+ idx, smmu_hdl);
+ rc = -EINVAL;
+ goto end;
+ }
+
+ if (!iommu_cb_set.cb_info[idx].qdss_support) {
+ CAM_ERR(CAM_SMMU,
+ "QDSS memory not supported for this SMMU handle");
+ rc = -EINVAL;
+ goto end;
+ }
+
+ mutex_lock(&iommu_cb_set.cb_info[idx].lock);
+ if (iommu_cb_set.cb_info[idx].is_qdss_allocated) {
+ CAM_ERR(CAM_SMMU, "Trying to allocate twice");
+ rc = -ENOMEM;
+ goto unlock_and_end;
+ }
+
+ qdss_len = iommu_cb_set.cb_info[idx].qdss_info.iova_len;
+ qdss_start = iommu_cb_set.cb_info[idx].qdss_info.iova_start;
+ qdss_phy_addr = iommu_cb_set.cb_info[idx].qdss_phy_addr;
+ CAM_DBG(CAM_SMMU, "QDSS area len from DT = %zu", qdss_len);
+
+ domain = iommu_cb_set.cb_info[idx].mapping->domain;
+ rc = iommu_map(domain,
+ qdss_start,
+ qdss_phy_addr,
+ qdss_len,
+ IOMMU_READ|IOMMU_WRITE);
+
+ if (rc) {
+ CAM_ERR(CAM_SMMU, "Failed to map QDSS into IOMMU");
+ goto unlock_and_end;
+ }
+
+ iommu_cb_set.cb_info[idx].is_qdss_allocated = true;
+
+ *iova = iommu_cb_set.cb_info[idx].qdss_info.iova_start;
+ *len = qdss_len;
+ mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
+
+ return rc;
+
+unlock_and_end:
+ mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
+end:
+ return rc;
+}
+EXPORT_SYMBOL(cam_smmu_alloc_qdss);
+
+int cam_smmu_dealloc_qdss(int32_t smmu_hdl)
+{
+ int rc = 0;
+ int32_t idx;
+ size_t qdss_len = 0;
+ size_t qdss_start = 0;
+ struct iommu_domain *domain;
+ size_t unmapped = 0;
+
+ if (smmu_hdl == HANDLE_INIT) {
+ CAM_ERR(CAM_SMMU, "Error: Invalid handle");
+ return -EINVAL;
+ }
+
+ idx = GET_SMMU_TABLE_IDX(smmu_hdl);
+ if (idx < 0 || idx >= iommu_cb_set.cb_num) {
+ CAM_ERR(CAM_SMMU,
+ "Error: handle or index invalid. idx = %d hdl = %x",
+ idx, smmu_hdl);
+ rc = -EINVAL;
+ goto end;
+ }
+
+ if (!iommu_cb_set.cb_info[idx].qdss_support) {
+ CAM_ERR(CAM_SMMU,
+ "QDSS memory not supported for this SMMU handle");
+ rc = -EINVAL;
+ goto end;
+ }
+
+ mutex_lock(&iommu_cb_set.cb_info[idx].lock);
+ if (!iommu_cb_set.cb_info[idx].is_qdss_allocated) {
+ CAM_ERR(CAM_SMMU,
+ "Trying to deallocate qdss that is not allocated");
+ rc = -ENOMEM;
+ goto unlock_and_end;
+ }
+
+ qdss_len = iommu_cb_set.cb_info[idx].qdss_info.iova_len;
+ qdss_start = iommu_cb_set.cb_info[idx].qdss_info.iova_start;
+ domain = iommu_cb_set.cb_info[idx].mapping->domain;
+ unmapped = iommu_unmap(domain, qdss_start, qdss_len);
+
+ if (unmapped != qdss_len) {
+ CAM_ERR(CAM_SMMU, "Only %zu unmapped out of total %zu",
+ unmapped,
+ qdss_len);
+ rc = -EINVAL;
+ }
+
+ iommu_cb_set.cb_info[idx].is_qdss_allocated = false;
+
+unlock_and_end:
+ mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
+end:
+ return rc;
+}
+EXPORT_SYMBOL(cam_smmu_dealloc_qdss);
+
int cam_smmu_get_region_info(int32_t smmu_hdl,
enum cam_smmu_region_id region_id,
struct cam_smmu_region_info *region_info)
@@ -3009,6 +3145,7 @@
uint32_t region_start;
uint32_t region_len;
uint32_t region_id;
+ uint32_t qdss_region_phy_addr = 0;
num_regions++;
rc = of_property_read_string(child_node,
@@ -3043,6 +3180,17 @@
return -EINVAL;
}
+ if (strcmp(region_name, qdss_region_name) == 0) {
+ rc = of_property_read_u32(child_node,
+ "qdss-phy-addr", &qdss_region_phy_addr);
+ if (rc < 0) {
+ of_node_put(mem_map_node);
+ CAM_ERR(CAM_SMMU,
+ "Failed to read qdss phy addr");
+ return -EINVAL;
+ }
+ }
+
switch (region_id) {
case CAM_SMMU_REGION_FIRMWARE:
cb->firmware_support = 1;
@@ -3069,6 +3217,12 @@
cb->secheap_info.iova_start = region_start;
cb->secheap_info.iova_len = region_len;
break;
+ case CAM_SMMU_REGION_QDSS:
+ cb->qdss_support = 1;
+ cb->qdss_info.iova_start = region_start;
+ cb->qdss_info.iova_len = region_len;
+ cb->qdss_phy_addr = qdss_region_phy_addr;
+ break;
default:
CAM_ERR(CAM_SMMU,
"Incorrect region id present in DT file: %d",
diff --git a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.h b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.h
index b062258..254e382 100644
--- a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.h
+++ b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.h
@@ -46,7 +46,8 @@
CAM_SMMU_REGION_SHARED,
CAM_SMMU_REGION_SCRATCH,
CAM_SMMU_REGION_IO,
- CAM_SMMU_REGION_SECHEAP
+ CAM_SMMU_REGION_SECHEAP,
+ CAM_SMMU_REGION_QDSS
};
/**
@@ -345,4 +346,26 @@
*/
int cam_smmu_release_sec_heap(int32_t smmu_hdl);
+/**
+ * @brief Allocates qdss for context bank
+ *
+ * @param smmu_hdl: SMMU handle identifying context bank
+ * @param iova: IOVA address of allocated qdss
+ * @param len: Length of allocated qdss memory
+ *
+ * @return Status of operation. Negative in case of error. Zero otherwise.
+ */
+int cam_smmu_alloc_qdss(int32_t smmu_hdl,
+ dma_addr_t *iova,
+ size_t *len);
+
+/**
+ * @brief Deallocates qdss memory for context bank
+ *
+ * @param smmu_hdl: SMMU handle identifying the context bank
+ *
+ * @return Status of operation. Negative in case of error. Zero otherwise.
+ */
+int cam_smmu_dealloc_qdss(int32_t smmu_hdl);
+
#endif /* _CAM_SMMU_API_H_ */
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
index 55e2646..dc316b1 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
@@ -816,9 +816,13 @@
static int msm_jpegdma_reqbufs(struct file *file,
void *fh, struct v4l2_requestbuffers *req)
{
+ int ret = 0;
struct jpegdma_ctx *ctx = msm_jpegdma_ctx_from_fh(fh);
- return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, req);
+ mutex_lock(&ctx->lock);
+ ret = v4l2_m2m_reqbufs(file, ctx->m2m_ctx, req);
+ mutex_unlock(&ctx->lock);
+ return ret;
}
/*
@@ -925,11 +929,11 @@
{
struct jpegdma_ctx *ctx = msm_jpegdma_ctx_from_fh(fh);
int ret;
-
+ mutex_lock(&ctx->lock);
ret = v4l2_m2m_streamoff(file, ctx->m2m_ctx, buf_type);
if (ret < 0)
dev_err(ctx->jdma_device->dev, "Stream off fails\n");
-
+ mutex_unlock(&ctx->lock);
return ret;
}
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c
index 702be49..627d72c 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c
@@ -79,8 +79,10 @@
*/
static inline long long jpegdma_do_div(long long num, long long den)
{
- do_div(num, den);
- return num;
+ uint64_t n = (uint64_t) num;
+
+ do_div(n, (uint32_t)den);
+ return n;
}
/*
@@ -919,7 +921,7 @@
static int msm_jpegdma_hw_calc_config(struct msm_jpegdma_size_config *size_cfg,
struct msm_jpegdma_plane *plane)
{
- u64 scale_hor, scale_ver, phase;
+ u64 scale_hor, scale_ver, phase = 0;
u64 in_width, in_height;
u64 out_width, out_height;
struct msm_jpegdma_config *config;
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
index 5c13de5..87e0172 100644
--- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
@@ -443,7 +443,8 @@
vb2_v4l2_buf->sequence = sequence;
vb2_v4l2_buf->timecode.type = buf_type;
vb2_v4l2_buf->vb2_buf.timestamp =
- (ts->tv_sec * 1000000 + ts->tv_usec) * 1000;
+ ((u64)ts->tv_sec * 1000000 +
+ ts->tv_usec) * 1000;
vb2_buffer_done(&vb2_v4l2_buf->vb2_buf,
VB2_BUF_STATE_DONE);
msm_vb2->in_freeq = 0;
diff --git a/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c b/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c
index 87150fa..4dcb3b1 100644
--- a/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c
@@ -3574,7 +3574,7 @@
static void populate_frame_data(struct vidc_frame_data *data,
const struct vb2_buffer *vb, struct msm_vidc_inst *inst)
{
- int64_t time_usec;
+ u64 time_usec;
int extra_idx;
enum v4l2_buf_type type = vb->type;
enum vidc_ports port = type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
@@ -5213,7 +5213,7 @@
int msm_vidc_comm_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
{
u32 property_id = 0;
- u64 us_per_frame = 0;
+ u64 us_per_frame = 0, fps_u64 = 0;
void *pdata;
int rc = 0, fps = 0;
struct hal_frame_rate frame_rate;
@@ -5251,8 +5251,9 @@
goto exit;
}
- fps = USEC_PER_SEC;
- do_div(fps, us_per_frame);
+ fps_u64 = USEC_PER_SEC;
+ do_div(fps_u64, us_per_frame);
+ fps = fps_u64;
if (fps % 15 == 14 || fps % 24 == 23)
fps = fps + 1;
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 91d29f5..f7c63cf 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -39,6 +39,9 @@
.max_power = 40, \
}
+#define WIL_BRP_ANT_LIMIT_MIN (1)
+#define WIL_BRP_ANT_LIMIT_MAX (27)
+
static struct ieee80211_channel wil_60ghz_channels[] = {
CHAN60G(1, 0),
CHAN60G(2, 0),
@@ -52,6 +55,49 @@
};
#endif
+enum wil_nl_60g_cmd_type {
+ NL_60G_CMD_FW_WMI,
+ NL_60G_CMD_DEBUG,
+ NL_60G_CMD_STATISTICS,
+ NL_60G_CMD_REGISTER,
+};
+
+enum wil_nl_60g_evt_type {
+ NL_60G_EVT_DRIVER_ERROR,
+ NL_60G_EVT_FW_ERROR,
+ NL_60G_EVT_FW_WMI,
+ NL_60G_EVT_DRIVER_SHUTOWN,
+ NL_60G_EVT_DRIVER_DEBUG_EVENT,
+};
+
+enum wil_nl_60g_debug_cmd {
+ NL_60G_DBG_FORCE_WMI_SEND,
+};
+
+struct wil_nl_60g_send_receive_wmi {
+ u32 cmd_id; /* enum wmi_command_id or enum wmi_event_id */
+ u8 reserved[2];
+ u8 dev_id; /* mid */
+ u16 buf_len;
+ u8 buf[0];
+} __packed;
+
+struct wil_nl_60g_event {
+ u32 evt_type; /* wil_nl_60g_evt_type */
+ u32 buf_len;
+ u8 reserved[9];
+ u8 buf[0];
+} __packed;
+
+struct wil_nl_60g_debug { /* NL_60G_CMD_DEBUG */
+ u32 cmd_id; /* wil_nl_60g_debug_cmd */
+} __packed;
+
+struct wil_nl_60g_debug_force_wmi {
+ struct wil_nl_60g_debug hdr;
+ u32 enable;
+} __packed;
+
/* Vendor id to be used in vendor specific command and events
* to user space.
* NOTE: The authoritative place for definition of QCA_NL80211_VENDOR_ID,
@@ -65,17 +111,24 @@
#define WIL_MAX_RF_SECTORS (128)
#define WIL_CID_ALL (0xff)
-enum qca_wlan_vendor_attr_rf_sector {
+enum qca_wlan_vendor_attr_wil {
QCA_ATTR_MAC_ADDR = 6,
+ QCA_ATTR_FEATURE_FLAGS = 7,
+ QCA_ATTR_TEST = 8,
QCA_ATTR_PAD = 13,
QCA_ATTR_TSF = 29,
QCA_ATTR_DMG_RF_SECTOR_INDEX = 30,
QCA_ATTR_DMG_RF_SECTOR_TYPE = 31,
QCA_ATTR_DMG_RF_MODULE_MASK = 32,
QCA_ATTR_DMG_RF_SECTOR_CFG = 33,
- QCA_ATTR_DMG_RF_SECTOR_MAX,
+ QCA_ATTR_BRP_ANT_LIMIT_MODE = 38,
+ QCA_ATTR_BRP_ANT_NUM_LIMIT = 39,
+ QCA_ATTR_WIL_MAX,
};
+#define WIL_ATTR_60G_CMD_TYPE QCA_ATTR_FEATURE_FLAGS
+#define WIL_ATTR_60G_BUF QCA_ATTR_TEST
+
enum qca_wlan_vendor_attr_dmg_rf_sector_type {
QCA_ATTR_DMG_RF_SECTOR_TYPE_RX,
QCA_ATTR_DMG_RF_SECTOR_TYPE_TX,
@@ -98,8 +151,22 @@
QCA_ATTR_DMG_RF_SECTOR_CFG_AFTER_LAST - 1
};
+enum qca_wlan_vendor_attr_brp_ant_limit_mode {
+ QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_DISABLE,
+ QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_EFFECTIVE,
+ QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_FORCE,
+ QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODES_NUM
+};
+
static const struct
-nla_policy wil_rf_sector_policy[QCA_ATTR_DMG_RF_SECTOR_MAX + 1] = {
+nla_policy wil_brp_ant_limit_policy[QCA_ATTR_WIL_MAX + 1] = {
+ [QCA_ATTR_MAC_ADDR] = { .len = ETH_ALEN },
+ [QCA_ATTR_BRP_ANT_NUM_LIMIT] = { .type = NLA_U8 },
+ [QCA_ATTR_BRP_ANT_LIMIT_MODE] = { .type = NLA_U8 },
+};
+
+static const struct
+nla_policy wil_rf_sector_policy[QCA_ATTR_WIL_MAX + 1] = {
[QCA_ATTR_MAC_ADDR] = { .len = ETH_ALEN },
[QCA_ATTR_DMG_RF_SECTOR_INDEX] = { .type = NLA_U16 },
[QCA_ATTR_DMG_RF_SECTOR_TYPE] = { .type = NLA_U8 },
@@ -118,7 +185,14 @@
[QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16] = { .type = NLA_U32 },
};
+static const struct
+nla_policy wil_nl_60g_policy[QCA_ATTR_WIL_MAX + 1] = {
+ [WIL_ATTR_60G_CMD_TYPE] = { .type = NLA_U32 },
+ [WIL_ATTR_60G_BUF] = { .type = NLA_BINARY },
+};
+
enum qca_nl80211_vendor_subcmds {
+ QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0,
QCA_NL80211_VENDOR_SUBCMD_LOC_GET_CAPA = 128,
QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION = 129,
QCA_NL80211_VENDOR_SUBCMD_FTM_ABORT_SESSION = 130,
@@ -132,6 +206,7 @@
QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SECTOR_CFG = 140,
QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SELECTED_SECTOR = 141,
QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SELECTED_SECTOR = 142,
+ QCA_NL80211_VENDOR_SUBCMD_BRP_SET_ANT_LIMIT = 153,
};
static int wil_rf_sector_get_cfg(struct wiphy *wiphy,
@@ -146,7 +221,11 @@
static int wil_rf_sector_set_selected(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data, int data_len);
+static int wil_brp_set_ant_limit(struct wiphy *wiphy, struct wireless_dev *wdev,
+ const void *data, int data_len);
+static int wil_nl_60g_handle_cmd(struct wiphy *wiphy, struct wireless_dev *wdev,
+ const void *data, int data_len);
/* vendor specific commands */
static const struct wiphy_vendor_command wil_nl80211_vendor_commands[] = {
{
@@ -221,6 +300,20 @@
WIPHY_VENDOR_CMD_NEED_RUNNING,
.doit = wil_rf_sector_set_selected
},
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_BRP_SET_ANT_LIMIT,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = wil_brp_set_ant_limit
+ },
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_UNSPEC,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV,
+ .doit = wil_nl_60g_handle_cmd
+ },
};
/* vendor specific events */
@@ -237,6 +330,10 @@
.vendor_id = QCA_NL80211_VENDOR_ID,
.subcmd = QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT
},
+ [QCA_NL80211_VENDOR_EVENT_UNSPEC_INDEX] = {
+ .vendor_id = QCA_NL80211_VENDOR_ID,
+ .subcmd = QCA_NL80211_VENDOR_SUBCMD_UNSPEC
+ },
};
static struct ieee80211_supported_band wil_band_60ghz = {
@@ -2052,7 +2149,7 @@
{
struct wil6210_priv *wil = wdev_to_wil(wdev);
int rc;
- struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
+ struct nlattr *tb[QCA_ATTR_WIL_MAX + 1];
u16 sector_index;
u8 sector_type;
u32 rf_modules_vec;
@@ -2069,7 +2166,7 @@
if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
return -EOPNOTSUPP;
- rc = nla_parse(tb, QCA_ATTR_DMG_RF_SECTOR_MAX, data, data_len,
+ rc = nla_parse(tb, QCA_ATTR_WIL_MAX, data, data_len,
wil_rf_sector_policy);
if (rc) {
wil_err(wil, "Invalid rf sector ATTR\n");
@@ -2171,7 +2268,7 @@
{
struct wil6210_priv *wil = wdev_to_wil(wdev);
int rc, tmp;
- struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
+ struct nlattr *tb[QCA_ATTR_WIL_MAX + 1];
struct nlattr *tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_MAX + 1];
u16 sector_index, rf_module_index;
u8 sector_type;
@@ -2187,7 +2284,7 @@
if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
return -EOPNOTSUPP;
- rc = nla_parse(tb, QCA_ATTR_DMG_RF_SECTOR_MAX, data, data_len,
+ rc = nla_parse(tb, QCA_ATTR_WIL_MAX, data, data_len,
wil_rf_sector_policy);
if (rc) {
wil_err(wil, "Invalid rf sector ATTR\n");
@@ -2278,7 +2375,7 @@
{
struct wil6210_priv *wil = wdev_to_wil(wdev);
int rc;
- struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
+ struct nlattr *tb[QCA_ATTR_WIL_MAX + 1];
u8 sector_type, mac_addr[ETH_ALEN];
int cid = 0;
struct wmi_get_selected_rf_sector_index_cmd cmd;
@@ -2291,7 +2388,7 @@
if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
return -EOPNOTSUPP;
- rc = nla_parse(tb, QCA_ATTR_DMG_RF_SECTOR_MAX, data, data_len,
+ rc = nla_parse(tb, QCA_ATTR_WIL_MAX, data, data_len,
wil_rf_sector_policy);
if (rc) {
wil_err(wil, "Invalid rf sector ATTR\n");
@@ -2390,7 +2487,7 @@
{
struct wil6210_priv *wil = wdev_to_wil(wdev);
int rc;
- struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
+ struct nlattr *tb[QCA_ATTR_WIL_MAX + 1];
u16 sector_index;
u8 sector_type, mac_addr[ETH_ALEN], i;
int cid = 0;
@@ -2398,7 +2495,7 @@
if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
return -EOPNOTSUPP;
- rc = nla_parse(tb, QCA_ATTR_DMG_RF_SECTOR_MAX, data, data_len,
+ rc = nla_parse(tb, QCA_ATTR_WIL_MAX, data, data_len,
wil_rf_sector_policy);
if (rc) {
wil_err(wil, "Invalid rf sector ATTR\n");
@@ -2477,3 +2574,259 @@
return rc;
}
+
+static int
+wil_brp_wmi_set_ant_limit(struct wil6210_priv *wil, u8 cid, u8 limit_mode,
+ u8 antenna_num_limit)
+{
+ int rc;
+ struct wmi_brp_set_ant_limit_cmd cmd = {
+ .cid = cid,
+ .limit_mode = limit_mode,
+ .ant_limit = antenna_num_limit,
+ };
+ struct {
+ struct wmi_cmd_hdr wmi;
+ struct wmi_brp_set_ant_limit_event evt;
+ } __packed reply;
+
+ reply.evt.status = WMI_FW_STATUS_FAILURE;
+
+ rc = wmi_call(wil, WMI_BRP_SET_ANT_LIMIT_CMDID, &cmd, sizeof(cmd),
+ WMI_BRP_SET_ANT_LIMIT_EVENTID, &reply,
+ sizeof(reply), 250);
+ if (rc)
+ return rc;
+
+ if (reply.evt.status != WMI_FW_STATUS_SUCCESS) {
+ wil_err(wil, "brp set antenna limit failed with status %d\n",
+ reply.evt.status);
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+static int wil_brp_set_ant_limit(struct wiphy *wiphy, struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ struct wil6210_priv *wil = wdev_to_wil(wdev);
+ struct nlattr *tb[QCA_ATTR_WIL_MAX + 1];
+ u8 mac_addr[ETH_ALEN];
+ u8 antenna_num_limit = 0;
+ u8 limit_mode;
+ int cid = 0;
+ int rc;
+
+ if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
+ return -ENOTSUPP;
+
+ rc = nla_parse(tb, QCA_ATTR_WIL_MAX, data, data_len,
+ wil_brp_ant_limit_policy);
+ if (rc) {
+ wil_err(wil, "Invalid ant limit ATTR\n");
+ return rc;
+ }
+
+ if (!tb[QCA_ATTR_BRP_ANT_LIMIT_MODE] || !tb[QCA_ATTR_MAC_ADDR]) {
+ wil_err(wil, "Invalid antenna limit spec\n");
+ return -EINVAL;
+ }
+
+ limit_mode = nla_get_u8(tb[QCA_ATTR_BRP_ANT_LIMIT_MODE]);
+ if (limit_mode >= QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODES_NUM) {
+ wil_err(wil, "Invalid limit mode %d\n", limit_mode);
+ return -EINVAL;
+ }
+
+ if (limit_mode != QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_DISABLE) {
+ if (!tb[QCA_ATTR_BRP_ANT_NUM_LIMIT]) {
+ wil_err(wil, "Invalid limit number\n");
+ return -EINVAL;
+ }
+
+ antenna_num_limit = nla_get_u8(tb[QCA_ATTR_BRP_ANT_NUM_LIMIT]);
+ if (antenna_num_limit > WIL_BRP_ANT_LIMIT_MAX ||
+ antenna_num_limit < WIL_BRP_ANT_LIMIT_MIN) {
+ wil_err(wil, "Invalid number of antenna limit: %d\n",
+ antenna_num_limit);
+ return -EINVAL;
+ }
+ }
+
+ ether_addr_copy(mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR]));
+ cid = wil_find_cid(wil, mac_addr);
+ if (cid < 0) {
+ wil_err(wil, "invalid MAC address %pM\n", mac_addr);
+ return -ENOENT;
+ }
+
+ return wil_brp_wmi_set_ant_limit(wil, cid, limit_mode,
+ antenna_num_limit);
+}
+
+static int wil_nl_60g_handle_cmd(struct wiphy *wiphy, struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ struct wil6210_priv *wil = wdev_to_wil(wdev);
+ struct nlattr *tb[QCA_ATTR_WIL_MAX + 1];
+ struct wil_nl_60g_send_receive_wmi *cmd;
+ struct wil_nl_60g_debug_force_wmi debug_force_wmi;
+ int rc, len;
+ u32 wil_nl_60g_cmd_type, publish;
+
+ rc = nla_parse(tb, QCA_ATTR_WIL_MAX, data, data_len,
+ wil_nl_60g_policy);
+ if (rc) {
+ wil_err(wil, "Invalid nl_60g_cmd ATTR\n");
+ return rc;
+ }
+
+ if (!tb[WIL_ATTR_60G_CMD_TYPE]) {
+ wil_err(wil, "Invalid nl_60g_cmd type\n");
+ return -EINVAL;
+ }
+
+ wil_nl_60g_cmd_type = nla_get_u32(tb[WIL_ATTR_60G_CMD_TYPE]);
+
+ switch (wil_nl_60g_cmd_type) {
+ case NL_60G_CMD_REGISTER:
+ if (!tb[WIL_ATTR_60G_BUF]) {
+ wil_err(wil, "Invalid nl_60g_cmd spec\n");
+ return -EINVAL;
+ }
+
+ len = nla_len(tb[WIL_ATTR_60G_BUF]);
+ if (len != sizeof(publish)) {
+ wil_err(wil, "cmd buffer wrong len %d\n", len);
+ return -EINVAL;
+ }
+ memcpy(&publish, nla_data(tb[WIL_ATTR_60G_BUF]), len);
+ wil->publish_nl_evt = publish;
+
+ wil_dbg_wmi(wil, "Publish wmi event %s\n",
+ publish ? "enabled" : "disabled");
+ break;
+ case NL_60G_CMD_DEBUG:
+ if (!tb[WIL_ATTR_60G_BUF]) {
+ wil_err(wil, "Invalid nl_60g_cmd spec\n");
+ return -EINVAL;
+ }
+
+ len = nla_len(tb[WIL_ATTR_60G_BUF]);
+ if (len < sizeof(struct wil_nl_60g_debug)) {
+ wil_err(wil, "cmd buffer too short %d\n", len);
+ return -EINVAL;
+ }
+
+ memcpy(&debug_force_wmi, nla_data(tb[WIL_ATTR_60G_BUF]),
+ sizeof(struct wil_nl_60g_debug));
+
+ switch (debug_force_wmi.hdr.cmd_id) {
+ case NL_60G_DBG_FORCE_WMI_SEND:
+ if (len != sizeof(debug_force_wmi)) {
+ wil_err(wil, "cmd buffer wrong len %d\n", len);
+ return -EINVAL;
+ }
+
+ memcpy(&debug_force_wmi, nla_data(tb[WIL_ATTR_60G_BUF]),
+ sizeof(debug_force_wmi));
+ wil->force_wmi_send = debug_force_wmi.enable;
+
+ wil_dbg_wmi(wil, "force sending wmi commands %d\n",
+ wil->force_wmi_send);
+ break;
+ default:
+ rc = -EINVAL;
+ wil_err(wil, "invalid debug_cmd id %d",
+ debug_force_wmi.hdr.cmd_id);
+ }
+ break;
+ case NL_60G_CMD_FW_WMI:
+ if (!tb[WIL_ATTR_60G_BUF]) {
+ wil_err(wil, "Invalid nl_60g_cmd spec\n");
+ return -EINVAL;
+ }
+
+ len = nla_len(tb[WIL_ATTR_60G_BUF]);
+ if (len < offsetof(struct wil_nl_60g_send_receive_wmi, buf)) {
+ wil_err(wil, "wmi cmd buffer too small\n");
+ return -EINVAL;
+ }
+
+ cmd = kmalloc(len, GFP_KERNEL);
+ if (!cmd)
+ return -ENOMEM;
+
+ memcpy(cmd, nla_data(tb[WIL_ATTR_60G_BUF]), (unsigned int)len);
+
+ wil_dbg_wmi(wil, "sending user-space command (0x%04x) [%d]\n",
+ cmd->cmd_id, cmd->buf_len);
+
+ if (wil->force_wmi_send)
+ rc = wmi_force_send(wil, cmd->cmd_id, cmd->buf,
+ cmd->buf_len);
+ else
+ rc = wmi_send(wil, cmd->cmd_id, cmd->buf, cmd->buf_len);
+
+ kfree(cmd);
+ break;
+ default:
+ rc = -EINVAL;
+ wil_err(wil, "invalid nl_60g_cmd type %d", wil_nl_60g_cmd_type);
+ }
+
+ return rc;
+}
+
+void wil_nl_60g_receive_wmi_evt(struct wil6210_priv *wil, u8 *cmd, int len)
+{
+ struct sk_buff *vendor_event = NULL;
+ struct wil_nl_60g_event *evt;
+ struct wil_nl_60g_send_receive_wmi *wmi_buf;
+ struct wmi_cmd_hdr *wmi_hdr = (struct wmi_cmd_hdr *)cmd;
+ int data_len;
+
+ if (!wil->publish_nl_evt)
+ return;
+
+ wil_dbg_wmi(wil, "report wmi event to user-space (0x%04x) [%d]\n",
+ le16_to_cpu(wmi_hdr->command_id), len);
+
+ data_len = len - sizeof(struct wmi_cmd_hdr);
+
+ evt = kzalloc(sizeof(*evt) + sizeof(*wmi_buf) + data_len, GFP_KERNEL);
+ if (!evt)
+ return;
+
+ evt->evt_type = NL_60G_EVT_FW_WMI;
+ evt->buf_len = sizeof(*wmi_buf) + data_len;
+
+ wmi_buf = (struct wil_nl_60g_send_receive_wmi *)evt->buf;
+
+ wmi_buf->cmd_id = le16_to_cpu(wmi_hdr->command_id);
+ wmi_buf->dev_id = wmi_hdr->mid;
+ wmi_buf->buf_len = data_len;
+ memcpy(wmi_buf->buf, cmd + sizeof(struct wmi_cmd_hdr), data_len);
+
+ vendor_event = cfg80211_vendor_event_alloc(
+ wil_to_wiphy(wil),
+ NULL,
+ data_len + 4 + NLMSG_HDRLEN +
+ sizeof(*evt) + sizeof(*wmi_buf),
+ QCA_NL80211_VENDOR_EVENT_UNSPEC_INDEX,
+ GFP_KERNEL);
+ if (!vendor_event)
+ goto out;
+
+ if (nla_put(vendor_event, WIL_ATTR_60G_BUF,
+ sizeof(*evt) + sizeof(*wmi_buf) + data_len, evt)) {
+ wil_err(wil, "failed to fill WIL_ATTR_60G_BUF\n");
+ goto out;
+ }
+
+ cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+
+out:
+ kfree(evt);
+}
diff --git a/drivers/net/wireless/ath/wil6210/ftm.h b/drivers/net/wireless/ath/wil6210/ftm.h
index 21923c2..e9efad7 100644
--- a/drivers/net/wireless/ath/wil6210/ftm.h
+++ b/drivers/net/wireless/ath/wil6210/ftm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -417,6 +417,7 @@
QCA_NL80211_VENDOR_EVENT_FTM_MEAS_RESULT_INDEX,
QCA_NL80211_VENDOR_EVENT_FTM_SESSION_DONE_INDEX,
QCA_NL80211_VENDOR_EVENT_AOA_MEAS_RESULT_INDEX,
+ QCA_NL80211_VENDOR_EVENT_UNSPEC_INDEX,
};
/* measurement parameters. Specified for each peer as part
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 9cef0f0..2baa6cf 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -1228,6 +1228,8 @@
wmi_event_flush(wil);
+ wil->force_wmi_send = false;
+
flush_workqueue(wil->wq_service);
flush_workqueue(wil->wmi_wq);
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 2f6d6c9..9b68663 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -811,6 +811,9 @@
u32 rgf_fw_assert_code_addr;
u32 rgf_ucode_assert_code_addr;
u32 iccm_base;
+
+ bool publish_nl_evt; /* deliver WMI events to user space */
+ bool force_wmi_send; /* allow WMI command while FW in sysassert */
};
#define wil_to_wiphy(i) (i->wdev->wiphy)
@@ -943,6 +946,7 @@
int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr,
struct wil6210_mbox_hdr *hdr);
int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len);
+int wmi_force_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len);
void wmi_recv_cmd(struct wil6210_priv *wil);
int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
u16 reply_id, void *reply, u8 reply_size, int to_msec);
@@ -1114,6 +1118,7 @@
void wil_aoa_evt_meas(struct wil6210_priv *wil,
struct wmi_aoa_meas_event *evt,
int len);
+void wil_nl_60g_receive_wmi_evt(struct wil6210_priv *wil, u8 *cmd, int len);
/* link loss */
int wmi_link_maintain_cfg_write(struct wil6210_priv *wil,
const u8 *addr,
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index f2dba31..5510132 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -517,7 +517,8 @@
}
}
-static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
+static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
+ bool force_send)
{
struct {
struct wil6210_mbox_hdr hdr;
@@ -549,7 +550,7 @@
might_sleep();
- if (!test_bit(wil_status_fwready, wil->status)) {
+ if (!test_bit(wil_status_fwready, wil->status) && !force_send) {
wil_err(wil, "WMI: cannot send command while FW not ready\n");
return -EAGAIN;
}
@@ -588,7 +589,7 @@
wil_dbg_wmi(wil, "Head 0x%08x -> 0x%08x\n", r->head, next_head);
/* wait till FW finish with previous command */
for (retry = 5; retry > 0; retry--) {
- if (!test_bit(wil_status_fwready, wil->status)) {
+ if (!test_bit(wil_status_fwready, wil->status) && !force_send) {
wil_err(wil, "WMI: cannot send command while FW not ready\n");
rc = -EAGAIN;
goto out;
@@ -643,7 +644,18 @@
int rc;
mutex_lock(&wil->wmi_mutex);
- rc = __wmi_send(wil, cmdid, buf, len);
+ rc = __wmi_send(wil, cmdid, buf, len, false);
+ mutex_unlock(&wil->wmi_mutex);
+
+ return rc;
+}
+
+int wmi_force_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
+{
+ int rc;
+
+ mutex_lock(&wil->wmi_mutex);
+ rc = __wmi_send(wil, cmdid, buf, len, true);
mutex_unlock(&wil->wmi_mutex);
return rc;
@@ -1363,6 +1375,7 @@
struct wmi_cmd_hdr *wmi = &evt->event.wmi;
u16 id = le16_to_cpu(wmi->command_id);
u32 tstamp = le32_to_cpu(wmi->fw_timestamp);
+ wil_nl_60g_receive_wmi_evt(wil, cmd, len);
if (test_bit(wil_status_resuming, wil->status)) {
if (id == WMI_TRAFFIC_RESUME_EVENTID)
clear_bit(wil_status_resuming,
@@ -1436,7 +1449,7 @@
reinit_completion(&wil->wmi_call);
spin_unlock(&wil->wmi_ev_lock);
- rc = __wmi_send(wil, cmdid, buf, len);
+ rc = __wmi_send(wil, cmdid, buf, len, false);
if (rc)
goto out;
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index 207ed06..dab5db5 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -63,6 +63,16 @@
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm 9615 platform.
+config PINCTRL_MDM9650
+ tristate "QTI MDM9650 pin controller driver"
+ depends on GPIOLIB && OF
+ select PINCTRL_MSM
+ help
+ This is the pinctrl, pinmux, pinconf and gpiolib driver settings
+ for the QTI TLMM block which is found in the QTI MDM9650
+ platform.
+ Say Y here to enable pinctrl settings for MDM9650.
+
config PINCTRL_MSM8X74
tristate "Qualcomm 8x74 pin controller driver"
depends on GPIOLIB && OF
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index e5c3b34..5389139 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -22,3 +22,4 @@
obj-$(CONFIG_PINCTRL_SDM845) += pinctrl-sdm845.o pinctrl-sdm845-v2.o
obj-$(CONFIG_PINCTRL_SDM670) += pinctrl-sdm670.o
obj-$(CONFIG_PINCTRL_SDXPOORWILLS) += pinctrl-sdxpoorwills.o
+obj-$(CONFIG_PINCTRL_MDM9650) += pinctrl-mdm9650.o
diff --git a/drivers/pinctrl/qcom/pinctrl-mdm9650.c b/drivers/pinctrl/qcom/pinctrl-mdm9650.c
new file mode 100644
index 0000000..c80e932
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-mdm9650.c
@@ -0,0 +1,1224 @@
+/*
+ * Copyright (c) 2015, 2017-2018, 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 <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-msm.h"
+
+#define FUNCTION(fname) \
+ [msm_mux_##fname] = { \
+ .name = #fname, \
+ .groups = fname##_groups, \
+ .ngroups = ARRAY_SIZE(fname##_groups), \
+ }
+
+#define REG_BASE 0x0
+#define REG_SIZE 0x1000
+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9) \
+ { \
+ .name = "gpio" #id, \
+ .pins = gpio##id##_pins, \
+ .npins = (unsigned int)ARRAY_SIZE(gpio##id##_pins), \
+ .funcs = (int[]){ \
+ msm_mux_gpio, /* gpio mode */ \
+ msm_mux_##f1, \
+ msm_mux_##f2, \
+ msm_mux_##f3, \
+ msm_mux_##f4, \
+ msm_mux_##f5, \
+ msm_mux_##f6, \
+ msm_mux_##f7, \
+ msm_mux_##f8, \
+ msm_mux_##f9 \
+ }, \
+ .nfuncs = 10, \
+ .ctl_reg = REG_BASE + REG_SIZE * id, \
+ .io_reg = REG_BASE + 0x4 + REG_SIZE * id, \
+ .intr_cfg_reg = REG_BASE + 0x8 + REG_SIZE * id, \
+ .intr_status_reg = REG_BASE + 0xc + REG_SIZE * id, \
+ .intr_target_reg = REG_BASE + 0x8 + REG_SIZE * id, \
+ .mux_bit = 2, \
+ .pull_bit = 0, \
+ .drv_bit = 6, \
+ .oe_bit = 9, \
+ .in_bit = 0, \
+ .out_bit = 1, \
+ .intr_enable_bit = 0, \
+ .intr_status_bit = 0, \
+ .intr_target_bit = 5, \
+ .intr_target_kpss_val = 4, \
+ .intr_raw_status_bit = 4, \
+ .intr_polarity_bit = 1, \
+ .intr_detection_bit = 2, \
+ .intr_detection_width = 2, \
+ }
+
+#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \
+ { \
+ .name = #pg_name, \
+ .pins = pg_name##_pins, \
+ .npins = (unsigned int)ARRAY_SIZE(pg_name##_pins), \
+ .ctl_reg = ctl, \
+ .io_reg = 0, \
+ .intr_cfg_reg = 0, \
+ .intr_status_reg = 0, \
+ .intr_target_reg = 0, \
+ .mux_bit = -1, \
+ .pull_bit = pull, \
+ .drv_bit = drv, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = -1, \
+ .intr_enable_bit = -1, \
+ .intr_status_bit = -1, \
+ .intr_target_bit = -1, \
+ .intr_raw_status_bit = -1, \
+ .intr_polarity_bit = -1, \
+ .intr_detection_bit = -1, \
+ .intr_detection_width = -1, \
+ }
+static const struct pinctrl_pin_desc mdm9650_pins[] = {
+ PINCTRL_PIN(0, "GPIO_0"),
+ PINCTRL_PIN(1, "GPIO_1"),
+ PINCTRL_PIN(2, "GPIO_2"),
+ PINCTRL_PIN(3, "GPIO_3"),
+ PINCTRL_PIN(4, "GPIO_4"),
+ PINCTRL_PIN(5, "GPIO_5"),
+ PINCTRL_PIN(6, "GPIO_6"),
+ PINCTRL_PIN(7, "GPIO_7"),
+ PINCTRL_PIN(8, "GPIO_8"),
+ PINCTRL_PIN(9, "GPIO_9"),
+ PINCTRL_PIN(10, "GPIO_10"),
+ PINCTRL_PIN(11, "GPIO_11"),
+ PINCTRL_PIN(12, "GPIO_12"),
+ PINCTRL_PIN(13, "GPIO_13"),
+ PINCTRL_PIN(14, "GPIO_14"),
+ PINCTRL_PIN(15, "GPIO_15"),
+ PINCTRL_PIN(16, "GPIO_16"),
+ PINCTRL_PIN(17, "GPIO_17"),
+ PINCTRL_PIN(18, "GPIO_18"),
+ PINCTRL_PIN(19, "GPIO_19"),
+ PINCTRL_PIN(20, "GPIO_20"),
+ PINCTRL_PIN(21, "GPIO_21"),
+ PINCTRL_PIN(22, "GPIO_22"),
+ PINCTRL_PIN(23, "GPIO_23"),
+ PINCTRL_PIN(24, "GPIO_24"),
+ PINCTRL_PIN(25, "GPIO_25"),
+ PINCTRL_PIN(26, "GPIO_26"),
+ PINCTRL_PIN(27, "GPIO_27"),
+ PINCTRL_PIN(28, "GPIO_28"),
+ PINCTRL_PIN(29, "GPIO_29"),
+ PINCTRL_PIN(30, "GPIO_30"),
+ PINCTRL_PIN(31, "GPIO_31"),
+ PINCTRL_PIN(32, "GPIO_32"),
+ PINCTRL_PIN(33, "GPIO_33"),
+ PINCTRL_PIN(34, "GPIO_34"),
+ PINCTRL_PIN(35, "GPIO_35"),
+ PINCTRL_PIN(36, "GPIO_36"),
+ PINCTRL_PIN(37, "GPIO_37"),
+ PINCTRL_PIN(38, "GPIO_38"),
+ PINCTRL_PIN(39, "GPIO_39"),
+ PINCTRL_PIN(40, "GPIO_40"),
+ PINCTRL_PIN(41, "GPIO_41"),
+ PINCTRL_PIN(42, "GPIO_42"),
+ PINCTRL_PIN(43, "GPIO_43"),
+ PINCTRL_PIN(44, "GPIO_44"),
+ PINCTRL_PIN(45, "GPIO_45"),
+ PINCTRL_PIN(46, "GPIO_46"),
+ PINCTRL_PIN(47, "GPIO_47"),
+ PINCTRL_PIN(48, "GPIO_48"),
+ PINCTRL_PIN(49, "GPIO_49"),
+ PINCTRL_PIN(50, "GPIO_50"),
+ PINCTRL_PIN(51, "GPIO_51"),
+ PINCTRL_PIN(52, "GPIO_52"),
+ PINCTRL_PIN(53, "GPIO_53"),
+ PINCTRL_PIN(54, "GPIO_54"),
+ PINCTRL_PIN(55, "GPIO_55"),
+ PINCTRL_PIN(56, "GPIO_56"),
+ PINCTRL_PIN(57, "GPIO_57"),
+ PINCTRL_PIN(58, "GPIO_58"),
+ PINCTRL_PIN(59, "GPIO_59"),
+ PINCTRL_PIN(60, "GPIO_60"),
+ PINCTRL_PIN(61, "GPIO_61"),
+ PINCTRL_PIN(62, "GPIO_62"),
+ PINCTRL_PIN(63, "GPIO_63"),
+ PINCTRL_PIN(64, "GPIO_64"),
+ PINCTRL_PIN(65, "GPIO_65"),
+ PINCTRL_PIN(66, "GPIO_66"),
+ PINCTRL_PIN(67, "GPIO_67"),
+ PINCTRL_PIN(68, "GPIO_68"),
+ PINCTRL_PIN(69, "GPIO_69"),
+ PINCTRL_PIN(70, "GPIO_70"),
+ PINCTRL_PIN(71, "GPIO_71"),
+ PINCTRL_PIN(72, "GPIO_72"),
+ PINCTRL_PIN(73, "GPIO_73"),
+ PINCTRL_PIN(74, "GPIO_74"),
+ PINCTRL_PIN(75, "GPIO_75"),
+ PINCTRL_PIN(76, "GPIO_76"),
+ PINCTRL_PIN(77, "GPIO_77"),
+ PINCTRL_PIN(78, "GPIO_78"),
+ PINCTRL_PIN(79, "GPIO_79"),
+ PINCTRL_PIN(80, "GPIO_80"),
+ PINCTRL_PIN(81, "GPIO_81"),
+ PINCTRL_PIN(82, "GPIO_82"),
+ PINCTRL_PIN(83, "GPIO_83"),
+ PINCTRL_PIN(84, "GPIO_84"),
+ PINCTRL_PIN(85, "GPIO_85"),
+ PINCTRL_PIN(86, "GPIO_86"),
+ PINCTRL_PIN(87, "GPIO_87"),
+ PINCTRL_PIN(88, "GPIO_88"),
+ PINCTRL_PIN(89, "GPIO_89"),
+ PINCTRL_PIN(90, "GPIO_90"),
+ PINCTRL_PIN(91, "GPIO_91"),
+ PINCTRL_PIN(92, "GPIO_92"),
+ PINCTRL_PIN(93, "GPIO_93"),
+ PINCTRL_PIN(94, "GPIO_94"),
+ PINCTRL_PIN(95, "GPIO_95"),
+ PINCTRL_PIN(96, "GPIO_96"),
+ PINCTRL_PIN(97, "GPIO_97"),
+ PINCTRL_PIN(98, "GPIO_98"),
+ PINCTRL_PIN(99, "GPIO_99"),
+ PINCTRL_PIN(100, "SDC1_CLK"),
+ PINCTRL_PIN(101, "SDC1_CMD"),
+ PINCTRL_PIN(102, "SDC1_DATA"),
+ PINCTRL_PIN(103, "SDC2_CLK"),
+ PINCTRL_PIN(104, "SDC2_CMD"),
+ PINCTRL_PIN(105, "SDC2_DATA"),
+ PINCTRL_PIN(106, "QDSD_CLK"),
+ PINCTRL_PIN(107, "QDSD_CMD"),
+ PINCTRL_PIN(108, "QDSD_DATA0"),
+ PINCTRL_PIN(109, "QDSD_DATA1"),
+ PINCTRL_PIN(110, "QDSD_DATA2"),
+ PINCTRL_PIN(111, "QDSD_DATA3"),
+};
+
+#define DECLARE_MSM_GPIO_PINS(pin) \
+ static const unsigned int gpio##pin##_pins[] = { pin }
+DECLARE_MSM_GPIO_PINS(0);
+DECLARE_MSM_GPIO_PINS(1);
+DECLARE_MSM_GPIO_PINS(2);
+DECLARE_MSM_GPIO_PINS(3);
+DECLARE_MSM_GPIO_PINS(4);
+DECLARE_MSM_GPIO_PINS(5);
+DECLARE_MSM_GPIO_PINS(6);
+DECLARE_MSM_GPIO_PINS(7);
+DECLARE_MSM_GPIO_PINS(8);
+DECLARE_MSM_GPIO_PINS(9);
+DECLARE_MSM_GPIO_PINS(10);
+DECLARE_MSM_GPIO_PINS(11);
+DECLARE_MSM_GPIO_PINS(12);
+DECLARE_MSM_GPIO_PINS(13);
+DECLARE_MSM_GPIO_PINS(14);
+DECLARE_MSM_GPIO_PINS(15);
+DECLARE_MSM_GPIO_PINS(16);
+DECLARE_MSM_GPIO_PINS(17);
+DECLARE_MSM_GPIO_PINS(18);
+DECLARE_MSM_GPIO_PINS(19);
+DECLARE_MSM_GPIO_PINS(20);
+DECLARE_MSM_GPIO_PINS(21);
+DECLARE_MSM_GPIO_PINS(22);
+DECLARE_MSM_GPIO_PINS(23);
+DECLARE_MSM_GPIO_PINS(24);
+DECLARE_MSM_GPIO_PINS(25);
+DECLARE_MSM_GPIO_PINS(26);
+DECLARE_MSM_GPIO_PINS(27);
+DECLARE_MSM_GPIO_PINS(28);
+DECLARE_MSM_GPIO_PINS(29);
+DECLARE_MSM_GPIO_PINS(30);
+DECLARE_MSM_GPIO_PINS(31);
+DECLARE_MSM_GPIO_PINS(32);
+DECLARE_MSM_GPIO_PINS(33);
+DECLARE_MSM_GPIO_PINS(34);
+DECLARE_MSM_GPIO_PINS(35);
+DECLARE_MSM_GPIO_PINS(36);
+DECLARE_MSM_GPIO_PINS(37);
+DECLARE_MSM_GPIO_PINS(38);
+DECLARE_MSM_GPIO_PINS(39);
+DECLARE_MSM_GPIO_PINS(40);
+DECLARE_MSM_GPIO_PINS(41);
+DECLARE_MSM_GPIO_PINS(42);
+DECLARE_MSM_GPIO_PINS(43);
+DECLARE_MSM_GPIO_PINS(44);
+DECLARE_MSM_GPIO_PINS(45);
+DECLARE_MSM_GPIO_PINS(46);
+DECLARE_MSM_GPIO_PINS(47);
+DECLARE_MSM_GPIO_PINS(48);
+DECLARE_MSM_GPIO_PINS(49);
+DECLARE_MSM_GPIO_PINS(50);
+DECLARE_MSM_GPIO_PINS(51);
+DECLARE_MSM_GPIO_PINS(52);
+DECLARE_MSM_GPIO_PINS(53);
+DECLARE_MSM_GPIO_PINS(54);
+DECLARE_MSM_GPIO_PINS(55);
+DECLARE_MSM_GPIO_PINS(56);
+DECLARE_MSM_GPIO_PINS(57);
+DECLARE_MSM_GPIO_PINS(58);
+DECLARE_MSM_GPIO_PINS(59);
+DECLARE_MSM_GPIO_PINS(60);
+DECLARE_MSM_GPIO_PINS(61);
+DECLARE_MSM_GPIO_PINS(62);
+DECLARE_MSM_GPIO_PINS(63);
+DECLARE_MSM_GPIO_PINS(64);
+DECLARE_MSM_GPIO_PINS(65);
+DECLARE_MSM_GPIO_PINS(66);
+DECLARE_MSM_GPIO_PINS(67);
+DECLARE_MSM_GPIO_PINS(68);
+DECLARE_MSM_GPIO_PINS(69);
+DECLARE_MSM_GPIO_PINS(70);
+DECLARE_MSM_GPIO_PINS(71);
+DECLARE_MSM_GPIO_PINS(72);
+DECLARE_MSM_GPIO_PINS(73);
+DECLARE_MSM_GPIO_PINS(74);
+DECLARE_MSM_GPIO_PINS(75);
+DECLARE_MSM_GPIO_PINS(76);
+DECLARE_MSM_GPIO_PINS(77);
+DECLARE_MSM_GPIO_PINS(78);
+DECLARE_MSM_GPIO_PINS(79);
+DECLARE_MSM_GPIO_PINS(80);
+DECLARE_MSM_GPIO_PINS(81);
+DECLARE_MSM_GPIO_PINS(82);
+DECLARE_MSM_GPIO_PINS(83);
+DECLARE_MSM_GPIO_PINS(84);
+DECLARE_MSM_GPIO_PINS(85);
+DECLARE_MSM_GPIO_PINS(86);
+DECLARE_MSM_GPIO_PINS(87);
+DECLARE_MSM_GPIO_PINS(88);
+DECLARE_MSM_GPIO_PINS(89);
+DECLARE_MSM_GPIO_PINS(90);
+DECLARE_MSM_GPIO_PINS(91);
+DECLARE_MSM_GPIO_PINS(92);
+DECLARE_MSM_GPIO_PINS(93);
+DECLARE_MSM_GPIO_PINS(94);
+DECLARE_MSM_GPIO_PINS(95);
+DECLARE_MSM_GPIO_PINS(96);
+DECLARE_MSM_GPIO_PINS(97);
+DECLARE_MSM_GPIO_PINS(98);
+DECLARE_MSM_GPIO_PINS(99);
+
+static const unsigned int sdc1_clk_pins[] = { 100 };
+static const unsigned int sdc1_cmd_pins[] = { 101 };
+static const unsigned int sdc1_data_pins[] = { 102 };
+static const unsigned int sdc2_clk_pins[] = { 103 };
+static const unsigned int sdc2_cmd_pins[] = { 104 };
+static const unsigned int sdc2_data_pins[] = { 105 };
+static const unsigned int qdsd_clk_pins[] = { 106 };
+static const unsigned int qdsd_cmd_pins[] = { 107 };
+static const unsigned int qdsd_data0_pins[] = { 108 };
+static const unsigned int qdsd_data1_pins[] = { 109 };
+static const unsigned int qdsd_data2_pins[] = { 110 };
+static const unsigned int qdsd_data3_pins[] = { 111 };
+
+enum mdm9650_functions {
+ msm_mux_uim2_data,
+ msm_mux_qdss_stm31,
+ msm_mux_ebi0_wrcdc,
+ msm_mux_uim2_present,
+ msm_mux_qdss_stm30,
+ msm_mux_blsp_spi1,
+ msm_mux_uim2_reset,
+ msm_mux_qdss_stm29,
+ msm_mux_uim2_clk,
+ msm_mux_blsp_i2c1,
+ msm_mux_qdss_stm28,
+ msm_mux_blsp_spi2,
+ msm_mux_blsp_uart1,
+ msm_mux_blsp_uart2,
+ msm_mux_blsp_uart4,
+ msm_mux_qdss_stm23,
+ msm_mux_qdss_tracedata_a,
+ msm_mux_qdss_stm22,
+ msm_mux_qdss_stm21,
+ msm_mux_blsp_i2c2,
+ msm_mux_qdss_stm20,
+ msm_mux_pri_mi2s_ws_b,
+ msm_mux_blsp_spi3,
+ msm_mux_blsp_uart3,
+ msm_mux_ldo_en,
+ msm_mux_qdss_cti_trig1_out_b,
+ msm_mux_pwr_modem,
+ msm_mux_pri_mi2s_data0_b,
+ msm_mux_qdss_cti_trig1_in_b,
+ msm_mux_pwr_nav,
+ msm_mux_pri_mi2s_data1_b,
+ msm_mux_blsp_i2c3,
+ msm_mux_pwr_crypto,
+ msm_mux_pri_mi2s_sck_b,
+ msm_mux_pri_mi2s_ws_a,
+ msm_mux_qdss_stm19,
+ msm_mux_pri_mi2s_data0_a,
+ msm_mux_qdss_stm18,
+ msm_mux_pri_mi2s_data1_a,
+ msm_mux_slimbus_data,
+ msm_mux_qdss_stm17,
+ msm_mux_bimc_dte0,
+ msm_mux_native_tsens,
+ msm_mux_pri_mi2s_sck_a,
+ msm_mux_blsp_i2c4,
+ msm_mux_slimbus_clk,
+ msm_mux_qdss_stm16,
+ msm_mux_bimc_dte1,
+ msm_mux_sec_mi2s_ws_a,
+ msm_mux_blsp_spi4,
+ msm_mux_qdss_stm27,
+ msm_mux_sec_mi2s_data0_a,
+ msm_mux_qdss_cti,
+ msm_mux_qdss_stm26,
+ msm_mux_sec_mi2s_data1_a,
+ msm_mux_qdss_stm25,
+ msm_mux_sec_mi2s_sck_a,
+ msm_mux_qdss_stm24,
+ msm_mux_sec_mi2s_ws_b,
+ msm_mux_ebi2_a,
+ msm_mux_sec_mi2s_data0_b,
+ msm_mux_ebi2_lcd,
+ msm_mux_sec_mi2s_data1_b,
+ msm_mux_ebi1_smt4,
+ msm_mux_sec_mi2s_sck_b,
+ msm_mux_m_voc_ext_vfr_ref_irq_a,
+ msm_mux_adsp_ext_vfr_irq_a,
+ msm_mux_qdss_stm11,
+ msm_mux_epm1,
+ msm_mux_m_voc_ext_vfr_ref_irq_2_a,
+ msm_mux_adsp_ext_vfr_irq_b,
+ msm_mux_qdss_stm10,
+ msm_mux_native_char,
+ msm_mux_native_char3,
+ msm_mux_native_char2,
+ msm_mux_native_char1,
+ msm_mux_native_char0,
+ msm_mux_pa_indicator,
+ msm_mux_qdss_traceclk_a,
+ msm_mux_prng_rosc,
+ msm_mux_nav_pps_in_a,
+ msm_mux_qdss_tracectl_a,
+ msm_mux_epm2,
+ msm_mux_nav_pps_in_b,
+ msm_mux_coex_uart,
+ msm_mux_nav_dr,
+ msm_mux_cri_trng0,
+ msm_mux_qlink_req,
+ msm_mux_qlink_en,
+ msm_mux_cri_trng1,
+ msm_mux_cri_trng,
+ msm_mux_ap2mdm_status,
+ msm_mux_mdm2ap_status,
+ msm_mux_ap2mdm_err,
+ msm_mux_mdm2ap_err,
+ msm_mux_qdss_stm15,
+ msm_mux_ap2mdm_vdd,
+ msm_mux_qdss_stm14,
+ msm_mux_mdm2ap_vdd,
+ msm_mux_qdss_stm13,
+ msm_mux_ap2mdm_wake,
+ msm_mux_m_voc_ext_vfr_ref_irq_2_b,
+ msm_mux_qdss_stm12,
+ msm_mux_pciehost_rst,
+ msm_mux_pci_e,
+ msm_mux_qdss_stm9,
+ msm_mux_qdss_cti_trig1_out_a,
+ msm_mux_qdss_cti_trig2_in_b,
+ msm_mux_qdss_stm8,
+ msm_mux_qdss_cti_trig1_in_a,
+ msm_mux_qdss_cti_trig2_out_b,
+ msm_mux_qdss_stm7,
+ msm_mux_pcie_clkreq,
+ msm_mux_qdss_stm6,
+ msm_mux_qdss_stm5,
+ msm_mux_ap2mdm_chnl,
+ msm_mux_qdss_stm4,
+ msm_mux_qdss_cti_trig2_out_a,
+ msm_mux_qdss_stm3,
+ msm_mux_mdm2ap_chnl,
+ msm_mux_m_voc_ext_vfr_ref_irq_b,
+ msm_mux_qdss_stm2,
+ msm_mux_uim_batt,
+ msm_mux_qdss_stm1,
+ msm_mux_qdss_cti_trig2_in_a,
+ msm_mux_qdss_stm0,
+ msm_mux_i2s_mclk,
+ msm_mux_audio_ref,
+ msm_mux_ldo_update,
+ msm_mux_dbg_out,
+ msm_mux_gcc_plltest,
+ msm_mux_uim1_data,
+ msm_mux_uim1_present,
+ msm_mux_uim1_reset,
+ msm_mux_uim1_clk,
+ msm_mux_gpio,
+ msm_mux_NA,
+};
+
+static const char * const uim2_data_groups[] = {
+ "gpio0",
+};
+static const char * const gpio_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+ "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+ "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+ "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+ "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+ "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+ "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+ "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+ "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+ "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
+ "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
+ "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
+ "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91",
+ "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98",
+ "gpio99",
+};
+static const char * const qdss_stm31_groups[] = {
+ "gpio0",
+};
+static const char * const ebi0_wrcdc_groups[] = {
+ "gpio0", "gpio2",
+};
+static const char * const uim2_present_groups[] = {
+ "gpio1",
+};
+static const char * const qdss_stm30_groups[] = {
+ "gpio1",
+};
+static const char * const blsp_spi1_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio68", "gpio69", "gpio71",
+};
+static const char * const uim2_reset_groups[] = {
+ "gpio2",
+};
+static const char * const blsp_i2c1_groups[] = {
+ "gpio2", "gpio3", "gpio84", "gpio85",
+};
+static const char * const qdss_stm29_groups[] = {
+ "gpio2",
+};
+static const char * const uim2_clk_groups[] = {
+ "gpio3",
+};
+static const char * const qdss_stm28_groups[] = {
+ "gpio3",
+};
+static const char * const blsp_spi2_groups[] = {
+ "gpio4", "gpio5", "gpio6", "gpio7", "gpio60", "gpio68", "gpio71",
+};
+static const char * const blsp_uart1_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio20", "gpio21", "gpio22",
+ "gpio23",
+};
+static const char * const blsp_uart2_groups[] = {
+ "gpio4", "gpio5", "gpio6", "gpio7",
+};
+static const char * const qdss_stm23_groups[] = {
+ "gpio4",
+};
+static const char * const qdss_tracedata_a_groups[] = {
+ "gpio4", "gpio5", "gpio6", "gpio7", "gpio8", "gpio9", "gpio16",
+ "gpio17", "gpio18", "gpio19", "gpio20", "gpio22", "gpio40", "gpio43",
+ "gpio68", "gpio69",
+};
+static const char * const qdss_stm22_groups[] = {
+ "gpio5",
+};
+static const char * const blsp_i2c2_groups[] = {
+ "gpio6", "gpio7", "gpio48", "gpio49",
+};
+static const char * const qdss_stm21_groups[] = {
+ "gpio6",
+};
+static const char * const qdss_stm20_groups[] = {
+ "gpio7",
+};
+static const char * const pri_mi2s_ws_b_groups[] = {
+ "gpio8",
+};
+static const char * const blsp_spi3_groups[] = {
+ "gpio8", "gpio9", "gpio10", "gpio11", "gpio68", "gpio69", "gpio71",
+};
+static const char * const blsp_uart3_groups[] = {
+ "gpio8", "gpio9", "gpio10", "gpio11",
+};
+static const char * const blsp_uart4_groups[] = {
+ "gpio12", "gpio13", "gpio14", "gpio15", "gpio16", "gpio17", "gpio18",
+ "gpio19",
+};
+static const char * const ldo_en_groups[] = {
+ "gpio8",
+};
+static const char * const qdss_cti_trig1_out_b_groups[] = {
+ "gpio8",
+};
+static const char * const pwr_modem_groups[] = {
+ "gpio8",
+};
+static const char * const pri_mi2s_data0_b_groups[] = {
+ "gpio9",
+};
+static const char * const qdss_cti_trig1_in_b_groups[] = {
+ "gpio9",
+};
+static const char * const pwr_nav_groups[] = {
+ "gpio9",
+};
+static const char * const pri_mi2s_data1_b_groups[] = {
+ "gpio10",
+};
+static const char * const blsp_i2c3_groups[] = {
+ "gpio10", "gpio11",
+};
+static const char * const pwr_crypto_groups[] = {
+ "gpio10",
+};
+static const char * const pri_mi2s_sck_b_groups[] = {
+ "gpio11",
+};
+static const char * const pri_mi2s_ws_a_groups[] = {
+ "gpio12",
+};
+static const char * const qdss_stm19_groups[] = {
+ "gpio12",
+};
+static const char * const pri_mi2s_data0_a_groups[] = {
+ "gpio13",
+};
+static const char * const qdss_stm18_groups[] = {
+ "gpio13",
+};
+static const char * const pri_mi2s_data1_a_groups[] = {
+ "gpio14",
+};
+static const char * const blsp_i2c4_groups[] = {
+ "gpio14", "gpio15", "gpio18", "gpio19",
+};
+static const char * const slimbus_data_groups[] = {
+ "gpio14",
+};
+static const char * const qdss_stm17_groups[] = {
+ "gpio14",
+};
+static const char * const bimc_dte0_groups[] = {
+ "gpio14", "gpio59",
+};
+static const char * const native_tsens_groups[] = {
+ "gpio14",
+};
+static const char * const pri_mi2s_sck_a_groups[] = {
+ "gpio15",
+};
+static const char * const slimbus_clk_groups[] = {
+ "gpio15",
+};
+static const char * const qdss_stm16_groups[] = {
+ "gpio15",
+};
+static const char * const bimc_dte1_groups[] = {
+ "gpio15", "gpio60",
+};
+static const char * const sec_mi2s_ws_a_groups[] = {
+ "gpio16",
+};
+static const char * const blsp_spi4_groups[] = {
+ "gpio16", "gpio17", "gpio18", "gpio19", "gpio68", "gpio69", "gpio71",
+};
+static const char * const qdss_stm27_groups[] = {
+ "gpio16",
+};
+static const char * const sec_mi2s_data0_a_groups[] = {
+ "gpio17",
+};
+static const char * const qdss_cti_groups[] = {
+ "gpio17", "gpio18", "gpio52", "gpio53", "gpio92", "gpio93",
+};
+static const char * const qdss_stm26_groups[] = {
+ "gpio17",
+};
+static const char * const sec_mi2s_data1_a_groups[] = {
+ "gpio18",
+};
+static const char * const qdss_stm25_groups[] = {
+ "gpio18",
+};
+static const char * const sec_mi2s_sck_a_groups[] = {
+ "gpio19",
+};
+static const char * const qdss_stm24_groups[] = {
+ "gpio19",
+};
+static const char * const sec_mi2s_ws_b_groups[] = {
+ "gpio20",
+};
+static const char * const ebi2_a_groups[] = {
+ "gpio20",
+};
+static const char * const sec_mi2s_data0_b_groups[] = {
+ "gpio21",
+};
+static const char * const ebi2_lcd_groups[] = {
+ "gpio21", "gpio22", "gpio23",
+};
+static const char * const sec_mi2s_data1_b_groups[] = {
+ "gpio22",
+};
+static const char * const ebi1_smt4_groups[] = {
+ "gpio22",
+};
+static const char * const sec_mi2s_sck_b_groups[] = {
+ "gpio23",
+};
+static const char * const m_voc_ext_vfr_ref_irq_a_groups[] = {
+ "gpio24",
+};
+static const char * const adsp_ext_vfr_irq_a_groups[] = {
+ "gpio24",
+};
+static const char * const qdss_stm11_groups[] = {
+ "gpio24",
+};
+static const char * const epm1_groups[] = {
+ "gpio25",
+};
+static const char * const m_voc_ext_vfr_ref_irq_2_a_groups[] = {
+ "gpio25",
+};
+static const char * const adsp_ext_vfr_irq_b_groups[] = {
+ "gpio25",
+};
+static const char * const qdss_stm10_groups[] = {
+ "gpio25",
+};
+static const char * const native_char_groups[] = {
+ "gpio27",
+};
+static const char * const native_char3_groups[] = {
+ "gpio28",
+};
+static const char * const native_char2_groups[] = {
+ "gpio29",
+};
+static const char * const native_char1_groups[] = {
+ "gpio32",
+};
+static const char * const native_char0_groups[] = {
+ "gpio33",
+};
+static const char * const pa_indicator_groups[] = {
+ "gpio36",
+};
+static const char * const qdss_traceclk_a_groups[] = {
+ "gpio36",
+};
+static const char * const prng_rosc_groups[] = {
+ "gpio47",
+};
+static const char * const nav_pps_in_a_groups[] = {
+ "gpio50",
+};
+static const char * const qdss_tracectl_a_groups[] = {
+ "gpio50",
+};
+static const char * const epm2_groups[] = {
+ "gpio51",
+};
+static const char * const nav_pps_in_b_groups[] = {
+ "gpio51",
+};
+static const char * const coex_uart_groups[] = {
+ "gpio52", "gpio53",
+};
+static const char * const nav_dr_groups[] = {
+ "gpio39",
+};
+static const char * const cri_trng0_groups[] = {
+ "gpio40",
+};
+static const char * const qlink_req_groups[] = {
+ "gpio41",
+};
+static const char * const qlink_en_groups[] = {
+ "gpio42",
+};
+static const char * const cri_trng1_groups[] = {
+ "gpio43",
+};
+static const char * const cri_trng_groups[] = {
+ "gpio44",
+};
+static const char * const ap2mdm_status_groups[] = {
+ "gpio54",
+};
+static const char * const mdm2ap_status_groups[] = {
+ "gpio55",
+};
+static const char * const ap2mdm_err_groups[] = {
+ "gpio56",
+};
+static const char * const mdm2ap_err_groups[] = {
+ "gpio57",
+};
+static const char * const qdss_stm15_groups[] = {
+ "gpio57",
+};
+static const char * const ap2mdm_vdd_groups[] = {
+ "gpio58",
+};
+static const char * const qdss_stm14_groups[] = {
+ "gpio58",
+};
+static const char * const mdm2ap_vdd_groups[] = {
+ "gpio59",
+};
+static const char * const qdss_stm13_groups[] = {
+ "gpio59",
+};
+static const char * const ap2mdm_wake_groups[] = {
+ "gpio60",
+};
+static const char * const m_voc_ext_vfr_ref_irq_2_b_groups[] = {
+ "gpio60",
+};
+static const char * const qdss_stm12_groups[] = {
+ "gpio60",
+};
+static const char * const pciehost_rst_groups[] = {
+ "gpio61",
+};
+static const char * const pci_e_groups[] = {
+ "gpio61", "gpio61", "gpio65",
+};
+static const char * const qdss_stm9_groups[] = {
+ "gpio61",
+};
+static const char * const qdss_cti_trig1_out_a_groups[] = {
+ "gpio62",
+};
+static const char * const qdss_cti_trig2_in_b_groups[] = {
+ "gpio62",
+};
+static const char * const qdss_stm8_groups[] = {
+ "gpio62",
+};
+static const char * const qdss_cti_trig1_in_a_groups[] = {
+ "gpio63",
+};
+static const char * const qdss_cti_trig2_out_b_groups[] = {
+ "gpio63",
+};
+static const char * const qdss_stm7_groups[] = {
+ "gpio63",
+};
+static const char * const pcie_clkreq_groups[] = {
+ "gpio64",
+};
+static const char * const qdss_stm6_groups[] = {
+ "gpio64",
+};
+static const char * const qdss_stm5_groups[] = {
+ "gpio65",
+};
+static const char * const ap2mdm_chnl_groups[] = {
+ "gpio66",
+};
+static const char * const qdss_stm4_groups[] = {
+ "gpio66",
+};
+static const char * const qdss_cti_trig2_out_a_groups[] = {
+ "gpio67",
+};
+static const char * const qdss_stm3_groups[] = {
+ "gpio67",
+};
+static const char * const mdm2ap_chnl_groups[] = {
+ "gpio68",
+};
+static const char * const m_voc_ext_vfr_ref_irq_b_groups[] = {
+ "gpio68",
+};
+static const char * const qdss_stm2_groups[] = {
+ "gpio68",
+};
+static const char * const uim_batt_groups[] = {
+ "gpio69",
+};
+static const char * const qdss_stm1_groups[] = {
+ "gpio69",
+};
+static const char * const qdss_cti_trig2_in_a_groups[] = {
+ "gpio70",
+};
+static const char * const qdss_stm0_groups[] = {
+ "gpio70",
+};
+static const char * const i2s_mclk_groups[] = {
+ "gpio71",
+};
+static const char * const audio_ref_groups[] = {
+ "gpio71",
+};
+static const char * const ldo_update_groups[] = {
+ "gpio71",
+};
+static const char * const dbg_out_groups[] = {
+ "gpio71",
+};
+static const char * const gcc_plltest_groups[] = {
+ "gpio73", "gpio74",
+};
+static const char * const uim1_data_groups[] = {
+ "gpio76",
+};
+static const char * const uim1_present_groups[] = {
+ "gpio77",
+};
+static const char * const uim1_reset_groups[] = {
+ "gpio78",
+};
+static const char * const uim1_clk_groups[] = {
+ "gpio79",
+};
+
+static const struct msm_function mdm9650_functions[] = {
+ FUNCTION(gpio),
+ FUNCTION(uim2_data),
+ FUNCTION(qdss_stm31),
+ FUNCTION(ebi0_wrcdc),
+ FUNCTION(uim2_present),
+ FUNCTION(blsp_uart1),
+ FUNCTION(qdss_stm30),
+ FUNCTION(blsp_spi1),
+ FUNCTION(uim2_reset),
+ FUNCTION(blsp_i2c1),
+ FUNCTION(qdss_stm29),
+ FUNCTION(uim2_clk),
+ FUNCTION(qdss_stm28),
+ FUNCTION(blsp_spi2),
+ FUNCTION(blsp_uart2),
+ FUNCTION(qdss_stm23),
+ FUNCTION(qdss_tracedata_a),
+ FUNCTION(qdss_stm22),
+ FUNCTION(blsp_i2c2),
+ FUNCTION(qdss_stm21),
+ FUNCTION(qdss_stm20),
+ FUNCTION(pri_mi2s_ws_b),
+ FUNCTION(blsp_spi3),
+ FUNCTION(blsp_uart3),
+ FUNCTION(ldo_en),
+ FUNCTION(qdss_cti_trig1_out_b),
+ FUNCTION(pwr_modem),
+ FUNCTION(pri_mi2s_data0_b),
+ FUNCTION(qdss_cti_trig1_in_b),
+ FUNCTION(pwr_nav),
+ FUNCTION(pri_mi2s_data1_b),
+ FUNCTION(blsp_i2c3),
+ FUNCTION(pwr_crypto),
+ FUNCTION(pri_mi2s_sck_b),
+ FUNCTION(pri_mi2s_ws_a),
+ FUNCTION(blsp_uart4),
+ FUNCTION(qdss_stm19),
+ FUNCTION(pri_mi2s_data0_a),
+ FUNCTION(qdss_stm18),
+ FUNCTION(pri_mi2s_data1_a),
+ FUNCTION(blsp_i2c4),
+ FUNCTION(slimbus_data),
+ FUNCTION(qdss_stm17),
+ FUNCTION(bimc_dte0),
+ FUNCTION(native_tsens),
+ FUNCTION(pri_mi2s_sck_a),
+ FUNCTION(slimbus_clk),
+ FUNCTION(qdss_stm16),
+ FUNCTION(bimc_dte1),
+ FUNCTION(sec_mi2s_ws_a),
+ FUNCTION(blsp_spi4),
+ FUNCTION(qdss_stm27),
+ FUNCTION(sec_mi2s_data0_a),
+ FUNCTION(qdss_cti),
+ FUNCTION(qdss_stm26),
+ FUNCTION(sec_mi2s_data1_a),
+ FUNCTION(qdss_stm25),
+ FUNCTION(sec_mi2s_sck_a),
+ FUNCTION(qdss_stm24),
+ FUNCTION(sec_mi2s_ws_b),
+ FUNCTION(ebi2_a),
+ FUNCTION(sec_mi2s_data0_b),
+ FUNCTION(ebi2_lcd),
+ FUNCTION(sec_mi2s_data1_b),
+ FUNCTION(ebi1_smt4),
+ FUNCTION(sec_mi2s_sck_b),
+ FUNCTION(m_voc_ext_vfr_ref_irq_a),
+ FUNCTION(adsp_ext_vfr_irq_a),
+ FUNCTION(qdss_stm11),
+ FUNCTION(epm1),
+ FUNCTION(m_voc_ext_vfr_ref_irq_2_a),
+ FUNCTION(adsp_ext_vfr_irq_b),
+ FUNCTION(qdss_stm10),
+ FUNCTION(native_char),
+ FUNCTION(native_char3),
+ FUNCTION(native_char2),
+ FUNCTION(native_char1),
+ FUNCTION(native_char0),
+ FUNCTION(pa_indicator),
+ FUNCTION(qdss_traceclk_a),
+ FUNCTION(prng_rosc),
+ FUNCTION(nav_pps_in_a),
+ FUNCTION(qdss_tracectl_a),
+ FUNCTION(epm2),
+ FUNCTION(nav_pps_in_b),
+ FUNCTION(coex_uart),
+ FUNCTION(nav_dr),
+ FUNCTION(cri_trng0),
+ FUNCTION(qlink_req),
+ FUNCTION(qlink_en),
+ FUNCTION(cri_trng1),
+ FUNCTION(cri_trng),
+ FUNCTION(ap2mdm_status),
+ FUNCTION(mdm2ap_status),
+ FUNCTION(ap2mdm_err),
+ FUNCTION(mdm2ap_err),
+ FUNCTION(qdss_stm15),
+ FUNCTION(ap2mdm_vdd),
+ FUNCTION(qdss_stm14),
+ FUNCTION(mdm2ap_vdd),
+ FUNCTION(qdss_stm13),
+ FUNCTION(ap2mdm_wake),
+ FUNCTION(m_voc_ext_vfr_ref_irq_2_b),
+ FUNCTION(qdss_stm12),
+ FUNCTION(pciehost_rst),
+ FUNCTION(pci_e),
+ FUNCTION(qdss_stm9),
+ FUNCTION(qdss_cti_trig1_out_a),
+ FUNCTION(qdss_cti_trig2_in_b),
+ FUNCTION(qdss_stm8),
+ FUNCTION(qdss_cti_trig1_in_a),
+ FUNCTION(qdss_cti_trig2_out_b),
+ FUNCTION(qdss_stm7),
+ FUNCTION(pcie_clkreq),
+ FUNCTION(qdss_stm6),
+ FUNCTION(qdss_stm5),
+ FUNCTION(ap2mdm_chnl),
+ FUNCTION(qdss_stm4),
+ FUNCTION(qdss_cti_trig2_out_a),
+ FUNCTION(qdss_stm3),
+ FUNCTION(mdm2ap_chnl),
+ FUNCTION(m_voc_ext_vfr_ref_irq_b),
+ FUNCTION(qdss_stm2),
+ FUNCTION(uim_batt),
+ FUNCTION(qdss_stm1),
+ FUNCTION(qdss_cti_trig2_in_a),
+ FUNCTION(qdss_stm0),
+ FUNCTION(i2s_mclk),
+ FUNCTION(audio_ref),
+ FUNCTION(ldo_update),
+ FUNCTION(dbg_out),
+ FUNCTION(gcc_plltest),
+ FUNCTION(uim1_data),
+ FUNCTION(uim1_present),
+ FUNCTION(uim1_reset),
+ FUNCTION(uim1_clk),
+};
+
+static const struct msm_pingroup mdm9650_groups[] = {
+ PINGROUP(0, uim2_data, blsp_spi1, blsp_uart1, qdss_stm31,
+ ebi0_wrcdc, NA, NA, NA, NA),
+ PINGROUP(1, uim2_present, blsp_spi1, blsp_uart1, qdss_stm30, NA,
+ NA, NA, NA, NA),
+ PINGROUP(2, uim2_reset, blsp_spi1, blsp_uart1, blsp_i2c1,
+ qdss_stm29, ebi0_wrcdc, NA, NA, NA),
+ PINGROUP(3, uim2_clk, blsp_spi1, blsp_uart1, blsp_i2c1,
+ qdss_stm28, NA, NA, NA, NA),
+ PINGROUP(4, blsp_spi2, blsp_uart2, NA, qdss_stm23, qdss_tracedata_a,
+ NA, NA, NA, NA),
+ PINGROUP(5, blsp_spi2, blsp_uart2, NA, qdss_stm22, qdss_tracedata_a,
+ NA, NA, NA, NA),
+ PINGROUP(6, blsp_spi2, blsp_uart2, blsp_i2c2, NA, qdss_stm21,
+ qdss_tracedata_a, NA, NA, NA),
+ PINGROUP(7, blsp_spi2, blsp_uart2, blsp_i2c2, NA, qdss_stm20,
+ qdss_tracedata_a, NA, NA, NA),
+ PINGROUP(8, pri_mi2s_ws_b, blsp_spi3, blsp_uart3, ldo_en, NA,
+ qdss_tracedata_a, qdss_cti_trig1_out_b, pwr_modem, NA),
+ PINGROUP(9, pri_mi2s_data0_b, blsp_spi3, blsp_uart3, NA,
+ qdss_tracedata_a, qdss_cti_trig1_in_b, pwr_nav, NA, NA),
+ PINGROUP(10, pri_mi2s_data1_b, blsp_spi3, blsp_uart3, blsp_i2c3,
+ pwr_crypto, NA, NA, NA, NA),
+ PINGROUP(11, pri_mi2s_sck_b, blsp_spi3, blsp_uart3, blsp_i2c3, NA, NA,
+ NA, NA, NA),
+ PINGROUP(12, pri_mi2s_ws_a, blsp_uart4, NA, qdss_stm19, NA, NA,
+ NA, NA, NA),
+ PINGROUP(13, pri_mi2s_data0_a, blsp_uart4, NA, qdss_stm18, NA, NA,
+ NA, NA, NA),
+ PINGROUP(14, pri_mi2s_data1_a, blsp_uart4, blsp_i2c4,
+ slimbus_data, NA, NA, qdss_stm17, bimc_dte0, native_tsens),
+ PINGROUP(15, pri_mi2s_sck_a, blsp_uart4, blsp_i2c4,
+ slimbus_clk, NA, qdss_stm16, bimc_dte1, NA, NA),
+ PINGROUP(16, sec_mi2s_ws_a, blsp_spi4, blsp_uart4, NA, NA,
+ qdss_stm27, qdss_tracedata_a, NA, NA),
+ PINGROUP(17, sec_mi2s_data0_a, blsp_spi4, blsp_uart4, qdss_cti,
+ qdss_stm26, qdss_tracedata_a, NA, NA, NA),
+ PINGROUP(18, sec_mi2s_data1_a, blsp_spi4, blsp_uart4,
+ blsp_i2c4, qdss_cti, NA, qdss_stm25, qdss_tracedata_a,
+ NA),
+ PINGROUP(19, sec_mi2s_sck_a, blsp_spi4, blsp_uart4,
+ blsp_i2c4, NA, qdss_stm24, qdss_tracedata_a, NA, NA),
+ PINGROUP(20, sec_mi2s_ws_b, ebi2_a, blsp_uart1, qdss_tracedata_a,
+ NA, NA, NA, NA, NA),
+ PINGROUP(21, sec_mi2s_data0_b, ebi2_lcd, blsp_uart1, NA, NA, NA,
+ NA, NA, NA),
+ PINGROUP(22, sec_mi2s_data1_b, ebi2_lcd, blsp_uart1,
+ qdss_tracedata_a, NA, ebi1_smt4, NA, NA, NA),
+ PINGROUP(23, sec_mi2s_sck_b, ebi2_lcd, blsp_uart1, NA, NA, NA,
+ NA, NA, NA),
+ PINGROUP(24, m_voc_ext_vfr_ref_irq_a, adsp_ext_vfr_irq_a, NA,
+ qdss_stm11, NA, NA, NA, NA, NA),
+ PINGROUP(25, m_voc_ext_vfr_ref_irq_2_a, adsp_ext_vfr_irq_b, NA,
+ qdss_stm10, NA, NA, NA, NA, NA),
+ PINGROUP(26, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(27, NA, NA, native_char, NA, NA, NA, NA, NA, NA),
+ PINGROUP(28, NA, NA, NA, native_char3, NA, NA, NA, NA, NA),
+ PINGROUP(29, NA, NA, NA, native_char2, NA, NA, NA, NA, NA),
+ PINGROUP(30, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(31, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(32, NA, native_char1, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(33, NA, native_char0, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(34, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(35, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(36, NA, pa_indicator, qdss_traceclk_a, NA, NA, NA, NA, NA, NA),
+ PINGROUP(37, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(38, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(39, NA, nav_dr, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(40, cri_trng0, qdss_tracedata_a, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(41, qlink_req, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(42, qlink_en, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(43, cri_trng1, qdss_tracedata_a, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(44, NA, cri_trng, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(45, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(46, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(47, NA, prng_rosc, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(48, NA, blsp_i2c2, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(49, NA, blsp_i2c2, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(50, nav_pps_in_a, qdss_tracectl_a, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(51, nav_pps_in_b, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(52, coex_uart, qdss_cti, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(53, coex_uart, NA, qdss_cti, NA, NA, NA, NA, NA, NA),
+ PINGROUP(54, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(55, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(56, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(57, NA, qdss_stm15, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(58, NA, qdss_stm14, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(59, NA, qdss_stm13, bimc_dte0, NA, NA, NA, NA, NA, NA),
+ PINGROUP(60, m_voc_ext_vfr_ref_irq_2_b, blsp_spi2, NA, NA, qdss_stm12,
+ bimc_dte1, NA, NA, NA),
+ PINGROUP(61, pci_e, pci_e, NA, NA, qdss_stm9, NA, NA, NA, NA),
+ PINGROUP(62, qdss_cti_trig1_out_a, qdss_cti_trig2_in_b, NA, qdss_stm8,
+ NA, NA, NA, NA, NA),
+ PINGROUP(63, qdss_cti_trig1_in_a, qdss_cti_trig2_out_b, NA, qdss_stm7,
+ NA, NA, NA, NA, NA),
+ PINGROUP(64, pcie_clkreq, qdss_stm6, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(65, NA, qdss_stm5, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(66, NA, qdss_stm4, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(67, qdss_cti_trig2_out_a, NA, qdss_stm3, NA, NA, NA, NA, NA,
+ NA),
+ PINGROUP(68, m_voc_ext_vfr_ref_irq_b, blsp_spi1, blsp_spi2, blsp_spi3,
+ blsp_spi4, NA, qdss_stm2, qdss_tracedata_a, NA),
+ PINGROUP(69, uim_batt, blsp_spi1, blsp_spi3, blsp_spi4, qdss_stm1,
+ qdss_tracedata_a, NA, NA, NA),
+ PINGROUP(70, qdss_cti_trig2_in_a, NA, qdss_stm0, NA, NA, NA, NA, NA,
+ NA),
+ PINGROUP(71, i2s_mclk, audio_ref, blsp_spi1, blsp_spi2, blsp_spi3,
+ blsp_spi4, ldo_update, dbg_out, NA),
+ PINGROUP(72, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(73, NA, NA, gcc_plltest, NA, NA, NA, NA, NA, NA),
+ PINGROUP(74, NA, gcc_plltest, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(75, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(76, uim1_data, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(77, uim1_present, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(78, uim1_reset, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(79, uim1_clk, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(80, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(81, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(82, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(83, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(84, NA, NA, blsp_i2c1, NA, NA, NA, NA, NA, NA),
+ PINGROUP(85, NA, NA, blsp_i2c1, NA, NA, NA, NA, NA, NA),
+ PINGROUP(86, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(87, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(88, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(89, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(90, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(91, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(92, NA, NA, qdss_cti, NA, NA, NA, NA, NA, NA),
+ PINGROUP(93, NA, NA, qdss_cti, NA, NA, NA, NA, NA, NA),
+ PINGROUP(94, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(95, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(96, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(97, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(98, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(99, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ SDC_QDSD_PINGROUP(sdc1_clk, 0x10a000, 13, 6),
+ SDC_QDSD_PINGROUP(sdc1_cmd, 0x10a000, 11, 3),
+ SDC_QDSD_PINGROUP(sdc1_data, 0x10a000, 9, 0),
+ SDC_QDSD_PINGROUP(sdc2_clk, 0x109000, 14, 6),
+ SDC_QDSD_PINGROUP(sdc2_cmd, 0x109000, 11, 3),
+ SDC_QDSD_PINGROUP(sdc2_data, 0x109000, 9, 0),
+ SDC_QDSD_PINGROUP(qdsd_clk, 0x19c000, 3, 0),
+ SDC_QDSD_PINGROUP(qdsd_cmd, 0x19c000, 8, 5),
+ SDC_QDSD_PINGROUP(qdsd_data0, 0x19c000, 13, 10),
+ SDC_QDSD_PINGROUP(qdsd_data1, 0x19c000, 18, 15),
+ SDC_QDSD_PINGROUP(qdsd_data2, 0x19c000, 23, 20),
+ SDC_QDSD_PINGROUP(qdsd_data3, 0x19c000, 28, 25),
+};
+
+static const struct msm_pinctrl_soc_data mdm9650_pinctrl = {
+ .pins = mdm9650_pins,
+ .npins = ARRAY_SIZE(mdm9650_pins),
+ .functions = mdm9650_functions,
+ .nfunctions = ARRAY_SIZE(mdm9650_functions),
+ .groups = mdm9650_groups,
+ .ngroups = ARRAY_SIZE(mdm9650_groups),
+ .ngpios = 100,
+};
+
+static int mdm9650_pinctrl_probe(struct platform_device *pdev)
+{
+ return msm_pinctrl_probe(pdev, &mdm9650_pinctrl);
+}
+
+static const struct of_device_id mdm9650_pinctrl_of_match[] = {
+ { .compatible = "qcom,mdm9650-pinctrl", },
+ { },
+};
+
+static struct platform_driver mdm9650_pinctrl_driver = {
+ .driver = {
+ .name = "mdm9650-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = mdm9650_pinctrl_of_match,
+ },
+ .probe = mdm9650_pinctrl_probe,
+ .remove = msm_pinctrl_remove,
+};
+
+static int __init mdm9650_pinctrl_init(void)
+{
+ return platform_driver_register(&mdm9650_pinctrl_driver);
+}
+arch_initcall(mdm9650_pinctrl_init);
+
+static void __exit mdm9650_pinctrl_exit(void)
+{
+ platform_driver_unregister(&mdm9650_pinctrl_driver);
+}
+module_exit(mdm9650_pinctrl_exit);
+
+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. MDM9650 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, mdm9650_pinctrl_of_match);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 6307137..754c1f4 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -371,11 +371,9 @@
static int ipa3_active_clients_panic_notifier(struct notifier_block *this,
unsigned long event, void *ptr)
{
- mutex_lock(&ipa3_ctx->ipa3_active_clients.mutex);
ipa3_active_clients_log_print_table(active_clients_table_buf,
IPA3_ACTIVE_CLIENTS_TABLE_BUF_SIZE);
IPAERR("%s", active_clients_table_buf);
- mutex_unlock(&ipa3_ctx->ipa3_active_clients.mutex);
return NOTIFY_DONE;
}
@@ -4517,8 +4515,6 @@
IPADBG("teth_bridge initialized");
}
- ipa3_debugfs_init();
-
result = ipa3_uc_interface_init();
if (result)
IPAERR(":ipa Uc interface init failed (%d)\n", -result);
@@ -4556,6 +4552,8 @@
complete_all(&ipa3_ctx->init_completion_obj);
pr_info("IPA driver initialization was successful.\n");
+ ipa3_debugfs_init();
+
return 0;
fail_teth_bridge_driver_init:
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
index 17e4838..93f2597 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
@@ -192,7 +192,7 @@
chan_props.ring_len = 2 * GSI_CHAN_RE_SIZE_16B;
chan_props.ring_base_vaddr =
dma_alloc_coherent(ipa3_ctx->pdev, chan_props.ring_len,
- &chan_dma_addr, 0);
+ &chan_dma_addr, GFP_ATOMIC);
chan_props.ring_base_addr = chan_dma_addr;
chan_dma->base = chan_props.ring_base_vaddr;
chan_dma->phys_base = chan_props.ring_base_addr;
@@ -295,7 +295,7 @@
memset(&xfer_elem, 0, sizeof(struct gsi_xfer_elem));
buff = dma_alloc_coherent(ipa3_ctx->pdev, 1, &dma_addr,
- GFP_KERNEL);
+ GFP_ATOMIC);
xfer_elem.addr = dma_addr;
xfer_elem.len = 1;
xfer_elem.flags = GSI_XFER_FLAG_EOT;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
index 2f9a468..9a0f44a 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
@@ -3555,6 +3555,11 @@
dma_addr_t dma_addr;
dma_addr_t evt_dma_addr;
int result;
+ gfp_t mem_flag = GFP_KERNEL;
+
+ if (in->client == IPA_CLIENT_APPS_WAN_CONS ||
+ in->client == IPA_CLIENT_APPS_WAN_PROD)
+ mem_flag = GFP_ATOMIC;
if (!ep) {
IPAERR("EP context is empty\n");
@@ -3592,7 +3597,7 @@
gsi_evt_ring_props.ring_base_vaddr =
dma_alloc_coherent(ipa3_ctx->pdev,
gsi_evt_ring_props.ring_len,
- &evt_dma_addr, GFP_KERNEL);
+ &evt_dma_addr, mem_flag);
if (!gsi_evt_ring_props.ring_base_vaddr) {
IPAERR("fail to dma alloc %u bytes\n",
gsi_evt_ring_props.ring_len);
@@ -3662,7 +3667,7 @@
gsi_channel_props.ring_len = 2 * in->desc_fifo_sz;
gsi_channel_props.ring_base_vaddr =
dma_alloc_coherent(ipa3_ctx->pdev, gsi_channel_props.ring_len,
- &dma_addr, GFP_KERNEL);
+ &dma_addr, mem_flag);
if (!gsi_channel_props.ring_base_vaddr) {
IPAERR("fail to dma alloc %u bytes\n",
gsi_channel_props.ring_len);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hw_stats.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hw_stats.c
index 8a4d945..547c9da 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_hw_stats.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hw_stats.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -24,12 +24,63 @@
int ipa_hw_stats_init(void)
{
+ int ret = 0, ep_index;
+ struct ipa_teth_stats_endpoints *teth_stats_init;
+
if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0)
return 0;
/* initialize stats here */
ipa3_ctx->hw_stats.enabled = true;
- return 0;
+
+ teth_stats_init = kzalloc(sizeof(*teth_stats_init), GFP_KERNEL);
+ if (!teth_stats_init) {
+ IPAERR("mem allocated failed!\n");
+ return -ENOMEM;
+ }
+ /* enable prod mask */
+ teth_stats_init->prod_mask = (
+ IPA_CLIENT_BIT_32(IPA_CLIENT_Q6_WAN_PROD) |
+ IPA_CLIENT_BIT_32(IPA_CLIENT_USB_PROD) |
+ IPA_CLIENT_BIT_32(IPA_CLIENT_WLAN1_PROD));
+
+ if (IPA_CLIENT_BIT_32(IPA_CLIENT_Q6_WAN_PROD)) {
+ ep_index = ipa3_get_ep_mapping(IPA_CLIENT_Q6_WAN_PROD);
+ if (ep_index == -1) {
+ IPAERR("Invalid client.\n");
+ kfree(teth_stats_init);
+ return -EINVAL;
+ }
+ teth_stats_init->dst_ep_mask[ep_index] =
+ (IPA_CLIENT_BIT_32(IPA_CLIENT_WLAN1_CONS) |
+ IPA_CLIENT_BIT_32(IPA_CLIENT_USB_CONS));
+ }
+
+ if (IPA_CLIENT_BIT_32(IPA_CLIENT_USB_PROD)) {
+ ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB_PROD);
+ if (ep_index == -1) {
+ IPAERR("Invalid client.\n");
+ kfree(teth_stats_init);
+ return -EINVAL;
+ }
+ teth_stats_init->dst_ep_mask[ep_index] =
+ IPA_CLIENT_BIT_32(IPA_CLIENT_Q6_WAN_CONS);
+ }
+
+ if (IPA_CLIENT_BIT_32(IPA_CLIENT_WLAN1_PROD)) {
+ ep_index = ipa3_get_ep_mapping(IPA_CLIENT_WLAN1_PROD);
+ if (ep_index == -1) {
+ IPAERR("Invalid client.\n");
+ kfree(teth_stats_init);
+ return -EINVAL;
+ }
+ teth_stats_init->dst_ep_mask[ep_index] =
+ IPA_CLIENT_BIT_32(IPA_CLIENT_Q6_WAN_CONS);
+ }
+
+ ret = ipa_init_teth_stats(teth_stats_init);
+ kfree(teth_stats_init);
+ return ret;
}
int ipa_init_quota_stats(u32 pipe_bitmask)
@@ -348,9 +399,12 @@
/* reset driver's cache */
memset(&ipa3_ctx->hw_stats.teth.init, 0,
sizeof(ipa3_ctx->hw_stats.teth.init));
- for (i = 0; i < IPA_CLIENT_MAX; i++)
+ for (i = 0; i < IPA_CLIENT_MAX; i++) {
+ memset(&ipa3_ctx->hw_stats.teth.prod_stats_sum[i], 0,
+ sizeof(ipa3_ctx->hw_stats.teth.prod_stats_sum[i]));
memset(&ipa3_ctx->hw_stats.teth.prod_stats[i], 0,
sizeof(ipa3_ctx->hw_stats.teth.prod_stats[i]));
+ }
ipa3_ctx->hw_stats.teth.init.prod_bitmask = in->prod_mask;
memcpy(ipa3_ctx->hw_stats.teth.init.cons_bitmask, in->dst_ep_mask,
sizeof(ipa3_ctx->hw_stats.teth.init.cons_bitmask));
@@ -458,8 +512,7 @@
return ret;
}
-int ipa_get_teth_stats(enum ipa_client_type prod,
- struct ipa_quota_stats_all *out)
+int ipa_get_teth_stats(void)
{
int i, j;
int ret;
@@ -470,15 +523,14 @@
struct ipa_mem_buffer mem;
struct ipa3_desc desc = { 0 };
struct ipahal_stats_tethering_all *stats;
+ struct ipa_hw_stats_teth *sw_stats = &ipa3_ctx->hw_stats.teth;
+ struct ipahal_stats_init_tethering *init =
+ (struct ipahal_stats_init_tethering *)
+ &ipa3_ctx->hw_stats.teth.init;
if (!ipa3_ctx->hw_stats.enabled)
return 0;
- if (!IPA_CLIENT_IS_PROD(prod) || ipa3_get_ep_mapping(prod) == -1) {
- IPAERR("invalid prod %d\n", prod);
- return -EINVAL;
- }
-
get_offset.init = ipa3_ctx->hw_stats.teth.init;
ret = ipahal_stats_get_offset(IPAHAL_HW_STATS_TETHERING, &get_offset,
&offset);
@@ -539,6 +591,12 @@
goto free_stats;
}
+ /* reset prod_stats cache */
+ for (i = 0; i < IPA_CLIENT_MAX; i++) {
+ memset(&ipa3_ctx->hw_stats.teth.prod_stats[i], 0,
+ sizeof(ipa3_ctx->hw_stats.teth.prod_stats[i]));
+ }
+
/*
* update driver cache.
* the stats were read from hardware with clear_after_read meaning
@@ -546,8 +604,6 @@
*/
for (i = 0; i < IPA_CLIENT_MAX; i++) {
for (j = 0; j < IPA_CLIENT_MAX; j++) {
- struct ipa_hw_stats_teth *sw_stats =
- &ipa3_ctx->hw_stats.teth;
int prod_idx = ipa3_get_ep_mapping(i);
int cons_idx = ipa3_get_ep_mapping(j);
@@ -557,29 +613,64 @@
if (cons_idx == -1 || cons_idx >= IPA3_MAX_NUM_PIPES)
continue;
- if (ipa3_ctx->ep[prod_idx].client != i ||
- ipa3_ctx->ep[cons_idx].client != j)
- continue;
+ /* save hw-query result */
+ if ((init->prod_bitmask & (1 << prod_idx)) &&
+ (init->cons_bitmask[prod_idx]
+ & (1 << cons_idx))) {
+ IPADBG_LOW("prod %d cons %d\n",
+ prod_idx, cons_idx);
+ IPADBG_LOW("num_ipv4_bytes %lld\n",
+ stats->stats[prod_idx][cons_idx].
+ num_ipv4_bytes);
+ IPADBG_LOW("num_ipv4_pkts %lld\n",
+ stats->stats[prod_idx][cons_idx].
+ num_ipv4_pkts);
+ IPADBG_LOW("num_ipv6_pkts %lld\n",
+ stats->stats[prod_idx][cons_idx].
+ num_ipv6_pkts);
+ IPADBG_LOW("num_ipv6_bytes %lld\n",
+ stats->stats[prod_idx][cons_idx].
+ num_ipv6_bytes);
- sw_stats->prod_stats[i].client[j].num_ipv4_bytes +=
- stats->stats[prod_idx][cons_idx].num_ipv4_bytes;
- sw_stats->prod_stats[i].client[j].num_ipv4_pkts +=
- stats->stats[prod_idx][cons_idx].num_ipv4_pkts;
- sw_stats->prod_stats[i].client[j].num_ipv6_bytes +=
- stats->stats[prod_idx][cons_idx].num_ipv6_bytes;
- sw_stats->prod_stats[i].client[j].num_ipv6_pkts +=
- stats->stats[prod_idx][cons_idx].num_ipv6_pkts;
+ /* update stats*/
+ sw_stats->prod_stats[i].
+ client[j].num_ipv4_bytes =
+ stats->stats[prod_idx][cons_idx].
+ num_ipv4_bytes;
+ sw_stats->prod_stats[i].
+ client[j].num_ipv4_pkts =
+ stats->stats[prod_idx][cons_idx].
+ num_ipv4_pkts;
+ sw_stats->prod_stats[i].
+ client[j].num_ipv6_bytes =
+ stats->stats[prod_idx][cons_idx].
+ num_ipv6_bytes;
+ sw_stats->prod_stats[i].
+ client[j].num_ipv6_pkts =
+ stats->stats[prod_idx][cons_idx].
+ num_ipv6_pkts;
+
+ /* Accumulated stats */
+ sw_stats->prod_stats_sum[i].
+ client[j].num_ipv4_bytes +=
+ stats->stats[prod_idx][cons_idx].
+ num_ipv4_bytes;
+ sw_stats->prod_stats_sum[i].
+ client[j].num_ipv4_pkts +=
+ stats->stats[prod_idx][cons_idx].
+ num_ipv4_pkts;
+ sw_stats->prod_stats_sum[i].
+ client[j].num_ipv6_bytes +=
+ stats->stats[prod_idx][cons_idx].
+ num_ipv6_bytes;
+ sw_stats->prod_stats_sum[i].
+ client[j].num_ipv6_pkts +=
+ stats->stats[prod_idx][cons_idx].
+ num_ipv6_pkts;
+ }
}
}
- if (!out) {
- ret = 0;
- goto free_stats;
- }
-
- /* copy results to out parameter */
- *out = ipa3_ctx->hw_stats.teth.prod_stats[prod];
-
ret = 0;
free_stats:
kfree(stats);
@@ -591,6 +682,22 @@
}
+int ipa_query_teth_stats(enum ipa_client_type prod,
+ struct ipa_quota_stats_all *out, bool reset)
+{
+ if (!IPA_CLIENT_IS_PROD(prod) || ipa3_get_ep_mapping(prod) == -1) {
+ IPAERR("invalid prod %d\n", prod);
+ return -EINVAL;
+ }
+
+ /* copy results to out parameter */
+ if (reset)
+ *out = ipa3_ctx->hw_stats.teth.prod_stats[prod];
+ else
+ *out = ipa3_ctx->hw_stats.teth.prod_stats_sum[prod];
+ return 0;
+}
+
int ipa_reset_teth_stats(enum ipa_client_type prod, enum ipa_client_type cons)
{
int ret;
@@ -605,14 +712,14 @@
}
/* reading stats will reset them in hardware */
- ret = ipa_get_teth_stats(prod, NULL);
+ ret = ipa_get_teth_stats();
if (ret) {
IPAERR("ipa_get_teth_stats failed %d\n", ret);
return ret;
}
/* reset driver's cache */
- stats = &ipa3_ctx->hw_stats.teth.prod_stats[prod].client[cons];
+ stats = &ipa3_ctx->hw_stats.teth.prod_stats_sum[prod].client[cons];
memset(stats, 0, sizeof(*stats));
return 0;
}
@@ -632,7 +739,7 @@
}
/* reading stats will reset them in hardware */
- ret = ipa_get_teth_stats(prod, NULL);
+ ret = ipa_get_teth_stats();
if (ret) {
IPAERR("ipa_get_teth_stats failed %d\n", ret);
return ret;
@@ -640,7 +747,7 @@
/* reset driver's cache */
for (i = 0; i < IPA_CLIENT_MAX; i++) {
- stats = &ipa3_ctx->hw_stats.teth.prod_stats[prod].client[i];
+ stats = &ipa3_ctx->hw_stats.teth.prod_stats_sum[prod].client[i];
memset(stats, 0, sizeof(*stats));
}
@@ -659,7 +766,7 @@
/* reading stats will reset them in hardware */
for (i = 0; i < IPA_CLIENT_MAX; i++) {
if (IPA_CLIENT_IS_PROD(i) && ipa3_get_ep_mapping(i) != -1) {
- ret = ipa_get_teth_stats(i, NULL);
+ ret = ipa_get_teth_stats();
if (ret) {
IPAERR("ipa_get_teth_stats failed %d\n", ret);
return ret;
@@ -671,7 +778,7 @@
/* reset driver's cache */
for (i = 0; i < IPA_CLIENT_MAX; i++) {
- stats = &ipa3_ctx->hw_stats.teth.prod_stats[i];
+ stats = &ipa3_ctx->hw_stats.teth.prod_stats_sum[i];
memset(stats, 0, sizeof(*stats));
}
@@ -1566,7 +1673,7 @@
(1 << ep_idx)))
continue;
- res = ipa_get_teth_stats(i, out);
+ res = ipa_get_teth_stats();
if (res) {
mutex_unlock(&ipa3_ctx->lock);
kfree(out);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index 4a8e7c7..d0db35a 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -1124,6 +1124,7 @@
struct ipa_hw_stats_teth {
struct ipahal_stats_init_tethering init;
+ struct ipa_quota_stats_all prod_stats_sum[IPA_CLIENT_MAX];
struct ipa_quota_stats_all prod_stats[IPA_CLIENT_MAX];
};
@@ -2251,8 +2252,10 @@
int ipa_init_teth_stats(struct ipa_teth_stats_endpoints *in);
-int ipa_get_teth_stats(enum ipa_client_type prod,
- struct ipa_quota_stats_all *out);
+int ipa_get_teth_stats(void);
+
+int ipa_query_teth_stats(enum ipa_client_type prod,
+ struct ipa_quota_stats_all *out, bool reset);
int ipa_reset_teth_stats(enum ipa_client_type prod, enum ipa_client_type cons);
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
index 833520c..561c533 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
@@ -3183,9 +3183,6 @@
req->reset_stats_valid = true;
req->reset_stats = true;
IPAWANDBG("reset the pipe stats\n");
- } else {
- /* print tethered-client enum */
- IPAWANDBG("Tethered-client enum(%d)\n", data->ipa_client);
}
rc = ipa3_qmi_get_data_stats(req, resp);
@@ -3277,7 +3274,7 @@
if (data->ipa_client == ipa_get_client(resp->
ul_src_pipe_stats_list[pipe_len].
pipe_index)) {
- /* update the DL stats */
+ /* update the UL stats */
data->ipv4_tx_packets += resp->
ul_src_pipe_stats_list[pipe_len].
num_ipv4_packets;
@@ -3304,6 +3301,133 @@
return 0;
}
+static int rmnet_ipa3_query_tethering_stats_hw(
+ struct wan_ioctl_query_tether_stats *data, bool reset)
+{
+ int rc = 0;
+ struct ipa_quota_stats_all *con_stats;
+
+ if (reset) {
+ IPAWANERR("only reset the pipe stats without returning stats");
+ rc = ipa_get_teth_stats();
+ if (rc) {
+ IPAWANERR("ipa_get_teth_stats failed %d,\n", rc);
+ return rc;
+ }
+ return 0;
+ }
+ /* qet HW-stats */
+ rc = ipa_get_teth_stats();
+ if (rc) {
+ IPAWANDBG("ipa_get_teth_stats failed %d,\n", rc);
+ return rc;
+ }
+
+ /* query DL stats */
+ IPAWANDBG("reset the pipe stats? (%d)\n", reset);
+ con_stats = kzalloc(sizeof(*con_stats), GFP_KERNEL);
+ if (!con_stats) {
+ IPAWANERR("no memory\n");
+ return -ENOMEM;
+ }
+ rc = ipa_query_teth_stats(IPA_CLIENT_Q6_WAN_PROD, con_stats, reset);
+ if (rc) {
+ IPAERR("IPA_CLIENT_Q6_WAN_PROD query failed %d,\n", rc);
+ kfree(con_stats);
+ return rc;
+ }
+ IPAWANDBG("wlan: v4_rx_p(%d) b(%lld) v6_rx_p(%d) b(%lld)\n",
+ con_stats->client[IPA_CLIENT_WLAN1_CONS].num_ipv4_pkts,
+ con_stats->client[IPA_CLIENT_WLAN1_CONS].num_ipv4_bytes,
+ con_stats->client[IPA_CLIENT_WLAN1_CONS].num_ipv6_pkts,
+ con_stats->client[IPA_CLIENT_WLAN1_CONS].num_ipv6_bytes);
+
+ IPAWANDBG("usb: v4_rx_p(%d) b(%lld) v6_rx_p(%d) b(%lld)\n",
+ con_stats->client[IPA_CLIENT_USB_CONS].num_ipv4_pkts,
+ con_stats->client[IPA_CLIENT_USB_CONS].num_ipv4_bytes,
+ con_stats->client[IPA_CLIENT_USB_CONS].num_ipv6_pkts,
+ con_stats->client[IPA_CLIENT_USB_CONS].num_ipv6_bytes);
+
+ /* update the DL stats */
+ data->ipv4_rx_packets =
+ con_stats->client[IPA_CLIENT_WLAN1_CONS].num_ipv4_pkts +
+ con_stats->client[IPA_CLIENT_USB_CONS].num_ipv4_pkts;
+ data->ipv6_rx_packets =
+ con_stats->client[IPA_CLIENT_WLAN1_CONS].num_ipv6_pkts +
+ con_stats->client[IPA_CLIENT_USB_CONS].num_ipv6_pkts;
+ data->ipv4_rx_bytes =
+ con_stats->client[IPA_CLIENT_WLAN1_CONS].num_ipv4_bytes +
+ con_stats->client[IPA_CLIENT_USB_CONS].num_ipv4_bytes;
+ data->ipv6_rx_bytes =
+ con_stats->client[IPA_CLIENT_WLAN1_CONS].num_ipv6_bytes +
+ con_stats->client[IPA_CLIENT_USB_CONS].num_ipv6_bytes;
+
+ IPAWANDBG("v4_rx_p(%lu) v6_rx_p(%lu) v4_rx_b(%lu) v6_rx_b(%lu)\n",
+ (unsigned long int) data->ipv4_rx_packets,
+ (unsigned long int) data->ipv6_rx_packets,
+ (unsigned long int) data->ipv4_rx_bytes,
+ (unsigned long int) data->ipv6_rx_bytes);
+
+ /* query USB UL stats */
+ memset(con_stats, 0, sizeof(struct ipa_quota_stats_all));
+ rc = ipa_query_teth_stats(IPA_CLIENT_USB_PROD, con_stats, reset);
+ if (rc) {
+ IPAERR("IPA_CLIENT_USB_PROD query failed %d\n", rc);
+ kfree(con_stats);
+ return rc;
+ }
+
+ IPAWANDBG("usb: v4_tx_p(%d) b(%lld) v6_tx_p(%d) b(%lld)\n",
+ con_stats->client[IPA_CLIENT_Q6_WAN_CONS].num_ipv4_pkts,
+ con_stats->client[IPA_CLIENT_Q6_WAN_CONS].num_ipv4_bytes,
+ con_stats->client[IPA_CLIENT_Q6_WAN_CONS].num_ipv6_pkts,
+ con_stats->client[IPA_CLIENT_Q6_WAN_CONS].num_ipv6_bytes);
+
+ /* update the USB UL stats */
+ data->ipv4_tx_packets =
+ con_stats->client[IPA_CLIENT_Q6_WAN_CONS].num_ipv4_pkts;
+ data->ipv6_tx_packets =
+ con_stats->client[IPA_CLIENT_Q6_WAN_CONS].num_ipv6_pkts;
+ data->ipv4_tx_bytes =
+ con_stats->client[IPA_CLIENT_Q6_WAN_CONS].num_ipv4_bytes;
+ data->ipv6_tx_bytes =
+ con_stats->client[IPA_CLIENT_Q6_WAN_CONS].num_ipv6_bytes;
+
+ /* query WLAN UL stats */
+ memset(con_stats, 0, sizeof(struct ipa_quota_stats_all));
+ rc = ipa_query_teth_stats(IPA_CLIENT_WLAN1_PROD, con_stats, reset);
+ if (rc) {
+ IPAERR("IPA_CLIENT_WLAN1_PROD query failed %d\n", rc);
+ kfree(con_stats);
+ return rc;
+ }
+
+ IPAWANDBG("wlan: v4_tx_p(%d) b(%lld) v6_tx_p(%d) b(%lld)\n",
+ con_stats->client[IPA_CLIENT_Q6_WAN_CONS].num_ipv4_pkts,
+ con_stats->client[IPA_CLIENT_Q6_WAN_CONS].num_ipv4_bytes,
+ con_stats->client[IPA_CLIENT_Q6_WAN_CONS].num_ipv6_pkts,
+ con_stats->client[IPA_CLIENT_Q6_WAN_CONS].num_ipv6_bytes);
+
+ /* update the wlan UL stats */
+ data->ipv4_tx_packets +=
+ con_stats->client[IPA_CLIENT_Q6_WAN_CONS].num_ipv4_pkts;
+ data->ipv6_tx_packets +=
+ con_stats->client[IPA_CLIENT_Q6_WAN_CONS].num_ipv6_pkts;
+ data->ipv4_tx_bytes +=
+ con_stats->client[IPA_CLIENT_Q6_WAN_CONS].num_ipv4_bytes;
+ data->ipv6_tx_bytes +=
+ con_stats->client[IPA_CLIENT_Q6_WAN_CONS].num_ipv6_bytes;
+
+ IPAWANDBG("v4_tx_p(%lu) v6_tx_p(%lu) v4_tx_b(%lu) v6_tx_b(%lu)\n",
+ (unsigned long int) data->ipv4_tx_packets,
+ (unsigned long int) data->ipv6_tx_packets,
+ (unsigned long int) data->ipv4_tx_bytes,
+ (unsigned long int) data->ipv6_tx_bytes);
+ kfree(con_stats);
+ return rc;
+}
+
+
int rmnet_ipa3_query_tethering_stats(struct wan_ioctl_query_tether_stats *data,
bool reset)
{
@@ -3373,11 +3497,26 @@
} else {
IPAWANDBG_LOW(" query modem-backhaul stats\n");
tether_stats.ipa_client = data->ipa_client;
- rc = rmnet_ipa3_query_tethering_stats_modem(
- &tether_stats, data->reset_stats);
- if (rc) {
- IPAWANERR("modem WAN_IOC_QUERY_TETHER_STATS failed\n");
- return rc;
+ if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0 ||
+ !ipa3_ctx->hw_stats.enabled) {
+ IPAWANDBG("hw version %d,hw_stats.enabled %d\n",
+ ipa3_ctx->ipa_hw_type,
+ ipa3_ctx->hw_stats.enabled);
+ /* get modem stats from QMI */
+ rc = rmnet_ipa3_query_tethering_stats_modem(
+ &tether_stats, data->reset_stats);
+ if (rc) {
+ IPAWANERR("modem QUERY_TETHER_STATS failed\n");
+ return rc;
+ }
+ } else {
+ /* get modem stats from IPA-HW counters */
+ rc = rmnet_ipa3_query_tethering_stats_hw(
+ &tether_stats, data->reset_stats);
+ if (rc) {
+ IPAWANERR("modem QUERY_TETHER_STATS failed\n");
+ return rc;
+ }
}
data->tx_bytes = tether_stats.ipv4_tx_bytes
+ tether_stats.ipv6_tx_bytes;
diff --git a/drivers/power/supply/qcom/fg-core.h b/drivers/power/supply/qcom/fg-core.h
index e77cf35..76bb974 100644
--- a/drivers/power/supply/qcom/fg-core.h
+++ b/drivers/power/supply/qcom/fg-core.h
@@ -182,8 +182,10 @@
FG_SRAM_DELTA_BSOC_THR,
FG_SRAM_RECHARGE_SOC_THR,
FG_SRAM_RECHARGE_VBATT_THR,
+ FG_SRAM_KI_COEFF_LOW_DISCHG,
FG_SRAM_KI_COEFF_MED_DISCHG,
FG_SRAM_KI_COEFF_HI_DISCHG,
+ FG_SRAM_KI_COEFF_HI_CHG,
FG_SRAM_KI_COEFF_FULL_SOC,
FG_SRAM_ESR_TIGHT_FILTER,
FG_SRAM_ESR_BROAD_FILTER,
@@ -299,6 +301,8 @@
int esr_meas_curr_ma;
int bmd_en_delay_ms;
int ki_coeff_full_soc_dischg;
+ int ki_coeff_low_dischg;
+ int ki_coeff_hi_chg;
int jeita_thresholds[NUM_JEITA_LEVELS];
int ki_coeff_soc[KI_COEFF_SOC_LEVELS];
int ki_coeff_med_dischg[KI_COEFF_SOC_LEVELS];
diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c
index 18732c0..420f2fd 100644
--- a/drivers/power/supply/qcom/qpnp-fg-gen3.c
+++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c
@@ -128,6 +128,8 @@
#define KI_COEFF_MED_DISCHG_v2_OFFSET 0
#define KI_COEFF_HI_DISCHG_v2_WORD 10
#define KI_COEFF_HI_DISCHG_v2_OFFSET 1
+#define KI_COEFF_HI_CHG_v2_WORD 11
+#define KI_COEFF_HI_CHG_v2_OFFSET 2
#define DELTA_BSOC_THR_v2_WORD 12
#define DELTA_BSOC_THR_v2_OFFSET 3
#define DELTA_MSOC_THR_v2_WORD 13
@@ -312,12 +314,18 @@
ESR_TIMER_CHG_INIT_OFFSET, 2, 1, 1, 0, fg_encode_default, NULL),
PARAM(ESR_PULSE_THRESH, ESR_PULSE_THRESH_WORD, ESR_PULSE_THRESH_OFFSET,
1, 100000, 390625, 0, fg_encode_default, NULL),
+ PARAM(KI_COEFF_LOW_DISCHG, KI_COEFF_LOW_DISCHG_v2_WORD,
+ KI_COEFF_LOW_DISCHG_v2_OFFSET, 1, 1000, 244141, 0,
+ fg_encode_default, NULL),
PARAM(KI_COEFF_MED_DISCHG, KI_COEFF_MED_DISCHG_v2_WORD,
KI_COEFF_MED_DISCHG_v2_OFFSET, 1, 1000, 244141, 0,
fg_encode_default, NULL),
PARAM(KI_COEFF_HI_DISCHG, KI_COEFF_HI_DISCHG_v2_WORD,
KI_COEFF_HI_DISCHG_v2_OFFSET, 1, 1000, 244141, 0,
fg_encode_default, NULL),
+ PARAM(KI_COEFF_HI_CHG, KI_COEFF_HI_CHG_v2_WORD,
+ KI_COEFF_HI_CHG_v2_OFFSET, 1, 1000, 244141, 0,
+ fg_encode_default, NULL),
PARAM(KI_COEFF_FULL_SOC, KI_COEFF_FULL_SOC_WORD,
KI_COEFF_FULL_SOC_OFFSET, 1, 1000, 244141, 0,
fg_encode_default, NULL),
@@ -4221,6 +4229,35 @@
}
}
+ if (chip->dt.ki_coeff_low_dischg != -EINVAL) {
+ fg_encode(chip->sp, FG_SRAM_KI_COEFF_LOW_DISCHG,
+ chip->dt.ki_coeff_low_dischg, &val);
+ rc = fg_sram_write(chip,
+ chip->sp[FG_SRAM_KI_COEFF_LOW_DISCHG].addr_word,
+ chip->sp[FG_SRAM_KI_COEFF_LOW_DISCHG].addr_byte,
+ &val, chip->sp[FG_SRAM_KI_COEFF_LOW_DISCHG].len,
+ FG_IMA_DEFAULT);
+ if (rc < 0) {
+ pr_err("Error in writing ki_coeff_low_dischg, rc=%d\n",
+ rc);
+ return rc;
+ }
+ }
+
+ if (chip->dt.ki_coeff_hi_chg != -EINVAL) {
+ fg_encode(chip->sp, FG_SRAM_KI_COEFF_HI_CHG,
+ chip->dt.ki_coeff_hi_chg, &val);
+ rc = fg_sram_write(chip,
+ chip->sp[FG_SRAM_KI_COEFF_HI_CHG].addr_word,
+ chip->sp[FG_SRAM_KI_COEFF_HI_CHG].addr_byte,
+ &val, chip->sp[FG_SRAM_KI_COEFF_HI_CHG].len,
+ FG_IMA_DEFAULT);
+ if (rc < 0) {
+ pr_err("Error in writing ki_coeff_hi_chg, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
return 0;
}
@@ -4683,6 +4720,16 @@
if (!rc)
chip->dt.ki_coeff_full_soc_dischg = temp;
+ chip->dt.ki_coeff_hi_chg = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,ki-coeff-hi-chg", &temp);
+ if (!rc)
+ chip->dt.ki_coeff_hi_chg = temp;
+
+ chip->dt.ki_coeff_low_dischg = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,ki-coeff-low-dischg", &temp);
+ if (!rc)
+ chip->dt.ki_coeff_low_dischg = temp;
+
rc = fg_parse_dt_property_u32_array(node, "qcom,ki-coeff-soc-dischg",
chip->dt.ki_coeff_soc, KI_COEFF_SOC_LEVELS);
if (rc < 0)
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 00b6e38..fe7ae5f 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -688,6 +688,7 @@
vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, false, 0);
vote(chg->usb_icl_votable, SW_QC3_VOTER, false, 0);
vote(chg->usb_icl_votable, USBIN_USBIN_BOOST_VOTER, false, 0);
+ vote(chg->usb_icl_votable, HVDCP2_ICL_VOTER, false, 0);
cancel_delayed_work_sync(&chg->hvdcp_detect_work);
@@ -2245,11 +2246,15 @@
pr_err("Failed to force 5V\n");
break;
case POWER_SUPPLY_DP_DM_FORCE_9V:
+ /* Force 1A ICL before requesting higher voltage */
+ vote(chg->usb_icl_votable, HVDCP2_ICL_VOTER, true, 1000000);
rc = smblib_force_vbus_voltage(chg, FORCE_9V_BIT);
if (rc < 0)
pr_err("Failed to force 9V\n");
break;
case POWER_SUPPLY_DP_DM_FORCE_12V:
+ /* Force 1A ICL before requesting higher voltage */
+ vote(chg->usb_icl_votable, HVDCP2_ICL_VOTER, true, 1000000);
rc = smblib_force_vbus_voltage(chg, FORCE_12V_BIT);
if (rc < 0)
pr_err("Failed to force 12V\n");
@@ -3607,10 +3612,12 @@
case QC_9V_BIT:
smblib_set_opt_freq_buck(chg,
chg->chg_freq.freq_9V);
+ vote(chg->usb_icl_votable, HVDCP2_ICL_VOTER, false, 0);
break;
case QC_12V_BIT:
smblib_set_opt_freq_buck(chg,
chg->chg_freq.freq_12V);
+ vote(chg->usb_icl_votable, HVDCP2_ICL_VOTER, false, 0);
break;
default:
smblib_set_opt_freq_buck(chg,
@@ -4131,6 +4138,7 @@
vote(chg->usb_icl_votable, SW_QC3_VOTER, false, 0);
vote(chg->usb_icl_votable, OTG_VOTER, false, 0);
vote(chg->usb_icl_votable, CTM_VOTER, false, 0);
+ vote(chg->usb_icl_votable, HVDCP2_ICL_VOTER, false, 0);
/* reset hvdcp voters */
vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, true, 0);
diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h
index 00a4086..32f2b4d 100644
--- a/drivers/power/supply/qcom/smb-lib.h
+++ b/drivers/power/supply/qcom/smb-lib.h
@@ -69,6 +69,7 @@
#define PL_FCC_LOW_VOTER "PL_FCC_LOW_VOTER"
#define WBC_VOTER "WBC_VOTER"
#define MOISTURE_VOTER "MOISTURE_VOTER"
+#define HVDCP2_ICL_VOTER "HVDCP2_ICL_VOTER"
#define VCONN_MAX_ATTEMPTS 3
#define OTG_MAX_ATTEMPTS 3
diff --git a/drivers/regulator/cpr4-apss-regulator.c b/drivers/regulator/cpr4-apss-regulator.c
index a9602cb..1f8f8be 100644
--- a/drivers/regulator/cpr4-apss-regulator.c
+++ b/drivers/regulator/cpr4-apss-regulator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, 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
@@ -36,9 +36,11 @@
#include "cpr3-regulator.h"
#define MSM8953_APSS_FUSE_CORNERS 4
+#define SDM632_POWER_APSS_FUSE_CORNERS 5
+#define SDM632_PERF_APSS_FUSE_CORNERS 3
/**
- * struct cpr4_msm8953_apss_fuses - APSS specific fuse data for MSM8953
+ * struct cpr4_apss_fuses - APSS specific fuse data
* @ro_sel: Ring oscillator select fuse parameter value for each
* fuse corner
* @init_voltage: Initial (i.e. open-loop) voltage fuse parameter value
@@ -61,11 +63,11 @@
*
* This struct holds the values for all of the fuses read from memory.
*/
-struct cpr4_msm8953_apss_fuses {
- u64 ro_sel[MSM8953_APSS_FUSE_CORNERS];
- u64 init_voltage[MSM8953_APSS_FUSE_CORNERS];
- u64 target_quot[MSM8953_APSS_FUSE_CORNERS];
- u64 quot_offset[MSM8953_APSS_FUSE_CORNERS];
+struct cpr4_apss_fuses {
+ u64 *ro_sel;
+ u64 *init_voltage;
+ u64 *target_quot;
+ u64 *quot_offset;
u64 speed_bin;
u64 cpr_fusing_rev;
u64 foundry_id;
@@ -80,6 +82,7 @@
* where: fusing revision = 0 - 7 and speed bin = 0 - 7
*/
#define CPR4_MSM8953_APSS_FUSE_COMBO_COUNT 64
+#define CPR4_SDM632_APSS_FUSE_COMBO_COUNT 64
/*
* Constants which define the name of each fuse corner.
@@ -98,6 +101,38 @@
[CPR4_MSM8953_APSS_FUSE_CORNER_TURBO_L1] = "TURBO_L1",
};
+enum cpr4_sdm632_power_apss_fuse_corner {
+ CPR4_SDM632_POWER_APSS_FUSE_CORNER_LOWSVS = 0,
+ CPR4_SDM632_POWER_APSS_FUSE_CORNER_SVS = 1,
+ CPR4_SDM632_POWER_APSS_FUSE_CORNER_SVS_L1 = 2,
+ CPR4_SDM632_POWER_APSS_FUSE_CORNER_NOM = 3,
+ CPR4_SDM632_POWER_APSS_FUSE_CORNER_TURBO_L1 = 4,
+};
+
+static const char * const cpr4_sdm632_power_apss_fuse_corner_name[] = {
+ [CPR4_SDM632_POWER_APSS_FUSE_CORNER_LOWSVS] = "LowSVS",
+ [CPR4_SDM632_POWER_APSS_FUSE_CORNER_SVS] = "SVS",
+ [CPR4_SDM632_POWER_APSS_FUSE_CORNER_SVS_L1] = "SVS_L1",
+ [CPR4_SDM632_POWER_APSS_FUSE_CORNER_NOM] = "NOM",
+ [CPR4_SDM632_POWER_APSS_FUSE_CORNER_TURBO_L1] = "TURBO_L1",
+};
+
+enum cpr4_sdm632_perf_apss_fuse_corner {
+ CPR4_SDM632_PERF_APSS_FUSE_CORNER_SVS_L1 = 0,
+ CPR4_SDM632_PERF_APSS_FUSE_CORNER_NOM = 1,
+ CPR4_SDM632_PERF_APSS_FUSE_CORNER_TURBO_L1 = 2,
+};
+
+static const char * const cpr4_sdm632_perf_apss_fuse_corner_name[] = {
+ [CPR4_SDM632_PERF_APSS_FUSE_CORNER_SVS_L1] = "SVS_L1",
+ [CPR4_SDM632_PERF_APSS_FUSE_CORNER_NOM] = "NOM",
+ [CPR4_SDM632_PERF_APSS_FUSE_CORNER_TURBO_L1] = "TURBO_L1",
+};
+
+/* APSS cluster thread IDs */
+#define CPR4_APSS_POWER_CLUSTER_ID 0
+#define CPR4_APSS_PERF_CLUSTER_ID 1
+
/*
* MSM8953 APSS fuse parameter locations:
*
@@ -179,12 +214,88 @@
};
/*
+ * SDM632 APSS fuse parameter locations:
+ *
+ * Structs are organized with the following dimensions:
+ * Outer: 0 to 3 for fuse corners from lowest to highest corner
+ * Inner: large enough to hold the longest set of parameter segments which
+ * fully defines a fuse parameter, +1 (for NULL termination).
+ * Each segment corresponds to a contiguous group of bits from a
+ * single fuse row. These segments are concatentated together in
+ * order to form the full fuse parameter value. The segments for
+ * a given parameter may correspond to different fuse rows.
+ */
+static const struct cpr3_fuse_param
+sdm632_apss_ro_sel_param[2][SDM632_POWER_APSS_FUSE_CORNERS][2] = {
+ [CPR4_APSS_POWER_CLUSTER_ID] = {
+ {{73, 28, 31}, {} },
+ {{73, 24, 27}, {} },
+ {{73, 20, 23}, {} },
+ {{73, 16, 19}, {} },
+ {{73, 12, 15}, {} },
+ },
+ [CPR4_APSS_PERF_CLUSTER_ID] = {
+ {{73, 8, 11}, {} },
+ {{73, 4, 7}, {} },
+ {{73, 0, 3}, {} },
+ },
+};
+
+static const struct cpr3_fuse_param
+sdm632_apss_init_voltage_param[2][SDM632_POWER_APSS_FUSE_CORNERS][2] = {
+ [CPR4_APSS_POWER_CLUSTER_ID] = {
+ {{74, 18, 23}, {} },
+ {{74, 12, 17}, {} },
+ {{71, 24, 29}, {} },
+ {{74, 6, 11}, {} },
+ {{74, 0, 5}, {} },
+ },
+ [CPR4_APSS_PERF_CLUSTER_ID] = {
+ {{71, 18, 23}, {} },
+ {{71, 12, 17}, {} },
+ {{71, 6, 11}, {} },
+ },
+};
+
+static const struct cpr3_fuse_param
+sdm632_apss_target_quot_param[2][SDM632_POWER_APSS_FUSE_CORNERS][2] = {
+ [CPR4_APSS_POWER_CLUSTER_ID] = {
+ {{75, 44, 55}, {} },
+ {{75, 32, 43}, {} },
+ {{72, 44, 55}, {} },
+ {{75, 20, 31}, {} },
+ {{75, 8, 19}, {} },
+ },
+ [CPR4_APSS_PERF_CLUSTER_ID] = {
+ {{72, 32, 43}, {} },
+ {{72, 20, 31}, {} },
+ {{72, 8, 19}, {} },
+ },
+};
+
+static const struct cpr3_fuse_param
+sdm632_apss_quot_offset_param[2][SDM632_POWER_APSS_FUSE_CORNERS][2] = {
+ [CPR4_APSS_POWER_CLUSTER_ID] = {
+ {{} },
+ {{74, 39, 45}, {} },
+ {{71, 46, 52}, {} },
+ {{74, 32, 38}, {} },
+ {{74, 24, 30}, {} },
+ },
+ [CPR4_APSS_PERF_CLUSTER_ID] = {
+ {{} },
+ {{71, 39, 45}, {} },
+ {{71, 32, 38}, {} },
+ },
+};
+
+/*
* The maximum number of fuse combinations possible for the selected fuse
* parameters in fuse combo map logic.
* Here, possible speed-bin values = 8, fuse revision values = 8, and foundry
* identifier values = 8. Total number of combinations = 512 (i.e., 8 * 8 * 8)
*/
-#define CPR4_MSM8953_APSS_FUSE_COMBO_MAP_MAX_COUNT 512
+#define CPR4_APSS_FUSE_COMBO_MAP_MAX_COUNT 512
/*
@@ -204,13 +315,37 @@
1065000,
};
-#define MSM8953_APSS_FUSE_STEP_VOLT 10000
-#define MSM8953_APSS_VOLTAGE_FUSE_SIZE 6
-#define MSM8953_APSS_QUOT_OFFSET_SCALE 5
+/*
+ * Open loop voltage fuse reference voltages in microvolts for SDM632
+ */
+static const int
+sdm632_apss_fuse_ref_volt[2][SDM632_POWER_APSS_FUSE_CORNERS] = {
+ [CPR4_APSS_POWER_CLUSTER_ID] = {
+ 645000,
+ 720000,
+ 790000,
+ 865000,
+ 1065000,
+ },
+ [CPR4_APSS_PERF_CLUSTER_ID] = {
+ 790000,
+ 865000,
+ 1065000,
+ },
+};
+
+#define CPR4_APSS_FUSE_STEP_VOLT 10000
+#define CPR4_APSS_VOLTAGE_FUSE_SIZE 6
+#define CPR4_APSS_QUOT_OFFSET_SCALE 5
#define MSM8953_APSS_CPR_SENSOR_COUNT 13
+#define SDM632_APSS_CPR_SENSOR_COUNT 16
+#define SDM632_APSS_THREAD0_SENSOR_MIN 0
+#define SDM632_APSS_THREAD0_SENSOR_MAX 6
+#define SDM632_APSS_THREAD1_SENSOR_MIN 7
+#define SDM632_APSS_THREAD1_SENSOR_MAX 15
-#define MSM8953_APSS_CPR_CLOCK_RATE 19200000
+#define CPR4_APSS_CPR_CLOCK_RATE 19200000
#define MSM8953_APSS_MAX_TEMP_POINTS 3
#define MSM8953_APSS_TEMP_SENSOR_ID_START 4
@@ -240,51 +375,31 @@
/* Use a very high value for max aging margin to be applied */
#define MSM8953_APSS_AGING_MAX_AGE_MARGIN_QUOT (-1000)
+/*
+ * SOC IDs
+ */
+enum soc_id {
+ MSM8953_SOC_ID = 1,
+ SDM632_SOC_ID = 2,
+};
+
/**
- * cpr4_msm8953_apss_read_fuse_data() - load APSS specific fuse parameter values
+ * cpr4_msm8953_apss_read_fuse_data() - load MSM8953 APSS specific fuse
+ * parameter values
* @vreg: Pointer to the CPR3 regulator
+ * @fuse: APSS specific fuse data
*
- * This function allocates a cpr4_msm8953_apss_fuses struct, fills it with
- * values read out of hardware fuses, and finally copies common fuse values
- * into the CPR3 regulator struct.
+ * This function fills cpr4_apss_fuses struct with values read out of hardware
+ * fuses.
*
* Return: 0 on success, errno on failure
*/
-static int cpr4_msm8953_apss_read_fuse_data(struct cpr3_regulator *vreg)
+static int cpr4_msm8953_apss_read_fuse_data(struct cpr3_regulator *vreg,
+ struct cpr4_apss_fuses *fuse)
{
void __iomem *base = vreg->thread->ctrl->fuse_base;
- struct cpr4_msm8953_apss_fuses *fuse;
int i, rc;
- fuse = devm_kzalloc(vreg->thread->ctrl->dev, sizeof(*fuse), GFP_KERNEL);
- if (!fuse)
- return -ENOMEM;
-
- rc = cpr3_read_fuse_param(base, msm8953_apss_speed_bin_param,
- &fuse->speed_bin);
- if (rc) {
- cpr3_err(vreg, "Unable to read speed bin fuse, rc=%d\n", rc);
- return rc;
- }
- cpr3_info(vreg, "speed bin = %llu\n", fuse->speed_bin);
-
- rc = cpr3_read_fuse_param(base, msm8953_cpr_fusing_rev_param,
- &fuse->cpr_fusing_rev);
- if (rc) {
- cpr3_err(vreg, "Unable to read CPR fusing revision fuse, rc=%d\n",
- rc);
- return rc;
- }
- cpr3_info(vreg, "CPR fusing revision = %llu\n", fuse->cpr_fusing_rev);
-
- rc = cpr3_read_fuse_param(base, msm8953_apss_foundry_id_param,
- &fuse->foundry_id);
- if (rc) {
- cpr3_err(vreg, "Unable to read foundry id fuse, rc=%d\n", rc);
- return rc;
- }
- cpr3_info(vreg, "foundry id = %llu\n", fuse->foundry_id);
-
rc = cpr3_read_fuse_param(base, msm8953_misc_fuse_volt_adj_param,
&fuse->misc);
if (rc) {
@@ -372,9 +487,180 @@
return -EINVAL;
}
+ return 0;
+}
+
+/**
+ * cpr4_sdm632_apss_read_fuse_data() - load SDM632 APSS specific fuse
+ * parameter values
+ * @vreg: Pointer to the CPR3 regulator
+ * @fuse: APSS specific fuse data
+ *
+ * This function fills cpr4_apss_fuses struct with values read out of hardware
+ * fuses.
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int cpr4_sdm632_apss_read_fuse_data(struct cpr3_regulator *vreg,
+ struct cpr4_apss_fuses *fuse)
+{
+ void __iomem *base = vreg->thread->ctrl->fuse_base;
+ int i, id, rc, fuse_corners;
+
+ id = vreg->thread->thread_id;
+ if (id == CPR4_APSS_POWER_CLUSTER_ID)
+ fuse_corners = SDM632_POWER_APSS_FUSE_CORNERS;
+ else
+ fuse_corners = SDM632_PERF_APSS_FUSE_CORNERS;
+
+ for (i = 0; i < fuse_corners; i++) {
+ rc = cpr3_read_fuse_param(base,
+ sdm632_apss_init_voltage_param[id][i],
+ &fuse->init_voltage[i]);
+ if (rc) {
+ cpr3_err(vreg, "Unable to read fuse-corner %d initial voltage fuse, rc=%d\n",
+ i, rc);
+ return rc;
+ }
+
+ rc = cpr3_read_fuse_param(base,
+ sdm632_apss_target_quot_param[id][i],
+ &fuse->target_quot[i]);
+ if (rc) {
+ cpr3_err(vreg, "Unable to read fuse-corner %d target quotient fuse, rc=%d\n",
+ i, rc);
+ return rc;
+ }
+
+ rc = cpr3_read_fuse_param(base,
+ sdm632_apss_ro_sel_param[id][i],
+ &fuse->ro_sel[i]);
+ if (rc) {
+ cpr3_err(vreg, "Unable to read fuse-corner %d RO select fuse, rc=%d\n",
+ i, rc);
+ return rc;
+ }
+
+ rc = cpr3_read_fuse_param(base,
+ sdm632_apss_quot_offset_param[id][i],
+ &fuse->quot_offset[i]);
+ if (rc) {
+ cpr3_err(vreg, "Unable to read fuse-corner %d quotient offset fuse, rc=%d\n",
+ i, rc);
+ return rc;
+ }
+ }
+
+ vreg->fuse_combo = fuse->cpr_fusing_rev + (8 * fuse->speed_bin);
+ if (vreg->fuse_combo >= CPR4_SDM632_APSS_FUSE_COMBO_COUNT) {
+ cpr3_err(vreg, "invalid CPR fuse combo = %d found\n",
+ vreg->fuse_combo);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * cpr4_apss_read_fuse_data() - load APSS specific fuse parameter values
+ * @vreg: Pointer to the CPR3 regulator
+ *
+ * This function allocates a cpr4_apss_fuses struct, fills it with
+ * values read out of hardware fuses, and finally copies common fuse values
+ * into the CPR3 regulator struct.
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int cpr4_apss_read_fuse_data(struct cpr3_regulator *vreg)
+{
+ void __iomem *base = vreg->thread->ctrl->fuse_base;
+ struct cpr4_apss_fuses *fuse;
+ int rc, fuse_corners;
+ enum soc_id soc_revision;
+
+ fuse = devm_kzalloc(vreg->thread->ctrl->dev, sizeof(*fuse), GFP_KERNEL);
+ if (!fuse)
+ return -ENOMEM;
+
+ soc_revision = vreg->thread->ctrl->soc_revision;
+ switch (soc_revision) {
+ case MSM8953_SOC_ID:
+ fuse_corners = MSM8953_APSS_FUSE_CORNERS;
+ break;
+ case SDM632_SOC_ID:
+ if (vreg->thread->thread_id == CPR4_APSS_POWER_CLUSTER_ID)
+ fuse_corners = SDM632_POWER_APSS_FUSE_CORNERS;
+ else
+ fuse_corners = SDM632_PERF_APSS_FUSE_CORNERS;
+ break;
+ default:
+ cpr3_err(vreg, "unsupported soc id = %d\n", soc_revision);
+ return -EINVAL;
+ }
+
+ fuse->ro_sel = devm_kcalloc(vreg->thread->ctrl->dev, fuse_corners,
+ sizeof(*fuse->ro_sel), GFP_KERNEL);
+ fuse->init_voltage = devm_kcalloc(vreg->thread->ctrl->dev, fuse_corners,
+ sizeof(*fuse->init_voltage), GFP_KERNEL);
+ fuse->target_quot = devm_kcalloc(vreg->thread->ctrl->dev, fuse_corners,
+ sizeof(*fuse->target_quot), GFP_KERNEL);
+ fuse->quot_offset = devm_kcalloc(vreg->thread->ctrl->dev, fuse_corners,
+ sizeof(*fuse->quot_offset), GFP_KERNEL);
+
+ if (!fuse->ro_sel || !fuse->init_voltage || !fuse->target_quot
+ || !fuse->quot_offset)
+ return -ENOMEM;
+
+ rc = cpr3_read_fuse_param(base, msm8953_apss_speed_bin_param,
+ &fuse->speed_bin);
+ if (rc) {
+ cpr3_err(vreg, "Unable to read speed bin fuse, rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = cpr3_read_fuse_param(base, msm8953_cpr_fusing_rev_param,
+ &fuse->cpr_fusing_rev);
+ if (rc) {
+ cpr3_err(vreg, "Unable to read CPR fusing revision fuse, rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ rc = cpr3_read_fuse_param(base, msm8953_apss_foundry_id_param,
+ &fuse->foundry_id);
+ if (rc) {
+ cpr3_err(vreg, "Unable to read foundry id fuse, rc=%d\n", rc);
+ return rc;
+ }
+ cpr3_info(vreg, "speed bin = %llu, CPR fusing revision = %llu, foundry id = %llu\n",
+ fuse->speed_bin, fuse->cpr_fusing_rev,
+ fuse->foundry_id);
+
+ switch (soc_revision) {
+ case MSM8953_SOC_ID:
+ rc = cpr4_msm8953_apss_read_fuse_data(vreg, fuse);
+ if (rc) {
+ cpr3_err(vreg, "msm8953 apss fuse data read failed, rc=%d\n",
+ rc);
+ return rc;
+ }
+ break;
+ case SDM632_SOC_ID:
+ rc = cpr4_sdm632_apss_read_fuse_data(vreg, fuse);
+ if (rc) {
+ cpr3_err(vreg, "sdm632 apss fuse data read failed, rc=%d\n",
+ rc);
+ return rc;
+ }
+ break;
+ default:
+ cpr3_err(vreg, "unsupported soc id = %d\n", soc_revision);
+ return -EINVAL;
+ }
+
vreg->speed_bin_fuse = fuse->speed_bin;
vreg->cpr_rev_fuse = fuse->cpr_fusing_rev;
- vreg->fuse_corner_count = MSM8953_APSS_FUSE_CORNERS;
+ vreg->fuse_corner_count = fuse_corners;
vreg->platform_fuses = fuse;
return 0;
@@ -426,7 +712,7 @@
struct cpr3_regulator *vreg, u32 *volt_adjust)
{
struct device_node *node = vreg->of_node;
- struct cpr4_msm8953_apss_fuses *fuse = vreg->platform_fuses;
+ struct cpr4_apss_fuses *fuse = vreg->platform_fuses;
int tuple_list_size = MSM8953_MISC_FUSE_VAL_COUNT;
int i, offset, rc, len = 0;
const char *prop_name = "qcom,cpr-misc-fuse-voltage-adjustment";
@@ -473,7 +759,7 @@
}
/**
- * cpr4_msm8953_apss_calculate_open_loop_voltages() - calculate the open-loop
+ * cpr4_apss_calculate_open_loop_voltages() - calculate the open-loop
* voltage for each corner of a CPR3 regulator
* @vreg: Pointer to the CPR3 regulator
*
@@ -489,16 +775,18 @@
*
* Return: 0 on success, errno on failure
*/
-static int cpr4_msm8953_apss_calculate_open_loop_voltages(
- struct cpr3_regulator *vreg)
+static int cpr4_apss_calculate_open_loop_voltages(struct cpr3_regulator *vreg)
{
struct device_node *node = vreg->of_node;
- struct cpr4_msm8953_apss_fuses *fuse = vreg->platform_fuses;
- int i, j, rc = 0;
+ struct cpr4_apss_fuses *fuse = vreg->platform_fuses;
+ int i, j, id, rc = 0;
bool allow_interpolation;
u64 freq_low, volt_low, freq_high, volt_high;
+ const int *ref_volt;
int *fuse_volt, *misc_adj_volt;
int *fmax_corner;
+ const char * const *corner_name;
+ enum soc_id soc_revision;
fuse_volt = kcalloc(vreg->fuse_corner_count, sizeof(*fuse_volt),
GFP_KERNEL);
@@ -509,15 +797,34 @@
goto done;
}
+ id = vreg->thread->thread_id;
+ soc_revision = vreg->thread->ctrl->soc_revision;
+
+ switch (soc_revision) {
+ case MSM8953_SOC_ID:
+ ref_volt = msm8953_apss_fuse_ref_volt;
+ corner_name = cpr4_msm8953_apss_fuse_corner_name;
+ break;
+ case SDM632_SOC_ID:
+ ref_volt = sdm632_apss_fuse_ref_volt[id];
+ if (id == CPR4_APSS_POWER_CLUSTER_ID)
+ corner_name = cpr4_sdm632_power_apss_fuse_corner_name;
+ else
+ corner_name = cpr4_sdm632_perf_apss_fuse_corner_name;
+ break;
+ default:
+ cpr3_err(vreg, "unsupported soc id = %d\n", soc_revision);
+ rc = -EINVAL;
+ goto done;
+ }
+
for (i = 0; i < vreg->fuse_corner_count; i++) {
- fuse_volt[i] = cpr3_convert_open_loop_voltage_fuse(
- msm8953_apss_fuse_ref_volt[i],
- MSM8953_APSS_FUSE_STEP_VOLT, fuse->init_voltage[i],
- MSM8953_APSS_VOLTAGE_FUSE_SIZE);
+ fuse_volt[i] = cpr3_convert_open_loop_voltage_fuse(ref_volt[i],
+ CPR4_APSS_FUSE_STEP_VOLT, fuse->init_voltage[i],
+ CPR4_APSS_VOLTAGE_FUSE_SIZE);
/* Log fused open-loop voltage values for debugging purposes. */
- cpr3_info(vreg, "fused %8s: open-loop=%7d uV\n",
- cpr4_msm8953_apss_fuse_corner_name[i],
+ cpr3_info(vreg, "fused %8s: open-loop=%7d uV\n", corner_name[i],
fuse_volt[i]);
}
@@ -643,7 +950,7 @@
struct cpr3_regulator *vreg, int *volt_adjust,
int *volt_adjust_fuse, int *ro_scale)
{
- struct cpr4_msm8953_apss_fuses *fuse = vreg->platform_fuses;
+ struct cpr4_apss_fuses *fuse = vreg->platform_fuses;
u32 quot, ro;
int quot_adjust;
int i, fuse_corner;
@@ -670,7 +977,7 @@
}
/**
- * cpr4_msm8953_apss_calculate_target_quotients() - calculate the CPR target
+ * cpr4_apss_calculate_target_quotients() - calculate the CPR target
* quotient for each corner of a CPR3 regulator
* @vreg: Pointer to the CPR3 regulator
*
@@ -686,10 +993,9 @@
*
* Return: 0 on success, errno on failure
*/
-static int cpr4_msm8953_apss_calculate_target_quotients(
- struct cpr3_regulator *vreg)
+static int cpr4_apss_calculate_target_quotients(struct cpr3_regulator *vreg)
{
- struct cpr4_msm8953_apss_fuses *fuse = vreg->platform_fuses;
+ struct cpr4_apss_fuses *fuse = vreg->platform_fuses;
int rc;
bool allow_interpolation;
u64 freq_low, freq_high, prev_quot;
@@ -700,18 +1006,45 @@
int *fmax_corner;
int *volt_adjust, *volt_adjust_fuse, *ro_scale;
int *voltage_adj_misc;
+ int lowest_fuse_corner, highest_fuse_corner;
+ const char * const *corner_name;
+ switch (vreg->thread->ctrl->soc_revision) {
+ case MSM8953_SOC_ID:
+ corner_name = cpr4_msm8953_apss_fuse_corner_name;
+ lowest_fuse_corner = CPR4_MSM8953_APSS_FUSE_CORNER_LOWSVS;
+ highest_fuse_corner = CPR4_MSM8953_APSS_FUSE_CORNER_TURBO_L1;
+ break;
+ case SDM632_SOC_ID:
+ if (vreg->thread->thread_id == CPR4_APSS_POWER_CLUSTER_ID) {
+ corner_name = cpr4_sdm632_power_apss_fuse_corner_name;
+ lowest_fuse_corner =
+ CPR4_SDM632_POWER_APSS_FUSE_CORNER_LOWSVS;
+ highest_fuse_corner =
+ CPR4_SDM632_POWER_APSS_FUSE_CORNER_TURBO_L1;
+ } else {
+ corner_name = cpr4_sdm632_perf_apss_fuse_corner_name;
+ lowest_fuse_corner =
+ CPR4_SDM632_PERF_APSS_FUSE_CORNER_SVS_L1;
+ highest_fuse_corner =
+ CPR4_SDM632_PERF_APSS_FUSE_CORNER_TURBO_L1;
+ }
+ break;
+ default:
+ cpr3_err(vreg, "unsupported soc id = %d\n",
+ vreg->thread->ctrl->soc_revision);
+ return -EINVAL;
+ }
/* Log fused quotient values for debugging purposes. */
- cpr3_info(vreg, "fused LowSVS: quot[%2llu]=%4llu\n",
- fuse->ro_sel[CPR4_MSM8953_APSS_FUSE_CORNER_LOWSVS],
- fuse->target_quot[CPR4_MSM8953_APSS_FUSE_CORNER_LOWSVS]);
- for (i = CPR4_MSM8953_APSS_FUSE_CORNER_SVS;
- i <= CPR4_MSM8953_APSS_FUSE_CORNER_TURBO_L1; i++)
+ cpr3_info(vreg, "fused %8s: quot[%2llu]=%4llu\n",
+ corner_name[lowest_fuse_corner],
+ fuse->ro_sel[lowest_fuse_corner],
+ fuse->target_quot[lowest_fuse_corner]);
+ for (i = lowest_fuse_corner + 1; i <= highest_fuse_corner; i++)
cpr3_info(vreg, "fused %8s: quot[%2llu]=%4llu, quot_offset[%2llu]=%4llu\n",
- cpr4_msm8953_apss_fuse_corner_name[i],
- fuse->ro_sel[i], fuse->target_quot[i],
+ corner_name[i], fuse->ro_sel[i], fuse->target_quot[i],
fuse->ro_sel[i], fuse->quot_offset[i] *
- MSM8953_APSS_QUOT_OFFSET_SCALE);
+ CPR4_APSS_QUOT_OFFSET_SCALE);
allow_interpolation = of_property_read_bool(vreg->of_node,
"qcom,allow-quotient-interpolation");
@@ -790,7 +1123,7 @@
* Interpolation is not possible for corners mapped to the lowest fuse
* corner so use the fuse corner value directly.
*/
- i = CPR4_MSM8953_APSS_FUSE_CORNER_LOWSVS;
+ i = lowest_fuse_corner;
quot_adjust = cpr3_quot_adjustment(ro_scale[i], volt_adjust_fuse[i]);
quot = fuse->target_quot[i] + quot_adjust;
quot_high[i] = quot_low[i] = quot;
@@ -799,19 +1132,17 @@
cpr3_debug(vreg, "adjusted fuse corner %d RO%u target quot: %llu --> %u (%d uV)\n",
i, ro, fuse->target_quot[i], quot, volt_adjust_fuse[i]);
- for (i = 0; i <= fmax_corner[CPR4_MSM8953_APSS_FUSE_CORNER_LOWSVS];
- i++)
+ for (i = 0; i <= fmax_corner[lowest_fuse_corner]; i++)
vreg->corner[i].target_quot[ro] = quot;
- for (i = CPR4_MSM8953_APSS_FUSE_CORNER_SVS;
- i < vreg->fuse_corner_count; i++) {
+ for (i = lowest_fuse_corner + 1; i < vreg->fuse_corner_count; i++) {
quot_high[i] = fuse->target_quot[i];
if (fuse->ro_sel[i] == fuse->ro_sel[i - 1])
quot_low[i] = quot_high[i - 1];
else
quot_low[i] = quot_high[i]
- fuse->quot_offset[i]
- * MSM8953_APSS_QUOT_OFFSET_SCALE;
+ * CPR4_APSS_QUOT_OFFSET_SCALE;
if (quot_high[i] < quot_low[i]) {
cpr3_debug(vreg, "quot_high[%d]=%llu < quot_low[%d]=%llu; overriding: quot_high[%d]=%llu\n",
i, quot_high[i], i, quot_low[i],
@@ -1029,7 +1360,7 @@
static int cpr4_apss_parse_boost_properties(struct cpr3_regulator *vreg)
{
struct cpr3_controller *ctrl = vreg->thread->ctrl;
- struct cpr4_msm8953_apss_fuses *fuse = vreg->platform_fuses;
+ struct cpr4_apss_fuses *fuse = vreg->platform_fuses;
struct cpr3_corner *corner;
int i, boost_voltage, final_boost_volt, rc = 0;
int *boost_table = NULL, *boost_temp_adj = NULL;
@@ -1054,9 +1385,9 @@
boost_voltage = cpr3_convert_open_loop_voltage_fuse(
MSM8953_APSS_BOOST_FUSE_REF_VOLT,
- MSM8953_APSS_FUSE_STEP_VOLT,
+ CPR4_APSS_FUSE_STEP_VOLT,
fuse->boost_voltage,
- MSM8953_APSS_VOLTAGE_FUSE_SIZE);
+ CPR4_APSS_VOLTAGE_FUSE_SIZE);
/* Log boost voltage value for debugging purposes. */
cpr3_info(vreg, "Boost open-loop=%7d uV\n", boost_voltage);
@@ -1174,11 +1505,11 @@
* Constants which define the selection fuse parameters used in fuse combo map
* logic.
*/
-enum cpr4_msm8953_apss_fuse_combo_parameters {
- MSM8953_APSS_SPEED_BIN = 0,
- MSM8953_APSS_CPR_FUSE_REV,
- MSM8953_APSS_FOUNDRY_ID,
- MSM8953_APSS_FUSE_COMBO_PARAM_COUNT,
+enum cpr4_apss_fuse_combo_parameters {
+ CPR4_APSS_SPEED_BIN = 0,
+ CPR4_APSS_CPR_FUSE_REV,
+ CPR4_APSS_FOUNDRY_ID,
+ CPR4_APSS_FUSE_COMBO_PARAM_COUNT,
};
/**
@@ -1190,20 +1521,20 @@
*/
static int cpr4_parse_fuse_combo_map(struct cpr3_regulator *vreg)
{
- struct cpr4_msm8953_apss_fuses *fuse = vreg->platform_fuses;
+ struct cpr4_apss_fuses *fuse = vreg->platform_fuses;
u64 *fuse_val;
int rc;
- fuse_val = kcalloc(MSM8953_APSS_FUSE_COMBO_PARAM_COUNT,
+ fuse_val = kcalloc(CPR4_APSS_FUSE_COMBO_PARAM_COUNT,
sizeof(*fuse_val), GFP_KERNEL);
if (!fuse_val)
return -ENOMEM;
- fuse_val[MSM8953_APSS_SPEED_BIN] = fuse->speed_bin;
- fuse_val[MSM8953_APSS_CPR_FUSE_REV] = fuse->cpr_fusing_rev;
- fuse_val[MSM8953_APSS_FOUNDRY_ID] = fuse->foundry_id;
+ fuse_val[CPR4_APSS_SPEED_BIN] = fuse->speed_bin;
+ fuse_val[CPR4_APSS_CPR_FUSE_REV] = fuse->cpr_fusing_rev;
+ fuse_val[CPR4_APSS_FOUNDRY_ID] = fuse->foundry_id;
rc = cpr3_parse_fuse_combo_map(vreg, fuse_val,
- MSM8953_APSS_FUSE_COMBO_PARAM_COUNT);
+ CPR4_APSS_FUSE_COMBO_PARAM_COUNT);
if (rc == -ENODEV) {
cpr3_debug(vreg, "using legacy fuse combo logic, rc=%d\n",
rc);
@@ -1211,8 +1542,7 @@
} else if (rc < 0) {
cpr3_err(vreg, "error reading fuse combo map data, rc=%d\n",
rc);
- } else if (vreg->fuse_combo >=
- CPR4_MSM8953_APSS_FUSE_COMBO_MAP_MAX_COUNT) {
+ } else if (vreg->fuse_combo >= CPR4_APSS_FUSE_COMBO_MAP_MAX_COUNT) {
cpr3_err(vreg, "invalid CPR fuse combo = %d found\n",
vreg->fuse_combo);
rc = -EINVAL;
@@ -1231,10 +1561,10 @@
*/
static int cpr4_apss_init_regulator(struct cpr3_regulator *vreg)
{
- struct cpr4_msm8953_apss_fuses *fuse;
+ struct cpr4_apss_fuses *fuse;
int rc;
- rc = cpr4_msm8953_apss_read_fuse_data(vreg);
+ rc = cpr4_apss_read_fuse_data(vreg);
if (rc) {
cpr3_err(vreg, "unable to read CPR fuse data, rc=%d\n", rc);
return rc;
@@ -1264,7 +1594,7 @@
return rc;
}
- rc = cpr4_msm8953_apss_calculate_open_loop_voltages(vreg);
+ rc = cpr4_apss_calculate_open_loop_voltages(vreg);
if (rc) {
cpr3_err(vreg, "unable to calculate open-loop voltages, rc=%d\n",
rc);
@@ -1286,7 +1616,7 @@
return rc;
}
- rc = cpr4_msm8953_apss_calculate_target_quotients(vreg);
+ rc = cpr4_apss_calculate_target_quotients(vreg);
if (rc) {
cpr3_err(vreg, "unable to calculate target quotients, rc=%d\n",
rc);
@@ -1329,7 +1659,7 @@
*/
static int cpr4_apss_init_aging(struct cpr3_controller *ctrl)
{
- struct cpr4_msm8953_apss_fuses *fuse = NULL;
+ struct cpr4_apss_fuses *fuse = NULL;
struct cpr3_regulator *vreg = NULL;
u32 aging_ro_scale;
int i, j, rc;
@@ -1404,7 +1734,7 @@
*/
static int cpr4_apss_init_controller(struct cpr3_controller *ctrl)
{
- int rc;
+ int i, rc;
rc = cpr3_parse_common_ctrl_data(ctrl);
if (rc) {
@@ -1471,10 +1801,20 @@
return rc;
}
- ctrl->sensor_count = MSM8953_APSS_CPR_SENSOR_COUNT;
+ switch (ctrl->soc_revision) {
+ case MSM8953_SOC_ID:
+ ctrl->sensor_count = MSM8953_APSS_CPR_SENSOR_COUNT;
+ break;
+ case SDM632_SOC_ID:
+ ctrl->sensor_count = SDM632_APSS_CPR_SENSOR_COUNT;
+ break;
+ default:
+ cpr3_err(ctrl, "unsupported soc id = %d\n", ctrl->soc_revision);
+ return -EINVAL;
+ }
/*
- * APSS only has one thread (0) per controller so the zeroed
+ * MSM8953 APSS only has one thread (0) per controller so the zeroed
* array does not need further modification.
*/
ctrl->sensor_owner = devm_kcalloc(ctrl->dev, ctrl->sensor_count,
@@ -1482,7 +1822,17 @@
if (!ctrl->sensor_owner)
return -ENOMEM;
- ctrl->cpr_clock_rate = MSM8953_APSS_CPR_CLOCK_RATE;
+ /* Specify sensor ownership for SDM632 APSS CPR */
+ if (ctrl->soc_revision == SDM632_SOC_ID) {
+ for (i = SDM632_APSS_THREAD0_SENSOR_MIN;
+ i <= SDM632_APSS_THREAD0_SENSOR_MAX; i++)
+ ctrl->sensor_owner[i] = 0;
+ for (i = SDM632_APSS_THREAD1_SENSOR_MIN;
+ i <= SDM632_APSS_THREAD1_SENSOR_MAX; i++)
+ ctrl->sensor_owner[i] = 1;
+ }
+
+ ctrl->cpr_clock_rate = CPR4_APSS_CPR_CLOCK_RATE;
ctrl->ctrl_type = CPR_CTRL_TYPE_CPR4;
ctrl->supports_hw_closed_loop = true;
ctrl->use_hw_closed_loop = of_property_read_bool(ctrl->dev->of_node,
@@ -1505,11 +1855,26 @@
return cpr3_regulator_resume(ctrl);
}
+/* Data corresponds to the SoC revision */
+static const struct of_device_id cpr4_regulator_match_table[] = {
+ {
+ .compatible = "qcom,cpr4-msm8953-apss-regulator",
+ .data = (void *)(uintptr_t)MSM8953_SOC_ID,
+ },
+ {
+ .compatible = "qcom,cpr4-sdm632-apss-regulator",
+ .data = (void *)(uintptr_t)SDM632_SOC_ID,
+ },
+ {}
+};
+
static int cpr4_apss_regulator_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct cpr3_controller *ctrl;
- int i, rc;
+ struct cpr3_regulator *vreg;
+ const struct of_device_id *match;
+ int i, j, rc, max_thread_id;
if (!dev->of_node) {
dev_err(dev, "Device tree node is missing\n");
@@ -1524,6 +1889,12 @@
/* Set to false later if anything precludes CPR operation. */
ctrl->cpr_allowed_hw = true;
+ match = of_match_node(cpr4_regulator_match_table, dev->of_node);
+ if (match)
+ ctrl->soc_revision = (uintptr_t)match->data;
+ else
+ cpr3_err(ctrl, "could not find compatible string match\n");
+
rc = of_property_read_string(dev->of_node, "qcom,cpr-ctrl-name",
&ctrl->name);
if (rc) {
@@ -1538,16 +1909,19 @@
return rc;
}
- rc = cpr3_allocate_threads(ctrl, 0, 0);
+ max_thread_id = 0;
+ /* SDM632 uses 2 CPR HW threads */
+ if (ctrl->soc_revision == SDM632_SOC_ID)
+ max_thread_id = 1;
+ rc = cpr3_allocate_threads(ctrl, 0, max_thread_id);
if (rc) {
cpr3_err(ctrl, "failed to allocate CPR thread array, rc=%d\n",
rc);
return rc;
}
- if (ctrl->thread_count != 1) {
- cpr3_err(ctrl, "expected 1 thread but found %d\n",
- ctrl->thread_count);
+ if (ctrl->thread_count < 1) {
+ cpr3_err(ctrl, "thread nodes are missing\n");
return -EINVAL;
}
@@ -1559,19 +1933,24 @@
return rc;
}
- rc = cpr4_apss_init_thread(&ctrl->thread[0]);
- if (rc) {
- cpr3_err(ctrl, "thread initialization failed, rc=%d\n", rc);
- return rc;
- }
-
- for (i = 0; i < ctrl->thread[0].vreg_count; i++) {
- rc = cpr4_apss_init_regulator(&ctrl->thread[0].vreg[i]);
+ for (i = 0; i < ctrl->thread_count; i++) {
+ rc = cpr4_apss_init_thread(&ctrl->thread[i]);
if (rc) {
- cpr3_err(&ctrl->thread[0].vreg[i], "regulator initialization failed, rc=%d\n",
- rc);
+ cpr3_err(ctrl, "thread %u initialization failed, rc=%d\n",
+ ctrl->thread[i].thread_id, rc);
return rc;
}
+
+ for (j = 0; j < ctrl->thread[i].vreg_count; j++) {
+ vreg = &ctrl->thread[i].vreg[j];
+
+ rc = cpr4_apss_init_regulator(vreg);
+ if (rc) {
+ cpr3_err(vreg, "regulator initialization failed, rc=%d\n",
+ rc);
+ return rc;
+ }
+ }
}
rc = cpr4_apss_init_aging(ctrl);
@@ -1593,11 +1972,6 @@
return cpr3_regulator_unregister(ctrl);
}
-static const struct of_device_id cpr4_regulator_match_table[] = {
- { .compatible = "qcom,cpr4-msm8953-apss-regulator", },
- {}
-};
-
static struct platform_driver cpr4_apss_regulator_driver = {
.driver = {
.name = "qcom,cpr4-apss-regulator",
diff --git a/drivers/scsi/ufs/ufs-debugfs.c b/drivers/scsi/ufs/ufs-debugfs.c
index 11e11e4..1f3967d 100644
--- a/drivers/scsi/ufs/ufs-debugfs.c
+++ b/drivers/scsi/ufs/ufs-debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, 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
@@ -954,6 +954,49 @@
hba->ufs_stats.power_mode_change_cnt);
seq_printf(file, "hibern8_exit_cnt = %d\n",
hba->ufs_stats.hibern8_exit_cnt);
+
+ seq_printf(file, "pa_err_cnt_total = %d\n",
+ hba->ufs_stats.pa_err_cnt_total);
+ seq_printf(file, "pa_lane_0_err_cnt = %d\n",
+ hba->ufs_stats.pa_err_cnt[UFS_EC_PA_LANE_0]);
+ seq_printf(file, "pa_lane_1_err_cnt = %d\n",
+ hba->ufs_stats.pa_err_cnt[UFS_EC_PA_LANE_1]);
+ seq_printf(file, "pa_line_reset_err_cnt = %d\n",
+ hba->ufs_stats.pa_err_cnt[UFS_EC_PA_LINE_RESET]);
+ seq_printf(file, "dl_err_cnt_total = %d\n",
+ hba->ufs_stats.dl_err_cnt_total);
+ seq_printf(file, "dl_nac_received_err_cnt = %d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_NAC_RECEIVED]);
+ seq_printf(file, "dl_tcx_replay_timer_expired_err_cnt = %d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_TCx_REPLAY_TIMER_EXPIRED]);
+ seq_printf(file, "dl_afcx_request_timer_expired_err_cnt = %d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_AFCx_REQUEST_TIMER_EXPIRED]);
+ seq_printf(file, "dl_fcx_protection_timer_expired_err_cnt = %d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_FCx_PROTECT_TIMER_EXPIRED]);
+ seq_printf(file, "dl_crc_err_cnt = %d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_CRC_ERROR]);
+ seq_printf(file, "dll_rx_buffer_overflow_err_cnt = %d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_RX_BUFFER_OVERFLOW]);
+ seq_printf(file, "dl_max_frame_length_exceeded_err_cnt = %d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_MAX_FRAME_LENGTH_EXCEEDED]);
+ seq_printf(file, "dl_wrong_sequence_number_err_cnt = %d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_WRONG_SEQUENCE_NUMBER]);
+ seq_printf(file, "dl_afc_frame_syntax_err_cnt = %d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_AFC_FRAME_SYNTAX_ERROR]);
+ seq_printf(file, "dl_nac_frame_syntax_err_cnt = %d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_NAC_FRAME_SYNTAX_ERROR]);
+ seq_printf(file, "dl_eof_syntax_err_cnt = %d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_EOF_SYNTAX_ERROR]);
+ seq_printf(file, "dl_frame_syntax_err_cnt = %d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_FRAME_SYNTAX_ERROR]);
+ seq_printf(file, "dl_bad_ctrl_symbol_type_err_cnt = %d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_BAD_CTRL_SYMBOL_TYPE]);
+ seq_printf(file, "dl_pa_init_err_cnt = %d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_PA_INIT_ERROR]);
+ seq_printf(file, "dl_pa_error_ind_received = %d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_PA_ERROR_IND_RECEIVED]);
+ seq_printf(file, "dme_err_cnt = %d\n", hba->ufs_stats.dme_err_cnt);
+
return 0;
}
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 393f6cd..f3e79e3 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -174,6 +174,33 @@
}
#endif
+static void ufshcd_update_uic_error_cnt(struct ufs_hba *hba, u32 reg, int type)
+{
+ unsigned long err_bits;
+ int ec;
+
+ switch (type) {
+ case UFS_UIC_ERROR_PA:
+ err_bits = reg & UIC_PHY_ADAPTER_LAYER_ERROR_CODE_MASK;
+ for_each_set_bit(ec, &err_bits, UFS_EC_PA_MAX) {
+ hba->ufs_stats.pa_err_cnt[ec]++;
+ hba->ufs_stats.pa_err_cnt_total++;
+ }
+ break;
+ case UFS_UIC_ERROR_DL:
+ err_bits = reg & UIC_DATA_LINK_LAYER_ERROR_CODE_MASK;
+ for_each_set_bit(ec, &err_bits, UFS_EC_DL_MAX) {
+ hba->ufs_stats.dl_err_cnt[ec]++;
+ hba->ufs_stats.dl_err_cnt_total++;
+ }
+ break;
+ case UFS_UIC_ERROR_DME:
+ hba->ufs_stats.dme_err_cnt++;
+ default:
+ break;
+ }
+}
+
#define PWR_INFO_MASK 0xF
#define PWR_RX_OFFSET 4
@@ -940,6 +967,33 @@
hba->capabilities, hba->caps);
dev_err(hba->dev, "quirks=0x%x, dev. quirks=0x%x\n", hba->quirks,
hba->dev_info.quirks);
+ dev_err(hba->dev, "pa_err_cnt_total=%d, pa_lane_0_err_cnt=%d, pa_lane_1_err_cnt=%d, pa_line_reset_err_cnt=%d\n",
+ hba->ufs_stats.pa_err_cnt_total,
+ hba->ufs_stats.pa_err_cnt[UFS_EC_PA_LANE_0],
+ hba->ufs_stats.pa_err_cnt[UFS_EC_PA_LANE_1],
+ hba->ufs_stats.pa_err_cnt[UFS_EC_PA_LINE_RESET]);
+ dev_err(hba->dev, "dl_err_cnt_total=%d, dl_nac_received_err_cnt=%d, dl_tcx_replay_timer_expired_err_cnt=%d\n",
+ hba->ufs_stats.dl_err_cnt_total,
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_NAC_RECEIVED],
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_TCx_REPLAY_TIMER_EXPIRED]);
+ dev_err(hba->dev, "dl_afcx_request_timer_expired_err_cnt=%d, dl_fcx_protection_timer_expired_err_cnt=%d, dl_crc_err_cnt=%d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_AFCx_REQUEST_TIMER_EXPIRED],
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_FCx_PROTECT_TIMER_EXPIRED],
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_CRC_ERROR]);
+ dev_err(hba->dev, "dll_rx_buffer_overflow_err_cnt=%d, dl_max_frame_length_exceeded_err_cnt=%d, dl_wrong_sequence_number_err_cnt=%d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_RX_BUFFER_OVERFLOW],
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_MAX_FRAME_LENGTH_EXCEEDED],
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_WRONG_SEQUENCE_NUMBER]);
+ dev_err(hba->dev, "dl_afc_frame_syntax_err_cnt=%d, dl_nac_frame_syntax_err_cnt=%d, dl_eof_syntax_err_cnt=%d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_AFC_FRAME_SYNTAX_ERROR],
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_NAC_FRAME_SYNTAX_ERROR],
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_EOF_SYNTAX_ERROR]);
+ dev_err(hba->dev, "dl_frame_syntax_err_cnt=%d, dl_bad_ctrl_symbol_type_err_cnt=%d, dl_pa_init_err_cnt=%d, dl_pa_error_ind_received=%d\n",
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_FRAME_SYNTAX_ERROR],
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_BAD_CTRL_SYMBOL_TYPE],
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_PA_INIT_ERROR],
+ hba->ufs_stats.dl_err_cnt[UFS_EC_DL_PA_ERROR_IND_RECEIVED]);
+ dev_err(hba->dev, "dme_err_cnt=%d\n", hba->ufs_stats.dme_err_cnt);
}
/**
@@ -6591,6 +6645,7 @@
*/
dev_dbg(hba->dev, "%s: UIC Lane error reported, reg 0x%x\n",
__func__, reg);
+ ufshcd_update_uic_error_cnt(hba, reg, UFS_UIC_ERROR_PA);
ufshcd_update_uic_reg_hist(&hba->ufs_stats.pa_err, reg);
/*
@@ -6617,6 +6672,7 @@
reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_DATA_LINK_LAYER);
if ((reg & UIC_DATA_LINK_LAYER_ERROR) &&
(reg & UIC_DATA_LINK_LAYER_ERROR_CODE_MASK)) {
+ ufshcd_update_uic_error_cnt(hba, reg, UFS_UIC_ERROR_DL);
ufshcd_update_uic_reg_hist(&hba->ufs_stats.dl_err, reg);
if (reg & UIC_DATA_LINK_LAYER_ERROR_PA_INIT) {
@@ -6654,6 +6710,7 @@
reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_DME);
if ((reg & UIC_DME_ERROR) &&
(reg & UIC_DME_ERROR_CODE_MASK)) {
+ ufshcd_update_uic_error_cnt(hba, reg, UFS_UIC_ERROR_DME);
ufshcd_update_uic_reg_hist(&hba->ufs_stats.dme_err, reg);
hba->uic_error |= UFSHCD_UIC_DME_ERROR;
retval |= IRQ_HANDLED;
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 24d116a..a6b47aa 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -650,6 +650,11 @@
struct ufs_uic_err_reg_hist nl_err;
struct ufs_uic_err_reg_hist tl_err;
struct ufs_uic_err_reg_hist dme_err;
+ u32 pa_err_cnt_total;
+ u32 pa_err_cnt[UFS_EC_PA_MAX];
+ u32 dl_err_cnt_total;
+ u32 dl_err_cnt[UFS_EC_DL_MAX];
+ u32 dme_err_cnt;
};
/* UFS Host Controller debug print bitmask */
diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h
index 87affc4..fb18bc8 100644
--- a/drivers/scsi/ufs/ufshci.h
+++ b/drivers/scsi/ufs/ufshci.h
@@ -183,6 +183,43 @@
PWR_FATAL_ERROR = 0x05,
};
+/* Host UIC error type */
+enum ufshcd_uic_err_type {
+ UFS_UIC_ERROR_PA,
+ UFS_UIC_ERROR_DL,
+ UFS_UIC_ERROR_DME,
+};
+
+/* Host UIC error code PHY adapter layer */
+enum ufshcd_ec_pa {
+ UFS_EC_PA_LANE_0,
+ UFS_EC_PA_LANE_1,
+ UFS_EC_PA_LANE_2,
+ UFS_EC_PA_LANE_3,
+ UFS_EC_PA_LINE_RESET,
+ UFS_EC_PA_MAX,
+};
+
+/* Host UIC error code data link layer */
+enum ufshcd_ec_dl {
+ UFS_EC_DL_NAC_RECEIVED,
+ UFS_EC_DL_TCx_REPLAY_TIMER_EXPIRED,
+ UFS_EC_DL_AFCx_REQUEST_TIMER_EXPIRED,
+ UFS_EC_DL_FCx_PROTECT_TIMER_EXPIRED,
+ UFS_EC_DL_CRC_ERROR,
+ UFS_EC_DL_RX_BUFFER_OVERFLOW,
+ UFS_EC_DL_MAX_FRAME_LENGTH_EXCEEDED,
+ UFS_EC_DL_WRONG_SEQUENCE_NUMBER,
+ UFS_EC_DL_AFC_FRAME_SYNTAX_ERROR,
+ UFS_EC_DL_NAC_FRAME_SYNTAX_ERROR,
+ UFS_EC_DL_EOF_SYNTAX_ERROR,
+ UFS_EC_DL_FRAME_SYNTAX_ERROR,
+ UFS_EC_DL_BAD_CTRL_SYMBOL_TYPE,
+ UFS_EC_DL_PA_INIT_ERROR,
+ UFS_EC_DL_PA_ERROR_IND_RECEIVED,
+ UFS_EC_DL_MAX,
+};
+
/* HCE - Host Controller Enable 34h */
#define CONTROLLER_ENABLE UFS_BIT(0)
#define CRYPTO_GENERAL_ENABLE UFS_BIT(1)
diff --git a/drivers/soc/qcom/memshare/msm_memshare.c b/drivers/soc/qcom/memshare/msm_memshare.c
index 0ae25a1..77a76d2 100644
--- a/drivers/soc/qcom/memshare/msm_memshare.c
+++ b/drivers/soc/qcom/memshare/msm_memshare.c
@@ -270,6 +270,9 @@
{
int i = 0, ret;
char *client_name = NULL;
+ u32 source_vmlist[1] = {VMID_MSS_MSA};
+ int dest_vmids[1] = {VMID_HLOS};
+ int dest_perms[1] = {PERM_READ|PERM_WRITE|PERM_EXEC};
for (i = 0; i < num_clients; i++) {
@@ -296,6 +299,33 @@
continue;
}
+ if (memblock[i].hyp_mapping &&
+ memblock[i].peripheral ==
+ DHMS_MEM_PROC_MPSS_V01) {
+ pr_debug("memshare: hypervisor unmapping for client id: %d\n",
+ memblock[i].client_id);
+ if (memblock[i].alloc_request)
+ continue;
+ ret = hyp_assign_phys(
+ memblock[i].phy_addr,
+ memblock[i].size,
+ source_vmlist,
+ 1, dest_vmids,
+ dest_perms, 1);
+ if (ret) {
+ /*
+ * This is an error case as hyp
+ * mapping was successful
+ * earlier but during unmap
+ * it lead to failure.
+ */
+ pr_err("memshare: %s, failed to map the region to APPS\n",
+ __func__);
+ } else {
+ memblock[i].hyp_mapping = 0;
+ }
+ }
+
ramdump_segments_tmp = kcalloc(1,
sizeof(struct ramdump_segment),
GFP_KERNEL);
@@ -322,8 +352,7 @@
static int modem_notifier_cb(struct notifier_block *this, unsigned long code,
void *_cmd)
{
- int i;
- int ret;
+ int i, ret;
u32 source_vmlist[1] = {VMID_MSS_MSA};
int dest_vmids[1] = {VMID_HLOS};
int dest_perms[1] = {PERM_READ|PERM_WRITE|PERM_EXEC};
@@ -335,8 +364,7 @@
case SUBSYS_BEFORE_SHUTDOWN:
bootup_request++;
- for (i = 0; ((i < MAX_CLIENTS) &&
- !memblock[i].guarantee); i++)
+ for (i = 0; i < MAX_CLIENTS; i++)
memblock[i].alloc_request = 0;
break;
@@ -373,14 +401,15 @@
memblock[i].client_id);
}
- if (memblock[i].free_memory == 0) {
- if (memblock[i].peripheral ==
- DHMS_MEM_PROC_MPSS_V01 &&
- !memblock[i].guarantee &&
- memblock[i].allotted &&
- !memblock[i].alloc_request) {
- pr_debug("memshare: hypervisor unmapping for client id: %d\n",
- memblock[i].client_id);
+ if (memblock[i].free_memory == 0 &&
+ memblock[i].peripheral ==
+ DHMS_MEM_PROC_MPSS_V01 &&
+ !memblock[i].guarantee &&
+ memblock[i].allotted &&
+ !memblock[i].alloc_request) {
+ pr_debug("memshare: hypervisor unmapping for client id: %d\n",
+ memblock[i].client_id);
+ if (memblock[i].hyp_mapping) {
ret = hyp_assign_phys(
memblock[i].phy_addr,
memblock[i].size,
@@ -400,13 +429,13 @@
} else {
memblock[i].hyp_mapping = 0;
}
- dma_free_attrs(memsh_drv->dev,
- memblock[i].size,
- memblock[i].virtual_addr,
- memblock[i].phy_addr,
- attrs);
- free_client(i);
}
+ dma_free_attrs(memsh_drv->dev,
+ memblock[i].size,
+ memblock[i].virtual_addr,
+ memblock[i].phy_addr,
+ attrs);
+ free_client(i);
}
}
bootup_request++;
@@ -541,7 +570,6 @@
memblock[client_id].allotted = 1;
memblock[client_id].size = alloc_req->num_bytes;
memblock[client_id].peripheral = alloc_req->proc_id;
- memblock[client_id].alloc_request = 1;
}
}
pr_debug("memshare: In %s, free memory count for client id: %d = %d",
@@ -549,6 +577,7 @@
memblock[client_id].free_memory);
memblock[client_id].sequence_id = alloc_req->sequence_id;
+ memblock[client_id].alloc_request = 1;
fill_alloc_response(alloc_resp, client_id, &resp);
/*
@@ -975,7 +1004,6 @@
return rc;
}
memblock[num_clients].allotted = 1;
- memblock[num_clients].alloc_request = 1;
shared_hyp_mapping(num_clients);
}
diff --git a/drivers/soc/qcom/msm_smd.c b/drivers/soc/qcom/msm_smd.c
index 1631984..eb7aede 100644
--- a/drivers/soc/qcom/msm_smd.c
+++ b/drivers/soc/qcom/msm_smd.c
@@ -1,7 +1,7 @@
/* drivers/soc/qcom/msm_smd.c
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2008-2017, 2018, The Linux Foundation. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -269,11 +269,12 @@
uint32_t *dest_local = (uint32_t *)dest;
uint32_t *src_local = (uint32_t *)src;
+ if (WARN_ON(!dest_local || !src_local))
+ return dest;
WARN_ON(num_bytes & SMD_FIFO_ADDR_ALIGN_BYTES);
- WARN_ON(!dest_local ||
- ((uintptr_t)dest_local & SMD_FIFO_ADDR_ALIGN_BYTES));
- WARN_ON(!src_local ||
- ((uintptr_t)src_local & SMD_FIFO_ADDR_ALIGN_BYTES));
+ WARN_ON(((uintptr_t)dest_local & SMD_FIFO_ADDR_ALIGN_BYTES));
+ WARN_ON(((uintptr_t)src_local & SMD_FIFO_ADDR_ALIGN_BYTES));
+
num_bytes /= sizeof(uint32_t);
while (num_bytes--)
@@ -301,11 +302,12 @@
uint32_t *dest_local = (uint32_t *)dest;
uint32_t *src_local = (uint32_t *)src;
+ if (WARN_ON(!dest_local || !src_local))
+ return dest;
WARN_ON(num_bytes & SMD_FIFO_ADDR_ALIGN_BYTES);
- WARN_ON(!dest_local ||
- ((uintptr_t)dest_local & SMD_FIFO_ADDR_ALIGN_BYTES));
- WARN_ON(!src_local ||
- ((uintptr_t)src_local & SMD_FIFO_ADDR_ALIGN_BYTES));
+ WARN_ON(((uintptr_t)dest_local & SMD_FIFO_ADDR_ALIGN_BYTES));
+ WARN_ON(((uintptr_t)src_local & SMD_FIFO_ADDR_ALIGN_BYTES));
+
num_bytes /= sizeof(uint32_t);
while (num_bytes--)
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index 25a7d47..d5de12b 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -571,6 +571,13 @@
/* sdxpoorwills ID */
[334] = {SDX_CPU_SDXPOORWILLS, "SDXPOORWILLS"},
+ /* 9650 IDs */
+ [279] = {MSM_CPU_9650, "MDM9650"},
+ [283] = {MSM_CPU_9650, "MDM9650"},
+ [284] = {MSM_CPU_9650, "MDM9650"},
+ [285] = {MSM_CPU_9650, "MDM9650"},
+ [286] = {MSM_CPU_9650, "MDM9650"},
+
/* SDM670 ID */
[336] = {MSM_CPU_SDM670, "SDM670"},
@@ -602,7 +609,6 @@
[353] = {MSM_CPU_SDM439, "SDM439"},
[354] = {MSM_CPU_SDM429, "SDM429"},
-
/* Uninitialized IDs are not known to run Linux.
* MSM_CPU_UNKNOWN is set to 0 to ensure these IDs are
* considered as unknown CPU.
@@ -1526,6 +1532,10 @@
dummy_socinfo.id = 347;
strlcpy(dummy_socinfo.build_id, "qcs605 - ",
sizeof(dummy_socinfo.build_id));
+ } else if (early_machine_is_mdm9650()) {
+ dummy_socinfo.id = 286;
+ strlcpy(dummy_socinfo.build_id, "mdm9650 - ",
+ sizeof(dummy_socinfo.build_id));
} else if (early_machine_is_sdxpoorwills()) {
dummy_socinfo.id = 334;
strlcpy(dummy_socinfo.build_id, "sdxpoorwills - ",
diff --git a/drivers/staging/android/ion/msm/msm_ion.c b/drivers/staging/android/ion/msm/msm_ion.c
index a3eebca..4b9e359 100644
--- a/drivers/staging/android/ion/msm/msm_ion.c
+++ b/drivers/staging/android/ion/msm/msm_ion.c
@@ -659,7 +659,8 @@
vmid == VMID_CP_CAMERA_PREVIEW ||
vmid == VMID_CP_SPSS_SP ||
vmid == VMID_CP_SPSS_SP_SHARED ||
- vmid == VMID_CP_SPSS_HLOS_SHARED);
+ vmid == VMID_CP_SPSS_HLOS_SHARED ||
+ vmid == VMID_CP_CDSP);
}
unsigned int count_set_bits(unsigned long val)
@@ -709,6 +710,8 @@
return VMID_CP_SPSS_SP_SHARED;
if (flags & ION_FLAG_CP_SPSS_HLOS_SHARED)
return VMID_CP_SPSS_HLOS_SHARED;
+ if (flags & ION_FLAG_CP_CDSP)
+ return VMID_CP_CDSP;
return -EINVAL;
}
diff --git a/drivers/staging/android/uapi/msm_ion.h b/drivers/staging/android/uapi/msm_ion.h
index d510fda..eb60bad 100644
--- a/drivers/staging/android/uapi/msm_ion.h
+++ b/drivers/staging/android/uapi/msm_ion.h
@@ -90,6 +90,8 @@
#define ION_FLAG_CP_SEC_DISPLAY ION_BIT(25)
#define ION_FLAG_CP_APP ION_BIT(26)
#define ION_FLAG_CP_CAMERA_PREVIEW ION_BIT(27)
+/* ION_FLAG_ALLOW_NON_CONTIG uses ION_BIT(28) */
+#define ION_FLAG_CP_CDSP ION_BIT(29)
#define ION_FLAG_CP_SPSS_HLOS_SHARED ION_BIT(30)
/**
diff --git a/drivers/thermal/qcom/qti_virtual_sensor.c b/drivers/thermal/qcom/qti_virtual_sensor.c
index cc66f37..8d988eb 100644
--- a/drivers/thermal/qcom/qti_virtual_sensor.c
+++ b/drivers/thermal/qcom/qti_virtual_sensor.c
@@ -91,6 +91,17 @@
"cpuss3-usr"},
.logic = VIRT_MAXIMUM,
},
+ {
+ .virt_zone_name = "hexa-cpu-max-step",
+ .num_sensors = 6,
+ .sensor_names = {"apc1-cpu0-usr",
+ "apc1-cpu1-usr",
+ "apc1-cpu2-usr",
+ "apc1-cpu3-usr",
+ "cpuss0-usr",
+ "cpuss1-usr"},
+ .logic = VIRT_MAXIMUM,
+ },
};
int qti_virtual_sensor_register(struct device *dev)
diff --git a/drivers/thermal/tsens2xxx.c b/drivers/thermal/tsens2xxx.c
index af60a4b..0dc375f 100644
--- a/drivers/thermal/tsens2xxx.c
+++ b/drivers/thermal/tsens2xxx.c
@@ -31,6 +31,7 @@
#define TSENS_TM_CRITICAL_INT_EN BIT(2)
#define TSENS_TM_UPPER_INT_EN BIT(1)
#define TSENS_TM_LOWER_INT_EN BIT(0)
+#define TSENS_TM_UPPER_LOWER_INT_DISABLE 0xffffffff
#define TSENS_TM_SN_UPPER_LOWER_THRESHOLD(n) ((n) + 0x20)
#define TSENS_TM_SN_ADDR_OFFSET 0x4
#define TSENS_TM_UPPER_THRESHOLD_SET(n) ((n) << 12)
@@ -531,6 +532,7 @@
void __iomem *srot_addr;
void __iomem *sensor_int_mask_addr;
unsigned int srot_val, crit_mask, crit_val;
+ void __iomem *int_mask_addr;
srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_srot_addr + 0x4);
srot_val = readl_relaxed(srot_addr);
@@ -573,6 +575,9 @@
mb();
}
+ int_mask_addr = TSENS_TM_UPPER_LOWER_INT_MASK(tmdev->tsens_tm_addr);
+ writel_relaxed(TSENS_TM_UPPER_LOWER_INT_DISABLE, int_mask_addr);
+
writel_relaxed(TSENS_TM_CRITICAL_INT_EN |
TSENS_TM_UPPER_INT_EN | TSENS_TM_LOWER_INT_EN,
TSENS_TM_INT_EN(tmdev->tsens_tm_addr));
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index 6788e75..b3c3f97 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -1589,6 +1589,7 @@
int j;
unsigned int num_chars;
char buf[4] = { 0 };
+ const u32 *buffer;
if (is_uartdm)
num_chars = min(count - i, (unsigned int)sizeof(buf));
@@ -1613,7 +1614,8 @@
while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
cpu_relax();
- iowrite32_rep(tf, buf, 1);
+ buffer = (const u32 *)buf;
+ writel_relaxed_no_log(*buffer, tf);
i += num_chars;
}
spin_unlock(&port->lock);
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index edf855c..d1a63da 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1248,6 +1248,10 @@
"snps,disable-clk-gating");
dwc->enable_bus_suspend = device_property_read_bool(dev,
"snps,bus-suspend-enable");
+ dwc->usb3_u1u2_disable = device_property_read_bool(dev,
+ "snps,usb3-u1u2-disable");
+ dwc->usb2_l1_disable = device_property_read_bool(dev,
+ "snps,usb2-l1-disable");
if (dwc->enable_bus_suspend) {
pm_runtime_set_autosuspend_delay(dev, 500);
pm_runtime_use_autosuspend(dev);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 69d3fa8..4407a83 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -943,6 +943,8 @@
* 3 - Reserved
* @is_drd: device supports dual-role or not
* @err_evt_seen: previous event in queue was erratic error
+ * @usb3_u1u2_disable: if true, disable U1U2 low power modes in Superspeed mode
+ * @usb1_l1_disable: if true, disable L1 low power modes in Highspeed mode
* @in_lpm: indicates if controller is in low power mode (no clocks)
* @tx_fifo_size: Available RAM size for TX fifo allocation
* @irq: irq number
@@ -1126,6 +1128,8 @@
/* Indicate if need to disable controller internal clkgating */
unsigned disable_clk_gating:1;
unsigned enable_bus_suspend:1;
+ unsigned usb3_u1u2_disable:1;
+ unsigned usb2_l1_disable:1;
atomic_t in_lpm;
int tx_fifo_size;
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 986c97c..8cf49fa 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -16,6 +16,7 @@
* GNU General Public License for more details.
*/
+#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
@@ -35,6 +36,10 @@
#include "gadget.h"
#include "io.h"
+static bool enable_dwc3_u1u2;
+module_param(enable_dwc3_u1u2, bool, 0644);
+MODULE_PARM_DESC(enable_dwc3_u1u2, "Enable support for U1U2 low power modes");
+
static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep);
static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
struct dwc3_ep *dep, struct dwc3_request *req);
@@ -454,6 +459,9 @@
(dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS))
return -EINVAL;
+ if (dwc->usb3_u1u2_disable && !enable_dwc3_u1u2)
+ return -EINVAL;
+
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
if (set)
reg |= DWC3_DCTL_INITU1ENA;
@@ -469,6 +477,9 @@
(dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS))
return -EINVAL;
+ if (dwc->usb3_u1u2_disable && !enable_dwc3_u1u2)
+ return -EINVAL;
+
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
if (set)
reg |= DWC3_DCTL_INITU2ENA;
@@ -639,13 +650,16 @@
usb_gadget_set_state(&dwc->gadget,
USB_STATE_CONFIGURED);
- /*
- * Enable transition to U1/U2 state when
- * nothing is pending from application.
- */
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
- reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA);
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ if (!dwc->usb3_u1u2_disable || enable_dwc3_u1u2) {
+ /*
+ * Enable transition to U1/U2 state when
+ * nothing is pending from application.
+ */
+ reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg |= (DWC3_DCTL_ACCEPTU1ENA |
+ DWC3_DCTL_ACCEPTU2ENA);
+ dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ }
}
break;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 0a12974..f90d0c9 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -3880,6 +3880,7 @@
dwc->gadget.sg_supported = true;
dwc->gadget.name = "dwc3-gadget";
dwc->gadget.is_otg = dwc->dr_mode == USB_DR_MODE_OTG;
+ dwc->gadget.l1_supported = !dwc->usb2_l1_disable;
/*
* FIXME We might be setting max_speed to <SUPER, however versions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 4f8a8f6..f6fc30a 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1733,10 +1733,12 @@
if (gadget->speed >= USB_SPEED_SUPER) {
cdev->desc.bcdUSB = cpu_to_le16(0x0310);
cdev->desc.bMaxPacketSize0 = 9;
- } else if (!disable_l1_for_hs) {
+ } else if (gadget->l1_supported
+ && !disable_l1_for_hs) {
cdev->desc.bcdUSB = cpu_to_le16(0x0210);
}
- } else if (!disable_l1_for_hs) {
+ } else if (gadget->l1_supported
+ && !disable_l1_for_hs) {
cdev->desc.bcdUSB = cpu_to_le16(0x0210);
DBG(cdev, "Config HS device with LPM(L1)\n");
}
@@ -1775,7 +1777,8 @@
case USB_DT_BOS:
if ((gadget_is_superspeed(gadget) &&
(gadget->speed >= USB_SPEED_SUPER)) ||
- !disable_l1_for_hs) {
+ (gadget->l1_supported
+ && !disable_l1_for_hs)) {
value = bos_desc(cdev);
value = min(w_length, (u16) value);
}
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 31c8e4d..47f1a8e 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -871,9 +871,13 @@
ffs_log("enter: ret %d", ret);
if (io_data->read && ret > 0) {
+ mm_segment_t oldfs = get_fs();
+
+ set_fs(USER_DS);
use_mm(io_data->mm);
ret = ffs_copy_to_iter(io_data->buf, ret, &io_data->data);
unuse_mm(io_data->mm);
+ set_fs(oldfs);
}
io_data->kiocb->ki_complete(io_data->kiocb, ret, ret);
diff --git a/drivers/usb/gadget/function/f_mtp.c b/drivers/usb/gadget/function/f_mtp.c
index 714e395..4cc7d94 100644
--- a/drivers/usb/gadget/function/f_mtp.c
+++ b/drivers/usb/gadget/function/f_mtp.c
@@ -1893,7 +1893,6 @@
dev->function.disable = mtp_function_disable;
dev->function.setup = mtp_ctrlreq_configfs;
dev->function.free_func = mtp_free;
- fi->f = &dev->function;
return &dev->function;
}
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c
index 24f8f1c..9e38809 100644
--- a/drivers/usb/gadget/function/u_ether.c
+++ b/drivers/usb/gadget/function/u_ether.c
@@ -780,7 +780,8 @@
}
/* apply outgoing CDC or RNDIS filters */
- if (skb && !is_promisc(cdc_filter)) {
+ if (!test_bit(RMNET_MODE_LLP_IP, &dev->flags) &&
+ !is_promisc(cdc_filter)) {
u8 *dest = skb->data;
if (is_multicast_ether_addr(dest)) {
@@ -794,6 +795,7 @@
else
type = USB_CDC_PACKET_TYPE_ALL_MULTICAST;
if (!(cdc_filter & type)) {
+ dev->net->stats.tx_dropped++;
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index e59334b..57e038d 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -348,7 +348,7 @@
rp->r.rnf_error = mon_text_error;
rp->r.rnf_complete = mon_text_complete;
- snprintf(rp->slab_name, SLAB_NAME_SZ, "mon_text_%p", rp);
+ snprintf(rp->slab_name, SLAB_NAME_SZ, "mon_text_%pK", rp);
rp->e_slab = kmem_cache_create(rp->slab_name,
sizeof(struct mon_event_text), sizeof(long), 0,
mon_text_ctor);
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 23beb58..45d5522 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -941,5 +941,6 @@
struct sched_domain;
unsigned long cpufreq_scale_freq_capacity(struct sched_domain *sd, int cpu);
-unsigned long cpufreq_scale_max_freq_capacity(int cpu);
+unsigned long cpufreq_scale_max_freq_capacity(struct sched_domain *sd, int cpu);
+unsigned long cpufreq_scale_min_freq_capacity(struct sched_domain *sd, int cpu);
#endif /* _LINUX_CPUFREQ_H */
diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h
index 3e97574..0f57407 100644
--- a/include/linux/sched/sysctl.h
+++ b/include/linux/sched/sysctl.h
@@ -21,7 +21,6 @@
extern unsigned int sysctl_sched_child_runs_first;
extern unsigned int sysctl_sched_is_big_little;
extern unsigned int sysctl_sched_sync_hint_enable;
-extern unsigned int sysctl_sched_initial_task_util;
extern unsigned int sysctl_sched_cstate_aware;
extern unsigned int sysctl_sched_capacity_margin;
extern unsigned int sysctl_sched_capacity_margin_down;
diff --git a/include/linux/sw_sync.h b/include/linux/sw_sync.h
new file mode 100644
index 0000000..69f1391
--- /dev/null
+++ b/include/linux/sw_sync.h
@@ -0,0 +1,59 @@
+/*
+ * include/linux/sw_sync.h
+ *
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_SW_SYNC_H
+#define _LINUX_SW_SYNC_H
+
+#include <linux/types.h>
+#include <linux/kconfig.h>
+#include <linux/sync.h>
+#include <uapi/linux/sw_sync.h>
+
+struct sw_sync_timeline {
+ struct sync_timeline obj;
+
+ u32 value;
+};
+
+struct sw_sync_pt {
+ struct sync_pt pt;
+
+ u32 value;
+};
+
+#if IS_ENABLED(CONFIG_SW_SYNC)
+struct sw_sync_timeline *sw_sync_timeline_create(const char *name);
+void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc);
+
+struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value);
+#else
+static inline struct sw_sync_timeline *sw_sync_timeline_create(const char *name)
+{
+ return NULL;
+}
+
+static inline void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc)
+{
+}
+
+static inline struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj,
+ u32 value)
+{
+ return NULL;
+}
+#endif /* IS_ENABLED(CONFIG_SW_SYNC) */
+
+#endif /* _LINUX_SW_SYNC_H */
diff --git a/include/linux/sync.h b/include/linux/sync.h
new file mode 100644
index 0000000..a443b52
--- /dev/null
+++ b/include/linux/sync.h
@@ -0,0 +1,349 @@
+/*
+ * include/linux/sync.h
+ *
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _LINUX_SYNC_H
+#define _LINUX_SYNC_H
+
+#include <linux/types.h>
+#include <linux/kref.h>
+#include <linux/ktime.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+
+#include <uapi/linux/sync.h>
+
+struct sync_timeline;
+struct sync_pt;
+struct sync_fence;
+struct seq_file;
+
+/**
+ * struct sync_timeline_ops - sync object implementation ops
+ * @driver_name: name of the implementation
+ * @dup: duplicate a sync_pt
+ * @has_signaled: returns:
+ * 1 if pt has signaled
+ * 0 if pt has not signaled
+ * <0 on error
+ * @compare: returns:
+ * 1 if b will signal before a
+ * 0 if a and b will signal at the same time
+ * -1 if a will signal before b
+ * @free_pt: called before sync_pt is freed
+ * @release_obj: called before sync_timeline is freed
+ * @print_obj: deprecated
+ * @print_pt: deprecated
+ * @fill_driver_data: write implementation specific driver data to data.
+ * should return an error if there is not enough room
+ * as specified by size. This information is returned
+ * to userspace by SYNC_IOC_FENCE_INFO.
+ * @timeline_value_str: fill str with the value of the sync_timeline's counter
+ * @pt_value_str: fill str with the value of the sync_pt
+ */
+struct sync_timeline_ops {
+ const char *driver_name;
+
+ /* required */
+ struct sync_pt * (*dup)(struct sync_pt *pt);
+
+ /* required */
+ int (*has_signaled)(struct sync_pt *pt);
+
+ /* required */
+ int (*compare)(struct sync_pt *a, struct sync_pt *b);
+
+ /* optional */
+ void (*free_pt)(struct sync_pt *sync_pt);
+
+ /* optional */
+ void (*release_obj)(struct sync_timeline *sync_timeline);
+
+ /* deprecated */
+ void (*print_obj)(struct seq_file *s,
+ struct sync_timeline *sync_timeline);
+
+ /* deprecated */
+ void (*print_pt)(struct seq_file *s, struct sync_pt *sync_pt);
+
+ /* optional */
+ int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size);
+
+ /* optional */
+ void (*timeline_value_str)(struct sync_timeline *timeline, char *str,
+ int size);
+
+ /* optional */
+ void (*pt_value_str)(struct sync_pt *pt, char *str, int size);
+
+ /* optional */
+ void (*pt_log)(struct sync_pt *pt);
+};
+
+/**
+ * struct sync_timeline - sync object
+ * @kref: reference count on fence.
+ * @ops: ops that define the implementation of the sync_timeline
+ * @name: name of the sync_timeline. Useful for debugging
+ * @destroyed: set when sync_timeline is destroyed
+ * @child_list_head: list of children sync_pts for this sync_timeline
+ * @child_list_lock: lock protecting @child_list_head, destroyed, and
+ * sync_pt.status
+ * @active_list_head: list of active (unsignaled/errored) sync_pts
+ * @sync_timeline_list: membership in global sync_timeline_list
+ */
+struct sync_timeline {
+ struct kref kref;
+ const struct sync_timeline_ops *ops;
+ char name[64];
+
+ /* protected by child_list_lock */
+ bool destroyed;
+
+ struct list_head child_list_head;
+ spinlock_t child_list_lock;
+
+ struct list_head active_list_head;
+ spinlock_t active_list_lock;
+
+ struct list_head sync_timeline_list;
+};
+
+/**
+ * struct sync_pt - sync point
+ * @parent: sync_timeline to which this sync_pt belongs
+ * @child_list: membership in sync_timeline.child_list_head
+ * @active_list: membership in sync_timeline.active_list_head
+ * @signaled_list: membership in temporary signaled_list on stack
+ * @fence: sync_fence to which the sync_pt belongs
+ * @pt_list: membership in sync_fence.pt_list_head
+ * @status: 1: signaled, 0:active, <0: error
+ * @timestamp: time which sync_pt status transitioned from active to
+ * signaled or error.
+ */
+struct sync_pt {
+ struct sync_timeline *parent;
+ struct list_head child_list;
+
+ struct list_head active_list;
+ struct list_head signaled_list;
+
+ struct sync_fence *fence;
+ struct list_head pt_list;
+
+ /* protected by parent->active_list_lock */
+ int status;
+
+ ktime_t timestamp;
+};
+
+/**
+ * struct sync_fence - sync fence
+ * @file: file representing this fence
+ * @kref: reference count on fence.
+ * @name: name of sync_fence. Useful for debugging
+ * @pt_list_head: list of sync_pts in the fence. immutable once fence
+ * is created
+ * @waiter_list_head: list of asynchronous waiters on this fence
+ * @waiter_list_lock: lock protecting @waiter_list_head and @status
+ * @status: 1: signaled, 0:active, <0: error
+ *
+ * @wq: wait queue for fence signaling
+ * @sync_fence_list: membership in global fence list
+ */
+struct sync_fence {
+ struct file *file;
+ struct kref kref;
+ char name[64];
+
+ /* this list is immutable once the fence is created */
+ struct list_head pt_list_head;
+
+ struct list_head waiter_list_head;
+ spinlock_t waiter_list_lock; /* also protects status */
+ int status;
+
+ wait_queue_head_t wq;
+
+ struct list_head sync_fence_list;
+};
+
+struct sync_fence_waiter;
+typedef void (*sync_callback_t)(struct sync_fence *fence,
+ struct sync_fence_waiter *waiter);
+
+/**
+ * struct sync_fence_waiter - metadata for asynchronous waiter on a fence
+ * @waiter_list: membership in sync_fence.waiter_list_head
+ * @callback: function pointer to call when fence signals
+ * @callback_data: pointer to pass to @callback
+ */
+struct sync_fence_waiter {
+ struct list_head waiter_list;
+
+ sync_callback_t callback;
+};
+
+static inline void sync_fence_waiter_init(struct sync_fence_waiter *waiter,
+ sync_callback_t callback)
+{
+ waiter->callback = callback;
+}
+
+/*
+ * API for sync_timeline implementers
+ */
+
+/**
+ * sync_timeline_create() - creates a sync object
+ * @ops: specifies the implementation ops for the object
+ * @size: size to allocate for this obj
+ * @name: sync_timeline name
+ *
+ * Creates a new sync_timeline which will use the implementation specified by
+ * @ops. @size bytes will be allocated allowing for implementation specific
+ * data to be kept after the generic sync_timeline struct.
+ */
+struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
+ int size, const char *name);
+
+/**
+ * sync_timeline_destroy() - destroys a sync object
+ * @obj: sync_timeline to destroy
+ *
+ * A sync implementation should call this when the @obj is going away
+ * (i.e. module unload.) @obj won't actually be freed until all its children
+ * sync_pts are freed.
+ */
+void sync_timeline_destroy(struct sync_timeline *obj);
+
+/**
+ * sync_timeline_signal() - signal a status change on a sync_timeline
+ * @obj: sync_timeline to signal
+ *
+ * A sync implementation should call this any time one of it's sync_pts
+ * has signaled or has an error condition.
+ */
+void sync_timeline_signal(struct sync_timeline *obj);
+
+/**
+ * sync_pt_create() - creates a sync pt
+ * @parent: sync_pt's parent sync_timeline
+ * @size: size to allocate for this pt
+ *
+ * Creates a new sync_pt as a child of @parent. @size bytes will be
+ * allocated allowing for implementation specific data to be kept after
+ * the generic sync_timeline struct.
+ */
+struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size);
+
+/**
+ * sync_pt_free() - frees a sync pt
+ * @pt: sync_pt to free
+ *
+ * This should only be called on sync_pts which have been created but
+ * not added to a fence.
+ */
+void sync_pt_free(struct sync_pt *pt);
+
+/**
+ * sync_fence_create() - creates a sync fence
+ * @name: name of fence to create
+ * @pt: sync_pt to add to the fence
+ *
+ * Creates a fence containg @pt. Once this is called, the fence takes
+ * ownership of @pt.
+ */
+struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt);
+
+/*
+ * API for sync_fence consumers
+ */
+
+/**
+ * sync_fence_merge() - merge two fences
+ * @name: name of new fence
+ * @a: fence a
+ * @b: fence b
+ *
+ * Creates a new fence which contains copies of all the sync_pts in both
+ * @a and @b. @a and @b remain valid, independent fences.
+ */
+struct sync_fence *sync_fence_merge(const char *name,
+ struct sync_fence *a, struct sync_fence *b);
+
+/**
+ * sync_fence_fdget() - get a fence from an fd
+ * @fd: fd referencing a fence
+ *
+ * Ensures @fd references a valid fence, increments the refcount of the backing
+ * file, and returns the fence.
+ */
+struct sync_fence *sync_fence_fdget(int fd);
+
+/**
+ * sync_fence_put() - puts a reference of a sync fence
+ * @fence: fence to put
+ *
+ * Puts a reference on @fence. If this is the last reference, the fence and
+ * all it's sync_pts will be freed
+ */
+void sync_fence_put(struct sync_fence *fence);
+
+/**
+ * sync_fence_install() - installs a fence into a file descriptor
+ * @fence: fence to install
+ * @fd: file descriptor in which to install the fence
+ *
+ * Installs @fence into @fd. @fd's should be acquired through
+ * get_unused_fd_flags(O_CLOEXEC).
+ */
+void sync_fence_install(struct sync_fence *fence, int fd);
+
+/**
+ * sync_fence_wait_async() - registers and async wait on the fence
+ * @fence: fence to wait on
+ * @waiter: waiter callback struck
+ *
+ * Returns 1 if @fence has already signaled.
+ *
+ * Registers a callback to be called when @fence signals or has an error.
+ * @waiter should be initialized with sync_fence_waiter_init().
+ */
+int sync_fence_wait_async(struct sync_fence *fence,
+ struct sync_fence_waiter *waiter);
+
+/**
+ * sync_fence_cancel_async() - cancels an async wait
+ * @fence: fence to wait on
+ * @waiter: waiter callback struck
+ *
+ * returns 0 if waiter was removed from fence's async waiter list.
+ * returns -ENOENT if waiter was not found on fence's async waiter list.
+ *
+ * Cancels a previously registered async wait. Will fail gracefully if
+ * @waiter was never registered or if @fence has already signaled @waiter.
+ */
+int sync_fence_cancel_async(struct sync_fence *fence,
+ struct sync_fence_waiter *waiter);
+
+/**
+ * sync_fence_wait() - wait on fence
+ * @fence: fence to wait on
+ * @tiemout: timeout in ms
+ *
+ * Wait for @fence to be signaled or have an error. Waits indefinitely
+ * if @timeout < 0
+ */
+int sync_fence_wait(struct sync_fence *fence, long timeout);
+
+#endif /* _LINUX_SYNC_H */
diff --git a/include/soc/qcom/secure_buffer.h b/include/soc/qcom/secure_buffer.h
index d9a526d..75f017c 100644
--- a/include/soc/qcom/secure_buffer.h
+++ b/include/soc/qcom/secure_buffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, 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
@@ -41,6 +41,7 @@
VMID_CP_CAMERA_PREVIEW = 0x1D,
VMID_CP_SPSS_SP_SHARED = 0x22,
VMID_CP_SPSS_HLOS_SHARED = 0x24,
+ VMID_CP_CDSP = 0x2A,
VMID_LAST,
VMID_INVAL = -1
};
diff --git a/include/soc/qcom/socinfo.h b/include/soc/qcom/socinfo.h
index 7dc2680..280a6d9 100644
--- a/include/soc/qcom/socinfo.h
+++ b/include/soc/qcom/socinfo.h
@@ -120,6 +120,8 @@
of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,sdm439")
#define early_machine_is_sdm429() \
of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,sdm429")
+#define early_machine_is_mdm9650() \
+ of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,mdm9650")
#else
#define of_board_is_sim() 0
#define of_board_is_rumi() 0
@@ -169,6 +171,7 @@
#define early_machine_is_sdm632() 0
#define early_machine_is_sdm439() 0
#define early_machine_is_sdm429() 0
+#define early_machine_is_mdm9650() 0
#endif
#define PLATFORM_SUBTYPE_MDM 1
@@ -241,6 +244,7 @@
MSM_CPU_8937,
MSM_CPU_SDM439,
MSM_CPU_SDM429,
+ MSM_CPU_9650,
};
struct msm_soc_info {
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index 63f2baf..23a3b9a 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -643,160 +643,118 @@
#ifdef CONFIG_SMP
TRACE_EVENT(sched_cpu_util,
- TP_PROTO(struct task_struct *p, int cpu, int task_util, unsigned long curr_util, unsigned long new_cum_util, int sync),
+ TP_PROTO(int cpu),
- TP_ARGS(p, cpu, task_util, curr_util, new_cum_util, sync),
+ TP_ARGS(cpu),
TP_STRUCT__entry(
- __array(char, comm, TASK_COMM_LEN )
- __field(int, pid )
__field(unsigned int, cpu )
- __field(int, task_util )
__field(unsigned int, nr_running )
- __field(long, cpu_util )
+ __field(long, cpu_util )
__field(long, cpu_util_cum )
- __field(long, new_cum_util )
__field(unsigned int, capacity_curr )
__field(unsigned int, capacity )
- __field(unsigned long, curr_util )
- __field(int, sync )
+ __field(unsigned int, capacity_orig )
__field(int, idle_state )
- __field(unsigned int, irqload )
- __field(int, high_irqload )
- __field(int, task_in_cum_demand )
+ __field(u64, irqload )
),
TP_fast_assign(
- memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
- __entry->pid = p->pid;
__entry->cpu = cpu;
- __entry->task_util = task_util;
__entry->nr_running = cpu_rq(cpu)->nr_running;
__entry->cpu_util = cpu_util(cpu);
__entry->cpu_util_cum = cpu_util_cum(cpu, 0);
- __entry->new_cum_util = new_cum_util;
- __entry->task_in_cum_demand = task_in_cum_window_demand(cpu_rq(cpu), p);
__entry->capacity_curr = capacity_curr_of(cpu);
__entry->capacity = capacity_of(cpu);
- __entry->curr_util = curr_util;
- __entry->sync = sync;
+ __entry->capacity_orig = capacity_orig_of(cpu);
__entry->idle_state = idle_get_state_idx(cpu_rq(cpu));
__entry->irqload = sched_irqload(cpu);
- __entry->high_irqload = sched_cpu_high_irqload(cpu);
),
- TP_printk("comm=%s pid=%d cpu=%d task_util=%d nr_running=%d cpu_util=%ld cpu_util_cum=%ld new_cum_util=%ld task_in_cum=%d capacity_curr=%u capacity=%u curr_util=%ld sync=%d idle_state=%d irqload=%u high_irqload=%u",
- __entry->comm, __entry->pid, __entry->cpu, __entry->task_util, __entry->nr_running, __entry->cpu_util, __entry->cpu_util_cum, __entry->new_cum_util, __entry->task_in_cum_demand, __entry->capacity_curr, __entry->capacity, __entry->curr_util, __entry->sync, __entry->idle_state, __entry->irqload, __entry->high_irqload)
+ TP_printk("cpu=%d nr_running=%d cpu_util=%ld cpu_util_cum=%ld capacity_curr=%u capacity=%u capacity_orig=%u idle_state=%d irqload=%llu",
+ __entry->cpu, __entry->nr_running, __entry->cpu_util, __entry->cpu_util_cum, __entry->capacity_curr, __entry->capacity, __entry->capacity_orig, __entry->idle_state, __entry->irqload)
);
-TRACE_EVENT(sched_energy_diff_packing,
+TRACE_EVENT(sched_energy_diff,
- TP_PROTO(struct task_struct *p, unsigned long task_util,
- int targeted_cpus, int nrg_pack, int nrg_spread),
+ TP_PROTO(struct task_struct *p, int prev_cpu, unsigned int prev_energy,
+ int next_cpu, unsigned int next_energy,
+ int backup_cpu, unsigned int backup_energy),
- TP_ARGS(p, task_util, targeted_cpus, nrg_pack, nrg_spread),
+ TP_ARGS(p, prev_cpu, prev_energy, next_cpu, next_energy,
+ backup_cpu, backup_energy),
TP_STRUCT__entry(
- __array(char, comm, TASK_COMM_LEN )
- __field(int, pid )
- __field(unsigned long, task_util )
- __field(int, targeted_cpus )
- __field(int, nrg_pack )
- __field(int, nrg_spread )
+ __field(int, pid )
+ __field(int, prev_cpu )
+ __field(int, prev_energy )
+ __field(int, next_cpu )
+ __field(int, next_energy )
+ __field(int, backup_cpu )
+ __field(int, backup_energy )
),
TP_fast_assign(
- memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
__entry->pid = p->pid;
- __entry->task_util = task_util;
- __entry->targeted_cpus = targeted_cpus;
- __entry->nrg_pack = nrg_pack;
- __entry->nrg_spread = nrg_spread;
+ __entry->prev_cpu = prev_cpu;
+ __entry->prev_energy = prev_energy;
+ __entry->next_cpu = next_cpu;
+ __entry->next_energy = next_energy;
+ __entry->backup_cpu = backup_cpu;
+ __entry->backup_energy = backup_energy;
),
- TP_printk("comm=%s pid=%d task_util=%lu targeted_cpus=%d nrg_pack=%d nrg_spread=%d nrg_diff=%d",
- __entry->comm, __entry->pid, __entry->task_util,
- __entry->targeted_cpus, __entry->nrg_pack,
- __entry->nrg_spread, __entry->nrg_pack - __entry->nrg_spread)
+ TP_printk("pid=%d prev_cpu=%d prev_energy=%u next_cpu=%d next_energy=%u backup_cpu=%d backup_energy=%u",
+ __entry->pid, __entry->prev_cpu, __entry->prev_energy,
+ __entry->next_cpu, __entry->next_energy,
+ __entry->backup_cpu, __entry->backup_energy)
);
-DECLARE_EVENT_CLASS(sched_task_util,
+TRACE_EVENT(sched_task_util,
- TP_PROTO(struct task_struct *p, int task_cpu, unsigned long task_util, int nominated_cpu, int target_cpu, int ediff, bool need_idle),
+ TP_PROTO(struct task_struct *p, int next_cpu, int backup_cpu,
+ int target_cpu, bool sync, bool need_idle,
+ bool placement_boost, int rtg_cpu),
- TP_ARGS(p, task_cpu, task_util, nominated_cpu, target_cpu, ediff, need_idle),
+ TP_ARGS(p, next_cpu, backup_cpu, target_cpu, sync, need_idle,
+ placement_boost, rtg_cpu),
TP_STRUCT__entry(
- __array(char, comm, TASK_COMM_LEN )
__field(int, pid )
- __field(int, task_cpu )
- __field(unsigned long, task_util )
- __field(unsigned long, cpu_util_freq )
- __field(int, nominated_cpu )
+ __array(char, comm, TASK_COMM_LEN )
+ __field(unsigned long, util )
+ __field(int, prev_cpu )
+ __field(int, next_cpu )
+ __field(int, backup_cpu )
__field(int, target_cpu )
- __field(int, ediff )
+ __field(bool, sync )
__field(bool, need_idle )
+ __field(bool, placement_boost )
+ __field(int, rtg_cpu )
__field(u64, latency )
),
TP_fast_assign(
- memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
__entry->pid = p->pid;
- __entry->task_cpu = task_cpu;
- __entry->task_util = task_util;
- __entry->cpu_util_freq = cpu_util_freq(target_cpu, NULL);
- __entry->nominated_cpu = nominated_cpu;
+ memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+ __entry->util = task_util(p);
+ __entry->prev_cpu = task_cpu(p);
+ __entry->next_cpu = next_cpu;
+ __entry->backup_cpu = backup_cpu;
__entry->target_cpu = target_cpu;
- __entry->ediff = ediff;
+ __entry->sync = sync;
__entry->need_idle = need_idle;
+ __entry->placement_boost = placement_boost;
+ __entry->rtg_cpu = rtg_cpu;
__entry->latency = p->ravg.mark_start ?
ktime_get_ns() -
p->ravg.mark_start : 0;
),
- TP_printk("comm=%s pid=%d task_cpu=%d task_util=%lu nominated_cpu=%d target_cpu=%d energy_diff=%d need_idle=%d latency=%llu",
- __entry->comm, __entry->pid, __entry->task_cpu, __entry->task_util, __entry->nominated_cpu, __entry->target_cpu, __entry->ediff, __entry->need_idle, __entry->latency)
+ TP_printk("pid=%d comm=%s util=%lu prev_cpu=%d next_cpu=%d backup_cpu=%d target_cpu=%d sync=%d need_idle=%d placement_boost=%d rtg_cpu=%d latency=%llu",
+ __entry->pid, __entry->comm, __entry->util, __entry->prev_cpu, __entry->next_cpu, __entry->backup_cpu, __entry->target_cpu, __entry->sync, __entry->need_idle, __entry->placement_boost, __entry->rtg_cpu, __entry->latency)
);
-DEFINE_EVENT(sched_task_util, sched_task_util_bias_to_waker,
- TP_PROTO(struct task_struct *p, int task_cpu, unsigned long task_util, int nominated_cpu, int target_cpu, int ediff, bool need_idle),
- TP_ARGS(p, task_cpu, task_util, nominated_cpu, target_cpu, ediff, need_idle)
-);
-
-DEFINE_EVENT(sched_task_util, sched_task_util_colocated,
- TP_PROTO(struct task_struct *p, int task_cpu, unsigned long task_util, int nominated_cpu, int target_cpu, int ediff, bool need_idle),
- TP_ARGS(p, task_cpu, task_util, nominated_cpu, target_cpu, ediff, need_idle)
-);
-
-DEFINE_EVENT(sched_task_util, sched_task_util_boosted,
- TP_PROTO(struct task_struct *p, int task_cpu, unsigned long task_util, int nominated_cpu, int target_cpu, int ediff, bool need_idle),
- TP_ARGS(p, task_cpu, task_util, nominated_cpu, target_cpu, ediff, need_idle)
-);
-
-DEFINE_EVENT(sched_task_util, sched_task_util_overutilzed,
- TP_PROTO(struct task_struct *p, int task_cpu, unsigned long task_util, int nominated_cpu, int target_cpu, int ediff, bool need_idle),
- TP_ARGS(p, task_cpu, task_util, nominated_cpu, target_cpu, ediff, need_idle)
-);
-
-DEFINE_EVENT(sched_task_util, sched_task_util_energy_diff,
- TP_PROTO(struct task_struct *p, int task_cpu, unsigned long task_util, int nominated_cpu, int target_cpu, int ediff, bool need_idle),
- TP_ARGS(p, task_cpu, task_util, nominated_cpu, target_cpu, ediff, need_idle)
-);
-
-DEFINE_EVENT(sched_task_util, sched_task_util_energy_aware,
- TP_PROTO(struct task_struct *p, int task_cpu, unsigned long task_util, int nominated_cpu, int target_cpu, int ediff, bool need_idle),
- TP_ARGS(p, task_cpu, task_util, nominated_cpu, target_cpu, ediff, need_idle)
-);
-
-DEFINE_EVENT(sched_task_util, sched_task_util_imbalance,
- TP_PROTO(struct task_struct *p, int task_cpu, unsigned long task_util, int nominated_cpu, int target_cpu, int ediff, bool need_idle),
- TP_ARGS(p, task_cpu, task_util, nominated_cpu, target_cpu, ediff, need_idle)
-);
-
-DEFINE_EVENT(sched_task_util, sched_task_util_need_idle,
- TP_PROTO(struct task_struct *p, int task_cpu, unsigned long task_util, int nominated_cpu, int target_cpu, int ediff, bool need_idle),
- TP_ARGS(p, task_cpu, task_util, nominated_cpu, target_cpu, ediff, need_idle)
-);
#endif
/*
@@ -1433,22 +1391,36 @@
);
#ifdef CONFIG_SMP
+
+#ifdef CONFIG_SCHED_WALT
+extern unsigned int sysctl_sched_use_walt_cpu_util;
+extern unsigned int sysctl_sched_use_walt_task_util;
+extern unsigned int sched_ravg_window;
+extern unsigned int walt_disabled;
+#endif
+
/*
* Tracepoint for accounting sched averages for tasks.
*/
TRACE_EVENT(sched_load_avg_task,
- TP_PROTO(struct task_struct *tsk, struct sched_avg *avg),
- TP_ARGS(tsk, avg),
+
+ TP_PROTO(struct task_struct *tsk, struct sched_avg *avg, void *_ravg),
+
+ TP_ARGS(tsk, avg, _ravg),
+
TP_STRUCT__entry(
__array( char, comm, TASK_COMM_LEN )
__field( pid_t, pid )
__field( int, cpu )
__field( unsigned long, load_avg )
__field( unsigned long, util_avg )
+ __field( unsigned long, util_avg_pelt )
+ __field( u32, util_avg_walt )
__field( u64, load_sum )
__field( u32, util_sum )
__field( u32, period_contrib )
),
+
TP_fast_assign(
memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
__entry->pid = tsk->pid;
@@ -1458,79 +1430,124 @@
__entry->load_sum = avg->load_sum;
__entry->util_sum = avg->util_sum;
__entry->period_contrib = avg->period_contrib;
+ __entry->util_avg_pelt = avg->util_avg;
+ __entry->util_avg_walt = 0;
+#ifdef CONFIG_SCHED_WALT
+ __entry->util_avg_walt = ((struct ravg*)_ravg)->demand /
+ (sched_ravg_window >> SCHED_CAPACITY_SHIFT);
+ if (!walt_disabled && sysctl_sched_use_walt_task_util)
+ __entry->util_avg = __entry->util_avg_walt;
+#endif
),
- TP_printk("comm=%s pid=%d cpu=%d load_avg=%lu util_avg=%lu load_sum=%llu"
+ TP_printk("comm=%s pid=%d cpu=%d load_avg=%lu util_avg=%lu "
+ "util_avg_pelt=%lu util_avg_walt=%u load_sum=%llu"
" util_sum=%u period_contrib=%u",
__entry->comm,
__entry->pid,
__entry->cpu,
__entry->load_avg,
__entry->util_avg,
+ __entry->util_avg_pelt,
+ __entry->util_avg_walt,
(u64)__entry->load_sum,
(u32)__entry->util_sum,
(u32)__entry->period_contrib)
);
+
/*
* Tracepoint for accounting sched averages for cpus.
*/
TRACE_EVENT(sched_load_avg_cpu,
+
TP_PROTO(int cpu, struct cfs_rq *cfs_rq),
+
TP_ARGS(cpu, cfs_rq),
+
TP_STRUCT__entry(
__field( int, cpu )
__field( unsigned long, load_avg )
__field( unsigned long, util_avg )
+ __field( unsigned long, util_avg_pelt )
+ __field( u32, util_avg_walt )
),
+
TP_fast_assign(
__entry->cpu = cpu;
__entry->load_avg = cfs_rq->avg.load_avg;
__entry->util_avg = cfs_rq->avg.util_avg;
+ __entry->util_avg_pelt = cfs_rq->avg.util_avg;
+ __entry->util_avg_walt = 0;
+#ifdef CONFIG_SCHED_WALT
+ __entry->util_avg_walt = div64_ul(cpu_rq(cpu)->prev_runnable_sum,
+ sched_ravg_window >> SCHED_CAPACITY_SHIFT);
+ if (!walt_disabled && sysctl_sched_use_walt_cpu_util)
+ __entry->util_avg = __entry->util_avg_walt;
+#endif
),
- TP_printk("cpu=%d load_avg=%lu util_avg=%lu",
- __entry->cpu, __entry->load_avg, __entry->util_avg)
+
+ TP_printk("cpu=%d load_avg=%lu util_avg=%lu "
+ "util_avg_pelt=%lu util_avg_walt=%u",
+ __entry->cpu, __entry->load_avg, __entry->util_avg,
+ __entry->util_avg_pelt, __entry->util_avg_walt)
);
+
/*
* Tracepoint for sched_tune_config settings
*/
TRACE_EVENT(sched_tune_config,
+
TP_PROTO(int boost),
+
TP_ARGS(boost),
+
TP_STRUCT__entry(
__field( int, boost )
),
+
TP_fast_assign(
__entry->boost = boost;
),
+
TP_printk("boost=%d ", __entry->boost)
);
+
/*
* Tracepoint for accounting CPU boosted utilization
*/
TRACE_EVENT(sched_boost_cpu,
+
TP_PROTO(int cpu, unsigned long util, long margin),
+
TP_ARGS(cpu, util, margin),
+
TP_STRUCT__entry(
__field( int, cpu )
__field( unsigned long, util )
__field(long, margin )
),
+
TP_fast_assign(
__entry->cpu = cpu;
__entry->util = util;
__entry->margin = margin;
),
+
TP_printk("cpu=%d util=%lu margin=%ld",
__entry->cpu,
__entry->util,
__entry->margin)
);
+
/*
* Tracepoint for schedtune_tasks_update
*/
TRACE_EVENT(sched_tune_tasks_update,
+
TP_PROTO(struct task_struct *tsk, int cpu, int tasks, int idx,
int boost, int max_boost),
+
TP_ARGS(tsk, cpu, tasks, idx, boost, max_boost),
+
TP_STRUCT__entry(
__array( char, comm, TASK_COMM_LEN )
__field( pid_t, pid )
@@ -1540,6 +1557,7 @@
__field( int, boost )
__field( int, max_boost )
),
+
TP_fast_assign(
memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
__entry->pid = tsk->pid;
@@ -1549,104 +1567,109 @@
__entry->boost = boost;
__entry->max_boost = max_boost;
),
+
TP_printk("pid=%d comm=%s "
"cpu=%d tasks=%d idx=%d boost=%d max_boost=%d",
__entry->pid, __entry->comm,
__entry->cpu, __entry->tasks, __entry->idx,
__entry->boost, __entry->max_boost)
);
+
/*
* Tracepoint for schedtune_boostgroup_update
*/
TRACE_EVENT(sched_tune_boostgroup_update,
+
TP_PROTO(int cpu, int variation, int max_boost),
+
TP_ARGS(cpu, variation, max_boost),
+
TP_STRUCT__entry(
__field( int, cpu )
__field( int, variation )
__field( int, max_boost )
),
+
TP_fast_assign(
__entry->cpu = cpu;
__entry->variation = variation;
__entry->max_boost = max_boost;
),
+
TP_printk("cpu=%d variation=%d max_boost=%d",
__entry->cpu, __entry->variation, __entry->max_boost)
);
+
/*
* Tracepoint for accounting task boosted utilization
*/
TRACE_EVENT(sched_boost_task,
+
TP_PROTO(struct task_struct *tsk, unsigned long util, long margin),
+
TP_ARGS(tsk, util, margin),
+
TP_STRUCT__entry(
__array( char, comm, TASK_COMM_LEN )
__field( pid_t, pid )
__field( unsigned long, util )
__field( long, margin )
+
),
+
TP_fast_assign(
memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
__entry->pid = tsk->pid;
__entry->util = util;
__entry->margin = margin;
),
+
TP_printk("comm=%s pid=%d util=%lu margin=%ld",
__entry->comm, __entry->pid,
__entry->util,
__entry->margin)
);
+
/*
- * Tracepoint for accounting sched group energy
+ * Tracepoint for find_best_target
*/
-TRACE_EVENT(sched_energy_diff,
- TP_PROTO(struct task_struct *tsk, int scpu, int dcpu, int udelta,
- int nrgb, int nrga, int nrgd, int capb, int capa, int capd,
- int nrgn, int nrgp),
- TP_ARGS(tsk, scpu, dcpu, udelta,
- nrgb, nrga, nrgd, capb, capa, capd,
- nrgn, nrgp),
+TRACE_EVENT(sched_find_best_target,
+
+ TP_PROTO(struct task_struct *tsk, bool prefer_idle,
+ unsigned long min_util, int start_cpu,
+ int best_idle, int best_active, int target),
+
+ TP_ARGS(tsk, prefer_idle, min_util, start_cpu,
+ best_idle, best_active, target),
+
TP_STRUCT__entry(
__array( char, comm, TASK_COMM_LEN )
- __field( pid_t, pid )
- __field( int, scpu )
- __field( int, dcpu )
- __field( int, udelta )
- __field( int, nrgb )
- __field( int, nrga )
- __field( int, nrgd )
- __field( int, capb )
- __field( int, capa )
- __field( int, capd )
- __field( int, nrgn )
- __field( int, nrgp )
+ __field( pid_t, pid )
+ __field( unsigned long, min_util )
+ __field( bool, prefer_idle )
+ __field( int, start_cpu )
+ __field( int, best_idle )
+ __field( int, best_active )
+ __field( int, target )
),
+
TP_fast_assign(
memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
__entry->pid = tsk->pid;
- __entry->scpu = scpu;
- __entry->dcpu = dcpu;
- __entry->udelta = udelta;
- __entry->nrgb = nrgb;
- __entry->nrga = nrga;
- __entry->nrgd = nrgd;
- __entry->capb = capb;
- __entry->capa = capa;
- __entry->capd = capd;
- __entry->nrgn = nrgn;
- __entry->nrgp = nrgp;
+ __entry->min_util = min_util;
+ __entry->prefer_idle = prefer_idle;
+ __entry->start_cpu = start_cpu;
+ __entry->best_idle = best_idle;
+ __entry->best_active = best_active;
+ __entry->target = target;
),
- TP_printk("pid=%d comm=%s "
- "src_cpu=%d dst_cpu=%d usage_delta=%d "
- "nrg_before=%d nrg_after=%d nrg_diff=%d "
- "cap_before=%d cap_after=%d cap_delta=%d "
- "nrg_delta=%d nrg_payoff=%d",
+
+ TP_printk("pid=%d comm=%s prefer_idle=%d start_cpu=%d "
+ "best_idle=%d best_active=%d target=%d",
__entry->pid, __entry->comm,
- __entry->scpu, __entry->dcpu, __entry->udelta,
- __entry->nrgb, __entry->nrga, __entry->nrgd,
- __entry->capb, __entry->capa, __entry->capd,
- __entry->nrgn, __entry->nrgp)
+ __entry->prefer_idle, __entry->start_cpu,
+ __entry->best_idle, __entry->best_active,
+ __entry->target)
);
TRACE_EVENT(sched_group_energy,
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index f8e92fbc..a17b435 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -426,7 +426,9 @@
header-y += stddef.h
header-y += string.h
header-y += suspend_ioctls.h
+header-y += sync.h
header-y += swab.h
+header-y += sw_sync.h
header-y += synclink.h
header-y += sync_file.h
header-y += sysctl.h
diff --git a/include/uapi/linux/msm_kgsl.h b/include/uapi/linux/msm_kgsl.h
index 9ee2a8b..943ba9e 100644
--- a/include/uapi/linux/msm_kgsl.h
+++ b/include/uapi/linux/msm_kgsl.h
@@ -331,6 +331,7 @@
#define KGSL_PROP_MIN_ACCESS_LENGTH 0x1A
#define KGSL_PROP_UBWC_MODE 0x1B
#define KGSL_PROP_DEVICE_QTIMER 0x20
+#define KGSL_PROP_L3_PWR_CONSTRAINT 0x22
struct kgsl_shadowprop {
unsigned long gpuaddr;
@@ -1119,11 +1120,19 @@
#define KGSL_CONSTRAINT_NONE 0
#define KGSL_CONSTRAINT_PWRLEVEL 1
+/* L3 constraint Type */
+#define KGSL_CONSTRAINT_L3_NONE 2
+#define KGSL_CONSTRAINT_L3_PWRLEVEL 3
+
/* PWRLEVEL constraint level*/
/* set to min frequency */
-#define KGSL_CONSTRAINT_PWR_MIN 0
+#define KGSL_CONSTRAINT_PWR_MIN 0
/* set to max frequency */
-#define KGSL_CONSTRAINT_PWR_MAX 1
+#define KGSL_CONSTRAINT_PWR_MAX 1
+
+/* L3 PWRLEVEL constraint level */
+#define KGSL_CONSTRAINT_L3_PWR_MED 0
+#define KGSL_CONSTRAINT_L3_PWR_MAX 1
struct kgsl_device_constraint_pwrlevel {
unsigned int level;
diff --git a/include/uapi/linux/sw_sync.h b/include/uapi/linux/sw_sync.h
new file mode 100644
index 0000000..9b5d486
--- /dev/null
+++ b/include/uapi/linux/sw_sync.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _UAPI_LINUX_SW_SYNC_H
+#define _UAPI_LINUX_SW_SYNC_H
+
+#include <linux/types.h>
+
+struct sw_sync_create_fence_data {
+ __u32 value;
+ char name[32];
+ __s32 fence; /* fd of new fence */
+};
+
+#define SW_SYNC_IOC_MAGIC 'W'
+
+#define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0,\
+ struct sw_sync_create_fence_data)
+#define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32)
+
+#endif /* _UAPI_LINUX_SW_SYNC_H */
diff --git a/include/uapi/linux/sync.h b/include/uapi/linux/sync.h
new file mode 100644
index 0000000..e964c75
--- /dev/null
+++ b/include/uapi/linux/sync.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _UAPI_LINUX_SYNC_H
+#define _UAPI_LINUX_SYNC_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/**
+ * struct sync_merge_data - data passed to merge ioctl
+ * @fd2: file descriptor of second fence
+ * @name: name of new fence
+ * @fence: returns the fd of the new fence to userspace
+ */
+struct sync_merge_data {
+ __s32 fd2; /* fd of second fence */
+ char name[32]; /* name of new fence */
+ __s32 fence; /* fd on newly created fence */
+};
+
+/**
+ * struct sync_pt_info - detailed sync_pt information
+ * @len: length of sync_pt_info including any driver_data
+ * @obj_name: name of parent sync_timeline
+ * @driver_name: name of driver implementing the parent
+ * @status: status of the sync_pt 0:active 1:signaled <0:error
+ * @timestamp_ns: timestamp of status change in nanoseconds
+ * @driver_data: any driver dependent data
+ */
+struct sync_pt_info {
+ __u32 len;
+ char obj_name[32];
+ char driver_name[32];
+ __s32 status;
+ __u64 timestamp_ns;
+
+ __u8 driver_data[0];
+};
+
+/**
+ * struct sync_fence_info_data - data returned from fence info ioctl
+ * @len: ioctl caller writes the size of the buffer its passing in.
+ * ioctl returns length of sync_fence_data returned to userspace
+ * including pt_info.
+ * @name: name of fence
+ * @status: status of fence. 1: signaled 0:active <0:error
+ * @pt_info: a sync_pt_info struct for every sync_pt in the fence
+ */
+struct sync_fence_info_data {
+ __u32 len;
+ char name[32];
+ __s32 status;
+
+ __u8 pt_info[0];
+};
+
+#define SYNC_IOC_MAGIC '>'
+
+/**
+ * DOC: SYNC_IOC_WAIT - wait for a fence to signal
+ *
+ * pass timeout in milliseconds. Waits indefinitely timeout < 0.
+ */
+#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __s32)
+
+/**
+ * DOC: SYNC_IOC_MERGE - merge two fences
+ *
+ * Takes a struct sync_merge_data. Creates a new fence containing copies of
+ * the sync_pts in both the calling fd and sync_merge_data.fd2. Returns the
+ * new fence's fd in sync_merge_data.fence
+ */
+#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data)
+
+/**
+ * DOC: SYNC_IOC_FENCE_INFO - get detailed information on a fence
+ *
+ * Takes a struct sync_fence_info_data with extra space allocated for pt_info.
+ * Caller should write the size of the buffer into len. On return, len is
+ * updated to reflect the total size of the sync_fence_info_data including
+ * pt_info.
+ *
+ * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence.
+ * To iterate over the sync_pt_infos, use the sync_pt_info.len field.
+ */
+#define SYNC_IOC_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2,\
+ struct sync_fence_info_data)
+
+#endif /* _UAPI_LINUX_SYNC_H */
diff --git a/include/uapi/linux/usb/usb_ctrl_qti.h b/include/uapi/linux/usb/usb_ctrl_qti.h
index b02272a..2dbf14f 100644
--- a/include/uapi/linux/usb/usb_ctrl_qti.h
+++ b/include/uapi/linux/usb/usb_ctrl_qti.h
@@ -4,7 +4,7 @@
#include <linux/types.h>
#include <linux/ioctl.h>
-#define MAX_QTI_PKT_SIZE 2048
+#define MAX_QTI_PKT_SIZE 8192
#define QTI_CTRL_IOCTL_MAGIC 'r'
#define QTI_CTRL_GET_LINE_STATE _IOR(QTI_CTRL_IOCTL_MAGIC, 2, int)
diff --git a/kernel/sched/Makefile b/kernel/sched/Makefile
index 4b87c4e..38cbc0d 100644
--- a/kernel/sched/Makefile
+++ b/kernel/sched/Makefile
@@ -28,4 +28,3 @@
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
obj-$(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) += cpufreq_schedutil.o
obj-$(CONFIG_SCHED_CORE_CTL) += core_ctl.o
-obj-$(CONFIG_CPU_FREQ_GOV_SCHED) += cpufreq_sched.o
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index ad2b980..23a7f9c 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -3233,70 +3233,6 @@
unsigned int capacity_margin_freq = 1280; /* ~20% margin */
-#ifdef CONFIG_CPU_FREQ_GOV_SCHED
-
-static inline
-unsigned long sum_capacity_reqs(unsigned long cfs_cap,
- struct sched_capacity_reqs *scr, int cpu)
-{
- unsigned long total = add_capacity_margin(cfs_cap + scr->rt, cpu);
- return total += scr->dl;
-}
-
-unsigned long boosted_cpu_util(int cpu);
-static void sched_freq_tick_pelt(int cpu)
-{
- unsigned long cpu_utilization = boosted_cpu_util(cpu);
- unsigned long capacity_curr = capacity_curr_of(cpu);
- struct sched_capacity_reqs *scr;
-
- scr = &per_cpu(cpu_sched_capacity_reqs, cpu);
- if (sum_capacity_reqs(cpu_utilization, scr, cpu) < capacity_curr)
- return;
-
- /*
- * To make free room for a task that is building up its "real"
- * utilization and to harm its performance the least, request
- * a jump to a higher OPP as soon as the margin of free capacity
- * is impacted (specified by capacity_margin_freq).
- */
- set_cfs_cpu_capacity(cpu, true, cpu_utilization);
-}
-
-#ifdef CONFIG_SCHED_WALT
-static void sched_freq_tick_walt(int cpu)
-{
- unsigned long cpu_utilization = cpu_util_freq(cpu, NULL);
-
- if (walt_disabled || !sysctl_sched_use_walt_cpu_util)
- return sched_freq_tick_pelt(cpu);
-
- cpu_utilization = cpu_utilization * SCHED_CAPACITY_SCALE /
- capacity_orig_of(cpu);
- /*
- * It is likely that the load is growing so we
- * keep the added margin in our request as an
- * extra boost.
- */
- set_cfs_cpu_capacity(cpu, true, cpu_utilization);
-
-}
-#define _sched_freq_tick(cpu) sched_freq_tick_walt(cpu)
-#else
-#define _sched_freq_tick(cpu) sched_freq_tick_pelt(cpu)
-#endif /* CONFIG_SCHED_WALT */
-
-static void sched_freq_tick(int cpu)
-{
- if (!sched_freq())
- return;
-
- _sched_freq_tick(cpu);
-}
-#else
-static inline void sched_freq_tick(int cpu) { }
-#endif /* CONFIG_CPU_FREQ_GOV_SCHED */
-
/*
* This function gets called by the timer code, with HZ frequency.
* We call it with interrupts disabled.
@@ -3326,7 +3262,6 @@
curr->sched_class->task_tick(rq, curr, 0);
cpu_load_update_active(rq);
calc_global_load_tick(rq);
- sched_freq_tick(cpu);
early_notif = early_detection_notify(rq, wallclock);
if (early_notif)
diff --git a/kernel/sched/cpufreq_sched.c b/kernel/sched/cpufreq_sched.c
deleted file mode 100644
index 843eaa7..0000000
--- a/kernel/sched/cpufreq_sched.c
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Turquette <mturquette@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/cpufreq.h>
-#include <linux/module.h>
-#include <linux/kthread.h>
-#include <linux/percpu.h>
-#include <linux/irq_work.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-
-#define CREATE_TRACE_POINTS
-#include <trace/events/cpufreq_sched.h>
-
-#include "sched.h"
-
-#define THROTTLE_DOWN_NSEC 50000000 /* 50ms default */
-#define THROTTLE_UP_NSEC 500000 /* 500us default */
-
-struct static_key __read_mostly __sched_freq = STATIC_KEY_INIT_FALSE;
-static bool __read_mostly cpufreq_driver_slow;
-
-#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_SCHED
-static struct cpufreq_governor cpufreq_gov_sched;
-#endif
-
-static DEFINE_PER_CPU(unsigned long, enabled);
-DEFINE_PER_CPU(struct sched_capacity_reqs, cpu_sched_capacity_reqs);
-
-struct gov_tunables {
- struct gov_attr_set attr_set;
- unsigned int up_throttle_nsec;
- unsigned int down_throttle_nsec;
-};
-
-/**
- * gov_data - per-policy data internal to the governor
- * @up_throttle: next throttling period expiry if increasing OPP
- * @down_throttle: next throttling period expiry if decreasing OPP
- * @up_throttle_nsec: throttle period length in nanoseconds if increasing OPP
- * @down_throttle_nsec: throttle period length in nanoseconds if decreasing OPP
- * @task: worker thread for dvfs transition that may block/sleep
- * @irq_work: callback used to wake up worker thread
- * @requested_freq: last frequency requested by the sched governor
- *
- * struct gov_data is the per-policy cpufreq_sched-specific data structure. A
- * per-policy instance of it is created when the cpufreq_sched governor receives
- * the CPUFREQ_GOV_START condition and a pointer to it exists in the gov_data
- * member of struct cpufreq_policy.
- *
- * Readers of this data must call down_read(policy->rwsem). Writers must
- * call down_write(policy->rwsem).
- */
-struct gov_data {
- ktime_t up_throttle;
- ktime_t down_throttle;
- struct gov_tunables *tunables;
- struct list_head tunables_hook;
- struct task_struct *task;
- struct irq_work irq_work;
- unsigned int requested_freq;
-};
-
-static void cpufreq_sched_try_driver_target(struct cpufreq_policy *policy,
- unsigned int freq)
-{
- struct gov_data *gd = policy->governor_data;
-
- /* avoid race with cpufreq_sched_stop */
- if (!down_write_trylock(&policy->rwsem))
- return;
-
- __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
-
- gd->up_throttle = ktime_add_ns(ktime_get(),
- gd->tunables->up_throttle_nsec);
- gd->down_throttle = ktime_add_ns(ktime_get(),
- gd->tunables->down_throttle_nsec);
- up_write(&policy->rwsem);
-}
-
-static bool finish_last_request(struct gov_data *gd, unsigned int cur_freq)
-{
- ktime_t now = ktime_get();
-
- ktime_t throttle = gd->requested_freq < cur_freq ?
- gd->down_throttle : gd->up_throttle;
-
- if (ktime_after(now, throttle))
- return false;
-
- while (1) {
- int usec_left = ktime_to_ns(ktime_sub(throttle, now));
-
- usec_left /= NSEC_PER_USEC;
- trace_cpufreq_sched_throttled(usec_left);
- usleep_range(usec_left, usec_left + 100);
- now = ktime_get();
- if (ktime_after(now, throttle))
- return true;
- }
-}
-
-/*
- * we pass in struct cpufreq_policy. This is safe because changing out the
- * policy requires a call to __cpufreq_governor(policy, CPUFREQ_GOV_STOP),
- * which tears down all of the data structures and __cpufreq_governor(policy,
- * CPUFREQ_GOV_START) will do a full rebuild, including this kthread with the
- * new policy pointer
- */
-static int cpufreq_sched_thread(void *data)
-{
- struct sched_param param;
- struct cpufreq_policy *policy;
- struct gov_data *gd;
- unsigned int new_request = 0;
- unsigned int last_request = 0;
- int ret;
-
- policy = (struct cpufreq_policy *) data;
- gd = policy->governor_data;
-
- param.sched_priority = 50;
- ret = sched_setscheduler_nocheck(gd->task, SCHED_FIFO, ¶m);
- if (ret) {
- pr_warn("%s: failed to set SCHED_FIFO\n", __func__);
- do_exit(-EINVAL);
- } else {
- pr_debug("%s: kthread (%d) set to SCHED_FIFO\n",
- __func__, gd->task->pid);
- }
-
- do {
- new_request = gd->requested_freq;
- if (new_request == last_request) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (kthread_should_stop())
- break;
- schedule();
- } else {
- /*
- * if the frequency thread sleeps while waiting to be
- * unthrottled, start over to check for a newer request
- */
- if (finish_last_request(gd, policy->cur))
- continue;
- last_request = new_request;
- cpufreq_sched_try_driver_target(policy, new_request);
- }
- } while (!kthread_should_stop());
-
- return 0;
-}
-
-static void cpufreq_sched_irq_work(struct irq_work *irq_work)
-{
- struct gov_data *gd;
-
- gd = container_of(irq_work, struct gov_data, irq_work);
- if (!gd)
- return;
-
- wake_up_process(gd->task);
-}
-
-static void update_fdomain_capacity_request(int cpu)
-{
- unsigned int freq_new, index_new, cpu_tmp;
- struct cpufreq_policy *policy;
- struct gov_data *gd;
- unsigned long capacity = 0;
-
- /*
- * Avoid grabbing the policy if possible. A test is still
- * required after locking the CPU's policy to avoid racing
- * with the governor changing.
- */
- if (!per_cpu(enabled, cpu))
- return;
-
- policy = cpufreq_cpu_get(cpu);
- if (IS_ERR_OR_NULL(policy))
- return;
-
- if (policy->governor != &cpufreq_gov_sched ||
- !policy->governor_data)
- goto out;
-
- gd = policy->governor_data;
-
- /* find max capacity requested by cpus in this policy */
- for_each_cpu(cpu_tmp, policy->cpus) {
- struct sched_capacity_reqs *scr;
-
- scr = &per_cpu(cpu_sched_capacity_reqs, cpu_tmp);
- capacity = max(capacity, scr->total);
- }
-
- /* Convert the new maximum capacity request into a cpu frequency */
- freq_new = capacity * policy->max >> SCHED_CAPACITY_SHIFT;
- index_new = cpufreq_frequency_table_target(policy, freq_new, CPUFREQ_RELATION_L);
- freq_new = policy->freq_table[index_new].frequency;
-
- if (freq_new > policy->max)
- freq_new = policy->max;
-
- if (freq_new < policy->min)
- freq_new = policy->min;
-
- trace_cpufreq_sched_request_opp(cpu, capacity, freq_new,
- gd->requested_freq);
- if (freq_new == gd->requested_freq)
- goto out;
-
- gd->requested_freq = freq_new;
-
- /*
- * Throttling is not yet supported on platforms with fast cpufreq
- * drivers.
- */
- if (cpufreq_driver_slow)
- irq_work_queue_on(&gd->irq_work, cpu);
- else
- cpufreq_sched_try_driver_target(policy, freq_new);
-
-out:
- cpufreq_cpu_put(policy);
-}
-
-void update_cpu_capacity_request(int cpu, bool request)
-{
- unsigned long new_capacity;
- struct sched_capacity_reqs *scr;
-
- /* The rq lock serializes access to the CPU's sched_capacity_reqs. */
- lockdep_assert_held(&cpu_rq(cpu)->lock);
-
- scr = &per_cpu(cpu_sched_capacity_reqs, cpu);
-
-#ifdef CONFIG_SCHED_WALT
- if (walt_disabled || !sysctl_sched_use_walt_cpu_util)
- new_capacity = scr->cfs + scr->rt;
-#endif
- new_capacity = scr->cfs;
- new_capacity = new_capacity * capacity_margin_freq
- / SCHED_CAPACITY_SCALE;
- new_capacity += scr->dl;
-
- if (new_capacity == scr->total)
- return;
-
- trace_cpufreq_sched_update_capacity(cpu, request, scr, new_capacity);
-
- scr->total = new_capacity;
- if (request)
- update_fdomain_capacity_request(cpu);
-}
-
-static inline void set_sched_freq(void)
-{
- static_key_slow_inc(&__sched_freq);
-}
-
-static inline void clear_sched_freq(void)
-{
- static_key_slow_dec(&__sched_freq);
-}
-
-/* Tunables */
-static struct gov_tunables *global_tunables;
-
-static inline struct gov_tunables *to_tunables(struct gov_attr_set *attr_set)
-{
- return container_of(attr_set, struct gov_tunables, attr_set);
-}
-
-static ssize_t up_throttle_nsec_show(struct gov_attr_set *attr_set, char *buf)
-{
- struct gov_tunables *tunables = to_tunables(attr_set);
-
- return sprintf(buf, "%u\n", tunables->up_throttle_nsec);
-}
-
-static ssize_t up_throttle_nsec_store(struct gov_attr_set *attr_set,
- const char *buf, size_t count)
-{
- struct gov_tunables *tunables = to_tunables(attr_set);
- int ret;
- long unsigned int val;
-
- ret = kstrtoul(buf, 0, &val);
- if (ret < 0)
- return ret;
- tunables->up_throttle_nsec = val;
- return count;
-}
-
-static ssize_t down_throttle_nsec_show(struct gov_attr_set *attr_set, char *buf)
-{
- struct gov_tunables *tunables = to_tunables(attr_set);
-
- return sprintf(buf, "%u\n", tunables->down_throttle_nsec);
-}
-
-static ssize_t down_throttle_nsec_store(struct gov_attr_set *attr_set,
- const char *buf, size_t count)
-{
- struct gov_tunables *tunables = to_tunables(attr_set);
- int ret;
- long unsigned int val;
-
- ret = kstrtoul(buf, 0, &val);
- if (ret < 0)
- return ret;
- tunables->down_throttle_nsec = val;
- return count;
-}
-
-static struct governor_attr up_throttle_nsec = __ATTR_RW(up_throttle_nsec);
-static struct governor_attr down_throttle_nsec = __ATTR_RW(down_throttle_nsec);
-
-static struct attribute *schedfreq_attributes[] = {
- &up_throttle_nsec.attr,
- &down_throttle_nsec.attr,
- NULL
-};
-
-static struct kobj_type tunables_ktype = {
- .default_attrs = schedfreq_attributes,
- .sysfs_ops = &governor_sysfs_ops,
-};
-
-static int cpufreq_sched_policy_init(struct cpufreq_policy *policy)
-{
- struct gov_data *gd;
- int cpu;
- int rc;
-
- for_each_cpu(cpu, policy->cpus)
- memset(&per_cpu(cpu_sched_capacity_reqs, cpu), 0,
- sizeof(struct sched_capacity_reqs));
-
- gd = kzalloc(sizeof(*gd), GFP_KERNEL);
- if (!gd)
- return -ENOMEM;
-
- policy->governor_data = gd;
-
- if (!global_tunables) {
- gd->tunables = kzalloc(sizeof(*gd->tunables), GFP_KERNEL);
- if (!gd->tunables)
- goto free_gd;
-
- gd->tunables->up_throttle_nsec =
- policy->cpuinfo.transition_latency ?
- policy->cpuinfo.transition_latency :
- THROTTLE_UP_NSEC;
- gd->tunables->down_throttle_nsec =
- THROTTLE_DOWN_NSEC;
-
- rc = kobject_init_and_add(&gd->tunables->attr_set.kobj,
- &tunables_ktype,
- get_governor_parent_kobj(policy),
- "%s", cpufreq_gov_sched.name);
- if (rc)
- goto free_tunables;
-
- gov_attr_set_init(&gd->tunables->attr_set,
- &gd->tunables_hook);
-
- pr_debug("%s: throttle_threshold = %u [ns]\n",
- __func__, gd->tunables->up_throttle_nsec);
-
- if (!have_governor_per_policy())
- global_tunables = gd->tunables;
- } else {
- gd->tunables = global_tunables;
- gov_attr_set_get(&global_tunables->attr_set,
- &gd->tunables_hook);
- }
-
- policy->governor_data = gd;
- if (cpufreq_driver_is_slow()) {
- cpufreq_driver_slow = true;
- gd->task = kthread_create(cpufreq_sched_thread, policy,
- "kschedfreq:%d",
- cpumask_first(policy->related_cpus));
- if (IS_ERR_OR_NULL(gd->task)) {
- pr_err("%s: failed to create kschedfreq thread\n",
- __func__);
- goto free_tunables;
- }
- get_task_struct(gd->task);
- kthread_bind_mask(gd->task, policy->related_cpus);
- wake_up_process(gd->task);
- init_irq_work(&gd->irq_work, cpufreq_sched_irq_work);
- }
-
- set_sched_freq();
-
- return 0;
-
-free_tunables:
- kfree(gd->tunables);
-free_gd:
- policy->governor_data = NULL;
- kfree(gd);
- return -ENOMEM;
-}
-
-static void cpufreq_sched_policy_exit(struct cpufreq_policy *policy)
-{
- unsigned int count;
- struct gov_data *gd = policy->governor_data;
-
- clear_sched_freq();
- if (cpufreq_driver_slow) {
- kthread_stop(gd->task);
- put_task_struct(gd->task);
- }
-
- count = gov_attr_set_put(&gd->tunables->attr_set, &gd->tunables_hook);
- if (!count) {
- if (!have_governor_per_policy())
- global_tunables = NULL;
- kfree(gd->tunables);
- }
-
- policy->governor_data = NULL;
-
- kfree(gd);
-}
-
-static int cpufreq_sched_start(struct cpufreq_policy *policy)
-{
- int cpu;
-
- for_each_cpu(cpu, policy->cpus)
- per_cpu(enabled, cpu) = 1;
-
- return 0;
-}
-
-static void cpufreq_sched_limits(struct cpufreq_policy *policy)
-{
- unsigned int clamp_freq;
- struct gov_data *gd = policy->governor_data;;
-
- pr_debug("limit event for cpu %u: %u - %u kHz, currently %u kHz\n",
- policy->cpu, policy->min, policy->max,
- policy->cur);
-
- clamp_freq = clamp(gd->requested_freq, policy->min, policy->max);
-
- if (policy->cur != clamp_freq)
- __cpufreq_driver_target(policy, clamp_freq, CPUFREQ_RELATION_L);
-}
-
-static void cpufreq_sched_stop(struct cpufreq_policy *policy)
-{
- int cpu;
-
- for_each_cpu(cpu, policy->cpus)
- per_cpu(enabled, cpu) = 0;
-}
-
-
-#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_SCHED
-static
-#endif
-struct cpufreq_governor cpufreq_gov_sched = {
- .name = "sched",
- .init = cpufreq_sched_policy_init,
- .exit = cpufreq_sched_policy_exit,
- .start = cpufreq_sched_start,
- .stop = cpufreq_sched_stop,
- .limits = cpufreq_sched_limits,
- .owner = THIS_MODULE,
-};
-
-static int __init cpufreq_sched_init(void)
-{
- int cpu;
-
- for_each_cpu(cpu, cpu_possible_mask)
- per_cpu(enabled, cpu) = 0;
- return cpufreq_register_governor(&cpufreq_gov_sched);
-}
-
-#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_SCHED
-struct cpufreq_governor *cpufreq_default_governor(void)
-{
- return &cpufreq_gov_sched;
-}
-#endif
-
-/* Try to make this the default governor */
-fs_initcall(cpufreq_sched_init);
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index 32b67eb..53974cc 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -19,10 +19,6 @@
#include "sched.h"
#include "tune.h"
-#ifdef CONFIG_SCHED_WALT
-unsigned long boosted_cpu_util(int cpu);
-#endif
-
#define SUGOV_KTHREAD_PRIORITY 50
struct sugov_tunables {
@@ -182,8 +178,7 @@
*util = min(rq->cfs.avg.util_avg, cfs_max);
*max = cfs_max;
- *util = cpu_util_freq(cpu, &loadcpu->walt_load);
- *util = boosted_cpu_util(cpu);
+ *util = boosted_cpu_util(cpu, &loadcpu->walt_load);
}
static void sugov_set_iowait_boost(struct sugov_cpu *sg_cpu, u64 time,
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
old mode 100755
new mode 100644
index 1cb03a4..75ea4ff
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -87,7 +87,6 @@
unsigned int sysctl_sched_is_big_little = 1;
unsigned int sysctl_sched_sync_hint_enable = 1;
-unsigned int sysctl_sched_initial_task_util = 0;
unsigned int sysctl_sched_cstate_aware = 1;
DEFINE_PER_CPU_READ_MOSTLY(int, sched_load_boost);
@@ -165,6 +164,7 @@
*/
unsigned int sysctl_sched_capacity_margin = 1078; /* ~5% margin */
unsigned int sysctl_sched_capacity_margin_down = 1205; /* ~15% margin */
+#define capacity_margin sysctl_sched_capacity_margin
static inline void update_load_add(struct load_weight *lw, unsigned long inc)
{
@@ -288,10 +288,6 @@
return mul_u64_u32_shr(delta_exec, fact, shift);
}
-#ifdef CONFIG_SMP
-static int active_load_balance_cpu_stop(void *data);
-#endif
-
const struct sched_class fair_sched_class;
/**************************************************************
@@ -792,9 +788,7 @@
/*
* At this point, util_avg won't be used in select_task_rq_fair anyway
*/
- sa->util_avg = sched_freq() ?
- sysctl_sched_initial_task_util :
- 0;
+ sa->util_avg = 0;
sa->util_sum = 0;
/* when this task enqueue'ed, it will contribute to its cfs_rq's load_avg */
}
@@ -3379,6 +3373,7 @@
struct rq *rq = rq_of(cfs_rq);
int cpu = cpu_of(rq);
int decayed;
+ void *ptr = NULL;
/*
* Track task load average for carrying it to new CPU after migrated, and
@@ -3396,8 +3391,12 @@
if (decayed && (flags & UPDATE_TG))
update_tg_load_avg(cfs_rq, 0);
- if (entity_is_task(se))
- trace_sched_load_avg_task(task_of(se), &se->avg);
+ if (entity_is_task(se)) {
+#ifdef CONFIG_SCHED_WALT
+ ptr = (void *)&(task_of(se)->ravg);
+#endif
+ trace_sched_load_avg_task(task_of(se), &se->avg, ptr);
+ }
}
/**
@@ -4851,24 +4850,6 @@
#ifdef CONFIG_SMP
static unsigned long capacity_orig_of(int cpu);
static unsigned long cpu_util(int cpu);
-unsigned long boosted_cpu_util(int cpu);
-#else
-#define boosted_cpu_util(cpu) cpu_util_freq(cpu)
-#endif
-
-#ifdef CONFIG_SMP
-static void update_capacity_of(int cpu)
-{
- unsigned long req_cap;
-
- if (!sched_freq())
- return;
-
- /* Convert scale-invariant capacity to cpu. */
- req_cap = boosted_cpu_util(cpu);
- req_cap = req_cap * SCHED_CAPACITY_SCALE / capacity_orig_of(cpu);
- set_cfs_cpu_capacity(cpu, true, req_cap);
-}
#endif
/*
@@ -4883,7 +4864,6 @@
struct sched_entity *se = &p->se;
#ifdef CONFIG_SMP
int task_new = flags & ENQUEUE_WAKEUP_NEW;
- int task_wakeup = flags & ENQUEUE_WAKEUP;
#endif
#ifdef CONFIG_SCHED_WALT
@@ -4961,16 +4941,6 @@
rq->rd->overutilized = true;
trace_sched_overutilized(true);
}
-
- /*
- * We want to potentially trigger a freq switch
- * request only for tasks that are waking up; this is
- * because we get here also during load balancing, but
- * in these cases it seems wise to trigger as single
- * request after load balancing is done.
- */
- if (task_new || task_wakeup)
- update_capacity_of(cpu_of(rq));
}
#endif /* CONFIG_SMP */
@@ -5048,13 +5018,6 @@
*/
schedtune_dequeue_task(p, cpu_of(rq));
- if (!se) {
- if (rq->cfs.nr_running)
- update_capacity_of(cpu_of(rq));
- else if (sched_freq())
- set_cfs_cpu_capacity(cpu_of(rq), false, 0);
- }
-
#endif /* CONFIG_SMP */
hrtick_update(rq);
@@ -5527,6 +5490,15 @@
}
/*
+ * Externally visible function. Let's keep the one above
+ * so that the check is inlined/optimized in the sched paths.
+ */
+bool sched_is_energy_aware(void)
+{
+ return energy_aware();
+}
+
+/*
* Returns the current capacity of cpu after applying both
* cpu and freq scaling.
*/
@@ -5538,44 +5510,88 @@
}
/*
- * Externally visible function. Let's keep the one above
- * so that the check is inlined/optimized in the sched paths.
+ * Returns the current capacity of cpu after applying both
+ * cpu and min freq scaling.
*/
-bool sched_is_energy_aware(void)
+unsigned long capacity_min_of(int cpu)
{
- return energy_aware();
+ if (!sched_feat(MIN_CAPACITY_CAPPING))
+ return 0;
+ return arch_scale_cpu_capacity(NULL, cpu) *
+ arch_scale_min_freq_capacity(NULL, cpu)
+ >> SCHED_CAPACITY_SHIFT;
}
+/*
+ * CPU candidates.
+ *
+ * These are labels to reference CPU candidates for an energy_diff.
+ * Currently we support only two possible candidates: the task's previous CPU
+ * and another candiate CPU.
+ * More advanced/aggressive EAS selection policies can consider more
+ * candidates.
+ */
+#define EAS_CPU_PRV 0
+#define EAS_CPU_NXT 1
+#define EAS_CPU_BKP 2
+#define EAS_CPU_CNT 3
+
+/*
+ * energy_diff - supports the computation of the estimated energy impact in
+ * moving a "task"'s "util_delta" between different CPU candidates.
+ */
struct energy_env {
+ /* Utilization to move */
+ struct task_struct *p;
+ int util_delta;
+
+ /* Mask of CPUs candidates to evaluate */
+ cpumask_t cpus_mask;
+
+ /* CPU candidates to evaluate */
+ struct {
+
+ /* CPU ID, must be in cpus_mask */
+ int cpu_id;
+
+ /*
+ * Index (into sched_group_energy::cap_states) of the OPP the
+ * CPU needs to run at if the task is placed on it.
+ * This includes the both active and blocked load, due to
+ * other tasks on this CPU, as well as the task's own
+ * utilization.
+ */
+ int cap_idx;
+ int cap;
+
+ /* Estimated system energy */
+ unsigned int energy;
+
+ /* Estimated energy variation wrt EAS_CPU_PRV */
+ int nrg_delta;
+
+ } cpu[EAS_CPU_CNT];
+
+ /*
+ * Index (into energy_env::cpu) of the morst energy efficient CPU for
+ * the specified energy_env::task
+ */
+ int next_idx;
+
+ /* Support data */
struct sched_group *sg_top;
struct sched_group *sg_cap;
- int cap_idx;
- int util_delta;
- int src_cpu;
- int dst_cpu;
- int energy;
- int payoff;
- int sync_cpu;
- unsigned long curr_util;
- struct task_struct *task;
- struct {
- int before;
- int after;
- int delta;
- int diff;
- } nrg;
- struct {
- int before;
- int after;
- int delta;
- } cap;
+ struct sched_group *sg;
};
+static int cpu_util_wake(int cpu, struct task_struct *p);
+
/*
* __cpu_norm_util() returns the cpu util relative to a specific capacity,
- * i.e. it's busy ratio, in the range [0..SCHED_LOAD_SCALE] which is useful for
- * energy calculations. Using the scale-invariant util returned by
- * cpu_util() and approximating scale-invariant util by:
+ * i.e. it's busy ratio, in the range [0..SCHED_LOAD_SCALE], which is useful for
+ * energy calculations.
+ *
+ * Since util is a scale-invariant utilization defined as:
*
* util ~ (curr_freq/max_freq)*1024 * capacity_orig/1024 * running_time/time
*
@@ -5585,83 +5601,41 @@
*
* norm_util = running_time/time ~ util/capacity
*/
-static unsigned long __cpu_norm_util(int cpu, unsigned long capacity, int delta)
+static unsigned long __cpu_norm_util(unsigned long util, unsigned long capacity)
{
- int util = cpu_util_cum(cpu, delta);
-
if (util >= capacity)
return SCHED_CAPACITY_SCALE;
- return DIV_ROUND_UP(util << SCHED_CAPACITY_SHIFT, capacity);
+ return (util << SCHED_CAPACITY_SHIFT)/capacity;
}
-static inline bool
-bias_to_waker_cpu(struct task_struct *p, int cpu, struct cpumask *rtg_target)
+static unsigned long group_max_util(struct energy_env *eenv, int cpu_idx)
{
- int rtg_target_cpu = rtg_target ? cpumask_first(rtg_target) : cpu;
-
- return cpumask_test_cpu(cpu, tsk_cpus_allowed(p)) &&
- cpu_active(cpu) && !cpu_isolated(cpu) &&
- capacity_orig_of(cpu) >= capacity_orig_of(rtg_target_cpu) &&
- task_fits_max(p, cpu);
-}
-
-static int calc_util_delta(struct energy_env *eenv, int cpu)
-{
-#ifdef CONFIG_SCHED_WALT
- if (cpu == eenv->src_cpu) {
- if (!walt_disabled && sysctl_sched_use_walt_task_util &&
- !task_in_cum_window_demand(cpu_rq(cpu), eenv->task)) {
- if (eenv->util_delta == 0)
- /*
- * energy before - calculate energy cost when
- * the new task is placed onto src_cpu. The
- * task is not on a runqueue so its util is not
- * in the WALT's cr_avg as it's discounted when
- * it slept last time. Hence return task's util
- * as delta to calculate energy cost of src_cpu
- * as if the new task on it.
- */
- return task_util(eenv->task);
- /*
- * energy after - WALT's cr_avg already doesn't have the
- * new task's util accounted in. Thus return 0 delta to
- * calculate energy cost of the src_cpu without the
- * task's util.
- */
- return 0;
- }
- /*
- * Task is already on a runqueue for example while load
- * balancing. WALT's cpu util already accounted the task's
- * util. return 0 delta for energy before so energy calculation
- * to be done with the task's util accounted, return -task_util
- * for energy after so the calculation to be doen with
- * discounted task's util.
- */
- return -eenv->util_delta;
- }
-#else
- if (cpu == eenv->src_cpu)
- return -eenv->util_delta;
-#endif
- if (cpu == eenv->dst_cpu)
- return eenv->util_delta;
- return 0;
-}
-
-static
-unsigned long group_max_util(struct energy_env *eenv)
-{
- int i, delta;
unsigned long max_util = 0;
+ unsigned long util;
+ int cpu;
- for_each_cpu(i, sched_group_cpus(eenv->sg_cap)) {
- delta = calc_util_delta(eenv, i);
- /* substract sync_cpu's rq->curr util to discount its cost */
- if (eenv->sync_cpu == i)
- delta -= eenv->curr_util;
- max_util = max(max_util, cpu_util_cum(i, delta));
+ for_each_cpu(cpu, sched_group_cpus(eenv->sg_cap)) {
+ util = cpu_util_wake(cpu, eenv->p);
+
+ /*
+ * If we are looking at the target CPU specified by the eenv,
+ * then we should add the (estimated) utilization of the task
+ * assuming we will wake it up on that CPU.
+ */
+ if (unlikely(cpu == eenv->cpu[cpu_idx].cpu_id))
+ util += eenv->util_delta;
+
+ max_util = max(max_util, util);
+
+ /*
+ * Take into account any minimum frequency imposed
+ * elsewhere which limits the energy states available
+ * If the MIN_CAPACITY_CAPPING feature is not enabled
+ * capacity_min_of will return 0 (not capped).
+ */
+ max_util = max(max_util, capacity_min_of(cpu));
+
}
return max_util;
@@ -5669,60 +5643,64 @@
/*
* group_norm_util() returns the approximated group util relative to it's
- * current capacity (busy ratio) in the range [0..SCHED_LOAD_SCALE] for use in
- * energy calculations. Since task executions may or may not overlap in time in
- * the group the true normalized util is between max(cpu_norm_util(i)) and
- * sum(cpu_norm_util(i)) when iterating over all cpus in the group, i. The
- * latter is used as the estimate as it leads to a more pessimistic energy
+ * current capacity (busy ratio), in the range [0..SCHED_LOAD_SCALE], for use
+ * in energy calculations.
+ *
+ * Since task executions may or may not overlap in time in the group the true
+ * normalized util is between MAX(cpu_norm_util(i)) and SUM(cpu_norm_util(i))
+ * when iterating over all CPUs in the group.
+ * The latter estimate is used as it leads to a more pessimistic energy
* estimate (more busy).
*/
static unsigned
-long group_norm_util(struct energy_env *eenv, struct sched_group *sg)
+long group_norm_util(struct energy_env *eenv, int cpu_idx)
{
- int i, delta;
- unsigned long util_sum = 0;
- unsigned long capacity = sg->sge->cap_states[eenv->cap_idx].cap;
+ unsigned long capacity = eenv->cpu[cpu_idx].cap;
+ unsigned long util, util_sum = 0;
+ int cpu;
- for_each_cpu(i, sched_group_cpus(sg)) {
- delta = calc_util_delta(eenv, i);
- /* substract sync_cpu's rq->curr util to discount its cost */
- if (eenv->sync_cpu == i)
- delta -= eenv->curr_util;
- util_sum += __cpu_norm_util(i, capacity, delta);
+ for_each_cpu(cpu, sched_group_cpus(eenv->sg)) {
+ util = cpu_util_wake(cpu, eenv->p);
+
+ /*
+ * If we are looking at the target CPU specified by the eenv,
+ * then we should add the (estimated) utilization of the task
+ * assuming we will wake it up on that CPU.
+ */
+ if (unlikely(cpu == eenv->cpu[cpu_idx].cpu_id))
+ util += eenv->util_delta;
+
+ util_sum += __cpu_norm_util(util, capacity);
}
- if (util_sum > SCHED_CAPACITY_SCALE)
- return SCHED_CAPACITY_SCALE;
- return util_sum;
+ return min_t(unsigned long, util_sum, SCHED_CAPACITY_SCALE);
}
-static int __find_new_capacity(unsigned long util,
- const struct sched_group_energy const *sge)
+static int find_new_capacity(struct energy_env *eenv, int cpu_idx)
{
- int idx;
+ const struct sched_group_energy *sge = eenv->sg->sge;
+ int idx, max_idx = sge->nr_cap_states - 1;
+ unsigned long util = group_max_util(eenv, cpu_idx);
+
+ /* default is max_cap if we don't find a match */
+ eenv->cpu[cpu_idx].cap_idx = max_idx;
+ eenv->cpu[cpu_idx].cap = sge->cap_states[max_idx].cap;
for (idx = 0; idx < sge->nr_cap_states; idx++) {
- if (sge->cap_states[idx].cap >= util)
- return idx;
+ if (sge->cap_states[idx].cap >= util) {
+ /* Keep track of SG's capacity */
+ eenv->cpu[cpu_idx].cap_idx = idx;
+ eenv->cpu[cpu_idx].cap = sge->cap_states[idx].cap;
+ break;
+ }
}
- return (sge->nr_cap_states - 1);
+ return eenv->cpu[cpu_idx].cap_idx;
}
-static int find_new_capacity(struct energy_env *eenv,
- const struct sched_group_energy const *sge)
+static int group_idle_state(struct energy_env *eenv, int cpu_idx)
{
- int idx;
- unsigned long util = group_max_util(eenv);
-
- idx = __find_new_capacity(util, sge);
- eenv->cap_idx = idx;
-
- return idx;
-}
-
-static int group_idle_state(struct energy_env *eenv, struct sched_group *sg)
-{
+ struct sched_group *sg = eenv->sg;
int i, state = INT_MAX;
int src_in_grp, dst_in_grp;
long grp_util = 0;
@@ -5731,31 +5709,29 @@
for_each_cpu(i, sched_group_cpus(sg))
state = min(state, idle_get_state_idx(cpu_rq(i)));
- if (unlikely(state == INT_MAX))
- return -EINVAL;
-
/* Take non-cpuidle idling into account (active idle/arch_cpu_idle()) */
state++;
- /*
- * Try to estimate if a deeper idle state is
- * achievable when we move the task.
- */
- for_each_cpu(i, sched_group_cpus(sg))
- grp_util += cpu_util(i);
-
- src_in_grp = cpumask_test_cpu(eenv->src_cpu, sched_group_cpus(sg));
- dst_in_grp = cpumask_test_cpu(eenv->dst_cpu, sched_group_cpus(sg));
+ src_in_grp = cpumask_test_cpu(eenv->cpu[EAS_CPU_PRV].cpu_id,
+ sched_group_cpus(sg));
+ dst_in_grp = cpumask_test_cpu(eenv->cpu[cpu_idx].cpu_id,
+ sched_group_cpus(sg));
if (src_in_grp == dst_in_grp) {
/* both CPUs under consideration are in the same group or not in
* either group, migration should leave idle state the same.
*/
goto end;
}
- /* add or remove util as appropriate to indicate what group util
- * will be (worst case - no concurrent execution) after moving the task
+
+ /*
+ * Try to estimate if a deeper idle state is
+ * achievable when we move the task.
*/
- grp_util += src_in_grp ? -eenv->util_delta : eenv->util_delta;
+ for_each_cpu(i, sched_group_cpus(sg)) {
+ grp_util += cpu_util_wake(i, eenv->p);
+ if (unlikely(i == eenv->cpu[cpu_idx].cpu_id))
+ grp_util += eenv->util_delta;
+ }
if (grp_util <=
((long)sg->sgc->max_capacity * (int)sg->group_weight)) {
@@ -5789,22 +5765,65 @@
}
/*
- * sched_group_energy(): Computes the absolute energy consumption of cpus
- * belonging to the sched_group including shared resources shared only by
- * members of the group. Iterates over all cpus in the hierarchy below the
- * sched_group starting from the bottom working it's way up before going to
- * the next cpu until all cpus are covered at all levels. The current
- * implementation is likely to gather the same util statistics multiple times.
- * This can probably be done in a faster but more complex way.
- * Note: sched_group_energy() may fail when racing with sched_domain updates.
+ * calc_sg_energy: compute energy for the eenv's SG (i.e. eenv->sg).
+ *
+ * This works in iterations to compute the SG's energy for each CPU
+ * candidate defined by the energy_env's cpu array.
+ *
+ * NOTE: in the following computations for busy_energy and idle_energy we do
+ * not shift by SCHED_CAPACITY_SHIFT in order to reduce rounding errors.
+ * The required scaling will be performed just one time, by the calling
+ * functions, once we accumulated the contributons for all the SGs.
*/
-static int sched_group_energy(struct energy_env *eenv)
+static void calc_sg_energy(struct energy_env *eenv)
{
- struct sched_domain *sd;
- int cpu;
- u64 total_energy = 0;
+ struct sched_group *sg = eenv->sg;
+ int busy_energy, idle_energy;
+ unsigned int busy_power;
+ unsigned int idle_power;
+ unsigned long sg_util;
+ int cap_idx, idle_idx;
+ int total_energy = 0;
+ int cpu_idx;
+
+ for (cpu_idx = EAS_CPU_PRV; cpu_idx < EAS_CPU_CNT; ++cpu_idx) {
+
+
+ if (eenv->cpu[cpu_idx].cpu_id == -1)
+ continue;
+ /* Compute ACTIVE energy */
+ cap_idx = find_new_capacity(eenv, cpu_idx);
+ busy_power = sg->sge->cap_states[cap_idx].power;
+ /*
+ * in order to calculate cpu_norm_util, we need to know which
+ * capacity level the group will be at, so calculate that first
+ */
+ sg_util = group_norm_util(eenv, cpu_idx);
+
+ busy_energy = sg_util * busy_power;
+
+ /* Compute IDLE energy */
+ idle_idx = group_idle_state(eenv, cpu_idx);
+ idle_power = sg->sge->idle_states[idle_idx].power;
+
+ idle_energy = SCHED_CAPACITY_SCALE - sg_util;
+ idle_energy *= idle_power;
+
+ total_energy = busy_energy + idle_energy;
+ eenv->cpu[cpu_idx].energy += total_energy;
+ }
+}
+
+/*
+ * compute_energy() computes the absolute variation in energy consumption by
+ * moving eenv.util_delta from EAS_CPU_PRV to EAS_CPU_NXT.
+ *
+ * NOTE: compute_energy() may fail when racing with sched_domain updates, in
+ * which case we abort by returning -EINVAL.
+ */
+static int compute_energy(struct energy_env *eenv)
+{
struct cpumask visit_cpus;
- struct sched_group *sg;
int cpu_count;
WARN_ON(!eenv->sg_top->sge);
@@ -5824,8 +5843,8 @@
while (!cpumask_empty(&visit_cpus)) {
struct sched_group *sg_shared_cap = NULL;
-
- cpu = cpumask_first(&visit_cpus);
+ int cpu = cpumask_first(&visit_cpus);
+ struct sched_domain *sd;
/*
* Is the group utilization affected by cpus outside this
@@ -5834,69 +5853,29 @@
* when we took visit_cpus.
*/
sd = rcu_dereference(per_cpu(sd_scs, cpu));
-
if (sd && sd->parent)
sg_shared_cap = sd->parent->groups;
for_each_domain(cpu, sd) {
- sg = sd->groups;
+ struct sched_group *sg = sd->groups;
/* Has this sched_domain already been visited? */
if (sd->child && group_first_cpu(sg) != cpu)
break;
do {
- unsigned long group_util;
- int sg_busy_energy, sg_idle_energy;
- int cap_idx, idle_idx;
-
+ eenv->sg_cap = sg;
if (sg_shared_cap && sg_shared_cap->group_weight >= sg->group_weight)
eenv->sg_cap = sg_shared_cap;
- else
- eenv->sg_cap = sg;
- cap_idx = find_new_capacity(eenv, sg->sge);
+ /*
+ * Compute the energy for all the candidate
+ * CPUs in the current visited SG.
+ */
+ eenv->sg = sg;
+ calc_sg_energy(eenv);
- if (sg->group_weight == 1) {
- /* Remove capacity of src CPU (before task move) */
- if (eenv->util_delta == 0 &&
- cpumask_test_cpu(eenv->src_cpu, sched_group_cpus(sg))) {
- eenv->cap.before = sg->sge->cap_states[cap_idx].cap;
- eenv->cap.delta -= eenv->cap.before;
- }
- /* Add capacity of dst CPU (after task move) */
- if (eenv->util_delta != 0 &&
- cpumask_test_cpu(eenv->dst_cpu, sched_group_cpus(sg))) {
- eenv->cap.after = sg->sge->cap_states[cap_idx].cap;
- eenv->cap.delta += eenv->cap.after;
- }
- }
-
- idle_idx = group_idle_state(eenv, sg);
- if (unlikely(idle_idx < 0))
- return idle_idx;
-
- if (idle_idx > sg->sge->nr_idle_states - 1)
- idle_idx = sg->sge->nr_idle_states - 1;
-
- group_util = group_norm_util(eenv, sg);
- sg_busy_energy = (group_util * sg->sge->cap_states[cap_idx].power);
-
- if (idle_idx == 0)
- sg_idle_energy = ((SCHED_CAPACITY_SCALE - group_util)
- * sg->sge->cap_states[cap_idx].power);
- else
- sg_idle_energy = ((SCHED_CAPACITY_SCALE - group_util)
- * sg->sge->idle_states[idle_idx].power);
-
- total_energy += sg_busy_energy + sg_idle_energy;
-
- trace_sched_group_energy(group_first_cpu(sg),
- group_util, total_energy,
- sg_busy_energy, sg_idle_energy,
- idle_idx,
- sg->sge->cap_states[eenv->cap_idx].cap);
-
+ /* remove CPUs we have just visited */
if (!sd->child) {
/*
* cpu_count here is the number of
@@ -5937,7 +5916,6 @@
continue;
}
- eenv->energy = total_energy >> SCHED_CAPACITY_SHIFT;
return 0;
}
@@ -5947,166 +5925,106 @@
}
/*
- * energy_diff(): Estimate the energy impact of changing the utilization
- * distribution. eenv specifies the change: utilisation amount, source, and
- * destination cpu. Source or destination cpu may be -1 in which case the
- * utilization is removed from or added to the system (e.g. task wake-up). If
- * both are specified, the utilization is migrated.
+ * select_energy_cpu_idx(): estimate the energy impact of changing the
+ * utilization distribution.
+ *
+ * The eenv parameter specifies the changes: utilisation amount and a pair of
+ * possible CPU candidates (the previous CPU and a different target CPU).
+ *
+ * This function returns the index of a CPU candidate specified by the
+ * energy_env which corresponds to the first CPU saving energy.
+ * Thus, 0 (EAS_CPU_PRV) means that non of the CPU candidate is more energy
+ * efficient than running on prev_cpu. This is also the value returned in case
+ * of abort due to error conditions during the computations.
+ * A value greater than zero means that the first energy-efficient CPU is the
+ * one represented by eenv->cpu[eenv->next_idx].cpu_id.
*/
-static inline int __energy_diff(struct energy_env *eenv)
+static inline int select_energy_cpu_idx(struct energy_env *eenv)
{
struct sched_domain *sd;
struct sched_group *sg;
- int sd_cpu = -1, energy_before = 0, energy_after = 0;
- int diff, margin;
+ int sd_cpu = -1;
+ int cpu_idx;
+ int margin;
- struct energy_env eenv_before = {
- .util_delta = 0,
- .src_cpu = eenv->src_cpu,
- .dst_cpu = eenv->dst_cpu,
- .nrg = { 0, 0, 0, 0},
- .cap = { 0, 0, 0 },
- .task = eenv->task,
- .sync_cpu = eenv->sync_cpu,
- };
-
- if (eenv->src_cpu == eenv->dst_cpu)
- return 0;
-
- sd_cpu = (eenv->src_cpu != -1) ? eenv->src_cpu : eenv->dst_cpu;
+ sd_cpu = eenv->cpu[EAS_CPU_PRV].cpu_id;
sd = rcu_dereference(per_cpu(sd_ea, sd_cpu));
-
if (!sd)
- return 0; /* Error */
+ return EAS_CPU_PRV;
+
+ cpumask_clear(&eenv->cpus_mask);
+ for (cpu_idx = EAS_CPU_PRV; cpu_idx < EAS_CPU_CNT; ++cpu_idx) {
+ int cpu = eenv->cpu[cpu_idx].cpu_id;
+
+ if (cpu < 0)
+ continue;
+ cpumask_set_cpu(cpu, &eenv->cpus_mask);
+ }
sg = sd->groups;
-
do {
- if (cpu_in_sg(sg, eenv->src_cpu) || cpu_in_sg(sg, eenv->dst_cpu)) {
- eenv_before.sg_top = eenv->sg_top = sg;
+ /* Skip SGs which do not contains a candidate CPU */
+ if (!cpumask_intersects(&eenv->cpus_mask, sched_group_cpus(sg)))
+ continue;
- if (sched_group_energy(&eenv_before))
- return 0; /* Invalid result abort */
- energy_before += eenv_before.energy;
+ eenv->sg_top = sg;
+ /* energy is unscaled to reduce rounding errors */
+ if (compute_energy(eenv) == -EINVAL)
+ return EAS_CPU_PRV;
- /* Keep track of SRC cpu (before) capacity */
- eenv->cap.before = eenv_before.cap.before;
- eenv->cap.delta = eenv_before.cap.delta;
-
- if (sched_group_energy(eenv))
- return 0; /* Invalid result abort */
- energy_after += eenv->energy;
- }
} while (sg = sg->next, sg != sd->groups);
- eenv->nrg.before = energy_before;
- eenv->nrg.after = energy_after;
- eenv->nrg.diff = eenv->nrg.after - eenv->nrg.before;
- eenv->payoff = 0;
-#ifndef CONFIG_SCHED_TUNE
- trace_sched_energy_diff(eenv->task,
- eenv->src_cpu, eenv->dst_cpu, eenv->util_delta,
- eenv->nrg.before, eenv->nrg.after, eenv->nrg.diff,
- eenv->cap.before, eenv->cap.after, eenv->cap.delta,
- eenv->nrg.delta, eenv->payoff);
-#endif
+ /* Scale energy before comparisons */
+ for (cpu_idx = EAS_CPU_PRV; cpu_idx < EAS_CPU_CNT; ++cpu_idx)
+ eenv->cpu[cpu_idx].energy >>= SCHED_CAPACITY_SHIFT;
+
/*
- * Dead-zone margin preventing too many migrations.
+ * Compute the dead-zone margin used to prevent too many task
+ * migrations with negligible energy savings.
+ * An energy saving is considered meaningful if it reduces the energy
+ * consumption of EAS_CPU_PRV CPU candidate by at least ~1.56%
*/
+ margin = eenv->cpu[EAS_CPU_PRV].energy >> 6;
- margin = eenv->nrg.before >> 6; /* ~1.56% */
+ /*
+ * By default the EAS_CPU_PRV CPU is considered the most energy
+ * efficient, with a 0 energy variation.
+ */
+ eenv->next_idx = EAS_CPU_PRV;
- diff = eenv->nrg.after - eenv->nrg.before;
-
- eenv->nrg.diff = (abs(diff) < margin) ? 0 : eenv->nrg.diff;
-
- return eenv->nrg.diff;
-}
-
-#ifdef CONFIG_SCHED_TUNE
-
-struct target_nrg schedtune_target_nrg;
-extern bool schedtune_initialized;
-/*
- * System energy normalization
- * Returns the normalized value, in the range [0..SCHED_CAPACITY_SCALE],
- * corresponding to the specified energy variation.
- */
-static inline int
-normalize_energy(int energy_diff)
-{
- u32 normalized_nrg;
-
- /* during early setup, we don't know the extents */
- if (unlikely(!schedtune_initialized))
- return energy_diff < 0 ? -1 : 1 ;
-
-#ifdef CONFIG_SCHED_DEBUG
- {
- int max_delta;
-
- /* Check for boundaries */
- max_delta = schedtune_target_nrg.max_power;
- max_delta -= schedtune_target_nrg.min_power;
- WARN_ON(abs(energy_diff) >= max_delta);
+ trace_sched_energy_diff(eenv->p, eenv->cpu[EAS_CPU_PRV].cpu_id,
+ eenv->cpu[EAS_CPU_PRV].energy,
+ eenv->cpu[EAS_CPU_NXT].cpu_id,
+ eenv->cpu[EAS_CPU_NXT].energy,
+ eenv->cpu[EAS_CPU_BKP].cpu_id,
+ eenv->cpu[EAS_CPU_BKP].energy);
+ /*
+ * Compare the other CPU candidates to find a CPU which can be
+ * more energy efficient then EAS_CPU_PRV
+ */
+ for (cpu_idx = EAS_CPU_NXT; cpu_idx < EAS_CPU_CNT; ++cpu_idx) {
+ /* Skip not valid scheduled candidates */
+ if (eenv->cpu[cpu_idx].cpu_id < 0)
+ continue;
+ /* Compute energy delta wrt EAS_CPU_PRV */
+ eenv->cpu[cpu_idx].nrg_delta =
+ eenv->cpu[cpu_idx].energy -
+ eenv->cpu[EAS_CPU_PRV].energy;
+ /* filter energy variations within the dead-zone margin */
+ if (abs(eenv->cpu[cpu_idx].nrg_delta) < margin)
+ eenv->cpu[cpu_idx].nrg_delta = 0;
+ /* update the schedule candidate with min(nrg_delta) */
+ if (eenv->cpu[cpu_idx].nrg_delta <
+ eenv->cpu[eenv->next_idx].nrg_delta) {
+ eenv->next_idx = cpu_idx;
+ if (sched_feat(FBT_STRICT_ORDER))
+ break;
+ }
}
-#endif
- /* Do scaling using positive numbers to increase the range */
- normalized_nrg = (energy_diff < 0) ? -energy_diff : energy_diff;
-
- /* Scale by energy magnitude */
- normalized_nrg <<= SCHED_CAPACITY_SHIFT;
-
- /* Normalize on max energy for target platform */
- normalized_nrg = reciprocal_divide(
- normalized_nrg, schedtune_target_nrg.rdiv);
-
- return (energy_diff < 0) ? -normalized_nrg : normalized_nrg;
+ return eenv->next_idx;
}
-static inline int
-energy_diff(struct energy_env *eenv)
-{
- int boost = schedtune_task_boost(eenv->task);
- int nrg_delta;
-
- /* Conpute "absolute" energy diff */
- __energy_diff(eenv);
-
- /* Return energy diff when boost margin is 0 */
- if (boost == 0)
- return eenv->nrg.diff;
-
- /* Compute normalized energy diff */
- nrg_delta = normalize_energy(eenv->nrg.diff);
- eenv->nrg.delta = nrg_delta;
-
- eenv->payoff = schedtune_accept_deltas(
- eenv->nrg.delta,
- eenv->cap.delta,
- eenv->task);
-
- trace_sched_energy_diff(eenv->task,
- eenv->src_cpu, eenv->dst_cpu, eenv->util_delta,
- eenv->nrg.before, eenv->nrg.after, eenv->nrg.diff,
- eenv->cap.before, eenv->cap.after, eenv->cap.delta,
- eenv->nrg.delta, eenv->payoff);
-
- /*
- * When SchedTune is enabled, the energy_diff() function will return
- * the computed energy payoff value. Since the energy_diff() return
- * value is expected to be negative by its callers, this evaluation
- * function return a negative value each time the evaluation return a
- * positive payoff, which is the condition for the acceptance of
- * a scheduling decision
- */
- return -eenv->payoff;
-}
-#else /* CONFIG_SCHED_TUNE */
-#define energy_diff(eenv) __energy_diff(eenv)
-#endif
-
/*
* Detect M:N waker/wakee relationships via a switching-frequency heuristic.
*
@@ -6203,7 +6121,7 @@
return 1;
}
-static inline unsigned long boosted_task_util(struct task_struct *task);
+static inline unsigned long boosted_task_util(struct task_struct *p);
static inline bool __task_fits(struct task_struct *p, int cpu, int util)
{
@@ -6234,20 +6152,14 @@
return __task_fits(p, cpu, 0);
}
-static inline bool task_fits_spare(struct task_struct *p, int cpu)
+bool __cpu_overutilized(int cpu, int delta)
{
- return __task_fits(p, cpu, cpu_util(cpu));
-}
-
-bool __cpu_overutilized(int cpu, unsigned long util)
-{
- return (capacity_orig_of(cpu) * 1024 <
- util * sysctl_sched_capacity_margin);
+ return (capacity_of(cpu) * 1024) < ((cpu_util(cpu) + delta) * capacity_margin);
}
bool cpu_overutilized(int cpu)
{
- return __cpu_overutilized(cpu, cpu_util(cpu));
+ return __cpu_overutilized(cpu, 0);
}
#ifdef CONFIG_SCHED_TUNE
@@ -6292,16 +6204,16 @@
}
static inline long
-schedtune_task_margin(struct task_struct *task)
+schedtune_task_margin(struct task_struct *p)
{
- int boost = schedtune_task_boost(task);
+ int boost = schedtune_task_boost(p);
unsigned long util;
long margin;
if (boost == 0)
return 0;
- util = task_util(task);
+ util = task_util(p);
margin = schedtune_margin(util, boost);
return margin;
@@ -6316,7 +6228,7 @@
}
static inline int
-schedtune_task_margin(struct task_struct *task)
+schedtune_task_margin(struct task_struct *p)
{
return 0;
}
@@ -6324,9 +6236,9 @@
#endif /* CONFIG_SCHED_TUNE */
unsigned long
-boosted_cpu_util(int cpu)
+boosted_cpu_util(int cpu, struct sched_walt_cpu_load *walt_load)
{
- unsigned long util = cpu_util_freq(cpu, NULL);
+ unsigned long util = cpu_util_freq(cpu, walt_load);
long margin = schedtune_cpu_margin(util, cpu);
trace_sched_boost_cpu(cpu, util, margin);
@@ -6335,41 +6247,48 @@
}
static inline unsigned long
-boosted_task_util(struct task_struct *task)
+boosted_task_util(struct task_struct *p)
{
- unsigned long util = task_util(task);
- long margin = schedtune_task_margin(task);
+ unsigned long util = task_util(p);
+ long margin = schedtune_task_margin(p);
- trace_sched_boost_task(task, util, margin);
+ trace_sched_boost_task(p, util, margin);
return util + margin;
}
+static unsigned long capacity_spare_wake(int cpu, struct task_struct *p)
+{
+ return capacity_orig_of(cpu) - cpu_util_wake(cpu, p);
+}
+
/*
* find_idlest_group finds and returns the least busy CPU group within the
* domain.
+ *
+ * Assumes p is allowed on at least one CPU in sd.
*/
static struct sched_group *
find_idlest_group(struct sched_domain *sd, struct task_struct *p,
int this_cpu, int sd_flag)
{
struct sched_group *idlest = NULL, *group = sd->groups;
- struct sched_group *fit_group = NULL, *spare_group = NULL;
- unsigned long min_load = ULONG_MAX, this_load = 0;
- unsigned long fit_capacity = ULONG_MAX;
- unsigned long max_spare_capacity;
-
+ struct sched_group *most_spare_sg = NULL;
+ unsigned long min_runnable_load = ULONG_MAX;
+ unsigned long this_runnable_load = ULONG_MAX;
+ unsigned long min_avg_load = ULONG_MAX, this_avg_load = ULONG_MAX;
+ unsigned long most_spare = 0, this_spare = 0;
int load_idx = sd->forkexec_idx;
- int imbalance = 100 + (sd->imbalance_pct-100)/2;
-
- max_spare_capacity = sysctl_sched_capacity_margin -
- SCHED_CAPACITY_SCALE;
+ int imbalance_scale = 100 + (sd->imbalance_pct-100)/2;
+ unsigned long imbalance = scale_load_down(NICE_0_LOAD) *
+ (sd->imbalance_pct-100) / 100;
if (sd_flag & SD_BALANCE_WAKE)
load_idx = sd->wake_idx;
do {
- unsigned long load, avg_load, spare_capacity;
+ unsigned long load, avg_load, runnable_load;
+ unsigned long spare_cap, max_spare_cap;
int local_group;
int i;
@@ -6381,8 +6300,13 @@
local_group = cpumask_test_cpu(this_cpu,
sched_group_cpus(group));
- /* Tally up the load of all CPUs in the group */
+ /*
+ * Tally up the load of all CPUs in the group and find
+ * the group containing the CPU with most spare capacity.
+ */
avg_load = 0;
+ runnable_load = 0;
+ max_spare_cap = 0;
for_each_cpu(i, sched_group_cpus(group)) {
/* Bias balancing toward cpus of our domain */
@@ -6391,55 +6315,85 @@
else
load = target_load(i, load_idx);
- avg_load += load;
+ runnable_load += load;
- /*
- * Look for most energy-efficient group that can fit
- * that can fit the task.
- */
- if (capacity_of(i) < fit_capacity && task_fits_spare(p, i)) {
- fit_capacity = capacity_of(i);
- fit_group = group;
- }
+ avg_load += cfs_rq_load_avg(&cpu_rq(i)->cfs);
- /*
- * Look for group which has most spare capacity on a
- * single cpu.
- */
- spare_capacity = capacity_of(i) - cpu_util(i);
- if (spare_capacity > max_spare_capacity) {
- max_spare_capacity = spare_capacity;
- spare_group = group;
- }
+ spare_cap = capacity_spare_wake(i, p);
+
+ if (spare_cap > max_spare_cap)
+ max_spare_cap = spare_cap;
}
/* Adjust by relative CPU capacity of the group */
- avg_load = (avg_load * SCHED_CAPACITY_SCALE) / group->sgc->capacity;
+ avg_load = (avg_load * SCHED_CAPACITY_SCALE) /
+ group->sgc->capacity;
+ runnable_load = (runnable_load * SCHED_CAPACITY_SCALE) /
+ group->sgc->capacity;
if (local_group) {
- this_load = avg_load;
- } else if (avg_load < min_load) {
- min_load = avg_load;
- idlest = group;
+ this_runnable_load = runnable_load;
+ this_avg_load = avg_load;
+ this_spare = max_spare_cap;
+ } else {
+ if (min_runnable_load > (runnable_load + imbalance)) {
+ /*
+ * The runnable load is significantly smaller
+ * so we can pick this new cpu
+ */
+ min_runnable_load = runnable_load;
+ min_avg_load = avg_load;
+ idlest = group;
+ } else if ((runnable_load < (min_runnable_load + imbalance)) &&
+ (100*min_avg_load > imbalance_scale*avg_load)) {
+ /*
+ * The runnable loads are close so we take
+ * into account blocked load through avg_load
+ * which is blocked + runnable load
+ */
+ min_avg_load = avg_load;
+ idlest = group;
+ }
+
+ if (most_spare < max_spare_cap) {
+ most_spare = max_spare_cap;
+ most_spare_sg = group;
+ }
}
} while (group = group->next, group != sd->groups);
- if (fit_group)
- return fit_group;
+ /*
+ * The cross-over point between using spare capacity or least load
+ * is too conservative for high utilization tasks on partially
+ * utilized systems if we require spare_capacity > task_util(p),
+ * so we allow for some task stuffing by using
+ * spare_capacity > task_util(p)/2.
+ * spare capacity can't be used for fork because the utilization has
+ * not been set yet as it need to get a rq to init the utilization
+ */
+ if (sd_flag & SD_BALANCE_FORK)
+ goto skip_spare;
- if (spare_group)
- return spare_group;
+ if (this_spare > task_util(p) / 2 &&
+ imbalance_scale*this_spare > 100*most_spare)
+ return NULL;
+ else if (most_spare > task_util(p) / 2)
+ return most_spare_sg;
- if (!idlest || 100*this_load < imbalance*min_load)
+skip_spare:
+ if (!idlest ||
+ (min_runnable_load > (this_runnable_load + imbalance)) ||
+ ((this_runnable_load < (min_runnable_load + imbalance)) &&
+ (100*this_avg_load < imbalance_scale*min_avg_load)))
return NULL;
return idlest;
}
/*
- * find_idlest_cpu - find the idlest cpu among the cpus in group.
+ * find_idlest_group_cpu - find the idlest cpu among the cpus in group.
*/
static int
-find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
+find_idlest_group_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
{
unsigned long load, min_load = ULONG_MAX;
unsigned int min_exit_latency = UINT_MAX;
@@ -6454,7 +6408,7 @@
/* Traverse only the allowed CPUs */
for_each_cpu_and(i, sched_group_cpus(group), tsk_cpus_allowed(p)) {
- if (task_fits_spare(p, i)) {
+ if (idle_cpu(i)) {
struct rq *rq = cpu_rq(i);
struct cpuidle_state *idle = idle_get_state(rq);
if (idle && idle->exit_latency < min_exit_latency) {
@@ -6466,8 +6420,7 @@
min_exit_latency = idle->exit_latency;
latest_idle_timestamp = rq->idle_stamp;
shallowest_idle_cpu = i;
- } else if (idle_cpu(i) &&
- (!idle || idle->exit_latency == min_exit_latency) &&
+ } else if ((!idle || idle->exit_latency == min_exit_latency) &&
rq->idle_stamp > latest_idle_timestamp) {
/*
* If equal or no active idle state, then
@@ -6476,13 +6429,6 @@
*/
latest_idle_timestamp = rq->idle_stamp;
shallowest_idle_cpu = i;
- } else if (shallowest_idle_cpu == -1) {
- /*
- * If we haven't found an idle CPU yet
- * pick a non-idle one that can fit the task as
- * fallback.
- */
- shallowest_idle_cpu = i;
}
} else if (shallowest_idle_cpu == -1) {
load = weighted_cpuload(i);
@@ -6496,6 +6442,68 @@
return shallowest_idle_cpu != -1 ? shallowest_idle_cpu : least_loaded_cpu;
}
+static inline int find_idlest_cpu(struct sched_domain *sd, struct task_struct *p,
+ int cpu, int prev_cpu, int sd_flag)
+{
+ int wu = sd_flag & SD_BALANCE_WAKE;
+ int cas_cpu = -1;
+ int new_cpu = cpu;
+
+ if (wu) {
+ schedstat_inc(p->se.statistics.nr_wakeups_cas_attempts);
+ schedstat_inc(this_rq()->eas_stats.cas_attempts);
+ }
+
+ if (!cpumask_intersects(sched_domain_span(sd), &p->cpus_allowed))
+ return prev_cpu;
+
+ while (sd) {
+ struct sched_group *group;
+ struct sched_domain *tmp;
+ int weight;
+
+ if (wu)
+ schedstat_inc(sd->eas_stats.cas_attempts);
+
+ if (!(sd->flags & sd_flag)) {
+ sd = sd->child;
+ continue;
+ }
+
+ group = find_idlest_group(sd, p, cpu, sd_flag);
+ if (!group) {
+ sd = sd->child;
+ continue;
+ }
+
+ new_cpu = find_idlest_group_cpu(group, p, cpu);
+ if (new_cpu == cpu) {
+ /* Now try balancing at a lower domain level of cpu */
+ sd = sd->child;
+ continue;
+ }
+
+ /* Now try balancing at a lower domain level of new_cpu */
+ cpu = cas_cpu = new_cpu;
+ weight = sd->span_weight;
+ sd = NULL;
+ for_each_domain(cpu, tmp) {
+ if (weight <= tmp->span_weight)
+ break;
+ if (tmp->flags & sd_flag)
+ sd = tmp;
+ }
+ /* while loop will break here if sd == NULL */
+ }
+
+ if (wu && (cas_cpu >= 0)) {
+ schedstat_inc(p->se.statistics.nr_wakeups_cas_count);
+ schedstat_inc(this_rq()->eas_stats.cas_count);
+ }
+
+ return new_cpu;
+}
+
#ifdef CONFIG_SCHED_SMT
static inline void set_idle_cores(int cpu, int val)
@@ -6571,7 +6579,7 @@
idle = false;
}
- if (!cpu_isolated(cpu) && idle)
+ if (idle)
return core;
}
@@ -6593,8 +6601,6 @@
for_each_cpu(cpu, cpu_smt_mask(target)) {
if (!cpumask_test_cpu(cpu, tsk_cpus_allowed(p)))
continue;
- if (cpu_isolated(cpu))
- continue;
if (idle_cpu(cpu))
return cpu;
}
@@ -6647,8 +6653,6 @@
for_each_cpu_wrap(cpu, sched_domain_span(sd), target) {
if (!cpumask_test_cpu(cpu, tsk_cpus_allowed(p)))
continue;
- if (cpu_isolated(cpu))
- continue;
if (idle_cpu(cpu))
break;
}
@@ -6677,7 +6681,7 @@
schedstat_inc(this_rq()->eas_stats.sis_attempts);
if (!sysctl_sched_cstate_aware) {
- if (idle_cpu(target) && !cpu_isolated(target)) {
+ if (idle_cpu(target)) {
schedstat_inc(p->se.statistics.nr_wakeups_sis_idle);
schedstat_inc(this_rq()->eas_stats.sis_idle);
return target;
@@ -6686,8 +6690,7 @@
/*
* If the prevous cpu is cache affine and idle, don't be stupid.
*/
- if (i != target && cpus_share_cache(i, target) &&
- idle_cpu(i) && !cpu_isolated(i)) {
+ if (i != target && cpus_share_cache(i, target) && idle_cpu(i)) {
schedstat_inc(p->se.statistics.nr_wakeups_sis_cache_affine);
schedstat_inc(this_rq()->eas_stats.sis_cache_affine);
return i;
@@ -6728,9 +6731,6 @@
unsigned long new_usage = boosted_task_util(p);
unsigned long capacity_orig = capacity_orig_of(i);
- if (cpu_isolated(i))
- continue;
-
if (new_usage > capacity_orig || !idle_cpu(i))
goto next;
@@ -6750,9 +6750,6 @@
}
} else {
for_each_cpu(i, sched_group_cpus(sg)) {
- if (cpu_isolated(i))
- continue;
-
if (i == target || !idle_cpu(i))
goto next;
}
@@ -6780,463 +6777,654 @@
}
/*
- * Should task be woken to any available idle cpu?
- *
- * Waking tasks to idle cpu has mixed implications on both performance and
- * power. In many cases, scheduler can't estimate correctly impact of using idle
- * cpus on either performance or power. PF_WAKE_UP_IDLE allows external kernel
- * module to pass a strong hint to scheduler that the task in question should be
- * woken to idle cpu, generally to improve performance.
+ * cpu_util_wake: Compute cpu utilization with any contributions from
+ * the waking task p removed. check_for_migration() looks for a better CPU of
+ * rq->curr. For that case we should return cpu util with contributions from
+ * currently running task p removed.
*/
+static int cpu_util_wake(int cpu, struct task_struct *p)
+{
+ unsigned long util, capacity;
+
+#ifdef CONFIG_SCHED_WALT
+ /*
+ * WALT does not decay idle tasks in the same manner
+ * as PELT, so it makes little sense to subtract task
+ * utilization from cpu utilization. Instead just use
+ * cpu_util for this case.
+ */
+ if (!walt_disabled && sysctl_sched_use_walt_cpu_util &&
+ p->state == TASK_WAKING)
+ return cpu_util(cpu);
+#endif
+ /* Task has no contribution or is new */
+ if (cpu != task_cpu(p) || !p->se.avg.last_update_time)
+ return cpu_util(cpu);
+
+ capacity = capacity_orig_of(cpu);
+ util = max_t(long, cpu_util(cpu) - task_util(p), 0);
+
+ return (util >= capacity) ? capacity : util;
+}
+
+struct find_best_target_env {
+ struct cpumask *rtg_target;
+ bool need_idle;
+ bool placement_boost;
+ bool avoid_prev_cpu;
+};
+
+static bool is_packing_eligible(struct task_struct *p, int target_cpu,
+ struct find_best_target_env *fbt_env,
+ unsigned int target_cpus_count)
+{
+ unsigned long tutil, estimated_capacity;
+
+ if (fbt_env->placement_boost || fbt_env->need_idle)
+ return false;
+
+ if (target_cpus_count != 1)
+ return true;
+
+ if (task_in_cum_window_demand(cpu_rq(target_cpu), p))
+ tutil = 0;
+ else
+ tutil = task_util(p);
+
+ estimated_capacity = cpu_util_cum(target_cpu, tutil);
+ estimated_capacity = add_capacity_margin(estimated_capacity,
+ target_cpu);
+
+ /*
+ * If there is only one active CPU and it is already above its current
+ * capacity, avoid placing additional task on the CPU.
+ */
+ return (estimated_capacity <= capacity_curr_of(target_cpu));
+}
+
+static inline bool skip_sg(struct task_struct *p, struct sched_group *sg,
+ struct cpumask *rtg_target)
+{
+ int fcpu = group_first_cpu(sg);
+
+ /* Are all CPUs isolated in this group? */
+ if (!sg->group_weight)
+ return true;
+
+ if (!task_fits_max(p, fcpu))
+ return true;
+
+ if (rtg_target && !cpumask_test_cpu(fcpu, rtg_target))
+ return true;
+
+ return false;
+}
+
+static int start_cpu(bool boosted)
+{
+ struct root_domain *rd = cpu_rq(smp_processor_id())->rd;
+ int start_cpu;
+
+ start_cpu = boosted ? rd->max_cap_orig_cpu : rd->min_cap_orig_cpu;
+
+ return walt_start_cpu(start_cpu);
+}
+
+static inline int find_best_target(struct task_struct *p, int *backup_cpu,
+ bool boosted, bool prefer_idle,
+ struct find_best_target_env *fbt_env)
+{
+ unsigned long min_util = boosted_task_util(p);
+ unsigned long target_capacity = ULONG_MAX;
+ unsigned long min_wake_util = ULONG_MAX;
+ unsigned long target_max_spare_cap = 0;
+ unsigned long target_util = ULONG_MAX;
+ unsigned long best_active_util = ULONG_MAX;
+ unsigned long target_idle_max_spare_cap = 0;
+ int best_idle_cstate = INT_MAX;
+ struct sched_domain *sd;
+ struct sched_group *sg;
+ int best_active_cpu = -1;
+ int best_idle_cpu = -1;
+ int target_cpu = -1;
+ int cpu, i;
+ unsigned int active_cpus_count = 0;
+
+ *backup_cpu = -1;
+
+ schedstat_inc(p->se.statistics.nr_wakeups_fbt_attempts);
+ schedstat_inc(this_rq()->eas_stats.fbt_attempts);
+
+ /* Find start CPU based on boost value */
+ cpu = start_cpu(boosted);
+ if (cpu < 0) {
+ schedstat_inc(p->se.statistics.nr_wakeups_fbt_no_cpu);
+ schedstat_inc(this_rq()->eas_stats.fbt_no_cpu);
+ return -1;
+ }
+
+ /* Find SD for the start CPU */
+ sd = rcu_dereference(per_cpu(sd_ea, cpu));
+ if (!sd) {
+ schedstat_inc(p->se.statistics.nr_wakeups_fbt_no_sd);
+ schedstat_inc(this_rq()->eas_stats.fbt_no_sd);
+ return -1;
+ }
+
+ /* Scan CPUs in all SDs */
+ sg = sd->groups;
+ do {
+ cpumask_t search_cpus;
+ bool do_rotate = false, avoid_prev_cpu = false;
+
+ if (skip_sg(p, sg, fbt_env->rtg_target))
+ continue;
+
+ cpumask_copy(&search_cpus, tsk_cpus_allowed(p));
+ cpumask_and(&search_cpus, &search_cpus, sched_group_cpus(sg));
+ i = find_first_cpu_bit(p, &search_cpus, sg, &avoid_prev_cpu,
+ &do_rotate, &first_cpu_bit_env);
+ if (do_rotate)
+ fbt_env->avoid_prev_cpu = avoid_prev_cpu;
+
+retry:
+ while ((i = cpumask_next(i, &search_cpus)) < nr_cpu_ids) {
+ unsigned long capacity_curr = capacity_curr_of(i);
+ unsigned long capacity_orig = capacity_orig_of(i);
+ unsigned long wake_util, new_util, min_capped_util;
+
+ cpumask_clear_cpu(i, &search_cpus);
+ if (avoid_prev_cpu && i == task_cpu(p))
+ continue;
+
+ if (!cpu_online(i) || cpu_isolated(i) || is_reserved(i))
+ continue;
+
+ if (walt_cpu_high_irqload(i))
+ continue;
+
+ trace_sched_cpu_util(i);
+
+ /*
+ * p's blocked utilization is still accounted for on prev_cpu
+ * so prev_cpu will receive a negative bias due to the double
+ * accounting. However, the blocked utilization may be zero.
+ */
+ wake_util = cpu_util_wake(i, p);
+ new_util = wake_util + task_util(p);
+
+ /*
+ * Ensure minimum capacity to grant the required boost.
+ * The target CPU can be already at a capacity level higher
+ * than the one required to boost the task.
+ */
+ new_util = max(min_util, new_util);
+
+ /*
+ * Include minimum capacity constraint:
+ * new_util contains the required utilization including
+ * boost. min_capped_util also takes into account a
+ * minimum capacity cap imposed on the CPU by external
+ * actors.
+ */
+ min_capped_util = max(new_util, capacity_min_of(i));
+
+ if (new_util > capacity_orig)
+ continue;
+
+ /*
+ * Case A) Latency sensitive tasks
+ *
+ * Unconditionally favoring tasks that prefer idle CPU to
+ * improve latency.
+ *
+ * Looking for:
+ * - an idle CPU, whatever its idle_state is, since
+ * the first CPUs we explore are more likely to be
+ * reserved for latency sensitive tasks.
+ * - a non idle CPU where the task fits in its current
+ * capacity and has the maximum spare capacity.
+ * - a non idle CPU with lower contention from other
+ * tasks and running at the lowest possible OPP.
+ *
+ * The last two goals tries to favor a non idle CPU
+ * where the task can run as if it is "almost alone".
+ * A maximum spare capacity CPU is favoured since
+ * the task already fits into that CPU's capacity
+ * without waiting for an OPP chance.
+ *
+ * The following code path is the only one in the CPUs
+ * exploration loop which is always used by
+ * prefer_idle tasks. It exits the loop with wither a
+ * best_active_cpu or a target_cpu which should
+ * represent an optimal choice for latency sensitive
+ * tasks.
+ */
+ if (prefer_idle) {
+
+ /*
+ * Case A.1: IDLE CPU
+ * Return the first IDLE CPU we find.
+ */
+ if (idle_cpu(i)) {
+ schedstat_inc(p->se.statistics.nr_wakeups_fbt_pref_idle);
+ schedstat_inc(this_rq()->eas_stats.fbt_pref_idle);
+
+ trace_sched_find_best_target(p,
+ prefer_idle, min_util,
+ cpu, best_idle_cpu,
+ best_active_cpu, i);
+
+ return i;
+ }
+
+ /*
+ * Case A.2: Target ACTIVE CPU
+ * Favor CPUs with max spare capacity.
+ */
+ if ((capacity_curr > new_util) &&
+ (capacity_orig - new_util > target_max_spare_cap)) {
+ target_max_spare_cap = capacity_orig - new_util;
+ target_cpu = i;
+ continue;
+ }
+ if (target_cpu != -1)
+ continue;
+
+
+ /*
+ * Case A.3: Backup ACTIVE CPU
+ * Favor CPUs with:
+ * - lower utilization due to other tasks
+ * - lower utilization with the task in
+ */
+ if (wake_util > min_wake_util)
+ continue;
+ if (new_util > best_active_util)
+ continue;
+ min_wake_util = wake_util;
+ best_active_util = new_util;
+ best_active_cpu = i;
+ continue;
+ }
+
+ /*
+ * Favor CPUs with smaller capacity for Non latency
+ * sensitive tasks.
+ */
+ if (capacity_orig > target_capacity)
+ continue;
+
+ /*
+ * Case B) Non latency sensitive tasks on IDLE CPUs.
+ *
+ * Find an optimal backup IDLE CPU for non latency
+ * sensitive tasks.
+ *
+ * Looking for:
+ * - minimizing the capacity_orig,
+ * i.e. preferring LITTLE CPUs
+ * - favoring shallowest idle states
+ * i.e. avoid to wakeup deep-idle CPUs
+ *
+ * The following code path is used by non latency
+ * sensitive tasks if IDLE CPUs are available. If at
+ * least one of such CPUs are available it sets the
+ * best_idle_cpu to the most suitable idle CPU to be
+ * selected.
+ *
+ * If idle CPUs are available, favour these CPUs to
+ * improve performances by spreading tasks.
+ * Indeed, the energy_diff() computed by the caller
+ * will take care to ensure the minimization of energy
+ * consumptions without affecting performance.
+ */
+ if (idle_cpu(i)) {
+ int idle_idx = idle_get_state_idx(cpu_rq(i));
+
+ /* Favor CPUs that won't end up running at a
+ * high OPP.
+ */
+ if ((capacity_orig - min_capped_util) <
+ target_idle_max_spare_cap)
+ continue;
+
+ /*
+ * Skip CPUs in deeper idle state, but only
+ * if they are also less energy efficient.
+ * IOW, prefer a deep IDLE LITTLE CPU vs a
+ * shallow idle big CPU.
+ */
+ if (sysctl_sched_cstate_aware &&
+ best_idle_cstate <= idle_idx)
+ continue;
+
+ /* Keep track of best idle CPU */
+ target_capacity = capacity_orig;
+ target_idle_max_spare_cap = capacity_orig -
+ min_capped_util;
+ best_idle_cstate = idle_idx;
+ best_idle_cpu = i;
+ continue;
+ }
+
+ /*
+ * Case C) Non latency sensitive tasks on ACTIVE CPUs.
+ *
+ * Pack tasks in the most energy efficient capacities.
+ *
+ * This task packing strategy prefers more energy
+ * efficient CPUs (i.e. pack on smaller maximum
+ * capacity CPUs) while also trying to spread tasks to
+ * run them all at the lower OPP.
+ *
+ * This assumes for example that it's more energy
+ * efficient to run two tasks on two CPUs at a lower
+ * OPP than packing both on a single CPU but running
+ * that CPU at an higher OPP.
+ *
+ * Thus, this case keep track of the CPU with the
+ * smallest maximum capacity and highest spare maximum
+ * capacity.
+ */
+
+ active_cpus_count++;
+
+ /* Favor CPUs with maximum spare capacity */
+ if ((capacity_orig - min_capped_util) <
+ target_max_spare_cap)
+ continue;
+
+ target_max_spare_cap = capacity_orig - min_capped_util;
+ target_capacity = capacity_orig;
+ target_util = new_util;
+ target_cpu = i;
+ }
+
+ if (do_rotate) {
+ /*
+ * We started iteration somewhere in the middle of
+ * cpumask. Iterate once again from bit 0 to the
+ * previous starting point bit.
+ */
+ do_rotate = false;
+ i = -1;
+ goto retry;
+ }
+
+ if (!sysctl_sched_is_big_little && !prefer_idle) {
+
+ /*
+ * If we find an idle CPU in the primary cluster,
+ * stop the search. We select this idle CPU or
+ * the active CPU (if there is one), whichever
+ * saves the energy.
+ */
+ if (best_idle_cpu != -1)
+ break;
+
+ if (fbt_env->placement_boost) {
+ target_capacity = ULONG_MAX;
+ continue;
+ }
+
+ /*
+ * If we found an active CPU and its utilization
+ * is below the minimum packing threshold (overlap),
+ * no need to search further. Otherwise reset
+ * the target_capacity and continue the search.
+ */
+ if (target_cpu != -1 && target_util <
+ sched_smp_overlap_capacity)
+ break;
+
+ target_capacity = ULONG_MAX;
+ }
+ } while (sg = sg->next, sg != sd->groups);
+
+ if (best_idle_cpu != -1 && !is_packing_eligible(p, target_cpu, fbt_env,
+ active_cpus_count)) {
+ if (target_cpu == task_cpu(p))
+ fbt_env->avoid_prev_cpu = true;
+
+ target_cpu = best_idle_cpu;
+ best_idle_cpu = -1;
+ }
+
+ /*
+ * For non latency sensitive tasks, cases B and C in the previous loop,
+ * we pick the best IDLE CPU only if we was not able to find a target
+ * ACTIVE CPU.
+ *
+ * Policies priorities:
+ *
+ * - prefer_idle tasks:
+ *
+ * a) IDLE CPU available, we return immediately
+ * b) ACTIVE CPU where task fits and has the bigger maximum spare
+ * capacity (i.e. target_cpu)
+ * c) ACTIVE CPU with less contention due to other tasks
+ * (i.e. best_active_cpu)
+ *
+ * - NON prefer_idle tasks:
+ *
+ * a) ACTIVE CPU: target_cpu
+ * b) IDLE CPU: best_idle_cpu
+ */
+ if (target_cpu == -1)
+ target_cpu = prefer_idle
+ ? best_active_cpu
+ : best_idle_cpu;
+ else
+ *backup_cpu = prefer_idle
+ ? best_active_cpu
+ : best_idle_cpu;
+
+ trace_sched_find_best_target(p, prefer_idle, min_util, cpu,
+ best_idle_cpu, best_active_cpu,
+ target_cpu);
+
+ schedstat_inc(p->se.statistics.nr_wakeups_fbt_count);
+ schedstat_inc(this_rq()->eas_stats.fbt_count);
+
+ return target_cpu;
+}
+
+/*
+ * Disable WAKE_AFFINE in the case where task @p doesn't fit in the
+ * capacity of either the waking CPU @cpu or the previous CPU @prev_cpu.
+ *
+ * In that case WAKE_AFFINE doesn't make sense and we'll let
+ * BALANCE_WAKE sort things out.
+ */
+static int wake_cap(struct task_struct *p, int cpu, int prev_cpu)
+{
+ long min_cap, max_cap;
+ min_cap = min(capacity_orig_of(prev_cpu), capacity_orig_of(cpu));
+ max_cap = cpu_rq(cpu)->rd->max_cpu_capacity.val;
+ /* Minimum capacity is close to max, no need to abort wake_affine */
+ if (max_cap - min_cap < max_cap >> 3)
+ return 0;
+
+ /* Bring task utilization in sync with prev_cpu */
+ sync_entity_load_avg(&p->se);
+
+ return min_cap * 1024 < task_util(p) * capacity_margin;
+}
+
static inline int wake_to_idle(struct task_struct *p)
{
return (current->flags & PF_WAKE_UP_IDLE) ||
(p->flags & PF_WAKE_UP_IDLE);
}
-static bool
-is_packing_eligible(struct task_struct *p, unsigned long task_util,
- struct sched_group *sg_target,
- unsigned long target_cpu_new_util_cum,
- int targeted_cpus)
+static inline bool
+bias_to_waker_cpu(struct task_struct *p, int cpu, struct cpumask *rtg_target)
{
- int cpu_cap_idx_pack, cpu_cap_idx_spread, cap_idx0, cap_idx1;
+ int rtg_target_cpu = rtg_target ? cpumask_first(rtg_target) : cpu;
- if (targeted_cpus > 1)
- /*
- * More than one CPUs were evaulated and target_cpu is the
- * least loaded CPU among the CPUs. Thus target_cpu won't
- * raise OPP.
- */
- return true;
-
- /*
- * There is only one CPU out of C-state.
- *
- * cpu_cap_idx_pack contains estimated OPP index of target_cpu when we
- * pack the new task onto the target_cpu.
- * cap_idx0 and cap_idx1 contain OPP indices of two CPUs, one for
- * target_cpu without new task's load, one other for new idle CPU with
- * task's load.
- *
- * Pack : Spread :
- * cap_idx_pack is new OPP. max(cap_idx0, cap_idx1) is new OPP.
- * ________________ ________________
- * | | | | ______________
- * | cap_idx_pack | | cap_idx0 | | cap_idx1 |
- * | (target_cpu) | | (target_cpu) | | (idle cpu) |
- * ---------------- ---------------- --------------
- *
- * The target_cpu's current capacity can be much more than target_cpu's
- * current utilization due to for example hysteresis while task
- * migration. In that the case, packing onto the target_cpu based on
- * current capacity would deprive chance to lower the OPP and will end
- * up making target_cpu to keep the higher OOP longer than spreading.
- *
- * Try task packing only when packing won't make to keep the current
- * OPP longer than wihout packing.
- */
-
- cpu_cap_idx_pack = __find_new_capacity(target_cpu_new_util_cum,
- sg_target->sge);
-
- cap_idx0 = __find_new_capacity(target_cpu_new_util_cum - task_util,
- sg_target->sge);
- cap_idx1 = __find_new_capacity(task_util, sg_target->sge);
-
- cpu_cap_idx_spread = max(cap_idx0, cap_idx1);
-
- trace_sched_energy_diff_packing(p, task_util, targeted_cpus,
- cpu_cap_idx_pack, cpu_cap_idx_spread);
-
- return cpu_cap_idx_pack == cpu_cap_idx_spread;
+ return cpumask_test_cpu(cpu, tsk_cpus_allowed(p)) &&
+ cpu_active(cpu) && !cpu_isolated(cpu) &&
+ capacity_orig_of(cpu) >= capacity_orig_of(rtg_target_cpu) &&
+ task_fits_max(p, cpu);
}
-unsigned int sched_smp_overlap_capacity = SCHED_CAPACITY_SCALE;
-
-static int energy_aware_wake_cpu(struct task_struct *p, int target, int sync)
+static inline struct cpumask *find_rtg_target(struct task_struct *p)
{
- struct sched_domain *sd;
- struct sched_group *sg, *sg_target, *start_sg;
- int target_max_cap = INT_MAX;
- int target_cpu = -1, targeted_cpus = 0;
- unsigned long task_util_boosted = 0, curr_util = 0;
- long new_util, new_util_cum;
- int i;
- int ediff = -1;
- int cpu = smp_processor_id();
- int min_util_cpu = -1;
- int min_util_cpu_idle_idx = INT_MAX;
- long min_util_cpu_util_cum = LONG_MAX;
- unsigned int min_util = UINT_MAX;
- int cpu_idle_idx;
- int min_idle_idx_cpu;
- int min_idle_idx = INT_MAX;
- bool safe_to_pack = false;
- unsigned int target_cpu_util = UINT_MAX;
- long target_cpu_new_util_cum = LONG_MAX;
- struct cpumask *rtg_target = NULL;
- int isolated_candidate = -1;
- bool need_idle;
- enum sched_boost_policy placement_boost = task_sched_boost(p) ?
- sched_boost_policy() : SCHED_BOOST_NONE;
struct related_thread_group *grp;
- cpumask_t search_cpus;
- int prev_cpu = task_cpu(p);
- int start_cpu = walt_start_cpu(prev_cpu);
- bool do_rotate = false;
- bool avoid_prev_cpu = false;
+ struct cpumask *rtg_target;
- sd = rcu_dereference(per_cpu(sd_ea, start_cpu));
+ rcu_read_lock();
- if (!sd)
- return target;
-
- sg = sd->groups;
- sg_target = sg;
-
- sync = sync && sysctl_sched_sync_hint_enable;
-
- curr_util = boosted_task_util(cpu_rq(cpu)->curr);
-
- need_idle = wake_to_idle(p) || schedtune_prefer_idle(p);
- if (need_idle)
- sync = 0;
grp = task_related_thread_group(p);
- if (grp && grp->preferred_cluster)
+ if (grp && grp->preferred_cluster) {
rtg_target = &grp->preferred_cluster->cpus;
-
- if (sync && bias_to_waker_cpu(p, cpu, rtg_target)) {
- trace_sched_task_util_bias_to_waker(p, prev_cpu,
- task_util(p), cpu, cpu, 0, need_idle);
- return cpu;
+ if (!task_fits_max(p, cpumask_first(rtg_target)))
+ rtg_target = NULL;
+ } else {
+ rtg_target = NULL;
}
- task_util_boosted = boosted_task_util(p);
- if (sysctl_sched_is_big_little) {
- /*
- * Find group with sufficient capacity. We only get here if no cpu is
- * overutilized. We may end up overutilizing a cpu by adding the task,
- * but that should not be any worse than select_idle_sibling().
- * load_balance() should sort it out later as we get above the tipping
- * point.
- */
- do {
- int max_cap_cpu;
- cpumask_t avail_cpus;
+ rcu_read_unlock();
- /* Are all CPUs isolated in this group? */
- if (unlikely(!sg->group_weight))
- continue;
+ return rtg_target;
+}
- /* Can this task run on any CPUs of this group? */
- cpumask_and(&avail_cpus, sched_group_cpus(sg),
- tsk_cpus_allowed(p));
- cpumask_andnot(&avail_cpus, &avail_cpus,
- cpu_isolated_mask);
- if (cpumask_empty(&avail_cpus))
- continue;
+static int select_energy_cpu_brute(struct task_struct *p, int prev_cpu, int sync)
+{
+ bool boosted, prefer_idle;
+ struct sched_domain *sd;
+ int target_cpu;
+ int backup_cpu = -1;
+ int next_cpu = -1;
+ struct cpumask *rtg_target = find_rtg_target(p);
+ struct find_best_target_env fbt_env;
- /* Assuming all cpus are the same in group */
- max_cap_cpu = group_first_cpu(sg);
+ schedstat_inc(p->se.statistics.nr_wakeups_secb_attempts);
+ schedstat_inc(this_rq()->eas_stats.secb_attempts);
- /*
- * Assume smaller max capacity means more energy-efficient.
- * Ideally we should query the energy model for the right
- * answer but it easily ends up in an exhaustive search.
- */
- if (capacity_orig_of(max_cap_cpu) < target_max_cap &&
- task_fits_max(p, max_cap_cpu)) {
- sg_target = sg;
+#ifdef CONFIG_CGROUP_SCHEDTUNE
+ boosted = schedtune_task_boost(p) > 0;
+ prefer_idle = schedtune_prefer_idle(p) > 0;
+#else
+ boosted = get_sysctl_sched_cfs_boost() > 0;
+ prefer_idle = 0;
+#endif
- if (rtg_target) {
- /*
- * For tasks that belong to a related
- * thread group, select the preferred
- * cluster if the task can fit there,
- * otherwise select the cluster which
- * can fit the task.
- */
- if (cpumask_test_cpu(max_cap_cpu,
- rtg_target))
- break;
- continue;
- }
-
- target_max_cap = capacity_of(max_cap_cpu);
- }
- } while (sg = sg->next, sg != sd->groups);
+ fbt_env.rtg_target = rtg_target;
+ if (sched_feat(EAS_USE_NEED_IDLE) && prefer_idle) {
+ fbt_env.need_idle = true;
+ prefer_idle = false;
+ } else {
+ fbt_env.need_idle = wake_to_idle(p);
}
+ fbt_env.placement_boost = task_sched_boost(p) ?
+ sched_boost_policy() != SCHED_BOOST_NONE :
+ false;
+ fbt_env.avoid_prev_cpu = false;
- start_sg = sg_target;
-next_sg:
- cpumask_copy(&search_cpus, tsk_cpus_allowed(p));
- cpumask_and(&search_cpus, &search_cpus,
- sched_group_cpus(sg_target));
+ if (prefer_idle || fbt_env.need_idle)
+ sync = 0;
- i = find_first_cpu_bit(p, &search_cpus, sg_target,
- &avoid_prev_cpu, &do_rotate,
- &first_cpu_bit_env);
+ if (sysctl_sched_sync_hint_enable && sync) {
+ int cpu = smp_processor_id();
-retry:
- /* Find cpu with sufficient capacity */
- while ((i = cpumask_next(i, &search_cpus)) < nr_cpu_ids) {
- cpumask_clear_cpu(i, &search_cpus);
-
- if (cpu_isolated(i))
- continue;
-
- if (isolated_candidate == -1)
- isolated_candidate = i;
-
- if (avoid_prev_cpu && i == prev_cpu)
- continue;
-
- if (is_reserved(i))
- continue;
-
- if (sched_cpu_high_irqload(i))
- continue;
-
- /*
- * Since this code is inside sched_is_big_little,
- * we are going to assume that boost policy is
- * SCHED_BOOST_ON_BIG.
- */
- if (placement_boost != SCHED_BOOST_NONE) {
- new_util = cpu_util(i);
- if (new_util < min_util) {
- min_util_cpu = i;
- min_util = new_util;
- }
- continue;
- }
-
- /*
- * p's blocked utilization is still accounted for on prev_cpu
- * so prev_cpu will receive a negative bias due to the double
- * accounting. However, the blocked utilization may be zero.
- */
- new_util = cpu_util(i) + task_util_boosted;
-
- if (task_in_cum_window_demand(cpu_rq(i), p))
- new_util_cum = cpu_util_cum(i, 0) +
- task_util_boosted - task_util(p);
- else
- new_util_cum = cpu_util_cum(i, 0) +
- task_util_boosted;
-
- if (sync && i == cpu)
- new_util -= curr_util;
-
- trace_sched_cpu_util(p, i, task_util_boosted, curr_util,
- new_util_cum, sync);
-
- /*
- * Ensure minimum capacity to grant the required boost.
- * The target CPU can be already at a capacity level higher
- * than the one required to boost the task.
- */
- if (new_util > capacity_orig_of(i))
- continue;
-
- cpu_idle_idx = idle_get_state_idx(cpu_rq(i));
-
- if (!need_idle &&
- add_capacity_margin(new_util_cum, i) <
- capacity_curr_of(i)) {
- if (sysctl_sched_cstate_aware) {
- if (cpu_idle_idx < min_idle_idx) {
- min_idle_idx = cpu_idle_idx;
- min_idle_idx_cpu = i;
- target_cpu = i;
- target_cpu_util = new_util;
- target_cpu_new_util_cum =
- new_util_cum;
- targeted_cpus = 1;
- } else if (cpu_idle_idx ==
- min_idle_idx &&
- (target_cpu_util >
- new_util ||
- (target_cpu_util ==
- new_util &&
- (i == prev_cpu ||
- (target_cpu !=
- prev_cpu &&
- target_cpu_new_util_cum >
- new_util_cum))))) {
- min_idle_idx_cpu = i;
- target_cpu = i;
- target_cpu_util = new_util;
- target_cpu_new_util_cum =
- new_util_cum;
- targeted_cpus++;
- }
- } else if (cpu_rq(i)->nr_running) {
- target_cpu = i;
- do_rotate = false;
- break;
- }
- } else if (!need_idle) {
- /*
- * At least one CPU other than target_cpu is
- * going to raise CPU's OPP higher than current
- * because current CPU util is more than current
- * capacity + margin. We can safely do task
- * packing without worrying about doing such
- * itself raises OPP.
- */
- safe_to_pack = true;
- }
-
- /*
- * cpu has capacity at higher OPP, keep it as
- * fallback.
- */
- if (new_util < min_util) {
- min_util_cpu = i;
- min_util = new_util;
- min_util_cpu_idle_idx = cpu_idle_idx;
- min_util_cpu_util_cum = new_util_cum;
- } else if (sysctl_sched_cstate_aware &&
- min_util == new_util) {
- if (min_util_cpu == task_cpu(p))
- continue;
-
- if (i == task_cpu(p) ||
- (cpu_idle_idx < min_util_cpu_idle_idx ||
- (cpu_idle_idx == min_util_cpu_idle_idx &&
- min_util_cpu_util_cum > new_util_cum))) {
- min_util_cpu = i;
- min_util_cpu_idle_idx = cpu_idle_idx;
- min_util_cpu_util_cum = new_util_cum;
- }
+ if (bias_to_waker_cpu(p, cpu, rtg_target)) {
+ schedstat_inc(p->se.statistics.nr_wakeups_secb_sync);
+ schedstat_inc(this_rq()->eas_stats.secb_sync);
+ return cpu;
}
}
- if (do_rotate) {
- /*
- * We started iteration somewhere in the middle of
- * cpumask. Iterate once again from bit 0 to the
- * previous starting point bit.
- */
- do_rotate = false;
- i = -1;
- goto retry;
+ rcu_read_lock();
+
+ sd = rcu_dereference(per_cpu(sd_ea, prev_cpu));
+ if (!sd) {
+ target_cpu = prev_cpu;
+ goto unlock;
}
- /*
- * If we don't find a CPU that fits this task without
- * increasing OPP above sched_smp_overlap_capacity or
- * when placement boost is active, expand the search to
- * the other groups on a SMP system.
- */
- if (!sysctl_sched_is_big_little &&
- (placement_boost == SCHED_BOOST_ON_ALL ||
- (target_cpu == -1 && min_util_cpu_util_cum >
- sched_smp_overlap_capacity))) {
- if (sg_target->next != start_sg) {
- sg_target = sg_target->next;
- goto next_sg;
- }
+ sync_entity_load_avg(&p->se);
+
+ /* Find a cpu with sufficient capacity */
+ next_cpu = find_best_target(p, &backup_cpu, boosted, prefer_idle,
+ &fbt_env);
+ if (next_cpu == -1) {
+ target_cpu = prev_cpu;
+ goto unlock;
}
- if (target_cpu == -1 ||
- (target_cpu != min_util_cpu && !safe_to_pack &&
- !is_packing_eligible(p, task_util_boosted, sg_target,
- target_cpu_new_util_cum,
- targeted_cpus))) {
- if (likely(min_util_cpu != -1))
- target_cpu = min_util_cpu;
- else if (cpu_isolated(task_cpu(p)) &&
- isolated_candidate != -1)
- target_cpu = isolated_candidate;
- else
- target_cpu = task_cpu(p);
+ if (fbt_env.placement_boost || fbt_env.need_idle ||
+ fbt_env.avoid_prev_cpu || (rtg_target &&
+ !cpumask_test_cpu(prev_cpu, rtg_target))) {
+ target_cpu = next_cpu;
+ goto unlock;
}
- if (target_cpu != task_cpu(p) && !avoid_prev_cpu &&
- !cpu_isolated(task_cpu(p))) {
+ /* Unconditionally prefer IDLE CPUs for boosted/prefer_idle tasks */
+ if ((boosted || prefer_idle) && idle_cpu(next_cpu)) {
+ schedstat_inc(p->se.statistics.nr_wakeups_secb_idle_bt);
+ schedstat_inc(this_rq()->eas_stats.secb_idle_bt);
+ target_cpu = next_cpu;
+ goto unlock;
+ }
+
+ target_cpu = prev_cpu;
+ if (next_cpu != prev_cpu) {
+ int delta = 0;
struct energy_env eenv = {
- .util_delta = task_util(p),
- .src_cpu = task_cpu(p),
- .dst_cpu = target_cpu,
- .task = p,
- .sync_cpu = sync ? smp_processor_id() : -1,
- .curr_util = curr_util,
+ .p = p,
+ .util_delta = task_util(p),
+ /* Task's previous CPU candidate */
+ .cpu[EAS_CPU_PRV] = {
+ .cpu_id = prev_cpu,
+ },
+ /* Main alternative CPU candidate */
+ .cpu[EAS_CPU_NXT] = {
+ .cpu_id = next_cpu,
+ },
+ /* Backup alternative CPU candidate */
+ .cpu[EAS_CPU_BKP] = {
+ .cpu_id = backup_cpu,
+ },
};
- /*
- * We always want to migrate the task to the preferred cluster.
- */
- if (rtg_target) {
- trace_sched_task_util_colocated(p, task_cpu(p),
- task_util(p),
- cpumask_first(rtg_target),
- target_cpu, 0, need_idle);
- return target_cpu;
- }
-
- if (need_idle) {
- trace_sched_task_util_need_idle(p, task_cpu(p),
- task_util(p),
- target_cpu, target_cpu,
- 0, need_idle);
- return target_cpu;
- }
-
- /*
- * We always want to migrate the task to the best CPU when
- * placement boost is active.
- */
- if (placement_boost) {
- trace_sched_task_util_boosted(p, task_cpu(p),
- task_util(p),
- target_cpu,
- target_cpu, 0, need_idle);
- return target_cpu;
- }
#ifdef CONFIG_SCHED_WALT
- if (walt_disabled || !sysctl_sched_use_walt_cpu_util)
- task_util_boosted = 0;
-#else
- task_util_boosted = 0;
+ if (!walt_disabled && sysctl_sched_use_walt_cpu_util &&
+ p->state == TASK_WAKING)
+ delta = task_util(p);
#endif
/* Not enough spare capacity on previous cpu */
- if (__cpu_overutilized(task_cpu(p),
- cpu_util(task_cpu(p)) +
- task_util_boosted)) {
- trace_sched_task_util_overutilzed(p, task_cpu(p),
- task_util(p), target_cpu,
- target_cpu, 0, need_idle);
- return target_cpu;
+ if (__cpu_overutilized(prev_cpu, delta)) {
+ schedstat_inc(p->se.statistics.nr_wakeups_secb_insuff_cap);
+ schedstat_inc(this_rq()->eas_stats.secb_insuff_cap);
+ target_cpu = next_cpu;
+ goto unlock;
}
- ediff = energy_diff(&eenv);
-
- if (!sysctl_sched_cstate_aware) {
- if (ediff >= 0) {
- trace_sched_task_util_energy_diff(p,
- task_cpu(p), task_util(p),
- target_cpu, task_cpu(p), ediff,
- need_idle);
- return task_cpu(p);
- }
- } else {
- if (ediff > 0) {
- trace_sched_task_util_energy_diff(p,
- task_cpu(p), task_util(p),
- target_cpu, task_cpu(p), ediff,
- need_idle);
- return task_cpu(p);
- }
+ /* Check if EAS_CPU_NXT is a more energy efficient CPU */
+ if (select_energy_cpu_idx(&eenv) != EAS_CPU_PRV) {
+ schedstat_inc(p->se.statistics.nr_wakeups_secb_nrg_sav);
+ schedstat_inc(this_rq()->eas_stats.secb_nrg_sav);
+ target_cpu = eenv.cpu[eenv.next_idx].cpu_id;
+ goto unlock;
}
+
+ schedstat_inc(p->se.statistics.nr_wakeups_secb_no_nrg_sav);
+ schedstat_inc(this_rq()->eas_stats.secb_no_nrg_sav);
+ target_cpu = prev_cpu;
+ goto unlock;
}
- trace_sched_task_util_energy_aware(p, task_cpu(p), task_util(p),
- target_cpu, target_cpu, ediff,
- need_idle);
+ schedstat_inc(p->se.statistics.nr_wakeups_secb_count);
+ schedstat_inc(this_rq()->eas_stats.secb_count);
+
+unlock:
+ trace_sched_task_util(p, next_cpu, backup_cpu, target_cpu, sync,
+ fbt_env.need_idle, fbt_env.placement_boost,
+ rtg_target ? cpumask_first(rtg_target) : -1);
+ rcu_read_unlock();
return target_cpu;
}
@@ -7261,20 +7449,15 @@
int want_affine = 0;
int sync = wake_flags & WF_SYNC;
- if (energy_aware()) {
- rcu_read_lock();
- new_cpu = energy_aware_wake_cpu(p, prev_cpu, sync);
- rcu_read_unlock();
- return new_cpu;
- }
-
if (sd_flag & SD_BALANCE_WAKE) {
record_wakee(p);
- want_affine = (!wake_wide(p) && task_fits_max(p, cpu) &&
- cpumask_test_cpu(cpu, tsk_cpus_allowed(p))) ||
- energy_aware();
+ want_affine = (!wake_wide(p) && !wake_cap(p, cpu, prev_cpu) &&
+ cpumask_test_cpu(cpu, tsk_cpus_allowed(p)));
}
+ if (energy_aware())
+ return select_energy_cpu_brute(p, prev_cpu, sync);
+
rcu_read_lock();
for_each_domain(cpu, tmp) {
if (!(tmp->flags & SD_LOAD_BALANCE))
@@ -7302,45 +7485,21 @@
new_cpu = cpu;
}
+ if (sd && !(sd_flag & SD_BALANCE_FORK)) {
+ /*
+ * We're going to need the task's util for capacity_spare_wake
+ * in find_idlest_group. Sync it up to prev_cpu's
+ * last_update_time.
+ */
+ sync_entity_load_avg(&p->se);
+ }
+
if (!sd) {
- if (energy_aware() && !cpu_rq(cpu)->rd->overutilized)
- new_cpu = energy_aware_wake_cpu(p, prev_cpu, sync);
- else if (sd_flag & SD_BALANCE_WAKE) /* XXX always ? */
+ if (sd_flag & SD_BALANCE_WAKE) /* XXX always ? */
new_cpu = select_idle_sibling(p, prev_cpu, new_cpu);
- } else while (sd) {
- struct sched_group *group;
- int weight;
-
- if (!(sd->flags & sd_flag)) {
- sd = sd->child;
- continue;
- }
-
- group = find_idlest_group(sd, p, cpu, sd_flag);
- if (!group) {
- sd = sd->child;
- continue;
- }
-
- new_cpu = find_idlest_cpu(group, p, cpu);
- if (new_cpu == -1 || new_cpu == cpu) {
- /* Now try balancing at a lower domain level of cpu */
- sd = sd->child;
- continue;
- }
-
- /* Now try balancing at a lower domain level of new_cpu */
- cpu = new_cpu;
- weight = sd->span_weight;
- sd = NULL;
- for_each_domain(cpu, tmp) {
- if (weight <= tmp->span_weight)
- break;
- if (tmp->flags & sd_flag)
- sd = tmp;
- }
- /* while loop will break here if sd == NULL */
+ } else {
+ new_cpu = find_idlest_cpu(sd, p, cpu, prev_cpu, sd_flag);
}
rcu_read_unlock();
@@ -8304,10 +8463,6 @@
{
raw_spin_lock(&rq->lock);
attach_task(rq, p);
- /*
- * We want to potentially raise target_cpu's OPP.
- */
- update_capacity_of(cpu_of(rq));
raw_spin_unlock(&rq->lock);
}
@@ -8329,11 +8484,6 @@
attach_task(env->dst_rq, p);
}
- /*
- * We want to potentially raise env.dst_cpu's OPP.
- */
- update_capacity_of(env->dst_cpu);
-
raw_spin_unlock(&env->dst_rq->lock);
}
@@ -8569,6 +8719,9 @@
cpu_rq(cpu)->cpu_capacity_orig = capacity;
+ capacity *= arch_scale_max_freq_capacity(sd, cpu);
+ capacity >>= SCHED_CAPACITY_SHIFT;
+
mcc = &cpu_rq(cpu)->rd->max_cpu_capacity;
raw_spin_lock_irqsave(&mcc->lock, flags);
@@ -8800,6 +8953,38 @@
return group_other;
}
+#ifdef CONFIG_NO_HZ_COMMON
+/*
+ * idle load balancing data
+ * - used by the nohz balance, but we want it available here
+ * so that we can see which CPUs have no tick.
+ */
+static struct {
+ cpumask_var_t idle_cpus_mask;
+ atomic_t nr_cpus;
+ unsigned long next_balance; /* in jiffy units */
+} nohz ____cacheline_aligned;
+
+static inline void update_cpu_stats_if_tickless(struct rq *rq)
+{
+ /* only called from update_sg_lb_stats when irqs are disabled */
+ if (cpumask_test_cpu(rq->cpu, nohz.idle_cpus_mask)) {
+ /* rate limit updates to once-per-jiffie at most */
+ if (READ_ONCE(jiffies) <= rq->last_load_update_tick)
+ return;
+
+ raw_spin_lock(&rq->lock);
+ update_rq_clock(rq);
+ cpu_load_update_idle(rq);
+ update_cfs_rq_load_avg(rq->clock_task, &rq->cfs, false);
+ raw_spin_unlock(&rq->lock);
+ }
+}
+
+#else
+static inline void update_cpu_stats_if_tickless(struct rq *rq) { }
+#endif
+
/**
* update_sg_lb_stats - Update sched_group's statistics for load balancing.
* @env: The load balancing environment.
@@ -8830,6 +9015,12 @@
if (cpu_isolated(i))
continue;
+ /* if we are entering idle and there are CPUs with
+ * their tick stopped, do an update for them
+ */
+ if (env->idle == CPU_NEWLY_IDLE)
+ update_cpu_stats_if_tickless(rq);
+
/* Bias balancing toward cpus of our domain */
if (local_group)
load = target_load(i, load_idx);
@@ -9729,11 +9920,6 @@
* ld_moved - cumulative load moved across iterations
*/
cur_ld_moved = detach_tasks(&env);
- /*
- * We want to potentially lower env.src_cpu's OPP.
- */
- if (cur_ld_moved)
- update_capacity_of(env.src_cpu);
/*
* We've detached some tasks from busiest_rq. Every
@@ -9981,7 +10167,6 @@
struct sched_domain *sd;
int pulled_task = 0;
u64 curr_cost = 0;
- long removed_util=0;
if (cpu_isolated(this_cpu))
return 0;
@@ -10006,17 +10191,6 @@
raw_spin_unlock(&this_rq->lock);
- /*
- * If removed_util_avg is !0 we most probably migrated some task away
- * from this_cpu. In this case we might be willing to trigger an OPP
- * update, but we want to do so if we don't find anybody else to pull
- * here (we will trigger an OPP update with the pulled task's enqueue
- * anyway).
- *
- * Record removed_util before calling update_blocked_averages, and use
- * it below (before returning) to see if an OPP update is required.
- */
- removed_util = atomic_long_read(&(this_rq->cfs).removed_util_avg);
update_blocked_averages(this_cpu);
rcu_read_lock();
for_each_domain(this_cpu, sd) {
@@ -10083,13 +10257,6 @@
if (pulled_task)
this_rq->idle_stamp = 0;
- else if (removed_util) {
- /*
- * No task pulled and someone has been migrated away.
- * Good case to trigger an OPP update.
- */
- update_capacity_of(this_cpu);
- }
return pulled_task;
}
@@ -10171,10 +10338,6 @@
p = detach_one_task(&env);
if (p) {
schedstat_inc(sd->alb_pushed);
- /*
- * We want to potentially lower env.src_cpu's OPP.
- */
- update_capacity_of(env.src_cpu);
/* Active balancing done, reset the failure counter. */
sd->nr_balance_failed = 0;
moved = true;
@@ -10220,12 +10383,6 @@
* needed, they will kick the idle load balancer, which then does idle
* load balancing for all the idle CPUs.
*/
-static struct {
- cpumask_var_t idle_cpus_mask;
- atomic_t nr_cpus;
- unsigned long next_balance; /* in jiffy units */
-} nohz ____cacheline_aligned;
-
static inline int find_new_ilb(int type)
{
int ilb = nr_cpu_ids;
@@ -11628,7 +11785,7 @@
raw_spin_lock(&migration_lock);
rcu_read_lock();
- new_cpu = energy_aware_wake_cpu(p, cpu, 0);
+ new_cpu = select_energy_cpu_brute(p, cpu, 0);
rcu_read_unlock();
if (capacity_orig_of(new_cpu) > capacity_orig_of(cpu)) {
active_balance = kick_active_balance(rq, p, new_cpu);
diff --git a/kernel/sched/features.h b/kernel/sched/features.h
index a1afd13..ef52be4 100644
--- a/kernel/sched/features.h
+++ b/kernel/sched/features.h
@@ -83,3 +83,24 @@
#else
SCHED_FEAT(ENERGY_AWARE, false)
#endif
+
+/*
+ * Minimum capacity capping. Keep track of minimum capacity factor when
+ * minimum frequency available to a policy is modified.
+ * If enabled, this can be used to inform the scheduler about capacity
+ * restrictions.
+ */
+SCHED_FEAT(MIN_CAPACITY_CAPPING, false)
+
+/*
+ * Enforce the priority of candidates selected by find_best_target()
+ * ON: If the target CPU saves any energy, use that.
+ * OFF: Use whichever of target or backup saves most.
+ */
+SCHED_FEAT(FBT_STRICT_ORDER, false)
+/*
+ * Enforce schedtune.prefer_idle to take need_idle path.
+ * ON: schedtune.prefer_idle is replaced with need_idle
+ * OFF: schedtune.prefer_idle is honored as is.
+ */
+SCHED_FEAT(EAS_USE_NEED_IDLE, true)
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 9bab9e2..8329e9c 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1471,7 +1471,7 @@
extern void set_cpus_allowed_common(struct task_struct *p, const struct cpumask *new_mask);
-bool __cpu_overutilized(int cpu, unsigned long util);
+bool __cpu_overutilized(int cpu, int delta);
bool cpu_overutilized(int cpu);
#endif
@@ -1699,6 +1699,26 @@
}
#endif
+#ifndef arch_scale_max_freq_capacity
+static __always_inline
+unsigned long arch_scale_max_freq_capacity(struct sched_domain *sd, int cpu)
+{
+ return SCHED_CAPACITY_SCALE;
+}
+#endif
+
+#ifndef arch_scale_min_freq_capacity
+static __always_inline
+unsigned long arch_scale_min_freq_capacity(struct sched_domain *sd, int cpu)
+{
+ /*
+ * Multiplied with any capacity value, this scale factor will return
+ * 0, which represents an un-capped state
+ */
+ return 0;
+}
+#endif
+
#ifndef arch_scale_cpu_capacity
static __always_inline
unsigned long arch_scale_cpu_capacity(struct sched_domain *sd, int cpu)
@@ -1870,7 +1890,7 @@
walt_load->prev_window_util = util;
walt_load->nl = nl;
walt_load->pl = pl;
- walt_load->ws = rq->window_start;
+ walt_load->ws = rq->load_reported_window;
}
return (util >= capacity) ? capacity : util;
@@ -1892,6 +1912,8 @@
#endif /* CONFIG_SCHED_WALT */
+extern unsigned long
+boosted_cpu_util(int cpu, struct sched_walt_cpu_load *walt_load);
#endif
extern unsigned int capacity_margin_freq;
@@ -1906,76 +1928,6 @@
return cpu_capacity;
}
-#ifdef CONFIG_CPU_FREQ_GOV_SCHED
-#define capacity_max SCHED_CAPACITY_SCALE
-extern struct static_key __sched_freq;
-
-static inline bool sched_freq(void)
-{
- return static_key_false(&__sched_freq);
-}
-
-DECLARE_PER_CPU(struct sched_capacity_reqs, cpu_sched_capacity_reqs);
-void update_cpu_capacity_request(int cpu, bool request);
-
-static inline void set_cfs_cpu_capacity(int cpu, bool request,
- unsigned long capacity)
-{
- struct sched_capacity_reqs *scr = &per_cpu(cpu_sched_capacity_reqs, cpu);
-
-#ifdef CONFIG_SCHED_WALT
- if (!walt_disabled && sysctl_sched_use_walt_cpu_util) {
- int rtdl = scr->rt + scr->dl;
- /*
- * WALT tracks the utilization of a CPU considering the load
- * generated by all the scheduling classes.
- * Since the following call to:
- * update_cpu_capacity
- * is already adding the RT and DL utilizations let's remove
- * these contributions from the WALT signal.
- */
- if (capacity > rtdl)
- capacity -= rtdl;
- else
- capacity = 0;
- }
-#endif
- if (scr->cfs != capacity) {
- scr->cfs = capacity;
- update_cpu_capacity_request(cpu, request);
- }
-}
-
-static inline void set_rt_cpu_capacity(int cpu, bool request,
- unsigned long capacity)
-{
- if (per_cpu(cpu_sched_capacity_reqs, cpu).rt != capacity) {
- per_cpu(cpu_sched_capacity_reqs, cpu).rt = capacity;
- update_cpu_capacity_request(cpu, request);
- }
-}
-
-static inline void set_dl_cpu_capacity(int cpu, bool request,
- unsigned long capacity)
-{
- if (per_cpu(cpu_sched_capacity_reqs, cpu).dl != capacity) {
- per_cpu(cpu_sched_capacity_reqs, cpu).dl = capacity;
- update_cpu_capacity_request(cpu, request);
- }
-}
-#else
-static inline bool sched_freq(void) { return false; }
-static inline void set_cfs_cpu_capacity(int cpu, bool request,
- unsigned long capacity)
-{ }
-static inline void set_rt_cpu_capacity(int cpu, bool request,
- unsigned long capacity)
-{ }
-static inline void set_dl_cpu_capacity(int cpu, bool request,
- unsigned long capacity)
-{ }
-#endif
-
static inline void sched_rt_avg_update(struct rq *rq, u64 rt_delta)
{
rq->rt_avg += rt_delta * arch_scale_freq_capacity(NULL, cpu_of(rq));
@@ -2318,7 +2270,8 @@
(rq->load_reported_window == rq->window_start) &&
!(flags & exception_flags))
return;
- rq->load_reported_window = rq->window_start;
+ if (!(flags & exception_flags))
+ rq->load_reported_window = rq->window_start;
#endif
data = rcu_dereference_sched(*per_cpu_ptr(&cpufreq_update_util_data,
diff --git a/kernel/sched/tune.c b/kernel/sched/tune.c
index 93643ba..bdcd174 100644
--- a/kernel/sched/tune.c
+++ b/kernel/sched/tune.c
@@ -20,7 +20,7 @@
unsigned int sysctl_sched_cfs_boost __read_mostly;
extern struct reciprocal_value schedtune_spc_rdiv;
-extern struct target_nrg schedtune_target_nrg;
+struct target_nrg schedtune_target_nrg;
/* Performance Boost region (B) threshold params */
static int perf_boost_idx;
diff --git a/kernel/sched/walt.c b/kernel/sched/walt.c
index 33daa99..b4d815c 100644
--- a/kernel/sched/walt.c
+++ b/kernel/sched/walt.c
@@ -2193,6 +2193,7 @@
int __read_mostly min_power_cpu;
+unsigned int sched_smp_overlap_capacity;
void walt_sched_energy_populated_callback(void)
{
struct sched_cluster *cluster;
diff --git a/kernel/sched/walt.h b/kernel/sched/walt.h
index 7edae12..414c4ae 100644
--- a/kernel/sched/walt.h
+++ b/kernel/sched/walt.h
@@ -181,6 +181,7 @@
{
return sched_irqload(cpu) >= sysctl_sched_cpu_high_irqload;
}
+#define walt_cpu_high_irqload(cpu) sched_cpu_high_irqload(cpu)
static inline int exiting_task(struct task_struct *p)
{
diff --git a/mm/page_io.c b/mm/page_io.c
index a2651f5..efe6fd6 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -56,7 +56,7 @@
* Also clear PG_reclaim to avoid rotate_reclaimable_page()
*/
set_page_dirty(page);
- pr_alert("Write-error on swap-device (%u:%u:%llu)\n",
+ pr_alert_ratelimited("Write-error on swap-device (%u:%u:%llu)\n",
imajor(bio->bi_bdev->bd_inode),
iminor(bio->bi_bdev->bd_inode),
(unsigned long long)bio->bi_iter.bi_sector);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 7cea430..febd5ab 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -12058,7 +12058,7 @@
struct net_device *dev = info->user_ptr[1];
struct cfg80211_external_auth_params params;
- if (rdev->ops->external_auth)
+ if (!rdev->ops->external_auth)
return -EOPNOTSUPP;
if (!info->attrs[NL80211_ATTR_SSID])
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 46e6b28..3b3455a 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -872,11 +872,6 @@
&x->replay);
if (ret)
goto out;
- if (x->props.output_mark) {
- ret = nla_put_u32(skb, XFRMA_OUTPUT_MARK, x->props.output_mark);
- if (ret)
- goto out;
- }
if (x->security)
ret = copy_sec_ctx(x->security, skb);
if (x->props.output_mark) {