Merge "mmc: msm_sdcc: don't return error if regulator info is not available"
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom-wdog-debug.txt b/Documentation/devicetree/bindings/arm/msm/qcom-wdog-debug.txt
new file mode 100644
index 0000000..e5fd1b2
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/qcom-wdog-debug.txt
@@ -0,0 +1,16 @@
+* Qualcomm's Watchdog Debug Image Controller
+
+The Qualcomm's Watchdog debug image controller is used for enabling/disabling of
+watchdog debug image feature.
+
+Required properties:
+- compatible : should be "qcom,msm-wdog-debug"
+- reg : base page aligned physical base address of the controller and length of
+ memory mapped region.
+
+Example:
+
+ qcom,msm-wdog-debug@fc401000 {
+ compatible = "qcom,msm-wdogi-debug";
+ reg = <0xfc401000 0x1000>;
+ };
diff --git a/Documentation/devicetree/bindings/iommu/msm_iommu.txt b/Documentation/devicetree/bindings/iommu/msm_iommu.txt
index f5a2590..7a90cc0 100644
--- a/Documentation/devicetree/bindings/iommu/msm_iommu.txt
+++ b/Documentation/devicetree/bindings/iommu/msm_iommu.txt
@@ -19,6 +19,19 @@
Optional properties:
- qcom,needs-alt-core-clk : boolean to enable the secondary core clock for
access to the IOMMU configuration registers
+- qcom,iommu-bfb-regs : An array of unsigned 32-bit integers corresponding to
+ BFB register addresses that need to be configured for performance tuning
+ purposes. If this property is present, the qcom,iommu-bfb-data must also be
+ present. Register addresses are specified as an offset from the base of the
+ IOMMU hardware block. This property may be omitted if no BFB register
+ configuration needs to be done for a particular IOMMU hardware instance. The
+ registers specified by this property shall fall within the IOMMU
+ implementation-defined register region.
+- qcom,iommu-bfb-data : An array of unsigned 32-bit integers representing the
+ values to be programmed into the corresponding registers given by the
+ qcom,iommu-bfb-regs property. If this property is present, the
+ qcom,iommu-bfb-regs property shall also be present, and the lengths of both
+ properties shall be the same.
Example:
@@ -26,6 +39,8 @@
compatible = "qcom,msm-smmu-v2";
reg = <0xfda64000 0x10000>;
vdd-supply = <&gdsc_iommu>;
+ qcom,iommu-bfb-regs = <0x204c 0x2050>;
+ qcom,iommu-bfb-data = <0xffff 0xffce>;
qcom,iommu-ctx@fda6c000 {
reg = <0xfda6c000 0x1000>;
diff --git a/arch/arm/boot/dts/mpq8092-iommu.dtsi b/arch/arm/boot/dts/mpq8092-iommu.dtsi
old mode 100755
new mode 100644
diff --git a/arch/arm/boot/dts/msm-pm8841.dtsi b/arch/arm/boot/dts/msm-pm8841.dtsi
index 069a248..ea83231 100644
--- a/arch/arm/boot/dts/msm-pm8841.dtsi
+++ b/arch/arm/boot/dts/msm-pm8841.dtsi
@@ -22,7 +22,7 @@
#address-cells = <1>;
#size-cells = <1>;
- pm8841_mpps {
+ pm8841_mpps: mpps {
spmi-dev-container;
compatible = "qcom,qpnp-pin";
gpio-controller;
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index d58a71d..f1e18cf 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -203,7 +203,7 @@
};
};
- pm8941_gpios {
+ pm8941_gpios: gpios {
spmi-dev-container;
compatible = "qcom,qpnp-pin";
gpio-controller;
@@ -393,7 +393,7 @@
};
};
- pm8941_mpps {
+ pm8941_mpps: mpps {
spmi-dev-container;
compatible = "qcom,qpnp-pin";
gpio-controller;
diff --git a/arch/arm/boot/dts/msm8974-cdp.dts b/arch/arm/boot/dts/msm8974-cdp.dts
index 7aeb33c..aff0adc 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dts
+++ b/arch/arm/boot/dts/msm8974-cdp.dts
@@ -168,3 +168,196 @@
cd-gpios = <&msmgpio 62 0x1>;
wp-gpios = <&pm8941_gpios 29 0x1>;
};
+
+&pm8941_gpios {
+ gpio@c000 { /* GPIO 1 */
+ };
+
+ gpio@c100 { /* GPIO 2 */
+ };
+
+ gpio@c200 { /* GPIO 3 */
+ qcom,mode = <0>;
+ qcom,pull = <0>;
+ qcom,vin-sel = <2>;
+ qcom,select = <0>;
+ };
+
+ gpio@c300 { /* GPIO 4 */
+ qcom,mode = <0>;
+ qcom,pull = <0>;
+ qcom,vin-sel = <2>;
+ qcom,select = <0>;
+ };
+
+ gpio@c400 { /* GPIO 5 */
+ qcom,mode = <0>;
+ qcom,pull = <0>;
+ qcom,vin-sel = <2>;
+ qcom,select = <0>;
+ };
+
+ gpio@c500 { /* GPIO 6 */
+ };
+
+ gpio@c600 { /* GPIO 7 */
+ };
+
+ gpio@c700 { /* GPIO 8 */
+ };
+
+ gpio@c800 { /* GPIO 9 */
+ };
+
+ gpio@c900 { /* GPIO 10 */
+ };
+
+ gpio@ca00 { /* GPIO 11 */
+ };
+
+ gpio@cb00 { /* GPIO 12 */
+ };
+
+ gpio@cc00 { /* GPIO 13 */
+ };
+
+ gpio@cd00 { /* GPIO 14 */
+ };
+
+ gpio@ce00 { /* GPIO 15 */
+ qcom,mode = <1>;
+ qcom,output-type = <0>;
+ qcom,pull = <5>;
+ qcom,vin-sel = <2>;
+ qcom,out-strength = <3>;
+ qcom,src-select = <2>;
+ qcom,master-en = <1>;
+ };
+
+ gpio@cf00 { /* GPIO 16 */
+ };
+
+ gpio@d000 { /* GPIO 17 */
+ };
+
+ gpio@d100 { /* GPIO 18 */
+ };
+
+ gpio@d200 { /* GPIO 19 */
+ qcom,mode = <1>; /* QPNP_PIN_MODE_DIG_OUT */
+ qcom,output-type = <0>; /* QPNP_PIN_OUT_BUF_CMOS */
+ qcom,pull = <5>; /* QPNP_PIN_PULL_NO */
+ qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */
+ qcom,out-strength = <2>; /* QPNP_PIN_OUT_STRENGTH_MED */
+ qcom,src-select = <0>; /* QPNP_PIN_SEL_FUNC_CONSTANT */
+ qcom,master-en = <1>;
+ };
+
+ gpio@d300 { /* GPIO 20 */
+ };
+
+ gpio@d400 { /* GPIO 21 */
+ };
+
+ gpio@d500 { /* GPIO 22 */
+ };
+
+ gpio@d600 { /* GPIO 23 */
+ };
+
+ gpio@d700 { /* GPIO 24 */
+ };
+
+ gpio@d800 { /* GPIO 25 */
+ };
+
+ gpio@d900 { /* GPIO 26 */
+ };
+
+ gpio@da00 { /* GPIO 27 */
+ };
+
+ gpio@db00 { /* GPIO 28 */
+ };
+
+ gpio@dc00 { /* GPIO 29 */
+ qcom,pull = <0>; /* set to default pull */
+ qcom,master-en = <1>;
+ qcom,vin-sel = <2>; /* select 1.8 V source */
+ };
+
+ gpio@dd00 { /* GPIO 30 */
+ };
+
+ gpio@de00 { /* GPIO 31 */
+ };
+
+ gpio@df00 { /* GPIO 32 */
+ };
+
+ gpio@e000 { /* GPIO 33 */
+ };
+
+ gpio@e100 { /* GPIO 34 */
+ };
+
+ gpio@e200 { /* GPIO 35 */
+ };
+
+ gpio@e300 { /* GPIO 36 */
+ };
+};
+
+&pm8941_mpps {
+
+ mpp@a000 { /* MPP 1 */
+ };
+
+ mpp@a100 { /* MPP 2 */
+ };
+
+ mpp@a200 { /* MPP 3 */
+ };
+
+ mpp@a300 { /* MPP 4 */
+ };
+
+ mpp@a400 { /* MPP 5 */
+ /* SPI_ETH config */
+ qcom,mode = <1>; /* DIG_OUT */
+ qcom,output-type = <0>; /* CMOS */
+ qcom,vin-sel = <2>; /* PM8941_S3 1.8V > 1.6V */
+ qcom,src-select = <0>; /* CONSTANT */
+ qcom,master-en = <1>; /* ENABLE MPP */
+ };
+
+ mpp@a500 { /* MPP 6 */
+ /* SPI_ETH_RST config */
+ qcom,mode = <1>; /* DIG_OUT */
+ qcom,output-type = <0>; /* CMOS */
+ qcom,vin-sel = <2>; /* PM8941_S3 1.8V > 1.6V */
+ qcom,src-select = <0>; /* CONSTANT */
+ qcom,master-en = <1>; /* ENABLE MPP */
+ };
+
+ mpp@a600 { /* MPP 7 */
+ };
+
+ mpp@a700 { /* MPP 8 */
+ };
+};
+
+&pm8841_mpps {
+
+ mpp@a000 { /* MPP 1 */
+ };
+
+ mpp@a100 { /* MPP 2 */
+ };
+
+ mpp@a200 { /* MPP 3 */
+ };
+
+ mpp@a300 { /* MPP 4 */
+ };
+};
diff --git a/arch/arm/boot/dts/msm8974-gpio.dtsi b/arch/arm/boot/dts/msm8974-gpio.dtsi
deleted file mode 100644
index e298340..0000000
--- a/arch/arm/boot/dts/msm8974-gpio.dtsi
+++ /dev/null
@@ -1,214 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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,pm8941@0 {
-
- pm8941_gpios: pm8941_gpios {
-
- gpio@c000 {
- };
-
- gpio@c100 {
- };
-
- gpio@c200 {
- qcom,mode = <0>;
- qcom,pull = <0>;
- qcom,vin-sel = <2>;
- qcom,select = <0>;
- };
-
- gpio@c300 {
- qcom,mode = <0>;
- qcom,pull = <0>;
- qcom,vin-sel = <2>;
- qcom,select = <0>;
- };
-
- gpio@c400 {
- qcom,mode = <0>;
- qcom,pull = <0>;
- qcom,vin-sel = <2>;
- qcom,select = <0>;
- };
-
- gpio@c500 {
- };
-
- gpio@c600 {
- };
-
- gpio@c700 {
- };
-
- gpio@c800 {
- };
-
- gpio@c900 {
- };
-
- gpio@ca00 {
- };
-
- gpio@cb00 {
- };
-
- gpio@cc00 {
- };
-
- gpio@cd00 {
- };
-
- gpio@ce00 {
- qcom,mode = <1>;
- qcom,output-type = <0>;
- qcom,pull = <5>;
- qcom,vin-sel = <2>;
- qcom,out-strength = <3>;
- qcom,src-select = <2>;
- qcom,master-en = <1>;
- };
-
- gpio@cf00 {
- };
-
- gpio@d000 {
- };
-
- gpio@d100 {
- };
-
- gpio@d200 {
- qcom,mode = <1>; /* QPNP_PIN_MODE_DIG_OUT */
- qcom,output-type = <0>; /* QPNP_PIN_OUT_BUF_CMOS */
- qcom,pull = <5>; /* QPNP_PIN_PULL_NO */
- qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */
- qcom,out-strength = <2>; /* QPNP_PIN_OUT_STRENGTH_MED */
- qcom,src-select = <0>; /* QPNP_PIN_SEL_FUNC_CONSTANT */
- qcom,master-en = <1>;
- };
-
- gpio@d300 {
- };
-
- gpio@d400 {
- };
-
- gpio@d500 {
- };
-
- gpio@d600 {
- };
-
- gpio@d700 {
- };
-
- gpio@d800 {
- };
-
- gpio@d900 {
- };
-
- gpio@da00 {
- };
-
- gpio@db00 {
- };
-
- gpio@dc00 {
- qcom,pull = <0>; /* set to default pull */
- qcom,master-en = <1>;
- qcom,vin-sel = <2>; /* select 1.8 V source */
- };
-
- gpio@dd00 {
- };
-
- gpio@de00 {
- };
-
- gpio@df00 {
- };
-
- gpio@e000 {
- };
-
- gpio@e100 {
- };
-
- gpio@e200 {
- };
-
- gpio@e300 {
- };
- };
-
- pm8941_mpps: pm8941_mpps {
-
- mpp@a000 {
- };
-
- mpp@a100 {
- };
-
- mpp@a200 {
- };
-
- mpp@a300 {
- };
-
- mpp@a400 {
- /* SPI_ETH config */
- qcom,mode = <1>; /* DIG_OUT */
- qcom,output-type = <0>; /* CMOS */
- qcom,vin-sel = <2>; /* PM8941_S3 1.8V > 1.6V */
- qcom,src-select = <0>; /* CONSTANT */
- qcom,master-en = <1>; /* ENABLE MPP */
- };
-
- mpp@a500 {
- /* SPI_ETH_RST config */
- qcom,mode = <1>; /* DIG_OUT */
- qcom,output-type = <0>; /* CMOS */
- qcom,vin-sel = <2>; /* PM8941_S3 1.8V > 1.6V */
- qcom,src-select = <0>; /* CONSTANT */
- qcom,master-en = <1>; /* ENABLE MPP */
- };
-
- mpp@a600 {
- };
-
- mpp@a700 {
- };
- };
- };
-
- qcom,pm8841@4 {
-
- pm8841_mpps: pm8841_mpps {
-
- mpp@a000 {
- };
-
- mpp@a100 {
- };
-
- mpp@a200 {
- };
-
- mpp@a300 {
- };
- };
- };
-};
diff --git a/arch/arm/boot/dts/msm8974-liquid.dts b/arch/arm/boot/dts/msm8974-liquid.dts
index 5de2d43..2abc1d5 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dts
+++ b/arch/arm/boot/dts/msm8974-liquid.dts
@@ -24,4 +24,195 @@
};
};
+&pm8941_gpios {
+ gpio@c000 { /* GPIO 1 */
+ };
+ gpio@c100 { /* GPIO 2 */
+ };
+
+ gpio@c200 { /* GPIO 3 */
+ qcom,mode = <0>;
+ qcom,pull = <0>;
+ qcom,vin-sel = <2>;
+ qcom,select = <0>;
+ };
+
+ gpio@c300 { /* GPIO 4 */
+ qcom,mode = <0>;
+ qcom,pull = <0>;
+ qcom,vin-sel = <2>;
+ qcom,select = <0>;
+ };
+
+ gpio@c400 { /* GPIO 5 */
+ qcom,mode = <0>;
+ qcom,pull = <0>;
+ qcom,vin-sel = <2>;
+ qcom,select = <0>;
+ };
+
+ gpio@c500 { /* GPIO 6 */
+ };
+
+ gpio@c600 { /* GPIO 7 */
+ };
+
+ gpio@c700 { /* GPIO 8 */
+ };
+
+ gpio@c800 { /* GPIO 9 */
+ };
+
+ gpio@c900 { /* GPIO 10 */
+ };
+
+ gpio@ca00 { /* GPIO 11 */
+ };
+
+ gpio@cb00 { /* GPIO 12 */
+ };
+
+ gpio@cc00 { /* GPIO 13 */
+ };
+
+ gpio@cd00 { /* GPIO 14 */
+ };
+
+ gpio@ce00 { /* GPIO 15 */
+ qcom,mode = <1>;
+ qcom,output-type = <0>;
+ qcom,pull = <5>;
+ qcom,vin-sel = <2>;
+ qcom,out-strength = <3>;
+ qcom,src-select = <2>;
+ qcom,master-en = <1>;
+ };
+
+ gpio@cf00 { /* GPIO 16 */
+ };
+
+ gpio@d000 { /* GPIO 17 */
+ };
+
+ gpio@d100 { /* GPIO 18 */
+ };
+
+ gpio@d200 { /* GPIO 19 */
+ qcom,mode = <1>; /* QPNP_PIN_MODE_DIG_OUT */
+ qcom,output-type = <0>; /* QPNP_PIN_OUT_BUF_CMOS */
+ qcom,pull = <5>; /* QPNP_PIN_PULL_NO */
+ qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */
+ qcom,out-strength = <2>; /* QPNP_PIN_OUT_STRENGTH_MED */
+ qcom,src-select = <0>; /* QPNP_PIN_SEL_FUNC_CONSTANT */
+ qcom,master-en = <1>;
+ };
+
+ gpio@d300 { /* GPIO 20 */
+ };
+
+ gpio@d400 { /* GPIO 21 */
+ };
+
+ gpio@d500 { /* GPIO 22 */
+ };
+
+ gpio@d600 { /* GPIO 23 */
+ };
+
+ gpio@d700 { /* GPIO 24 */
+ };
+
+ gpio@d800 { /* GPIO 25 */
+ };
+
+ gpio@d900 { /* GPIO 26 */
+ };
+
+ gpio@da00 { /* GPIO 27 */
+ };
+
+ gpio@db00 { /* GPIO 28 */
+ };
+
+ gpio@dc00 { /* GPIO 29 */
+ qcom,pull = <0>; /* set to default pull */
+ qcom,master-en = <1>;
+ qcom,vin-sel = <2>; /* select 1.8 V source */
+ };
+
+ gpio@dd00 { /* GPIO 30 */
+ };
+
+ gpio@de00 { /* GPIO 31 */
+ };
+
+ gpio@df00 { /* GPIO 32 */
+ };
+
+ gpio@e000 { /* GPIO 33 */
+ };
+
+ gpio@e100 { /* GPIO 34 */
+ };
+
+ gpio@e200 { /* GPIO 35 */
+ };
+
+ gpio@e300 { /* GPIO 36 */
+ };
+};
+
+&pm8941_mpps {
+
+ mpp@a000 { /* MPP 1 */
+ };
+
+ mpp@a100 { /* MPP 2 */
+ };
+
+ mpp@a200 { /* MPP 3 */
+ };
+
+ mpp@a300 { /* MPP 4 */
+ };
+
+ mpp@a400 { /* MPP 5 */
+ /* SPI_ETH config */
+ qcom,mode = <1>; /* DIG_OUT */
+ qcom,output-type = <0>; /* CMOS */
+ qcom,vin-sel = <2>; /* PM8941_S3 1.8V > 1.6V */
+ qcom,src-select = <0>; /* CONSTANT */
+ qcom,master-en = <1>; /* ENABLE MPP */
+ };
+
+ mpp@a500 { /* MPP 6 */
+ /* SPI_ETH_RST config */
+ qcom,mode = <1>; /* DIG_OUT */
+ qcom,output-type = <0>; /* CMOS */
+ qcom,vin-sel = <2>; /* PM8941_S3 1.8V > 1.6V */
+ qcom,src-select = <0>; /* CONSTANT */
+ qcom,master-en = <1>; /* ENABLE MPP */
+ };
+
+ mpp@a600 { /* MPP 7 */
+ };
+
+ mpp@a700 { /* MPP 8 */
+ };
+};
+
+&pm8841_mpps {
+
+ mpp@a000 { /* MPP 1 */
+ };
+
+ mpp@a100 { /* MPP 2 */
+ };
+
+ mpp@a200 { /* MPP 3 */
+ };
+
+ mpp@a300 { /* MPP 4 */
+ };
+};
diff --git a/arch/arm/boot/dts/msm8974-mtp.dts b/arch/arm/boot/dts/msm8974-mtp.dts
index ed89368..e183d04 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dts
+++ b/arch/arm/boot/dts/msm8974-mtp.dts
@@ -167,3 +167,196 @@
interrupt-names = "core_irq", "bam_irq", "status_irq";
cd-gpios = <&msmgpio 62 0x1>;
};
+
+&pm8941_gpios {
+ gpio@c000 { /* GPIO 1 */
+ };
+
+ gpio@c100 { /* GPIO 2 */
+ };
+
+ gpio@c200 { /* GPIO 3 */
+ qcom,mode = <0>;
+ qcom,pull = <0>;
+ qcom,vin-sel = <2>;
+ qcom,select = <0>;
+ };
+
+ gpio@c300 { /* GPIO 4 */
+ qcom,mode = <0>;
+ qcom,pull = <0>;
+ qcom,vin-sel = <2>;
+ qcom,select = <0>;
+ };
+
+ gpio@c400 { /* GPIO 5 */
+ qcom,mode = <0>;
+ qcom,pull = <0>;
+ qcom,vin-sel = <2>;
+ qcom,select = <0>;
+ };
+
+ gpio@c500 { /* GPIO 6 */
+ };
+
+ gpio@c600 { /* GPIO 7 */
+ };
+
+ gpio@c700 { /* GPIO 8 */
+ };
+
+ gpio@c800 { /* GPIO 9 */
+ };
+
+ gpio@c900 { /* GPIO 10 */
+ };
+
+ gpio@ca00 { /* GPIO 11 */
+ };
+
+ gpio@cb00 { /* GPIO 12 */
+ };
+
+ gpio@cc00 { /* GPIO 13 */
+ };
+
+ gpio@cd00 { /* GPIO 14 */
+ };
+
+ gpio@ce00 { /* GPIO 15 */
+ qcom,mode = <1>;
+ qcom,output-type = <0>;
+ qcom,pull = <5>;
+ qcom,vin-sel = <2>;
+ qcom,out-strength = <3>;
+ qcom,src-select = <2>;
+ qcom,master-en = <1>;
+ };
+
+ gpio@cf00 { /* GPIO 16 */
+ };
+
+ gpio@d000 { /* GPIO 17 */
+ };
+
+ gpio@d100 { /* GPIO 18 */
+ };
+
+ gpio@d200 { /* GPIO 19 */
+ qcom,mode = <1>; /* QPNP_PIN_MODE_DIG_OUT */
+ qcom,output-type = <0>; /* QPNP_PIN_OUT_BUF_CMOS */
+ qcom,pull = <5>; /* QPNP_PIN_PULL_NO */
+ qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */
+ qcom,out-strength = <2>; /* QPNP_PIN_OUT_STRENGTH_MED */
+ qcom,src-select = <0>; /* QPNP_PIN_SEL_FUNC_CONSTANT */
+ qcom,master-en = <1>;
+ };
+
+ gpio@d300 { /* GPIO 20 */
+ };
+
+ gpio@d400 { /* GPIO 21 */
+ };
+
+ gpio@d500 { /* GPIO 22 */
+ };
+
+ gpio@d600 { /* GPIO 23 */
+ };
+
+ gpio@d700 { /* GPIO 24 */
+ };
+
+ gpio@d800 { /* GPIO 25 */
+ };
+
+ gpio@d900 { /* GPIO 26 */
+ };
+
+ gpio@da00 { /* GPIO 27 */
+ };
+
+ gpio@db00 { /* GPIO 28 */
+ };
+
+ gpio@dc00 { /* GPIO 29 */
+ qcom,pull = <0>; /* set to default pull */
+ qcom,master-en = <1>;
+ qcom,vin-sel = <2>; /* select 1.8 V source */
+ };
+
+ gpio@dd00 { /* GPIO 30 */
+ };
+
+ gpio@de00 { /* GPIO 31 */
+ };
+
+ gpio@df00 { /* GPIO 32 */
+ };
+
+ gpio@e000 { /* GPIO 33 */
+ };
+
+ gpio@e100 { /* GPIO 34 */
+ };
+
+ gpio@e200 { /* GPIO 35 */
+ };
+
+ gpio@e300 { /* GPIO 36 */
+ };
+};
+
+&pm8941_mpps {
+
+ mpp@a000 { /* MPP 1 */
+ };
+
+ mpp@a100 { /* MPP 2 */
+ };
+
+ mpp@a200 { /* MPP 3 */
+ };
+
+ mpp@a300 { /* MPP 4 */
+ };
+
+ mpp@a400 { /* MPP 5 */
+ /* SPI_ETH config */
+ qcom,mode = <1>; /* DIG_OUT */
+ qcom,output-type = <0>; /* CMOS */
+ qcom,vin-sel = <2>; /* PM8941_S3 1.8V > 1.6V */
+ qcom,src-select = <0>; /* CONSTANT */
+ qcom,master-en = <1>; /* ENABLE MPP */
+ };
+
+ mpp@a500 { /* MPP 6 */
+ /* SPI_ETH_RST config */
+ qcom,mode = <1>; /* DIG_OUT */
+ qcom,output-type = <0>; /* CMOS */
+ qcom,vin-sel = <2>; /* PM8941_S3 1.8V > 1.6V */
+ qcom,src-select = <0>; /* CONSTANT */
+ qcom,master-en = <1>; /* ENABLE MPP */
+ };
+
+ mpp@a600 { /* MPP 7 */
+ };
+
+ mpp@a700 { /* MPP 8 */
+ };
+};
+
+&pm8841_mpps {
+
+ mpp@a000 { /* MPP 1 */
+ };
+
+ mpp@a100 { /* MPP 2 */
+ };
+
+ mpp@a200 { /* MPP 3 */
+ };
+
+ mpp@a300 { /* MPP 4 */
+ };
+};
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 9ed61ed..b992e86 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -239,6 +239,19 @@
qcom,bam-dma-res-pipes = <6>;
};
+ spi@f9966000 {
+ compatible = "qcom,spi-qup-v2";
+ cell-index = <7>;
+ reg = <0xf9966000 0x1000>;
+ interrupts = <0 104 0>;
+ spi-max-frequency = <19200000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ gpios = <&msmgpio 56 0>, /* CLK */
+ <&msmgpio 54 0>, /* MISO */
+ <&msmgpio 53 0>; /* MOSI */
+ cs-gpios = <&msmgpio 55 0>;
+ };
slim@fe12f000 {
cell-index = <1>;
@@ -1032,11 +1045,16 @@
reg = <0xfc834000 0x7000>;
interrupts = <0 29 1>;
};
+
+ qcom,msm-wdog-debug@fc401000 {
+ compatible = "qcom,msm-wdog-debug";
+ reg = <0xfc401000 0x1000>;
+ };
+
};
/include/ "msm-pm8x41-rpm-regulator.dtsi"
/include/ "msm-pm8841.dtsi"
/include/ "msm-pm8941.dtsi"
/include/ "msm8974-regulator.dtsi"
-/include/ "msm8974-gpio.dtsi"
/include/ "msm8974-clock.dtsi"
diff --git a/arch/arm/boot/dts/msm8974_pm.dtsi b/arch/arm/boot/dts/msm8974_pm.dtsi
index 77f2532..e39a72a 100644
--- a/arch/arm/boot/dts/msm8974_pm.dtsi
+++ b/arch/arm/boot/dts/msm8974_pm.dtsi
@@ -117,10 +117,9 @@
qcom,vctl-port = <0x0>;
qcom,phase-port = <0x1>;
qcom,saw2-spm-cmd-ret = [00 20 03 22 00 0f];
- qcom,saw2-spm-cmd-gdhs = [00 20 32 0b 42 07 44 22 50 02 32 50
- 0f];
- qcom,saw2-spm-cmd-pc = [00 10 32 b0 11 0b 42 07 01 b0 12 44 a0
- 50 02 32 a0 50 0f];
+ qcom,saw2-spm-cmd-gdhs = [00 20 32 42 07 44 22 50 02 32 50 0f];
+ qcom,saw2-spm-cmd-pc = [00 10 32 b0 11 42 07 01 b0 12 44
+ 50 02 32 50 0f];
};
qcom,lpm-resources {
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 3fdc804..45d52e4 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -506,3 +506,4 @@
CONFIG_CRYPTO_DEV_QCEDEV=m
CONFIG_CRC_CCITT=y
CONFIG_WCNSS_MEM_PRE_ALLOC=y
+CONFIG_CONTROL_TRACE=m
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 4daaa12..465598f 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -524,3 +524,4 @@
CONFIG_CRYPTO_DEV_QCEDEV=m
CONFIG_CRC_CCITT=y
CONFIG_WCNSS_MEM_PRE_ALLOC=y
+CONFIG_CONTROL_TRACE=m
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 47f9ba3..2f1833e 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -402,3 +402,4 @@
CONFIG_CRYPTO_DEV_QCE=m
CONFIG_CRYPTO_DEV_QCEDEV=m
CONFIG_CRC_CCITT=y
+CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index f6e51af..1230fbe 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -398,7 +398,6 @@
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
# CONFIG_DEBUG_PREEMPT is not set
CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_INFO=y
@@ -422,3 +421,4 @@
CONFIG_CRYPTO_DEV_QCE=m
CONFIG_CRYPTO_DEV_QCEDEV=m
CONFIG_CRC_CCITT=y
+CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index 4cb3f6b..364a1bf 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -146,11 +146,3 @@
# CONFIG_CRYPTO_HW is not set
CONFIG_CRC_CCITT=y
CONFIG_LIBCRC32C=y
-CONFIG_MMC=y
-CONFIG_MMC_PERF_PROFILING=y
-CONFIG_MMC_CLKGATE=y
-CONFIG_MMC_PARANOID_SD_INIT=y
-CONFIG_MMC_BLOCK_MINORS=32
-CONFIG_MMC_TEST=m
-CONFIG_MMC_MSM=y
-CONFIG_MMC_MSM_SPS_SUPPORT=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index a551d3c..157f159 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1903,7 +1903,7 @@
config MSM_PIL_MODEM
tristate "Modem (ARM11) Boot Support"
- depends on MSM_PIL
+ depends on MSM_PIL && MSM_SUBSYSTEM_RESTART
help
Support for booting and shutting down ARM11 Modem processors.
@@ -2643,4 +2643,12 @@
such as display backlight, vreg pin-ctrl, smps clock over the RPC
interface. This support is required for MSMs on which the APPS
does not have a direct access to the PMIC.
+
+config MSM_ENABLE_WDOG_DEBUG_CONTROL
+ bool "MSM Watchdog driver to disable debug Image"
+ help
+ This driver supports the configuration of the GCC_WDOG_DEBUG register
+ used to control debug image.
+ This support is currently required for MSM8974 to disable debug image
+ on PS HOLD reset
endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index a2151d5..1b42d2d 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -65,6 +65,8 @@
$(obj)/smd_rpc_sym.c: $(src)/smd_rpc_sym $(src)/mkrpcsym.pl
$(call if_changed,mkrpcsym)
+obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o remote_spinlock.o smd_private.o
+
obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
obj-$(CONFIG_MSM_SECURE_IO) += scm-io.o
obj-$(CONFIG_MSM_PIL) += peripheral-loader.o
@@ -96,7 +98,6 @@
ifdef CONFIG_DEBUG_FS
obj-$(CONFIG_MSM_IPC_LOGGING) += ipc_logging_debug.o
endif
-obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o remote_spinlock.o smd_private.o
obj-y += socinfo.o
ifndef CONFIG_ARCH_MSM8960
ifndef CONFIG_ARCH_MSM8X60
@@ -194,7 +195,7 @@
obj-y += subsystem_notif.o
obj-y += subsystem_restart.o
obj-y += ramdump.o
- obj-$(CONFIG_ARCH_MSM8X60) += modem-8660.o lpass-8660.o
+ obj-$(CONFIG_ARCH_MSM8X60) += lpass-8660.o
endif
obj-$(CONFIG_MSM_SYSMON_COMM) += sysmon.o
obj-$(CONFIG_MSM_MODEM_8960) += modem-8960.o
@@ -288,7 +289,6 @@
obj-$(CONFIG_ARCH_MSM8974) += gdsc.o
obj-$(CONFIG_ARCH_MSM8974) += krait-regulator.o
obj-$(CONFIG_ARCH_MSM9625) += board-9625.o board-9625-gpiomux.o
-obj-$(CONFIG_ARCH_MSM9625) += clock-local2.o clock-pll.o clock-9625.o clock-rpm.o clock-voter.o
obj-$(CONFIG_ARCH_MSM8930) += acpuclock-8930.o acpuclock-8627.o acpuclock-8930aa.o
obj-$(CONFIG_ARCH_MPQ8092) += board-8092.o board-8092-gpiomux.o
obj-$(CONFIG_ARCH_MSM8226) += board-8226.o board-8226-gpiomux.o
@@ -384,6 +384,7 @@
obj-$(CONFIG_MSM_RPC_USB) += rpc_hsusb.o rpc_fsusb.o
obj-$(CONFIG_MSM_RPC_PMAPP) += rpc_pmapp.o
+obj-$(CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL) += wdog_debug.o
ifdef CONFIG_MSM_CPR
obj-$(CONFIG_DEBUG_FS) += msm_cpr-debug.o
diff --git a/arch/arm/mach-msm/acpuclock-8064.c b/arch/arm/mach-msm/acpuclock-8064.c
index d0de62b..d10211bc 100644
--- a/arch/arm/mach-msm/acpuclock-8064.c
+++ b/arch/arm/mach-msm/acpuclock-8064.c
@@ -18,6 +18,7 @@
#include <mach/msm_bus_board.h>
#include <mach/msm_bus.h>
+#include "mach/socinfo.h"
#include "acpuclock.h"
#include "acpuclock-krait.h"
@@ -94,6 +95,10 @@
},
};
+/*
+ * The correct maximum rate for 8064ab in 600 MHZ.
+ * We rely on the RPM rounding requests up here.
+*/
static struct msm_bus_paths bw_level_tbl[] __initdata = {
[0] = BW_MBPS(640), /* At least 80 MHz on bus. */
[1] = BW_MBPS(1064), /* At least 133 MHz on bus. */
@@ -110,7 +115,7 @@
.name = "acpuclk-8064",
};
-static struct l2_level l2_freq_tbl[] __initdata __initdata = {
+static struct l2_level l2_freq_tbl[] __initdata = {
[0] = { { 384000, PLL_8, 0, 0x00 }, 1050000, 1050000, 1 },
[1] = { { 432000, HFPLL, 2, 0x20 }, 1050000, 1050000, 2 },
[2] = { { 486000, HFPLL, 2, 0x24 }, 1050000, 1050000, 2 },
@@ -127,10 +132,12 @@
[13] = { { 1080000, HFPLL, 1, 0x28 }, 1150000, 1150000, 5 },
[14] = { { 1134000, HFPLL, 1, 0x2A }, 1150000, 1150000, 5 },
[15] = { { 1188000, HFPLL, 1, 0x2C }, 1150000, 1150000, 5 },
+ /* L2 Level 16 is for 8064ab only */
+ [16] = { { 1242000, HFPLL, 1, 0x2E }, 1150000, 1150000, 5 },
{ }
};
-static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
+static struct acpu_level tbl_slow[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 950000 },
{ 0, { 432000, HFPLL, 2, 0x20 }, L2(6), 975000 },
{ 1, { 486000, HFPLL, 2, 0x24 }, L2(6), 975000 },
@@ -156,7 +163,7 @@
{ 0, { 0 } }
};
-static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
+static struct acpu_level tbl_nom[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 900000 },
{ 0, { 432000, HFPLL, 2, 0x20 }, L2(6), 925000 },
{ 1, { 486000, HFPLL, 2, 0x24 }, L2(6), 925000 },
@@ -182,7 +189,7 @@
{ 0, { 0 } }
};
-static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
+static struct acpu_level tbl_fast[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 850000 },
{ 0, { 432000, HFPLL, 2, 0x20 }, L2(6), 875000 },
{ 1, { 486000, HFPLL, 2, 0x24 }, L2(6), 875000 },
@@ -208,12 +215,91 @@
{ 0, { 0 } }
};
-static struct pvs_table pvs_tables[NUM_PVS] __initdata = {
-[PVS_SLOW] = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
-[PVS_NOMINAL] = { acpu_freq_tbl_nom, sizeof(acpu_freq_tbl_nom), 25000 },
-[PVS_FAST] = { acpu_freq_tbl_fast, sizeof(acpu_freq_tbl_fast), 25000 },
-/* TODO: update the faster table when data is available */
-[PVS_FASTER] = { acpu_freq_tbl_fast, sizeof(acpu_freq_tbl_fast), 25000 },
+static struct acpu_level tbl_slow_1p7[] __initdata = {
+ { 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 950000 },
+ { 0, { 432000, HFPLL, 2, 0x20 }, L2(6), 975000 },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(6), 975000 },
+ { 0, { 540000, HFPLL, 2, 0x28 }, L2(6), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(6), 1000000 },
+ { 0, { 648000, HFPLL, 1, 0x18 }, L2(6), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(6), 1025000 },
+ { 0, { 756000, HFPLL, 1, 0x1C }, L2(6), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(6), 1075000 },
+ { 0, { 864000, HFPLL, 1, 0x20 }, L2(6), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(6), 1100000 },
+ { 0, { 972000, HFPLL, 1, 0x24 }, L2(6), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(6), 1125000 },
+ { 0, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
+ { 0, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
+ { 1, { 1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
+ { 0, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
+ { 1, { 1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
+ { 0, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
+ { 1, { 1458000, HFPLL, 1, 0x36 }, L2(15), 1237500 },
+ { 1, { 1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
+ { 1, { 1566000, HFPLL, 1, 0x3A }, L2(15), 1250000 },
+ { 1, { 1620000, HFPLL, 1, 0x3C }, L2(15), 1250000 },
+ { 1, { 1674000, HFPLL, 1, 0x3E }, L2(15), 1250000 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level tbl_slow_2p0[] __initdata = {
+ { 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 950000 },
+ { 0, { 432000, HFPLL, 2, 0x20 }, L2(6), 975000 },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(6), 975000 },
+ { 0, { 540000, HFPLL, 2, 0x28 }, L2(6), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(6), 1000000 },
+ { 0, { 648000, HFPLL, 1, 0x18 }, L2(6), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(6), 1025000 },
+ { 0, { 756000, HFPLL, 1, 0x1C }, L2(6), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(6), 1075000 },
+ { 0, { 864000, HFPLL, 1, 0x20 }, L2(6), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(6), 1100000 },
+ { 0, { 972000, HFPLL, 1, 0x24 }, L2(6), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(6), 1125000 },
+ { 0, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
+ { 0, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
+ { 1, { 1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
+ { 0, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
+ { 1, { 1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
+ { 0, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
+ { 1, { 1458000, HFPLL, 1, 0x36 }, L2(15), 1237500 },
+ { 1, { 1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
+ { 1, { 1566000, HFPLL, 1, 0x3A }, L2(15), 1250000 },
+ { 1, { 1620000, HFPLL, 1, 0x3C }, L2(15), 1250000 },
+ { 1, { 1674000, HFPLL, 1, 0x3E }, L2(15), 1250000 },
+ { 1, { 1728000, HFPLL, 1, 0x40 }, L2(15), 1250000 },
+ { 1, { 1782000, HFPLL, 1, 0x42 }, L2(15), 1250000 },
+ { 1, { 1836000, HFPLL, 1, 0x44 }, L2(15), 1250000 },
+ { 1, { 1890000, HFPLL, 1, 0x46 }, L2(15), 1250000 },
+ { 1, { 1944000, HFPLL, 1, 0x48 }, L2(15), 1250000 },
+ { 1, { 1998000, HFPLL, 1, 0x4A }, L2(15), 1250000 },
+ { 0, { 0 } }
+};
+
+static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+ [0][PVS_SLOW] = {tbl_slow, sizeof(tbl_slow), 0 },
+ [0][PVS_NOMINAL] = {tbl_nom, sizeof(tbl_nom), 25000 },
+ [0][PVS_FAST] = {tbl_fast, sizeof(tbl_fast), 25000 },
+ [0][PVS_FASTER] = {tbl_fast, sizeof(tbl_fast), 25000 },
+
+ [1][0] = { tbl_slow_1p7, sizeof(tbl_slow_1p7), 0 },
+ [1][1] = { tbl_slow_1p7, sizeof(tbl_slow_1p7), 0 },
+ [1][2] = { tbl_slow_1p7, sizeof(tbl_slow_1p7), 0 },
+ [1][3] = { tbl_slow_1p7, sizeof(tbl_slow_1p7), 0 },
+ [1][4] = { tbl_slow_1p7, sizeof(tbl_slow_1p7), 0 },
+ [1][5] = { tbl_slow_1p7, sizeof(tbl_slow_1p7), 0 },
+ [1][6] = { tbl_slow_1p7, sizeof(tbl_slow_1p7), 0 },
+
+ [2][0] = { tbl_slow_2p0, sizeof(tbl_slow_2p0), 0 },
+ [2][1] = { tbl_slow_2p0, sizeof(tbl_slow_2p0), 0 },
+ [2][2] = { tbl_slow_2p0, sizeof(tbl_slow_2p0), 0 },
+ [2][3] = { tbl_slow_2p0, sizeof(tbl_slow_2p0), 0 },
+ [2][4] = { tbl_slow_2p0, sizeof(tbl_slow_2p0), 0 },
+ [2][5] = { tbl_slow_2p0, sizeof(tbl_slow_2p0), 0 },
+ [2][6] = { tbl_slow_2p0, sizeof(tbl_slow_2p0), 0 },
};
static struct acpuclk_krait_params acpuclk_8064_params __initdata = {
@@ -230,6 +316,12 @@
static int __init acpuclk_8064_probe(struct platform_device *pdev)
{
+ if (cpu_is_apq8064ab() ||
+ SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) {
+ acpuclk_8064_params.hfpll_data->low_vdd_l_max = 37;
+ acpuclk_8064_params.hfpll_data->nom_vdd_l_max = 74;
+ }
+
return acpuclk_krait_init(&pdev->dev, &acpuclk_8064_params);
}
diff --git a/arch/arm/mach-msm/acpuclock-8627.c b/arch/arm/mach-msm/acpuclock-8627.c
index da49656..ac29cac 100644
--- a/arch/arm/mach-msm/acpuclock-8627.c
+++ b/arch/arm/mach-msm/acpuclock-8627.c
@@ -127,10 +127,10 @@
{ 0, { 0 } }
};
-static struct pvs_table pvs_tables[NUM_PVS] __initdata = {
- [PVS_SLOW] = { acpu_freq_tbl, sizeof(acpu_freq_tbl), 0 },
- [PVS_NOMINAL] = { acpu_freq_tbl, sizeof(acpu_freq_tbl), 25000 },
- [PVS_FAST] = { acpu_freq_tbl, sizeof(acpu_freq_tbl), 25000 },
+static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+ [0][PVS_SLOW] = { acpu_freq_tbl, sizeof(acpu_freq_tbl), 0 },
+ [0][PVS_NOMINAL] = { acpu_freq_tbl, sizeof(acpu_freq_tbl), 25000 },
+ [0][PVS_FAST] = { acpu_freq_tbl, sizeof(acpu_freq_tbl), 25000 },
};
static struct acpuclk_krait_params acpuclk_8627_params __initdata = {
diff --git a/arch/arm/mach-msm/acpuclock-8930.c b/arch/arm/mach-msm/acpuclock-8930.c
index b4f2a1e..e46599a 100644
--- a/arch/arm/mach-msm/acpuclock-8930.c
+++ b/arch/arm/mach-msm/acpuclock-8930.c
@@ -213,10 +213,10 @@
{ 0, { 0 } }
};
-static struct pvs_table pvs_tables[NUM_PVS] __initdata = {
-[PVS_SLOW] = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
-[PVS_NOMINAL] = { acpu_freq_tbl_nom, sizeof(acpu_freq_tbl_nom), 25000 },
-[PVS_FAST] = { acpu_freq_tbl_fast, sizeof(acpu_freq_tbl_fast), 25000 },
+static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+[0][PVS_SLOW] = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
+[0][PVS_NOMINAL] = { acpu_freq_tbl_nom, sizeof(acpu_freq_tbl_nom), 25000 },
+[0][PVS_FAST] = { acpu_freq_tbl_fast, sizeof(acpu_freq_tbl_fast), 25000 },
};
static struct acpuclk_krait_params acpuclk_8930_params __initdata = {
diff --git a/arch/arm/mach-msm/acpuclock-8930aa.c b/arch/arm/mach-msm/acpuclock-8930aa.c
index bcb00ea..9d2b6fc 100644
--- a/arch/arm/mach-msm/acpuclock-8930aa.c
+++ b/arch/arm/mach-msm/acpuclock-8930aa.c
@@ -189,10 +189,10 @@
{ 0, { 0 } }
};
-static struct pvs_table pvs_tables[NUM_PVS] __initdata = {
-[PVS_SLOW] = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
-[PVS_NOMINAL] = { acpu_freq_tbl_nom, sizeof(acpu_freq_tbl_nom), 25000 },
-[PVS_FAST] = { acpu_freq_tbl_fast, sizeof(acpu_freq_tbl_fast), 25000 },
+static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+[0][PVS_SLOW] = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
+[0][PVS_NOMINAL] = { acpu_freq_tbl_nom, sizeof(acpu_freq_tbl_nom), 25000 },
+[0][PVS_FAST] = { acpu_freq_tbl_fast, sizeof(acpu_freq_tbl_fast), 25000 },
};
static struct acpuclk_krait_params acpuclk_8930aa_params __initdata = {
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index cf6a6c2..d7d3edd 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -195,10 +195,10 @@
{ 0, { 0 } }
};
-static struct pvs_table pvs_tables[NUM_PVS] __initdata = {
-[PVS_SLOW] = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
-[PVS_NOMINAL] = { acpu_freq_tbl_nom, sizeof(acpu_freq_tbl_nom), 25000 },
-[PVS_FAST] = { acpu_freq_tbl_fast, sizeof(acpu_freq_tbl_fast), 25000 },
+static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+[0][PVS_SLOW] = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
+[0][PVS_NOMINAL] = { acpu_freq_tbl_nom, sizeof(acpu_freq_tbl_nom), 25000 },
+[0][PVS_FAST] = { acpu_freq_tbl_fast, sizeof(acpu_freq_tbl_fast), 25000 },
};
static struct acpuclk_krait_params acpuclk_8960_params __initdata = {
diff --git a/arch/arm/mach-msm/acpuclock-8960ab.c b/arch/arm/mach-msm/acpuclock-8960ab.c
index 91ccd37..ae1cd7b 100644
--- a/arch/arm/mach-msm/acpuclock-8960ab.c
+++ b/arch/arm/mach-msm/acpuclock-8960ab.c
@@ -135,10 +135,10 @@
{ 0, { 0 } }
};
-static struct pvs_table pvs_tables[NUM_PVS] __initdata = {
-[PVS_SLOW] = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
-[PVS_NOMINAL] = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
-[PVS_FAST] = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
+static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+[0][PVS_SLOW] = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
+[0][PVS_NOMINAL] = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
+[0][PVS_FAST] = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
};
static struct acpuclk_krait_params acpuclk_8960ab_params __initdata = {
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index 4a755bd..098f854 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -170,10 +170,10 @@
{ 0, { 0 } }
};
-static struct pvs_table pvs_tables[NUM_PVS] __initdata = {
- [PVS_SLOW] = { acpu_freq_tbl, sizeof(acpu_freq_tbl) },
- [PVS_NOMINAL] = { acpu_freq_tbl, sizeof(acpu_freq_tbl) },
- [PVS_FAST] = { acpu_freq_tbl, sizeof(acpu_freq_tbl) },
+static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+ [0][PVS_SLOW] = { acpu_freq_tbl, sizeof(acpu_freq_tbl) },
+ [0][PVS_NOMINAL] = { acpu_freq_tbl, sizeof(acpu_freq_tbl) },
+ [0][PVS_FAST] = { acpu_freq_tbl, sizeof(acpu_freq_tbl) },
};
static struct acpuclk_krait_params acpuclk_8974_params __initdata = {
diff --git a/arch/arm/mach-msm/acpuclock-krait.c b/arch/arm/mach-msm/acpuclock-krait.c
index 79c01b2..57c4411 100644
--- a/arch/arm/mach-msm/acpuclock-krait.c
+++ b/arch/arm/mach-msm/acpuclock-krait.c
@@ -946,58 +946,68 @@
}
}
-static int __init select_freq_plan(u32 pte_efuse_phys)
+static int __init get_speed_bin(u32 pte_efuse)
+{
+ uint32_t speed_bin;
+
+ speed_bin = pte_efuse & 0xF;
+ if (speed_bin == 0xF)
+ speed_bin = (pte_efuse >> 4) & 0xF;
+
+ if (speed_bin == 0xF) {
+ speed_bin = 0;
+ dev_warn(drv.dev, "SPEED BIN: Defaulting to %d\n", speed_bin);
+ } else {
+ dev_info(drv.dev, "SPEED BIN: %d\n", speed_bin);
+ }
+
+ return speed_bin;
+}
+
+static int __init get_pvs_bin(u32 pte_efuse)
+{
+ uint32_t pvs_bin;
+
+ pvs_bin = (pte_efuse >> 10) & 0x7;
+ if (pvs_bin == 0x7)
+ pvs_bin = (pte_efuse >> 13) & 0x7;
+
+ if (pvs_bin == 0x7) {
+ pvs_bin = 0;
+ dev_warn(drv.dev, "ACPU PVS: Defaulting to %d\n", pvs_bin);
+ } else {
+ dev_info(drv.dev, "ACPU PVS: %d\n", pvs_bin);
+ }
+
+ return pvs_bin;
+}
+
+static struct pvs_table * __init select_freq_plan(u32 pte_efuse_phys,
+ struct pvs_table (*pvs_tables)[NUM_PVS])
{
void __iomem *pte_efuse;
- u32 pte_efuse_val, pvs, tbl_idx;
- char *pvs_names[] = { "Slow", "Nominal", "Fast", "Faster", "Unknown" };
+ u32 pte_efuse_val, tbl_idx, bin_idx;
pte_efuse = ioremap(pte_efuse_phys, 4);
- /* Select frequency tables. */
- if (pte_efuse) {
- pte_efuse_val = readl_relaxed(pte_efuse);
- pvs = (pte_efuse_val >> 10) & 0x7;
- iounmap(pte_efuse);
- if (pvs == 0x7)
- pvs = (pte_efuse_val >> 13) & 0x7;
-
- switch (pvs) {
- case 0x0:
- case 0x7:
- tbl_idx = PVS_SLOW;
- break;
- case 0x1:
- tbl_idx = PVS_NOMINAL;
- break;
- case 0x3:
- tbl_idx = PVS_FAST;
- break;
- case 0x4:
- tbl_idx = PVS_FASTER;
- break;
- default:
- tbl_idx = PVS_UNKNOWN;
- break;
- }
- } else {
- tbl_idx = PVS_UNKNOWN;
+ if (!pte_efuse) {
dev_err(drv.dev, "Unable to map QFPROM base\n");
- }
- if (tbl_idx == PVS_UNKNOWN) {
- tbl_idx = PVS_SLOW;
- dev_warn(drv.dev, "ACPU PVS: Defaulting to %s\n",
- pvs_names[tbl_idx]);
- } else {
- dev_info(drv.dev, "ACPU PVS: %s\n", pvs_names[tbl_idx]);
+ return NULL;
}
- return tbl_idx;
+ pte_efuse_val = readl_relaxed(pte_efuse);
+ iounmap(pte_efuse);
+
+ /* Select frequency tables. */
+ bin_idx = get_speed_bin(pte_efuse_val);
+ tbl_idx = get_pvs_bin(pte_efuse_val);
+
+ return &pvs_tables[bin_idx][tbl_idx];
}
static void __init drv_data_init(struct device *dev,
const struct acpuclk_krait_params *params)
{
- int tbl_idx;
+ struct pvs_table *pvs;
drv.dev = dev;
drv.scalable = kmemdup(params->scalable, params->scalable_size,
@@ -1020,12 +1030,12 @@
GFP_KERNEL);
BUG_ON(!drv.bus_scale->usecase);
- tbl_idx = select_freq_plan(params->pte_efuse_phys);
- drv.acpu_freq_tbl = kmemdup(params->pvs_tables[tbl_idx].table,
- params->pvs_tables[tbl_idx].size,
- GFP_KERNEL);
+ pvs = select_freq_plan(params->pte_efuse_phys, params->pvs_tables);
+ BUG_ON(!pvs->table);
+
+ drv.acpu_freq_tbl = kmemdup(pvs->table, pvs->size, GFP_KERNEL);
BUG_ON(!drv.acpu_freq_tbl);
- drv.boost_uv = params->pvs_tables[tbl_idx].boost_uv;
+ drv.boost_uv = pvs->boost_uv;
acpuclk_krait_data.power_collapse_khz = params->stby_khz;
acpuclk_krait_data.wait_for_irq_khz = params->stby_khz;
diff --git a/arch/arm/mach-msm/acpuclock-krait.h b/arch/arm/mach-msm/acpuclock-krait.h
index 84a5b5e..3fa10e3 100644
--- a/arch/arm/mach-msm/acpuclock-krait.h
+++ b/arch/arm/mach-msm/acpuclock-krait.h
@@ -46,14 +46,18 @@
*/
enum pvs {
PVS_SLOW = 0,
- PVS_NOMINAL,
- PVS_FAST,
- PVS_FASTER,
- PVS_UNKNOWN,
- NUM_PVS
+ PVS_NOMINAL = 1,
+ PVS_FAST = 3,
+ PVS_FASTER = 4,
+ NUM_PVS = 7
};
/**
+ * The maximum number of speed bins.
+ */
+#define NUM_SPEED_BINS (16)
+
+/**
* enum scalables - IDs of frequency scalable hardware blocks.
*/
enum scalables {
@@ -186,8 +190,8 @@
const bool has_droop_ctl;
const u32 droop_offset;
const u32 droop_val;
- const u32 low_vdd_l_max;
- const u32 nom_vdd_l_max;
+ u32 low_vdd_l_max;
+ u32 nom_vdd_l_max;
const u32 low_vco_l_max;
const int vdd[NUM_HFPLL_VDD];
};
@@ -237,7 +241,7 @@
* @scalable: Array of scalables.
* @scalable_size: Size of @scalable.
* @hfpll_data: HFPLL configuration data.
- * @pvs_tables: CPU frequency tables.
+ * @pvs_tables: 2D array of CPU frequency tables.
* @l2_freq_tbl: L2 frequency table.
* @l2_freq_tbl_size: Size of @l2_freq_tbl.
* @pte_efuse_phys: Physical address of PTE EFUSE.
@@ -248,7 +252,7 @@
struct scalable *scalable;
size_t scalable_size;
struct hfpll_data *hfpll_data;
- struct pvs_table *pvs_tables;
+ struct pvs_table (*pvs_tables)[NUM_PVS];
struct l2_level *l2_freq_tbl;
size_t l2_freq_tbl_size;
phys_addr_t pte_efuse_phys;
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index a08f45c..cb03d4b 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -31,6 +31,7 @@
.drv = GPIOMUX_DRV_8MA,
.func = GPIOMUX_FUNC_GPIO,
};
+#endif
/* The SPI configurations apply to GSBI 5*/
static struct gpiomux_setting gpio_spi_config = {
@@ -60,6 +61,7 @@
.pull = GPIOMUX_PULL_UP,
};
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
struct msm_gpiomux_config apq8064_ethernet_configs[] = {
{
.gpio = 43,
@@ -361,6 +363,22 @@
.pull = GPIOMUX_PULL_NONE,
};
+static struct gpiomux_setting audio_auxpcm[] = {
+/* Suspended state */
+ {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+ },
+/* Active state */
+ {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+ },
+};
+
+
static struct gpiomux_setting wcnss_5wire_suspend_cfg = {
.func = GPIOMUX_FUNC_GPIO,
.drv = GPIOMUX_DRV_2MA,
@@ -682,7 +700,6 @@
[GPIOMUX_SUSPENDED] = &gsbi1_uart_config,
},
},
-#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
{
.gpio = 51, /* GSBI5 QUP SPI_DATA_MOSI */
.settings = {
@@ -713,7 +730,6 @@
[GPIOMUX_SUSPENDED] = &gpio_spi_config,
},
},
-#endif
{
.gpio = 30, /* FP CS */
.settings = {
@@ -846,6 +862,37 @@
},
};
+static struct msm_gpiomux_config mpq8064_audio_auxpcm_configs[] __initdata = {
+ {
+ .gpio = 43,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+ [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+ },
+ },
+ {
+ .gpio = 44,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+ [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+ },
+ },
+ {
+ .gpio = 45,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+ [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+ },
+ },
+ {
+ .gpio = 46,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+ [GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+ },
+ },
+};
+
/* External 3.3 V regulator enable */
static struct msm_gpiomux_config apq8064_ext_regulator_configs[] __initdata = {
{
@@ -1527,6 +1574,10 @@
if (machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd() ||
machine_is_mpq8064_dtv()) {
+
+ msm_gpiomux_install(mpq8064_audio_auxpcm_configs,
+ ARRAY_SIZE(mpq8064_audio_auxpcm_configs));
+
msm_gpiomux_install(mpq8064_spkr_i2s_config,
ARRAY_SIZE(mpq8064_spkr_i2s_config));
}
diff --git a/arch/arm/mach-msm/board-8064-gpu.c b/arch/arm/mach-msm/board-8064-gpu.c
index 122505e..68debff 100644
--- a/arch/arm/mach-msm/board-8064-gpu.c
+++ b/arch/arm/mach-msm/board-8064-gpu.c
@@ -251,11 +251,17 @@
{
unsigned int version = socinfo_get_version();
- if ((SOCINFO_VERSION_MAJOR(version) == 1) &&
- (SOCINFO_VERSION_MINOR(version) == 1))
- kgsl_3d0_pdata.chipid = ADRENO_CHIPID(3, 2, 0, 1);
- else
- kgsl_3d0_pdata.chipid = ADRENO_CHIPID(3, 2, 0, 0);
+ if (cpu_is_apq8064ab())
+ kgsl_3d0_pdata.pwrlevel[0].gpu_freq = 450000000;
+ if (SOCINFO_VERSION_MAJOR(version) == 2) {
+ kgsl_3d0_pdata.chipid = ADRENO_CHIPID(3, 2, 0, 2);
+ } else {
+ if ((SOCINFO_VERSION_MAJOR(version) == 1) &&
+ (SOCINFO_VERSION_MINOR(version) == 1))
+ kgsl_3d0_pdata.chipid = ADRENO_CHIPID(3, 2, 0, 1);
+ else
+ kgsl_3d0_pdata.chipid = ADRENO_CHIPID(3, 2, 0, 0);
+ }
platform_device_register(&device_kgsl_3d0);
}
diff --git a/arch/arm/mach-msm/board-8064-storage.c b/arch/arm/mach-msm/board-8064-storage.c
index c81a637..379d7ae 100644
--- a/arch/arm/mach-msm/board-8064-storage.c
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -338,6 +338,11 @@
apq8064_add_sdcc(2, apq8064_sdc2_pdata);
if (apq8064_sdc3_pdata) {
+ if (machine_is_mpq8064_hrd() || machine_is_mpq8064_dtv()) {
+ apq8064_sdc3_pdata->uhs_caps &= ~(MMC_CAP_UHS_SDR12 |
+ MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_DDR50 |
+ MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104);
+ }
if (!machine_is_apq8064_cdp()) {
apq8064_sdc3_pdata->wpswitch_gpio = 0;
apq8064_sdc3_pdata->is_wpswitch_active_low = false;
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 1efc64b..2fd1a68 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1769,6 +1769,27 @@
},
};
+static struct msm_bus_vectors qseecom_enable_dfab_sfpb_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_ADM_PORT0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 70000000UL,
+ .ib = 70000000UL,
+ },
+ {
+ .src = MSM_BUS_MASTER_ADM_PORT1,
+ .dst = MSM_BUS_SLAVE_GSBI1_UART,
+ .ab = 2480000000UL,
+ .ib = 2480000000UL,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPDM,
+ .dst = MSM_BUS_SLAVE_SPDM,
+ .ib = (64 * 8) * 1000000UL,
+ .ab = (64 * 8) * 100000UL,
+ },
+};
+
static struct msm_bus_paths qseecom_hw_bus_scale_usecases[] = {
{
ARRAY_SIZE(qseecom_clks_init_vectors),
@@ -1782,6 +1803,10 @@
ARRAY_SIZE(qseecom_enable_sfpb_vectors),
qseecom_enable_sfpb_vectors,
},
+ {
+ ARRAY_SIZE(qseecom_enable_dfab_sfpb_vectors),
+ qseecom_enable_dfab_sfpb_vectors,
+ },
};
static struct msm_bus_scale_pdata qseecom_bus_pdata = {
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index b84e66e..ed876c0 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1048,6 +1048,27 @@
},
};
+static struct msm_bus_vectors qseecom_enable_dfab_sfpb_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ib = (492 * 8) * 1000000UL,
+ .ab = (492 * 8) * 100000UL,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_SPS,
+ .ib = (492 * 8) * 1000000UL,
+ .ab = (492 * 8) * 100000UL,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPDM,
+ .dst = MSM_BUS_SLAVE_SPDM,
+ .ib = (64 * 8) * 1000000UL,
+ .ab = (64 * 8) * 100000UL,
+ },
+};
+
static struct msm_bus_paths qseecom_hw_bus_scale_usecases[] = {
{
ARRAY_SIZE(qseecom_clks_init_vectors),
@@ -1061,6 +1082,10 @@
ARRAY_SIZE(qseecom_enable_sfpb_vectors),
qseecom_enable_sfpb_vectors,
},
+ {
+ ARRAY_SIZE(qseecom_enable_dfab_sfpb_vectors),
+ qseecom_enable_dfab_sfpb_vectors,
+ },
};
static struct msm_bus_scale_pdata qseecom_bus_pdata = {
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index d93a4fa..947b53f 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1113,6 +1113,27 @@
},
};
+static struct msm_bus_vectors qseecom_enable_dfab_sfpb_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ib = (492 * 8) * 1000000UL,
+ .ab = (492 * 8) * 100000UL,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_SPS,
+ .ib = (492 * 8) * 1000000UL,
+ .ab = (492 * 8) * 100000UL,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPDM,
+ .dst = MSM_BUS_SLAVE_SPDM,
+ .ib = (64 * 8) * 1000000UL,
+ .ab = (64 * 8) * 100000UL,
+ },
+};
+
static struct msm_bus_paths qseecom_hw_bus_scale_usecases[] = {
{
ARRAY_SIZE(qseecom_clks_init_vectors),
@@ -1126,6 +1147,10 @@
ARRAY_SIZE(qseecom_enable_sfpb_vectors),
qseecom_enable_sfpb_vectors,
},
+ {
+ ARRAY_SIZE(qseecom_enable_dfab_sfpb_vectors),
+ qseecom_enable_dfab_sfpb_vectors,
+ },
};
static struct msm_bus_scale_pdata qseecom_bus_pdata = {
diff --git a/arch/arm/mach-msm/board-8974-gpiomux.c b/arch/arm/mach-msm/board-8974-gpiomux.c
index 1577a2b..8568340 100644
--- a/arch/arm/mach-msm/board-8974-gpiomux.c
+++ b/arch/arm/mach-msm/board-8974-gpiomux.c
@@ -271,6 +271,30 @@
[GPIOMUX_SUSPENDED] = &gpio_uart_config,
},
},
+ {
+ .gpio = 53, /* BLSP2 QUP4 SPI_DATA_MOSI */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ },
+ },
+ {
+ .gpio = 54, /* BLSP2 QUP4 SPI_DATA_MISO */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ },
+ },
+ {
+ .gpio = 56, /* BLSP2 QUP4 SPI_CLK */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ },
+ },
+ {
+ .gpio = 55, /* BLSP2 QUP4 SPI_CS0_N */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ },
+ },
};
static struct msm_gpiomux_config msm8974_slimbus_config[] __initdata = {
diff --git a/arch/arm/mach-msm/board-9625.c b/arch/arm/mach-msm/board-9625.c
index 5f556fb..797f5f1 100644
--- a/arch/arm/mach-msm/board-9625.c
+++ b/arch/arm/mach-msm/board-9625.c
@@ -103,7 +103,7 @@
pr_err("%s: socinfo_init() failed\n", __func__);
msm9625_init_gpiomux();
- msm_clock_init(&msm9625_clock_init_data);
+ msm_clock_init(&msm_dummy_clock_init_data);
of_platform_populate(NULL, of_default_bus_match_table,
msm9625_auxdata_lookup, NULL);
}
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 2a51e66..13c4be2 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -841,7 +841,7 @@
static void __init msm8625_reserve(void)
{
msm7x27a_reserve();
- memblock_remove(MSM8625_SECONDARY_PHYS, SZ_8);
+ memblock_remove(MSM8625_CPU_PHYS, SZ_8);
memblock_remove(MSM8625_WARM_BOOT_PHYS, SZ_32);
}
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 205db58..ee13e04 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -5190,7 +5190,7 @@
int bahama_not_marimba = bahama_present();
- if (bahama_not_marimba == -1) {
+ if (bahama_not_marimba < 0) {
printk(KERN_WARNING "%s: bahama_present: %d\n",
__func__, bahama_not_marimba);
return -ENODEV;
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index ed1fafc..ec8e438 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -812,7 +812,7 @@
static void __init msm8625_reserve(void)
{
- memblock_remove(MSM8625_SECONDARY_PHYS, SZ_8);
+ memblock_remove(MSM8625_CPU_PHYS, SZ_8);
msm7627a_reserve();
}
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index b60f693..2cd2cd4 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -1534,6 +1534,11 @@
static CLK_SDC(sdc4_clk, 4, 3, 33000000, 67000000);
static CLK_SDC(sdc5_clk, 5, 2, 33000000, 67000000);
+static unsigned long fmax_sdc1_8064v2[MAX_VDD_LEVELS] __initdata = {
+ [VDD_DIG_LOW] = 100000000,
+ [VDD_DIG_NOMINAL] = 200000000,
+};
+
#define F_TSIF_REF(f, s, d, m, n) \
{ \
.freq_hz = f, \
@@ -1907,6 +1912,7 @@
F_CE3( 0, gnd, 1),
F_CE3( 48000000, pll8, 8),
F_CE3(100000000, pll3, 12),
+ F_CE3(120000000, pll3, 10),
F_END
};
@@ -1929,6 +1935,11 @@
},
};
+static unsigned long fmax_ce3_8064v2[MAX_VDD_LEVELS] __initdata = {
+ [VDD_DIG_LOW] = 57000000,
+ [VDD_DIG_NOMINAL] = 120000000,
+};
+
static struct branch_clk ce3_core_clk = {
.b = {
.ctl_reg = CE3_CORE_CLK_CTL_REG,
@@ -3540,11 +3551,12 @@
F_GFX3D(145455000, pll2, 2, 11),
F_GFX3D(160000000, pll2, 1, 5),
F_GFX3D(177778000, pll2, 2, 9),
+ F_GFX3D(192000000, pll8, 1, 2),
F_GFX3D(200000000, pll2, 1, 4),
F_GFX3D(228571000, pll2, 2, 7),
F_GFX3D(266667000, pll2, 1, 3),
- F_GFX3D(325000000, pll15, 1, 3),
F_GFX3D(400000000, pll2, 1, 2),
+ F_GFX3D(450000000, pll15, 1, 2),
F_END
};
@@ -3570,6 +3582,12 @@
F_END
};
+static unsigned long fmax_gfx3d_8064ab[MAX_VDD_LEVELS] __initdata = {
+ [VDD_DIG_LOW] = 128000000,
+ [VDD_DIG_NOMINAL] = 325000000,
+ [VDD_DIG_HIGH] = 450000000
+};
+
static unsigned long fmax_gfx3d_8064[MAX_VDD_LEVELS] __initdata = {
[VDD_DIG_LOW] = 128000000,
[VDD_DIG_NOMINAL] = 325000000,
@@ -4295,6 +4313,7 @@
F_VCODEC(133330000, pll2, 1, 6),
F_VCODEC(200000000, pll2, 1, 4),
F_VCODEC(228570000, pll2, 2, 7),
+ F_VCODEC(266670000, pll2, 1, 3),
F_END
};
@@ -4325,6 +4344,12 @@
},
};
+static unsigned long fmax_vcodec_8064v2[MAX_VDD_LEVELS] __initdata = {
+ [VDD_DIG_LOW] = 100000000,
+ [VDD_DIG_NOMINAL] = 200000000,
+ [VDD_DIG_HIGH] = 266670000,
+};
+
#define F_VPE(f, s, d) \
{ \
.freq_hz = f, \
@@ -5065,6 +5090,8 @@
writel_relaxed(0x80|BVAL(5, 3, clk_sel), GCC_APCS_CLK_DIAG);
measure->sample_ticks = 0x4000;
measure->multiplier = 2;
+ if (cpu_is_krait_v3())
+ measure->multiplier = 8;
break;
default:
ret = -EPERM;
@@ -6302,7 +6329,7 @@
writel_relaxed(0x3C7097F9, AHB_EN2_REG);
}
- if (cpu_is_apq8064())
+ if (cpu_is_apq8064() || cpu_is_apq8064ab())
rmwreg(0x00000001, AHB_EN3_REG, 0x00000001);
/* Deassert all locally-owned MM AHB resets. */
@@ -6325,7 +6352,7 @@
rmwreg(0x0027FCFF, MAXI_EN3_REG, 0x003FFFFF);
rmwreg(0x0027FCFF, MAXI_EN4_REG, 0x017FFFFF);
- if (cpu_is_apq8064())
+ if (cpu_is_apq8064() || cpu_is_apq8064ab())
rmwreg(0x019FECFF, MAXI_EN5_REG, 0x01FFEFFF);
if (cpu_is_msm8930() || cpu_is_msm8930aa() || cpu_is_msm8627())
rmwreg(0x000004FF, MAXI_EN5_REG, 0x00000FFF);
@@ -6363,7 +6390,8 @@
rmwreg(0x80FF0000, VFE_CC_REG, 0xE0FF4010);
rmwreg(0x800000FF, VFE_CC2_REG, 0xE00000FF);
rmwreg(0x80FF0000, VPE_CC_REG, 0xE0FF0010);
- if (cpu_is_msm8960ab() || cpu_is_msm8960() || cpu_is_apq8064()) {
+ if (cpu_is_msm8960ab() || cpu_is_msm8960() || cpu_is_apq8064()
+ || cpu_is_apq8064ab()) {
rmwreg(0x80FF0000, DSI2_BYTE_CC_REG, 0xE0FF0010);
rmwreg(0x80FF0000, DSI2_PIXEL_CC_REG, 0xE0FF0010);
rmwreg(0x80FF0000, JPEGD_CC_REG, 0xE0FF0010);
@@ -6381,7 +6409,7 @@
rmwreg(0x80FF0000, GFX2D0_CC_REG, 0xE0FF0010);
rmwreg(0x80FF0000, GFX2D1_CC_REG, 0xE0FF0010);
}
- if (cpu_is_apq8064()) {
+ if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
rmwreg(0x00000000, TV_CC_REG, 0x00004010);
rmwreg(0x80FF0000, VCAP_CC_REG, 0xE0FF1010);
}
@@ -6392,7 +6420,7 @@
* and wake-up value to max.
*/
rmwreg(0x0000004F, USB_HS1_HCLK_FS_REG, 0x0000007F);
- if (cpu_is_apq8064()) {
+ if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
rmwreg(0x0000004F, USB_HS3_HCLK_FS_REG, 0x0000007F);
rmwreg(0x0000004F, USB_HS4_HCLK_FS_REG, 0x0000007F);
}
@@ -6414,7 +6442,8 @@
/* Source the dsi_byte_clks from the DSI PHY PLLs */
rmwreg(0x1, DSI1_BYTE_NS_REG, 0x7);
- if (cpu_is_msm8960ab() || cpu_is_msm8960() || cpu_is_apq8064())
+ if (cpu_is_msm8960ab() || cpu_is_msm8960() || cpu_is_apq8064()
+ || cpu_is_apq8064ab())
rmwreg(0x2, DSI2_BYTE_NS_REG, 0x7);
/* Source the dsi1_esc_clk from the DSI1 PHY PLLs */
@@ -6424,7 +6453,7 @@
* Source the sata_phy_ref_clk from PXO and set predivider of
* sata_pmalive_clk to 1.
*/
- if (cpu_is_apq8064()) {
+ if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
rmwreg(0, SATA_PHY_REF_CLK_CTL_REG, 0x1);
rmwreg(0, SATA_PMALIVE_CLK_CTL_REG, 0x3);
}
@@ -6433,7 +6462,7 @@
* TODO: Programming below PLLs and prng_clk is temporary and
* needs to be removed after bootloaders program them.
*/
- if (cpu_is_apq8064()) {
+ if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
u32 is_pll_enabled;
/* Program pxo_src_clk to source from PXO */
@@ -6445,9 +6474,6 @@
/* Ref clk = 27MHz and program pll14 to 480MHz */
configure_sr_pll(&pll14_config, &pll14_regs, 1);
- /* Program PLL15 to 975MHz with ref clk = 27MHz */
- configure_sr_pll(&pll15_config, &pll15_regs, 0);
-
/* Check if PLL4 is active */
is_pll_enabled = readl_relaxed(LCC_PLL0_STATUS_REG) & BIT(16);
if (!is_pll_enabled)
@@ -6462,6 +6488,17 @@
writel_relaxed(0x2B, PRNG_CLK_NS_REG);
}
+ if (cpu_is_apq8064()) {
+ /* Program PLL15 to 975MHz with ref clk = 27MHz */
+ configure_sr_pll(&pll15_config, &pll15_regs, 0);
+ } else if (cpu_is_apq8064ab()) {
+ /* Program PLL15 to 900MHZ */
+ pll15_config.l = 0x21 | BVAL(31, 7, 0x620);
+ pll15_config.m = 0x1;
+ pll15_config.n = 0x3;
+ configure_sr_pll(&pll15_config, &pll15_regs, 0);
+ }
+
/*
* Program PLL15 to 900MHz with ref clk = 27MHz and
* only enable PLL main output.
@@ -6482,7 +6519,7 @@
/* Initialize clock registers. */
reg_init();
- if (cpu_is_apq8064())
+ if (cpu_is_apq8064() || cpu_is_apq8064ab())
vdd_sr2_hdmi_pll.set_vdd = set_vdd_sr2_hdmi_pll_8064;
/* Detect PLL4 programmed for alternate 491.52MHz clock plan. */
@@ -6524,13 +6561,32 @@
}
/*
* Change the freq tables for and voltage requirements for
- * clocks which differ between 8960 and 8064.
+ * clocks which differ between chips.
*/
if (cpu_is_apq8064()) {
gfx3d_clk.freq_tbl = clk_tbl_gfx3d_8064;
memcpy(gfx3d_clk.c.fmax, fmax_gfx3d_8064,
sizeof(gfx3d_clk.c.fmax));
+ }
+ if (cpu_is_apq8064ab()) {
+ gfx3d_clk.freq_tbl = clk_tbl_gfx3d_8064;
+
+ memcpy(gfx3d_clk.c.fmax, fmax_gfx3d_8064ab,
+ sizeof(gfx3d_clk.c.fmax));
+ }
+ if ((cpu_is_apq8064() &&
+ SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) ||
+ cpu_is_apq8064ab()) {
+
+ memcpy(vcodec_clk.c.fmax, fmax_vcodec_8064v2,
+ sizeof(vcodec_clk.c.fmax));
+ memcpy(ce3_src_clk.c.fmax, fmax_ce3_8064v2,
+ sizeof(ce3_src_clk.c.fmax));
+ memcpy(sdc1_clk.c.fmax, fmax_sdc1_8064v2,
+ sizeof(sdc1_clk.c.fmax));
+ }
+ if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
memcpy(ijpeg_clk.c.fmax, fmax_ijpeg_8064,
sizeof(ijpeg_clk.c.fmax));
memcpy(mdp_clk.c.fmax, fmax_mdp_8064,
@@ -6606,7 +6662,7 @@
clk_set_rate(&tsif_ref_clk.c, 105000);
clk_set_rate(&tssc_clk.c, 27000000);
clk_set_rate(&usb_hs1_xcvr_clk.c, 60000000);
- if (cpu_is_apq8064()) {
+ if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
clk_set_rate(&usb_hs3_xcvr_clk.c, 60000000);
clk_set_rate(&usb_hs4_xcvr_clk.c, 60000000);
}
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index a64e6a5..10de231 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -2183,6 +2183,18 @@
},
};
+struct branch_clk gcc_sys_noc_usb3_axi_clk = {
+ .cbcr_reg = SYS_NOC_USB3_AXI_CBCR,
+ .parent = &usb30_master_clk_src.c,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sys_noc_usb3_axi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sys_noc_usb3_axi_clk.c),
+ },
+};
+
static struct branch_clk gcc_usb30_master_clk = {
.cbcr_reg = USB30_MASTER_CBCR,
.bcr_reg = USB_30_BCR,
@@ -2193,6 +2205,7 @@
.dbg_name = "gcc_usb30_master_clk",
.ops = &clk_ops_branch,
CLK_INIT(gcc_usb30_master_clk.c),
+ .depends = &gcc_sys_noc_usb3_axi_clk.c,
},
};
@@ -2207,18 +2220,6 @@
},
};
-struct branch_clk gcc_sys_noc_usb3_axi_clk = {
- .cbcr_reg = SYS_NOC_USB3_AXI_CBCR,
- .parent = &usb30_master_clk_src.c,
- .has_sibling = 1,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_sys_noc_usb3_axi_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_sys_noc_usb3_axi_clk.c),
- },
-};
-
struct branch_clk gcc_usb30_sleep_clk = {
.cbcr_reg = USB30_SLEEP_CBCR,
.has_sibling = 1,
@@ -5039,6 +5040,7 @@
CLK_LOOKUP("core_clk", gcc_blsp1_uart6_apps_clk.c, ""),
CLK_LOOKUP("iface_clk", gcc_blsp2_ahb_clk.c, "f9967000.i2c"),
+ CLK_LOOKUP("iface_clk", gcc_blsp2_ahb_clk.c, "f9966000.spi"),
CLK_LOOKUP("iface_clk", gcc_blsp2_ahb_clk.c, "f995e000.serial"),
CLK_LOOKUP("core_clk", gcc_blsp2_qup1_i2c_apps_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_blsp2_qup1_spi_apps_clk.c, ""),
@@ -5047,8 +5049,8 @@
CLK_LOOKUP("core_clk", gcc_blsp2_qup3_i2c_apps_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_blsp2_qup3_spi_apps_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_blsp2_qup4_i2c_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp2_qup4_spi_apps_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_blsp2_qup5_i2c_apps_clk.c, "f9967000.i2c"),
+ CLK_LOOKUP("core_clk", gcc_blsp2_qup4_spi_apps_clk.c, "f9966000.spi"),
CLK_LOOKUP("core_clk", gcc_blsp2_qup5_spi_apps_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_blsp2_qup6_i2c_apps_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_blsp2_qup6_spi_apps_clk.c, ""),
diff --git a/arch/arm/mach-msm/clock-9625.c b/arch/arm/mach-msm/clock-9625.c
deleted file mode 100644
index a07eebb..0000000
--- a/arch/arm/mach-msm/clock-9625.c
+++ /dev/null
@@ -1,2278 +0,0 @@
-/* Copyright (c) 2012, 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 <linux/init.h>
-#include <linux/err.h>
-#include <linux/ctype.h>
-#include <linux/io.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-
-#include <mach/clk.h>
-#include <mach/rpm-regulator-smd.h>
-#include <mach/socinfo.h>
-
-#include "clock-local2.h"
-#include "clock-pll.h"
-#include "clock-rpm.h"
-#include "clock-voter.h"
-#include "clock.h"
-
-enum {
- GCC_BASE,
- LPASS_BASE,
- APCS_BASE,
- APCS_PLL_BASE,
- N_BASES,
-};
-
-static void __iomem *virt_bases[N_BASES];
-
-#define GCC_REG_BASE(x) (void __iomem *)(virt_bases[GCC_BASE] + (x))
-#define LPASS_REG_BASE(x) (void __iomem *)(virt_bases[LPASS_BASE] + (x))
-#define APCS_REG_BASE(x) (void __iomem *)(virt_bases[APCS_BASE] + (x))
-#define APCS_PLL_REG_BASE(x) (void __iomem *)(virt_bases[APCS_PLL_BASE] + (x))
-
-/* GCC registers */
-#define GPLL0_MODE_REG 0x0000
-#define GPLL0_L_REG 0x0004
-#define GPLL0_M_REG 0x0008
-#define GPLL0_N_REG 0x000C
-#define GPLL0_USER_CTL_REG 0x0010
-#define GPLL0_CONFIG_CTL_REG 0x0014
-#define GPLL0_TEST_CTL_REG 0x0018
-#define GPLL0_STATUS_REG 0x001C
-
-#define GPLL1_MODE_REG 0x0040
-#define GPLL1_L_REG 0x0044
-#define GPLL1_M_REG 0x0048
-#define GPLL1_N_REG 0x004C
-#define GPLL1_USER_CTL_REG 0x0050
-#define GPLL1_CONFIG_CTL_REG 0x0054
-#define GPLL1_TEST_CTL_REG 0x0058
-#define GPLL1_STATUS_REG 0x005C
-
-#define GCC_DEBUG_CLK_CTL_REG 0x1880
-#define CLOCK_FRQ_MEASURE_CTL_REG 0x1884
-#define CLOCK_FRQ_MEASURE_STATUS_REG 0x1888
-#define GCC_PLLTEST_PAD_CFG_REG 0x188C
-#define GCC_XO_DIV4_CBCR_REG 0x10C8
-#define APCS_GPLL_ENA_VOTE_REG 0x1480
-#define APCS_CLOCK_BRANCH_ENA_VOTE 0x1484
-#define APCS_CLOCK_SLEEP_ENA_VOTE 0x1488
-
-#define APCS_CLK_DIAG_REG 0x001C
-
-#define APCS_CPU_PLL_MODE_REG 0x0000
-#define APCS_CPU_PLL_L_REG 0x0004
-#define APCS_CPU_PLL_M_REG 0x0008
-#define APCS_CPU_PLL_N_REG 0x000C
-#define APCS_CPU_PLL_USER_CTL_REG 0x0010
-#define APCS_CPU_PLL_CONFIG_CTL_REG 0x0014
-#define APCS_CPU_PLL_TEST_CTL_REG 0x0018
-#define APCS_CPU_PLL_STATUS_REG 0x001C
-
-#define USB_HSIC_SYSTEM_CMD_RCGR 0x041C
-#define USB_HSIC_XCVR_FS_CMD_RCGR 0x0424
-#define USB_HSIC_CMD_RCGR 0x0440
-#define USB_HSIC_IO_CAL_CMD_RCGR 0x0458
-#define USB_HS_SYSTEM_CMD_RCGR 0x0490
-#define SDCC2_APPS_CMD_RCGR 0x0510
-#define SDCC3_APPS_CMD_RCGR 0x0550
-#define BLSP1_QUP1_SPI_APPS_CMD_RCGR 0x064C
-#define BLSP1_UART1_APPS_CMD_RCGR 0x068C
-#define BLSP1_QUP2_SPI_APPS_CMD_RCGR 0x06CC
-#define BLSP1_UART2_APPS_CMD_RCGR 0x070C
-#define BLSP1_QUP3_SPI_APPS_CMD_RCGR 0x074C
-#define BLSP1_UART3_APPS_CMD_RCGR 0x078C
-#define BLSP1_QUP4_SPI_APPS_CMD_RCGR 0x07CC
-#define BLSP1_UART4_APPS_CMD_RCGR 0x080C
-#define BLSP1_QUP5_SPI_APPS_CMD_RCGR 0x084C
-#define BLSP1_UART5_APPS_CMD_RCGR 0x088C
-#define BLSP1_QUP6_SPI_APPS_CMD_RCGR 0x08CC
-#define BLSP1_UART6_APPS_CMD_RCGR 0x090C
-#define PDM2_CMD_RCGR 0x0CD0
-#define CE1_CMD_RCGR 0x1050
-#define GP1_CMD_RCGR 0x1904
-#define GP2_CMD_RCGR 0x1944
-#define GP3_CMD_RCGR 0x1984
-#define QPIC_CMD_RCGR 0x1A50
-#define IPA_CMD_RCGR 0x1A90
-
-#define USB_HS_HSIC_BCR 0x0400
-#define USB_HS_BCR 0x0480
-#define SDCC2_BCR 0x0500
-#define SDCC3_BCR 0x0540
-#define BLSP1_BCR 0x05C0
-#define BLSP1_QUP1_BCR 0x0640
-#define BLSP1_UART1_BCR 0x0680
-#define BLSP1_QUP2_BCR 0x06C0
-#define BLSP1_UART2_BCR 0x0700
-#define BLSP1_QUP3_BCR 0x0740
-#define BLSP1_UART3_BCR 0x0780
-#define BLSP1_QUP4_BCR 0x07C0
-#define BLSP1_UART4_BCR 0x0800
-#define BLSP1_QUP5_BCR 0x0840
-#define BLSP1_UART5_BCR 0x0880
-#define BLSP1_QUP6_BCR 0x08C0
-#define BLSP1_UART6_BCR 0x0900
-#define PDM_BCR 0x0CC0
-#define PRNG_BCR 0x0D00
-#define BAM_DMA_BCR 0x0D40
-#define BOOT_ROM_BCR 0x0E00
-#define CE1_BCR 0x1040
-#define QPIC_BCR 0x1040
-#define IPA_BCR 0x1A80
-
-
-#define SYS_NOC_IPA_AXI_CBCR 0x0128
-#define USB_HSIC_AHB_CBCR 0x0408
-#define USB_HSIC_SYSTEM_CBCR 0x040C
-#define USB_HSIC_CBCR 0x0410
-#define USB_HSIC_IO_CAL_CBCR 0x0414
-#define USB_HSIC_XCVR_FS_CBCR 0x042C
-#define USB_HS_SYSTEM_CBCR 0x0484
-#define USB_HS_AHB_CBCR 0x0488
-#define SDCC2_APPS_CBCR 0x0504
-#define SDCC2_AHB_CBCR 0x0508
-#define SDCC3_APPS_CBCR 0x0544
-#define SDCC3_AHB_CBCR 0x0548
-#define BLSP1_AHB_CBCR 0x05C4
-#define BLSP1_QUP1_SPI_APPS_CBCR 0x0644
-#define BLSP1_QUP1_I2C_APPS_CBCR 0x0648
-#define BLSP1_UART1_APPS_CBCR 0x0684
-#define BLSP1_UART1_SIM_CBCR 0x0688
-#define BLSP1_QUP2_SPI_APPS_CBCR 0x06C4
-#define BLSP1_QUP2_I2C_APPS_CBCR 0x06C8
-#define BLSP1_UART2_APPS_CBCR 0x0704
-#define BLSP1_UART2_SIM_CBCR 0x0708
-#define BLSP1_QUP3_SPI_APPS_CBCR 0x0744
-#define BLSP1_QUP3_I2C_APPS_CBCR 0x0748
-#define BLSP1_UART3_APPS_CBCR 0x0784
-#define BLSP1_UART3_SIM_CBCR 0x0788
-#define BLSP1_QUP4_SPI_APPS_CBCR 0x07C4
-#define BLSP1_QUP4_I2C_APPS_CBCR 0x07C8
-#define BLSP1_UART4_APPS_CBCR 0x0804
-#define BLSP1_UART4_SIM_CBCR 0x0808
-#define BLSP1_QUP5_SPI_APPS_CBCR 0x0844
-#define BLSP1_QUP5_I2C_APPS_CBCR 0x0848
-#define BLSP1_UART5_APPS_CBCR 0x0884
-#define BLSP1_UART5_SIM_CBCR 0x0888
-#define BLSP1_QUP6_SPI_APPS_CBCR 0x08C4
-#define BLSP1_QUP6_I2C_APPS_CBCR 0x08C8
-#define BLSP1_UART6_APPS_CBCR 0x0904
-#define BLSP1_UART6_SIM_CBCR 0x0908
-#define BOOT_ROM_AHB_CBCR 0x0E04
-#define PDM_AHB_CBCR 0x0CC4
-#define PDM_XO4_CBCR 0x0CC8
-#define PDM_AHB_CBCR 0x0CC4
-#define PDM_XO4_CBCR 0x0CC8
-#define PDM2_CBCR 0x0CCC
-#define PRNG_AHB_CBCR 0x0D04
-#define BAM_DMA_AHB_CBCR 0x0D44
-#define MSG_RAM_AHB_CBCR 0x0E44
-#define CE1_CBCR 0x1044
-#define CE1_AXI_CBCR 0x1048
-#define CE1_AHB_CBCR 0x104C
-#define GCC_AHB_CBCR 0x10C0
-#define GP1_CBCR 0x1900
-#define GP2_CBCR 0x1940
-#define GP3_CBCR 0x1980
-#define QPIC_CBCR 0x1A44
-#define QPIC_AHB_CBCR 0x1A48
-#define IPA_CBCR 0x1A84
-#define IPA_CNOC_CBCR 0x1A88
-#define IPA_SLEEP_CBCR 0x1A8C
-
-/* LPASS registers */
-/* TODO: Needs to double check lpass regiserts after get the SWI for hw */
-#define LPAPLL_MODE_REG 0x0000
-#define LPAPLL_L_REG 0x0004
-#define LPAPLL_M_REG 0x0008
-#define LPAPLL_N_REG 0x000C
-#define LPAPLL_USER_CTL_REG 0x0010
-#define LPAPLL_CONFIG_CTL_REG 0x0014
-#define LPAPLL_TEST_CTL_REG 0x0018
-#define LPAPLL_STATUS_REG 0x001C
-
-#define LPASS_DEBUG_CLK_CTL_REG 0x29000
-#define LPASS_LPA_PLL_VOTE_APPS_REG 0x2000
-
-#define LPAIF_PRI_CMD_RCGR 0xB000
-#define LPAIF_SEC_CMD_RCGR 0xC000
-#define LPAIF_PCM0_CMD_RCGR 0xF000
-#define LPAIF_PCM1_CMD_RCGR 0x10000
-#define SLIMBUS_CMD_RCGR 0x12000
-#define LPAIF_PCMOE_CMD_RCGR 0x13000
-
-#define AUDIO_CORE_BCR 0x4000
-
-#define AUDIO_CORE_LPAIF_PRI_OSR_CBCR 0xB014
-#define AUDIO_CORE_LPAIF_PRI_IBIT_CBCR 0xB018
-#define AUDIO_CORE_LPAIF_PRI_EBIT_CBCR 0xB01C
-#define AUDIO_CORE_LPAIF_SEC_OSR_CBCR 0xC014
-#define AUDIO_CORE_LPAIF_SEC_IBIT_CBCR 0xC018
-#define AUDIO_CORE_LPAIF_SEC_EBIT_CBCR 0xC01C
-#define AUDIO_CORE_LPAIF_PCM0_IBIT_CBCR 0xF014
-#define AUDIO_CORE_LPAIF_PCM0_EBIT_CBCR 0xF018
-#define AUDIO_CORE_LPAIF_PCM1_IBIT_CBCR 0x10014
-#define AUDIO_CORE_LPAIF_PCM1_EBIT_CBCR 0x10018
-#define AUDIO_CORE_RESAMPLER_CORE_CBCR 0x11014
-#define AUDIO_CORE_RESAMPLER_LFABIF_CBCR 0x11018
-#define AUDIO_CORE_SLIMBUS_CORE_CBCR 0x12014
-#define AUDIO_CORE_SLIMBUS_LFABIF_CBCR 0x12018
-#define AUDIO_CORE_LPAIF_PCM_DATA_OE_CBCR 0x13014
-
-/* Mux source select values */
-#define cxo_source_val 0
-#define gpll0_source_val 1
-#define gpll1_hsic_source_val 4
-#define gnd_source_val 5
-#define cxo_lpass_source_val 0
-#define lpapll0_lpass_source_val 1
-#define gpll0_lpass_source_val 5
-
-#define F(f, s, div, m, n) \
- { \
- .freq_hz = (f), \
- .src_clk = &s##_clk_src.c, \
- .m_val = (m), \
- .n_val = ~((n)-(m)) * !!(n), \
- .d_val = ~(n),\
- .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
- | BVAL(10, 8, s##_source_val), \
- }
-
-#define F_HSIC(f, s, div, m, n) \
- { \
- .freq_hz = (f), \
- .src_clk = &s##_clk_src.c, \
- .m_val = (m), \
- .n_val = ~((n)-(m)) * !!(n), \
- .d_val = ~(n),\
- .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
- | BVAL(10, 8, s##_hsic_source_val), \
- }
-
-#define F_LPASS(f, s, div, m, n) \
- { \
- .freq_hz = (f), \
- .src_clk = &s##_clk_src.c, \
- .m_val = (m), \
- .n_val = ~((n)-(m)) * !!(n), \
- .d_val = ~(n),\
- .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
- | BVAL(10, 8, s##_lpass_source_val), \
- }
-
-
-#define VDD_DIG_FMAX_MAP1(l1, f1) \
- .vdd_class = &vdd_dig, \
- .fmax[VDD_DIG_##l1] = (f1)
-#define VDD_DIG_FMAX_MAP2(l1, f1, l2, f2) \
- .vdd_class = &vdd_dig, \
- .fmax[VDD_DIG_##l1] = (f1), \
- .fmax[VDD_DIG_##l2] = (f2)
-#define VDD_DIG_FMAX_MAP3(l1, f1, l2, f2, l3, f3) \
- .vdd_class = &vdd_dig, \
- .fmax[VDD_DIG_##l1] = (f1), \
- .fmax[VDD_DIG_##l2] = (f2), \
- .fmax[VDD_DIG_##l3] = (f3)
-
-enum vdd_dig_levels {
- VDD_DIG_NONE,
- VDD_DIG_LOW,
- VDD_DIG_NOMINAL,
- VDD_DIG_HIGH
-};
-
-/* TODO: Add regulator set voltage APIs when support is available */
-static int set_vdd_dig(struct clk_vdd_class *vdd_class, int level)
-{
- return 0;
-}
-
-static DEFINE_VDD_CLASS(vdd_dig, set_vdd_dig);
-
-/* TODO: Needs to confirm the below values */
-#define RPM_MISC_CLK_TYPE 0x306b6c63
-#define RPM_BUS_CLK_TYPE 0x316b6c63
-#define RPM_MEM_CLK_TYPE 0x326b6c63
-
-#define RPM_SMD_KEY_ENABLE 0x62616E45
-
-#define CXO_ID 0x0
-#define QDSS_ID 0x1
-#define RPM_SCALING_ENABLE_ID 0x2
-
-#define PNOC_ID 0x0
-#define SNOC_ID 0x1
-#define CNOC_ID 0x2
-
-#define BIMC_ID 0x0
-
-#define D0_ID 1
-#define D1_ID 2
-#define A0_ID 3
-#define A1_ID 4
-#define A2_ID 5
-
-DEFINE_CLK_RPM_SMD_BRANCH(cxo_clk_src, cxo_a_clk_src,
- RPM_MISC_CLK_TYPE, CXO_ID, 19200000);
-
-DEFINE_CLK_RPM_SMD(cnoc_clk, cnoc_a_clk, RPM_BUS_CLK_TYPE, CNOC_ID, NULL);
-DEFINE_CLK_RPM_SMD(pnoc_clk, pnoc_a_clk, RPM_BUS_CLK_TYPE, PNOC_ID, NULL);
-DEFINE_CLK_RPM_SMD(snoc_clk, snoc_a_clk, RPM_BUS_CLK_TYPE, SNOC_ID, NULL);
-
-DEFINE_CLK_RPM_SMD(bimc_clk, bimc_a_clk, RPM_MEM_CLK_TYPE, BIMC_ID, NULL);
-
-DEFINE_CLK_RPM_SMD_QDSS(qdss_clk, qdss_a_clk, RPM_MISC_CLK_TYPE, QDSS_ID);
-
-DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_d0, cxo_d0_a, D0_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_d1, cxo_d1_a, D1_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a0, cxo_a0_a, A0_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a1, cxo_a1_a, A1_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a2, cxo_a2_a, A2_ID);
-
-DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_d0_pin, cxo_d0_a_pin, D0_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_d1_pin, cxo_d1_a_pin, D1_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a0_pin, cxo_a0_a_pin, A0_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a1_pin, cxo_a1_a_pin, A1_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a2_pin, cxo_a2_a_pin, A2_ID);
-
-static struct pll_vote_clk gpll0_clk_src = {
- .en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE_REG,
- .status_reg = (void __iomem *)GPLL0_STATUS_REG,
- .status_mask = BIT(17),
- .parent = &cxo_clk_src.c,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .rate = 600000000,
- .dbg_name = "gpll0_clk_src",
- .ops = &clk_ops_pll_vote,
- CLK_INIT(gpll0_clk_src.c),
- },
-};
-
-static struct pll_vote_clk lpapll0_clk_src = {
- .en_reg = (void __iomem *)LPASS_LPA_PLL_VOTE_APPS_REG,
- .en_mask = BIT(0),
- .status_reg = (void __iomem *)LPAPLL_STATUS_REG,
- .status_mask = BIT(17),
- .parent = &cxo_clk_src.c,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .rate = 393216000,
- .dbg_name = "lpapll0_clk_src",
- .ops = &clk_ops_pll_vote,
- CLK_INIT(lpapll0_clk_src.c),
- },
-};
-
-static struct pll_vote_clk gpll1_clk_src = {
- .en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE_REG,
- .en_mask = BIT(1),
- .status_reg = (void __iomem *)GPLL1_STATUS_REG,
- .status_mask = BIT(17),
- .parent = &cxo_clk_src.c,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .rate = 480000000,
- .dbg_name = "gpll1_clk_src",
- .ops = &clk_ops_pll_vote,
- CLK_INIT(gpll1_clk_src.c),
- },
-};
-
-static struct pll_clk apcspll_clk_src = {
- .mode_reg = (void __iomem *)APCS_CPU_PLL_MODE_REG,
- .status_reg = (void __iomem *)APCS_CPU_PLL_STATUS_REG,
- .parent = &cxo_clk_src.c,
- .base = &virt_bases[APCS_PLL_BASE],
- .c = {
- .rate = 748800000,
- .dbg_name = "apcspll_clk_src",
- .ops = &clk_ops_local_pll,
- CLK_INIT(apcspll_clk_src.c),
- },
-};
-
-static DEFINE_CLK_VOTER(pnoc_msmbus_clk, &pnoc_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(snoc_msmbus_clk, &snoc_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(cnoc_msmbus_clk, &cnoc_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(pnoc_msmbus_a_clk, &pnoc_a_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(snoc_msmbus_a_clk, &snoc_a_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(cnoc_msmbus_a_clk, &cnoc_a_clk.c, LONG_MAX);
-
-static DEFINE_CLK_VOTER(bimc_msmbus_clk, &bimc_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(bimc_msmbus_a_clk, &bimc_a_clk.c, LONG_MAX);
-
-static DEFINE_CLK_VOTER(pnoc_sdcc2_clk, &pnoc_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(pnoc_sdcc3_clk, &pnoc_clk.c, LONG_MAX);
-
-static DEFINE_CLK_VOTER(pnoc_sps_clk, &pnoc_clk.c, LONG_MAX);
-
-static struct clk_freq_tbl ftbl_gcc_ipa_clk[] = {
- F( 50000000, gpll0, 12, 0, 0),
- F( 92310000, gpll0, 6.5, 0, 0),
- F(100000000, gpll0, 6, 0, 0),
- F_END
-};
-
-static struct rcg_clk ipa_clk_src = {
- .cmd_rcgr_reg = IPA_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_ipa_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "ipa_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 100000000),
- CLK_INIT(ipa_clk_src.c)
- },
-};
-
-static struct clk_freq_tbl ftbl_gcc_blsp1_qup1_6_spi_apps_clk[] = {
- F(960000, cxo, 10, 1, 2),
- F(4800000, cxo, 4, 0, 0),
- F(9600000, cxo, 2, 0, 0),
- F(15000000, gpll0, 10, 1, 4),
- F(19200000, cxo, 1, 0, 0),
- F(25000000, gpll0, 12, 1, 2),
- F(50000000, gpll0, 12, 0, 0),
- F_END
-};
-
-static struct rcg_clk blsp1_qup1_spi_apps_clk_src = {
- .cmd_rcgr_reg = BLSP1_QUP1_SPI_APPS_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "blsp1_qup1_spi_apps_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
- CLK_INIT(blsp1_qup1_spi_apps_clk_src.c)
- },
-};
-
-static struct rcg_clk blsp1_qup2_spi_apps_clk_src = {
- .cmd_rcgr_reg = BLSP1_QUP2_SPI_APPS_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "blsp1_qup2_spi_apps_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
- CLK_INIT(blsp1_qup2_spi_apps_clk_src.c)
- },
-};
-
-static struct rcg_clk blsp1_qup3_spi_apps_clk_src = {
- .cmd_rcgr_reg = BLSP1_QUP3_SPI_APPS_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "blsp1_qup3_spi_apps_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
- CLK_INIT(blsp1_qup3_spi_apps_clk_src.c)
- },
-};
-
-static struct rcg_clk blsp1_qup4_spi_apps_clk_src = {
- .cmd_rcgr_reg = BLSP1_QUP4_SPI_APPS_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "blsp1_qup4_spi_apps_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
- CLK_INIT(blsp1_qup4_spi_apps_clk_src.c)
- },
-};
-
-static struct rcg_clk blsp1_qup5_spi_apps_clk_src = {
- .cmd_rcgr_reg = BLSP1_QUP5_SPI_APPS_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "blsp1_qup5_spi_apps_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
- CLK_INIT(blsp1_qup5_spi_apps_clk_src.c)
- },
-};
-
-static struct rcg_clk blsp1_qup6_spi_apps_clk_src = {
- .cmd_rcgr_reg = BLSP1_QUP6_SPI_APPS_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "blsp1_qup6_spi_apps_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
- CLK_INIT(blsp1_qup6_spi_apps_clk_src.c)
- },
-};
-
-static struct clk_freq_tbl ftbl_gcc_blsp1_uart1_6_apps_clk[] = {
- F(3686400, gpll0, 1, 96, 15625),
- F(7372800, gpll0, 1, 192, 15625),
- F(14745600, gpll0, 1, 384, 15625),
- F(16000000, gpll0, 5, 2, 15),
- F(19200000, cxo, 1, 0, 0),
- F(24000000, gpll0, 5, 1, 5),
- F(32000000, gpll0, 1, 4, 75),
- F(40000000, gpll0, 15, 0, 0),
- F(46400000, gpll0, 1, 29, 375),
- F(48000000, gpll0, 12.5, 0, 0),
- F(51200000, gpll0, 1, 32, 375),
- F(56000000, gpll0, 1, 7, 75),
- F(58982400, gpll0, 1, 1536, 15625),
- F(60000000, gpll0, 10, 0, 0),
- F_END
-};
-
-static struct rcg_clk blsp1_uart1_apps_clk_src = {
- .cmd_rcgr_reg = BLSP1_UART1_APPS_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "blsp1_uart1_apps_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
- CLK_INIT(blsp1_uart1_apps_clk_src.c)
- },
-};
-
-static struct rcg_clk blsp1_uart2_apps_clk_src = {
- .cmd_rcgr_reg = BLSP1_UART2_APPS_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "blsp1_uart2_apps_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
- CLK_INIT(blsp1_uart2_apps_clk_src.c)
- },
-};
-
-static struct rcg_clk blsp1_uart3_apps_clk_src = {
- .cmd_rcgr_reg = BLSP1_UART3_APPS_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "blsp1_uart3_apps_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
- CLK_INIT(blsp1_uart3_apps_clk_src.c)
- },
-};
-
-static struct rcg_clk blsp1_uart4_apps_clk_src = {
- .cmd_rcgr_reg = BLSP1_UART4_APPS_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "blsp1_uart4_apps_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
- CLK_INIT(blsp1_uart4_apps_clk_src.c)
- },
-};
-
-static struct rcg_clk blsp1_uart5_apps_clk_src = {
- .cmd_rcgr_reg = BLSP1_UART5_APPS_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "blsp1_uart5_apps_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
- CLK_INIT(blsp1_uart5_apps_clk_src.c)
- },
-};
-
-static struct rcg_clk blsp1_uart6_apps_clk_src = {
- .cmd_rcgr_reg = BLSP1_UART6_APPS_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "blsp1_uart6_apps_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
- CLK_INIT(blsp1_uart6_apps_clk_src.c)
- },
-};
-
-static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = {
- F(50000000, gpll0, 12, 0, 0),
- F(100000000, gpll0, 6, 0, 0),
- F_END
-};
-
-static struct rcg_clk ce1_clk_src = {
- .cmd_rcgr_reg = CE1_CMD_RCGR,
- .set_rate = set_rate_hid,
- .freq_tbl = ftbl_gcc_ce1_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "ce1_clk_src",
- .ops = &clk_ops_rcg,
- VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 100000000),
- CLK_INIT(ce1_clk_src.c),
- },
-};
-
-static struct clk_freq_tbl ftbl_gcc_gp_clk[] = {
- F(19200000, cxo, 1, 0, 0),
- F_END
-};
-
-static struct rcg_clk gp1_clk_src = {
- .cmd_rcgr_reg = GP1_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_gp_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gp1_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
- CLK_INIT(gp1_clk_src.c)
- },
-};
-
-static struct rcg_clk gp2_clk_src = {
- .cmd_rcgr_reg = GP2_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_gp_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gp2_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
- CLK_INIT(gp2_clk_src.c)
- },
-};
-
-static struct rcg_clk gp3_clk_src = {
- .cmd_rcgr_reg = GP3_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_gp_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gp3_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
- CLK_INIT(gp3_clk_src.c)
- },
-};
-
-static struct clk_freq_tbl ftbl_gcc_pdm2_clk[] = {
- F(60000000, gpll0, 10, 0, 0),
- F_END
-};
-
-static struct rcg_clk pdm2_clk_src = {
- .cmd_rcgr_reg = PDM2_CMD_RCGR,
- .set_rate = set_rate_hid,
- .freq_tbl = ftbl_gcc_pdm2_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "pdm2_clk_src",
- .ops = &clk_ops_rcg,
- VDD_DIG_FMAX_MAP1(LOW, 60000000),
- CLK_INIT(pdm2_clk_src.c),
- },
-};
-
-static struct clk_freq_tbl ftbl_gcc_qpic_clk[] = {
- F(50000000, gpll0, 12, 0, 0),
- F(100000000, gpll0, 6, 0, 0),
- F_END
-};
-
-static struct rcg_clk qpic_clk_src = {
- .cmd_rcgr_reg = QPIC_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_qpic_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "qpic_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 100000000),
- CLK_INIT(qpic_clk_src.c)
- },
-};
-
-static struct clk_freq_tbl ftbl_gcc_sdcc2_apps_clk[] = {
- F(144000, cxo, 16, 3, 25),
- F(400000, cxo, 12, 1, 4),
- F(20000000, gpll0, 15, 1, 2),
- F(25000000, gpll0, 12, 1, 2),
- F(50000000, gpll0, 12, 0, 0),
- F(100000000, gpll0, 6, 0, 0),
- F(200000000, gpll0, 3, 0, 0),
- F_END
-};
-
-static struct clk_freq_tbl ftbl_gcc_sdcc3_apps_clk[] = {
- F(144000, cxo, 16, 3, 25),
- F(400000, cxo, 12, 1, 4),
- F(20000000, gpll0, 15, 1, 2),
- F(25000000, gpll0, 12, 1, 2),
- F(50000000, gpll0, 12, 0, 0),
- F(100000000, gpll0, 6, 0, 0),
- F_END
-};
-
-static struct rcg_clk sdcc2_apps_clk_src = {
- .cmd_rcgr_reg = SDCC2_APPS_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_sdcc2_apps_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "sdcc2_apps_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
- CLK_INIT(sdcc2_apps_clk_src.c)
- },
-};
-
-static struct rcg_clk sdcc3_apps_clk_src = {
- .cmd_rcgr_reg = SDCC3_APPS_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_gcc_sdcc3_apps_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "sdcc3_apps_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 100000000),
- CLK_INIT(sdcc3_apps_clk_src.c)
- },
-};
-
-static struct clk_freq_tbl ftbl_gcc_usb_hs_system_clk[] = {
- F(75000000, gpll0, 8, 0, 0),
- F_END
-};
-
-static struct rcg_clk usb_hs_system_clk_src = {
- .cmd_rcgr_reg = USB_HS_SYSTEM_CMD_RCGR,
- .set_rate = set_rate_hid,
- .freq_tbl = ftbl_gcc_usb_hs_system_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "usb_hs_system_clk_src",
- .ops = &clk_ops_rcg,
- VDD_DIG_FMAX_MAP2(LOW, 37500000, NOMINAL, 75000000),
- CLK_INIT(usb_hs_system_clk_src.c),
- },
-};
-
-static struct clk_freq_tbl ftbl_gcc_usb_hsic_clk[] = {
- F_HSIC(480000000, gpll1, 1, 0, 0),
- F_END
-};
-
-static struct rcg_clk usb_hsic_clk_src = {
- .cmd_rcgr_reg = USB_HSIC_CMD_RCGR,
- .set_rate = set_rate_hid,
- .freq_tbl = ftbl_gcc_usb_hsic_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "usb_hsic_clk_src",
- .ops = &clk_ops_rcg,
- VDD_DIG_FMAX_MAP1(LOW, 480000000),
- CLK_INIT(usb_hsic_clk_src.c),
- },
-};
-
-static struct clk_freq_tbl ftbl_gcc_usb_hsic_io_cal_clk[] = {
- F(9600000, cxo, 2, 0, 0),
- F_END
-};
-
-static struct rcg_clk usb_hsic_io_cal_clk_src = {
- .cmd_rcgr_reg = USB_HSIC_IO_CAL_CMD_RCGR,
- .set_rate = set_rate_hid,
- .freq_tbl = ftbl_gcc_usb_hsic_io_cal_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "usb_hsic_io_cal_clk_src",
- .ops = &clk_ops_rcg,
- VDD_DIG_FMAX_MAP1(LOW, 9600000),
- CLK_INIT(usb_hsic_io_cal_clk_src.c),
- },
-};
-
-static struct clk_freq_tbl ftbl_gcc_usb_hsic_system_clk[] = {
- F(75000000, gpll0, 8, 0, 0),
- F_END
-};
-
-static struct rcg_clk usb_hsic_system_clk_src = {
- .cmd_rcgr_reg = USB_HSIC_SYSTEM_CMD_RCGR,
- .set_rate = set_rate_hid,
- .freq_tbl = ftbl_gcc_usb_hsic_system_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "usb_hsic_system_clk_src",
- .ops = &clk_ops_rcg,
- VDD_DIG_FMAX_MAP2(LOW, 60000000, NOMINAL, 75000000),
- CLK_INIT(usb_hsic_system_clk_src.c),
- },
-};
-
-static struct clk_freq_tbl ftbl_gcc_usb_hsic_xcvr_fs_clk[] = {
- F(60000000, gpll0, 10, 0, 0),
- F_END
-};
-
-static struct rcg_clk usb_hsic_xcvr_fs_clk_src = {
- .cmd_rcgr_reg = USB_HSIC_XCVR_FS_CMD_RCGR,
- .set_rate = set_rate_hid,
- .freq_tbl = ftbl_gcc_usb_hsic_xcvr_fs_clk,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "usb_hsic_xcvr_fs_clk_src",
- .ops = &clk_ops_rcg,
- VDD_DIG_FMAX_MAP1(LOW, 60000000),
- CLK_INIT(usb_hsic_xcvr_fs_clk_src.c),
- },
-};
-
-static struct local_vote_clk gcc_bam_dma_ahb_clk = {
- .cbcr_reg = BAM_DMA_AHB_CBCR,
- .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
- .en_mask = BIT(12),
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_bam_dma_ahb_clk",
- .ops = &clk_ops_vote,
- CLK_INIT(gcc_bam_dma_ahb_clk.c),
- },
-};
-
-static struct local_vote_clk gcc_blsp1_ahb_clk = {
- .cbcr_reg = BLSP1_AHB_CBCR,
- .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
- .en_mask = BIT(17),
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_ahb_clk",
- .ops = &clk_ops_vote,
- CLK_INIT(gcc_blsp1_ahb_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_qup1_i2c_apps_clk = {
- .cbcr_reg = BLSP1_QUP1_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
- .has_sibling = 1,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_qup1_i2c_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_qup1_i2c_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_qup1_spi_apps_clk = {
- .cbcr_reg = BLSP1_QUP1_SPI_APPS_CBCR,
- .parent = &blsp1_qup1_spi_apps_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_qup1_spi_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_qup1_spi_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_qup2_i2c_apps_clk = {
- .cbcr_reg = BLSP1_QUP2_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
- .has_sibling = 1,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_qup2_i2c_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_qup2_i2c_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_qup2_spi_apps_clk = {
- .cbcr_reg = BLSP1_QUP2_SPI_APPS_CBCR,
- .parent = &blsp1_qup2_spi_apps_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_qup2_spi_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_qup2_spi_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = {
- .cbcr_reg = BLSP1_QUP3_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
- .has_sibling = 1,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_qup3_i2c_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_qup3_i2c_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_qup3_spi_apps_clk = {
- .cbcr_reg = BLSP1_QUP3_SPI_APPS_CBCR,
- .parent = &blsp1_qup3_spi_apps_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_qup3_spi_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_qup3_spi_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_qup4_i2c_apps_clk = {
- .cbcr_reg = BLSP1_QUP4_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
- .has_sibling = 1,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_qup4_i2c_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_qup4_i2c_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_qup4_spi_apps_clk = {
- .cbcr_reg = BLSP1_QUP4_SPI_APPS_CBCR,
- .parent = &blsp1_qup4_spi_apps_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_qup4_spi_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_qup4_spi_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_qup5_i2c_apps_clk = {
- .cbcr_reg = BLSP1_QUP5_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
- .has_sibling = 1,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_qup5_i2c_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_qup5_i2c_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_qup5_spi_apps_clk = {
- .cbcr_reg = BLSP1_QUP5_SPI_APPS_CBCR,
- .parent = &blsp1_qup5_spi_apps_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_qup5_spi_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_qup5_spi_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_qup6_i2c_apps_clk = {
- .cbcr_reg = BLSP1_QUP6_I2C_APPS_CBCR,
- .parent = &cxo_clk_src.c,
- .has_sibling = 1,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_qup6_i2c_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_qup6_i2c_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_qup6_spi_apps_clk = {
- .cbcr_reg = BLSP1_QUP6_SPI_APPS_CBCR,
- .parent = &blsp1_qup6_spi_apps_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_qup6_spi_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_qup6_spi_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_uart1_apps_clk = {
- .cbcr_reg = BLSP1_UART1_APPS_CBCR,
- .parent = &blsp1_uart1_apps_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_uart1_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_uart1_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_uart2_apps_clk = {
- .cbcr_reg = BLSP1_UART2_APPS_CBCR,
- .parent = &blsp1_uart2_apps_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_uart2_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_uart2_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_uart3_apps_clk = {
- .cbcr_reg = BLSP1_UART3_APPS_CBCR,
- .parent = &blsp1_uart3_apps_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_uart3_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_uart3_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_uart4_apps_clk = {
- .cbcr_reg = BLSP1_UART4_APPS_CBCR,
- .parent = &blsp1_uart4_apps_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_uart4_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_uart4_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_uart5_apps_clk = {
- .cbcr_reg = BLSP1_UART5_APPS_CBCR,
- .parent = &blsp1_uart5_apps_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_uart5_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_uart5_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_blsp1_uart6_apps_clk = {
- .cbcr_reg = BLSP1_UART6_APPS_CBCR,
- .parent = &blsp1_uart6_apps_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_blsp1_uart6_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_blsp1_uart6_apps_clk.c),
- },
-};
-
-static struct local_vote_clk gcc_boot_rom_ahb_clk = {
- .cbcr_reg = BOOT_ROM_AHB_CBCR,
- .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
- .en_mask = BIT(10),
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_boot_rom_ahb_clk",
- .ops = &clk_ops_vote,
- CLK_INIT(gcc_boot_rom_ahb_clk.c),
- },
-};
-
-static struct local_vote_clk gcc_ce1_ahb_clk = {
- .cbcr_reg = CE1_AHB_CBCR,
- .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
- .en_mask = BIT(3),
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_ce1_ahb_clk",
- .ops = &clk_ops_vote,
- CLK_INIT(gcc_ce1_ahb_clk.c),
- },
-};
-
-static struct local_vote_clk gcc_ce1_axi_clk = {
- .cbcr_reg = CE1_AXI_CBCR,
- .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
- .en_mask = BIT(4),
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_ce1_axi_clk",
- .ops = &clk_ops_vote,
- CLK_INIT(gcc_ce1_axi_clk.c),
- },
-};
-
-static struct local_vote_clk gcc_ce1_clk = {
- .cbcr_reg = CE1_CBCR,
- .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
- .en_mask = BIT(5),
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_ce1_clk",
- .ops = &clk_ops_vote,
- CLK_INIT(gcc_ce1_clk.c),
- },
-};
-
-static struct branch_clk gcc_gp1_clk = {
- .cbcr_reg = GP1_CBCR,
- .parent = &gp1_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_gp1_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_gp1_clk.c),
- },
-};
-
-static struct branch_clk gcc_gp2_clk = {
- .cbcr_reg = GP2_CBCR,
- .parent = &gp2_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_gp2_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_gp2_clk.c),
- },
-};
-
-static struct branch_clk gcc_gp3_clk = {
- .cbcr_reg = GP3_CBCR,
- .parent = &gp3_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_gp3_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_gp3_clk.c),
- },
-};
-
-static struct branch_clk gcc_ipa_clk = {
- .cbcr_reg = IPA_CBCR,
- .parent = &ipa_clk_src.c,
- .has_sibling = 1,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_ipa_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_ipa_clk.c),
- },
-};
-
-static struct branch_clk gcc_ipa_cnoc_clk = {
- .cbcr_reg = IPA_CNOC_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_ipa_cnoc_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_ipa_cnoc_clk.c),
- },
-};
-
-static struct branch_clk gcc_pdm2_clk = {
- .cbcr_reg = PDM2_CBCR,
- .parent = &pdm2_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_pdm2_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_pdm2_clk.c),
- },
-};
-
-static struct branch_clk gcc_pdm_ahb_clk = {
- .cbcr_reg = PDM_AHB_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_pdm_ahb_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_pdm_ahb_clk.c),
- },
-};
-
-static struct local_vote_clk gcc_prng_ahb_clk = {
- .cbcr_reg = PRNG_AHB_CBCR,
- .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
- .en_mask = BIT(13),
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_prng_ahb_clk",
- .ops = &clk_ops_vote,
- CLK_INIT(gcc_prng_ahb_clk.c),
- },
-};
-
-static struct branch_clk gcc_qpic_ahb_clk = {
- .cbcr_reg = QPIC_AHB_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_qpic_ahb_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_qpic_ahb_clk.c),
- },
-};
-
-static struct branch_clk gcc_qpic_clk = {
- .cbcr_reg = QPIC_CBCR,
- .parent = &qpic_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_qpic_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_qpic_clk.c),
- },
-};
-
-static struct branch_clk gcc_sdcc2_ahb_clk = {
- .cbcr_reg = SDCC2_AHB_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_sdcc2_ahb_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_sdcc2_ahb_clk.c),
- },
-};
-
-static struct branch_clk gcc_sdcc2_apps_clk = {
- .cbcr_reg = SDCC2_APPS_CBCR,
- .parent = &sdcc2_apps_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_sdcc2_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_sdcc2_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_sdcc3_ahb_clk = {
- .cbcr_reg = SDCC3_AHB_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_sdcc3_ahb_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_sdcc3_ahb_clk.c),
- },
-};
-
-static struct branch_clk gcc_sdcc3_apps_clk = {
- .cbcr_reg = SDCC3_APPS_CBCR,
- .parent = &sdcc3_apps_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_sdcc3_apps_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_sdcc3_apps_clk.c),
- },
-};
-
-static struct branch_clk gcc_sys_noc_ipa_axi_clk = {
- .cbcr_reg = SYS_NOC_IPA_AXI_CBCR,
- .parent = &ipa_clk_src.c,
- .has_sibling = 1,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_sys_noc_ipa_axi_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_sys_noc_ipa_axi_clk.c),
- },
-};
-
-static struct branch_clk gcc_usb_hs_ahb_clk = {
- .cbcr_reg = USB_HS_AHB_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_usb_hs_ahb_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_usb_hs_ahb_clk.c),
- },
-};
-
-static struct branch_clk gcc_usb_hs_system_clk = {
- .cbcr_reg = USB_HS_SYSTEM_CBCR,
- .bcr_reg = USB_HS_BCR,
- .parent = &usb_hs_system_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_usb_hs_system_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_usb_hs_system_clk.c),
- },
-};
-
-static struct branch_clk gcc_usb_hsic_ahb_clk = {
- .cbcr_reg = USB_HSIC_AHB_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_usb_hsic_ahb_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_usb_hsic_ahb_clk.c),
- },
-};
-
-static struct branch_clk gcc_usb_hsic_clk = {
- .cbcr_reg = USB_HSIC_CBCR,
- .parent = &usb_hsic_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_usb_hsic_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_usb_hsic_clk.c),
- },
-};
-
-static struct branch_clk gcc_usb_hsic_io_cal_clk = {
- .cbcr_reg = USB_HSIC_IO_CAL_CBCR,
- .parent = &usb_hsic_io_cal_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_usb_hsic_io_cal_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_usb_hsic_io_cal_clk.c),
- },
-};
-
-static struct branch_clk gcc_usb_hsic_system_clk = {
- .cbcr_reg = USB_HSIC_SYSTEM_CBCR,
- .bcr_reg = USB_HS_HSIC_BCR,
- .parent = &usb_hsic_system_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_usb_hsic_system_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_usb_hsic_system_clk.c),
- },
-};
-
-static struct branch_clk gcc_usb_hsic_xcvr_fs_clk = {
- .cbcr_reg = USB_HSIC_XCVR_FS_CBCR,
- .parent = &usb_hsic_xcvr_fs_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[GCC_BASE],
- .c = {
- .dbg_name = "gcc_usb_hsic_xcvr_fs_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(gcc_usb_hsic_xcvr_fs_clk.c),
- },
-};
-
-/* LPASS clock data */
-static struct clk_freq_tbl ftbl_audio_core_lpaif_clock[] = {
- F_LPASS( 512000, lpapll0, 16, 1, 48),
- F_LPASS( 768000, lpapll0, 16, 1, 32),
- F_LPASS( 1024000, lpapll0, 16, 1, 24),
- F_LPASS( 1536000, lpapll0, 16, 1, 16),
- F_LPASS( 2048000, lpapll0, 16, 1, 12),
- F_LPASS( 3072000, lpapll0, 16, 1, 8),
- F_LPASS( 4096000, lpapll0, 16, 1, 6),
- F_LPASS( 6144000, lpapll0, 16, 1, 4),
- F_LPASS( 8192000, lpapll0, 16, 1, 3),
- F_LPASS(12288000, lpapll0, 16, 1, 2),
- F_END
-};
-
-static struct rcg_clk audio_core_lpaif_pcmoe_clk_src = {
- .cmd_rcgr_reg = LPAIF_PCMOE_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_audio_core_lpaif_clock,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pcmoe_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP1(LOW, 12290000),
- CLK_INIT(audio_core_lpaif_pcmoe_clk_src.c)
- },
-};
-
-static struct rcg_clk audio_core_lpaif_pri_clk_src = {
- .cmd_rcgr_reg = LPAIF_PRI_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_audio_core_lpaif_clock,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pri_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 9220000, NOMINAL, 18440000),
- CLK_INIT(audio_core_lpaif_pri_clk_src.c)
- },
-};
-
-static struct rcg_clk audio_core_lpaif_sec_clk_src = {
- .cmd_rcgr_reg = LPAIF_SEC_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_audio_core_lpaif_clock,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_sec_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 6140000, NOMINAL, 12290000),
- CLK_INIT(audio_core_lpaif_sec_clk_src.c)
- },
-};
-
-static struct clk_freq_tbl ftbl_audio_core_slimbus_core_clock[] = {
- F_LPASS(26041000, lpapll0, 1, 10, 151),
- F_END
-};
-
-static struct rcg_clk audio_core_slimbus_core_clk_src = {
- .cmd_rcgr_reg = SLIMBUS_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_audio_core_slimbus_core_clock,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_slimbus_core_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 13110000, NOMINAL, 26210000),
- CLK_INIT(audio_core_slimbus_core_clk_src.c)
- },
-};
-
-static struct rcg_clk audio_core_lpaif_pcm0_clk_src = {
- .cmd_rcgr_reg = LPAIF_PCM0_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_audio_core_lpaif_clock,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pcm0_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 4100000, NOMINAL, 8190000),
- CLK_INIT(audio_core_lpaif_pcm0_clk_src.c)
- },
-};
-
-static struct rcg_clk audio_core_lpaif_pcm1_clk_src = {
- .cmd_rcgr_reg = LPAIF_PCM1_CMD_RCGR,
- .set_rate = set_rate_mnd,
- .freq_tbl = ftbl_audio_core_lpaif_clock,
- .current_freq = &rcg_dummy_freq,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pcm1_clk_src",
- .ops = &clk_ops_rcg_mnd,
- VDD_DIG_FMAX_MAP2(LOW, 4100000, NOMINAL, 8190000),
- CLK_INIT(audio_core_lpaif_pcm1_clk_src.c)
- },
-};
-
-static struct branch_clk audio_core_slimbus_lfabif_clk = {
- .cbcr_reg = AUDIO_CORE_SLIMBUS_LFABIF_CBCR,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_slimbus_lfabif_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_slimbus_lfabif_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_pcm_data_oe_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_PCM_DATA_OE_CBCR,
- .parent = &audio_core_lpaif_pcmoe_clk_src.c,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pcm_data_oe_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_pcm_data_oe_clk.c),
- },
-};
-
-static struct branch_clk audio_core_slimbus_core_clk = {
- .cbcr_reg = AUDIO_CORE_SLIMBUS_CORE_CBCR,
- .parent = &audio_core_slimbus_core_clk_src.c,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_slimbus_core_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_slimbus_core_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_pri_ebit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_PRI_EBIT_CBCR,
- .has_sibling = 0,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pri_ebit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_pri_ebit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_pri_ibit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_PRI_IBIT_CBCR,
- .parent = &audio_core_lpaif_pri_clk_src.c,
- .has_sibling = 1,
- .max_div = 15,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pri_ibit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_pri_ibit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_pri_osr_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_PRI_OSR_CBCR,
- .parent = &audio_core_lpaif_pri_clk_src.c,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pri_osr_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_pri_osr_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_pcm0_ebit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_PCM0_EBIT_CBCR,
- .has_sibling = 0,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pcm0_ebit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_pcm0_ebit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_pcm0_ibit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_PCM0_IBIT_CBCR,
- .parent = &audio_core_lpaif_pcm0_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pcm0_ibit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_pcm0_ibit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_sec_ebit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_SEC_EBIT_CBCR,
- .has_sibling = 0,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_sec_ebit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_sec_ebit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_sec_ibit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_SEC_IBIT_CBCR,
- .parent = &audio_core_lpaif_sec_clk_src.c,
- .has_sibling = 1,
- .max_div = 15,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_sec_ibit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_sec_ibit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_sec_osr_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_SEC_OSR_CBCR,
- .parent = &audio_core_lpaif_sec_clk_src.c,
- .has_sibling = 1,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_sec_osr_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_sec_osr_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_pcm1_ebit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_PCM1_EBIT_CBCR,
- .has_sibling = 0,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pcm1_ebit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_pcm1_ebit_clk.c),
- },
-};
-
-static struct branch_clk audio_core_lpaif_pcm1_ibit_clk = {
- .cbcr_reg = AUDIO_CORE_LPAIF_PCM1_IBIT_CBCR,
- .parent = &audio_core_lpaif_pcm1_clk_src.c,
- .has_sibling = 0,
- .base = &virt_bases[LPASS_BASE],
- .c = {
- .dbg_name = "audio_core_lpaif_pcm1_ibit_clk",
- .ops = &clk_ops_branch,
- CLK_INIT(audio_core_lpaif_pcm1_ibit_clk.c),
- },
-};
-
-static DEFINE_CLK_MEASURE(a5_m_clk);
-
-#ifdef CONFIG_DEBUG_FS
-
-struct measure_mux_entry {
- struct clk *c;
- int base;
- u32 debug_mux;
-};
-
-struct measure_mux_entry measure_mux[] = {
- {&gcc_pdm_ahb_clk.c, GCC_BASE, 0x00d0},
- {&gcc_usb_hsic_xcvr_fs_clk.c, GCC_BASE, 0x005d},
- {&gcc_usb_hsic_system_clk.c, GCC_BASE, 0x0059},
- {&gcc_usb_hsic_io_cal_clk.c, GCC_BASE, 0x005b},
- {&gcc_sdcc3_ahb_clk.c, GCC_BASE, 0x0079},
- {&gcc_blsp1_qup5_i2c_apps_clk.c, GCC_BASE, 0x009d},
- {&gcc_blsp1_qup1_spi_apps_clk.c, GCC_BASE, 0x008a},
- {&gcc_blsp1_uart2_apps_clk.c, GCC_BASE, 0x0091},
- {&gcc_blsp1_qup4_spi_apps_clk.c, GCC_BASE, 0x0098},
- {&gcc_blsp1_qup3_spi_apps_clk.c, GCC_BASE, 0x0093},
- {&gcc_blsp1_qup6_i2c_apps_clk.c, GCC_BASE, 0x00a2},
- {&gcc_bam_dma_ahb_clk.c, GCC_BASE, 0x00e0},
- {&gcc_sdcc3_apps_clk.c, GCC_BASE, 0x0078},
- {&gcc_usb_hs_system_clk.c, GCC_BASE, 0x0060},
- {&gcc_blsp1_ahb_clk.c, GCC_BASE, 0x0088},
- {&gcc_blsp1_uart4_apps_clk.c, GCC_BASE, 0x009a},
- {&gcc_blsp1_qup2_spi_apps_clk.c, GCC_BASE, 0x008e},
- {&gcc_usb_hsic_ahb_clk.c, GCC_BASE, 0x0058},
- {&gcc_blsp1_uart3_apps_clk.c, GCC_BASE, 0x0095},
- {&gcc_ce1_axi_clk.c, GCC_BASE, 0x0139},
- {&gcc_blsp1_qup5_spi_apps_clk.c, GCC_BASE, 0x009c},
- {&gcc_usb_hs_ahb_clk.c, GCC_BASE, 0x0061},
- {&gcc_blsp1_qup6_spi_apps_clk.c, GCC_BASE, 0x00a1},
- {&gcc_prng_ahb_clk.c, GCC_BASE, 0x00d8},
- {&gcc_blsp1_qup3_i2c_apps_clk.c, GCC_BASE, 0x0094},
- {&gcc_usb_hsic_clk.c, GCC_BASE, 0x005a},
- {&gcc_blsp1_uart6_apps_clk.c, GCC_BASE, 0x00a3},
- {&gcc_sdcc2_apps_clk.c, GCC_BASE, 0x0070},
- {&gcc_blsp1_uart1_apps_clk.c, GCC_BASE, 0x008c},
- {&gcc_blsp1_qup4_i2c_apps_clk.c, GCC_BASE, 0x0099},
- {&gcc_boot_rom_ahb_clk.c, GCC_BASE, 0x00f8},
- {&gcc_ce1_ahb_clk.c, GCC_BASE, 0x013a},
- {&gcc_pdm2_clk.c, GCC_BASE, 0x00d2},
- {&gcc_blsp1_uart5_apps_clk.c, GCC_BASE, 0x009e},
- {&gcc_blsp1_qup2_i2c_apps_clk.c, GCC_BASE, 0x0090},
- {&gcc_blsp1_qup1_i2c_apps_clk.c, GCC_BASE, 0x008b},
- {&gcc_sdcc2_ahb_clk.c, GCC_BASE, 0x0071},
- {&gcc_ce1_clk.c, GCC_BASE, 0x0138},
- {&gcc_sys_noc_ipa_axi_clk.c, GCC_BASE, 0x0007},
-
- {&audio_core_lpaif_pcm_data_oe_clk.c, LPASS_BASE, 0x0030},
- {&audio_core_slimbus_core_clk.c, LPASS_BASE, 0x003d},
- {&audio_core_lpaif_pri_clk_src.c, LPASS_BASE, 0x0017},
- {&audio_core_lpaif_sec_clk_src.c, LPASS_BASE, 0x0016},
- {&audio_core_slimbus_core_clk_src.c, LPASS_BASE, 0x0011},
- {&audio_core_lpaif_pcm1_clk_src.c, LPASS_BASE, 0x0012},
- {&audio_core_lpaif_pcm0_clk_src.c, LPASS_BASE, 0x0013},
- {&audio_core_lpaif_pcmoe_clk_src.c, LPASS_BASE, 0x000f},
- {&audio_core_slimbus_lfabif_clk.c, LPASS_BASE, 0x003e},
-
- {&a5_m_clk, APCS_BASE, 0x3},
-
- {&dummy_clk, N_BASES, 0x0000},
-};
-
-static int measure_clk_set_parent(struct clk *c, struct clk *parent)
-{
- struct measure_clk *clk = to_measure_clk(c);
- unsigned long flags;
- u32 regval, clk_sel, i;
-
- if (!parent)
- return -EINVAL;
-
- for (i = 0; i < (ARRAY_SIZE(measure_mux) - 1); i++)
- if (measure_mux[i].c == parent)
- break;
-
- if (measure_mux[i].c == &dummy_clk)
- return -EINVAL;
-
- spin_lock_irqsave(&local_clock_reg_lock, flags);
- /*
- * Program the test vector, measurement period (sample_ticks)
- * and scaling multiplier.
- */
- clk->sample_ticks = 0x10000;
- clk->multiplier = 1;
-
- writel_relaxed(0, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL_REG));
- writel_relaxed(0, GCC_REG_BASE(GCC_DEBUG_CLK_CTL_REG));
-
- switch (measure_mux[i].base) {
-
- case GCC_BASE:
- clk_sel = measure_mux[i].debug_mux;
- break;
-
- case LPASS_BASE:
- clk_sel = 0x161;
- regval = BVAL(15, 0, measure_mux[i].debug_mux);
- writel_relaxed(regval, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL_REG));
-
- /* Activate debug clock output */
- regval |= BIT(20);
- writel_relaxed(regval, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL_REG));
- break;
-
- case APCS_BASE:
- clk_sel = 0x16A;
- regval = BVAL(5, 3, measure_mux[i].debug_mux);
- writel_relaxed(regval, APCS_REG_BASE(APCS_CLK_DIAG_REG));
-
- /* Activate debug clock output */
- regval |= BIT(7);
- writel_relaxed(regval, APCS_REG_BASE(APCS_CLK_DIAG_REG));
- break;
-
- default:
- return -EINVAL;
- }
-
- /* Set debug mux clock index */
- regval = BVAL(8, 0, clk_sel);
- writel_relaxed(regval, GCC_REG_BASE(GCC_DEBUG_CLK_CTL_REG));
-
- /* Activate debug clock output */
- regval |= BIT(16);
- writel_relaxed(regval, GCC_REG_BASE(GCC_DEBUG_CLK_CTL_REG));
-
- /* Make sure test vector is set before starting measurements. */
- mb();
- spin_unlock_irqrestore(&local_clock_reg_lock, flags);
-
- return 0;
-}
-
-/* Sample clock for 'ticks' reference clock ticks. */
-static u32 run_measurement(unsigned ticks)
-{
- /* Stop counters and set the XO4 counter start value. */
- writel_relaxed(ticks, GCC_REG_BASE(CLOCK_FRQ_MEASURE_CTL_REG));
-
- /* Wait for timer to become ready. */
- while ((readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS_REG)) &
- BIT(25)) != 0)
- cpu_relax();
-
- /* Run measurement and wait for completion. */
- writel_relaxed(BIT(20)|ticks, GCC_REG_BASE(CLOCK_FRQ_MEASURE_CTL_REG));
- while ((readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS_REG)) &
- BIT(25)) == 0)
- cpu_relax();
-
- /* Return measured ticks. */
- return readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS_REG)) &
- BM(24, 0);
-}
-
-/*
- * Perform a hardware rate measurement for a given clock.
- * FOR DEBUG USE ONLY: Measurements take ~15 ms!
- */
-static unsigned long measure_clk_get_rate(struct clk *c)
-{
- unsigned long flags;
- u32 gcc_xo4_reg_backup;
- u64 raw_count_short, raw_count_full;
- struct measure_clk *clk = to_measure_clk(c);
- unsigned ret;
-
- ret = clk_prepare_enable(&cxo_clk_src.c);
- if (ret) {
- pr_warning("CXO clock failed to enable. Can't measure\n");
- return 0;
- }
-
- spin_lock_irqsave(&local_clock_reg_lock, flags);
-
- /* Enable CXO/4 and RINGOSC branch. */
- gcc_xo4_reg_backup = readl_relaxed(GCC_REG_BASE(GCC_XO_DIV4_CBCR_REG));
- writel_relaxed(0x1, GCC_REG_BASE(GCC_XO_DIV4_CBCR_REG));
-
- /*
- * The ring oscillator counter will not reset if the measured clock
- * is not running. To detect this, run a short measurement before
- * the full measurement. If the raw results of the two are the same
- * then the clock must be off.
- */
-
- /* Run a short measurement. (~1 ms) */
- raw_count_short = run_measurement(0x1000);
- /* Run a full measurement. (~14 ms) */
- raw_count_full = run_measurement(clk->sample_ticks);
-
- writel_relaxed(gcc_xo4_reg_backup, GCC_REG_BASE(GCC_XO_DIV4_CBCR_REG));
-
- /* Return 0 if the clock is off. */
- if (raw_count_full == raw_count_short) {
- ret = 0;
- } else {
- /* Compute rate in Hz. */
- raw_count_full = ((raw_count_full * 10) + 15) * 4800000;
- do_div(raw_count_full, ((clk->sample_ticks * 10) + 35));
- ret = (raw_count_full * clk->multiplier);
- }
- /*TODO: Confirm this is value is correct */
- writel_relaxed(0x51A00, GCC_REG_BASE(GCC_PLLTEST_PAD_CFG_REG));
- spin_unlock_irqrestore(&local_clock_reg_lock, flags);
-
- clk_disable_unprepare(&cxo_clk_src.c);
-
- return ret;
-}
-#else /* !CONFIG_DEBUG_FS */
-static int measure_clk_set_parent(struct clk *clk, struct clk *parent)
-{
- return -EINVAL;
-}
-
-static unsigned long measure_clk_get_rate(struct clk *clk)
-{
- return 0;
-}
-#endif /* CONFIG_DEBUG_FS */
-
-static struct clk_ops clk_ops_measure = {
- .set_parent = measure_clk_set_parent,
- .get_rate = measure_clk_get_rate,
-};
-
-static struct measure_clk measure_clk = {
- .c = {
- .dbg_name = "measure_clk",
- .ops = &clk_ops_measure,
- CLK_INIT(measure_clk.c),
- },
- .multiplier = 1,
-};
-
-static struct clk_lookup msm_clocks_9625[] = {
- CLK_LOOKUP("xo", cxo_clk_src.c, ""),
- CLK_LOOKUP("measure", measure_clk.c, "debug"),
-
- CLK_LOOKUP("pll0", gpll0_clk_src.c, "f9010000.qcom,acpuclk"),
- CLK_LOOKUP("pll14", apcspll_clk_src.c, "f9010000.qcom,acpuclk"),
-
- CLK_LOOKUP("dma_bam_pclk", gcc_bam_dma_ahb_clk.c, ""),
- CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "msm_serial_hsl.0"),
- CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "spi_qsd.1"),
- CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f9966000.i2c"),
- CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp1_qup1_i2c_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp1_qup1_spi_apps_clk.c, "spi_qsd.1"),
- CLK_LOOKUP("core_clk", gcc_blsp1_qup2_i2c_apps_clk.c, "f9966000.i2c"),
- CLK_LOOKUP("core_clk", gcc_blsp1_qup2_spi_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp1_qup3_i2c_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp1_qup3_spi_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp1_qup4_i2c_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp1_qup4_spi_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp1_qup5_i2c_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp1_qup5_spi_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp1_qup6_i2c_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp1_qup6_spi_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp1_uart1_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp1_uart2_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp1_uart3_apps_clk.c, "msm_serial_hsl.0"),
- CLK_LOOKUP("core_clk", gcc_blsp1_uart4_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp1_uart5_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp1_uart6_apps_clk.c, ""),
-
- CLK_LOOKUP("core_clk", gcc_ce1_clk.c, ""),
- CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, ""),
- CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, ""),
-
- CLK_LOOKUP("core_clk", gcc_gp1_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_gp2_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_gp3_clk.c, ""),
-
- CLK_LOOKUP("core_src_clk", ipa_clk_src.c, ""),
- CLK_LOOKUP("core_clk", gcc_ipa_clk.c, ""),
- CLK_LOOKUP("bus_clk", gcc_sys_noc_ipa_axi_clk.c, ""),
- CLK_LOOKUP("iface_clk", gcc_ipa_cnoc_clk.c, ""),
-
- CLK_LOOKUP("core_clk", gcc_pdm2_clk.c, ""),
- CLK_LOOKUP("iface_clk", gcc_pdm_ahb_clk.c, ""),
-
- CLK_LOOKUP("core_clk", gcc_qpic_clk.c, ""),
- CLK_LOOKUP("iface_clk", gcc_qpic_ahb_clk.c, ""),
-
- CLK_LOOKUP("iface_clk", gcc_sdcc2_ahb_clk.c, "f98a4000.qcom,sdcc"),
- CLK_LOOKUP("core_clk", gcc_sdcc2_apps_clk.c, "f98a4000.qcom,sdcc"),
- CLK_LOOKUP("bus_clk", pnoc_sdcc2_clk.c, "f98a4000.qcom,sdcc"),
- CLK_LOOKUP("iface_clk", gcc_sdcc3_ahb_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_sdcc3_apps_clk.c, ""),
- CLK_LOOKUP("bus_clk", pnoc_sdcc3_clk.c, ""),
-
- CLK_LOOKUP("iface_clk", gcc_usb_hs_ahb_clk.c, "f9a55000.usb"),
- CLK_LOOKUP("core_clk", gcc_usb_hs_system_clk.c, "f9a55000.usb"),
- CLK_LOOKUP("iface_clk", gcc_usb_hsic_ahb_clk.c, "f9a15000.hsic"),
- CLK_LOOKUP("phy_clk", gcc_usb_hsic_clk.c, "f9a15000.hsic"),
- CLK_LOOKUP("cal_clk", gcc_usb_hsic_io_cal_clk.c, "f9a15000.hsic"),
- CLK_LOOKUP("core_clk", gcc_usb_hsic_system_clk.c, "f9a15000.hsic"),
- CLK_LOOKUP("alt_core_clk", gcc_usb_hsic_xcvr_fs_clk.c,
- "f9a15000.hsic"),
-
- /* LPASS clocks */
- CLK_LOOKUP("core_clk", audio_core_slimbus_core_clk.c, "fe12f000.slim"),
- CLK_LOOKUP("iface_clk", audio_core_slimbus_lfabif_clk.c, ""),
- CLK_LOOKUP("core_clk", audio_core_lpaif_pri_clk_src.c, ""),
- CLK_LOOKUP("osr_clk", audio_core_lpaif_pri_osr_clk.c, ""),
- CLK_LOOKUP("ebit_clk", audio_core_lpaif_pri_ebit_clk.c, ""),
- CLK_LOOKUP("ibit_clk", audio_core_lpaif_pri_ibit_clk.c, ""),
- CLK_LOOKUP("core_clk", audio_core_lpaif_sec_clk_src.c, ""),
- CLK_LOOKUP("osr_clk", audio_core_lpaif_sec_osr_clk.c, ""),
- CLK_LOOKUP("ebit_clk", audio_core_lpaif_sec_ebit_clk.c, ""),
- CLK_LOOKUP("ibit_clk", audio_core_lpaif_sec_ibit_clk.c, ""),
- CLK_LOOKUP("core_clk", audio_core_lpaif_pcm0_clk_src.c, ""),
- CLK_LOOKUP("ebit_clk", audio_core_lpaif_pcm0_ebit_clk.c, ""),
- CLK_LOOKUP("ibit_clk", audio_core_lpaif_pcm0_ibit_clk.c, ""),
- CLK_LOOKUP("core_clk", audio_core_lpaif_pcm1_clk_src.c, ""),
- CLK_LOOKUP("ebit_clk", audio_core_lpaif_pcm1_ebit_clk.c, ""),
- CLK_LOOKUP("ibit_clk", audio_core_lpaif_pcm1_ibit_clk.c, ""),
- CLK_LOOKUP("core_oe_src_clk", audio_core_lpaif_pcmoe_clk_src.c, ""),
- CLK_LOOKUP("core_oe_clk", audio_core_lpaif_pcm_data_oe_clk.c, ""),
-
- /* RPM and voter clocks */
- CLK_LOOKUP("bus_clk", snoc_clk.c, ""),
- CLK_LOOKUP("bus_clk", pnoc_clk.c, ""),
- CLK_LOOKUP("bus_clk", cnoc_clk.c, ""),
- CLK_LOOKUP("mem_clk", bimc_clk.c, ""),
- CLK_LOOKUP("bus_clk", snoc_a_clk.c, ""),
- CLK_LOOKUP("bus_clk", pnoc_a_clk.c, ""),
- CLK_LOOKUP("bus_clk", cnoc_a_clk.c, ""),
- CLK_LOOKUP("mem_clk", bimc_a_clk.c, ""),
-
- CLK_LOOKUP("bus_clk", cnoc_msmbus_clk.c, ""),
- CLK_LOOKUP("bus_a_clk", cnoc_msmbus_a_clk.c, ""),
- CLK_LOOKUP("bus_clk", snoc_msmbus_clk.c, ""),
- CLK_LOOKUP("bus_a_clk", snoc_msmbus_a_clk.c, ""),
- CLK_LOOKUP("bus_clk", pnoc_msmbus_clk.c, ""),
- CLK_LOOKUP("bus_a_clk", pnoc_msmbus_a_clk.c, ""),
- CLK_LOOKUP("mem_clk", bimc_msmbus_clk.c, ""),
- CLK_LOOKUP("mem_a_clk", bimc_msmbus_a_clk.c, ""),
-
- CLK_LOOKUP("dfab_clk", pnoc_sps_clk.c, "msm_sps"),
-
- CLK_LOOKUP("a5_m_clk", a5_m_clk, ""),
-};
-
-static struct pll_config_regs gpll0_regs __initdata = {
- .l_reg = (void __iomem *)GPLL0_L_REG,
- .m_reg = (void __iomem *)GPLL0_M_REG,
- .n_reg = (void __iomem *)GPLL0_N_REG,
- .config_reg = (void __iomem *)GPLL0_USER_CTL_REG,
- .mode_reg = (void __iomem *)GPLL0_MODE_REG,
- .base = &virt_bases[GCC_BASE],
-};
-
-/* GPLL0 at 600 MHz, main output enabled. */
-static struct pll_config gpll0_config __initdata = {
- .l = 0x1f,
- .m = 0x1,
- .n = 0x4,
- .vco_val = 0x0,
- .vco_mask = BM(21, 20),
- .pre_div_val = 0x0,
- .pre_div_mask = BM(14, 12),
- .post_div_val = 0x0,
- .post_div_mask = BM(9, 8),
- .mn_ena_val = BIT(24),
- .mn_ena_mask = BIT(24),
- .main_output_val = BIT(0),
- .main_output_mask = BIT(0),
-};
-
-static struct pll_config_regs gpll1_regs __initdata = {
- .l_reg = (void __iomem *)GPLL1_L_REG,
- .m_reg = (void __iomem *)GPLL1_M_REG,
- .n_reg = (void __iomem *)GPLL1_N_REG,
- .config_reg = (void __iomem *)GPLL1_USER_CTL_REG,
- .mode_reg = (void __iomem *)GPLL1_MODE_REG,
- .base = &virt_bases[GCC_BASE],
-};
-
-/* GPLL1 at 480 MHz, main output enabled. */
-static struct pll_config gpll1_config __initdata = {
- .l = 0x19,
- .m = 0x0,
- .n = 0x1,
- .vco_val = 0x0,
- .vco_mask = BM(21, 20),
- .pre_div_val = 0x0,
- .pre_div_mask = BM(14, 12),
- .post_div_val = 0x0,
- .post_div_mask = BM(9, 8),
- .main_output_val = BIT(0),
- .main_output_mask = BIT(0),
-};
-
-static struct pll_config_regs lpapll0_regs __initdata = {
- .l_reg = (void __iomem *)LPAPLL_L_REG,
- .m_reg = (void __iomem *)LPAPLL_M_REG,
- .n_reg = (void __iomem *)LPAPLL_N_REG,
- .config_reg = (void __iomem *)LPAPLL_USER_CTL_REG,
- .mode_reg = (void __iomem *)LPAPLL_MODE_REG,
- .base = &virt_bases[LPASS_BASE],
-};
-
-/* LPAPLL0 at 393.216 MHz, main output enabled. */
-static struct pll_config lpapll0_config __initdata = {
- .l = 0x28,
- .m = 0x18,
- .n = 0x19,
- .vco_val = 0x0,
- .vco_mask = BM(21, 20),
- .pre_div_val = 0x0,
- .pre_div_mask = BM(14, 12),
- .post_div_val = BVAL(9, 8, 0x1),
- .post_div_mask = BM(9, 8),
- .mn_ena_val = BIT(24),
- .mn_ena_mask = BIT(24),
- .main_output_val = BIT(0),
- .main_output_mask = BIT(0),
-};
-
-static struct pll_config_regs apcspll_regs __initdata = {
- .l_reg = (void __iomem *)APCS_CPU_PLL_L_REG,
- .m_reg = (void __iomem *)APCS_CPU_PLL_M_REG,
- .n_reg = (void __iomem *)APCS_CPU_PLL_N_REG,
- .config_reg = (void __iomem *)APCS_CPU_PLL_USER_CTL_REG,
- .mode_reg = (void __iomem *)APCS_CPU_PLL_MODE_REG,
- .base = &virt_bases[APCS_PLL_BASE],
-};
-
-/* A5PLL with 998.4MHz */
-static struct pll_config apcspll_config __initdata = {
- .l = 0x34,
- .m = 0x0,
- .n = 0x1,
- .vco_val = 0x0,
- .vco_mask = BM(21, 20),
- .pre_div_val = 0x0,
- .pre_div_mask = BM(14, 12),
- .post_div_val = BVAL(9, 8, 0x0),
- .post_div_mask = BM(9, 8),
- .mn_ena_val = BIT(24),
- .mn_ena_mask = BIT(24),
- .main_output_val = BIT(0),
- .main_output_mask = BIT(0),
-};
-
-#define PLL_AUX_OUTPUT_BIT 1
-#define PLL_AUX2_OUTPUT_BIT 2
-
-static void __init configure_apcs_pll(void)
-{
- u32 regval;
-
- configure_sr_hpm_lp_pll(&apcspll_config, &apcspll_regs, 0);
- writel_relaxed(0x00141200,
- APCS_PLL_REG_BASE(APCS_CPU_PLL_CONFIG_CTL_REG));
- regval = readl_relaxed(APCS_PLL_REG_BASE(APCS_CPU_PLL_USER_CTL_REG));
- regval |= BIT(PLL_AUX_OUTPUT_BIT) | BIT(PLL_AUX2_OUTPUT_BIT);
- writel_relaxed(regval, APCS_PLL_REG_BASE(APCS_CPU_PLL_USER_CTL_REG));
-}
-
-static void __init reg_init(void)
-{
- u32 regval;
-
- if (!(readl_relaxed(GCC_REG_BASE(GPLL0_STATUS_REG))
- & gpll0_clk_src.status_mask))
- configure_sr_hpm_lp_pll(&gpll0_config, &gpll0_regs, 1);
-
- if (!(readl_relaxed(GCC_REG_BASE(GPLL1_STATUS_REG))
- & gpll1_clk_src.status_mask))
- configure_sr_hpm_lp_pll(&gpll1_config, &gpll1_regs, 1);
-
- configure_sr_hpm_lp_pll(&lpapll0_config, &lpapll0_regs, 1);
-
- /* TODO: Remove A5 pll configuration once the bootloader is avaiable */
- regval = readl_relaxed(APCS_PLL_REG_BASE(APCS_CPU_PLL_MODE_REG));
- if ((regval & BM(2, 0)) != 0x7)
- configure_apcs_pll();
-
- /* TODO:
- * 1) do we need to turn on AUX2 output too?
- * 2) if need to vote off all sleep clocks
- */
-
- /* Enable GPLL0's aux outputs. */
- regval = readl_relaxed(GCC_REG_BASE(GPLL0_USER_CTL_REG));
- regval |= BIT(PLL_AUX_OUTPUT_BIT) | BIT(PLL_AUX2_OUTPUT_BIT);
- writel_relaxed(regval, GCC_REG_BASE(GPLL0_USER_CTL_REG));
-
- /* Vote for GPLL0 to turn on. Needed by acpuclock. */
- regval = readl_relaxed(GCC_REG_BASE(APCS_GPLL_ENA_VOTE_REG));
- regval |= BIT(0);
- writel_relaxed(regval, GCC_REG_BASE(APCS_GPLL_ENA_VOTE_REG));
-
- /*
- * TODO: Confirm that no clocks need to be voted on in this sleep vote
- * register.
- */
- writel_relaxed(0x0, GCC_REG_BASE(APCS_CLOCK_SLEEP_ENA_VOTE));
-}
-
-static void __init msm9625_clock_post_init(void)
-{
- /*
- * Hold an active set vote for CXO; this is because CXO is expected
- * to remain on whenever CPUs aren't power collapsed.
- */
- clk_prepare_enable(&cxo_a_clk_src.c);
-
- /* TODO :FIXME */
- clk_prepare_enable(&gcc_qpic_ahb_clk.c);
-
- /* Set rates for single-rate clocks. */
- clk_set_rate(&usb_hs_system_clk_src.c,
- usb_hs_system_clk_src.freq_tbl[0].freq_hz);
- clk_set_rate(&usb_hsic_clk_src.c,
- usb_hsic_clk_src.freq_tbl[0].freq_hz);
- clk_set_rate(&usb_hsic_io_cal_clk_src.c,
- usb_hsic_io_cal_clk_src.freq_tbl[0].freq_hz);
- clk_set_rate(&usb_hsic_system_clk_src.c,
- usb_hsic_system_clk_src.freq_tbl[0].freq_hz);
- clk_set_rate(&usb_hsic_xcvr_fs_clk_src.c,
- usb_hsic_xcvr_fs_clk_src.freq_tbl[0].freq_hz);
- clk_set_rate(&pdm2_clk_src.c, pdm2_clk_src.freq_tbl[0].freq_hz);
- clk_set_rate(&audio_core_slimbus_core_clk_src.c,
- audio_core_slimbus_core_clk_src.freq_tbl[0].freq_hz);
-}
-
-#define GCC_CC_PHYS 0xFC400000
-#define GCC_CC_SIZE SZ_16K
-
-#define LPASS_CC_PHYS 0xFE000000
-#define LPASS_CC_SIZE SZ_256K
-
-#define APCS_GCC_CC_PHYS 0xF9011000
-#define APCS_GCC_CC_SIZE SZ_4K
-
-#define APCS_PLL_PHYS 0xF9008018
-#define APCS_PLL_SIZE 0x18
-
-static void __init msm9625_clock_pre_init(void)
-{
- virt_bases[GCC_BASE] = ioremap(GCC_CC_PHYS, GCC_CC_SIZE);
- if (!virt_bases[GCC_BASE])
- panic("clock-9625: Unable to ioremap GCC memory!");
-
- virt_bases[LPASS_BASE] = ioremap(LPASS_CC_PHYS, LPASS_CC_SIZE);
- if (!virt_bases[LPASS_BASE])
- panic("clock-9625: Unable to ioremap LPASS_CC memory!");
-
- virt_bases[APCS_BASE] = ioremap(APCS_GCC_CC_PHYS, APCS_GCC_CC_SIZE);
- if (!virt_bases[APCS_BASE])
- panic("clock-9625: Unable to ioremap APCS_GCC_CC memory!");
-
- virt_bases[APCS_PLL_BASE] = ioremap(APCS_PLL_PHYS, APCS_PLL_SIZE);
- if (!virt_bases[APCS_PLL_BASE])
- panic("clock-9625: Unable to ioremap APCS_PLL memory!");
-
- clk_ops_local_pll.enable = sr_hpm_lp_pll_clk_enable;
-
- reg_init();
-}
-
-/* TODO: Add vdd level unvote */
-static int __init msm9625_clock_late_init(void)
-{
- return 0;
-}
-
-struct clock_init_data msm9625_clock_init_data __initdata = {
- .table = msm_clocks_9625,
- .size = ARRAY_SIZE(msm_clocks_9625),
- .pre_init = msm9625_clock_pre_init,
- .post_init = msm9625_clock_post_init,
- .late_init = msm9625_clock_late_init,
-};
diff --git a/arch/arm/mach-msm/clock-debug.c b/arch/arm/mach-msm/clock-debug.c
index e942173..8bd4433 100644
--- a/arch/arm/mach-msm/clock-debug.c
+++ b/arch/arm/mach-msm/clock-debug.c
@@ -218,6 +218,28 @@
.release = seq_release,
};
+static int clock_parent_show(struct seq_file *m, void *unused)
+{
+ struct clk *clock = m->private;
+ struct clk *parent = clk_get_parent(clock);
+
+ seq_printf(m, "%s\n", (parent ? parent->dbg_name : "None"));
+
+ return 0;
+}
+
+static int clock_parent_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, clock_parent_show, inode->i_private);
+}
+
+static const struct file_operations clock_parent_fops = {
+ .open = clock_parent_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
static struct dentry *debugfs_base;
static u32 debug_suspend;
@@ -274,6 +296,10 @@
S_IRUGO, clk_dir, clock, &fmax_rates_fops))
goto error;
+ if (!debugfs_create_file("parent", S_IRUGO, clk_dir, clock,
+ &clock_parent_fops))
+ goto error;
+
return 0;
error:
debugfs_remove_recursive(clk_dir);
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index eead627..c30bd79 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -133,6 +133,18 @@
unvote_vdd_level(clk->vdd_class, level);
}
+/* Returns true if the rate is valid without voting for it */
+static bool is_rate_valid(struct clk *clk, unsigned long rate)
+{
+ int level;
+
+ if (!clk->vdd_class)
+ return true;
+
+ level = find_vdd_level(clk, rate);
+ return level >= 0;
+}
+
int clk_prepare(struct clk *clk)
{
int ret = 0;
@@ -331,14 +343,16 @@
/* Enforce vdd requirements for target frequency. */
rc = vote_rate_vdd(clk, rate);
if (rc)
- goto err_vote_vdd;
+ goto out;
rc = clk->ops->set_rate(clk, rate);
if (rc)
goto err_set_rate;
/* Release vdd requirements for starting frequency. */
unvote_rate_vdd(clk, start_rate);
- } else {
+ } else if (is_rate_valid(clk, rate)) {
rc = clk->ops->set_rate(clk, rate);
+ } else {
+ rc = -EINVAL;
}
if (!rc)
@@ -349,7 +363,6 @@
err_set_rate:
unvote_rate_vdd(clk, rate);
-err_vote_vdd:
goto out;
}
EXPORT_SYMBOL(clk_set_rate);
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index 8a75d390..48f897b 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -34,7 +34,6 @@
};
extern struct clock_init_data msm9615_clock_init_data;
-extern struct clock_init_data msm9625_clock_init_data;
extern struct clock_init_data apq8064_clock_init_data;
extern struct clock_init_data fsm9xxx_clock_init_data;
extern struct clock_init_data msm7x01a_clock_init_data;
diff --git a/arch/arm/mach-msm/devices-iommu.c b/arch/arm/mach-msm/devices-iommu.c
index acf577e..6434a63 100644
--- a/arch/arm/mach-msm/devices-iommu.c
+++ b/arch/arm/mach-msm/devices-iommu.c
@@ -1017,13 +1017,13 @@
ARRAY_SIZE(msm_iommu_gfx2d_devs));
}
- if (cpu_is_apq8064() || cpu_is_msm8960ab()) {
+ if (cpu_is_apq8064() || cpu_is_msm8960ab() || cpu_is_apq8064ab()) {
platform_add_devices(msm_iommu_jpegd_devs,
ARRAY_SIZE(msm_iommu_jpegd_devs));
platform_add_devices(msm_iommu_adreno3xx_gfx_devs,
ARRAY_SIZE(msm_iommu_adreno3xx_gfx_devs));
}
- if (cpu_is_apq8064())
+ if (cpu_is_apq8064() || cpu_is_apq8064ab())
platform_add_devices(msm_iommu_vcap_devs,
ARRAY_SIZE(msm_iommu_vcap_devs));
@@ -1039,14 +1039,14 @@
ARRAY_SIZE(msm_iommu_gfx2d_ctx_devs));
}
- if (cpu_is_apq8064() || cpu_is_msm8960ab()) {
+ if (cpu_is_apq8064() || cpu_is_msm8960ab() || cpu_is_apq8064ab()) {
platform_add_devices(msm_iommu_jpegd_ctx_devs,
ARRAY_SIZE(msm_iommu_jpegd_ctx_devs));
platform_add_devices(msm_iommu_adreno3xx_ctx_devs,
ARRAY_SIZE(msm_iommu_adreno3xx_ctx_devs));
}
- if (cpu_is_apq8064())
+ if (cpu_is_apq8064() || cpu_is_apq8064ab())
platform_add_devices(msm_iommu_vcap_ctx_devs,
ARRAY_SIZE(msm_iommu_vcap_ctx_devs));
@@ -1081,12 +1081,12 @@
for (i = 0; i < ARRAY_SIZE(msm_iommu_jpegd_devs); i++)
platform_device_unregister(msm_iommu_jpegd_devs[i]);
}
- if (cpu_is_apq8064()) {
+ if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
for (i = 0; i < ARRAY_SIZE(msm_iommu_vcap_ctx_devs); i++)
platform_device_unregister(msm_iommu_vcap_ctx_devs[i]);
}
- if (cpu_is_apq8064() || cpu_is_msm8960ab()) {
+ if (cpu_is_apq8064() || cpu_is_msm8960ab() || cpu_is_apq8064ab()) {
for (i = 0; i < ARRAY_SIZE(msm_iommu_adreno3xx_ctx_devs);
i++)
platform_device_unregister(
@@ -1097,7 +1097,7 @@
platform_device_unregister(
msm_iommu_jpegd_ctx_devs[i]);
- if (cpu_is_apq8064()) {
+ if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
for (i = 0; i < ARRAY_SIZE(msm_iommu_vcap_devs);
i++)
platform_device_unregister(
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 65dfc31..50ab26f 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -1664,12 +1664,13 @@
* These are various Vdd levels supported by PMIC
*/
static uint32_t msm_c2_pmic_mv[] __initdata = {
- 1300000, 1287500, 1275000, 1262500, 1250000,
- 1237500, 1225000, 1212500, 1200000, 1187500,
- 1175000, 1162500, 1150000, 1137500, 1125000,
- 1112500, 1100000, 1087500, 1075000, 1062500,
- 1050000, 1037500, 1025000, 1012500, 0, 0, 0,
- 0, 0, 0, 0, 1000,
+ 1350000, 1337500, 1325000, 1312500, 1300000,
+ 1287500, 1275000, 1262500, 1250000, 1237500,
+ 1225000, 1212500, 1200000, 1187500, 1175000,
+ 1162500, 1150000, 1137500, 1125000, 1112500,
+ 1100000, 1087500, 1075000, 1062500, 0,
+ 0, 0, 0, 0, 0,
+ 0, 1050000,
};
/**
@@ -1709,9 +1710,9 @@
.step_quot = ~0,
.tgt_volt_offset = 0,
.turbo_Vmax = 1350000,
- .turbo_Vmin = 950000,
+ .turbo_Vmin = 1100000,
.nom_Vmax = 1350000,
- .nom_Vmin = 950000,
+ .nom_Vmin = 1100000,
.calibrated_uV = 1300000,
},
};
@@ -1729,7 +1730,7 @@
uint32_t quot;
/* This formula is as per chip characterization data */
- quot = max_quot - (((max_freq - new_freq) * 5) / 10);
+ quot = max_quot - (((max_freq - new_freq) * 7) / 10);
return quot;
}
@@ -1749,7 +1750,7 @@
static struct msm_cpr_config msm_cpr_pdata = {
.ref_clk_khz = 19200,
- .delay_us = 25000,
+ .delay_us = 1000,
.irq_line = 0,
.cpr_mode_data = msm_cpr_mode_data,
.tgt_count_div_N = 1,
@@ -1757,7 +1758,7 @@
.ceiling = 40,
.sw_vlevel = 20,
.up_threshold = 1,
- .dn_threshold = 2,
+ .dn_threshold = 4,
.up_margin = 0,
.dn_margin = 0,
.max_nom_freq = 700800,
@@ -1819,6 +1820,22 @@
* enough to represent the value of maximum quot
*/
msm_cpr_pdata.max_quot = cpr_info->turbo_quot * 10 + 600;
+ /**
+ * Fused Quot value for 1.2GHz on a 1.2GHz part is lower than
+ * the quot value calculated using the scaling factor formula for
+ * 1.2GHz when running on a 1.4GHz part. So, prop up the Quot for
+ * a 1.2GHz part by a chip characterization recommended value.
+ * Ditto for a 1.0GHz part.
+ */
+ if (msm8625_cpu_id() == MSM8625A) {
+ msm_cpr_pdata.max_quot += 100;
+ if (msm_cpr_pdata.max_quot > 1400)
+ msm_cpr_pdata.max_quot = 1400;
+ } else if (msm8625_cpu_id() == MSM8625) {
+ msm_cpr_pdata.max_quot += 120;
+ if (msm_cpr_pdata.max_quot > 1350)
+ msm_cpr_pdata.max_quot = 1350;
+ }
/**
* Bits 4:0 of pvs_fuse provide mapping to the safe boot up voltage.
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index 7bffd9b..b88fb50 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -210,6 +210,7 @@
};
#define MSM_MSS_REGS_PHYS 0x10200000
+#define MSM_MSS_WDOG_PHYS 0x10020000
static struct resource msm_8660_modem_resources[] = {
{
@@ -217,6 +218,16 @@
.end = MSM_MSS_REGS_PHYS + SZ_256 - 1,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = MSM_MSS_WDOG_PHYS,
+ .end = MSM_MSS_WDOG_PHYS + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MARM_WDOG_EXPIRED,
+ .end = MARM_WDOG_EXPIRED,
+ .flags = IORESOURCE_IRQ,
+ },
};
struct platform_device msm_pil_modem = {
diff --git a/arch/arm/mach-msm/gss-8064.c b/arch/arm/mach-msm/gss-8064.c
index e528650..ba6af61 100644
--- a/arch/arm/mach-msm/gss-8064.c
+++ b/arch/arm/mach-msm/gss-8064.c
@@ -200,7 +200,7 @@
{
int ret;
- if (!cpu_is_apq8064())
+ if (!(cpu_is_apq8064() || cpu_is_apq8064ab()))
return -ENODEV;
ret = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_RESET,
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index b14f145..f63af64 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -38,6 +38,8 @@
/* Maximum number of SMT entries allowed by the system */
#define MAX_NUM_SMR 128
+#define MAX_NUM_BFB_REGS 32
+
/**
* struct msm_iommu_dev - a single IOMMU hardware instance
* name Human-readable name given to this IOMMU HW instance
@@ -64,6 +66,17 @@
int mids[MAX_NUM_MIDS];
};
+/**
+ * struct msm_iommu_bfb_settings - a set of IOMMU BFB tuning parameters
+ * regs An array of register offsets to configure
+ * data Values to write to corresponding registers
+ * length Number of valid entries in the offset/val arrays
+ */
+struct msm_iommu_bfb_settings {
+ unsigned int regs[MAX_NUM_BFB_REGS];
+ unsigned int data[MAX_NUM_BFB_REGS];
+ int length;
+};
/**
* struct msm_iommu_drvdata - A single IOMMU hardware instance
@@ -76,6 +89,7 @@
* @name: Human-readable name of this IOMMU device
* @gdsc: Regulator needed to power this HW block (v2 only)
* @nsmr: Size of the SMT on this HW block (v2 only)
+ * @bfb_settings: Optional BFB performance tuning parameters
*
* A msm_iommu_drvdata holds the global driver data about a single piece
* of an IOMMU hardware instance.
@@ -90,6 +104,7 @@
const char *name;
struct regulator *gdsc;
unsigned int nsmr;
+ struct msm_iommu_bfb_settings *bfb_settings;
};
/**
diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-v2.h b/arch/arm/mach-msm/include/mach/iommu_hw-v2.h
index b01dbd8..c4991bf 100644
--- a/arch/arm/mach-msm/include/mach/iommu_hw-v2.h
+++ b/arch/arm/mach-msm/include/mach/iommu_hw-v2.h
@@ -15,6 +15,8 @@
#define CTX_SHIFT 12
#define CTX_OFFSET 0x8000
+#define IMPLDEF_OFFSET 0x2000
+#define IMPLDEF_LENGTH 0xDFF
#define GET_GLOBAL_REG(reg, base) (readl_relaxed((base) + (reg)))
#define GET_CTX_REG(reg, base, ctx) \
diff --git a/arch/arm/mach-msm/include/mach/irqs-8625.h b/arch/arm/mach-msm/include/mach/irqs-8625.h
index 413a778..2ec0e21 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8625.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8625.h
@@ -87,6 +87,8 @@
#define MSM8625_INT_CPR_IRQ0 (GIC_SPI_START + 32 + 25)
#define MSM8625_INT_CPR_IRQ1 (GIC_SPI_START + 32 + 26)
#define MSM8625_INT_CPR_IRQ2 (GIC_SPI_START + 32 + 27)
+#define MSM8625_INT_ACSR_MP_CORE_IPC2 (GIC_SPI_START + 32 + 28)
+#define MSM8625_INT_ACSR_MP_CORE_IPC3 (GIC_SPI_START + 32 + 29)
#define MSM8625_INT_ADSP_A11_SMSM MSM8625_INT_ADSP_A11
#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index 6f925d4..8dbd29c 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -101,7 +101,7 @@
#define MSM_DBG_IMEM_BASE IOMEM(0xFB600000) /* 4K */
#define MSM_STRONGLY_ORDERED_PAGE 0xFA0F0000
-#define MSM8625_SECONDARY_PHYS 0x0FE00000
+#define MSM8625_CPU_PHYS 0x0FE00000
#if defined(CONFIG_ARCH_MSM9615) || defined(CONFIG_ARCH_MSM7X27) \
diff --git a/arch/arm/mach-msm/include/mach/msm_smsm.h b/arch/arm/mach-msm/include/mach/msm_smsm.h
index be8f6c1..44b52b6 100644
--- a/arch/arm/mach-msm/include/mach/msm_smsm.h
+++ b/arch/arm/mach-msm/include/mach/msm_smsm.h
@@ -57,8 +57,7 @@
#define SMSM_PWRC 0x00000200
#define SMSM_TIMEWAIT 0x00000400
#define SMSM_TIMEINIT 0x00000800
-#define SMSM_PWRC_EARLY_EXIT 0x00001000
-#define SMSM_LTE_COEX_AWAKE 0x00001000
+#define SMSM_PROC_AWAKE 0x00001000
#define SMSM_WFPI 0x00002000
#define SMSM_SLEEP 0x00004000
#define SMSM_SLEEPEXIT 0x00008000
diff --git a/arch/arm/mach-msm/include/mach/socinfo.h b/arch/arm/mach-msm/include/mach/socinfo.h
index 546cbaf..225440c 100644
--- a/arch/arm/mach-msm/include/mach/socinfo.h
+++ b/arch/arm/mach-msm/include/mach/socinfo.h
@@ -89,6 +89,7 @@
MSM_CPU_7X25AA,
MSM_CPU_7X25AB,
MSM_CPU_8064,
+ MSM_CPU_8064AB,
MSM_CPU_8930,
MSM_CPU_8930AA,
MSM_CPU_7X27AA,
@@ -304,6 +305,15 @@
#endif
}
+static inline int cpu_is_apq8064ab(void)
+{
+#ifdef CONFIG_ARCH_APQ8064
+ return read_msm_cpu_type() == MSM_CPU_8064AB;
+#else
+ return 0;
+#endif
+}
+
static inline int cpu_is_msm8930(void)
{
#ifdef CONFIG_ARCH_MSM8930
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index 74c1c4a..a785389 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -173,63 +173,29 @@
struct reserve_info *reserve_info;
-static unsigned long stable_size(struct membank *mb,
- unsigned long unstable_limit)
-{
- unsigned long upper_limit = mb->start + mb->size;
-
- if (!unstable_limit)
- return mb->size;
-
- /* Check for 32 bit roll-over */
- if (upper_limit >= mb->start) {
- /* If we didn't roll over we can safely make the check below */
- if (upper_limit <= unstable_limit)
- return mb->size;
- }
-
- if (mb->start >= unstable_limit)
- return 0;
- return unstable_limit - mb->start;
-}
-
-/* stable size of all memory banks contiguous to and below this one */
-static unsigned long total_stable_size(unsigned long bank)
-{
- int i;
- struct membank *mb = &meminfo.bank[bank];
- int memtype = reserve_info->paddr_to_memtype(mb->start);
- unsigned long size;
-
- size = stable_size(mb, reserve_info->low_unstable_address);
- for (i = bank - 1, mb = &meminfo.bank[bank - 1]; i >= 0; i--, mb--) {
- if (mb->start + mb->size != (mb + 1)->start)
- break;
- if (reserve_info->paddr_to_memtype(mb->start) != memtype)
- break;
- size += stable_size(mb, reserve_info->low_unstable_address);
- }
- return size;
-}
-
+/**
+ * calculate_reserve_limits() - calculate reserve limits for all
+ * memtypes
+ *
+ * for each memtype in the reserve_info->memtype_reserve_table, sets
+ * the `limit' field to the largest size of any memblock of that
+ * memtype.
+ */
static void __init calculate_reserve_limits(void)
{
- int i;
- struct membank *mb;
+ struct memblock_region *mr;
int memtype;
struct memtype_reserve *mt;
- unsigned long size;
- for (i = 0, mb = &meminfo.bank[0]; i < meminfo.nr_banks; i++, mb++) {
- memtype = reserve_info->paddr_to_memtype(mb->start);
+ for_each_memblock(memory, mr) {
+ memtype = reserve_info->paddr_to_memtype(mr->base);
if (memtype == MEMTYPE_NONE) {
- pr_warning("unknown memory type for bank at %lx\n",
- (long unsigned int)mb->start);
+ pr_warning("unknown memory type for region at %lx\n",
+ (long unsigned int)mr->base);
continue;
}
mt = &reserve_info->memtype_reserve_table[memtype];
- size = total_stable_size(i);
- mt->limit = max(mt->limit, size);
+ mt->limit = max_t(unsigned long, mt->limit, mr->size);
}
}
@@ -252,50 +218,38 @@
static void __init reserve_memory_for_mempools(void)
{
- int i, memtype, membank_type;
+ int memtype, memreg_type;
struct memtype_reserve *mt;
- struct membank *mb;
+ struct memblock_region *mr, *mr_candidate = NULL;
int ret;
- unsigned long size;
mt = &reserve_info->memtype_reserve_table[0];
for (memtype = 0; memtype < MEMTYPE_MAX; memtype++, mt++) {
if (mt->flags & MEMTYPE_FLAGS_FIXED || !mt->size)
continue;
- /* We know we will find memory bank(s) of the proper size
- * as we have limited the size of the memory pool for
- * each memory type to the largest total size of the memory
- * banks which are contiguous and of the correct memory type.
- * Choose the memory bank with the highest physical
+ /* Choose the memory block with the highest physical
* address which is large enough, so that we will not
* take memory from the lowest memory bank which the kernel
* is in (and cause boot problems) and so that we might
* be able to steal memory that would otherwise become
- * highmem. However, do not use unstable memory.
+ * highmem.
*/
- for (i = meminfo.nr_banks - 1; i >= 0; i--) {
- mb = &meminfo.bank[i];
- membank_type =
- reserve_info->paddr_to_memtype(mb->start);
- if (memtype != membank_type)
+ for_each_memblock(memory, mr) {
+ memreg_type =
+ reserve_info->paddr_to_memtype(mr->base);
+ if (memtype != memreg_type)
continue;
- size = total_stable_size(i);
- if (size >= mt->size) {
- size = stable_size(mb,
- reserve_info->low_unstable_address);
- if (!size)
- continue;
- /* mt->size may be larger than size, all this
- * means is that we are carving the memory pool
- * out of multiple contiguous memory banks.
- */
- mt->start = mb->start + (size - mt->size);
- ret = memblock_remove(mt->start, mt->size);
- BUG_ON(ret);
- break;
- }
+ if (mr->size >= mt->size
+ && (mr_candidate == NULL
+ || mr->base > mr_candidate->base))
+ mr_candidate = mr;
}
+ BUG_ON(mr_candidate == NULL);
+ /* bump mt up against the top of the region */
+ mt->start = mr_candidate->base + mr_candidate->size - mt->size;
+ ret = memblock_remove(mt->start, mt->size);
+ BUG_ON(ret);
}
}
diff --git a/arch/arm/mach-msm/modem-8660.c b/arch/arm/mach-msm/modem-8660.c
deleted file mode 100644
index 096ed9c..0000000
--- a/arch/arm/mach-msm/modem-8660.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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 <linux/interrupt.h>
-#include <linux/reboot.h>
-#include <linux/workqueue.h>
-#include <linux/io.h>
-#include <linux/jiffies.h>
-#include <linux/stringify.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/err.h>
-
-#include <mach/irqs.h>
-#include <mach/scm.h>
-#include <mach/peripheral-loader.h>
-#include <mach/subsystem_restart.h>
-#include <mach/subsystem_notif.h>
-
-#include "smd_private.h"
-#include "modem_notifier.h"
-#include "ramdump.h"
-
-#define MODEM_HWIO_MSS_RESET_ADDR 0x00902C48
-#define MODULE_NAME "modem_8660"
-#define MODEM_WDOG_ENABLE 0x10020008
-#define MODEM_CLEANUP_DELAY_MS 20
-
-#define SUBSYS_FATAL_DEBUG
-
-#if defined(SUBSYS_FATAL_DEBUG)
-static void debug_crash_modem_fn(struct work_struct *);
-static int reset_modem;
-static int ignore_smsm_ack;
-
-static DECLARE_DELAYED_WORK(debug_crash_modem_work,
- debug_crash_modem_fn);
-
-module_param(reset_modem, int, 0644);
-#endif
-
-static struct subsys_device *modem_8660_dev;
-
-/* Subsystem restart: Modem data, functions */
-static void *modem_ramdump_dev;
-static void modem_fatal_fn(struct work_struct *);
-static void modem_unlock_timeout(struct work_struct *work);
-static int modem_notif_handler(struct notifier_block *this,
- unsigned long code,
- void *_cmd);
-static DECLARE_WORK(modem_fatal_work, modem_fatal_fn);
-static DECLARE_DELAYED_WORK(modem_unlock_timeout_work,
- modem_unlock_timeout);
-
-static struct notifier_block modem_notif_nb = {
- .notifier_call = modem_notif_handler,
-};
-
-static void modem_unlock_timeout(struct work_struct *work)
-{
- void __iomem *hwio_modem_reset_addr =
- ioremap_nocache(MODEM_HWIO_MSS_RESET_ADDR, 8);
- pr_crit("%s: Timeout waiting for modem to unlock.\n", MODULE_NAME);
-
- /* Set MSS_MODEM_RESET to 0x0 since the unlock didn't work */
- writel_relaxed(0x0, hwio_modem_reset_addr);
- /* Write needs to go through before the modem is restarted. */
- mb();
- iounmap(hwio_modem_reset_addr);
-
- subsystem_restart_dev(modem_8660_dev);
- enable_irq(MARM_WDOG_EXPIRED);
-}
-
-static void modem_fatal_fn(struct work_struct *work)
-{
- uint32_t modem_state;
- uint32_t panic_smsm_states = SMSM_RESET | SMSM_SYSTEM_DOWNLOAD;
- uint32_t reset_smsm_states = SMSM_SYSTEM_REBOOT_USR |
- SMSM_SYSTEM_PWRDWN_USR;
-
- pr_err("%s: Watchdog bite received from modem!\n", MODULE_NAME);
-
- modem_state = smsm_get_state(SMSM_MODEM_STATE);
- pr_err("%s: Modem SMSM state = 0x%x!", MODULE_NAME, modem_state);
-
- if (modem_state == 0 || modem_state & panic_smsm_states) {
-
- subsystem_restart_dev(modem_8660_dev);
- enable_irq(MARM_WDOG_EXPIRED);
-
- } else if (modem_state & reset_smsm_states) {
-
- pr_err("%s: User-invoked system reset/powerdown.",
- MODULE_NAME);
- kernel_restart(NULL);
-
- } else {
-
- int ret;
- void *hwio_modem_reset_addr =
- ioremap_nocache(MODEM_HWIO_MSS_RESET_ADDR, 8);
-
- pr_err("%s: Modem AHB locked up.\n", MODULE_NAME);
- pr_err("%s: Trying to free up modem!\n", MODULE_NAME);
-
- writel_relaxed(0x3, hwio_modem_reset_addr);
-
- /* If we are still alive after 6 seconds (allowing for
- * the 5-second-delayed-panic-reboot), modem is either
- * still wedged or SMSM didn't come through. Force panic
- * in that case.
- */
- ret = schedule_delayed_work(&modem_unlock_timeout_work,
- msecs_to_jiffies(6000));
-
- iounmap(hwio_modem_reset_addr);
- }
-}
-
-static int modem_notif_handler(struct notifier_block *this,
- unsigned long code,
- void *_cmd)
-{
- if (code == MODEM_NOTIFIER_START_RESET) {
- if (ignore_smsm_ack) {
- ignore_smsm_ack = 0;
- goto out;
- }
- pr_err("%s: Modem error fatal'ed.", MODULE_NAME);
- subsystem_restart_dev(modem_8660_dev);
- }
-out:
- return NOTIFY_DONE;
-}
-
-static int modem_shutdown(const struct subsys_desc *crashed_subsys)
-{
- void __iomem *modem_wdog_addr;
-
- /* If the modem didn't already crash, setting SMSM_RESET
- * here will help flush caches etc. The ignore_smsm_ack
- * flag is set to ignore the SMSM_RESET notification
- * that is generated due to the modem settings its own
- * SMSM_RESET bit in response to the apps setting the
- * apps SMSM_RESET bit.
- */
- if (!(smsm_get_state(SMSM_MODEM_STATE) & SMSM_RESET)) {
- ignore_smsm_ack = 1;
- smsm_reset_modem(SMSM_RESET);
- }
-
- /* Disable the modem watchdog to allow clean modem bootup */
- modem_wdog_addr = ioremap_nocache(MODEM_WDOG_ENABLE, 8);
- writel_relaxed(0x0, modem_wdog_addr);
-
- /*
- * The write above needs to go through before the modem is
- * powered up again (subsystem restart).
- */
- mb();
- iounmap(modem_wdog_addr);
-
- /* Wait here to allow the modem to clean up caches etc. */
- msleep(MODEM_CLEANUP_DELAY_MS);
- pil_force_shutdown("modem");
- disable_irq_nosync(MARM_WDOG_EXPIRED);
-
-
-
- return 0;
-}
-
-static int modem_powerup(const struct subsys_desc *crashed_subsys)
-{
- int ret;
-
- ret = pil_force_boot("modem");
- enable_irq(MARM_WDOG_EXPIRED);
-
- return ret;
-}
-
-/* FIXME: Get address, size from PIL */
-static struct ramdump_segment modem_segments[] = {
- {0x42F00000, 0x46000000 - 0x42F00000} };
-
-static int modem_ramdump(int enable, const struct subsys_desc *crashed_subsys)
-{
- if (enable)
- return do_ramdump(modem_ramdump_dev, modem_segments,
- ARRAY_SIZE(modem_segments));
- else
- return 0;
-}
-
-static void modem_crash_shutdown(const struct subsys_desc *crashed_subsys)
-{
- /* If modem hasn't already crashed, send SMSM_RESET. */
- if (!(smsm_get_state(SMSM_MODEM_STATE) & SMSM_RESET)) {
- modem_unregister_notifier(&modem_notif_nb);
- smsm_reset_modem(SMSM_RESET);
- }
-
- /* Wait to allow the modem to clean up caches etc. */
- mdelay(5);
-}
-
-static irqreturn_t modem_wdog_bite_irq(int irq, void *dev_id)
-{
- int ret;
-
- ret = schedule_work(&modem_fatal_work);
- disable_irq_nosync(MARM_WDOG_EXPIRED);
-
- return IRQ_HANDLED;
-}
-
-static struct subsys_desc subsys_8660_modem = {
- .name = "modem",
- .shutdown = modem_shutdown,
- .powerup = modem_powerup,
- .ramdump = modem_ramdump,
- .crash_shutdown = modem_crash_shutdown
-};
-
-static int __init modem_8660_init(void)
-{
- int ret;
-
- /* Need to listen for SMSM_RESET always */
- modem_register_notifier(&modem_notif_nb);
-
-#if defined(SUBSYS_FATAL_DEBUG)
- schedule_delayed_work(&debug_crash_modem_work, msecs_to_jiffies(5000));
-#endif
-
- ret = request_irq(MARM_WDOG_EXPIRED, modem_wdog_bite_irq,
- IRQF_TRIGGER_RISING, "modem_wdog", NULL);
-
- if (ret < 0) {
- pr_err("%s: Unable to request MARM_WDOG_EXPIRED irq.",
- __func__);
- goto out;
- }
-
- modem_ramdump_dev = create_ramdump_device("modem");
-
- if (!modem_ramdump_dev) {
- ret = -ENOMEM;
- goto out;
- }
-
- modem_8660_dev = subsys_register(&subsys_8660_modem);
- if (IS_ERR(modem_8660_dev))
- ret = PTR_ERR(modem_8660_dev);
-out:
- return ret;
-}
-
-static void __exit modem_8660_exit(void)
-{
- subsys_unregister(modem_8660_dev);
- free_irq(MARM_WDOG_EXPIRED, NULL);
-}
-
-#ifdef SUBSYS_FATAL_DEBUG
-static void debug_crash_modem_fn(struct work_struct *work)
-{
- if (reset_modem == 1)
- smsm_reset_modem(SMSM_RESET);
-
- reset_modem = 0;
- schedule_delayed_work(&debug_crash_modem_work, msecs_to_jiffies(1000));
-}
-#endif
-
-module_init(modem_8660_init);
-module_exit(modem_8660_exit);
-
diff --git a/arch/arm/mach-msm/modem-8960.c b/arch/arm/mach-msm/modem-8960.c
index f0a123b..83b3bc4 100644
--- a/arch/arm/mach-msm/modem-8960.c
+++ b/arch/arm/mach-msm/modem-8960.c
@@ -258,7 +258,7 @@
{
int ret;
- if (cpu_is_apq8064())
+ if (cpu_is_apq8064() || cpu_is_apq8064ab())
return -ENODEV;
ret = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_RESET,
diff --git a/arch/arm/mach-msm/msm_cpr.c b/arch/arm/mach-msm/msm_cpr.c
index 12f7d96..c00352d 100644
--- a/arch/arm/mach-msm/msm_cpr.c
+++ b/arch/arm/mach-msm/msm_cpr.c
@@ -1,5 +1,4 @@
-/*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, 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
@@ -54,6 +53,26 @@
module_param(enable, bool, 0644);
MODULE_PARM_DESC(enable, "CPR Enable");
+static int msm_cpr_debug_mask;
+module_param_named(
+ debug_mask, msm_cpr_debug_mask, int, S_IRUGO | S_IWUSR
+);
+
+enum {
+ /* configuration log */
+ MSM_CPR_DEBUG_CONFIG = BIT(0),
+ /* step up/down interrupt log */
+ MSM_CPR_DEBUG_STEPS = BIT(1),
+ /* cpu frequency notification log */
+ MSM_CPR_DEBUG_FREQ_TRANS = BIT(2),
+};\
+
+#define msm_cpr_debug(mask, message, ...) \
+ do { \
+ if ((mask) & msm_cpr_debug_mask) \
+ pr_info(message, ##__VA_ARGS__); \
+ } while (0)
+
struct msm_cpr {
int curr_osc;
int cpr_mode;
@@ -65,7 +84,9 @@
unsigned int irq;
uint32_t cur_Vmin;
uint32_t cur_Vmax;
+ uint32_t prev_volt_uV;
struct mutex cpr_mutex;
+ spinlock_t cpr_lock;
struct regulator *vreg_cx;
const struct msm_cpr_config *config;
struct notifier_block freq_transition;
@@ -133,17 +154,17 @@
/* Enable the CPR H/W Block */
static void cpr_enable(struct msm_cpr *cpr)
{
- mutex_lock(&cpr->cpr_mutex);
+ spin_lock(&cpr->cpr_lock);
cpr_modify_reg(cpr, RBCPR_CTL, LOOP_EN_M, ENABLE_CPR);
- mutex_unlock(&cpr->cpr_mutex);
+ spin_unlock(&cpr->cpr_lock);
}
/* Disable the CPR H/W Block */
static void cpr_disable(struct msm_cpr *cpr)
{
- mutex_lock(&cpr->cpr_mutex);
+ spin_lock(&cpr->cpr_lock);
cpr_modify_reg(cpr, RBCPR_CTL, LOOP_EN_M, DISABLE_CPR);
- mutex_unlock(&cpr->cpr_mutex);
+ spin_unlock(&cpr->cpr_lock);
}
static int32_t cpr_poll_result(struct msm_cpr *cpr)
@@ -154,8 +175,7 @@
rc = readl_poll_timeout(cpr->base + RBCPR_RESULT_0, val, ~val & BUSY_M,
10, 1000);
if (rc)
- pr_info("%s: RBCPR_RESULT_0 read error: %d\n",
- __func__, rc);
+ pr_err("RBCPR_RESULT_0 read error: %d\n", rc);
return rc;
}
@@ -167,8 +187,7 @@
rc = readl_poll_timeout(cpr->base + RBIF_IRQ_STATUS, val, val & 0x1,
10, 1000);
if (rc)
- pr_info("%s: RBCPR_IRQ_STATUS read error: %d\n",
- __func__, rc);
+ pr_err("RBCPR_IRQ_STATUS read error: %d\n", rc);
return rc;
}
@@ -200,15 +219,16 @@
*/
level_uV = chip_data->turbo_Vmax -
(chip_data->tgt_volt_offset * cpr->vp->step_size);
- pr_debug("tgt_volt_uV = %d\n", level_uV);
+ msm_cpr_debug(MSM_CPR_DEBUG_CONFIG,
+ "tgt_volt_uV = %d\n", level_uV);
/* Call the PMIC specific routine to set the voltage */
rc = regulator_set_voltage(cpr->vreg_cx, level_uV, level_uV);
if (rc) {
- pr_err("%s: Initial voltage set at %duV failed. %d\n",
- __func__, level_uV, rc);
+ pr_err("Initial voltage set at %duV failed\n", level_uV);
return;
}
+
rc = regulator_enable(cpr->vreg_cx);
if (rc) {
pr_err("failed to enable %s, rc=%d\n", "vdd_cx", rc);
@@ -226,15 +246,13 @@
/* IRQ is already disabled */
rc = cpr_poll_result_done(cpr);
if (rc) {
- pr_err("%s: Quot1: Exiting due to INT_DONE poll timeout\n",
- __func__);
+ pr_err("Quot1: Exiting due to INT_DONE poll timeout\n");
return;
}
rc = cpr_poll_result(cpr);
if (rc) {
- pr_err("%s: Quot1: Exiting due to BUSY poll timeout\n",
- __func__);
+ pr_err("Quot1: Exiting due to BUSY poll timeout\n");
return;
}
@@ -242,14 +260,14 @@
/* Take second CPR measurement at a lower voltage to get QUOT2 */
level_uV -= 4 * cpr->vp->step_size;
- pr_debug("tgt_volt_uV = %d\n", level_uV);
+ msm_cpr_debug(MSM_CPR_DEBUG_CONFIG,
+ "tgt_volt_uV = %d\n", level_uV);
cpr_modify_reg(cpr, RBCPR_CTL, LOOP_EN_M, DISABLE_CPR);
/* Call the PMIC specific routine to set the voltage */
rc = regulator_set_voltage(cpr->vreg_cx, level_uV, level_uV);
if (rc) {
- pr_err("%s: Voltage set at %duV failed. %d\n",
- __func__, level_uV, rc);
+ pr_err("Voltage set at %duV failed\n", level_uV);
return;
}
@@ -259,15 +277,13 @@
/* cpr_write_reg(cpr, RBIF_CONT_NACK_CMD, 0x1); */
rc = cpr_poll_result_done(cpr);
if (rc) {
- pr_err("%s: Quot2: Exiting due to INT_DONE poll timeout\n",
- __func__);
+ pr_err("Quot2: Exiting due to INT_DONE poll timeout\n");
goto err_poll_result_done;
}
/* IRQ is already disabled */
rc = cpr_poll_result(cpr);
if (rc) {
- pr_err("%s: Quot2: Exiting due to BUSY poll timeout\n",
- __func__);
+ pr_err("Quot2: Exiting due to BUSY poll timeout\n");
goto err_poll_result;
}
quot2 = (cpr_read_reg(cpr, RBCPR_DEBUG1) & QUOT_SLOW_M) >> 12;
@@ -283,8 +299,8 @@
chip_data->step_quot > STEP_QUOT_MAX)
chip_data->step_quot = STEP_QUOT_MAX;
- pr_info("%s: Step Quot is %d\n",
- __func__, chip_data->step_quot);
+ msm_cpr_debug(MSM_CPR_DEBUG_CONFIG,
+ "Step Quot is %d\n", chip_data->step_quot);
/* Disable the cpr */
cpr_modify_reg(cpr, RBCPR_CTL, LOOP_EN_M, DISABLE_CPR);
@@ -329,27 +345,31 @@
static void
cpr_up_event_handler(struct msm_cpr *cpr, uint32_t new_volt)
{
- int rc, set_volt_uV;
+ int set_volt_uV, rc;
struct msm_cpr_mode *chip_data;
chip_data = &cpr->config->cpr_mode_data[cpr->cpr_mode];
- /**
- * FIXME: Need to handle a potential race condition between
- * freq switch handler and CPR interrupt handler here
- */
/* Set New PMIC voltage */
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "current Vmin=%d Vmax=%d\n", cpr->cur_Vmin, cpr->cur_Vmax);
set_volt_uV = (new_volt < cpr->cur_Vmax ? new_volt
: cpr->cur_Vmax);
- rc = regulator_set_voltage(cpr->vreg_cx, set_volt_uV,
- set_volt_uV);
+
+ if (cpr->prev_volt_uV == set_volt_uV)
+ rc = regulator_sync_voltage(cpr->vreg_cx);
+ else
+ rc = regulator_set_voltage(cpr->vreg_cx, set_volt_uV,
+ set_volt_uV);
if (rc) {
- pr_err("%s: Voltage set at %duV failed. %d\n",
- __func__, set_volt_uV, rc);
+ pr_err("Unable to set_voltage = %d, rc(%d)\n", set_volt_uV, rc);
cpr_irq_clr_and_nack(cpr, BIT(4) | BIT(0));
return;
}
- pr_info("(railway_voltage: %d uV)\n", set_volt_uV);
+
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "(railway_voltage: %d uV)\n", set_volt_uV);
+ cpr->prev_volt_uV = set_volt_uV;
cpr->max_volt_set = (set_volt_uV == cpr->cur_Vmax) ? 1 : 0;
@@ -371,27 +391,29 @@
static void
cpr_dn_event_handler(struct msm_cpr *cpr, uint32_t new_volt)
{
- int rc, set_volt_uV;
+ int set_volt_uV, rc;
struct msm_cpr_mode *chip_data;
chip_data = &cpr->config->cpr_mode_data[cpr->cpr_mode];
- /**
- * FIXME: Need to handle a potential race condition between
- * freq switch handler and CPR interrupt handler here
- */
/* Set New PMIC volt */
set_volt_uV = (new_volt > cpr->cur_Vmin ? new_volt
: cpr->cur_Vmin);
- rc = regulator_set_voltage(cpr->vreg_cx, set_volt_uV,
- set_volt_uV);
+
+ if (cpr->prev_volt_uV == set_volt_uV)
+ rc = regulator_sync_voltage(cpr->vreg_cx);
+ else
+ rc = regulator_set_voltage(cpr->vreg_cx, set_volt_uV,
+ set_volt_uV);
if (rc) {
- pr_err("%s: Voltage at %duV failed %d\n",
- __func__, set_volt_uV, rc);
+ pr_err("Unable to set_voltage = %d, rc(%d)\n", set_volt_uV, rc);
cpr_irq_clr_and_nack(cpr, BIT(2) | BIT(0));
return;
}
- pr_info("(railway_voltage: %d uV)\n", set_volt_uV);
+
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "(railway_voltage: %d uV)\n", set_volt_uV);
+ cpr->prev_volt_uV = set_volt_uV;
cpr->max_volt_set = 0;
@@ -415,7 +437,8 @@
SW_AUTO_CONT_NACK_DN_EN_M,
SW_AUTO_CONT_NACK_DN_EN);
cpr_irq_set(cpr, DOWN_INT, 0);
- pr_debug("%s: DOWN_INT disabled\n", __func__);
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "DOWN_INT disabled\n");
}
}
/* Acknowledge the Recommendation */
@@ -429,9 +452,18 @@
chip_data = &cpr->config->cpr_mode_data[cpr->cpr_mode];
error_step = cpr_read_reg(cpr, RBCPR_RESULT_0) >> 2;
- error_step &= 0xF;
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "RBCPR_RESULT_0 17:6=%d\n", (cpr_read_reg(cpr,
+ RBCPR_RESULT_0) >> 6) & 0xFFF);
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "RBCPR_RESULT_0 Busy_b19=%d\n", (cpr_read_reg(cpr,
+ RBCPR_RESULT_0) >> 19) & 0x1);
+
+ error_step &= 0xF;
curr_volt = regulator_get_voltage(cpr->vreg_cx);
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "Current voltage=%d\n", curr_volt);
if (action == UP) {
/* Clear IRQ, ACK and return if Vdd already at Vmax */
@@ -447,15 +479,29 @@
*/
if (error_step < (cpr->config->up_threshold +
cpr->config->up_margin)) {
- pr_debug("UP_INT error step too small to set\n");
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "UP_INT error step too small to set\n");
cpr_irq_clr_and_nack(cpr, BIT(4) | BIT(0));
return;
}
+ /**
+ * As per chip characterization recommendation, add a step
+ * to up error steps to increase system stability
+ */
+ error_step += 1;
+
/* Calculte new PMIC voltage */
new_volt = curr_volt + (error_step * cpr->vp->step_size);
- pr_debug("UP_INT: new_volt: %d\n", new_volt);
- pr_info("(UP Voltage recommended by CPR: %d uV)\n", new_volt);
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "UP_INT: new_volt: %d, error_step=%d\n",
+ new_volt, error_step);
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "Current RBCPR_GCNT_TARGET(%d): = 0x%x\n",
+ cpr->curr_osc, readl_relaxed(cpr->base +
+ RBCPR_GCNT_TARGET(cpr->curr_osc)) & TARGET_M);
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "(UP Voltage recommended by CPR: %d uV)\n", new_volt);
cpr_up_event_handler(cpr, new_volt);
} else if (action == DOWN) {
@@ -465,15 +511,35 @@
*/
if (error_step < (cpr->config->dn_threshold +
cpr->config->dn_margin)) {
- pr_debug("DOWN_INT error_step too small to set\n");
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "DOWN_INT error_step=%d is too small to set\n",
+ error_step);
cpr_irq_clr_and_nack(cpr, BIT(2) | BIT(0));
return;
}
+ /**
+ * As per chip characterization recommendation, deduct 2 steps
+ * from down error steps to decrease chances of getting closer
+ * to the system level Vmin, thereby improving stability
+ */
+ error_step -= 2;
+
+ /* Keep down step upto two per interrupt to avoid any spike */
+ if (error_step > 2)
+ error_step = 2;
+
/* Calculte new PMIC voltage */
new_volt = curr_volt - (error_step * cpr->vp->step_size);
- pr_debug("DOWN_INT: new_volt: %d\n", new_volt);
- pr_info("(DN Voltage recommended by CPR: %d uV)\n", new_volt);
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "DOWN_INT: new_volt: %d, error_step=%d\n",
+ new_volt, error_step);
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "Current RBCPR_GCNT_TARGET(%d): = 0x%x\n",
+ cpr->curr_osc, readl_relaxed(cpr->base +
+ RBCPR_GCNT_TARGET(cpr->curr_osc)) & TARGET_M);
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "(DN Voltage recommended by CPR: %d uV)\n", new_volt);
cpr_dn_event_handler(cpr, new_volt);
}
}
@@ -488,31 +554,36 @@
/* Following sequence of handling is as per each IRQ's priority */
if (reg_val & BIT(4)) {
- pr_debug(" CPR:IRQ %d occured for UP Flag\n", irq);
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "CPR:IRQ %d occured for UP Flag\n", irq);
cpr_set_vdd(cpr, UP);
} else if ((reg_val & BIT(2)) && !(ctl_reg & SW_AUTO_CONT_NACK_DN_EN)) {
- pr_debug(" CPR:IRQ %d occured for Down Flag\n", irq);
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "CPR:IRQ %d occured for Down Flag\n", irq);
cpr_set_vdd(cpr, DOWN);
} else if (reg_val & BIT(1)) {
- pr_debug(" CPR:IRQ %d occured for Min Flag\n", irq);
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "CPR:IRQ %d occured for Min Flag\n", irq);
cpr_irq_clr_and_nack(cpr, BIT(1) | BIT(0));
} else if (reg_val & BIT(5)) {
- pr_debug(" CPR:IRQ %d occured for MAX Flag\n", irq);
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "CPR:IRQ %d occured for MAX Flag\n", irq);
cpr_irq_clr_and_nack(cpr, BIT(5) | BIT(0));
} else if (reg_val & BIT(3)) {
/* SW_AUTO_CONT_ACK_EN is enabled */
- pr_debug(" CPR:IRQ %d occured for Mid Flag\n", irq);
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "CPR:IRQ %d occured for Mid Flag\n", irq);
}
return IRQ_HANDLED;
}
static void cpr_config(struct msm_cpr *cpr)
{
- uint32_t delay_count, cnt = 0, rc, tmp_uV;
+ uint32_t delay_count, cnt = 0, rc;
struct msm_cpr_mode *chip_data;
chip_data = &cpr->config->cpr_mode_data[cpr->cpr_mode];
@@ -543,11 +614,16 @@
* for all the ring oscilators
*/
while (cnt < NUM_OSC) {
+ msm_cpr_debug(MSM_CPR_DEBUG_CONFIG,
+ "Prog:cnt(%d) gcnt=0x%x quot=0x%x\n", cnt,
+ chip_data->ring_osc_data[cnt].gcnt,
+ chip_data->ring_osc_data[cnt].quot);
cpr_modify_reg(cpr, RBCPR_GCNT_TARGET(cnt),
(GCNT_M | TARGET_M),
(chip_data->ring_osc_data[cnt].gcnt << 12 |
chip_data->ring_osc_data[cnt].quot));
- pr_debug("RBCPR_GCNT_TARGET(%d): = 0x%x\n", cnt,
+ msm_cpr_debug(MSM_CPR_DEBUG_CONFIG,
+ "RBCPR_GCNT_TARGET(%d): = 0x%x\n", cnt,
readl_relaxed(cpr->base + RBCPR_GCNT_TARGET(cnt)));
cnt++;
}
@@ -555,16 +631,11 @@
/* Configure the step quot */
cpr_2pt_kv_analysis(cpr, chip_data);
- /**
- * Call the PMIC specific routine to set the voltage
- * Set with an extra step since it helps as per
- * characterization data.
- */
- chip_data->calibrated_uV += cpr->vp->step_size;
- tmp_uV = chip_data->calibrated_uV;
- rc = regulator_set_voltage(cpr->vreg_cx, tmp_uV, tmp_uV);
+ /* Call the PMIC specific routine to set the voltage */
+ rc = regulator_set_voltage(cpr->vreg_cx, chip_data->calibrated_uV,
+ chip_data->calibrated_uV);
if (rc)
- pr_err("%s: Voltage set failed %d\n", __func__, rc);
+ pr_err("Voltage set failed %d\n", rc);
/*
* Program the Timer Register for delay between CPR measurements
@@ -575,6 +646,11 @@
cpr->config->delay_us);
cpr_write_reg(cpr, RBCPR_TIMER_INTERVAL, delay_count);
+ /* Use Consecutive Down to avoid any interrupt due to spike */
+ cpr_write_reg(cpr, RBIF_TIMER_ADJUST, (0x2 << RBIF_CONS_DN_SHIFT));
+ msm_cpr_debug(MSM_CPR_DEBUG_CONFIG, "RBIF_TIMER_ADJUST: 0x%x\n",
+ readl_relaxed(cpr->base + RBIF_TIMER_ADJUST));
+
/* Enable the Timer */
cpr_modify_reg(cpr, RBCPR_CTL, TIMER_M, ENABLE_TIMER);
@@ -593,19 +669,23 @@
switch (val) {
case CPUFREQ_PRECHANGE:
- pr_debug("pre freq change notification to cpr\n");
-
+ msm_cpr_debug(MSM_CPR_DEBUG_FREQ_TRANS,
+ "pre freq change notification to cpr\n");
/* Disable Measurement to stop generation of CPR IRQs */
cpr_disable(cpr);
/* Disable routing of IRQ to App */
cpr_irq_set(cpr, INT_MASK & ~MID_INT, 0);
disable_irq(cpr->irq);
cpr_write_reg(cpr, RBIF_IRQ_CLEAR, ALL_CPR_IRQ);
- pr_debug("RBCPR_CTL: 0x%x\n",
+
+ msm_cpr_debug(MSM_CPR_DEBUG_FREQ_TRANS,
+ "RBCPR_CTL: 0x%x\n",
readl_relaxed(cpr->base + RBCPR_CTL));
- pr_debug("RBIF_IRQ_STATUS: 0x%x\n",
+ msm_cpr_debug(MSM_CPR_DEBUG_FREQ_TRANS,
+ "RBIF_IRQ_STATUS: 0x%x\n",
cpr_read_reg(cpr, RBIF_IRQ_STATUS));
- pr_debug("RBIF_IRQ_EN(0): 0x%x\n",
+ msm_cpr_debug(MSM_CPR_DEBUG_FREQ_TRANS,
+ "RBIF_IRQ_EN(0): 0x%x\n",
cpr_read_reg(cpr, RBIF_IRQ_EN(cpr->config->irq_line)));
cpr->prev_mode = cpr->cpr_mode;
@@ -634,12 +714,15 @@
new_freq / 1000);
cpr_modify_reg(cpr, RBCPR_GCNT_TARGET(cpr->curr_osc), TARGET_M,
quot);
- pr_debug("RBCPR_GCNT_TARGET(%d): = 0x%x\n", cpr->curr_osc,
+ msm_cpr_debug(MSM_CPR_DEBUG_FREQ_TRANS,
+ "RBCPR_GCNT_TARGET(%d): = 0x%x\n", cpr->curr_osc,
readl_relaxed(cpr->base +
RBCPR_GCNT_TARGET(cpr->curr_osc)));
- pr_debug("%s: new_freq: %d, set_freq: %d, quot: %d\n", __func__,
+ msm_cpr_debug(MSM_CPR_DEBUG_FREQ_TRANS,
+ "new_freq: %d, quot_freq: %d, quot: %d\n",
freqs->new, new_freq, quot);
- pr_info("%s: PVS Voltage setting is: %d\n", __func__,
+ msm_cpr_debug(MSM_CPR_DEBUG_FREQ_TRANS,
+ "PVS Voltage setting is: %d\n",
regulator_get_voltage(cpr->vreg_cx));
enable_irq(cpr->irq);
@@ -656,18 +739,28 @@
if (ctl_reg & SW_AUTO_CONT_NACK_DN_EN)
cpr_modify_reg(cpr, RBCPR_CTL,
SW_AUTO_CONT_NACK_DN_EN_M, 0);
- pr_debug("RBIF_IRQ_EN(0): 0x%x\n",
+ if (cpr->max_volt_set)
+ cpr->max_volt_set = 0;
+
+ msm_cpr_debug(MSM_CPR_DEBUG_FREQ_TRANS,
+ "RBIF_IRQ_EN(0): 0x%x\n",
cpr_read_reg(cpr, RBIF_IRQ_EN(cpr->config->irq_line)));
- pr_debug("RBCPR_CTL: 0x%x\n",
+ msm_cpr_debug(MSM_CPR_DEBUG_FREQ_TRANS,
+ "RBCPR_CTL: 0x%x\n",
readl_relaxed(cpr->base + RBCPR_CTL));
- pr_debug("RBIF_IRQ_STATUS: 0x%x\n",
+ msm_cpr_debug(MSM_CPR_DEBUG_FREQ_TRANS,
+ "RBIF_IRQ_STATUS: 0x%x\n",
cpr_read_reg(cpr, RBIF_IRQ_STATUS));
+
+ /* Clear all the interrupts */
+ cpr_write_reg(cpr, RBIF_IRQ_CLEAR, ALL_CPR_IRQ);
+
cpr_enable(cpr);
break;
default:
break;
}
- return 0;
+ return NOTIFY_OK;
}
#ifdef CONFIG_PM
@@ -695,6 +788,9 @@
cpr_write_reg(cpr, RBCPR_CTL,
cpr_save_state.rbcpr_ctl);
+ /* Clear all the interrupts */
+ cpr_write_reg(cpr, RBIF_IRQ_CLEAR, ALL_CPR_IRQ);
+
enable_irq(cpr->irq);
cpr_enable(cpr);
@@ -711,6 +807,9 @@
cpr_disable(cpr);
disable_irq(cpr->irq);
+ /* Clear all the interrupts */
+ cpr_write_reg(cpr, RBIF_IRQ_CLEAR, ALL_CPR_IRQ);
+
cpr_save_state.rbif_timer_interval =
cpr_read_reg(cpr, RBCPR_TIMER_INTERVAL);
cpr_save_state.rbif_int_en =
@@ -733,12 +832,18 @@
void msm_cpr_pm_resume(void)
{
+ if (!enable)
+ return;
+
msm_cpr_resume(&cpr_pdev->dev);
}
EXPORT_SYMBOL(msm_cpr_pm_resume);
void msm_cpr_pm_suspend(void)
{
+ if (!enable)
+ return;
+
msm_cpr_suspend(&cpr_pdev->dev);
}
EXPORT_SYMBOL(msm_cpr_pm_suspend);
@@ -746,14 +851,26 @@
void msm_cpr_disable(void)
{
- struct msm_cpr *cpr = platform_get_drvdata(cpr_pdev);
+ struct msm_cpr *cpr;
+
+ if (!enable)
+ return;
+
+ cpr = platform_get_drvdata(cpr_pdev);
+
cpr_disable(cpr);
}
EXPORT_SYMBOL(msm_cpr_disable);
void msm_cpr_enable(void)
{
- struct msm_cpr *cpr = platform_get_drvdata(cpr_pdev);
+ struct msm_cpr *cpr;
+
+ if (!enable)
+ return;
+
+ cpr = platform_get_drvdata(cpr_pdev);
+
cpr_enable(cpr);
}
EXPORT_SYMBOL(msm_cpr_enable);
@@ -772,12 +889,15 @@
if (!pdata) {
pr_err("CPR: Platform data is not available\n");
+ enable = false;
return -EIO;
}
cpr = devm_kzalloc(&pdev->dev, sizeof(struct msm_cpr), GFP_KERNEL);
- if (!cpr)
+ if (!cpr) {
+ enable = false;
return -ENOMEM;
+ }
/* Initialize platform_data */
cpr->config = pdata;
@@ -820,7 +940,7 @@
cpr->vp = pdata->vp_data;
- mutex_init(&cpr->cpr_mutex);
+ spin_lock_init(&cpr->cpr_lock);
/* Initialize the Voltage domain for CPR */
cpr->vreg_cx = regulator_get(&pdev->dev, "vddx_cx");
@@ -840,12 +960,15 @@
platform_set_drvdata(pdev, cpr);
chip_data = &cpr->config->cpr_mode_data[cpr->cpr_mode];
- pr_info("CPR Platform Data (upside_steps: %d) (downside_steps: %d) ",
+ msm_cpr_debug(MSM_CPR_DEBUG_CONFIG,
+ "CPR Platform Data (upside_steps: %d) (downside_steps: %d))",
cpr->config->up_threshold, cpr->config->dn_threshold);
- pr_info("(nominal_voltage: %duV) (turbo_voltage: %duV)\n",
+ msm_cpr_debug(MSM_CPR_DEBUG_CONFIG,
+ "(nominal_voltage: %duV) (turbo_voltage: %duV)\n",
cpr->config->cpr_mode_data[NORMAL_MODE].calibrated_uV,
cpr->config->cpr_mode_data[TURBO_MODE].calibrated_uV);
- pr_info("(Current corner: TURBO) (gcnt_target: %d) (quot: %d)\n",
+ msm_cpr_debug(MSM_CPR_DEBUG_CONFIG,
+ "(Current corner: TURBO) (gcnt_target: %d) (quot: %d)\n",
chip_data->ring_osc_data[chip_data->ring_osc].gcnt,
chip_data->ring_osc_data[chip_data->ring_osc].quot);
@@ -880,6 +1003,8 @@
cpufreq_register_notifier(&cpr->freq_transition,
CPUFREQ_TRANSITION_NOTIFIER);
+ pr_info("MSM CPR driver successfully registered!\n");
+
return res;
err_reg_get:
@@ -887,6 +1012,7 @@
err_ioremap:
iounmap(base);
out:
+ enable = false;
return res;
}
@@ -901,7 +1027,6 @@
regulator_put(cpr->vreg_cx);
free_irq(cpr->irq, cpr);
iounmap(cpr->base);
- mutex_destroy(&cpr->cpr_mutex);
platform_set_drvdata(pdev, NULL);
return 0;
diff --git a/arch/arm/mach-msm/msm_cpr.h b/arch/arm/mach-msm/msm_cpr.h
index e690c63..005d9b1 100644
--- a/arch/arm/mach-msm/msm_cpr.h
+++ b/arch/arm/mach-msm/msm_cpr.h
@@ -72,6 +72,9 @@
#define SW_AUTO_CONT_ACK_EN BIT(5)
#define SW_AUTO_CONT_NACK_DN_EN BIT(6)
+/* Shift Values */
+#define RBIF_CONS_DN_SHIFT (0x4)
+
/* Test values for RBCPR RUMI Testing */
#define GNT_CNT 0xC0
#define TARGET 0xEFF
diff --git a/arch/arm/mach-msm/msm_xo.c b/arch/arm/mach-msm/msm_xo.c
index 2d61504..404b350 100644
--- a/arch/arm/mach-msm/msm_xo.c
+++ b/arch/arm/mach-msm/msm_xo.c
@@ -236,7 +236,7 @@
int needs_workaround = cpu_is_msm8960() || cpu_is_apq8064() ||
cpu_is_msm8930() || cpu_is_msm8930aa() ||
cpu_is_msm9615() || cpu_is_msm8627() ||
- cpu_is_msm8960ab();
+ cpu_is_msm8960ab() || cpu_is_apq8064ab();
if (xo_voter->mode == mode)
return 0;
diff --git a/arch/arm/mach-msm/pil-modem.c b/arch/arm/mach-msm/pil-modem.c
index 8344496..ecb3800 100644
--- a/arch/arm/mach-msm/pil-modem.c
+++ b/arch/arm/mach-msm/pil-modem.c
@@ -19,11 +19,19 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
#include <mach/msm_iomap.h>
+#include <mach/subsystem_restart.h>
+#include <mach/msm_smsm.h>
+#include <mach/peripheral-loader.h>
+#include "modem_notifier.h"
#include "peripheral-loader.h"
#include "scm-pas.h"
+#include "ramdump.h"
#define MARM_BOOT_CONTROL 0x0010
#define MARM_RESET (MSM_CLK_CTL_BASE + 0x2BD4)
@@ -46,12 +54,22 @@
#define PLL_ENA_MARM (MSM_CLK_CTL_BASE + 0x3500)
#define PLL8_STATUS (MSM_CLK_CTL_BASE + 0x3158)
#define CLK_HALT_MSS_SMPSS_MISC_STATE (MSM_CLK_CTL_BASE + 0x2FDC)
+#define MSS_MODEM_RESET (MSM_CLK_CTL_BASE + 0x2C48)
struct modem_data {
void __iomem *base;
+ void __iomem *wdog;
unsigned long start_addr;
struct pil_device *pil;
struct clk *xo;
+ struct notifier_block notifier;
+ int ignore_smsm_ack;
+ int irq;
+ struct subsys_device *subsys;
+ struct subsys_desc subsys_desc;
+ struct delayed_work unlock_work;
+ struct work_struct fatal_work;
+ struct ramdump_device *ramdump_dev;
};
static int make_modem_proxy_votes(struct pil_desc *pil)
@@ -161,7 +179,7 @@
return 0;
}
-static int modem_shutdown(struct pil_desc *pil)
+static int modem_pil_shutdown(struct pil_desc *pil)
{
u32 reg;
@@ -203,7 +221,7 @@
static struct pil_reset_ops pil_modem_ops = {
.init_image = modem_init_image,
.auth_and_reset = modem_reset,
- .shutdown = modem_shutdown,
+ .shutdown = modem_pil_shutdown,
.proxy_vote = make_modem_proxy_votes,
.proxy_unvote = remove_modem_proxy_votes,
};
@@ -232,11 +250,166 @@
.proxy_unvote = remove_modem_proxy_votes,
};
+static void modem_crash_shutdown(const struct subsys_desc *subsys)
+{
+ struct modem_data *drv;
+
+ /* If modem hasn't already crashed, send SMSM_RESET. */
+ drv = container_of(subsys, struct modem_data, subsys_desc);
+ if (!(smsm_get_state(SMSM_MODEM_STATE) & SMSM_RESET)) {
+ modem_unregister_notifier(&drv->notifier);
+ smsm_reset_modem(SMSM_RESET);
+ }
+
+ /* Wait to allow the modem to clean up caches etc. */
+ mdelay(5);
+}
+
+static irqreturn_t modem_wdog_bite_irq(int irq, void *dev_id)
+{
+ struct modem_data *drv = dev_id;
+
+ schedule_work(&drv->fatal_work);
+ disable_irq_nosync(drv->irq);
+
+ return IRQ_HANDLED;
+}
+
+static void modem_unlock_timeout(struct work_struct *work)
+{
+ struct modem_data *drv;
+ struct delayed_work *dwork = to_delayed_work(work);
+
+ pr_crit("Timeout waiting for modem to unlock.\n");
+
+ drv = container_of(dwork, struct modem_data, unlock_work);
+ /* The unlock didn't work, clear the reset */
+ writel_relaxed(0x0, MSS_MODEM_RESET);
+ mb();
+
+ subsystem_restart_dev(drv->subsys);
+ enable_irq(drv->irq);
+}
+
+static void modem_fatal_fn(struct work_struct *work)
+{
+ u32 modem_state;
+ u32 panic_smsm_states = SMSM_RESET | SMSM_SYSTEM_DOWNLOAD;
+ u32 reset_smsm_states = SMSM_SYSTEM_REBOOT_USR | SMSM_SYSTEM_PWRDWN_USR;
+ struct modem_data *drv;
+
+ drv = container_of(work, struct modem_data, fatal_work);
+
+ pr_err("Watchdog bite received from modem!\n");
+
+ modem_state = smsm_get_state(SMSM_MODEM_STATE);
+ pr_err("Modem SMSM state = 0x%x!\n", modem_state);
+
+ if (modem_state == 0 || modem_state & panic_smsm_states) {
+ subsystem_restart_dev(drv->subsys);
+ enable_irq(drv->irq);
+ } else if (modem_state & reset_smsm_states) {
+ pr_err("User-invoked system reset/powerdown.");
+ kernel_restart(NULL);
+ } else {
+ unsigned long timeout = msecs_to_jiffies(6000);
+
+ pr_err("Modem AHB locked up. Trying to free up modem!\n");
+
+ writel_relaxed(0x3, MSS_MODEM_RESET);
+ /*
+ * If we are still alive (allowing for the 5 second
+ * delayed-panic-reboot), the modem is either still wedged or
+ * SMSM didn't come through. Force panic in that case.
+ */
+ schedule_delayed_work(&drv->unlock_work, timeout);
+ }
+}
+
+static int modem_notif_handler(struct notifier_block *nb, unsigned long code,
+ void *p)
+{
+ struct modem_data *drv = container_of(nb, struct modem_data, notifier);
+
+ if (code == MODEM_NOTIFIER_START_RESET) {
+ if (drv->ignore_smsm_ack) {
+ drv->ignore_smsm_ack = 0;
+ } else {
+ pr_err("Modem error fatal'ed.");
+ subsystem_restart_dev(drv->subsys);
+ }
+ }
+ return NOTIFY_DONE;
+}
+
+static int modem_shutdown(const struct subsys_desc *subsys)
+{
+ struct modem_data *drv;
+
+ drv = container_of(subsys, struct modem_data, subsys_desc);
+ /*
+ * If the modem didn't already crash, setting SMSM_RESET here will help
+ * flush caches etc. The ignore_smsm_ack flag is set to ignore the
+ * SMSM_RESET notification that is generated due to the modem settings
+ * its own SMSM_RESET bit in response to the apps setting the apps
+ * SMSM_RESET bit.
+ */
+ if (!(smsm_get_state(SMSM_MODEM_STATE) & SMSM_RESET)) {
+ drv->ignore_smsm_ack = 1;
+ smsm_reset_modem(SMSM_RESET);
+ }
+
+ /* Disable the modem watchdog to allow clean modem bootup */
+ writel_relaxed(0x0, drv->wdog + 0x8);
+ /*
+ * The write above needs to go through before the modem is powered up
+ * again.
+ */
+ mb();
+ /* Wait here to allow the modem to clean up caches, etc. */
+ msleep(20);
+
+ pil_force_shutdown("modem");
+ disable_irq_nosync(drv->irq);
+
+ return 0;
+}
+
+static int modem_powerup(const struct subsys_desc *subsys)
+{
+ struct modem_data *drv;
+ int ret;
+
+ drv = container_of(subsys, struct modem_data, subsys_desc);
+ ret = pil_force_boot("modem");
+ enable_irq(drv->irq);
+
+ return ret;
+}
+
+/* FIXME: Get address, size from PIL */
+static struct ramdump_segment modem_segments[] = {
+ { 0x42F00000, 0x46000000 - 0x42F00000 },
+};
+
+static int modem_ramdump(int enable, const struct subsys_desc *subsys)
+{
+ struct modem_data *drv;
+
+ drv = container_of(subsys, struct modem_data, subsys_desc);
+ if (enable)
+ return do_ramdump(drv->ramdump_dev, modem_segments,
+ ARRAY_SIZE(modem_segments));
+ else
+ return 0;
+}
+
static int __devinit pil_modem_driver_probe(struct platform_device *pdev)
{
struct modem_data *drv;
struct resource *res;
struct pil_desc *desc;
+ int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
@@ -247,6 +420,10 @@
return -ENOMEM;
platform_set_drvdata(pdev, drv);
+ drv->irq = platform_get_irq(pdev, 0);
+ if (drv->irq < 0)
+ return drv->irq;
+
drv->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
if (!drv->base)
return -ENOMEM;
@@ -259,6 +436,14 @@
if (!desc)
return -ENOMEM;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res)
+ return -EINVAL;
+
+ drv->wdog = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!drv->wdog)
+ return -ENOMEM;
+
desc->name = "modem";
desc->depends_on = "q6";
desc->dev = &pdev->dev;
@@ -273,16 +458,61 @@
dev_info(&pdev->dev, "using non-secure boot\n");
}
drv->pil = msm_pil_register(desc);
- if (IS_ERR(drv->pil)) {
+ if (IS_ERR(drv->pil))
return PTR_ERR(drv->pil);
+
+ drv->notifier.notifier_call = modem_notif_handler,
+ ret = modem_register_notifier(&drv->notifier);
+ if (ret)
+ goto err_notify;
+
+ drv->subsys_desc.name = "modem";
+ drv->subsys_desc.shutdown = modem_shutdown;
+ drv->subsys_desc.powerup = modem_powerup;
+ drv->subsys_desc.ramdump = modem_ramdump;
+ drv->subsys_desc.crash_shutdown = modem_crash_shutdown;
+
+ INIT_WORK(&drv->fatal_work, modem_fatal_fn);
+ INIT_DELAYED_WORK(&drv->unlock_work, modem_unlock_timeout);
+
+ drv->subsys = subsys_register(&drv->subsys_desc);
+ if (IS_ERR(drv->subsys)) {
+ ret = PTR_ERR(drv->subsys);
+ goto err_subsys;
}
+
+ drv->ramdump_dev = create_ramdump_device("modem");
+ if (!drv->ramdump_dev) {
+ ret = -ENOMEM;
+ goto err_ramdump;
+ }
+
+ ret = devm_request_irq(&pdev->dev, drv->irq, modem_wdog_bite_irq,
+ IRQF_TRIGGER_RISING, "modem_watchdog", drv);
+ if (ret)
+ goto err_irq;
return 0;
+
+err_irq:
+ destroy_ramdump_device(drv->ramdump_dev);
+err_ramdump:
+ subsys_unregister(drv->subsys);
+err_subsys:
+ modem_unregister_notifier(&drv->notifier);
+err_notify:
+ msm_pil_unregister(drv->pil);
+ return ret;
}
static int __devexit pil_modem_driver_exit(struct platform_device *pdev)
{
struct modem_data *drv = platform_get_drvdata(pdev);
+
+ destroy_ramdump_device(drv->ramdump_dev);
+ subsys_unregister(drv->subsys);
+ modem_unregister_notifier(&drv->notifier);
msm_pil_unregister(drv->pil);
+
return 0;
}
diff --git a/arch/arm/mach-msm/platsmp-8625.c b/arch/arm/mach-msm/platsmp-8625.c
index 700f966..e8f8c59 100644
--- a/arch/arm/mach-msm/platsmp-8625.c
+++ b/arch/arm/mach-msm/platsmp-8625.c
@@ -28,19 +28,28 @@
#include <mach/msm_iomap.h>
#include "pm.h"
-#define MSM_CORE1_RESET 0xA8600590
-#define MSM_CORE1_STATUS_MSK 0x02800000
+#define CORE_RESET_BASE 0xA8600590
+#define MSM_CORE_STATUS_MSK 0x02800000
/*
* control for which core is the next to come out of the secondary
* boot "holding pen"
*/
-int pen_release = -1;
+volatile int pen_release = -1;
-static bool cold_boot_done;
+static DEFINE_PER_CPU(bool, cold_boot_done);
+
+struct per_cpu_data {
+ unsigned int reset_off;
+ unsigned int offset;
+ unsigned int ipc_irq;
+ void __iomem *reset_core_base;
+};
static uint32_t *msm8625_boot_vector;
-static void __iomem *reset_core1_base;
+
+
+static struct per_cpu_data cpu_data[CONFIG_NR_CPUS];
/*
* Write pen_release in a way that is guaranteed to be visible to all
@@ -65,7 +74,8 @@
/*
* MP_CORE_IPC will be used to generate interrupt and can be used by either
* of core.
- * To bring core1 out of GDFS we need to raise the SPI using the MP_CORE_IPC.
+ * To bring secondary cores out of GDFS we need to raise the SPI using the
+ * MP_CORE_IPC.
*/
static void raise_clear_spi(unsigned int cpu, bool set)
{
@@ -112,8 +122,8 @@
/* clear the IPC1(SPI-8) pending SPI */
if (power_collapsed) {
- raise_clear_spi(1, false);
- clear_pending_spi(MSM8625_INT_ACSR_MP_CORE_IPC1);
+ raise_clear_spi(cpu, false);
+ clear_pending_spi(cpu_data[cpu].ipc_irq);
power_collapsed = 0;
}
@@ -124,7 +134,7 @@
spin_unlock(&boot_lock);
}
-static int __cpuinit msm8625_release_secondary(void)
+static int __cpuinit msm8625_release_secondary(unsigned int cpu)
{
void __iomem *base_ptr;
int value = 0;
@@ -137,33 +147,35 @@
*/
timeout = jiffies + usecs_to_jiffies(20);
while (time_before(jiffies, timeout)) {
- value = __raw_readl(MSM_CFG_CTL_BASE + 0x3c);
- if ((value & MSM_CORE1_STATUS_MSK) ==
- MSM_CORE1_STATUS_MSK)
+ value = __raw_readl(MSM_CFG_CTL_BASE + cpu_data[cpu].offset);
+ if ((value & MSM_CORE_STATUS_MSK) ==
+ MSM_CORE_STATUS_MSK)
break;
udelay(1);
}
if (!value) {
- pr_err("Core 1 cannot be brought out of Reset!!!\n");
+ pr_err("Core %u cannot be brought out of Reset!!!\n", cpu);
return -ENODEV;
}
- base_ptr = ioremap_nocache(MSM_CORE1_RESET, SZ_4);
+ base_ptr = ioremap_nocache(CORE_RESET_BASE +
+ cpu_data[cpu].reset_off, SZ_4);
if (!base_ptr)
return -ENODEV;
- /* Reset core 1 out of reset */
+
+ /* Reset core out of reset */
__raw_writel(0x0, base_ptr);
mb();
- reset_core1_base = base_ptr;
+ cpu_data[cpu].reset_core_base = base_ptr;
return 0;
}
void __iomem *core1_reset_base(void)
{
- return reset_core1_base;
+ return cpu_data[1].reset_core_base;
}
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
@@ -172,12 +184,12 @@
preset_lpj = loops_per_jiffy;
- if (cold_boot_done == false) {
- if (msm8625_release_secondary()) {
- pr_err("Failed to release secondary core\n");
+ if (per_cpu(cold_boot_done, cpu) == false) {
+ if (msm8625_release_secondary(cpu)) {
+ pr_err("Failed to release core %u\n", cpu);
return -ENODEV;
}
- cold_boot_done = true;
+ per_cpu(cold_boot_done, cpu) = true;
}
/*
@@ -200,13 +212,13 @@
* and branch to the address found there.
*
* power_collapsed is the flag which will be updated for Powercollapse.
- * Once we are out of PC, as Core1 will be in the state of GDFS which
- * needs to be brought out by raising an SPI.
+ * Once we are out of PC, as secondary cores will be in the state of
+ * GDFS which needs to be brought out by raising an SPI.
*/
if (power_collapsed) {
core1_gic_configure_and_raise();
- raise_clear_spi(1, true);
+ raise_clear_spi(cpu, true);
} else {
gic_raise_softirq(cpumask_of(cpu), 1);
}
@@ -247,6 +259,34 @@
set_smp_cross_call(gic_raise_softirq);
}
+static void per_cpu_data(unsigned int cpu, unsigned int off,
+ unsigned int off1, unsigned int irq)
+{
+ cpu_data[cpu].reset_off = off;
+ cpu_data[cpu].offset = off1;
+ cpu_data[cpu].ipc_irq = irq;
+}
+
+static void enable_boot_remapper(unsigned long bit, unsigned int off)
+{
+ int value;
+
+ /* Enable boot remapper address */
+ value = __raw_readl(MSM_CFG_CTL_BASE + off);
+ __raw_writel(value | bit, MSM_CFG_CTL_BASE + off) ;
+ mb();
+}
+
+static void remapper_address(unsigned long phys, unsigned int off)
+{
+ /*
+ * Write the address of secondary startup into the
+ * boot remapper register. The secondary CPU branches to this address.
+ */
+ __raw_writel(phys, (MSM_CFG_CTL_BASE + off));
+ mb();
+}
+
static void __init msm8625_boot_vector_init(uint32_t *boot_vector,
unsigned long entry)
{
@@ -260,8 +300,8 @@
void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
- int i, value;
- void __iomem *second_ptr;
+ int i, cpu, value;
+ void __iomem *cpu_ptr;
/*
* Initialise the present map, which describes the set of CPUs
@@ -272,25 +312,41 @@
scu_enable(scu_base_addr());
- /*
- * Write the address of secondary startup into the
- * boot remapper register. The secondary CPU branches to this address.
- */
- __raw_writel(MSM8625_SECONDARY_PHYS, (MSM_CFG_CTL_BASE + 0x34));
- mb();
-
- second_ptr = ioremap_nocache(MSM8625_SECONDARY_PHYS, SZ_8);
- if (!second_ptr) {
- pr_err("failed to ioremap for secondary core\n");
+ cpu_ptr = ioremap_nocache(MSM8625_CPU_PHYS, SZ_8);
+ if (!cpu_ptr) {
+ pr_err("failed to ioremap for secondary cores\n");
return;
}
- msm8625_boot_vector_init(second_ptr,
+ msm8625_boot_vector_init(cpu_ptr,
virt_to_phys(msm_secondary_startup));
- iounmap(second_ptr);
- /* Enable boot remapper address: bit 26 for core1 */
- value = __raw_readl(MSM_CFG_CTL_BASE + 0x30);
- __raw_writel(value | (0x4 << 24), MSM_CFG_CTL_BASE + 0x30) ;
- mb();
+ iounmap(cpu_ptr);
+
+ for_each_possible_cpu(cpu) {
+ switch (cpu) {
+ case 0:
+ break;
+ case 1:
+ remapper_address(MSM8625_CPU_PHYS, 0x34);
+ per_cpu_data(cpu, 0x0, 0x3c,
+ MSM8625_INT_ACSR_MP_CORE_IPC1);
+ enable_boot_remapper(BIT(26), 0x30);
+ break;
+ case 2:
+ remapper_address((MSM8625_CPU_PHYS >> 16), 0x4C);
+ per_cpu_data(cpu, 0x8, 0x50,
+ MSM8625_INT_ACSR_MP_CORE_IPC2);
+ enable_boot_remapper(BIT(25), 0x48);
+ break;
+ case 3:
+ value = __raw_readl(MSM_CFG_CTL_BASE + 0x4C);
+ remapper_address(value | MSM8625_CPU_PHYS, 0x4C);
+ per_cpu_data(cpu, 0xC, 0x50,
+ MSM8625_INT_ACSR_MP_CORE_IPC3);
+ enable_boot_remapper(BIT(26), 0x48);
+ break;
+ }
+
+ }
}
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index f6ed1ea..aa05559 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -165,7 +165,8 @@
return krait_release_secondary_sim(0xf9088000, cpu);
if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm8930aa() ||
- cpu_is_apq8064() || cpu_is_msm8627() || cpu_is_msm8960ab())
+ cpu_is_apq8064() || cpu_is_msm8627() || cpu_is_msm8960ab() ||
+ cpu_is_apq8064ab())
return krait_release_secondary(0x02088000, cpu);
if (cpu_is_msm8974())
@@ -176,17 +177,9 @@
}
DEFINE_PER_CPU(int, cold_boot_done);
-static int cold_boot_flags[] = {
- 0,
- SCM_FLAG_COLDBOOT_CPU1,
- SCM_FLAG_COLDBOOT_CPU2,
- SCM_FLAG_COLDBOOT_CPU3,
-};
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
- int ret;
- unsigned int flag = 0;
unsigned long timeout;
pr_debug("Starting secondary CPU %d\n", cpu);
@@ -194,19 +187,8 @@
/* Set preset_lpj to avoid subsequent lpj recalculations */
preset_lpj = loops_per_jiffy;
- if (cpu > 0 && cpu < ARRAY_SIZE(cold_boot_flags))
- flag = cold_boot_flags[cpu];
- else
- __WARN();
-
if (per_cpu(cold_boot_done, cpu) == false) {
- ret = scm_set_boot_addr(virt_to_phys(msm_secondary_startup),
- flag);
- if (ret == 0)
- release_secondary(cpu);
- else
- printk(KERN_DEBUG "Failed to set secondary core boot "
- "address\n");
+ release_secondary(cpu);
per_cpu(cold_boot_done, cpu) = true;
}
@@ -274,6 +256,28 @@
set_smp_cross_call(gic_raise_softirq);
}
+static int cold_boot_flags[] __initdata = {
+ 0,
+ SCM_FLAG_COLDBOOT_CPU1,
+ SCM_FLAG_COLDBOOT_CPU2,
+ SCM_FLAG_COLDBOOT_CPU3,
+};
+
void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
+ int cpu, map;
+ unsigned int flags = 0;
+
+ for_each_present_cpu(cpu) {
+ map = cpu_logical_map(cpu);
+ if (map > ARRAY_SIZE(cold_boot_flags)) {
+ set_cpu_present(cpu, false);
+ __WARN();
+ continue;
+ }
+ flags |= cold_boot_flags[map];
+ }
+
+ if (scm_set_boot_addr(virt_to_phys(msm_secondary_startup), flags))
+ pr_warn("Failed to set CPU boot address\n");
}
diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
index 5883b0c..2189747 100644
--- a/arch/arm/mach-msm/restart.c
+++ b/arch/arm/mach-msm/restart.c
@@ -36,6 +36,7 @@
#include <mach/scm.h>
#include "msm_watchdog.h"
#include "timer.h"
+#include "wdog_debug.h"
#define WDT0_RST 0x38
#define WDT0_EN 0x40
@@ -250,8 +251,11 @@
__raw_writel(5*0x31F3, msm_tmr0_base + WDT0_BARK_TIME);
__raw_writel(0x31F3, msm_tmr0_base + WDT0_BITE_TIME);
__raw_writel(1, msm_tmr0_base + WDT0_EN);
- } else
+ } else {
+ /* Needed for 8974: Reset GCC_WDOG_DEBUG register */
+ msm_disable_wdog_debug();
__raw_writel(0, MSM_MPM2_PSHOLD_BASE);
+ }
mdelay(10000);
printk(KERN_ERR "Restarting has failed\n");
diff --git a/arch/arm/mach-msm/rpm-smd.c b/arch/arm/mach-msm/rpm-smd.c
index a9d1ed8..7c31e76 100644
--- a/arch/arm/mach-msm/rpm-smd.c
+++ b/arch/arm/mach-msm/rpm-smd.c
@@ -149,8 +149,6 @@
uint32_t id_ack;
};
-static int irq_process;
-
LIST_HEAD(msm_rpm_ack_list);
static void msm_rpm_notify_sleep_chain(struct rpm_message_header *hdr,
@@ -518,20 +516,18 @@
uint32_t msg_id;
int errno;
char buf[MAX_ERR_BUFFER_SIZE] = {0};
- unsigned long flags;
- while (smd_is_pkt_avail(msm_rpm_data.ch_info) && !irq_process) {
- spin_lock_irqsave(&msm_rpm_data.smd_lock_read, flags);
+ if (!spin_trylock(&msm_rpm_data.smd_lock_read))
+ return;
+ while (smd_is_pkt_avail(msm_rpm_data.ch_info)) {
if (msm_rpm_read_smd_data(buf)) {
- spin_unlock_irqrestore(&msm_rpm_data.smd_lock_read,
- flags);
break;
}
msg_id = msm_rpm_get_msg_id_from_ack(buf);
errno = msm_rpm_get_error_from_ack(buf);
msm_rpm_process_ack(msg_id, errno);
- spin_unlock_irqrestore(&msm_rpm_data.smd_lock_read, flags);
}
+ spin_unlock(&msm_rpm_data.smd_lock_read);
}
#define DEBUG_PRINT_BUFFER_SIZE 512
@@ -783,7 +779,14 @@
int msm_rpm_send_request(struct msm_rpm_request *handle)
{
- return msm_rpm_send_data(handle, MSM_RPM_MSG_REQUEST_TYPE, false);
+ int ret;
+ static DEFINE_MUTEX(send_mtx);
+
+ mutex_lock(&send_mtx);
+ ret = msm_rpm_send_data(handle, MSM_RPM_MSG_REQUEST_TYPE, false);
+ mutex_unlock(&send_mtx);
+
+ return ret;
}
EXPORT_SYMBOL(msm_rpm_send_request);
@@ -837,7 +840,6 @@
return 0;
spin_lock_irqsave(&msm_rpm_data.smd_lock_read, flags);
- irq_process = true;
elem = msm_rpm_get_entry_from_msg_id(msg_id);
@@ -868,7 +870,6 @@
rc = elem->errno;
msm_rpm_free_list_entry(elem);
wait_ack_cleanup:
- irq_process = false;
spin_unlock_irqrestore(&msm_rpm_data.smd_lock_read, flags);
return rc;
}
diff --git a/arch/arm/mach-msm/rpm_resources.c b/arch/arm/mach-msm/rpm_resources.c
index 3ab5a98..dfed3aa 100644
--- a/arch/arm/mach-msm/rpm_resources.c
+++ b/arch/arm/mach-msm/rpm_resources.c
@@ -1132,7 +1132,8 @@
static int __init msm_rpmrs_l2_init(void)
{
if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm8930aa() ||
- cpu_is_apq8064() || cpu_is_msm8627() || cpu_is_msm8960ab()) {
+ cpu_is_apq8064() || cpu_is_msm8627() || cpu_is_msm8960ab() ||
+ cpu_is_apq8064ab()) {
msm_pm_set_l2_flush_flag(0);
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index b228147..20ad72f 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -3513,7 +3513,7 @@
static struct restart_notifier_block restart_notifiers[] = {
{SMD_MODEM, "modem", .nb.notifier_call = restart_notifier_cb},
{SMD_Q6, "lpass", .nb.notifier_call = restart_notifier_cb},
- {SMD_WCNSS, "riva", .nb.notifier_call = restart_notifier_cb},
+ {SMD_WCNSS, "wcnss", .nb.notifier_call = restart_notifier_cb},
{SMD_DSPS, "dsps", .nb.notifier_call = restart_notifier_cb},
{SMD_MODEM, "gss", .nb.notifier_call = restart_notifier_cb},
{SMD_Q6, "adsp", .nb.notifier_call = restart_notifier_cb},
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 86de130..ac077e9 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -286,6 +286,9 @@
/* 8092 IDs */
[146] = MSM_CPU_8092,
+ /* 8064AB IDs */
+ [153] = MSM_CPU_8064AB,
+
/* Uninitialized IDs are not known to run Linux.
MSM_CPU_UNKNOWN is set to 0 to ensure these IDs are
considered as unknown CPU. */
diff --git a/arch/arm/mach-msm/spm-v2.c b/arch/arm/mach-msm/spm-v2.c
index 1eab9bf..f0d3d06 100644
--- a/arch/arm/mach-msm/spm-v2.c
+++ b/arch/arm/mach-msm/spm-v2.c
@@ -179,7 +179,7 @@
}
}
-static inline uint32_t msm_spm_drv_get_sts_curr_pmic_data(
+uint32_t msm_spm_drv_get_sts_curr_pmic_data(
struct msm_spm_driver_data *dev)
{
if (dev->major == SAW2_MAJOR_2) {
diff --git a/arch/arm/mach-msm/spm.h b/arch/arm/mach-msm/spm.h
index e81e335..09ee26a 100644
--- a/arch/arm/mach-msm/spm.h
+++ b/arch/arm/mach-msm/spm.h
@@ -141,6 +141,13 @@
int msm_spm_set_vdd(unsigned int cpu, unsigned int vlevel);
/**
+ * msm_spm_get_vdd(): Get core voltage
+ * @cpu: core id
+ * @return: Returns encoded PMIC data.
+ */
+unsigned int msm_spm_get_vdd(unsigned int cpu);
+
+/**
* msm_spm_turn_on_cpu_rail(): Power on cpu rail before turning on core
* @cpu: core id
*/
@@ -239,6 +246,11 @@
return -ENOSYS;
}
+static inline unsigned int msm_spm_get_vdd(unsigned int cpu)
+{
+ return 0;
+}
+
static inline void msm_spm_reinit(void)
{
/* empty */
diff --git a/arch/arm/mach-msm/spm_devices.c b/arch/arm/mach-msm/spm_devices.c
index b87b0f1..2cbed94 100644
--- a/arch/arm/mach-msm/spm_devices.c
+++ b/arch/arm/mach-msm/spm_devices.c
@@ -75,6 +75,15 @@
}
EXPORT_SYMBOL(msm_spm_set_vdd);
+unsigned int msm_spm_get_vdd(unsigned int cpu)
+{
+ struct msm_spm_device *dev;
+
+ dev = &per_cpu(msm_cpu_spm_device, cpu);
+ return msm_spm_drv_get_sts_curr_pmic_data(&dev->reg_data);
+}
+EXPORT_SYMBOL(msm_spm_get_vdd);
+
static int msm_spm_dev_set_low_power_mode(struct msm_spm_device *dev,
unsigned int mode, bool notify_rpm)
{
@@ -159,7 +168,8 @@
reg = saw_bases[cpu];
if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm8930aa() ||
- cpu_is_apq8064() || cpu_is_msm8627() || cpu_is_msm8960ab()) {
+ cpu_is_apq8064() || cpu_is_msm8627() || cpu_is_msm8960ab() ||
+ cpu_is_apq8064ab()) {
val = 0xA4;
reg += 0x14;
timeout = 512;
diff --git a/arch/arm/mach-msm/spm_driver.h b/arch/arm/mach-msm/spm_driver.h
index f272adb0..4cdfd33 100644
--- a/arch/arm/mach-msm/spm_driver.h
+++ b/arch/arm/mach-msm/spm_driver.h
@@ -35,6 +35,8 @@
uint32_t addr);
int msm_spm_drv_set_vdd(struct msm_spm_driver_data *dev,
unsigned int vlevel);
+uint32_t msm_spm_drv_get_sts_curr_pmic_data(
+ struct msm_spm_driver_data *dev);
int msm_spm_drv_write_seq_data(struct msm_spm_driver_data *dev,
uint8_t *cmd, uint32_t *offset);
void msm_spm_drv_flush_seq_entry(struct msm_spm_driver_data *dev);
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 668f4cc..b361d9d 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -966,7 +966,7 @@
if (cpu_is_msm8x60() || cpu_is_msm8960() || cpu_is_apq8064() ||
cpu_is_msm8930() || cpu_is_msm8930aa() || cpu_is_msm8627() ||
- cpu_is_msm8960ab())
+ cpu_is_msm8960ab() || cpu_is_apq8064ab())
__raw_writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
if (__get_cpu_var(first_boot)) {
@@ -1064,7 +1064,7 @@
dgt->flags |= MSM_CLOCK_FLAGS_UNSTABLE_COUNT;
} else if (cpu_is_msm8960() || cpu_is_apq8064() || cpu_is_msm8930() ||
cpu_is_msm8930aa() || cpu_is_msm8627() ||
- cpu_is_msm8960ab()) {
+ cpu_is_msm8960ab() || cpu_is_apq8064ab()) {
global_timer_offset = MSM_TMR0_BASE - MSM_TMR_BASE;
dgt->freq = 6750000;
__raw_writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
@@ -1127,7 +1127,7 @@
if (cpu_is_msm8x60() || cpu_is_msm8960() || cpu_is_apq8064() ||
cpu_is_msm8930() || cpu_is_msm9615() || cpu_is_msm8625() ||
cpu_is_msm8627() || cpu_is_msm8930aa() ||
- cpu_is_msm8960ab()) {
+ cpu_is_msm8960ab() || cpu_is_apq8064ab()) {
clock->percpu_evt = alloc_percpu(struct clock_event_device *);
if (!clock->percpu_evt) {
pr_err("msm_timer_init: memory allocation "
diff --git a/arch/arm/mach-msm/wcnss-ssr-8960.c b/arch/arm/mach-msm/wcnss-ssr-8960.c
index f014df9..5516e30 100644
--- a/arch/arm/mach-msm/wcnss-ssr-8960.c
+++ b/arch/arm/mach-msm/wcnss-ssr-8960.c
@@ -186,7 +186,7 @@
}
static struct subsys_desc riva_8960 = {
- .name = "riva",
+ .name = "wcnss",
.shutdown = riva_shutdown,
.powerup = riva_powerup,
.ramdump = riva_ramdump,
diff --git a/arch/arm/mach-msm/wdog_debug.c b/arch/arm/mach-msm/wdog_debug.c
new file mode 100644
index 0000000..82800cf
--- /dev/null
+++ b/arch/arm/mach-msm/wdog_debug.c
@@ -0,0 +1,149 @@
+/* Copyright (c) 2012, 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/kernel.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <mach/scm.h>
+#include <linux/slab.h>
+
+#define MODULE_NAME "wdog_debug"
+#define WDOG_DEBUG_EN 17
+#define GCC_WDOG_DEBUG_OFFSET 0x780
+
+struct msm_wdog_debug_data {
+ unsigned int __iomem phys_base;
+ size_t size;
+ void __iomem *base;
+ struct device *dev;
+};
+
+static struct msm_wdog_debug_data *wdog_data;
+
+void msm_disable_wdog_debug(void)
+{
+ unsigned long int value;
+
+ if (wdog_data == NULL)
+ return;
+ value = readl_relaxed(wdog_data->base + GCC_WDOG_DEBUG_OFFSET);
+ value &= ~BIT(WDOG_DEBUG_EN);
+ writel_relaxed(value, wdog_data->base + GCC_WDOG_DEBUG_OFFSET);
+}
+EXPORT_SYMBOL(msm_disable_wdog_debug);
+
+void msm_enable_wdog_debug(void)
+{
+ unsigned long int value;
+
+ if (wdog_data == NULL)
+ return;
+ value = readl_relaxed(wdog_data->base + GCC_WDOG_DEBUG_OFFSET);
+ value |= BIT(WDOG_DEBUG_EN);
+ writel_relaxed(value, wdog_data->base + GCC_WDOG_DEBUG_OFFSET);
+}
+EXPORT_SYMBOL(msm_enable_wdog_debug);
+
+static int __devexit msm_wdog_debug_remove(struct platform_device *pdev)
+{
+ kfree(wdog_data);
+ wdog_data = NULL;
+ pr_info("MSM wdog_debug Exit - Deactivated\n");
+ return 0;
+}
+
+static int __devinit msm_wdog_debug_dt_to_pdata(struct platform_device *pdev,
+ struct msm_wdog_debug_data *pdata)
+{
+ struct resource *wdog_resource;
+
+ wdog_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!wdog_resource) {
+ dev_err(&pdev->dev, \
+ "%s cannot allocate resource for wdog_debug\n", \
+ __func__);
+ return -ENXIO;
+ }
+ pdata->size = resource_size(wdog_resource);
+ pdata->phys_base = wdog_resource->start;
+ if (unlikely(!(devm_request_region(&pdev->dev, pdata->phys_base,
+ pdata->size, "msm-wdog-debug")))) {
+ dev_err(&pdev->dev, "%s cannot reserve wdog_debug region\n",
+ __func__);
+ return -ENXIO;
+ }
+ pdata->base = devm_ioremap(&pdev->dev, pdata->phys_base,
+ pdata->size);
+ if (!pdata->base) {
+ dev_err(&pdev->dev, "%s cannot map wdog register space\n",
+ __func__);
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+static int __devinit msm_wdog_debug_probe(struct platform_device *pdev)
+{
+ int ret;
+ if (!pdev->dev.of_node)
+ return -ENODEV;
+ wdog_data = kzalloc(sizeof(struct msm_wdog_debug_data), GFP_KERNEL);
+ if (!wdog_data)
+ return -ENOMEM;
+ ret = msm_wdog_debug_dt_to_pdata(pdev, wdog_data);
+ if (ret)
+ goto err;
+ wdog_data->dev = &pdev->dev;
+ platform_set_drvdata(pdev, wdog_data);
+ msm_enable_wdog_debug();
+ return 0;
+err:
+ kzfree(wdog_data);
+ wdog_data = NULL;
+ return ret;
+}
+
+static struct of_device_id msm_wdog_debug_match_table[] = {
+ { .compatible = "qcom,msm-wdog-debug" },
+ {}
+};
+
+static struct platform_driver msm_wdog_debug_driver = {
+ .probe = msm_wdog_debug_probe,
+ .remove = msm_wdog_debug_remove,
+ .driver = {
+ .name = MODULE_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = msm_wdog_debug_match_table,
+ },
+};
+
+static int __devinit wdog_debug_init(void)
+{
+ return platform_driver_register(&msm_wdog_debug_driver);
+}
+module_init(wdog_debug_init);
+
+static void __exit wdog_debug_exit(void)
+{
+ platform_driver_unregister(&msm_wdog_debug_driver);
+}
+module_exit(wdog_debug_exit);
+
+MODULE_DESCRIPTION("MSM Driver to disable debug Image");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/wdog_debug.h b/arch/arm/mach-msm/wdog_debug.h
new file mode 100644
index 0000000..920aa89
--- /dev/null
+++ b/arch/arm/mach-msm/wdog_debug.h
@@ -0,0 +1,24 @@
+/* Copyright (c) 2012, 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.
+ */
+
+#ifndef __WDOG_DEBUG_H
+#define __WDOG_DEBUG_H
+
+#ifdef CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL
+void msm_enable_wdog_debug(void);
+void msm_disable_wdog_debug(void);
+#else
+void msm_enable_wdog_debug(void) { }
+void msm_disable_wdog_debug(void) { }
+#endif
+
+#endif
diff --git a/drivers/char/diag/Makefile b/drivers/char/diag/Makefile
index ea75ffd..6ecc970 100644
--- a/drivers/char/diag/Makefile
+++ b/drivers/char/diag/Makefile
@@ -2,4 +2,4 @@
obj-$(CONFIG_DIAG_SDIO_PIPE) += diagfwd_sdio.o
obj-$(CONFIG_DIAG_BRIDGE_CODE) += diagfwd_hsic.o
obj-$(CONFIG_DIAG_BRIDGE_CODE) += diagfwd_smux.o
-diagchar-objs := diagchar_core.o diagchar_hdlc.o diagfwd.o diagmem.o diagfwd_cntl.o diag_dci.o
+diagchar-objs := diagchar_core.o diagchar_hdlc.o diagfwd.o diagmem.o diagfwd_cntl.o diag_dci.o diag_masks.o diag_debugfs.o
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c
new file mode 100644
index 0000000..ed0f08e
--- /dev/null
+++ b/drivers/char/diag/diag_debugfs.c
@@ -0,0 +1,305 @@
+/* Copyright (c) 2011-2012, 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.
+ */
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include "diagchar.h"
+#include "diagfwd.h"
+
+#define DEBUG_BUF_SIZE 4096
+static struct dentry *diag_dbgfs_dent;
+static int diag_dbgfs_table_index;
+
+static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ char *buf;
+ int ret;
+
+ buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
+ if (!buf) {
+ pr_err("diag: %s, Error allocating memory\n", __func__);
+ return -ENOMEM;
+ }
+
+ ret = scnprintf(buf, DEBUG_BUF_SIZE,
+ "modem ch: 0x%x\n"
+ "lpass ch: 0x%x\n"
+ "riva ch: 0x%x\n"
+ "dci ch: 0x%x\n"
+ "modem cntl_ch: 0x%x\n"
+ "lpass cntl_ch: 0x%x\n"
+ "riva cntl_ch: 0x%x\n"
+ "CPU Tools id: %d\n"
+ "Apps only: %d\n"
+ "Apps master: %d\n"
+ "Check Polling Response: %d\n"
+ "polling_reg_flag: %d\n"
+ "uses device tree: %d\n"
+ "in_busy_1: %d\n"
+ "in_busy_2: %d\n"
+ "in_busy_lpass_1: %d\n"
+ "in_busy_lpass_2: %d\n"
+ "in_busy_wcnss_1: %d\n"
+ "in_busy_wcnss_2: %d\n"
+ "in_busy_dci: %d\n"
+ "logging_mode: %d\n",
+ (unsigned int)driver->ch,
+ (unsigned int)driver->chlpass,
+ (unsigned int)driver->ch_wcnss,
+ (unsigned int)driver->ch_dci,
+ (unsigned int)driver->ch_cntl,
+ (unsigned int)driver->chlpass_cntl,
+ (unsigned int)driver->ch_wcnss_cntl,
+ chk_config_get_id(),
+ chk_apps_only(),
+ chk_apps_master(),
+ chk_polling_response(),
+ driver->polling_reg_flag,
+ driver->use_device_tree,
+ driver->in_busy_1,
+ driver->in_busy_2,
+ driver->in_busy_lpass_1,
+ driver->in_busy_lpass_2,
+ driver->in_busy_wcnss_1,
+ driver->in_busy_wcnss_2,
+ driver->in_busy_dci,
+ driver->logging_mode);
+
+#ifdef CONFIG_DIAG_OVER_USB
+ ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
+ "usb_connected: %d\n",
+ driver->usb_connected);
+#endif
+ ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
+
+ kfree(buf);
+ return ret;
+}
+
+static ssize_t diag_dbgfs_read_workpending(struct file *file,
+ char __user *ubuf, size_t count, loff_t *ppos)
+{
+ char *buf;
+ int ret;
+
+ buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
+ if (!buf) {
+ pr_err("diag: %s, Error allocating memory\n", __func__);
+ return -ENOMEM;
+ }
+
+ ret = scnprintf(buf, DEBUG_BUF_SIZE,
+ "Pending status for work_stucts:\n"
+ "diag_drain_work: %d\n"
+ "diag_read_smd_work: %d\n"
+ "diag_read_smd_cntl_work: %d\n"
+ "diag_read_smd_lpass_work: %d\n"
+ "diag_read_smd_lpass_cntl_work: %d\n"
+ "diag_read_smd_wcnss_work: %d\n"
+ "diag_read_smd_wcnss_cntl_work: %d\n"
+ "diag_modem_mask_update_work: %d\n"
+ "diag_lpass_mask_update_work: %d\n"
+ "diag_wcnss_mask_update_work: %d\n"
+ "diag_read_smd_dci_work: %d\n",
+ work_pending(&(driver->diag_drain_work)),
+ work_pending(&(driver->diag_read_smd_work)),
+ work_pending(&(driver->diag_read_smd_cntl_work)),
+ work_pending(&(driver->diag_read_smd_lpass_work)),
+ work_pending(&(driver->diag_read_smd_lpass_cntl_work)),
+ work_pending(&(driver->diag_read_smd_wcnss_work)),
+ work_pending(&(driver->diag_read_smd_wcnss_cntl_work)),
+ work_pending(&(driver->diag_modem_mask_update_work)),
+ work_pending(&(driver->diag_lpass_mask_update_work)),
+ work_pending(&(driver->diag_wcnss_mask_update_work)),
+ work_pending(&(driver->diag_read_smd_dci_work)));
+
+#ifdef CONFIG_DIAG_OVER_USB
+ ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
+ "diag_proc_hdlc_work: %d\n"
+ "diag_read_work: %d\n",
+ work_pending(&(driver->diag_proc_hdlc_work)),
+ work_pending(&(driver->diag_read_work)));
+#endif
+ ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
+
+ kfree(buf);
+ return ret;
+}
+
+static ssize_t diag_dbgfs_read_table(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ char *buf;
+ int ret = 0;
+ int i;
+ int bytes_remaining;
+ int bytes_in_buffer = 0;
+ int bytes_written;
+ int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
+
+ if (diag_dbgfs_table_index >= diag_max_reg) {
+ /* Done. Reset to prepare for future requests */
+ diag_dbgfs_table_index = 0;
+ return 0;
+ }
+
+ buf = kzalloc(sizeof(char) * buf_size, GFP_KERNEL);
+ if (!buf) {
+ pr_err("diag: %s, Error allocating memory\n", __func__);
+ return -ENOMEM;
+ }
+
+ bytes_remaining = buf_size;
+ for (i = diag_dbgfs_table_index; i < diag_max_reg; i++) {
+ /* Do not process empty entries in the table */
+ if (driver->table[i].process_id == 0)
+ continue;
+
+ bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
+ "i: %3d, cmd_code: %4x, subsys_id: %4x, "
+ "client: %2d, cmd_code_lo: %4x, "
+ "cmd_code_hi: %4x, process_id: %5d\n",
+ i,
+ driver->table[i].cmd_code,
+ driver->table[i].subsys_id,
+ driver->table[i].client_id,
+ driver->table[i].cmd_code_lo,
+ driver->table[i].cmd_code_hi,
+ driver->table[i].process_id);
+
+ bytes_in_buffer += bytes_written;
+
+ /* Check if there is room to add another table entry */
+ bytes_remaining = buf_size - bytes_in_buffer;
+ if (bytes_remaining < bytes_written)
+ break;
+ }
+ diag_dbgfs_table_index = i;
+
+ *ppos = 0;
+ ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
+
+ kfree(buf);
+ return ret;
+}
+
+#ifdef CONFIG_DIAG_BRIDGE_CODE
+static ssize_t diag_dbgfs_read_hsic(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ char *buf;
+ int ret;
+
+ buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
+ if (!buf) {
+ pr_err("diag: %s, Error allocating memory\n", __func__);
+ return -ENOMEM;
+ }
+
+ ret = scnprintf(buf, DEBUG_BUF_SIZE,
+ "hsic ch: %d\n"
+ "hsic_inited: %d\n"
+ "hsic enabled: %d\n"
+ "hsic_opened: %d\n"
+ "hsic_suspend: %d\n"
+ "in_busy_hsic_read_on_device: %d\n"
+ "in_busy_hsic_write: %d\n"
+ "count_hsic_pool: %d\n"
+ "count_hsic_write_pool: %d\n"
+ "diag_hsic_pool: %x\n"
+ "diag_hsic_write_pool: %x\n"
+ "write_len_mdm: %d\n"
+ "num_hsic_buf_tbl_entries: %d\n"
+ "usb_mdm_connected: %d\n"
+ "diag_read_mdm_work: %d\n"
+ "diag_read_hsic_work: %d\n"
+ "diag_disconnect_work: %d\n"
+ "diag_usb_read_complete_work: %d\n",
+ driver->hsic_ch,
+ driver->hsic_inited,
+ driver->hsic_device_enabled,
+ driver->hsic_device_opened,
+ driver->hsic_suspend,
+ driver->in_busy_hsic_read_on_device,
+ driver->in_busy_hsic_write,
+ driver->count_hsic_pool,
+ driver->count_hsic_write_pool,
+ (unsigned int)driver->diag_hsic_pool,
+ (unsigned int)driver->diag_hsic_write_pool,
+ driver->write_len_mdm,
+ driver->num_hsic_buf_tbl_entries,
+ driver->usb_mdm_connected,
+ work_pending(&(driver->diag_read_mdm_work)),
+ work_pending(&(driver->diag_read_hsic_work)),
+ work_pending(&(driver->diag_disconnect_work)),
+ work_pending(&(driver->diag_usb_read_complete_work)));
+
+ ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
+
+ kfree(buf);
+ return ret;
+}
+
+const struct file_operations diag_dbgfs_hsic_ops = {
+ .read = diag_dbgfs_read_hsic,
+};
+#endif
+
+const struct file_operations diag_dbgfs_status_ops = {
+ .read = diag_dbgfs_read_status,
+};
+
+const struct file_operations diag_dbgfs_table_ops = {
+ .read = diag_dbgfs_read_table,
+};
+
+const struct file_operations diag_dbgfs_workpending_ops = {
+ .read = diag_dbgfs_read_workpending,
+};
+
+void diag_debugfs_init(void)
+{
+ diag_dbgfs_dent = debugfs_create_dir("diag", 0);
+ if (IS_ERR(diag_dbgfs_dent))
+ return;
+
+ debugfs_create_file("status", 0444, diag_dbgfs_dent, 0,
+ &diag_dbgfs_status_ops);
+
+ debugfs_create_file("table", 0444, diag_dbgfs_dent, 0,
+ &diag_dbgfs_table_ops);
+
+ debugfs_create_file("work_pending", 0444, diag_dbgfs_dent, 0,
+ &diag_dbgfs_workpending_ops);
+
+#ifdef CONFIG_DIAG_BRIDGE_CODE
+ debugfs_create_file("hsic", 0444, diag_dbgfs_dent, 0,
+ &diag_dbgfs_hsic_ops);
+#endif
+
+ diag_dbgfs_table_index = 0;
+}
+
+void diag_debugfs_cleanup(void)
+{
+ if (diag_dbgfs_dent) {
+ debugfs_remove_recursive(diag_dbgfs_dent);
+ diag_dbgfs_dent = NULL;
+ }
+}
+#else
+void diag_debugfs_init(void) { }
+void diag_debugfs_cleanup(void) { }
+#endif
diff --git a/drivers/char/diag/diag_debugfs.h b/drivers/char/diag/diag_debugfs.h
new file mode 100644
index 0000000..4bc8b0f
--- /dev/null
+++ b/drivers/char/diag/diag_debugfs.h
@@ -0,0 +1,19 @@
+/* Copyright (c)2012, 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.
+ */
+
+#ifndef DIAG_DEBUGFS_H
+#define DIAG_DEBUGFS_H
+
+void diag_debugfs_init(void);
+void diag_debugfs_cleanup(void);
+
+#endif
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
new file mode 100644
index 0000000..5316548
--- /dev/null
+++ b/drivers/char/diag/diag_masks.c
@@ -0,0 +1,790 @@
+/* Copyright (c) 2008-2012, 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/slab.h>
+#include <linux/delay.h>
+#include <linux/diagchar.h>
+#include <linux/kmemleak.h>
+#include <linux/workqueue.h>
+#include "diagchar.h"
+#include "diagfwd_cntl.h"
+#include "diag_masks.h"
+
+int diag_event_config;
+int diag_event_num_bytes;
+
+#define ALL_EQUIP_ID 100
+#define ALL_SSID -1
+#define MAX_SSID_PER_RANGE 100
+
+struct mask_info {
+ int equip_id;
+ int num_items;
+ int index;
+};
+
+#define CREATE_MSG_MASK_TBL_ROW(XX) \
+do { \
+ *(int *)(msg_mask_tbl_ptr) = MSG_SSID_ ## XX; \
+ msg_mask_tbl_ptr += 4; \
+ *(int *)(msg_mask_tbl_ptr) = MSG_SSID_ ## XX ## _LAST; \
+ msg_mask_tbl_ptr += 4; \
+ /* mimic the last entry as actual_last while creation */ \
+ *(int *)(msg_mask_tbl_ptr) = MSG_SSID_ ## XX ## _LAST; \
+ msg_mask_tbl_ptr += 4; \
+ /* increment by MAX_SSID_PER_RANGE cells */ \
+ msg_mask_tbl_ptr += MAX_SSID_PER_RANGE * sizeof(int); \
+} while (0)
+
+#define WAIT_FOR_SMD(num_delays, delay_time) \
+do { \
+ int count; \
+ for (count = 0; count < (num_delays); count++) \
+ udelay((delay_time)); \
+} while (0)
+
+static void diag_print_mask_table(void)
+{
+/* Enable this to print mask table when updated */
+#ifdef MASK_DEBUG
+ int first, last, actual_last;
+ uint8_t *ptr = driver->msg_masks;
+ int i = 0;
+ pr_info("diag: F3 message mask table\n");
+ while (*(uint32_t *)(ptr + 4)) {
+ first = *(uint32_t *)ptr;
+ ptr += 4;
+ last = *(uint32_t *)ptr;
+ ptr += 4;
+ actual_last = *(uint32_t *)ptr;
+ ptr += 4;
+ pr_info("diag: SSID %d, %d - %d\n", first, last, actual_last);
+ for (i = 0 ; i <= actual_last - first ; i++)
+ pr_info("diag: MASK:%x\n", *((uint32_t *)ptr + i));
+ ptr += MAX_SSID_PER_RANGE*4;
+ }
+#endif
+}
+
+void diag_create_msg_mask_table(void)
+{
+ uint8_t *msg_mask_tbl_ptr = driver->msg_masks;
+
+ CREATE_MSG_MASK_TBL_ROW(0);
+ CREATE_MSG_MASK_TBL_ROW(1);
+ CREATE_MSG_MASK_TBL_ROW(2);
+ CREATE_MSG_MASK_TBL_ROW(3);
+ CREATE_MSG_MASK_TBL_ROW(4);
+ CREATE_MSG_MASK_TBL_ROW(5);
+ CREATE_MSG_MASK_TBL_ROW(6);
+ CREATE_MSG_MASK_TBL_ROW(7);
+ CREATE_MSG_MASK_TBL_ROW(8);
+ CREATE_MSG_MASK_TBL_ROW(9);
+ CREATE_MSG_MASK_TBL_ROW(10);
+ CREATE_MSG_MASK_TBL_ROW(11);
+ CREATE_MSG_MASK_TBL_ROW(12);
+ CREATE_MSG_MASK_TBL_ROW(13);
+ CREATE_MSG_MASK_TBL_ROW(14);
+ CREATE_MSG_MASK_TBL_ROW(15);
+ CREATE_MSG_MASK_TBL_ROW(16);
+ CREATE_MSG_MASK_TBL_ROW(17);
+ CREATE_MSG_MASK_TBL_ROW(18);
+ CREATE_MSG_MASK_TBL_ROW(19);
+ CREATE_MSG_MASK_TBL_ROW(20);
+ CREATE_MSG_MASK_TBL_ROW(21);
+ CREATE_MSG_MASK_TBL_ROW(22);
+ CREATE_MSG_MASK_TBL_ROW(23);
+}
+
+static void diag_set_msg_mask(int rt_mask)
+{
+ int first_ssid, last_ssid, i;
+ uint8_t *parse_ptr, *ptr = driver->msg_masks;
+
+ mutex_lock(&driver->diagchar_mutex);
+ while (*(uint32_t *)(ptr + 4)) {
+ first_ssid = *(uint32_t *)ptr;
+ ptr += 8; /* increment by 8 to skip 'last' */
+ last_ssid = *(uint32_t *)ptr;
+ ptr += 4;
+ parse_ptr = ptr;
+ pr_debug("diag: updating range %d %d\n", first_ssid, last_ssid);
+ for (i = 0; i < last_ssid - first_ssid + 1; i++) {
+ *(int *)parse_ptr = rt_mask;
+ parse_ptr += 4;
+ }
+ ptr += MAX_SSID_PER_RANGE * 4;
+ }
+ mutex_unlock(&driver->diagchar_mutex);
+}
+
+static void diag_update_msg_mask(int start, int end , uint8_t *buf)
+{
+ int found = 0, first, last, actual_last;
+ uint8_t *actual_last_ptr;
+ uint8_t *ptr = driver->msg_masks;
+ uint8_t *ptr_buffer_start = &(*(driver->msg_masks));
+ uint8_t *ptr_buffer_end = &(*(driver->msg_masks)) + MSG_MASK_SIZE;
+
+ mutex_lock(&driver->diagchar_mutex);
+
+ /* First SSID can be zero : So check that last is non-zero */
+ while (*(uint32_t *)(ptr + 4)) {
+ first = *(uint32_t *)ptr;
+ ptr += 4;
+ last = *(uint32_t *)ptr;
+ ptr += 4;
+ actual_last = *(uint32_t *)ptr;
+ actual_last_ptr = ptr;
+ ptr += 4;
+ if (start >= first && start <= actual_last) {
+ ptr += (start - first)*4;
+ if (end > actual_last) {
+ pr_info("diag: ssid range mismatch\n");
+ actual_last = end;
+ *(uint32_t *)(actual_last_ptr) = end;
+ }
+ if (CHK_OVERFLOW(ptr_buffer_start, ptr, ptr_buffer_end,
+ (((end - start)+1)*4))) {
+ pr_debug("diag: update ssid start %d, end %d\n",
+ start, end);
+ memcpy(ptr, buf , ((end - start)+1)*4);
+ } else
+ pr_alert("diag: Not enough space MSG_MASK\n");
+ found = 1;
+ break;
+ } else {
+ ptr += MAX_SSID_PER_RANGE*4;
+ }
+ }
+ /* Entry was not found - add new table */
+ if (!found) {
+ if (CHK_OVERFLOW(ptr_buffer_start, ptr, ptr_buffer_end,
+ 8 + ((end - start) + 1)*4)) {
+ memcpy(ptr, &(start) , 4);
+ ptr += 4;
+ memcpy(ptr, &(end), 4);
+ ptr += 4;
+ memcpy(ptr, &(end), 4); /* create actual_last entry */
+ ptr += 4;
+ pr_debug("diag: adding NEW ssid start %d, end %d\n",
+ start, end);
+ memcpy(ptr, buf , ((end - start) + 1)*4);
+ } else
+ pr_alert("diag: Not enough buffer space for MSG_MASK\n");
+ }
+ mutex_unlock(&driver->diagchar_mutex);
+ diag_print_mask_table();
+}
+
+void diag_toggle_event_mask(int toggle)
+{
+ uint8_t *ptr = driver->event_masks;
+
+ mutex_lock(&driver->diagchar_mutex);
+ if (toggle)
+ memset(ptr, 0xFF, EVENT_MASK_SIZE);
+ else
+ memset(ptr, 0, EVENT_MASK_SIZE);
+ mutex_unlock(&driver->diagchar_mutex);
+}
+
+
+static void diag_update_event_mask(uint8_t *buf, int toggle, int num_bytes)
+{
+ uint8_t *ptr = driver->event_masks;
+ uint8_t *temp = buf + 2;
+
+ mutex_lock(&driver->diagchar_mutex);
+ if (!toggle)
+ memset(ptr, 0 , EVENT_MASK_SIZE);
+ else
+ if (CHK_OVERFLOW(ptr, ptr,
+ ptr+EVENT_MASK_SIZE, num_bytes))
+ memcpy(ptr, temp , num_bytes);
+ else
+ printk(KERN_CRIT "Not enough buffer space for EVENT_MASK\n");
+ mutex_unlock(&driver->diagchar_mutex);
+}
+
+static void diag_disable_log_mask(void)
+{
+ int i = 0;
+ struct mask_info *parse_ptr = (struct mask_info *)(driver->log_masks);
+
+ pr_debug("diag: disable log masks\n");
+ mutex_lock(&driver->diagchar_mutex);
+ for (i = 0; i < MAX_EQUIP_ID; i++) {
+ pr_debug("diag: equip id %d\n", parse_ptr->equip_id);
+ if (!(parse_ptr->equip_id)) /* Reached a null entry */
+ break;
+ memset(driver->log_masks + parse_ptr->index, 0,
+ (parse_ptr->num_items + 7)/8);
+ parse_ptr++;
+ }
+ mutex_unlock(&driver->diagchar_mutex);
+}
+
+int chk_equip_id_and_mask(int equip_id, uint8_t *buf)
+{
+ int i = 0, flag = 0, num_items, offset;
+ unsigned char *ptr_data;
+ struct mask_info *ptr = (struct mask_info *)(driver->log_masks);
+
+ pr_debug("diag: received equip id = %d\n", equip_id);
+ /* Check if this is valid equipment ID */
+ for (i = 0; i < MAX_EQUIP_ID; i++) {
+ if ((ptr->equip_id == equip_id) && (ptr->index != 0)) {
+ offset = ptr->index;
+ num_items = ptr->num_items;
+ flag = 1;
+ break;
+ }
+ ptr++;
+ }
+ if (!flag)
+ return -EPERM;
+ ptr_data = driver->log_masks + offset;
+ memcpy(buf, ptr_data, (num_items+7)/8);
+ return 0;
+}
+
+static void diag_update_log_mask(int equip_id, uint8_t *buf, int num_items)
+{
+ uint8_t *temp = buf;
+ int i = 0;
+ unsigned char *ptr_data;
+ int offset = (sizeof(struct mask_info))*MAX_EQUIP_ID;
+ struct mask_info *ptr = (struct mask_info *)(driver->log_masks);
+
+ pr_debug("diag: received equip id = %d\n", equip_id);
+ mutex_lock(&driver->diagchar_mutex);
+ /* Check if we already know index of this equipment ID */
+ for (i = 0; i < MAX_EQUIP_ID; i++) {
+ if ((ptr->equip_id == equip_id) && (ptr->index != 0)) {
+ offset = ptr->index;
+ break;
+ }
+ if ((ptr->equip_id == 0) && (ptr->index == 0)) {
+ /* Reached a null entry */
+ ptr->equip_id = equip_id;
+ ptr->num_items = num_items;
+ ptr->index = driver->log_masks_length;
+ offset = driver->log_masks_length;
+ driver->log_masks_length += ((num_items+7)/8);
+ break;
+ }
+ ptr++;
+ }
+ ptr_data = driver->log_masks + offset;
+ if (CHK_OVERFLOW(driver->log_masks, ptr_data, driver->log_masks
+ + LOG_MASK_SIZE, (num_items+7)/8))
+ memcpy(ptr_data, temp , (num_items+7)/8);
+ else
+ pr_err("diag: Not enough buffer space for LOG_MASK\n");
+ mutex_unlock(&driver->diagchar_mutex);
+}
+
+void diag_modem_mask_update_fn(struct work_struct *work)
+{
+ diag_send_msg_mask_update(driver->ch_cntl, ALL_SSID,
+ ALL_SSID, MODEM_PROC);
+ diag_send_log_mask_update(driver->ch_cntl, ALL_EQUIP_ID);
+ diag_send_event_mask_update(driver->ch_cntl, diag_event_num_bytes);
+}
+
+void diag_lpass_mask_update_fn(struct work_struct *work)
+{
+ diag_send_msg_mask_update(driver->chlpass_cntl, ALL_SSID,
+ ALL_SSID, LPASS_PROC);
+ diag_send_log_mask_update(driver->chlpass_cntl, ALL_EQUIP_ID);
+ diag_send_event_mask_update(driver->chlpass_cntl, diag_event_num_bytes);
+}
+
+void diag_wcnss_mask_update_fn(struct work_struct *work)
+{
+ diag_send_msg_mask_update(driver->ch_wcnss_cntl, ALL_SSID,
+ ALL_SSID, WCNSS_PROC);
+ diag_send_log_mask_update(driver->ch_wcnss_cntl, ALL_EQUIP_ID);
+ diag_send_event_mask_update(driver->ch_wcnss_cntl,
+ diag_event_num_bytes);
+}
+
+void diag_send_log_mask_update(smd_channel_t *ch, int equip_id)
+{
+ void *buf = driver->buf_log_mask_update;
+ int header_size = sizeof(struct diag_ctrl_log_mask);
+ struct mask_info *ptr = (struct mask_info *)driver->log_masks;
+ int i, size, wr_size = -ENOMEM, retry_count = 0;
+
+ mutex_lock(&driver->diag_cntl_mutex);
+ for (i = 0; i < MAX_EQUIP_ID; i++) {
+ size = (ptr->num_items+7)/8;
+ /* reached null entry */
+ if ((ptr->equip_id == 0) && (ptr->index == 0))
+ break;
+ driver->log_mask->cmd_type = DIAG_CTRL_MSG_LOG_MASK;
+ driver->log_mask->num_items = ptr->num_items;
+ driver->log_mask->data_len = 11 + size;
+ driver->log_mask->stream_id = 1; /* 2, if dual stream */
+ driver->log_mask->status = 3; /* status for valid mask */
+ driver->log_mask->equip_id = ptr->equip_id;
+ driver->log_mask->log_mask_size = size;
+ /* send only desired update, NOT ALL */
+ if (equip_id == ALL_EQUIP_ID || equip_id ==
+ driver->log_mask->equip_id) {
+ memcpy(buf, driver->log_mask, header_size);
+ memcpy(buf+header_size, driver->log_masks+ptr->index,
+ size);
+ if (ch) {
+ while (retry_count < 3) {
+ wr_size = smd_write(ch, buf,
+ header_size + size);
+ if (wr_size == -ENOMEM) {
+ retry_count++;
+ WAIT_FOR_SMD(5, 2000);
+ } else
+ break;
+ }
+ if (wr_size != header_size + size)
+ pr_err("diag: log mask update failed %d, tried %d",
+ wr_size, header_size + size);
+ else
+ pr_debug("diag: updated log equip ID %d,len %d\n",
+ driver->log_mask->equip_id,
+ driver->log_mask->log_mask_size);
+ } else
+ pr_err("diag: ch not valid for log update\n");
+ }
+ ptr++;
+ }
+ mutex_unlock(&driver->diag_cntl_mutex);
+}
+
+void diag_send_event_mask_update(smd_channel_t *ch, int num_bytes)
+{
+ void *buf = driver->buf_event_mask_update;
+ int header_size = sizeof(struct diag_ctrl_event_mask);
+ int wr_size = -ENOMEM, retry_count = 0;
+
+ mutex_lock(&driver->diag_cntl_mutex);
+ if (num_bytes == 0) {
+ pr_debug("diag: event mask not set yet, so no update\n");
+ mutex_unlock(&driver->diag_cntl_mutex);
+ return;
+ }
+ /* send event mask update */
+ driver->event_mask->cmd_type = DIAG_CTRL_MSG_EVENT_MASK;
+ driver->event_mask->data_len = 7 + num_bytes;
+ driver->event_mask->stream_id = 1; /* 2, if dual stream */
+ driver->event_mask->status = 3; /* status for valid mask */
+ driver->event_mask->event_config = diag_event_config; /* event config */
+ driver->event_mask->event_mask_size = num_bytes;
+ memcpy(buf, driver->event_mask, header_size);
+ memcpy(buf+header_size, driver->event_masks, num_bytes);
+ if (ch) {
+ while (retry_count < 3) {
+ wr_size = smd_write(ch, buf, header_size + num_bytes);
+ if (wr_size == -ENOMEM) {
+ retry_count++;
+ WAIT_FOR_SMD(5, 2000);
+ } else
+ break;
+ }
+ if (wr_size != header_size + num_bytes)
+ pr_err("diag: error writing event mask %d, tried %d\n",
+ wr_size, header_size + num_bytes);
+ } else
+ pr_err("diag: ch not valid for event update\n");
+ mutex_unlock(&driver->diag_cntl_mutex);
+}
+
+void diag_send_msg_mask_update(smd_channel_t *ch, int updated_ssid_first,
+ int updated_ssid_last, int proc)
+{
+ void *buf = driver->buf_msg_mask_update;
+ int first, last, actual_last, size = -ENOMEM, retry_count = 0;
+ int header_size = sizeof(struct diag_ctrl_msg_mask);
+ uint8_t *ptr = driver->msg_masks;
+
+ mutex_lock(&driver->diag_cntl_mutex);
+ while (*(uint32_t *)(ptr + 4)) {
+ first = *(uint32_t *)ptr;
+ ptr += 4;
+ last = *(uint32_t *)ptr;
+ ptr += 4;
+ actual_last = *(uint32_t *)ptr;
+ ptr += 4;
+ if ((updated_ssid_first >= first && updated_ssid_last <=
+ actual_last) || (updated_ssid_first == ALL_SSID)) {
+ /* send f3 mask update */
+ driver->msg_mask->cmd_type = DIAG_CTRL_MSG_F3_MASK;
+ driver->msg_mask->msg_mask_size = actual_last -
+ first + 1;
+ driver->msg_mask->data_len = 11 +
+ 4 * (driver->msg_mask->msg_mask_size);
+ driver->msg_mask->stream_id = 1; /* 2, if dual stream */
+ driver->msg_mask->status = 3; /* status valid mask */
+ driver->msg_mask->msg_mode = 0; /* Legcay mode */
+ driver->msg_mask->ssid_first = first;
+ driver->msg_mask->ssid_last = actual_last;
+ memcpy(buf, driver->msg_mask, header_size);
+ memcpy(buf+header_size, ptr,
+ 4 * (driver->msg_mask->msg_mask_size));
+ if (ch) {
+ while (retry_count < 3) {
+ size = smd_write(ch, buf, header_size +
+ 4*(driver->msg_mask->msg_mask_size));
+ if (size == -ENOMEM) {
+ retry_count++;
+ WAIT_FOR_SMD(5, 2000);
+ } else
+ break;
+ }
+ if (size != header_size +
+ 4*(driver->msg_mask->msg_mask_size))
+ pr_err("diag: proc %d, msg mask update fail %d, tried %d\n",
+ proc, size, (header_size +
+ 4*(driver->msg_mask->msg_mask_size)));
+ else
+ pr_debug("diag: sending mask update for ssid first %d, last %d on PROC %d\n",
+ first, actual_last, proc);
+ } else
+ pr_err("diag: proc %d, ch invalid msg mask update\n",
+ proc);
+ }
+ ptr += MAX_SSID_PER_RANGE*4;
+ }
+ mutex_unlock(&driver->diag_cntl_mutex);
+}
+
+int diag_process_apps_masks(unsigned char *buf, int len)
+{
+ int packet_type = 1;
+ int i;
+ int ssid_first, ssid_last, ssid_range;
+ int rt_mask, rt_first_ssid, rt_last_ssid, rt_mask_size;
+ uint8_t *rt_mask_ptr;
+ int equip_id, num_items;
+#if defined(CONFIG_DIAG_OVER_USB)
+ int payload_length;
+#endif
+
+ /* Set log masks */
+ if (*buf == 0x73 && *(int *)(buf+4) == 3) {
+ buf += 8;
+ /* Read Equip ID and pass as first param below*/
+ diag_update_log_mask(*(int *)buf, buf+8, *(int *)(buf+4));
+ diag_update_userspace_clients(LOG_MASKS_TYPE);
+#if defined(CONFIG_DIAG_OVER_USB)
+ if (chk_apps_only()) {
+ driver->apps_rsp_buf[0] = 0x73;
+ *(int *)(driver->apps_rsp_buf + 4) = 0x3; /* op. ID */
+ *(int *)(driver->apps_rsp_buf + 8) = 0x0; /* success */
+ payload_length = 8 + ((*(int *)(buf + 4)) + 7)/8;
+ for (i = 0; i < payload_length; i++)
+ *(int *)(driver->apps_rsp_buf+12+i) = *(buf+i);
+ if (driver->ch_cntl)
+ diag_send_log_mask_update(driver->ch_cntl,
+ *(int *)buf);
+ if (driver->chlpass_cntl)
+ diag_send_log_mask_update(driver->chlpass_cntl,
+ *(int *)buf);
+ if (driver->ch_wcnss_cntl)
+ diag_send_log_mask_update(driver->ch_wcnss_cntl,
+ *(int *)buf);
+ encode_rsp_and_send(12 + payload_length - 1);
+ return 0;
+ }
+#endif
+ } /* Get log masks */
+ else if (*buf == 0x73 && *(int *)(buf+4) == 4) {
+#if defined(CONFIG_DIAG_OVER_USB)
+ if (!(driver->ch) && chk_apps_only()) {
+ equip_id = *(int *)(buf + 8);
+ num_items = *(int *)(buf + 12);
+ driver->apps_rsp_buf[0] = 0x73;
+ driver->apps_rsp_buf[1] = 0x0;
+ driver->apps_rsp_buf[2] = 0x0;
+ driver->apps_rsp_buf[3] = 0x0;
+ *(int *)(driver->apps_rsp_buf + 4) = 0x4;
+ if (!chk_equip_id_and_mask(equip_id,
+ driver->apps_rsp_buf+20))
+ *(int *)(driver->apps_rsp_buf + 8) = 0x0;
+ else
+ *(int *)(driver->apps_rsp_buf + 8) = 0x1;
+ *(int *)(driver->apps_rsp_buf + 12) = equip_id;
+ *(int *)(driver->apps_rsp_buf + 16) = num_items;
+ encode_rsp_and_send(20+(num_items+7)/8-1);
+ return 0;
+ }
+#endif
+ } /* Disable log masks */
+ else if (*buf == 0x73 && *(int *)(buf+4) == 0) {
+ /* Disable mask for each log code */
+ diag_disable_log_mask();
+ diag_update_userspace_clients(LOG_MASKS_TYPE);
+#if defined(CONFIG_DIAG_OVER_USB)
+ if (chk_apps_only()) {
+ driver->apps_rsp_buf[0] = 0x73;
+ driver->apps_rsp_buf[1] = 0x0;
+ driver->apps_rsp_buf[2] = 0x0;
+ driver->apps_rsp_buf[3] = 0x0;
+ *(int *)(driver->apps_rsp_buf + 4) = 0x0;
+ *(int *)(driver->apps_rsp_buf + 8) = 0x0; /* status */
+ if (driver->ch_cntl)
+ diag_send_log_mask_update(driver->ch_cntl,
+ ALL_EQUIP_ID);
+ if (driver->chlpass_cntl)
+ diag_send_log_mask_update(driver->chlpass_cntl,
+ ALL_EQUIP_ID);
+ if (driver->ch_wcnss_cntl)
+ diag_send_log_mask_update(driver->ch_wcnss_cntl,
+ ALL_EQUIP_ID);
+ encode_rsp_and_send(11);
+ return 0;
+ }
+#endif
+ } /* Get runtime message mask */
+ else if ((*buf == 0x7d) && (*(buf+1) == 0x3)) {
+ ssid_first = *(uint16_t *)(buf + 2);
+ ssid_last = *(uint16_t *)(buf + 4);
+#if defined(CONFIG_DIAG_OVER_USB)
+ if (!(driver->ch) && chk_apps_only()) {
+ driver->apps_rsp_buf[0] = 0x7d;
+ driver->apps_rsp_buf[1] = 0x3;
+ *(uint16_t *)(driver->apps_rsp_buf+2) = ssid_first;
+ *(uint16_t *)(driver->apps_rsp_buf+4) = ssid_last;
+ driver->apps_rsp_buf[6] = 0x1; /* Success Status */
+ driver->apps_rsp_buf[7] = 0x0;
+ rt_mask_ptr = driver->msg_masks;
+ while (*(uint32_t *)(rt_mask_ptr + 4)) {
+ rt_first_ssid = *(uint32_t *)rt_mask_ptr;
+ rt_mask_ptr += 8; /* +8 to skip 'last' */
+ rt_last_ssid = *(uint32_t *)rt_mask_ptr;
+ rt_mask_ptr += 4;
+ if (ssid_first == rt_first_ssid && ssid_last ==
+ rt_last_ssid) {
+ rt_mask_size = 4 * (rt_last_ssid -
+ rt_first_ssid + 1);
+ memcpy(driver->apps_rsp_buf+8,
+ rt_mask_ptr, rt_mask_size);
+ encode_rsp_and_send(8+rt_mask_size-1);
+ return 0;
+ }
+ rt_mask_ptr += MAX_SSID_PER_RANGE*4;
+ }
+ }
+#endif
+ } /* Set runtime message mask */
+ else if ((*buf == 0x7d) && (*(buf+1) == 0x4)) {
+ ssid_first = *(uint16_t *)(buf + 2);
+ ssid_last = *(uint16_t *)(buf + 4);
+ ssid_range = 4 * (ssid_last - ssid_first + 1);
+ pr_debug("diag: received mask update for ssid_first = %d, ssid_last = %d",
+ ssid_first, ssid_last);
+ diag_update_msg_mask(ssid_first, ssid_last , buf + 8);
+ diag_update_userspace_clients(MSG_MASKS_TYPE);
+#if defined(CONFIG_DIAG_OVER_USB)
+ if (chk_apps_only()) {
+ for (i = 0; i < 8 + ssid_range; i++)
+ *(driver->apps_rsp_buf + i) = *(buf+i);
+ *(driver->apps_rsp_buf + 6) = 0x1;
+ if (driver->ch_cntl)
+ diag_send_msg_mask_update(driver->ch_cntl,
+ ssid_first, ssid_last, MODEM_PROC);
+ if (driver->chlpass_cntl)
+ diag_send_msg_mask_update(driver->chlpass_cntl,
+ ssid_first, ssid_last, LPASS_PROC);
+ if (driver->ch_wcnss_cntl)
+ diag_send_msg_mask_update(driver->ch_wcnss_cntl,
+ ssid_first, ssid_last, WCNSS_PROC);
+ encode_rsp_and_send(8 + ssid_range - 1);
+ return 0;
+ }
+#endif
+ } /* Set ALL runtime message mask */
+ else if ((*buf == 0x7d) && (*(buf+1) == 0x5)) {
+ rt_mask = *(int *)(buf + 4);
+ diag_set_msg_mask(rt_mask);
+ diag_update_userspace_clients(MSG_MASKS_TYPE);
+#if defined(CONFIG_DIAG_OVER_USB)
+ if (chk_apps_only()) {
+ driver->apps_rsp_buf[0] = 0x7d; /* cmd_code */
+ driver->apps_rsp_buf[1] = 0x5; /* set subcommand */
+ driver->apps_rsp_buf[2] = 1; /* success */
+ driver->apps_rsp_buf[3] = 0; /* rsvd */
+ *(int *)(driver->apps_rsp_buf + 4) = rt_mask;
+ /* send msg mask update to peripheral */
+ if (driver->ch_cntl)
+ diag_send_msg_mask_update(driver->ch_cntl,
+ ALL_SSID, ALL_SSID, MODEM_PROC);
+ if (driver->chlpass_cntl)
+ diag_send_msg_mask_update(driver->chlpass_cntl,
+ ALL_SSID, ALL_SSID, LPASS_PROC);
+ if (driver->ch_wcnss_cntl)
+ diag_send_msg_mask_update(driver->ch_wcnss_cntl,
+ ALL_SSID, ALL_SSID, WCNSS_PROC);
+ encode_rsp_and_send(7);
+ return 0;
+ }
+#endif
+ } else if (*buf == 0x82) { /* event mask change */
+ buf += 4;
+ diag_event_num_bytes = (*(uint16_t *)buf)/8+1;
+ diag_update_event_mask(buf, 1, (*(uint16_t *)buf)/8+1);
+ diag_update_userspace_clients(EVENT_MASKS_TYPE);
+#if defined(CONFIG_DIAG_OVER_USB)
+ if (chk_apps_only()) {
+ driver->apps_rsp_buf[0] = 0x82;
+ driver->apps_rsp_buf[1] = 0x0;
+ *(uint16_t *)(driver->apps_rsp_buf + 2) = 0x0;
+ *(uint16_t *)(driver->apps_rsp_buf + 4) =
+ EVENT_LAST_ID + 1;
+ memcpy(driver->apps_rsp_buf+6, driver->event_masks,
+ EVENT_LAST_ID/8+1);
+ if (driver->ch_cntl)
+ diag_send_event_mask_update(driver->ch_cntl,
+ diag_event_num_bytes);
+ if (driver->chlpass_cntl)
+ diag_send_event_mask_update(
+ driver->chlpass_cntl,
+ diag_event_num_bytes);
+ if (driver->ch_wcnss_cntl)
+ diag_send_event_mask_update(
+ driver->ch_wcnss_cntl, diag_event_num_bytes);
+ encode_rsp_and_send(6 + EVENT_LAST_ID/8);
+ return 0;
+ }
+#endif
+ } else if (*buf == 0x60) {
+ diag_event_config = *(buf+1);
+ diag_toggle_event_mask(*(buf+1));
+ diag_update_userspace_clients(EVENT_MASKS_TYPE);
+#if defined(CONFIG_DIAG_OVER_USB)
+ if (chk_apps_only()) {
+ driver->apps_rsp_buf[0] = 0x60;
+ driver->apps_rsp_buf[1] = 0x0;
+ driver->apps_rsp_buf[2] = 0x0;
+ if (driver->ch_cntl)
+ diag_send_event_mask_update(driver->ch_cntl,
+ diag_event_num_bytes);
+ if (driver->chlpass_cntl)
+ diag_send_event_mask_update(
+ driver->chlpass_cntl,
+ diag_event_num_bytes);
+ if (driver->ch_wcnss_cntl)
+ diag_send_event_mask_update(
+ driver->ch_wcnss_cntl, diag_event_num_bytes);
+ encode_rsp_and_send(2);
+ return 0;
+ }
+#endif
+ }
+
+ return packet_type;
+}
+
+void diag_masks_init(void)
+{
+ if (driver->event_mask == NULL) {
+ driver->event_mask = kzalloc(sizeof(
+ struct diag_ctrl_event_mask), GFP_KERNEL);
+ if (driver->event_mask == NULL)
+ goto err;
+ kmemleak_not_leak(driver->event_mask);
+ }
+ if (driver->msg_mask == NULL) {
+ driver->msg_mask = kzalloc(sizeof(
+ struct diag_ctrl_msg_mask), GFP_KERNEL);
+ if (driver->msg_mask == NULL)
+ goto err;
+ kmemleak_not_leak(driver->msg_mask);
+ }
+ if (driver->log_mask == NULL) {
+ driver->log_mask = kzalloc(sizeof(
+ struct diag_ctrl_log_mask), GFP_KERNEL);
+ if (driver->log_mask == NULL)
+ goto err;
+ kmemleak_not_leak(driver->log_mask);
+ }
+
+ if (driver->buf_msg_mask_update == NULL) {
+ driver->buf_msg_mask_update = kzalloc(APPS_BUF_SIZE,
+ GFP_KERNEL);
+ if (driver->buf_msg_mask_update == NULL)
+ goto err;
+ kmemleak_not_leak(driver->buf_msg_mask_update);
+ }
+ if (driver->buf_log_mask_update == NULL) {
+ driver->buf_log_mask_update = kzalloc(APPS_BUF_SIZE,
+ GFP_KERNEL);
+ if (driver->buf_log_mask_update == NULL)
+ goto err;
+ kmemleak_not_leak(driver->buf_log_mask_update);
+ }
+ if (driver->buf_event_mask_update == NULL) {
+ driver->buf_event_mask_update = kzalloc(APPS_BUF_SIZE,
+ GFP_KERNEL);
+ if (driver->buf_event_mask_update == NULL)
+ goto err;
+ kmemleak_not_leak(driver->buf_event_mask_update);
+ }
+ if (driver->msg_masks == NULL) {
+ driver->msg_masks = kzalloc(MSG_MASK_SIZE, GFP_KERNEL);
+ if (driver->msg_masks == NULL)
+ goto err;
+ kmemleak_not_leak(driver->msg_masks);
+ }
+ diag_create_msg_mask_table();
+ diag_event_num_bytes = 0;
+ if (driver->log_masks == NULL) {
+ driver->log_masks = kzalloc(LOG_MASK_SIZE, GFP_KERNEL);
+ if (driver->log_masks == NULL)
+ goto err;
+ kmemleak_not_leak(driver->log_masks);
+ }
+ driver->log_masks_length = (sizeof(struct mask_info))*MAX_EQUIP_ID;
+ if (driver->event_masks == NULL) {
+ driver->event_masks = kzalloc(EVENT_MASK_SIZE, GFP_KERNEL);
+ if (driver->event_masks == NULL)
+ goto err;
+ kmemleak_not_leak(driver->event_masks);
+ }
+#ifdef CONFIG_DIAG_OVER_USB
+ INIT_WORK(&(driver->diag_modem_mask_update_work),
+ diag_modem_mask_update_fn);
+ INIT_WORK(&(driver->diag_lpass_mask_update_work),
+ diag_lpass_mask_update_fn);
+ INIT_WORK(&(driver->diag_wcnss_mask_update_work),
+ diag_wcnss_mask_update_fn);
+#endif
+ return;
+err:
+ pr_err("diag: Could not initialize diag mask buffers");
+ kfree(driver->event_mask);
+ kfree(driver->log_mask);
+ kfree(driver->msg_mask);
+ kfree(driver->msg_masks);
+ kfree(driver->log_masks);
+ kfree(driver->event_masks);
+}
+
+void diag_masks_exit(void)
+{
+ kfree(driver->event_mask);
+ kfree(driver->log_mask);
+ kfree(driver->msg_mask);
+ kfree(driver->msg_masks);
+ kfree(driver->log_masks);
+ kfree(driver->event_masks);
+}
diff --git a/drivers/char/diag/diag_masks.h b/drivers/char/diag/diag_masks.h
new file mode 100644
index 0000000..bcf5bc2
--- /dev/null
+++ b/drivers/char/diag/diag_masks.h
@@ -0,0 +1,27 @@
+/* Copyright (c) 2012, 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.
+ */
+
+#ifndef DIAG_MASKS_H
+#define DIAG_MASKS_H
+
+#include "diagfwd.h"
+
+int chk_equip_id_and_mask(int equip_id, uint8_t *buf);
+void diag_send_event_mask_update(smd_channel_t *, int num_bytes);
+void diag_send_msg_mask_update(smd_channel_t *, int ssid_first,
+ int ssid_last, int proc);
+void diag_send_log_mask_update(smd_channel_t *, int);
+int diag_process_apps_masks(unsigned char *buf, int len);
+void diag_masks_init(void);
+void diag_masks_exit(void);
+extern int diag_event_num_bytes;
+#endif
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 814fe64..09da40c 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -37,6 +37,8 @@
#include "diagfwd_smux.h"
#endif
#include <linux/timer.h>
+#include "diag_debugfs.h"
+#include "diag_masks.h"
MODULE_DESCRIPTION("Diag Char Driver");
MODULE_LICENSE("GPL v2");
@@ -1422,6 +1424,7 @@
diag_debugfs_init();
diagfwd_init();
diagfwd_cntl_init();
+ diag_masks_init();
driver->dci_state = diag_dci_init();
diag_sdio_fn(INIT);
diag_bridge_fn(INIT);
@@ -1457,6 +1460,7 @@
diagchar_cleanup();
diagfwd_exit();
diagfwd_cntl_exit();
+ diag_masks_exit();
diag_sdio_fn(EXIT);
diag_bridge_fn(EXIT);
return -1;
@@ -1470,6 +1474,7 @@
diagmem_exit(driver, POOL_TYPE_ALL);
diagfwd_exit();
diagfwd_cntl_exit();
+ diag_masks_exit();
diag_sdio_fn(EXIT);
diag_bridge_fn(EXIT);
diag_debugfs_cleanup();
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 737edbf..a537bb3 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -39,63 +39,38 @@
#include "diagfwd_sdio.h"
#endif
#include "diag_dci.h"
+#include "diag_masks.h"
#define MODE_CMD 41
#define RESET_ID 2
-#define ALL_EQUIP_ID 100
-#define ALL_SSID -1
-#define MAX_SSID_PER_RANGE 100
int diag_debug_buf_idx;
unsigned char diag_debug_buf[1024];
static unsigned int buf_tbl_size = 8; /*Number of entries in table of buffers */
struct diag_master_table entry;
smd_channel_t *ch_temp = NULL, *chlpass_temp = NULL, *ch_wcnss_temp = NULL;
-int diag_event_num_bytes;
-int diag_event_config;
struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 };
struct diag_hdlc_dest_type enc = { NULL, NULL, 0 };
-struct mask_info {
- int equip_id;
- int num_items;
- int index;
-};
-#define CREATE_MSG_MASK_TBL_ROW(XX) \
-do { \
- *(int *)(msg_mask_tbl_ptr) = MSG_SSID_ ## XX; \
- msg_mask_tbl_ptr += 4; \
- *(int *)(msg_mask_tbl_ptr) = MSG_SSID_ ## XX ## _LAST; \
- msg_mask_tbl_ptr += 4; \
- /* mimic the last entry as actual_last while creation */ \
- *(int *)(msg_mask_tbl_ptr) = MSG_SSID_ ## XX ## _LAST; \
- msg_mask_tbl_ptr += 4; \
- /* increment by MAX_SSID_PER_RANGE cells */ \
- msg_mask_tbl_ptr += MAX_SSID_PER_RANGE * sizeof(int); \
-} while (0)
-
-#define ENCODE_RSP_AND_SEND(buf_length) \
-do { \
- send.state = DIAG_STATE_START; \
- send.pkt = driver->apps_rsp_buf; \
- send.last = (void *)(driver->apps_rsp_buf + buf_length); \
- send.terminate = 1; \
- if (!driver->in_busy_1) { \
- enc.dest = driver->buf_in_1; \
- enc.dest_last = (void *)(driver->buf_in_1 + APPS_BUF_SIZE - 1);\
- diag_hdlc_encode(&send, &enc); \
- driver->write_ptr_1->buf = driver->buf_in_1; \
- driver->write_ptr_1->length = (int)(enc.dest - \
- (void *)(driver->buf_in_1)); \
- driver->in_busy_1 = 1; \
- diag_device_write(driver->buf_in_1, MODEM_DATA, \
- driver->write_ptr_1); \
- memset(driver->apps_rsp_buf, '\0', APPS_BUF_SIZE); \
- } \
-} while (0)
-
-#define CHK_OVERFLOW(bufStart, start, end, length) \
-((bufStart <= start) && (end - start >= length)) ? 1 : 0
+void encode_rsp_and_send(int buf_length)
+{
+ send.state = DIAG_STATE_START;
+ send.pkt = driver->apps_rsp_buf;
+ send.last = (void *)(driver->apps_rsp_buf + buf_length);
+ send.terminate = 1;
+ if (!driver->in_busy_1) {
+ enc.dest = driver->buf_in_1;
+ enc.dest_last = (void *)(driver->buf_in_1 + APPS_BUF_SIZE - 1);
+ diag_hdlc_encode(&send, &enc);
+ driver->write_ptr_1->buf = driver->buf_in_1;
+ driver->write_ptr_1->length = (int)(enc.dest -
+ (void *)(driver->buf_in_1));
+ driver->in_busy_1 = 1;
+ diag_device_write(driver->buf_in_1, MODEM_DATA,
+ driver->write_ptr_1);
+ memset(driver->apps_rsp_buf, '\0', APPS_BUF_SIZE);
+ }
+}
/* Determine if this device uses a device tree */
#ifdef CONFIG_OF
@@ -136,6 +111,7 @@
case MSM_CPU_8960AB:
return AO8960_TOOLS_ID;
case MSM_CPU_8064:
+ case MSM_CPU_8064AB:
return APQ8064_TOOLS_ID;
case MSM_CPU_8930:
case MSM_CPU_8930AA:
@@ -163,6 +139,7 @@
case MSM_CPU_8960:
case MSM_CPU_8960AB:
case MSM_CPU_8064:
+ case MSM_CPU_8064AB:
case MSM_CPU_8930:
case MSM_CPU_8930AA:
case MSM_CPU_8627:
@@ -185,7 +162,7 @@
return 1;
else if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm8930aa() ||
cpu_is_msm9615() || cpu_is_apq8064() || cpu_is_msm8627() ||
- cpu_is_msm8960ab())
+ cpu_is_msm8960ab() || cpu_is_apq8064ab())
return 1;
else
return 0;
@@ -559,248 +536,6 @@
}
}
-static void diag_print_mask_table(void)
-{
-/* Enable this to print mask table when updated */
-#ifdef MASK_DEBUG
- int first, last, actual_last;
- uint8_t *ptr = driver->msg_masks;
- int i = 0;
- pr_info("diag: F3 message mask table\n");
- while (*(uint32_t *)(ptr + 4)) {
- first = *(uint32_t *)ptr;
- ptr += 4;
- last = *(uint32_t *)ptr;
- ptr += 4;
- actual_last = *(uint32_t *)ptr;
- ptr += 4;
- pr_info("diag: SSID %d, %d - %d\n", first, last, actual_last);
- for (i = 0 ; i <= actual_last - first ; i++)
- pr_info("diag: MASK:%x\n", *((uint32_t *)ptr + i));
- ptr += MAX_SSID_PER_RANGE*4;
- }
-#endif
-}
-
-void diag_create_msg_mask_table(void)
-{
- uint8_t *msg_mask_tbl_ptr = driver->msg_masks;
-
- CREATE_MSG_MASK_TBL_ROW(0);
- CREATE_MSG_MASK_TBL_ROW(1);
- CREATE_MSG_MASK_TBL_ROW(2);
- CREATE_MSG_MASK_TBL_ROW(3);
- CREATE_MSG_MASK_TBL_ROW(4);
- CREATE_MSG_MASK_TBL_ROW(5);
- CREATE_MSG_MASK_TBL_ROW(6);
- CREATE_MSG_MASK_TBL_ROW(7);
- CREATE_MSG_MASK_TBL_ROW(8);
- CREATE_MSG_MASK_TBL_ROW(9);
- CREATE_MSG_MASK_TBL_ROW(10);
- CREATE_MSG_MASK_TBL_ROW(11);
- CREATE_MSG_MASK_TBL_ROW(12);
- CREATE_MSG_MASK_TBL_ROW(13);
- CREATE_MSG_MASK_TBL_ROW(14);
- CREATE_MSG_MASK_TBL_ROW(15);
- CREATE_MSG_MASK_TBL_ROW(16);
- CREATE_MSG_MASK_TBL_ROW(17);
- CREATE_MSG_MASK_TBL_ROW(18);
- CREATE_MSG_MASK_TBL_ROW(19);
- CREATE_MSG_MASK_TBL_ROW(20);
- CREATE_MSG_MASK_TBL_ROW(21);
- CREATE_MSG_MASK_TBL_ROW(22);
- CREATE_MSG_MASK_TBL_ROW(23);
-}
-
-static void diag_set_msg_mask(int rt_mask)
-{
- int first_ssid, last_ssid, i;
- uint8_t *parse_ptr, *ptr = driver->msg_masks;
-
- mutex_lock(&driver->diagchar_mutex);
- while (*(uint32_t *)(ptr + 4)) {
- first_ssid = *(uint32_t *)ptr;
- ptr += 8; /* increment by 8 to skip 'last' */
- last_ssid = *(uint32_t *)ptr;
- ptr += 4;
- parse_ptr = ptr;
- pr_debug("diag: updating range %d %d\n", first_ssid, last_ssid);
- for (i = 0; i < last_ssid - first_ssid + 1; i++) {
- *(int *)parse_ptr = rt_mask;
- parse_ptr += 4;
- }
- ptr += MAX_SSID_PER_RANGE * 4;
- }
- mutex_unlock(&driver->diagchar_mutex);
-}
-
-static void diag_update_msg_mask(int start, int end , uint8_t *buf)
-{
- int found = 0, first, last, actual_last;
- uint8_t *actual_last_ptr;
- uint8_t *ptr = driver->msg_masks;
- uint8_t *ptr_buffer_start = &(*(driver->msg_masks));
- uint8_t *ptr_buffer_end = &(*(driver->msg_masks)) + MSG_MASK_SIZE;
-
- mutex_lock(&driver->diagchar_mutex);
-
- /* First SSID can be zero : So check that last is non-zero */
- while (*(uint32_t *)(ptr + 4)) {
- first = *(uint32_t *)ptr;
- ptr += 4;
- last = *(uint32_t *)ptr;
- ptr += 4;
- actual_last = *(uint32_t *)ptr;
- actual_last_ptr = ptr;
- ptr += 4;
- if (start >= first && start <= actual_last) {
- ptr += (start - first)*4;
- if (end > actual_last) {
- pr_info("diag: ssid range mismatch\n");
- actual_last = end;
- *(uint32_t *)(actual_last_ptr) = end;
- }
- if (CHK_OVERFLOW(ptr_buffer_start, ptr, ptr_buffer_end,
- (((end - start)+1)*4))) {
- pr_debug("diag: update ssid start %d, end %d\n",
- start, end);
- memcpy(ptr, buf , ((end - start)+1)*4);
- } else
- pr_alert("diag: Not enough space MSG_MASK\n");
- found = 1;
- break;
- } else {
- ptr += MAX_SSID_PER_RANGE*4;
- }
- }
- /* Entry was not found - add new table */
- if (!found) {
- if (CHK_OVERFLOW(ptr_buffer_start, ptr, ptr_buffer_end,
- 8 + ((end - start) + 1)*4)) {
- memcpy(ptr, &(start) , 4);
- ptr += 4;
- memcpy(ptr, &(end), 4);
- ptr += 4;
- memcpy(ptr, &(end), 4); /* create actual_last entry */
- ptr += 4;
- pr_debug("diag: adding NEW ssid start %d, end %d\n",
- start, end);
- memcpy(ptr, buf , ((end - start) + 1)*4);
- } else
- pr_alert("diag: Not enough buffer space for MSG_MASK\n");
- }
- mutex_unlock(&driver->diagchar_mutex);
- diag_print_mask_table();
-}
-
-void diag_toggle_event_mask(int toggle)
-{
- uint8_t *ptr = driver->event_masks;
-
- mutex_lock(&driver->diagchar_mutex);
- if (toggle)
- memset(ptr, 0xFF, EVENT_MASK_SIZE);
- else
- memset(ptr, 0, EVENT_MASK_SIZE);
- mutex_unlock(&driver->diagchar_mutex);
-}
-
-static void diag_update_event_mask(uint8_t *buf, int toggle, int num_bytes)
-{
- uint8_t *ptr = driver->event_masks;
- uint8_t *temp = buf + 2;
-
- mutex_lock(&driver->diagchar_mutex);
- if (!toggle)
- memset(ptr, 0 , EVENT_MASK_SIZE);
- else
- if (CHK_OVERFLOW(ptr, ptr,
- ptr+EVENT_MASK_SIZE, num_bytes))
- memcpy(ptr, temp , num_bytes);
- else
- printk(KERN_CRIT "Not enough buffer space "
- "for EVENT_MASK\n");
- mutex_unlock(&driver->diagchar_mutex);
-}
-
-static void diag_disable_log_mask(void)
-{
- int i = 0;
- struct mask_info *parse_ptr = (struct mask_info *)(driver->log_masks);
-
- pr_debug("diag: disable log masks\n");
- mutex_lock(&driver->diagchar_mutex);
- for (i = 0; i < MAX_EQUIP_ID; i++) {
- pr_debug("diag: equip id %d\n", parse_ptr->equip_id);
- if (!(parse_ptr->equip_id)) /* Reached a null entry */
- break;
- memset(driver->log_masks + parse_ptr->index, 0,
- (parse_ptr->num_items + 7)/8);
- parse_ptr++;
- }
- mutex_unlock(&driver->diagchar_mutex);
-}
-
-int chk_equip_id_and_mask(int equip_id, uint8_t *buf)
-{
- int i = 0, flag = 0, num_items, offset;
- unsigned char *ptr_data;
- struct mask_info *ptr = (struct mask_info *)(driver->log_masks);
-
- pr_debug("diag: received equip id = %d\n", equip_id);
- /* Check if this is valid equipment ID */
- for (i = 0; i < MAX_EQUIP_ID; i++) {
- if ((ptr->equip_id == equip_id) && (ptr->index != 0)) {
- offset = ptr->index;
- num_items = ptr->num_items;
- flag = 1;
- break;
- }
- ptr++;
- }
- if (!flag)
- return -EPERM;
- ptr_data = driver->log_masks + offset;
- memcpy(buf, ptr_data, (num_items+7)/8);
- return 0;
-}
-
-static void diag_update_log_mask(int equip_id, uint8_t *buf, int num_items)
-{
- uint8_t *temp = buf;
- int i = 0;
- unsigned char *ptr_data;
- int offset = (sizeof(struct mask_info))*MAX_EQUIP_ID;
- struct mask_info *ptr = (struct mask_info *)(driver->log_masks);
-
- pr_debug("diag: received equip id = %d\n", equip_id);
- mutex_lock(&driver->diagchar_mutex);
- /* Check if we already know index of this equipment ID */
- for (i = 0; i < MAX_EQUIP_ID; i++) {
- if ((ptr->equip_id == equip_id) && (ptr->index != 0)) {
- offset = ptr->index;
- break;
- }
- if ((ptr->equip_id == 0) && (ptr->index == 0)) {
- /* Reached a null entry */
- ptr->equip_id = equip_id;
- ptr->num_items = num_items;
- ptr->index = driver->log_masks_length;
- offset = driver->log_masks_length;
- driver->log_masks_length += ((num_items+7)/8);
- break;
- }
- ptr++;
- }
- ptr_data = driver->log_masks + offset;
- if (CHK_OVERFLOW(driver->log_masks, ptr_data, driver->log_masks
- + LOG_MASK_SIZE, (num_items+7)/8))
- memcpy(ptr_data, temp , (num_items+7)/8);
- else
- pr_err("diag: Not enough buffer space for LOG_MASK\n");
- mutex_unlock(&driver->diagchar_mutex);
-}
-
static void diag_update_pkt_buffer(unsigned char *buf)
{
unsigned char *ptr = driver->pkt_buf;
@@ -869,415 +604,21 @@
}
}
-void diag_modem_mask_update_fn(struct work_struct *work)
-{
- diag_send_msg_mask_update(driver->ch_cntl, ALL_SSID,
- ALL_SSID, MODEM_PROC);
- diag_send_log_mask_update(driver->ch_cntl, ALL_EQUIP_ID);
- diag_send_event_mask_update(driver->ch_cntl, diag_event_num_bytes);
-}
-
-void diag_lpass_mask_update_fn(struct work_struct *work)
-{
- diag_send_msg_mask_update(driver->chlpass_cntl, ALL_SSID,
- ALL_SSID, LPASS_PROC);
- diag_send_log_mask_update(driver->chlpass_cntl, ALL_EQUIP_ID);
- diag_send_event_mask_update(driver->chlpass_cntl, diag_event_num_bytes);
-}
-
-void diag_wcnss_mask_update_fn(struct work_struct *work)
-{
- diag_send_msg_mask_update(driver->ch_wcnss_cntl, ALL_SSID,
- ALL_SSID, WCNSS_PROC);
- diag_send_log_mask_update(driver->ch_wcnss_cntl, ALL_EQUIP_ID);
- diag_send_event_mask_update(driver->ch_wcnss_cntl,
- diag_event_num_bytes);
-}
-
-void diag_send_log_mask_update(smd_channel_t *ch, int equip_id)
-{
- void *buf = driver->buf_log_mask_update;
- int header_size = sizeof(struct diag_ctrl_log_mask);
- struct mask_info *ptr = (struct mask_info *)driver->log_masks;
- int i, size, wr_size = -ENOMEM, retry_count = 0, timer;
-
- mutex_lock(&driver->diag_cntl_mutex);
- for (i = 0; i < MAX_EQUIP_ID; i++) {
- size = (ptr->num_items+7)/8;
- /* reached null entry */
- if ((ptr->equip_id == 0) && (ptr->index == 0))
- break;
- driver->log_mask->cmd_type = DIAG_CTRL_MSG_LOG_MASK;
- driver->log_mask->num_items = ptr->num_items;
- driver->log_mask->data_len = 11 + size;
- driver->log_mask->stream_id = 1; /* 2, if dual stream */
- driver->log_mask->status = 3; /* status for valid mask */
- driver->log_mask->equip_id = ptr->equip_id;
- driver->log_mask->log_mask_size = size;
- /* send only desired update, NOT ALL */
- if (equip_id == ALL_EQUIP_ID || equip_id ==
- driver->log_mask->equip_id) {
- memcpy(buf, driver->log_mask, header_size);
- memcpy(buf+header_size, driver->log_masks+ptr->index,
- size);
- if (ch) {
- while (retry_count < 3) {
- wr_size = smd_write(ch, buf,
- header_size + size);
- if (wr_size == -ENOMEM) {
- retry_count++;
- for (timer = 0; timer < 5;
- timer++)
- udelay(2000);
- } else
- break;
- }
- if (wr_size != header_size + size)
- pr_err("diag: log mask update failed"
- " %d, tried %d", wr_size, header_size + size);
- else
- pr_debug("diag: updated log equip ID %d"
- ",len %d\n", driver->log_mask->equip_id,
- driver->log_mask->log_mask_size);
- } else
- pr_err("diag: ch not valid for log update\n");
- }
- ptr++;
- }
- mutex_unlock(&driver->diag_cntl_mutex);
-}
-
-void diag_send_event_mask_update(smd_channel_t *ch, int num_bytes)
-{
- void *buf = driver->buf_event_mask_update;
- int header_size = sizeof(struct diag_ctrl_event_mask);
- int wr_size = -ENOMEM, retry_count = 0, timer;
-
- mutex_lock(&driver->diag_cntl_mutex);
- if (num_bytes == 0) {
- pr_debug("diag: event mask not set yet, so no update\n");
- mutex_unlock(&driver->diag_cntl_mutex);
- return;
- }
- /* send event mask update */
- driver->event_mask->cmd_type = DIAG_CTRL_MSG_EVENT_MASK;
- driver->event_mask->data_len = 7 + num_bytes;
- driver->event_mask->stream_id = 1; /* 2, if dual stream */
- driver->event_mask->status = 3; /* status for valid mask */
- driver->event_mask->event_config = diag_event_config; /* event config */
- driver->event_mask->event_mask_size = num_bytes;
- memcpy(buf, driver->event_mask, header_size);
- memcpy(buf+header_size, driver->event_masks, num_bytes);
- if (ch) {
- while (retry_count < 3) {
- wr_size = smd_write(ch, buf, header_size + num_bytes);
- if (wr_size == -ENOMEM) {
- retry_count++;
- for (timer = 0; timer < 5; timer++)
- udelay(2000);
- } else
- break;
- }
- if (wr_size != header_size + num_bytes)
- pr_err("diag: error writing event mask %d, tried %d\n",
- wr_size, header_size + num_bytes);
- } else
- pr_err("diag: ch not valid for event update\n");
- mutex_unlock(&driver->diag_cntl_mutex);
-}
-
-void diag_send_msg_mask_update(smd_channel_t *ch, int updated_ssid_first,
- int updated_ssid_last, int proc)
-{
- void *buf = driver->buf_msg_mask_update;
- int first, last, actual_last, size = -ENOMEM, retry_count = 0, timer;
- int header_size = sizeof(struct diag_ctrl_msg_mask);
- uint8_t *ptr = driver->msg_masks;
-
- mutex_lock(&driver->diag_cntl_mutex);
- while (*(uint32_t *)(ptr + 4)) {
- first = *(uint32_t *)ptr;
- ptr += 4;
- last = *(uint32_t *)ptr;
- ptr += 4;
- actual_last = *(uint32_t *)ptr;
- ptr += 4;
- if ((updated_ssid_first >= first && updated_ssid_last <=
- actual_last) || (updated_ssid_first == ALL_SSID)) {
- /* send f3 mask update */
- driver->msg_mask->cmd_type = DIAG_CTRL_MSG_F3_MASK;
- driver->msg_mask->msg_mask_size = actual_last -
- first + 1;
- driver->msg_mask->data_len = 11 +
- 4 * (driver->msg_mask->msg_mask_size);
- driver->msg_mask->stream_id = 1; /* 2, if dual stream */
- driver->msg_mask->status = 3; /* status valid mask */
- driver->msg_mask->msg_mode = 0; /* Legcay mode */
- driver->msg_mask->ssid_first = first;
- driver->msg_mask->ssid_last = actual_last;
- memcpy(buf, driver->msg_mask, header_size);
- memcpy(buf+header_size, ptr,
- 4 * (driver->msg_mask->msg_mask_size));
- if (ch) {
- while (retry_count < 3) {
- size = smd_write(ch, buf, header_size +
- 4*(driver->msg_mask->msg_mask_size));
- if (size == -ENOMEM) {
- retry_count++;
- for (timer = 0; timer < 5;
- timer++)
- udelay(2000);
- } else
- break;
- }
- if (size != header_size +
- 4*(driver->msg_mask->msg_mask_size))
- pr_err("diag: proc %d, msg mask update "
- "fail %d, tried %d\n", proc, size,
- header_size + 4*(driver->msg_mask->msg_mask_size));
- else
- pr_debug("diag: sending mask update for ssid first %d, last %d on PROC %d\n",
- first, actual_last, proc);
- } else
- pr_err("diag: proc %d, ch invalid msg mask"
- "update\n", proc);
- }
- ptr += MAX_SSID_PER_RANGE*4;
- }
- mutex_unlock(&driver->diag_cntl_mutex);
-}
-
static int diag_process_apps_pkt(unsigned char *buf, int len)
{
uint16_t subsys_cmd_code;
int subsys_id, ssid_first, ssid_last, ssid_range;
int packet_type = 1, i, cmd_code;
- int rt_mask, rt_first_ssid, rt_last_ssid, rt_mask_size;
unsigned char *temp = buf;
- uint8_t *rt_mask_ptr;
- int data_type, equip_id, num_items;
+ int data_type;
#if defined(CONFIG_DIAG_OVER_USB)
- int payload_length;
unsigned char *ptr;
#endif
- /* Set log masks */
- if (*buf == 0x73 && *(int *)(buf+4) == 3) {
- buf += 8;
- /* Read Equip ID and pass as first param below*/
- diag_update_log_mask(*(int *)buf, buf+8, *(int *)(buf+4));
- diag_update_userspace_clients(LOG_MASKS_TYPE);
-#if defined(CONFIG_DIAG_OVER_USB)
- if (chk_apps_only()) {
- driver->apps_rsp_buf[0] = 0x73;
- *(int *)(driver->apps_rsp_buf + 4) = 0x3; /* op. ID */
- *(int *)(driver->apps_rsp_buf + 8) = 0x0; /* success */
- payload_length = 8 + ((*(int *)(buf + 4)) + 7)/8;
- for (i = 0; i < payload_length; i++)
- *(int *)(driver->apps_rsp_buf+12+i) = *(buf+i);
- if (driver->ch_cntl)
- diag_send_log_mask_update(driver->ch_cntl,
- *(int *)buf);
- if (driver->chlpass_cntl)
- diag_send_log_mask_update(driver->chlpass_cntl,
- *(int *)buf);
- if (driver->ch_wcnss_cntl)
- diag_send_log_mask_update(driver->ch_wcnss_cntl,
- *(int *)buf);
- ENCODE_RSP_AND_SEND(12 + payload_length - 1);
- return 0;
- } else
- buf = temp;
-#endif
- } /* Get log masks */
- else if (*buf == 0x73 && *(int *)(buf+4) == 4) {
-#if defined(CONFIG_DIAG_OVER_USB)
- if (!(driver->ch) && chk_apps_only()) {
- equip_id = *(int *)(buf + 8);
- num_items = *(int *)(buf + 12);
- driver->apps_rsp_buf[0] = 0x73;
- driver->apps_rsp_buf[1] = 0x0;
- driver->apps_rsp_buf[2] = 0x0;
- driver->apps_rsp_buf[3] = 0x0;
- *(int *)(driver->apps_rsp_buf + 4) = 0x4;
- if (!chk_equip_id_and_mask(equip_id,
- driver->apps_rsp_buf+20))
- *(int *)(driver->apps_rsp_buf + 8) = 0x0;
- else
- *(int *)(driver->apps_rsp_buf + 8) = 0x1;
- *(int *)(driver->apps_rsp_buf + 12) = equip_id;
- *(int *)(driver->apps_rsp_buf + 16) = num_items;
- ENCODE_RSP_AND_SEND(20+(num_items+7)/8-1);
- return 0;
- } else
- buf = temp;
-#endif
- } /* Disable log masks */
- else if (*buf == 0x73 && *(int *)(buf+4) == 0) {
- /* Disable mask for each log code */
- diag_disable_log_mask();
- diag_update_userspace_clients(LOG_MASKS_TYPE);
-#if defined(CONFIG_DIAG_OVER_USB)
- if (chk_apps_only()) {
- driver->apps_rsp_buf[0] = 0x73;
- driver->apps_rsp_buf[1] = 0x0;
- driver->apps_rsp_buf[2] = 0x0;
- driver->apps_rsp_buf[3] = 0x0;
- *(int *)(driver->apps_rsp_buf + 4) = 0x0;
- *(int *)(driver->apps_rsp_buf + 8) = 0x0; /* status */
- if (driver->ch_cntl)
- diag_send_log_mask_update(driver->ch_cntl,
- ALL_EQUIP_ID);
- if (driver->chlpass_cntl)
- diag_send_log_mask_update(driver->chlpass_cntl,
- ALL_EQUIP_ID);
- if (driver->ch_wcnss_cntl)
- diag_send_log_mask_update(driver->ch_wcnss_cntl,
- ALL_EQUIP_ID);
- ENCODE_RSP_AND_SEND(11);
- return 0;
- }
-#endif
- } /* Get runtime message mask */
- else if ((*buf == 0x7d) && (*(buf+1) == 0x3)) {
- ssid_first = *(uint16_t *)(buf + 2);
- ssid_last = *(uint16_t *)(buf + 4);
-#if defined(CONFIG_DIAG_OVER_USB)
- if (!(driver->ch) && chk_apps_only()) {
- driver->apps_rsp_buf[0] = 0x7d;
- driver->apps_rsp_buf[1] = 0x3;
- *(uint16_t *)(driver->apps_rsp_buf+2) = ssid_first;
- *(uint16_t *)(driver->apps_rsp_buf+4) = ssid_last;
- driver->apps_rsp_buf[6] = 0x1; /* Success Status */
- driver->apps_rsp_buf[7] = 0x0;
- rt_mask_ptr = driver->msg_masks;
- while (*(uint32_t *)(rt_mask_ptr + 4)) {
- rt_first_ssid = *(uint32_t *)rt_mask_ptr;
- rt_mask_ptr += 8; /* +8 to skip 'last' */
- rt_last_ssid = *(uint32_t *)rt_mask_ptr;
- rt_mask_ptr += 4;
- if (ssid_first == rt_first_ssid && ssid_last ==
- rt_last_ssid) {
- rt_mask_size = 4 * (rt_last_ssid -
- rt_first_ssid + 1);
- memcpy(driver->apps_rsp_buf+8,
- rt_mask_ptr, rt_mask_size);
- ENCODE_RSP_AND_SEND(8+rt_mask_size-1);
- return 0;
- }
- rt_mask_ptr += MAX_SSID_PER_RANGE*4;
- }
- } else
- buf = temp;
-#endif
- } /* Set runtime message mask */
- else if ((*buf == 0x7d) && (*(buf+1) == 0x4)) {
- ssid_first = *(uint16_t *)(buf + 2);
- ssid_last = *(uint16_t *)(buf + 4);
- ssid_range = 4 * (ssid_last - ssid_first + 1);
- pr_debug("diag: received mask update for ssid_first = %d,"
- " ssid_last = %d", ssid_first, ssid_last);
- diag_update_msg_mask(ssid_first, ssid_last , buf + 8);
- diag_update_userspace_clients(MSG_MASKS_TYPE);
-#if defined(CONFIG_DIAG_OVER_USB)
- if (chk_apps_only()) {
- for (i = 0; i < 8 + ssid_range; i++)
- *(driver->apps_rsp_buf + i) = *(buf+i);
- *(driver->apps_rsp_buf + 6) = 0x1;
- if (driver->ch_cntl)
- diag_send_msg_mask_update(driver->ch_cntl,
- ssid_first, ssid_last, MODEM_PROC);
- if (driver->chlpass_cntl)
- diag_send_msg_mask_update(driver->chlpass_cntl,
- ssid_first, ssid_last, LPASS_PROC);
- if (driver->ch_wcnss_cntl)
- diag_send_msg_mask_update(driver->ch_wcnss_cntl,
- ssid_first, ssid_last, WCNSS_PROC);
- ENCODE_RSP_AND_SEND(8 + ssid_range - 1);
- return 0;
- } else
- buf = temp;
-#endif
- } /* Set ALL runtime message mask */
- else if ((*buf == 0x7d) && (*(buf+1) == 0x5)) {
- rt_mask = *(int *)(buf + 4);
- diag_set_msg_mask(rt_mask);
- diag_update_userspace_clients(MSG_MASKS_TYPE);
-#if defined(CONFIG_DIAG_OVER_USB)
- if (chk_apps_only()) {
- driver->apps_rsp_buf[0] = 0x7d; /* cmd_code */
- driver->apps_rsp_buf[1] = 0x5; /* set subcommand */
- driver->apps_rsp_buf[2] = 1; /* success */
- driver->apps_rsp_buf[3] = 0; /* rsvd */
- *(int *)(driver->apps_rsp_buf + 4) = rt_mask;
- /* send msg mask update to peripheral */
- if (driver->ch_cntl)
- diag_send_msg_mask_update(driver->ch_cntl,
- ALL_SSID, ALL_SSID, MODEM_PROC);
- if (driver->chlpass_cntl)
- diag_send_msg_mask_update(driver->chlpass_cntl,
- ALL_SSID, ALL_SSID, LPASS_PROC);
- if (driver->ch_wcnss_cntl)
- diag_send_msg_mask_update(driver->ch_wcnss_cntl,
- ALL_SSID, ALL_SSID, WCNSS_PROC);
- ENCODE_RSP_AND_SEND(7);
- return 0;
- } else
- buf = temp;
-#endif
- } else if (*buf == 0x82) { /* event mask change */
- buf += 4;
- diag_event_num_bytes = (*(uint16_t *)buf)/8+1;
- diag_update_event_mask(buf, 1, (*(uint16_t *)buf)/8+1);
- diag_update_userspace_clients(EVENT_MASKS_TYPE);
-#if defined(CONFIG_DIAG_OVER_USB)
- if (chk_apps_only()) {
- driver->apps_rsp_buf[0] = 0x82;
- driver->apps_rsp_buf[1] = 0x0;
- *(uint16_t *)(driver->apps_rsp_buf + 2) = 0x0;
- *(uint16_t *)(driver->apps_rsp_buf + 4) =
- EVENT_LAST_ID + 1;
- memcpy(driver->apps_rsp_buf+6, driver->event_masks,
- EVENT_LAST_ID/8+1);
- if (driver->ch_cntl)
- diag_send_event_mask_update(driver->ch_cntl,
- diag_event_num_bytes);
- if (driver->chlpass_cntl)
- diag_send_event_mask_update(
- driver->chlpass_cntl,
- diag_event_num_bytes);
- if (driver->ch_wcnss_cntl)
- diag_send_event_mask_update(
- driver->ch_wcnss_cntl, diag_event_num_bytes);
- ENCODE_RSP_AND_SEND(6 + EVENT_LAST_ID/8);
- return 0;
- } else
- buf = temp;
-#endif
- } else if (*buf == 0x60) {
- diag_event_config = *(buf+1);
- diag_toggle_event_mask(*(buf+1));
- diag_update_userspace_clients(EVENT_MASKS_TYPE);
-#if defined(CONFIG_DIAG_OVER_USB)
- if (chk_apps_only()) {
- driver->apps_rsp_buf[0] = 0x60;
- driver->apps_rsp_buf[1] = 0x0;
- driver->apps_rsp_buf[2] = 0x0;
- if (driver->ch_cntl)
- diag_send_event_mask_update(driver->ch_cntl,
- diag_event_num_bytes);
- if (driver->chlpass_cntl)
- diag_send_event_mask_update(
- driver->chlpass_cntl,
- diag_event_num_bytes);
- if (driver->ch_wcnss_cntl)
- diag_send_event_mask_update(
- driver->ch_wcnss_cntl, diag_event_num_bytes);
- ENCODE_RSP_AND_SEND(2);
- return 0;
- }
-#endif
- }
+ /* Check if the command is a supported mask command */
+ if (diag_process_apps_masks(buf, len) == 0)
+ return 0;
+
/* Check for registered clients and forward packet to apropriate proc */
cmd_code = (int)(*(char *)buf);
temp++;
@@ -1334,7 +675,7 @@
for (i = 0; i < 4; i++)
*(driver->apps_rsp_buf+i) = *(buf+i);
*(uint32_t *)(driver->apps_rsp_buf+4) = PKT_SIZE;
- ENCODE_RSP_AND_SEND(7);
+ encode_rsp_and_send(7);
return 0;
}
/* Check for Apps Only & get event mask request */
@@ -1345,7 +686,7 @@
*(uint16_t *)(driver->apps_rsp_buf + 4) = EVENT_LAST_ID + 1;
for (i = 0; i < EVENT_LAST_ID/8 + 1; i++)
*(unsigned char *)(driver->apps_rsp_buf + 6 + i) = 0x0;
- ENCODE_RSP_AND_SEND(6 + EVENT_LAST_ID/8);
+ encode_rsp_and_send(6 + EVENT_LAST_ID/8);
return 0;
}
/* Get log ID range & Check for Apps Only */
@@ -1370,7 +711,7 @@
*(int *)(driver->apps_rsp_buf + 64) = LOG_GET_ITEM_NUM(LOG_13);
*(int *)(driver->apps_rsp_buf + 68) = LOG_GET_ITEM_NUM(LOG_14);
*(int *)(driver->apps_rsp_buf + 72) = LOG_GET_ITEM_NUM(LOG_15);
- ENCODE_RSP_AND_SEND(75);
+ encode_rsp_and_send(75);
return 0;
}
/* Respond to Get SSID Range request message */
@@ -1428,7 +769,7 @@
*(uint16_t *)(driver->apps_rsp_buf + 94) = MSG_SSID_21_LAST;
*(uint16_t *)(driver->apps_rsp_buf + 96) = MSG_SSID_22;
*(uint16_t *)(driver->apps_rsp_buf + 98) = MSG_SSID_22_LAST;
- ENCODE_RSP_AND_SEND(99);
+ encode_rsp_and_send(99);
return 0;
}
/* Check for Apps Only Respond to Get Subsys Build mask */
@@ -1540,14 +881,14 @@
*(int *)(ptr + i) = msg_bld_masks_22[i/4];
break;
}
- ENCODE_RSP_AND_SEND(8 + ssid_range - 1);
+ encode_rsp_and_send(8 + ssid_range - 1);
return 0;
}
/* Check for download command */
else if ((cpu_is_msm8x60() || chk_apps_master()) && (*buf == 0x3A)) {
/* send response back */
driver->apps_rsp_buf[0] = *buf;
- ENCODE_RSP_AND_SEND(0);
+ encode_rsp_and_send(0);
msleep(5000);
/* call download API */
msm_set_restart_mode(RESTART_DLOAD);
@@ -1567,7 +908,7 @@
for (i = 0; i < 13; i++)
driver->apps_rsp_buf[i+3] = 0;
- ENCODE_RSP_AND_SEND(15);
+ encode_rsp_and_send(15);
return 0;
}
}
@@ -1578,7 +919,7 @@
for (i = 0; i < 55; i++)
driver->apps_rsp_buf[i] = 0;
- ENCODE_RSP_AND_SEND(54);
+ encode_rsp_and_send(54);
return 0;
}
/* respond to 0x7c command */
@@ -1591,12 +932,12 @@
chk_config_get_id();
*(unsigned char *)(driver->apps_rsp_buf + 12) = '\0';
*(unsigned char *)(driver->apps_rsp_buf + 13) = '\0';
- ENCODE_RSP_AND_SEND(13);
+ encode_rsp_and_send(13);
return 0;
}
}
#endif
- return packet_type;
+ return packet_type;
}
#ifdef CONFIG_DIAG_OVER_USB
@@ -1611,7 +952,7 @@
driver->apps_rsp_buf[0] = 0x13; /* error code 13 */
for (i = 0; i < index; i++)
driver->apps_rsp_buf[i+1] = *(driver->hdlc_buf+i);
- ENCODE_RSP_AND_SEND(index - 3);
+ encode_rsp_and_send(index - 3);
}
#else
static inline void diag_send_error_rsp(int index) {}
@@ -1994,27 +1335,6 @@
driver->use_device_tree = has_device_tree();
mutex_init(&driver->diag_cntl_mutex);
- if (driver->event_mask == NULL) {
- driver->event_mask = kzalloc(sizeof(
- struct diag_ctrl_event_mask), GFP_KERNEL);
- if (driver->event_mask == NULL)
- goto err;
- kmemleak_not_leak(driver->event_mask);
- }
- if (driver->msg_mask == NULL) {
- driver->msg_mask = kzalloc(sizeof(
- struct diag_ctrl_msg_mask), GFP_KERNEL);
- if (driver->msg_mask == NULL)
- goto err;
- kmemleak_not_leak(driver->msg_mask);
- }
- if (driver->log_mask == NULL) {
- driver->log_mask = kzalloc(sizeof(
- struct diag_ctrl_log_mask), GFP_KERNEL);
- if (driver->log_mask == NULL)
- goto err;
- kmemleak_not_leak(driver->log_mask);
- }
if (driver->buf_in_1 == NULL) {
driver->buf_in_1 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
if (driver->buf_in_1 == NULL)
@@ -2051,28 +1371,6 @@
goto err;
kmemleak_not_leak(driver->buf_in_wcnss_2);
}
-
- if (driver->buf_msg_mask_update == NULL) {
- driver->buf_msg_mask_update = kzalloc(APPS_BUF_SIZE,
- GFP_KERNEL);
- if (driver->buf_msg_mask_update == NULL)
- goto err;
- kmemleak_not_leak(driver->buf_msg_mask_update);
- }
- if (driver->buf_log_mask_update == NULL) {
- driver->buf_log_mask_update = kzalloc(APPS_BUF_SIZE,
- GFP_KERNEL);
- if (driver->buf_log_mask_update == NULL)
- goto err;
- kmemleak_not_leak(driver->buf_log_mask_update);
- }
- if (driver->buf_event_mask_update == NULL) {
- driver->buf_event_mask_update = kzalloc(APPS_BUF_SIZE,
- GFP_KERNEL);
- if (driver->buf_event_mask_update == NULL)
- goto err;
- kmemleak_not_leak(driver->buf_event_mask_update);
- }
if (driver->usb_buf_out == NULL &&
(driver->usb_buf_out = kzalloc(USB_MAX_OUT_BUF,
GFP_KERNEL)) == NULL)
@@ -2087,23 +1385,6 @@
if (driver->user_space_data == NULL)
goto err;
kmemleak_not_leak(driver->user_space_data);
- if (driver->msg_masks == NULL
- && (driver->msg_masks = kzalloc(MSG_MASK_SIZE,
- GFP_KERNEL)) == NULL)
- goto err;
- kmemleak_not_leak(driver->msg_masks);
- diag_create_msg_mask_table();
- diag_event_num_bytes = 0;
- if (driver->log_masks == NULL &&
- (driver->log_masks = kzalloc(LOG_MASK_SIZE, GFP_KERNEL)) == NULL)
- goto err;
- kmemleak_not_leak(driver->log_masks);
- driver->log_masks_length = (sizeof(struct mask_info))*MAX_EQUIP_ID;
- if (driver->event_masks == NULL &&
- (driver->event_masks = kzalloc(EVENT_MASK_SIZE,
- GFP_KERNEL)) == NULL)
- goto err;
- kmemleak_not_leak(driver->event_masks);
if (driver->client_map == NULL &&
(driver->client_map = kzalloc
((driver->num_clients) * sizeof(struct diag_client_map),
@@ -2192,12 +1473,6 @@
#ifdef CONFIG_DIAG_OVER_USB
INIT_WORK(&(driver->diag_proc_hdlc_work), diag_process_hdlc_fn);
INIT_WORK(&(driver->diag_read_work), diag_read_work_fn);
- INIT_WORK(&(driver->diag_modem_mask_update_work),
- diag_modem_mask_update_fn);
- INIT_WORK(&(driver->diag_lpass_mask_update_work),
- diag_lpass_mask_update_fn);
- INIT_WORK(&(driver->diag_wcnss_mask_update_work),
- diag_wcnss_mask_update_fn);
driver->legacy_ch = usb_diag_open(DIAG_LEGACY, driver,
diag_usb_legacy_notifier);
if (IS_ERR(driver->legacy_ch)) {
@@ -2210,40 +1485,34 @@
return;
err:
- pr_err("diag: Could not initialize diag buffers");
- kfree(driver->event_mask);
- kfree(driver->log_mask);
- kfree(driver->msg_mask);
- kfree(driver->buf_in_1);
- kfree(driver->buf_in_2);
- kfree(driver->buf_in_lpass_1);
- kfree(driver->buf_in_lpass_2);
- kfree(driver->buf_in_wcnss_1);
- kfree(driver->buf_in_wcnss_2);
- kfree(driver->buf_msg_mask_update);
- kfree(driver->buf_log_mask_update);
- kfree(driver->buf_event_mask_update);
- kfree(driver->usb_buf_out);
- kfree(driver->hdlc_buf);
- kfree(driver->msg_masks);
- kfree(driver->log_masks);
- kfree(driver->event_masks);
- kfree(driver->client_map);
- kfree(driver->buf_tbl);
- kfree(driver->data_ready);
- kfree(driver->table);
- kfree(driver->pkt_buf);
- kfree(driver->write_ptr_1);
- kfree(driver->write_ptr_2);
- kfree(driver->write_ptr_lpass_1);
- kfree(driver->write_ptr_lpass_2);
- kfree(driver->write_ptr_wcnss_1);
- kfree(driver->write_ptr_wcnss_2);
- kfree(driver->usb_read_ptr);
- kfree(driver->apps_rsp_buf);
- kfree(driver->user_space_data);
- if (driver->diag_wq)
- destroy_workqueue(driver->diag_wq);
+ pr_err("diag: Could not initialize diag buffers");
+ kfree(driver->buf_in_1);
+ kfree(driver->buf_in_2);
+ kfree(driver->buf_in_lpass_1);
+ kfree(driver->buf_in_lpass_2);
+ kfree(driver->buf_in_wcnss_1);
+ kfree(driver->buf_in_wcnss_2);
+ kfree(driver->buf_msg_mask_update);
+ kfree(driver->buf_log_mask_update);
+ kfree(driver->buf_event_mask_update);
+ kfree(driver->usb_buf_out);
+ kfree(driver->hdlc_buf);
+ kfree(driver->client_map);
+ kfree(driver->buf_tbl);
+ kfree(driver->data_ready);
+ kfree(driver->table);
+ kfree(driver->pkt_buf);
+ kfree(driver->write_ptr_1);
+ kfree(driver->write_ptr_2);
+ kfree(driver->write_ptr_lpass_1);
+ kfree(driver->write_ptr_lpass_2);
+ kfree(driver->write_ptr_wcnss_1);
+ kfree(driver->write_ptr_wcnss_2);
+ kfree(driver->usb_read_ptr);
+ kfree(driver->apps_rsp_buf);
+ kfree(driver->user_space_data);
+ if (driver->diag_wq)
+ destroy_workqueue(driver->diag_wq);
}
void diagfwd_exit(void)
@@ -2262,9 +1531,6 @@
platform_driver_unregister(&msm_smd_ch1_driver);
platform_driver_unregister(&msm_diag_dci_driver);
platform_driver_unregister(&diag_smd_lite_driver);
- kfree(driver->event_mask);
- kfree(driver->log_mask);
- kfree(driver->msg_mask);
kfree(driver->buf_in_1);
kfree(driver->buf_in_2);
kfree(driver->buf_in_lpass_1);
@@ -2276,9 +1542,6 @@
kfree(driver->buf_event_mask_update);
kfree(driver->usb_buf_out);
kfree(driver->hdlc_buf);
- kfree(driver->msg_masks);
- kfree(driver->log_masks);
- kfree(driver->event_masks);
kfree(driver->client_map);
kfree(driver->buf_tbl);
kfree(driver->data_ready);
diff --git a/drivers/char/diag/diagfwd.h b/drivers/char/diag/diagfwd.h
index cf7fda6..a0631d6 100644
--- a/drivers/char/diag/diagfwd.h
+++ b/drivers/char/diag/diagfwd.h
@@ -16,6 +16,9 @@
#define NO_PROCESS 0
#define NON_APPS_PROC -1
+#define CHK_OVERFLOW(bufStart, start, end, length) \
+ ((((bufStart) <= (start)) && ((end) - (start) >= (length))) ? 1 : 0)
+
void diagfwd_init(void);
void diagfwd_exit(void);
void diag_process_hdlc(void *data, unsigned len);
@@ -31,11 +34,9 @@
int chk_apps_only(void);
int chk_apps_master(void);
int chk_polling_response(void);
-void diag_send_event_mask_update(smd_channel_t *, int num_bytes);
-void diag_send_msg_mask_update(smd_channel_t *, int ssid_first,
- int ssid_last, int proc);
-void diag_send_log_mask_update(smd_channel_t *, int);
+void diag_update_userspace_clients(unsigned int type);
void diag_update_sleeping_process(int process_id, int data_type);
+void encode_rsp_and_send(int buf_length);
/* State for diag forwarding */
#ifdef CONFIG_DIAG_OVER_USB
int diagfwd_connect(void);
@@ -43,6 +44,5 @@
#endif
extern int diag_debug_buf_idx;
extern unsigned char diag_debug_buf[1024];
-extern int diag_event_num_bytes;
extern struct platform_driver msm_diag_dci_driver;
#endif
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 3bbd3fb..4848a1d 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -17,9 +17,6 @@
#include "diagchar.h"
#include "diagfwd.h"
#include "diagfwd_cntl.h"
-#ifdef CONFIG_DEBUG_FS
-#include <linux/debugfs.h>
-#endif
/* tracks which peripheral is undergoing SSR */
static uint16_t reg_dirty;
#define HDR_SIZ 8
@@ -365,291 +362,3 @@
kfree(driver->buf_in_lpass_cntl);
kfree(driver->buf_in_wcnss_cntl);
}
-
-#ifdef CONFIG_DEBUG_FS
-#define DEBUG_BUF_SIZE 4096
-static struct dentry *diag_dbgfs_dent;
-static int diag_dbgfs_table_index;
-
-static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
- size_t count, loff_t *ppos)
-{
- char *buf;
- int ret;
-
- buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
- if (!buf) {
- pr_err("diag: %s, Error allocating memory\n", __func__);
- return -ENOMEM;
- }
-
- ret = scnprintf(buf, DEBUG_BUF_SIZE,
- "modem ch: 0x%x\n"
- "lpass ch: 0x%x\n"
- "riva ch: 0x%x\n"
- "dci ch: 0x%x\n"
- "modem cntl_ch: 0x%x\n"
- "lpass cntl_ch: 0x%x\n"
- "riva cntl_ch: 0x%x\n"
- "CPU Tools id: %d\n"
- "Apps only: %d\n"
- "Apps master: %d\n"
- "Check Polling Response: %d\n"
- "polling_reg_flag: %d\n"
- "uses device tree: %d\n"
- "in_busy_1: %d\n"
- "in_busy_2: %d\n"
- "in_busy_lpass_1: %d\n"
- "in_busy_lpass_2: %d\n"
- "in_busy_wcnss_1: %d\n"
- "in_busy_wcnss_2: %d\n"
- "in_busy_dci: %d\n"
- "logging_mode: %d\n",
- (unsigned int)driver->ch,
- (unsigned int)driver->chlpass,
- (unsigned int)driver->ch_wcnss,
- (unsigned int)driver->ch_dci,
- (unsigned int)driver->ch_cntl,
- (unsigned int)driver->chlpass_cntl,
- (unsigned int)driver->ch_wcnss_cntl,
- chk_config_get_id(),
- chk_apps_only(),
- chk_apps_master(),
- chk_polling_response(),
- driver->polling_reg_flag,
- driver->use_device_tree,
- driver->in_busy_1,
- driver->in_busy_2,
- driver->in_busy_lpass_1,
- driver->in_busy_lpass_2,
- driver->in_busy_wcnss_1,
- driver->in_busy_wcnss_2,
- driver->in_busy_dci,
- driver->logging_mode);
-
-#ifdef CONFIG_DIAG_OVER_USB
- ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
- "usb_connected: %d\n",
- driver->usb_connected);
-#endif
- ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
-
- kfree(buf);
- return ret;
-}
-
-static ssize_t diag_dbgfs_read_workpending(struct file *file,
- char __user *ubuf, size_t count, loff_t *ppos)
-{
- char *buf;
- int ret;
-
- buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
- if (!buf) {
- pr_err("diag: %s, Error allocating memory\n", __func__);
- return -ENOMEM;
- }
-
- ret = scnprintf(buf, DEBUG_BUF_SIZE,
- "Pending status for work_stucts:\n"
- "diag_drain_work: %d\n"
- "diag_read_smd_work: %d\n"
- "diag_read_smd_cntl_work: %d\n"
- "diag_read_smd_lpass_work: %d\n"
- "diag_read_smd_lpass_cntl_work: %d\n"
- "diag_read_smd_wcnss_work: %d\n"
- "diag_read_smd_wcnss_cntl_work: %d\n"
- "diag_modem_mask_update_work: %d\n"
- "diag_lpass_mask_update_work: %d\n"
- "diag_wcnss_mask_update_work: %d\n"
- "diag_read_smd_dci_work: %d\n",
- work_pending(&(driver->diag_drain_work)),
- work_pending(&(driver->diag_read_smd_work)),
- work_pending(&(driver->diag_read_smd_cntl_work)),
- work_pending(&(driver->diag_read_smd_lpass_work)),
- work_pending(&(driver->diag_read_smd_lpass_cntl_work)),
- work_pending(&(driver->diag_read_smd_wcnss_work)),
- work_pending(&(driver->diag_read_smd_wcnss_cntl_work)),
- work_pending(&(driver->diag_modem_mask_update_work)),
- work_pending(&(driver->diag_lpass_mask_update_work)),
- work_pending(&(driver->diag_wcnss_mask_update_work)),
- work_pending(&(driver->diag_read_smd_dci_work)));
-
-#ifdef CONFIG_DIAG_OVER_USB
- ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
- "diag_proc_hdlc_work: %d\n"
- "diag_read_work: %d\n",
- work_pending(&(driver->diag_proc_hdlc_work)),
- work_pending(&(driver->diag_read_work)));
-#endif
- ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
-
- kfree(buf);
- return ret;
-}
-
-static ssize_t diag_dbgfs_read_table(struct file *file, char __user *ubuf,
- size_t count, loff_t *ppos)
-{
- char *buf;
- int ret = 0;
- int i;
- int bytes_remaining;
- int bytes_in_buffer = 0;
- int bytes_written;
- int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
-
- if (diag_dbgfs_table_index >= diag_max_reg) {
- /* Done. Reset to prepare for future requests */
- diag_dbgfs_table_index = 0;
- return 0;
- }
-
- buf = kzalloc(sizeof(char) * buf_size, GFP_KERNEL);
- if (!buf) {
- pr_err("diag: %s, Error allocating memory\n", __func__);
- return -ENOMEM;
- }
-
- bytes_remaining = buf_size;
- for (i = diag_dbgfs_table_index; i < diag_max_reg; i++) {
- /* Do not process empty entries in the table */
- if (driver->table[i].process_id == 0)
- continue;
-
- bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
- "i: %3d, cmd_code: %4x, subsys_id: %4x, "
- "client: %2d, cmd_code_lo: %4x, "
- "cmd_code_hi: %4x, process_id: %5d\n",
- i,
- driver->table[i].cmd_code,
- driver->table[i].subsys_id,
- driver->table[i].client_id,
- driver->table[i].cmd_code_lo,
- driver->table[i].cmd_code_hi,
- driver->table[i].process_id);
-
- bytes_in_buffer += bytes_written;
-
- /* Check if there is room to add another table entry */
- bytes_remaining = buf_size - bytes_in_buffer;
- if (bytes_remaining < bytes_written)
- break;
- }
- diag_dbgfs_table_index = i;
-
- *ppos = 0;
- ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
-
- kfree(buf);
- return ret;
-}
-
-#ifdef CONFIG_DIAG_BRIDGE_CODE
-static ssize_t diag_dbgfs_read_hsic(struct file *file, char __user *ubuf,
- size_t count, loff_t *ppos)
-{
- char *buf;
- int ret;
-
- buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
- if (!buf) {
- pr_err("diag: %s, Error allocating memory\n", __func__);
- return -ENOMEM;
- }
-
- ret = scnprintf(buf, DEBUG_BUF_SIZE,
- "hsic ch: %d\n"
- "hsic_inited: %d\n"
- "hsic enabled: %d\n"
- "hsic_opened: %d\n"
- "hsic_suspend: %d\n"
- "in_busy_hsic_read_on_device: %d\n"
- "in_busy_hsic_write: %d\n"
- "count_hsic_pool: %d\n"
- "count_hsic_write_pool: %d\n"
- "diag_hsic_pool: %x\n"
- "diag_hsic_write_pool: %x\n"
- "write_len_mdm: %d\n"
- "num_hsic_buf_tbl_entries: %d\n"
- "usb_mdm_connected: %d\n"
- "diag_read_mdm_work: %d\n"
- "diag_read_hsic_work: %d\n"
- "diag_disconnect_work: %d\n"
- "diag_usb_read_complete_work: %d\n",
- driver->hsic_ch,
- driver->hsic_inited,
- driver->hsic_device_enabled,
- driver->hsic_device_opened,
- driver->hsic_suspend,
- driver->in_busy_hsic_read_on_device,
- driver->in_busy_hsic_write,
- driver->count_hsic_pool,
- driver->count_hsic_write_pool,
- (unsigned int)driver->diag_hsic_pool,
- (unsigned int)driver->diag_hsic_write_pool,
- driver->write_len_mdm,
- driver->num_hsic_buf_tbl_entries,
- driver->usb_mdm_connected,
- work_pending(&(driver->diag_read_mdm_work)),
- work_pending(&(driver->diag_read_hsic_work)),
- work_pending(&(driver->diag_disconnect_work)),
- work_pending(&(driver->diag_usb_read_complete_work)));
-
- ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
-
- kfree(buf);
- return ret;
-}
-
-const struct file_operations diag_dbgfs_hsic_ops = {
- .read = diag_dbgfs_read_hsic,
-};
-#endif
-
-const struct file_operations diag_dbgfs_status_ops = {
- .read = diag_dbgfs_read_status,
-};
-
-const struct file_operations diag_dbgfs_table_ops = {
- .read = diag_dbgfs_read_table,
-};
-
-const struct file_operations diag_dbgfs_workpending_ops = {
- .read = diag_dbgfs_read_workpending,
-};
-
-void diag_debugfs_init(void)
-{
- diag_dbgfs_dent = debugfs_create_dir("diag", 0);
- if (IS_ERR(diag_dbgfs_dent))
- return;
-
- debugfs_create_file("status", 0444, diag_dbgfs_dent, 0,
- &diag_dbgfs_status_ops);
-
- debugfs_create_file("table", 0444, diag_dbgfs_dent, 0,
- &diag_dbgfs_table_ops);
-
- debugfs_create_file("work_pending", 0444, diag_dbgfs_dent, 0,
- &diag_dbgfs_workpending_ops);
-
-#ifdef CONFIG_DIAG_BRIDGE_CODE
- debugfs_create_file("hsic", 0444, diag_dbgfs_dent, 0,
- &diag_dbgfs_hsic_ops);
-#endif
-
- diag_dbgfs_table_index = 0;
-}
-
-void diag_debugfs_cleanup(void)
-{
- if (diag_dbgfs_dent) {
- debugfs_remove_recursive(diag_dbgfs_dent);
- diag_dbgfs_dent = NULL;
- }
-}
-#else
-void diag_debugfs_init(void) { }
-void diag_debugfs_cleanup(void) { }
-#endif
diff --git a/drivers/char/diag/diagfwd_cntl.h b/drivers/char/diag/diagfwd_cntl.h
index e6f5352..8a0ec3f 100644
--- a/drivers/char/diag/diagfwd_cntl.h
+++ b/drivers/char/diag/diagfwd_cntl.h
@@ -88,7 +88,5 @@
void diag_clean_modem_reg_fn(struct work_struct *);
void diag_clean_lpass_reg_fn(struct work_struct *);
void diag_clean_wcnss_reg_fn(struct work_struct *);
-void diag_debugfs_init(void);
-void diag_debugfs_cleanup(void);
#endif
diff --git a/drivers/gpu/msm/a3xx_reg.h b/drivers/gpu/msm/a3xx_reg.h
index 05c7967..6a010a9 100644
--- a/drivers/gpu/msm/a3xx_reg.h
+++ b/drivers/gpu/msm/a3xx_reg.h
@@ -65,13 +65,17 @@
#define A3XX_RBBM_INT_CLEAR_CMD 0x061
#define A3XX_RBBM_INT_0_MASK 0x063
#define A3XX_RBBM_INT_0_STATUS 0x064
+#define A3XX_RBBM_PERFCTR_CTL 0x80
#define A3XX_RBBM_GPU_BUSY_MASKED 0x88
+#define A3XX_RBBM_PERFCTR_SP_7_LO 0xE0
+#define A3XX_RBBM_PERFCTR_SP_7_HI 0xE1
#define A3XX_RBBM_RBBM_CTL 0x100
#define A3XX_RBBM_RBBM_CTL 0x100
#define A3XX_RBBM_PERFCTR_PWR_1_LO 0x0EC
#define A3XX_RBBM_PERFCTR_PWR_1_HI 0x0ED
#define A3XX_RBBM_DEBUG_BUS_CTL 0x111
#define A3XX_RBBM_DEBUG_BUS_DATA_STATUS 0x112
+
/* Following two are same as on A2XX, just in a different place */
#define A3XX_CP_PFP_UCODE_ADDR 0x1C9
#define A3XX_CP_PFP_UCODE_DATA 0x1CA
@@ -160,6 +164,7 @@
#define A3XX_VPC_VPC_DEBUG_RAM_READ 0xE62
#define A3XX_UCHE_CACHE_MODE_CONTROL_REG 0xE82
#define A3XX_UCHE_CACHE_INVALIDATE0_REG 0xEA0
+#define A3XX_SP_PERFCOUNTER7_SELECT 0xECB
#define A3XX_GRAS_CL_CLIP_CNTL 0x2040
#define A3XX_GRAS_CL_GB_CLIP_ADJ 0x2044
#define A3XX_GRAS_CL_VPORT_XOFFSET 0x2048
@@ -528,4 +533,7 @@
/* RBBM_CLOCK_CTL default value */
#define A3XX_RBBM_CLOCK_CTL_DEFAULT 0xBFFFFFFF
+/* COUNTABLE FOR SP PERFCOUNTER */
+#define SP_FS_FULL_ALU_INSTRUCTIONS 0x0E
+
#endif
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index cf7f3ce..e0d40be 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -127,6 +127,8 @@
REG_CP_IB1_BUFSZ,
REG_CP_IB2_BASE,
REG_CP_IB2_BUFSZ,
+ 0,
+ 0
};
const unsigned int hang_detect_regs_count = ARRAY_SIZE(hang_detect_regs);
@@ -1233,6 +1235,12 @@
*/
hang_detect_regs[0] = adreno_dev->gpudev->reg_rbbm_status;
+ /* Add A3XX specific registers for hang detection */
+ if (adreno_is_a3xx(adreno_dev)) {
+ hang_detect_regs[6] = A3XX_RBBM_PERFCTR_SP_7_LO;
+ hang_detect_regs[7] = A3XX_RBBM_PERFCTR_SP_7_HI;
+ }
+
status = kgsl_mmu_start(device);
if (status)
goto error_clk_off;
@@ -2156,6 +2164,10 @@
return 0;
for (i = 0; i < hang_detect_regs_count; i++) {
+
+ if (hang_detect_regs[i] == 0)
+ continue;
+
adreno_regread(device, hang_detect_regs[i],
&curr_reg_val[i]);
if (curr_reg_val[i] != prev_reg_val[i]) {
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index 2388fff..8de2c70 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1749,9 +1749,6 @@
if (status & (CP_INT_CNTL__IB1_INT_MASK | CP_INT_CNTL__RB_INT_MASK)) {
queue_work(device->work_queue, &device->ts_expired_ws);
wake_up_interruptible_all(&device->wait_queue);
- atomic_notifier_call_chain(&(device->ts_notifier_list),
- device->id,
- NULL);
}
}
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 7bf928f..104baf8 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -2587,9 +2587,6 @@
/* Schedule work to free mem and issue ibs */
queue_work(device->work_queue, &device->ts_expired_ws);
-
- atomic_notifier_call_chain(&device->ts_notifier_list,
- device->id, NULL);
}
#define A3XX_IRQ_CALLBACK(_c) { .func = _c }
@@ -2836,6 +2833,17 @@
adreno_regwrite(device, A3XX_RB_GMEM_BASE_ADDR,
(unsigned int)(adreno_dev->ocmem_base >> 14));
}
+
+ /* Turn on performance counters */
+ adreno_regwrite(device, A3XX_RBBM_PERFCTR_CTL, 0x01);
+
+ /*
+ * Set SP perfcounter 7 to count SP_FS_FULL_ALU_INSTRUCTIONS
+ * we will use this to augment our hang detection
+ */
+
+ adreno_regwrite(device, A3XX_SP_PERFCOUNTER7_SELECT,
+ SP_FS_FULL_ALU_INSTRUCTIONS);
}
/* Defined in adreno_a3xx_snapshot.c */
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 1ff219b..0dd140b 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -503,7 +503,7 @@
* support, we must use the global timestamp since issueibcmds
* will be returning that one.
*/
- if (context->flags & CTXT_FLAGS_PER_CONTEXT_TS)
+ if (context && context->flags & CTXT_FLAGS_PER_CONTEXT_TS)
context_id = context->id;
/* reserve space to temporarily turn off protected mode
@@ -518,7 +518,7 @@
total_sizedwords += 7;
total_sizedwords += 2; /* scratchpad ts for recovery */
- if (context->flags & CTXT_FLAGS_PER_CONTEXT_TS) {
+ if (context && context->flags & CTXT_FLAGS_PER_CONTEXT_TS) {
total_sizedwords += 3; /* sop timestamp */
total_sizedwords += 4; /* eop timestamp */
total_sizedwords += 3; /* global timestamp without cache
@@ -591,7 +591,7 @@
GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x00);
}
- if (context->flags & CTXT_FLAGS_PER_CONTEXT_TS) {
+ if (context && context->flags & CTXT_FLAGS_PER_CONTEXT_TS) {
/* start-of-pipeline timestamp */
GSL_RB_WRITE(ringcmds, rcmd_gpu,
cp_type3_packet(CP_MEM_WRITE, 2));
@@ -902,6 +902,7 @@
unsigned int i;
struct adreno_context *drawctxt;
unsigned int start_index = 0;
+ int ret;
if (device->state & KGSL_STATE_HUNG)
return -EBUSY;
@@ -948,9 +949,15 @@
if (unlikely(adreno_dev->ib_check_level >= 1 &&
!_parse_ibs(dev_priv, ibdesc[i].gpuaddr,
ibdesc[i].sizedwords))) {
- kfree(link);
- return -EINVAL;
+ ret = -EINVAL;
+ goto done;
}
+
+ if (ibdesc[i].sizedwords == 0) {
+ ret = -EINVAL;
+ goto done;
+ }
+
*cmds++ = CP_HDR_INDIRECT_BUFFER_PFD;
*cmds++ = ibdesc[i].gpuaddr;
*cmds++ = ibdesc[i].sizedwords;
@@ -972,7 +979,6 @@
KGSL_CMD_INFO(device, "<%d:0x%x> g %08x numibs %d\n",
context->id, *timestamp, (unsigned int)ibdesc, numibs);
- kfree(link);
#ifdef CONFIG_MSM_KGSL_CFF_DUMP
/*
@@ -982,13 +988,16 @@
*/
adreno_idle(device);
#endif
+
/* If context hung and recovered then return error so that the
* application may handle it */
- if (drawctxt->flags & CTXT_FLAGS_GPU_HANG_RECOVERED)
- return -EDEADLK;
- else
- return 0;
+ ret = (drawctxt->flags & CTXT_FLAGS_GPU_HANG_RECOVERED) ?
+ -EDEADLK : 0;
+
+done:
+ kfree(link);
+ return ret;
}
static int _find_start_of_cmd_seq(struct adreno_ringbuffer *rb,
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index ccc6119..664d519 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -507,24 +507,6 @@
return ret;
}
-int kgsl_register_ts_notifier(struct kgsl_device *device,
- struct notifier_block *nb)
-{
- BUG_ON(device == NULL);
- return atomic_notifier_chain_register(&device->ts_notifier_list,
- nb);
-}
-EXPORT_SYMBOL(kgsl_register_ts_notifier);
-
-int kgsl_unregister_ts_notifier(struct kgsl_device *device,
- struct notifier_block *nb)
-{
- BUG_ON(device == NULL);
- return atomic_notifier_chain_unregister(&device->ts_notifier_list,
- nb);
-}
-EXPORT_SYMBOL(kgsl_unregister_ts_notifier);
-
int kgsl_check_timestamp(struct kgsl_device *device,
struct kgsl_context *context, unsigned int timestamp)
{
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 2ca3a4f..dc597f5 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -155,7 +155,6 @@
struct kgsl_pwrctrl pwrctrl;
int open_count;
- struct atomic_notifier_head ts_notifier_list;
struct mutex mutex;
uint32_t state;
uint32_t requested_state;
@@ -210,7 +209,6 @@
.hwaccess_gate = COMPLETION_INITIALIZER((_dev).hwaccess_gate),\
.suspend_gate = COMPLETION_INITIALIZER((_dev).suspend_gate),\
.recovery_gate = COMPLETION_INITIALIZER((_dev).recovery_gate),\
- .ts_notifier_list = ATOMIC_NOTIFIER_INIT((_dev).ts_notifier_list),\
.idle_check_ws = __WORK_INITIALIZER((_dev).idle_check_ws,\
kgsl_idle_check),\
.ts_expired_ws = __WORK_INITIALIZER((_dev).ts_expired_ws,\
@@ -374,12 +372,6 @@
int kgsl_check_timestamp(struct kgsl_device *device,
struct kgsl_context *context, unsigned int timestamp);
-int kgsl_register_ts_notifier(struct kgsl_device *device,
- struct notifier_block *nb);
-
-int kgsl_unregister_ts_notifier(struct kgsl_device *device,
- struct notifier_block *nb);
-
int kgsl_device_platform_probe(struct kgsl_device *device);
void kgsl_device_platform_remove(struct kgsl_device *device);
diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h
index 81ab3fb..bba06bc 100644
--- a/drivers/gpu/msm/kgsl_trace.h
+++ b/drivers/gpu/msm/kgsl_trace.h
@@ -315,16 +315,18 @@
TP_STRUCT__entry(
__field(unsigned int, gpuaddr)
__field(unsigned int, size)
+ __field(unsigned int, tgid)
),
TP_fast_assign(
__entry->gpuaddr = mem_entry->memdesc.gpuaddr;
__entry->size = mem_entry->memdesc.size;
+ __entry->tgid = mem_entry->priv->pid;
),
TP_printk(
- "gpuaddr=0x%08x size=%d",
- __entry->gpuaddr, __entry->size
+ "gpuaddr=0x%08x size=%d tgid=%d",
+ __entry->gpuaddr, __entry->size, __entry->tgid
)
);
@@ -339,6 +341,7 @@
__field(unsigned int, size)
__field(int, fd)
__field(int, type)
+ __field(unsigned int, tgid)
),
TP_fast_assign(
@@ -346,12 +349,13 @@
__entry->size = mem_entry->memdesc.size;
__entry->fd = fd;
__entry->type = mem_entry->memtype;
+ __entry->tgid = mem_entry->priv->pid;
),
TP_printk(
- "gpuaddr=0x%08x size=%d type=%d fd=%d",
+ "gpuaddr=0x%08x size=%d type=%d fd=%d tgid=%d",
__entry->gpuaddr, __entry->size,
- __entry->type, __entry->fd
+ __entry->type, __entry->fd, __entry->tgid
)
);
@@ -366,17 +370,20 @@
__field(unsigned int, size)
__field(int, type)
__field(int, fd)
+ __field(unsigned int, tgid)
),
TP_fast_assign(
__entry->gpuaddr = mem_entry->memdesc.gpuaddr;
__entry->size = mem_entry->memdesc.size;
__entry->type = mem_entry->memtype;
+ __entry->tgid = mem_entry->priv->pid;
),
TP_printk(
- "gpuaddr=0x%08x size=%d type=%d",
- __entry->gpuaddr, __entry->size, __entry->type
+ "gpuaddr=0x%08x size=%d type=%d tgid=%d",
+ __entry->gpuaddr, __entry->size, __entry->type,
+ __entry->tgid
)
);
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index 8ddc991..712bc60 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -212,10 +212,6 @@
queue_work(device->work_queue, &device->ts_expired_ws);
wake_up_interruptible(&device->wait_queue);
-
- atomic_notifier_call_chain(
- &(device->ts_notifier_list),
- device->id, NULL);
}
}
diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c
index 9f64cec..775e95d 100644
--- a/drivers/input/misc/pmic8xxx-pwrkey.c
+++ b/drivers/input/misc/pmic8xxx-pwrkey.c
@@ -178,10 +178,22 @@
pwrkey->key_press_irq = key_press_irq;
pwrkey->key_release_irq = key_release_irq;
pwrkey->pwr = pwr;
- pwrkey->press = false;
platform_set_drvdata(pdev, pwrkey);
+ /* check power key status during boot */
+ err = pm8xxx_read_irq_stat(pdev->dev.parent, key_press_irq);
+ if (err < 0) {
+ dev_err(&pdev->dev, "reading irq status failed\n");
+ goto unreg_input_dev;
+ }
+ pwrkey->press = !!err;
+
+ if (pwrkey->press) {
+ input_report_key(pwrkey->pwr, KEY_POWER, 1);
+ input_sync(pwrkey->pwr);
+ }
+
err = request_any_context_irq(key_press_irq, pwrkey_press_irq,
IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_press", pwrkey);
if (err < 0) {
diff --git a/drivers/iommu/msm_iommu-v2.c b/drivers/iommu/msm_iommu-v2.c
index c7f6b82..f49d009 100644
--- a/drivers/iommu/msm_iommu-v2.c
+++ b/drivers/iommu/msm_iommu-v2.c
@@ -169,8 +169,10 @@
mb();
}
-static void __program_iommu(void __iomem *base, int smt_size)
+static void __program_iommu(void __iomem *base, int smt_size,
+ struct msm_iommu_bfb_settings *bfb_settings)
{
+ int i;
__reset_iommu(base, smt_size);
SET_CR0_SMCFCFG(base, 1);
@@ -181,6 +183,12 @@
SET_CR0_GFIE(base, 1);
SET_CR0_GFRE(base, 1);
SET_CR0_CLIENTPD(base, 0);
+
+ if (bfb_settings)
+ for (i = 0; i < bfb_settings->length; i++)
+ SET_GLOBAL_REG(base, bfb_settings->regs[i],
+ bfb_settings->data[i]);
+
mb(); /* Make sure writes complete before returning */
}
@@ -200,6 +208,17 @@
mb();
}
+static void __release_smg(void __iomem *base, int ctx, int smt_size)
+{
+ int i;
+
+ /* Invalidate any SMGs associated with this context */
+ for (i = 0; i < smt_size; i++)
+ if (GET_SMR_VALID(base, i) &&
+ GET_S2CR_CBNDX(base, i) == ctx)
+ SET_SMR_VALID(base, i, 0);
+}
+
static void __program_context(void __iomem *base, int ctx, int ncb,
phys_addr_t pgtable, int redirect,
u32 *sids, int len, int smt_size)
@@ -416,7 +435,8 @@
}
if (!msm_iommu_ctx_attached(dev->parent))
- __program_iommu(iommu_drvdata->base, iommu_drvdata->nsmr);
+ __program_iommu(iommu_drvdata->base, iommu_drvdata->nsmr,
+ iommu_drvdata->bfb_settings);
__program_context(iommu_drvdata->base, ctx_drvdata->num,
iommu_drvdata->ncb, __pa(priv->pt.fl_table),
@@ -458,6 +478,9 @@
GET_CB_CONTEXTIDR_ASID(iommu_drvdata->base, ctx_drvdata->num));
__reset_context(iommu_drvdata->base, ctx_drvdata->num);
+ __release_smg(iommu_drvdata->base, ctx_drvdata->num,
+ iommu_drvdata->nsmr);
+
__disable_clocks(iommu_drvdata);
regulator_disable(iommu_drvdata->gdsc);
diff --git a/drivers/iommu/msm_iommu_dev-v2.c b/drivers/iommu/msm_iommu_dev-v2.c
index 8c26f95..237d601 100644
--- a/drivers/iommu/msm_iommu_dev-v2.c
+++ b/drivers/iommu/msm_iommu_dev-v2.c
@@ -29,6 +29,66 @@
#include <mach/iommu_hw-v2.h>
#include <mach/iommu.h>
+static int msm_iommu_parse_bfb_settings(struct platform_device *pdev,
+ struct msm_iommu_drvdata *drvdata)
+{
+ struct msm_iommu_bfb_settings *bfb_settings;
+ u32 nreg, nval;
+ int ret, i;
+
+ /*
+ * It is not valid for a device to have the qcom,iommu-bfb-regs
+ * property but not the qcom,iommu-bfb-data property, and vice versa.
+ */
+ if (!of_get_property(pdev->dev.of_node, "qcom,iommu-bfb-regs", &nreg)) {
+ if (of_get_property(pdev->dev.of_node, "qcom,iommu-bfb-data",
+ &nval))
+ return -EINVAL;
+ return 0;
+ }
+
+ if (!of_get_property(pdev->dev.of_node, "qcom,iommu-bfb-data", &nval))
+ return -EINVAL;
+
+ if (nreg >= sizeof(bfb_settings->regs))
+ return -EINVAL;
+
+ if (nval >= sizeof(bfb_settings->data))
+ return -EINVAL;
+
+ if (nval != nreg)
+ return -EINVAL;
+
+ bfb_settings = devm_kzalloc(&pdev->dev, sizeof(*bfb_settings),
+ GFP_KERNEL);
+ if (!bfb_settings)
+ return -ENOMEM;
+
+ ret = of_property_read_u32_array(pdev->dev.of_node,
+ "qcom,iommu-bfb-regs",
+ bfb_settings->regs,
+ nreg / sizeof(*bfb_settings->regs));
+ if (ret)
+ return ret;
+
+ ret = of_property_read_u32_array(pdev->dev.of_node,
+ "qcom,iommu-bfb-data",
+ bfb_settings->data,
+ nval / sizeof(*bfb_settings->data));
+ if (ret)
+ return ret;
+
+ bfb_settings->length = nreg / sizeof(*bfb_settings->regs);
+
+ for (i = 0; i < bfb_settings->length; i++)
+ if (bfb_settings->regs[i] < IMPLDEF_OFFSET ||
+ bfb_settings->regs[i] >= IMPLDEF_OFFSET + IMPLDEF_LENGTH)
+ return -EINVAL;
+
+ drvdata->bfb_settings = bfb_settings;
+ return 0;
+}
+
static int msm_iommu_parse_dt(struct platform_device *pdev,
struct msm_iommu_drvdata *drvdata)
{
@@ -40,6 +100,10 @@
if (ret)
goto fail;
+ ret = msm_iommu_parse_bfb_settings(pdev, drvdata);
+ if (ret)
+ goto fail;
+
ret = of_property_read_u32(pdev->dev.of_node, "qcom,iommu-smt-size",
&nsmr);
if (ret)
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 2d9296c..17303dd 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -210,11 +210,13 @@
int dirty;
int node_type;
struct timeval timestamp;
+ uint32_t frame_id;
};
struct msm_cam_timestamp {
uint8_t present;
struct timeval timestamp;
+ uint32_t frame_id;
};
struct msm_cam_buf_map_info {
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index a3c7243..2919d23 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -434,7 +434,11 @@
D("%s Copying timestamp as %ld.%ld", __func__,
cam_ts->timestamp.tv_sec, cam_ts->timestamp.tv_usec);
buf->vidbuf.v4l2_buf.timestamp = cam_ts->timestamp;
+ buf->vidbuf.v4l2_buf.sequence = cam_ts->frame_id;
}
+ D("%s Notify user about buffer %d image_mode %d frame_id %d", __func__,
+ buf->vidbuf.v4l2_buf.index, pcam_inst->image_mode,
+ buf->vidbuf.v4l2_buf.sequence);
vb2_buffer_done(&buf->vidbuf, VB2_BUF_STATE_DONE);
return 0;
}
@@ -821,6 +825,7 @@
__func__, pcam_inst, frame->ch_paddr[0], ret_frame->dirty);
cam_ts.present = 1;
cam_ts.timestamp = ret_frame->timestamp;
+ cam_ts.frame_id = ret_frame->frame_id;
if (ret_frame->dirty)
/* the frame is dirty, not going to disptach to app */
rc = msm_mctl_release_free_buf(pmctl, pcam_inst, frame);
diff --git a/drivers/media/video/msm/msm_mctl_pp.c b/drivers/media/video/msm/msm_mctl_pp.c
index a114b37..105426e 100644
--- a/drivers/media/video/msm/msm_mctl_pp.c
+++ b/drivers/media/video/msm/msm_mctl_pp.c
@@ -636,6 +636,9 @@
ret_frame.dirty = dirty;
ret_frame.node_type = 0;
ret_frame.timestamp = frame.timestamp;
+ ret_frame.frame_id = frame.frame_id;
+ D("%s frame_id: %d buffer idx %d\n", __func__,
+ frame.frame_id, frame.buf_idx);
rc = msm_mctl_buf_done_pp(p_mctl, &buf_handle, &buf, &ret_frame);
return rc;
}
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.c b/drivers/media/video/msm/vfe/msm_vfe32.c
index 6e22388..db0db36 100644
--- a/drivers/media/video/msm/vfe/msm_vfe32.c
+++ b/drivers/media/video/msm/vfe/msm_vfe32.c
@@ -587,6 +587,25 @@
atomic_set(&share_ctrl->handle_common_irq, 1);
}
+static void axi_clear_all_interrupts(struct vfe_share_ctrl_t *share_ctrl)
+{
+ atomic_set(&share_ctrl->handle_common_irq, 0);
+ msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+ share_ctrl->vfebase + VFE_IRQ_MASK_0);
+ msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+ share_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+ /* clear all pending interrupts*/
+ msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+ share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+ msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+ share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+ /* Ensure the write order while writing
+ *to the command register using the barrier */
+ msm_camera_io_w_mb(1,
+ share_ctrl->vfebase + VFE_IRQ_CMD);
+}
+
static void axi_disable_irq(struct vfe_share_ctrl_t *share_ctrl,
uint32_t mode)
{
@@ -632,24 +651,6 @@
msm_camera_io_w(irq_mask, share_ctrl->vfebase +
VFE_IRQ_MASK_0);
}
- /*Dont Disable for concurrent*/
- if (share_ctrl->axi_ref_cnt == 1) {
- atomic_set(&share_ctrl->handle_common_irq, 0);
- msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
- share_ctrl->vfebase + VFE_IRQ_MASK_0);
- msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
- share_ctrl->vfebase + VFE_IRQ_MASK_1);
-
- /* clear all pending interrupts*/
- msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
- share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
- msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
- share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
- /* Ensure the write order while writing
- *to the command register using the barrier */
- msm_camera_io_w_mb(1,
- share_ctrl->vfebase + VFE_IRQ_CMD);
- }
}
static void vfe32_stop(struct vfe32_ctrl_type *vfe32_ctrl)
@@ -5554,6 +5555,8 @@
axi_ctrl->share_ctrl->axi_ref_cnt--;
if (axi_ctrl->share_ctrl->axi_ref_cnt > 0)
return;
+
+ axi_clear_all_interrupts(axi_ctrl->share_ctrl);
axi_ctrl->share_ctrl->dual_enabled = 0;
disable_irq(axi_ctrl->vfeirq->start);
tasklet_kill(&axi_ctrl->vfe32_tasklet);
diff --git a/drivers/media/video/msm_wfd/enc-mfc-subdev.c b/drivers/media/video/msm_wfd/enc-mfc-subdev.c
index 3292d78..09a5e32 100644
--- a/drivers/media/video/msm_wfd/enc-mfc-subdev.c
+++ b/drivers/media/video/msm_wfd/enc-mfc-subdev.c
@@ -2199,7 +2199,7 @@
if (rc)
WFD_MSG_ERR("Failed to free recon buffer\n");
- if (IS_ERR_OR_NULL(
+ if (!IS_ERR_OR_NULL(
client_ctx->recon_buffer_ion_handle[i])) {
if (!inst->secure) {
ion_unmap_iommu(
diff --git a/drivers/media/video/vcap_v4l2.c b/drivers/media/video/vcap_v4l2.c
index 7ac78cb..753171c 100644
--- a/drivers/media/video/vcap_v4l2.c
+++ b/drivers/media/video/vcap_v4l2.c
@@ -1957,8 +1957,10 @@
/* init video device*/
vfd = video_device_alloc();
- if (!vfd)
+ if (!vfd) {
+ ret = -ENOMEM;
goto deinit_vc;
+ }
*vfd = vcap_template;
vfd->v4l2_dev = &dev->v4l2_dev;
@@ -1972,6 +1974,7 @@
dev->vcap_wq = create_workqueue("vcap");
if (!dev->vcap_wq) {
+ ret = -ENOMEM;
pr_err("Could not create workqueue");
goto rel_vdev;
}
@@ -1979,6 +1982,8 @@
dev->ion_client = msm_ion_client_create(-1, "vcap");
if (IS_ERR((void *)dev->ion_client)) {
pr_err("could not get ion client");
+ ret = PTR_ERR(dev->ion_client);
+ dev->ion_client = NULL;
goto rel_vcap_wq;
}
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 4840e64..bc8eccf 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -142,7 +142,6 @@
static DEFINE_MUTEX(pil_access_lock);
static DEFINE_MUTEX(qsee_bw_mutex);
-static DEFINE_MUTEX(qsee_sfpb_bw_mutex);
static DEFINE_MUTEX(app_access_lock);
static int qsee_bw_count;
@@ -1198,28 +1197,41 @@
case CLK_DFAB:
mutex_lock(&qsee_bw_mutex);
if (!qsee_bw_count) {
- ret = msm_bus_scale_client_update_request(
- qsee_perf_client, 1);
+ if (qsee_sfpb_bw_count > 0)
+ ret = msm_bus_scale_client_update_request(
+ qsee_perf_client, 3);
+ else
+ ret = msm_bus_scale_client_update_request(
+ qsee_perf_client, 1);
if (ret)
pr_err("DFAB Bandwidth req failed (%d)\n",
ret);
else
qsee_bw_count++;
+ } else {
+ qsee_bw_count++;
}
mutex_unlock(&qsee_bw_mutex);
break;
case CLK_SFPB:
- mutex_lock(&qsee_sfpb_bw_mutex);
+ mutex_lock(&qsee_bw_mutex);
if (!qsee_sfpb_bw_count) {
- ret = msm_bus_scale_client_update_request(
- qsee_perf_client, 2);
+ if (qsee_bw_count > 0)
+ ret = msm_bus_scale_client_update_request(
+ qsee_perf_client, 3);
+ else
+ ret = msm_bus_scale_client_update_request(
+ qsee_perf_client, 2);
+
if (ret)
pr_err("SFPB Bandwidth req failed (%d)\n",
ret);
else
qsee_sfpb_bw_count++;
+ } else {
+ qsee_sfpb_bw_count++;
}
- mutex_unlock(&qsee_sfpb_bw_mutex);
+ mutex_unlock(&qsee_bw_mutex);
break;
default:
pr_err("Clock type not defined\n");
@@ -1238,29 +1250,44 @@
switch (clk_type) {
case CLK_DFAB:
mutex_lock(&qsee_bw_mutex);
- if (qsee_bw_count > 0) {
- if (qsee_bw_count-- == 1) {
+ if (qsee_bw_count == 0) {
+ pr_err("Client error.Extra call to disable DFAB clk\n");
+ mutex_unlock(&qsee_bw_mutex);
+ return;
+ }
+
+ if ((qsee_bw_count > 0) && (qsee_bw_count-- == 1)) {
+ if (qsee_sfpb_bw_count > 0)
+ ret = msm_bus_scale_client_update_request(
+ qsee_perf_client, 2);
+ else
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 0);
- if (ret)
- pr_err("SFPB Bandwidth req fail (%d)\n",
+ if (ret)
+ pr_err("SFPB Bandwidth req fail (%d)\n",
ret);
- }
}
mutex_unlock(&qsee_bw_mutex);
break;
case CLK_SFPB:
- mutex_lock(&qsee_sfpb_bw_mutex);
- if (qsee_sfpb_bw_count > 0) {
- if (qsee_sfpb_bw_count-- == 1) {
+ mutex_lock(&qsee_bw_mutex);
+ if (qsee_sfpb_bw_count == 0) {
+ pr_err("Client error.Extra call to disable SFPB clk\n");
+ mutex_unlock(&qsee_bw_mutex);
+ return;
+ }
+ if ((qsee_sfpb_bw_count > 0) && (qsee_sfpb_bw_count-- == 1)) {
+ if (qsee_bw_count > 0)
+ ret = msm_bus_scale_client_update_request(
+ qsee_perf_client, 1);
+ else
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 0);
- if (ret)
- pr_err("SFPB Bandwidth req fail (%d)\n",
+ if (ret)
+ pr_err("SFPB Bandwidth req fail (%d)\n",
ret);
- }
}
- mutex_unlock(&qsee_sfpb_bw_mutex);
+ mutex_unlock(&qsee_bw_mutex);
break;
default:
pr_err("Clock type not defined\n");
@@ -1697,7 +1724,6 @@
mutex_unlock(&pil_access_lock);
}
kfree(data);
- qsee_disable_clock_vote(CLK_DFAB);
return ret;
}
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 7e144ed..595bc5d 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1779,6 +1779,7 @@
msmsdcc_irq(int irq, void *dev_id)
{
struct msmsdcc_host *host = dev_id;
+ struct mmc_host *mmc = host->mmc;
u32 status;
int ret = 0;
int timer = 0;
@@ -1820,6 +1821,12 @@
*/
wake_lock(&host->sdio_wlock);
} else {
+ if (!mmc->card || !mmc_card_sdio(mmc->card)) {
+ WARN(1, "%s: SDCC core interrupt received for non-SDIO cards when SDCC clocks are off\n",
+ mmc_hostname(mmc));
+ ret = 1;
+ break;
+ }
spin_unlock(&host->lock);
mmc_signal_sdio_irq(host->mmc);
spin_lock(&host->lock);
@@ -1848,6 +1855,12 @@
#endif
if (status & MCI_SDIOINTROPE) {
+ if (!mmc->card || mmc_card_sdio(mmc->card)) {
+ WARN(1, "%s: SDIO interrupt received for non-SDIO card\n",
+ mmc_hostname(mmc));
+ ret = 1;
+ break;
+ }
if (host->sdcc_suspending)
wake_lock(&host->sdio_suspend_wlock);
spin_unlock(&host->lock);
@@ -2826,6 +2839,14 @@
msmsdcc_set_vdd_io_vol(host, VDD_IO_LOW, 0);
msmsdcc_update_io_pad_pwr_switch(host);
msmsdcc_setup_pins(host, false);
+ /*
+ * Reset the mask to prevent hitting any pending interrupts
+ * after powering up the card again.
+ */
+ if (atomic_read(&host->clks_on)) {
+ writel_relaxed(0, host->base + MMCIMASK0);
+ mb();
+ }
break;
case MMC_POWER_UP:
/* writing PWR_UP bit is redundant */
diff --git a/drivers/net/ethernet/msm/msm_rmnet.c b/drivers/net/ethernet/msm/msm_rmnet.c
index 61df241..41ad8af 100644
--- a/drivers/net/ethernet/msm/msm_rmnet.c
+++ b/drivers/net/ethernet/msm/msm_rmnet.c
@@ -501,16 +501,10 @@
static int __rmnet_close(struct net_device *dev)
{
struct rmnet_private *p = netdev_priv(dev);
- int rc;
- unsigned long flags;
- if (p->ch) {
- rc = smd_close(p->ch);
- spin_lock_irqsave(&p->lock, flags);
- p->ch = 0;
- spin_unlock_irqrestore(&p->lock, flags);
- return rc;
- } else
+ if (p->ch)
+ return 0;
+ else
return -EBADF;
}
@@ -529,12 +523,9 @@
static int rmnet_stop(struct net_device *dev)
{
- struct rmnet_private *p = netdev_priv(dev);
-
DBG0("[%s] rmnet_stop()\n", dev->name);
netif_stop_queue(dev);
- tasklet_kill(&p->tsklt);
/* TODO: unload modem safely,
currently, this causes unnecessary unloads */
diff --git a/drivers/thermal/msm8974-tsens.c b/drivers/thermal/msm8974-tsens.c
index 7169dc0..77cc1f9 100644
--- a/drivers/thermal/msm8974-tsens.c
+++ b/drivers/thermal/msm8974-tsens.c
@@ -10,6 +10,9 @@
* GNU General Public License for more details.
*
*/
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/thermal.h>
@@ -743,8 +746,7 @@
IORESOURCE_MEM, "tsens_physical");
if (!tmdev->res_tsens_mem) {
pr_err("Could not get tsens physical address resource\n");
- rc = -EINVAL;
- goto fail_free_irq;
+ return -EINVAL;
}
tmdev->tsens_len = tmdev->res_tsens_mem->end -
@@ -754,8 +756,7 @@
tmdev->tsens_len, tmdev->res_tsens_mem->name);
if (!res_mem) {
pr_err("Request tsens physical memory region failed\n");
- rc = -EINVAL;
- goto fail_free_irq;
+ return -EINVAL;
}
tmdev->tsens_addr = ioremap(res_mem->start, tmdev->tsens_len);
@@ -805,9 +806,6 @@
if (tmdev->res_tsens_mem)
release_mem_region(tmdev->res_tsens_mem->start,
tmdev->tsens_len);
-fail_free_irq:
- free_irq(tmdev->tsens_irq, tmdev);
-
return rc;
}
@@ -827,8 +825,10 @@
tmdev->pdev = pdev;
rc = tsens_calib_sensors();
- if (rc < 0)
+ if (rc < 0) {
+ pr_err("Calibration failed\n");
goto fail;
+ }
tsens_hw_init();
@@ -848,8 +848,7 @@
if (tmdev->res_tsens_mem)
release_mem_region(tmdev->res_tsens_mem->start,
tmdev->tsens_len);
- free_irq(tmdev->tsens_irq, tmdev);
- kfree(tmdev);
+ tmdev = NULL;
return rc;
}
@@ -930,7 +929,6 @@
tmdev->tsens_len);
free_irq(tmdev->tsens_irq, tmdev);
platform_set_drvdata(pdev, NULL);
- kfree(tmdev);
return 0;
}
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index b8b7f68..0ace679 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -2661,6 +2661,7 @@
mEp->desc = NULL;
mEp->ep.desc = NULL;
+ mEp->ep.maxpacket = USHRT_MAX;
spin_unlock_irqrestore(mEp->lock, flags);
return retval;
@@ -3135,7 +3136,8 @@
mEp->ep.name = mEp->name;
mEp->ep.ops = &usb_ep_ops;
- mEp->ep.maxpacket = CTRL_PAYLOAD_MAX;
+ mEp->ep.maxpacket =
+ k ? USHRT_MAX : CTRL_PAYLOAD_MAX;
INIT_LIST_HEAD(&mEp->qh.queue);
spin_unlock_irqrestore(udc->lock, flags);
diff --git a/drivers/usb/gadget/f_rmnet_smd.c b/drivers/usb/gadget/f_rmnet_smd.c
index b71f646..5e2c6ed 100644
--- a/drivers/usb/gadget/f_rmnet_smd.c
+++ b/drivers/usb/gadget/f_rmnet_smd.c
@@ -907,13 +907,14 @@
* Register platform driver to be notified in case SMD channels
* later becomes ready to be opened.
*/
- ret = platform_driver_register(&dev->pdrv);
- if (ret)
- ERROR(cdev, "Platform driver %s register failed %d\n",
- dev->pdrv.driver.name, ret);
- else
- dev->is_pdrv_used = 1;
-
+ if (!dev->is_pdrv_used) {
+ ret = platform_driver_register(&dev->pdrv);
+ if (ret)
+ ERROR(cdev, "pdrv %s register failed %d\n",
+ dev->pdrv.driver.name, ret);
+ else
+ dev->is_pdrv_used = 1;
+ }
return;
}
wait_event(dev->smd_ctl.wait, test_bit(CH_OPENED,
diff --git a/drivers/usb/otg/msm72k_otg.c b/drivers/usb/otg/msm72k_otg.c
index f62ae76..ca1b155 100644
--- a/drivers/usb/otg/msm72k_otg.c
+++ b/drivers/usb/otg/msm72k_otg.c
@@ -1229,7 +1229,7 @@
static irqreturn_t msm_otg_irq(int irq, void *data)
{
struct msm_otg *dev = data;
- u32 otgsc, sts, pc, sts_mask;
+ u32 otgsc, sts, pc;
irqreturn_t ret = IRQ_HANDLED;
int work = 0;
enum usb_otg_state state;
@@ -1250,12 +1250,16 @@
otgsc = readl(USB_OTGSC);
sts = readl(USB_USBSTS);
- sts_mask = (otgsc & OTGSC_INTR_MASK) >> 8;
-
- if (!((otgsc & sts_mask) || (sts & STS_PCI))) {
+ /* At times during USB disconnect, hardware generates 1MSIS interrupt
+ * during PHY reset, which leads to irq not handled error as IRQ_NONE
+ * is notified. To workaround this issue, check for all the
+ * OTG_INTR_STS_MASK bits and if set, clear them and notify IRQ_HANDLED.
+ */
+ if (!((otgsc & OTGSC_INTR_STS_MASK) || (sts & STS_PCI))) {
ret = IRQ_NONE;
goto out;
}
+ writel_relaxed(otgsc, USB_OTGSC);
spin_lock_irqsave(&dev->lock, flags);
state = dev->phy.state;
@@ -1277,10 +1281,8 @@
set_bit(A_BUS_REQ, &dev->inputs);
clear_bit(ID, &dev->inputs);
}
- writel(otgsc, USB_OTGSC);
work = 1;
} else if (otgsc & OTGSC_BSVIS) {
- writel(otgsc, USB_OTGSC);
/* BSV interrupt comes when operating as an A-device
* (VBUS on/off).
* But, handle BSV when charger is removed from ACA in ID_A
@@ -1298,7 +1300,6 @@
work = 1;
} else if (otgsc & OTGSC_DPIS) {
pr_debug("DPIS detected\n");
- writel(otgsc, USB_OTGSC);
set_bit(A_SRP_DET, &dev->inputs);
set_bit(A_BUS_REQ, &dev->inputs);
work = 1;
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 60018bf..813fc94 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -77,6 +77,11 @@
USB_PHY_REG_LPM_OFF,
};
+static char *override_phy_init;
+module_param(override_phy_init, charp, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(override_phy_init,
+ "Override HSUSB PHY Init Settings");
+
static DECLARE_COMPLETION(pmic_vbus_init);
static struct msm_otg *the_msm_otg;
static bool debug_aca_enabled;
@@ -384,12 +389,26 @@
static void ulpi_init(struct msm_otg *motg)
{
struct msm_otg_platform_data *pdata = motg->pdata;
- int *seq = pdata->phy_init_seq;
+ int aseq[10];
+ int *seq = NULL;
+
+ if (override_phy_init) {
+ pr_debug("%s(): HUSB PHY Init:%s\n", __func__,
+ override_phy_init);
+ get_options(override_phy_init, ARRAY_SIZE(aseq), aseq);
+ seq = &aseq[1];
+ } else {
+ seq = pdata->phy_init_seq;
+ }
if (!seq)
return;
while (seq[0] >= 0) {
+ if (override_phy_init)
+ pr_debug("ulpi: write 0x%02x to 0x%02x\n",
+ seq[0], seq[1]);
+
dev_vdbg(motg->phy.dev, "ulpi: write 0x%02x to 0x%02x\n",
seq[0], seq[1]);
ulpi_write(&motg->phy, seq[0], seq[1]);
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index 54d7090..ed4c25d 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -820,14 +820,6 @@
---help---
Support for DVI mode for MSM HDMI 1080p Panel
-config FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
- depends on FB_MSM_HDMI_MSM_PANEL
- bool "Use HDCP mode"
- default y
- ---help---
- Support for HDCP mode for MSM HDMI 1080p Panel
- Choose to enable HDCP
-
config FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
depends on FB_MSM_HDMI_MSM_PANEL
bool "Enable CEC"
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 3b1610a..deef4ab 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -69,12 +69,7 @@
static void hdmi_msm_dump_regs(const char *prefix);
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
static void hdmi_msm_hdcp_enable(void);
-#else
-static inline void hdmi_msm_hdcp_enable(void) {}
-#endif
-
static void hdmi_msm_turn_on(void);
static int hdmi_msm_audio_off(void);
static int hdmi_msm_read_edid(void);
@@ -678,7 +673,6 @@
case 0x00D8: return "ACR_48_1";
case 0x00E4: return "AUDIO_INFO0";
case 0x00E8: return "AUDIO_INFO1";
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
case 0x0110: return "HDCP_CTRL";
case 0x0114: return "HDCP_DEBUG_CTRL";
case 0x0118: return "HDCP_INT_CTRL";
@@ -693,7 +687,6 @@
case 0x014C: return "HDCP_RCVPORT_DATA5";
case 0x0150: return "HDCP_RCVPORT_DATA6";
case 0x0168: return "HDCP_RCVPORT_DATA12";
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
case 0x01D0: return "AUDIO_CFG";
case 0x0208: return "USEC_REFTIMER";
case 0x020C: return "DDC_CTRL";
@@ -708,14 +701,10 @@
case 0x0250: return "HPD_INT_STATUS";
case 0x0254: return "HPD_INT_CTRL";
case 0x0258: return "HPD_CTRL";
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
case 0x025C: return "HDCP_ENTROPY_CTRL1";
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
case 0x027C: return "DDC_REF";
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
case 0x0284: return "HDCP_SW_UPPER_AKSV";
case 0x0288: return "HDCP_SW_LOWER_AKSV";
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
case 0x02B4: return "ACTIVE_H";
case 0x02B8: return "ACTIVE_V";
case 0x02BC: return "ACTIVE_V_F2";
@@ -784,7 +773,7 @@
DEV_INFO("HDMI HPD: CONNECTED: send ONLINE\n");
kobject_uevent(external_common_state->uevent_kobj, KOBJ_ONLINE);
- if (!external_common_state->present_hdcp) {
+ if (!hdmi_msm_state->hdcp_enable) {
/* Send Audio for HDMI Compliance Cases*/
envp[0] = "HDCP_STATE=PASS";
envp[1] = NULL;
@@ -873,10 +862,13 @@
}
#endif
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
static void hdcp_deauthenticate(void);
static void hdmi_msm_hdcp_reauth_work(struct work_struct *work)
{
+ if (!hdmi_msm_state->hdcp_enable) {
+ DEV_DBG("%s: HDCP not enabled\n", __func__);
+ return;
+ }
/* Don't process recursive actions */
mutex_lock(&hdmi_msm_state_mutex);
@@ -894,17 +886,20 @@
* Therefore, as surprising as it may sound do reauth
* only if the device is HDCP-capable
*/
- if (external_common_state->present_hdcp) {
- hdcp_deauthenticate();
- mutex_lock(&hdcp_auth_state_mutex);
- hdmi_msm_state->reauth = TRUE;
- mutex_unlock(&hdcp_auth_state_mutex);
- mod_timer(&hdmi_msm_state->hdcp_timer, jiffies + HZ/2);
- }
+ hdcp_deauthenticate();
+ mutex_lock(&hdcp_auth_state_mutex);
+ hdmi_msm_state->reauth = TRUE;
+ mutex_unlock(&hdcp_auth_state_mutex);
+ mod_timer(&hdmi_msm_state->hdcp_timer, jiffies + HZ/2);
}
static void hdmi_msm_hdcp_work(struct work_struct *work)
{
+ if (!hdmi_msm_state->hdcp_enable) {
+ DEV_DBG("%s: HDCP not enabled\n", __func__);
+ return;
+ }
+
/* Only re-enable if cable still connected */
mutex_lock(&external_common_state_hpd_mutex);
if (external_common_state->hpd_state &&
@@ -925,7 +920,111 @@
hdmi_msm_state->reauth = FALSE;
}
}
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+
+int hdmi_msm_process_hdcp_interrupts(void)
+{
+ int rc = -1;
+ uint32 hdcp_int_val;
+ char *envp[2];
+
+ if (!hdmi_msm_state->hdcp_enable) {
+ DEV_DBG("%s: HDCP not enabled\n", __func__);
+ return -EINVAL;
+ }
+
+ /* HDCP_INT_CTRL[0x0118]
+ * [0] AUTH_SUCCESS_INT [R] HDCP Authentication Success
+ * interrupt status
+ * [1] AUTH_SUCCESS_ACK [W] Acknowledge bit for HDCP
+ * Authentication Success bit - write 1 to clear
+ * [2] AUTH_SUCCESS_MASK [R/W] Mask bit for HDCP Authentication
+ * Success interrupt - set to 1 to enable interrupt */
+ hdcp_int_val = HDMI_INP_ND(0x0118);
+ if ((hdcp_int_val & (1 << 2)) && (hdcp_int_val & (1 << 0))) {
+ /* AUTH_SUCCESS_INT */
+ HDMI_OUTP(0x0118, (hdcp_int_val | (1 << 1)) & ~(1 << 0));
+ DEV_INFO("HDCP: AUTH_SUCCESS_INT received\n");
+ complete_all(&hdmi_msm_state->hdcp_success_done);
+ return 0;
+ }
+
+ /* [4] AUTH_FAIL_INT [R] HDCP Authentication Lost
+ * interrupt Status
+ * [5] AUTH_FAIL_ACK [W] Acknowledge bit for HDCP
+ * Authentication Lost bit - write 1 to clear
+ * [6] AUTH_FAIL_MASK [R/W] Mask bit fo HDCP Authentication
+ * Lost interrupt set to 1 to enable interrupt
+ * [7] AUTH_FAIL_INFO_ACK [W] Acknowledge bit for HDCP
+ * Authentication Failure Info field - write 1 to clear */
+ if ((hdcp_int_val & (1 << 6)) && (hdcp_int_val & (1 << 4))) {
+ /* AUTH_FAIL_INT */
+ /* Clear and Disable */
+ uint32 link_status = HDMI_INP_ND(0x011C);
+ HDMI_OUTP(0x0118, (hdcp_int_val | (1 << 5))
+ & ~((1 << 6) | (1 << 4)));
+ DEV_INFO("HDCP: AUTH_FAIL_INT received, LINK0_STATUS=0x%08x\n",
+ link_status);
+ if (hdmi_msm_state->full_auth_done) {
+ switch_set_state(&external_common_state->sdev, 0);
+ DEV_INFO("Hdmi state switched to %d: %s\n",
+ external_common_state->sdev.state, __func__);
+
+ envp[0] = "HDCP_STATE=FAIL";
+ envp[1] = NULL;
+ DEV_INFO("HDMI HPD:QDSP OFF\n");
+ kobject_uevent_env(external_common_state->uevent_kobj,
+ KOBJ_CHANGE, envp);
+
+ mutex_lock(&hdcp_auth_state_mutex);
+ hdmi_msm_state->full_auth_done = FALSE;
+ mutex_unlock(&hdcp_auth_state_mutex);
+ /* Calling reauth only when authentication
+ * is sucessful or else we always go into
+ * the reauth loop. Also, No need to reauthenticate
+ * if authentication failed because of cable disconnect
+ */
+ if (((link_status & 0xF0) >> 4) != 0x7) {
+ DEV_DBG("Reauthenticate From %s HDCP FAIL INT ",
+ __func__);
+ queue_work(hdmi_work_queue,
+ &hdmi_msm_state->hdcp_reauth_work);
+ } else {
+ DEV_INFO("HDCP: HDMI cable disconnected\n");
+ }
+ }
+
+ /* Clear AUTH_FAIL_INFO as well */
+ HDMI_OUTP(0x0118, (hdcp_int_val | (1 << 7)));
+ return 0;
+ }
+
+ /* [8] DDC_XFER_REQ_INT [R] HDCP DDC Transfer Request
+ * interrupt status
+ * [9] DDC_XFER_REQ_ACK [W] Acknowledge bit for HDCP DDC
+ * Transfer Request bit - write 1 to clear
+ * [10] DDC_XFER_REQ_MASK [R/W] Mask bit for HDCP DDC Transfer
+ * Request interrupt - set to 1 to enable interrupt */
+ if ((hdcp_int_val & (1 << 10)) && (hdcp_int_val & (1 << 8))) {
+ /* DDC_XFER_REQ_INT */
+ HDMI_OUTP_ND(0x0118, (hdcp_int_val | (1 << 9)) & ~(1 << 8));
+ if (!(hdcp_int_val & (1 << 12)))
+ return 0;
+ }
+ /* [12] DDC_XFER_DONE_INT [R] HDCP DDC Transfer done interrupt
+ * status
+ * [13] DDC_XFER_DONE_ACK [W] Acknowledge bit for HDCP DDC
+ * Transfer done bit - write 1 to clear
+ * [14] DDC_XFER_DONE_MASK [R/W] Mask bit for HDCP DDC Transfer
+ * done interrupt - set to 1 to enable interrupt */
+ if ((hdcp_int_val & (1 << 14)) && (hdcp_int_val & (1 << 12))) {
+ /* DDC_XFER_DONE_INT */
+ HDMI_OUTP_ND(0x0118, (hdcp_int_val | (1 << 13)) & ~(1 << 12));
+ DEV_INFO("HDCP: DDC_XFER_DONE received\n");
+ return 0;
+ }
+
+ return rc;
+}
static irqreturn_t hdmi_msm_isr(int irq, void *dev_id)
{
@@ -936,10 +1035,6 @@
#endif
uint32 ddc_int_ctrl;
uint32 audio_int_val;
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
- uint32 hdcp_int_val;
- char *envp[2];
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
static uint32 fifo_urun_int_occurred;
static uint32 sample_drop_int_occurred;
const uint32 occurrence_limit = 5;
@@ -1057,96 +1152,8 @@
return IRQ_HANDLED;
}
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
- /* HDCP_INT_CTRL[0x0118]
- * [0] AUTH_SUCCESS_INT [R] HDCP Authentication Success
- * interrupt status
- * [1] AUTH_SUCCESS_ACK [W] Acknowledge bit for HDCP
- * Authentication Success bit - write 1 to clear
- * [2] AUTH_SUCCESS_MASK [R/W] Mask bit for HDCP Authentication
- * Success interrupt - set to 1 to enable interrupt */
- hdcp_int_val = HDMI_INP_ND(0x0118);
- if ((hdcp_int_val & (1 << 2)) && (hdcp_int_val & (1 << 0))) {
- /* AUTH_SUCCESS_INT */
- HDMI_OUTP(0x0118, (hdcp_int_val | (1 << 1)) & ~(1 << 0));
- DEV_INFO("HDCP: AUTH_SUCCESS_INT received\n");
- complete_all(&hdmi_msm_state->hdcp_success_done);
+ if (!hdmi_msm_process_hdcp_interrupts())
return IRQ_HANDLED;
- }
- /* [4] AUTH_FAIL_INT [R] HDCP Authentication Lost
- * interrupt Status
- * [5] AUTH_FAIL_ACK [W] Acknowledge bit for HDCP
- * Authentication Lost bit - write 1 to clear
- * [6] AUTH_FAIL_MASK [R/W] Mask bit fo HDCP Authentication
- * Lost interrupt set to 1 to enable interrupt
- * [7] AUTH_FAIL_INFO_ACK [W] Acknowledge bit for HDCP
- * Authentication Failure Info field - write 1 to clear */
- if ((hdcp_int_val & (1 << 6)) && (hdcp_int_val & (1 << 4))) {
- /* AUTH_FAIL_INT */
- /* Clear and Disable */
- uint32 link_status = HDMI_INP_ND(0x011C);
- HDMI_OUTP(0x0118, (hdcp_int_val | (1 << 5))
- & ~((1 << 6) | (1 << 4)));
- DEV_INFO("HDCP: AUTH_FAIL_INT received, LINK0_STATUS=0x%08x\n",
- link_status);
- if (hdmi_msm_state->full_auth_done) {
- switch_set_state(&external_common_state->sdev, 0);
- DEV_INFO("Hdmi state switched to %d: %s\n",
- external_common_state->sdev.state, __func__);
-
- envp[0] = "HDCP_STATE=FAIL";
- envp[1] = NULL;
- DEV_INFO("HDMI HPD:QDSP OFF\n");
- kobject_uevent_env(external_common_state->uevent_kobj,
- KOBJ_CHANGE, envp);
-
- mutex_lock(&hdcp_auth_state_mutex);
- hdmi_msm_state->full_auth_done = FALSE;
- mutex_unlock(&hdcp_auth_state_mutex);
- /* Calling reauth only when authentication
- * is sucessful or else we always go into
- * the reauth loop. Also, No need to reauthenticate
- * if authentication failed because of cable disconnect
- */
- if (((link_status & 0xF0) >> 4) != 0x7) {
- DEV_DBG("Reauthenticate From %s HDCP FAIL INT ",
- __func__);
- queue_work(hdmi_work_queue,
- &hdmi_msm_state->hdcp_reauth_work);
- } else {
- DEV_INFO("HDCP: HDMI cable disconnected\n");
- }
- }
-
- /* Clear AUTH_FAIL_INFO as well */
- HDMI_OUTP(0x0118, (hdcp_int_val | (1 << 7)));
- return IRQ_HANDLED;
- }
- /* [8] DDC_XFER_REQ_INT [R] HDCP DDC Transfer Request
- * interrupt status
- * [9] DDC_XFER_REQ_ACK [W] Acknowledge bit for HDCP DDC
- * Transfer Request bit - write 1 to clear
- * [10] DDC_XFER_REQ_MASK [R/W] Mask bit for HDCP DDC Transfer
- * Request interrupt - set to 1 to enable interrupt */
- if ((hdcp_int_val & (1 << 10)) && (hdcp_int_val & (1 << 8))) {
- /* DDC_XFER_REQ_INT */
- HDMI_OUTP_ND(0x0118, (hdcp_int_val | (1 << 9)) & ~(1 << 8));
- if (!(hdcp_int_val & (1 << 12)))
- return IRQ_HANDLED;
- }
- /* [12] DDC_XFER_DONE_INT [R] HDCP DDC Transfer done interrupt
- * status
- * [13] DDC_XFER_DONE_ACK [W] Acknowledge bit for HDCP DDC
- * Transfer done bit - write 1 to clear
- * [14] DDC_XFER_DONE_MASK [R/W] Mask bit for HDCP DDC Transfer
- * done interrupt - set to 1 to enable interrupt */
- if ((hdcp_int_val & (1 << 14)) && (hdcp_int_val & (1 << 12))) {
- /* DDC_XFER_DONE_INT */
- HDMI_OUTP_ND(0x0118, (hdcp_int_val | (1 << 13)) & ~(1 << 12));
- DEV_INFO("HDCP: DDC_XFER_DONE received\n");
- return IRQ_HANDLED;
- }
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
/* Process CEC Interrupt */
@@ -1305,7 +1312,7 @@
if (external_common_state->hdmi_sink == 0) {
/* HDMI_DVI_SEL */
reg_val |= 0x00000002;
- if (external_common_state->present_hdcp)
+ if (hdmi_msm_state->hdcp_enable)
/* HDMI Encryption */
reg_val |= 0x00000004;
/* HDMI_CTRL */
@@ -1313,7 +1320,7 @@
/* HDMI_DVI_SEL */
reg_val &= ~0x00000002;
} else {
- if (external_common_state->present_hdcp)
+ if (hdmi_msm_state->hdcp_enable)
/* HDMI_Encryption_ON */
reg_val |= 0x00000006;
else
@@ -1393,7 +1400,6 @@
return 0;
}
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
static int hdmi_msm_ddc_write(uint32 dev_addr, uint32 offset,
const uint8 *data_buf, uint32 data_len, const char *what)
{
@@ -1589,7 +1595,6 @@
error:
return status;
}
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
static int hdmi_msm_ddc_read_retry(uint32 dev_addr, uint32 offset,
uint8 *data_buf, uint32 data_len, uint32 request_len, int retry,
@@ -2150,9 +2155,13 @@
return status;
}
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
static void hdcp_auth_info(uint32 auth_info)
{
+ if (!hdmi_msm_state->hdcp_enable) {
+ DEV_DBG("%s: HDCP not enabled\n", __func__);
+ return;
+ }
+
switch (auth_info) {
case 0:
DEV_INFO("%s: None", __func__);
@@ -2187,6 +2196,11 @@
static void hdcp_key_state(uint32 key_state)
{
+ if (!hdmi_msm_state->hdcp_enable) {
+ DEV_DBG("%s: HDCP not enabled\n", __func__);
+ return;
+ }
+
switch (key_state) {
case 0:
DEV_WARN("%s: No HDCP Keys", __func__);
@@ -2230,6 +2244,11 @@
{
int hdcp_link_status = HDMI_INP(0x011C);
+ if (!hdmi_msm_state->hdcp_enable) {
+ DEV_DBG("%s: HDCP not enabled\n", __func__);
+ return;
+ }
+
/* Disable HDCP interrupts */
HDMI_OUTP(0x0118, 0x0);
@@ -2257,6 +2276,11 @@
int failure;
int nack0;
+ if (!hdmi_msm_state->hdcp_enable) {
+ DEV_DBG("%s: HDCP not enabled\n", __func__);
+ return;
+ }
+
/*
* Check for any DDC transfer failures
* 0x0128 HDCP_DDC_STATUS
@@ -2367,6 +2391,11 @@
static uint8 buf[0xFF];
memset(buf, 0, sizeof(buf));
+ if (!hdmi_msm_state->hdcp_enable) {
+ DEV_DBG("%s: HDCP not enabled\n", __func__);
+ return 0;
+ }
+
if (!is_part1_done) {
is_part1_done = TRUE;
@@ -2654,6 +2683,11 @@
int ret;
uint8 buf[4];
+ if (!hdmi_msm_state->hdcp_enable) {
+ DEV_DBG("%s: HDCP not enabled\n", __func__);
+ return 0;
+ }
+
snprintf(what, sizeof(what), "V' H0");
ret = hdmi_msm_ddc_read(0x74, 0x20, buf, 4, 5, what, TRUE);
if (ret) {
@@ -2746,6 +2780,11 @@
boolean ksv_done = FALSE;
+ if (!hdmi_msm_state->hdcp_enable) {
+ DEV_DBG("%s: HDCP not enabled\n", __func__);
+ return 0;
+ }
+
memset(buf, 0, sizeof(buf));
memset(kvs_fifo, 0, sizeof(kvs_fifo));
@@ -2938,6 +2977,12 @@
{
int ret = 0;
int poll = 3000;
+
+ if (!hdmi_msm_state->hdcp_enable) {
+ DEV_DBG("%s: HDCP not enabled\n", __func__);
+ return 0;
+ }
+
while (poll) {
/* 0x011C HDCP_LINK0_STATUS
[30:28] KEYS_STATE = 3 = "Valid"
@@ -2968,7 +3013,7 @@
uint32 found_repeater = 0x0;
char *envp[2];
- if (!hdmi_msm_has_hdcp()) {
+ if (!hdmi_msm_state->hdcp_enable) {
DEV_INFO("%s: HDCP NOT ENABLED\n", __func__);
return;
}
@@ -3069,7 +3114,6 @@
DEV_INFO("Hdmi state switched to %d: %s\n",
external_common_state->sdev.state, __func__);
}
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
static void hdmi_msm_video_setup(int video_format)
{
@@ -3587,11 +3631,9 @@
{
msm_hdmi_sample_rate = rate;
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
- if (hdmi_msm_has_hdcp())
+ if (hdmi_msm_state->hdcp_enable)
hdcp_deauthenticate();
else
-#endif
hdmi_msm_turn_on();
}
EXPORT_SYMBOL(hdmi_msm_audio_sample_rate_reset);
@@ -4161,12 +4203,10 @@
#endif
hdmi_msm_spd_infoframe_packetsetup();
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
- if (hdmi_msm_state->reauth) {
+ if (hdmi_msm_state->hdcp_enable && hdmi_msm_state->reauth) {
hdmi_msm_hdcp_enable();
hdmi_msm_state->reauth = FALSE ;
}
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
/* re-initialize CEC if enabled */
@@ -4211,12 +4251,15 @@
}
}
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
static void hdmi_msm_hdcp_timer(unsigned long data)
{
+ if (!hdmi_msm_state->hdcp_enable) {
+ DEV_DBG("%s: HDCP not enabled\n", __func__);
+ return;
+ }
+
queue_work(hdmi_work_queue, &hdmi_msm_state->hdcp_work);
}
-#endif
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
static void hdmi_msm_cec_read_timer_func(unsigned long data)
@@ -4381,12 +4424,14 @@
mutex_unlock(&external_common_state_hpd_mutex);
hdmi_msm_turn_on();
- /* Kick off HDCP Authentication */
- mutex_lock(&hdcp_auth_state_mutex);
- hdmi_msm_state->reauth = FALSE;
- hdmi_msm_state->full_auth_done = FALSE;
- mutex_unlock(&hdcp_auth_state_mutex);
- mod_timer(&hdmi_msm_state->hdcp_timer, jiffies + HZ/2);
+ if (hdmi_msm_state->hdcp_enable) {
+ /* Kick off HDCP Authentication */
+ mutex_lock(&hdcp_auth_state_mutex);
+ hdmi_msm_state->reauth = FALSE;
+ hdmi_msm_state->full_auth_done = FALSE;
+ mutex_unlock(&hdcp_auth_state_mutex);
+ mod_timer(&hdmi_msm_state->hdcp_timer, jiffies + HZ/2);
+ }
} else
mutex_unlock(&external_common_state_hpd_mutex);
@@ -4410,16 +4455,14 @@
external_common_state->sdev.state, __func__);
if (on) {
hdmi_msm_read_edid();
- if (hdmi_msm_has_hdcp())
- hdmi_msm_state->reauth = FALSE ;
+ hdmi_msm_state->reauth = FALSE ;
/* Build EDID table */
hdmi_msm_turn_on();
DEV_INFO("HDMI HPD: CONNECTED: send ONLINE\n");
kobject_uevent(external_common_state->uevent_kobj,
KOBJ_ONLINE);
- hdmi_msm_hdcp_enable();
envp[0] = 0;
- if (!hdmi_msm_has_hdcp()) {
+ if (!hdmi_msm_state->hdcp_enable) {
/* Send Audio for HDMI Compliance Cases*/
envp[0] = "HDCP_STATE=PASS";
envp[1] = NULL;
@@ -4429,6 +4472,8 @@
switch_set_state(&external_common_state->sdev, 1);
DEV_INFO("Hdmi state switched to %d: %s\n",
external_common_state->sdev.state, __func__);
+ } else {
+ hdmi_msm_hdcp_enable();
}
} else {
DEV_INFO("HDMI HPD: DISCONNECTED: send OFFLINE\n");
@@ -4452,7 +4497,6 @@
if (!hdmi_msm_state->hdmi_app_clk)
return -ENODEV;
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
mutex_lock(&hdmi_msm_state_mutex);
if (hdmi_msm_state->hdcp_activating) {
hdmi_msm_state->panel_power_on = FALSE;
@@ -4461,13 +4505,10 @@
return 0;
}
mutex_unlock(&hdmi_msm_state_mutex);
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
DEV_INFO("power: OFF (audio off, Reset Core)\n");
hdmi_msm_audio_off();
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
hdcp_deauthenticate();
-#endif
hdmi_msm_powerdown_phy();
hdmi_msm_state->panel_power_on = FALSE;
@@ -4479,6 +4520,28 @@
return hdmi_msm_state->is_mhl_enabled;
}
+void hdmi_msm_config_hdcp_feature(void)
+{
+ if (hdcp_feature_on && hdmi_msm_has_hdcp()) {
+ init_timer(&hdmi_msm_state->hdcp_timer);
+ hdmi_msm_state->hdcp_timer.function = hdmi_msm_hdcp_timer;
+ hdmi_msm_state->hdcp_timer.data = (uint32)NULL;
+ hdmi_msm_state->hdcp_timer.expires = 0xffffffffL;
+
+ init_completion(&hdmi_msm_state->hdcp_success_done);
+ INIT_WORK(&hdmi_msm_state->hdcp_reauth_work,
+ hdmi_msm_hdcp_reauth_work);
+ INIT_WORK(&hdmi_msm_state->hdcp_work, hdmi_msm_hdcp_work);
+ hdmi_msm_state->hdcp_enable = TRUE;
+ } else {
+ del_timer(&hdmi_msm_state->hdcp_timer);
+ hdmi_msm_state->hdcp_enable = FALSE;
+ }
+ external_common_state->present_hdcp = hdmi_msm_state->hdcp_enable;
+ DEV_INFO("%s: HDCP Feature: %s\n", __func__,
+ hdmi_msm_state->hdcp_enable ? "Enabled" : "Disabled");
+}
+
static int __devinit hdmi_msm_probe(struct platform_device *pdev)
{
int rc;
@@ -4591,15 +4654,6 @@
hdmi_msm_state->hpd_state_timer.expires = 0xffffffffL;
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
- init_timer(&hdmi_msm_state->hdcp_timer);
- hdmi_msm_state->hdcp_timer.function =
- hdmi_msm_hdcp_timer;
- hdmi_msm_state->hdcp_timer.data = (uint32)NULL;
-
- hdmi_msm_state->hdcp_timer.expires = 0xffffffffL;
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
-
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
init_timer(&hdmi_msm_state->cec_read_timer);
hdmi_msm_state->cec_read_timer.function =
@@ -4626,22 +4680,7 @@
goto error;
}
- if (hdmi_msm_has_hdcp()) {
- /* Don't Set Encryption in case of non HDCP builds */
- external_common_state->present_hdcp = FALSE;
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
- external_common_state->present_hdcp = TRUE;
-#endif
- } else {
- external_common_state->present_hdcp = FALSE;
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
- /*
- * If the device is not hdcp capable do
- * not start hdcp timer.
- */
- del_timer(&hdmi_msm_state->hdcp_timer);
-#endif
- }
+ hdmi_msm_config_hdcp_feature();
/* Initialize hdmi node and register with switch driver */
if (hdmi_prim_display)
@@ -4825,11 +4864,6 @@
hdmi_common_init_panel_info(&hdmi_msm_panel_data.panel_info);
init_completion(&hdmi_msm_state->ddc_sw_done);
INIT_WORK(&hdmi_msm_state->hpd_state_work, hdmi_msm_hpd_state_work);
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
- init_completion(&hdmi_msm_state->hdcp_success_done);
- INIT_WORK(&hdmi_msm_state->hdcp_reauth_work, hdmi_msm_hdcp_reauth_work);
- INIT_WORK(&hdmi_msm_state->hdcp_work, hdmi_msm_hdcp_work);
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
INIT_WORK(&hdmi_msm_state->cec_latch_detect_work,
@@ -4853,9 +4887,6 @@
" RELEASE"
#endif
" AUDIO EDID HPD HDCP"
-#ifndef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
- ":0"
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
" DVI"
#ifndef CONFIG_FB_MSM_HDMI_MSM_PANEL_DVI_SUPPORT
":0"
@@ -4885,6 +4916,15 @@
return rv;
pr_debug("%s: HDCP feature = %d\n", __func__, hdcp_feature_on);
+ if (hdmi_msm_state) {
+ if ((HDMI_INP(0x0250) & 0x2)) {
+ pr_err("%s: Unable to set HDCP feature", __func__);
+ pr_err("%s: HDMI panel is currently turned on",
+ __func__);
+ } else if (hdcp_feature_on != hdmi_msm_state->hdcp_enable) {
+ hdmi_msm_config_hdcp_feature();
+ }
+ }
return 0;
}
diff --git a/drivers/video/msm/hdmi_msm.h b/drivers/video/msm/hdmi_msm.h
index 5d27412..20bd492 100644
--- a/drivers/video/msm/hdmi_msm.h
+++ b/drivers/video/msm/hdmi_msm.h
@@ -64,13 +64,12 @@
struct timer_list hpd_state_timer;
struct completion ddc_sw_done;
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+ bool hdcp_enable;
boolean hdcp_activating;
boolean reauth ;
struct work_struct hdcp_reauth_work, hdcp_work;
struct completion hdcp_success_done;
struct timer_list hdcp_timer;
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
boolean cec_enabled;
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index c36e4b4..6c0d08d 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -184,7 +184,7 @@
base = 0x18000;
break;
case MDP_BLOCK_OVERLAY_2:
- base = (mdp_rev >= MDP_REV_44) ? 0x88000 : 0;
+ base = (mdp_rev >= MDP_REV_43) ? 0x88000 : 0;
break;
default:
break;
@@ -2525,6 +2525,7 @@
#endif
static int contSplash_update_done;
char *cp;
+ unsigned int mdp_r = 0;
if ((pdev->id == 0) && (pdev->num_resources > 0)) {
mdp_init_pdev = pdev;
@@ -2546,6 +2547,15 @@
}
mdp_rev = mdp_pdata->mdp_rev;
+ if (mdp_rev == MDP_REV_42) {
+ mdp_r = inpdw(MDP_BASE + 0x0);
+ mdp_r = ((mdp_r & 0x30000) >> 16);
+ if (mdp_r == 3) {
+ mdp_rev = MDP_REV_43;
+ mdp_pdata->mdp_rev = MDP_REV_43;
+ }
+ }
+
mdp_iommu_split_domain = mdp_pdata->mdp_iommu_split_domain;
rc = mdp_irq_clk_setup(pdev, mdp_pdata->cont_splash_enabled);
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 005e87c..b7d4c32 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -349,7 +349,7 @@
uint32 ov_cnt;
uint32 dmap_cnt;
uint32 dmae_cnt;
- uint32 blt_end;
+ uint32 blt_end; /* used by mddi only */
uint32 blt_ov_koff;
uint32 blt_ov_done;
uint32 blt_dmap_koff;
@@ -543,12 +543,9 @@
void mdp4_overlay0_done_dsi_cmd(int cndx);
void mdp4_primary_rdptr(void);
void mdp4_dsi_cmd_overlay(struct msm_fb_data_type *mfd);
-int mdp4_overlay_commit(struct fb_info *info, int mixer);
-int mdp4_dsi_video_pipe_commit(void);
-int mdp4_dsi_cmd_pipe_commit(void);
+int mdp4_lcdc_pipe_commit(int cndx, int wait);
+int mdp4_dtv_pipe_commit(int cndx, int wait);
int mdp4_dsi_cmd_update_cnt(int cndx);
-int mdp4_lcdc_pipe_commit(void);
-int mdp4_dtv_pipe_commit(void);
void mdp4_dsi_rdptr_init(int cndx);
void mdp4_dsi_vsync_init(int cndx);
void mdp4_lcdc_vsync_init(int cndx);
@@ -577,6 +574,7 @@
int mdp4_overlay_play_wait(struct fb_info *info,
struct msmfb_overlay_data *req);
int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req);
+int mdp4_overlay_commit(struct fb_info *info, int mixer);
struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(int ptype, int mixer);
void mdp4_overlay_dma_commit(int mixer);
void mdp4_overlay_vsync_commit(struct mdp4_overlay_pipe *pipe);
@@ -763,6 +761,8 @@
void mdp4_dsi_video_wait4vsync(int cndx, long long *vtime);
void mdp4_dsi_cmd_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
void mdp4_dsi_video_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
+int mdp4_dsi_video_pipe_commit(int cndx, int wait);
+int mdp4_dsi_cmd_pipe_commit(int cndx, int wait);
void mdp4_dsi_cmd_vsync_ctrl(struct fb_info *info, int enable);
void mdp4_dsi_video_vsync_ctrl(struct fb_info *info, int enable);
#ifdef CONFIG_FB_MSM_MDP303
@@ -812,6 +812,14 @@
struct mdp4_overlay_pipe *pipe)
{
}
+static inline int mdp4_dsi_video_pipe_commit(int cndx, int wait)
+{
+ return 0;
+}
+static inline int mdp4_dsi_cmd_pipe_commit(int cndx, int wait)
+{
+ return 0;
+}
static inline void mdp4_dsi_cmd_vsync_ctrl(struct fb_info *info,
int enable)
{
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index b154a3b..8f308c3 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -1992,7 +1992,8 @@
blend->bg_alpha = 0x0ff - s_pipe->alpha;
blend->fg_alpha = s_pipe->alpha;
blend->co3_sel = 1; /* use fg alpha */
-
+ pr_debug("%s: bg alpha %d, fg alpha %d\n",
+ __func__, blend->bg_alpha, blend->fg_alpha);
if (s_pipe->is_fg) {
if (s_pipe->alpha == 0xff) {
blend->solidfill = 1;
@@ -2008,10 +2009,9 @@
MDP4_BLEND_FG_ALPHA_FG_PIXEL;
else
blend->fg_alpha = 0xff;
+ blend->op |= MDP4_BLEND_BG_INV_ALPHA;
} else
blend->op = MDP4_BLEND_BG_ALPHA_FG_CONST;
-
- blend->op |= MDP4_BLEND_BG_INV_ALPHA;
} else if (d_alpha) {
ptype = mdp4_overlay_format2type(s_pipe->src_format);
if (ptype == OVERLAY_TYPE_VIDEO) {
@@ -3464,8 +3464,7 @@
if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
/* cndx = 0 */
mdp4_dsi_cmd_pipe_queue(0, pipe);
- }
- if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
+ } else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
/* cndx = 0 */
mdp4_dsi_video_pipe_queue(0, pipe);
} else if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
@@ -3527,6 +3526,46 @@
return ret;
}
+int mdp4_overlay_commit(struct fb_info *info, int mixer)
+{
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+ if (mfd == NULL)
+ return -ENODEV;
+
+ if (!mfd->panel_power_on) /* suspended */
+ return -EINVAL;
+
+ if (mixer >= MDP4_MIXER_MAX)
+ return -EPERM;
+
+ mutex_lock(&mfd->dma->ov_mutex);
+
+ mdp4_overlay_mdp_perf_upd(mfd, 1);
+
+ if (mixer == MDP4_MIXER0) {
+ if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
+ /* cndx = 0 */
+ mdp4_dsi_cmd_pipe_commit(0, 1);
+ } else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
+ /* cndx = 0 */
+ mdp4_dsi_video_pipe_commit(0, 1);
+ } else if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
+ /* cndx = 0 */
+ mdp4_lcdc_pipe_commit(0, 1);
+ }
+ } else if (mixer == MDP4_MIXER1) {
+ if (ctrl->panel_mode & MDP4_PANEL_DTV)
+ mdp4_dtv_pipe_commit(0, 1);
+ }
+
+ mdp4_overlay_mdp_perf_upd(mfd, 0);
+
+ mutex_unlock(&mfd->dma->ov_mutex);
+
+ return 0;
+}
+
struct msm_iommu_ctx {
char *name;
int domain;
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index 488f2af..6fb9dc4 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -250,7 +250,7 @@
static void mdp4_dsi_cmd_blt_ov_update(struct mdp4_overlay_pipe *pipe);
-int mdp4_dsi_cmd_pipe_commit(void)
+int mdp4_dsi_cmd_pipe_commit(int cndx, int wait)
{
int i, undx;
int mixer = 0;
@@ -377,6 +377,12 @@
mdp4_stat.overlay_commit[pipe->mixer_num]++;
+ if (wait) {
+ long long tick;
+
+ mdp4_dsi_cmd_wait4vsync(cndx, &tick);
+ }
+
return cnt;
}
@@ -1016,6 +1022,8 @@
struct msm_fb_data_type *mfd;
struct vsycn_ctrl *vctrl;
struct mdp4_overlay_pipe *pipe;
+ struct vsync_update *vp;
+ int undx;
pr_debug("%s+:\n", __func__);
@@ -1048,6 +1056,16 @@
mdp_clk_ctrl(0);
}
+ undx = vctrl->update_ndx;
+ vp = &vctrl->vlist[undx];
+ if (vp->update_cnt) {
+ /*
+ * pipe's iommu will be freed at next overlay play
+ * and iommu_drop statistic will be increased by one
+ */
+ vp->update_cnt = 0; /* empty queue */
+ }
+
vctrl->clk_enabled = 0;
vctrl->vsync_enabled = 0;
vctrl->clk_control = 0;
@@ -1099,6 +1117,7 @@
struct vsycn_ctrl *vctrl;
struct mdp4_overlay_pipe *pipe;
unsigned long flags;
+ long long tick;
vctrl = &vsync_ctrl_db[cndx];
@@ -1139,8 +1158,10 @@
mdp4_overlay_mdp_perf_upd(mfd, 1);
mutex_lock(&mfd->dma->ov_mutex);
- mdp4_dsi_cmd_pipe_commit();
+ mdp4_dsi_cmd_pipe_commit(cndx, 0);
mutex_unlock(&mfd->dma->ov_mutex);
+ mdp4_dsi_cmd_wait4vsync(cndx, &tick);
+
mdp4_overlay_mdp_perf_upd(mfd, 0);
}
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index 6c9edb5..04f59f6 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -147,7 +147,7 @@
static void mdp4_dsi_video_wait4dmap(int cndx);
static void mdp4_dsi_video_wait4ov(int cndx);
-int mdp4_dsi_video_pipe_commit(void)
+int mdp4_dsi_video_pipe_commit(int cndx, int wait)
{
int i, undx;
@@ -159,7 +159,7 @@
unsigned long flags;
int cnt = 0;
- vctrl = &vsync_ctrl_db[0];
+ vctrl = &vsync_ctrl_db[cndx];
mutex_lock(&vctrl->update_lock);
undx = vctrl->update_ndx;
@@ -253,6 +253,13 @@
mdp4_stat.overlay_commit[pipe->mixer_num]++;
+ if (wait) {
+ if (pipe->ov_blt_addr)
+ mdp4_dsi_video_wait4ov(cndx);
+ else
+ mdp4_dsi_video_wait4dmap(cndx);
+ }
+
return cnt;
}
@@ -682,8 +689,9 @@
struct msm_fb_data_type *mfd;
struct vsycn_ctrl *vctrl;
struct mdp4_overlay_pipe *pipe;
+ struct vsync_update *vp;
unsigned long flags;
- int need_wait = 0;
+ int undx, need_wait = 0;
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
vctrl = &vsync_ctrl_db[cndx];
@@ -716,6 +724,16 @@
vsync_irq_disable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
}
+ undx = vctrl->update_ndx;
+ vp = &vctrl->vlist[undx];
+ if (vp->update_cnt) {
+ /*
+ * pipe's iommu will be freed at next overlay play
+ * and iommu_drop statistic will be increased by one
+ */
+ vp->update_cnt = 0; /* empty queue */
+ }
+
if (pipe) {
/* sanity check, free pipes besides base layer */
mdp4_overlay_unset_mixer(pipe->mixer_num);
@@ -1075,13 +1093,13 @@
mdp4_overlay_mdp_perf_upd(mfd, 1);
mutex_lock(&mfd->dma->ov_mutex);
- mdp4_dsi_video_pipe_commit();
+ mdp4_dsi_video_pipe_commit(cndx, 0);
mutex_unlock(&mfd->dma->ov_mutex);
if (pipe->ov_blt_addr)
- mdp4_dsi_video_wait4ov(0);
+ mdp4_dsi_video_wait4ov(cndx);
else
- mdp4_dsi_video_wait4dmap(0);
+ mdp4_dsi_video_wait4dmap(cndx);
mdp4_overlay_mdp_perf_upd(mfd, 0);
}
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index a89b5be..50f9eb0 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -165,7 +165,7 @@
static void mdp4_dtv_blt_ov_update(struct mdp4_overlay_pipe *pipe);
static void mdp4_dtv_wait4dmae(int cndx);
-int mdp4_dtv_pipe_commit(void)
+int mdp4_dtv_pipe_commit(int cndx, int wait)
{
int i, undx;
@@ -177,7 +177,7 @@
unsigned long flags;
int cnt = 0;
- vctrl = &vsync_ctrl_db[0];
+ vctrl = &vsync_ctrl_db[cndx];
mutex_lock(&vctrl->update_lock);
undx = vctrl->update_ndx;
vp = &vctrl->vlist[undx];
@@ -236,6 +236,9 @@
spin_unlock_irqrestore(&vctrl->spin_lock, flags);
mdp4_stat.overlay_commit[pipe->mixer_num]++;
+ if (wait)
+ mdp4_dtv_wait4dmae(cndx);
+
return cnt;
}
@@ -594,8 +597,10 @@
struct msm_fb_data_type *mfd;
int ret = 0;
int cndx = 0;
+ int undx;
struct vsycn_ctrl *vctrl;
struct mdp4_overlay_pipe *pipe;
+ struct vsync_update *vp;
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
@@ -641,6 +646,16 @@
vsync_irq_disable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
}
+ undx = vctrl->update_ndx;
+ vp = &vctrl->vlist[undx];
+ if (vp->update_cnt) {
+ /*
+ * pipe's iommu will be freed at next overlay play
+ * and iommu_drop statistic will be increased by one
+ */
+ vp->update_cnt = 0; /* empty queue */
+ }
+
ret = panel_next_off(pdev);
mdp_footswitch_ctrl(FALSE);
@@ -1060,7 +1075,7 @@
mutex_lock(&mfd->dma->ov_mutex);
mdp4_overlay_mdp_perf_upd(mfd, 1);
- mdp4_dtv_pipe_commit();
+ mdp4_dtv_pipe_commit(cndx, 0);
mdp4_overlay_mdp_perf_upd(mfd, 0);
mutex_unlock(&mfd->dma->ov_mutex);
}
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index 78c69b8..8796334 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -152,7 +152,7 @@
static void mdp4_lcdc_wait4dmap(int cndx);
static void mdp4_lcdc_wait4ov(int cndx);
-int mdp4_lcdc_pipe_commit(void)
+int mdp4_lcdc_pipe_commit(int cndx, int wait)
{
int i, undx;
@@ -164,7 +164,7 @@
unsigned long flags;
int cnt = 0;
- vctrl = &vsync_ctrl_db[0];
+ vctrl = &vsync_ctrl_db[cndx];
mutex_lock(&vctrl->update_lock);
undx = vctrl->update_ndx;
@@ -257,6 +257,13 @@
mdp4_stat.overlay_commit[pipe->mixer_num]++;
+ if (wait) {
+ if (pipe->ov_blt_addr)
+ mdp4_lcdc_wait4ov(cndx);
+ else
+ mdp4_lcdc_wait4dmap(cndx);
+ }
+
return cnt;
}
@@ -666,8 +673,9 @@
struct msm_fb_data_type *mfd;
struct vsycn_ctrl *vctrl;
struct mdp4_overlay_pipe *pipe;
+ struct vsync_update *vp;
unsigned long flags;
- int need_wait = 0;
+ int undx, need_wait = 0;
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
vctrl = &vsync_ctrl_db[cndx];
@@ -700,6 +708,16 @@
vsync_irq_disable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
}
+ undx = vctrl->update_ndx;
+ vp = &vctrl->vlist[undx];
+ if (vp->update_cnt) {
+ /*
+ * pipe's iommu will be freed at next overlay play
+ * and iommu_drop statistic will be increased by one
+ */
+ vp->update_cnt = 0; /* empty queue */
+ }
+
if (pipe) {
/* sanity check, free pipes besides base layer */
mdp4_overlay_unset_mixer(pipe->mixer_num);
@@ -962,13 +980,13 @@
mdp4_overlay_mdp_perf_upd(mfd, 1);
mutex_lock(&mfd->dma->ov_mutex);
- mdp4_lcdc_pipe_commit();
+ mdp4_lcdc_pipe_commit(cndx, 0);
mutex_unlock(&mfd->dma->ov_mutex);
if (pipe->ov_blt_addr)
- mdp4_lcdc_wait4ov(0);
+ mdp4_lcdc_wait4ov(cndx);
else
- mdp4_lcdc_wait4dmap(0);
+ mdp4_lcdc_wait4dmap(cndx);
mdp4_overlay_mdp_perf_upd(mfd, 0);
}
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index 80ef22a..87921e6 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -110,21 +110,22 @@
.csc_data = {
(0),
{
- 0x0200, 0x0000, 0x0000,
- 0x0000, 0x0200, 0x0000,
- 0x0000, 0x0000, 0x0200,
+ 0x0083, 0x0102, 0x0032,
+ 0x1fb5, 0x1f6c, 0x00e1,
+ 0x00e1, 0x1f45, 0x1fdc,
},
{
0x0, 0x0, 0x0,
},
{
- 0, 0, 0,
+ 0x0010, 0x0080, 0x0080,
},
{
0, 0xff, 0, 0xff, 0, 0xff,
},
{
- 0, 0xff, 0, 0xff, 0, 0xff,
+ 0x0010, 0x00eb, 0x0010,
+ 0x00f0, 0x0010, 0x00f0,
},
},
},
@@ -133,21 +134,22 @@
.csc_data = {
(0),
{
- 0x0200, 0x0000, 0x0000,
- 0x0000, 0x0200, 0x0000,
- 0x0000, 0x0000, 0x0200,
+ 0x0083, 0x0102, 0x0032,
+ 0x1fb5, 0x1f6c, 0x00e1,
+ 0x00e1, 0x1f45, 0x1fdc,
},
{
0x0, 0x0, 0x0,
},
{
- 0, 0, 0,
+ 0x0010, 0x0080, 0x0080,
},
{
0, 0xff, 0, 0xff, 0, 0xff,
},
{
- 0, 0xff, 0, 0xff, 0, 0xff,
+ 0x0010, 0x00eb, 0x0010,
+ 0x00f0, 0x0010, 0x00f0,
},
},
},
@@ -176,7 +178,6 @@
},
};
-
unsigned is_mdp4_hw_reset(void)
{
unsigned hw_reset = 0;
@@ -2138,7 +2139,7 @@
base = 0x1A000;
break;
case MDP_BLOCK_OVERLAY_2:
- base = (mdp_rev >= MDP_REV_44) ? 0x8A000 : 0x0;
+ base = (mdp_rev >= MDP_REV_43) ? 0x8A000 : 0x0;
break;
case MDP_BLOCK_VG_1:
base = 0x24000;
@@ -2658,7 +2659,7 @@
break;
case MDP_BLOCK_OVERLAY_2:
- valid = (mdp_rev >= MDP_REV_44) ? 1 : 0;
+ valid = (mdp_rev >= MDP_REV_43) ? 1 : 0;
break;
default:
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 161f54a..5966989 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -351,6 +351,7 @@
{
struct mdss_mdp_ctl *ctl;
u32 width, height;
+ int ret = 0;
if (!mfd)
return -ENODEV;
@@ -363,23 +364,30 @@
return -EINVAL;
}
- ctl = mdss_mdp_ctl_alloc();
-
- if (!ctl) {
- pr_err("unable to allocate ctl\n");
- return -ENOMEM;
+ if (!mfd->ctl) {
+ ctl = mdss_mdp_ctl_alloc();
+ if (!ctl) {
+ pr_err("unable to allocate ctl\n");
+ return -ENOMEM;
+ }
+ ctl->mfd = mfd;
+ mfd->ctl = ctl;
+ } else {
+ ctl = mfd->ctl;
}
- ctl->mfd = mfd;
ctl->width = width;
ctl->height = height;
ctl->dst_format = mfd->panel_info.out_format;
- ctl->mixer_left = mdss_mdp_mixer_alloc(MDSS_MDP_MIXER_TYPE_INTF);
if (!ctl->mixer_left) {
- pr_err("unable to allocate layer mixer\n");
- mdss_mdp_ctl_free(ctl);
- return -ENOMEM;
+ ctl->mixer_left =
+ mdss_mdp_mixer_alloc(MDSS_MDP_MIXER_TYPE_INTF);
+ if (!ctl->mixer_left) {
+ pr_err("unable to allocate layer mixer\n");
+ ret = -ENOMEM;
+ goto ctl_init_fail;
+ }
}
if (width > MAX_MIXER_WIDTH)
@@ -390,17 +398,20 @@
ctl->mixer_left->ctl = ctl;
if (width < ctl->width) {
- ctl->mixer_right =
- mdss_mdp_mixer_alloc(MDSS_MDP_MIXER_TYPE_INTF);
- if (!ctl->mixer_right) {
- pr_err("unable to allocate right layer mixer\n");
- mdss_mdp_mixer_free(ctl->mixer_left);
- mdss_mdp_ctl_free(ctl);
- return -ENOMEM;
+ if (ctl->mixer_right == NULL) {
+ ctl->mixer_right =
+ mdss_mdp_mixer_alloc(MDSS_MDP_MIXER_TYPE_INTF);
+ if (!ctl->mixer_right) {
+ pr_err("unable to allocate right mixer\n");
+ ret = -ENOMEM;
+ goto ctl_init_fail;
+ }
}
ctl->mixer_right->width = width;
ctl->mixer_right->height = height;
ctl->mixer_right->ctl = ctl;
+ } else if (ctl->mixer_right) {
+ mdss_mdp_mixer_free(ctl->mixer_right);
}
switch (mfd->panel_info.type) {
@@ -432,9 +443,8 @@
break;
default:
pr_err("unsupported panel type (%d)\n", mfd->panel_info.type);
- mdss_mdp_ctl_free(ctl);
- return -EINVAL;
-
+ ret = -EINVAL;
+ goto ctl_init_fail;
}
ctl->opmode |= (ctl->intf_num << 4);
@@ -444,9 +454,17 @@
MDSS_MDP_CTL_OP_PACK_3D_H_ROW_INT;
}
- mfd->ctl = ctl;
+ctl_init_fail:
+ if (IS_ERR_VALUE(ret)) {
+ if (ctl->mixer_left)
+ mdss_mdp_mixer_free(ctl->mixer_left);
+ if (ctl->mixer_right)
+ mdss_mdp_mixer_free(ctl->mixer_right);
+ mdss_mdp_ctl_free(ctl);
+ mfd->ctl = NULL;
+ }
- return 0;
+ return ret;
}
static int mdss_mdp_ctl_destroy(struct msm_fb_data_type *mfd)
@@ -487,12 +505,11 @@
return -ENODEV;
}
- if (!mfd->ctl) {
- if (mdss_mdp_ctl_init(mfd)) {
- pr_err("unable to initialize ctl\n");
- return -ENODEV;
- }
+ if (mdss_mdp_ctl_init(mfd)) {
+ pr_err("unable to initialize ctl\n");
+ return -ENODEV;
}
+
ctl = mfd->ctl;
if (ctl->power_on) {
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index f70ef91..f76b508 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -326,7 +326,6 @@
}
pipe->params_changed++;
- pipe->play_cnt = 0;
req->id = pipe->ndx;
@@ -704,7 +703,6 @@
fbi = mfd->fbi;
if (fbi->fix.smem_len == 0) {
- pr_warn("fb memory not allocated\n");
mdss_mdp_overlay_kickoff(mfd->ctl);
return;
}
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 9f05a6a..1994b1b 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -2961,6 +2961,19 @@
return ret;
}
+static int msmfb_overlay_commit(struct fb_info *info, unsigned long *argp)
+{
+ int ret, ndx;
+
+ ret = copy_from_user(&ndx, argp, sizeof(ndx));
+ if (ret) {
+ pr_err("%s: ioctl failed\n", __func__);
+ return ret;
+ }
+
+ return mdp4_overlay_commit(info, ndx);
+}
+
static int msmfb_overlay_play(struct fb_info *info, unsigned long *argp)
{
int ret;
@@ -3388,6 +3401,11 @@
case MSMFB_OVERLAY_UNSET:
ret = msmfb_overlay_unset(info, argp);
break;
+ case MSMFB_OVERLAY_COMMIT:
+ down(&msm_fb_ioctl_ppp_sem);
+ ret = msmfb_overlay_commit(info, argp);
+ up(&msm_fb_ioctl_ppp_sem);
+ break;
case MSMFB_OVERLAY_PLAY:
ret = msmfb_overlay_play(info, argp);
break;
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index 861084a..1cdc434 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -71,6 +71,8 @@
#define MSMFB_OVERLAY_VSYNC_CTRL _IOW(MSMFB_IOCTL_MAGIC, 160, unsigned int)
#define MSMFB_VSYNC_CTRL _IOW(MSMFB_IOCTL_MAGIC, 161, unsigned int)
#define MSMFB_METADATA_SET _IOW(MSMFB_IOCTL_MAGIC, 162, struct msmfb_metadata)
+#define MSMFB_OVERLAY_COMMIT _IOW(MSMFB_IOCTL_MAGIC, 163, unsigned int)
+
#define FB_TYPE_3D_PANEL 0x10101010
#define MDP_IMGTYPE2_START 0x10000
#define MSMFB_DRIVER_VERSION 0xF9E8D701
diff --git a/include/media/vcap_fmt.h b/include/media/vcap_fmt.h
index 2641720..3b1bd7c2 100644
--- a/include/media/vcap_fmt.h
+++ b/include/media/vcap_fmt.h
@@ -13,6 +13,7 @@
#ifndef VCAP_FMT_H
#define VCAP_FMT_H
+#include <linux/videodev2.h>
#define V4L2_BUF_TYPE_INTERLACED_IN_DECODER (V4L2_BUF_TYPE_PRIVATE)
diff --git a/sound/soc/msm/apq8064-i2s.c b/sound/soc/msm/apq8064-i2s.c
index 6b5314a..e309370 100644
--- a/sound/soc/msm/apq8064-i2s.c
+++ b/sound/soc/msm/apq8064-i2s.c
@@ -2690,7 +2690,8 @@
static void __exit msm_audio_exit(void)
{
- if (!cpu_is_apq8064() || (socinfo_get_id() == 130)) {
+ if (!(cpu_is_apq8064() || cpu_is_apq8064ab()) ||
+ (socinfo_get_id() == 130)) {
pr_err("%s: Not the right machine type\n", __func__);
return ;
}
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index c8cf681..b921df1 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -2101,7 +2101,8 @@
{
int ret;
u32 version = socinfo_get_platform_version();
- if (!cpu_is_apq8064() || (socinfo_get_id() == 130) ||
+ if (!(cpu_is_apq8064() || cpu_is_apq8064ab()) ||
+ (socinfo_get_id() == 130) ||
(machine_is_apq8064_mtp() &&
(SOCINFO_VERSION_MINOR(version) == 1))) {
pr_info("%s: Not APQ8064 in SLIMBUS mode\n", __func__);
@@ -2141,7 +2142,8 @@
static void __exit msm_audio_exit(void)
{
- if (!cpu_is_apq8064() || (socinfo_get_id() == 130)) {
+ if (!(cpu_is_apq8064() || cpu_is_apq8064ab()) ||
+ (socinfo_get_id() == 130)) {
pr_err("%s: Not the right machine type\n", __func__);
return ;
}
diff --git a/sound/soc/msm/mpq8064.c b/sound/soc/msm/mpq8064.c
index 957b656..3cb7c58 100644
--- a/sound/soc/msm/mpq8064.c
+++ b/sound/soc/msm/mpq8064.c
@@ -45,6 +45,11 @@
#define TOP_SPK_AMP_POS 0x4
#define TOP_SPK_AMP_NEG 0x8
+#define GPIO_AUX_PCM_DOUT 43
+#define GPIO_AUX_PCM_DIN 44
+#define GPIO_AUX_PCM_SYNC 45
+#define GPIO_AUX_PCM_CLK 46
+
#define TABLA_EXT_CLK_RATE 12288000
#define TABLA_MBHC_DEF_BUTTONS 8
@@ -942,6 +947,78 @@
return ret;
}
+static int mpq8064_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ /* PCM only supports mono output with 8khz sample rate */
+ rate->min = rate->max = 8000;
+ channels->min = channels->max = 1;
+
+ return 0;
+}
+
+static int mpq8064_aux_pcm_get_gpios(void)
+{
+ int ret = 0;
+
+ pr_debug("%s\n", __func__);
+
+ ret = gpio_request(GPIO_AUX_PCM_DOUT, "AUX PCM DOUT");
+ if (ret < 0) {
+ pr_err("%s: Failed to request gpio(%d): AUX PCM DOUT",
+ __func__, GPIO_AUX_PCM_DOUT);
+ goto fail_dout;
+ }
+
+ ret = gpio_request(GPIO_AUX_PCM_DIN, "AUX PCM DIN");
+ if (ret < 0) {
+ pr_err("%s: Failed to request gpio(%d): AUX PCM DIN",
+ __func__, GPIO_AUX_PCM_DIN);
+ goto fail_din;
+ }
+
+ ret = gpio_request(GPIO_AUX_PCM_SYNC, "AUX PCM SYNC");
+ if (ret < 0) {
+ pr_err("%s: Failed to request gpio(%d): AUX PCM SYNC",
+ __func__, GPIO_AUX_PCM_SYNC);
+ goto fail_sync;
+ }
+ ret = gpio_request(GPIO_AUX_PCM_CLK, "AUX PCM CLK");
+ if (ret < 0) {
+ pr_err("%s: Failed to request gpio(%d): AUX PCM CLK",
+ __func__, GPIO_AUX_PCM_CLK);
+ goto fail_clk;
+ }
+
+ return 0;
+
+fail_clk:
+ gpio_free(GPIO_AUX_PCM_SYNC);
+fail_sync:
+ gpio_free(GPIO_AUX_PCM_DIN);
+fail_din:
+ gpio_free(GPIO_AUX_PCM_DOUT);
+fail_dout:
+
+ return ret;
+}
+
+static int mpq8064_aux_pcm_free_gpios(void)
+{
+ gpio_free(GPIO_AUX_PCM_DIN);
+ gpio_free(GPIO_AUX_PCM_DOUT);
+ gpio_free(GPIO_AUX_PCM_SYNC);
+ gpio_free(GPIO_AUX_PCM_CLK);
+
+ return 0;
+}
+
static int msm_startup(struct snd_pcm_substream *substream)
{
pr_debug("%s(): substream = %s stream = %d\n", __func__,
@@ -955,12 +1032,39 @@
substream->name, substream->stream);
}
+static int mpq8064_auxpcm_startup(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+
+ pr_debug("%s(): substream = %s\n", __func__, substream->name);
+ ret = mpq8064_aux_pcm_get_gpios();
+ if (ret < 0) {
+ pr_err("%s: Aux PCM GPIO request failed\n", __func__);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void mpq8064_auxpcm_shutdown(struct snd_pcm_substream *substream)
+{
+
+ pr_debug("%s(): substream = %s\n", __func__, substream->name);
+ mpq8064_aux_pcm_free_gpios();
+}
+
+
static struct snd_soc_ops msm_be_ops = {
.startup = msm_startup,
.hw_params = msm_hw_params,
.shutdown = msm_shutdown,
};
+static struct snd_soc_ops mpq8064_auxpcm_be_ops = {
+ .startup = mpq8064_auxpcm_startup,
+ .shutdown = mpq8064_auxpcm_shutdown,
+};
+
+
static int mpq8064_sec_i2s_rx_free_gpios(void)
{
int i;
@@ -1270,6 +1374,20 @@
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
},
+ {
+ .name = "AUXPCM Hostless",
+ .stream_name = "AUXPCM Hostless",
+ .cpu_dai_name = "AUXPCM_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1, /* dainlink has playback support */
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
/* Secondary I2S RX Hostless */
{
.name = "SEC_I2S_RX Hostless",
@@ -1451,6 +1569,31 @@
.no_pcm = 1,
.be_id = MSM_BACKEND_DAI_AFE_PCM_TX,
},
+ /* AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_AUXPCM_RX,
+ .stream_name = "AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6.2",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .be_id = MSM_BACKEND_DAI_AUXPCM_RX,
+ .be_hw_params_fixup = mpq8064_auxpcm_be_params_fixup,
+ .ops = &mpq8064_auxpcm_be_ops,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_AUXPCM_TX,
+ .stream_name = "AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .be_id = MSM_BACKEND_DAI_AUXPCM_TX,
+ .be_hw_params_fixup = mpq8064_auxpcm_be_params_fixup,
+ },
};
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index 550a492..0b9d54f 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -551,9 +551,7 @@
prtd->enabled = 1;
if (compr->info.codec_param.codec.id ==
- SND_AUDIOCODEC_AC3_PASS_THROUGH ||
- compr->info.codec_param.codec.id ==
- SND_AUDIOCODEC_DTS_PASS_THROUGH)
+ SND_AUDIOCODEC_PASS_THROUGH)
msm_pcm_routing_reg_psthr_stream(
soc_prtd->dai_link->be_id,
prtd->session_id, substream->stream,
@@ -768,9 +766,7 @@
q6asm_audio_client_buf_free_contiguous(dir,
prtd->audio_client);
if (compr->info.codec_param.codec.id ==
- SND_AUDIOCODEC_AC3_PASS_THROUGH ||
- compr->info.codec_param.codec.id ==
- SND_AUDIOCODEC_DTS_PASS_THROUGH)
+ SND_AUDIOCODEC_PASS_THROUGH)
msm_pcm_routing_reg_psthr_stream(
soc_prtd->dai_link->be_id,
prtd->session_id, substream->stream,
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index b086b8e..6865871 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -798,6 +798,25 @@
return 0;
}
+static int32_t is_no_wait_cmd_rsp(uint32_t opcode, uint32_t *cmd_type)
+{
+ if (opcode == APR_BASIC_RSP_RESULT) {
+ if (cmd_type != NULL) {
+ switch (cmd_type[0]) {
+ case ASM_SESSION_CMD_RUN:
+ case ASM_SESSION_CMD_PAUSE:
+ case ASM_DATA_CMD_EOS:
+ return 1;
+ default:
+ break;
+ }
+ } else
+ pr_err("%s: null pointer!", __func__);
+ } else if (opcode == ASM_DATA_CMDRSP_EOS)
+ return 1;
+
+ return 0;
+}
static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
{
@@ -818,14 +837,16 @@
ac->session);
return -EINVAL;
}
- if (atomic_read(&ac->nowait_cmd_cnt) > 0) {
+
+ payload = data->payload;
+ if ((atomic_read(&ac->nowait_cmd_cnt) > 0) &&
+ is_no_wait_cmd_rsp(data->opcode, payload)) {
pr_debug("%s: nowait_cmd_cnt %d\n",
__func__,
atomic_read(&ac->nowait_cmd_cnt));
atomic_dec(&ac->nowait_cmd_cnt);
wakeup_flag = 0;
}
- payload = data->payload;
if (data->opcode == RESET_EVENTS) {
pr_debug("q6asm_callback: Reset event is received: %d %d apr[%p]\n",